// called from a curve subclass int SkEdge::updateLine(SkFixed x0, SkFixed y0, SkFixed x1, SkFixed y1) { SkASSERT(fWinding == 1 || fWinding == -1); SkASSERT(fCurveCount != 0); // SkASSERT(fCurveShift != 0); y0 >>= 10; y1 >>= 10; SkASSERT(y0 <= y1); int top = SkFDot6Round(y0); int bot = SkFDot6Round(y1); // SkASSERT(top >= fFirstY); // are we a zero-height line? if (top == bot) return 0; x0 >>= 10; x1 >>= 10; SkFixed slope = SkFDot6Div(x1 - x0, y1 - y0); const SkFDot6 dy = SkEdge_Compute_DY(top, y0); fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, dy)); // + SK_Fixed1/2 fDX = slope; fFirstY = top; fLastY = bot - 1; return 1; }
int SkEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip, int shift) { SkFDot6 x0, y0, x1, y1; { #ifdef SK_SCALAR_IS_FLOAT 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); #else shift = 10 - shift; x0 = p0.fX >> shift; y0 = p0.fY >> shift; x1 = p1.fX >> shift; y1 = p1.fY >> shift; #endif } 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; } // are we completely above or below the clip? if (NULL != clip && (top >= clip->fBottom || bot <= clip->fTop)) { return 0; } SkFixed slope = SkFDot6Div(x1 - x0, y1 - y0); fX = SkFDot6ToFixed(x0 + SkFixedMul(slope, (32 - y0) & 63)); // + SK_Fixed1/2 fDX = slope; fFirstY = top; fLastY = bot - 1; fCurveCount = 0; fWinding = SkToS8(winding); fCurveShift = 0; if (clip) { this->chopLineWithClip(*clip); } return 1; }
int SkEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip, int shift) { SkFDot6 x0, y0, x1, y1; { #ifdef SK_RASTERIZE_EVEN_ROUNDING x0 = SkScalarRoundToFDot6(p0.fX, shift); y0 = SkScalarRoundToFDot6(p0.fY, shift); x1 = SkScalarRoundToFDot6(p1.fX, shift); y1 = SkScalarRoundToFDot6(p1.fY, shift); #else 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); #endif } 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; } // are we completely above or below the clip? if (clip && (top >= clip->fBottom || bot <= clip->fTop)) { return 0; } SkFixed slope = SkFDot6Div(x1 - x0, y1 - y0); const SkFDot6 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; if (clip) { this->chopLineWithClip(*clip); } return 1; }
static inline SkFixed quickSkFDot6Div(SkFDot6 a, SkFDot6 b) { if (SkAbs32(b) < kInverseTableSize) { SkASSERT((int64_t)a * QuickFDot6Inverse::Lookup(b) <= SK_MaxS32); SkFixed ourAnswer = (a * QuickFDot6Inverse::Lookup(b)) >> 6; #ifdef SK_DEBUG SkFixed directAnswer = SkFDot6Div(a, b); SkASSERT( (directAnswer == 0 && ourAnswer == 0) || SkFixedDiv(SkAbs32(directAnswer - ourAnswer), SkAbs32(directAnswer)) <= 1 << 10 ); #endif return ourAnswer; } else {