| 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 "SkColorFilter.h" | 8 #include "SkColorFilter.h" |
| 9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkDraw.h" | 10 #include "SkDraw.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 path.setFillType(SkPath::kEvenOdd_FillType); | 81 path.setFillType(SkPath::kEvenOdd_FillType); |
| 82 | 82 |
| 83 const SkMatrix* preMatrix = nullptr; | 83 const SkMatrix* preMatrix = nullptr; |
| 84 const bool pathIsMutable = true; | 84 const bool pathIsMutable = true; |
| 85 this->drawPath(draw, path, paint, preMatrix, pathIsMutable); | 85 this->drawPath(draw, path, paint, preMatrix, pathIsMutable); |
| 86 } | 86 } |
| 87 | 87 |
| 88 void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const
SkColor colors[4], | 88 void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const
SkColor colors[4], |
| 89 const SkPoint texCoords[4], SkXfermode* xmode, cons
t SkPaint& paint) { | 89 const SkPoint texCoords[4], SkXfermode* xmode, cons
t SkPaint& paint) { |
| 90 SkPatchUtils::VertexData data; | 90 SkPatchUtils::VertexData data; |
| 91 | 91 |
| 92 SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix); | 92 SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix); |
| 93 | 93 |
| 94 // It automatically adjusts lodX and lodY in case it exceeds the number of i
ndices. | 94 // It automatically adjusts lodX and lodY in case it exceeds the number of i
ndices. |
| 95 // If it fails to generate the vertices, then we do not draw. | 95 // If it fails to generate the vertices, then we do not draw. |
| 96 if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(
), lod.height())) { | 96 if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(
), lod.height())) { |
| 97 this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCo
unt, data.fPoints, | 97 this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCo
unt, data.fPoints, |
| 98 data.fTexCoords, data.fColors, xmode, data.fIndices,
data.fIndexCount, | 98 data.fTexCoords, data.fColors, xmode, data.fIndices,
data.fIndexCount, |
| 99 paint); | 99 paint); |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 | 102 |
| 103 void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
alar x, SkScalar y, | 103 void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
alar x, SkScalar y, |
| 104 const SkPaint &paint, SkDrawFilter* drawFilter)
{ | 104 const SkPaint &paint, SkDrawFilter* drawFilter)
{ |
| 105 | 105 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 | 169 |
| 170 SkRect srcR, dstR; | 170 SkRect srcR, dstR; |
| 171 while (iter.next(&srcR, &dstR)) { | 171 while (iter.next(&srcR, &dstR)) { |
| 172 this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_S
rcRectConstraint); | 172 this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_S
rcRectConstraint); |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, co
nst SkIRect& center, | 176 void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, co
nst SkIRect& center, |
| 177 const SkRect& dst, const SkPaint& paint) { | 177 const SkRect& dst, const SkPaint& paint) { |
| 178 SkNinePatchIter iter(bitmap.width(), bitmap.height(), center, dst); | 178 SkNinePatchIter iter(bitmap.width(), bitmap.height(), center, dst); |
| 179 | 179 |
| 180 SkRect srcR, dstR; | 180 SkRect srcR, dstR; |
| 181 while (iter.next(&srcR, &dstR)) { | 181 while (iter.next(&srcR, &dstR)) { |
| 182 this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict
_SrcRectConstraint); | 182 this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict
_SrcRectConstraint); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 | 185 |
| 186 void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkR
SXform xform[], | 186 void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkR
SXform xform[], |
| 187 const SkRect tex[], const SkColor colors[], int cou
nt, | 187 const SkRect tex[], const SkColor colors[], int cou
nt, |
| 188 SkXfermode::Mode mode, const SkPaint& paint) { | 188 SkXfermode::Mode mode, const SkPaint& paint) { |
| 189 SkPath path; | 189 SkPath path; |
| 190 path.setIsVolatile(true); | 190 path.setIsVolatile(true); |
| 191 | 191 |
| 192 for (int i = 0; i < count; ++i) { | 192 for (int i = 0; i < count; ++i) { |
| 193 SkPoint quad[4]; | 193 SkPoint quad[4]; |
| 194 xform[i].toQuad(tex[i].width(), tex[i].height(), quad); | 194 xform[i].toQuad(tex[i].width(), tex[i].height(), quad); |
| 195 | 195 |
| 196 SkMatrix localM; | 196 SkMatrix localM; |
| 197 localM.setRSXform(xform[i]); | 197 localM.setRSXform(xform[i]); |
| 198 localM.preTranslate(-tex[i].left(), -tex[i].top()); | 198 localM.preTranslate(-tex[i].left(), -tex[i].top()); |
| 199 | 199 |
| 200 SkPaint pnt(paint); | 200 SkPaint pnt(paint); |
| 201 sk_sp<SkShader> shader = atlas->makeShader(SkShader::kClamp_TileMode, | 201 sk_sp<SkShader> shader = atlas->makeShader(SkShader::kClamp_TileMode, |
| 202 SkShader::kClamp_TileMode, | 202 SkShader::kClamp_TileMode, |
| 203 &localM); | 203 &localM); |
| 204 if (!shader) { | 204 if (!shader) { |
| 205 break; | 205 break; |
| 206 } | 206 } |
| 207 pnt.setShader(std::move(shader)); | 207 pnt.setShader(std::move(shader)); |
| 208 | 208 |
| 209 if (colors) { | 209 if (colors) { |
| 210 pnt.setColorFilter(SkColorFilter::MakeModeFilter(colors[i], mode)); | 210 pnt.setColorFilter(SkColorFilter::MakeModeFilter(colors[i], mode)); |
| 211 } | 211 } |
| 212 | 212 |
| 213 path.rewind(); | 213 path.rewind(); |
| 214 path.addPoly(quad, 4, true); | 214 path.addPoly(quad, 4, true); |
| 215 path.setConvexity(SkPath::kConvex_Convexity); | 215 path.setConvexity(SkPath::kConvex_Convexity); |
| 216 this->drawPath(draw, path, pnt, nullptr, true); | 216 this->drawPath(draw, path, pnt, nullptr, true); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 220 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 221 | 221 |
| 222 bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowByt
es, int x, int y) { | 222 bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowByt
es, int x, int y) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 pmap = &tempStorage; | 276 pmap = &tempStorage; |
| 277 } | 277 } |
| 278 return this->onPeekPixels(pmap); | 278 return this->onPeekPixels(pmap); |
| 279 } | 279 } |
| 280 | 280 |
| 281 ////////////////////////////////////////////////////////////////////////////////
////////// | 281 ////////////////////////////////////////////////////////////////////////////////
////////// |
| 282 | 282 |
| 283 static void morphpoints(SkPoint dst[], const SkPoint src[], int count, | 283 static void morphpoints(SkPoint dst[], const SkPoint src[], int count, |
| 284 SkPathMeasure& meas, const SkMatrix& matrix) { | 284 SkPathMeasure& meas, const SkMatrix& matrix) { |
| 285 SkMatrix::MapXYProc proc = matrix.getMapXYProc(); | 285 SkMatrix::MapXYProc proc = matrix.getMapXYProc(); |
| 286 | 286 |
| 287 for (int i = 0; i < count; i++) { | 287 for (int i = 0; i < count; i++) { |
| 288 SkPoint pos; | 288 SkPoint pos; |
| 289 SkVector tangent; | 289 SkVector tangent; |
| 290 | 290 |
| 291 proc(matrix, src[i].fX, src[i].fY, &pos); | 291 proc(matrix, src[i].fX, src[i].fY, &pos); |
| 292 SkScalar sx = pos.fX; | 292 SkScalar sx = pos.fX; |
| 293 SkScalar sy = pos.fY; | 293 SkScalar sy = pos.fY; |
| 294 | 294 |
| 295 if (!meas.getPosTan(sx, &pos, &tangent)) { | 295 if (!meas.getPosTan(sx, &pos, &tangent)) { |
| 296 // set to 0 if the measure failed, so that we just set dst == pos | 296 // set to 0 if the measure failed, so that we just set dst == pos |
| 297 tangent.set(0, 0); | 297 tangent.set(0, 0); |
| 298 } | 298 } |
| 299 | 299 |
| 300 /* This is the old way (that explains our approach but is way too slow | 300 /* This is the old way (that explains our approach but is way too slow |
| 301 SkMatrix matrix; | 301 SkMatrix matrix; |
| 302 SkPoint pt; | 302 SkPoint pt; |
| 303 | 303 |
| 304 pt.set(sx, sy); | 304 pt.set(sx, sy); |
| 305 matrix.setSinCos(tangent.fY, tangent.fX); | 305 matrix.setSinCos(tangent.fY, tangent.fX); |
| 306 matrix.preTranslate(-sx, 0); | 306 matrix.preTranslate(-sx, 0); |
| 307 matrix.postTranslate(pos.fX, pos.fY); | 307 matrix.postTranslate(pos.fX, pos.fY); |
| 308 matrix.mapPoints(&dst[i], &pt, 1); | 308 matrix.mapPoints(&dst[i], &pt, 1); |
| 309 */ | 309 */ |
| 310 dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy), | 310 dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy), |
| 311 pos.fY + SkScalarMul(tangent.fX, sy)); | 311 pos.fY + SkScalarMul(tangent.fX, sy)); |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 | 314 |
| 315 /* TODO | 315 /* TODO |
| 316 | 316 |
| 317 Need differentially more subdivisions when the follow-path is curvy. Not sure h
ow to | 317 Need differentially more subdivisions when the follow-path is curvy. Not sure h
ow to |
| 318 determine that, but we need it. I guess a cheap answer is let the caller tell u
s, | 318 determine that, but we need it. I guess a cheap answer is let the caller tell u
s, |
| 319 but that seems like a cop-out. Another answer is to get Rob Johnson to figure i
t out. | 319 but that seems like a cop-out. Another answer is to get Rob Johnson to figure i
t out. |
| 320 */ | 320 */ |
| 321 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, | 321 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, |
| 322 const SkMatrix& matrix) { | 322 const SkMatrix& matrix) { |
| 323 SkPath::Iter iter(src, false); | 323 SkPath::Iter iter(src, false); |
| 324 SkPoint srcP[4], dstP[3]; | 324 SkPoint srcP[4], dstP[3]; |
| 325 SkPath::Verb verb; | 325 SkPath::Verb verb; |
| 326 | 326 |
| 327 while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { | 327 while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { |
| 328 switch (verb) { | 328 switch (verb) { |
| 329 case SkPath::kMove_Verb: | 329 case SkPath::kMove_Verb: |
| 330 morphpoints(dstP, srcP, 1, meas, matrix); | 330 morphpoints(dstP, srcP, 1, meas, matrix); |
| 331 dst->moveTo(dstP[0]); | 331 dst->moveTo(dstP[0]); |
| 332 break; | 332 break; |
| 333 case SkPath::kLine_Verb: | 333 case SkPath::kLine_Verb: |
| 334 // turn lines into quads to look bendy | 334 // turn lines into quads to look bendy |
| 335 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX); | 335 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX); |
| 336 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY); | 336 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 352 SkDEBUGFAIL("unknown verb"); | 352 SkDEBUGFAIL("unknown verb"); |
| 353 break; | 353 break; |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 } | 356 } |
| 357 | 357 |
| 358 void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
yteLength, | 358 void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
yteLength, |
| 359 const SkPath& follow, const SkMatrix* matrix, | 359 const SkPath& follow, const SkMatrix* matrix, |
| 360 const SkPaint& paint) { | 360 const SkPaint& paint) { |
| 361 SkASSERT(byteLength == 0 || text != nullptr); | 361 SkASSERT(byteLength == 0 || text != nullptr); |
| 362 | 362 |
| 363 // nothing to draw | 363 // nothing to draw |
| 364 if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) { | 364 if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) { |
| 365 return; | 365 return; |
| 366 } | 366 } |
| 367 | 367 |
| 368 SkTextToPathIter iter((const char*)text, byteLength, paint, true); | 368 SkTextToPathIter iter((const char*)text, byteLength, paint, true); |
| 369 SkPathMeasure meas(follow, false); | 369 SkPathMeasure meas(follow, false); |
| 370 SkScalar hOffset = 0; | 370 SkScalar hOffset = 0; |
| 371 | 371 |
| 372 // need to measure first | 372 // need to measure first |
| 373 if (paint.getTextAlign() != SkPaint::kLeft_Align) { | 373 if (paint.getTextAlign() != SkPaint::kLeft_Align) { |
| 374 SkScalar pathLen = meas.getLength(); | 374 SkScalar pathLen = meas.getLength(); |
| 375 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | 375 if (paint.getTextAlign() == SkPaint::kCenter_Align) { |
| 376 pathLen = SkScalarHalf(pathLen); | 376 pathLen = SkScalarHalf(pathLen); |
| 377 } | 377 } |
| 378 hOffset += pathLen; | 378 hOffset += pathLen; |
| 379 } | 379 } |
| 380 | 380 |
| 381 const SkPath* iterPath; | 381 const SkPath* iterPath; |
| 382 SkScalar xpos; | 382 SkScalar xpos; |
| 383 SkMatrix scaledMatrix; | 383 SkMatrix scaledMatrix; |
| 384 SkScalar scale = iter.getPathScale(); | 384 SkScalar scale = iter.getPathScale(); |
| 385 | 385 |
| 386 scaledMatrix.setScale(scale, scale); | 386 scaledMatrix.setScale(scale, scale); |
| 387 | 387 |
| 388 while (iter.next(&iterPath, &xpos)) { | 388 while (iter.next(&iterPath, &xpos)) { |
| 389 if (iterPath) { | 389 if (iterPath) { |
| 390 SkPath tmp; | 390 SkPath tmp; |
| 391 SkMatrix m(scaledMatrix); | 391 SkMatrix m(scaledMatrix); |
| 392 | 392 |
| 393 tmp.setIsVolatile(true); | 393 tmp.setIsVolatile(true); |
| 394 m.postTranslate(xpos + hOffset, 0); | 394 m.postTranslate(xpos + hOffset, 0); |
| 395 if (matrix) { | 395 if (matrix) { |
| 396 m.postConcat(*matrix); | 396 m.postConcat(*matrix); |
| 397 } | 397 } |
| 398 morphpath(&tmp, *iterPath, meas, m); | 398 morphpath(&tmp, *iterPath, meas, m); |
| 399 this->drawPath(draw, tmp, iter.getPaint(), nullptr, true); | 399 this->drawPath(draw, tmp, iter.getPaint(), nullptr, true); |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 } | 402 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 flags &= ~SkPaint::kLCDRenderText_Flag; | 451 flags &= ~SkPaint::kLCDRenderText_Flag; |
| 452 flags |= SkPaint::kGenA8FromLCD_Flag; | 452 flags |= SkPaint::kGenA8FromLCD_Flag; |
| 453 } | 453 } |
| 454 | 454 |
| 455 return flags; | 455 return flags; |
| 456 } | 456 } |
| 457 | 457 |
| 458 sk_sp<SkSurface> SkBaseDevice::makeSurface(SkImageInfo const&, SkSurfaceProps co
nst&) { | 458 sk_sp<SkSurface> SkBaseDevice::makeSurface(SkImageInfo const&, SkSurfaceProps co
nst&) { |
| 459 return nullptr; | 459 return nullptr; |
| 460 } | 460 } |
| OLD | NEW |