diff --git a/gyp/core.gyp b/gyp/core.gyp index a74f0b2d52..868abea646 100644 --- a/gyp/core.gyp +++ b/gyp/core.gyp @@ -23,7 +23,6 @@ '../include/xml', '../src/core', '../src/opts', - '../src/sfnt', '../src/image', ], 'sources': [ diff --git a/include/core/SkAdvancedTypefaceMetrics.h b/include/core/SkAdvancedTypefaceMetrics.h index 11926888f5..e75365ba31 100755 --- a/include/core/SkAdvancedTypefaceMetrics.h +++ b/include/core/SkAdvancedTypefaceMetrics.h @@ -35,21 +35,15 @@ public: kCFF_Font, kTrueType_Font, kOther_Font, + kNotEmbeddable_Font }; // The type of the underlying font program. This field determines which - // of the following fields are valid. If it is kOther_Font the per glyph - // information will never be populated. + // of the following fields are valid. If it is kOther_Font or + // kNotEmbeddable_Font, the per glyph information will never be populated. FontType fType; - enum FontFlags { - kEmpty_FontFlag = 0x0, //! fCatalog; diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index e419391b2d..09a64324af 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -6,10 +6,8 @@ */ #include "SkAdvancedTypefaceMetrics.h" -#include "SkEndian.h" #include "SkFontDescriptor.h" #include "SkFontHost.h" -#include "SkOTTable_OS_2.h" #include "SkStream.h" #include "SkTypeface.h" @@ -261,26 +259,7 @@ SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics::PerGlyphInfo info, const uint32_t* glyphIDs, uint32_t glyphIDsCount) const { - SkAdvancedTypefaceMetrics* result = - this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); - if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) { - struct SkOTTableOS2 os2table; - if (this->getTableData(SkEndian_SwapBE32(SkOTTableOS2::TAG), 0, - sizeof(os2table), &os2table) > 0) { - if (os2table.version.v2.fsType.field.Restricted || - os2table.version.v2.fsType.field.Bitmap) { - result->fFlags = SkTBitOr( - result->fFlags, - SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag); - } - if (os2table.version.v2.fsType.field.NoSubsetting) { - result->fFlags = SkTBitOr( - result->fFlags, - SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag); - } - } - } - return result; + return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp index 79699a0292..0633d30828 100644 --- a/src/pdf/SkPDFDocument.cpp +++ b/src/pdf/SkPDFDocument.cpp @@ -258,13 +258,11 @@ bool SkPDFDocument::appendPage(SkPDFDevice* pdfDevice) { return true; } -// Deprecated. void SkPDFDocument::getCountOfFontTypes( - int counts[SkAdvancedTypefaceMetrics::kOther_Font + 2]) const { + int counts[SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1]) const { sk_bzero(counts, sizeof(int) * - (SkAdvancedTypefaceMetrics::kOther_Font + 2)); + (SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1)); SkTDArray seenFonts; - int notEmbeddable = 0; for (int pageNumber = 0; pageNumber < fPages.count(); pageNumber++) { const SkTDArray& fontResources = @@ -274,49 +272,9 @@ void SkPDFDocument::getCountOfFontTypes( if (seenFonts.find(fontID) == -1) { counts[fontResources[font]->getType()]++; seenFonts.push(fontID); - if (!fontResources[font]->canEmbed()) { - notEmbeddable++; - } } } } - counts[SkAdvancedTypefaceMetrics::kOther_Font + 1] = notEmbeddable; -} - -void SkPDFDocument::getCountOfFontTypes( - int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1], - int* notSubsettableCount, - int* notEmbeddableCount) const { - sk_bzero(counts, sizeof(int) * - (SkAdvancedTypefaceMetrics::kOther_Font + 1)); - SkTDArray seenFonts; - int notSubsettable = 0; - int notEmbeddable = 0; - - for (int pageNumber = 0; pageNumber < fPages.count(); pageNumber++) { - const SkTDArray& fontResources = - fPages[pageNumber]->getFontResources(); - for (int font = 0; font < fontResources.count(); font++) { - SkFontID fontID = fontResources[font]->typeface()->uniqueID(); - if (seenFonts.find(fontID) == -1) { - counts[fontResources[font]->getType()]++; - seenFonts.push(fontID); - if (!fontResources[font]->canSubset()) { - notSubsettable++; - } - if (!fontResources[font]->canEmbed()) { - notEmbeddable++; - } - } - } - } - if (notSubsettableCount) { - *notSubsettableCount = notSubsettable; - - } - if (notEmbeddableCount) { - *notEmbeddableCount = notEmbeddable; - } } void SkPDFDocument::emitHeader(SkWStream* stream) { diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 30c11d9792..1641a8916c 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -749,24 +749,6 @@ SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() { return fFontType; } -bool SkPDFFont::canEmbed() const { - if (!fFontInfo.get()) { - SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); - return true; - } - return (fFontInfo->fFlags & - SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag) == 0; -} - -bool SkPDFFont::canSubset() const { - if (!fFontInfo.get()) { - SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); - return true; - } - return (fFontInfo->fFlags & - SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag) == 0; -} - bool SkPDFFont::hasGlyph(uint16_t id) { return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0; } @@ -815,7 +797,7 @@ SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { // This only is to catch callers who pass invalid glyph ids. // If glyph id is invalid, then we will create duplicate entries - // for TrueType fonts. + // for True Type fonts. SkAdvancedTypefaceMetrics::FontType fontType = fontMetrics.get() ? fontMetrics.get()->fType : SkAdvancedTypefaceMetrics::kOther_Font; @@ -895,8 +877,9 @@ SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface, fLastGlyphID(info ? info->fLastGlyphID : 0), fFontInfo(SkSafeRef(info)), fDescriptor(SkSafeRef(relatedFontDescriptor)) { - if (info == NULL || - info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) { + if (info == NULL) { + fFontType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; + } else if (info->fMultiMaster) { fFontType = SkAdvancedTypefaceMetrics::kOther_Font; } else { fFontType = info->fType; @@ -908,10 +891,9 @@ SkPDFFont* SkPDFFont::Create(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface, uint16_t glyphID, SkPDFDict* relatedFontDescriptor) { SkAdvancedTypefaceMetrics::FontType type = - info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font; + info ? info->fType : SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; - if (info && - (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) { + if (info && info->fMultiMaster) { NOT_IMPLEMENTED(true, true); return new SkPDFType3Font(info, typeface, @@ -930,7 +912,8 @@ SkPDFFont* SkPDFFont::Create(SkAdvancedTypefaceMetrics* info, } SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font || - type == SkAdvancedTypefaceMetrics::kOther_Font); + type == SkAdvancedTypefaceMetrics::kOther_Font || + type == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font); return new SkPDFType3Font(info, typeface, glyphID); } @@ -1057,17 +1040,11 @@ SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface) : SkPDFFont(info, typeface, NULL) { SkDEBUGCODE(fPopulated = false); - if (!canSubset()) { - populate(NULL); - } } SkPDFType0Font::~SkPDFType0Font() {} SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) { - if (!canSubset()) { - return NULL; - } SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface()); newSubset->populate(subset); return newSubset; @@ -1116,34 +1093,19 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, SkAutoTUnref descriptor(new SkPDFDict("FontDescriptor")); setFontDescriptor(descriptor.get()); addResource(descriptor.get()); - insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); - if (!addCommonFontDescriptorEntries(defaultWidth)) { - return false; - } - if (!canEmbed()) { - return true; - } switch (getType()) { case SkAdvancedTypefaceMetrics::kTrueType_Font: { - SkAutoTUnref fontStream; - int fontSize = 0; - if (canSubset()) { - SkPDFStream* rawStream = NULL; - fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), + SkASSERT(subset); + // Font subsetting + SkPDFStream* rawStream = NULL; + int fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), typeface(), *subset, &rawStream); - fontStream.reset(rawStream); - } else { - int ttcIndex; - SkAutoTUnref fontData( - typeface()->openStream(&ttcIndex)); - fontStream.reset(new SkPDFStream(fontData.get())); - fontSize = fontData->getLength(); - } SkASSERT(fontSize); - SkASSERT(fontStream.get()); + SkASSERT(rawStream); + SkAutoTUnref fontStream(rawStream); addResource(fontStream.get()); fontStream->insertInt("Length1", fontSize); @@ -1171,7 +1133,9 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, default: SkASSERT(false); } - return true; + + insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); + return addCommonFontDescriptorEntries(defaultWidth); } bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { @@ -1287,15 +1251,12 @@ bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { if (fontData == NULL) { return false; } - if (canEmbed()) { - SkAutoTUnref fontStream(new SkPDFStream(fontData)); - addResource(fontStream.get()); - fontStream->insertInt("Length1", header); - fontStream->insertInt("Length2", data); - fontStream->insertInt("Length3", trailer); - descriptor->insert("FontFile", - new SkPDFObjRef(fontStream.get()))->unref(); - } + SkAutoTUnref fontStream(new SkPDFStream(fontData)); + 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()); insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); diff --git a/src/pdf/SkPDFFont.h b/src/pdf/SkPDFFont.h index 815c73ac22..694c69ac39 100644 --- a/src/pdf/SkPDFFont.h +++ b/src/pdf/SkPDFFont.h @@ -99,14 +99,6 @@ public: */ virtual bool multiByteGlyphs() const = 0; - /** Returns true if the machine readable licensing bits allow embedding. - */ - bool canEmbed() const; - - /** Returns true if the machine readable licensing bits allow subsetting. - */ - bool canSubset() const; - /** Return true if this font has an encoding for the passed glyph id. */ bool hasGlyph(uint16_t glyphID); @@ -129,7 +121,8 @@ public: * @param typeface The typeface to find. * @param glyphID Specify which section of a large font is of interest. */ - static SkPDFFont* GetFontResource(SkTypeface* typeface, uint16_t glyphID); + static SkPDFFont* GetFontResource(SkTypeface* typeface, + uint16_t glyphID); /** Subset the font based on usage set. Returns a SkPDFFont instance with * subset. @@ -195,6 +188,8 @@ private: // this will be a subset if the font has more than 255 glyphs. uint16_t fFirstGlyphID; uint16_t fLastGlyphID; + // The font info is only kept around after construction for large + // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs. SkAutoTUnref fFontInfo; SkTDArray fResources; SkAutoTUnref fDescriptor; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index 134cc052be..fd87a66dc6 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -411,20 +411,6 @@ static bool canEmbed(FT_Face face) { #endif } -static bool canSubset(FT_Face face) { -#ifdef FT_FSTYPE_NO_SUBSETTING - FT_UShort fsType = FT_Get_FSType_Flags(face); - return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0; -#else - // No subset is 0x100. - TT_OS2* os2_table; - if ((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != NULL) { - return (os2_table->fsType & 0x100) == 0; - } - return false; // We tried, fail safe. -#endif -} - static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) { const FT_UInt glyph_id = FT_Get_Char_Index(face, letter); if (!glyph_id) @@ -509,21 +495,7 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; info->fFontName.set(FT_Get_Postscript_Name(face)); - info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; - if (FT_HAS_MULTIPLE_MASTERS(face)) { - info->fFlags = SkTBitOr( - info->fFlags, SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag); - } - if (!canEmbed(face)) { - info->fFlags = SkTBitOr( - info->fFlags, - SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag); - } - if (!canSubset(face)) { - info->fFlags = SkTBitOr( - info->fFlags, - SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag); - } + info->fMultiMaster = FT_HAS_MULTIPLE_MASTERS(face); info->fLastGlyphID = face->num_glyphs - 1; info->fEmSize = 1000; @@ -616,7 +588,8 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax, face->bbox.xMax, face->bbox.yMin); - if (!FT_IS_SCALABLE(face)) { + if (!canEmbed(face) || !FT_IS_SCALABLE(face) || + info->fType == SkAdvancedTypefaceMetrics::kOther_Font) { perGlyphInfo = SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo; } @@ -679,6 +652,9 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( populate_glyph_to_unicode(face, &(info->fGlyphToUnicode)); } + if (!canEmbed(face)) + info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; + return info; #endif } diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index b115965415..3c1a274887 100755 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1539,16 +1539,17 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( CFStringToSkString(fontName, &info->fFontName); } + info->fMultiMaster = false; CFIndex glyphCount = CTFontGetGlyphCount(ctFont); info->fLastGlyphID = SkToU16(glyphCount - 1); info->fEmSize = CTFontGetUnitsPerEm(ctFont); - info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; - info->fStyle = 0; if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { populate_glyph_to_unicode(ctFont, glyphCount, &info->fGlyphToUnicode); } + info->fStyle = 0; + // If it's not a truetype font, mark it as 'other'. Assume that TrueType // fonts always have both glyf and loca tables. At the least, this is what // sfntly needs to subset the font. CTFontCopyAttribute() does not always @@ -1612,7 +1613,10 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( } } - if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { + if (false) { // TODO: haven't figured out how to know if font is embeddable + // (information is in the OS/2 table) + info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; + } else if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) { skia_advanced_typeface_metrics_utils::appendRange(&info->fGlyphWidths, 0); info->fGlyphWidths->fAdvance.append(1, &min_width); diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 7ea6cdabb7..aee2b863e6 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -1851,18 +1851,10 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics( info = new SkAdvancedTypefaceMetrics; info->fEmSize = otm.otmEMSquare; + info->fMultiMaster = false; info->fLastGlyphID = SkToU16(glyphCount - 1); info->fStyle = 0; tchar_to_skstring(lf.lfFaceName, &info->fFontName); - info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; - // If bit 1 is set, the font may not be embedded in a document. - // If bit 1 is clear, the font can be embedded. - // If bit 2 is set, the embedding is read-only. - if (otm.otmfsType & 0x1) { - info->fFlags = SkTBitOr( - info->fFlags, - SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag); - } if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode)); @@ -1923,7 +1915,13 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics( } } - if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { + // If bit 1 is set, the font may not be embedded in a document. + // If bit 1 is clear, the font can be embedded. + // If bit 2 is set, the embedding is read-only. + if (otm.otmfsType & 0x1) { + info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; + } else if (perGlyphInfo & + SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) { appendRange(&info->fGlyphWidths, 0); info->fGlyphWidths->fAdvance.append(1, &min_width); diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp index 3df743055a..00623623b0 100644 --- a/src/ports/SkFontHost_win_dw.cpp +++ b/src/ports/SkFontHost_win_dw.cpp @@ -1490,9 +1490,10 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( info = new SkAdvancedTypefaceMetrics; info->fEmSize = dwfm.designUnitsPerEm; + info->fMultiMaster = false; info->fLastGlyphID = SkToU16(glyphCount - 1); info->fStyle = 0; - info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; + SkTScopedComPtr familyNames; SkTScopedComPtr faceNames; @@ -1600,7 +1601,12 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( } */ - if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { + // If Restricted, the font may not be embedded in a document. + // If not Restricted, the font can be embedded. + // If PreviewPrint, the embedding is read-only. + if (os2Table->version.v0.fsType.field.Restricted) { + info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; + } else if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { if (fixedWidth) { appendRange(&info->fGlyphWidths, 0); int16_t advance;