[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/core/SkAdvancedTypefaceMetrics.cpp b/src/core/SkAdvancedTypefaceMetrics.cpp
index f786671..cff0989 100644
--- a/src/core/SkAdvancedTypefaceMetrics.cpp
+++ b/src/core/SkAdvancedTypefaceMetrics.cpp
@@ -65,6 +65,8 @@
 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
         FontHandle fontHandle,
         int num_glyphs,
+        const uint32_t* subsetGlyphIDs,
+        uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
     // Assuming that an ASCII representation of a width or a glyph id is,
     // on average, 3 characters long gives the following cut offs for
@@ -82,10 +84,17 @@
     curRange = appendRange(&result, 0);
     Data lastAdvance = SK_MinS16;
     int repeats = 0;
+    uint32_t subsetIndex = 0;
     for (int gId = 0; gId <= num_glyphs; gId++) {
-        Data advance;
+        Data advance = 0;
         if (gId < num_glyphs) {
-            SkAssertResult(getAdvance(fontHandle, gId, &advance));
+            // Get glyph id only when subset is NULL, or the id is in subset.
+            if (!subsetGlyphIDs ||
+                (subsetIndex < subsetGlyphIDsLength &&
+                static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
+                SkAssertResult(getAdvance(fontHandle, gId, &advance));
+                ++subsetIndex;
+            }
         } else {
             advance = SK_MinS16;
         }
@@ -139,16 +148,22 @@
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
         HDC hdc,
         int num_glyphs,
+        const uint32_t* subsetGlyphIDs,
+        uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
 #elif defined(SK_BUILD_FOR_UNIX)
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
         FT_Face face,
         int num_glyphs,
+        const uint32_t* subsetGlyphIDs,
+        uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
         CTFontRef ctFont,
         int num_glyphs,
+        const uint32_t* subsetGlyphIDs,
+        uint32_t subsetGlyphIDsLength,
         bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
 #endif
 template void resetRange(
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 82ccca5..268fcc9 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -43,7 +43,7 @@
     // The initial value of 0 is fine, since a typeface's uniqueID should not
     // be zero.
     static uint32_t gDefaultFontID;
-    
+
     if (0 == gDefaultFontID) {
         SkTypeface* defaultFace =
                 SkFontHost::CreateTypeface(NULL, NULL, NULL, 0,
@@ -93,6 +93,11 @@
 }
 
 SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
-        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) const {
-    return SkFontHost::GetAdvancedTypefaceMetrics(fUniqueID, perGlyphInfo);
+        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
+        const uint32_t* glyphIDs,
+        uint32_t glyphIDsCount) const {
+    return SkFontHost::GetAdvancedTypefaceMetrics(fUniqueID,
+                                                  perGlyphInfo,
+                                                  glyphIDs,
+                                                  glyphIDsCount);
 }
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index d96afa8..7fe8b5c 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -528,7 +528,7 @@
 
 static int get_subset_font_stream(const char* fontName,
                                   const SkTypeface* typeface,
-                                  const SkPDFGlyphSet* subset,
+                                  const SkTDArray<uint32_t>& subset,
                                   SkPDFStream** fontStream) {
     SkRefPtr<SkStream> fontData =
             SkFontHost::OpenStream(SkTypeface::UniqueID(typeface));
@@ -537,11 +537,6 @@
     int fontSize = fontData->getLength();
 
 #if defined (SK_SFNTLY_SUBSETTER)
-    // Generate glyph id array.
-    SkTDArray<uint32_t> glyphIDs;
-    glyphIDs.push(0);  // Always include glyph 0.
-    subset->exportTo(&glyphIDs);
-
     // Read font into buffer.
     SkPDFStream* subsetFontStream = NULL;
     SkTDArray<unsigned char> originalFont;
@@ -555,8 +550,8 @@
         int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
                                                        originalFont.begin(),
                                                        fontSize,
-                                                       glyphIDs.begin(),
-                                                       glyphIDs.count(),
+                                                       subset.begin(),
+                                                       subset.count(),
                                                        &subsetFont);
         if (subsetFontSize > 0 && subsetFont != NULL) {
             SkAutoDataUnref data(SkData::NewWithProc(subsetFont,
@@ -751,13 +746,26 @@
         relatedFontDescriptor = relatedFont->getFontDescriptor();
     } else {
         SkAdvancedTypefaceMetrics::PerGlyphInfo info;
-        info = SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo;
-        info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
-                  info, SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo);
+        info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo;
         info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
                   info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo);
-        fontMetrics = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info);
+#if !defined (SK_SFNTLY_SUBSETTER)
+        info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
+                  info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
+#endif
+        fontMetrics =
+            SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0);
+#if defined (SK_SFNTLY_SUBSETTER)
         SkSafeUnref(fontMetrics.get());  // SkRefPtr and Get both took a ref.
+        if (fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
+            // Font does not support subsetting, get new info with advance.
+            info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
+                      info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
+            fontMetrics =
+                SkFontHost::GetAdvancedTypefaceMetrics(fontID, info, NULL, 0);
+            SkSafeUnref(fontMetrics.get());  // SkRefPtr and Get both took a ref
+        }
+#endif
     }
 
     SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID,
@@ -850,6 +858,13 @@
     return fFontInfo.get();
 }
 
+void SkPDFFont::setFontInfo(SkAdvancedTypefaceMetrics* info) {
+    if (info == NULL || info == fFontInfo.get()) {
+        return;
+    }
+    fFontInfo = info;
+}
+
 uint16_t SkPDFFont::firstGlyphID() const {
     return fFirstGlyphID;
 }
@@ -978,9 +993,10 @@
     insertName("BaseFont", fontInfo()->fFontName);
     insertName("Encoding", "Identity-H");
 
+    SkPDFCIDFont* newCIDFont;
+    newCIDFont = new SkPDFCIDFont(fontInfo(), typeface(), subset);
+
     // Pass ref new created to fResources.
-    SkPDFCIDFont* newCIDFont =
-        new SkPDFCIDFont(fontInfo(), typeface(), subset);
     addResource(newCIDFont);
     SkRefPtr<SkPDFArray> descendantFonts = new SkPDFArray();
     descendantFonts->unref();  // SkRefPtr and new took a reference.
@@ -1006,18 +1022,19 @@
 SkPDFCIDFont::~SkPDFCIDFont() {}
 
 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
-                                     const SkPDFGlyphSet* subset) {
+                                     const SkTDArray<uint32_t>* subset) {
     SkRefPtr<SkPDFDict> descriptor = new SkPDFDict("FontDescriptor");
     descriptor->unref();  // SkRefPtr and new both took a ref.
     setFontDescriptor(descriptor.get());
 
     switch (getType()) {
         case SkAdvancedTypefaceMetrics::kTrueType_Font: {
+            SkASSERT(subset);
             // Font subsetting
             SkPDFStream* rawStream = NULL;
             int fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(),
                                                   typeface(),
-                                                  subset,
+                                                  *subset,
                                                   &rawStream);
             SkASSERT(fontSize);
             SkASSERT(rawStream);
@@ -1060,6 +1077,36 @@
 }
 
 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
+    // Generate new font metrics with advance info for true type fonts.
+    if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
+        // Generate glyph id array.
+        SkTDArray<uint32_t> glyphIDs;
+        glyphIDs.push(0);  // Always include glyph 0.
+        if (subset) {
+            subset->exportTo(&glyphIDs);
+        }
+
+        SkRefPtr<SkAdvancedTypefaceMetrics> fontMetrics;
+        SkAdvancedTypefaceMetrics::PerGlyphInfo info;
+        info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo;
+        info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
+                  info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo);
+        uint32_t* glyphs = (glyphIDs.count() == 1) ? NULL : glyphIDs.begin();
+        uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
+        fontMetrics =
+            SkFontHost::GetAdvancedTypefaceMetrics(
+                    SkTypeface::UniqueID(typeface()),
+                    info,
+                    glyphs,
+                    glyphsCount);
+        SkSafeUnref(fontMetrics.get());  // SkRefPtr and Get both took a ref
+        setFontInfo(fontMetrics.get());
+        addFontDescriptor(0, &glyphIDs);
+    } else {
+        // Other CID fonts
+        addFontDescriptor(0, NULL);
+    }
+
     insertName("BaseFont", fontInfo()->fFontName);
 
     if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) {
@@ -1078,8 +1125,6 @@
     sysInfo->insertInt("Supplement", 0);
     insert("CIDSystemInfo", sysInfo.get());
 
-    addFontDescriptor(0, subset);
-
     if (fontInfo()->fGlyphWidths.get()) {
         int16_t defaultWidth = 0;
         SkRefPtr<SkPDFArray> widths =
diff --git a/src/pdf/SkPDFFontImpl.h b/src/pdf/SkPDFFontImpl.h
index 61983a4..d298a38 100755
--- a/src/pdf/SkPDFFontImpl.h
+++ b/src/pdf/SkPDFFontImpl.h
@@ -46,7 +46,8 @@
                  const SkPDFGlyphSet* subset);
 
     bool populate(const SkPDFGlyphSet* subset);
-    bool addFontDescriptor(int16_t defaultWidth, const SkPDFGlyphSet* subset);
+    bool addFontDescriptor(int16_t defaultWidth,
+                           const SkTDArray<uint32_t>* subset);
 };
 
 class SkPDFType1Font : public SkPDFFont {
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));
         }
     }