joshualitt | ecd1a69 | 2015-08-10 10:08:26 -0700 | [diff] [blame] | 1 | /* |
| 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 | |
joshualitt | 14205b1 | 2015-08-10 11:40:56 -0700 | [diff] [blame] | 10 | #include "GrAAStrokeRectBatch.h" |
joshualitt | 7fc2a26 | 2015-08-10 10:30:14 -0700 | [diff] [blame] | 11 | #include "GrStrokeRectBatch.h" |
joshualitt | ecd1a69 | 2015-08-10 10:08:26 -0700 | [diff] [blame] | 12 | |
joshualitt | 14205b1 | 2015-08-10 11:40:56 -0700 | [diff] [blame] | 13 | #include "SkStrokeRec.h" |
| 14 | |
| 15 | static 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 | |
joshualitt | ecd1a69 | 2015-08-10 10:08:26 -0700 | [diff] [blame] | 31 | namespace GrRectBatchFactory { |
| 32 | |
joshualitt | ecd1a69 | 2015-08-10 10:08:26 -0700 | [diff] [blame] | 33 | |
joshualitt | 7fc2a26 | 2015-08-10 10:30:14 -0700 | [diff] [blame] | 34 | GrBatch* 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 | |
joshualitt | 14205b1 | 2015-08-10 11:40:56 -0700 | [diff] [blame] | 47 | GrBatch* 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 | |
| 106 | GrBatch* 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 | |
joshualitt | ecd1a69 | 2015-08-10 10:08:26 -0700 | [diff] [blame] | 123 | }; |