[PDF] Subset font advance data (W array).

Patch by arthurhsu@chromium.org. Original CL:
http://codereview.appspot.com/4830068
http://codereview.appspot.com/4905051/

Review URL: http://codereview.appspot.com/4911042

git-svn-id: http://skia.googlecode.com/svn/trunk@2134 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 2894a3d..0939015 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -408,7 +408,9 @@
 // static
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID,
-        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount) {
 #if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
     return NULL;
 #else
@@ -521,7 +523,7 @@
     info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
                                     face->bbox.xMax, face->bbox.yMin);
 
-    if (!canEmbed(face) || !FT_IS_SCALABLE(face) || 
+    if (!canEmbed(face) || !FT_IS_SCALABLE(face) ||
             info->fType == SkAdvancedTypefaceMetrics::kOther_Font) {
         perGlyphInfo = SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo;
     }
@@ -552,7 +554,11 @@
                         SkAdvancedTypefaceMetrics::WidthRange::kRange);
         } else {
             info->fGlyphWidths.reset(
-                getAdvanceData(face, face->num_glyphs, &getWidthAdvance));
+                getAdvanceData(face,
+                               face->num_glyphs,
+                               glyphIDs,
+                               glyphIDsCount,
+                               &getWidthAdvance));
         }
     }
 
@@ -588,6 +594,7 @@
     return info;
 #endif
 }
+
 ///////////////////////////////////////////////////////////////////////////
 
 static bool bothZero(SkScalar a, SkScalar b) {
@@ -622,7 +629,7 @@
         // to do subpixel, we must have at most slight hinting
         h = SkPaint::kSlight_Hinting;
     }
-#ifndef SK_IGNORE_ROTATED_FREETYPE_FIX 
+#ifndef SK_IGNORE_ROTATED_FREETYPE_FIX
     // rotated text looks bad with hinting, so we disable it as needed
     if (!isAxisAligned(*rec)) {
         h = SkPaint::kNo_Hinting;
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index 70bc0b6..d5c50fb 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -40,7 +40,7 @@
 
 static uint32_t find_from_name(const char name[]) {
     CFStringRef str = CFStringCreateWithCString(NULL, name,
-                                                kCFStringEncodingUTF8); 
+                                                kCFStringEncodingUTF8);
     uint32_t fontID = ::ATSFontFindFromName(str, kATSOptionFlagsDefault);
     CFRelease(str);
     return fontID;
@@ -93,7 +93,7 @@
     ATSUStyle       fStyle;
     CGColorSpaceRef fGrayColorSpace;
     CGAffineTransform   fTransform;
-    
+
     static OSStatus MoveTo(const Float32Point *pt, void *cb);
     static OSStatus Line(const Float32Point *pt, void *cb);
     static OSStatus Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb);
