Revert "[PDF] Refactor SkPDFFont to enable font/cmap subsetting."

The PDF xref table is corrupt with this change. Revert until we figure it out.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@1944 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pdf/SkBitSet.cpp b/src/pdf/SkBitSet.cpp
index c7af832..f19dd69 100755
--- a/src/pdf/SkBitSet.cpp
+++ b/src/pdf/SkBitSet.cpp
@@ -73,12 +73,12 @@
     }
 }
 
-bool SkBitSet::isBitSet(int index) const {
+bool SkBitSet::isBitSet(int index) {
     uint32_t mask = 1 << (index % 32);
     return (*internalGet(index) & mask);
 }
 
-bool SkBitSet::orBits(const SkBitSet& source) {
+bool SkBitSet::orBits(SkBitSet& source) {
     if (fBitCount != source.fBitCount) {
         return false;
     }
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index e2dfba6..619d55d 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -424,8 +424,8 @@
     }
 }
 
-SkDevice* SkPDFDevice::onCreateCompatibleDevice(SkBitmap::Config config,
-                                                int width, int height,
+SkDevice* SkPDFDevice::onCreateCompatibleDevice(SkBitmap::Config config, 
+                                                int width, int height, 
                                                 bool isOpaque,
                                                 Usage usage) {
     SkMatrix initialTransform;
@@ -544,7 +544,7 @@
 }
 
 SkPDFDevice::~SkPDFDevice() {
-    this->cleanUp(true);
+    this->cleanUp();
 }
 
 void SkPDFDevice::init() {
@@ -553,24 +553,18 @@
     fLastContentEntry = NULL;
     fMarginContentEntries.reset();
     fLastMarginContentEntry = NULL;
-    fDrawingArea = kContent_DrawingArea;
-    if (fFontGlyphUsage == NULL) {
-        fFontGlyphUsage.reset(new SkPDFGlyphSetMap());
-    }
+    fDrawingArea = kContent_DrawingArea; 
 }
 
-void SkPDFDevice::cleanUp(bool clearFontUsage) {
+void SkPDFDevice::cleanUp() {
     fGraphicStateResources.unrefAll();
     fXObjectResources.unrefAll();
     fFontResources.unrefAll();
     fShaderResources.unrefAll();
-    if (clearFontUsage) {
-        fFontGlyphUsage->reset();
-    }
 }
 
 void SkPDFDevice::clear(SkColor color) {
-    this->cleanUp(true);
+    this->cleanUp();
     this->init();
 
     SkPaint paint;
@@ -831,8 +825,6 @@
         size_t availableGlyphs =
             font->glyphsToPDFFontEncoding(glyphIDs + consumedGlyphCount,
                                           numGlyphs - consumedGlyphCount);
-        fFontGlyphUsage->noteGlyphUsage(font, glyphIDs + consumedGlyphCount,
-                                        availableGlyphs);
         SkString encodedString =
             SkPDFString::FormatString(glyphIDs + consumedGlyphCount,
                                       availableGlyphs, font->multiByteGlyphs());
@@ -901,7 +893,6 @@
             i--;
             continue;
         }
-        fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
         SkScalar x = pos[i * scalarsPerPos];
         SkScalar y = scalarsPerPos == 1 ? constY : pos[i * scalarsPerPos + 1];
         align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y, NULL);
@@ -961,9 +952,6 @@
     fXObjectResources.push(xobject);  // Transfer reference.
     SkPDFUtils::DrawFormXObject(fXObjectResources.count() - 1,
                                 &content.entry()->fContent);
-
-    // Merge glyph sets from the drawn device.
-    fFontGlyphUsage->merge(pdfDevice->getFontGlyphUsage());
 }
 
 ContentEntry* SkPDFDevice::getLastContentEntry() {
@@ -1154,7 +1142,7 @@
         SkRect r = SkRect::MakeWH(this->width(), this->height());
         emit_clip(NULL, &r, &data);
     }
-
+    
     SkPDFDevice::copyContentEntriesToData(fContentEntries.get(), &data);
 
     // potentially we could cache this SkData, and only rebuild it if we
@@ -1166,10 +1154,7 @@
         SkRefPtr<SkPDFFormXObject>* xobject) {
     *xobject = new SkPDFFormXObject(this);
     (*xobject)->unref();  // SkRefPtr and new both took a reference.
-    // We always draw the form xobjects that we create back into the device, so
-    // we simply preserve the font usage instead of pulling it out and merging
-    // it back in later.
-    cleanUp(false);  // Reset this device to have no content.
+    cleanUp();  // Reset this device to have no content.
     init();
 }
 
diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp
index 38f4f32..71c3784 100644
--- a/src/pdf/SkPDFDocument.cpp
+++ b/src/pdf/SkPDFDocument.cpp
@@ -18,7 +18,6 @@
 #include "SkPDFDevice.h"
 #include "SkPDFDocument.h"
 #include "SkPDFPage.h"
-#include "SkPDFFont.h"
 #include "SkStream.h"
 
 // Add the resources, starting at firstIndex to the catalog, removing any dupes.
@@ -38,29 +37,6 @@
     }
 }
 
