Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: src/core/SkDevice.cpp

Issue 925343003: use common impl for drawTextOnPath (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkBitmapDevice.cpp ('k') | src/core/SkDraw.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « src/core/SkBitmapDevice.cpp ('k') | src/core/SkDraw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698