@@ -122,20 +122,20 @@
 {
     SkAutoMutexAcquire  ac(gFTMutex);
     OSStatus err;
-    
+
     err = ::ATSUCreateStyle(&fStyle);
     SkASSERT(0 == err);
-            
+
     SkMatrix    m;
     fRec.getSingleMatrix(&m);
-    
+
     fTransform = CGAffineTransformMake(SkScalarToFloat(m[SkMatrix::kMScaleX]),
                                        SkScalarToFloat(m[SkMatrix::kMSkewX]),
                                        SkScalarToFloat(m[SkMatrix::kMSkewY]),
                                        SkScalarToFloat(m[SkMatrix::kMScaleY]),
                                        SkScalarToFloat(m[SkMatrix::kMTransX]),
                                        SkScalarToFloat(m[SkMatrix::kMTransY]));
-                                       
+
     ATSStyleRenderingOptions renderOpts = kATSStyleApplyAntiAliasing;
     switch (fRec.getHinting()) {
         case SkPaint::kNo_Hinting:
@@ -192,16 +192,16 @@
 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni)
 {
     SkAutoMutexAcquire  ac(gFTMutex);
-    
+
     OSStatus err;
     UniChar achar = uni;
     err = ::ATSUSetTextPointerLocation(fLayout,&achar,0,1,1);
     err = ::ATSUSetRunStyle(fLayout,fStyle,kATSUFromTextBeginning,kATSUToTextEnd);
-        
+
     ATSLayoutRecord *layoutPtr;
     ItemCount count;
     ATSGlyphRef glyph;
-    
+
     err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(fLayout,0,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr,&count);
     glyph = layoutPtr->glyphID;
     ::ATSUDirectReleaseLayoutDataArrayPtr(NULL,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr);
@@ -260,7 +260,7 @@
 {
     SkAutoMutexAcquire  ac(gFTMutex);
     SkASSERT(fLayout);
-    
+
     sk_bzero(glyph.fImage, glyph.fHeight * glyph.rowBytes());
     CGContextRef contextRef = ::CGBitmapContextCreate(glyph.fImage,
                                               glyph.fWidth, glyph.fHeight, 8,
@@ -270,10 +270,10 @@
         SkASSERT(false);
         return;
     }
-    
+
     ::CGContextSetGrayFillColor(contextRef, 1.0, 1.0);
     ::CGContextSetTextDrawingMode(contextRef, kCGTextFill);
-    
+
     CGGlyph glyphID = glyph.getGlyphID(fBaseGlyphCount);
     CGFontRef fontRef = CGFontCreateWithPlatformFont(&fRec.fFontID);
     CGContextSetFont(contextRef, fontRef);
@@ -281,7 +281,7 @@
     CGContextSetTextMatrix(contextRef, fTransform);
     CGContextShowGlyphsAtPoint(contextRef, -glyph.fLeft,
                                glyph.fTop + glyph.fHeight, &glyphID, 1);
-    
+
     ::CGContextRelease(contextRef);
 }
 
@@ -359,7 +359,7 @@
     for (int i = 0; i < 5; i++) {
         pts[i].set(0, SkIntToScalar(ys[i]) / upem);
     }
-    
+
     sk_free(hhea);
     sk_free(head);
     return true;
@@ -368,7 +368,7 @@
 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx,
                                               SkPaint::FontMetrics* my) {
     SkPoint pts[5];
-    
+
     if (!init_vertical_metrics(fRec.fFontID, pts)) {
         // these are not as accurate as init_vertical_metrics :(
         ATSFontMetrics metrics;
@@ -380,7 +380,7 @@
         pts[3].set(0, -SkFloatToScalar(metrics.descent));
         pts[4].set(0, SkFloatToScalar(metrics.leading));    //+ or -?
     }
-    
+
     SkMatrix m;
     fRec.getSingleMatrix(&m);
     m.mapPoints(pts, 5);
@@ -415,7 +415,7 @@
 {
     SkAutoMutexAcquire  ac(gFTMutex);
     OSStatus err,result;
-    
+
     err = ::ATSUGlyphGetCubicPaths(
             fStyle,glyph.fID,
             &SkScalerContext_Mac::MoveTo,
@@ -476,7 +476,9 @@
 // static
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID,
-        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount) {
     SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
     return NULL;
 }
@@ -545,33 +547,33 @@
         if (ATSFontGetTableDirectory(fontID, 0, NULL, &size)) {
             return;
         }
-        
+
         SkAutoMalloc storage(size);
         SkSFNTHeader* header = reinterpret_cast<SkSFNTHeader*>(storage.get());
         if (ATSFontGetTableDirectory(fontID, size, header, &size)) {
             return;
         }
-        
+
         fCount = SkEndian_SwapBE16(header->fNumTables);
         fData = header;
         storage.detach();
     }
-    
+
     ~SfntHeader() {
         sk_free(fData);
     }
-    
+
     int count() const { return fCount; }
     const SkSFNTDirEntry* entries() const {
         return reinterpret_cast<const SkSFNTDirEntry*>
             (reinterpret_cast<char*>(fData) + sizeof(SkSFNTHeader));
     }
-    
+
 private:
     int     fCount;
     void*   fData;
 };
-        
+
 int SkFontHost::CountTables(SkFontID fontID) {
     SfntHeader header(fontID, false);
     return header.count();
@@ -609,4 +611,3 @@
     }
     return length;
 }
-
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index 42d7ce2..5a5ad8f 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -129,13 +129,13 @@
     CTFontDescriptorRef         ctFontDesc;
     CFStringRef                 cfFontName;
     CTFontRef                   ctFont;
-    
-    
+
+
     // Get the state we need
     ctFontDesc   = NULL;
     ctFont       = NULL;
     ctFontTraits = 0;
-    
+
     if (theStyle & SkTypeface::kBold) {
         ctFontTraits |= kCTFontBoldTrait;
     }
@@ -143,27 +143,27 @@
     if (theStyle & SkTypeface::kItalic) {
         ctFontTraits |= kCTFontItalicTrait;
     }
-    
+
     // Create the font info
     cfFontName   = CFStringCreateWithCString(NULL, familyName, kCFStringEncodingUTF8);
     cfFontTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits);
     cfAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     cfTraits     = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    
