diff options
Diffstat (limited to 'skia/sgl/SkStrokerPriv.cpp')
-rw-r--r-- | skia/sgl/SkStrokerPriv.cpp | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/skia/sgl/SkStrokerPriv.cpp b/skia/sgl/SkStrokerPriv.cpp deleted file mode 100644 index 07833ca..0000000 --- a/skia/sgl/SkStrokerPriv.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* libs/graphics/sgl/SkStrokerPriv.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "SkStrokerPriv.h" -#include "SkGeometry.h" -#include "SkPath.h" - -static void ButtCapper(SkPath* path, const SkPoint& pivot, - const SkVector& normal, const SkPoint& stop, - SkPath*) -{ - path->lineTo(stop.fX, stop.fY); -} - -static void RoundCapper(SkPath* path, const SkPoint& pivot, - const SkVector& normal, const SkPoint& stop, - SkPath*) -{ - SkScalar px = pivot.fX; - SkScalar py = pivot.fY; - SkScalar nx = normal.fX; - SkScalar ny = normal.fY; - SkScalar sx = SkScalarMul(nx, CUBIC_ARC_FACTOR); - SkScalar sy = SkScalarMul(ny, CUBIC_ARC_FACTOR); - - path->cubicTo(px + nx + CWX(sx, sy), py + ny + CWY(sx, sy), - px + CWX(nx, ny) + sx, py + CWY(nx, ny) + sy, - px + CWX(nx, ny), py + CWY(nx, ny)); - path->cubicTo(px + CWX(nx, ny) - sx, py + CWY(nx, ny) - sy, - px - nx + CWX(sx, sy), py - ny + CWY(sx, sy), - stop.fX, stop.fY); -} - -static void SquareCapper(SkPath* path, const SkPoint& pivot, - const SkVector& normal, const SkPoint& stop, - SkPath* otherPath) -{ - SkVector parallel; - normal.rotateCW(¶llel); - - if (otherPath) - { - path->setLastPt(pivot.fX + normal.fX + parallel.fX, pivot.fY + normal.fY + parallel.fY); - path->lineTo(pivot.fX - normal.fX + parallel.fX, pivot.fY - normal.fY + parallel.fY); - } - else - { - path->lineTo(pivot.fX + normal.fX + parallel.fX, pivot.fY + normal.fY + parallel.fY); - path->lineTo(pivot.fX - normal.fX + parallel.fX, pivot.fY - normal.fY + parallel.fY); - path->lineTo(stop.fX, stop.fY); - } -} - -///////////////////////////////////////////////////////////////////////////// - -static bool is_clockwise(const SkVector& before, const SkVector& after) -{ - return SkScalarMul(before.fX, after.fY) - SkScalarMul(before.fY, after.fX) > 0; -} - -enum AngleType { - kNearly180_AngleType, - kSharp_AngleType, - kShallow_AngleType, - kNearlyLine_AngleType -}; - -static AngleType Dot2AngleType(SkScalar dot) -{ -// need more precise fixed normalization -// SkASSERT(SkScalarAbs(dot) <= SK_Scalar1 + SK_ScalarNearlyZero); - - if (dot >= 0) // shallow or line - return SkScalarNearlyZero(SK_Scalar1 - dot) ? kNearlyLine_AngleType : kShallow_AngleType; - else // sharp or 180 - return SkScalarNearlyZero(SK_Scalar1 + dot) ? kNearly180_AngleType : kSharp_AngleType; -} - -static void HandleInnerJoin(SkPath* inner, const SkPoint& pivot, const SkVector& after) -{ -#if 1 - /* In the degenerate case that the stroke radius is larger than our segments - just connecting the two inner segments may "show through" as a funny - diagonal. To pseudo-fix this, we go through the pivot point. This adds - an extra point/edge, but I can't see a cheap way to know when this is - not needed :( - */ - inner->lineTo(pivot.fX, pivot.fY); -#endif - - inner->lineTo(pivot.fX - after.fX, pivot.fY - after.fY); -} - -static void BluntJoiner(SkPath* outer, SkPath* inner, const SkVector& beforeUnitNormal, - const SkPoint& pivot, const SkVector& afterUnitNormal, - SkScalar radius, SkScalar invMiterLimit, bool, bool) -{ - SkVector after; - afterUnitNormal.scale(radius, &after); - - if (!is_clockwise(beforeUnitNormal, afterUnitNormal)) - { - SkTSwap<SkPath*>(outer, inner); - after.negate(); - } - - outer->lineTo(pivot.fX + after.fX, pivot.fY + after.fY); - HandleInnerJoin(inner, pivot, after); -} - -static void RoundJoiner(SkPath* outer, SkPath* inner, const SkVector& beforeUnitNormal, - const SkPoint& pivot, const SkVector& afterUnitNormal, - SkScalar radius, SkScalar invMiterLimit, bool, bool) -{ - SkScalar dotProd = SkPoint::DotProduct(beforeUnitNormal, afterUnitNormal); - AngleType angleType = Dot2AngleType(dotProd); - - if (angleType == kNearlyLine_AngleType) - return; - - SkVector before = beforeUnitNormal; - SkVector after = afterUnitNormal; - SkRotationDirection dir = kCW_SkRotationDirection; - - if (!is_clockwise(before, after)) - { - SkTSwap<SkPath*>(outer, inner); - before.negate(); - after.negate(); - dir = kCCW_SkRotationDirection; - } - - SkPoint pts[kSkBuildQuadArcStorage]; - SkMatrix matrix; - matrix.setScale(radius, radius); - matrix.postTranslate(pivot.fX, pivot.fY); - int count = SkBuildQuadArc(before, after, dir, &matrix, pts); - SkASSERT((count & 1) == 1); - - if (count > 1) - { - for (int i = 1; i < count; i += 2) - outer->quadTo(pts[i].fX, pts[i].fY, pts[i+1].fX, pts[i+1].fY); - - after.scale(radius); - HandleInnerJoin(inner, pivot, after); - } -} - -#ifdef SK_SCALAR_IS_FLOAT - #define kOneOverSqrt2 (0.707106781f) -#else - #define kOneOverSqrt2 (46341) -#endif - -static void MiterJoiner(SkPath* outer, SkPath* inner, const SkVector& beforeUnitNormal, - const SkPoint& pivot, const SkVector& afterUnitNormal, - SkScalar radius, SkScalar invMiterLimit, - bool prevIsLine, bool currIsLine) -{ - // negate the dot since we're using normals instead of tangents - SkScalar dotProd = SkPoint::DotProduct(beforeUnitNormal, afterUnitNormal); - AngleType angleType = Dot2AngleType(dotProd); - SkVector before = beforeUnitNormal; - SkVector after = afterUnitNormal; - SkVector mid; - SkScalar sinHalfAngle; - bool ccw; - - if (angleType == kNearlyLine_AngleType) - return; - if (angleType == kNearly180_AngleType) - { - currIsLine = false; - goto DO_BLUNT; - } - - ccw = !is_clockwise(before, after); - if (ccw) - { - SkTSwap<SkPath*>(outer, inner); - before.negate(); - after.negate(); - } - - /* Before we enter the world of square-roots and divides, - check if we're trying to join an upright right angle - (common case for stroking rectangles). If so, special case - that (for speed an accuracy). - Note: we only need to check one normal if dot==0 - */ - if (0 == dotProd && invMiterLimit <= kOneOverSqrt2) - { - mid.set(SkScalarMul(before.fX + after.fX, radius), - SkScalarMul(before.fY + after.fY, radius)); - goto DO_MITER; - } - - /* midLength = radius / sinHalfAngle - if (midLength > miterLimit * radius) abort - if (radius / sinHalf > miterLimit * radius) abort - if (1 / sinHalf > miterLimit) abort - if (1 / miterLimit > sinHalf) abort - My dotProd is opposite sign, since it is built from normals and not tangents - hence 1 + dot instead of 1 - dot in the formula - */ - sinHalfAngle = SkScalarSqrt(SkScalarHalf(SK_Scalar1 + dotProd)); - if (sinHalfAngle < invMiterLimit) - { - currIsLine = false; - goto DO_BLUNT; - } - - // choose the most accurate way to form the initial mid-vector - if (angleType == kSharp_AngleType) - { - mid.set(after.fY - before.fY, before.fX - after.fX); - if (ccw) - mid.negate(); - } - else - mid.set(before.fX + after.fX, before.fY + after.fY); - - mid.setLength(SkScalarDiv(radius, sinHalfAngle)); -DO_MITER: - if (prevIsLine) - outer->setLastPt(pivot.fX + mid.fX, pivot.fY + mid.fY); - else - outer->lineTo(pivot.fX + mid.fX, pivot.fY + mid.fY); - -DO_BLUNT: - after.scale(radius); - if (!currIsLine) - outer->lineTo(pivot.fX + after.fX, pivot.fY + after.fY); - HandleInnerJoin(inner, pivot, after); -} - -///////////////////////////////////////////////////////////////////////////// - -SkStrokerPriv::CapProc SkStrokerPriv::CapFactory(SkPaint::Cap cap) -{ - static const SkStrokerPriv::CapProc gCappers[] = { - ButtCapper, RoundCapper, SquareCapper - }; - - SkASSERT((unsigned)cap < SkPaint::kCapCount); - return gCappers[cap]; -} - -SkStrokerPriv::JoinProc SkStrokerPriv::JoinFactory(SkPaint::Join join) -{ - static const SkStrokerPriv::JoinProc gJoiners[] = { - MiterJoiner, RoundJoiner, BluntJoiner - }; - - SkASSERT((unsigned)join < SkPaint::kJoinCount); - return gJoiners[join]; -} - - - |