Diff
Modified: trunk/LayoutTests/ChangeLog (258491 => 258492)
--- trunk/LayoutTests/ChangeLog 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/ChangeLog 2020-03-16 12:41:52 UTC (rev 258492)
@@ -1,3 +1,21 @@
+2020-03-16 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [Cairo][SVG] marker-mid isn't shown on a joint of rectilinearly connected line-to path segments
+ https://bugs.webkit.org/show_bug.cgi?id=113849
+
+ Reviewed by Adrian Perez de Castro.
+
+ Remove svg/custom/local-url-reference-marker.html from expectations and rebaseline other tests.
+
+ * platform/gtk/TestExpectations:
+ * platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-01-b-manual-expected.txt:
+ * platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-02-b-manual-expected.txt:
+ * platform/gtk/imported/w3c/web-platform-tests/svg/painting/marker-008-expected.txt:
+ * platform/gtk/imported/w3c/web-platform-tests/svg/text/reftests/textpath-shape-001-expected.txt:
+ * platform/gtk/svg/text/text-path-01-b-expected.png:
+ * platform/gtk/svg/text/text-path-01-b-expected.txt:
+ * platform/wpe/TestExpectations:
+
2020-03-16 Nikolas Zimmermann <nzimmerm...@igalia.com>
[Gtk] Update pixel test baseline in svg/ subdirectory
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2020-03-16 12:41:52 UTC (rev 258492)
@@ -3604,8 +3604,6 @@
webkit.org/b/107825 media/nodesFromRect-shadowContent.html [ Failure Crash Timeout ]
webkit.org/b/107825 media/video-controls-fullscreen-volume.html [ Failure Crash ]
-webkit.org/b/113849 svg/custom/local-url-reference-marker.html [ ImageOnlyFailure ]
-
# Test marked in TestExpectations as failing on non-retina displays, passing on GTK port
webkit.org/b/129113 fast/multicol/newmulticol/clipping.html [ Pass ]
Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-01-b-manual-expected.txt (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-01-b-manual-expected.txt 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-01-b-manual-expected.txt 2020-03-16 12:41:52 UTC (rev 258492)
@@ -18,7 +18,7 @@
chunk 1 text run 2 at (211.37,63.08) startOffset 1 endOffset 2 width 13.69: "e"
chunk 1 text run 3 at (220.27,49.99) startOffset 2 endOffset 3 width 18.00: "x"
chunk 1 text run 4 at (229.72,39.54) startOffset 3 endOffset 4 width 10.20: "t"
- chunk 1 text run 5 at (237.20,33.54) startOffset 4 endOffset 5 width 9.00: " "
+ chunk 1 text run 5 at (237.20,33.53) startOffset 4 endOffset 5 width 9.00: " "
chunk 1 text run 6 at (249.38,27.89) startOffset 5 endOffset 6 width 18.00: "o"
chunk 1 text run 7 at (267.06,29.00) startOffset 6 endOffset 7 width 18.00: "n"
chunk 1 text run 8 at (278.59,35.91) startOffset 7 endOffset 8 width 9.00: " "
@@ -45,7 +45,7 @@
RenderSVGInlineText {#text} at (45,0) size 156x112
chunk 1 text run 1 at (64.17,96.02) startOffset 0 endOffset 1 width 10.20: "t"
chunk 1 text run 2 at (71.65,90.02) startOffset 1 endOffset 2 width 9.00: " "
- chunk 1 text run 3 at (83.84,84.39) startOffset 2 endOffset 3 width 18.00: "o"
+ chunk 1 text run 3 at (83.85,84.39) startOffset 2 endOffset 3 width 18.00: "o"
chunk 1 text run 4 at (101.52,85.48) startOffset 3 endOffset 4 width 18.00: "n"
chunk 1 text run 5 at (113.05,92.40) startOffset 4 endOffset 5 width 9.00: " "
chunk 1 text run 6 at (122.09,101.16) startOffset 5 endOffset 6 width 16.20: "a"
Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-02-b-manual-expected.txt (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-02-b-manual-expected.txt 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/import/text-path-02-b-manual-expected.txt 2020-03-16 12:41:52 UTC (rev 258492)
@@ -15,7 +15,7 @@
RenderSVGTSpan {tspan} at (0,0) size 208x124
RenderSVGInlineText {#text} at (0,0) size 208x124
chunk 1 text run 1 at (199.12,88.96) startOffset 16 endOffset 17 width 25.80: "N"
- chunk 1 text run 2 at (208.45,68.19) startOffset 17 endOffset 18 width 19.80: "e"
+ chunk 1 text run 2 at (208.44,68.18) startOffset 17 endOffset 18 width 19.80: "e"
chunk 1 text run 3 at (218.99,51.66) startOffset 18 endOffset 19 width 19.44: "g"
chunk 1 text run 4 at (232.27,37.27) startOffset 19 endOffset 20 width 19.80: "a"
chunk 1 text run 5 at (244.77,29.42) startOffset 20 endOffset 21 width 9.84: "t"
@@ -66,13 +66,13 @@
chunk 1 text run 4 at (286.01,42.80) startOffset 3 endOffset 4 width 7.80: "i"
chunk 1 text run 5 at (291.95,49.56) startOffset 4 endOffset 5 width 10.20: "t"
chunk 1 text run 6 at (297.50,56.64) startOffset 5 endOffset 6 width 7.80: "i"
- chunk 1 text run 7 at (305.18,67.01) startOffset 6 endOffset 7 width 18.00: "v"
+ chunk 1 text run 7 at (305.18,67.00) startOffset 6 endOffset 7 width 18.00: "v"
chunk 1 text run 8 at (317.13,81.15) startOffset 7 endOffset 8 width 19.08: "e"
chunk 1 text run 9 at (328.39,90.49) startOffset 8 endOffset 9 width 10.20: " "
chunk 1 text run 10 at (341.33,98.03) startOffset 9 endOffset 10 width 19.80: "o"
chunk 1 text run 11 at (355.23,103.11) startOffset 10 endOffset 11 width 9.84: "f"
chunk 1 text run 12 at (363.89,104.73) startOffset 11 endOffset 12 width 7.80: "f"
- chunk 1 text run 13 at (376.37,104.23) startOffset 12 endOffset 13 width 17.28: "s"
+ chunk 1 text run 13 at (376.37,104.22) startOffset 12 endOffset 13 width 17.28: "s"
chunk 1 text run 14 at (392.89,96.17) startOffset 13 endOffset 14 width 19.80: "e"
chunk 1 text run 15 at (404.03,86.40) startOffset 14 endOffset 15 width 9.84: "t"
chunk 1 text run 16 at (411.43,79.65) startOffset 15 endOffset 16 width 10.20: " "
@@ -97,7 +97,7 @@
chunk 1 text run 12 at (198.36,161.23) startOffset 11 endOffset 12 width 7.80: "f"
chunk 1 text run 13 at (210.84,160.73) startOffset 12 endOffset 13 width 17.28: "s"
chunk 1 text run 14 at (227.36,152.66) startOffset 13 endOffset 14 width 19.80: "e"
- chunk 1 text run 15 at (238.49,142.90) startOffset 14 endOffset 15 width 9.84: "t"
+ chunk 1 text run 15 at (238.49,142.89) startOffset 14 endOffset 15 width 9.84: "t"
chunk 1 text run 16 at (245.90,136.15) startOffset 15 endOffset 16 width 10.20: " "
RenderSVGInlineText {#text} at (0,0) size 0x0
RenderSVGContainer {g} at (16,518) size 380x60
Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/painting/marker-008-expected.txt (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/painting/marker-008-expected.txt 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/painting/marker-008-expected.txt 2020-03-16 12:41:52 UTC (rev 258492)
@@ -14,6 +14,6 @@
RenderSVGPath {polygon} at (200,149) size 100x56 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [end marker=markerTest] [points="250 150 200 150"]
RenderSVGPath {polyline} at (150,199) size 150x56 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [end marker=markerTest] [points="150 200 200 200 250 200"]
RenderSVGPath {line} at (300,49) size 100x2 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [x1=300.00] [y1=50.00] [x2=400.00] [y2=50.00]
- RenderSVGPath {path} at (300,99) size 100x2 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [data="" 300 100 L 350 100 L 400 100"]
+ RenderSVGPath {path} at (300,99) size 100x56 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [data="" 300 100 L 350 100 L 400 100"]
RenderSVGPath {polygon} at (300,149) size 100x56 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [points="300 150 350 150"]
- RenderSVGPath {polyline} at (300,199) size 100x2 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [points="300 200 350 200 400 200"]
+ RenderSVGPath {polyline} at (300,199) size 100x56 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#000000]}] [middle marker=markerTest] [points="300 200 350 200 400 200"]
Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/text/reftests/textpath-shape-001-expected.txt (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/text/reftests/textpath-shape-001-expected.txt 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/svg/text/reftests/textpath-shape-001-expected.txt 2020-03-16 12:41:52 UTC (rev 258492)
@@ -32,7 +32,7 @@
chunk 1 text run 18 at (190.00,226.78) startOffset 17 endOffset 18 width 4.80: " "
chunk 1 text run 19 at (189.67,233.66) startOffset 18 endOffset 19 width 9.00: "s"
chunk 1 text run 20 at (187.42,239.83) startOffset 19 endOffset 20 width 4.20: "i"
- chunk 1 text run 21 at (184.79,243.47) startOffset 20 endOffset 21 width 4.80: "t"
+ chunk 1 text run 21 at (184.78,243.47) startOffset 20 endOffset 21 width 4.80: "t"
chunk 1 text run 22 at (181.16,246.60) startOffset 21 endOffset 22 width 4.80: " "
chunk 1 text run 23 at (174.60,249.47) startOffset 22 endOffset 23 width 9.60: "a"
chunk 1 text run 24 at (162.64,250.00) startOffset 23 endOffset 24 width 14.40: "m"
@@ -42,7 +42,7 @@
chunk 1 text run 28 at (133.84,250.00) startOffset 27 endOffset 28 width 4.80: " "
chunk 1 text run 29 at (126.94,250.00) startOffset 28 endOffset 29 width 9.00: "c"
chunk 1 text run 30 at (117.64,250.00) startOffset 29 endOffset 30 width 9.60: "o"
- chunk 1 text run 31 at (108.05,249.91) startOffset 30 endOffset 31 width 9.60: "n"
+ chunk 1 text run 31 at (108.04,249.91) startOffset 30 endOffset 31 width 9.60: "n"
chunk 1 text run 32 at (99.33,246.92) startOffset 31 endOffset 32 width 9.00: "s"
chunk 1 text run 33 at (92.87,240.34) startOffset 32 endOffset 33 width 9.60: "e"
chunk 1 text run 34 at (90.06,231.56) startOffset 33 endOffset 34 width 9.00: "c"
@@ -57,7 +57,7 @@
chunk 1 text run 43 at (90.49,165.60) startOffset 42 endOffset 43 width 4.20: "i"
chunk 1 text run 44 at (93.29,159.01) startOffset 43 endOffset 44 width 10.20: "p"
chunk 1 text run 45 at (98.23,153.83) startOffset 44 endOffset 45 width 4.20: "i"
- chunk 1 text run 46 at (104.10,150.88) startOffset 45 endOffset 46 width 9.00: "s"
+ chunk 1 text run 46 at (104.11,150.88) startOffset 45 endOffset 46 width 9.00: "s"
RenderSVGInlineText {#text} at (0,0) size 0x0
RenderSVGContainer {use} at (482,249) size 169x169
RenderSVGEllipse {circle} at (482,249) size 169x169 [stroke={[type=SOLID] [color=#ADD8E6]}] [cx=340.00] [cy=200.00] [r=50.00]
Modified: trunk/LayoutTests/platform/gtk/svg/text/text-path-01-b-expected.png
(Binary files differ)
Modified: trunk/LayoutTests/platform/gtk/svg/text/text-path-01-b-expected.txt (258491 => 258492)
--- trunk/LayoutTests/platform/gtk/svg/text/text-path-01-b-expected.txt 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/gtk/svg/text/text-path-01-b-expected.txt 2020-03-16 12:41:52 UTC (rev 258492)
@@ -17,7 +17,7 @@
chunk 1 text run 2 at (211.37,63.08) startOffset 1 endOffset 2 width 13.69: "e"
chunk 1 text run 3 at (220.27,49.99) startOffset 2 endOffset 3 width 18.00: "x"
chunk 1 text run 4 at (229.72,39.54) startOffset 3 endOffset 4 width 10.20: "t"
- chunk 1 text run 5 at (237.20,33.54) startOffset 4 endOffset 5 width 9.00: " "
+ chunk 1 text run 5 at (237.20,33.53) startOffset 4 endOffset 5 width 9.00: " "
chunk 1 text run 6 at (249.38,27.89) startOffset 5 endOffset 6 width 18.00: "o"
chunk 1 text run 7 at (267.06,29.00) startOffset 6 endOffset 7 width 18.00: "n"
chunk 1 text run 8 at (278.59,35.91) startOffset 7 endOffset 8 width 9.00: " "
@@ -43,7 +43,7 @@
RenderSVGInlineText {#text} at (45,0) size 156x112
chunk 1 text run 1 at (64.17,96.02) startOffset 0 endOffset 1 width 10.20: "t"
chunk 1 text run 2 at (71.65,90.02) startOffset 1 endOffset 2 width 9.00: " "
- chunk 1 text run 3 at (83.84,84.39) startOffset 2 endOffset 3 width 18.00: "o"
+ chunk 1 text run 3 at (83.85,84.39) startOffset 2 endOffset 3 width 18.00: "o"
chunk 1 text run 4 at (101.52,85.48) startOffset 3 endOffset 4 width 18.00: "n"
chunk 1 text run 5 at (113.05,92.40) startOffset 4 endOffset 5 width 9.00: " "
chunk 1 text run 6 at (122.09,101.16) startOffset 5 endOffset 6 width 16.20: "a"
Modified: trunk/LayoutTests/platform/wpe/TestExpectations (258491 => 258492)
--- trunk/LayoutTests/platform/wpe/TestExpectations 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/LayoutTests/platform/wpe/TestExpectations 2020-03-16 12:41:52 UTC (rev 258492)
@@ -1948,7 +1948,6 @@
webkit.org/b/163831 svg/custom/acid3-test-77.html [ Failure ]
webkit.org/b/134758 svg/custom/composited-svg-with-opacity.html [ ImageOnlyFailure Pass ]
webkit.org/b/131347 svg/custom/hidpi-masking-clipping.svg [ Failure ImageOnlyFailure Timeout ]
-webkit.org/b/113849 svg/custom/local-url-reference-marker.html [ ImageOnlyFailure ]
webkit.org/b/160137 svg/custom/non-scaling-stroke.svg [ Failure Pass ]
webkit.org/b/160137 svg/custom/non-scaling-stroke-update.svg [ ImageOnlyFailure Pass ]
webkit.org/b/112228 svg/custom/resources-css-scaled.html [ ImageOnlyFailure ]
Modified: trunk/Source/WebCore/ChangeLog (258491 => 258492)
--- trunk/Source/WebCore/ChangeLog 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/Source/WebCore/ChangeLog 2020-03-16 12:41:52 UTC (rev 258492)
@@ -1,3 +1,52 @@
+2020-03-16 Hurnjoo Lee <hurnjoo....@samsung.com>, Fujii Hironori <hironori.fu...@sony.com>, Carlos Garcia Campos <cgar...@igalia.com>
+
+ [Cairo][SVG] marker-mid isn't shown on a joint of rectilinearly connected line-to path segments
+ https://bugs.webkit.org/show_bug.cgi?id=113849
+
+ Reviewed by Adrian Perez de Castro.
+
+ Marker-mid of svg is not displayed because path elements that added to
+ cairo backend are optimized. If the new line_to has same slope with
+ the previous path element, then the path element is joined to previous
+ path element.
+
+ Example:
+
+ added path elements : moveto(-5,-2), lineto(0,-2), lineto(5,-2)
+ cairo_path_data : moveto(-5,-2), lineto(5, -2)
+
+ This patch stores all of path informations separately in order to avoid
+ this problem. When generating positions of markers, we use stored path
+ informations instead of cairo_path_data.
+
+ When a new operation can't be directly stored in an ElementPath, we fallback to use cairo_path_data() in
+ Path::apply().
+
+ * platform/graphics/Path.h: Add new constructor that receives a cairo context, make ensureCairoPath() private
+ and add m_elements member.
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::Font::platformPathForGlyph const): Create a cairo context for the path and use the new constructor
+ that receives a RefPtr<cairo_t>&&.
+ * platform/graphics/cairo/PathCairo.cpp:
+ (WebCore::Path::Path): Initialize m_elements to an empty vector when created without a cairo context.
+ (WebCore::Path::operator=): Also copy m_elements.
+ (WebCore::Path::clear): Initialize m_elements to an empty vector.
+ (WebCore::Path::translate): Apply the translate to elements in m_elements.
+ (WebCore::Path::appendElement): Helper to add an operation to m_elements.
+ (WebCore::Path::moveToSlowCase): Call appendElement() if m_elements is not nullopt.
+ (WebCore::Path::addLineToSlowCase): Ditto.
+ (WebCore::Path::addRect): Ditto.
+ (WebCore::Path::addQuadCurveToSlowCase): Ditto.
+ (WebCore::Path::addBezierCurveToSlowCase): Ditto.
+ (WebCore::Path::addArcSlowCase): Set m_elements to nullopt.
+ (WebCore::Path::addArcTo): Ditto.
+ (WebCore::Path::addEllipse): Ditto.
+ (WebCore::Path::addPath): Ditto.
+ (WebCore::Path::closeSubpath): Call appendElement() if m_elements is not nullopt.
+ (WebCore::Path::applySlowCase const): Use elements from m_elements if it's not nullopt, otherwise fallback to
+ use cairo_path_data.
+ (WebCore::Path::transform): Apply the transform to elements in m_elements.
+
2020-03-16 Rob Buis <rb...@igalia.com>
Remove addHTTPOriginIfNeeded calls
Modified: trunk/Source/WebCore/platform/graphics/Path.h (258491 => 258492)
--- trunk/Source/WebCore/platform/graphics/Path.h 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/Source/WebCore/platform/graphics/Path.h 2020-03-16 12:41:52 UTC (rev 258492)
@@ -122,6 +122,9 @@
#if USE(CG)
Path(RetainPtr<CGMutablePathRef>&&);
#endif
+#if USE(CAIRO)
+ explicit Path(RefPtr<cairo_t>&&);
+#endif
WEBCORE_EXPORT ~Path();
WEBCORE_EXPORT Path(const Path&);
@@ -192,10 +195,8 @@
PlatformPathPtr platformPath() const { return m_path; }
#endif
+#if !USE(CAIRO)
// ensurePlatformPath() will allocate a PlatformPath if it has not yet been and will never return null.
-#if USE(CAIRO)
- cairo_t* ensureCairoPath();
-#else
WEBCORE_EXPORT PlatformPathPtr ensurePlatformPath();
#endif
@@ -257,6 +258,11 @@
#endif
#if USE(CAIRO)
+ cairo_t* ensureCairoPath();
+ void appendElement(PathElement::Type, Vector<FloatPoint, 3>&&);
+#endif
+
+#if USE(CAIRO)
RefPtr<cairo_t> m_path;
#else
mutable PlatformPathStorageType m_path;
@@ -274,6 +280,9 @@
#if USE(CG)
mutable bool m_copyPathBeforeMutation { false };
#endif
+#if USE(CAIRO)
+ Optional<Vector<PathElement>> m_elements;
+#endif
};
WTF::TextStream& operator<<(WTF::TextStream&, const Path&);
Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp (258491 => 258492)
--- trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2020-03-16 12:41:52 UTC (rev 258492)
@@ -43,6 +43,7 @@
#include "ImageBuffer.h"
#include "Pattern.h"
#include "PlatformContextCairo.h"
+#include "RefPtrCairo.h"
#include "ShadowBlur.h"
namespace WebCore {
@@ -81,19 +82,18 @@
Path Font::platformPathForGlyph(Glyph glyph) const
{
- Path path;
- cairo_t* cr = path.ensureCairoPath();
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(adoptRef(cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1)).get()));
cairo_glyph_t cairoGlyph = { glyph, 0, 0 };
- cairo_set_scaled_font(cr, platformData().scaledFont());
- cairo_glyph_path(cr, &cairoGlyph, 1);
+ cairo_set_scaled_font(cr.get(), platformData().scaledFont());
+ cairo_glyph_path(cr.get(), &cairoGlyph, 1);
float syntheticBoldOffset = this->syntheticBoldOffset();
if (syntheticBoldOffset) {
- cairo_translate(cr, syntheticBoldOffset, 0);
- cairo_glyph_path(cr, &cairoGlyph, 1);
+ cairo_translate(cr.get(), syntheticBoldOffset, 0);
+ cairo_glyph_path(cr.get(), &cairoGlyph, 1);
}
- return path;
+ return Path(WTFMove(cr));
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/cairo/PathCairo.cpp (258491 => 258492)
--- trunk/Source/WebCore/platform/graphics/cairo/PathCairo.cpp 2020-03-16 12:17:06 UTC (rev 258491)
+++ trunk/Source/WebCore/platform/graphics/cairo/PathCairo.cpp 2020-03-16 12:41:52 UTC (rev 258492)
@@ -39,8 +39,16 @@
namespace WebCore {
-Path::Path() = default;
+Path::Path()
+ : m_elements(Vector<PathElement>())
+{
+}
+Path::Path(RefPtr<cairo_t>&& path)
+ : m_path(WTFMove(path))
+{
+}
+
Path::~Path() = default;
Path::Path(Path&&) = default;
@@ -54,6 +62,7 @@
CairoUniquePtr<cairo_path_t> pathCopy(cairo_copy_path(other.m_path.get()));
cairo_append_path(ensureCairoPath(), pathCopy.get());
+ m_elements = other.m_elements;
}
cairo_t* Path::ensureCairoPath()
@@ -70,6 +79,7 @@
if (other.isNull()) {
m_path = nullptr;
+ m_elements = Vector<PathElement>();
return *this;
}
@@ -76,6 +86,7 @@
clear();
CairoUniquePtr<cairo_path_t> pathCopy(cairo_copy_path(other.m_path.get()));
cairo_append_path(ensureCairoPath(), pathCopy.get());
+ m_elements = other.m_elements;
return *this;
}
@@ -87,6 +98,7 @@
cairo_identity_matrix(m_path.get());
cairo_new_path(m_path.get());
+ m_elements = Vector<PathElement>();
}
bool Path::isEmptySlowCase() const
@@ -106,21 +118,87 @@
void Path::translate(const FloatSize& p)
{
cairo_translate(ensureCairoPath(), -p.width(), -p.height());
+
+ if (!m_elements)
+ return;
+
+ for (auto& element : m_elements.value()) {
+ switch (element.type) {
+ case PathElement::Type::MoveToPoint:
+ case PathElement::Type::AddLineToPoint:
+ element.points[0].move(p);
+ break;
+ case PathElement::Type::AddQuadCurveToPoint:
+ element.points[0].move(p);
+ element.points[1].move(p);
+ break;
+ case PathElement::Type::AddCurveToPoint:
+ element.points[0].move(p);
+ element.points[1].move(p);
+ element.points[2].move(p);
+ break;
+ case PathElement::Type::CloseSubpath:
+ break;
+ }
+ }
}
+void Path::appendElement(PathElement::Type type, Vector<FloatPoint, 3>&& points)
+{
+ PathElement element;
+ element.type = type;
+ switch (type) {
+ case PathElement::Type::MoveToPoint:
+ case PathElement::Type::AddLineToPoint:
+ element.points[0] = points[0];
+ break;
+ case PathElement::Type::AddQuadCurveToPoint:
+ element.points[0] = points[0];
+ element.points[1] = points[1];
+ break;
+ case PathElement::Type::AddCurveToPoint:
+ element.points[0] = points[0];
+ element.points[1] = points[1];
+ element.points[2] = points[2];
+ break;
+ case PathElement::Type::CloseSubpath:
+ break;
+ }
+ m_elements->append(WTFMove(element));
+}
+
void Path::moveToSlowCase(const FloatPoint& p)
{
cairo_move_to(ensureCairoPath(), p.x(), p.y());
+ if (m_elements)
+ appendElement(PathElement::Type::MoveToPoint, { p });
}
void Path::addLineToSlowCase(const FloatPoint& p)
{
cairo_line_to(ensureCairoPath(), p.x(), p.y());
+ if (m_elements)
+ appendElement(PathElement::Type::AddLineToPoint, { p });
}
void Path::addRect(const FloatRect& rect)
{
cairo_rectangle(ensureCairoPath(), rect.x(), rect.y(), rect.width(), rect.height());
+
+ if (!m_elements)
+ return;
+
+ FloatPoint point(rect.location());
+ appendElement(PathElement::Type::MoveToPoint, { point });
+ point.move(rect.width(), 0);
+ appendElement(PathElement::Type::AddLineToPoint, { point });
+ point.move(0, rect.height());
+ appendElement(PathElement::Type::AddLineToPoint, { point });
+ point.move(-rect.width(), 0);
+ appendElement(PathElement::Type::AddLineToPoint, { point });
+ appendElement(PathElement::Type::CloseSubpath, { });
+ if (cairo_has_current_point(m_path.get()))
+ appendElement(PathElement::Type::MoveToPoint, { currentPointSlowCase() });
}
void Path::addQuadCurveToSlowCase(const FloatPoint& controlPoint, const FloatPoint& point)
@@ -136,6 +214,8 @@
x + 2.0 / 3.0 * (x1 - x), y + 2.0 / 3.0 * (y1 - y),
x2 + 2.0 / 3.0 * (x1 - x2), y2 + 2.0 / 3.0 * (y1 - y2),
x2, y2);
+ if (m_elements)
+ appendElement(PathElement::Type::AddQuadCurveToPoint, { controlPoint, point });
}
void Path::addBezierCurveToSlowCase(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& controlPoint3)
@@ -142,10 +222,13 @@
{
cairo_curve_to(ensureCairoPath(), controlPoint1.x(), controlPoint1.y(),
controlPoint2.x(), controlPoint2.y(), controlPoint3.x(), controlPoint3.y());
+ if (m_elements)
+ appendElement(PathElement::Type::AddCurveToPoint, { controlPoint1, controlPoint2, controlPoint3 });
}
void Path::addArcSlowCase(const FloatPoint& p, float r, float startAngle, float endAngle, bool anticlockwise)
{
+ m_elements = WTF::nullopt;
cairo_t* cr = ensureCairoPath();
float sweep = endAngle - startAngle;
const float twoPI = 2 * piFloat;
@@ -185,6 +268,8 @@
if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || !radius
|| !areaOfTriangleFormedByPoints(p0, p1, p2)) {
cairo_line_to(m_path.get(), p1.x(), p1.y());
+ if (m_elements)
+ appendElement(PathElement::Type::AddLineToPoint, { p1 });
return;
}
@@ -196,6 +281,8 @@
// all points on a line logic
if (cos_phi == -1) {
cairo_line_to(m_path.get(), p1.x(), p1.y());
+ if (m_elements)
+ appendElement(PathElement::Type::AddLineToPoint, { p1 });
return;
}
if (cos_phi == 1) {
@@ -204,9 +291,12 @@
double factor_max = max_length / p1p0_length;
FloatPoint ep((p0.x() + factor_max * p1p0.x()), (p0.y() + factor_max * p1p0.y()));
cairo_line_to(m_path.get(), ep.x(), ep.y());
+ if (m_elements)
+ appendElement(PathElement::Type::AddLineToPoint, { ep });
return;
}
+ m_elements = WTF::nullopt;
float tangent = radius / tan(acos(cos_phi) / 2);
float factor_p1p0 = tangent / p1p0_length;
FloatPoint t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
@@ -250,6 +340,7 @@
void Path::addEllipse(FloatPoint point, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise)
{
+ m_elements = WTF::nullopt;
cairo_t* cr = ensureCairoPath();
cairo_save(cr);
cairo_translate(cr, point.x(), point.y());
@@ -266,6 +357,7 @@
void Path::addEllipse(const FloatRect& rect)
{
+ m_elements = WTF::nullopt;
cairo_t* cr = ensureCairoPath();
cairo_save(cr);
float yRadius = .5 * rect.height();
@@ -285,6 +377,8 @@
if (cairo_matrix_invert(&matrix) != CAIRO_STATUS_SUCCESS)
return;
+ m_elements = WTF::nullopt;
+
cairo_t* cr = path.cairoPath();
cairo_save(cr);
cairo_transform(cr, &matrix);
@@ -296,6 +390,11 @@
void Path::closeSubpath()
{
cairo_close_path(ensureCairoPath());
+ if (m_elements) {
+ appendElement(PathElement::Type::CloseSubpath, { });
+ if (cairo_has_current_point(m_path.get()))
+ appendElement(PathElement::Type::MoveToPoint, { currentPointSlowCase() });
+ }
}
FloatRect Path::boundingRectSlowCase() const
@@ -348,6 +447,12 @@
void Path::applySlowCase(const PathApplierFunction& function) const
{
+ if (m_elements) {
+ for (const auto& element : m_elements.value())
+ function(element);
+ return;
+ }
+
CairoUniquePtr<cairo_path_t> pathCopy(cairo_copy_path(m_path.get()));
cairo_path_data_t* data;
PathElement pathElement;
@@ -390,6 +495,29 @@
cairo_matrix_t matrix = toCairoMatrix(transform);
cairo_matrix_invert(&matrix);
cairo_transform(ensureCairoPath(), &matrix);
+
+ if (!m_elements)
+ return;
+
+ for (auto& element : m_elements.value()) {
+ switch (element.type) {
+ case PathElement::Type::MoveToPoint:
+ case PathElement::Type::AddLineToPoint:
+ element.points[0] = transform.mapPoint(element.points[0]);
+ break;
+ case PathElement::Type::AddQuadCurveToPoint:
+ element.points[0] = transform.mapPoint(element.points[0]);
+ element.points[1] = transform.mapPoint(element.points[1]);
+ break;
+ case PathElement::Type::AddCurveToPoint:
+ element.points[0] = transform.mapPoint(element.points[0]);
+ element.points[1] = transform.mapPoint(element.points[1]);
+ element.points[2] = transform.mapPoint(element.points[2]);
+ break;
+ case PathElement::Type::CloseSubpath:
+ break;
+ }
+ }
}
bool Path::isNull() const