-static void perform_font_subsetting(SkPDFCatalog* catalog,
-                                    const SkTDArray<SkPDFPage*>& pages,
-                                    SkTDArray<SkPDFObject*>* substitutes) {
-    SkASSERT(catalog);
-    SkASSERT(substitutes);
-
-    SkPDFGlyphSetMap usage;
-    for (int i = 0; i < pages.count(); ++i) {
-        usage.merge(pages[i]->getFontGlyphUsage());
-    }
-    SkPDFGlyphSetMap::F2BIter iterator(usage);
-    SkPDFGlyphSetMap::FontGlyphSetPair* entry = iterator.next();
-    while (entry) {
-        SkPDFFont* subsetFont =
-            entry->fFont->getFontSubset(entry->fGlyphSet);
-        if (subsetFont) {
-            catalog->setSubstitute(entry->fFont, subsetFont);
-            substitutes->push(subsetFont);  // Transfer ownership to substitutes
-        }
-        entry = iterator.next();
-    }
-}
-
 SkPDFDocument::SkPDFDocument(Flags flags)
         : fXRefFileOffset(0),
           fSecondPageFirstResourceIndex(0) {
@@ -79,7 +55,6 @@
         fPageTree[i]->clear();
     fPageTree.safeUnrefAll();
     fPageResources.safeUnrefAll();
-    fSubstitutes.safeUnrefAll();
 }
 
 bool SkPDFDocument::emitPDF(SkWStream* stream) {
@@ -123,9 +98,6 @@
             }
         }
 
-        // Build font subsetting info before proceeding.
-        perform_font_subsetting(fCatalog.get(), fPages, &fSubstitutes);
-
         // Figure out the size of things and inform the catalog of file offsets.
         off_t fileOffset = headerSize();
         fileOffset += fCatalog->setFileOffset(fDocCatalog.get(), fileOffset);
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
old mode 100644
new mode 100755
index f50580a..be16c76
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -20,10 +20,8 @@
 #include "SkFontHost.h"
 #include "SkGlyphCache.h"
 #include "SkPaint.h"
-#include "SkPDFCatalog.h"
 #include "SkPDFDevice.h"
 #include "SkPDFFont.h"
-#include "SkPDFFontImpl.h"
 #include "SkPDFStream.h"
 #include "SkPDFTypes.h"
 #include "SkPDFUtils.h"
