source: webkit/trunk/Source/WebCore/platform/graphics/GraphicsContext.h

Last change on this file was 295621, checked in by Cameron McCormack, 3 years ago

Add a new DrawDecomposedGlyphs display list item to avoid repeatedly sending glyphs when using the GlyphDisplayListCache
https://bugs.webkit.org/show_bug.cgi?id=240497
<rdar://93387615>

Reviewed by Simon Fraser.

The GlyphDisplayListCache is used to record a display list for
frequently painting text content. With GPU Process DOM rendering, there
is significant overhead in sending the contents of these display lists
over IPC. The contents of these display lists don't change if the text
content in the document doesn't change, so we could greatly reduce the
overhead by treating the data inside a display list item for glyph
drawing as a remote resource.

This commit adds:

  • a new display list item, DrawDecomposedGlyphs, to represent drawing a glyph list resource
  • a new class, DecomposedGlyphs, which is the resource type
  • a new struct, PositionedGlyphs, to provide a common place for the glyph drawing fields (the vector of glyph IDs, the anchor position, etc.) to live, so that we don't have duplication between DisplayList::DrawGlyphs and DecomposedGlyphs

So that a DrawDecomposedGlyphs command can be replayed from a
GlyphDisplayListCache's in-memory display list and recorded to a
RemoteDisplayListRecorder, the GraphicsContext API gains a new
drawDecomposedGlyphs function.

A new argument to the DisplayList::RecordImpl constructor (and the
DrawGlyphsRecorder) is added to represent how to record drawText
commands:

  • DrawGlyphsMode::Normal, which records each GraphicsContext::drawText call with a single DrawText command
  • DrawGlyphsMode::DeconstructToDrawGlyphsCommands, which ensures different text layers get deconstructed into separate DrawText commands
  • DrawGlyphsMode::DeconstructToDrawDecomposedGlyphsCommands, which ensures different text layers get desconstructed into separate DrawDecomposedGlyphs commands

FontCascade::displayListForTextRun is updated to use that last value.

Additionally, GlyphDisplayListCache is extended to cache display lists
keyed off TextRun/FontCascade/etc. values. This allows sharing of the same
cached display list between different elements on the page that have the same
text content.

This sharing would not be valid if the two elements have different
values for the color property, and the text contains COLRv0 glyphs that
alternate painting of specific colors and the color fill color, since
the recording would incorrectly record a setFillBrush command
corresponding to the first element's fill color. Rather than extend the
glyph recorder to parameterize the current fill (and stroke) colors, we
detect when outlines are drawn with colors other than the context's
initial colors, and prevent sharing. This is done by checking whether
the recorded display list contains items that aren't known to be safe
for sharing.

Similarly, if the sharing would not be valid if the contains bitmap
images (like those from emoji fonts) or SVG glyphs, both of which are
captured as DrawNativeImage commands, if the text is drawn at different
scales. This is because the size of the images is dependent on the
scale. We detect and prevent reuse across different text runs if the
scale is different, by checking the recorded display list for
DrawNativeImage commands and by storing the context scale on the
GlyphDisplayListCache::Entry.

  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-color-expected.txt:
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-colr-unshared-expected.txt: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-colr-unshared.html: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-scaled-unshared-expected.txt: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-scaled-unshared.html: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-shadow-unshared-expected.txt: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-shadow-unshared.html: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-shared-expected.txt: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-shared.html: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-svg-unshared-expected.txt: Added.
  • LayoutTests/fast/text/glyph-display-lists/glyph-display-list-svg-unshared.html: Added.
  • Source/WTF/wtf/PlatformHave.h:
  • Source/WebCore/Headers.cmake:
  • Source/WebCore/Sources.txt:
  • Source/WebCore/WebCore.xcodeproj/project.pbxproj:
  • Source/WebCore/page/MemoryRelease.cpp:

(WebCore::releaseNoncriticalMemory):

  • Source/WebCore/platform/graphics/BifurcatedGraphicsContext.cpp:

(WebCore::BifurcatedGraphicsContext::drawDecomposedGlyphs):

  • Source/WebCore/platform/graphics/BifurcatedGraphicsContext.h:
  • Source/WebCore/platform/graphics/DecomposedGlyphs.cpp: Added.

(WebCore::DecomposedGlyphs::create):
(WebCore::DecomposedGlyphs::DecomposedGlyphs):
(WebCore::m_renderingResourceIdentifier):

  • Source/WebCore/platform/graphics/DecomposedGlyphs.h: Added.

(WebCore::DecomposedGlyphs::positionedGlyphs const):
(WebCore::DecomposedGlyphs::bounds const):
(WebCore::DecomposedGlyphs::addObserver):
(WebCore::DecomposedGlyphs::removeObserver):
(WebCore::DecomposedGlyphs::renderingResourceIdentifier const):

  • Source/WebCore/platform/graphics/FontCascade.cpp:

