зеркало из https://github.com/mozilla/moz-skia.git
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
This commit is contained in:
Родитель
d3b13bd5af
Коммит
a76de3d1a9
|
@ -818,8 +818,11 @@ void SkCanvas::restoreToCount(int count) {
|
|||
|
||||
// can't draw it if its empty, or its too big for a fixed-point width or height
|
||||
static bool reject_bitmap(const SkBitmap& bitmap) {
|
||||
return bitmap.width() <= 0 || bitmap.height() <= 0 ||
|
||||
bitmap.width() > 32767 || bitmap.height() > 32767;
|
||||
return bitmap.width() <= 0 || bitmap.height() <= 0
|
||||
#ifndef SK_ALLOW_OVER_32K_BITMAPS
|
||||
|| bitmap.width() > 32767 || bitmap.height() > 32767
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче