GrTextContext.cpp revision 570d2f81a65fc868d6300a7edf34c0d5d048c5d6
1/* 2 * Copyright 2010 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrTextContext.h" 9#include "GrContext.h" 10#include "GrDrawTarget.h" 11#include "GrFontScaler.h" 12 13#include "SkAutoKern.h" 14#include "SkGlyphCache.h" 15 16GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) : 17 fFallbackTextContext(NULL), 18 fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) { 19} 20 21GrTextContext::~GrTextContext() { 22 SkDELETE(fFallbackTextContext); 23} 24 25void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint, 26 const SkPaint& skPaint) { 27 fClip = clip; 28 29 fRenderTarget.reset(SkRef(rt)); 30 31 fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect); 32 33 fDrawTarget = fContext->getTextTarget(); 34 35 fPaint = grPaint; 36 fSkPaint = skPaint; 37} 38 39bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, 40 const SkPaint& skPaint, const SkMatrix& viewMatrix, 41 const char text[], size_t byteLength, 42 SkScalar x, SkScalar y) { 43 44 GrTextContext* textContext = this; 45 do { 46 if (textContext->canDraw(skPaint, viewMatrix)) { 47 textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y); 48 return true; 49 } 50 textContext = textContext->fFallbackTextContext; 51 } while (textContext); 52 53 return false; 54} 55 56bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, 57 const SkPaint& skPaint, const SkMatrix& viewMatrix, 58 const char text[], size_t byteLength, 59 const SkScalar pos[], int scalarsPerPosition, 60 const SkPoint& offset) { 61 62 GrTextContext* textContext = this; 63 do { 64 if (textContext->canDraw(skPaint, viewMatrix)) { 65 textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, pos, 66 scalarsPerPosition, offset); 67 return true; 68 } 69 textContext = textContext->fFallbackTextContext; 70 } while (textContext); 71 72 return false; 73} 74 75 76//*** change to output positions? 77int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, 78 const char text[], size_t byteLength, SkVector* stopVector) { 79 SkFixed x = 0, y = 0; 80 const char* stop = text + byteLength; 81 82 SkAutoKern autokern; 83 84 int numGlyphs = 0; 85 while (text < stop) { 86 // don't need x, y here, since all subpixel variants will have the 87 // same advance 88 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 89 90 x += autokern.adjust(glyph) + glyph.fAdvanceX; 91 y += glyph.fAdvanceY; 92 ++numGlyphs; 93 } 94 stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); 95 96 SkASSERT(text == stop); 97 98 return numGlyphs; 99} 100 101static void GlyphCacheAuxProc(void* data) { 102 GrFontScaler* scaler = (GrFontScaler*)data; 103 SkSafeUnref(scaler); 104} 105 106GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { 107 void* auxData; 108 GrFontScaler* scaler = NULL; 109 110 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { 111 scaler = (GrFontScaler*)auxData; 112 } 113 if (NULL == scaler) { 114 scaler = SkNEW_ARGS(GrFontScaler, (cache)); 115 cache->setAuxProc(GlyphCacheAuxProc, scaler); 116 } 117 118 return scaler; 119} 120