(WebCore::FontCascade::displayListForTextRun const):

  • Source/WebCore/platform/graphics/GraphicsContext.cpp:

(WebCore::GraphicsContext::drawDecomposedGlyphs):

  • Source/WebCore/platform/graphics/GraphicsContext.h:

(WebCore::GraphicsContext::drawGlyphsAndCacheResources):
(WebCore::GraphicsContext::drawGlyphsAndCacheFont): Deleted.

  • Source/WebCore/platform/graphics/NullGraphicsContext.h:
  • Source/WebCore/platform/graphics/PositionedGlyphs.cpp: Copied from Source/WebCore/platform/graphics/win/DrawGlyphsRecorderWin.cpp.

(WebCore::PositionedGlyphs::computeBounds const):

  • Source/WebCore/platform/graphics/PositionedGlyphs.h: Added.

(WebCore::PositionedGlyphs::PositionedGlyphs):
(WebCore::PositionedGlyphs::encode const):
(WebCore::PositionedGlyphs::decode):

  • Source/WebCore/platform/graphics/TextRun.cpp:

(WebCore::operator<<):

  • Source/WebCore/platform/graphics/TextRun.h:

(WebCore::TextRun::TextRun):
(WebCore::TextRun::isHashTableEmptyValue const):
(WebCore::TextRun::isHashTableDeletedValue const):
(WebCore::TextRun::isolatedCopy const):

  • Source/WebCore/platform/graphics/TextRunHash.h: Added.

(WebCore::add):
(WebCore::TextRun::operator== const):
(WebCore::TextRunHash::hash):
(WebCore::TextRunHash::equal):
(WTF::HashTraits<WebCore::TextRun>::isDeletedValue):
(WTF::HashTraits<WebCore::TextRun>::isEmptyValue):
(WTF::HashTraits<WebCore::TextRun>::constructDeletedValue):
(WTF::HashTraits<WebCore::TextRun>::emptyValue):

  • Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp:

(WebCore::GraphicsContextCairo::drawDecomposedGlyphs):

  • Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.h:
  • Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp:

(WebCore::DrawGlyphsRecorder::createInternalContext):
(WebCore::DrawGlyphsRecorder::updateCTM):
(WebCore::DrawGlyphsRecorder::recordDrawGlyphs):

  • Source/WebCore/platform/graphics/displaylists/DisplayList.cpp:

(WebCore::DisplayList::DisplayList::description const):
(WebCore::DisplayList::DisplayList::append):

  • Source/WebCore/platform/graphics/displaylists/DisplayList.h:

(WebCore::DisplayList::DisplayList::cacheDecomposedGlyphs):

  • Source/WebCore/platform/graphics/displaylists/DisplayListItemBuffer.cpp:

(WebCore::DisplayList::ItemHandle::apply):
(WebCore::DisplayList::ItemHandle::destroy):
(WebCore::DisplayList::ItemHandle::safeCopy const):

  • Source/WebCore/platform/graphics/displaylists/DisplayListItemType.cpp:

(WebCore::DisplayList::sizeOfItemInBytes):
(WebCore::DisplayList::isDrawingItem):
(WebCore::DisplayList::isInlineItem):

  • Source/WebCore/platform/graphics/displaylists/DisplayListItemType.h:
  • Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp:

(WebCore::DisplayList::DrawGlyphs::DrawGlyphs):
(WebCore::DisplayList::m_bounds):
(WebCore::DisplayList::DrawGlyphs::apply const):
(WebCore::DisplayList::DrawDecomposedGlyphs::apply const):
(WebCore::DisplayList::operator<<):
(WebCore::DisplayList::dumpItem):
(WebCore::DisplayList::dumpItemHandle):
(WebCore::DisplayList::DrawGlyphs::computeBounds): Deleted.

  • Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:

(WebCore::DisplayList::DrawGlyphs::localAnchor const):
(WebCore::DisplayList::DrawGlyphs::anchorPoint const):
(WebCore::DisplayList::DrawGlyphs::glyphs const):
(WebCore::DisplayList::DrawGlyphs::encode const):
(WebCore::DisplayList::DrawGlyphs::decode):
(WebCore::DisplayList::DrawDecomposedGlyphs::DrawDecomposedGlyphs):
(WebCore::DisplayList::DrawDecomposedGlyphs::fontIdentifier const):
(WebCore::DisplayList::DrawDecomposedGlyphs::decomposedGlyphsIdentifier const):
(WebCore::DisplayList::DrawDecomposedGlyphs::globalBounds const):
(WebCore::DisplayList::DrawDecomposedGlyphs::localBounds const):

  • Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp:

(WebCore::DisplayList::Recorder::Recorder):
(WebCore::DisplayList::Recorder::shouldDeconstructDrawGlyphs const):
(WebCore::DisplayList::Recorder::drawGlyphs):
(WebCore::DisplayList::Recorder::drawDecomposedGlyphs):
(WebCore::DisplayList::Recorder::drawGlyphsAndCacheResources):
(WebCore::DisplayList::Recorder::drawGlyphsAndCacheFont): Deleted.

  • Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h:
  • Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.cpp:

