SkFontHost_FreeType constructor to correctly release resources.

BUG=chromium:589848

Review URL: https://codereview.chromium.org/1751883004
This commit is contained in:
bungeman 2016-03-01 15:15:09 -08:00 committed by Commit bot
parent 87a223401d
commit aabd71cc2c

View File

@ -25,6 +25,7 @@
#include "SkString.h"
#include "SkTemplates.h"
#include "SkTypes.h"
#include "SkUniquePtr.h"
#if defined(SK_CAN_USE_DLOPEN)
#include <dlfcn.h>
@ -148,7 +149,7 @@ SK_DECLARE_STATIC_MUTEX(gFTMutex);
static FreeTypeLibrary* gFTLibrary;
static SkFaceRec* gFaceRecHead;
// Private to RefFreeType and UnrefFreeType
// Private to ref_ft_library and unref_ft_library
static int gFTCount;
// Caller must lock gFTMutex before calling this function.
@ -171,6 +172,7 @@ static void unref_ft_library() {
--gFTCount;
if (0 == gFTCount) {
SkASSERT(nullptr == gFaceRecHead);
SkASSERT(nullptr != gFTLibrary);
delete gFTLibrary;
SkDEBUGCODE(gFTLibrary = nullptr;)
@ -675,6 +677,8 @@ void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
//BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119
//Cap the requested size as larger sizes give bogus values.
//Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed.
//Note that this also currently only protects against large text size requests,
//the total matrix is not taken into account here.
if (rec->fTextSize > SkIntToScalar(1 << 14)) {
rec->fTextSize = SkIntToScalar(1 << 14);
}
@ -786,6 +790,9 @@ static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const SkDescriptor* desc)
: SkScalerContext_FreeType_Base(typeface, desc)
, fFace(nullptr)
, fFTSize(nullptr)
, fStrikeIndex(-1)
{
SkAutoMutexAcquire ac(gFTMutex);
@ -794,10 +801,10 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S
}
// load the font file
fStrikeIndex = -1;
fFTSize = nullptr;
fFace = ref_ft_face(typeface);
if (nullptr == fFace) {
using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face>, unref_ft_face>;
skstd::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft_face(typeface));
if (nullptr == ftFace) {
SkDEBUGF(("Could not create FT_Face.\n"));
return;
}
@ -883,34 +890,41 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S
fLoadGlyphFlags = loadFlags;
}
FT_Error err = FT_New_Size(fFace, &fFTSize);
if (err != 0) {
SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, fFace->family_name));
fFace = nullptr;
return;
}
err = FT_Activate_Size(fFTSize);
if (err != 0) {
SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", fFace, fScaleX, fScaleY,
err));
fFTSize = nullptr;
using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Size>, FT_Done_Size>;
skstd::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFace]() -> FT_Size {
FT_Size size;
FT_Error err = FT_New_Size(ftFace.get(), &size);
if (err != 0) {
SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, ftFace->family_name));
return nullptr;
}
return size;
}());
if (nullptr == ftSize) {
SkDEBUGF(("Could not create FT_Size.\n"));
return;
}
if (FT_IS_SCALABLE(fFace)) {
err = FT_Set_Char_Size(fFace, fScaleX, fScaleY, 72, 72);
FT_Error err = FT_Activate_Size(ftSize.get());
if (err != 0) {
SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n",
ftFace.get(), fScaleX, fScaleY, err));
return;
}
if (FT_IS_SCALABLE(ftFace)) {
err = FT_Set_Char_Size(ftFace.get(), fScaleX, fScaleY, 72, 72);
if (err != 0) {
SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n",
fFace, fScaleX, fScaleY, err));
fFace = nullptr;
ftFace.get(), fScaleX, fScaleY, err));
return;
}
FT_Set_Transform(fFace, &fMatrix22, nullptr);
} else if (FT_HAS_FIXED_SIZES(fFace)) {
fStrikeIndex = chooseBitmapStrike(fFace, fScaleY);
FT_Set_Transform(ftFace.get(), &fMatrix22, nullptr);
} else if (FT_HAS_FIXED_SIZES(ftFace)) {
fStrikeIndex = chooseBitmapStrike(ftFace.get(), fScaleY);
if (fStrikeIndex == -1) {
SkDEBUGF(("no glyphs for font \"%s\" size %f?\n",
fFace->family_name, SkFDot6ToScalar(fScaleY)));
ftFace->family_name, SkFDot6ToScalar(fScaleY)));
} else {
// FreeType does no provide linear metrics for bitmap fonts.
linearMetrics = false;
@ -928,6 +942,8 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S
fFace->family_name, SkFDot6ToScalar(fScaleY)));
}
fFTSize = ftSize.release();
fFace = ftFace.release();
fDoLinearMetrics = linearMetrics;
}