blob: 34392d6ed35bf38b14f00026f1e6ad498312487d [file] [log] [blame]
joshualittaa2f6582015-07-29 10:14:58 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkRandomScalerContext.h"
9#include "SkGlyph.h"
10#include "SkPath.h"
11#include "SkCanvas.h"
joshualitt65e96b42015-07-31 11:45:22 -070012#include "SkRasterizer.h"
joshualittaa2f6582015-07-29 10:14:58 -070013
14class SkRandomScalerContext : public SkScalerContext {
15public:
joshualitt65e96b42015-07-31 11:45:22 -070016 SkRandomScalerContext(SkRandomTypeface*, const SkDescriptor*, bool fFakeIt);
joshualittaa2f6582015-07-29 10:14:58 -070017 virtual ~SkRandomScalerContext();
18
19protected:
20 unsigned generateGlyphCount() override;
21 uint16_t generateCharToGlyph(SkUnichar) override;
22 void generateAdvance(SkGlyph*) override;
23 void generateMetrics(SkGlyph*) override;
24 void generateImage(const SkGlyph&) override;
25 void generatePath(const SkGlyph&, SkPath*) override;
26 void generateFontMetrics(SkPaint::FontMetrics*) override;
27
28private:
29 SkRandomTypeface* fFace;
30 SkScalerContext* fProxy;
joshualittd164a712015-07-31 15:10:31 -070031 SkMatrix fMatrix;
joshualitt65e96b42015-07-31 11:45:22 -070032 bool fFakeIt;
joshualittaa2f6582015-07-29 10:14:58 -070033};
34
35#define STD_SIZE 1
36
37#include "SkDescriptor.h"
38
joshualitt65e96b42015-07-31 11:45:22 -070039SkRandomScalerContext::SkRandomScalerContext(SkRandomTypeface* face, const SkDescriptor* desc,
40 bool fakeIt)
joshualittaa2f6582015-07-29 10:14:58 -070041 : SkScalerContext(face, desc)
joshualitt65e96b42015-07-31 11:45:22 -070042 , fFace(face)
43 , fFakeIt(fakeIt) {
joshualittd164a712015-07-31 15:10:31 -070044 size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec);
45 SkAutoDescriptor ad(descSize);
46 SkDescriptor* newDesc = ad.getDesc();
47
48 newDesc->init();
49 void* entry = newDesc->addEntry(kRec_SkDescriptorTag,
50 sizeof(SkScalerContext::Rec), &fRec);
51 {
52 SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry;
53 rec->fTextSize = STD_SIZE;
54 rec->fPreScaleX = SK_Scalar1;
55 rec->fPreSkewX = 0;
56 rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
57 rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0;
58 }
59 SkASSERT(descSize == newDesc->getLength());
60 newDesc->computeChecksum();
61
62 fProxy = face->proxy()->createScalerContext(newDesc);
63
64 fRec.getSingleMatrix(&fMatrix);
65 fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE);
joshualittaa2f6582015-07-29 10:14:58 -070066}
67
68SkRandomScalerContext::~SkRandomScalerContext() {
69 SkDELETE(fProxy);
70}
71
72unsigned SkRandomScalerContext::generateGlyphCount() {
73 return fProxy->getGlyphCount();
74}
75
76uint16_t SkRandomScalerContext::generateCharToGlyph(SkUnichar uni) {
77 return fProxy->charToGlyphID(uni);
78}
79
80void SkRandomScalerContext::generateAdvance(SkGlyph* glyph) {
81 fProxy->getAdvance(glyph);
joshualittd164a712015-07-31 15:10:31 -070082
83 SkVector advance;
84 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
85 SkFixedToScalar(glyph->fAdvanceY), &advance);
86 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
87 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
joshualittaa2f6582015-07-29 10:14:58 -070088}
89
90void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
joshualittaa2f6582015-07-29 10:14:58 -070091 // Here we will change the mask format of the glyph
92 // NOTE this is being overridden by the base class
93 SkMask::Format format;
joshualitt65e96b42015-07-31 11:45:22 -070094 switch (glyph->getGlyphID() % 3) {
joshualittaa2f6582015-07-29 10:14:58 -070095 case 0:
96 format = SkMask::kLCD16_Format;
97 break;
98 case 1:
99 format = SkMask::kA8_Format;
100 break;
101 case 2:
102 format = SkMask::kARGB32_Format;
103 break;
joshualittaa2f6582015-07-29 10:14:58 -0700104 }
105
joshualitt65e96b42015-07-31 11:45:22 -0700106 fProxy->getMetrics(glyph);
107
joshualittaa2f6582015-07-29 10:14:58 -0700108 glyph->fMaskFormat = format;
joshualitt65e96b42015-07-31 11:45:22 -0700109 if (fFakeIt) {
110 return;
111 }
112 if (SkMask::kARGB32_Format == format) {
joshualittd164a712015-07-31 15:10:31 -0700113 SkVector advance;
114 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
115 SkFixedToScalar(glyph->fAdvanceY), &advance);
116 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
117 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
118
joshualitt65e96b42015-07-31 11:45:22 -0700119 SkPath path;
120 fProxy->getPath(*glyph, &path);
joshualittd164a712015-07-31 15:10:31 -0700121 path.transform(fMatrix);
joshualitt65e96b42015-07-31 11:45:22 -0700122
123 SkRect storage;
124 const SkPaint& paint = fFace->paint();
125 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
126 &storage,
127 SkPaint::kFill_Style);
128 SkIRect ibounds;
129 newBounds.roundOut(&ibounds);
130 glyph->fLeft = ibounds.fLeft;
131 glyph->fTop = ibounds.fTop;
132 glyph->fWidth = ibounds.width();
133 glyph->fHeight = ibounds.height();
134 } else {
135 SkPath devPath, fillPath;
136 SkMatrix fillToDevMatrix;
137
138 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
139
140 // just use devPath
141 const SkIRect ir = devPath.getBounds().roundOut();
142
143 if (ir.isEmpty() || !ir.is16Bit()) {
144 glyph->fLeft = 0;
145 glyph->fTop = 0;
146 glyph->fWidth = 0;
147 glyph->fHeight = 0;
148 return;
149 }
150 glyph->fLeft = ir.fLeft;
151 glyph->fTop = ir.fTop;
152 glyph->fWidth = SkToU16(ir.width());
153 glyph->fHeight = SkToU16(ir.height());
154
155 if (glyph->fWidth > 0) {
156 switch (glyph->fMaskFormat) {
157 case SkMask::kLCD16_Format:
158 glyph->fWidth += 2;
159 glyph->fLeft -= 1;
160 break;
161 default:
162 break;
163 }
164 }
165 }
joshualittaa2f6582015-07-29 10:14:58 -0700166}
167
168void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
169 SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
joshualitt65e96b42015-07-31 11:45:22 -0700170 switch (glyph.getGlyphID() % 3) {
joshualittaa2f6582015-07-29 10:14:58 -0700171 case 0:
joshualittaa2f6582015-07-29 10:14:58 -0700172 format = SkMask::kLCD16_Format;
173 break;
joshualitt65e96b42015-07-31 11:45:22 -0700174 case 1:
joshualittaa2f6582015-07-29 10:14:58 -0700175 format = SkMask::kA8_Format;
176 break;
joshualitt65e96b42015-07-31 11:45:22 -0700177 case 2:
joshualittaa2f6582015-07-29 10:14:58 -0700178 format = SkMask::kARGB32_Format;
179 break;
180 }
181 const_cast<SkGlyph&>(glyph).fMaskFormat = format;
182
183 // if the format is ARGB, we just draw the glyph from path ourselves. Otherwise, we force
184 // our proxy context to generate the image from paths.
joshualitt65e96b42015-07-31 11:45:22 -0700185 if (!fFakeIt) {
186 if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
187 SkPath path;
188 fProxy->getPath(glyph, &path);
joshualittaa2f6582015-07-29 10:14:58 -0700189
joshualitt65e96b42015-07-31 11:45:22 -0700190 SkBitmap bm;
191 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
192 glyph.fImage, glyph.rowBytes());
193 bm.eraseColor(0);
joshualittaa2f6582015-07-29 10:14:58 -0700194
joshualitt65e96b42015-07-31 11:45:22 -0700195 SkCanvas canvas(bm);
196 canvas.translate(-SkIntToScalar(glyph.fLeft),
197 -SkIntToScalar(glyph.fTop));
joshualittd164a712015-07-31 15:10:31 -0700198 canvas.concat(fMatrix);
joshualitt65e96b42015-07-31 11:45:22 -0700199 canvas.drawPath(path, fFace->paint());
200 } else {
201 fProxy->forceGenerateImageFromPath();
202 fProxy->getImage(glyph);
203 fProxy->forceOffGenerateImageFromPath();
204 }
joshualittaa2f6582015-07-29 10:14:58 -0700205 } else {
joshualitt65e96b42015-07-31 11:45:22 -0700206 sk_bzero(glyph.fImage, glyph.computeImageSize());
joshualittaa2f6582015-07-29 10:14:58 -0700207 }
208}
209
210void SkRandomScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
211 fProxy->getPath(glyph, path);
joshualittd164a712015-07-31 15:10:31 -0700212 path->transform(fMatrix);
joshualittaa2f6582015-07-29 10:14:58 -0700213}
214
215void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {
216 fProxy->getFontMetrics(metrics);
joshualittd164a712015-07-31 15:10:31 -0700217 if (metrics) {
218 SkScalar scale = fMatrix.getScaleY();
219 metrics->fTop = SkScalarMul(metrics->fTop, scale);
220 metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
221 metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
222 metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
223 metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
224 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
225 metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
226 metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
227 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
228 }
joshualittaa2f6582015-07-29 10:14:58 -0700229}
230
231///////////////////////////////////////////////////////////////////////////////
232
233#include "SkTypefaceCache.h"
234
joshualitt65e96b42015-07-31 11:45:22 -0700235SkRandomTypeface::SkRandomTypeface(SkTypeface* proxy, const SkPaint& paint, bool fakeIt)
joshualittaa2f6582015-07-29 10:14:58 -0700236 : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false)
237 , fProxy(SkRef(proxy))
joshualitt65e96b42015-07-31 11:45:22 -0700238 , fPaint(paint)
239 , fFakeIt(fakeIt) {}
joshualittaa2f6582015-07-29 10:14:58 -0700240
241SkRandomTypeface::~SkRandomTypeface() {
242 fProxy->unref();
243}
244
245SkScalerContext* SkRandomTypeface::onCreateScalerContext(
246 const SkDescriptor* desc) const {
joshualitt65e96b42015-07-31 11:45:22 -0700247 return SkNEW_ARGS(SkRandomScalerContext, (const_cast<SkRandomTypeface*>(this), desc, fFakeIt));
joshualittaa2f6582015-07-29 10:14:58 -0700248}
249
250void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const {
251 fProxy->filterRec(rec);
252 rec->setHinting(SkPaint::kNo_Hinting);
253 rec->fMaskFormat = SkMask::kARGB32_Format;
254}
255
256SkAdvancedTypefaceMetrics* SkRandomTypeface::onGetAdvancedTypefaceMetrics(
257 PerGlyphInfo info,
258 const uint32_t* glyphIDs,
259 uint32_t glyphIDsCount) const {
260 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
261}
262
263SkStreamAsset* SkRandomTypeface::onOpenStream(int* ttcIndex) const {
264 return fProxy->openStream(ttcIndex);
265}
266
267void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
268 bool* isLocal) const {
269 fProxy->getFontDescriptor(desc, isLocal);
270}
271
272int SkRandomTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
273 uint16_t glyphs[], int glyphCount) const {
274 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
275}
276
277int SkRandomTypeface::onCountGlyphs() const {
278 return fProxy->countGlyphs();
279}
280
281int SkRandomTypeface::onGetUPEM() const {
282 return fProxy->getUnitsPerEm();
283}
284
285void SkRandomTypeface::onGetFamilyName(SkString* familyName) const {
286 fProxy->getFamilyName(familyName);
287}
288
289SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() const {
290 return fProxy->createFamilyNameIterator();
291}
292
293int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const {
294 return fProxy->getTableTags(tags);
295}
296
297size_t SkRandomTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
298 size_t length, void* data) const {
299 return fProxy->getTableData(tag, offset, length, data);
300}
301