Use Type3 fonts for platforms that don't yet support SkFontHost::GetAdvancedTypefaceMetrics.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@922 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
vandebo@chromium.org 2011-03-10 22:50:28 +00:00
parent 5ba2d5b187
commit f77e27deb9
2 changed files with 52 additions and 29 deletions

View File

@ -120,7 +120,7 @@ private:
void populateType0Font();
void populateCIDFont();
bool populateType1Font();
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
@ -128,10 +128,14 @@ private:
* information including glyph paths are queried from the platform
* dependent SkGlyphCache.
*/
void populateType3Font();
void populateType3Font(int16_t glyphID);
bool addFontDescriptor(int16_t defaultWidth);
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);
};

View File

@ -24,6 +24,7 @@
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
#include "SkPDFUtils.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkTypeface.h"
@ -401,7 +402,7 @@ SkPDFFont* SkPDFFont::getFontResource(SkTypeface* typeface, uint16_t glyphID) {
fontDescriptor = relatedFont->fDescriptor.get();
} else {
fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, true);
fontInfo->unref(); // SkRefPtr and get info both took a reference.
SkSafeUnref(fontInfo.get()); // SkRefPtr and Get both took a reference.
}
SkPDFFont* font = new SkPDFFont(fontInfo.get(), typeface, glyphID, false,
@ -450,16 +451,23 @@ SkPDFFont::SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo,
#endif
fMultiByteGlyphs(false),
fFirstGlyphID(1),
fLastGlyphID(fontInfo->fLastGlyphID),
fLastGlyphID(fontInfo ? fontInfo->fLastGlyphID : 0),
fFontInfo(fontInfo),
fDescriptor(fontDescriptor) {
if (fontInfo->fMultiMaster) {
SkAdvancedTypefaceMetrics::FontType type;
if (fontInfo) {
type = fontInfo->fType;
} else {
type = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
}
if (fontInfo && fontInfo->fMultiMaster) {
SkASSERT(false); // Not supported yet.
fontInfo->fType = SkAdvancedTypefaceMetrics::kOther_Font;
}
if (fontInfo->fType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
fontInfo->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
if (descendantFont) {
populateCIDFont();
} else {
@ -471,22 +479,16 @@ SkPDFFont::SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo,
return;
}
// Single byte glyph encoding supports a max of 255 glyphs.
fFirstGlyphID = glyphID - (glyphID - 1) % 255;
if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
fLastGlyphID = fFirstGlyphID + 255 - 1;
}
if (fontInfo->fType == SkAdvancedTypefaceMetrics::kType1_Font &&
populateType1Font()) {
if (type == SkAdvancedTypefaceMetrics::kType1_Font &&
populateType1Font(glyphID)) {
return;
}
SkASSERT(fontInfo->fType == SkAdvancedTypefaceMetrics::kType1_Font ||
fontInfo->fType == SkAdvancedTypefaceMetrics::kCFF_Font ||
fontInfo->fType == SkAdvancedTypefaceMetrics::kOther_Font ||
fontInfo->fType == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
populateType3Font();
SkASSERT(type == SkAdvancedTypefaceMetrics::kType1_Font ||
type == SkAdvancedTypefaceMetrics::kCFF_Font ||
type == SkAdvancedTypefaceMetrics::kOther_Font ||
type == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
populateType3Font(glyphID);
}
void SkPDFFont::populateType0Font() {
@ -563,10 +565,12 @@ void SkPDFFont::populateCIDFont() {
}
}
bool SkPDFFont::populateType1Font() {
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;
@ -615,7 +619,19 @@ bool SkPDFFont::populateType1Font() {
return true;
}
void SkPDFFont::populateType3Font() {
void SkPDFFont::populateType3Font(int16_t glyphID) {
SkPaint paint;
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 (fLastGlyphID == 0) {
fLastGlyphID = cache->getGlyphCount() - 1;
}
adjustGlyphRangeForSingleByteEncoding(glyphID);
insert("Subtype", new SkPDFName("Type3"))->unref();
// Flip about the x-axis and scale by 1/1000.
SkMatrix fontMatrix;
@ -639,12 +655,6 @@ void SkPDFFont::populateType3Font() {
SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
widthArray->unref(); // SkRefPtr and new both took a ref.
SkPaint paint;
paint.setTypeface(fTypeface.get());
paint.setTextSize(1000);
SkAutoGlyphCache autoCache(paint, NULL);
SkGlyphCache* cache = autoCache.getCache();
SkIRect bbox = SkIRect::MakeEmpty();
for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) {
SkString characterName;
@ -682,7 +692,7 @@ void SkPDFFont::populateType3Font() {
insert("LastChar", new SkPDFInt(fLastGlyphID))->unref();
insert("Widths", widthArray.get());
if (fFontInfo->fLastGlyphID <= 255)
if (fFontInfo && fFontInfo->fLastGlyphID <= 255)
fFontInfo = NULL;
}
@ -811,6 +821,15 @@ void SkPDFFont::addWidthInfoFromRange(
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;