blob: e874acbb4919e64affdf04e6e67112e34cc899de [file] [log] [blame]
joshualittecd1a692015-08-10 10:08:26 -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 "GrRectBatchFactory.h"
9
joshualitt14205b12015-08-10 11:40:56 -070010#include "GrAAStrokeRectBatch.h"
joshualitt7fc2a262015-08-10 10:30:14 -070011#include "GrStrokeRectBatch.h"
joshualittecd1a692015-08-10 10:08:26 -070012
joshualitt14205b12015-08-10 11:40:56 -070013#include "SkStrokeRec.h"
14
15static GrBatch* create_stroke_aa_batch(GrColor color,
16 const SkMatrix& viewMatrix,
17 const SkRect& devOutside,
18 const SkRect& devOutsideAssist,
19 const SkRect& devInside,
20 bool miterStroke) {
21 GrAAStrokeRectBatch::Geometry geometry;
22 geometry.fColor = color;
23 geometry.fDevOutside = devOutside;
24 geometry.fDevOutsideAssist = devOutsideAssist;
25 geometry.fDevInside = devInside;
26 geometry.fMiterStroke = miterStroke;
27
28 return GrAAStrokeRectBatch::Create(geometry, viewMatrix);
29}
30
joshualittecd1a692015-08-10 10:08:26 -070031namespace GrRectBatchFactory {
32
joshualittecd1a692015-08-10 10:08:26 -070033
joshualitt7fc2a262015-08-10 10:30:14 -070034GrBatch* CreateStrokeBW(GrColor color,
35 const SkMatrix& viewMatrix,
36 const SkRect& rect,
37 SkScalar strokeWidth,
38 bool snapToPixelCenters) {
39 GrStrokeRectBatch::Geometry geometry;
40 geometry.fColor = color;
41 geometry.fViewMatrix = viewMatrix;
42 geometry.fRect = rect;
43 geometry.fStrokeWidth = strokeWidth;
44 return GrStrokeRectBatch::Create(geometry, snapToPixelCenters);
45}
46
joshualitt14205b12015-08-10 11:40:56 -070047GrBatch* CreateStrokeAA(GrColor color,
48 const SkMatrix& viewMatrix,
49 const SkRect& rect,
50 const SkRect& devRect,
51 const SkStrokeRec& stroke) {
52 SkVector devStrokeSize;
53 SkScalar width = stroke.getWidth();
54 if (width > 0) {
55 devStrokeSize.set(width, width);
56 viewMatrix.mapVectors(&devStrokeSize, 1);
57 devStrokeSize.setAbs(devStrokeSize);
58 } else {
59 devStrokeSize.set(SK_Scalar1, SK_Scalar1);
60 }
61
62 const SkScalar dx = devStrokeSize.fX;
63 const SkScalar dy = devStrokeSize.fY;
64 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
65 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);
66
67 SkScalar spare;
68 {
69 SkScalar w = devRect.width() - dx;
70 SkScalar h = devRect.height() - dy;
71 spare = SkTMin(w, h);
72 }
73
74 SkRect devOutside(devRect);
75 devOutside.outset(rx, ry);
76
77 bool miterStroke = true;
78 // For hairlines, make bevel and round joins appear the same as mitered ones.
79 // small miter limit means right angles show bevel...
80 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join ||
81 stroke.getMiter() < SK_ScalarSqrt2)) {
82 miterStroke = false;
83 }
84
85 if (spare <= 0 && miterStroke) {
86 return CreateFillAA(color, viewMatrix, devOutside, devOutside);
87 }
88
89 SkRect devInside(devRect);
90 devInside.inset(rx, ry);
91
92 SkRect devOutsideAssist(devRect);
93
94 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist)
95 // to draw the outer of the rect. Because there are 8 vertices on the outer
96 // edge, while vertex number of inner edge is 4, the same as miter-stroke.
97 if (!miterStroke) {
98 devOutside.inset(0, ry);
99 devOutsideAssist.outset(0, ry);
100 }
101
102 return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutsideAssist, devInside,
103 miterStroke);
104}
105
106GrBatch* CreateFillNestedRectsAA(GrColor color,
107 const SkMatrix& viewMatrix,
108 const SkRect rects[2]) {
109 SkASSERT(viewMatrix.rectStaysRect());
110 SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty());
111
112 SkRect devOutside, devInside;
113 viewMatrix.mapRect(&devOutside, rects[0]);
114 viewMatrix.mapRect(&devInside, rects[1]);
115
116 if (devInside.isEmpty()) {
117 return CreateFillAA(color, viewMatrix, devOutside, devOutside);
118 }
119
120 return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutside, devInside, true);
121}
122
joshualittecd1a692015-08-10 10:08:26 -0700123};