aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkDraw.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-01-13 18:30:42 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-01-13 18:30:42 +0000
commita76de3d1a92134c3e95ad7fce99234f92fa48268 (patch)
treec597c62c5daaf56b81a5f69819a528a9e5e8a1da /src/core/SkDraw.cpp
parentd3b13bd5af686278a6d2586a5d6304cb9fba70b7 (diff)
If you #define SK_ALLOW_OVER_32K_BITMAPS, then skia will try to draw bitmaps
whose dimensions exceed 32K. In my testing, this is fine, but I'm coding this as an opt-in feature for now, to allow for more testing before its enabled by default. git-svn-id: http://skia.googlecode.com/svn/trunk@693 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkDraw.cpp')
-rw-r--r--src/core/SkDraw.cpp228
1 files changed, 115 insertions, 113 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index a117ab7216..541860c12a 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2,16 +2,16 @@
**
** 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
+** 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
+** 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
+** 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.
*/
@@ -47,13 +47,13 @@ public:
fDraw->fBounder = fBounder;
}
}
-
+
void clearBounder(const SkDraw* draw) {
fDraw = const_cast<SkDraw*>(draw);
fBounder = draw->fBounder;
fDraw->fBounder = NULL;
}
-
+
private:
SkDraw* fDraw;
SkBounder* fBounder;
@@ -186,9 +186,9 @@ static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap,
if (!SkXfermode::IsMode(paint.getXfermode(), &mode)) {
return NULL;
}
-
+
SkColor color = paint.getColor();
-
+
// collaps modes based on color...
if (SkXfermode::kSrcOver_Mode == mode) {
unsigned alpha = SkColorGetA(color);
@@ -198,7 +198,7 @@ static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap,
mode = SkXfermode::kSrc_Mode;
}
}
-
+
switch (mode) {
case SkXfermode::kClear_Mode:
// SkDebugf("--- D_Clear_BitmapXferProc\n");
@@ -208,7 +208,7 @@ static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap,
return D_Dst_BitmapXferProc; // ignore data
case SkXfermode::kSrc_Mode: {
/*
- should I worry about dithering for the lower depths?
+ should I worry about dithering for the lower depths?
*/
SkPMColor pmc = SkPreMultiplyColor(color);
switch (bitmap.config()) {
@@ -291,7 +291,7 @@ void SkDraw::drawPaint(const SkPaint& paint) const {
if (fBounder && !fBounder->doIRect(devRect)) {
return;
}
-
+
/* If we don't have a shader (i.e. we're just a solid color) we may
be faster to operate directly on the device bitmap, rather than invoking
a blitter. Esp. true for xfermodes, which require a colorshader to be
@@ -304,7 +304,7 @@ void SkDraw::drawPaint(const SkPaint& paint) const {
if (D_Dst_BitmapXferProc == proc) { // nothing to do
return;
}
-
+
SkRegion::Iterator iter(*fClip);
while (!iter.done()) {
CallBitmapXferProc(*fBitmap, iter.rect(), proc, procData);
@@ -323,15 +323,15 @@ struct PtProcRec {
SkCanvas::PointMode fMode;
const SkPaint* fPaint;
const SkRegion* fClip;
-
+
// computed values
SkFixed fRadius;
-
+
typedef void (*Proc)(const PtProcRec&, const SkPoint devPts[], int count,
SkBlitter*);
bool init(SkCanvas::PointMode, const SkPaint&, const SkMatrix* matrix,
- const SkRegion* clip);
+ const SkRegion* clip);
Proc chooseProc(SkBlitter* blitter);
};
@@ -339,7 +339,7 @@ static void bw_pt_rect_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
int count, SkBlitter* blitter) {
SkASSERT(rec.fClip->isRect());
const SkIRect& r = rec.fClip->getBounds();
-
+
for (int i = 0; i < count; i++) {
int x = SkScalarFloor(devPts[i].fX);
int y = SkScalarFloor(devPts[i].fY);
@@ -357,7 +357,7 @@ static void bw_pt_rect_16_hair_proc(const PtProcRec& rec,
uint32_t value;
const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
SkASSERT(bitmap);
-
+
uint16_t* addr = bitmap->getAddr16(0, 0);
int rb = bitmap->rowBytes();
@@ -420,13 +420,13 @@ static void bw_square_proc(const PtProcRec& rec, const SkPoint devPts[],
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.fClip, blitter);
}
}
@@ -437,13 +437,13 @@ static void aa_square_proc(const PtProcRec& rec, const SkPoint devPts[],
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::AntiFillXRect(r, rec.fClip, blitter);
}
}
@@ -483,7 +483,7 @@ bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint,
PtProcRec::Proc PtProcRec::chooseProc(SkBlitter* blitter) {
Proc proc = NULL;
-
+
// for our arrays
SkASSERT(0 == SkCanvas::kPoints_PointMode);
SkASSERT(1 == SkCanvas::kLines_PointMode);
@@ -554,7 +554,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
if ((long)count <= 0) {
return;
}
-
+
SkAutoRestoreBounder arb;
if (fBounder) {
@@ -569,7 +569,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
SkASSERT(pts != NULL);
SkDEBUGCODE(this->validate();)
-
+
// nothing to draw
if (fClip->isEmpty() ||
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
@@ -586,7 +586,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
PtProcRec::Proc proc = rec.chooseProc(bltr);
// we have to back up subsequent passes if we're in polygon mode
const size_t backup = (SkCanvas::kPolygon_PointMode == mode);
-
+
do {
size_t n = count;
if (n > MAX_DEV_PTS) {
@@ -609,11 +609,11 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
SkScalar width = paint.getStrokeWidth();
SkScalar radius = SkScalarHalf(width);
-
+
if (paint.getStrokeCap() == SkPaint::kRound_Cap) {
SkPath path;
SkMatrix preMatrix;
-
+
path.addCircle(0, 0, radius);
for (size_t i = 0; i < count; i++) {
preMatrix.setTranslate(pts[i].fX, pts[i].fY);
@@ -628,7 +628,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
}
} else {
SkRect r;
-
+
for (size_t i = 0; i < count; i++) {
r.fLeft = pts[i].fX - radius;
r.fTop = pts[i].fY - radius;
@@ -779,7 +779,7 @@ public:
fPaint->setColor(fColor);
fPaint->setStrokeWidth(fWidth);
}
-
+
private:
SkPaint* fPaint;
SkColor fColor;
@@ -835,7 +835,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint,
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style ||
paint.getRasterizer()) {
SkPath* result = pathPtr;
-
+
if (!pathIsMutable) {
result = &tmpPath;
pathIsMutable = true;
@@ -852,7 +852,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint,
}
// at this point we're done with prePathMatrix
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
-
+
/*
If the device thickness < 1.0, then make it a hairline, and
modulate alpha if the thickness is even smaller (e.g. thickness == 0.5
@@ -860,7 +860,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint,
*/
SkAutoPaintRestoreColorStrokeWidth aprc(paint);
-
+
// can we approximate a thin (but not hairline) stroke with an alpha-modulated
// hairline? Only if the matrix scales evenly in X and Y, and the device-width is
// less than a pixel
@@ -870,18 +870,18 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint,
if (width > 0 && map_radius(*matrix, &width)) {
int scale = (int)SkScalarMul(width, 256);
int alpha = paint.getAlpha() * scale >> 8;
-
+
// pretend to be a hairline, with a modulated alpha
((SkPaint*)&paint)->setAlpha(alpha);
((SkPaint*)&paint)->setStrokeWidth(0);
}
}
-
+
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
doFill = paint.getFillPath(*pathPtr, &tmpPath);
pathPtr = &tmpPath;
}
-
+
if (paint.getRasterizer()) {
SkMask mask;
if (paint.getRasterizer()->rasterize(*pathPtr, *matrix,
@@ -953,7 +953,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
const SkPaint& paint) const {
SkASSERT(bitmap.getConfig() == SkBitmap::kA8_Config);
- if (just_translate(*fMatrix, bitmap)) {
+ if (just_translate(*fMatrix, bitmap)) {
int ix = SkScalarRound(fMatrix->getTranslateX());
int iy = SkScalarRound(fMatrix->getTranslateY());
@@ -962,17 +962,17 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
mask.fFormat = SkMask::kA8_Format;
mask.fRowBytes = bitmap.rowBytes();
mask.fImage = bitmap.getAddr8(0, 0);
-
+
this->drawDevMask(mask, paint);
} else { // need to xform the bitmap first
SkRect r;
SkMask mask;
-
+
r.set(0, 0,
SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
fMatrix->mapRect(&r);
r.round(&mask.fBounds);
-
+
// set the mask's bounds to the transformed bitmap-bounds,
// clipped to the actual device
{
@@ -996,14 +996,14 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
SkAutoMalloc storage(size);
mask.fImage = (uint8_t*)storage.get();
memset(mask.fImage, 0, size);
-
+
// now draw our bitmap(src) into mask(dst), transformed by the matrix
{
SkBitmap device;
device.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
mask.fBounds.height(), mask.fRowBytes);
device.setPixels(mask.fImage);
-
+
SkCanvas c(device);
// need the unclipped top/left for the translate
c.translate(-SkIntToScalar(mask.fBounds.fLeft),
@@ -1028,9 +1028,9 @@ static bool clipped_out(const SkMatrix& m, const SkRegion& c,
const SkRect& srcR) {
SkRect dstR;
SkIRect devIR;
-
+
m.mapRect(&dstR, srcR);
- dstR.roundOut(&devIR);
+ dstR.roundOut(&devIR);
return c.quickReject(devIR);
}
@@ -1052,14 +1052,16 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
return;
}
-
+
+#ifndef SK_ALLOW_OVER_32K_BITMAPS
// run away on too-big bitmaps for now (exceed 16.16)
if (bitmap.width() > 32767 || bitmap.height() > 32767) {
return;
}
-
+#endif
+
SkAutoPaintStyleRestore restore(paint, SkPaint::kFill_Style);
-
+
SkMatrix matrix;
if (!matrix.setConcat(*fMatrix, prematrix)) {
return;
@@ -1114,12 +1116,12 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
paint.getXfermode(), paint.getAlpha(), paint.getColorFilter());
#endif
}
-
+
// now make a temp draw on the stack, and use it
//
SkDraw draw(*this);
draw.fMatrix = &matrix;
-
+
if (bitmap.getConfig() == SkBitmap::kA8_Config) {
draw.drawBitmapAsMask(bitmap, paint);
} else {
@@ -1128,7 +1130,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
SkRect r;
r.set(0, 0, SkIntToScalar(bitmap.width()),
SkIntToScalar(bitmap.height()));
- // is this ok if paint has a rasterizer?
+ // is this ok if paint has a rasterizer?
draw.drawRect(r, paint);
}
}
@@ -1136,7 +1138,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
const SkPaint& paint) const {
SkDEBUGCODE(this->validate();)
-
+
// nothing to draw
if (fClip->isEmpty() ||
bitmap.width() == 0 || bitmap.height() == 0 ||
@@ -1188,12 +1190,12 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
// tell the shader our offset
matrix.setTranslate(r.fLeft, r.fTop);
paint.getShader()->setLocalMatrix(matrix);
-
+
SkDraw draw(*this);
matrix.reset();
draw.fMatrix = &matrix;
// call ourself with a rect
- // is this OK if paint has a rasterizer?
+ // is this OK if paint has a rasterizer?
draw.drawRect(r, paint);
}
@@ -1209,7 +1211,7 @@ static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
const char* stop = text + byteLength;
SkAutoKern autokern;
-
+
while (text < stop) {
// don't need x, y here, since all subpixel variants will have the
// same advance
@@ -1291,7 +1293,7 @@ static void handle_aftertext(const SkDraw* draw, const SkPaint& paint,
}
// disable warning : local variable used without having been initialized
-#if defined _WIN32 && _MSC_VER >= 1300
+#if defined _WIN32 && _MSC_VER >= 1300
#pragma warning ( push )
#pragma warning ( disable : 4701 )
#endif
@@ -1327,8 +1329,8 @@ static void D1G_NoBounder_RectClip(const SkDraw1Glyph& state,
return;
bounds = &storage;
}
-
- uint8_t* aa = (uint8_t*)glyph.fImage;
+
+ uint8_t* aa = (uint8_t*)glyph.fImage;
if (NULL == aa) {
aa = (uint8_t*)state.fCache->findImage(glyph);
if (NULL == aa) {
@@ -1368,7 +1370,7 @@ static void D1G_NoBounder_RgnClip(const SkDraw1Glyph& state,
return;
}
}
-
+
mask.fRowBytes = glyph.rowBytes();
mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
mask.fImage = (uint8_t*)aa;
@@ -1517,7 +1519,7 @@ void SkDraw::drawText(const char text[], size_t byteLength,
SkAutoGlyphCache autoCache(paint, matrix);
SkGlyphCache* cache = autoCache.getCache();
SkAutoBlitterChoose blitter(*fBitmap, *matrix, paint);
-
+
// transform our starting point
{
SkPoint loc;
@@ -1542,7 +1544,7 @@ void SkDraw::drawText(const char text[], size_t byteLength,
x -= stopX;
y -= stopY;
}
-
+
SkFixed fx = SkScalarToFixed(x);
SkFixed fy = SkScalarToFixed(y);
const char* stop = text + byteLength;
@@ -1611,7 +1613,7 @@ static AlignProc pick_align_proc(SkPaint::Align align) {
static const AlignProc gProcs[] = {
leftAlignProc, centerAlignProc, rightAlignProc
};
-
+
SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
return gProcs[align];
@@ -1620,14 +1622,14 @@ static AlignProc pick_align_proc(SkPaint::Align align) {
class TextMapState {
public:
mutable SkPoint fLoc;
-
+
TextMapState(const SkMatrix& matrix, SkScalar y)
: fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {}
typedef void (*Proc)(const TextMapState&, const SkScalar pos[]);
-
+
Proc pickProc(int scalarsPerPosition);
-
+
private:
const SkMatrix& fMatrix;
SkMatrix::MapXYProc fProc;
@@ -1638,17 +1640,17 @@ private:
static void MapXProc(const TextMapState& state, const SkScalar pos[]) {
state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc);
}
-
+
static void MapXYProc(const TextMapState& state, const SkScalar pos[]) {
state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc);
}
-
+
static void MapOnlyScaleXProc(const TextMapState& state,
const SkScalar pos[]) {
state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX,
state.fTransformedY);
}
-
+
static void MapOnlyTransXProc(const TextMapState& state,
const SkScalar pos[]) {
state.fLoc.set(*pos + state.fTransX, state.fTransformedY);
@@ -1657,7 +1659,7 @@ private:
TextMapState::Proc TextMapState::pickProc(int scalarsPerPosition) {
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
-
+
if (1 == scalarsPerPosition) {
unsigned mtype = fMatrix.getType();
if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
@@ -1707,12 +1709,12 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
matrix = fMVMatrix;
}
}
-
+
SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
SkAutoGlyphCache autoCache(paint, matrix);
SkGlyphCache* cache = autoCache.getCache();
SkAutoBlitterChoose blitter(*fBitmap, *matrix, paint);
-
+
const char* stop = text + byteLength;
AlignProc alignProc = pick_align_proc(paint.getTextAlign());
SkDraw1Glyph d1g;
@@ -1726,9 +1728,9 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
if (SkPaint::kLeft_Align == paint.getTextAlign()) {
while (text < stop) {
-
+
tmsProc(tms, pos);
-
+
SkFixed fx = SkScalarToFixed(tms.fLoc.fX);
SkFixed fy = SkScalarToFixed(tms.fLoc.fY);
SkFixed fxMask = ~0;
@@ -1739,10 +1741,10 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
} else if (kRound_X_Baseline == roundBaseline) {
fxMask = 0;
}
-
+
const SkGlyph& glyph = glyphCacheProc(cache, &text,
fx & fxMask, fy & fyMask);
-
+
if (glyph.fWidth) {
proc(d1g, fx, fy, glyph);
}
@@ -1751,7 +1753,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
} else {
while (text < stop) {
const SkGlyph* glyph = &glyphCacheProc(cache, &text, 0, 0);
-
+
if (glyph->fWidth) {
SkDEBUGCODE(SkFixed prevAdvX = glyph->fAdvanceX;)
SkDEBUGCODE(SkFixed prevAdvY = glyph->fAdvanceY;)
@@ -1760,7 +1762,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
SkFixed fxMask = ~0;
SkFixed fyMask = ~0;
tmsProc(tms, pos);
-
+
{
SkIPoint fixedLoc;
alignProc(tms.fLoc, *glyph, &fixedLoc);
@@ -1773,13 +1775,13 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
fxMask = 0;
}
}
-
+
// have to call again, now that we've been "aligned"
glyph = &glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
// the assumption is that the advance hasn't changed
SkASSERT(prevAdvX == glyph->fAdvanceX);
SkASSERT(prevAdvY == glyph->fAdvanceY);
-
+
proc(d1g, fx, fy, *glyph);
}
pos += scalarsPerPosition;
@@ -1789,13 +1791,13 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
while (text < stop) {
// the last 2 parameters are ignored
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
-
+
if (glyph.fWidth) {
tmsProc(tms, pos);
-
+
SkIPoint fixedLoc;
alignProc(tms.fLoc, glyph, &fixedLoc);
-
+
proc(d1g, fixedLoc.fX + SK_FixedHalf,
fixedLoc.fY + SK_FixedHalf, glyph);
}
@@ -1915,7 +1917,7 @@ void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
SkScalar scale = iter.getPathScale();
scaledMatrix.setScale(scale, scale);
-
+
while ((iterPath = iter.next(&xpos)) != NULL) {
SkPath tmp;
SkMatrix m(scaledMatrix);
@@ -1947,15 +1949,15 @@ struct VertState {
fCount = vCount;
}
}
-
- typedef bool (*Proc)(VertState*);
+
+ typedef bool (*Proc)(VertState*);
Proc chooseProc(SkCanvas::VertexMode mode);
private:
int fCount;
int fCurrIndex;
const uint16_t* fIndices;
-
+
static bool Triangles(VertState*);
static bool TrianglesX(VertState*);
static bool TriangleStrip(VertState*);
@@ -2072,7 +2074,7 @@ static HairProc ChooseHairProc(bool doAntiAlias) {
static bool texture_to_matrix(const VertState& state, const SkPoint verts[],
const SkPoint texs[], SkMatrix* matrix) {
SkPoint src[3], dst[3];
-
+
src[0] = texs[state.f0];
src[1] = texs[state.f1];
src[2] = texs[state.f2];
@@ -2087,18 +2089,18 @@ public:
SkTriColorShader() {}
bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
-
+
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
-
+
protected:
SkTriColorShader(SkFlattenableReadBuffer& buffer) : SkShader(buffer) {}
-
+
virtual Factory getFactory() { return CreateProc; }
-
+
private:
SkMatrix fDstToUnit;
SkPMColor fColors[3];
-
+
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkTriColorShader, (buffer));
}
@@ -2107,11 +2109,11 @@ private:
bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[],
int index0, int index1, int index2) {
-
+
fColors[0] = SkPreMultiplyColor(colors[index0]);
fColors[1] = SkPreMultiplyColor(colors[index1]);
fColors[2] = SkPreMultiplyColor(colors[index2]);
-
+
SkMatrix m, im;
m.reset();
m.set(0, pts[index1].fX - pts[index0].fX);
@@ -2142,11 +2144,11 @@ static int ScalarTo256(SkScalar v) {
void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
SkPoint src;
-
+
for (int i = 0; i < count; i++) {
fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
x += 1;
-
+
int scale1 = ScalarTo256(src.fX);
int scale2 = ScalarTo256(src.fY);
int scale0 = 256 - scale1 - scale2;
@@ -2158,7 +2160,7 @@ void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
}
scale0 = 0;
}
-
+
dstC[i] = SkAlphaMulQ(fColors[0], scale0) +
SkAlphaMulQ(fColors[1], scale1) +
SkAlphaMulQ(fColors[2], scale2);
@@ -2171,18 +2173,18 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
const uint16_t indices[], int indexCount,
const SkPaint& paint) const {
SkASSERT(0 == count || NULL != vertices);
-
+
// abort early if there is nothing to draw
if (count < 3 || (indices && indexCount < 3) || fClip->isEmpty() ||
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
return;
}
-
+
// transform out vertices into device coordinates
SkAutoSTMalloc<16, SkPoint> storage(count);
SkPoint* devVerts = storage.get();
fMatrix->mapPoints(devVerts, vertices, count);
-
+
if (fBounder) {
SkRect bounds;
bounds.set(devVerts, count);
@@ -2190,7 +2192,7 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
return;
}
}
-
+
/*
We can draw the vertices in 1 of 4 ways:
@@ -2198,7 +2200,7 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
- just colors (no shader/texture[], has colors[])
- just texture (has shader/texture[], no colors[])
- colors * texture (has shader/texture[], has colors[])
-
+
Thus for texture drawing, we need both texture[] and a shader.
*/
@@ -2241,17 +2243,17 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
// setup our state and function pointer for iterating triangles
VertState state(count, indices, indexCount);
VertState::Proc vertProc = state.chooseProc(vmode);
-
+
if (NULL != textures || NULL != colors) {
SkMatrix localM, tempM;
bool hasLocalM = shader && shader->getLocalMatrix(&localM);
-
+
if (NULL != colors) {
if (!triShader.setContext(*fBitmap, p, *fMatrix)) {
colors = NULL;
}
}
-
+
while (vertProc(&state)) {
if (NULL != textures) {
if (texture_to_matrix(state, vertices, textures, &tempM)) {
@@ -2424,12 +2426,12 @@ static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
pathBounds.inset(-SK_ScalarHalf, -SK_ScalarHalf);
pathBounds.roundOut(bounds);
}
-
+
if (filter) {
SkASSERT(filterMatrix);
-
+
SkMask srcM, dstM;
-
+
srcM.fBounds = *bounds;
srcM.fFormat = SkMask::kA8_Format;
srcM.fImage = NULL;
@@ -2442,7 +2444,7 @@ static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
if (clipBounds && !SkIRect::Intersects(*clipBounds, *bounds)) {
return false;
}
-
+
// (possibly) trim the srcM bounds to reflect the clip
// (plus whatever slop the filter needs)
if (clipBounds && !clipBounds->contains(*bounds)) {
@@ -2492,7 +2494,7 @@ bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
if (!compute_bounds(devPath, clipBounds, filter, filterMatrix, &mask->fBounds))
return false;
}
-
+
if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) {
mask->fFormat = SkMask::kA8_Format;
mask->fRowBytes = mask->fBounds.width();
@@ -2508,6 +2510,6 @@ bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
if (SkMask::kJustComputeBounds_CreateMode != mode) {
draw_into_mask(*mask, devPath);
}
-
+
return true;
}