1 /*
2 * Copyright 2018 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 "src/core/SkDraw.h"
9 #include "src/core/SkFontPriv.h"
10 #include "src/core/SkPaintPriv.h"
11 #include "src/core/SkRasterClip.h"
12 #include "src/core/SkScalerContext.h"
13 #include "src/core/SkStrike.h"
14 #include "src/core/SkUtils.h"
15
16 // disable warning : local variable used without having been initialized
17 #if defined _WIN32
18 #pragma warning ( push )
19 #pragma warning ( disable : 4701 )
20 #endif
21
22 ////////////////////////////////////////////////////////////////////////////////////////////////////
23
paintMasks(SkSpan<const SkMask> masks,const SkPaint & paint) const24 void SkDraw::paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const {
25
26 // The size used for a typical blitter.
27 SkSTArenaAlloc<3308> alloc;
28 SkBlitter* blitter = SkBlitter::Choose(fDst, *fMatrix, paint, &alloc, false);
29 if (fCoverage) {
30 blitter = alloc.make<SkPairBlitter>(
31 blitter,
32 SkBlitter::Choose(*fCoverage, *fMatrix, SkPaint(), &alloc, true));
33 }
34
35 SkAAClipBlitterWrapper wrapper{*fRC, blitter};
36 blitter = wrapper.getBlitter();
37
38 bool useRegion = fRC->isBW() && !fRC->isRect();
39
40 if (useRegion) {
41 for (const SkMask& mask : masks) {
42 SkRegion::Cliperator clipper(fRC->bwRgn(), mask.fBounds);
43
44 if (!clipper.done()) {
45 if (SkMask::kARGB32_Format == mask.fFormat) {
46 SkBitmap bm;
47 bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.size()),
48 mask.fImage,
49 mask.fRowBytes);
50 this->drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), paint);
51 } else {
52 const SkIRect& cr = clipper.rect();
53 do {
54 blitter->blitMask(mask, cr);
55 clipper.next();
56 } while (!clipper.done());
57 }
58 }
59 }
60 } else {
61 SkIRect clipBounds = fRC->isBW() ? fRC->bwRgn().getBounds()
62 : fRC->aaRgn().getBounds();
63 for (const SkMask& mask : masks) {
64 SkIRect storage;
65 const SkIRect* bounds = &mask.fBounds;
66
67 // this extra test is worth it, assuming that most of the time it succeeds
68 // since we can avoid writing to storage
69 if (!clipBounds.containsNoEmptyCheck(mask.fBounds)) {
70 if (!storage.intersectNoEmptyCheck(mask.fBounds, clipBounds)) {
71 continue;
72 }
73 bounds = &storage;
74 }
75
76 if (SkMask::kARGB32_Format == mask.fFormat) {
77 SkBitmap bm;
78 bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.size()),
79 mask.fImage,
80 mask.fRowBytes);
81 this->drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), paint);
82 } else {
83 blitter->blitMask(mask, *bounds);
84 }
85 }
86 }
87 }
88
paintPaths(SkSpan<const SkPathPos> pathsAndPositions,SkScalar scale,const SkPaint & paint) const89 void SkDraw::paintPaths(SkSpan<const SkPathPos> pathsAndPositions,
90 SkScalar scale,
91 const SkPaint& paint) const {
92 for (const auto& pathAndPos : pathsAndPositions) {
93 SkMatrix m;
94 SkPoint position = pathAndPos.position;
95 m.setScaleTranslate(scale, scale, position.x(), position.y());
96 this->drawPath(*pathAndPos.path, paint, &m, false);
97 }
98 }
99
drawGlyphRunList(const SkGlyphRunList & glyphRunList,SkGlyphRunListPainter * glyphPainter) const100 void SkDraw::drawGlyphRunList(const SkGlyphRunList& glyphRunList,
101 SkGlyphRunListPainter* glyphPainter) const {
102
103 SkDEBUGCODE(this->validate();)
104
105 if (fRC->isEmpty()) {
106 return;
107 }
108
109 glyphPainter->drawForBitmapDevice(glyphRunList, *fMatrix, this);
110 }
111
112 #if defined _WIN32
113 #pragma warning ( pop )
114 #endif
115
116