| 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 #include "GrBitmapTextContext.h" | 7 #include "GrBitmapTextContext.h" |
| 8 | 8 |
| 9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
| 10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const
SkPaint& paint, | 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const
SkPaint& paint, |
| 97 const SkMatrix& viewMatrix, SkScala
r x, SkScalar y) { | 97 const SkMatrix& viewMatrix, SkScala
r x, SkScalar y) { |
| 98 // We always regenerate blobs with patheffects or mask filters we could cach
e these | 98 // We always regenerate blobs with patheffects or mask filters we could cach
e these |
| 99 // TODO find some way to cache the maskfilter / patheffects on the textblob | 99 // TODO find some way to cache the maskfilter / patheffects on the textblob |
| 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY
!= y || | 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY
!= y || |
| 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() !
= blob.fStyle; | 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() !
= blob.fStyle; |
| 102 } | 102 } |
| 103 | 103 |
| 104 |
| 105 inline SkGlyphCache* GrBitmapTextContextB::setupCache(BitmapTextBlob::Run* run, |
| 106 const SkPaint& skPaint, |
| 107 const SkMatrix& viewMatrix
) { |
| 108 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); |
| 109 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
| 110 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; |
| 111 } |
| 112 |
| 113 inline void GrBitmapTextContextB::BlobGlyphCount(int* glyphCount, int* runCount, |
| 114 const SkTextBlob* blob) { |
| 115 SkTextBlob::RunIterator itCounter(blob); |
| 116 for (; !itCounter.done(); itCounter.next(), (*runCount)++) { |
| 117 *glyphCount += itCounter.glyphCount(); |
| 118 } |
| 119 } |
| 120 |
| 121 GrBitmapTextContextB::BitmapTextBlob* GrBitmapTextContextB::CreateBlob(int glyph
Count, |
| 122 int runCo
unt) { |
| 123 // We allocate size for the BitmapTextBlob itself, plus size for the vertice
s array, |
| 124 // and size for the glyphIds array. |
| 125 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >=
kLCDTextVASize, |
| 126 vertex_attribute_changed); |
| 127 size_t verticesCount = glyphCount * kVerticesPerGlyph * kGrayTextVASize; |
| 128 size_t length = sizeof(BitmapTextBlob) + |
| 129 verticesCount + |
| 130 glyphCount * sizeof(GrGlyph::PackedID) + |
| 131 sizeof(BitmapTextBlob::Run) * runCount; |
| 132 |
| 133 BitmapTextBlob* cacheBlob = SkNEW_PLACEMENT(sk_malloc_throw(length), BitmapT
extBlob); |
| 134 |
| 135 // setup offsets for vertices / glyphs |
| 136 cacheBlob->fVertices = sizeof(BitmapTextBlob) + reinterpret_cast<unsigned ch
ar*>(cacheBlob); |
| 137 cacheBlob->fGlyphIDs = |
| 138 reinterpret_cast<GrGlyph::PackedID*>(cacheBlob->fVertices + vertices
Count); |
| 139 cacheBlob->fRuns = reinterpret_cast<BitmapTextBlob::Run*>(cacheBlob->fGlyphI
Ds + glyphCount); |
| 140 |
| 141 // Initialize runs |
| 142 for (int i = 0; i < runCount; i++) { |
| 143 SkNEW_PLACEMENT(&cacheBlob->fRuns[i], BitmapTextBlob::Run); |
| 144 } |
| 145 cacheBlob->fRunCount = runCount; |
| 146 return cacheBlob; |
| 147 } |
| 148 |
| 104 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 149 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
| 105 const SkPaint& skPaint, const SkMatrix&
viewMatrix, | 150 const SkPaint& skPaint, const SkMatrix&
viewMatrix, |
| 106 const SkTextBlob* blob, SkScalar x, SkSc
alar y, | 151 const SkTextBlob* blob, SkScalar x, SkSc
alar y, |
| 107 SkDrawFilter* drawFilter, const SkIRect&
clipBounds) { | 152 SkDrawFilter* drawFilter, const SkIRect&
clipBounds) { |
| 108 BitmapTextBlob* cacheBlob; | 153 BitmapTextBlob* cacheBlob; |
| 109 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); | 154 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); |
| 110 | |
| 111 SkIRect clipRect; | 155 SkIRect clipRect; |
| 112 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 156 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 113 | 157 |
| 114 if (foundBlob) { | 158 if (foundBlob) { |
| 115 cacheBlob = *foundBlob; | 159 cacheBlob = *foundBlob; |
| 116 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { | 160 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { |
| 117 // We can get away with reusing the blob if there are no outstanding
refs on it. | 161 // We have to remake the blob because changes may invalidate our mas
ks. |
| 118 // However, we still have to reset all of the runs. | 162 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
| 119 if (!cacheBlob->unique()) { | 163 // but we'd have to clear the subrun information |
| 120 cacheBlob->unref(); | 164 cacheBlob->unref(); |
| 121 cacheBlob = SkNEW(BitmapTextBlob); | 165 int glyphCount = 0; |
| 122 fCache.set(blob->uniqueID(), cacheBlob); | 166 int runCount = 0; |
| 123 } | 167 BlobGlyphCount(&glyphCount, &runCount, blob); |
| 168 cacheBlob = CreateBlob(glyphCount, runCount); |
| 169 fCache.set(blob->uniqueID(), cacheBlob); |
| 124 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, | 170 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, |
| 125 clipRect); | 171 clipRect); |
| 126 } | 172 } |
| 127 } else { | 173 } else { |
| 128 cacheBlob = SkNEW(BitmapTextBlob); | 174 int glyphCount = 0; |
| 175 int runCount = 0; |
| 176 BlobGlyphCount(&glyphCount, &runCount, blob); |
| 177 cacheBlob = CreateBlob(glyphCount, runCount); |
| 129 fCache.set(blob->uniqueID(), cacheBlob); | 178 fCache.set(blob->uniqueID(), cacheBlob); |
| 130 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); | 179 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); |
| 131 } | 180 } |
| 132 | 181 |
| 133 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 182 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
| 134 // info. | 183 // info. |
| 135 GrPaint grPaint; | 184 GrPaint grPaint; |
| 136 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); | 185 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); |
| 137 | 186 |
| 138 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat
rix, | 187 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat
rix, |
| 139 fSkPaint.getAlpha()); | 188 fSkPaint.getAlpha()); |
| 140 } | 189 } |
| 141 | 190 |
| 142 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 191 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
| 143 const SkPaint& skPaint, const SkMa
trix& viewMatrix, | 192 const SkPaint& skPaint, const SkMa
trix& viewMatrix, |
| 144 const SkTextBlob* blob, SkScalar x
, SkScalar y, | 193 const SkTextBlob* blob, SkScalar x
, SkScalar y, |
| 145 SkDrawFilter* drawFilter, const Sk
IRect& clipRect) { | 194 SkDrawFilter* drawFilter, const Sk
IRect& clipRect) { |
| 146 cacheBlob->fViewMatrix = viewMatrix; | 195 cacheBlob->fViewMatrix = viewMatrix; |
| 147 cacheBlob->fX = x; | 196 cacheBlob->fX = x; |
| 148 cacheBlob->fY = y; | 197 cacheBlob->fY = y; |
| 149 cacheBlob->fStyle = skPaint.getStyle(); | 198 cacheBlob->fStyle = skPaint.getStyle(); |
| 150 cacheBlob->fRuns.reset(blob->fRunCount); | |
| 151 | 199 |
| 152 // Regenerate textblob | 200 // Regenerate textblob |
| 153 SkPaint runPaint = skPaint; | 201 SkPaint runPaint = skPaint; |
| 154 SkTextBlob::RunIterator it(blob); | 202 SkTextBlob::RunIterator it(blob); |
| 155 for (int run = 0; !it.done(); it.next(), run++) { | 203 for (int run = 0; !it.done(); it.next(), run++) { |
| 156 size_t textLen = it.glyphCount() * sizeof(uint16_t); | 204 int glyphCount = it.glyphCount(); |
| 205 size_t textLen = glyphCount * sizeof(uint16_t); |
| 157 const SkPoint& offset = it.offset(); | 206 const SkPoint& offset = it.offset(); |
| 158 // applyFontToPaint() always overwrites the exact same attributes, | 207 // applyFontToPaint() always overwrites the exact same attributes, |
| 159 // so it is safe to not re-seed the paint for this reason. | 208 // so it is safe to not re-seed the paint for this reason. |
| 160 it.applyFontToPaint(&runPaint); | 209 it.applyFontToPaint(&runPaint); |
| 161 | 210 |
| 162 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { | 211 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { |
| 163 // A false return from filter() means we should abort the current dr
aw. | 212 // A false return from filter() means we should abort the current dr
aw. |
| 164 runPaint = skPaint; | 213 runPaint = skPaint; |
| 165 continue; | 214 continue; |
| 166 } | 215 } |
| 167 | 216 |
| 168 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); | 217 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); |
| 169 | 218 |
| 219 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPaint,
viewMatrix); |
| 220 |
| 221 // setup vertex / glyphIndex for the new run |
| 222 if (run > 0) { |
| 223 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); |
| 224 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back(
); |
| 225 |
| 226 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; |
| 227 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; |
| 228 |
| 229 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; |
| 230 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; |
| 231 } |
| 232 |
| 170 switch (it.positioning()) { | 233 switch (it.positioning()) { |
| 171 case SkTextBlob::kDefault_Positioning: | 234 case SkTextBlob::kDefault_Positioning: |
| 172 this->internalDrawText(cacheBlob, run, runPaint, viewMatrix, | 235 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr
ix, |
| 173 (const char *)it.glyphs(), textLen, | 236 (const char *)it.glyphs(), textLen, |
| 174 x + offset.x(), y + offset.y(), clipRect)
; | 237 x + offset.x(), y + offset.y(), clipRect)
; |
| 175 break; | 238 break; |
| 176 case SkTextBlob::kHorizontal_Positioning: | 239 case SkTextBlob::kHorizontal_Positioning: |
| 177 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 240 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, |
| 178 (const char*)it.glyphs(), textLen, it.
pos(), 1, | 241 (const char*)it.glyphs(), textLen, it.
pos(), 1, |
| 179 SkPoint::Make(x, y + offset.y()), clip
Rect); | 242 SkPoint::Make(x, y + offset.y()), clip
Rect); |
| 180 break; | 243 break; |
| 181 case SkTextBlob::kFull_Positioning: | 244 case SkTextBlob::kFull_Positioning: |
| 182 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 245 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM
atrix, |
| 183 (const char*)it.glyphs(), textLen, it.
pos(), 2, | 246 (const char*)it.glyphs(), textLen, it.
pos(), 2, |
| 184 SkPoint::Make(x, y), clipRect); | 247 SkPoint::Make(x, y), clipRect); |
| 185 break; | 248 break; |
| 186 } | 249 } |
| 187 | 250 |
| 188 if (drawFilter) { | 251 if (drawFilter) { |
| 189 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | 252 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. |
| 190 runPaint = skPaint; | 253 runPaint = skPaint; |
| 191 } | 254 } |
| 255 |
| 256 SkGlyphCache::AttachCache(cache); |
| 192 } | 257 } |
| 193 } | 258 } |
| 194 | 259 |
| 195 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, | 260 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
| 196 const GrPaint& paint, const SkPaint& skPain
t, | 261 const GrPaint& paint, const SkPaint& skPain
t, |
| 197 const SkMatrix& viewMatrix, | 262 const SkMatrix& viewMatrix, |
| 198 const char text[], size_t byteLength, | 263 const char text[], size_t byteLength, |
| 199 SkScalar x, SkScalar y, const SkIRect& regi
onClipBounds) { | 264 SkScalar x, SkScalar y, const SkIRect& regi
onClipBounds) { |
| 200 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 265 int glyphCount = skPaint.countText(text, byteLength); |
| 266 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
| 201 blob->fViewMatrix = viewMatrix; | 267 blob->fViewMatrix = viewMatrix; |
| 202 blob->fX = x; | 268 blob->fX = x; |
| 203 blob->fY = y; | 269 blob->fY = y; |
| 204 blob->fStyle = skPaint.getStyle(); | 270 blob->fStyle = skPaint.getStyle(); |
| 205 blob->fRuns.push_back(); | |
| 206 | 271 |
| 207 SkIRect clipRect; | 272 SkIRect clipRect; |
| 208 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 273 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 209 this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y,
clipRect); | 274 |
| 275 // setup cache |
| 276 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 277 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength
, x, y, clipRect); |
| 278 SkGlyphCache::AttachCache(cache); |
| 279 |
| 210 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk
Paint.getAlpha()); | 280 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk
Paint.getAlpha()); |
| 211 } | 281 } |
| 212 | 282 |
| 213 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, | 283 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
| 214 const SkPaint& skPaint, | 284 SkGlyphCache* cache, const SkPaint&
skPaint, |
| 215 const SkMatrix& viewMatrix, | 285 const SkMatrix& viewMatrix, |
| 216 const char text[], size_t byteLength, | 286 const char text[], size_t byteLength, |
| 217 SkScalar x, SkScalar y, const SkIRect
& clipRect) { | 287 SkScalar x, SkScalar y, const SkIRect
& clipRect) { |
| 218 SkASSERT(byteLength == 0 || text != NULL); | 288 SkASSERT(byteLength == 0 || text != NULL); |
| 219 | 289 |
| 220 // nothing to draw | 290 // nothing to draw |
| 221 if (text == NULL || byteLength == 0) { | 291 if (text == NULL || byteLength == 0) { |
| 222 return; | 292 return; |
| 223 } | 293 } |
| 224 | 294 |
| 225 fCurrStrike = NULL; | 295 fCurrStrike = NULL; |
| 226 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 296 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 227 | 297 |
| 228 // Get GrFontScaler from cache | 298 // Get GrFontScaler from cache |
| 229 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 230 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties,
&viewMatrix, | |
| 231 false)); | |
| 232 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
| 233 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri
ptor->data()); | |
| 234 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
| 235 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 299 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 236 | 300 |
| 237 // transform our starting point | 301 // transform our starting point |
| 238 { | 302 { |
| 239 SkPoint loc; | 303 SkPoint loc; |
| 240 viewMatrix.mapXY(x, y, &loc); | 304 viewMatrix.mapXY(x, y, &loc); |
| 241 x = loc.fX; | 305 x = loc.fX; |
| 242 y = loc.fY; | 306 y = loc.fY; |
| 243 } | 307 } |
| 244 | 308 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 GrGlyph::kCoverage_MaskStyle), | 360 GrGlyph::kCoverage_MaskStyle), |
| 297 Sk48Dot16FloorToInt(fx), | 361 Sk48Dot16FloorToInt(fx), |
| 298 Sk48Dot16FloorToInt(fy), | 362 Sk48Dot16FloorToInt(fy), |
| 299 fontScaler, | 363 fontScaler, |
| 300 clipRect); | 364 clipRect); |
| 301 } | 365 } |
| 302 | 366 |
| 303 fx += glyph.fAdvanceX; | 367 fx += glyph.fAdvanceX; |
| 304 fy += glyph.fAdvanceY; | 368 fy += glyph.fAdvanceY; |
| 305 } | 369 } |
| 306 | |
| 307 SkGlyphCache::AttachCache(cache); | |
| 308 } | 370 } |
| 309 | 371 |
| 310 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, | 372 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
| 311 const GrPaint& paint, const SkPaint& skP
aint, | 373 const GrPaint& paint, const SkPaint& skP
aint, |
| 312 const SkMatrix& viewMatrix, | 374 const SkMatrix& viewMatrix, |
| 313 const char text[], size_t byteLength, | 375 const char text[], size_t byteLength, |
| 314 const SkScalar pos[], int scalarsPerPosi
tion, | 376 const SkScalar pos[], int scalarsPerPosi
tion, |
| 315 const SkPoint& offset, const SkIRect& re
gionClipBounds) { | 377 const SkPoint& offset, const SkIRect& re
gionClipBounds) { |
| 316 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 378 int glyphCount = skPaint.countText(text, byteLength); |
| 379 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
| 317 blob->fStyle = skPaint.getStyle(); | 380 blob->fStyle = skPaint.getStyle(); |
| 318 blob->fRuns.push_back(); | |
| 319 blob->fViewMatrix = viewMatrix; | 381 blob->fViewMatrix = viewMatrix; |
| 320 | 382 |
| 321 SkIRect clipRect; | 383 SkIRect clipRect; |
| 322 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 384 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 323 this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, po
s, | 385 |
| 386 // setup cache |
| 387 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 388 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen
gth, pos, |
| 324 scalarsPerPosition, offset, clipRect); | 389 scalarsPerPosition, offset, clipRect); |
| 390 SkGlyphCache::AttachCache(cache); |
| 391 |
| 325 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS
kPaint.getAlpha()); | 392 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS
kPaint.getAlpha()); |
| 326 } | 393 } |
| 327 | 394 |
| 328 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde
x, | 395 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde
x, |
| 329 const SkPaint& skPaint, | 396 SkGlyphCache* cache, const SkPain
t& skPaint, |
| 330 const SkMatrix& viewMatrix, | 397 const SkMatrix& viewMatrix, |
| 331 const char text[], size_t byteLeng
th, | 398 const char text[], size_t byteLeng
th, |
| 332 const SkScalar pos[], int scalarsP
erPosition, | 399 const SkScalar pos[], int scalarsP
erPosition, |
| 333 const SkPoint& offset, const SkIRe
ct& clipRect) { | 400 const SkPoint& offset, const SkIRe
ct& clipRect) { |
| 334 SkASSERT(byteLength == 0 || text != NULL); | 401 SkASSERT(byteLength == 0 || text != NULL); |
| 335 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 402 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 336 | 403 |
| 337 // nothing to draw | 404 // nothing to draw |
| 338 if (text == NULL || byteLength == 0) { | 405 if (text == NULL || byteLength == 0) { |
| 339 return; | 406 return; |
| 340 } | 407 } |
| 341 | 408 |
| 342 fCurrStrike = NULL; | 409 fCurrStrike = NULL; |
| 343 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 410 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 344 | 411 |
| 345 // Get GrFontScaler from cache | 412 // Get GrFontScaler from cache |
| 346 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 347 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties,
&viewMatrix, | |
| 348 false)); | |
| 349 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
| 350 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri
ptor->data()); | |
| 351 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
| 352 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 413 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 353 | 414 |
| 354 const char* stop = text + byteLength; | 415 const char* stop = text + byteLength; |
| 355 SkTextAlignProc alignProc(skPaint.getTextAlign()); | 416 SkTextAlignProc alignProc(skPaint.getTextAlign()); |
| 356 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); | 417 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); |
| 357 SkScalar halfSampleX = 0, halfSampleY = 0; | 418 SkScalar halfSampleX = 0, halfSampleY = 0; |
| 358 | 419 |
| 359 if (cache->isSubpixel()) { | 420 if (cache->isSubpixel()) { |
| 360 // maybe we should skip the rounding if linearText is set | 421 // maybe we should skip the rounding if linearText is set |
| 361 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); | 422 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 GrGlyph::kCoverage_MaskStyle
), | 541 GrGlyph::kCoverage_MaskStyle
), |
| 481 Sk48Dot16FloorToInt(fx), | 542 Sk48Dot16FloorToInt(fx), |
| 482 Sk48Dot16FloorToInt(fy), | 543 Sk48Dot16FloorToInt(fy), |
| 483 fontScaler, | 544 fontScaler, |
| 484 clipRect); | 545 clipRect); |
| 485 } | 546 } |
| 486 pos += scalarsPerPosition; | 547 pos += scalarsPerPosition; |
| 487 } | 548 } |
| 488 } | 549 } |
| 489 } | 550 } |
| 490 SkGlyphCache::AttachCache(cache); | |
| 491 } | 551 } |
| 492 | 552 |
| 493 static size_t get_vertex_stride(GrMaskFormat maskFormat) { | 553 static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
| 494 switch (maskFormat) { | 554 switch (maskFormat) { |
| 495 case kA8_GrMaskFormat: | 555 case kA8_GrMaskFormat: |
| 496 return kGrayTextVASize; | 556 return kGrayTextVASize; |
| 497 case kARGB_GrMaskFormat: | 557 case kARGB_GrMaskFormat: |
| 498 return kColorTextVASize; | 558 return kColorTextVASize; |
| 499 default: | 559 default: |
| 500 return kLCDTextVASize; | 560 return kLCDTextVASize; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 // flag the glyph as being dead? | 593 // flag the glyph as being dead? |
| 534 SkDELETE(path); | 594 SkDELETE(path); |
| 535 return; | 595 return; |
| 536 } | 596 } |
| 537 glyph->fPath = path; | 597 glyph->fPath = path; |
| 538 } | 598 } |
| 539 SkASSERT(glyph->fPath); | 599 SkASSERT(glyph->fPath); |
| 540 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v
y)); | 600 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v
y)); |
| 541 return; | 601 return; |
| 542 } | 602 } |
| 603 |
| 604 Run& run = blob->fRuns[runIndex]; |
| 605 |
| 543 GrMaskFormat format = glyph->fMaskFormat; | 606 GrMaskFormat format = glyph->fMaskFormat; |
| 607 |
| 608 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); |
| 609 if (run.fInitialized && subRun->fMaskFormat != format) { |
| 610 PerSubRunInfo* newSubRun = &run.fSubRunInfo.push_back(); |
| 611 newSubRun->fGlyphStartIndex = subRun->fGlyphEndIndex; |
| 612 newSubRun->fGlyphEndIndex = subRun->fGlyphEndIndex; |
| 613 |
| 614 newSubRun->fVertexStartIndex = subRun->fVertexEndIndex; |
| 615 newSubRun->fVertexEndIndex = subRun->fVertexEndIndex; |
| 616 |
| 617 subRun = newSubRun; |
| 618 } |
| 619 |
| 620 run.fInitialized = true; |
| 621 subRun->fMaskFormat = format; |
| 622 blob->fGlyphIDs[subRun->fGlyphEndIndex] = packed; |
| 623 |
| 544 size_t vertexStride = get_vertex_stride(format); | 624 size_t vertexStride = get_vertex_stride(format); |
| 545 | 625 |
| 546 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 547 int glyphIdx = run.fInfos[format].fGlyphIDs.count(); | |
| 548 *run.fInfos[format].fGlyphIDs.append() = packed; | |
| 549 run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVertice
sPerGlyph)); | |
| 550 | |
| 551 SkRect r; | 626 SkRect r; |
| 552 r.fLeft = SkIntToScalar(x); | 627 r.fLeft = SkIntToScalar(x); |
| 553 r.fTop = SkIntToScalar(y); | 628 r.fTop = SkIntToScalar(y); |
| 554 r.fRight = r.fLeft + SkIntToScalar(width); | 629 r.fRight = r.fLeft + SkIntToScalar(width); |
| 555 r.fBottom = r.fTop + SkIntToScalar(height); | 630 r.fBottom = r.fTop + SkIntToScalar(height); |
| 556 | 631 |
| 557 run.fVertexBounds.joinNonEmptyArg(r); | 632 run.fVertexBounds.joinNonEmptyArg(r); |
| 558 GrColor color = fPaint.getColor(); | 633 GrColor color = fPaint.getColor(); |
| 559 run.fColor = color; | 634 run.fColor = color; |
| 560 | 635 |
| 561 intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.be
gin()); | 636 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert
exEndIndex); |
| 562 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
| 563 | 637 |
| 564 // V0 | 638 // V0 |
| 565 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); | 639 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); |
| 566 position->set(r.fLeft, r.fTop); | 640 position->set(r.fLeft, r.fTop); |
| 567 if (kA8_GrMaskFormat == format) { | 641 if (kA8_GrMaskFormat == format) { |
| 568 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; | 642 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; |
| 569 *colorPtr = color; | 643 *colorPtr = color; |
| 570 } | 644 } |
| 571 vertex += vertexStride; | 645 vertex += vertexStride; |
| 572 | 646 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 588 } | 662 } |
| 589 vertex += vertexStride; | 663 vertex += vertexStride; |
| 590 | 664 |
| 591 // V3 | 665 // V3 |
| 592 position = reinterpret_cast<SkPoint*>(vertex); | 666 position = reinterpret_cast<SkPoint*>(vertex); |
| 593 position->set(r.fRight, r.fTop); | 667 position->set(r.fRight, r.fTop); |
| 594 if (kA8_GrMaskFormat == format) { | 668 if (kA8_GrMaskFormat == format) { |
| 595 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; | 669 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint))
; |
| 596 *colorPtr = color; | 670 *colorPtr = color; |
| 597 } | 671 } |
| 672 |
| 673 subRun->fGlyphEndIndex++; |
| 674 subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; |
| 598 } | 675 } |
| 599 | 676 |
| 600 class BitmapTextBatch : public GrBatch { | 677 class BitmapTextBatch : public GrBatch { |
| 601 public: | 678 public: |
| 602 typedef GrBitmapTextContextB::BitmapTextBlob Blob; | 679 typedef GrBitmapTextContextB::BitmapTextBlob Blob; |
| 603 typedef Blob::Run Run; | 680 typedef Blob::Run Run; |
| 604 typedef Run::PerFormatInfo TextInfo; | 681 typedef Run::SubRunInfo TextInfo; |
| 605 struct Geometry { | 682 struct Geometry { |
| 606 Geometry() {} | 683 Geometry() {} |
| 607 Geometry(const Geometry& geometry) | 684 Geometry(const Geometry& geometry) |
| 608 : fBlob(SkRef(geometry.fBlob.get())) | 685 : fBlob(SkRef(geometry.fBlob.get())) |
| 609 , fRun(geometry.fRun) | 686 , fRun(geometry.fRun) |
| 687 , fSubRun(geometry.fSubRun) |
| 610 , fColor(geometry.fColor) {} | 688 , fColor(geometry.fColor) {} |
| 611 SkAutoTUnref<Blob> fBlob; | 689 SkAutoTUnref<Blob> fBlob; |
| 612 int fRun; | 690 int fRun; |
| 691 int fSubRun; |
| 613 GrColor fColor; | 692 GrColor fColor; |
| 614 }; | 693 }; |
| 615 | 694 |
| 616 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat
maskFormat, | 695 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat
maskFormat, |
| 617 GrBatchFontCache* fontCache) { | 696 int glyphCount, GrBatchFontCache* fontCache) { |
| 618 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCac
he)); | 697 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, glyphCo
unt, fontCache)); |
| 619 } | 698 } |
| 620 | 699 |
| 621 const char* name() const override { return "BitmapTextBatch"; } | 700 const char* name() const override { return "BitmapTextBatch"; } |
| 622 | 701 |
| 623 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 702 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 624 if (kARGB_GrMaskFormat == fMaskFormat) { | 703 if (kARGB_GrMaskFormat == fMaskFormat) { |
| 625 out->setUnknownFourComponents(); | 704 out->setUnknownFourComponents(); |
| 626 } else { | 705 } else { |
| 627 out->setKnownFourComponents(fBatch.fColor); | 706 out->setKnownFourComponents(fBatch.fColor); |
| 628 } | 707 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); | 790 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); |
| 712 drawInfo.adjustStartVertex(firstVertex); | 791 drawInfo.adjustStartVertex(firstVertex); |
| 713 drawInfo.setVertexBuffer(vertexBuffer); | 792 drawInfo.setVertexBuffer(vertexBuffer); |
| 714 drawInfo.setIndexBuffer(quadIndexBuffer); | 793 drawInfo.setIndexBuffer(quadIndexBuffer); |
| 715 | 794 |
| 716 int instancesToFlush = 0; | 795 int instancesToFlush = 0; |
| 717 for (int i = 0; i < instanceCount; i++) { | 796 for (int i = 0; i < instanceCount; i++) { |
| 718 Geometry& args = fGeoData[i]; | 797 Geometry& args = fGeoData[i]; |
| 719 Blob* blob = args.fBlob; | 798 Blob* blob = args.fBlob; |
| 720 Run& run = blob->fRuns[args.fRun]; | 799 Run& run = blob->fRuns[args.fRun]; |
| 721 TextInfo& info = run.fInfos[fMaskFormat]; | 800 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
| 722 | 801 |
| 723 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); | 802 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
| 724 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; | 803 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas
Gen; |
| 725 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo
r != args.fColor; | 804 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo
r != args.fColor; |
| 726 int glyphCount = info.fGlyphIDs.count(); | 805 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 727 | 806 |
| 728 // We regenerate both texture coords and colors in the blob itself,
and update the | 807 // We regenerate both texture coords and colors in the blob itself,
and update the |
| 729 // atlas generation. If we don't end up purging any unused plots, w
e can avoid | 808 // atlas generation. If we don't end up purging any unused plots, w
e can avoid |
| 730 // regenerating the coords. We could take a finer grained approach
to updating texture | 809 // regenerating the coords. We could take a finer grained approach
to updating texture |
| 731 // coords but its not clear if the extra bookkeeping would offset an
y gains. | 810 // coords but its not clear if the extra bookkeeping would offset an
y gains. |
| 732 // To avoid looping over the glyphs twice, we do one loop and condit
ionally update color | 811 // To avoid looping over the glyphs twice, we do one loop and condit
ionally update color |
| 733 // or coords as needed. One final note, if we have to break a run f
or an atlas eviction | 812 // or coords as needed. One final note, if we have to break a run f
or an atlas eviction |
| 734 // then we can't really trust the atlas has all of the correct data.
Atlas evictions | 813 // then we can't really trust the atlas has all of the correct data.
Atlas evictions |
| 735 // should be pretty rare, so we just always regenerate in those case
s | 814 // should be pretty rare, so we just always regenerate in those case
s |
| 736 if (regenerateTextureCoords || regenerateColors) { | 815 if (regenerateTextureCoords || regenerateColors) { |
| 737 // first regenerate texture coordinates / colors if need be | 816 // first regenerate texture coordinates / colors if need be |
| 738 const SkDescriptor* desc = NULL; | 817 const SkDescriptor* desc = NULL; |
| 739 SkGlyphCache* cache = NULL; | 818 SkGlyphCache* cache = NULL; |
| 740 GrFontScaler* scaler = NULL; | 819 GrFontScaler* scaler = NULL; |
| 741 GrBatchTextStrike* strike = NULL; | 820 GrBatchTextStrike* strike = NULL; |
| 742 bool brokenRun = false; | 821 bool brokenRun = false; |
| 743 if (regenerateTextureCoords) { | 822 if (regenerateTextureCoords) { |
| 744 desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor
->data()); | 823 desc = run.fDescriptor.getDesc(); |
| 745 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | 824 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
| 746 scaler = GrTextContext::GetGrFontScaler(cache); | 825 scaler = GrTextContext::GetGrFontScaler(cache); |
| 747 strike = fFontCache->getStrike(scaler); | 826 strike = fFontCache->getStrike(scaler); |
| 748 } | 827 } |
| 749 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 828 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
| 750 GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx]; | 829 GrGlyph::PackedID glyphID = blob->fGlyphIDs[glyphIdx + info.
fGlyphStartIndex]; |
| 751 | 830 |
| 752 if (regenerateTextureCoords) { | 831 if (regenerateTextureCoords) { |
| 753 // Upload the glyph only if needed | 832 // Upload the glyph only if needed |
| 754 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); | 833 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); |
| 755 SkASSERT(glyph); | 834 SkASSERT(glyph); |
| 756 | 835 |
| 757 if (!fFontCache->hasGlyph(glyph) && | 836 if (!fFontCache->hasGlyph(glyph) && |
| 758 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { | 837 !strike->addGlyphToAtlas(batchTarget, glyph, scaler)
) { |
| 759 this->flush(batchTarget, &drawInfo, instancesToFlush
, | 838 this->flush(batchTarget, &drawInfo, instancesToFlush
, |
| 760 maxInstancesPerDraw); | 839 maxInstancesPerDraw); |
| 761 this->initDraw(batchTarget, gp, pipeline); | 840 this->initDraw(batchTarget, gp, pipeline); |
| 762 instancesToFlush = 0; | 841 instancesToFlush = 0; |
| 763 brokenRun = glyphIdx > 0; | 842 brokenRun = glyphIdx > 0; |
| 764 | 843 |
| 765 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, glyph, | 844 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(
batchTarget, glyph, |
| 766
scaler); | 845
scaler); |
| 767 SkASSERT(success); | 846 SkASSERT(success); |
| 768 } | 847 } |
| 769 | 848 |
| 770 fFontCache->setGlyphRefToken(glyph, batchTarget->current
Token()); | 849 fFontCache->setGlyphRefToken(glyph, batchTarget->current
Token()); |
| 771 | 850 |
| 772 // Texture coords are the last vertex attribute so we ge
t a pointer to the | 851 // Texture coords are the last vertex attribute so we ge
t a pointer to the |
| 773 // first one and then map with stride in regenerateTextu
reCoords | 852 // first one and then map with stride in regenerateTextu
reCoords |
| 774 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti
ces.begin()); | 853 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); |
| 854 vertex += info.fVertexStartIndex; |
| 775 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | 855 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
| 776 vertex += vertexStride - sizeof(SkIPoint16); | 856 vertex += vertexStride - sizeof(SkIPoint16); |
| 777 | 857 |
| 778 this->regenerateTextureCoords(glyph, vertex, vertexStrid
e); | 858 this->regenerateTextureCoords(glyph, vertex, vertexStrid
e); |
| 779 } | 859 } |
| 780 | 860 |
| 781 if (regenerateColors) { | 861 if (regenerateColors) { |
| 782 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti
ces.begin()); | 862 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert
ices); |
| 863 vertex += info.fVertexStartIndex; |
| 783 vertex += vertexStride * glyphIdx * kVerticesPerGlyph +
sizeof(SkPoint); | 864 vertex += vertexStride * glyphIdx * kVerticesPerGlyph +
sizeof(SkPoint); |
| 784 this->regenerateColors(vertex, vertexStride, args.fColor
); | 865 this->regenerateColors(vertex, vertexStride, args.fColor
); |
| 785 } | 866 } |
| 786 | 867 |
| 787 instancesToFlush++; | 868 instancesToFlush++; |
| 788 } | 869 } |
| 789 | 870 |
| 790 if (regenerateTextureCoords) { | 871 if (regenerateTextureCoords) { |
| 791 SkGlyphCache::AttachCache(cache); | 872 SkGlyphCache::AttachCache(cache); |
| 792 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : | 873 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt
lasGeneration : |
| 793 fFontCache->atlasGenerat
ion(fMaskFormat); | 874 fFontCache->atlasGenerat
ion(fMaskFormat); |
| 794 } | 875 } |
| 795 } else { | 876 } else { |
| 796 instancesToFlush += glyphCount; | 877 instancesToFlush += glyphCount; |
| 797 } | 878 } |
| 798 | 879 |
| 799 // now copy all vertices | 880 // now copy all vertices |
| 800 int byteCount = info.fVertices.count(); | 881 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; |
| 801 memcpy(currVertex, info.fVertices.begin(), byteCount); | 882 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou
nt); |
| 802 | 883 |
| 803 currVertex += byteCount; | 884 currVertex += byteCount; |
| 804 } | 885 } |
| 805 | 886 |
| 806 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra
w); | 887 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra
w); |
| 807 } | 888 } |
| 808 | 889 |
| 809 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 890 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 810 | 891 |
| 811 private: | 892 private: |
| 812 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo
rmat, | 893 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo
rmat, |
| 813 GrBatchFontCache* fontCache) | 894 int glyphCount, GrBatchFontCache* fontCache) |
| 814 : fMaskFormat(maskFormat) | 895 : fMaskFormat(maskFormat) |
| 815 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) | 896 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
| 816 , fFontCache(fontCache) { | 897 , fFontCache(fontCache) { |
| 817 this->initClassID<BitmapTextBatch>(); | 898 this->initClassID<BitmapTextBatch>(); |
| 818 fGeoData.push_back(geometry); | 899 fGeoData.push_back(geometry); |
| 819 fBatch.fColor = color; | 900 fBatch.fColor = color; |
| 820 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; | 901 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; |
| 821 int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat].
fGlyphIDs.count(); | 902 fBatch.fNumGlyphs = glyphCount; |
| 822 fBatch.fNumGlyphs = numGlyphs; | |
| 823 } | 903 } |
| 824 | 904 |
| 825 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS
tride) { | 905 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS
tride) { |
| 826 int width = glyph->fBounds.width(); | 906 int width = glyph->fBounds.width(); |
| 827 int height = glyph->fBounds.height(); | 907 int height = glyph->fBounds.height(); |
| 828 int u0 = glyph->fAtlasLocation.fX; | 908 int u0 = glyph->fAtlasLocation.fX; |
| 829 int v0 = glyph->fAtlasLocation.fY; | 909 int v0 = glyph->fAtlasLocation.fY; |
| 830 int u1 = u0 + width; | 910 int u1 = u0 + width; |
| 831 int v1 = v0 + height; | 911 int v1 = v0 + height; |
| 832 | 912 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 int fNumGlyphs; | 1005 int fNumGlyphs; |
| 926 }; | 1006 }; |
| 927 | 1007 |
| 928 BatchTracker fBatch; | 1008 BatchTracker fBatch; |
| 929 SkSTArray<1, Geometry, true> fGeoData; | 1009 SkSTArray<1, Geometry, true> fGeoData; |
| 930 GrMaskFormat fMaskFormat; | 1010 GrMaskFormat fMaskFormat; |
| 931 GrPixelConfig fPixelConfig; | 1011 GrPixelConfig fPixelConfig; |
| 932 GrBatchFontCache* fFontCache; | 1012 GrBatchFontCache* fFontCache; |
| 933 }; | 1013 }; |
| 934 | 1014 |
| 935 void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blo
b, int i, | |
| 936 GrPipelineBuilder* pipelineBuilder, GrMas
kFormat format, | |
| 937 GrColor color, int paintAlpha) { | |
| 938 if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) { | |
| 939 return; | |
| 940 } | |
| 941 | |
| 942 if (kARGB_GrMaskFormat == format) { | |
| 943 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha); | |
| 944 } | |
| 945 | |
| 946 BitmapTextBatch::Geometry geometry; | |
| 947 geometry.fBlob.reset(SkRef(blob)); | |
| 948 geometry.fRun = i; | |
| 949 geometry.fColor = color; | |
| 950 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, | |
| 951 fContext->getBatchFontCa
che())); | |
| 952 | |
| 953 target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds); | |
| 954 } | |
| 955 | |
| 956 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR
enderTarget* rt, | 1015 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR
enderTarget* rt, |
| 957 const GrPaint& paint, const GrClip& clip, | 1016 const GrPaint& paint, const GrClip& clip, |
| 958 const SkMatrix& viewMatrix, int paintAlpha) { | 1017 const SkMatrix& viewMatrix, int paintAlpha) { |
| 959 GrPipelineBuilder pipelineBuilder; | 1018 GrPipelineBuilder pipelineBuilder; |
| 960 pipelineBuilder.setFromPaint(paint, rt, clip); | 1019 pipelineBuilder.setFromPaint(paint, rt, clip); |
| 961 | 1020 |
| 962 GrColor color = paint.getColor(); | 1021 GrColor color = paint.getColor(); |
| 963 for (int i = 0; i < blob->fRuns.count(); i++) { | 1022 for (uint32_t run = 0; run < blob->fRunCount; run++) { |
| 964 this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, c
olor, paintAlpha); | 1023 for (int subRun = 0; subRun < blob->fRuns[run].fSubRunInfo.count(); subR
un++) { |
| 965 this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat,
color, paintAlpha); | 1024 PerSubRunInfo& info = blob->fRuns[run].fSubRunInfo[subRun]; |
| 966 this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat,
color, paintAlpha); | 1025 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 1026 if (0 == glyphCount) { |
| 1027 continue; |
| 1028 } |
| 1029 |
| 1030 GrMaskFormat format = info.fMaskFormat; |
| 1031 if (kARGB_GrMaskFormat == format) { |
| 1032 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paint
Alpha); |
| 1033 } |
| 1034 |
| 1035 BitmapTextBatch::Geometry geometry; |
| 1036 geometry.fBlob.reset(SkRef(blob)); |
| 1037 geometry.fRun = run; |
| 1038 geometry.fSubRun = subRun; |
| 1039 geometry.fColor = color; |
| 1040 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color,
format, glyphCount, |
| 1041 fContext->getBat
chFontCache())); |
| 1042 |
| 1043 target->drawBatch(&pipelineBuilder, batch, &blob->fRuns[run].fVertex
Bounds); |
| 1044 } |
| 967 } | 1045 } |
| 968 | 1046 |
| 969 // Now flush big glyphs | 1047 // Now flush big glyphs |
| 970 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { | 1048 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { |
| 971 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; | 1049 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; |
| 972 SkMatrix translate; | 1050 SkMatrix translate; |
| 973 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly
ph.fVy)); | 1051 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly
ph.fVy)); |
| 974 SkPath tmpPath(bigGlyph.fPath); | 1052 SkPath tmpPath(bigGlyph.fPath); |
| 975 tmpPath.transform(translate); | 1053 tmpPath.transform(translate); |
| 976 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 1054 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 SkSafeSetNull(fCurrTexture); | 1631 SkSafeSetNull(fCurrTexture); |
| 1554 } | 1632 } |
| 1555 } | 1633 } |
| 1556 | 1634 |
| 1557 inline void GrBitmapTextContext::finish() { | 1635 inline void GrBitmapTextContext::finish() { |
| 1558 this->flush(); | 1636 this->flush(); |
| 1559 fTotalVertexCount = 0; | 1637 fTotalVertexCount = 0; |
| 1560 | 1638 |
| 1561 GrTextContext::finish(); | 1639 GrTextContext::finish(); |
| 1562 } | 1640 } |
| OLD | NEW |