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

Side by Side Diff: src/ports/SkScalerContext_win_dw.cpp

Issue 2065833002: Support pixel antialising in DirectWrite. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Use the same grid fit mode no matter the rotation. Created 4 years, 4 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/ports/SkScalerContext_win_dw.h ('k') | src/ports/SkTypeface_win_dw.h » ('j') | 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 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
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
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
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
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « src/ports/SkScalerContext_win_dw.h ('k') | src/ports/SkTypeface_win_dw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698