1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkEdge.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,129 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkEdge_DEFINED 1.14 +#define SkEdge_DEFINED 1.15 + 1.16 +#include "SkRect.h" 1.17 +#include "SkFDot6.h" 1.18 +#include "SkMath.h" 1.19 + 1.20 +// This correctly favors the lower-pixel when y0 is on a 1/2 pixel boundary 1.21 +#define SkEdge_Compute_DY(top, y0) ((top << 6) + 32 - (y0)) 1.22 + 1.23 +struct SkEdge { 1.24 + enum Type { 1.25 + kLine_Type, 1.26 + kQuad_Type, 1.27 + kCubic_Type 1.28 + }; 1.29 + 1.30 + SkEdge* fNext; 1.31 + SkEdge* fPrev; 1.32 + 1.33 + SkFixed fX; 1.34 + SkFixed fDX; 1.35 + int32_t fFirstY; 1.36 + int32_t fLastY; 1.37 + int8_t fCurveCount; // only used by kQuad(+) and kCubic(-) 1.38 + uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception 1.39 + uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic 1.40 + int8_t fWinding; // 1 or -1 1.41 + 1.42 + int setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip, 1.43 + int shiftUp); 1.44 + // call this version if you know you don't have a clip 1.45 + inline int setLine(const SkPoint& p0, const SkPoint& p1, int shiftUp); 1.46 + inline int updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by); 1.47 + void chopLineWithClip(const SkIRect& clip); 1.48 + 1.49 + inline bool intersectsClip(const SkIRect& clip) const { 1.50 + SkASSERT(fFirstY < clip.fBottom); 1.51 + return fLastY >= clip.fTop; 1.52 + } 1.53 + 1.54 +#ifdef SK_DEBUG 1.55 + void dump() const { 1.56 + SkDebugf("edge: firstY:%d lastY:%d x:%g dx:%g w:%d\n", fFirstY, fLastY, SkFixedToFloat(fX), SkFixedToFloat(fDX), fWinding); 1.57 + } 1.58 + 1.59 + void validate() const { 1.60 + SkASSERT(fPrev && fNext); 1.61 + SkASSERT(fPrev->fNext == this); 1.62 + SkASSERT(fNext->fPrev == this); 1.63 + 1.64 + SkASSERT(fFirstY <= fLastY); 1.65 + SkASSERT(SkAbs32(fWinding) == 1); 1.66 + } 1.67 +#endif 1.68 +}; 1.69 + 1.70 +struct SkQuadraticEdge : public SkEdge { 1.71 + SkFixed fQx, fQy; 1.72 + SkFixed fQDx, fQDy; 1.73 + SkFixed fQDDx, fQDDy; 1.74 + SkFixed fQLastX, fQLastY; 1.75 + 1.76 + int setQuadratic(const SkPoint pts[3], int shiftUp); 1.77 + int updateQuadratic(); 1.78 +}; 1.79 + 1.80 +struct SkCubicEdge : public SkEdge { 1.81 + SkFixed fCx, fCy; 1.82 + SkFixed fCDx, fCDy; 1.83 + SkFixed fCDDx, fCDDy; 1.84 + SkFixed fCDDDx, fCDDDy; 1.85 + SkFixed fCLastX, fCLastY; 1.86 + 1.87 + int setCubic(const SkPoint pts[4], const SkIRect* clip, int shiftUp); 1.88 + int updateCubic(); 1.89 +}; 1.90 + 1.91 +int SkEdge::setLine(const SkPoint& p0, const SkPoint& p1, int shift) { 1.92 + SkFDot6 x0, y0, x1, y1; 1.93 + 1.94 + { 1.95 + float scale = float(1 << (shift + 6)); 1.96 + x0 = int(p0.fX * scale); 1.97 + y0 = int(p0.fY * scale); 1.98 + x1 = int(p1.fX * scale); 1.99 + y1 = int(p1.fY * scale); 1.100 + } 1.101 + 1.102 + int winding = 1; 1.103 + 1.104 + if (y0 > y1) { 1.105 + SkTSwap(x0, x1); 1.106 + SkTSwap(y0, y1); 1.107 + winding = -1; 1.108 + } 1.109 + 1.110 + int top = SkFDot6Round(y0); 1.111 + int bot = SkFDot6Round(y1); 1.112 + 1.113 + // are we a zero-height line? 1.114 + if (top == bot) { 1.115 + return 0; 1.116 + } 1.117 + 1.118 + SkFixed slope = SkFDot6Div(x1 - x0, y1 - y0); 1.119 + const int dy = SkEdge_Compute_DY(top, y0); 1.120 + 1.121 + fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, dy)); // + SK_Fixed1/2 1.122 + fDX = slope; 1.123 + fFirstY = top; 1.124 + fLastY = bot - 1; 1.125 + fCurveCount = 0; 1.126 + fWinding = SkToS8(winding); 1.127 + fCurveShift = 0; 1.128 + return 1; 1.129 +} 1.130 + 1.131 + 1.132 +#endif