(WebCore::DisplayList::RecorderImpl::RecorderImpl):
(WebCore::DisplayList::RecorderImpl::recordDrawDecomposedGlyphs):
(WebCore::DisplayList::RecorderImpl::recordResourceUse):

  • Source/WebCore/platform/graphics/displaylists/DisplayListRecorderImpl.h:
  • Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp:

(WebCore::DisplayList::applyDrawDecomposedGlyphs):
(WebCore::DisplayList::Replayer::applyItem):
(WebCore::DisplayList::Replayer::replay):

  • Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h:
  • Source/WebCore/platform/graphics/displaylists/DisplayListResourceHeap.h:

(WebCore::DisplayList::LocalResourceHeap::add):

  • Source/WebCore/platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp:

(WebCore::DrawGlyphsRecorder::drawGlyphs):

  • Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:

(Nicosia::CairoOperationRecorder::drawDecomposedGlyphs):

  • Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.h:
  • Source/WebCore/platform/graphics/win/DrawGlyphsRecorderWin.cpp:

(WebCore::DrawGlyphsRecorder::drawGlyphs):

  • Source/WebCore/platform/text/TextDirection.h:

(WebCore::operator<<):

  • Source/WebCore/platform/text/TextFlags.cpp:

(WebCore::operator<<):

  • Source/WebCore/platform/text/TextFlags.h:

(WebCore::ExpansionBehavior::operator== const):

  • Source/WebCore/rendering/GlyphDisplayListCache.cpp: Added.

(WebCore::canShareDisplayListWithItem):
(WebCore::add):
(WebCore::GlyphDisplayListCacheKeyTranslator::hash):
(WebCore::GlyphDisplayListCacheKeyTranslator::equal):
(WebCore::GlyphDisplayListCache::singleton):
(WebCore::GlyphDisplayListCache::clear):
(WebCore::GlyphDisplayListCache::size const):
(WebCore::GlyphDisplayListCache::sizeInBytes const):
(WebCore::GlyphDisplayListCache::get):
(WebCore::GlyphDisplayListCache::getIfExists):
(WebCore::GlyphDisplayListCache::remove):
(WebCore::GlyphDisplayListCache::canShareDisplayList):
(WebCore::GlyphDisplayListCacheEntry::~GlyphDisplayListCacheEntry):

  • Source/WebCore/rendering/GlyphDisplayListCache.h:

(WebCore::GlyphDisplayListCacheEntry::create):
(WebCore::GlyphDisplayListCacheEntry::operator== const):
(WebCore::GlyphDisplayListCacheEntry::displayList):
(WebCore::GlyphDisplayListCacheEntry::GlyphDisplayListCacheEntry):
(WebCore::add):
(WebCore::GlyphDisplayListCacheEntryHash::hash):
(WebCore::GlyphDisplayListCacheEntryHash::equal):
(WebCore::GlyphDisplayListCache::get):
(WebCore::GlyphDisplayListCache::getIfExists):
(WebCore::GlyphDisplayListCache::remove):
(WebCore::GlyphDisplayListCache::singleton): Deleted.
(WebCore::GlyphDisplayListCache::clear): Deleted.
(WebCore::GlyphDisplayListCache::size const): Deleted.
(WebCore::GlyphDisplayListCache::sizeInBytes const): Deleted.

  • Source/WebCore/rendering/RenderLayerCompositor.cpp:
  • Source/WebCore/rendering/TextPainter.cpp:

(WebCore::TextPainter::clearGlyphDisplayLists): Deleted.

  • Source/WebCore/rendering/TextPainter.h:

(WebCore::TextPainter::setGlyphDisplayListIfNeeded):
(WebCore::TextPainter::removeGlyphDisplayList):
(WebCore::TextPainter::glyphDisplayListIfExists):

  • Source/WebCore/testing/Internals.cpp:

(WebCore::toDisplayListFlags):
(WebCore::Internals::displayListForElement):
(WebCore::Internals::replayDisplayListForElement):
(WebCore::Internals::cachedGlyphDisplayListsForTextNode):

  • Source/WebCore/testing/Internals.h:
  • Source/WebCore/testing/Internals.idl:
  • Source/WebKit/GPUProcess/graphics/QualifiedResourceHeap.h:

(WebKit::QualifiedResourceHeap::add):
(WebKit::QualifiedResourceHeap::getDecomposedGlyphs const):
(WebKit::QualifiedResourceHeap::removeDecomposedGlyphs):
(WebKit::QualifiedResourceHeap::checkInvariants const):

  • Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp:

(WebKit::RemoteDisplayListRecorder::drawDecomposedGlyphs):
(WebKit::RemoteDisplayListRecorder::drawDecomposedGlyphsWithQualifiedIdentifiers):

  • Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.h:
  • Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.messages.in:
  • Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp:

