Clean up FreeType code for 2.3.8.
authorbungeman <bungeman@google.com>
Fri, 21 Nov 2014 21:18:34 +0000 (13:18 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 21 Nov 2014 21:18:34 +0000 (13:18 -0800)
We already require FreeType 2.3.8 in order to compile and run.
Make this requirement explicit and take advantage of it.

Review URL: https://codereview.chromium.org/748063003

gyp/freetype.gyp
src/ports/SkFontHost_FreeType.cpp

index cd71e78dabaf0763922be145a23c2c1af378626a..fc528d426db9e12d955b5117dbe9266132b39a14 100644 (file)
@@ -41,9 +41,9 @@
                       ],
                     },
                     'defines': [
-                      # The font host requires at least FreeType 2.3.0
-                      # at runtime.
-                      'SK_FONTHOST_FREETYPE_RUNTIME_VERSION=0x020300',
+                      # Skia's FreeType port requires at least FreeType 2.3.8
+                      # for building and at runtime.
+                      'SK_FONTHOST_FREETYPE_RUNTIME_VERSION=0x020308',
                       'SK_CAN_USE_DLOPEN=1',
                     ],
                   }
index 0c28cc28904231d87f9cf76713c2dfe08e41b4e3..7f70d4e045af56959119309503da2169a4cbf0fc 100644 (file)
 #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.
@@ -79,7 +58,8 @@
 
 //#define ENABLE_GLYPH_SPEW     // for tracing calls
 //#define DUMP_STRIKE_CREATION
-
+//#define SK_FONTHOST_FREETYPE_USE_NORMAL_LCD_FILTER
+//#define SK_FONTHOST_FREETYPE_RUNTIME_VERSION
 //#define SK_GAMMA_APPLY_TO_A8
 
 using namespace skia_advanced_typeface_metrics_utils;
@@ -118,13 +98,14 @@ typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char
 
 // Caller must lock gFTMutex before calling this function.
 static bool InitFreetype() {
+    gFTMutex.assertHeld();
+
     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 +117,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 +135,6 @@ static bool InitFreetype() {
 #endif
 #endif
     }
-#else
-    gLCDSupport = false;
-#endif
     gLCDSupportValid = true;
 
     return true;
@@ -291,6 +268,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) {
+    gFTMutex.assertHeld();
+
     const SkFontID fontID = typeface->uniqueID();
     SkFaceRec* rec = gFaceRecHead;
     while (rec) {
@@ -316,24 +295,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 +318,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) {
+    gFTMutex.assertHeld();
+
     SkFaceRec*  rec = gFaceRecHead;
     SkFaceRec*  prev = NULL;
     while (rec) {
@@ -399,57 +377,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 +400,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 +408,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 +601,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 +1038,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 +1063,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 +1110,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 +1250,23 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
 #endif
 }
 
+static void clear_glyph_image(const SkGlyph& glyph) {
+    sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight);
+}
 
 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 +1275,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);