Create GrTextUtils

BUG=skia:

Review URL: https://codereview.chromium.org/1514933002
This commit is contained in:
joshualitt 2015-12-10 13:20:58 -08:00 committed by Commit bot
parent 90c4d5fec8
commit 0a42e6827b
9 changed files with 160 additions and 138 deletions

View File

@ -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',

View File

@ -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;

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

94
src/gpu/GrTextUtils.cpp Normal file
View File

@ -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;
}
}

45
src/gpu/GrTextUtils.h Normal file
View File

@ -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