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