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

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: Fix nits 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
« no previous file with comments | « 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> fallbackTxt;
298 SkTArray<SkScalar> fallbackPos;
297 299
298 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 300 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
299 while (text < stop) { 301 while (text < stop) {
302 const char* lastText = text;
300 // the last 2 parameters are ignored 303 // the last 2 parameters are ignored
301 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 304 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
302 305
303 if (glyph.fWidth) { 306 if (glyph.fWidth) {
304 SkScalar x = offset.x() + pos[0]; 307 SkScalar x = offset.x() + pos[0];
305 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 308 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
306 309
307 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), 310 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
308 glyph.getSubXFixed(), 311 glyph.getSubXFixed(),
309 glyph.getSubYFixed()), 312 glyph.getSubYFixed()),
310 SkScalarToFixed(x), 313 SkScalarToFixed(x),
311 SkScalarToFixed(y), 314 SkScalarToFixed(y),
312 fontScaler); 315 fontScaler)) {
316 // couldn't append, send to fallback
317 fallbackTxt.push_back_n(text-lastText, lastText);
318 fallbackPos.push_back(pos[0]);
319 if (2 == scalarsPerPosition) {
320 fallbackPos.push_back(pos[1]);
321 }
322 }
313 } 323 }
314 pos += scalarsPerPosition; 324 pos += scalarsPerPosition;
315 } 325 }
316 } else { 326 } else {
317 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf 327 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf
318 : SK_Scalar1; 328 : SK_Scalar1;
319 while (text < stop) { 329 while (text < stop) {
330 const char* lastText = text;
320 // the last 2 parameters are ignored 331 // the last 2 parameters are ignored
321 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 332 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
322 333
323 if (glyph.fWidth) { 334 if (glyph.fWidth) {
324 SkScalar x = offset.x() + pos[0]; 335 SkScalar x = offset.x() + pos[0];
325 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 336 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
326 337
327 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio; 338 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT extRatio;
328 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio; 339 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT extRatio;
329 340
330 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), 341 if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
331 glyph.getSubXFixed(), 342 glyph.getSubXFixed(),
332 glyph.getSubYFixed()), 343 glyph.getSubYFixed()),
333 SkScalarToFixed(x - advanceX), 344 SkScalarToFixed(x - advanceX),
334 SkScalarToFixed(y - advanceY), 345 SkScalarToFixed(y - advanceY),
335 fontScaler); 346 fontScaler)) {
347 // couldn't append, send to fallback
348 fallbackTxt.push_back_n(text-lastText, lastText);
349 fallbackPos.push_back(pos[0]);
350 if (2 == scalarsPerPosition) {
351 fallbackPos.push_back(pos[1]);
352 }
353 }
336 } 354 }
337 pos += scalarsPerPosition; 355 pos += scalarsPerPosition;
338 } 356 }
339 } 357 }
340 358
341 this->finish(); 359 this->finish();
360
361 if (fallbackTxt.count() > 0) {
362 fFallbackTextContext->drawPosText(paint, skPaint, fallbackTxt.begin(), f allbackTxt.count(),
363 fallbackPos.begin(), scalarsPerPositio n, offset);
364 }
342 } 365 }
343 366
344 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 367 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
345 unsigned r = SkColorGetR(c); 368 unsigned r = SkColorGetR(c);
346 unsigned g = SkColorGetG(c); 369 unsigned g = SkColorGetG(c);
347 unsigned b = SkColorGetB(c); 370 unsigned b = SkColorGetB(c);
348 return GrColorPackRGBA(r, g, b, 0xff); 371 return GrColorPackRGBA(r, g, b, 0xff);
349 } 372 }
350 373
351 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) { 374 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 params, flags)); 414 params, flags));
392 #endif 415 #endif
393 } 416 }
394 fEffectTextureUniqueID = textureUniqueID; 417 fEffectTextureUniqueID = textureUniqueID;
395 fEffectColor = filteredColor; 418 fEffectColor = filteredColor;
396 fEffectFlags = flags; 419 fEffectFlags = flags;
397 } 420 }
398 421
399 } 422 }
400 423
401 void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed, 424 // Returns true if this method handled the glyph, false if needs to be passed to fallback
425 //
426 bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
402 SkFixed vx, SkFixed vy, 427 SkFixed vx, SkFixed vy,
403 GrFontScaler* scaler) { 428 GrFontScaler* scaler) {
404 if (NULL == fDrawTarget) { 429 if (NULL == fDrawTarget) {
405 return; 430 return true;
406 } 431 }
407 432
408 if (NULL == fStrike) { 433 if (NULL == fStrike) {
409 fStrike = fContext->getFontCache()->getStrike(scaler, true); 434 fStrike = fContext->getFontCache()->getStrike(scaler, true);
410 } 435 }
411 436
412 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); 437 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
413 if (NULL == glyph || glyph->fBounds.isEmpty()) { 438 if (NULL == glyph || glyph->fBounds.isEmpty()) {
414 return; 439 return true;
415 } 440 }
416 441
417 // TODO: support color glyphs 442 // fallback to color glyph support
418 if (kA8_GrMaskFormat != glyph->fMaskFormat) { 443 if (kA8_GrMaskFormat != glyph->fMaskFormat) {
419 return; 444 return false;
420 } 445 }
421 446
422 SkScalar sx = SkFixedToScalar(vx); 447 SkScalar sx = SkFixedToScalar(vx);
423 SkScalar sy = SkFixedToScalar(vy); 448 SkScalar sy = SkFixedToScalar(vy);
424 /* 449 /*
425 // not valid, need to find a different solution for this 450 // not valid, need to find a different solution for this
426 vx += SkIntToFixed(glyph->fBounds.fLeft); 451 vx += SkIntToFixed(glyph->fBounds.fLeft);
427 vy += SkIntToFixed(glyph->fBounds.fTop); 452 vy += SkIntToFixed(glyph->fBounds.fTop);
428 453
429 // keep them as ints until we've done the clip-test 454 // 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)) { 492 fStrike->addGlyphToAtlas(glyph, scaler)) {
468 goto HAS_ATLAS; 493 goto HAS_ATLAS;
469 } 494 }
470 } 495 }
471 496
472 if (NULL == glyph->fPath) { 497 if (NULL == glyph->fPath) {
473 SkPath* path = SkNEW(SkPath); 498 SkPath* path = SkNEW(SkPath);
474 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 499 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
475 // flag the glyph as being dead? 500 // flag the glyph as being dead?
476 delete path; 501 delete path;
477 return; 502 return true;
478 } 503 }
479 glyph->fPath = path; 504 glyph->fPath = path;
480 } 505 }
481 506
482 // flush any accumulated draws before drawing this glyph as a path. 507 // flush any accumulated draws before drawing this glyph as a path.
483 this->flush(); 508 this->flush();
484 509
485 GrContext::AutoMatrix am; 510 GrContext::AutoMatrix am;
486 SkMatrix ctm; 511 SkMatrix ctm;
487 ctm.setScale(fTextRatio, fTextRatio); 512 ctm.setScale(fTextRatio, fTextRatio);
488 ctm.postTranslate(sx, sy); 513 ctm.postTranslate(sx, sy);
489 GrPaint tmpPaint(fPaint); 514 GrPaint tmpPaint(fPaint);
490 am.setPreConcat(fContext, ctm, &tmpPaint); 515 am.setPreConcat(fContext, ctm, &tmpPaint);
491 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); 516 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
492 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); 517 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo);
493 return; 518 return true;
494 } 519 }
495 520
496 HAS_ATLAS: 521 HAS_ATLAS:
497 SkASSERT(glyph->fPlot); 522 SkASSERT(glyph->fPlot);
498 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); 523 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
499 glyph->fPlot->setDrawToken(drawToken); 524 glyph->fPlot->setDrawToken(drawToken);
500 525
501 GrTexture* texture = glyph->fPlot->texture(); 526 GrTexture* texture = glyph->fPlot->texture();
502 SkASSERT(texture); 527 SkASSERT(texture);
503 528
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 } 624 }
600 // color comes after position. 625 // color comes after position.
601 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1); 626 GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
602 for (int i = 0; i < 4; ++i) { 627 for (int i = 0; i < 4; ++i) {
603 *colors = fPaint.getColor(); 628 *colors = fPaint.getColor();
604 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize); 629 colors = reinterpret_cast<GrColor*>(reinterpret_cast<intptr_t>(color s) + vertSize);
605 } 630 }
606 } 631 }
607 632
608 fCurrVertex += 4; 633 fCurrVertex += 4;
634
635 return true;
609 } 636 }
610 637
611 void GrDistanceFieldTextContext::flush() { 638 void GrDistanceFieldTextContext::flush() {
612 if (NULL == fDrawTarget) { 639 if (NULL == fDrawTarget) {
613 return; 640 return;
614 } 641 }
615 642
616 GrDrawState* drawState = fDrawTarget->drawState(); 643 GrDrawState* drawState = fDrawTarget->drawState();
617 GrDrawState::AutoRestoreEffects are(drawState); 644 GrDrawState::AutoRestoreEffects are(drawState);
618 645
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 fVertexBounds.setLargestInverted(); 700 fVertexBounds.setLargestInverted();
674 } 701 }
675 } 702 }
676 703
677 inline void GrDistanceFieldTextContext::finish() { 704 inline void GrDistanceFieldTextContext::finish() {
678 this->flush(); 705 this->flush();
679 706
680 GrTextContext::finish(); 707 GrTextContext::finish();
681 } 708 }
682 709
OLDNEW
« no previous file with comments | « src/gpu/GrDistanceFieldTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698