OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrTextContext.h" | 8 #include "GrTextContext.h" |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
11 #include "GrFontScaler.h" | 11 #include "GrFontScaler.h" |
12 | 12 |
13 #include "SkAutoKern.h" | 13 #include "SkAutoKern.h" |
| 14 #include "SkDrawProcs.h" |
14 #include "SkGlyphCache.h" | 15 #include "SkGlyphCache.h" |
| 16 #include "SkGpuDevice.h" |
| 17 #include "SkTextMapStateProc.h" |
| 18 #include "SkTextToPathIter.h" |
15 | 19 |
16 GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& prope
rties) : | 20 GrTextContext::GrTextContext(GrContext* context, SkGpuDevice* gpuDevice, |
17 fFallbackTextContext(NULL), | 21 const SkDeviceProperties& properties) |
18 fContext(context), fDeviceProperties(properties), fD
rawTarget(NULL) { | 22 : fFallbackTextContext(NULL) |
| 23 , fContext(context) |
| 24 , fGpuDevice(gpuDevice) |
| 25 , fDeviceProperties(properties) |
| 26 , fDrawTarget(NULL) { |
19 } | 27 } |
20 | 28 |
21 GrTextContext::~GrTextContext() { | 29 GrTextContext::~GrTextContext() { |
22 SkDELETE(fFallbackTextContext); | 30 SkDELETE(fFallbackTextContext); |
23 } | 31 } |
24 | 32 |
25 void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint&
grPaint, | 33 void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint&
grPaint, |
26 const SkPaint& skPaint) { | 34 const SkPaint& skPaint, const SkIRect& regionClipBounds
) { |
27 fClip = clip; | 35 fClip = clip; |
28 | 36 |
29 fRenderTarget.reset(SkRef(rt)); | 37 fRenderTarget.reset(SkRef(rt)); |
30 | 38 |
| 39 fRegionClipBounds = regionClipBounds; |
31 fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(),
&fClipRect); | 40 fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(),
&fClipRect); |
32 | 41 |
33 fDrawTarget = fContext->getTextTarget(); | 42 fDrawTarget = fContext->getTextTarget(); |
34 | 43 |
35 fPaint = grPaint; | 44 fPaint = grPaint; |
36 fSkPaint = skPaint; | 45 fSkPaint = skPaint; |
37 } | 46 } |
38 | 47 |
39 bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
nt& paint, | 48 void GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
nt& paint, |
40 const SkPaint& skPaint, const SkMatrix& viewMatrix, | 49 const SkPaint& skPaint, const SkMatrix& viewMatrix, |
41 const char text[], size_t byteLength, | 50 const char text[], size_t byteLength, |
42 SkScalar x, SkScalar y) { | 51 SkScalar x, SkScalar y, const SkIRect& clipBounds)
{ |
43 if (!fContext->getTextTarget()) { | 52 if (!fContext->getTextTarget()) { |
44 return false; | 53 return; |
45 } | 54 } |
46 | 55 |
47 GrTextContext* textContext = this; | 56 GrTextContext* textContext = this; |
48 do { | 57 do { |
49 if (textContext->canDraw(skPaint, viewMatrix)) { | 58 if (textContext->canDraw(skPaint, viewMatrix)) { |
50 textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text,
byteLength, x, y); | 59 textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text,
byteLength, x, y, |
51 return true; | 60 clipBounds); |
| 61 return; |
52 } | 62 } |
53 textContext = textContext->fFallbackTextContext; | 63 textContext = textContext->fFallbackTextContext; |
54 } while (textContext); | 64 } while (textContext); |
55 | 65 |
56 return false; | 66 // fall back to drawing as a path |
| 67 this->drawTextAsPath(skPaint, viewMatrix, text, byteLength, x, y, clipBounds
); |
57 } | 68 } |
58 | 69 |
59 bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
Paint& paint, | 70 void GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
Paint& paint, |
60 const SkPaint& skPaint, const SkMatrix& viewMatr
ix, | 71 const SkPaint& skPaint, const SkMatrix& viewMatr
ix, |
61 const char text[], size_t byteLength, | 72 const char text[], size_t byteLength, |
62 const SkScalar pos[], int scalarsPerPosition, | 73 const SkScalar pos[], int scalarsPerPosition, |
63 const SkPoint& offset) { | 74 const SkPoint& offset, const SkIRect& clipBounds
) { |
64 if (!fContext->getTextTarget()) { | 75 if (!fContext->getTextTarget()) { |
65 return false; | 76 return; |
66 } | 77 } |
67 | 78 |
68 GrTextContext* textContext = this; | 79 GrTextContext* textContext = this; |
69 do { | 80 do { |
70 if (textContext->canDraw(skPaint, viewMatrix)) { | 81 if (textContext->canDraw(skPaint, viewMatrix)) { |
71 textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, tex
t, byteLength, pos, | 82 textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, tex
t, byteLength, pos, |
72 scalarsPerPosition, offset); | 83 scalarsPerPosition, offset, clipBounds); |
73 return true; | 84 return; |
74 } | 85 } |
75 textContext = textContext->fFallbackTextContext; | 86 textContext = textContext->fFallbackTextContext; |
76 } while (textContext); | 87 } while (textContext); |
77 | 88 |
78 return false; | 89 // fall back to drawing as a path |
| 90 this->drawPosTextAsPath(skPaint, viewMatrix, text, byteLength, pos, scalarsP
erPosition, offset, |
| 91 clipBounds); |
79 } | 92 } |
80 | 93 |
| 94 void GrTextContext::drawTextAsPath(const SkPaint& skPaint, const SkMatrix& viewM
atrix, |
| 95 const char text[], size_t byteLength, SkScala
r x, SkScalar y, |
| 96 const SkIRect& clipBounds) { |
| 97 SkTextToPathIter iter(text, byteLength, skPaint, true); |
| 98 |
| 99 SkMatrix matrix; |
| 100 matrix.setScale(iter.getPathScale(), iter.getPathScale()); |
| 101 matrix.postTranslate(x, y); |
| 102 |
| 103 const SkPath* iterPath; |
| 104 SkScalar xpos, prevXPos = 0; |
| 105 |
| 106 while (iter.next(&iterPath, &xpos)) { |
| 107 matrix.postTranslate(xpos - prevXPos, 0); |
| 108 if (iterPath) { |
| 109 const SkPaint& pnt = iter.getPaint(); |
| 110 fGpuDevice->internalDrawPath(*iterPath, pnt, viewMatrix, &matrix, cl
ipBounds, false); |
| 111 } |
| 112 prevXPos = xpos; |
| 113 } |
| 114 } |
| 115 |
| 116 void GrTextContext::drawPosTextAsPath(const SkPaint& origPaint, const SkMatrix&
viewMatrix, |
| 117 const char text[], size_t byteLength, |
| 118 const SkScalar pos[], int scalarsPerPositi
on, |
| 119 const SkPoint& offset, const SkIRect& clip
Bounds) { |
| 120 // setup our std paint, in hopes of getting hits in the cache |
| 121 SkPaint paint(origPaint); |
| 122 SkScalar matrixScale = paint.setupForAsPaths(); |
| 123 |
| 124 SkMatrix matrix; |
| 125 matrix.setScale(matrixScale, matrixScale); |
| 126 |
| 127 // Temporarily jam in kFill, so we only ever ask for the raw outline from th
e cache. |
| 128 paint.setStyle(SkPaint::kFill_Style); |
| 129 paint.setPathEffect(NULL); |
| 130 |
| 131 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
| 132 SkAutoGlyphCache autoCache(paint, NULL, NULL); |
| 133 SkGlyphCache* cache = autoCache.getCache(); |
| 134 |
| 135 const char* stop = text + byteLength; |
| 136 SkTextAlignProc alignProc(paint.getTextAlign()); |
| 137 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); |
| 138 |
| 139 // Now restore the original settings, so we "draw" with whatever style/strok
ing. |
| 140 paint.setStyle(origPaint.getStyle()); |
| 141 paint.setPathEffect(origPaint.getPathEffect()); |
| 142 |
| 143 while (text < stop) { |
| 144 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 145 if (glyph.fWidth) { |
| 146 const SkPath* path = cache->findPath(glyph); |
| 147 if (path) { |
| 148 SkPoint tmsLoc; |
| 149 tmsProc(pos, &tmsLoc); |
| 150 SkPoint loc; |
| 151 alignProc(tmsLoc, glyph, &loc); |
| 152 |
| 153 matrix[SkMatrix::kMTransX] = loc.fX; |
| 154 matrix[SkMatrix::kMTransY] = loc.fY; |
| 155 fGpuDevice->internalDrawPath(*path, paint, viewMatrix, &matrix,
clipBounds, false); |
| 156 } |
| 157 } |
| 158 pos += scalarsPerPosition; |
| 159 } |
| 160 } |
81 | 161 |
82 //*** change to output positions? | 162 //*** change to output positions? |
83 int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCachePr
oc, | 163 int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCachePr
oc, |
84 const char text[], size_t byteLength, SkVector*
stopVector) { | 164 const char text[], size_t byteLength, SkVector*
stopVector) { |
85 SkFixed x = 0, y = 0; | 165 SkFixed x = 0, y = 0; |
86 const char* stop = text + byteLength; | 166 const char* stop = text + byteLength; |
87 | 167 |
88 SkAutoKern autokern; | 168 SkAutoKern autokern; |
89 | 169 |
90 int numGlyphs = 0; | 170 int numGlyphs = 0; |
(...skipping 25 matching lines...) Expand all Loading... |
116 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { | 196 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { |
117 scaler = (GrFontScaler*)auxData; | 197 scaler = (GrFontScaler*)auxData; |
118 } | 198 } |
119 if (NULL == scaler) { | 199 if (NULL == scaler) { |
120 scaler = SkNEW_ARGS(GrFontScaler, (cache)); | 200 scaler = SkNEW_ARGS(GrFontScaler, (cache)); |
121 cache->setAuxProc(GlyphCacheAuxProc, scaler); | 201 cache->setAuxProc(GlyphCacheAuxProc, scaler); |
122 } | 202 } |
123 | 203 |
124 return scaler; | 204 return scaler; |
125 } | 205 } |
OLD | NEW |