Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "SkTypes.h" | 8 #include "SkTypes.h" |
| 9 #undef GetGlyphIndices | 9 #undef GetGlyphIndices |
| 10 | 10 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 vecs[0].fX = SkScalarRoundToScalar(advanceX); | 391 vecs[0].fX = SkScalarRoundToScalar(advanceX); |
| 392 fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); | 392 fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); |
| 393 } else { | 393 } else { |
| 394 fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); | 394 fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); |
| 395 } | 395 } |
| 396 | 396 |
| 397 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX); | 397 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX); |
| 398 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); | 398 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); |
| 399 } | 399 } |
| 400 | 400 |
| 401 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { | 401 void SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, |
| 402 glyph->fWidth = 0; | 402 DWRITE_RENDERING_MODE renderingMode, |
| 403 | 403 DWRITE_TEXTURE_TYPE textureType, |
| 404 this->generateAdvance(glyph); | 404 RECT* bbox) |
| 405 | 405 { |
| 406 //Measure raster size. | 406 //Measure raster size. |
| 407 fXform.dx = SkFixedToFloat(glyph->getSubXFixed()); | 407 fXform.dx = SkFixedToFloat(glyph->getSubXFixed()); |
| 408 fXform.dy = SkFixedToFloat(glyph->getSubYFixed()); | 408 fXform.dy = SkFixedToFloat(glyph->getSubYFixed()); |
| 409 | 409 |
| 410 FLOAT advance = 0; | 410 FLOAT advance = 0; |
| 411 | 411 |
| 412 UINT16 glyphId = glyph->getGlyphID(); | 412 UINT16 glyphId = glyph->getGlyphID(); |
| 413 | 413 |
| 414 DWRITE_GLYPH_OFFSET offset; | 414 DWRITE_GLYPH_OFFSET offset; |
| 415 offset.advanceOffset = 0.0f; | 415 offset.advanceOffset = 0.0f; |
| 416 offset.ascenderOffset = 0.0f; | 416 offset.ascenderOffset = 0.0f; |
| 417 | 417 |
| 418 DWRITE_GLYPH_RUN run; | 418 DWRITE_GLYPH_RUN run; |
| 419 run.glyphCount = 1; | 419 run.glyphCount = 1; |
| 420 run.glyphAdvances = &advance; | 420 run.glyphAdvances = &advance; |
| 421 run.fontFace = fTypeface->fDWriteFontFace.get(); | 421 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 422 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 422 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
| 423 run.bidiLevel = 0; | 423 run.bidiLevel = 0; |
| 424 run.glyphIndices = &glyphId; | 424 run.glyphIndices = &glyphId; |
| 425 run.isSideways = FALSE; | 425 run.isSideways = FALSE; |
| 426 run.glyphOffsets = &offset; | 426 run.glyphOffsets = &offset; |
| 427 | 427 |
| 428 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 428 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
| 429 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( | 429 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( |
| 430 &run, | 430 &run, |
| 431 1.0f, // pixelsPerDip, | 431 1.0f, // pixelsPerDip, |
| 432 &fXform, | 432 &fXform, |
| 433 fRenderingMode, | 433 renderingMode, |
| 434 fMeasuringMode, | 434 fMeasuringMode, |
| 435 0.0f, // baselineOriginX, | 435 0.0f, // baselineOriginX, |
| 436 0.0f, // baselineOriginY, | 436 0.0f, // baselineOriginY, |
| 437 &glyphRunAnalysis), | 437 &glyphRunAnalysis), |
| 438 "Could not create glyph run analysis."); | 438 "Could not create glyph run analysis."); |
| 439 | 439 |
| 440 HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), | |
| 441 "Could not get texture bounds."); | |
| 442 } | |
| 443 | |
| 444 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { | |
| 445 glyph->fWidth = 0; | |
| 446 | |
| 447 this->generateAdvance(glyph); | |
| 448 | |
| 440 RECT bbox; | 449 RECT bbox; |
| 441 HRVM(glyphRunAnalysis->GetAlphaTextureBounds(fTextureType, &bbox), | 450 this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox); |
| 442 "Could not get texture bounds."); | 451 |
| 452 if (bbox.left == bbox.right || bbox.top == bbox.bottom) { | |
| 453 if (DWRITE_TEXTURE_CLEARTYPE_3x1 == fTextureType) { | |
| 454 this->getBoundingBox(glyph, | |
| 455 DWRITE_RENDERING_MODE_ALIASED, | |
| 456 DWRITE_TEXTURE_ALIASED_1x1, | |
| 457 &bbox); | |
| 458 if (bbox.left != bbox.right && bbox.top != bbox.bottom) { | |
|
reed1
2014/08/27 22:46:54
/*
* DWRITE 3x1 seems to have a bug/feature where
| |
| 459 glyph->fForceBW = 1; | |
| 460 } | |
| 461 } | |
| 462 } | |
| 443 | 463 |
| 444 glyph->fWidth = SkToU16(bbox.right - bbox.left); | 464 glyph->fWidth = SkToU16(bbox.right - bbox.left); |
| 445 glyph->fHeight = SkToU16(bbox.bottom - bbox.top); | 465 glyph->fHeight = SkToU16(bbox.bottom - bbox.top); |
| 446 glyph->fLeft = SkToS16(bbox.left); | 466 glyph->fLeft = SkToS16(bbox.left); |
| 447 glyph->fTop = SkToS16(bbox.top); | 467 glyph->fTop = SkToS16(bbox.top); |
| 448 } | 468 } |
| 449 | 469 |
| 450 void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 470 void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
| 451 if (NULL == metrics) { | 471 if (NULL == metrics) { |
| 452 return; | 472 return; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 for (U16CPU i = 0; i < width; i++) { | 615 for (U16CPU i = 0; i < width; i++) { |
| 596 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 616 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
| 597 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 617 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
| 598 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 618 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
| 599 dst[i] = SkPackARGB32(0xFF, r, g, b); | 619 dst[i] = SkPackARGB32(0xFF, r, g, b); |
| 600 } | 620 } |
| 601 dst = (SkPMColor*)((char*)dst + dstRB); | 621 dst = (SkPMColor*)((char*)dst + dstRB); |
| 602 } | 622 } |
| 603 } | 623 } |
| 604 | 624 |
| 605 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { | 625 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, |
| 626 DWRITE_RENDERING_MODE renderingMode, | |
| 627 DWRITE_TEXTURE_TYPE textureType) | |
| 628 { | |
| 606 int sizeNeeded = glyph.fWidth * glyph.fHeight; | 629 int sizeNeeded = glyph.fWidth * glyph.fHeight; |
| 607 if (DWRITE_RENDERING_MODE_ALIASED != fRenderingMode) { | 630 if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) { |
| 608 sizeNeeded *= 3; | 631 sizeNeeded *= 3; |
| 609 } | 632 } |
| 610 if (sizeNeeded > fBits.count()) { | 633 if (sizeNeeded > fBits.count()) { |
| 611 fBits.setCount(sizeNeeded); | 634 fBits.setCount(sizeNeeded); |
| 612 } | 635 } |
| 613 | 636 |
| 614 // erase | 637 // erase |
| 615 memset(fBits.begin(), 0, sizeNeeded); | 638 memset(fBits.begin(), 0, sizeNeeded); |
| 616 | 639 |
| 617 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); | 640 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 632 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 655 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
| 633 run.bidiLevel = 0; | 656 run.bidiLevel = 0; |
| 634 run.glyphIndices = &index; | 657 run.glyphIndices = &index; |
| 635 run.isSideways = FALSE; | 658 run.isSideways = FALSE; |
| 636 run.glyphOffsets = &offset; | 659 run.glyphOffsets = &offset; |
| 637 | 660 |
| 638 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 661 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
| 639 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, | 662 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, |
| 640 1.0f, // pixelsPerDip, | 663 1.0f, // pixelsPerDip, |
| 641 &fXform, | 664 &fXform, |
| 642 fRenderingMode, | 665 renderingMode, |
| 643 fMeasuringMode, | 666 fMeasuringMode, |
| 644 0.0f, // baselineOriginX, | 667 0.0f, // baselineOriginX, |
| 645 0.0f, // baselineOriginY, | 668 0.0f, // baselineOriginY, |
| 646 &glyphRunAnalysis), | 669 &glyphRunAnalysis), |
| 647 "Could not create glyph run analysis."); | 670 "Could not create glyph run analysis."); |
| 648 | 671 |
| 649 //NOTE: this assumes that the glyph has already been measured | 672 //NOTE: this assumes that the glyph has already been measured |
| 650 //with an exact same glyph run analysis. | 673 //with an exact same glyph run analysis. |
| 651 RECT bbox; | 674 RECT bbox; |
| 652 bbox.left = glyph.fLeft; | 675 bbox.left = glyph.fLeft; |
| 653 bbox.top = glyph.fTop; | 676 bbox.top = glyph.fTop; |
| 654 bbox.right = glyph.fLeft + glyph.fWidth; | 677 bbox.right = glyph.fLeft + glyph.fWidth; |
| 655 bbox.bottom = glyph.fTop + glyph.fHeight; | 678 bbox.bottom = glyph.fTop + glyph.fHeight; |
| 656 HRNM(glyphRunAnalysis->CreateAlphaTexture(fTextureType, | 679 HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType, |
| 657 &bbox, | 680 &bbox, |
| 658 fBits.begin(), | 681 fBits.begin(), |
| 659 sizeNeeded), | 682 sizeNeeded), |
| 660 "Could not draw mask."); | 683 "Could not draw mask."); |
| 661 return fBits.begin(); | 684 return fBits.begin(); |
| 662 } | 685 } |
| 663 | 686 |
| 664 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { | 687 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { |
| 665 //Create the mask. | 688 //Create the mask. |
| 666 const void* bits = this->drawDWMask(glyph); | 689 DWRITE_RENDERING_MODE renderingMode = fRenderingMode; |
| 690 DWRITE_TEXTURE_TYPE textureType = fTextureType; | |
| 691 if (glyph.fForceBW) { | |
| 692 renderingMode = DWRITE_RENDERING_MODE_ALIASED; | |
| 693 textureType = DWRITE_TEXTURE_ALIASED_1x1; | |
| 694 } | |
| 695 const void* bits = this->drawDWMask(glyph, renderingMode, textureType); | |
| 667 if (!bits) { | 696 if (!bits) { |
| 668 sk_bzero(glyph.fImage, glyph.computeImageSize()); | 697 sk_bzero(glyph.fImage, glyph.computeImageSize()); |
| 669 return; | 698 return; |
| 670 } | 699 } |
| 671 | 700 |
| 672 //Copy the mask into the glyph. | 701 //Copy the mask into the glyph. |
| 673 const uint8_t* src = (const uint8_t*)bits; | 702 const uint8_t* src = (const uint8_t*)bits; |
| 674 if (DWRITE_RENDERING_MODE_ALIASED == fRenderingMode) { | 703 if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { |
| 675 bilevel_to_bw(src, glyph); | 704 bilevel_to_bw(src, glyph); |
| 676 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; | 705 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; |
| 677 } else if (!isLCD(fRec)) { | 706 } else if (!isLCD(fRec)) { |
| 678 if (fPreBlend.isApplicable()) { | 707 if (fPreBlend.isApplicable()) { |
| 679 rgb_to_a8<true>(src, glyph, fPreBlend.fG); | 708 rgb_to_a8<true>(src, glyph, fPreBlend.fG); |
| 680 } else { | 709 } else { |
| 681 rgb_to_a8<false>(src, glyph, fPreBlend.fG); | 710 rgb_to_a8<false>(src, glyph, fPreBlend.fG); |
| 682 } | 711 } |
| 683 } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) { | 712 } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) { |
| 684 if (fPreBlend.isApplicable()) { | 713 if (fPreBlend.isApplicable()) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 712 NULL, //advances | 741 NULL, //advances |
| 713 NULL, //offsets | 742 NULL, //offsets |
| 714 1, //num glyphs | 743 1, //num glyphs |
| 715 FALSE, //sideways | 744 FALSE, //sideways |
| 716 FALSE, //rtl | 745 FALSE, //rtl |
| 717 geometryToPath.get()), | 746 geometryToPath.get()), |
| 718 "Could not create glyph outline."); | 747 "Could not create glyph outline."); |
| 719 | 748 |
| 720 path->transform(fSkXform); | 749 path->transform(fSkXform); |
| 721 } | 750 } |
| OLD | NEW |