blob: ad37b9a98ffeba5516eaebc8176c2ee0f4a14f6c [file] [log] [blame]
Matt Sarett22886c42016-11-22 11:31:41 -05001/*
2 * Copyright 2016 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 "SkColorFilter.h"
Matt Sarettbe3bdd92016-12-12 18:35:43 -05009#include "SkDrawable.h"
Matt Sarett22886c42016-11-22 11:31:41 -050010#include "SkFindAndPlaceGlyph.h"
Herb Derby2e83b132017-02-10 11:47:58 -050011#include "SkImagePriv.h"
Matt Sarett84503cc2016-11-23 13:13:42 -050012#include "SkLatticeIter.h"
Matt Sarett22886c42016-11-22 11:31:41 -050013#include "SkOverdrawCanvas.h"
14#include "SkPatchUtils.h"
15#include "SkPath.h"
16#include "SkRRect.h"
17#include "SkRSXform.h"
18#include "SkTextBlob.h"
19#include "SkTextBlobRunIterator.h"
20
21namespace {
22class ProcessOneGlyphBounds {
23public:
24 ProcessOneGlyphBounds(SkOverdrawCanvas* canvas)
25 : fCanvas(canvas)
26 {}
27
28 void operator()(const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
29 int left = SkScalarFloorToInt(position.fX) + glyph.fLeft;
30 int top = SkScalarFloorToInt(position.fY) + glyph.fTop;
31 int right = left + glyph.fWidth;
32 int bottom = top + glyph.fHeight;
33 fCanvas->onDrawRect(SkRect::MakeLTRB(left, top, right, bottom), SkPaint());
34 }
35
36private:
37 SkOverdrawCanvas* fCanvas;
38};
39};
40
41SkOverdrawCanvas::SkOverdrawCanvas(SkCanvas* canvas)
42 : INHERITED(canvas->onImageInfo().width(), canvas->onImageInfo().height())
Matt Sarett22886c42016-11-22 11:31:41 -050043{
Matt Sarett84503cc2016-11-23 13:13:42 -050044 // Non-drawing calls that SkOverdrawCanvas does not override (translate, save, etc.)
45 // will pass through to the input canvas.
46 this->addCanvas(canvas);
47
Matt Sarett22886c42016-11-22 11:31:41 -050048 static constexpr float kIncrementAlpha[] = {
49 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
50 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
51 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
52 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
53 };
54
55 fPaint.setAntiAlias(false);
56 fPaint.setBlendMode(SkBlendMode::kPlus);
57 fPaint.setColorFilter(SkColorFilter::MakeMatrixFilterRowMajor255(kIncrementAlpha));
58}
59
Matt Sarett22886c42016-11-22 11:31:41 -050060void SkOverdrawCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
61 const SkPaint& paint) {
62 ProcessOneGlyphBounds processBounds(this);
63 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
64 this->getProps(&props);
65 SkAutoGlyphCache cache(paint, &props, 0, &this->getTotalMatrix());
66 SkFindAndPlaceGlyph::ProcessText(paint.getTextEncoding(), (const char*) text, byteLength,
67 SkPoint::Make(x, y), SkMatrix(), paint.getTextAlign(),
68 cache.get(), processBounds);
69}
70
71void SkOverdrawCanvas::drawPosTextCommon(const void* text, size_t byteLength, const SkScalar pos[],
72 int scalarsPerPos, const SkPoint& offset,
73 const SkPaint& paint) {
74 ProcessOneGlyphBounds processBounds(this);
75 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
76 this->getProps(&props);
77 SkAutoGlyphCache cache(paint, &props, 0, &this->getTotalMatrix());
78 SkFindAndPlaceGlyph::ProcessPosText(paint.getTextEncoding(), (const char*) text, byteLength,
79 SkPoint::Make(0, 0), SkMatrix(), (const SkScalar*) pos, 2,
80 paint.getTextAlign(), cache.get(), processBounds);
81}
82
83void SkOverdrawCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
84 const SkPaint& paint) {
85 this->drawPosTextCommon(text, byteLength, (SkScalar*) pos, 2, SkPoint::Make(0, 0), paint);
86}
87
88void SkOverdrawCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xs[],
89 SkScalar y, const SkPaint& paint) {
90 this->drawPosTextCommon(text, byteLength, (SkScalar*) xs, 1, SkPoint::Make(0, y), paint);
91}
92
93void SkOverdrawCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
94 const SkMatrix* matrix, const SkPaint& paint) {
95 SkASSERT(false);
96 return;
97}
98
99typedef int (*CountTextProc)(const char* text);
100static int count_utf16(const char* text) {
101 const uint16_t* prev = (uint16_t*)text;
102 (void)SkUTF16_NextUnichar(&prev);
103 return SkToInt((const char*)prev - text);
104}
105static int return_4(const char* text) { return 4; }
106static int return_2(const char* text) { return 2; }
107
108void SkOverdrawCanvas::onDrawTextRSXform(const void* text, size_t byteLength,
109 const SkRSXform xform[], const SkRect*,
110 const SkPaint& paint) {
111 CountTextProc proc = nullptr;
112 switch (paint.getTextEncoding()) {
113 case SkPaint::kUTF8_TextEncoding:
114 proc = SkUTF8_CountUTF8Bytes;
115 break;
116 case SkPaint::kUTF16_TextEncoding:
117 proc = count_utf16;
118 break;
119 case SkPaint::kUTF32_TextEncoding:
120 proc = return_4;
121 break;
122 case SkPaint::kGlyphID_TextEncoding:
123 proc = return_2;
124 break;
125 }
126 SkASSERT(proc);
127
128 SkMatrix matrix;
129 const void* stopText = (const char*)text + byteLength;
130 while ((const char*)text < (const char*)stopText) {
131 matrix.setRSXform(*xform++);
132 matrix.setConcat(this->getTotalMatrix(), matrix);
133 int subLen = proc((const char*)text);
134
135 this->save();
136 this->concat(matrix);
137 this->drawText(text, subLen, 0, 0, paint);
138 this->restore();
139
140 text = (const char*)text + subLen;
141 }
142}
143
144void SkOverdrawCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
145 const SkPaint& paint) {
146 SkPaint runPaint = paint;
147 SkTextBlobRunIterator it(blob);
148 for (;!it.done(); it.next()) {
149 size_t textLen = it.glyphCount() * sizeof(uint16_t);
150 const SkPoint& offset = it.offset();
151 it.applyFontToPaint(&runPaint);
152 switch (it.positioning()) {
153 case SkTextBlob::kDefault_Positioning:
154 this->onDrawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
155 break;
156 case SkTextBlob::kHorizontal_Positioning:
157 this->drawPosTextCommon(it.glyphs(), textLen, it.pos(), 1,
158 SkPoint::Make(x, y + offset.y()), runPaint);
159 break;
160 case SkTextBlob::kFull_Positioning:
161 this->drawPosTextCommon(it.glyphs(), textLen, it.pos(), 2, SkPoint::Make(x, y),
162 runPaint);
163 break;
164 default:
165 SkASSERT(false);
166 break;
167 }
168 }
169}
170
171void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
172 const SkPoint texCoords[4], SkBlendMode blendMode,
173 const SkPaint&) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500174 fList[0]->onDrawPatch(cubics, colors, texCoords, blendMode, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500175}
176
Matt Sarett84503cc2016-11-23 13:13:42 -0500177void SkOverdrawCanvas::onDrawPaint(const SkPaint& paint) {
178 if (0 == paint.getColor() && !paint.getColorFilter() && !paint.getShader()) {
179 // This is a clear, ignore it.
180 } else {
Matt Sarett25d6c832016-11-28 18:41:01 -0500181 fList[0]->onDrawPaint(this->overdrawPaint(paint));
Matt Sarett84503cc2016-11-23 13:13:42 -0500182 }
Matt Sarett22886c42016-11-22 11:31:41 -0500183}
184
Matt Sarett84503cc2016-11-23 13:13:42 -0500185void SkOverdrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500186 fList[0]->onDrawRect(rect, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500187}
188
189void SkOverdrawCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500190 fList[0]->onDrawRegion(region, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500191}
192
Matt Sarett84503cc2016-11-23 13:13:42 -0500193void SkOverdrawCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500194 fList[0]->onDrawOval(oval, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500195}
196
197void SkOverdrawCanvas::onDrawArc(const SkRect& arc, SkScalar startAngle, SkScalar sweepAngle,
Matt Sarett84503cc2016-11-23 13:13:42 -0500198 bool useCenter, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500199 fList[0]->onDrawArc(arc, startAngle, sweepAngle, useCenter, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500200}
201
Matt Sarett84503cc2016-11-23 13:13:42 -0500202void SkOverdrawCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
203 const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500204 fList[0]->onDrawDRRect(outer, inner, this->overdrawPaint(paint));
Matt Sarett84503cc2016-11-23 13:13:42 -0500205}
206
207void SkOverdrawCanvas::onDrawRRect(const SkRRect& rect, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500208 fList[0]->onDrawRRect(rect, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500209}
210
211void SkOverdrawCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint points[],
Matt Sarett84503cc2016-11-23 13:13:42 -0500212 const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500213 fList[0]->onDrawPoints(mode, count, points, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500214}
215
Mike Reedfed9cfd2017-03-17 12:09:04 -0400216void SkOverdrawCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode blendMode,
217 const SkPaint& paint) {
218 fList[0]->onDrawVerticesObject(vertices, blendMode, this->overdrawPaint(paint));
Matt Sarett22886c42016-11-22 11:31:41 -0500219}
220
221void SkOverdrawCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[],
222 const SkRect texs[], const SkColor colors[], int count,
Matt Sarett84503cc2016-11-23 13:13:42 -0500223 SkBlendMode mode, const SkRect* cull, const SkPaint* paint) {
224 SkPaint* paintPtr = &fPaint;
225 SkPaint storage;
226 if (paint) {
227 storage = this->overdrawPaint(*paint);
228 paintPtr = &storage;
229 }
230
Matt Sarett25d6c832016-11-28 18:41:01 -0500231 fList[0]->onDrawAtlas(image, xform, texs, colors, count, mode, cull, paintPtr);
Matt Sarett22886c42016-11-22 11:31:41 -0500232}
233
Matt Sarett84503cc2016-11-23 13:13:42 -0500234void SkOverdrawCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500235 fList[0]->onDrawPath(path, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500236}
237
238void SkOverdrawCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint*) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500239 fList[0]->onDrawRect(SkRect::MakeXYWH(x, y, image->width(), image->height()), fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500240}
241
242void SkOverdrawCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
243 const SkPaint*, SrcRectConstraint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500244 fList[0]->onDrawRect(dst, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500245}
246
247void SkOverdrawCanvas::onDrawImageNine(const SkImage*, const SkIRect&, const SkRect& dst,
248 const SkPaint*) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500249 fList[0]->onDrawRect(dst, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500250}
251
Matt Sarett84503cc2016-11-23 13:13:42 -0500252void SkOverdrawCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
253 const SkRect& dst, const SkPaint*) {
254 SkIRect bounds;
255 Lattice latticePlusBounds = lattice;
256 if (!latticePlusBounds.fBounds) {
257 bounds = SkIRect::MakeWH(image->width(), image->height());
258 latticePlusBounds.fBounds = &bounds;
259 }
260
261 if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
262 SkLatticeIter iter(latticePlusBounds, dst);
263
264 SkRect dummy, iterDst;
265 while (iter.next(&dummy, &iterDst)) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500266 fList[0]->onDrawRect(iterDst, fPaint);
Matt Sarett84503cc2016-11-23 13:13:42 -0500267 }
268 } else {
Matt Sarett25d6c832016-11-28 18:41:01 -0500269 fList[0]->onDrawRect(dst, fPaint);
Matt Sarett84503cc2016-11-23 13:13:42 -0500270 }
Matt Sarett22886c42016-11-22 11:31:41 -0500271}
272
273void SkOverdrawCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
274 const SkPaint*) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500275 fList[0]->onDrawRect(SkRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()), fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500276}
277
278void SkOverdrawCanvas::onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect& dst,
279 const SkPaint*, SrcRectConstraint) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500280 fList[0]->onDrawRect(dst, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500281}
282
283void SkOverdrawCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect& dst,
284 const SkPaint*) {
Matt Sarett25d6c832016-11-28 18:41:01 -0500285 fList[0]->onDrawRect(dst, fPaint);
Matt Sarett22886c42016-11-22 11:31:41 -0500286}
287
Matt Sarett84503cc2016-11-23 13:13:42 -0500288void SkOverdrawCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
289 const SkRect& dst, const SkPaint* paint) {
290 sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
291 this->onDrawImageLattice(image.get(), lattice, dst, paint);
Matt Sarett22886c42016-11-22 11:31:41 -0500292}
293
Matt Sarettbe3bdd92016-12-12 18:35:43 -0500294void SkOverdrawCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
295 drawable->draw(this, matrix);
296}
297
Matt Sarett22886c42016-11-22 11:31:41 -0500298void SkOverdrawCanvas::onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) {
299 SkASSERT(false);
300 return;
301}
Matt Sarett84503cc2016-11-23 13:13:42 -0500302
303inline SkPaint SkOverdrawCanvas::overdrawPaint(const SkPaint& paint) {
304 SkPaint newPaint = fPaint;
305 newPaint.setStyle(paint.getStyle());
306 newPaint.setStrokeWidth(paint.getStrokeWidth());
307 return newPaint;
308}