[PDF] Refactor SkPDFFont to enable font/cmap subsetting.
Patch from Arthur Hsu, original CL: http://codereview.appspot.com/4633050/ Committed: http://code.google.com/p/skia/source/detail?r=1943 Reverted: http://code.google.com/p/skia/source/detail?r=1944 Review URL: http://codereview.appspot.com/4811049 git-svn-id: http://skia.googlecode.com/svn/trunk@1956 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
d3a094ca34
commit
9859428e71
@ -27,11 +27,12 @@
|
||||
'../include/pdf/SkPDFTypes.h',
|
||||
'../include/pdf/SkPDFUtils.h',
|
||||
|
||||
'../src/pdf/SkBitSet.cpp',
|
||||
'../src/pdf/SkBitSet.cpp',
|
||||
'../src/pdf/SkPDFCatalog.cpp',
|
||||
'../src/pdf/SkPDFDevice.cpp',
|
||||
'../src/pdf/SkPDFDocument.cpp',
|
||||
'../src/pdf/SkPDFFont.cpp',
|
||||
'../src/pdf/SkPDFFontImpl.h',
|
||||
'../src/pdf/SkPDFFormXObject.cpp',
|
||||
'../src/pdf/SkPDFGraphicState.cpp',
|
||||
'../src/pdf/SkPDFImage.cpp',
|
||||
|
@ -40,12 +40,12 @@ public:
|
||||
|
||||
/** Test if bit index is set.
|
||||
*/
|
||||
bool isBitSet(int index);
|
||||
bool isBitSet(int index) const;
|
||||
|
||||
/** Or bits from source. false is returned if this doesn't have the same
|
||||
* bit count as source.
|
||||
*/
|
||||
bool orBits(SkBitSet& source);
|
||||
bool orBits(const SkBitSet& source);
|
||||
|
||||
private:
|
||||
SkAutoFree fBitData;
|
||||
@ -53,7 +53,7 @@ private:
|
||||
size_t fDwordCount;
|
||||
size_t fBitCount;
|
||||
|
||||
uint32_t* internalGet(int index) {
|
||||
uint32_t* internalGet(int index) const {
|
||||
SkASSERT((size_t)index < fBitCount);
|
||||
size_t internalIndex = index / 32;
|
||||
SkASSERT(internalIndex < fDwordCount);
|
||||
|
@ -30,6 +30,7 @@ class SkPDFDevice;
|
||||
class SkPDFDict;
|
||||
class SkPDFFont;
|
||||
class SkPDFFormXObject;
|
||||
class SkPDFGlyphSetMap;
|
||||
class SkPDFGraphicState;
|
||||
class SkPDFObject;
|
||||
class SkPDFShader;
|
||||
@ -150,11 +151,18 @@ public:
|
||||
* for calling data->unref() when it is finished.
|
||||
*/
|
||||
SK_API SkData* copyContentToData() const;
|
||||
|
||||
|
||||
SK_API const SkMatrix& initialTransform() const {
|
||||
return fInitialTransform;
|
||||
}
|
||||
|
||||
/** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
|
||||
* that shows on this device.
|
||||
*/
|
||||
const SkPDFGlyphSetMap& getFontGlyphUsage() const {
|
||||
return *(fFontGlyphUsage.get());
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO(vandebo) push most of SkPDFDevice's state into a core object in
|
||||
// order to get the right access levels without using friend.
|
||||
@ -183,17 +191,20 @@ private:
|
||||
ContentEntry* getLastContentEntry();
|
||||
void setLastContentEntry(ContentEntry* contentEntry);
|
||||
|
||||
// Glyph ids used for each font on this device.
|
||||
SkTScopedPtr<SkPDFGlyphSetMap> fFontGlyphUsage;
|
||||
|
||||
SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
|
||||
const SkRegion& existingClipRegion);
|
||||
|
||||
// override from SkDevice
|
||||
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque,
|
||||
Usage usage);
|
||||
|
||||
void init();
|
||||
void cleanUp();
|
||||
void cleanUp(bool clearFontUsage);
|
||||
void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);
|
||||
|
||||
// Clear the passed clip from all existing content entries.
|
||||
|
@ -81,6 +81,7 @@ private:
|
||||
SkTDArray<SkPDFDict*> fPageTree;
|
||||
SkRefPtr<SkPDFDict> fDocCatalog;
|
||||
SkTDArray<SkPDFObject*> fPageResources;
|
||||
SkTDArray<SkPDFObject*> fSubstitutes;
|
||||
int fSecondPageFirstResourceIndex;
|
||||
|
||||
SkRefPtr<SkPDFDict> fTrailerDict;
|
||||
|
@ -18,11 +18,63 @@
|
||||
#define SkPDFFont_DEFINED
|
||||
|
||||
#include "SkAdvancedTypefaceMetrics.h"
|
||||
#include "SkBitSet.h"
|
||||
#include "SkPDFTypes.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkThread.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkPaint;
|
||||
class SkPDFCatalog;
|
||||
class SkPDFFont;
|
||||
|
||||
class SkPDFGlyphSet : public SkNoncopyable {
|
||||
public:
|
||||
SkPDFGlyphSet();
|
||||
|
||||
void set(const uint16_t* glyphIDs, int numGlyphs);
|
||||
bool has(uint16_t glyphID) const;
|
||||
void merge(const SkPDFGlyphSet& usage);
|
||||
|
||||
private:
|
||||
SkBitSet fBitSet;
|
||||
};
|
||||
|
||||
class SkPDFGlyphSetMap : public SkNoncopyable {
|
||||
public:
|
||||
struct FontGlyphSetPair {
|
||||
FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
|
||||
|
||||
SkPDFFont* fFont;
|
||||
SkPDFGlyphSet* fGlyphSet;
|
||||
};
|
||||
|
||||
SkPDFGlyphSetMap();
|
||||
~SkPDFGlyphSetMap();
|
||||
|
||||
class F2BIter {
|
||||
public:
|
||||
F2BIter(const SkPDFGlyphSetMap& map);
|
||||
FontGlyphSetPair* next() const;
|
||||
void reset(const SkPDFGlyphSetMap& map);
|
||||
|
||||
private:
|
||||
const SkTDArray<FontGlyphSetPair>* fMap;
|
||||
mutable int fIndex;
|
||||
};
|
||||
|
||||
void merge(const SkPDFGlyphSetMap& usage);
|
||||
void reset();
|
||||
|
||||
void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
|
||||
int numGlyphs);
|
||||
|
||||
private:
|
||||
SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
|
||||
|
||||
SkTDArray<FontGlyphSetPair> fMap;
|
||||
};
|
||||
|
||||
|
||||
/** \class SkPDFFont
|
||||
A PDF Object class representing a font. The font may have resources
|
||||
@ -45,16 +97,16 @@ public:
|
||||
/** Returns the font type represented in this font. For Type0 fonts,
|
||||
* returns the type of the decendant font.
|
||||
*/
|
||||
SK_API SkAdvancedTypefaceMetrics::FontType getType();
|
||||
SK_API virtual SkAdvancedTypefaceMetrics::FontType getType();
|
||||
|
||||
/** Returns true if this font encoding supports glyph IDs above 255.
|
||||
*/
|
||||
SK_API virtual bool multiByteGlyphs() const = 0;
|
||||
|
||||
/** Return true if this font has an encoding for the passed glyph id.
|
||||
*/
|
||||
SK_API bool hasGlyph(uint16_t glyphID);
|
||||
|
||||
/** Returns true if this font encoding supports glyph IDs above 255.
|
||||
*/
|
||||
SK_API bool multiByteGlyphs();
|
||||
|
||||
/** Convert (in place) the input glyph IDs into the font encoding. If the
|
||||
* font has more glyphs than can be encoded (like a type 1 font with more
|
||||
* than 255 glyphs) this method only converts up to the first out of range
|
||||
@ -76,24 +128,52 @@ public:
|
||||
SK_API static SkPDFFont* GetFontResource(SkTypeface* typeface,
|
||||
uint16_t glyphID);
|
||||
|
||||
/** Subset the font based on usage set. Returns a SkPDFFont instance with
|
||||
* subset.
|
||||
* @param usage Glyph subset requested.
|
||||
* @return NULL if font does not support subsetting, a new instance
|
||||
* of SkPDFFont otherwise.
|
||||
*/
|
||||
SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
|
||||
|
||||
protected:
|
||||
// Common constructor to handle common members.
|
||||
SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
|
||||
uint16_t glyphID, bool descendantFont);
|
||||
|
||||
// Accessors for subclass.
|
||||
SkAdvancedTypefaceMetrics* fontInfo();
|
||||
uint16_t firstGlyphID() const;
|
||||
uint16_t lastGlyphID() const;
|
||||
void setLastGlyphID(uint16_t glyphID);
|
||||
|
||||
// Add object to resource list.
|
||||
void addResource(SkPDFObject* object);
|
||||
|
||||
// Accessors for FontDescriptor associated with this object.
|
||||
SkPDFDict* getFontDescriptor();
|
||||
void setFontDescriptor(SkPDFDict* descriptor);
|
||||
|
||||
// Add common entries to FontDescriptor.
|
||||
bool addCommonFontDescriptorEntries(int16_t defaultWidth);
|
||||
|
||||
/** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
|
||||
* including the passed glyphID.
|
||||
*/
|
||||
void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
|
||||
|
||||
// Generate ToUnicode table according to glyph usage subset.
|
||||
// If subset is NULL, all available glyph ids will be used.
|
||||
void populateToUnicodeTable(const SkPDFGlyphSet* subset);
|
||||
|
||||
// Create instances of derived types based on fontInfo.
|
||||
static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
|
||||
SkTypeface* typeface, uint16_t glyphID,
|
||||
SkPDFDict* fontDescriptor);
|
||||
|
||||
static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
|
||||
|
||||
private:
|
||||
SkRefPtr<SkTypeface> fTypeface;
|
||||
SkAdvancedTypefaceMetrics::FontType fType;
|
||||
#ifdef SK_DEBUG
|
||||
bool fDescendant;
|
||||
#endif
|
||||
bool fMultiByteGlyphs;
|
||||
|
||||
// The glyph IDs accessible with this font. For Type1 (non CID) fonts,
|
||||
// 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.
|
||||
SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
|
||||
SkTDArray<SkPDFObject*> fResources;
|
||||
SkRefPtr<SkPDFDict> fDescriptor;
|
||||
|
||||
class FontRec {
|
||||
public:
|
||||
SkPDFFont* fFont;
|
||||
@ -105,47 +185,23 @@ private:
|
||||
FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
|
||||
};
|
||||
|
||||
SkRefPtr<SkTypeface> fTypeface;
|
||||
|
||||
// The glyph IDs accessible with this font. For Type1 (non CID) fonts,
|
||||
// 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.
|
||||
SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
|
||||
SkTDArray<SkPDFObject*> fResources;
|
||||
SkRefPtr<SkPDFDict> fDescriptor;
|
||||
|
||||
SkAdvancedTypefaceMetrics::FontType fFontType;
|
||||
|
||||
// This should be made a hash table if performance is a problem.
|
||||
static SkTDArray<FontRec>& CanonicalFonts();
|
||||
static SkMutex& CanonicalFontsMutex();
|
||||
|
||||
/** Construct a new font dictionary and support objects.
|
||||
* @param fontInfo Information about the to create.
|
||||
* @param typeface The typeface for the font.
|
||||
* @param glyphID The glyph ID the caller is interested in. This
|
||||
* is important only for Type1 fonts, which have
|
||||
* more than 255 glyphs.
|
||||
* @param descendantFont If this is the descendant (true) or root
|
||||
* (Type 0 font - false) font dictionary. Only True
|
||||
* Type and CID encoded fonts will use a true value.
|
||||
* @param fontDescriptor If the font descriptor has already have generated
|
||||
* for this font, pass it in here, otherwise pass
|
||||
* NULL.
|
||||
*/
|
||||
SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
|
||||
uint16_t glyphID, bool descendantFont, SkPDFDict* fontDescriptor);
|
||||
|
||||
void populateType0Font();
|
||||
void populateCIDFont();
|
||||
bool populateType1Font(int16_t glyphID);
|
||||
|
||||
/** Populate the PDF font dictionary as Type3 font which includes glyph
|
||||
* descriptions with instructions for painting the glyphs. This function
|
||||
* doesn't use any fields from SkAdvancedTypefaceMetrics (fFontInfo). Font
|
||||
* information including glyph paths are queried from the platform
|
||||
* dependent SkGlyphCache.
|
||||
*/
|
||||
void populateType3Font(int16_t glyphID);
|
||||
bool addFontDescriptor(int16_t defaultWidth);
|
||||
void populateToUnicodeTable();
|
||||
void addWidthInfoFromRange(int16_t defaultWidth,
|
||||
const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry);
|
||||
/** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
|
||||
* including the passed glyphID.
|
||||
*/
|
||||
void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
|
||||
|
||||
static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,11 @@ public:
|
||||
*/
|
||||
SK_API const SkTDArray<SkPDFFont*>& getFontResources() const;
|
||||
|
||||
/** Returns a SkPDFGlyphSetMap which represents glyph usage of every font
|
||||
* that shows on this page.
|
||||
*/
|
||||
const SkPDFGlyphSetMap& getFontGlyphUsage() const;
|
||||
|
||||
private:
|
||||
// Multiple pages may reference the content.
|
||||
SkRefPtr<SkPDFDevice> fDevice;
|
||||
|
@ -73,12 +73,12 @@ void SkBitSet::setBit(int index, bool value) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SkBitSet::isBitSet(int index) {
|
||||
bool SkBitSet::isBitSet(int index) const {
|
||||
uint32_t mask = 1 << (index % 32);
|
||||
return (*internalGet(index) & mask);
|
||||
}
|
||||
|
||||
bool SkBitSet::orBits(SkBitSet& source) {
|
||||
bool SkBitSet::orBits(const SkBitSet& source) {
|
||||
if (fBitCount != source.fBitCount) {
|
||||
return false;
|
||||
}
|
||||
|
@ -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();
|
||||
this->cleanUp(true);
|
||||
}
|
||||
|
||||
void SkPDFDevice::init() {
|
||||
@ -553,18 +553,24 @@ void SkPDFDevice::init() {
|
||||
fLastContentEntry = NULL;
|
||||
fMarginContentEntries.reset();
|
||||
fLastMarginContentEntry = NULL;
|
||||
fDrawingArea = kContent_DrawingArea;
|
||||
fDrawingArea = kContent_DrawingArea;
|
||||
if (fFontGlyphUsage == NULL) {
|
||||
fFontGlyphUsage.reset(new SkPDFGlyphSetMap());
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::cleanUp() {
|
||||
void SkPDFDevice::cleanUp(bool clearFontUsage) {
|
||||
fGraphicStateResources.unrefAll();
|
||||
fXObjectResources.unrefAll();
|
||||
fFontResources.unrefAll();
|
||||
fShaderResources.unrefAll();
|
||||
if (clearFontUsage) {
|
||||
fFontGlyphUsage->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::clear(SkColor color) {
|
||||
this->cleanUp();
|
||||
this->cleanUp(true);
|
||||
this->init();
|
||||
|
||||
SkPaint paint;
|
||||
@ -825,6 +831,8 @@ 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());
|
||||
@ -893,6 +901,7 @@ 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);
|
||||
@ -952,6 +961,9 @@ 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() {
|
||||
@ -1142,7 +1154,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
|
||||
@ -1154,7 +1166,10 @@ void SkPDFDevice::createFormXObjectFromDevice(
|
||||
SkRefPtr<SkPDFFormXObject>* xobject) {
|
||||
*xobject = new SkPDFFormXObject(this);
|
||||
(*xobject)->unref(); // SkRefPtr and new both took a reference.
|
||||
cleanUp(); // Reset this device to have no content.
|
||||
// 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.
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#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.
|
||||
@ -37,6 +38,29 @@ 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) {
|
||||
@ -55,6 +79,7 @@ SkPDFDocument::~SkPDFDocument() {
|
||||
fPageTree[i]->clear();
|
||||
fPageTree.safeUnrefAll();
|
||||
fPageResources.safeUnrefAll();
|
||||
fSubstitutes.safeUnrefAll();
|
||||
}
|
||||
|
||||
bool SkPDFDocument::emitPDF(SkWStream* stream) {
|
||||
@ -98,6 +123,9 @@ 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);
|
||||
|
1008
src/pdf/SkPDFFont.cpp
Executable file → Normal file
1008
src/pdf/SkPDFFont.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
90
src/pdf/SkPDFFontImpl.h
Executable file
90
src/pdf/SkPDFFontImpl.h
Executable file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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
|
@ -141,3 +141,7 @@ void SkPDFPage::GeneratePageTree(const SkTDArray<SkPDFPage*>& pages,
|
||||
const SkTDArray<SkPDFFont*>& SkPDFPage::getFontResources() const {
|
||||
return fDevice->getFontResources();
|
||||
}
|
||||
|
||||
const SkPDFGlyphSetMap& SkPDFPage::getFontGlyphUsage() const {
|
||||
return fDevice->getFontGlyphUsage();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user