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

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