1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrTextContext.h"
#include "GrContext.h"
#include "SkAutoKern.h"
#include "SkGlyphCache.h"
#include "GrFontScaler.h"
GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
fFallbackTextContext(NULL),
fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
}
GrTextContext::~GrTextContext() {
SkDELETE(fFallbackTextContext);
}
void GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) {
const GrClipData* clipData = fContext->getClip();
SkRect devConservativeBound;
clipData->fClipStack->getConservativeBounds(
-clipData->fOrigin.fX,
-clipData->fOrigin.fY,
fContext->getRenderTarget()->width(),
fContext->getRenderTarget()->height(),
&devConservativeBound);
devConservativeBound.roundOut(&fClipRect);
fDrawTarget = fContext->getTextTarget();
fPaint = grPaint;
fSkPaint = skPaint;
}
bool GrTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
GrTextContext* textContext = this;
do {
if (textContext->canDraw(skPaint)) {
textContext->onDrawText(paint, skPaint, text, byteLength, x, y);
return true;
}
textContext = textContext->fFallbackTextContext;
} while (textContext);
return false;
}
bool GrTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) {
GrTextContext* textContext = this;
do {
if (textContext->canDraw(skPaint)) {
textContext->onDrawPosText(paint, skPaint, text, byteLength, pos, scalarsPerPosition,
offset);
return true;
}
textContext = textContext->fFallbackTextContext;
} while (textContext);
return false;
}
//*** 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);
}
GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) {
void* auxData;
GrFontScaler* scaler = NULL;
if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
scaler = (GrFontScaler*)auxData;
}
if (NULL == scaler) {
scaler = SkNEW_ARGS(GrFontScaler, (cache));
cache->setAuxProc(GlyphCacheAuxProc, scaler);
}
return scaler;
}
|