Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/gpu/GrDistanceFieldTextContext.cpp

Issue 670533002: Add color emoji fallback for distance field text. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« gm/dftext.cpp ('K') | « src/gpu/GrDistanceFieldTextContext.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrDistanceFieldTextContext.h" 8 #include "GrDistanceFieldTextContext.h"
9 #include "GrAtlas.h" 9 #include "GrAtlas.h"
10 #include "GrBitmapTextContext.h" 10 #include "GrBitmapTextContext.h"
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 287
288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
289 289
290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); 290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
291 SkGlyphCache* cache = autoCache.getCache(); 291 SkGlyphCache* cache = autoCache.getCache();
292 GrFontScaler* fontScaler = GetGrFontScaler(cache); 292 GrFontScaler* fontScaler = GetGrFontScaler(cache);
293 293
294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); 294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
295 295
296 const char* stop = text + byteLength; 296 const char* stop = text + byteLength;
297 SkTArray<char> fallbackText;
298 size_t fallbackByteLength = 0;
299 SkTArray<SkScalar> fallbackPos;
297 300
298 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 301 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
299 while (text < stop) { 302 while (text < stop) {
303 const char* lastText = text;
300 // the last 2 parameters are ignored 304 // the last 2 parameters are ignored
301 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 305 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
302 306
303 if (glyph.fWidth) { 307 if (glyph.fWidth) {
304 SkScalar x = offset.x() + pos[0]; 308 SkScalar x = offset.x() + pos[0];
305 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 309 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
306 310
307 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), 311 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
308 glyph.getSubXFixed(), 312 glyph.getSubXFixed(),
309 glyph.getSubYFixed()), 313 glyph.getSubYFixed()),
310 SkScalarToFixed(x), 314 SkScalarToFixed(x),
311 SkScalarToFixed(y), 315 SkScalarToFixed(y),
312 fontScaler); 316 fontScaler)) {
317 // couldn't append, send to fallback
318 size_t newByteLength = text-lastText;
robertphillips 2014/10/20 18:52:11 fallbackText.push_back_n(newByteLength, lastText);
jvanverth1 2014/10/20 20:04:40 Done.
319 for (size_t i = 0; i < newByteLength; ++i) {
320 fallbackText.push_back(*lastText);
321 ++lastText;
322 }
323 fallbackPos.push_back(pos[0]);
robertphillips 2014/10/20 18:52:11 const on left ?
jvanverth1 2014/10/20 20:04:40 Done.
324 if (scalarsPerPosition == 2) {
325 fallbackPos.push_back(pos[1]);
326 }
robertphillips 2014/10/20 18:52:11 Doesn't fallbackText.count() already store this?
jvanverth1 2014/10/20 20:04:40 Done.
327 fallbackByteLength += newByteLength;
328 }
313 } 329 }
314 pos += scalarsPerPosition; 330 pos += scalarsPerPosition;
315 } 331 }
316 } else { 332 } else {
317 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf 333 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf
318 : SK_Scalar1; 334 : SK_Scalar1;
319 while (text < stop) { 335 while (text < stop) {
336 const char* lastText = text;
320 // the last 2 parameters are ignored 337 // the last 2 parameters are ignored
321 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 338 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
322 339
323 if (glyph.fWidth) { 340 if (glyph.fWidth) {
324 SkScalar x = offset.x() + pos[0]; 341 SkScalar x = offset.x() + pos[0];
325 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 342 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
326 343
327 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio; 344 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio;
328 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio; 345 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio;
329 346
330 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), 347 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
331 glyph.getSubXFixed(), 348 glyph.getSubXFixed(),
332 glyph.getSubYFixed()), 349 glyph.getSubYFixed()),
333 SkScalarToFixed(x - advanceX), 350 SkScalarToFixed(x - advanceX),
334 SkScalarToFixed(y - advanceY), 351 SkScalarToFixed(y - advanceY),
335 fontScaler); 352 fontScaler)) {
353 // couldn't append, send to fallback
354 size_t newByteLength = text-lastText;
robertphillips 2014/10/20 18:52:11 push_back_n here too ?
jvanverth1 2014/10/20 20:04:41 Done.
355 for (size_t i = 0; i < newByteLength; ++i) {
356 fallbackText.push_back(*lastText);
357 ++lastText;
358 }
359 fallbackPos.push_back(pos[0]);
robertphillips 2014/10/20 18:52:11 const on left ?
jvanverth1 2014/10/20 20:04:40 Done.
360 if (scalarsPerPosition == 2) {
361 fallbackPos.push_back(pos[1]);
362 }
363 fallbackByteLength += newByteLength;
364 }
336 } 365 }
337 pos += scalarsPerPosition; 366 pos += scalarsPerPosition;
338 } 367 }
339 } 368 }
340 369
341 this->finish(); 370 this->finish();
371
372 if (fallbackByteLength > 0) {
373 fFallbackTextContext->drawPosText(paint, skPaint, fallbackText.begin(), fallbackByteLength,
374 fallbackPos.begin(), scalarsPerPositio n, offset);
375 }
342 } 376 }
343 377
344 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 378 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
345 unsigned r = SkColorGetR(c); 379 unsigned r = SkColorGetR(c);
346 unsigned g = SkColorGetG(c); 380 unsigned g = SkColorGetG(c);
347 unsigned b = SkColorGetB(c); 381 unsigned b = SkColorGetB(c);
348 return GrColorPackRGBA(r, g, b, 0xff); 382 return GrColorPackRGBA(r, g, b, 0xff);
349 } 383 }
350 384
351 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) { 385 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 params, flags)); 425 params, flags));
392 #endif 426 #endif
393 } 427 }
394 fEffectTextureUniqueID = textureUniqueID; 428 fEffectTextureUniqueID = textureUniqueID;
395 fEffectColor = filteredColor; 429 fEffectColor = filteredColor;
396 fEffectFlags = flags; 430 fEffectFlags = flags;
397 } 431 }
398 432
399 } 433 }
400 434
401 void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, 435 // Returns true if this method handled the glyph, false if needs to be passed to fallback
436 //
437 bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
402 SkFixed vx, SkFixed vy, 438 SkFixed vx, SkFixed vy,
403 GrFontScaler* scaler) { 439 GrFontScaler* scaler) {
404 if (NULL == fDrawTarget) { 440 if (NULL == fDrawTarget) {
405 return; 441 return true;
406 } 442 }
407 443
408 if (NULL == fStrike) { 444 if (NULL == fStrike) {
409 fStrike = fContext->getFontCache()->getStrike(scaler, true); 445 fStrike = fContext->getFontCache()->getStrike(scaler, true);
410 } 446 }
411 447
412 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); 448 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
413 if (NULL == glyph || glyph->fBounds.isEmpty()) { 449 if (NULL == glyph || glyph->fBounds.isEmpty()) {
414 return; 450 return true;
415 } 451 }
416 452
417 // TODO: support color glyphs 453 // fallback to color glyph support
418 if (kA8_GrMaskFormat != glyph->fMaskFormat) { 454 if (kA8_GrMaskFormat != glyph->fMaskFormat) {
419 return; 455 return false;
420 } 456 }
421 457
422 SkScalar sx = SkFixedToScalar(vx); 458 SkScalar sx = SkFixedToScalar(vx);
423 SkScalar sy = SkFixedToScalar(vy); 459 SkScalar sy = SkFixedToScalar(vy);
424 /* 460 /*
425 // not valid, need to find a different solution for this 461 // not valid, need to find a different solution for this
426 vx += SkIntToFixed(glyph->fBounds.fLeft); 462 vx += SkIntToFixed(glyph->fBounds.fLeft);
427 vy += SkIntToFixed(glyph->fBounds.fTop); 463 vy += SkIntToFixed(glyph->fBounds.fTop);
428 464
429 // keep them as ints until we've done the clip-test 465 // keep them as ints until we've done the clip-test
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 fStrike->addGlyphToAtlas(glyph, scaler)) { 503 fStrike->addGlyphToAtlas(glyph, scaler)) {
468 goto HAS_ATLAS; 504 goto HAS_ATLAS;
469 } 505 }
470 } 506 }
471 507
472 if (NULL == glyph->fPath) { 508 if (NULL == glyph->fPath) {
473 SkPath* path = SkNEW(SkPath); 509 SkPath* path = SkNEW(SkPath);
474 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 510 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
475 // flag the glyph as being dead? 511 // flag the glyph as being dead?
476 delete path; 512 delete path;
477 return; 513 return true;
478 } 514 }
479 glyph->fPath = path; 515 glyph->fPath = path;
480 } 516 }
481 517
482 // flush any accumulated draws before drawing this glyph as a path. 518 // flush any accumulated draws before drawing this glyph as a path.
483 this->flush(); 519 this->flush();
484 520
485 GrContext::AutoMatrix am; 521 GrContext::AutoMatrix am;
486 SkMatrix ctm; 522 SkMatrix ctm;
487 ctm.setScale(fTextRatio, fTextRatio); 523 ctm.setScale(fTextRatio, fTextRatio);
488 ctm.postTranslate(sx, sy); 524 ctm.postTranslate(sx, sy);
489 GrPaint tmpPaint(fPaint); 525 GrPaint tmpPaint(fPaint);
490 am.setPreConcat(fContext, ctm, &tmpPaint); 526 am.setPreConcat(fContext, ctm, &tmpPaint);
491 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); 527 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
492 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); 528 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo);
493 return; 529 return true;
494 } 530 }
495 531
496 HAS_ATLAS: 532 HAS_ATLAS:
497 SkASSERT(glyph->fPlot); 533 SkASSERT(glyph->fPlot);
498 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); 534 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
499 glyph->fPlot->setDrawToken(drawToken); 535 glyph->fPlot->setDrawToken(drawToken);
500 536
501 GrTexture* texture = glyph->fPlot->texture(); 537 GrTexture* texture = glyph->fPlot->texture();
502 SkASSERT(texture); 538 SkASSERT(texture);
503 539
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 } 635 }
600 // color comes after position. 636 // color comes after position.
601 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); 637 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
602 for (int i = 0; i < 4; ++i) { 638 for (int i = 0; i < 4; ++i) {
603 *colors = fPaint.getColor(); 639 *colors = fPaint.getColor();
604 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize); 640 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize);
605 } 641 }
606 } 642 }
607 643
608 fCurrVertex += 4; 644 fCurrVertex += 4;
645
646 return true;
609 } 647 }
610 648
611 void GrDistanceFieldTextContext::flush() { 649 void GrDistanceFieldTextContext::flush() {
612 if (NULL == fDrawTarget) { 650 if (NULL == fDrawTarget) {
613 return; 651 return;
614 } 652 }
615 653
616 GrDrawState* drawState = fDrawTarget->drawState(); 654 GrDrawState* drawState = fDrawTarget->drawState();
617 GrDrawState::AutoRestoreEffects are(drawState); 655 GrDrawState::AutoRestoreEffects are(drawState);
618 656
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 fVertexBounds.setLargestInverted(); 711 fVertexBounds.setLargestInverted();
674 } 712 }
675 } 713 }
676 714
677 inline void GrDistanceFieldTextContext::finish() { 715 inline void GrDistanceFieldTextContext::finish() {
678 this->flush(); 716 this->flush();
679 717
680 GrTextContext::finish(); 718 GrTextContext::finish();
681 } 719 }
682 720
OLDNEW
« gm/dftext.cpp ('K') | « src/gpu/GrDistanceFieldTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698