GrTextContext.cpp revision aab626c3670205d02ca42bb34a540f550cb75dc2
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 11#include "SkAutoKern.h" 12#include "SkGlyphCache.h" 13#include "GrFontScaler.h" 14 15GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) : 16 fFallbackTextContext(NULL), 17 fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) { 18} 19 20GrTextContext::~GrTextContext() { 21 SkDELETE(fFallbackTextContext); 22} 23 24void GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) { 25 const GrClipData* clipData = fContext->getClip(); 26 27 SkRect devConservativeBound; 28 clipData->fClipStack->getConservativeBounds( 29 -clipData->fOrigin.fX, 30 -clipData->fOrigin.fY, 31 fContext->getRenderTarget()->width(), 32 fContext->getRenderTarget()->height(), 33 &devConservativeBound); 34 35 devConservativeBound.roundOut(&fClipRect); 36 37 fDrawTarget = fContext->getTextTarget(); 38 39 fPaint = grPaint; 40 fSkPaint = skPaint; 41} 42 43bool GrTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, 44 const char text[], size_t byteLength, 45 SkScalar x, SkScalar y) { 46 47 GrTextContext* textContext = this; 48 do { 49 if (textContext->canDraw(skPaint)) { 50 textContext->onDrawText(paint, skPaint, text, byteLength, x, y); 51 return true; 52 } 53 textContext = textContext->fFallbackTextContext; 54 } while (textContext); 55 56 return false; 57} 58 59bool GrTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint, 60 const char text[], size_t byteLength, 61 const SkScalar pos[], int scalarsPerPosition, 62 const SkPoint& offset) { 63 64 GrTextContext* textContext = this; 65 do { 66 if (textContext->canDraw(skPaint)) { 67 textContext->onDrawPosText(paint, skPaint, text, byteLength, pos, scalarsPerPosition, 68 offset); 69 return true; 70 } 71 textContext = textContext->fFallbackTextContext; 72 } while (textContext); 73 74 return false; 75} 76 77 78//*** change to output positions? 79void GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, 80 const char text[], size_t byteLength, SkVector* stopVector) { 81 SkFixed x = 0, y = 0; 82 const char* stop = text + byteLength; 83 84 SkAutoKern autokern; 85 86 while (text < stop) { 87 // don't need x, y here, since all subpixel variants will have the 88 // same advance 89 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 90 91 x += autokern.adjust(glyph) + glyph.fAdvanceX; 92 y += glyph.fAdvanceY; 93 } 94 stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); 95 96 SkASSERT(text == stop); 97} 98 99static void GlyphCacheAuxProc(void* data) { 100 GrFontScaler* scaler = (GrFontScaler*)data; 101 SkSafeUnref(scaler); 102} 103 104GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { 105 void* auxData; 106 GrFontScaler* scaler = NULL; 107 108 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { 109 scaler = (GrFontScaler*)auxData; 110 } 111 if (NULL == scaler) { 112 scaler = SkNEW_ARGS(GrFontScaler, (cache)); 113 cache->setAuxProc(GlyphCacheAuxProc, scaler); 114 } 115 116 return scaler; 117} 118