diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 52a9c3a3e1..8baa40fcaa 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -190,6 +190,8 @@ '<(skia_src_path)/gpu/GrTextureProvider.cpp', '<(skia_src_path)/gpu/GrTexturePriv.h', '<(skia_src_path)/gpu/GrTextureAccess.cpp', + '<(skia_src_path)/gpu/GrTextUtils.cpp', + '<(skia_src_path)/gpu/GrTextUtils.h', '<(skia_src_path)/gpu/GrTransferBuffer.h', '<(skia_src_path)/gpu/GrTRecorder.h', '<(skia_src_path)/gpu/GrVertexBuffer.h', diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 2090ed2337..087f85e372 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -1094,7 +1094,7 @@ private: friend class GrDistanceFieldTextContext; friend class GrStencilAndCoverTextContext; friend class GrPathRendering; - friend class GrTextContext; + friend class GrTextUtils; friend class GrGLPathRendering; friend class SkScalerContext; friend class SkTextToPathIter; diff --git a/src/gpu/GrAtlasTextBlob.cpp b/src/gpu/GrAtlasTextBlob.cpp index 50ce0f8f83..dee6d133e3 100644 --- a/src/gpu/GrAtlasTextBlob.cpp +++ b/src/gpu/GrAtlasTextBlob.cpp @@ -10,6 +10,7 @@ #include "GrBlurUtils.h" #include "GrContext.h" #include "GrDrawContext.h" +#include "GrTextUtils.h" #include "SkColorFilter.h" #include "SkDrawFilter.h" #include "SkTextBlobRunIterator.h" @@ -300,8 +301,7 @@ void GrAtlasTextBlob::flushBigGlyphs(GrContext* context, GrDrawContext* dc, } } -void GrAtlasTextBlob::flushRunAsPaths(GrDrawContext* dc, - GrTextContext* textContext, +void GrAtlasTextBlob::flushRunAsPaths(GrContext* context, GrDrawContext* dc, const SkSurfaceProps& props, const SkTextBlobRunIterator& it, const GrClip& clip, const SkPaint& skPaint, @@ -322,28 +322,27 @@ void GrAtlasTextBlob::flushRunAsPaths(GrDrawContext* dc, switch (it.positioning()) { case SkTextBlob::kDefault_Positioning: - textContext->drawTextAsPath(dc, clip, runPaint, viewMatrix, + GrTextUtils::DrawTextAsPath(context, dc, clip, runPaint, viewMatrix, (const char *)it.glyphs(), textLen, x + offset.x(), y + offset.y(), clipBounds); break; case SkTextBlob::kHorizontal_Positioning: - textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, + GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), clipBounds); break; case SkTextBlob::kFull_Positioning: - textContext->drawPosTextAsPath(dc, clip, runPaint, viewMatrix, + GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds); break; } } -void GrAtlasTextBlob::flushCached(const SkTextBlob* blob, - GrContext* context, +void GrAtlasTextBlob::flushCached(GrContext* context, GrDrawContext* dc, - GrTextContext* textContext, + const SkTextBlob* blob, const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable, const SkPaint& skPaint, @@ -363,7 +362,7 @@ void GrAtlasTextBlob::flushCached(const SkTextBlob* blob, SkTextBlobRunIterator it(blob); for (int run = 0; !it.done(); it.next(), run++) { if (fRuns[run].fDrawAsPaths) { - this->flushRunAsPaths(dc, textContext, props, it, clip, skPaint, + this->flushRunAsPaths(context, dc, props, it, clip, skPaint, drawFilter, viewMatrix, clipBounds, x, y); continue; } diff --git a/src/gpu/GrAtlasTextBlob.h b/src/gpu/GrAtlasTextBlob.h index 0f99576930..d99ae707e0 100644 --- a/src/gpu/GrAtlasTextBlob.h +++ b/src/gpu/GrAtlasTextBlob.h @@ -316,10 +316,9 @@ public: const SkMatrix& viewMatrix, SkScalar x, SkScalar y); // flush a GrAtlasTextBlob associated with a SkTextBlob - void flushCached(const SkTextBlob* blob, - GrContext* context, + void flushCached(GrContext* context, GrDrawContext* dc, - GrTextContext* textContext, + const SkTextBlob* blob, const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable, const SkPaint& skPaint, @@ -377,8 +376,8 @@ private: SkScalar transX, SkScalar transY, const SkIRect& clipBounds); - void flushRunAsPaths(GrDrawContext* dc, - GrTextContext* textContext, + void flushRunAsPaths(GrContext* context, + GrDrawContext* dc, const SkSurfaceProps& props, const SkTextBlobRunIterator& it, const GrClip& clip, const SkPaint& skPaint, diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index 5e11eb58ac..735693b48c 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -203,7 +203,7 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc, blob, x, y, drawFilter, clip); } - cacheBlob->flushCached(blob, fContext, dc, this, fSurfaceProps, fDistanceAdjustTable, skPaint, + cacheBlob->flushCached(fContext, dc, blob, fSurfaceProps, fDistanceAdjustTable, skPaint, grPaint, drawFilter, clip, viewMatrix, clipBounds, x, y, transX, transY); } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 7ce7a3163c..8ff2523a73 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -6,20 +6,14 @@ */ #include "GrTextContext.h" -#include "GrBlurUtils.h" #include "GrContext.h" -#include "GrDrawContext.h" #include "GrFontScaler.h" +#include "GrTextUtils.h" -#include "SkAutoKern.h" #include "SkDrawFilter.h" -#include "SkDrawProcs.h" #include "SkGlyphCache.h" -#include "SkGpuDevice.h" #include "SkGrPriv.h" #include "SkTextBlobRunIterator.h" -#include "SkTextMapStateProc.h" -#include "SkTextToPathIter.h" GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfaceProps) : fFallbackTextContext(nullptr) @@ -51,7 +45,8 @@ void GrTextContext::drawText(GrDrawContext* dc, } while (textContext); // fall back to drawing as a path - this->drawTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, x, y, clipBounds); + GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, byteLength, x, y, + clipBounds); } void GrTextContext::drawPosText(GrDrawContext* dc, @@ -76,8 +71,8 @@ void GrTextContext::drawPosText(GrDrawContext* dc, } while (textContext); // fall back to drawing as a path - this->drawPosTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, pos, - scalarsPerPosition, offset, clipBounds); + GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, viewMatrix, text, + byteLength, pos, scalarsPerPosition, offset, clipBounds); } bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { @@ -160,105 +155,6 @@ void GrTextContext::drawTextBlob(GrDrawContext* dc, } } -void GrTextContext::drawTextAsPath(GrDrawContext* dc, - const GrClip& clip, - const SkPaint& skPaint, const SkMatrix& viewMatrix, - const char text[], size_t byteLength, SkScalar x, SkScalar y, - const SkIRect& clipBounds) { - SkTextToPathIter iter(text, byteLength, skPaint, true); - - SkMatrix matrix; - matrix.setScale(iter.getPathScale(), iter.getPathScale()); - matrix.postTranslate(x, y); - - const SkPath* iterPath; - SkScalar xpos, prevXPos = 0; - - while (iter.next(&iterPath, &xpos)) { - matrix.postTranslate(xpos - prevXPos, 0); - if (iterPath) { - const SkPaint& pnt = iter.getPaint(); - GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *iterPath, - pnt, viewMatrix, &matrix, clipBounds, false); - } - prevXPos = xpos; - } -} - -void GrTextContext::drawPosTextAsPath(GrDrawContext* dc, - const GrClip& clip, - const SkPaint& origPaint, const SkMatrix& viewMatrix, - const char text[], size_t byteLength, - const SkScalar pos[], int scalarsPerPosition, - const SkPoint& offset, const SkIRect& clipBounds) { - // setup our std paint, in hopes of getting hits in the cache - SkPaint paint(origPaint); - SkScalar matrixScale = paint.setupForAsPaths(); - - SkMatrix matrix; - matrix.setScale(matrixScale, matrixScale); - - // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache. - paint.setStyle(SkPaint::kFill_Style); - paint.setPathEffect(nullptr); - - SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); - SkAutoGlyphCache autoCache(paint, &fSurfaceProps, nullptr); - SkGlyphCache* cache = autoCache.getCache(); - - const char* stop = text + byteLength; - SkTextAlignProc alignProc(paint.getTextAlign()); - SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); - - // Now restore the original settings, so we "draw" with whatever style/stroking. - paint.setStyle(origPaint.getStyle()); - paint.setPathEffect(origPaint.getPathEffect()); - - while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); - if (glyph.fWidth) { - const SkPath* path = cache->findPath(glyph); - if (path) { - SkPoint tmsLoc; - tmsProc(pos, &tmsLoc); - SkPoint loc; - alignProc(tmsLoc, glyph, &loc); - - matrix[SkMatrix::kMTransX] = loc.fX; - matrix[SkMatrix::kMTransY] = loc.fY; - GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *path, paint, - viewMatrix, &matrix, clipBounds, false); - } - } - pos += scalarsPerPosition; - } -} - -// *** change to output positions? -int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, - const char text[], size_t byteLength, SkVector* stopVector) { - SkFixed x = 0, y = 0; - const char* stop = text + byteLength; - - SkAutoKern autokern; - - int numGlyphs = 0; - while (text < stop) { - // don't need x, y here, since all subpixel variants will have the - // same advance - const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); - - x += autokern.adjust(glyph) + glyph.fAdvanceX; - y += glyph.fAdvanceY; - ++numGlyphs; - } - stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); - - SkASSERT(text == stop); - - return numGlyphs; -} - static void GlyphCacheAuxProc(void* data) { GrFontScaler* scaler = (GrFontScaler*)data; SkSafeUnref(scaler); diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h index 387717c6bf..1e27caa935 100644 --- a/src/gpu/GrTextContext.h +++ b/src/gpu/GrTextContext.h @@ -65,20 +65,7 @@ protected: const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset, const SkIRect& clipBounds) = 0; - void drawTextAsPath(GrDrawContext*, const GrClip& clip, - const SkPaint& origPaint, const SkMatrix& viewMatrix, - const char text[], size_t byteLength, SkScalar x, SkScalar y, - const SkIRect& clipBounds); - void drawPosTextAsPath(GrDrawContext*, const GrClip& clip, - const SkPaint& origPaint, const SkMatrix& viewMatrix, - const char text[], size_t byteLength, - const SkScalar pos[], int scalarsPerPosition, - const SkPoint& offset, const SkIRect& clipBounds); - static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache); - // sets extent in stopVector and returns glyph count - static int MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, - const char text[], size_t byteLength, SkVector* stopVector); static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint); friend class GrAtlasTextBatch; diff --git a/src/gpu/GrTextUtils.cpp b/src/gpu/GrTextUtils.cpp new file mode 100644 index 0000000000..e56b5cb29e --- /dev/null +++ b/src/gpu/GrTextUtils.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrTextUtils.h" + +#include "GrBlurUtils.h" +#include "GrContext.h" +#include "GrDrawContext.h" +#include "SkDrawProcs.h" +#include "SkGlyphCache.h" +#include "SkPaint.h" +#include "SkRect.h" +#include "SkTextMapStateProc.h" +#include "SkTextToPathIter.h" + +void GrTextUtils::DrawTextAsPath(GrContext* context, GrDrawContext* dc, + const GrClip& clip, + const SkPaint& skPaint, const SkMatrix& viewMatrix, + const char text[], size_t byteLength, SkScalar x, SkScalar y, + const SkIRect& clipBounds) { + SkTextToPathIter iter(text, byteLength, skPaint, true); + + SkMatrix matrix; + matrix.setScale(iter.getPathScale(), iter.getPathScale()); + matrix.postTranslate(x, y); + + const SkPath* iterPath; + SkScalar xpos, prevXPos = 0; + + while (iter.next(&iterPath, &xpos)) { + matrix.postTranslate(xpos - prevXPos, 0); + if (iterPath) { + const SkPaint& pnt = iter.getPaint(); + GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *iterPath, + pnt, viewMatrix, &matrix, clipBounds, false); + } + prevXPos = xpos; + } +} + +void GrTextUtils::DrawPosTextAsPath(GrContext* context, + GrDrawContext* dc, + const SkSurfaceProps& props, + const GrClip& clip, + const SkPaint& origPaint, const SkMatrix& viewMatrix, + const char text[], size_t byteLength, + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkIRect& clipBounds) { + // setup our std paint, in hopes of getting hits in the cache + SkPaint paint(origPaint); + SkScalar matrixScale = paint.setupForAsPaths(); + + SkMatrix matrix; + matrix.setScale(matrixScale, matrixScale); + + // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache. + paint.setStyle(SkPaint::kFill_Style); + paint.setPathEffect(nullptr); + + SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); + SkAutoGlyphCache autoCache(paint, &props, nullptr); + SkGlyphCache* cache = autoCache.getCache(); + + const char* stop = text + byteLength; + SkTextAlignProc alignProc(paint.getTextAlign()); + SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); + + // Now restore the original settings, so we "draw" with whatever style/stroking. + paint.setStyle(origPaint.getStyle()); + paint.setPathEffect(origPaint.getPathEffect()); + + while (text < stop) { + const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); + if (glyph.fWidth) { + const SkPath* path = cache->findPath(glyph); + if (path) { + SkPoint tmsLoc; + tmsProc(pos, &tmsLoc); + SkPoint loc; + alignProc(tmsLoc, glyph, &loc); + + matrix[SkMatrix::kMTransX] = loc.fX; + matrix[SkMatrix::kMTransY] = loc.fY; + GrBlurUtils::drawPathWithMaskFilter(context, dc, clip, *path, paint, + viewMatrix, &matrix, clipBounds, false); + } + } + pos += scalarsPerPosition; + } +} diff --git a/src/gpu/GrTextUtils.h b/src/gpu/GrTextUtils.h new file mode 100644 index 0000000000..cd2067f464 --- /dev/null +++ b/src/gpu/GrTextUtils.h @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrTextUtils_DEFINED +#define GrTextUtils_DEFINED + +#include "SkScalar.h" + +class GrClip; +class GrContext; +class GrDrawContext; +class SkMatrix; +struct SkIRect; +class SkPaint; +struct SkPoint; +class SkSurfaceProps; + +/* + * A class to house a bunch of common text utilities. This class should *ONLY* have static + * functions. It is not a namespace only because we wish to friend SkPaint + * + */ +class GrTextUtils { +public: + +static void DrawTextAsPath(GrContext*, GrDrawContext*, const GrClip& clip, + const SkPaint& origPaint, const SkMatrix& viewMatrix, + const char text[], size_t byteLength, SkScalar x, SkScalar y, + const SkIRect& clipBounds); + +static void DrawPosTextAsPath(GrContext* context, + GrDrawContext* dc, + const SkSurfaceProps& props, + const GrClip& clip, + const SkPaint& origPaint, const SkMatrix& viewMatrix, + const char text[], size_t byteLength, + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkIRect& clipBounds); +}; + +#endif