(WebKit::RemoteRenderingBackend::cacheFontWithQualifiedIdentifier):
(WebKit::RemoteRenderingBackend::cacheDecomposedGlyphs):
(WebKit::RemoteRenderingBackend::cacheDecomposedGlyphsWithQualifiedIdentifier):

  • Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h:
  • Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in:
  • Source/WebKit/GPUProcess/graphics/RemoteResourceCache.cpp:

(WebKit::RemoteResourceCache::cacheDecomposedGlyphs):
(WebKit::RemoteResourceCache::cachedDecomposedGlyphs const):
(WebKit::RemoteResourceCache::releaseRemoteResource):

  • Source/WebKit/GPUProcess/graphics/RemoteResourceCache.h:
  • Source/WebKit/Scripts/webkit/messages.py:
  • Source/WebKit/Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<DecomposedGlyphs>::encode):
(IPC::ArgumentCoder<DecomposedGlyphs>::decode):

  • Source/WebKit/Shared/WebCoreArgumentCoders.h:
  • Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.cpp:

(WebKit::RemoteDisplayListRecorderProxy::RemoteDisplayListRecorderProxy):
(WebKit::RemoteDisplayListRecorderProxy::recordDrawDecomposedGlyphs):
(WebKit::RemoteDisplayListRecorderProxy::recordResourceUse):

  • Source/WebKit/WebProcess/GPU/graphics/RemoteDisplayListRecorderProxy.h:
  • Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp:

(WebKit::RemoteRenderingBackendProxy::cacheDecomposedGlyphs):

  • Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h:
  • Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp:

(WebKit::RemoteResourceCacheProxy::~RemoteResourceCacheProxy):
(WebKit::RemoteResourceCacheProxy::recordDecomposedGlyphsUse):
(WebKit::RemoteResourceCacheProxy::releaseDecomposedGlyphs):
(WebKit::RemoteResourceCacheProxy::clearDecomposedGlyphsMap):
(WebKit::RemoteResourceCacheProxy::remoteResourceCacheWasDestroyed):

  • Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.h:

Canonical link: https://commits.webkit.org/251626@main

  • Property svn:eol-style set to native
