aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2014-11-21 13:18:34 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-21 13:18:34 -0800
commit5ec443c506ed5b180018091c2d192e013dfb44ce (patch)
tree9d0d893e2d95438f6b9b82cb541cb8484590e3d2 /src/ports
parentfc1e996bccab153cb7da3d6a1115b0a1390dc252 (diff)
Clean up FreeType code for 2.3.8.
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
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp130
1 files changed, 33 insertions, 97 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 0c28cc2890..7f70d4e045 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.
@@ -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);