1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 11cb93a386Sopenharmony_ci#include "src/core/SkAdvancedTypefaceMetrics.h" 12cb93a386Sopenharmony_ci#include "src/core/SkGlyph.h" 13cb93a386Sopenharmony_ci#include "src/core/SkRectPriv.h" 14cb93a386Sopenharmony_ci#include "tools/fonts/RandomScalerContext.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciclass SkDescriptor; 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass RandomScalerContext : public SkScalerContext { 19cb93a386Sopenharmony_cipublic: 20cb93a386Sopenharmony_ci RandomScalerContext(sk_sp<SkRandomTypeface>, 21cb93a386Sopenharmony_ci const SkScalerContextEffects&, 22cb93a386Sopenharmony_ci const SkDescriptor*, 23cb93a386Sopenharmony_ci bool fFakeIt); 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ciprotected: 26cb93a386Sopenharmony_ci bool generateAdvance(SkGlyph*) override; 27cb93a386Sopenharmony_ci void generateMetrics(SkGlyph*) override; 28cb93a386Sopenharmony_ci void generateImage(const SkGlyph&) override; 29cb93a386Sopenharmony_ci bool generatePath(SkGlyphID, SkPath*) override; 30cb93a386Sopenharmony_ci void generateFontMetrics(SkFontMetrics*) override; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciprivate: 33cb93a386Sopenharmony_ci SkRandomTypeface* getRandomTypeface() const { 34cb93a386Sopenharmony_ci return static_cast<SkRandomTypeface*>(this->getTypeface()); 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci std::unique_ptr<SkScalerContext> fProxy; 37cb93a386Sopenharmony_ci bool fFakeIt; 38cb93a386Sopenharmony_ci}; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ciRandomScalerContext::RandomScalerContext(sk_sp<SkRandomTypeface> face, 41cb93a386Sopenharmony_ci const SkScalerContextEffects& effects, 42cb93a386Sopenharmony_ci const SkDescriptor* desc, 43cb93a386Sopenharmony_ci bool fakeIt) 44cb93a386Sopenharmony_ci : SkScalerContext(std::move(face), effects, desc) 45cb93a386Sopenharmony_ci , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc)) 46cb93a386Sopenharmony_ci , fFakeIt(fakeIt) { 47cb93a386Sopenharmony_ci fProxy->forceGenerateImageFromPath(); 48cb93a386Sopenharmony_ci} 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_cibool RandomScalerContext::generateAdvance(SkGlyph* glyph) { return fProxy->generateAdvance(glyph); } 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_civoid RandomScalerContext::generateMetrics(SkGlyph* glyph) { 53cb93a386Sopenharmony_ci // Here we will change the mask format of the glyph 54cb93a386Sopenharmony_ci // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied). 55cb93a386Sopenharmony_ci SkMask::Format format = SkMask::kA8_Format; 56cb93a386Sopenharmony_ci switch (glyph->getGlyphID() % 4) { 57cb93a386Sopenharmony_ci case 0: format = SkMask::kLCD16_Format; break; 58cb93a386Sopenharmony_ci case 1: format = SkMask::kA8_Format; break; 59cb93a386Sopenharmony_ci case 2: format = SkMask::kARGB32_Format; break; 60cb93a386Sopenharmony_ci case 3: format = SkMask::kBW_Format; break; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci *glyph = fProxy->internalMakeGlyph(glyph->getPackedID(), format); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci if (fFakeIt || (glyph->getGlyphID() % 4) != 2) { 66cb93a386Sopenharmony_ci return; 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci SkPath path; 70cb93a386Sopenharmony_ci if (!fProxy->getPath(glyph->getPackedID(), &path)) { 71cb93a386Sopenharmony_ci return; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci glyph->fMaskFormat = SkMask::kARGB32_Format; 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci SkRect storage; 76cb93a386Sopenharmony_ci const SkPaint& paint = this->getRandomTypeface()->paint(); 77cb93a386Sopenharmony_ci const SkRect& newBounds = 78cb93a386Sopenharmony_ci paint.doComputeFastBounds(path.getBounds(), &storage, SkPaint::kFill_Style); 79cb93a386Sopenharmony_ci SkIRect ibounds; 80cb93a386Sopenharmony_ci newBounds.roundOut(&ibounds); 81cb93a386Sopenharmony_ci glyph->fLeft = ibounds.fLeft; 82cb93a386Sopenharmony_ci glyph->fTop = ibounds.fTop; 83cb93a386Sopenharmony_ci glyph->fWidth = ibounds.width(); 84cb93a386Sopenharmony_ci glyph->fHeight = ibounds.height(); 85cb93a386Sopenharmony_ci} 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_civoid RandomScalerContext::generateImage(const SkGlyph& glyph) { 88cb93a386Sopenharmony_ci // TODO: can force down but not up 89cb93a386Sopenharmony_ci /* 90cb93a386Sopenharmony_ci SkMask::Format format = (SkMask::Format)glyph.fMaskFormat; 91cb93a386Sopenharmony_ci switch (glyph.getGlyphID() % 4) { 92cb93a386Sopenharmony_ci case 0: format = SkMask::kLCD16_Format; break; 93cb93a386Sopenharmony_ci case 1: format = SkMask::kA8_Format; break; 94cb93a386Sopenharmony_ci case 2: format = SkMask::kARGB32_Format; break; 95cb93a386Sopenharmony_ci case 3: format = SkMask::kBW_Format; break; 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci const_cast<SkGlyph&>(glyph).fMaskFormat = format; 98cb93a386Sopenharmony_ci */ 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci if (fFakeIt) { 101cb93a386Sopenharmony_ci sk_bzero(glyph.fImage, glyph.imageSize()); 102cb93a386Sopenharmony_ci return; 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci if (SkMask::kARGB32_Format != glyph.fMaskFormat) { 106cb93a386Sopenharmony_ci fProxy->getImage(glyph); 107cb93a386Sopenharmony_ci return; 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci // If the format is ARGB, just draw the glyph from path. 111cb93a386Sopenharmony_ci SkPath path; 112cb93a386Sopenharmony_ci if (!fProxy->getPath(glyph.getPackedID(), &path)) { 113cb93a386Sopenharmony_ci fProxy->getImage(glyph); 114cb93a386Sopenharmony_ci return; 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci SkBitmap bm; 118cb93a386Sopenharmony_ci bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), 119cb93a386Sopenharmony_ci glyph.fImage, 120cb93a386Sopenharmony_ci glyph.rowBytes()); 121cb93a386Sopenharmony_ci bm.eraseColor(0); 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci SkCanvas canvas(bm); 124cb93a386Sopenharmony_ci canvas.translate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop)); 125cb93a386Sopenharmony_ci canvas.drawPath(path, this->getRandomTypeface()->paint()); 126cb93a386Sopenharmony_ci} 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_cibool RandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) { 129cb93a386Sopenharmony_ci return fProxy->generatePath(glyph, path); 130cb93a386Sopenharmony_ci} 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_civoid RandomScalerContext::generateFontMetrics(SkFontMetrics* metrics) { 133cb93a386Sopenharmony_ci fProxy->getFontMetrics(metrics); 134cb93a386Sopenharmony_ci} 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ciSkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt) 139cb93a386Sopenharmony_ci : SkTypeface(proxy->fontStyle(), false) 140cb93a386Sopenharmony_ci , fProxy(std::move(proxy)) 141cb93a386Sopenharmony_ci , fPaint(paint) 142cb93a386Sopenharmony_ci , fFakeIt(fakeIt) {} 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_cistd::unique_ptr<SkScalerContext> SkRandomTypeface::onCreateScalerContext( 145cb93a386Sopenharmony_ci const SkScalerContextEffects& effects, const SkDescriptor* desc) const 146cb93a386Sopenharmony_ci{ 147cb93a386Sopenharmony_ci return std::make_unique<RandomScalerContext>( 148cb93a386Sopenharmony_ci sk_ref_sp(const_cast<SkRandomTypeface*>(this)), effects, desc, fFakeIt); 149cb93a386Sopenharmony_ci} 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_civoid SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const { 152cb93a386Sopenharmony_ci fProxy->filterRec(rec); 153cb93a386Sopenharmony_ci rec->setHinting(SkFontHinting::kNone); 154cb93a386Sopenharmony_ci rec->fMaskFormat = SkMask::kARGB32_Format; 155cb93a386Sopenharmony_ci} 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_civoid SkRandomTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const { 158cb93a386Sopenharmony_ci fProxy->getGlyphToUnicodeMap(glyphToUnicode); 159cb93a386Sopenharmony_ci} 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_cistd::unique_ptr<SkAdvancedTypefaceMetrics> SkRandomTypeface::onGetAdvancedMetrics() const { 162cb93a386Sopenharmony_ci return fProxy->getAdvancedMetrics(); 163cb93a386Sopenharmony_ci} 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_cistd::unique_ptr<SkStreamAsset> SkRandomTypeface::onOpenStream(int* ttcIndex) const { 166cb93a386Sopenharmony_ci return fProxy->openStream(ttcIndex); 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_cisk_sp<SkTypeface> SkRandomTypeface::onMakeClone(const SkFontArguments& args) const { 170cb93a386Sopenharmony_ci sk_sp<SkTypeface> proxy = fProxy->makeClone(args); 171cb93a386Sopenharmony_ci if (!proxy) { 172cb93a386Sopenharmony_ci return nullptr; 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci return sk_make_sp<SkRandomTypeface>(proxy, fPaint, fFakeIt); 175cb93a386Sopenharmony_ci} 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_civoid SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const { 178cb93a386Sopenharmony_ci // TODO: anything that uses this typeface isn't correctly serializable, since this typeface 179cb93a386Sopenharmony_ci // cannot be deserialized. 180cb93a386Sopenharmony_ci fProxy->getFontDescriptor(desc, isLocal); 181cb93a386Sopenharmony_ci} 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_civoid SkRandomTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const { 184cb93a386Sopenharmony_ci fProxy->unicharsToGlyphs(uni, count, glyphs); 185cb93a386Sopenharmony_ci} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ciint SkRandomTypeface::onCountGlyphs() const { return fProxy->countGlyphs(); } 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ciint SkRandomTypeface::onGetUPEM() const { return fProxy->getUnitsPerEm(); } 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_civoid SkRandomTypeface::onGetFamilyName(SkString* familyName) const { 192cb93a386Sopenharmony_ci fProxy->getFamilyName(familyName); 193cb93a386Sopenharmony_ci} 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_cibool SkRandomTypeface::onGetPostScriptName(SkString* postScriptName) const { 196cb93a386Sopenharmony_ci return fProxy->getPostScriptName(postScriptName); 197cb93a386Sopenharmony_ci} 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ciSkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const { 200cb93a386Sopenharmony_ci return fProxy->createFamilyNameIterator(); 201cb93a386Sopenharmony_ci} 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_civoid SkRandomTypeface::getPostScriptGlyphNames(SkString* names) const { 204cb93a386Sopenharmony_ci return fProxy->getPostScriptGlyphNames(names); 205cb93a386Sopenharmony_ci} 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_ciint SkRandomTypeface::onGetVariationDesignPosition( 208cb93a386Sopenharmony_ci SkFontArguments::VariationPosition::Coordinate coordinates[], 209cb93a386Sopenharmony_ci int coordinateCount) const { 210cb93a386Sopenharmony_ci return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount); 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_ciint SkRandomTypeface::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], 214cb93a386Sopenharmony_ci int parameterCount) const { 215cb93a386Sopenharmony_ci return fProxy->onGetVariationDesignParameters(parameters, parameterCount); 216cb93a386Sopenharmony_ci} 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_ciint SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const { 219cb93a386Sopenharmony_ci return fProxy->getTableTags(tags); 220cb93a386Sopenharmony_ci} 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_cisize_t SkRandomTypeface::onGetTableData(SkFontTableTag tag, 223cb93a386Sopenharmony_ci size_t offset, 224cb93a386Sopenharmony_ci size_t length, 225cb93a386Sopenharmony_ci void* data) const { 226cb93a386Sopenharmony_ci return fProxy->getTableData(tag, offset, length, data); 227cb93a386Sopenharmony_ci} 228