Chromium Code Reviews| Index: src/ports/SkFontHost_FreeType.cpp |
| diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp |
| index 0c28cc28904231d87f9cf76713c2dfe08e41b4e3..c516d1359678c1f334ffd4d9ab25fb10002c9ad5 100644 |
| --- a/src/ports/SkFontHost_FreeType.cpp |
| +++ b/src/ports/SkFontHost_FreeType.cpp |
| @@ -31,36 +31,15 @@ |
| #include <dlfcn.h> |
| #endif |
| #include <ft2build.h> |
| +#include FT_ADVANCES_H |
| +#include FT_BITMAP_H |
| #include FT_FREETYPE_H |
| +#include FT_LCD_FILTER_H |
| #include FT_OUTLINE_H |
| #include FT_SIZES_H |
| #include FT_TRUETYPE_TABLES_H |
| #include FT_TYPE1_TABLES_H |
| -#include FT_BITMAP_H |
| -// In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file. |
| -#include FT_SYNTHESIS_H |
| #include FT_XFREE86_H |
| -#ifdef FT_LCD_FILTER_H |
| -#include FT_LCD_FILTER_H |
| -#endif |
| - |
| -// Defined in FreeType 2.3.8 and later. |
| -// This is a silly build time check, we would need a runtime check if we really cared. |
| -#ifdef FT_ADVANCES_H |
| -#include FT_ADVANCES_H |
| -#endif |
| - |
| -#if 0 |
| -// Also include the files by name for build tools which require this. |
| -#include <freetype/freetype.h> |
| -#include <freetype/ftoutln.h> |
| -#include <freetype/ftsizes.h> |
| -#include <freetype/tttables.h> |
| -#include <freetype/ftadvanc.h> |
| -#include <freetype/ftlcdfil.h> |
| -#include <freetype/ftbitmap.h> |
| -#include <freetype/ftsynth.h> |
| -#endif |
| // FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA |
| // were introduced in FreeType 2.5.0. |
| @@ -118,13 +97,14 @@ typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char |
| // Caller must lock gFTMutex before calling this function. |
| static bool InitFreetype() { |
| + SkDEBUGCODE(gFTMutex.assertHeld()); |
|
mtklein
2014/11/21 21:00:03
Isn't the body of assertHeld() itself SkDEBUGCODE?
bungeman-skia
2014/11/21 21:07:43
Hmmm... so it is. Done.
|
| + |
| FT_Error err = FT_Init_FreeType(&gFTLibrary); |
| if (err) { |
| return false; |
| } |
| // Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs. |
| -#ifdef FT_LCD_FILTER_H |
| // Use default { 0x10, 0x40, 0x70, 0x40, 0x10 }, as it adds up to 0x110, simulating ink spread. |
| // SetLcdFilter must be called before SetLcdFilterWeights. |
| err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT); |
| @@ -136,10 +116,9 @@ static bool InitFreetype() { |
| // This also adds to 0x110 simulating ink spread, but provides better results than default. |
| static unsigned char gGaussianLikeHeavyWeights[] = { 0x1A, 0x43, 0x56, 0x43, 0x1A, }; |
| -#if defined(SK_FONTHOST_FREETYPE_RUNTIME_VERSION) && \ |
| - SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400 |
| +#if SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400 |
| err = FT_Library_SetLcdFilterWeights(gFTLibrary, gGaussianLikeHeavyWeights); |
| -#elif defined(SK_CAN_USE_DLOPEN) && SK_CAN_USE_DLOPEN == 1 |
| +#elif SK_CAN_USE_DLOPEN == 1 |
| //The FreeType library is already loaded, so symbols are available in process. |
| void* self = dlopen(NULL, RTLD_LAZY); |
| if (self) { |
| @@ -155,9 +134,6 @@ static bool InitFreetype() { |
| #endif |
| #endif |
| } |
| -#else |
| - gLCDSupport = false; |
| -#endif |
| gLCDSupportValid = true; |
| return true; |
| @@ -291,6 +267,8 @@ SkFaceRec::SkFaceRec(SkStream* strm, uint32_t fontID) |
| // Will return 0 on failure |
| // Caller must lock gFTMutex before calling this function. |
| static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { |
| + SkDEBUGCODE(gFTMutex.assertHeld()); |
| + |
| const SkFontID fontID = typeface->uniqueID(); |
| SkFaceRec* rec = gFaceRecHead; |
| while (rec) { |
| @@ -316,24 +294,21 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { |
| const void* memoryBase = strm->getMemoryBase(); |
| if (memoryBase) { |
| -//printf("mmap(%s)\n", keyString.c_str()); |
| args.flags = FT_OPEN_MEMORY; |
| args.memory_base = (const FT_Byte*)memoryBase; |
| args.memory_size = strm->getLength(); |
| } else { |
| -//printf("fopen(%s)\n", keyString.c_str()); |
| args.flags = FT_OPEN_STREAM; |
| args.stream = &rec->fFTStream; |
| } |
| FT_Error err = FT_Open_Face(gFTLibrary, &args, face_index, &rec->fFace); |
| if (err) { // bad filename, try the default font |
| - fprintf(stderr, "ERROR: unable to open font '%x'\n", fontID); |
| + SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); |
| SkDELETE(rec); |
| return NULL; |
| } else { |
| SkASSERT(rec->fFace); |
| - //fprintf(stderr, "Opened font '%s'\n", filename.c_str()); |
| rec->fNext = gFaceRecHead; |
| gFaceRecHead = rec; |
| return rec; |
| @@ -342,6 +317,8 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { |
| // Caller must lock gFTMutex before calling this function. |
| static void unref_ft_face(FT_Face face) { |
| + SkDEBUGCODE(gFTMutex.assertHeld()); |
| + |
| SkFaceRec* rec = gFaceRecHead; |
| SkFaceRec* prev = NULL; |
| while (rec) { |
| @@ -399,57 +376,15 @@ private: |
| /////////////////////////////////////////////////////////////////////////// |
| -// Work around for old versions of freetype. |
| -static FT_Error getAdvances(FT_Face face, FT_UInt start, FT_UInt count, |
| - FT_Int32 loadFlags, FT_Fixed* advances) { |
| -#ifdef FT_ADVANCES_H |
| - return FT_Get_Advances(face, start, count, loadFlags, advances); |
| -#else |
| - if (!face || start >= face->num_glyphs || |
| - start + count > face->num_glyphs || loadFlags != FT_LOAD_NO_SCALE) { |
| - return 6; // "Invalid argument." |
| - } |
| - if (count == 0) |
| - return 0; |
| - |
| - for (int i = 0; i < count; i++) { |
| - FT_Error err = FT_Load_Glyph(face, start + i, FT_LOAD_NO_SCALE); |
| - if (err) |
| - return err; |
| - advances[i] = face->glyph->advance.x; |
| - } |
| - |
| - return 0; |
| -#endif |
| -} |
| - |
| static bool canEmbed(FT_Face face) { |
| -#ifdef FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
| FT_UShort fsType = FT_Get_FSType_Flags(face); |
| return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING | |
| FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0; |
| -#else |
| - // No embedding is 0x2 and bitmap embedding only is 0x200. |
| - TT_OS2* os2_table; |
| - if ((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != NULL) { |
| - return (os2_table->fsType & 0x202) == 0; |
| - } |
| - return false; // We tried, fail safe. |
| -#endif |
| } |
| static bool canSubset(FT_Face face) { |
| -#ifdef FT_FSTYPE_NO_SUBSETTING |
| FT_UShort fsType = FT_Get_FSType_Flags(face); |
| return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0; |
| -#else |
| - // No subset is 0x100. |
| - TT_OS2* os2_table; |
| - if ((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != NULL) { |
| - return (os2_table->fsType & 0x100) == 0; |
| - } |
| - return false; // We tried, fail safe. |
| -#endif |
| } |
| static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) { |
| @@ -464,7 +399,7 @@ static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) { |
| static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) { |
| FT_Fixed advance = 0; |
| - if (getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { |
| + if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { |
| return false; |
| } |
| SkASSERT(data); |
| @@ -472,8 +407,7 @@ static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) { |
| return true; |
| } |
| -static void populate_glyph_to_unicode(FT_Face& face, |
| - SkTDArray<SkUnichar>* glyphToUnicode) { |
| +static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyphToUnicode) { |
| // Check and see if we have Unicode cmaps. |
| for (int i = 0; i < face->num_charmaps; ++i) { |
| // CMaps known to support Unicode: |
| @@ -666,10 +600,10 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( |
| for (int gID = 0; gID < face->num_glyphs; gID += 128) { |
| FT_Fixed advances[128]; |
| int advanceCount = 128; |
| - if (gID + advanceCount > face->num_glyphs) |
| + if (gID + advanceCount > face->num_glyphs) { |
| advanceCount = face->num_glyphs - gID; |
| - getAdvances(face, gID, advanceCount, FT_LOAD_NO_SCALE, |
| - advances); |
| + } |
| + FT_Get_Advances(face, gID, advanceCount, FT_LOAD_NO_SCALE, advances); |
| for (int i = 0; i < advanceCount; i++) { |
| int16_t advance = advances[i]; |
| info->fGlyphWidths->fAdvance.append(1, &advance); |
| @@ -1103,7 +1037,6 @@ SkUnichar SkScalerContext_FreeType::generateGlyphToChar(uint16_t glyph) { |
| } |
| void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) { |
| -#ifdef FT_ADVANCES_H |
| /* unhinted and light hinted text have linearly scaled advances |
| * which are very cheap to compute with some font formats... |
| */ |
| @@ -1129,7 +1062,7 @@ void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) { |
| return; |
| } |
| } |
| -#endif /* FT_ADVANCES_H */ |
| + |
| /* otherwise, we need to load/hint the glyph, which is slower */ |
| this->generateMetrics(glyph); |
| return; |
| @@ -1176,10 +1109,12 @@ void SkScalerContext_FreeType::getBBoxForCurrentGlyph(SkGlyph* glyph, |
| bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) { |
| const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter); |
| - if (!glyph_id) |
| + if (!glyph_id) { |
| return false; |
| - if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0) |
| + } |
| + if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0) { |
| return false; |
| + } |
| emboldenIfNeeded(fFace, fFace->glyph); |
| FT_Outline_Get_CBox(&fFace->glyph->outline, bbox); |
| return true; |
| @@ -1314,22 +1249,23 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { |
| #endif |
| } |
| +static void clear_glyph_image(const SkGlyph& glyph) { |
| + memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); |
|
mtklein
2014/11/21 21:00:03
sk_bzero?
bungeman-skia
2014/11/21 21:07:43
Why not, I just copy-pasted this to get around the
|
| +} |
| void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { |
| SkAutoMutexAcquire ac(gFTMutex); |
| - FT_Error err; |
| - |
| if (this->setupSize()) { |
| - goto ERROR; |
| + clear_glyph_image(glyph); |
| + return; |
| } |
| - err = FT_Load_Glyph( fFace, glyph.getGlyphID(), fLoadGlyphFlags); |
| + FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags); |
| if (err != 0) { |
| SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", |
| - glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err)); |
| - ERROR: |
| - memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); |
| + glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err)); |
| + clear_glyph_image(glyph); |
| return; |
| } |
| @@ -1338,8 +1274,7 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { |
| } |
| -void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, |
| - SkPath* path) { |
| +void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) { |
| SkAutoMutexAcquire ac(gFTMutex); |
| SkASSERT(path); |