OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrBitmapTextContext.h" | 8 #include "GrBitmapTextContext.h" |
9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
10 #include "GrDefaultGeoProcFactory.h" | 10 #include "GrDefaultGeoProcFactory.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 fTotalVertexCount = 0; | 59 fTotalVertexCount = 0; |
60 | 60 |
61 fVertexBounds.setLargestInverted(); | 61 fVertexBounds.setLargestInverted(); |
62 } | 62 } |
63 | 63 |
64 GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context, | 64 GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context, |
65 const SkDeviceProperties& props
) { | 65 const SkDeviceProperties& props
) { |
66 return SkNEW_ARGS(GrBitmapTextContext, (context, props)); | 66 return SkNEW_ARGS(GrBitmapTextContext, (context, props)); |
67 } | 67 } |
68 | 68 |
69 bool GrBitmapTextContext::canDraw(const SkPaint& paint) { | 69 bool GrBitmapTextContext::canDraw(const SkPaint& paint, const SkMatrix& viewMatr
ix) { |
70 return !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix()); | 70 return !SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix); |
71 } | 71 } |
72 | 72 |
73 inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPai
nt) { | 73 inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPai
nt) { |
74 GrTextContext::init(paint, skPaint); | 74 GrTextContext::init(paint, skPaint); |
75 | 75 |
76 fStrike = NULL; | 76 fStrike = NULL; |
77 | 77 |
78 fCurrTexture = NULL; | 78 fCurrTexture = NULL; |
79 fCurrVertex = 0; | 79 fCurrVertex = 0; |
80 | 80 |
81 fVertices = NULL; | 81 fVertices = NULL; |
82 fAllocVertexCount = 0; | 82 fAllocVertexCount = 0; |
83 fTotalVertexCount = 0; | 83 fTotalVertexCount = 0; |
84 } | 84 } |
85 | 85 |
86 void GrBitmapTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPain
t, | 86 void GrBitmapTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPain
t, |
| 87 const SkMatrix& viewMatrix, |
87 const char text[], size_t byteLength, | 88 const char text[], size_t byteLength, |
88 SkScalar x, SkScalar y) { | 89 SkScalar x, SkScalar y) { |
89 SkASSERT(byteLength == 0 || text != NULL); | 90 SkASSERT(byteLength == 0 || text != NULL); |
90 | 91 |
91 // nothing to draw | 92 // nothing to draw |
92 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { | 93 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { |
93 return; | 94 return; |
94 } | 95 } |
95 | 96 |
96 this->init(paint, skPaint); | 97 this->init(paint, skPaint); |
97 | 98 |
98 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 99 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
99 | 100 |
100 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa
trix()); | 101 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &viewMatrix); |
101 SkGlyphCache* cache = autoCache.getCache(); | 102 SkGlyphCache* cache = autoCache.getCache(); |
102 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 103 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
103 | 104 |
104 // transform our starting point | 105 // transform our starting point |
105 { | 106 { |
106 SkPoint loc; | 107 SkPoint loc; |
107 fContext->getMatrix().mapXY(x, y, &loc); | 108 viewMatrix.mapXY(x, y, &loc); |
108 x = loc.fX; | 109 x = loc.fX; |
109 y = loc.fY; | 110 y = loc.fY; |
110 } | 111 } |
111 | 112 |
112 // need to measure first | 113 // need to measure first |
113 int numGlyphs; | 114 int numGlyphs; |
114 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | 115 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { |
115 SkVector stopVector; | 116 SkVector stopVector; |
116 numGlyphs = MeasureText(cache, glyphCacheProc, text, byteLength, &stopVe
ctor); | 117 numGlyphs = MeasureText(cache, glyphCacheProc, text, byteLength, &stopVe
ctor); |
117 | 118 |
(...skipping 13 matching lines...) Expand all Loading... |
131 | 132 |
132 const char* stop = text + byteLength; | 133 const char* stop = text + byteLength; |
133 | 134 |
134 SkAutoKern autokern; | 135 SkAutoKern autokern; |
135 | 136 |
136 SkFixed fxMask = ~0; | 137 SkFixed fxMask = ~0; |
137 SkFixed fyMask = ~0; | 138 SkFixed fyMask = ~0; |
138 SkFixed halfSampleX, halfSampleY; | 139 SkFixed halfSampleX, halfSampleY; |
139 if (cache->isSubpixel()) { | 140 if (cache->isSubpixel()) { |
140 halfSampleX = halfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits); | 141 halfSampleX = halfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits); |
141 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(fContext->getM
atrix()); | 142 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
142 if (kX_SkAxisAlignment == baseline) { | 143 if (kX_SkAxisAlignment == baseline) { |
143 fyMask = 0; | 144 fyMask = 0; |
144 halfSampleY = SK_FixedHalf; | 145 halfSampleY = SK_FixedHalf; |
145 } else if (kY_SkAxisAlignment == baseline) { | 146 } else if (kY_SkAxisAlignment == baseline) { |
146 fxMask = 0; | 147 fxMask = 0; |
147 halfSampleX = SK_FixedHalf; | 148 halfSampleX = SK_FixedHalf; |
148 } | 149 } |
149 } else { | 150 } else { |
150 halfSampleX = halfSampleY = SK_FixedHalf; | 151 halfSampleX = halfSampleY = SK_FixedHalf; |
151 } | 152 } |
152 | 153 |
153 SkFixed fx = SkScalarToFixed(x) + halfSampleX; | 154 SkFixed fx = SkScalarToFixed(x) + halfSampleX; |
154 SkFixed fy = SkScalarToFixed(y) + halfSampleY; | 155 SkFixed fy = SkScalarToFixed(y) + halfSampleY; |
155 | 156 |
156 GrContext::AutoMatrix autoMatrix; | 157 if (!fPaint.localCoordChangeInverse(viewMatrix)) { |
157 autoMatrix.setIdentity(fContext, &fPaint); | 158 SkDebugf("Cannot invert viewmatrix\n"); |
| 159 } |
158 | 160 |
159 while (text < stop) { | 161 while (text < stop) { |
160 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy
Mask); | 162 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy
Mask); |
161 | 163 |
162 fx += autokern.adjust(glyph); | 164 fx += autokern.adjust(glyph); |
163 | 165 |
164 if (glyph.fWidth) { | 166 if (glyph.fWidth) { |
165 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 167 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
166 glyph.getSubXFixed(), | 168 glyph.getSubXFixed(), |
167 glyph.getSubYFixed()), | 169 glyph.getSubYFixed()), |
168 SkFixedFloorToFixed(fx), | 170 SkFixedFloorToFixed(fx), |
169 SkFixedFloorToFixed(fy), | 171 SkFixedFloorToFixed(fy), |
170 fontScaler); | 172 fontScaler); |
171 } | 173 } |
172 | 174 |
173 fx += glyph.fAdvanceX; | 175 fx += glyph.fAdvanceX; |
174 fy += glyph.fAdvanceY; | 176 fy += glyph.fAdvanceY; |
175 } | 177 } |
176 | 178 |
177 this->finish(); | 179 this->finish(); |
178 } | 180 } |
179 | 181 |
180 void GrBitmapTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skP
aint, | 182 void GrBitmapTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skP
aint, |
| 183 const SkMatrix& viewMatrix, |
181 const char text[], size_t byteLength, | 184 const char text[], size_t byteLength, |
182 const SkScalar pos[], int scalarsPerPosi
tion, | 185 const SkScalar pos[], int scalarsPerPosi
tion, |
183 const SkPoint& offset) { | 186 const SkPoint& offset) { |
184 SkASSERT(byteLength == 0 || text != NULL); | 187 SkASSERT(byteLength == 0 || text != NULL); |
185 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 188 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
186 | 189 |
187 // nothing to draw | 190 // nothing to draw |
188 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { | 191 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { |
189 return; | 192 return; |
190 } | 193 } |
191 | 194 |
192 this->init(paint, skPaint); | 195 this->init(paint, skPaint); |
193 | 196 |
194 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 197 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
195 | 198 |
196 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa
trix()); | 199 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &viewMatrix); |
197 SkGlyphCache* cache = autoCache.getCache(); | 200 SkGlyphCache* cache = autoCache.getCache(); |
198 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 201 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
199 | 202 |
200 // store original matrix before we reset, so we can use it to transform posi
tions | 203 // store original matrix before we reset, so we can use it to transform posi
tions |
201 SkMatrix ctm = fContext->getMatrix(); | 204 SkMatrix ctm = viewMatrix; |
202 GrContext::AutoMatrix autoMatrix; | 205 if (!fPaint.localCoordChangeInverse(viewMatrix)) { |
203 autoMatrix.setIdentity(fContext, &fPaint); | 206 SkDebugf("Cannot invert viewmatrix\n"); |
| 207 } |
204 | 208 |
205 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); | 209 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL); |
206 fTotalVertexCount = kVerticesPerGlyph*numGlyphs; | 210 fTotalVertexCount = kVerticesPerGlyph*numGlyphs; |
207 | 211 |
208 const char* stop = text + byteLength; | 212 const char* stop = text + byteLength; |
209 SkTextAlignProc alignProc(fSkPaint.getTextAlign()); | 213 SkTextAlignProc alignProc(fSkPaint.getTextAlign()); |
210 SkTextMapStateProc tmsProc(ctm, offset, scalarsPerPosition); | 214 SkTextMapStateProc tmsProc(ctm, offset, scalarsPerPosition); |
211 SkFixed halfSampleX = 0, halfSampleY = 0; | 215 SkFixed halfSampleX = 0, halfSampleY = 0; |
212 | 216 |
213 if (cache->isSubpixel()) { | 217 if (cache->isSubpixel()) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // flag the glyph as being dead? | 437 // flag the glyph as being dead? |
434 delete path; | 438 delete path; |
435 return; | 439 return; |
436 } | 440 } |
437 glyph->fPath = path; | 441 glyph->fPath = path; |
438 } | 442 } |
439 | 443 |
440 // flush any accumulated draws before drawing this glyph as a path. | 444 // flush any accumulated draws before drawing this glyph as a path. |
441 this->flush(); | 445 this->flush(); |
442 | 446 |
443 GrContext::AutoMatrix am; | |
444 SkMatrix translate; | 447 SkMatrix translate; |
445 translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds.
fLeft)), | 448 translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds.
fLeft)), |
446 SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.
fTop))); | 449 SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds.
fTop))); |
447 GrPaint tmpPaint(fPaint); | 450 GrPaint tmpPaint(fPaint); |
448 am.setPreConcat(fContext, translate, &tmpPaint); | 451 tmpPaint.localCoordChange(translate); |
449 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 452 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
450 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); | 453 fContext->drawPath(tmpPaint, translate, *glyph->fPath, strokeInfo); |
451 | 454 |
452 // remove this glyph from the vertices we need to allocate | 455 // remove this glyph from the vertices we need to allocate |
453 fTotalVertexCount -= kVerticesPerGlyph; | 456 fTotalVertexCount -= kVerticesPerGlyph; |
454 return; | 457 return; |
455 } | 458 } |
456 | 459 |
457 SkASSERT(glyph->fPlot); | 460 SkASSERT(glyph->fPlot); |
458 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); | 461 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); |
459 glyph->fPlot->setDrawToken(drawToken); | 462 glyph->fPlot->setDrawToken(drawToken); |
460 | 463 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 } | 606 } |
604 } | 607 } |
605 | 608 |
606 inline void GrBitmapTextContext::finish() { | 609 inline void GrBitmapTextContext::finish() { |
607 this->flush(); | 610 this->flush(); |
608 fTotalVertexCount = 0; | 611 fTotalVertexCount = 0; |
609 | 612 |
610 GrTextContext::finish(); | 613 GrTextContext::finish(); |
611 } | 614 } |
612 | 615 |
OLD | NEW |