| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/effects/SkCornerPathEffect.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkCornerPathEffect.h" | |
| 19 #include "SkPath.h" | |
| 20 #include "SkPoint.h" | |
| 21 #include "SkBuffer.h" | |
| 22 | |
| 23 SkCornerPathEffect::SkCornerPathEffect(SkScalar radius) : fRadius(radius) | |
| 24 { | |
| 25 } | |
| 26 | |
| 27 SkCornerPathEffect::~SkCornerPathEffect() | |
| 28 { | |
| 29 } | |
| 30 | |
| 31 static bool ComputeStep(const SkPoint& a, const SkPoint& b, SkScalar radius, SkP
oint* step) | |
| 32 { | |
| 33 SkScalar dist = SkPoint::Distance(a, b); | |
| 34 | |
| 35 step->set(b.fX - a.fX, b.fY - a.fY); | |
| 36 | |
| 37 if (dist <= radius * 2) { | |
| 38 step->scale(SK_ScalarHalf); | |
| 39 return false; | |
| 40 } | |
| 41 else { | |
| 42 step->scale(SkScalarDiv(radius, dist)); | |
| 43 return true; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 bool SkCornerPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* wi
dth) | |
| 48 { | |
| 49 if (fRadius == 0) | |
| 50 return false; | |
| 51 | |
| 52 SkPath::Iter iter(src, false); | |
| 53 SkPath::Verb verb, prevVerb = (SkPath::Verb)-1; | |
| 54 SkPoint pts[4]; | |
| 55 | |
| 56 bool closed; | |
| 57 SkPoint moveTo, lastCorner; | |
| 58 SkVector firstStep, step; | |
| 59 bool prevIsValid = true; | |
| 60 | |
| 61 // to avoid warnings | |
| 62 moveTo.set(0, 0); | |
| 63 firstStep.set(0, 0); | |
| 64 lastCorner.set(0, 0); | |
| 65 | |
| 66 for (;;) { | |
| 67 switch (verb = iter.next(pts)) { | |
| 68 case SkPath::kMove_Verb: | |
| 69 closed = iter.isClosedContour(); | |
| 70 if (closed) { | |
| 71 moveTo = pts[0]; | |
| 72 prevIsValid = false; | |
| 73 } | |
| 74 else { | |
| 75 dst->moveTo(pts[0]); | |
| 76 prevIsValid = true; | |
| 77 } | |
| 78 break; | |
| 79 case SkPath::kLine_Verb: | |
| 80 { | |
| 81 bool drawSegment = ComputeStep(pts[0], pts[1], fRadius, &step); | |
| 82 // prev corner | |
| 83 if (!prevIsValid) { | |
| 84 dst->moveTo(moveTo + step); | |
| 85 prevIsValid = true; | |
| 86 } | |
| 87 else { | |
| 88 dst->quadTo(pts[0].fX, pts[0].fY, pts[0].fX + step.fX, pts[0
].fY + step.fY); | |
| 89 } | |
| 90 if (drawSegment) { | |
| 91 dst->lineTo(pts[1].fX - step.fX, pts[1].fY - step.fY); | |
| 92 } | |
| 93 lastCorner = pts[1]; | |
| 94 prevIsValid = true; | |
| 95 } | |
| 96 break; | |
| 97 case SkPath::kQuad_Verb: | |
| 98 // TBD - just replicate the curve for now | |
| 99 if (!prevIsValid) | |
| 100 { | |
| 101 dst->moveTo(pts[0]); | |
| 102 prevIsValid = true; | |
| 103 } | |
| 104 dst->quadTo(pts[1], pts[2]); | |
| 105 lastCorner = pts[2]; | |
| 106 firstStep.set(0, 0); | |
| 107 break; | |
| 108 case SkPath::kCubic_Verb: | |
| 109 if (!prevIsValid) | |
| 110 { | |
| 111 dst->moveTo(pts[0]); | |
| 112 prevIsValid = true; | |
| 113 } | |
| 114 // TBD - just replicate the curve for now | |
| 115 dst->cubicTo(pts[1], pts[2], pts[3]); | |
| 116 lastCorner = pts[3]; | |
| 117 firstStep.set(0, 0); | |
| 118 break; | |
| 119 case SkPath::kClose_Verb: | |
| 120 if (firstStep.fX || firstStep.fY) | |
| 121 dst->quadTo(lastCorner.fX, lastCorner.fY, | |
| 122 lastCorner.fX + firstStep.fX, | |
| 123 lastCorner.fY + firstStep.fY); | |
| 124 dst->close(); | |
| 125 break; | |
| 126 case SkPath::kDone_Verb: | |
| 127 goto DONE; | |
| 128 } | |
| 129 | |
| 130 if (SkPath::kMove_Verb == prevVerb) | |
| 131 firstStep = step; | |
| 132 prevVerb = verb; | |
| 133 } | |
| 134 DONE: | |
| 135 return true; | |
| 136 } | |
| 137 | |
| 138 SkFlattenable::Factory SkCornerPathEffect::getFactory() | |
| 139 { | |
| 140 return CreateProc; | |
| 141 } | |
| 142 | |
| 143 void SkCornerPathEffect::flatten(SkFlattenableWriteBuffer& buffer) | |
| 144 { | |
| 145 buffer.writeScalar(fRadius); | |
| 146 } | |
| 147 | |
| 148 SkFlattenable* SkCornerPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) | |
| 149 { | |
| 150 return SkNEW_ARGS(SkCornerPathEffect, (buffer)); | |
| 151 } | |
| 152 | |
| 153 SkCornerPathEffect::SkCornerPathEffect(SkFlattenableReadBuffer& buffer) | |
| 154 { | |
| 155 fRadius = buffer.readScalar(); | |
| 156 } | |
| 157 | |
| OLD | NEW |