Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(655)

Unified Diff: skia/sgl/SkScan_Antihair.cpp

Issue 113827: Remove the remainder of the skia source code from the Chromium repo.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « skia/sgl/SkScan_AntiPath.cpp ('k') | skia/sgl/SkScan_Hairline.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: skia/sgl/SkScan_Antihair.cpp
===================================================================
--- skia/sgl/SkScan_Antihair.cpp (revision 16859)
+++ skia/sgl/SkScan_Antihair.cpp (working copy)
@@ -1,669 +0,0 @@
-/* libs/graphics/sgl/SkScan_Antihair.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 "SkScan.h"
-#include "SkBlitter.h"
-#include "SkColorPriv.h"
-#include "SkRegion.h"
-#include "SkFDot6.h"
-
-/* Our attempt to compute the worst case "bounds" for the horizontal and
- vertical cases has some numerical bug in it, and we sometimes undervalue
- our extends. The bug is that when this happens, we will set the clip to
- NULL (for speed), and thus draw outside of the clip by a pixel, which might
- only look bad, but it might also access memory outside of the valid range
- allcoated for the device bitmap.
-
- This define enables our fix to outset our "bounds" by 1, thus avoiding the
- chance of the bug, but at the cost of sometimes taking the rectblitter
- case (i.e. not setting the clip to NULL) when we might not actually need
- to. If we can improve/fix the actual calculations, then we can remove this
- step.
-*/
-#define OUTSET_BEFORE_CLIP_TEST true
-
-
-#define HLINE_STACK_BUFFER 100
-
-static inline int SmallDot6Scale(int value, int dot6) {
- SkASSERT((int16_t)value == value);
- SkASSERT((unsigned)dot6 <= 64);
- return SkMulS16(value, dot6) >> 6;
-}
-
-//#define TEST_GAMMA
-
-#ifdef TEST_GAMMA
- static uint8_t gGammaTable[256];
- #define ApplyGamma(table, alpha) (table)[alpha]
-
- static void build_gamma_table()
- {
- static bool gInit = false;
-
- if (gInit == false)
- {
- for (int i = 0; i < 256; i++)
- {
- SkFixed n = i * 257;
- n += n >> 15;
- SkASSERT(n >= 0 && n <= SK_Fixed1);
- n = SkFixedSqrt(n);
- n = n * 255 >> 16;
- // SkDebugf("morph %d -> %d\n", i, n);
- gGammaTable[i] = SkToU8(n);
- }
- gInit = true;
- }
- }
-#else
- #define ApplyGamma(table, alpha) SkToU8(alpha)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count, U8CPU alpha)
-{
- SkASSERT(count > 0);
-
- int16_t runs[HLINE_STACK_BUFFER + 1];
- uint8_t aa[HLINE_STACK_BUFFER];
-
- aa[0] = ApplyGamma(gGammaTable, alpha);
- do {
- int n = count;
- if (n > HLINE_STACK_BUFFER)
- n = HLINE_STACK_BUFFER;
-
- runs[0] = SkToS16(n);
- runs[n] = 0;
- blitter->blitAntiH(x, y, aa, runs);
- x += n;
- count -= n;
- } while (count > 0);
-}
-
-static SkFixed hline(int x, int stopx, SkFixed fy, SkFixed /*slope*/, SkBlitter* blitter, int mod64)
-{
- SkASSERT(x < stopx);
- int count = stopx - x;
- fy += SK_Fixed1/2;
-
- int y = fy >> 16;
- uint8_t a = (uint8_t)(fy >> 8);
-
- // lower line
- unsigned ma = SmallDot6Scale(a, mod64);
- if (ma) {
- call_hline_blitter(blitter, x, y, count, ma);
- }
-
- // upper line
- ma = SmallDot6Scale(255 - a, mod64);
- if (ma) {
- call_hline_blitter(blitter, x, y - 1, count, ma);
- }
-
- return fy - SK_Fixed1/2;
-}
-
-static SkFixed horish(int x, int stopx, SkFixed fy, SkFixed dy, SkBlitter* blitter, int mod64)
-{
- SkASSERT(x < stopx);
-
-#ifdef TEST_GAMMA
- const uint8_t* gamma = gGammaTable;
-#endif
- int16_t runs[2];
- uint8_t aa[1];
-
- runs[0] = 1;
- runs[1] = 0;
-
- fy += SK_Fixed1/2;
- do {
- int lower_y = fy >> 16;
- uint8_t a = (uint8_t)(fy >> 8);
- unsigned ma = SmallDot6Scale(a, mod64);
- if (ma)
- {
- aa[0] = ApplyGamma(gamma, ma);
- blitter->blitAntiH(x, lower_y, aa, runs);
- // the clipping blitters might edit runs, but should not affect us
- SkASSERT(runs[0] == 1);
- SkASSERT(runs[1] == 0);
- }
- ma = SmallDot6Scale(255 - a, mod64);
- if (ma)
- {
- aa[0] = ApplyGamma(gamma, ma);
- blitter->blitAntiH(x, lower_y - 1, aa, runs);
- // the clipping blitters might edit runs, but should not affect us
- SkASSERT(runs[0] == 1);
- SkASSERT(runs[1] == 0);
- }
- fy += dy;
- } while (++x < stopx);
-
- return fy - SK_Fixed1/2;
-}
-
-static SkFixed vline(int y, int stopy, SkFixed fx, SkFixed /*slope*/, SkBlitter* blitter, int mod64)
-{
- SkASSERT(y < stopy);
- fx += SK_Fixed1/2;
-
- int x = fx >> 16;
- int a = (uint8_t)(fx >> 8);
-
- unsigned ma = SmallDot6Scale(a, mod64);
- if (ma)
- blitter->blitV(x, y, stopy - y, ApplyGamma(gGammaTable, ma));
- ma = SmallDot6Scale(255 - a, mod64);
- if (ma)
- blitter->blitV(x - 1, y, stopy - y, ApplyGamma(gGammaTable, ma));
-
- return fx - SK_Fixed1/2;
-}
-
-static SkFixed vertish(int y, int stopy, SkFixed fx, SkFixed dx, SkBlitter* blitter, int mod64)
-{
- SkASSERT(y < stopy);
-#ifdef TEST_GAMMA
- const uint8_t* gamma = gGammaTable;
-#endif
- int16_t runs[3];
- uint8_t aa[2];
-
- runs[0] = 1;
- runs[2] = 0;
-
- fx += SK_Fixed1/2;
- do {
- int x = fx >> 16;
- uint8_t a = (uint8_t)(fx >> 8);
-
- aa[0] = ApplyGamma(gamma, SmallDot6Scale(255 - a, mod64));
- aa[1] = ApplyGamma(gamma, SmallDot6Scale(a, mod64));
- // the clippng blitters might overwrite this guy, so we have to reset it each time
- runs[1] = 1;
- blitter->blitAntiH(x - 1, y, aa, runs);
- // the clipping blitters might edit runs, but should not affect us
- SkASSERT(runs[0] == 1);
- SkASSERT(runs[2] == 0);
- fx += dx;
- } while (++y < stopy);
-
- return fx - SK_Fixed1/2;
-}
-
-typedef SkFixed (*LineProc)(int istart, int istop, SkFixed fstart, SkFixed slope, SkBlitter*, int);
-
-static inline SkFixed fastfixdiv(SkFDot6 a, SkFDot6 b)
-{
- SkASSERT((a << 16 >> 16) == a);
- SkASSERT(b != 0);
- return (a << 16) / b;
-}
-
-static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
- const SkIRect* clip, SkBlitter* blitter)
-{
- // check that we're no larger than 511 pixels (so we can do a faster div).
- // if we are, subdivide and call again
-
- if (SkAbs32(x1 - x0) > SkIntToFDot6(511) || SkAbs32(y1 - y0) > SkIntToFDot6(511))
- {
- int hx = (x0 + x1) >> 1;
- int hy = (y0 + y1) >> 1;
- do_anti_hairline(x0, y0, hx, hy, clip, blitter);
- do_anti_hairline(hx, hy, x1, y1, clip, blitter);
- return;
- }
-
- int scaleStart, scaleStop;
- int istart, istop;
- SkFixed fstart, slope;
- LineProc proc;
-
- if (SkAbs32(x1 - x0) > SkAbs32(y1 - y0)) // mostly horizontal
- {
- if (x0 > x1) { // we want to go left-to-right
- SkTSwap<SkFDot6>(x0, x1);
- SkTSwap<SkFDot6>(y0, y1);
- }
-
- istart = SkFDot6Floor(x0);
- istop = SkFDot6Ceil(x1);
- fstart = SkFDot6ToFixed(y0);
- if (y0 == y1) { // completely horizontal, take fast case
- slope = 0;
- proc = hline;
- } else {
- slope = fastfixdiv(y1 - y0, x1 - x0);
- SkASSERT(slope >= -SK_Fixed1 && slope <= SK_Fixed1);
- fstart += (slope * (32 - (x0 & 63)) + 32) >> 6;
- proc = horish;
- }
-
- SkASSERT(istop > istart);
- if (istop - istart == 1) {
- scaleStart = x1 - x0;
- SkASSERT(scaleStart >= 0 && scaleStart <= 64);
- scaleStop = 0;
- } else {
- scaleStart = 64 - (x0 & 63);
- scaleStop = x1 & 63;
- }
-
- if (clip)
- {
- if (istart >= clip->fRight || istop <= clip->fLeft)
- return;
- if (istart < clip->fLeft)
- {
- fstart += slope * (clip->fLeft - istart);
- istart = clip->fLeft;
- scaleStart = 64;
- }
- if (istop > clip->fRight) {
- istop = clip->fRight;
- scaleStop = 64;
- }
- SkASSERT(istart <= istop);
- if (istart == istop)
- return;
-
- // now test if our Y values are completely inside the clip
- int top, bottom;
- if (slope >= 0) // T2B
- {
- top = SkFixedFloor(fstart - SK_FixedHalf);
- bottom = SkFixedCeil(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
- }
- else // B2T
- {
- bottom = SkFixedCeil(fstart + SK_FixedHalf);
- top = SkFixedFloor(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
- }
- if (OUTSET_BEFORE_CLIP_TEST) {
- top -= 1;
- bottom += 1;
- }
- if (top >= clip->fBottom || bottom <= clip->fTop)
- return;
- if (clip->fTop <= top && clip->fBottom >= bottom)
- clip = NULL;
- }
- }
- else // mostly vertical
- {
- if (y0 > y1) // we want to go top-to-bottom
- {
- SkTSwap<SkFDot6>(x0, x1);
- SkTSwap<SkFDot6>(y0, y1);
- }
-
- istart = SkFDot6Floor(y0);
- istop = SkFDot6Ceil(y1);
- fstart = SkFDot6ToFixed(x0);
- if (x0 == x1)
- {
- if (y0 == y1) { // are we zero length?
- return; // nothing to do
- }
- slope = 0;
- proc = vline;
- }
- else
- {
- slope = fastfixdiv(x1 - x0, y1 - y0);
- SkASSERT(slope <= SK_Fixed1 && slope >= -SK_Fixed1);
- fstart += (slope * (32 - (y0 & 63)) + 32) >> 6;
- proc = vertish;
- }
-
- SkASSERT(istop > istart);
- if (istop - istart == 1) {
- scaleStart = y1 - y0;
- SkASSERT(scaleStart >= 0 && scaleStart <= 64);
- scaleStop = 0;
- } else {
- scaleStart = 64 - (y0 & 63);
- scaleStop = y1 & 63;
- }
-
- if (clip)
- {
- if (istart >= clip->fBottom || istop <= clip->fTop)
- return;
- if (istart < clip->fTop)
- {
- fstart += slope * (clip->fTop - istart);
- istart = clip->fTop;
- scaleStart = 64;
- }
- if (istop > clip->fBottom) {
- istop = clip->fBottom;
- scaleStop = 64;
- }
- SkASSERT(istart <= istop);
- if (istart == istop)
- return;
-
- // now test if our X values are completely inside the clip
- int left, right;
- if (slope >= 0) // L2R
- {
- left = SkFixedFloor(fstart - SK_FixedHalf);
- right = SkFixedCeil(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
- }
- else // R2L
- {
- right = SkFixedCeil(fstart + SK_FixedHalf);
- left = SkFixedFloor(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
- }
- if (OUTSET_BEFORE_CLIP_TEST) {
- left -= 1;
- right += 1;
- }
- if (left >= clip->fRight || right <= clip->fLeft)
- return;
- if (clip->fLeft <= left && clip->fRight >= right)
- clip = NULL;
- }
- }
-
- SkRectClipBlitter rectClipper;
- if (clip)
- {
- rectClipper.init(blitter, *clip);
- blitter = &rectClipper;
- }
-
- fstart = proc(istart, istart + 1, fstart, slope, blitter, scaleStart);
- istart += 1;
- int fullSpans = istop - istart - 1;
- if (fullSpans > 0) {
- fstart = proc(istart, istart + fullSpans, fstart, slope, blitter, 64);
- }
- if (scaleStop > 0) {
- proc(istop - 1, istop, fstart, slope, blitter, scaleStop);
- }
-}
-
-void SkScan::AntiHairLine(const SkPoint& pt0, const SkPoint& pt1,
- const SkRegion* clip, SkBlitter* blitter)
-{
- if (clip && clip->isEmpty())
- return;
-
- SkASSERT(clip == NULL || !clip->getBounds().isEmpty());
-
-#ifdef TEST_GAMMA
- build_gamma_table();
-#endif
-
- SkFDot6 x0 = SkScalarToFDot6(pt0.fX);
- SkFDot6 y0 = SkScalarToFDot6(pt0.fY);
- SkFDot6 x1 = SkScalarToFDot6(pt1.fX);
- SkFDot6 y1 = SkScalarToFDot6(pt1.fY);
-
- if (clip)
- {
- SkFDot6 left = SkMin32(x0, x1);
- SkFDot6 top = SkMin32(y0, y1);
- SkFDot6 right = SkMax32(x0, x1);
- SkFDot6 bottom = SkMax32(y0, y1);
- SkIRect ir;
-
- ir.set( SkFDot6Floor(left) - 1,
- SkFDot6Floor(top) - 1,
- SkFDot6Ceil(right) + 1,
- SkFDot6Ceil(bottom) + 1);
-
- if (clip->quickReject(ir))
- return;
- if (!clip->quickContains(ir))
- {
- SkRegion::Cliperator iter(*clip, ir);
- const SkIRect* r = &iter.rect();
-
- while (!iter.done())
- {
- do_anti_hairline(x0, y0, x1, y1, r, blitter);
- iter.next();
- }
- return;
- }
- // fall through to no-clip case
- }
- do_anti_hairline(x0, y0, x1, y1, NULL, blitter);
-}
-
-void SkScan::AntiHairRect(const SkRect& rect, const SkRegion* clip, SkBlitter* blitter)
-{
- if (clip)
- {
- SkIRect ir;
- SkRect r = rect;
-
- r.inset(-SK_Scalar1/2, -SK_Scalar1/2);
- r.roundOut(&ir);
- if (clip->quickReject(ir))
- return;
- if (clip->quickContains(ir))
- clip = NULL;
- }
-
- SkPoint p0, p1;
-
- p0.set(rect.fLeft, rect.fTop);
- p1.set(rect.fRight, rect.fTop);
- SkScan::AntiHairLine(p0, p1, clip, blitter);
- p0.set(rect.fRight, rect.fBottom);
- SkScan::AntiHairLine(p0, p1, clip, blitter);
- p1.set(rect.fLeft, rect.fBottom);
- SkScan::AntiHairLine(p0, p1, clip, blitter);
- p0.set(rect.fLeft, rect.fTop);
- SkScan::AntiHairLine(p0, p1, clip, blitter);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-typedef int FDot8; // 24.8 integer fixed point
-
-static inline FDot8 SkFixedToFDot8(SkFixed x) {
- return (x + 0x80) >> 8;
-}
-
-static void do_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha, SkBlitter* blitter)
-{
- SkASSERT(L < R);
-
- if ((L >> 8) == ((R - 1) >> 8)) // 1x1 pixel
- {
- blitter->blitV(L >> 8, top, 1, SkAlphaMul(alpha, R - L));
- return;
- }
-
- int left = L >> 8;
-
- if (L & 0xFF)
- {
- blitter->blitV(left, top, 1, SkAlphaMul(alpha, 256 - (L & 0xFF)));
- left += 1;
- }
-
- int rite = R >> 8;
- int width = rite - left;
- if (width > 0)
- call_hline_blitter(blitter, left, top, width, alpha);
-
- if (R & 0xFF)
- blitter->blitV(rite, top, 1, SkAlphaMul(alpha, R & 0xFF));
-}
-
-static void antifillrect(const SkXRect& xr, SkBlitter* blitter)
-{
- FDot8 L = SkFixedToFDot8(xr.fLeft);
- FDot8 T = SkFixedToFDot8(xr.fTop);
- FDot8 R = SkFixedToFDot8(xr.fRight);
- FDot8 B = SkFixedToFDot8(xr.fBottom);
-
- // check for empty now that we're in our reduced precision space
- if (L >= R || T >= B)
- return;
-
- int top = T >> 8;
- if (top == ((B - 1) >> 8)) // just one scanline high
- {
- do_scanline(L, top, R, B - T - 1, blitter);
- return;
- }
-
- if (T & 0xFF)
- {
- do_scanline(L, top, R, 256 - (T & 0xFF), blitter);
- top += 1;
- }
-
- int bot = B >> 8;
- int height = bot - top;
- if (height > 0)
- {
- int left = L >> 8;
- if (L & 0xFF)
- {
- blitter->blitV(left, top, height, 256 - (L & 0xFF));
- left += 1;
- }
- int rite = R >> 8;
- int width = rite - left;
- if (width > 0)
- blitter->blitRect(left, top, width, height);
- if (R & 0xFF)
- blitter->blitV(rite, top, height, R & 0xFF);
- }
-
- if (B & 0xFF)
- do_scanline(L, bot, R, B & 0xFF, blitter);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkScan::AntiFillXRect(const SkXRect& xr, const SkRegion* clip,
- SkBlitter* blitter) {
- if (clip) {
- SkIRect outerBounds;
- XRect_roundOut(xr, &outerBounds);
-
- if (clip->isRect()) {
- const SkIRect& clipBounds = clip->getBounds();
-
- if (clipBounds.contains(outerBounds)) {
- antifillrect(xr, blitter);
- } else {
- SkXRect tmpR;
- // this keeps our original edges fractional
- XRect_set(&tmpR, clipBounds);
- if (tmpR.intersect(xr)) {
- antifillrect(tmpR, blitter);
- }
- }
- } else {
- SkRegion::Cliperator clipper(*clip, outerBounds);
- const SkIRect& rr = clipper.rect();
-
- while (!clipper.done()) {
- SkXRect tmpR;
-
- // this keeps our original edges fractional
- XRect_set(&tmpR, rr);
- if (tmpR.intersect(xr)) {
- antifillrect(tmpR, blitter);
- }
- clipper.next();
- }
- }
- } else {
- antifillrect(xr, blitter);
- }
-}
-
-#ifdef SK_SCALAR_IS_FLOAT
-
-/* This guy takes a float-rect, but with the key improvement that it has
- already been clipped, so we know that it is safe to convert it into a
- XRect (fixedpoint), as it won't overflow.
-*/
-static void antifillrect(const SkRect& r, SkBlitter* blitter) {
- SkXRect xr;
-
- XRect_set(&xr, r);
- antifillrect(xr, blitter);
-}
-
-/* We repeat the clipping logic of AntiFillXRect because the float rect might
- overflow if we blindly converted it to an XRect. This sucks that we have to
- repeat the clipping logic, but I don't see how to share the code/logic.
-
- We clip r (as needed) into one or more (smaller) float rects, and then pass
- those to our version of antifillrect, which converts it into an XRect and
- then calls the blit.
-*/
-void SkScan::AntiFillRect(const SkRect& r, const SkRegion* clip,
- SkBlitter* blitter) {
- if (clip) {
- SkIRect outerBounds;
- r.roundOut(&outerBounds);
-
- if (clip->isRect()) {
- const SkIRect& clipBounds = clip->getBounds();
-
- if (clipBounds.contains(outerBounds)) {
- antifillrect(r, blitter);
- } else {
- SkRect tmpR;
- // this keeps our original edges fractional
- tmpR.set(clipBounds);
- if (tmpR.intersect(r)) {
- antifillrect(tmpR, blitter);
- }
- }
- } else {
- SkRegion::Cliperator clipper(*clip, outerBounds);
- const SkIRect& rr = clipper.rect();
-
- while (!clipper.done()) {
- SkRect tmpR;
- // this keeps our original edges fractional
- tmpR.set(rr);
- if (tmpR.intersect(r)) {
- antifillrect(tmpR, blitter);
- }
- clipper.next();
- }
- }
- } else {
- antifillrect(r, blitter);
- }
-}
-
-#endif
-
-
« no previous file with comments | « skia/sgl/SkScan_AntiPath.cpp ('k') | skia/sgl/SkScan_Hairline.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698