| 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 #if defined(SK_BUILD_FOR_WIN32) | 9 #if defined(SK_BUILD_FOR_WIN32) |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "SkRasterClip.h" | 27 #include "SkRasterClip.h" |
| 28 #include "SkScalerContext.h" | 28 #include "SkScalerContext.h" |
| 29 #include "SkScalerContext_win_dw.h" | 29 #include "SkScalerContext_win_dw.h" |
| 30 #include "SkSharedMutex.h" | 30 #include "SkSharedMutex.h" |
| 31 #include "SkTScopedComPtr.h" | 31 #include "SkTScopedComPtr.h" |
| 32 #include "SkTypeface_win_dw.h" | 32 #include "SkTypeface_win_dw.h" |
| 33 | 33 |
| 34 #include <dwrite.h> | 34 #include <dwrite.h> |
| 35 #if SK_HAS_DWRITE_1_H | 35 #if SK_HAS_DWRITE_1_H |
| 36 # include <dwrite_1.h> | 36 # include <dwrite_1.h> |
| 37 #else | |
| 38 # pragma message("No dwrite_1.h is available, font metrics may be affected.") | |
| 39 #endif | |
| 40 | |
| 41 #if SK_HAS_DWRITE_2_H | |
| 42 # include <dwrite_2.h> | |
| 43 #else | |
| 44 # pragma message("No dwrite_2.h is available, pixel antialiased glyph quality m
ay be affected.") | |
| 45 #endif | 37 #endif |
| 46 | 38 |
| 47 /* Note: | 39 /* Note: |
| 48 * In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe. | 40 * In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe. |
| 49 * The DWriteFactoryMutex protects the calls that are problematic. | 41 * The DWriteFactoryMutex protects the calls that are problematic. |
| 50 */ | 42 */ |
| 51 static SkSharedMutex DWriteFactoryMutex; | 43 static SkSharedMutex DWriteFactoryMutex; |
| 52 | 44 |
| 53 typedef SkAutoSharedMutexShared Shared; | 45 typedef SkAutoSharedMutexShared Shared; |
| 54 | 46 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 } | 205 } |
| 214 | 206 |
| 215 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface, | 207 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface, |
| 216 const SkScalerContextEffects& effects, | 208 const SkScalerContextEffects& effects, |
| 217 const SkDescriptor* desc) | 209 const SkDescriptor* desc) |
| 218 : SkScalerContext(typeface, effects, desc) | 210 : SkScalerContext(typeface, effects, desc) |
| 219 , fTypeface(SkRef(typeface)) | 211 , fTypeface(SkRef(typeface)) |
| 220 , fGlyphCount(-1) { | 212 , fGlyphCount(-1) { |
| 221 | 213 |
| 222 #if SK_HAS_DWRITE_2_H | 214 #if SK_HAS_DWRITE_2_H |
| 223 fIsColorFont = fTypeface->fFactory2 && | 215 fTypeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2); |
| 224 fTypeface->fDWriteFontFace2 && | 216 |
| 225 fTypeface->fDWriteFontFace2->IsColorFont(); | 217 SkTScopedComPtr<IDWriteFontFace2> fontFace2; |
| 218 fTypeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2); |
| 219 fIsColorFont = fFactory2.get() && fontFace2.get() && fontFace2->IsColorFont(
); |
| 226 #endif | 220 #endif |
| 227 | 221 |
| 228 // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC | 222 // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC |
| 229 // except when bi-level rendering is requested or there are embedded | 223 // except when bi-level rendering is requested or there are embedded |
| 230 // bi-level bitmaps (and the embedded bitmap flag is set and no rotation). | 224 // bi-level bitmaps (and the embedded bitmap flag is set and no rotation). |
| 231 // | 225 // |
| 232 // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do | 226 // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do |
| 233 // this. As a result, determine the actual size of the text and then see if | 227 // this. As a result, determine the actual size of the text and then see if |
| 234 // there are any embedded bi-level bitmaps of that size. If there are, then | 228 // there are any embedded bi-level bitmaps of that size. If there are, then |
| 235 // force bitmaps by requesting bi-level rendering. | 229 // force bitmaps by requesting bi-level rendering. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 317 |
| 324 // The normal case is to use natural symmetric rendering and linear metrics. | 318 // The normal case is to use natural symmetric rendering and linear metrics. |
| 325 } else { | 319 } else { |
| 326 fTextSizeRender = realTextSize; | 320 fTextSizeRender = realTextSize; |
| 327 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | 321 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
| 328 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; | 322 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; |
| 329 fTextSizeMeasure = realTextSize; | 323 fTextSizeMeasure = realTextSize; |
| 330 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 324 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 331 } | 325 } |
| 332 | 326 |
| 333 // DirectWrite2 allows for grayscale hinting. | |
| 334 #if SK_HAS_DWRITE_2_H | |
| 335 fAntiAliasMode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; | |
| 336 #ifndef SK_IGNORE_DW_GRAY_FIX | |
| 337 if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2 && | |
| 338 !isLCD(fRec) && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) | |
| 339 { | |
| 340 // DWRITE_TEXTURE_ALIASED_1x1 is now misnamed, it must also be used with
grayscale. | |
| 341 fTextureType = DWRITE_TEXTURE_ALIASED_1x1; | |
| 342 fAntiAliasMode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE; | |
| 343 } | |
| 344 #endif | |
| 345 #endif | |
| 346 | |
| 347 // DirectWrite2 allows hinting to be disabled. | |
| 348 #if SK_HAS_DWRITE_2_H | |
| 349 fGridFitMode = DWRITE_GRID_FIT_MODE_ENABLED; | |
| 350 if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2 && | |
| 351 fRec.getHinting() == SkPaint::kNo_Hinting) | |
| 352 { | |
| 353 fGridFitMode = DWRITE_GRID_FIT_MODE_DISABLED; | |
| 354 } | |
| 355 #endif | |
| 356 | |
| 357 if (this->isSubpixel()) { | 327 if (this->isSubpixel()) { |
| 358 fTextSizeMeasure = realTextSize; | 328 fTextSizeMeasure = realTextSize; |
| 359 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 329 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 360 } | 330 } |
| 361 } | 331 } |
| 362 | 332 |
| 363 SkScalerContext_DW::~SkScalerContext_DW() { | 333 SkScalerContext_DW::~SkScalerContext_DW() { |
| 364 } | 334 } |
| 365 | 335 |
| 366 unsigned SkScalerContext_DW::generateGlyphCount() { | 336 unsigned SkScalerContext_DW::generateGlyphCount() { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 run.fontFace = fTypeface->fDWriteFontFace.get(); | 425 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 456 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 426 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
| 457 run.bidiLevel = 0; | 427 run.bidiLevel = 0; |
| 458 run.glyphIndices = &glyphId; | 428 run.glyphIndices = &glyphId; |
| 459 run.isSideways = FALSE; | 429 run.isSideways = FALSE; |
| 460 run.glyphOffsets = &offset; | 430 run.glyphOffsets = &offset; |
| 461 | 431 |
| 462 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 432 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
| 463 { | 433 { |
| 464 SkAutoExclusive l(DWriteFactoryMutex); | 434 SkAutoExclusive l(DWriteFactoryMutex); |
| 465 if (fTypeface->fFactory2) { | 435 HRM(fTypeface->fFactory->CreateGlyphRunAnalysis( |
| 466 #if SK_HAS_DWRITE_2_H | 436 &run, |
| 467 HRNM(fTypeface->fFactory2->CreateGlyphRunAnalysis( | 437 1.0f, // pixelsPerDip, |
| 468 &run, | 438 &fXform, |
| 469 &fXform, | 439 renderingMode, |
| 470 renderingMode, | 440 fMeasuringMode, |
| 471 fMeasuringMode, | 441 0.0f, // baselineOriginX, |
| 472 fGridFitMode, | 442 0.0f, // baselineOriginY, |
| 473 fAntiAliasMode, | 443 &glyphRunAnalysis), |
| 474 0.0f, // baselineOriginX, | 444 "Could not create glyph run analysis."); |
| 475 0.0f, // baselineOriginY, | |
| 476 &glyphRunAnalysis), | |
| 477 "Could not create DW2 glyph run analysis."); | |
| 478 #endif | |
| 479 } else { | |
| 480 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, | |
| 481 1.0f, // pixelsPerDip, | |
| 482 &fXform, | |
| 483 renderingMode, | |
| 484 fMeasuringMode, | |
| 485 0.0f, // baselineOriginX, | |
| 486 0.0f, // baselineOriginY, | |
| 487 &glyphRunAnalysis), | |
| 488 "Could not create glyph run analysis."); | |
| 489 } | |
| 490 } | 445 } |
| 491 { | 446 { |
| 492 Shared l(DWriteFactoryMutex); | 447 Shared l(DWriteFactoryMutex); |
| 493 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), | 448 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), |
| 494 "Could not get texture bounds."); | 449 "Could not get texture bounds."); |
| 495 } | 450 } |
| 496 return S_OK; | 451 return S_OK; |
| 497 } | 452 } |
| 498 | 453 |
| 499 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like | 454 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 DWRITE_GLYPH_RUN run; | 491 DWRITE_GLYPH_RUN run; |
| 537 run.glyphCount = 1; | 492 run.glyphCount = 1; |
| 538 run.glyphAdvances = &advance; | 493 run.glyphAdvances = &advance; |
| 539 run.fontFace = fTypeface->fDWriteFontFace.get(); | 494 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 540 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 495 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
| 541 run.bidiLevel = 0; | 496 run.bidiLevel = 0; |
| 542 run.glyphIndices = &glyphId; | 497 run.glyphIndices = &glyphId; |
| 543 run.isSideways = FALSE; | 498 run.isSideways = FALSE; |
| 544 run.glyphOffsets = &offset; | 499 run.glyphOffsets = &offset; |
| 545 | 500 |
| 546 HRESULT hr = fTypeface->fFactory2->TranslateColorGlyphRun( | 501 HRESULT hr = fFactory2->TranslateColorGlyphRun( |
| 547 0, 0, &run, nullptr, fMeasuringMode, &fXform, 0, colorGlyph); | 502 0, 0, &run, nullptr, fMeasuringMode, &fXform, 0, colorGlyph); |
| 548 if (hr == DWRITE_E_NOCOLOR) { | 503 if (hr == DWRITE_E_NOCOLOR) { |
| 549 return false; | 504 return false; |
| 550 } | 505 } |
| 551 HRBM(hr, "Failed to translate color glyph run"); | 506 HRBM(hr, "Failed to translate color glyph run"); |
| 552 return true; | 507 return true; |
| 553 } | 508 } |
| 554 #endif | 509 #endif |
| 555 | 510 |
| 556 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { | 511 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 DWRITE_FONT_METRICS1 dwfm1; | 584 DWRITE_FONT_METRICS1 dwfm1; |
| 630 fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1); | 585 fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1); |
| 631 metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / up
em; | 586 metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / up
em; |
| 632 metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom
) / upem; | 587 metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom
) / upem; |
| 633 metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / u
pem; | 588 metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / u
pem; |
| 634 metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) /
upem; | 589 metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) /
upem; |
| 635 | 590 |
| 636 metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; | 591 metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; |
| 637 return; | 592 return; |
| 638 } | 593 } |
| 594 #else |
| 595 # pragma message("No dwrite_1.h is available, font metrics may be affected.") |
| 639 #endif | 596 #endif |
| 640 | 597 |
| 641 AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get()); | 598 AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get()); |
| 642 if (head.fExists && | 599 if (head.fExists && |
| 643 head.fSize >= sizeof(SkOTTableHead) && | 600 head.fSize >= sizeof(SkOTTableHead) && |
| 644 head->version == SkOTTableHead::version1) | 601 head->version == SkOTTableHead::version1) |
| 645 { | 602 { |
| 646 metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax
) / upem; | 603 metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax
) / upem; |
| 647 metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->y
Min) / upem; | 604 metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->y
Min) / upem; |
| 648 metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin
) / upem; | 605 metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin
) / upem; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 mask >>= 1; | 649 mask >>= 1; |
| 693 } | 650 } |
| 694 dst[byteCount] = byte; | 651 dst[byteCount] = byte; |
| 695 } | 652 } |
| 696 src += bitCount; | 653 src += bitCount; |
| 697 dst += dstRB; | 654 dst += dstRB; |
| 698 } | 655 } |
| 699 } | 656 } |
| 700 | 657 |
| 701 template<bool APPLY_PREBLEND> | 658 template<bool APPLY_PREBLEND> |
| 702 static void grayscale_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph
, | |
| 703 const uint8_t* table8) { | |
| 704 const size_t dstRB = glyph.rowBytes(); | |
| 705 const U16CPU width = glyph.fWidth; | |
| 706 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); | |
| 707 | |
| 708 for (U16CPU y = 0; y < glyph.fHeight; y++) { | |
| 709 for (U16CPU i = 0; i < width; i++) { | |
| 710 U8CPU a = *(src++); | |
| 711 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>(a, table8); | |
| 712 } | |
| 713 dst = SkTAddOffset<uint8_t>(dst, dstRB); | |
| 714 } | |
| 715 } | |
| 716 | |
| 717 template<bool APPLY_PREBLEND> | |
| 718 static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
t uint8_t* table8) { | 659 static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
t uint8_t* table8) { |
| 719 const size_t dstRB = glyph.rowBytes(); | 660 const size_t dstRB = glyph.rowBytes(); |
| 720 const U16CPU width = glyph.fWidth; | 661 const U16CPU width = glyph.fWidth; |
| 721 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); | 662 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); |
| 722 | 663 |
| 723 for (U16CPU y = 0; y < glyph.fHeight; y++) { | 664 for (U16CPU y = 0; y < glyph.fHeight; y++) { |
| 724 for (U16CPU i = 0; i < width; i++) { | 665 for (U16CPU i = 0; i < width; i++) { |
| 725 U8CPU r = *(src++); | 666 U8CPU r = *(src++); |
| 726 U8CPU g = *(src++); | 667 U8CPU g = *(src++); |
| 727 U8CPU b = *(src++); | 668 U8CPU b = *(src++); |
| 728 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8); | 669 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8); |
| 729 } | 670 } |
| 730 dst = SkTAddOffset<uint8_t>(dst, dstRB); | 671 dst = (uint8_t*)((char*)dst + dstRB); |
| 731 } | 672 } |
| 732 } | 673 } |
| 733 | 674 |
| 734 template<bool APPLY_PREBLEND, bool RGB> | 675 template<bool APPLY_PREBLEND, bool RGB> |
| 735 static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, | 676 static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, |
| 736 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { | 677 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { |
| 737 const size_t dstRB = glyph.rowBytes(); | 678 const size_t dstRB = glyph.rowBytes(); |
| 738 const U16CPU width = glyph.fWidth; | 679 const U16CPU width = glyph.fWidth; |
| 739 uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage); | 680 uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage); |
| 740 | 681 |
| 741 for (U16CPU y = 0; y < glyph.fHeight; y++) { | 682 for (U16CPU y = 0; y < glyph.fHeight; y++) { |
| 742 for (U16CPU i = 0; i < width; i++) { | 683 for (U16CPU i = 0; i < width; i++) { |
| 743 U8CPU r, g, b; | 684 U8CPU r, g, b; |
| 744 if (RGB) { | 685 if (RGB) { |
| 745 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 686 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
| 746 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 687 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
| 747 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 688 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
| 748 } else { | 689 } else { |
| 749 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 690 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
| 750 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 691 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
| 751 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 692 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
| 752 } | 693 } |
| 753 dst[i] = SkPack888ToRGB16(r, g, b); | 694 dst[i] = SkPack888ToRGB16(r, g, b); |
| 754 } | 695 } |
| 755 dst = SkTAddOffset<uint16_t>(dst, dstRB); | 696 dst = (uint16_t*)((char*)dst + dstRB); |
| 756 } | 697 } |
| 757 } | 698 } |
| 758 | 699 |
| 759 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, | 700 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, |
| 760 DWRITE_RENDERING_MODE renderingMode, | 701 DWRITE_RENDERING_MODE renderingMode, |
| 761 DWRITE_TEXTURE_TYPE textureType) | 702 DWRITE_TEXTURE_TYPE textureType) |
| 762 { | 703 { |
| 763 int sizeNeeded = glyph.fWidth * glyph.fHeight; | 704 int sizeNeeded = glyph.fWidth * glyph.fHeight; |
| 764 if (DWRITE_TEXTURE_CLEARTYPE_3x1 == textureType) { | 705 if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) { |
| 765 sizeNeeded *= 3; | 706 sizeNeeded *= 3; |
| 766 } | 707 } |
| 767 if (sizeNeeded > fBits.count()) { | 708 if (sizeNeeded > fBits.count()) { |
| 768 fBits.setCount(sizeNeeded); | 709 fBits.setCount(sizeNeeded); |
| 769 } | 710 } |
| 770 | 711 |
| 771 // erase | 712 // erase |
| 772 memset(fBits.begin(), 0, sizeNeeded); | 713 memset(fBits.begin(), 0, sizeNeeded); |
| 773 | 714 |
| 774 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); | 715 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 785 DWRITE_GLYPH_RUN run; | 726 DWRITE_GLYPH_RUN run; |
| 786 run.glyphCount = 1; | 727 run.glyphCount = 1; |
| 787 run.glyphAdvances = &advance; | 728 run.glyphAdvances = &advance; |
| 788 run.fontFace = fTypeface->fDWriteFontFace.get(); | 729 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 789 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 730 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
| 790 run.bidiLevel = 0; | 731 run.bidiLevel = 0; |
| 791 run.glyphIndices = &index; | 732 run.glyphIndices = &index; |
| 792 run.isSideways = FALSE; | 733 run.isSideways = FALSE; |
| 793 run.glyphOffsets = &offset; | 734 run.glyphOffsets = &offset; |
| 794 { | 735 { |
| 736 |
| 795 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 737 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
| 796 { | 738 { |
| 797 SkAutoExclusive l(DWriteFactoryMutex); | 739 SkAutoExclusive l(DWriteFactoryMutex); |
| 798 if (fTypeface->fFactory2) { | 740 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, |
| 799 #if SK_HAS_DWRITE_2_H | 741 1.0f, // pixelsPerDip, |
| 800 HRNM(fTypeface->fFactory2->CreateGlyphRunAnalysis(&run, | 742 &fXform, |
| 801 &fXform, | 743 renderingMode, |
| 802 renderingMode, | 744 fMeasuringMode, |
| 803 fMeasuringMode, | 745 0.0f, // baselineOriginX, |
| 804 fGridFitMode, | 746 0.0f, // baselineOriginY, |
| 805 fAntiAliasMode, | 747 &glyphRunAnalysis), |
| 806 0.0f, // baselineOriginX, | 748 "Could not create glyph run analysis."); |
| 807 0.0f, // baselineOriginY, | |
| 808 &glyphRunAnalysis), | |
| 809 "Could not create DW2 glyph run analysis."); | |
| 810 #endif | |
| 811 } else { | |
| 812 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, | |
| 813 1.0f, // pixelsPerDip, | |
| 814 &fXform, | |
| 815 renderingMode, | |
| 816 fMeasuringMode, | |
| 817 0.0f, // baselineOriginX, | |
| 818 0.0f, // baselineOriginY, | |
| 819 &glyphRunAnalysis), | |
| 820 "Could not create glyph run analysis."); | |
| 821 } | |
| 822 } | 749 } |
| 823 //NOTE: this assumes that the glyph has already been measured | 750 //NOTE: this assumes that the glyph has already been measured |
| 824 //with an exact same glyph run analysis. | 751 //with an exact same glyph run analysis. |
| 825 RECT bbox; | 752 RECT bbox; |
| 826 bbox.left = glyph.fLeft; | 753 bbox.left = glyph.fLeft; |
| 827 bbox.top = glyph.fTop; | 754 bbox.top = glyph.fTop; |
| 828 bbox.right = glyph.fLeft + glyph.fWidth; | 755 bbox.right = glyph.fLeft + glyph.fWidth; |
| 829 bbox.bottom = glyph.fTop + glyph.fHeight; | 756 bbox.bottom = glyph.fTop + glyph.fHeight; |
| 830 { | 757 { |
| 831 Shared l(DWriteFactoryMutex); | 758 Shared l(DWriteFactoryMutex); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 sk_bzero(glyph.fImage, glyph.computeImageSize()); | 858 sk_bzero(glyph.fImage, glyph.computeImageSize()); |
| 932 return; | 859 return; |
| 933 } | 860 } |
| 934 | 861 |
| 935 //Copy the mask into the glyph. | 862 //Copy the mask into the glyph. |
| 936 const uint8_t* src = (const uint8_t*)bits; | 863 const uint8_t* src = (const uint8_t*)bits; |
| 937 if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { | 864 if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { |
| 938 bilevel_to_bw(src, glyph); | 865 bilevel_to_bw(src, glyph); |
| 939 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; | 866 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; |
| 940 } else if (!isLCD(fRec)) { | 867 } else if (!isLCD(fRec)) { |
| 941 if (textureType == DWRITE_TEXTURE_ALIASED_1x1) { | 868 if (fPreBlend.isApplicable()) { |
| 942 if (fPreBlend.isApplicable()) { | 869 rgb_to_a8<true>(src, glyph, fPreBlend.fG); |
| 943 grayscale_to_a8<true>(src, glyph, fPreBlend.fG); | |
| 944 } else { | |
| 945 grayscale_to_a8<false>(src, glyph, fPreBlend.fG); | |
| 946 } | |
| 947 } else { | 870 } else { |
| 948 if (fPreBlend.isApplicable()) { | 871 rgb_to_a8<false>(src, glyph, fPreBlend.fG); |
| 949 rgb_to_a8<true>(src, glyph, fPreBlend.fG); | |
| 950 } else { | |
| 951 rgb_to_a8<false>(src, glyph, fPreBlend.fG); | |
| 952 } | |
| 953 } | 872 } |
| 954 } else { | 873 } else { |
| 955 SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat); | 874 SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat); |
| 956 if (fPreBlend.isApplicable()) { | 875 if (fPreBlend.isApplicable()) { |
| 957 if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) { | 876 if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) { |
| 958 rgb_to_lcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG
, fPreBlend.fB); | 877 rgb_to_lcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG
, fPreBlend.fB); |
| 959 } else { | 878 } else { |
| 960 rgb_to_lcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG,
fPreBlend.fB); | 879 rgb_to_lcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG,
fPreBlend.fB); |
| 961 } | 880 } |
| 962 } else { | 881 } else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 990 FALSE, //sideways | 909 FALSE, //sideways |
| 991 FALSE, //rtl | 910 FALSE, //rtl |
| 992 geometryToPath.get()), | 911 geometryToPath.get()), |
| 993 "Could not create glyph outline."); | 912 "Could not create glyph outline."); |
| 994 } | 913 } |
| 995 | 914 |
| 996 path->transform(fSkXform); | 915 path->transform(fSkXform); |
| 997 } | 916 } |
| 998 | 917 |
| 999 #endif//defined(SK_BUILD_FOR_WIN32) | 918 #endif//defined(SK_BUILD_FOR_WIN32) |
| OLD | NEW |