From a76de3d1a92134c3e95ad7fce99234f92fa48268 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Thu, 13 Jan 2011 18:30:42 +0000 Subject: 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 --- src/core/SkDraw.cpp | 228 ++++++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 113 deletions(-) (limited to 'src/core/SkDraw.cpp') 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(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(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; } -- cgit v1.2.3