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.") |
37 #endif | 45 #endif |
38 | 46 |
39 /* Note: | 47 /* Note: |
40 * In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe. | 48 * In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe. |
41 * The DWriteFactoryMutex protects the calls that are problematic. | 49 * The DWriteFactoryMutex protects the calls that are problematic. |
42 */ | 50 */ |
43 static SkSharedMutex DWriteFactoryMutex; | 51 static SkSharedMutex DWriteFactoryMutex; |
44 | 52 |
45 typedef SkAutoSharedMutexShared Shared; | 53 typedef SkAutoSharedMutexShared Shared; |
46 | 54 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 213 } |
206 | 214 |
207 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface, | 215 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface, |
208 const SkScalerContextEffects& effects, | 216 const SkScalerContextEffects& effects, |
209 const SkDescriptor* desc) | 217 const SkDescriptor* desc) |
210 : SkScalerContext(typeface, effects, desc) | 218 : SkScalerContext(typeface, effects, desc) |
211 , fTypeface(SkRef(typeface)) | 219 , fTypeface(SkRef(typeface)) |
212 , fGlyphCount(-1) { | 220 , fGlyphCount(-1) { |
213 | 221 |
214 #if SK_HAS_DWRITE_2_H | 222 #if SK_HAS_DWRITE_2_H |
215 fTypeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2); | 223 fIsColorFont = fTypeface->fFactory2 && |
216 | 224 fTypeface->fDWriteFontFace2 && |
217 SkTScopedComPtr<IDWriteFontFace2> fontFace2; | 225 fTypeface->fDWriteFontFace2->IsColorFont(); |
218 fTypeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2); | |
219 fIsColorFont = fFactory2.get() && fontFace2.get() && fontFace2->IsColorFont(
); | |
220 #endif | 226 #endif |
221 | 227 |
222 // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC | 228 // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC |
223 // except when bi-level rendering is requested or there are embedded | 229 // except when bi-level rendering is requested or there are embedded |
224 // bi-level bitmaps (and the embedded bitmap flag is set and no rotation). | 230 // bi-level bitmaps (and the embedded bitmap flag is set and no rotation). |
225 // | 231 // |
226 // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do | 232 // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do |
227 // this. As a result, determine the actual size of the text and then see if | 233 // this. As a result, determine the actual size of the text and then see if |
228 // there are any embedded bi-level bitmaps of that size. If there are, then | 234 // there are any embedded bi-level bitmaps of that size. If there are, then |
229 // force bitmaps by requesting bi-level rendering. | 235 // force bitmaps by requesting bi-level rendering. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 323 |
318 // The normal case is to use natural symmetric rendering and linear metrics. | 324 // The normal case is to use natural symmetric rendering and linear metrics. |
319 } else { | 325 } else { |
320 fTextSizeRender = realTextSize; | 326 fTextSizeRender = realTextSize; |
321 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | 327 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
322 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; | 328 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; |
323 fTextSizeMeasure = realTextSize; | 329 fTextSizeMeasure = realTextSize; |
324 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 330 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
325 } | 331 } |
326 | 332 |
| 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 (fRec.getHinting() == SkPaint::kNo_Hinting) { |
| 351 fGridFitMode = DWRITE_GRID_FIT_MODE_DISABLED; |
| 352 } else if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2) { |
| 353 [this]() { |
| 354 SkTScopedComPtr<IDWriteRenderingParams2> renderingParams; |
| 355 HRVM(fTypeface->fFactory2->CreateCustomRenderingParams( |
| 356 1.0, // gamma |
| 357 0.0, // enhancedContrast |
| 358 0.0, // grayscaleEnhancedContrast |
| 359 1.0, // clearTypeLevel |
| 360 DWRITE_PIXEL_GEOMETRY_RGB, |
| 361 fRenderingMode, |
| 362 DWRITE_GRID_FIT_MODE_DEFAULT, |
| 363 &renderingParams), |
| 364 "Could not create custom rendering params."); |
| 365 DWRITE_RENDERING_MODE ignoredRenderingMode; |
| 366 HRVM(fTypeface->fDWriteFontFace2->GetRecommendedRenderingMode( |
| 367 SkScalarToFloat(fTextSizeRender), |
| 368 1.0f, //dpiX |
| 369 1.0f, //dpiY |
| 370 nullptr, //&fXform, |
| 371 FALSE, //isSideways |
| 372 fRec.fMaskFormat == SkMask::kBW_Format ? DWRITE_OUTLINE_THR
ESHOLD_ALIASED |
| 373 : DWRITE_OUTLINE_THR
ESHOLD_ANTIALIASED, |
| 374 fMeasuringMode, |
| 375 renderingParams.get(), |
| 376 &ignoredRenderingMode, |
| 377 &fGridFitMode), |
| 378 "Could not get reccomended grid fit mode."); |
| 379 }(); |
| 380 } |
| 381 #endif |
| 382 |
327 if (this->isSubpixel()) { | 383 if (this->isSubpixel()) { |
328 fTextSizeMeasure = realTextSize; | 384 fTextSizeMeasure = realTextSize; |
329 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 385 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
330 } | 386 } |
331 } | 387 } |
332 | 388 |
333 SkScalerContext_DW::~SkScalerContext_DW() { | 389 SkScalerContext_DW::~SkScalerContext_DW() { |
334 } | 390 } |
335 | 391 |
336 unsigned SkScalerContext_DW::generateGlyphCount() { | 392 unsigned SkScalerContext_DW::generateGlyphCount() { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 run.fontFace = fTypeface->fDWriteFontFace.get(); | 481 run.fontFace = fTypeface->fDWriteFontFace.get(); |
426 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 482 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
427 run.bidiLevel = 0; | 483 run.bidiLevel = 0; |
428 run.glyphIndices = &glyphId; | 484 run.glyphIndices = &glyphId; |
429 run.isSideways = FALSE; | 485 run.isSideways = FALSE; |
430 run.glyphOffsets = &offset; | 486 run.glyphOffsets = &offset; |
431 | 487 |
432 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 488 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
433 { | 489 { |
434 SkAutoExclusive l(DWriteFactoryMutex); | 490 SkAutoExclusive l(DWriteFactoryMutex); |
435 HRM(fTypeface->fFactory->CreateGlyphRunAnalysis( | 491 if (fTypeface->fFactory2) { |
436 &run, | 492 #if SK_HAS_DWRITE_2_H |
437 1.0f, // pixelsPerDip, | 493 HRM(fTypeface->fFactory2->CreateGlyphRunAnalysis( |
438 &fXform, | 494 &run, |
439 renderingMode, | 495 &fXform, |
440 fMeasuringMode, | 496 renderingMode, |
441 0.0f, // baselineOriginX, | 497 fMeasuringMode, |
442 0.0f, // baselineOriginY, | 498 fGridFitMode, |
443 &glyphRunAnalysis), | 499 fAntiAliasMode, |
444 "Could not create glyph run analysis."); | 500 0.0f, // baselineOriginX, |
| 501 0.0f, // baselineOriginY, |
| 502 &glyphRunAnalysis), |
| 503 "Could not create DW2 glyph run analysis."); |
| 504 #endif |
| 505 } else { |
| 506 HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, |
| 507 1.0f, // pixelsPerDip, |
| 508 &fXform, |
| 509 renderingMode, |
| 510 fMeasuringMode, |
| 511 0.0f, // baselineOriginX, |
| 512 0.0f, // baselineOriginY, |
| 513 &glyphRunAnalysis), |
| 514 "Could not create glyph run analysis."); |
| 515 } |
445 } | 516 } |
446 { | 517 { |
447 Shared l(DWriteFactoryMutex); | 518 Shared l(DWriteFactoryMutex); |
448 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), | 519 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), |
449 "Could not get texture bounds."); | 520 "Could not get texture bounds."); |
450 } | 521 } |
451 return S_OK; | 522 return S_OK; |
452 } | 523 } |
453 | 524 |
454 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like | 525 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 DWRITE_GLYPH_RUN run; | 562 DWRITE_GLYPH_RUN run; |
492 run.glyphCount = 1; | 563 run.glyphCount = 1; |
493 run.glyphAdvances = &advance; | 564 run.glyphAdvances = &advance; |
494 run.fontFace = fTypeface->fDWriteFontFace.get(); | 565 run.fontFace = fTypeface->fDWriteFontFace.get(); |
495 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 566 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
496 run.bidiLevel = 0; | 567 run.bidiLevel = 0; |
497 run.glyphIndices = &glyphId; | 568 run.glyphIndices = &glyphId; |
498 run.isSideways = FALSE; | 569 run.isSideways = FALSE; |
499 run.glyphOffsets = &offset; | 570 run.glyphOffsets = &offset; |
500 | 571 |
501 HRESULT hr = fFactory2->TranslateColorGlyphRun( | 572 HRESULT hr = fTypeface->fFactory2->TranslateColorGlyphRun( |
502 0, 0, &run, nullptr, fMeasuringMode, &fXform, 0, colorGlyph); | 573 0, 0, &run, nullptr, fMeasuringMode, &fXform, 0, colorGlyph); |
503 if (hr == DWRITE_E_NOCOLOR) { | 574 if (hr == DWRITE_E_NOCOLOR) { |
504 return false; | 575 return false; |
505 } | 576 } |
506 HRBM(hr, "Failed to translate color glyph run"); | 577 HRBM(hr, "Failed to translate color glyph run"); |
507 return true; | 578 return true; |
508 } | 579 } |
509 #endif | 580 #endif |
510 | 581 |
511 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { | 582 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 DWRITE_FONT_METRICS1 dwfm1; | 655 DWRITE_FONT_METRICS1 dwfm1; |
585 fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1); | 656 fTypeface->fDWriteFontFace1->GetMetrics(&dwfm1); |
586 metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / up
em; | 657 metrics->fTop = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxTop) / up
em; |
587 metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom
) / upem; | 658 metrics->fBottom = -fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxBottom
) / upem; |
588 metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / u
pem; | 659 metrics->fXMin = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxLeft) / u
pem; |
589 metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) /
upem; | 660 metrics->fXMax = fTextSizeRender * SkIntToScalar(dwfm1.glyphBoxRight) /
upem; |
590 | 661 |
591 metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; | 662 metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; |
592 return; | 663 return; |
593 } | 664 } |
594 #else | |
595 # pragma message("No dwrite_1.h is available, font metrics may be affected.") | |
596 #endif | 665 #endif |
597 | 666 |
598 AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get()); | 667 AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get()); |
599 if (head.fExists && | 668 if (head.fExists && |
600 head.fSize >= sizeof(SkOTTableHead) && | 669 head.fSize >= sizeof(SkOTTableHead) && |
601 head->version == SkOTTableHead::version1) | 670 head->version == SkOTTableHead::version1) |
602 { | 671 { |
603 metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax
) / upem; | 672 metrics->fTop = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->yMax
) / upem; |
604 metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->y
Min) / upem; | 673 metrics->fBottom = -fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->y
Min) / upem; |
605 metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin
) / upem; | 674 metrics->fXMin = fTextSizeRender * (int16_t)SkEndian_SwapBE16(head->xMin
) / upem; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 mask >>= 1; | 718 mask >>= 1; |
650 } | 719 } |
651 dst[byteCount] = byte; | 720 dst[byteCount] = byte; |
652 } | 721 } |
653 src += bitCount; | 722 src += bitCount; |
654 dst += dstRB; | 723 dst += dstRB; |
655 } | 724 } |
656 } | 725 } |
657 | 726 |
658 template<bool APPLY_PREBLEND> | 727 template<bool APPLY_PREBLEND> |
| 728 static void grayscale_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph
, |
| 729 const uint8_t* table8) { |
| 730 const size_t dstRB = glyph.rowBytes(); |
| 731 const U16CPU width = glyph.fWidth; |
| 732 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); |
| 733 |
| 734 for (U16CPU y = 0; y < glyph.fHeight; y++) { |
| 735 for (U16CPU i = 0; i < width; i++) { |
| 736 U8CPU a = *(src++); |
| 737 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>(a, table8); |
| 738 } |
| 739 dst = SkTAddOffset<uint8_t>(dst, dstRB); |
| 740 } |
| 741 } |
| 742 |
| 743 template<bool APPLY_PREBLEND> |
659 static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
t uint8_t* table8) { | 744 static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
t uint8_t* table8) { |
660 const size_t dstRB = glyph.rowBytes(); | 745 const size_t dstRB = glyph.rowBytes(); |
661 const U16CPU width = glyph.fWidth; | 746 const U16CPU width = glyph.fWidth; |
662 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); | 747 uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage); |
663 | 748 |
664 for (U16CPU y = 0; y < glyph.fHeight; y++) { | 749 for (U16CPU y = 0; y < glyph.fHeight; y++) { |
665 for (U16CPU i = 0; i < width; i++) { | 750 for (U16CPU i = 0; i < width; i++) { |
666 U8CPU r = *(src++); | 751 U8CPU r = *(src++); |
667 U8CPU g = *(src++); | 752 U8CPU g = *(src++); |
668 U8CPU b = *(src++); | 753 U8CPU b = *(src++); |
669 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8); | 754 dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8); |
670 } | 755 } |
671 dst = (uint8_t*)((char*)dst + dstRB); | 756 dst = SkTAddOffset<uint8_t>(dst, dstRB); |
672 } | 757 } |
673 } | 758 } |
674 | 759 |
675 template<bool APPLY_PREBLEND, bool RGB> | 760 template<bool APPLY_PREBLEND, bool RGB> |
676 static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, | 761 static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, |
677 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { | 762 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { |
678 const size_t dstRB = glyph.rowBytes(); | 763 const size_t dstRB = glyph.rowBytes(); |
679 const U16CPU width = glyph.fWidth; | 764 const U16CPU width = glyph.fWidth; |
680 uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage); | 765 uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage); |
681 | 766 |
682 for (U16CPU y = 0; y < glyph.fHeight; y++) { | 767 for (U16CPU y = 0; y < glyph.fHeight; y++) { |
683 for (U16CPU i = 0; i < width; i++) { | 768 for (U16CPU i = 0; i < width; i++) { |
684 U8CPU r, g, b; | 769 U8CPU r, g, b; |
685 if (RGB) { | 770 if (RGB) { |
686 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 771 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
687 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 772 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
688 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 773 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
689 } else { | 774 } else { |
690 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 775 b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
691 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 776 g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
692 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 777 r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
693 } | 778 } |
694 dst[i] = SkPack888ToRGB16(r, g, b); | 779 dst[i] = SkPack888ToRGB16(r, g, b); |
695 } | 780 } |
696 dst = (uint16_t*)((char*)dst + dstRB); | 781 dst = SkTAddOffset<uint16_t>(dst, dstRB); |
697 } | 782 } |
698 } | 783 } |
699 | 784 |
700 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, | 785 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, |
701 DWRITE_RENDERING_MODE renderingMode, | 786 DWRITE_RENDERING_MODE renderingMode, |
702 DWRITE_TEXTURE_TYPE textureType) | 787 DWRITE_TEXTURE_TYPE textureType) |
703 { | 788 { |
704 int sizeNeeded = glyph.fWidth * glyph.fHeight; | 789 int sizeNeeded = glyph.fWidth * glyph.fHeight; |
705 if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) { | 790 if (DWRITE_TEXTURE_CLEARTYPE_3x1 == textureType) { |
706 sizeNeeded *= 3; | 791 sizeNeeded *= 3; |
707 } | 792 } |
708 if (sizeNeeded > fBits.count()) { | 793 if (sizeNeeded > fBits.count()) { |
709 fBits.setCount(sizeNeeded); | 794 fBits.setCount(sizeNeeded); |
710 } | 795 } |
711 | 796 |
712 // erase | 797 // erase |
713 memset(fBits.begin(), 0, sizeNeeded); | 798 memset(fBits.begin(), 0, sizeNeeded); |
714 | 799 |
715 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); | 800 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); |
(...skipping 10 matching lines...) Expand all Loading... |
726 DWRITE_GLYPH_RUN run; | 811 DWRITE_GLYPH_RUN run; |
727 run.glyphCount = 1; | 812 run.glyphCount = 1; |
728 run.glyphAdvances = &advance; | 813 run.glyphAdvances = &advance; |
729 run.fontFace = fTypeface->fDWriteFontFace.get(); | 814 run.fontFace = fTypeface->fDWriteFontFace.get(); |
730 run.fontEmSize = SkScalarToFloat(fTextSizeRender); | 815 run.fontEmSize = SkScalarToFloat(fTextSizeRender); |
731 run.bidiLevel = 0; | 816 run.bidiLevel = 0; |
732 run.glyphIndices = &index; | 817 run.glyphIndices = &index; |
733 run.isSideways = FALSE; | 818 run.isSideways = FALSE; |
734 run.glyphOffsets = &offset; | 819 run.glyphOffsets = &offset; |
735 { | 820 { |
736 | |
737 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 821 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
738 { | 822 { |
739 SkAutoExclusive l(DWriteFactoryMutex); | 823 SkAutoExclusive l(DWriteFactoryMutex); |
740 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, | 824 if (fTypeface->fFactory2) { |
741 1.0f, // pixelsPerDip, | 825 #if SK_HAS_DWRITE_2_H |
742 &fXform, | 826 HRNM(fTypeface->fFactory2->CreateGlyphRunAnalysis(&run, |
743 renderingMode, | 827 &fXform, |
744 fMeasuringMode, | 828 renderingMode, |
745 0.0f, // baselineOriginX, | 829 fMeasuringMode, |
746 0.0f, // baselineOriginY, | 830 fGridFitMode, |
747 &glyphRunAnalysis), | 831 fAntiAliasMode, |
748 "Could not create glyph run analysis."); | 832 0.0f, // baselineOriginX, |
| 833 0.0f, // baselineOriginY, |
| 834 &glyphRunAnalysis), |
| 835 "Could not create DW2 glyph run analysis."); |
| 836 #endif |
| 837 } else { |
| 838 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, |
| 839 1.0f, // pixelsPerDip, |
| 840 &fXform, |
| 841 renderingMode, |
| 842 fMeasuringMode, |
| 843 0.0f, // baselineOriginX, |
| 844 0.0f, // baselineOriginY, |
| 845 &glyphRunAnalysis), |
| 846 "Could not create glyph run analysis."); |
| 847 } |
749 } | 848 } |
750 //NOTE: this assumes that the glyph has already been measured | 849 //NOTE: this assumes that the glyph has already been measured |
751 //with an exact same glyph run analysis. | 850 //with an exact same glyph run analysis. |
752 RECT bbox; | 851 RECT bbox; |
753 bbox.left = glyph.fLeft; | 852 bbox.left = glyph.fLeft; |
754 bbox.top = glyph.fTop; | 853 bbox.top = glyph.fTop; |
755 bbox.right = glyph.fLeft + glyph.fWidth; | 854 bbox.right = glyph.fLeft + glyph.fWidth; |
756 bbox.bottom = glyph.fTop + glyph.fHeight; | 855 bbox.bottom = glyph.fTop + glyph.fHeight; |
757 { | 856 { |
758 Shared l(DWriteFactoryMutex); | 857 Shared l(DWriteFactoryMutex); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 sk_bzero(glyph.fImage, glyph.computeImageSize()); | 957 sk_bzero(glyph.fImage, glyph.computeImageSize()); |
859 return; | 958 return; |
860 } | 959 } |
861 | 960 |
862 //Copy the mask into the glyph. | 961 //Copy the mask into the glyph. |
863 const uint8_t* src = (const uint8_t*)bits; | 962 const uint8_t* src = (const uint8_t*)bits; |
864 if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { | 963 if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { |
865 bilevel_to_bw(src, glyph); | 964 bilevel_to_bw(src, glyph); |
866 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; | 965 const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format; |
867 } else if (!isLCD(fRec)) { | 966 } else if (!isLCD(fRec)) { |
868 if (fPreBlend.isApplicable()) { | 967 if (textureType == DWRITE_TEXTURE_ALIASED_1x1) { |
869 rgb_to_a8<true>(src, glyph, fPreBlend.fG); | 968 if (fPreBlend.isApplicable()) { |
| 969 grayscale_to_a8<true>(src, glyph, fPreBlend.fG); |
| 970 } else { |
| 971 grayscale_to_a8<false>(src, glyph, fPreBlend.fG); |
| 972 } |
870 } else { | 973 } else { |
871 rgb_to_a8<false>(src, glyph, fPreBlend.fG); | 974 if (fPreBlend.isApplicable()) { |
| 975 rgb_to_a8<true>(src, glyph, fPreBlend.fG); |
| 976 } else { |
| 977 rgb_to_a8<false>(src, glyph, fPreBlend.fG); |
| 978 } |
872 } | 979 } |
873 } else { | 980 } else { |
874 SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat); | 981 SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat); |
875 if (fPreBlend.isApplicable()) { | 982 if (fPreBlend.isApplicable()) { |
876 if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) { | 983 if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) { |
877 rgb_to_lcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG
, fPreBlend.fB); | 984 rgb_to_lcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG
, fPreBlend.fB); |
878 } else { | 985 } else { |
879 rgb_to_lcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG,
fPreBlend.fB); | 986 rgb_to_lcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG,
fPreBlend.fB); |
880 } | 987 } |
881 } else { | 988 } else { |
(...skipping 27 matching lines...) Expand all Loading... |
909 FALSE, //sideways | 1016 FALSE, //sideways |
910 FALSE, //rtl | 1017 FALSE, //rtl |
911 geometryToPath.get()), | 1018 geometryToPath.get()), |
912 "Could not create glyph outline."); | 1019 "Could not create glyph outline."); |
913 } | 1020 } |
914 | 1021 |
915 path->transform(fSkXform); | 1022 path->transform(fSkXform); |
916 } | 1023 } |
917 | 1024 |
918 #endif//defined(SK_BUILD_FOR_WIN32) | 1025 #endif//defined(SK_BUILD_FOR_WIN32) |
OLD | NEW |