@@ -36,10 +34,6 @@
 
 namespace {
 
-///////////////////////////////////////////////////////////////////////////////
-// File-Local Functions
-///////////////////////////////////////////////////////////////////////////////
-
 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
                      size_t* size) {
     // PFB sections have a two or six bytes header. 0x80 and a one byte
@@ -140,7 +134,7 @@
 
 SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
                             size_t* dataLen, size_t* trailerLen) {
-    // srcStream may be backed by a file or a unseekable fd, so we may not be
+    // srcStream may be backed by a file or a unseekable fd, so we may not be 
     // able to use skip(), rewind(), or getMemoryBase().  read()ing through
     // the input only once is doable, but very ugly. Furthermore, it'd be nice
     // if the data was NUL terminated so that we can use strstr() to search it.
@@ -391,14 +385,14 @@
 // Generate <bfchar> table according to PDF spec 1.4 and Adobe Technote 5014.
 static void append_cmap_bfchar_sections(
                 const SkTDArray<SkUnichar>& glyphUnicode,
-                const SkPDFGlyphSet* subset, SkDynamicMemoryWStream* cmap) {
+                SkDynamicMemoryWStream* cmap) {
     // PDF spec defines that every bf* list can have at most 100 entries.
     const size_t kMaxEntries = 100;
     uint16_t glyphId[kMaxEntries];
     SkUnichar unicode[kMaxEntries];
     size_t index = 0;
     for (int i = 0; i < glyphUnicode.count(); i++) {
-        if (glyphUnicode[i] && (subset == NULL || subset->has(i))) {
+        if (glyphUnicode[i]) {
             glyphId[index] = i;
             unicode[index] = glyphUnicode[i];
             ++index;
@@ -414,112 +408,6 @@
     }
 }
 
-static SkPDFStream* generate_tounicode_cmap(
-                        const SkTDArray<SkUnichar>& glyphUnicode,
-                        const SkPDFGlyphSet* subset) {
-    SkDynamicMemoryWStream cmap;
-    append_tounicode_header(&cmap);
-    append_cmap_bfchar_sections(glyphUnicode, subset, &cmap);
-    append_cmap_footer(&cmap);
-    SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream();
-    cmapStream->unref();  // SkRefPtr and new took a reference.
-    cmapStream->setData(cmap.copyToData());
-    return new SkPDFStream(cmapStream.get());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFGlyphSet
-///////////////////////////////////////////////////////////////////////////////
-
-SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) {
-}
-
-void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) {
-    for (int i = 0; i < numGlyphs; ++i) {
-        fBitSet.setBit(glyphIDs[i], true);
-    }
-}
-
-bool SkPDFGlyphSet::has(uint16_t glyphID) const {
-    return fBitSet.isBitSet(glyphID);
-}
-
-void SkPDFGlyphSet::merge(const SkPDFGlyphSet& usage) {
-    fBitSet.orBits(usage.fBitSet);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFGlyphSetMap
-///////////////////////////////////////////////////////////////////////////////
-SkPDFGlyphSetMap::FontGlyphSetPair::FontGlyphSetPair(SkPDFFont* font,
-                                                     SkPDFGlyphSet* glyphSet)
-        : fFont(font),
-          fGlyphSet(glyphSet) {
-}
-
-SkPDFGlyphSetMap::F2BIter::F2BIter(const SkPDFGlyphSetMap& map) {
-    reset(map);
-}
-
-SkPDFGlyphSetMap::FontGlyphSetPair* SkPDFGlyphSetMap::F2BIter::next() const {
-    if (fIndex >= fMap->count()) {
-        return NULL;
-    }
-    return &((*fMap)[fIndex++]);
-}
-
-void SkPDFGlyphSetMap::F2BIter::reset(const SkPDFGlyphSetMap& map) {
-    fMap = &(map.fMap);
-    fIndex = 0;
-}
-
-SkPDFGlyphSetMap::SkPDFGlyphSetMap() {
-}
-
-SkPDFGlyphSetMap::~SkPDFGlyphSetMap() {
-    reset();
-}
-
-void SkPDFGlyphSetMap::merge(const SkPDFGlyphSetMap& usage) {
-    for (int i = 0; i < usage.fMap.count(); ++i) {
-        SkPDFGlyphSet* myUsage = getGlyphSetForFont(usage.fMap[i].fFont);
-        myUsage->merge(*(usage.fMap[i].fGlyphSet));
-    }
-}
-
-void SkPDFGlyphSetMap::reset() {
-    for (int i = 0; i < fMap.count(); ++i) {
-        delete fMap[i].fGlyphSet;  // Should not be NULL.
-    }
-    fMap.reset();
-}
-
-void SkPDFGlyphSetMap::noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
-                                      int numGlyphs) {
-    SkPDFGlyphSet* subset = getGlyphSetForFont(font);
-    if (subset) {
-        subset->set(glyphIDs, numGlyphs);
-    }
-}
-
-SkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) {
-    int index = fMap.count();
-    for (int i = 0; i < index; ++i) {
-        if (fMap[i].fFont == font) {
-            return fMap[i].fGlyphSet;
-        }
-    }
-    fMap.append();
-    index = fMap.count() - 1;
-    fMap[index].fFont = font;
-    fMap[index].fGlyphSet = new SkPDFGlyphSet();
-    return fMap[index].fGlyphSet;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFFont
-///////////////////////////////////////////////////////////////////////////////
-
 /* Font subset design: It would be nice to be able to subset fonts
  * (particularly type 3 fonts), but it's a lot of work and not a priority.
  *
@@ -537,6 +425,11 @@
     int index;
     if (Find(SkTypeface::UniqueID(fTypeface.get()), fFirstGlyphID, &index)) {
         CanonicalFonts().removeShuffle(index);
+#ifdef SK_DEBUG
+        SkASSERT(!fDescendant);
+    } else {
+        SkASSERT(fDescendant);
+#endif
     }
     fResources.unrefAll();
 }
@@ -550,17 +443,21 @@
 }
 
 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() {
-    return fFontType;
+    return fType;
 }
 
 bool SkPDFFont::hasGlyph(uint16_t id) {
     return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0;
 }
 
+bool SkPDFFont::multiByteGlyphs() {
+    return fMultiByteGlyphs;
+}
+
 size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs,
                                           size_t numGlyphs) {
     // A font with multibyte glyphs will support all glyph IDs in a single font.
-    if (this->multiByteGlyphs()) {
+    if (fMultiByteGlyphs) {
         return numGlyphs;
     }
 
@@ -581,19 +478,19 @@
 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
     SkAutoMutexAcquire lock(CanonicalFontsMutex());
     const uint32_t fontID = SkTypeface::UniqueID(typeface);
-    int relatedFontIndex;
-    if (Find(fontID, glyphID, &relatedFontIndex)) {
-        CanonicalFonts()[relatedFontIndex].fFont->ref();
-        return CanonicalFonts()[relatedFontIndex].fFont;
+    int index;
+    if (Find(fontID, glyphID, &index)) {
+        CanonicalFonts()[index].fFont->ref();
+        return CanonicalFonts()[index].fFont;
     }
 
-    SkRefPtr<SkAdvancedTypefaceMetrics> fontMetrics;
-    SkPDFDict* relatedFontDescriptor = NULL;
-    if (relatedFontIndex >= 0) {
-        SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont;
+    SkRefPtr<SkAdvancedTypefaceMetrics> fontInfo;
+    SkPDFDict* fontDescriptor = NULL;
+    if (index >= 0) {
+        SkPDFFont* relatedFont = CanonicalFonts()[index].fFont;
         SkASSERT(relatedFont->fFontInfo.get());
-        fontMetrics = relatedFont->fontInfo();
-        relatedFontDescriptor = relatedFont->getFontDescriptor();
+        fontInfo = relatedFont->fFontInfo;
+        fontDescriptor = relatedFont->fDescriptor.get();
     } else {
         SkAdvancedTypefaceMetrics::PerGlyphInfo info;
         info = SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo;
@@ -601,21 +498,18 @@
                   info, SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo);
         info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
                   info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo);
-        fontMetrics = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info);
-        SkSafeUnref(fontMetrics.get());  // SkRefPtr and Get both took a ref.
+        fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info);
+        SkSafeUnref(fontInfo.get());  // SkRefPtr and Get both took a reference.
     }
 
-    SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID,
-                             relatedFontDescriptor);
+    SkPDFFont* font = new SkPDFFont(fontInfo.get(), typeface, glyphID, false,
+                                    fontDescriptor);
     FontRec newEntry(font, fontID, font->fFirstGlyphID);
+    index = CanonicalFonts().count();
     CanonicalFonts().push(newEntry);
     return font;  // Return the reference new SkPDFFont() created.
 }
 
-SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet* usage) {
-    return NULL;  // Default: no support.
-}
-
 // static
 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() {
     // This initialization is only thread safe with gcc.
@@ -642,270 +536,96 @@
     return false;
 }
 
-SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
-                     uint16_t glyphID, bool descendantFont)
+SkPDFFont::SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo,
+                     SkTypeface* typeface,
+                     uint16_t glyphID,
+                     bool descendantFont,
+                     SkPDFDict* fontDescriptor)
         : SkPDFDict("Font"),
           fTypeface(typeface),
+          fType(fontInfo ? fontInfo->fType :
+                           SkAdvancedTypefaceMetrics::kNotEmbeddable_Font),
+#ifdef SK_DEBUG
+          fDescendant(descendantFont),
+#endif
+          fMultiByteGlyphs(false),
           fFirstGlyphID(1),
-          fLastGlyphID(info ? info->fLastGlyphID : 0),
-          fFontInfo(info) {
-    if (info == NULL) {
-        fFontType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
-    } else if (info->fMultiMaster) {
-        fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
-    } else {
-        fFontType = info->fType;
-    }
-}
-
-// static
-SkPDFFont* SkPDFFont::Create(SkAdvancedTypefaceMetrics* info,
-                             SkTypeface* typeface, uint16_t glyphID,
-                             SkPDFDict* relatedFontDescriptor) {
-    SkAdvancedTypefaceMetrics::FontType type =
-        info ? info->fType : SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
-
-    if (info && info->fMultiMaster) {
+          fLastGlyphID(fontInfo ? fontInfo->fLastGlyphID : 0),
+          fFontInfo(fontInfo),
+          fDescriptor(fontDescriptor) {
+    if (fontInfo && fontInfo->fMultiMaster) {
         NOT_IMPLEMENTED(true, true);
-        return new SkPDFType3Font(info,
-                                  typeface,
-                                  glyphID,
-                                  relatedFontDescriptor);
+        fType = SkAdvancedTypefaceMetrics::kOther_Font;
     }
-    if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
-        type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
-        SkASSERT(relatedFontDescriptor == NULL);
-        return new SkPDFType0Font(info, typeface);
-    }
-    if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
-        return new SkPDFType1Font(info,
-                                  typeface,
-                                  glyphID,
-                                  relatedFontDescriptor);
-    }
-
-    SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
-             type == SkAdvancedTypefaceMetrics::kOther_Font ||
-             type == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
-
-    return new SkPDFType3Font(info, typeface, glyphID, relatedFontDescriptor);
-}
-
-SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
-    return fFontInfo.get();
-}
-
-uint16_t SkPDFFont::firstGlyphID() const {
-    return fFirstGlyphID;
-}
-
-uint16_t SkPDFFont::lastGlyphID() const {
-    return fLastGlyphID;
-}
-
-void SkPDFFont::setLastGlyphID(uint16_t glyphID) {
-    fLastGlyphID = glyphID;
-}
-
-void SkPDFFont::addResource(SkPDFObject* object) {
-    SkASSERT(object != NULL);
-    fResources.push(object);
-}
-
-SkPDFDict* SkPDFFont::getFontDescriptor() {
-    return fDescriptor.get();
-}
-
-void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) {
-    fDescriptor = descriptor;
-}
-
-bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) {
-    if (fDescriptor.get() == NULL) {
-        return false;
-    }
-
-    const uint16_t emSize = fFontInfo->fEmSize;
-
-    fDescriptor->insertName("FontName", fFontInfo->fFontName);
-    fDescriptor->insertInt("Flags", fFontInfo->fStyle);
-    fDescriptor->insertScalar("Ascent",
-            scaleFromFontUnits(fFontInfo->fAscent, emSize));
-    fDescriptor->insertScalar("Descent",
-            scaleFromFontUnits(fFontInfo->fDescent, emSize));
-    fDescriptor->insertScalar("StemV",
-            scaleFromFontUnits(fFontInfo->fStemV, emSize));
-    fDescriptor->insertScalar("CapHeight",
-            scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
-    fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
-    fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox,
-                                                 fFontInfo->fEmSize))->unref();
-
-    if (defaultWidth > 0) {
-        fDescriptor->insertScalar("MissingWidth",
-                scaleFromFontUnits(defaultWidth, emSize));
-    }
-    return true;
-}
-
-void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) {
-    // Single byte glyph encoding supports a max of 255 glyphs.
-    fFirstGlyphID = glyphID - (glyphID - 1) % 255;
-    if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
-        fLastGlyphID = fFirstGlyphID + 255 - 1;
-    }
-}
-
-bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const {
-    if (fFontID != b.fFontID)
-        return false;
-    if (fFont != NULL && b.fFont != NULL) {
-        return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID &&
-            fFont->fLastGlyphID == b.fFont->fLastGlyphID;
-    }
-    if (fGlyphID == 0 || b.fGlyphID == 0)
-        return true;
-
-    if (fFont != NULL) {
-        return fFont->fFirstGlyphID <= b.fGlyphID &&
-            b.fGlyphID <= fFont->fLastGlyphID;
-    } else if (b.fFont != NULL) {
-        return b.fFont->fFirstGlyphID <= fGlyphID &&
-            fGlyphID <= b.fFont->fLastGlyphID;
-    }
-    return fGlyphID == b.fGlyphID;
-}
-
-SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID)
-    : fFont(font),
-      fFontID(fontID),
-      fGlyphID(glyphID) {
-}
-
-void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
-    if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) {
+    if (fType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
+        fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
+        if (descendantFont) {
+            populateCIDFont();
+        } else {
+            populateType0Font();
+        }
+        // No need to hold onto the font info for fonts types that
+        // support multibyte glyphs.
+        fFontInfo = NULL;
         return;
     }
-    SkRefPtr<SkPDFStream> pdfCmap =
-        generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset);
-    addResource(pdfCmap.get());  // Pass reference from new.
+
+    if (fType == SkAdvancedTypefaceMetrics::kType1_Font &&
+        populateType1Font(glyphID)) {
+        return;
+    }
+
+    SkASSERT(fType == SkAdvancedTypefaceMetrics::kType1_Font ||
+             fType == SkAdvancedTypefaceMetrics::kCFF_Font ||
+             fType == SkAdvancedTypefaceMetrics::kOther_Font ||
+             fType == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
+    populateType3Font(glyphID);
+}
+
+void SkPDFFont::populateType0Font() {
+    fMultiByteGlyphs = true;
+
+    insertName("Subtype", "Type0");
+    insertName("BaseFont", fFontInfo->fFontName);
+    insertName("Encoding", "Identity-H");
+
+    SkRefPtr<SkPDFArray> descendantFonts = new SkPDFArray();
+    descendantFonts->unref();  // SkRefPtr and new took a reference.
+
+    // Pass ref new created to fResources.
+    fResources.push(
+        new SkPDFFont(fFontInfo.get(), fTypeface.get(), 1, true, NULL));
+    descendantFonts->append(new SkPDFObjRef(fResources.top()))->unref();
+    insert("DescendantFonts", descendantFonts.get());
+
+    populateToUnicodeTable();
+}
+
+void SkPDFFont::populateToUnicodeTable() {
+    if (fFontInfo.get() == NULL ||
+        fFontInfo->fGlyphToUnicode.begin() == NULL) {
+        return;
+    }
+
+    SkDynamicMemoryWStream cmap;
+    append_tounicode_header(&cmap);
+    append_cmap_bfchar_sections(fFontInfo->fGlyphToUnicode, &cmap);
+    append_cmap_footer(&cmap);
+    SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream();
+    cmapStream->unref();  // SkRefPtr and new took a reference.
+    cmapStream->setData(cmap.copyToData())->unref();
+    SkRefPtr<SkPDFStream> pdfCmap = new SkPDFStream(cmapStream.get());
+    fResources.push(pdfCmap.get());  // Pass reference from new.
     insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFType0Font
-///////////////////////////////////////////////////////////////////////////////
+void SkPDFFont::populateCIDFont() {
+    fMultiByteGlyphs = true;
+    insertName("BaseFont", fFontInfo->fFontName);
 
-SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info,
-                               SkTypeface* typeface)
-        : SkPDFFont(info, typeface, 0, false) {
-    SkDEBUGCODE(fPopulated = false);
-}
-
-SkPDFType0Font::~SkPDFType0Font() {}
-
-SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
-    SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface());
-    newSubset->populate(subset);
-    return newSubset;
-}
-
-#ifdef SK_DEBUG
-void SkPDFType0Font::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
-                                bool indirect) {
-    SkASSERT(fPopulated);
-    return INHERITED::emitObject(stream, catalog, indirect);
-}
-#endif
-
-bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
-    insertName("Subtype", "Type0");
-    insertName("BaseFont", fontInfo()->fFontName);
-    insertName("Encoding", "Identity-H");
-
-    // 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.
-    descendantFonts->append(new SkPDFObjRef(newCIDFont))->unref();
-    insert("DescendantFonts", descendantFonts.get());
-
-    populateToUnicodeTable(subset);
-
-    SkDEBUGCODE(fPopulated = true);
-    return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFCIDFont
-///////////////////////////////////////////////////////////////////////////////
-
-SkPDFCIDFont::SkPDFCIDFont(SkAdvancedTypefaceMetrics* info,
-                           SkTypeface* typeface, const SkPDFGlyphSet* subset)
-        : SkPDFFont(info, typeface, 0, true) {
-    populate(subset);
-}
-
-SkPDFCIDFont::~SkPDFCIDFont() {}
-
-bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
-                                     const SkPDFGlyphSet* 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: {
-            // TODO(arthurhsu): sfntly font subsetting
-            SkRefPtr<SkStream> fontData =
-                SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
-            fontData->unref();  // SkRefPtr and OpenStream both took a ref.
-            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
-            // SkRefPtr and new both ref()'d fontStream, pass one.
-            addResource(fontStream.get());
-
-            fontStream->insertInt("Length1", fontData->getLength());
-            descriptor->insert("FontFile2",
-                                new SkPDFObjRef(fontStream.get()))->unref();
-            break;
-        }
-        case SkAdvancedTypefaceMetrics::kCFF_Font:
-        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
-            SkRefPtr<SkStream> fontData =
-                SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
-            fontData->unref();  // SkRefPtr and OpenStream both took a ref.
-            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
-            // SkRefPtr and new both ref()'d fontStream, pass one.
-            addResource(fontStream.get());
-
-            if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) {
-                fontStream->insertName("Subtype", "Type1C");
-            } else {
-                fontStream->insertName("Subtype", "CIDFontType0c");
-            }
-            descriptor->insert("FontFile3",
-                                new SkPDFObjRef(fontStream.get()))->unref();
-            break;
-        }
-        default:
-            SkASSERT(false);
-    }
-
-    addResource(descriptor.get());
-    descriptor->ref();
-
-    insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
-    return addCommonFontDescriptorEntries(defaultWidth);
-}
-
-bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
-    insertName("BaseFont", fontInfo()->fFontName);
-
-    if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) {
+    if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kType1CID_Font) {
         insertName("Subtype", "CIDFontType0");
-    } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) {
+    } else if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
         insertName("Subtype", "CIDFontType2");
         insertName("CIDToGIDMap", "Identity");
     } else {
@@ -919,30 +639,29 @@
     sysInfo->insertInt("Supplement", 0);
     insert("CIDSystemInfo", sysInfo.get());
 
-    addFontDescriptor(0, subset);
+    addFontDescriptor(0);
 
-    if (fontInfo()->fGlyphWidths.get()) {
+    if (fFontInfo->fGlyphWidths.get()) {
         int16_t defaultWidth = 0;
         SkRefPtr<SkPDFArray> widths =
-            composeAdvanceData(fontInfo()->fGlyphWidths.get(),
-                               fontInfo()->fEmSize, &appendWidth,
-                               &defaultWidth);
+            composeAdvanceData(fFontInfo->fGlyphWidths.get(),
+                               fFontInfo->fEmSize, &appendWidth, &defaultWidth);
         widths->unref();  // SkRefPtr and compose both took a reference.
         if (widths->size())
             insert("W", widths.get());
         if (defaultWidth != 0) {
             insertScalar("DW", scaleFromFontUnits(defaultWidth,
-                                                  fontInfo()->fEmSize));
+                                                  fFontInfo->fEmSize));
         }
     }
-    if (fontInfo()->fVerticalMetrics.get()) {
+    if (fFontInfo->fVerticalMetrics.get()) {
         struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
         defaultAdvance.fVerticalAdvance = 0;
         defaultAdvance.fOriginXDisp = 0;
         defaultAdvance.fOriginYDisp = 0;
         SkRefPtr<SkPDFArray> advances =
-            composeAdvanceData(fontInfo()->fVerticalMetrics.get(),
-                               fontInfo()->fEmSize, &appendVerticalAdvance,
+            composeAdvanceData(fFontInfo->fVerticalMetrics.get(),
+                               fFontInfo->fEmSize, &appendVerticalAdvance,
                                &defaultAdvance);
         advances->unref();  // SkRefPtr and compose both took a ref.
         if (advances->size())
@@ -951,77 +670,22 @@
                 defaultAdvance.fOriginXDisp ||
                 defaultAdvance.fOriginYDisp) {
             insert("DW2", appendVerticalAdvance(defaultAdvance,
-                                                fontInfo()->fEmSize,
+                                                fFontInfo->fEmSize,
                                                 new SkPDFArray))->unref();
         }
     }
-
-    return true;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFType1Font
-///////////////////////////////////////////////////////////////////////////////
-
-SkPDFType1Font::SkPDFType1Font(SkAdvancedTypefaceMetrics* info,
-                               SkTypeface* typeface,
-                               uint16_t glyphID,
-                               SkPDFDict* relatedFontDescriptor)
-        : SkPDFFont(info, typeface, glyphID, false) {
-    populate(glyphID);
-}
-
-SkPDFType1Font::~SkPDFType1Font() {}
-
-bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
-    SkRefPtr<SkPDFDict> descriptor = getFontDescriptor();
-    if (descriptor.get() != NULL) {
-        addResource(descriptor.get());
-        descriptor->ref();
-        insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
-        return true;
-    }
-
-    descriptor = new SkPDFDict("FontDescriptor");
-    descriptor->unref();  // SkRefPtr and new both took a ref.
-    setFontDescriptor(descriptor.get());
-
-    size_t header SK_INIT_TO_AVOID_WARNING;
-    size_t data SK_INIT_TO_AVOID_WARNING;
-    size_t trailer SK_INIT_TO_AVOID_WARNING;
-    SkRefPtr<SkStream> rawFontData =
-        SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
-    rawFontData->unref();  // SkRefPtr and OpenStream both took a ref.
-    SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
-                                           &trailer);
-    if (fontData == NULL) {
-        return false;
-    }
-    SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData);
-    // SkRefPtr and new both ref()'d fontStream, pass one.
-    addResource(fontStream.get());
-    fontStream->insertInt("Length1", header);
-    fontStream->insertInt("Length2", data);
-    fontStream->insertInt("Length3", trailer);
-    descriptor->insert("FontFile", new SkPDFObjRef(fontStream.get()))->unref();
-
-    addResource(descriptor.get());
-    descriptor->ref();
-    insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
-
-    return addCommonFontDescriptorEntries(defaultWidth);
-}
-
-bool SkPDFType1Font::populate(int16_t glyphID) {
-    SkASSERT(!fontInfo()->fVerticalMetrics.get());
-    SkASSERT(fontInfo()->fGlyphWidths.get());
+bool SkPDFFont::populateType1Font(int16_t glyphID) {
+    SkASSERT(!fFontInfo->fVerticalMetrics.get());
+    SkASSERT(fFontInfo->fGlyphWidths.get());
 
     adjustGlyphRangeForSingleByteEncoding(glyphID);
 
     int16_t defaultWidth = 0;
     const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL;
     const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
-    for (widthEntry = fontInfo()->fGlyphWidths.get();
+    for (widthEntry = fFontInfo.get()->fGlyphWidths.get();
             widthEntry != NULL;
             widthEntry = widthEntry->fNext.get()) {
         switch (widthEntry->fType) {
@@ -1042,7 +706,7 @@
         return false;
 
     insertName("Subtype", "Type1");
-    insertName("BaseFont", fontInfo()->fFontName);
+    insertName("BaseFont", fFontInfo->fFontName);
 
     addWidthInfoFromRange(defaultWidth, widthRangeEntry);
 
@@ -1054,67 +718,26 @@
     encDiffs->unref();  // SkRefPtr and new both took a reference.
     encoding->insert("Differences", encDiffs.get());
 
-    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
+    encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2);
     encDiffs->appendInt(1);
-    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
-        encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str());
+    for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) {
+        encDiffs->appendName(fFontInfo->fGlyphNames->get()[gID].c_str());
     }
 
+    if (fFontInfo->fLastGlyphID <= 255)
+        fFontInfo = NULL;
     return true;
 }
 
-void SkPDFType1Font::addWidthInfoFromRange(
-        int16_t defaultWidth,
-        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
-    SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
-    widthArray->unref();  // SkRefPtr and new both took a ref.
-    int firstChar = 0;
-    if (widthRangeEntry) {
-        const uint16_t emSize = fontInfo()->fEmSize;
-        int startIndex = firstGlyphID() - widthRangeEntry->fStartId;
-        int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1;
-        if (startIndex < 0)
-            startIndex = 0;
-        if (endIndex > widthRangeEntry->fAdvance.count())
-            endIndex = widthRangeEntry->fAdvance.count();
-        if (widthRangeEntry->fStartId == 0) {
-            appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
-        } else {
-            firstChar = startIndex + widthRangeEntry->fStartId;
-        }
-        for (int i = startIndex; i < endIndex; i++)
-            appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
-    } else {
-        appendWidth(defaultWidth, 1000, widthArray.get());
-    }
-    insertInt("FirstChar", firstChar);
-    insertInt("LastChar", firstChar + widthArray->size() - 1);
-    insert("Widths", widthArray.get());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFType3Font
-///////////////////////////////////////////////////////////////////////////////
-
-SkPDFType3Font::SkPDFType3Font(SkAdvancedTypefaceMetrics* info,
-                               SkTypeface* typeface,
-                               uint16_t glyphID,
-                               SkPDFDict* relatedFontDescriptor)
-        : SkPDFFont(info, typeface, glyphID, false) {
-    populate(glyphID);
-}
-
-SkPDFType3Font::~SkPDFType3Font() {}
-
-bool SkPDFType3Font::populate(int16_t glyphID) {
+void SkPDFFont::populateType3Font(int16_t glyphID) {
     SkPaint paint;
-    paint.setTypeface(typeface());
+    paint.setTypeface(fTypeface.get());
     paint.setTextSize(1000);
     SkAutoGlyphCache autoCache(paint, NULL);
     SkGlyphCache* cache = autoCache.getCache();
     // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
-    if (lastGlyphID() == 0) {
-        setLastGlyphID(cache->getGlyphCount() - 1);
+    if (fLastGlyphID == 0) {
+        fLastGlyphID = cache->getGlyphCount() - 1;
     }
 
     adjustGlyphRangeForSingleByteEncoding(glyphID);
@@ -1136,14 +759,14 @@
     SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray;
     encDiffs->unref();  // SkRefPtr and new both took a reference.
     encoding->insert("Differences", encDiffs.get());
-    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
+    encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2);
     encDiffs->appendInt(1);
 
     SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
     widthArray->unref();  // SkRefPtr and new both took a ref.
 
     SkIRect bbox = SkIRect::MakeEmpty();
-    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
+    for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) {
         SkString characterName;
         characterName.printf("gid%d", gID);
         encDiffs->appendName(characterName.c_str());
@@ -1170,17 +793,176 @@
         SkRefPtr<SkPDFStream> glyphDescription =
             new SkPDFStream(glyphStream.get());
         // SkRefPtr and new both ref()'d charProcs, pass one.
-        addResource(glyphDescription.get());
+        fResources.push(glyphDescription.get());
         charProcs->insert(characterName.c_str(),
                           new SkPDFObjRef(glyphDescription.get()))->unref();
     }
 
     insert("FontBBox", makeFontBBox(bbox, 1000))->unref();
-    insertInt("FirstChar", firstGlyphID());
-    insertInt("LastChar", lastGlyphID());
+    insertInt("FirstChar", fFirstGlyphID);
+    insertInt("LastChar", fLastGlyphID);
     insert("Widths", widthArray.get());
     insertName("CIDToGIDMap", "Identity");
 
-    populateToUnicodeTable(NULL);
+    if (fFontInfo && fFontInfo->fLastGlyphID <= 255) {
+        fFontInfo = NULL;
+    }
+    populateToUnicodeTable();
+}
+
+bool SkPDFFont::addFontDescriptor(int16_t defaultWidth) {
+    if (fDescriptor.get() != NULL) {
+        fResources.push(fDescriptor.get());
+        fDescriptor->ref();
+        insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref();
+        return true;
+    }
+
+    fDescriptor = new SkPDFDict("FontDescriptor");
+    fDescriptor->unref();  // SkRefPtr and new both took a ref.
+
+    switch (fFontInfo->fType) {
+        case SkAdvancedTypefaceMetrics::kType1_Font: {
+            size_t header SK_INIT_TO_AVOID_WARNING;
+            size_t data SK_INIT_TO_AVOID_WARNING;
+            size_t trailer SK_INIT_TO_AVOID_WARNING;
+            SkRefPtr<SkStream> rawFontData =
+                SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
+            rawFontData->unref();  // SkRefPtr and OpenStream both took a ref.
+            SkStream* fontData = handleType1Stream(rawFontData.get(), &header,
+                                                   &data, &trailer);
+            if (fontData == NULL)
+                return false;
+            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData);
+            // SkRefPtr and new both ref()'d fontStream, pass one.
+            fResources.push(fontStream.get());
+            fontStream->insertInt("Length1", header);
+            fontStream->insertInt("Length2", data);
+            fontStream->insertInt("Length3", trailer);
+            fDescriptor->insert("FontFile",
+                                new SkPDFObjRef(fontStream.get()))->unref();
+            break;
+        }
+        case SkAdvancedTypefaceMetrics::kTrueType_Font: {
+            SkRefPtr<SkStream> fontData =
+                SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
+            fontData->unref();  // SkRefPtr and OpenStream both took a ref.
+            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
+            // SkRefPtr and new both ref()'d fontStream, pass one.
+            fResources.push(fontStream.get());
+
+            fontStream->insertInt("Length1", fontData->getLength());
+            fDescriptor->insert("FontFile2",
+                                new SkPDFObjRef(fontStream.get()))->unref();
+            break;
+        }
+        case SkAdvancedTypefaceMetrics::kCFF_Font:
+        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
+            SkRefPtr<SkStream> fontData =
+                SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
+            fontData->unref();  // SkRefPtr and OpenStream both took a ref.
+            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
+            // SkRefPtr and new both ref()'d fontStream, pass one.
+            fResources.push(fontStream.get());
+
+            if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kCFF_Font) {
+                fontStream->insertName("Subtype", "Type1C");
+            } else {
+                fontStream->insertName("Subtype", "CIDFontType0c");
+            }
+            fDescriptor->insert("FontFile3",
+                                new SkPDFObjRef(fontStream.get()))->unref();
+            break;
+        }
+        default:
+            SkASSERT(false);
+    }
+
+    const uint16_t emSize = fFontInfo->fEmSize;
+    fResources.push(fDescriptor.get());
+    fDescriptor->ref();
+    insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref();
+
+    fDescriptor->insertName("FontName", fFontInfo->fFontName);
+    fDescriptor->insertInt("Flags", fFontInfo->fStyle);
+    fDescriptor->insertScalar("Ascent",
+                              scaleFromFontUnits(fFontInfo->fAscent, emSize));
+    fDescriptor->insertScalar("Descent",
+                              scaleFromFontUnits(fFontInfo->fDescent, emSize));
+    fDescriptor->insertScalar("StemV",
+                              scaleFromFontUnits(fFontInfo->fStemV, emSize));
+    fDescriptor->insertScalar("CapHeight",
+                             scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
+    fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
+    fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox,
+                                                 fFontInfo->fEmSize))->unref();
+
+    if (defaultWidth > 0) {
+        fDescriptor->insertScalar("MissingWidth",
+                                  scaleFromFontUnits(defaultWidth, emSize));
+    }
     return true;
 }
+void SkPDFFont::addWidthInfoFromRange(
+        int16_t defaultWidth,
+        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
+    SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
+    widthArray->unref();  // SkRefPtr and new both took a ref.
+    int firstChar = 0;
+    if (widthRangeEntry) {
+        const uint16_t emSize = fFontInfo->fEmSize;
+        int startIndex = fFirstGlyphID - widthRangeEntry->fStartId;
+        int endIndex = startIndex + fLastGlyphID - fFirstGlyphID + 1;
+        if (startIndex < 0)
+            startIndex = 0;
+        if (endIndex > widthRangeEntry->fAdvance.count())
+            endIndex = widthRangeEntry->fAdvance.count();
+        if (widthRangeEntry->fStartId == 0) {
+            appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
+        } else {
+            firstChar = startIndex + widthRangeEntry->fStartId;
+        }
+        for (int i = startIndex; i < endIndex; i++)
+            appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
+    } else {
+        appendWidth(defaultWidth, 1000, widthArray.get());
+    }
+    insertInt("FirstChar", firstChar);
+    insertInt("LastChar", firstChar + widthArray->size() - 1);
+    insert("Widths", widthArray.get());
+}
+
+void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) {
+    // Single byte glyph encoding supports a max of 255 glyphs.
+    fFirstGlyphID = glyphID - (glyphID - 1) % 255;
+    if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
+        fLastGlyphID = fFirstGlyphID + 255 - 1;
+    }
+}
+
+
+bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const {
+    if (fFontID != b.fFontID)
+        return false;
+    if (fFont != NULL && b.fFont != NULL) {
+        return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID &&
+            fFont->fLastGlyphID == b.fFont->fLastGlyphID;
+    }
+    if (fGlyphID == 0 || b.fGlyphID == 0)
+        return true;
+
+    if (fFont != NULL) {
+        return fFont->fFirstGlyphID <= b.fGlyphID &&
+            b.fGlyphID <= fFont->fLastGlyphID;
+    } else if (b.fFont != NULL) {
+        return b.fFont->fFirstGlyphID <= fGlyphID &&
+            fGlyphID <= b.fFont->fLastGlyphID;
+    }
+    return fGlyphID == b.fGlyphID;
+}
+
+SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID)
+    : fFont(font),
+      fFontID(fontID),
+      fGlyphID(glyphID) {
+}
diff --git a/src/pdf/SkPDFFontImpl.h b/src/pdf/SkPDFFontImpl.h
deleted file mode 100755
index 2220625..0000000
--- a/src/pdf/SkPDFFontImpl.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SkPDFFontImpl_DEFINED
-#define SkPDFFontImpl_DEFINED
-
-#include "SkPDFFont.h"
-
-class SkPDFType0Font : public SkPDFFont {
-public:
-    virtual ~SkPDFType0Font();
-    virtual bool multiByteGlyphs() const { return true; }
-    SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
-#ifdef SK_DEBUG
-    virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
-                            bool indirect);
-#endif
-
-private:
-    friend class SkPDFFont;  // to access the constructor
-#ifdef SK_DEBUG
-    bool fPopulated;
-    typedef SkPDFDict INHERITED;
-#endif
-
-    SkPDFType0Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface);
-
-    bool populate(const SkPDFGlyphSet* subset);
-};
-
-class SkPDFCIDFont : public SkPDFFont {
-public:
-    virtual ~SkPDFCIDFont();
-    virtual bool multiByteGlyphs() const { return true; }
-
-private:
-    friend class SkPDFType0Font;  // to access the constructor
-
-    SkPDFCIDFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
-                 const SkPDFGlyphSet* subset);
-
-    bool populate(const SkPDFGlyphSet* subset);
-    bool addFontDescriptor(int16_t defaultWidth, const SkPDFGlyphSet* subset);
-};
-
-class SkPDFType1Font : public SkPDFFont {
-public:
-    virtual ~SkPDFType1Font();
-    virtual bool multiByteGlyphs() const { return false; }
-
-private:
-    friend class SkPDFFont;  // to access the constructor
-
-    SkPDFType1Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
-                   uint16_t glyphID, SkPDFDict* relatedFontDescriptor);
-
-    bool populate(int16_t glyphID);
-    bool addFontDescriptor(int16_t defaultWidth);
-    void addWidthInfoFromRange(int16_t defaultWidth,
-        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry);
-};
-
-class SkPDFType3Font : public SkPDFFont {
-public:
-    virtual ~SkPDFType3Font();
-    virtual bool multiByteGlyphs() const { return false; }
-
-private:
-    friend class SkPDFFont;  // to access the constructor
-
-    SkPDFType3Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
-                   uint16_t glyphID, SkPDFDict* relatedFontDescriptor);
-
-    bool populate(int16_t glyphID);
-};
-
-#endif
diff --git a/src/pdf/SkPDFPage.cpp b/src/pdf/SkPDFPage.cpp
index 846df64..09849b0 100644
--- a/src/pdf/SkPDFPage.cpp
+++ b/src/pdf/SkPDFPage.cpp
@@ -141,7 +141,3 @@
 const SkTDArray<SkPDFFont*>& SkPDFPage::getFontResources() const {
     return fDevice->getFontResources();
 }
-
-const SkPDFGlyphSetMap& SkPDFPage::getFontGlyphUsage() const {
-    return fDevice->getFontGlyphUsage();
-}