Skip to content

Commit

Permalink
[WinCairo] Use Cairo DirectWrite font backend
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=215259

Reviewed by Don Olmstead.

cairo 1.18.0 added the dwrite font backend. Use it instead of the
legacy cairo win32 font backend.

Windows port supports color font now. However, Windows port is still
using the lagacy Uniscribe API for shaping. It should be replaced by
DirectWrite in the future.

* Source/WebCore/PlatformWin.cmake:
* Source/WebCore/platform/graphics/FontPlatformData.h:
* Source/WebCore/platform/graphics/cairo/FontCairo.cpp:
(WebCore::FontCascade::drawGlyphs):
* Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* Source/WebCore/platform/graphics/win/FontCustomPlatformDataWin.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
* Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp:
(WebCore::getDWriteGdiInterop):
(WebCore::createCairoDWriteFontFace):
(WebCore::FontPlatformData::platformDataInit):
(WebCore::FontPlatformData::familyName const):
* Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp:
(WebCore::FontPlatformData::FontPlatformData):
* Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp:
(WebCore::Font::platformInit):
* LayoutTests/platform/wincairo/TestExpectations:
* Source/cmake/OptionsWin.cmake:

Canonical link: https://commits.webkit.org/269270@main
  • Loading branch information
fujii committed Oct 12, 2023
1 parent 2c0d56a commit 0f06694
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 28 deletions.
35 changes: 14 additions & 21 deletions LayoutTests/platform/wincairo/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,7 @@ streams/readable-stream-byob-request-worker.html [ Skip ]
# image diffs off by 0.0x%
css3/unicode-bidi-isolate-aharon.html [ ImageOnlyFailure ]
fast/css/cascade/box-shadow-and-webkit-box-shadow-cascade-order.html [ ImageOnlyFailure ]
fast/css/content-counter-010.htm [ ImageOnlyFailure ]
fast/css/counters/counter-list-item.html [ ImageOnlyFailure ]
fast/css/multiple-tabs.html [ ImageOnlyFailure ]
fast/css/unexpected-word-wrapping-with-non-empty-spans.html [ ImageOnlyFailure ]
fast/css-generated-content/close-quote-negative-depth.html [ ImageOnlyFailure Pass ]
fast/css-generated-content/content-property-change.html [ ImageOnlyFailure Pass ]
Expand Down Expand Up @@ -1255,8 +1253,6 @@ webkit.org/b/159755 fast/text/emoji-gender-6.html [ Pass ]
webkit.org/b/159755 fast/text/emoji-gender-8.html [ Pass ]
webkit.org/b/159755 fast/text/emoji-gender-9.html [ Pass ]

webkit.org/b/172056 fast/text/multiglyph-characters.html [ Pass ]

webkit.org/b/199186 fonts/use-typo-metrics-1.html [ Skip ]


