Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrTextContext.cpp
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
15 GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
16                             fFallbackTextContext(NULL),
17                             fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
18 }
19
20 GrTextContext::~GrTextContext() {
21     SkDELETE(fFallbackTextContext);
22 }
23
24 void 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
43 bool 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
59 bool 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?
79 int 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     int numGlyphs = 0;
87     while (text < stop) {
88         // don't need x, y here, since all subpixel variants will have the
89         // same advance
90         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
91
92         x += autokern.adjust(glyph) + glyph.fAdvanceX;
93         y += glyph.fAdvanceY;
94         ++numGlyphs;
95     }
96     stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
97
98     SkASSERT(text == stop);
99     
100     return numGlyphs;
101 }
102
103 static void GlyphCacheAuxProc(void* data) {
104     GrFontScaler* scaler = (GrFontScaler*)data;
105     SkSafeUnref(scaler);
106 }
107
108 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) {
109     void* auxData;
110     GrFontScaler* scaler = NULL;
111
112     if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
113         scaler = (GrFontScaler*)auxData;
114     }
115     if (NULL == scaler) {
116         scaler = SkNEW_ARGS(GrFontScaler, (cache));
117         cache->setAuxProc(GlyphCacheAuxProc, scaler);
118     }
119
120     return scaler;
121 }