Chromium Code Reviews| 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 |