File size: 22.0 KB
Line 
1/*
2 * Copyright (C) 2003-2022 Apple Inc. All rights reserved.
3 * Copyright (C) 2008-2009 Torch Mobile, Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include "DashArray.h"
30#include "DestinationColorSpace.h"
31#include "FloatRect.h"
32#include "FontCascade.h"
33#include "GraphicsContextState.h"
34#include "Image.h"
35#include "ImageOrientation.h"
36#include "ImagePaintingOptions.h"
37#include "IntRect.h"
38#include "Pattern.h"
39#include "PlatformGraphicsContext.h"
40#include "RenderingMode.h"
41#include <wtf/Function.h>
42#include <wtf/Noncopyable.h>
43#include <wtf/OptionSet.h>
44
45namespace WebCore {
46
47class AffineTransform;
48class DecomposedGlyphs;
49class Filter;
50class FilterResults;
51class FloatRoundedRect;
52class Gradient;
53class GraphicsContextPlatformPrivate;
54class ImageBuffer;
55class MediaPlayer;
56class GraphicsContextGL;
57class Path;
58class SystemImage;
59class TextRun;
60
61class GraphicsContext {
62 WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
63public:
64 WEBCORE_EXPORT GraphicsContext(const GraphicsContextState::ChangeFlags& = { }, InterpolationQuality = InterpolationQuality::Default);
65 WEBCORE_EXPORT GraphicsContext(const GraphicsContextState&);
66 WEBCORE_EXPORT virtual ~GraphicsContext();
67
68 virtual bool hasPlatformContext() const { return false; }
69 virtual PlatformGraphicsContext* platformContext() const { return nullptr; }
70
71 virtual bool paintingDisabled() const { return false; }
72 virtual bool performingPaintInvalidation() const { return false; }
73 virtual bool invalidatingControlTints() const { return false; }
74 virtual bool invalidatingImagesWithAsyncDecodes() const { return false; }
75 virtual bool detectingContentfulPaint() const { return false; }
76
77 // Context State
78
79 const SourceBrush& fillBrush() const { return m_state.fillBrush(); }
80 const Color& fillColor() const { return fillBrush().color(); }
81 Gradient* fillGradient() const { return fillBrush().gradient(); }
82 const AffineTransform& fillGradientSpaceTransform() const { return fillBrush().gradientSpaceTransform(); }
83 Pattern* fillPattern() const { return fillBrush().pattern(); }
84 void setFillBrush(const SourceBrush& brush) { m_state.setFillBrush(brush); didUpdateState(m_state); }
85 void setFillColor(const Color& color) { m_state.setFillColor(color); didUpdateState(m_state); }
86 void setFillGradient(Ref<Gradient>&& gradient, const AffineTransform& spaceTransform = { }) { m_state.setFillGradient(WTFMove(gradient), spaceTransform); didUpdateState(m_state); }
87 void setFillPattern(Ref<Pattern>&& pattern) { m_state.setFillPattern(WTFMove(pattern)); didUpdateState(m_state); }
88
89 WindRule fillRule() const { return m_state.fillRule(); }
90 void setFillRule(WindRule fillRule) { m_state.setFillRule(fillRule); didUpdateState(m_state); }
91
92 const SourceBrush& strokeBrush() const { return m_state.strokeBrush(); }
93 const Color& strokeColor() const { return strokeBrush().color(); }
94 Gradient* strokeGradient() const { return strokeBrush().gradient(); }
95 const AffineTransform& strokeGradientSpaceTransform() const { return strokeBrush().gradientSpaceTransform(); }
96 Pattern* strokePattern() const { return strokeBrush().pattern(); }
97 void setStrokeBrush(const SourceBrush& brush) { m_state.setStrokeBrush(brush); didUpdateState(m_state); }
98 void setStrokeColor(const Color& color) { m_state.setStrokeColor(color); didUpdateState(m_state); }
99 void setStrokeGradient(Ref<Gradient>&& gradient, const AffineTransform& spaceTransform = { }) { m_state.setStrokeGradient(WTFMove(gradient), spaceTransform); didUpdateState(m_state); }
100 void setStrokePattern(Ref<Pattern>&& pattern) { m_state.setStrokePattern(WTFMove(pattern)); didUpdateState(m_state); }
101
102 float strokeThickness() const { return m_state.strokeThickness(); }
103 void setStrokeThickness(float thickness) { m_state.setStrokeThickness(thickness); didUpdateState(m_state); }
104
105 StrokeStyle strokeStyle() const { return m_state.strokeStyle(); }
106 void setStrokeStyle(StrokeStyle style) { m_state.setStrokeStyle(style); didUpdateState(m_state); }
107
108 const DropShadow& dropShadow() const { return m_state.dropShadow(); }
109 FloatSize shadowOffset() const { return dropShadow().offset; }
110 float shadowBlur() const { return dropShadow().blurRadius; }
111 const Color& shadowColor() const { return dropShadow().color; }
112 void setDropShadow(const DropShadow& dropShadow) { m_state.setDropShadow(dropShadow); didUpdateState(m_state); }
113 void clearShadow() { setDropShadow({ }); }
114
115 // FIXME: Use dropShadow() and setDropShadow() instead of calling these functions.
116 WEBCORE_EXPORT bool getShadow(FloatSize&, float&, Color&) const;
117 void setShadow(const FloatSize& offset, float blurRadius, const Color& color, ShadowRadiusMode shadowRadiusMode = ShadowRadiusMode::Default) { setDropShadow({ offset, blurRadius, color, shadowRadiusMode }); }
118
119 bool hasVisibleShadow() const { return dropShadow().isVisible(); }
120 bool hasBlurredShadow() const { return dropShadow().isBlurred(); }
121 bool hasShadow() const { return dropShadow().hasOutsets(); }
122
123 CompositeMode compositeMode() const { return m_state.compositeMode(); }
124 CompositeOperator compositeOperation() const { return compositeMode().operation; }
125 BlendMode blendMode() const { return compositeMode().blendMode; }
126 void setCompositeMode(CompositeMode compositeMode) { m_state.setCompositeMode(compositeMode); didUpdateState(m_state); }
127 void setCompositeOperation(CompositeOperator operation, BlendMode blendMode = BlendMode::Normal) { setCompositeMode({ operation, blendMode }); }
128
129 float alpha() const { return m_state.alpha(); }
130 void setAlpha(float alpha) { m_state.setAlpha(alpha); didUpdateState(m_state); }
131
132 TextDrawingModeFlags textDrawingMode() const { return m_state.textDrawingMode(); }
133 void setTextDrawingMode(TextDrawingModeFlags textDrawingMode) { m_state.setTextDrawingMode(textDrawingMode); didUpdateState(m_state); }
134
135 InterpolationQuality imageInterpolationQuality() const { return m_state.imageInterpolationQuality(); }
136 void setImageInterpolationQuality(InterpolationQuality imageInterpolationQuality) { m_state.setImageInterpolationQuality(imageInterpolationQuality); didUpdateState(m_state); }
137
138 bool shouldAntialias() const { return m_state.shouldAntialias(); }
139 void setShouldAntialias(bool shouldAntialias) { m_state.setShouldAntialias(shouldAntialias); didUpdateState(m_state); }
140
141 bool shouldSmoothFonts() const { return m_state.shouldSmoothFonts(); }
142 void setShouldSmoothFonts(bool shouldSmoothFonts) { m_state.setShouldSmoothFonts(shouldSmoothFonts); didUpdateState(m_state); }
143
144 // Normally CG enables subpixel-quantization because it improves the performance of aligning glyphs.
145 // In some cases we have to disable to to ensure a high-quality output of the glyphs.
146 bool shouldSubpixelQuantizeFonts() const { return m_state.shouldSubpixelQuantizeFonts(); }
147 void setShouldSubpixelQuantizeFonts(bool shouldSubpixelQuantizeFonts) { m_state.setShouldSubpixelQuantizeFonts(shouldSubpixelQuantizeFonts); didUpdateState(m_state); }
148
149 bool shadowsIgnoreTransforms() const { return m_state.shadowsIgnoreTransforms(); }
150 void setShadowsIgnoreTransforms(bool shadowsIgnoreTransforms) { m_state.setShadowsIgnoreTransforms(shadowsIgnoreTransforms); didUpdateState(m_state); }
151
152 bool drawLuminanceMask() const { return m_state.drawLuminanceMask(); }
153 void setDrawLuminanceMask(bool drawLuminanceMask) { m_state.setDrawLuminanceMask(drawLuminanceMask); didUpdateState(m_state); }
154
155#if HAVE(OS_DARK_MODE_SUPPORT)
156 bool useDarkAppearance() const { return m_state.useDarkAppearance(); }
157 void setUseDarkAppearance(bool useDarkAppearance) { m_state.setUseDarkAppearance(useDarkAppearance); didUpdateState(m_state); }
158#endif
159
160 virtual const GraphicsContextState& state() const { return m_state; }
161 void updateState(GraphicsContextState&, const std::optional<GraphicsContextState>& lastDrawingState = std::nullopt);
162
163 // Called *after* any change to GraphicsContextState; generally used to propagate changes
164 // to the platform context's state.
165 virtual void didUpdateState(GraphicsContextState&) = 0;
166
167 WEBCORE_EXPORT virtual void save();
168 WEBCORE_EXPORT virtual void restore();
169
170 unsigned stackSize() const { return m_stack.size(); }
171
172#if USE(CG)
173 // FIXME: Should these really be public GraphicsContext methods?
174 virtual void applyStrokePattern() = 0;
175 virtual void applyFillPattern() = 0;
176
177 // FIXME: Can we make this a why instead of a what, and then have it exist cross-platform?
178 virtual void setIsCALayerContext(bool) = 0;
179 virtual bool isCALayerContext() const = 0;
180
181 // FIXME: Can this be a GraphicsContextCG constructor parameter? Or just be read off the context?
182 virtual void setIsAcceleratedContext(bool) = 0;
183#endif
184
185 virtual RenderingMode renderingMode() const { return RenderingMode::Unaccelerated; }
186
187 // Pixel Snapping
188
189 enum RoundingMode {
190 RoundAllSides,
191 RoundOriginAndDimensions
192 };
193 virtual FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides) = 0;
194 WEBCORE_EXPORT static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
195
196 // Shapes
197
198 // These draw methods will do both stroking and filling.
199 // FIXME: ...except drawRect(), which fills properly but always strokes
200 // using a 1-pixel stroke inset from the rect borders (of the correct
201 // stroke color).
202 virtual void drawRect(const FloatRect&, float borderThickness = 1) = 0;
203 virtual void drawLine(const FloatPoint&, const FloatPoint&) = 0;
204
205 virtual void drawEllipse(const FloatRect&) = 0;
206 WEBCORE_EXPORT virtual void drawRaisedEllipse(const FloatRect&, const Color& ellipseColor, const Color& shadowColor);
207
208 virtual void fillPath(const Path&) = 0;
209 virtual void strokePath(const Path&) = 0;
210 WEBCORE_EXPORT virtual void drawPath(const Path&);
211
212 virtual void fillEllipse(const FloatRect& ellipse) { fillEllipseAsPath(ellipse); }
213 virtual void strokeEllipse(const FloatRect& ellipse) { strokeEllipseAsPath(ellipse); }
214
215 virtual void fillRect(const FloatRect&) = 0;
216 virtual void fillRect(const FloatRect&, const Color&) = 0;
217 WEBCORE_EXPORT virtual void fillRect(const FloatRect&, Gradient&);
218 WEBCORE_EXPORT virtual void fillRect(const FloatRect&, const Color&, CompositeOperator, BlendMode = BlendMode::Normal);
219 virtual void fillRoundedRectImpl(const FloatRoundedRect&, const Color&) = 0;
220 WEBCORE_EXPORT virtual void fillRoundedRect(const FloatRoundedRect&, const Color&, BlendMode = BlendMode::Normal);
221 WEBCORE_EXPORT virtual void fillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect& roundedHoleRect, const Color&);
222
223 virtual void clearRect(const FloatRect&) = 0;
224
225 virtual void strokeRect(const FloatRect&, float lineWidth) = 0;
226
227 virtual void setLineCap(LineCap) = 0;
228 virtual void setLineDash(const DashArray&, float dashOffset) = 0;
229 virtual void setLineJoin(LineJoin) = 0;
230 virtual void setMiterLimit(float) = 0;
231
232 // Images, Patterns, and Media
233
234 IntSize compatibleImageBufferSize(const FloatSize&) const;
235
236 WEBCORE_EXPORT virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, float resolutionScale = 1, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMode> = std::nullopt, std::optional<RenderingMethod> = std::nullopt) const;
237
238 WEBCORE_EXPORT RefPtr<ImageBuffer> createScaledImageBuffer(const FloatSize&, const FloatSize& scale = { 1, 1 }, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMode> = std::nullopt, std::optional<RenderingMethod> = std::nullopt) const;
239 WEBCORE_EXPORT RefPtr<ImageBuffer> createScaledImageBuffer(const FloatRect&, const FloatSize& scale = { 1, 1 }, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMode> = std::nullopt, std::optional<RenderingMethod> = std::nullopt) const;
240
241 WEBCORE_EXPORT virtual RefPtr<ImageBuffer> createAlignedImageBuffer(const FloatSize&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMethod> = std::nullopt) const;
242 WEBCORE_EXPORT virtual RefPtr<ImageBuffer> createAlignedImageBuffer(const FloatRect&, const DestinationColorSpace& = DestinationColorSpace::SRGB(), std::optional<RenderingMethod> = std::nullopt) const;
243
244 virtual void drawNativeImage(NativeImage&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& = { }) = 0;
245
246 WEBCORE_EXPORT virtual void drawSystemImage(SystemImage&, const FloatRect&);
247
248 WEBCORE_EXPORT ImageDrawResult drawImage(Image&, const FloatPoint& destination, const ImagePaintingOptions& = { ImageOrientation::FromImage });
249 WEBCORE_EXPORT ImageDrawResult drawImage(Image&, const FloatRect& destination, const ImagePaintingOptions& = { ImageOrientation::FromImage });
250 WEBCORE_EXPORT virtual ImageDrawResult drawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { ImageOrientation::FromImage });
251
252 WEBCORE_EXPORT virtual ImageDrawResult drawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& = { });
253 WEBCORE_EXPORT virtual ImageDrawResult drawTiledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule, Image::TileRule, const ImagePaintingOptions& = { });
254
255 WEBCORE_EXPORT void drawImageBuffer(ImageBuffer&, const FloatPoint& destination, const ImagePaintingOptions& = { });
256 WEBCORE_EXPORT void drawImageBuffer(ImageBuffer&, const FloatRect& destination, const ImagePaintingOptions& = { });
257 WEBCORE_EXPORT virtual void drawImageBuffer(ImageBuffer&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { });
258
259 WEBCORE_EXPORT void drawConsumingImageBuffer(RefPtr<ImageBuffer>, const FloatPoint& destination, const ImagePaintingOptions& = { });
260 WEBCORE_EXPORT void drawConsumingImageBuffer(RefPtr<ImageBuffer>, const FloatRect& destination, const ImagePaintingOptions& = { });
261 WEBCORE_EXPORT virtual void drawConsumingImageBuffer(RefPtr<ImageBuffer>, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { });
262
263 WEBCORE_EXPORT virtual void drawFilteredImageBuffer(ImageBuffer* sourceImage, const FloatRect& sourceImageRect, Filter&, FilterResults&);
264
265 virtual void drawPattern(NativeImage&, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) = 0;
266 WEBCORE_EXPORT virtual void drawPattern(ImageBuffer&, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { });
267
268#if ENABLE(VIDEO)
269 WEBCORE_EXPORT virtual void paintFrameForMedia(MediaPlayer&, const FloatRect& destination);
270#endif
271
272 // Clipping
273
274 virtual void clip(const FloatRect&) = 0;
275 WEBCORE_EXPORT virtual void clipRoundedRect(const FloatRoundedRect&);
276
277 virtual void clipOut(const FloatRect&) = 0;
278 virtual void clipOut(const Path&) = 0;
279 WEBCORE_EXPORT virtual void clipOutRoundedRect(const FloatRoundedRect&);
280 virtual void clipPath(const Path&, WindRule = WindRule::EvenOdd) = 0;
281 WEBCORE_EXPORT virtual void clipToImageBuffer(ImageBuffer&, const FloatRect&);
282 WEBCORE_EXPORT virtual IntRect clipBounds() const;
283
284 // Text
285
286 WEBCORE_EXPORT virtual FloatSize drawText(const FontCascade&, const TextRun&, const FloatPoint&, unsigned from = 0, std::optional<unsigned> to = std::nullopt);
287 WEBCORE_EXPORT virtual void drawEmphasisMarks(const FontCascade&, const TextRun&, const AtomString& mark, const FloatPoint&, unsigned from = 0, std::optional<unsigned> to = std::nullopt);
288 WEBCORE_EXPORT virtual void drawBidiText(const FontCascade&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction = FontCascade::DoNotPaintIfFontNotReady);
289
290 virtual void drawGlyphsAndCacheResources(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& point, FontSmoothingMode fontSmoothingMode)
291 {
292 drawGlyphs(font, glyphs, advances, numGlyphs, point, fontSmoothingMode);
293 }
294
295 WEBCORE_EXPORT virtual void drawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned numGlyphs, const FloatPoint&, FontSmoothingMode);
296 WEBCORE_EXPORT virtual void drawDecomposedGlyphs(const Font&, const DecomposedGlyphs&);
297
298 WEBCORE_EXPORT FloatRect computeUnderlineBoundsForText(const FloatRect&, bool printing);
299 WEBCORE_EXPORT void drawLineForText(const FloatRect&, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
300 virtual void drawLinesForText(const FloatPoint&, float thickness, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke) = 0;
301 virtual void drawDotsForDocumentMarker(const FloatRect&, DocumentMarkerLineStyle) = 0;
302
303 // Transparency Layers
304
305 WEBCORE_EXPORT virtual void beginTransparencyLayer(float opacity);
306 WEBCORE_EXPORT virtual void endTransparencyLayer();
307 bool isInTransparencyLayer() const { return (m_transparencyLayerCount > 0) && supportsTransparencyLayers(); }
308
309 // Focus Rings
310
311 virtual void drawFocusRing(const Vector<FloatRect>&, float width, float offset, const Color&) = 0;
312 virtual void drawFocusRing(const Path&, float width, float offset, const Color&) = 0;
313 // FIXME: Can we hide these in the CG implementation? Or elsewhere?
314#if PLATFORM(MAC)
315 virtual void drawFocusRing(const Path&, double timeOffset, bool& needsRedraw, const Color&) = 0;
316 virtual void drawFocusRing(const Vector<FloatRect>&, double timeOffset, bool& needsRedraw, const Color&) = 0;
317#endif
318
319 // Transforms
320
321 void scale(float s) { scale({ s, s }); }
322 virtual void scale(const FloatSize&) = 0;
323 virtual void rotate(float angleInRadians) = 0;
324 void translate(const FloatSize& size) { translate(size.width(), size.height()); }
325 void translate(const FloatPoint& p) { translate(p.x(), p.y()); }
326 virtual void translate(float x, float y) = 0;
327
328 virtual void concatCTM(const AffineTransform&) = 0;
329 virtual void setCTM(const AffineTransform&) = 0;
330
331 enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
332 virtual AffineTransform getCTM(IncludeDeviceScale = PossiblyIncludeDeviceScale) const = 0;
333
334 // This function applies the device scale factor to the context, making the context capable of
335 // acting as a base-level context for a HiDPI environment.
336 virtual void applyDeviceScaleFactor(float factor) { scale(factor); }
337 WEBCORE_EXPORT FloatSize scaleFactor() const;
338 WEBCORE_EXPORT FloatSize scaleFactorForDrawing(const FloatRect& destRect, const FloatRect& srcRect) const;
339
340 // Links
341
342 virtual void setURLForRect(const URL&, const FloatRect&) { }
343
344 virtual void setDestinationForRect(const String&, const FloatRect&) { }
345 virtual void addDestinationAtPoint(const String&, const FloatPoint&) { }
346
347 virtual bool supportsInternalLinks() const { return false; }
348
349 // Contentful Paint Detection
350
351 void setContentfulPaintDetected() { m_contentfulPaintDetected = true; }
352 bool contenfulPaintDetected() const { return m_contentfulPaintDetected; }
353
354 // FIXME: Nothing in this section belongs here, and should be moved elsewhere.
355#if OS(WINDOWS)
356 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
357 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend); // The passed in HDC should be the one handed back by getWindowsContext.
358#endif
359
360#if OS(WINDOWS) && !USE(CAIRO)
361 // FIXME: This should not exist; we need a different place to
362 // put code shared between Windows CG and Windows Cairo backends.
363 virtual GraphicsContextPlatformPrivate* deprecatedPrivateContext() const { return nullptr; }
364#endif
365
366private:
367 virtual bool supportsTransparencyLayers() const { return true; }
368
369protected:
370 void fillEllipseAsPath(const FloatRect&);
371 void strokeEllipseAsPath(const FloatRect&);
372
373 FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatRect&, bool printing, Color&);
374
375 float dashedLineCornerWidthForStrokeWidth(float) const;
376 float dashedLinePatternWidthForStrokeWidth(float) const;
377 float dashedLinePatternOffsetForPatternAndStrokeWidth(float patternWidth, float strokeWidth) const;
378 Vector<FloatPoint> centerLineAndCutOffCorners(bool isVerticalLine, float cornerWidth, FloatPoint point1, FloatPoint point2) const;
379
380 GraphicsContextState m_state;
381
382private:
383 Vector<GraphicsContextState, 1> m_stack;
384
385 unsigned m_transparencyLayerCount { 0 };
386 bool m_contentfulPaintDetected { false };
387};
388
389} // namespace WebCore
390
391#include "GraphicsContextStateSaver.h"
Note: See TracBrowser for help on using the repository browser.