OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkDevice.h" | 8 #include "SkDevice.h" |
9 #include "SkDeviceProperties.h" | 9 #include "SkDeviceProperties.h" |
10 #include "SkDraw.h" | 10 #include "SkDraw.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 } | 205 } |
206 | 206 |
207 bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const S kMatrix*, | 207 bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const S kMatrix*, |
208 const SkPaint*) { | 208 const SkPaint*) { |
209 // The base class doesn't perform any accelerated picture rendering | 209 // The base class doesn't perform any accelerated picture rendering |
210 return false; | 210 return false; |
211 } | 211 } |
212 | 212 |
213 //////////////////////////////////////////////////////////////////////////////// ////////// | 213 //////////////////////////////////////////////////////////////////////////////// ////////// |
214 | 214 |
215 #include "SkDraw.h" | |
216 #include "SkPathMeasure.h" | |
217 #include "SkRasterClip.h" | |
218 #include "SkTextToPathIter.h" | |
hal.canary
2015/02/17 15:57:21
you can move these to the top of the file.
reed2
2015/02/17 18:26:55
Done.
| |
219 | |
220 static void morphpoints(SkPoint dst[], const SkPoint src[], int count, | |
221 SkPathMeasure& meas, const SkMatrix& matrix) { | |
222 SkMatrix::MapXYProc proc = matrix.getMapXYProc(); | |
223 | |
224 for (int i = 0; i < count; i++) { | |
225 SkPoint pos; | |
226 SkVector tangent; | |
227 | |
228 proc(matrix, src[i].fX, src[i].fY, &pos); | |
229 SkScalar sx = pos.fX; | |
230 SkScalar sy = pos.fY; | |
231 | |
232 if (!meas.getPosTan(sx, &pos, &tangent)) { | |
233 // set to 0 if the measure failed, so that we just set dst == pos | |
234 tangent.set(0, 0); | |
235 } | |
236 | |
237 /* This is the old way (that explains our approach but is way too slow | |
238 SkMatrix matrix; | |
239 SkPoint pt; | |
240 | |
241 pt.set(sx, sy); | |
242 matrix.setSinCos(tangent.fY, tangent.fX); | |
243 matrix.preTranslate(-sx, 0); | |
244 matrix.postTranslate(pos.fX, pos.fY); | |
245 matrix.mapPoints(&dst[i], &pt, 1); | |
246 */ | |
247 dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy), | |
248 pos.fY + SkScalarMul(tangent.fX, sy)); | |
249 } | |
250 } | |
251 | |
252 /* TODO | |
253 | |
254 Need differentially more subdivisions when the follow-path is curvy. Not sure h ow to | |
255 determine that, but we need it. I guess a cheap answer is let the caller tell u s, | |
256 but that seems like a cop-out. Another answer is to get Rob Johnson to figure i t out. | |
257 */ | |
258 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, | |
259 const SkMatrix& matrix) { | |
260 SkPath::Iter iter(src, false); | |
261 SkPoint srcP[4], dstP[3]; | |
262 SkPath::Verb verb; | |
263 | |
264 while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { | |
265 switch (verb) { | |
266 case SkPath::kMove_Verb: | |
267 morphpoints(dstP, srcP, 1, meas, matrix); | |
268 dst->moveTo(dstP[0]); | |
269 break; | |
270 case SkPath::kLine_Verb: | |
271 // turn lines into quads to look bendy | |
272 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX); | |
273 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY); | |
274 morphpoints(dstP, srcP, 2, meas, matrix); | |
275 dst->quadTo(dstP[0], dstP[1]); | |
276 break; | |
277 case SkPath::kQuad_Verb: | |
278 morphpoints(dstP, &srcP[1], 2, meas, matrix); | |
279 dst->quadTo(dstP[0], dstP[1]); | |
280 break; | |
281 case SkPath::kCubic_Verb: | |
282 morphpoints(dstP, &srcP[1], 3, meas, matrix); | |
283 dst->cubicTo(dstP[0], dstP[1], dstP[2]); | |
284 break; | |
285 case SkPath::kClose_Verb: | |
286 dst->close(); | |
287 break; | |
288 default: | |
289 SkDEBUGFAIL("unknown verb"); | |
290 break; | |
291 } | |
292 } | |
293 } | |
294 | |
295 void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b yteLength, | |
296 const SkPath& follow, const SkMatrix* matrix, | |
297 const SkPaint& paint) { | |
298 SkASSERT(byteLength == 0 || text != NULL); | |
299 | |
300 // nothing to draw | |
301 if (text == NULL || byteLength == 0 || draw.fRC->isEmpty()) { | |
302 return; | |
303 } | |
304 | |
305 SkTextToPathIter iter((const char*)text, byteLength, paint, true); | |
306 SkPathMeasure meas(follow, false); | |
307 SkScalar hOffset = 0; | |
308 | |
309 // need to measure first | |
310 if (paint.getTextAlign() != SkPaint::kLeft_Align) { | |
311 SkScalar pathLen = meas.getLength(); | |
312 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
313 pathLen = SkScalarHalf(pathLen); | |
314 } | |
315 hOffset += pathLen; | |
316 } | |
317 | |
318 const SkPath* iterPath; | |
319 SkScalar xpos; | |
320 SkMatrix scaledMatrix; | |
321 SkScalar scale = iter.getPathScale(); | |
322 | |
323 scaledMatrix.setScale(scale, scale); | |
324 | |
325 while (iter.next(&iterPath, &xpos)) { | |
326 if (iterPath) { | |
327 SkPath tmp; | |
328 SkMatrix m(scaledMatrix); | |
329 | |
330 tmp.setIsVolatile(true); | |
331 m.postTranslate(xpos + hOffset, 0); | |
332 if (matrix) { | |
333 m.postConcat(*matrix); | |
334 } | |
335 morphpath(&tmp, *iterPath, meas, m); | |
336 this->drawPath(draw, tmp, iter.getPaint(), NULL, true); | |
337 } | |
338 } | |
339 } | |
340 | |
341 //////////////////////////////////////////////////////////////////////////////// ////////// | |
342 | |
215 uint32_t SkBaseDevice::filterTextFlags(const SkPaint& paint) const { | 343 uint32_t SkBaseDevice::filterTextFlags(const SkPaint& paint) const { |
216 uint32_t flags = paint.getFlags(); | 344 uint32_t flags = paint.getFlags(); |
217 | 345 |
218 if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { | 346 if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { |
219 return flags; | 347 return flags; |
220 } | 348 } |
221 | 349 |
222 if (kUnknown_SkPixelGeometry == fLeakyProperties->pixelGeometry() | 350 if (kUnknown_SkPixelGeometry == fLeakyProperties->pixelGeometry() |
223 || this->onShouldDisableLCD(paint)) { | 351 || this->onShouldDisableLCD(paint)) { |
224 | 352 |
225 flags &= ~SkPaint::kLCDRenderText_Flag; | 353 flags &= ~SkPaint::kLCDRenderText_Flag; |
226 flags |= SkPaint::kGenA8FromLCD_Flag; | 354 flags |= SkPaint::kGenA8FromLCD_Flag; |
227 } | 355 } |
228 | 356 |
229 return flags; | 357 return flags; |
230 } | 358 } |
231 | 359 |
OLD | NEW |