aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-23 21:13:30 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-23 21:13:30 +0000
commit31dcee7b84ac8a50fe8269a39ac0431b01da48d1 (patch)
tree255ed941c795fdf6479562417119c43f6a35c3bb /src/pdf
parent6504cfdfc035f0a2cb854be9df352159873b9d62 (diff)
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
Diffstat (limited to 'src/pdf')
-rwxr-xr-xsrc/pdf/SkBitSet.cpp4
-rw-r--r--src/pdf/SkPDFDevice.cpp31
-rw-r--r--src/pdf/SkPDFDocument.cpp28
-rwxr-xr-x[-rw-r--r--]src/pdf/SkPDFFont.cpp776
-rwxr-xr-xsrc/pdf/SkPDFFontImpl.h90
-rw-r--r--src/pdf/SkPDFPage.cpp4
6 files changed, 289 insertions, 644 deletions
diff --git a/src/pdf/SkBitSet.cpp b/src/pdf/SkBitSet.cpp
index c7af832b43..f19dd69a51 100755
--- a/src/pdf/SkBitSet.cpp
+++ b/src/pdf/SkBitSet.cpp
@@ -73,12 +73,12 @@ void SkBitSet::setBit(int index, bool value) {
}
}
-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 e2dfba6941..619d55d4c1 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -424,8 +424,8 @@ void GraphicStackState::updateDrawingState(const GraphicStateEntry& state) {
}
}
-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(const SkISize& layerSize,
}
SkPDFDevice::~SkPDFDevice() {
- this->cleanUp(true);
+ this->cleanUp();
}
void SkPDFDevice::init() {
@@ -553,24 +553,18 @@ void SkPDFDevice::init() {
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 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
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 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
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 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkDevice* device, int x, int y,
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 @@ SkData* SkPDFDevice::copyContentToData() const {
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 @@ void SkPDFDevice::createFormXObjectFromDevice(
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 38f4f32977..71c3784c02 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 @@ void addResourcesToCatalog(int firstIndex, bool firstPage,
}
}
-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 @@ SkPDFDocument::~SkPDFDocument() {
fPageTree[i]->clear();
fPageTree.safeUnrefAll();
fPageResources.safeUnrefAll();
- fSubstitutes.safeUnrefAll();
}
bool SkPDFDocument::emitPDF(SkWStream* stream) {
@@ -123,9 +98,6 @@ bool SkPDFDocument::emitPDF(SkWStream* stream) {
}
}
- // 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
index f50580a4c4..be16c76936 100644..100755
--- 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 @@ int8_t hexToBin(uint8_t c) {
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 @@ static void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
// 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 void append_cmap_bfchar_sections(
}
}
-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 @@ SkPDFFont::~SkPDFFont() {
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 @@ SkTypeface* SkPDFFont::typeface() {
}
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 @@ size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs,
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 @@ SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
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 @@ bool SkPDFFont::Find(uint32_t fontID, uint16_t glyphID, int* index) {
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);
- }
- 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;
+ fType = SkAdvancedTypefaceMetrics::kOther_Font;
}
-}
-
-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;
+ 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;
}
- 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::kType1_Font &&
+ populateType1Font(glyphID)) {
return;
}
- SkRefPtr<SkPDFStream> pdfCmap =
- generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset);
- addResource(pdfCmap.get()); // Pass reference from new.
- insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class SkPDFType0Font
-///////////////////////////////////////////////////////////////////////////////
-SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info,
- SkTypeface* typeface)
- : SkPDFFont(info, typeface, 0, false) {
- SkDEBUGCODE(fPopulated = false);
+ SkASSERT(fType == SkAdvancedTypefaceMetrics::kType1_Font ||
+ fType == SkAdvancedTypefaceMetrics::kCFF_Font ||
+ fType == SkAdvancedTypefaceMetrics::kOther_Font ||
+ fType == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
+ populateType3Font(glyphID);
}
-SkPDFType0Font::~SkPDFType0Font() {}
+void SkPDFFont::populateType0Font() {
+ fMultiByteGlyphs = true;
-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("BaseFont", fFontInfo->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
-///////////////////////////////////////////////////////////////////////////////
+ // 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());
-SkPDFCIDFont::SkPDFCIDFont(SkAdvancedTypefaceMetrics* info,
- SkTypeface* typeface, const SkPDFGlyphSet* subset)
- : SkPDFFont(info, typeface, 0, true) {
- populate(subset);
+ populateToUnicodeTable();
}
-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);
+void SkPDFFont::populateToUnicodeTable() {
+ if (fFontInfo.get() == NULL ||
+ fFontInfo->fGlyphToUnicode.begin() == NULL) {
+ return;
}
- addResource(descriptor.get());
- descriptor->ref();
-
- insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
- return addCommonFontDescriptorEntries(defaultWidth);
+ 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();
}
-bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
- insertName("BaseFont", fontInfo()->fFontName);
+void SkPDFFont::populateCIDFont() {
+ fMultiByteGlyphs = true;
+ insertName("BaseFont", fFontInfo->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 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
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 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
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 @@ bool SkPDFType1Font::populate(int16_t glyphID) {
return false;
insertName("Subtype", "Type1");
- insertName("BaseFont", fontInfo()->fFontName);
+ insertName("BaseFont", fFontInfo->fFontName);
addWidthInfoFromRange(defaultWidth, widthRangeEntry);
@@ -1054,67 +718,26 @@ bool SkPDFType1Font::populate(int16_t glyphID) {
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 @@ bool SkPDFType3Font::populate(int16_t glyphID) {
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 @@ bool SkPDFType3Font::populate(int16_t glyphID) {
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 22206255c4..0000000000
--- 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 846df64a23..09849b0ac8 100644
--- a/src/pdf/SkPDFPage.cpp
+++ b/src/pdf/SkPDFPage.cpp
@@ -141,7 +141,3 @@ void SkPDFPage::GeneratePageTree(const SkTDArray<SkPDFPage*>& pages,
const SkTDArray<SkPDFFont*>& SkPDFPage::getFontResources() const {
return fDevice->getFontResources();
}
-
-const SkPDFGlyphSetMap& SkPDFPage::getFontGlyphUsage() const {
- return fDevice->getFontGlyphUsage();
-}