diff options
author | Mike Klein <mtklein@chromium.org> | 2017-11-10 11:33:43 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-10 17:02:20 +0000 |
commit | 10d66cc3f8624f2fc9825f38cb1b654f7bb00db9 (patch) | |
tree | 05d485a6ef42be2cf5734b22653c59804d140d5c /tools | |
parent | 8f7d4c3d86b252a68c9e9b45f69d741d4601a9e5 (diff) |
move Sk{Test,Random}ScalerContext to tools
There's no need for Skia users to link this test code.
Change-Id: I9d6ef2a053d0cf5cb916aa254389ca819c48bae1
Reviewed-on: https://skia-review.googlesource.com/69922
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/SkRandomScalerContext.cpp | 258 | ||||
-rw-r--r-- | tools/SkRandomScalerContext.h | 54 | ||||
-rw-r--r-- | tools/SkTestScalerContext.cpp | 290 | ||||
-rw-r--r-- | tools/SkTestScalerContext.h | 109 |
4 files changed, 711 insertions, 0 deletions
diff --git a/tools/SkRandomScalerContext.cpp b/tools/SkRandomScalerContext.cpp new file mode 100644 index 0000000000..49d9ab43ff --- /dev/null +++ b/tools/SkRandomScalerContext.cpp @@ -0,0 +1,258 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkAdvancedTypefaceMetrics.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkGlyph.h" +#include "SkMakeUnique.h" +#include "SkPath.h" +#include "SkRandomScalerContext.h" +#include "SkRasterizer.h" + +class SkDescriptor; + +class SkRandomScalerContext : public SkScalerContext { +public: + SkRandomScalerContext(sk_sp<SkRandomTypeface>, const SkScalerContextEffects&, + const SkDescriptor*, bool fFakeIt); + +protected: + unsigned generateGlyphCount() override; + uint16_t generateCharToGlyph(SkUnichar) override; + void generateAdvance(SkGlyph*) override; + void generateMetrics(SkGlyph*) override; + void generateImage(const SkGlyph&) override; + void generatePath(SkGlyphID, SkPath*) override; + void generateFontMetrics(SkPaint::FontMetrics*) override; + +private: + SkRandomTypeface* getRandomTypeface() const { + return static_cast<SkRandomTypeface*>(this->getTypeface()); + } + std::unique_ptr<SkScalerContext> fProxy; + bool fFakeIt; +}; + +SkRandomScalerContext::SkRandomScalerContext(sk_sp<SkRandomTypeface> face, + const SkScalerContextEffects& effects, + const SkDescriptor* desc, + bool fakeIt) + : SkScalerContext(std::move(face), effects, desc) + , fFakeIt(fakeIt) { + fProxy = this->getRandomTypeface()->proxy()->createScalerContext(effects, desc); +} + +unsigned SkRandomScalerContext::generateGlyphCount() { + return fProxy->getGlyphCount(); +} + +uint16_t SkRandomScalerContext::generateCharToGlyph(SkUnichar uni) { + return fProxy->charToGlyphID(uni); +} + +void SkRandomScalerContext::generateAdvance(SkGlyph* glyph) { + fProxy->getAdvance(glyph); +} + +void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) { + // Here we will change the mask format of the glyph + // NOTE this is being overridden by the base class + SkMask::Format format = SkMask::kARGB32_Format; // init to handle defective compilers + switch (glyph->getGlyphID() % 4) { + case 0: + format = SkMask::kLCD16_Format; + break; + case 1: + format = SkMask::kA8_Format; + break; + case 2: + format = SkMask::kARGB32_Format; + break; + case 3: + format = SkMask::kBW_Format; + break; + } + + fProxy->getMetrics(glyph); + + glyph->fMaskFormat = format; + if (fFakeIt) { + return; + } + if (SkMask::kARGB32_Format == format) { + SkPath path; + fProxy->getPath(glyph->getPackedID(), &path); + + SkRect storage; + const SkPaint& paint = this->getRandomTypeface()->paint(); + const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), + &storage, + SkPaint::kFill_Style); + SkIRect ibounds; + newBounds.roundOut(&ibounds); + glyph->fLeft = ibounds.fLeft; + glyph->fTop = ibounds.fTop; + glyph->fWidth = ibounds.width(); + glyph->fHeight = ibounds.height(); + } else { + SkPath devPath, fillPath; + SkMatrix fillToDevMatrix; + + this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix); + + // just use devPath + const SkIRect ir = devPath.getBounds().roundOut(); + + if (ir.isEmpty() || !ir.is16Bit()) { + glyph->fLeft = 0; + glyph->fTop = 0; + glyph->fWidth = 0; + glyph->fHeight = 0; + return; + } + glyph->fLeft = ir.fLeft; + glyph->fTop = ir.fTop; + glyph->fWidth = SkToU16(ir.width()); + glyph->fHeight = SkToU16(ir.height()); + + if (glyph->fWidth > 0) { + switch (glyph->fMaskFormat) { + case SkMask::kLCD16_Format: + glyph->fWidth += 2; + glyph->fLeft -= 1; + break; + default: + break; + } + } + } +} + +void SkRandomScalerContext::generateImage(const SkGlyph& glyph) { + SkMask::Format format = (SkMask::Format)glyph.fMaskFormat; + switch (glyph.getGlyphID() % 4) { + case 0: + format = SkMask::kLCD16_Format; + break; + case 1: + format = SkMask::kA8_Format; + break; + case 2: + format = SkMask::kARGB32_Format; + break; + case 3: + format = SkMask::kBW_Format; + break; + } + const_cast<SkGlyph&>(glyph).fMaskFormat = format; + + // if the format is ARGB, we just draw the glyph from path ourselves. Otherwise, we force + // our proxy context to generate the image from paths. + if (!fFakeIt) { + if (SkMask::kARGB32_Format == glyph.fMaskFormat) { + SkPath path; + fProxy->getPath(glyph.getPackedID(), &path); + + SkBitmap bm; + bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), + glyph.fImage, glyph.rowBytes()); + bm.eraseColor(0); + + SkCanvas canvas(bm); + canvas.translate(-SkIntToScalar(glyph.fLeft), + -SkIntToScalar(glyph.fTop)); + canvas.drawPath(path, this->getRandomTypeface()->paint()); + } else { + fProxy->forceGenerateImageFromPath(); + fProxy->getImage(glyph); + fProxy->forceOffGenerateImageFromPath(); + } + } else { + sk_bzero(glyph.fImage, glyph.computeImageSize()); + } +} + +void SkRandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) { + fProxy->generatePath(glyph, path); +} + +void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) { + fProxy->getFontMetrics(metrics); +} + +/////////////////////////////////////////////////////////////////////////////// + +#include "SkTypefaceCache.h" + +SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt) + : SkTypeface(proxy->fontStyle(), false) + , fProxy(std::move(proxy)) + , fPaint(paint) + , fFakeIt(fakeIt) {} + +SkScalerContext* SkRandomTypeface::onCreateScalerContext(const SkScalerContextEffects& effects, + const SkDescriptor* desc) const { + return new SkRandomScalerContext(sk_ref_sp(const_cast<SkRandomTypeface*>(this)), + effects, desc, fFakeIt); +} + +void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const { + fProxy->filterRec(rec); + rec->setHinting(SkPaint::kNo_Hinting); + rec->fMaskFormat = SkMask::kARGB32_Format; +} + +std::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const { + return fProxy->getAdvancedMetrics(); +} + +SkStreamAsset* SkRandomTypeface::onOpenStream(int* ttcIndex) const { + return fProxy->openStream(ttcIndex); +} + +void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, + bool* isLocal) const { + fProxy->getFontDescriptor(desc, isLocal); +} + +int SkRandomTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const { + return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); +} + +int SkRandomTypeface::onCountGlyphs() const { + return fProxy->countGlyphs(); +} + +int SkRandomTypeface::onGetUPEM() const { + return fProxy->getUnitsPerEm(); +} + +void SkRandomTypeface::onGetFamilyName(SkString* familyName) const { + fProxy->getFamilyName(familyName); +} + +SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const { + return fProxy->createFamilyNameIterator(); +} + +int SkRandomTypeface::onGetVariationDesignPosition( + SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const +{ + return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount); +} + +int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const { + return fProxy->getTableTags(tags); +} + +size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag, size_t offset, + size_t length, void* data) const { + return fProxy->getTableData(tag, offset, length, data); +} + diff --git a/tools/SkRandomScalerContext.h b/tools/SkRandomScalerContext.h new file mode 100644 index 0000000000..b71689d9e2 --- /dev/null +++ b/tools/SkRandomScalerContext.h @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkRandomScalerContext_DEFINED +#define SkRandomScalerContext_DEFINED + +#include "SkScalerContext.h" +#include "SkTypeface.h" + +/* + * This scaler context is for debug only purposes. It will 'randomly' but deterministically return + * LCD / A8 / BW / RBGA masks based off of the Glyph ID + */ + +class SkRandomTypeface : public SkTypeface { +public: + SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint&, bool fakeit); + + SkTypeface* proxy() const { return fProxy.get(); } + const SkPaint& paint() const { return fPaint; } + +protected: + SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, + const SkDescriptor*) const override; + void onFilterRec(SkScalerContextRec*) const override; + std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; + SkStreamAsset* onOpenStream(int* ttcIndex) const override; + void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const override; + + int onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const override; + int onCountGlyphs() const override; + int onGetUPEM() const override; + + void onGetFamilyName(SkString* familyName) const override; + SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; + + int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], + int coordinateCount) const override; + int onGetTableTags(SkFontTableTag tags[]) const override; + size_t onGetTableData(SkFontTableTag, size_t offset, + size_t length, void* data) const override; + +private: + sk_sp<SkTypeface> fProxy; + SkPaint fPaint; + bool fFakeIt; +}; + +#endif diff --git a/tools/SkTestScalerContext.cpp b/tools/SkTestScalerContext.cpp new file mode 100644 index 0000000000..34ec6af849 --- /dev/null +++ b/tools/SkTestScalerContext.cpp @@ -0,0 +1,290 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkAdvancedTypefaceMetrics.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkDescriptor.h" +#include "SkFontDescriptor.h" +#include "SkGlyph.h" +#include "SkMakeUnique.h" +#include "SkMask.h" +#include "SkOTUtils.h" +#include "SkPaintPriv.h" +#include "SkScalerContext.h" +#include "SkTestScalerContext.h" +#include "SkTypefaceCache.h" + +SkTestFont::SkTestFont(const SkTestFontData& fontData) + : INHERITED() + , fCharCodes(fontData.fCharCodes) + , fCharCodesCount(fontData.fCharCodes ? fontData.fCharCodesCount : 0) + , fWidths(fontData.fWidths) + , fMetrics(fontData.fMetrics) + , fName(fontData.fName) + , fPaths(nullptr) +{ + init(fontData.fPoints, fontData.fVerbs); +#ifdef SK_DEBUG + sk_bzero(fDebugBits, sizeof(fDebugBits)); + sk_bzero(fDebugOverage, sizeof(fDebugOverage)); +#endif +} + +SkTestFont::~SkTestFont() { + for (unsigned index = 0; index < fCharCodesCount; ++index) { + delete fPaths[index]; + } + delete[] fPaths; +} + +#ifdef SK_DEBUG + +#include "SkMutex.h" +SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex); + +#endif + +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; + } + } + } +#endif + for (unsigned index = 0; index < fCharCodesCount; ++index) { + if (fCharCodes[index] == (unsigned) charCode) { + return (int) index; + } + } + + SkDEBUGF(("missing '%c' (%d) from %s (weight %d, width %d, slant %d)\n", + (char) charCode, charCode, fDebugName, + fDebugStyle.weight(), fDebugStyle.width(), fDebugStyle.slant())); + return 0; +} + +void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) { + fPaths = new SkPath* [fCharCodesCount]; + for (unsigned index = 0; index < fCharCodesCount; ++index) { + SkPath* path = new 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; + } + } + // This should make SkPath::getBounds() queries threadsafe. + path->updateBoundsCache(); + fPaths[index] = path; + } +} + +SkTestTypeface::SkTestTypeface(sk_sp<SkTestFont> testFont, const SkFontStyle& style) + : SkTypeface(style, false) + , fTestFont(std::move(testFont)) { +} + +void SkTestTypeface::getAdvance(SkGlyph* glyph) { + // TODO(benjaminwagner): Update users to use floats. + glyph->fAdvanceX = SkFixedToFloat(fTestFont->fWidths[glyph->getGlyphID()]); + glyph->fAdvanceY = 0; +} + +void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) { + *metrics = fTestFont->fMetrics; +} + +void SkTestTypeface::getMetrics(SkGlyph* glyph) { + SkGlyphID glyphID = glyph->getGlyphID(); + glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0; + + // TODO(benjaminwagner): Update users to use floats. + glyph->fAdvanceX = SkFixedToFloat(fTestFont->fWidths[glyphID]); + glyph->fAdvanceY = 0; +} + +void SkTestTypeface::getPath(SkGlyphID glyphID, SkPath* path) { + glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0; + *path = *fTestFont->fPaths[glyphID]; +} + +void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const { + rec->setHinting(SkPaint::kNo_Hinting); +} + +std::unique_ptr<SkAdvancedTypefaceMetrics> SkTestTypeface::onGetAdvancedMetrics() const { // pdf only + std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics); + info->fFontName.set(fTestFont->fName); + int glyphCount = this->onCountGlyphs(); + + SkTDArray<SkUnichar>& toUnicode = info->fGlyphToUnicode; + toUnicode.setCount(glyphCount); + SkASSERT(glyphCount == SkToInt(fTestFont->fCharCodesCount)); + for (int gid = 0; gid < glyphCount; ++gid) { + toUnicode[gid] = SkToS32(fTestFont->fCharCodes[gid]); + } + return info; +} + +void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const { + desc->setFamilyName(fTestFont->fName); + desc->setStyle(this->fontStyle()); + *isLocal = false; +} + +int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const { + SkASSERT(encoding == kUTF32_Encoding); + for (int index = 0; index < glyphCount; ++index) { + SkUnichar ch = ((SkUnichar*) chars)[index]; + glyphs[index] = fTestFont->codeToIndex(ch); + } + return glyphCount; +} + +void SkTestTypeface::onGetFamilyName(SkString* familyName) const { + *familyName = fTestFont->fName; +} + +SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const { + SkString familyName(fTestFont->fName); + SkString language("und"); //undetermined + return new SkOTUtils::LocalizedStrings_SingleName(familyName, language); +} + +class SkTestScalerContext : public SkScalerContext { +public: + SkTestScalerContext(sk_sp<SkTestTypeface> face, const SkScalerContextEffects& effects, + const SkDescriptor* desc) + : SkScalerContext(std::move(face), effects, desc) + { + fRec.getSingleMatrix(&fMatrix); + this->forceGenerateImageFromPath(); + } + +protected: + SkTestTypeface* getTestTypeface() const { + return static_cast<SkTestTypeface*>(this->getTypeface()); + } + + unsigned generateGlyphCount() override { + return this->getTestTypeface()->onCountGlyphs(); + } + + uint16_t generateCharToGlyph(SkUnichar uni) override { + uint16_t glyph; + (void) this->getTestTypeface()->onCharsToGlyphs((const void *) &uni, + SkTypeface::kUTF32_Encoding, &glyph, 1); + return glyph; + } + + void generateAdvance(SkGlyph* glyph) override { + this->getTestTypeface()->getAdvance(glyph); + + const SkVector advance = fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX), + SkFloatToScalar(glyph->fAdvanceY)); + glyph->fAdvanceX = SkScalarToFloat(advance.fX); + glyph->fAdvanceY = SkScalarToFloat(advance.fY); + } + + void generateMetrics(SkGlyph* glyph) override { + this->getTestTypeface()->getMetrics(glyph); + + const SkVector advance = fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX), + SkFloatToScalar(glyph->fAdvanceY)); + glyph->fAdvanceX = SkScalarToFloat(advance.fX); + glyph->fAdvanceY = SkScalarToFloat(advance.fY); + + SkPath path; + this->getTestTypeface()->getPath(glyph->getGlyphID(), &path); + path.transform(fMatrix); + + SkRect storage; + const SkPaint paint; + const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), + &storage, + SkPaint::kFill_Style); + SkIRect ibounds; + newBounds.roundOut(&ibounds); + glyph->fLeft = ibounds.fLeft; + glyph->fTop = ibounds.fTop; + glyph->fWidth = ibounds.width(); + glyph->fHeight = ibounds.height(); + } + + void generateImage(const SkGlyph& glyph) override { + SkPath path; + this->getTestTypeface()->getPath(glyph.getGlyphID(), &path); + + SkBitmap bm; + bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), + glyph.fImage, glyph.rowBytes()); + bm.eraseColor(0); + + SkCanvas canvas(bm); + canvas.translate(-SkIntToScalar(glyph.fLeft), + -SkIntToScalar(glyph.fTop)); + canvas.concat(fMatrix); + SkPaint paint; + paint.setAntiAlias(true); + canvas.drawPath(path, paint); + } + + void generatePath(SkGlyphID glyph, SkPath* path) override { + this->getTestTypeface()->getPath(glyph, path); + path->transform(fMatrix); + } + + void generateFontMetrics(SkPaint::FontMetrics* metrics) override { + this->getTestTypeface()->getFontMetrics(metrics); + SkPaintPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY()); + } + +private: + SkMatrix fMatrix; +}; + +SkScalerContext* SkTestTypeface::onCreateScalerContext( + const SkScalerContextEffects& effects, const SkDescriptor* desc) const +{ + return new SkTestScalerContext(sk_ref_sp(const_cast<SkTestTypeface*>(this)), effects, desc); +} diff --git a/tools/SkTestScalerContext.h b/tools/SkTestScalerContext.h new file mode 100644 index 0000000000..1d362901eb --- /dev/null +++ b/tools/SkTestScalerContext.h @@ -0,0 +1,109 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkTestScalerContext_DEFINED +#define SkTestScalerContext_DEFINED + +#include "SkFixed.h" +#include "SkPaint.h" +#include "SkPath.h" +#include "SkRefCnt.h" +#include "SkTDArray.h" +#include "SkTypeface.h" + +class SkTestFont; + +struct SkTestFontData { + const SkScalar* fPoints; + const unsigned char* fVerbs; + const unsigned* fCharCodes; + const size_t fCharCodesCount; + const SkFixed* fWidths; + const SkPaint::FontMetrics& fMetrics; + const char* fName; + SkFontStyle fStyle; + sk_sp<SkTestFont> fCachedFont; +}; + +class SkTestFont : public SkRefCnt { +public: + SkTestFont(const SkTestFontData& ); + virtual ~SkTestFont(); + int codeToIndex(SkUnichar charCode) const; + void init(const SkScalar* pts, const unsigned char* verbs); +#ifdef SK_DEBUG // detect missing test font data + mutable unsigned char fDebugBits[16]; + mutable SkUnichar fDebugOverage[8]; + const char* fDebugName; + SkFontStyle fDebugStyle; + const char* debugFontName() const { return fName; } +#endif +private: + const unsigned* fCharCodes; + const size_t fCharCodesCount; + const SkFixed* fWidths; + const SkPaint::FontMetrics& fMetrics; + const char* fName; + SkPath** fPaths; + friend class SkTestTypeface; + typedef SkRefCnt INHERITED; +}; + + +class SkTestTypeface : public SkTypeface { +public: + SkTestTypeface(sk_sp<SkTestFont>, const SkFontStyle& style); + void getAdvance(SkGlyph* glyph); + void getFontMetrics(SkPaint::FontMetrics* metrics); + void getMetrics(SkGlyph* glyph); + void getPath(SkGlyphID glyph, SkPath* path); +protected: + SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, + const SkDescriptor* desc) const override; + void onFilterRec(SkScalerContextRec* rec) const override; + std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; + + SkStreamAsset* onOpenStream(int* ttcIndex) const override { + return nullptr; + } + + void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override; + + int onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const override; + + int onCountGlyphs() const override { + return (int) fTestFont->fCharCodesCount; + } + + int onGetUPEM() const override { + return 2048; + } + + void onGetFamilyName(SkString* familyName) const override; + SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; + + int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], + int coordinateCount) const override + { + return 0; + } + + int onGetTableTags(SkFontTableTag tags[]) const override { + return 0; + } + + size_t onGetTableData(SkFontTableTag tag, size_t offset, + size_t length, void* data) const override { + return 0; + } +private: + sk_sp<SkTestFont> fTestFont; + friend class SkTestScalerContext; +}; + +#endif |