Expand Down Expand Up @@ -1812,7 +1808,6 @@ editing/selection/move-by-word-visually-across-object-element-2.html [ Failure ]
editing/selection/move-by-word-visually-across-object-element-3.html [ Failure ]
editing/selection/select-out-of-floated-non-editable-13.html [ Failure ]
fast/animation/request-animation-frame-throttling-lowPowerMode.html [ Timeout ]
fast/box-shadow/box-shadow-huge-area-crash.html [ ImageOnlyFailure ]
fast/box-shadow/inset-box-shadow-fractional-radius.html [ ImageOnlyFailure ]
fast/canvas/canvas-blend-image.html [ Failure ]
fast/canvas/canvas-blend-solid.html [ Failure ]
Expand Down Expand Up @@ -1911,7 +1906,6 @@ fast/text/font-collection-2.html [ ImageOnlyFailure ]
fast/text/font-collection.html [ ImageOnlyFailure ]
fast/text/font-cursive-italic-cjk.html [ ImageOnlyFailure ]
fast/text/font-kerning.html [ ImageOnlyFailure ]
fast/text/font-variant-ligatures.html [ ImageOnlyFailure ]
fast/text/font-variations-feature-detection.html [ ImageOnlyFailure ]
fast/text/hyphenate-avoid-orphaned-word.html [ Failure ]
fast/text/image-alt-text-bidi-2.html [ ImageOnlyFailure ]
Expand All @@ -1920,9 +1914,6 @@ fast/text/international/bdi-dir-default-to-auto.html [ ImageOnlyFailure ]
fast/text/international/bdi-neutral-wrapped.html [ ImageOnlyFailure ]
fast/text/international/cjk-segmentation.html [ Failure ]
fast/text/international/inline-plaintext-is-isolated.html [ ImageOnlyFailure ]
fast/text/international/kana-voiced-sound-marks-1.html [ ImageOnlyFailure ]
fast/text/international/kana-voiced-sound-marks-2.html [ ImageOnlyFailure ]
fast/text/international/spaces-combined-in-vertical-text.html [ Failure ]
fast/text/international/system-language/declarative-language.html [ Failure ]
fast/text/international/system-language/han-quotes.html [ ImageOnlyFailure ]
fast/text/international/vertical-text-glyph-test.html [ Failure ]
Expand Down Expand Up @@ -1951,13 +1942,10 @@ fast/text/multiple-codeunit-vertical-upright.html [ ImageOnlyFailure ]
fast/text/multiple-feature-properties.html [ ImageOnlyFailure ]
fast/text/pua-charactersTreatedAsSpace.html [ ImageOnlyFailure ]
fast/text/small-caps-web-font.html [ ImageOnlyFailure ]
fast/text/small-line-height.html [ ImageOnlyFailure ]
fast/text/soft-hyphen-as-first-breaking-opportunity.html [ ImageOnlyFailure ]
fast/text/svg-font-face-with-kerning.html [ Failure ]
fast/text/synthetic-bold-transformed.html [ ImageOnlyFailure ]
fast/text/system-font-fallback-emoji.html [ Failure ]
fast/text/system-font-japanese-synthetic-italic.html [ ImageOnlyFailure ]
fast/text/system-font-weight-italic.html [ Failure ]
fast/text/system-font-weight.html [ Failure ]
fast/text/text-transform-turkish-and-azeri.html [ ImageOnlyFailure ]
fast/text/trak-optimizeLegibility.html [ ImageOnlyFailure ]
Expand Down Expand Up @@ -2017,15 +2005,13 @@ fast/gradients/alpha-premultiplied-representable-by-unpremultiplied.html [ Image
fast/gradients/alpha-premultiplied.html [ ImageOnlyFailure ]
fast/gradients/conic-gradient-alpha-unpremultiplied.html [ ImageOnlyFailure ]

fast/text/kerning-with-TextLayout.html [ ImageOnlyFailure ]
fast/js-promise/js-promise-invalid-context-access.html [ Failure ]

# Not applicable.
webgl/webgl-via-metal-flag-on.html [ Skip ]
webgl/webgl-via-metal-flag-off.html [ Skip ]
webgl/webgl-backend-type.html [ Skip ]

fast/text/synthetic-bold-percentage-word-spacing.html [ ImageOnlyFailure ]
fast/text/text-overflow-over-64k.html [ ImageOnlyFailure ]

webgl/lose-context-after-context-lost.html [ Failure ]
Expand All @@ -2036,7 +2022,6 @@ webgl/multiple-context-losses.html [ Failure ]
fast/css3-text/css3-text-decoration/text-decoration-dashed.html [ ImageOnlyFailure ]
fast/css3-text/css3-text-decoration/text-decoration-dotted-dashed.html [ ImageOnlyFailure ]
fast/css3-text/css3-text-decoration/text-decoration-dotted.html [ ImageOnlyFailure ]
fast/css3-text/css3-text-decoration/text-decoration-skip/text-decoration-skip-ink.html [ ImageOnlyFailure ]
fast/css3-text/css3-text-decoration/text-underline-style.html [ ImageOnlyFailure ]
fast/css3-text/font-synthesis.html [ ImageOnlyFailure ]

Expand Down Expand Up @@ -2334,15 +2319,13 @@ css3/filters/filtered-compositing-descendant.html [ Skip ]

compositing/animation/repaint-after-clearing-shared-backing.html [ ImageOnlyFailure ]
compositing/background-color/background-color-change-to-text.html [ ImageOnlyFailure ]
compositing/contents-scale/hidpi-compositing-layer-positioned-on-scaled-context.html [ ImageOnlyFailure ]
compositing/geometry/clipped-out-perspective.html [ ImageOnlyFailure ]
compositing/geometry/fixed-position-composited-page-scale-smaller-than-viewport.html [ ImageOnlyFailure ]
compositing/hidpi-subpixel-transform-origin.html [ ImageOnlyFailure ]
compositing/hidpi-transform-with-render-layer-on-fractional-pixel-value.html [ ImageOnlyFailure ]
compositing/layer-creation/deep-tree.html [ ImageOnlyFailure ]
compositing/text-on-scaled-layer.html [ ImageOnlyFailure ]
compositing/text-on-scaled-surface.html [ ImageOnlyFailure ]
compositing/child-layer-with-subpixel-gap-needs-repaint-when-parent-moves.html [ ImageOnlyFailure ]
compositing/clipping/cached-cliprect-with-compositing-boundary.html [ ImageOnlyFailure ]
compositing/filters/opacity-change-on-filtered-paints-into-ancestor.html [ ImageOnlyFailure ]
compositing/transforms/perspective-with-scrolling.html [ ImageOnlyFailure ]
Expand Down Expand Up @@ -2492,7 +2475,6 @@ fast/text/backslash-to-yen-sign.html [ Pass Failure ]
fast/text/all-small-caps-whitespace.html [ ImageOnlyFailure ]
fast/text/isolate-ignore.html [ ImageOnlyFailure ]
fast/text/multiple-renderers-with-hypen-on-boundary.html [ ImageOnlyFailure ]
fast/text/soft-hyphen-min-preferred-width.html [ ImageOnlyFailure ]
fast/text/whitespace/inline-whitespace-wrapping-8.html [ ImageOnlyFailure ]

# Depends on the system fonts
Expand All @@ -2519,8 +2501,6 @@ webkit.org/b/230413 fast/canvas/canvas-drawImage-detached-leak.html [ Pass Failu
# Doesn't support variable fonts
fast/text/variations [ Skip ]

fast/text/bidi-with-non-preserved-tab.html [ ImageOnlyFailure ]

webgl/2.0.0/conformance/context/context-eviction-with-garbage-collection.html [ Skip ] # Crash Timeout only on Buildbot

webkit.org/b/208022 http/tests/history/back-to-post.py [ Pass Failure Timeout ]
Expand Down Expand Up @@ -2575,7 +2555,6 @@ fast/reflections/reflection-masks-opacity.html [ Failure ]
fast/reflections/reflection-masks.html [ Failure ]
fast/text/ja-sans-serif.html [ ImageOnlyFailure ]
fast/text/simple-line-hyphens-with-word-letter-spacing.html [ ImageOnlyFailure ]
fast/text/softHyphen.html [ ImageOnlyFailure ]
fast/text/synthetic-oblique.html [ ImageOnlyFailure ]

webkit.org/b/245080 fast/text/whitespace/nowrap-clear-float.html [ Skip ] # Skip a failing dump render tree test
Expand All @@ -2590,3 +2569,17 @@ webkit.org/b/133151 js/cached-window-properties.html [ Skip ] # Slow
# Regressed by 269016@main
fast/css3-text/css3-text-decoration/text-decoration-thickness.html [ ImageOnlyFailure ]
fast/forms/listbox-zero-item-height.html [ Failure ]

fast/css/unicode-escape-in-8bit-string.html [ ImageOnlyFailure ]
fast/css/word-spacing-characters.html [ ImageOnlyFailure ]
fast/text/complex-first-glyph-with-initial-advance.html [ ImageOnlyFailure ]
fast/text/fitzpatrick-combination.html [ ImageOnlyFailure ]
fast/text/font-face-fall-off-end.html [ ImageOnlyFailure ]
fast/text/ipa-tone-letters.html [ Failure ]
fast/text/newline-width.html [ ImageOnlyFailure ]
fast/text/otsvg-spacing.html [ ImageOnlyFailure ]
fast/text/ruby-justify-tatechuyoko.html [ ImageOnlyFailure ]
fast/text/simple-line-layout-fallback-space-glyph.html [ ImageOnlyFailure ]
fast/text/simple-line-layout-line-box-contain-glyphs.html [ ImageOnlyFailure ]
fast/text/tab-stops-with-offset-from-parent.html [ ImageOnlyFailure ]
fast/text/word-break-keep-all-with-zero-width-space.html [ ImageOnlyFailure ]
1 change: 1 addition & 0 deletions Source/WebCore/PlatformWin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ if (ENABLE_VIDEO AND USE_MEDIA_FOUNDATION)
target_link_libraries(MediaFoundation INTERFACE
d3d9
delayimp
dwrite
dxva2
evr
mf
Expand Down
11 changes: 9 additions & 2 deletions Source/WebCore/platform/graphics/cairo/FontCairo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,18 @@ void FontCascade::drawGlyphs(GraphicsContext& context, const Font& font, const G
return;

auto xOffset = point.x();
Vector<cairo_glyph_t> cairoGlyphs(numGlyphs);
Vector<cairo_glyph_t> cairoGlyphs;
cairoGlyphs.reserveInitialCapacity(numGlyphs);
{
auto yOffset = point.y();
for (size_t i = 0; i < numGlyphs; ++i) {
cairoGlyphs[i] = { glyphs[i], xOffset, yOffset };
bool append = true;
#if PLATFORM(WIN)
// GlyphBuffer::makeGlyphInvisible expects 0xFFFF glyph is invisible. However, DirectWrite shows a blank square for it.
append = glyphs[i] != 0xFFFF;
#endif
if (append)
cairoGlyphs.uncheckedAppend({ glyphs[i], xOffset, yOffset });
xOffset += advances[i].width();
yOffset += advances[i].height();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

namespace WebCore {

cairo_font_face_t* createCairoDWriteFontFace(HFONT);

FontCustomPlatformData::FontCustomPlatformData(const String& name, FontPlatformData::CreationData&& creationData)
: name(name)
, creationData(WTFMove(creationData))
Expand Down Expand Up @@ -67,7 +69,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription&

auto hfont = adoptGDIObject(::CreateFontIndirect(&logFont));

cairo_font_face_t* fontFace = cairo_win32_font_face_create_for_hfont(hfont.get());
cairo_font_face_t* fontFace = createCairoDWriteFontFace(hfont.get());

FontPlatformData fontPlatformData(WTFMove(hfont), fontFace, size, bold, italic, this);

Expand Down
47 changes: 44 additions & 3 deletions Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,60 @@

#include "HWndDC.h"
#include "SharedBuffer.h"
#include <cairo-dwrite.h>
#include <wtf/HashMap.h>
#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>

#include <cairo-win32.h>

namespace WebCore {

static IDWriteGdiInterop* getDWriteGdiInterop()
{
static COMPtr<IDWriteGdiInterop> gdiInterop;
if (gdiInterop)
return gdiInterop.get();
COMPtr<IDWriteFactory> factory;
HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&factory));
RELEASE_ASSERT(SUCCEEDED(hr));
hr = factory->GetGdiInterop(&gdiInterop);
RELEASE_ASSERT(SUCCEEDED(hr));
return gdiInterop.get();
}

cairo_font_face_t*
createCairoDWriteFontFace(HFONT font)
{
IDWriteGdiInterop* gdiInterop = getDWriteGdiInterop();

bool retry = false;
GDIObject<HFONT> retryFont;
COMPtr<IDWriteFontFace> dwFace;
HWndDC hdc(nullptr);
while (font) {
HGDIOBJ oldFont = SelectObject(hdc, font);
HRESULT hr = gdiInterop->CreateFontFaceFromHdc(hdc, &dwFace);
SelectObject(hdc, oldFont);
if (SUCCEEDED(hr))
break;
if (retry)
break;
// CreateFontFaceFromHdc may fail if the font size is too large. Retry it by creating a smaller font.
LOGFONT logfont;
GetObject(font, sizeof(logfont), &logfont);
logfont.lfHeight = -32;
retryFont = adoptGDIObject(CreateFontIndirect(&logfont));
font = retryFont.get();
retry = true;
}
RELEASE_ASSERT(dwFace);
return cairo_dwrite_font_face_create_for_dwrite_fontface(dwFace.get());
}

void FontPlatformData::platformDataInit(HFONT font, float size, WCHAR* faceName)
{
cairo_font_face_t* fontFace = cairo_win32_font_face_create_for_hfont(font);
cairo_font_face_t* fontFace = createCairoDWriteFontFace(font);

cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
Expand Down
2 changes: 1 addition & 1 deletion Source/cmake/OptionsWin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")

set(CMAKE_DISABLE_PRECOMPILE_HEADERS OFF)

find_package(Cairo 1.15.12 REQUIRED)
find_package(Cairo 1.18.0 REQUIRED)
find_package(CURL 7.87.0 REQUIRED)
find_package(ICU 61.2 REQUIRED COMPONENTS data i18n uc)
find_package(JPEG 1.5.2 REQUIRED)
Expand Down

0 comments on commit 0f06694

Please sign in to comment.