diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/core/SkEdge.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/core/SkEdge.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,129 @@ + +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SkEdge_DEFINED +#define SkEdge_DEFINED + +#include "SkRect.h" +#include "SkFDot6.h" +#include "SkMath.h" + +// This correctly favors the lower-pixel when y0 is on a 1/2 pixel boundary +#define SkEdge_Compute_DY(top, y0) ((top << 6) + 32 - (y0)) + +struct SkEdge { + enum Type { + kLine_Type, + kQuad_Type, + kCubic_Type + }; + + SkEdge* fNext; + SkEdge* fPrev; + + SkFixed fX; + SkFixed fDX; + int32_t fFirstY; + int32_t fLastY; + int8_t fCurveCount; // only used by kQuad(+) and kCubic(-) + uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception + uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic + int8_t fWinding; // 1 or -1 + + int setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip, + int shiftUp); + // call this version if you know you don't have a clip + inline int setLine(const SkPoint& p0, const SkPoint& p1, int shiftUp); + inline int updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by); + void chopLineWithClip(const SkIRect& clip); + + inline bool intersectsClip(const SkIRect& clip) const { + SkASSERT(fFirstY < clip.fBottom); + return fLastY >= clip.fTop; + } + +#ifdef SK_DEBUG + void dump() const { + SkDebugf("edge: firstY:%d lastY:%d x:%g dx:%g w:%d\n", fFirstY, fLastY, SkFixedToFloat(fX), SkFixedToFloat(fDX), fWinding); + } + + void validate() const { + SkASSERT(fPrev && fNext); + SkASSERT(fPrev->fNext == this); + SkASSERT(fNext->fPrev == this); + + SkASSERT(fFirstY <= fLastY); + SkASSERT(SkAbs32(fWinding) == 1); + } +#endif +}; + +struct SkQuadraticEdge : public SkEdge { + SkFixed fQx, fQy; + SkFixed fQDx, fQDy; + SkFixed fQDDx, fQDDy; + SkFixed fQLastX, fQLastY; + + int setQuadratic(const SkPoint pts[3], int shiftUp); + int updateQuadratic(); +}; + +struct SkCubicEdge : public SkEdge { + SkFixed fCx, fCy; + SkFixed fCDx, fCDy; + SkFixed fCDDx, fCDDy; + SkFixed fCDDDx, fCDDDy; + SkFixed fCLastX, fCLastY; + + int setCubic(const SkPoint pts[4], const SkIRect* clip, int shiftUp); + int updateCubic(); +}; + +int SkEdge::setLine(const SkPoint& p0, const SkPoint& p1, int shift) { + SkFDot6 x0, y0, x1, y1; + + { + float scale = float(1 << (shift + 6)); + x0 = int(p0.fX * scale); + y0 = int(p0.fY * scale); + x1 = int(p1.fX * scale); + y1 = int(p1.fY * scale); + } + + int winding = 1; + + if (y0 > y1) { + SkTSwap(x0, x1); + SkTSwap(y0, y1); + winding = -1; + } + + int top = SkFDot6Round(y0); + int bot = SkFDot6Round(y1); + + // are we a zero-height line? + if (top == bot) { + return 0; + } + + SkFixed slope = SkFDot6Div(x1 - x0, y1 - y0); + const int dy = SkEdge_Compute_DY(top, y0); + + fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, dy)); // + SK_Fixed1/2 + fDX = slope; + fFirstY = top; + fLastY = bot - 1; + fCurveCount = 0; + fWinding = SkToS8(winding); + fCurveShift = 0; + return 1; +} + + +#endif