return activeOp(xorMiMask, xorSuMask, index, endIndex, op, sumMiWinding, sumSuWinding,
maxWinding, sumWinding, oppMaxWinding, oppSumWinding);
}
-
+
bool activeOp(int xorMiMask, int xorSuMask,
int index, int endIndex, ShapeOp op,
- int& sumMiWinding, int& sumSuWinding,
+ int& sumMiWinding, int& sumSuWinding,
int& maxWinding, int& sumWinding, int& oppMaxWinding, int& oppSumWinding) {
setUpWindings(index, endIndex, sumMiWinding, sumSuWinding,
maxWinding, sumWinding, oppMaxWinding, oppSumWinding);
The Opp variable name part designates that the value is for the Opposite operator.
Opposite values result from combining coincident spans.
*/
-
+
Segment* findNextOp(SkTDArray<Span*>& chase, int& nextStart, int& nextEnd,
bool& unsortable, ShapeOp op, const int xorMiMask, const int xorSuMask) {
const int startIndex = nextStart;
- const int endIndex = nextEnd;
+ const int endIndex = nextEnd;
SkASSERT(startIndex != endIndex);
const int count = fTs.count();
SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
markDoneBinary(SkMin32(index, endIndex), winding, oppWinding);
return last;
}
-
+
Span* markAndChaseDoneBinary(int index, int endIndex) {
int step = SkSign32(endIndex - index);
Span* last = innerChaseDoneBinary(index, step);
markWinding(min, winding);
return last;
}
-
+
Span* markAndChaseWinding(int index, int endIndex, int winding, int oppWinding) {
int min = SkMin32(index, endIndex);
int step = SkSign32(endIndex - index);
}
return oppWinding;
}
-
+
int updateOppWinding(const Angle* angle) const {
int startIndex = angle->start();
int endIndex = angle->end();
clips are Booleaned together. */
SkClipStack::BoundsType fFiniteBoundType;
SkRect fFiniteBound;
-
+
// When element is applied to the previous elements in the stack is the result known to be
// equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle.
bool fIsIntersectionOfRects;
inline bool operator!=(const Element& b) const;
inline bool canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const;
/* This method checks to see if two rect clips can be safely merged into one. The issue here
- is that to be strictly correct all the edges of the resulting rect must have the same
+ is that to be strictly correct all the edges of the resulting rect must have the same
anti-aliasing. */
bool rectRectIntersectAllowed(const SkRect& newR, bool newAA) const;
/** Determines possible finite bounds for the Element given the previous element of the
// add RR rendering shader to Ganesh (akin to cicle drawing code)
// - only for simple RRs
// detect and triangulate RRectorii rather than falling back to SW in Ganesh
-//
+//
/** \class SkRRect
- The SkRRect class represents a rounded rect with a potentially different
- radii for each corner. It does not have a constructor so must be
- initialized with one of the initialization functions (e.g., setEmpty,
+ The SkRRect class represents a rounded rect with a potentially different
+ radii for each corner. It does not have a constructor so must be
+ initialized with one of the initialization functions (e.g., setEmpty,
setRectRadii, etc.)
- This class is intended to roughly match CSS' border-*-*-radius capabilities.
+ This class is intended to roughly match CSS' border-*-*-radius capabilities.
This means:
- If either of a corner's radii are 0 the corner will be square.
+ If either of a corner's radii are 0 the corner will be square.
Negative radii are not allowed (they are clamped to zero).
If the corner curves overlap they will be proportionally reduced to fit.
*/
class SK_API SkRRect {
public:
- /**
+ /**
* Enum to capture the various possible subtypes of RR. Accessed
* by type(). The subtypes become progressively less restrictive.
*/
//!< The RR is actually a (non-empty) rect (i.e., at least one radius
//!< at each corner is zero)
- kRect_Type,
+ kRect_Type,
- //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal
+ //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal
//!< and >= width/2 and all the y radii are equal and >= height/2
- kOval_Type,
+ kOval_Type,
- //!< The RR is non-empty and all the x radii are equal & all y radii
- //!< are equal but it is not an oval (i.e., there are lines between
+ //!< The RR is non-empty and all the x radii are equal & all y radii
+ //!< are equal but it is not an oval (i.e., there are lines between
//!< the curves) nor a rect (i.e., both radii are non-zero)
- kSimple_Type,
+ kSimple_Type,
//!< A fully general (non-empty) RR. Some of the x and/or y radii are
//!< different from the others and there must be one corner where
kComplex_Type,
};
- /**
+ /**
* Returns the RR's sub type.
*/
Type type() const {
return fType;
}
- /**
+ /**
* Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii.
*/
- void setEmpty() {
+ void setEmpty() {
fRect.setEmpty();
memset(fRadii, 0, sizeof(fRadii));
fType = kEmpty_Type;
SkDEBUGCODE(this->validate();)
}
- /**
+ /**
* Set this RR to match the supplied rect. All radii will be 0.
*/
void setRect(const SkRect& rect) {
SkDEBUGCODE(this->validate();)
}
- /**
+ /**
* Set this RR to match the supplied oval. All x radii will equal half the
* width and all y radii will equal half the height.
*/
SkDEBUGCODE(this->validate();)
}
- /**
+ /**
* Initialize the RR with the same radii for all four corners.
*/
void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad);
- /**
+ /**
* Initialize the RR with potentially different radii for all four corners.
*/
void setRectRadii(const SkRect& rect, const SkVector radii[4]);
- // The radii are stored in UL, UR, LR, LL order.
+ // The radii are stored in UL, UR, LR, LL order.
enum Corner {
kUpperLeft_Corner,
kUpperRight_Corner,
SkRect fRect;
// Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[]
- SkVector fRadii[4];
+ SkVector fRadii[4];
mutable Type fType;
// TODO: add padding so we can use memcpy for flattening and not copy
// uninitialized data
uint32_t value;
const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
SkASSERT(bitmap);
-
+
uint16_t* addr = bitmap->getAddr16(0, 0);
int rb = bitmap->rowBytes();
-
+
for (int i = 0; i < count; i++) {
int x = SkScalarFloorToInt(devPts[i].fX);
int y = SkScalarFloorToInt(devPts[i].fY);
uint32_t value;
const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
SkASSERT(bitmap);
-
+
SkPMColor* addr = bitmap->getAddr32(0, 0);
int rb = bitmap->rowBytes();
-
+
for (int i = 0; i < count; i++) {
int x = SkScalarFloorToInt(devPts[i].fX);
int y = SkScalarFloorToInt(devPts[i].fY);
for (int i = 0; i < count; i++) {
SkFixed x = SkScalarToFixed(devPts[i].fX);
SkFixed y = SkScalarToFixed(devPts[i].fY);
-
+
SkXRect r;
r.fLeft = x - radius;
r.fTop = y - radius;
r.fRight = x + radius;
r.fBottom = y + radius;
-
+
SkScan::FillXRect(r, *rec.fRC, blitter);
}
}
}
// Proportionally scale down all radii to fit. Find the minimum ratio
- // of a side and the radii on that side (for all four sides) and use
+ // of a side and the radii on that side (for all four sides) and use
// that to scale down _all_ the radii. This algorithm is from the
// W3 spec (http://www.w3.org/TR/css3-background/) section 5.5 - Overlapping
// Curves:
- // "Let f = min(Li/Si), where i is one of { top, right, bottom, left },
+ // "Let f = min(Li/Si), where i is one of { top, right, bottom, left },
// Si is the sum of the two corresponding radii of the corners on side i,
- // and Ltop = Lbottom = the width of the box,
- // and Lleft = Lright = the height of the box.
+ // and Ltop = Lbottom = the width of the box,
+ // and Lleft = Lright = the height of the box.
// If f < 1, then all corner radii are reduced by multiplying them by f."
SkScalar scale = SK_Scalar1;
canonicalPt.set(x - fRect.centerX(), y - fRect.centerY());
index = kUpperLeft_Corner; // any corner will do in this case
} else {
- if (x < fRect.fLeft + fRadii[kUpperLeft_Corner].fX &&
+ if (x < fRect.fLeft + fRadii[kUpperLeft_Corner].fX &&
y < fRect.fTop + fRadii[kUpperLeft_Corner].fY) {
// UL corner
index = kUpperLeft_Corner;
SkASSERT(fRect.isEmpty());
SkASSERT(allRadiiZero && allRadiiSame && allCornersSquare);
- SkASSERT(0 == fRect.fLeft && 0 == fRect.fTop &&
+ SkASSERT(0 == fRect.fLeft && 0 == fRect.fTop &&
0 == fRect.fRight && 0 == fRect.fBottom);
break;
case kRect_Type:
SkCanvas::Config8888 config8888) SK_OVERRIDE {
not_supported();
}
-
+
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE {
this->addBitmapFromPaint(paint);
}
class NoSaveLayerCanvas : public SkCanvas {
public:
NoSaveLayerCanvas(SkDevice* device) : INHERITED(device) {}
-
+
// turn saveLayer() into save() for speed, should not affect correctness.
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
SaveFlags flags) SK_OVERRIDE {
SkAutoDataUnref adu(data);
gather_from_colors(result, refs, N, &array);
-
+
/*
* GatherPixelRefs is conservative, so it can return more bitmaps
* that we actually can see (usually because of conservative bounds
// Test out initialization methods
SkPoint zeroPt = { 0.0, 0.0 };
SkRRect empty;
-
+
empty.setEmpty();
REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type());
REPORTER_ASSERT(reporter, rr2.rect() == rect);
for (int i = 0; i < 4; ++i) {
- REPORTER_ASSERT(reporter,
+ REPORTER_ASSERT(reporter,
rr2.radii((SkRRect::Corner) i).equalsWithinTolerance(halfPoint));
}
for (int i = 0; i < 4; ++i) {
REPORTER_ASSERT(reporter, p == rr3.radii((SkRRect::Corner) i));
}
-
+
//----
SkPoint radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } };
// Test out the cases when the RR degenerates to a rect
static void test_round_rect_rects(skiatest::Reporter* reporter) {
SkRect r;
- static const SkPoint pts[] = {
+ static const SkPoint pts[] = {
// Upper Left
{ -SK_Scalar1, -SK_Scalar1 }, // out
{ SK_Scalar1, SK_Scalar1 }, // in
//----
SkRRect empty;
-
+
empty.setEmpty();
REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type());
static const SkScalar kEps = 0.1f;
static const SkScalar kWidthTol = SkScalarHalf(kWidth) * (SK_Scalar1 - SK_ScalarRoot2Over2);
static const SkScalar kHeightTol = SkScalarHalf(kHeight) * (SK_Scalar1 - SK_ScalarRoot2Over2);
- static const SkPoint pts[] = {
+ static const SkPoint pts[] = {
// Upper Left
{ kWidthTol - kEps, kHeightTol - kEps }, // out
{ kWidthTol + kEps, kHeightTol + kEps }, // in
static void test_round_rect_general(skiatest::Reporter* reporter) {
static const SkScalar kEps = 0.1f;
static const SkScalar kDist20 = 20 * (SK_Scalar1 - SK_ScalarRoot2Over2);
- static const SkPoint pts[] = {
+ static const SkPoint pts[] = {
// Upper Left
{ kDist20 - kEps, kDist20 - kEps }, // out
{ kDist20 + kEps, kDist20 + kEps }, // in
//----
static const SkScalar kDist50 = 50*(SK_Scalar1 - SK_ScalarRoot2Over2);
- static const SkPoint pts2[] = {
+ static const SkPoint pts2[] = {
// Upper Left
{ -SK_Scalar1, -SK_Scalar1 }, // out
{ SK_Scalar1, SK_Scalar1 }, // in
SkIntToScalar(fPicture->height()));
SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds);
SkSafeUnref(data);
-
+
return NULL == path; // we don't have anything to write
}
PictureRenderer* CreateGatherPixelRefsRenderer() {
return SkNEW(GatherRenderer);
}
-
+
} // namespace sk_tools