Add runtime detection for missing subpixel support in FreeType.
authoragl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 28 Jul 2009 18:38:08 +0000 (18:38 +0000)
committeragl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 28 Jul 2009 18:38:08 +0000 (18:38 +0000)
r291 added support for building on platforms where subpixel support
has been compiled out of FreeType. However, it turns out that there is
a common situation in which we build on platforms with subpixel
support, but have to run without it: people downloading Chromium from
the buildbots.

Because we this, we need a runtime solution. Modifying the conversion
routines for this seems suboptimal because the extra branches will
slow down everyone. So we probe subpixel support at runtime by trying
to install a low-pass filter. If we fail at this, then we map all the
SkScalerContext::Rec structures to remove subpixel mode.

http://codereview.appspot.com/98057

git-svn-id: http://skia.googlecode.com/svn/trunk@293 2bbb7eff-a529-9590-31e7-b0007b416f81

src/ports/SkFontHost_FreeType.cpp

index dbba1a28a4d0fb10b5eb5767e0a97c0cf80a6236..95025f91021bc4eafd2553b56948f83dc5f4bcec 100644 (file)
@@ -73,6 +73,8 @@ static SkMutex      gFTMutex;
 static int          gFTCount;
 static FT_Library   gFTLibrary;
 static SkFaceRec*   gFaceRecHead;
+static bool         gLCDSupportValid;  // true iff |gLCDSupport| has been set.
+static bool         gLCDSupport;  // true iff LCD is supported by the runtime.
 
 /////////////////////////////////////////////////////////////////////////
 
@@ -86,6 +88,8 @@ InitFreetype() {
     // Setup LCD filtering. This reduces colour fringes for LCD rendered
     // glyphs.
     err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT);
+    gLCDSupport = err == 0;
+    gLCDSupportValid = true;
 #endif
 
     return true;
@@ -263,6 +267,17 @@ static void unref_ft_face(FT_Face face) {
 ///////////////////////////////////////////////////////////////////////////
 
 void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
+    if (!gLCDSupportValid) {
+      InitFreetype();
+      FT_Done_FreeType(gFTLibrary);
+    }
+
+    if (!gLCDSupport && rec->isLCD()) {
+      // If the runtime Freetype library doesn't support LCD mode, we disable
+      // it here.
+      rec->fMaskFormat = SkMask::kA8_Format;
+    }
+
     SkPaint::Hinting h = rec->getHinting();
     if (SkPaint::kFull_Hinting == h && !rec->isLCD()) {
         // collapse full->normaling hinting if we're not doing LCD