From 79738cc7bf12d212bef4ff80591d1bf6f383663d Mon Sep 17 00:00:00 2001 From: bungeman Date: Wed, 11 Mar 2015 14:05:29 -0700 Subject: [PATCH] Glyph positions maintain 32 bit integer part. A glyph position when mapped from canvas space to device space may land outside the bounds of the current 16 bit integer part of device space. Device space is already limited to 32 bits for the integer part, but for a short space in drawText and drawPosText it is currently limited to 16 bits (SkFixed). Raise this limit by moving to 48.16. This matches the current similar fix for measureText. BUG=chromium:375322 Review URL: https://codereview.chromium.org/977623002 --- include/core/SkFixed.h | 15 ++++ src/core/SkDraw.cpp | 59 +++++++-------- src/core/SkDrawProcs.h | 31 +------- src/core/SkPaint.cpp | 8 --- src/device/xps/SkXPSDevice.cpp | 14 ++-- src/gpu/GrBitmapTextContext.cpp | 91 ++++++++++++------------ src/gpu/GrStencilAndCoverTextContext.cpp | 2 +- 7 files changed, 100 insertions(+), 120 deletions(-) diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h index f332661843..cde244efeb 100644 --- a/include/core/SkFixed.h +++ b/include/core/SkFixed.h @@ -150,4 +150,19 @@ typedef int64_t SkFixed3232; // 32.32 #define SkScalarToFixed3232(x) SkFloatToFixed3232(x) +/////////////////////////////////////////////////////////////////////////////// + +// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so +// we don't overflow along the way +typedef int64_t Sk48Dot16; + +#define Sk48Dot16FloorToInt(x) static_cast((x) >> 16) + +static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { + return static_cast(x * 1.5258789e-5); // x * (1.0f / (1 << 16)) +} +#define SkFloatTo48Dot16(x) (static_cast((x) * (1 << 16))) + +#define SkScalarTo48Dot16(x) SkFloatTo48Dot16(x) + #endif diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index b6738e2429..bd4e40e9f1 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1443,9 +1443,9 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength, ////////////////////////////////////////////////////////////////////////////// -static void D1G_RectClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) { - int left = SkFixedFloorToInt(fx); - int top = SkFixedFloorToInt(fy); +static void D1G_RectClip(const SkDraw1Glyph& state, Sk48Dot16 fx, Sk48Dot16 fy, const SkGlyph& glyph) { + int left = Sk48Dot16FloorToInt(fx); + int top = Sk48Dot16FloorToInt(fy); SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); SkASSERT((NULL == state.fClip && state.fAAClip) || (state.fClip && NULL == state.fAAClip && state.fClip->isRect())); @@ -1484,9 +1484,9 @@ static void D1G_RectClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, cons state.blitMask(mask, *bounds); } -static void D1G_RgnClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) { - int left = SkFixedFloorToInt(fx); - int top = SkFixedFloorToInt(fy); +static void D1G_RgnClip(const SkDraw1Glyph& state, Sk48Dot16 fx, Sk48Dot16 fy, const SkGlyph& glyph) { + int left = Sk48Dot16FloorToInt(fx); + int top = Sk48Dot16FloorToInt(fy); SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); SkASSERT(!state.fClip->isRect()); @@ -1534,9 +1534,9 @@ SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, Sk fPaint = &pnt; if (cache->isSubpixel()) { - fHalfSampleX = fHalfSampleY = SkGlyph::kSubpixelRound; + fHalfSampleX = fHalfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound); } else { - fHalfSampleX = fHalfSampleY = SK_FixedHalf; + fHalfSampleX = fHalfSampleY = SK_ScalarHalf; } if (hasCustomD1GProc(*draw)) { @@ -1647,15 +1647,15 @@ void SkDraw::drawText(const char text[], size_t byteLength, SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix); if (kX_SkAxisAlignment == baseline) { fyMask = 0; - d1g.fHalfSampleY = SK_FixedHalf; + d1g.fHalfSampleY = SK_ScalarHalf; } else if (kY_SkAxisAlignment == baseline) { fxMask = 0; - d1g.fHalfSampleX = SK_FixedHalf; + d1g.fHalfSampleX = SK_ScalarHalf; } } - SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX; - SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(x + d1g.fHalfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(y + d1g.fHalfSampleY); while (text < stop) { const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); @@ -1692,7 +1692,7 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, SkGlyphCache* cache = autoCache.getCache(); const char* stop = text + byteLength; - SkTextAlignProcScalar alignProc(paint.getTextAlign()); + SkTextAlignProc alignProc(paint.getTextAlign()); SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); // Now restore the original settings, so we "draw" with whatever style/stroking. @@ -1770,21 +1770,21 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, SkFixed fyMask = ~0; if (kX_SkAxisAlignment == baseline) { fyMask = 0; - d1g.fHalfSampleY = SK_FixedHalf; + d1g.fHalfSampleY = SK_ScalarHalf; } else if (kY_SkAxisAlignment == baseline) { fxMask = 0; - d1g.fHalfSampleX = SK_FixedHalf; + d1g.fHalfSampleX = SK_ScalarHalf; } if (SkPaint::kLeft_Align == paint.getTextAlign()) { while (text < stop) { SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkFixed fx = SkScalarToFixed(tmsLoc.fX) + d1g.fHalfSampleX; - SkFixed fy = SkScalarToFixed(tmsLoc.fY) + d1g.fHalfSampleY; - const SkGlyph& glyph = glyphCacheProc(cache, &text, - fx & fxMask, fy & fyMask); + Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + d1g.fHalfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + d1g.fHalfSampleY); + + const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); if (glyph.fWidth) { proc(d1g, fx, fy, glyph); @@ -1801,11 +1801,12 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;) SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkIPoint fixedLoc; - alignProc(tmsLoc, metricGlyph, &fixedLoc); - SkFixed fx = fixedLoc.fX + d1g.fHalfSampleX; - SkFixed fy = fixedLoc.fY + d1g.fHalfSampleY; + SkPoint alignLoc; + alignProc(tmsLoc, metricGlyph, &alignLoc); + + Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + d1g.fHalfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + d1g.fHalfSampleY); // have to call again, now that we've been "aligned" const SkGlyph& glyph = glyphCacheProc(cache, ¤tText, @@ -1831,8 +1832,8 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, tmsProc(pos, &tmsLoc); proc(d1g, - SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf, //d1g.fHalfSampleX, - SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf, //d1g.fHalfSampleY, + SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf), //d1g.fHalfSampleX, + SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf), //d1g.fHalfSampleY, glyph); } pos += scalarsPerPosition; @@ -1846,12 +1847,12 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkIPoint fixedLoc; - alignProc(tmsLoc, glyph, &fixedLoc); + SkPoint alignLoc; + alignProc(tmsLoc, glyph, &alignLoc); proc(d1g, - fixedLoc.fX + SK_FixedHalf, //d1g.fHalfSampleX, - fixedLoc.fY + SK_FixedHalf, //d1g.fHalfSampleY, + SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf), //d1g.fHalfSampleX, + SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf), //d1g.fHalfSampleY, glyph); } pos += scalarsPerPosition; diff --git a/src/core/SkDrawProcs.h b/src/core/SkDrawProcs.h index d059c67470..0a188235d2 100644 --- a/src/core/SkDrawProcs.h +++ b/src/core/SkDrawProcs.h @@ -24,9 +24,9 @@ struct SkDraw1Glyph { const SkPaint* fPaint; SkIRect fClipBounds; /** Half the sampling frequency of the rasterized glyph in x. */ - SkFixed fHalfSampleX; + SkScalar fHalfSampleX; /** Half the sampling frequency of the rasterized glyph in y. */ - SkFixed fHalfSampleY; + SkScalar fHalfSampleY; /** Draws one glyph. * @@ -35,7 +35,7 @@ struct SkDraw1Glyph { * e.g. 1/2 or 1/(2^(SkGlyph::kSubBits+1)) has already been added. * This added bias can be found in fHalfSampleX,Y. */ - typedef void (*Proc)(const SkDraw1Glyph&, SkFixed x, SkFixed y, const SkGlyph&); + typedef void (*Proc)(const SkDraw1Glyph&, Sk48Dot16 x, Sk48Dot16 y, const SkGlyph&); Proc init(const SkDraw* draw, SkBlitter* blitter, SkGlyphCache* cache, const SkPaint&); @@ -93,31 +93,6 @@ public: : fAlign(align) { } - // Returns the position of the glyph in fixed point, which may be rounded or not - // by the caller e.g. subpixel doesn't round. - // @param point interpreted as SkFixed [x, y]. - void operator()(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) { - if (SkPaint::kLeft_Align == fAlign) { - dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY)); - } else if (SkPaint::kCenter_Align == fAlign) { - dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1), - SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1)); - } else { - SkASSERT(SkPaint::kRight_Align == fAlign); - dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX, - SkScalarToFixed(loc.fY) - glyph.fAdvanceY); - } - } -private: - const SkPaint::Align fAlign; -}; - -class SkTextAlignProcScalar { -public: - SkTextAlignProcScalar(SkPaint::Align align) - : fAlign(align) { - } - // Returns the glyph position, which may be rounded or not by the caller // e.g. subpixel doesn't round. void operator()(const SkPoint& loc, const SkGlyph& glyph, SkPoint* dst) { diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 5774839ed8..b93236f0d1 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -804,14 +804,6 @@ static void set_bounds(const SkGlyph& g, SkRect* bounds) { SkIntToScalar(g.fTop + g.fHeight)); } -// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so -// we don't overflow along the way -typedef int64_t Sk48Dot16; - -static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { - return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) -} - static void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { SkScalar sx = Sk48Dot16ToScalar(dx); bounds->join(SkIntToScalar(g.fLeft) + sx, diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp index 3bb87b32a3..2ca799ac37 100644 --- a/src/device/xps/SkXPSDevice.cpp +++ b/src/device/xps/SkXPSDevice.cpp @@ -2057,15 +2057,15 @@ public: }; static void xps_draw_1_glyph(const SkDraw1Glyph& state, - SkFixed x, SkFixed y, + Sk48Dot16 fx, Sk48Dot16 fy, const SkGlyph& skGlyph) { SkASSERT(skGlyph.fWidth > 0 && skGlyph.fHeight > 0); SkXPSDrawProcs* procs = static_cast(state.fDraw->fProcs); //Draw pre-adds half the sampling frequency for floor rounding. - x -= state.fHalfSampleX; - y -= state.fHalfSampleY; + SkScalar x = Sk48Dot16ToScalar(fx) - state.fHalfSampleX; + SkScalar y = Sk48Dot16ToScalar(fy) - state.fHalfSampleY; XPS_GLYPH_INDEX* xpsGlyph = procs->xpsGlyphs.append(); uint16_t glyphID = skGlyph.getGlyphID(); @@ -2073,14 +2073,14 @@ static void xps_draw_1_glyph(const SkDraw1Glyph& state, xpsGlyph->index = glyphID; if (1 == procs->xpsGlyphs.count()) { xpsGlyph->advanceWidth = 0.0f; - xpsGlyph->horizontalOffset = SkFixedToFloat(x) * procs->centemPerUnit; - xpsGlyph->verticalOffset = SkFixedToFloat(y) * -procs->centemPerUnit; + xpsGlyph->horizontalOffset = SkScalarToFloat(x) * procs->centemPerUnit; + xpsGlyph->verticalOffset = SkScalarToFloat(y) * -procs->centemPerUnit; } else { const XPS_GLYPH_INDEX& first = procs->xpsGlyphs[0]; xpsGlyph->advanceWidth = 0.0f; - xpsGlyph->horizontalOffset = (SkFixedToFloat(x) * procs->centemPerUnit) + xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * procs->centemPerUnit) - first.horizontalOffset; - xpsGlyph->verticalOffset = (SkFixedToFloat(y) * -procs->centemPerUnit) + xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -procs->centemPerUnit) - first.verticalOffset; } } diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index a8ac78a209..3031f985ed 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -138,23 +138,23 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, SkFixed fxMask = ~0; SkFixed fyMask = ~0; - SkFixed halfSampleX, halfSampleY; + SkScalar halfSampleX, halfSampleY; if (cache->isSubpixel()) { - halfSampleX = halfSampleY = SkGlyph::kSubpixelRound; + halfSampleX = halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound); SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); if (kX_SkAxisAlignment == baseline) { fyMask = 0; - halfSampleY = SK_FixedHalf; + halfSampleY = SK_ScalarHalf; } else if (kY_SkAxisAlignment == baseline) { fxMask = 0; - halfSampleX = SK_FixedHalf; + halfSampleX = SK_ScalarHalf; } } else { - halfSampleX = halfSampleY = SK_FixedHalf; + halfSampleX = halfSampleY = SK_ScalarHalf; } - SkFixed fx = SkScalarToFixed(x) + halfSampleX; - SkFixed fy = SkScalarToFixed(y) + halfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(x + halfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY); // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix, but for // performance reasons we just invert here instead @@ -172,8 +172,8 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), + Sk48Dot16FloorToInt(fx), + Sk48Dot16FloorToInt(fy), fontScaler); } @@ -219,7 +219,7 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, const char* stop = text + byteLength; SkTextAlignProc alignProc(fSkPaint.getTextAlign()); SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); - SkFixed halfSampleX = 0, halfSampleY = 0; + SkScalar halfSampleX = 0, halfSampleY = 0; if (cache->isSubpixel()) { // maybe we should skip the rounding if linearText is set @@ -229,18 +229,18 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, SkFixed fyMask = ~0; if (kX_SkAxisAlignment == baseline) { fyMask = 0; - halfSampleY = SK_FixedHalf; + halfSampleY = SK_ScalarHalf; } else if (kY_SkAxisAlignment == baseline) { fxMask = 0; - halfSampleX = SK_FixedHalf; + halfSampleX = SK_ScalarHalf; } if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { while (text < stop) { SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkFixed fx = SkScalarToFixed(tmsLoc.fX) + halfSampleX; - SkFixed fy = SkScalarToFixed(tmsLoc.fY) + halfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY); const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); @@ -249,8 +249,8 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), + Sk48Dot16FloorToInt(fx), + Sk48Dot16FloorToInt(fy), fontScaler); } pos += scalarsPerPosition; @@ -265,11 +265,11 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;) SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkIPoint fixedLoc; - alignProc(tmsLoc, metricGlyph, &fixedLoc); + SkPoint alignLoc; + alignProc(tmsLoc, metricGlyph, &alignLoc); - SkFixed fx = fixedLoc.fX + halfSampleX; - SkFixed fy = fixedLoc.fY + halfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + halfSampleX); + Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + halfSampleY); // have to call again, now that we've been "aligned" const SkGlyph& glyph = glyphCacheProc(cache, ¤tText, @@ -282,8 +282,8 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), + Sk48Dot16FloorToInt(fx), + Sk48Dot16FloorToInt(fy), fontScaler); } pos += scalarsPerPosition; @@ -300,13 +300,13 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkFixed fx = SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf; //halfSampleX; - SkFixed fy = SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf; //halfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf); //halfSampleX; + Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); //halfSampleY; this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), + Sk48Dot16FloorToInt(fx), + Sk48Dot16FloorToInt(fy), fontScaler); } pos += scalarsPerPosition; @@ -320,16 +320,16 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, SkPoint tmsLoc; tmsProc(pos, &tmsLoc); - SkIPoint fixedLoc; - alignProc(tmsLoc, glyph, &fixedLoc); + SkPoint alignLoc; + alignProc(tmsLoc, glyph, &alignLoc); - SkFixed fx = fixedLoc.fX + SK_FixedHalf; //halfSampleX; - SkFixed fy = fixedLoc.fY + SK_FixedHalf; //halfSampleY; + Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf); //halfSampleX; + Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf); //halfSampleY; this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), + Sk48Dot16FloorToInt(fx), + Sk48Dot16FloorToInt(fy), fontScaler); } pos += scalarsPerPosition; @@ -405,7 +405,7 @@ inline bool GrBitmapTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scale } void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, - SkFixed vx, SkFixed vy, + int vx, int vy, GrFontScaler* scaler) { if (NULL == fDrawTarget) { return; @@ -420,16 +420,14 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, return; } - vx += SkIntToFixed(glyph->fBounds.fLeft); - vy += SkIntToFixed(glyph->fBounds.fTop); + int x = vx + glyph->fBounds.fLeft; + int y = vy + glyph->fBounds.fTop; // keep them as ints until we've done the clip-test int width = glyph->fBounds.width(); int height = glyph->fBounds.height(); // check if we clipped out - int x = vx >> 16; - int y = vy >> 16; if (fClipRect.quickReject(x, y, x + width, y + height)) { return; } @@ -450,8 +448,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, this->flush(); SkMatrix translate; - translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds.fLeft)), - SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.fTop))); + translate.setTranslate(SkIntToScalar(vx), SkIntToScalar(vy)); SkPath tmpPath(*glyph->fPath); tmpPath.transform(translate); GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); @@ -484,13 +481,13 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, } SkRect r; - r.fLeft = SkFixedToFloat(vx); - r.fTop = SkFixedToFloat(vy); - r.fRight = r.fLeft + width; - r.fBottom = r.fTop + height; + r.fLeft = SkIntToScalar(x); + r.fTop = SkIntToScalar(y); + r.fRight = r.fLeft + SkIntToScalar(width); + r.fBottom = r.fTop + SkIntToScalar(height); fVertexBounds.joinNonEmptyArg(r); - + int u0 = glyph->fAtlasLocation.fX; int v0 = glyph->fAtlasLocation.fY; int u1 = u0 + width; @@ -510,7 +507,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, sizeof(SkIPoint16)); textureCoords->set(u0, v0); vertex += vertSize; - + // V1 position = reinterpret_cast(vertex); position->set(r.fLeft, r.fBottom); @@ -521,7 +518,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, textureCoords = reinterpret_cast(vertex + vertSize - sizeof(SkIPoint16)); textureCoords->set(u0, v1); vertex += vertSize; - + // V2 position = reinterpret_cast(vertex); position->set(r.fRight, r.fBottom); @@ -532,7 +529,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed, textureCoords = reinterpret_cast(vertex + vertSize - sizeof(SkIPoint16)); textureCoords->set(u1, v1); vertex += vertSize; - + // V3 position = reinterpret_cast(vertex); position->set(r.fRight, r.fTop); diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index 4b121da905..e43387e66f 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -188,7 +188,7 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt, const char* stop = text + byteLength; SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); - SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign()); + SkTextAlignProc alignProc(fSkPaint.getTextAlign()); while (text < stop) { const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); if (glyph.fWidth) {