-    
+
+
     // Create the font
     if (cfFontName != NULL && cfFontTraits != NULL && cfAttributes != NULL && cfTraits != NULL) {
         CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits);
-        
+
         CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName);
         CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute,     cfTraits);
-        
+
         ctFontDesc = CTFontDescriptorCreateWithAttributes(cfAttributes);
         if (ctFontDesc != NULL) {
             ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, 0, NULL);
         }
     }
-    
+
     CFSafeRelease(cfFontName);
     CFSafeRelease(cfFontTraits);
     CFSafeRelease(cfAttributes);
@@ -233,7 +233,7 @@
                             void* ctx) {
     const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face);
     const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx);
-    
+
     return rec->fStyle == style && mface->fName.equals(rec->fName);
 }
 
@@ -246,7 +246,7 @@
         { "serif",      "Times"     },
         { "monospace",  "Courier"   }
     };
-    
+
     for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
         if (strcmp(name, gPairs[i].fFrom) == 0) {
             return gPairs[i].fTo;
@@ -262,18 +262,18 @@
     if (familyName) {
         familyName = map_css_names(familyName);
     }
-    
+
     // Clone an existing typeface
     // TODO: only clone if style matches the familyFace's style...
     if (familyName == NULL && familyFace != NULL) {
         familyFace->ref();
         return const_cast<SkTypeface*>(familyFace);
     }
-    
+
     if (!familyName || !*familyName) {
         familyName = FONT_DEFAULT_NAME;
     }
-    
+
     NameStyleRec rec = { familyName, style };
     SkTypeface* face = SkTypefaceCache::FindByProc(FindByNameStyle, &rec);
 
@@ -761,7 +761,9 @@
 // static
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID,
-        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount) {
     CTFontRef ctFont = GetFontRefFromFontID(fontID);
     ctFont = CTFontCreateCopyWithAttributes(ctFont, CTFontGetUnitsPerEm(ctFont),
                                             NULL, NULL);
@@ -771,11 +773,11 @@
     // plus 1 byte for the trailing null.
     int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(
         fontName), kCFStringEncodingUTF8) + 1;
-    info->fFontName.resize(length); 
+    info->fFontName.resize(length);
     CFStringGetCString(fontName, info->fFontName.writable_str(), length,
         kCFStringEncodingUTF8);
     // Resize to the actual UTF-8 length used, stripping the null character.
-    info->fFontName.resize(strlen(info->fFontName.c_str())); 
+    info->fFontName.resize(strlen(info->fFontName.c_str()));
     info->fMultiMaster = false;
     CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
     info->fLastGlyphID = SkToU16(glyphCount - 1);
@@ -824,7 +826,7 @@
     CGGlyph glyphs[count];
     CGRect boundingRects[count];
     if (CTFontGetGlyphsForCharacters(ctFont, stem_chars, glyphs, count)) {
-        CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation, 
+        CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation,
             glyphs, boundingRects, count);
         for (size_t i = 0; i < count; i++) {
             int16_t width = boundingRects[i].size.width;
@@ -847,7 +849,11 @@
                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
         } else {
             info->fGlyphWidths.reset(
-                getAdvanceData(ctFont, glyphCount, &getWidthAdvance));
+                getAdvanceData(ctFont,
+                               glyphCount,
+                               glyphIDs,
+                               glyphIDsCount,
+                               &getWidthAdvance));
         }
     }
 
@@ -989,7 +995,7 @@
                                   SkScalerContext::kAutohinting_Flag;
 
     rec->fFlags &= ~flagsWeDontSupport;
-    
+
     // we only support 2 levels of hinting
     SkPaint::Hinting h = rec->getHinting();
     if (SkPaint::kSlight_Hinting == h) {
@@ -1115,7 +1121,3 @@
     memcpy(data, CFDataGetBytePtr(cfData) + offset, length);
     return(length);
 }
-
-
-
-
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index f292bdd..4a091bc 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -743,7 +743,9 @@
 // static
 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
         uint32_t fontID,
-        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount) {
     LOGFONT lf;
     GetLogFontByID(fontID, &lf);
     SkAdvancedTypefaceMetrics* info = NULL;
@@ -863,7 +865,11 @@
                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
         } else {
             info->fGlyphWidths.reset(
-                getAdvanceData(hdc, glyphCount, &getWidthAdvance));
+                getAdvanceData(hdc,
+                               glyphCount,
+                               glyphIDs,
+                               glyphIDsCount,
+                               &getWidthAdvance));
         }
     }