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 "GrDrawTarget.h" | 10 #include "GrDrawTarget.h" |
11 #include "GrFontScaler.h" | 11 #include "GrFontScaler.h" |
12 #include "GrIndexBuffer.h" | 12 #include "GrIndexBuffer.h" |
13 #include "GrTextStrike.h" | 13 #include "GrTextStrike.h" |
14 #include "GrTextStrike_impl.h" | 14 #include "GrTextStrike_impl.h" |
15 #include "SkColorPriv.h" | 15 #include "SkColorPriv.h" |
16 #include "SkPath.h" | 16 #include "SkPath.h" |
17 #include "SkRTConf.h" | 17 #include "SkRTConf.h" |
18 #include "SkStrokeRec.h" | 18 #include "SkStrokeRec.h" |
19 #include "effects/GrCustomCoordsTextureEffect.h" | 19 #include "effects/GrCustomCoordsTextureEffect.h" |
20 | 20 |
21 #include "SkAutoKern.h" | 21 #include "SkAutoKern.h" |
22 #include "SkDraw.h" | 22 #include "SkDraw.h" |
| 23 #include "SkDrawProcs.h" |
23 #include "SkGlyphCache.h" | 24 #include "SkGlyphCache.h" |
24 #include "SkGpuDevice.h" | 25 #include "SkGpuDevice.h" |
25 #include "SkGr.h" | 26 #include "SkGr.h" |
| 27 #include "SkTextMapState.h" |
26 | 28 |
27 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, | 29 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, |
28 "Dump the contents of the font cache before every purge."); | 30 "Dump the contents of the font cache before every purge."); |
29 | 31 |
30 static const int kGlyphCoordsNoColorAttributeIndex = 1; | 32 static const int kGlyphCoordsNoColorAttributeIndex = 1; |
31 static const int kGlyphCoordsWithColorAttributeIndex = 2; | 33 static const int kGlyphCoordsWithColorAttributeIndex = 2; |
32 | 34 |
33 namespace { | 35 namespace { |
34 // position + texture coord | 36 // position + texture coord |
35 extern const GrVertexAttrib gTextVertexAttribs[] = { | 37 extern const GrVertexAttrib gTextVertexAttribs[] = { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 fontScaler); | 258 fontScaler); |
257 } | 259 } |
258 | 260 |
259 fx += glyph.fAdvanceX; | 261 fx += glyph.fAdvanceX; |
260 fy += glyph.fAdvanceY; | 262 fy += glyph.fAdvanceY; |
261 } | 263 } |
262 | 264 |
263 this->finish(); | 265 this->finish(); |
264 } | 266 } |
265 | 267 |
266 /////////////////////////////////////////////////////////////////////////////// | |
267 // Copied from SkDraw | |
268 | |
269 // last parameter is interpreted as SkFixed [x, y] | |
270 // return the fixed position, which may be rounded or not by the caller | |
271 // e.g. subpixel doesn't round | |
272 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*); | |
273 | |
274 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds
t) { | |
275 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY)); | |
276 } | |
277 | |
278 static void centerAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint*
dst) { | |
279 dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1), | |
280 SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1)); | |
281 } | |
282 | |
283 static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* d
st) { | |
284 dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX, | |
285 SkScalarToFixed(loc.fY) - glyph.fAdvanceY); | |
286 } | |
287 | |
288 static AlignProc pick_align_proc(SkPaint::Align align) { | |
289 static const AlignProc gProcs[] = { | |
290 leftAlignProc, centerAlignProc, rightAlignProc | |
291 }; | |
292 | |
293 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs)); | |
294 | |
295 return gProcs[align]; | |
296 } | |
297 | |
298 class BitmapTextMapState { | |
299 public: | |
300 mutable SkPoint fLoc; | |
301 | |
302 BitmapTextMapState(const SkMatrix& matrix, SkScalar y) | |
303 : fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {} | |
304 | |
305 typedef void (*Proc)(const BitmapTextMapState&, const SkScalar pos[]); | |
306 | |
307 Proc pickProc(int scalarsPerPosition); | |
308 | |
309 private: | |
310 const SkMatrix& fMatrix; | |
311 SkMatrix::MapXYProc fProc; | |
312 SkScalar fY; // ignored by MapXYProc | |
313 // these are only used by Only... procs | |
314 SkScalar fScaleX, fTransX, fTransformedY; | |
315 | |
316 static void MapXProc(const BitmapTextMapState& state, const SkScalar pos[])
{ | |
317 state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc); | |
318 } | |
319 | |
320 static void MapXYProc(const BitmapTextMapState& state, const SkScalar pos[])
{ | |
321 state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc); | |
322 } | |
323 | |
324 static void MapOnlyScaleXProc(const BitmapTextMapState& state, | |
325 const SkScalar pos[]) { | |
326 state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX, | |
327 state.fTransformedY); | |
328 } | |
329 | |
330 static void MapOnlyTransXProc(const BitmapTextMapState& state, | |
331 const SkScalar pos[]) { | |
332 state.fLoc.set(*pos + state.fTransX, state.fTransformedY); | |
333 } | |
334 }; | |
335 | |
336 BitmapTextMapState::Proc BitmapTextMapState::pickProc(int scalarsPerPosition) { | |
337 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | |
338 | |
339 if (1 == scalarsPerPosition) { | |
340 unsigned mtype = fMatrix.getType(); | |
341 if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) { | |
342 return MapXProc; | |
343 } else { | |
344 fScaleX = fMatrix.getScaleX(); | |
345 fTransX = fMatrix.getTranslateX(); | |
346 fTransformedY = SkScalarMul(fY, fMatrix.getScaleY()) + | |
347 fMatrix.getTranslateY(); | |
348 return (mtype & SkMatrix::kScale_Mask) ? | |
349 MapOnlyScaleXProc : MapOnlyTransXProc; | |
350 } | |
351 } else { | |
352 return MapXYProc; | |
353 } | |
354 } | |
355 | |
356 /////////////////////////////////////////////////////////////////////////////// | |
357 | |
358 void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
nt, | 268 void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPai
nt, |
359 const char text[], size_t byteLength, | 269 const char text[], size_t byteLength, |
360 const SkScalar pos[], SkScalar constY, | 270 const SkScalar pos[], SkScalar constY, |
361 int scalarsPerPosition) { | 271 int scalarsPerPosition) { |
362 SkASSERT(byteLength == 0 || text != NULL); | 272 SkASSERT(byteLength == 0 || text != NULL); |
363 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 273 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
364 | 274 |
365 // nothing to draw | 275 // nothing to draw |
366 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { | 276 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { |
367 return; | 277 return; |
368 } | 278 } |
369 | 279 |
370 this->init(paint, skPaint); | 280 this->init(paint, skPaint); |
371 | 281 |
372 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 282 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); |
373 | 283 |
374 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa
trix()); | 284 SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMa
trix()); |
375 SkGlyphCache* cache = autoCache.getCache(); | 285 SkGlyphCache* cache = autoCache.getCache(); |
376 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 286 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
377 | 287 |
378 // store original matrix before we reset, so we can use it to transform posi
tions | 288 // store original matrix before we reset, so we can use it to transform posi
tions |
379 SkMatrix ctm = fContext->getMatrix(); | 289 SkMatrix ctm = fContext->getMatrix(); |
380 GrContext::AutoMatrix autoMatrix; | 290 GrContext::AutoMatrix autoMatrix; |
381 autoMatrix.setIdentity(fContext, &fPaint); | 291 autoMatrix.setIdentity(fContext, &fPaint); |
382 | 292 |
383 const char* stop = text + byteLength; | 293 const char* stop = text + byteLength; |
384 AlignProc alignProc = pick_align_proc(fSkPaint.getTextAlign()); | 294 SkTextAlignProc alignProc(fSkPaint.getTextAlign()); |
385 BitmapTextMapState tms(ctm, constY); | 295 SkTextMapState tms(ctm, constY); |
386 BitmapTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); | 296 SkTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); |
387 SkFixed halfSampleX = 0, halfSampleY = 0; | 297 SkFixed halfSampleX = 0, halfSampleY = 0; |
388 | 298 |
389 if (cache->isSubpixel()) { | 299 if (cache->isSubpixel()) { |
390 // maybe we should skip the rounding if linearText is set | 300 // maybe we should skip the rounding if linearText is set |
391 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(ctm); | 301 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(ctm); |
392 | 302 |
393 SkFixed fxMask = ~0; | 303 SkFixed fxMask = ~0; |
394 SkFixed fyMask = ~0; | 304 SkFixed fyMask = ~0; |
395 if (kX_SkAxisAlignment == baseline) { | 305 if (kX_SkAxisAlignment == baseline) { |
396 fyMask = 0; | 306 fyMask = 0; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 431 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
522 return; | 432 return; |
523 } | 433 } |
524 | 434 |
525 vx += SkIntToFixed(glyph->fBounds.fLeft); | 435 vx += SkIntToFixed(glyph->fBounds.fLeft); |
526 vy += SkIntToFixed(glyph->fBounds.fTop); | 436 vy += SkIntToFixed(glyph->fBounds.fTop); |
527 | 437 |
528 // keep them as ints until we've done the clip-test | 438 // keep them as ints until we've done the clip-test |
529 SkFixed width = glyph->fBounds.width(); | 439 SkFixed width = glyph->fBounds.width(); |
530 SkFixed height = glyph->fBounds.height(); | 440 SkFixed height = glyph->fBounds.height(); |
531 | |
532 // check if we clipped out | 441 // check if we clipped out |
533 if (true || NULL == glyph->fPlot) { | 442 if (true || NULL == glyph->fPlot) { |
534 int x = vx >> 16; | 443 int x = vx >> 16; |
535 int y = vy >> 16; | 444 int y = vy >> 16; |
536 if (fClipRect.quickReject(x, y, x + width, y + height)) { | 445 if (fClipRect.quickReject(x, y, x + width, y + height)) { |
537 // SkCLZ(3); // so we can set a break-point in the debugger | 446 // SkCLZ(3); // so we can set a break-point in the debugger |
538 return; | 447 return; |
539 } | 448 } |
540 } | 449 } |
541 | 450 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 if (useColorVerts) { | 588 if (useColorVerts) { |
680 // color comes after position. | 589 // color comes after position. |
681 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); | 590 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); |
682 for (int i = 0; i < 4; ++i) { | 591 for (int i = 0; i < 4; ++i) { |
683 *colors = fPaint.getColor(); | 592 *colors = fPaint.getColor(); |
684 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors
) + vertSize); | 593 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(colors
) + vertSize); |
685 } | 594 } |
686 } | 595 } |
687 fCurrVertex += 4; | 596 fCurrVertex += 4; |
688 } | 597 } |
OLD | NEW |