| Index: src/fonts/SkTestScalerContext.cpp
|
| diff --git a/src/fonts/SkTestScalerContext.cpp b/src/fonts/SkTestScalerContext.cpp
|
| index 7d311cdbc0d91a337efd6858a8599d0dca0a05bc..854c98090488c3e8c53e8b99e03c0ccc3fa7883b 100644
|
| --- a/src/fonts/SkTestScalerContext.cpp
|
| +++ b/src/fonts/SkTestScalerContext.cpp
|
| @@ -8,6 +8,7 @@
|
| #include "SkBitmap.h"
|
| #include "SkCanvas.h"
|
| #include "SkDescriptor.h"
|
| +#include "SkFontDescriptor.h"
|
| #include "SkGlyph.h"
|
| #include "SkMask.h"
|
| // #include "SkOTUtils.h"
|
| @@ -15,126 +16,171 @@
|
| #include "SkTestScalerContext.h"
|
| #include "SkTypefaceCache.h"
|
|
|
| -class SkTestTypeface : public SkTypeface {
|
| -public:
|
| - SkTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& , SkTDArray<SkFixed>& ),
|
| - SkTypeface::Style style)
|
| - : SkTypeface(style, SkTypefaceCache::NewFontID(), false) {
|
| - fMetrics = (*funct)(fPaths, fWidths);
|
| - }
|
| +SkTestFont::SkTestFont(const SkTestFontData& fontData)
|
| + : INHERITED()
|
| + , fCharCodes(fontData.fCharCodes)
|
| + , fCharCodesCount(fontData.fCharCodesCount)
|
| + , fWidths(fontData.fWidths)
|
| + , fMetrics(fontData.fMetrics)
|
| + , fName(fontData.fName)
|
| + , fPaths(NULL)
|
| +{
|
| + init(fontData.fPoints, fontData.fVerbs);
|
| +#ifdef SK_DEBUG
|
| + sk_bzero(fDebugBits, sizeof(fDebugBits));
|
| + sk_bzero(fDebugOverage, sizeof(fDebugOverage));
|
| +#endif
|
| +}
|
|
|
| - virtual ~SkTestTypeface() {
|
| - fPaths.deleteAll();
|
| +SkTestFont::~SkTestFont() {
|
| + for (unsigned index = 0; index < fCharCodesCount; ++index) {
|
| + SkDELETE(fPaths[index]);
|
| }
|
| + SkDELETE_ARRAY(fPaths);
|
| +}
|
|
|
| - void getAdvance(SkGlyph* glyph) {
|
| - glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)];
|
| - glyph->fAdvanceY = 0;
|
| - }
|
| +#ifdef SK_DEBUG
|
|
|
| - void getFontMetrics(SkPaint::FontMetrics* metrics) {
|
| - *metrics = fMetrics;
|
| - }
|
| +#include "SkThread.h"
|
| +SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
|
|
|
| - void getMetrics(SkGlyph* glyph) {
|
| - glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)];
|
| - glyph->fAdvanceY = 0;
|
| - }
|
| +#endif
|
|
|
| - void getPath(const SkGlyph& glyph, SkPath* path) {
|
| - *path = *fPaths[SkGlyph::ID2Code(glyph.fID)];
|
| +int SkTestFont::codeToIndex(SkUnichar charCode) const {
|
| +#ifdef SK_DEBUG // detect missing test font data
|
| + {
|
| + SkAutoMutexAcquire ac(gUsedCharsMutex);
|
| + if (charCode >= ' ' && charCode <= '~') {
|
| + int bitOffset = charCode - ' ';
|
| + fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
|
| + } else {
|
| + int index = 0;
|
| + while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
|
| + && index < (int) sizeof(fDebugOverage)) {
|
| + ++index;
|
| + }
|
| + SkASSERT(index < (int) sizeof(fDebugOverage));
|
| + if (fDebugOverage[index] == 0) {
|
| + fDebugOverage[index] = charCode;
|
| + }
|
| + }
|
| }
|
| -
|
| -protected:
|
| - virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE;
|
| -
|
| - virtual void onFilterRec(SkScalerContextRec* rec) const SK_OVERRIDE {
|
| - rec->setHinting(SkPaint::kNo_Hinting);
|
| - rec->fMaskFormat = SkMask::kA8_Format;
|
| +#endif
|
| + for (unsigned index = 0; index < fCharCodesCount; ++index) {
|
| + if (fCharCodes[index] == (unsigned) charCode) {
|
| + return (int) index;
|
| + }
|
| }
|
| + SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
|
| + fDebugName, fDebugStyle));
|
| + return 0;
|
| +}
|
|
|
| - virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
|
| - SkAdvancedTypefaceMetrics::PerGlyphInfo ,
|
| - const uint32_t* glyphIDs,
|
| - uint32_t glyphIDsCount) const SK_OVERRIDE {
|
| - // pdf only
|
| - SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
|
| - info->fEmSize = 0;
|
| - info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
|
| - info->fStyle = 0;
|
| - info->fFontName.set("SkiaTest");
|
| - info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
|
| - info->fItalicAngle = 0;
|
| - info->fAscent = 0;
|
| - info->fDescent = 0;
|
| - info->fStemV = 0;
|
| - info->fCapHeight = 0;
|
| - info->fBBox = SkIRect::MakeEmpty();
|
| - return info;
|
| +void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
|
| + fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
|
| + for (unsigned index = 0; index < fCharCodesCount; ++index) {
|
| + SkPath* path = SkNEW(SkPath);
|
| + SkPath::Verb verb;
|
| + while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
|
| + switch (verb) {
|
| + case SkPath::kMove_Verb:
|
| + path->moveTo(pts[0], pts[1]);
|
| + pts += 2;
|
| + break;
|
| + case SkPath::kLine_Verb:
|
| + path->lineTo(pts[0], pts[1]);
|
| + pts += 2;
|
| + break;
|
| + case SkPath::kQuad_Verb:
|
| + path->quadTo(pts[0], pts[1], pts[2], pts[3]);
|
| + pts += 4;
|
| + break;
|
| + case SkPath::kCubic_Verb:
|
| + path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
|
| + pts += 6;
|
| + break;
|
| + case SkPath::kClose_Verb:
|
| + path->close();
|
| + break;
|
| + default:
|
| + SkDEBUGFAIL("bad verb");
|
| + return;
|
| + }
|
| + }
|
| + fPaths[index] = path;
|
| }
|
| +}
|
| +
|
| +SkTestTypeface::SkTestTypeface(SkTestFont* testFont, SkTypeface::Style style)
|
| + : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
|
| + , fTestFont(testFont) {
|
| +}
|
|
|
| - virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
|
| - SkASSERT(0); // don't expect to get here
|
| - return NULL;
|
| - }
|
| +void SkTestTypeface::getAdvance(SkGlyph* glyph) {
|
| + glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
|
| + glyph->fAdvanceY = 0;
|
| +}
|
|
|
| - virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE {
|
| - SkASSERT(0); // don't expect to get here
|
| - }
|
| +void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
|
| + *metrics = fTestFont->fMetrics;
|
| +}
|
|
|
| - virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
|
| - uint16_t glyphs[], int glyphCount) const SK_OVERRIDE {
|
| - SkASSERT(encoding == kUTF8_Encoding);
|
| - for (int index = 0; index < glyphCount; ++index) {
|
| - int ch = ((unsigned char*) chars)[index];
|
| - SkASSERT(ch < 0x7F);
|
| - if (ch < 0x20) {
|
| - glyphs[index] = 0;
|
| - } else {
|
| - glyphs[index] = ch - 0x20;
|
| - }
|
| - }
|
| - return glyphCount;
|
| - }
|
| +void SkTestTypeface::getMetrics(SkGlyph* glyph) {
|
| + glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
|
| + glyph->fAdvanceY = 0;
|
| +}
|
|
|
| - virtual int onCountGlyphs() const SK_OVERRIDE {
|
| - return fPaths.count();
|
| - }
|
| +void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
|
| + *path = *fTestFont->fPaths[SkGlyph::ID2Code(glyph.fID)];
|
| +}
|
|
|
| - virtual int onGetUPEM() const SK_OVERRIDE {
|
| - SkASSERT(0); // don't expect to get here
|
| - return 1;
|
| - }
|
| +void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
|
| + rec->setHinting(SkPaint::kNo_Hinting);
|
| + rec->fMaskFormat = SkMask::kA8_Format;
|
| +}
|
|
|
| - virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE {
|
| - SkString familyName("SkiaTest");
|
| - SkString language("und"); //undetermined
|
| - SkASSERT(0); // incomplete
|
| - return NULL;
|
| - // return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
|
| - }
|
| +SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
|
| + SkAdvancedTypefaceMetrics::PerGlyphInfo ,
|
| + const uint32_t* glyphIDs,
|
| + uint32_t glyphIDsCount) const {
|
| +// pdf only
|
| + SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
|
| + info->fEmSize = 0;
|
| + info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
|
| + info->fStyle = 0;
|
| + info->fFontName.set(fTestFont->fName);
|
| + info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
|
| + info->fItalicAngle = 0;
|
| + info->fAscent = 0;
|
| + info->fDescent = 0;
|
| + info->fStemV = 0;
|
| + info->fCapHeight = 0;
|
| + info->fBBox = SkIRect::MakeEmpty();
|
| + return info;
|
| +}
|
|
|
| - virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE {
|
| - return 0;
|
| - }
|
| +void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
|
| + desc->setFamilyName(fTestFont->fName);
|
| + desc->setFontFileName(fTestFont->fName);
|
| + *isLocal = false;
|
| +}
|
|
|
| - virtual size_t onGetTableData(SkFontTableTag tag, size_t offset,
|
| - size_t length, void* data) const SK_OVERRIDE {
|
| - return 0;
|
| +int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
|
| + uint16_t glyphs[], int glyphCount) const {
|
| + SkASSERT(encoding == kUTF16_Encoding);
|
| + for (int index = 0; index < glyphCount; ++index) {
|
| + SkUnichar ch = ((SkUnichar*) chars)[index];
|
| + glyphs[index] = fTestFont->codeToIndex(ch);
|
| }
|
| + return glyphCount;
|
| +}
|
|
|
| -private:
|
| - SkTDArray<SkPath* > fPaths;
|
| - SkTDArray<SkFixed> fWidths;
|
| - SkPaint::FontMetrics fMetrics;
|
| - friend class SkTestScalerContext;
|
| -};
|
| -
|
| -SkTypeface* CreateTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& pathArray,
|
| - SkTDArray<SkFixed>& widthArray),
|
| - SkTypeface::Style style) {
|
| - SkTypeface* test = SkNEW_ARGS(SkTestTypeface, (funct, style));
|
| - return test;
|
| +SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
|
| + SkString familyName(fTestFont->fName);
|
| + SkString language("und"); //undetermined
|
| +SkASSERT(0); // incomplete
|
| + return NULL;
|
| +// return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
|
| }
|
|
|
| class SkTestScalerContext : public SkScalerContext {
|
| @@ -156,10 +202,8 @@ protected:
|
| }
|
|
|
| virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
|
| - uint8_t ch = (uint8_t) uni;
|
| - SkASSERT(ch < 0x7f);
|
| uint16_t glyph;
|
| - (void) fFace->onCharsToGlyphs((const void *) &ch, SkTypeface::kUTF8_Encoding, &glyph, 1);
|
| + (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
|
| return glyph;
|
| }
|
|
|
|
|