OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2014 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 "SkPictureShader.h" | |
9 | |
10 #include "SkBitmap.h" | |
11 #include "SkBitmapProcShader.h" | |
12 #include "SkCanvas.h" | |
13 #include "SkPicture.h" | |
14 #include "SkReadBuffer.h" | |
15 | |
16 #if SK_SUPPORT_GPU | |
17 #include "GrContext.h" | |
18 #endif | |
19 | |
20 SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy) | |
21 : fPicture(picture) | |
22 , fTmx(tmx) | |
23 , fTmy(tmy) { | |
24 SkSafeRef(fPicture); | |
25 } | |
26 | |
27 SkPictureShader::SkPictureShader(SkReadBuffer& buffer) | |
28 : INHERITED(buffer) { | |
29 fTmx = static_cast<SkShader::TileMode>(buffer.read32()); | |
30 fTmy = static_cast<SkShader::TileMode>(buffer.read32()); | |
31 if (buffer.readBool()) { | |
32 fPicture = SkPicture::CreateFromBuffer(buffer); | |
33 } else { | |
34 fPicture = NULL; | |
35 } | |
36 } | |
37 | |
38 SkPictureShader::~SkPictureShader() { | |
39 SkSafeUnref(fPicture); | |
40 } | |
41 | |
42 void SkPictureShader::flatten(SkWriteBuffer& buffer) const { | |
43 this->INHERITED::flatten(buffer); | |
44 | |
45 buffer.write32(fTmx); | |
46 buffer.write32(fTmy); | |
47 buffer.writeBool(fPicture != NULL); | |
robertphillips
2014/04/02 18:15:35
NULL != ?
f(malita)
2014/04/07 15:06:24
Done.
| |
48 if (fPicture) { | |
49 fPicture->flatten(buffer); | |
50 } | |
51 } | |
52 | |
53 bool SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const { | |
54 if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) { | |
55 return false; | |
56 } | |
57 | |
58 SkMatrix m; | |
robertphillips
2014/04/02 18:15:35
this->
| |
59 if (hasLocalMatrix()) { | |
robertphillips
2014/04/02 18:15:35
this->
| |
60 m.setConcat(matrix, getLocalMatrix()); | |
61 } else { | |
62 m = matrix; | |
63 } | |
64 | |
65 // Rotation-invariant scale | |
66 float xScale = sqrtf(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSke wX()); | |
67 float yScale = sqrtf(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSke wY()); | |
reed1
2014/04/07 14:03:15
SkScalarSqrt
f(malita)
2014/04/07 15:06:24
Done.
| |
68 SkSize mappedSize = SkSize::Make(xScale * fPicture->width(), yScale * fPictu re->height()); | |
69 | |
70 SkISize tileSize = mappedSize.toRound(); | |
71 if (tileSize.isEmpty()) { | |
72 return false; | |
73 } | |
74 | |
75 // The actual scale, compensating for rounding. | |
76 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture-> width(), | |
77 SkIntToScalar(tileSize.height()) / fPicture- >height()); | |
78 | |
79 if (!fCachedShader || tileScale != fCachedTileScale) { | |
80 SkBitmap bm; | |
81 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) { | |
82 return false; | |
83 } | |
84 bm.eraseColor(SK_ColorTRANSPARENT); | |
85 | |
86 SkCanvas canvas(bm); | |
87 canvas.scale(tileScale.width(), tileScale.height()); | |
88 canvas.drawPicture(*fPicture); | |
89 | |
90 fCachedShader.reset(CreateBitmapShader(bm, fTmx, fTmy)); | |
91 fCachedTileScale = tileScale; | |
92 } | |
93 | |
94 SkMatrix shaderMatrix = getLocalMatrix(); | |
95 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height()); | |
96 fCachedShader->setLocalMatrix(shaderMatrix); | |
97 | |
98 return true; | |
99 } | |
100 | |
101 bool SkPictureShader::setContext(const SkBitmap& device, | |
102 const SkPaint& paint, | |
103 const SkMatrix& matrix) { | |
robertphillips
2014/04/02 18:15:35
this->
| |
104 if (!buildBitmapShader(matrix)) { | |
105 return false; | |
106 } | |
107 | |
108 if (!this->INHERITED::setContext(device, paint, matrix)) { | |
109 return false; | |
110 } | |
111 | |
112 SkASSERT(fCachedShader); | |
113 if (!fCachedShader->setContext(device, paint, matrix)) { | |
114 this->INHERITED::endContext(); | |
115 return false; | |
116 } | |
117 | |
118 return true; | |
119 } | |
120 | |
121 void SkPictureShader::endContext() { | |
122 SkASSERT(fCachedShader); | |
123 fCachedShader->endContext(); | |
124 | |
125 this->INHERITED::endContext(); | |
126 } | |
127 | |
128 uint32_t SkPictureShader::getFlags() { | |
robertphillips
2014/04/02 18:15:35
NULL !=
f(malita)
2014/04/07 15:06:24
Done.
| |
129 if (fCachedShader) { | |
130 return fCachedShader->getFlags(); | |
131 } | |
132 return 0; | |
133 } | |
134 | |
135 SkShader::ShadeProc SkPictureShader::asAShadeProc(void** ctx) { | |
136 if (fCachedShader) { | |
137 return fCachedShader->asAShadeProc(ctx); | |
138 } | |
139 return NULL; | |
140 } | |
141 | |
142 void SkPictureShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | |
143 SkASSERT(fCachedShader); | |
144 fCachedShader->shadeSpan(x, y, dstC, count); | |
145 } | |
146 | |
147 void SkPictureShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { | |
148 SkASSERT(fCachedShader); | |
149 fCachedShader->shadeSpan16(x, y, dstC, count); | |
150 } | |
151 | |
152 #ifndef SK_IGNORE_TO_STRING | |
153 void SkPictureShader::toString(SkString* str) const { | |
154 static const char* gTileModeName[SkShader::kTileModeCount] = { | |
155 "clamp", "repeat", "mirror" | |
156 }; | |
157 | |
158 str->appendf("PictureShader: [%d:%d] ", | |
159 fPicture ? fPicture->width() : 0, | |
160 fPicture ? fPicture->height() : 0); | |
161 | |
162 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]); | |
163 | |
164 this->INHERITED::toString(str); | |
165 } | |
166 #endif | |
167 | |
168 #if SK_SUPPORT_GPU | |
169 GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& pai nt) const { | |
robertphillips
2014/04/02 18:15:35
this->
| |
170 if (!buildBitmapShader(context->getMatrix())) { | |
171 return NULL; | |
172 } | |
173 SkASSERT(fCachedShader); | |
174 return fCachedShader->asNewEffect(context, paint); | |
175 } | |
176 #endif | |
OLD | NEW |