OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrDashingEffect.h" | 8 #include "GrDashingEffect.h" |
9 | 9 |
10 #include "../GrAARectRenderer.h" | 10 #include "../GrAARectRenderer.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m
atrix, | 158 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m
atrix, |
159 SkPoint* verts) { | 159 SkPoint* verts) { |
160 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop); | 160 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop); |
161 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom); | 161 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom); |
162 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom); | 162 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom); |
163 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop); | 163 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop); |
164 matrix.mapPoints(&verts[idx], 4); | 164 matrix.mapPoints(&verts[idx], 4); |
165 } | 165 } |
166 | 166 |
167 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
* drawState, | 167 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
* drawState, |
168 GrColor color, const SkPoint pts[2], const Gr
Paint& paint, | 168 GrColor color, const SkMatrix& viewMatrix, co
nst SkPoint pts[2], |
169 const GrStrokeInfo& strokeInfo) { | 169 const GrPaint& paint, const GrStrokeInfo& str
okeInfo) { |
170 const SkMatrix& vm = drawState->getViewMatrix(); | 170 if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, viewMatrix)) { |
171 | |
172 if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) { | |
173 return false; | 171 return false; |
174 } | 172 } |
175 | 173 |
176 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); | 174 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
177 | 175 |
178 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); | 176 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
179 | 177 |
180 SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); | 178 SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); |
181 | 179 |
182 // the phase should be normalized to be [0, sum of all intervals) | 180 // the phase should be normalized to be [0, sum of all intervals) |
(...skipping 14 matching lines...) Expand all Loading... |
197 } else { | 195 } else { |
198 srcRotInv.reset(); | 196 srcRotInv.reset(); |
199 memcpy(ptsRot, pts, 2 * sizeof(SkPoint)); | 197 memcpy(ptsRot, pts, 2 * sizeof(SkPoint)); |
200 } | 198 } |
201 | 199 |
202 bool useAA = paint.isAntiAlias(); | 200 bool useAA = paint.isAntiAlias(); |
203 | 201 |
204 // Scale corrections of intervals and stroke from view matrix | 202 // Scale corrections of intervals and stroke from view matrix |
205 SkScalar parallelScale; | 203 SkScalar parallelScale; |
206 SkScalar perpScale; | 204 SkScalar perpScale; |
207 calc_dash_scaling(¶llelScale, &perpScale, vm, ptsRot); | 205 calc_dash_scaling(¶llelScale, &perpScale, viewMatrix, ptsRot); |
208 | 206 |
209 bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth; | 207 bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth; |
210 | 208 |
211 // We always want to at least stroke out half a pixel on each side in device
space | 209 // We always want to at least stroke out half a pixel on each side in device
space |
212 // so 0.5f / perpScale gives us this min in src space | 210 // so 0.5f / perpScale gives us this min in src space |
213 SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale
); | 211 SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale
); |
214 | 212 |
215 SkScalar strokeAdj; | 213 SkScalar strokeAdj; |
216 if (!hasCap) { | 214 if (!hasCap) { |
217 strokeAdj = 0.f; | 215 strokeAdj = 0.f; |
218 } else { | 216 } else { |
219 strokeAdj = halfSrcStroke; | 217 strokeAdj = halfSrcStroke; |
220 } | 218 } |
221 | 219 |
222 SkScalar startAdj = 0; | 220 SkScalar startAdj = 0; |
223 | 221 |
224 SkMatrix combinedMatrix = srcRotInv; | 222 SkMatrix combinedMatrix = srcRotInv; |
225 combinedMatrix.postConcat(vm); | 223 combinedMatrix.postConcat(viewMatrix); |
226 | 224 |
227 bool lineDone = false; | 225 bool lineDone = false; |
228 SkRect startRect; | 226 SkRect startRect; |
229 bool hasStartRect = false; | 227 bool hasStartRect = false; |
230 // If we are using AA, check to see if we are drawing a partial dash at the
start. If so | 228 // If we are using AA, check to see if we are drawing a partial dash at the
start. If so |
231 // draw it separately here and adjust our start point accordingly | 229 // draw it separately here and adjust our start point accordingly |
232 if (useAA) { | 230 if (useAA) { |
233 if (srcPhase > 0 && srcPhase < info.fIntervals[0]) { | 231 if (srcPhase > 0 && srcPhase < info.fIntervals[0]) { |
234 SkPoint startPts[2]; | 232 SkPoint startPts[2]; |
235 startPts[0] = ptsRot[0]; | 233 startPts[0] = ptsRot[0]; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 // one giant dash | 319 // one giant dash |
322 ptsRot[0].fX -= hasStartRect ? startAdj : 0; | 320 ptsRot[0].fX -= hasStartRect ? startAdj : 0; |
323 ptsRot[1].fX += hasEndRect ? endAdj : 0; | 321 ptsRot[1].fX += hasEndRect ? endAdj : 0; |
324 startRect.set(ptsRot, 2); | 322 startRect.set(ptsRot, 2); |
325 startRect.outset(strokeAdj, halfSrcStroke); | 323 startRect.outset(strokeAdj, halfSrcStroke); |
326 hasStartRect = true; | 324 hasStartRect = true; |
327 hasEndRect = false; | 325 hasEndRect = false; |
328 lineDone = true; | 326 lineDone = true; |
329 | 327 |
330 SkPoint devicePts[2]; | 328 SkPoint devicePts[2]; |
331 vm.mapPoints(devicePts, ptsRot, 2); | 329 viewMatrix.mapPoints(devicePts, ptsRot, 2); |
332 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); | 330 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
333 if (hasCap) { | 331 if (hasCap) { |
334 lineLength += 2.f * halfDevStroke; | 332 lineLength += 2.f * halfDevStroke; |
335 } | 333 } |
336 devIntervals[0] = lineLength; | 334 devIntervals[0] = lineLength; |
337 } | 335 } |
338 | 336 |
339 // reset to device coordinates | 337 // reset to device coordinates |
340 SkMatrix invert; | 338 SkMatrix invert; |
341 if (!vm.invert(&invert)) { | 339 if (!viewMatrix.invert(&invert)) { |
342 SkDebugf("Failed to invert\n"); | 340 SkDebugf("Failed to invert\n"); |
343 return false; | 341 return false; |
344 } | 342 } |
345 | 343 |
346 GrDrawState::AutoViewMatrixRestore avmr(drawState); | |
347 | |
348 SkAutoTUnref<const GrGeometryProcessor> gp; | 344 SkAutoTUnref<const GrGeometryProcessor> gp; |
349 bool fullDash = devIntervals[1] > 0.f || useAA; | 345 bool fullDash = devIntervals[1] > 0.f || useAA; |
350 if (fullDash) { | 346 if (fullDash) { |
351 SkPathEffect::DashInfo devInfo; | 347 SkPathEffect::DashInfo devInfo; |
352 devInfo.fPhase = devPhase; | 348 devInfo.fPhase = devPhase; |
353 devInfo.fCount = 2; | 349 devInfo.fCount = 2; |
354 devInfo.fIntervals = devIntervals; | 350 devInfo.fIntervals = devIntervals; |
355 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : | 351 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : |
356 kFillBW_GrProcessorEdgeType; | 352 kFillBW_GrProcessorEdgeType; |
357 bool isRoundCap = SkPaint::kRound_Cap == cap; | 353 bool isRoundCap = SkPaint::kRound_Cap == cap; |
358 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : | 354 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : |
359 GrDashingEffect::kNonRou
nd_DashCap; | 355 GrDashingEffect::kNonRou
nd_DashCap; |
360 gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth,
capType, invert)); | 356 gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth,
capType, invert)); |
361 } else { | 357 } else { |
362 // Set up the vertex data for the line and start/end dashes | 358 // Set up the vertex data for the line and start/end dashes |
363 gp.reset(GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory:
:kPosition_GPType, | 359 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosit
ion_GPType, |
| 360 color, |
| 361 SkMatrix::I(), |
364 invert)); | 362 invert)); |
365 } | 363 } |
366 | 364 |
367 int totalRectCnt = 0; | 365 int totalRectCnt = 0; |
368 | 366 |
369 totalRectCnt += !lineDone ? 1 : 0; | 367 totalRectCnt += !lineDone ? 1 : 0; |
370 totalRectCnt += hasStartRect ? 1 : 0; | 368 totalRectCnt += hasStartRect ? 1 : 0; |
371 totalRectCnt += hasEndRect ? 1 : 0; | 369 totalRectCnt += hasEndRect ? 1 : 0; |
372 | 370 |
373 GrDrawTarget::AutoReleaseGeometry geo(target, | 371 GrDrawTarget::AutoReleaseGeometry geo(target, |
374 totalRectCnt * 4, | 372 totalRectCnt * 4, |
375 gp->getVertexStride(), 0); | 373 gp->getVertexStride(), 0); |
376 if (!geo.succeeded()) { | 374 if (!geo.succeeded()) { |
377 SkDebugf("Failed to get space for vertices!\n"); | 375 SkDebugf("Failed to get space for vertices!\n"); |
378 return false; | 376 return false; |
379 } | 377 } |
380 | 378 |
381 int curVIdx = 0; | 379 int curVIdx = 0; |
382 | 380 |
383 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { | 381 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { |
384 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices | 382 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices |
385 startOffset -= halfDevStroke; | 383 startOffset -= halfDevStroke; |
386 } | 384 } |
387 | 385 |
388 // Draw interior part of dashed line | 386 // Draw interior part of dashed line |
389 if (!lineDone) { | 387 if (!lineDone) { |
390 SkPoint devicePts[2]; | 388 SkPoint devicePts[2]; |
391 vm.mapPoints(devicePts, ptsRot, 2); | 389 viewMatrix.mapPoints(devicePts, ptsRot, 2); |
392 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); | 390 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
393 if (hasCap) { | 391 if (hasCap) { |
394 lineLength += 2.f * halfDevStroke; | 392 lineLength += 2.f * halfDevStroke; |
395 } | 393 } |
396 | 394 |
397 SkRect bounds; | 395 SkRect bounds; |
398 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); | 396 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); |
399 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); | 397 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); |
400 if (fullDash) { | 398 if (fullDash) { |
401 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); | 399 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 | 666 |
669 GrGLGeometryProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracke
r& bt) const { | 667 GrGLGeometryProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracke
r& bt) const { |
670 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); | 668 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); |
671 } | 669 } |
672 | 670 |
673 DashingCircleEffect::DashingCircleEffect(GrColor color, | 671 DashingCircleEffect::DashingCircleEffect(GrColor color, |
674 GrPrimitiveEdgeType edgeType, | 672 GrPrimitiveEdgeType edgeType, |
675 const DashInfo& info, | 673 const DashInfo& info, |
676 SkScalar radius, | 674 SkScalar radius, |
677 const SkMatrix& localMatrix) | 675 const SkMatrix& localMatrix) |
678 : INHERITED(color, false, localMatrix), fEdgeType(edgeType) { | 676 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { |
679 this->initClassID<DashingCircleEffect>(); | 677 this->initClassID<DashingCircleEffect>(); |
680 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); | 678 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
681 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); | 679 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
682 SkScalar onLen = info.fIntervals[0]; | 680 SkScalar onLen = info.fIntervals[0]; |
683 SkScalar offLen = info.fIntervals[1]; | 681 SkScalar offLen = info.fIntervals[1]; |
684 fIntervalLength = onLen + offLen; | 682 fIntervalLength = onLen + offLen; |
685 fRadius = radius; | 683 fRadius = radius; |
686 fCenterX = SkScalarHalf(offLen); | 684 fCenterX = SkScalarHalf(offLen); |
687 } | 685 } |
688 | 686 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 kGrProcessorEdgeTypeCnt)); | 719 kGrProcessorEdgeTypeCnt)); |
722 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); | 720 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); |
723 DashInfo info; | 721 DashInfo info; |
724 info.fCount = 2; | 722 info.fCount = 2; |
725 SkAutoTArray<SkScalar> intervals(info.fCount); | 723 SkAutoTArray<SkScalar> intervals(info.fCount); |
726 info.fIntervals = intervals.get(); | 724 info.fIntervals = intervals.get(); |
727 info.fIntervals[0] = 0; | 725 info.fIntervals[0] = 0; |
728 info.fIntervals[1] = random->nextRangeScalar(0, 10.f); | 726 info.fIntervals[1] = random->nextRangeScalar(0, 10.f); |
729 info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]); | 727 info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]); |
730 | 728 |
731 return DashingCircleEffect::Create(GrRandomColor(random), edgeType, info, st
rokeWidth, | 729 return DashingCircleEffect::Create(GrRandomColor(random), |
| 730 edgeType, info, strokeWidth, |
732 GrProcessorUnitTest::TestMatrix(random)); | 731 GrProcessorUnitTest::TestMatrix(random)); |
733 } | 732 } |
734 | 733 |
735 ////////////////////////////////////////////////////////////////////////////// | 734 ////////////////////////////////////////////////////////////////////////////// |
736 | 735 |
737 class GLDashingLineEffect; | 736 class GLDashingLineEffect; |
738 | 737 |
739 struct DashingLineBatchTracker { | 738 struct DashingLineBatchTracker { |
740 GrGPInput fInputColorType; | 739 GrGPInput fInputColorType; |
741 GrColor fColor; | 740 GrColor fColor; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 961 |
963 GrGLGeometryProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker&
bt) const { | 962 GrGLGeometryProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker&
bt) const { |
964 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); | 963 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); |
965 } | 964 } |
966 | 965 |
967 DashingLineEffect::DashingLineEffect(GrColor color, | 966 DashingLineEffect::DashingLineEffect(GrColor color, |
968 GrPrimitiveEdgeType edgeType, | 967 GrPrimitiveEdgeType edgeType, |
969 const DashInfo& info, | 968 const DashInfo& info, |
970 SkScalar strokeWidth, | 969 SkScalar strokeWidth, |
971 const SkMatrix& localMatrix) | 970 const SkMatrix& localMatrix) |
972 : INHERITED(color, false, localMatrix), fEdgeType(edgeType) { | 971 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { |
973 this->initClassID<DashingLineEffect>(); | 972 this->initClassID<DashingLineEffect>(); |
974 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); | 973 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
975 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); | 974 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
976 SkScalar onLen = info.fIntervals[0]; | 975 SkScalar onLen = info.fIntervals[0]; |
977 SkScalar offLen = info.fIntervals[1]; | 976 SkScalar offLen = info.fIntervals[1]; |
978 SkScalar halfOffLen = SkScalarHalf(offLen); | 977 SkScalar halfOffLen = SkScalarHalf(offLen); |
979 SkScalar halfStroke = SkScalarHalf(strokeWidth); | 978 SkScalar halfStroke = SkScalarHalf(strokeWidth); |
980 fIntervalLength = onLen + offLen; | 979 fIntervalLength = onLen + offLen; |
981 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); | 980 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); |
982 } | 981 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 kGrProcessorEdgeTypeCnt)); | 1014 kGrProcessorEdgeTypeCnt)); |
1016 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); | 1015 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f); |
1017 DashInfo info; | 1016 DashInfo info; |
1018 info.fCount = 2; | 1017 info.fCount = 2; |
1019 SkAutoTArray<SkScalar> intervals(info.fCount); | 1018 SkAutoTArray<SkScalar> intervals(info.fCount); |
1020 info.fIntervals = intervals.get(); | 1019 info.fIntervals = intervals.get(); |
1021 info.fIntervals[0] = random->nextRangeScalar(0, 10.f); | 1020 info.fIntervals[0] = random->nextRangeScalar(0, 10.f); |
1022 info.fIntervals[1] = random->nextRangeScalar(0, 10.f); | 1021 info.fIntervals[1] = random->nextRangeScalar(0, 10.f); |
1023 info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fInterval
s[1]); | 1022 info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fInterval
s[1]); |
1024 | 1023 |
1025 return DashingLineEffect::Create(GrRandomColor(random), edgeType, info, stro
keWidth, | 1024 return DashingLineEffect::Create(GrRandomColor(random), |
| 1025 edgeType, info, strokeWidth, |
1026 GrProcessorUnitTest::TestMatrix(random)); | 1026 GrProcessorUnitTest::TestMatrix(random)); |
1027 } | 1027 } |
1028 | 1028 |
1029 ////////////////////////////////////////////////////////////////////////////// | 1029 ////////////////////////////////////////////////////////////////////////////// |
1030 | 1030 |
1031 GrGeometryProcessor* GrDashingEffect::Create(GrColor color, | 1031 GrGeometryProcessor* GrDashingEffect::Create(GrColor color, |
1032 GrPrimitiveEdgeType edgeType, | 1032 GrPrimitiveEdgeType edgeType, |
1033 const SkPathEffect::DashInfo& info, | 1033 const SkPathEffect::DashInfo& info, |
1034 SkScalar strokeWidth, | 1034 SkScalar strokeWidth, |
1035 GrDashingEffect::DashCap cap, | 1035 GrDashingEffect::DashCap cap, |
1036 const SkMatrix& localMatrix) { | 1036 const SkMatrix& localMatrix) { |
1037 switch (cap) { | 1037 switch (cap) { |
1038 case GrDashingEffect::kRound_DashCap: | 1038 case GrDashingEffect::kRound_DashCap: |
1039 return DashingCircleEffect::Create(color, edgeType, info, SkScalarHa
lf(strokeWidth), | 1039 return DashingCircleEffect::Create(color, edgeType, info, |
| 1040 SkScalarHalf(strokeWidth), |
1040 localMatrix); | 1041 localMatrix); |
1041 case GrDashingEffect::kNonRound_DashCap: | 1042 case GrDashingEffect::kNonRound_DashCap: |
1042 return DashingLineEffect::Create(color, edgeType, info, strokeWidth,
localMatrix); | 1043 return DashingLineEffect::Create(color, edgeType, info, strokeWidth,
localMatrix); |
1043 default: | 1044 default: |
1044 SkFAIL("Unexpected dashed cap."); | 1045 SkFAIL("Unexpected dashed cap."); |
1045 } | 1046 } |
1046 return NULL; | 1047 return NULL; |
1047 } | 1048 } |
OLD | NEW |