<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207681] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207681">207681</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2016-10-21 10:10:31 -0700 (Fri, 21 Oct 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[Win][Direct2D] Correct some memory leaks and other minor bugs
https://bugs.webkit.org/show_bug.cgi?id=163769
Reviewed by Alex Christensen.
Several D2D handles were being leaked.
Direct2D sometimes returns an infinite rect containing { -inf, -inf, FloatMax, FloatMax },
sometimes { -FloatMax, -FloatMax, inf, inf }, and various combinations thereof. This caused
most SVG drawing to decide no screen rect was contained in the "infinite rect" so nothing
would be drawn.
Tested by existing layout tests.
* platform/graphics/GraphicsContext.h:
* platform/graphics/win/FloatRectDirect2D.cpp:
(WebCore::isInfiniteRect): Recognize various infinite rects in Windows.
(WebCore::FloatRect::FloatRect): Convert a Windows infinite rect to the style
we use inside WebKit.
* platform/graphics/win/FontCascadeDirect2D.cpp:
(WebCore::FontCascade::drawGlyphs): Use cached brushes if possible.
* platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp:
(WebCore::GlyphPage::fill): Don't terminate on this error case.
* platform/graphics/win/GradientDirect2D.cpp:
(WebCore::Gradient::generateGradient): Don't leak gradients.
* platform/graphics/win/GraphicsContextDirect2D.cpp:
(WebCore::GraphicsContextPlatformPrivate::brushWithColor): Added.
(WebCore::GraphicsContext::brushWithColor): Added.
(WebCore::GraphicsContextPlatformPrivate::concatCTM): Perform transform multiplication
in the right order (hint: it's not distributive).
(WebCore::GraphicsContext::drawWithShadow): Use convenience method.
(WebCore::GraphicsContext::fillRect): Ditto.
(WebCore::GraphicsContext::platformFillRoundedRect): Ditto.
(WebCore::GraphicsContext::clearRect): Ditto.
(WebCore::GraphicsContext::setPlatformStrokeColor): Ditto.
(WebCore::GraphicsContext::setPlatformFillColor): Ditto.
* platform/graphics/win/PathDirect2D.cpp:
(WebCore::Path::polygonPathFromPoints): No need to convert manually.
(WebCore::Path::~Path): Don't leak ID2D1Geometry entities.
(WebCore::Path::appendGeometry): Ditto.
(WebCore::Path::createGeometryWithFillMode): Ditto.
(WebCore::Path::Path): Ditto.
(WebCore::Path::operator=): Ditto.
(WebCore::Path::strokeBoundingRect): Provide an implementation.
(WebCore::Path::addRect): No need for manual casting here.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContexth">trunk/Source/WebCore/platform/graphics/GraphicsContext.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinFloatRectDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/FloatRectDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinFontCascadeDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinGlyphPageTreeNodeDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinGradientDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinGraphicsContextDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinPathDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/ChangeLog        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -1,3 +1,51 @@
</span><ins>+2016-10-20 Brent Fulgham <bfulgham@apple.com>
+
+ [Win][Direct2D] Correct some memory leaks and other minor bugs
+ https://bugs.webkit.org/show_bug.cgi?id=163769
+
+ Reviewed by Alex Christensen.
+
+ Several D2D handles were being leaked.
+
+ Direct2D sometimes returns an infinite rect containing { -inf, -inf, FloatMax, FloatMax },
+ sometimes { -FloatMax, -FloatMax, inf, inf }, and various combinations thereof. This caused
+ most SVG drawing to decide no screen rect was contained in the "infinite rect" so nothing
+ would be drawn.
+
+ Tested by existing layout tests.
+
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/win/FloatRectDirect2D.cpp:
+ (WebCore::isInfiniteRect): Recognize various infinite rects in Windows.
+ (WebCore::FloatRect::FloatRect): Convert a Windows infinite rect to the style
+ we use inside WebKit.
+ * platform/graphics/win/FontCascadeDirect2D.cpp:
+ (WebCore::FontCascade::drawGlyphs): Use cached brushes if possible.
+ * platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp:
+ (WebCore::GlyphPage::fill): Don't terminate on this error case.
+ * platform/graphics/win/GradientDirect2D.cpp:
+ (WebCore::Gradient::generateGradient): Don't leak gradients.
+ * platform/graphics/win/GraphicsContextDirect2D.cpp:
+ (WebCore::GraphicsContextPlatformPrivate::brushWithColor): Added.
+ (WebCore::GraphicsContext::brushWithColor): Added.
+ (WebCore::GraphicsContextPlatformPrivate::concatCTM): Perform transform multiplication
+ in the right order (hint: it's not distributive).
+ (WebCore::GraphicsContext::drawWithShadow): Use convenience method.
+ (WebCore::GraphicsContext::fillRect): Ditto.
+ (WebCore::GraphicsContext::platformFillRoundedRect): Ditto.
+ (WebCore::GraphicsContext::clearRect): Ditto.
+ (WebCore::GraphicsContext::setPlatformStrokeColor): Ditto.
+ (WebCore::GraphicsContext::setPlatformFillColor): Ditto.
+ * platform/graphics/win/PathDirect2D.cpp:
+ (WebCore::Path::polygonPathFromPoints): No need to convert manually.
+ (WebCore::Path::~Path): Don't leak ID2D1Geometry entities.
+ (WebCore::Path::appendGeometry): Ditto.
+ (WebCore::Path::createGeometryWithFillMode): Ditto.
+ (WebCore::Path::Path): Ditto.
+ (WebCore::Path::operator=): Ditto.
+ (WebCore::Path::strokeBoundingRect): Provide an implementation.
+ (WebCore::Path::addRect): No need for manual casting here.
+
</ins><span class="cx"> 2016-10-21 Wenson Hsieh <wenson_hsieh@apple.com>
</span><span class="cx">
</span><span class="cx"> Fix minor style issue in the signature of StaticRange::create
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> interface ID2D1DCRenderTarget;
</span><span class="cx"> interface ID2D1RenderTarget;
</span><span class="cx"> interface ID2D1Factory;
</span><ins>+interface ID2D1SolidColorBrush;
</ins><span class="cx"> typedef ID2D1RenderTarget PlatformGraphicsContext;
</span><span class="cx"> #elif USE(CAIRO)
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -559,6 +560,8 @@
</span><span class="cx"> ID2D1Brush* solidFillBrush() const;
</span><span class="cx"> ID2D1Brush* patternStrokeBrush() const;
</span><span class="cx"> ID2D1Brush* patternFillBrush() const;
</span><ins>+
+ ID2D1SolidColorBrush* brushWithColor(const Color&);
</ins><span class="cx"> #endif
</span><span class="cx"> #else // PLATFORM(WIN)
</span><span class="cx"> bool shouldIncludeChildWindows() const { return false; }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinFloatRectDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/FloatRectDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/FloatRectDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/FloatRectDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -33,10 +33,33 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+static bool isInfiniteRect(const D2D1_RECT_F& rect)
+{
+ if (!std::isinf(rect.top) && rect.top != -std::numeric_limits<float>::max())
+ return false;
+
+ if (!std::isinf(rect.left) && rect.left != -std::numeric_limits<float>::max())
+ return false;
+
+ if (!std::isinf(rect.bottom) && rect.bottom != std::numeric_limits<float>::max())
+ return false;
+
+ if (!std::isinf(rect.right) && rect.right != std::numeric_limits<float>::max())
+ return false;
+
+ return true;
+}
+
</ins><span class="cx"> FloatRect::FloatRect(const D2D1_RECT_F& r)
</span><del>- : m_location(FloatPoint(r.left, r.top))
- , m_size(FloatSize(r.right - r.left, r.bottom - r.top))
</del><span class="cx"> {
</span><ins>+ // Infinite Rect case:
+ if (isInfiniteRect(r)) {
+ *this = infiniteRect();
+ return;
+ }
+
+ m_location = FloatPoint(r.left, r.top);
+ m_size = FloatSize(r.right - r.left, r.bottom - r.top);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> FloatRect::operator D2D1_RECT_F() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinFontCascadeDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -129,13 +129,10 @@
</span><span class="cx"> // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
</span><span class="cx"> float shadowTextY = point.y() + translation.height() + shadowOffset.height() * (graphicsContext.shadowsIgnoreTransforms() ? -1 : 1);
</span><span class="cx">
</span><del>- COMPtr<ID2D1SolidColorBrush> shadowBrush;
- if (!SUCCEEDED(context->CreateSolidColorBrush(graphicsContext.colorWithGlobalAlpha(shadowFillColor), &shadowBrush)))
- return;
-
- context->DrawGlyphRun(D2D1::Point2F(shadowTextX, shadowTextY), &glyphRun, shadowBrush.get());
</del><ins>+ auto shadowBrush = graphicsContext.brushWithColor(shadowFillColor);
+ context->DrawGlyphRun(D2D1::Point2F(shadowTextX, shadowTextY), &glyphRun, shadowBrush);
</ins><span class="cx"> if (font.syntheticBoldOffset())
</span><del>- context->DrawGlyphRun(D2D1::Point2F(shadowTextX + font.syntheticBoldOffset(), shadowTextY), &glyphRun, shadowBrush.get());
</del><ins>+ context->DrawGlyphRun(D2D1::Point2F(shadowTextX + font.syntheticBoldOffset(), shadowTextY), &glyphRun, shadowBrush);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> context->DrawGlyphRun(D2D1::Point2F(point.x() + translation.width(), point.y() + translation.height()), &glyphRun, graphicsContext.solidFillBrush());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinGlyphPageTreeNodeDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -67,7 +67,8 @@
</span><span class="cx"> hr = analyzer->GetGlyphs(buffer, bufferLength, fontPlatformData.dwFontFace(), fontPlatformData.orientation() == Vertical, false,
</span><span class="cx"> &helper.m_analysis, nullptr, nullptr, nullptr, nullptr, 0, GlyphPage::size, clusterMap, textProperties.data(),
</span><span class="cx"> localGlyphBuffer, glyphProperties.data(), &returnedCount);
</span><del>- RELEASE_ASSERT(SUCCEEDED(hr));
</del><ins>+ if (!SUCCEEDED(hr))
+ return false;
</ins><span class="cx">
</span><span class="cx"> for (unsigned i = 0; i < GlyphPage::size; i++) {
</span><span class="cx"> Glyph glyph = localGlyphBuffer[i];
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinGradientDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -66,6 +66,11 @@
</span><span class="cx"> HRESULT hr = renderTarget->CreateGradientStopCollection(gradientStops.data(), gradientStops.size(), &gradientStopCollection);
</span><span class="cx"> RELEASE_ASSERT(SUCCEEDED(hr));
</span><span class="cx">
</span><ins>+ if (m_gradient) {
+ m_gradient->Release();
+ m_gradient = nullptr;
+ }
+
</ins><span class="cx"> if (m_radial) {
</span><span class="cx"> FloatSize offset = p1() - p0();
</span><span class="cx"> ID2D1RadialGradientBrush* radialGradient = nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinGraphicsContextDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -274,7 +274,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> auto existingBrush = m_solidColoredBrushCache.ensure(colorKey, [this, color] {
</span><del>- ID2D1SolidColorBrush* colorBrush = nullptr;
</del><ins>+ COMPtr<ID2D1SolidColorBrush> colorBrush;
</ins><span class="cx"> m_renderTarget->CreateSolidColorBrush(color, &colorBrush);
</span><span class="cx"> return colorBrush;
</span><span class="cx"> });
</span><span class="lines">@@ -282,6 +282,11 @@
</span><span class="cx"> return existingBrush.iterator->value;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ID2D1SolidColorBrush* GraphicsContext::brushWithColor(const Color& color)
+{
+ return m_data->brushWithColor(colorWithGlobalAlpha(color)).get();
+}
+
</ins><span class="cx"> void GraphicsContextPlatformPrivate::clip(const FloatRect& rect)
</span><span class="cx"> {
</span><span class="cx"> if (m_renderStates.isEmpty())
</span><span class="lines">@@ -320,7 +325,8 @@
</span><span class="cx"> D2D1_MATRIX_3X2_F currentTransform;
</span><span class="cx"> m_renderTarget->GetTransform(&currentTransform);
</span><span class="cx">
</span><del>- m_renderTarget->SetTransform(affineTransform * AffineTransform(currentTransform));
</del><ins>+ D2D1_MATRIX_3X2_F transformToConcat = affineTransform;
+ m_renderTarget->SetTransform(transformToConcat * currentTransform);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void GraphicsContextPlatformPrivate::flush()
</span><span class="lines">@@ -882,7 +888,8 @@
</span><span class="cx">
</span><span class="cx"> deviceContext->BeginDraw();
</span><span class="cx"> deviceContext->DrawImage(compositor.get(), D2D1_INTERPOLATION_MODE_LINEAR);
</span><del>- deviceContext->EndDraw();
</del><ins>+ hr = deviceContext->EndDraw();
+ ASSERT(SUCCEEDED(hr));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void GraphicsContext::fillPath(const Path& path)
</span><span class="lines">@@ -1051,7 +1058,7 @@
</span><span class="cx">
</span><span class="cx"> drawWithoutShadow(rect, [this, rect, color](ID2D1RenderTarget* renderTarget) {
</span><span class="cx"> const D2D1_RECT_F d2dRect = rect;
</span><del>- renderTarget->FillRectangle(&d2dRect, m_data->brushWithColor(colorWithGlobalAlpha(color)).get());
</del><ins>+ renderTarget->FillRectangle(&d2dRect, brushWithColor(color));
</ins><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1085,8 +1092,7 @@
</span><span class="cx"> bool hasCustomFill = m_state.fillGradient || m_state.fillPattern;
</span><span class="cx"> if (!hasCustomFill && equalWidths && equalHeights && radii.topLeft().width() * 2 == r.width() && radii.topLeft().height() * 2 == r.height()) {
</span><span class="cx"> auto roundedRect = D2D1::RoundedRect(r, radii.topLeft().width(), radii.topLeft().height());
</span><del>- COMPtr<ID2D1SolidColorBrush> fillBrush = m_data->brushWithColor(colorWithGlobalAlpha(color));
- context->FillRoundedRectangle(roundedRect, fillBrush.get());
</del><ins>+ context->FillRoundedRectangle(roundedRect, brushWithColor(color));
</ins><span class="cx"> } else {
</span><span class="cx"> D2DContextStateSaver stateSaver(*m_data);
</span><span class="cx"> setFillColor(color);
</span><span class="lines">@@ -1345,7 +1351,7 @@
</span><span class="cx">
</span><span class="cx"> renderTarget->SetTags(1, __LINE__);
</span><span class="cx"> rectToClear.intersect(renderTargetRect);
</span><del>- renderTarget->FillRectangle(rectToClear, m_data->brushWithColor(colorWithGlobalAlpha(fillColor())).get());
</del><ins>+ renderTarget->FillRectangle(rectToClear, solidFillBrush());
</ins><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1668,7 +1674,7 @@
</span><span class="cx">
</span><span class="cx"> m_data->m_solidStrokeBrush = nullptr;
</span><span class="cx">
</span><del>- m_data->m_solidStrokeBrush = m_data->brushWithColor(colorWithGlobalAlpha(strokeColor()));
</del><ins>+ m_data->m_solidStrokeBrush = brushWithColor(strokeColor());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void GraphicsContext::setPlatformStrokeThickness(float thickness)
</span><span class="lines">@@ -1683,7 +1689,7 @@
</span><span class="cx">
</span><span class="cx"> m_data->m_solidFillBrush = nullptr;
</span><span class="cx">
</span><del>- m_data->m_solidFillBrush = m_data->brushWithColor(colorWithGlobalAlpha(fillColor()));
</del><ins>+ m_data->m_solidFillBrush = brushWithColor(fillColor());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void GraphicsContext::setPlatformShouldAntialias(bool enable)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinPathDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp (207680 => 207681)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp        2016-10-21 17:08:19 UTC (rev 207680)
+++ trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp        2016-10-21 17:10:31 UTC (rev 207681)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx"> Vector<D2D1_POINT_2F, 32> d2dPoints;
</span><span class="cx"> d2dPoints.reserveInitialCapacity(points.size() - 1);
</span><span class="cx"> for (auto point : points)
</span><del>- d2dPoints.uncheckedAppend(D2D1::Point2F(point.x(), point.y()));
</del><ins>+ d2dPoints.uncheckedAppend(point);
</ins><span class="cx">
</span><span class="cx"> path.moveTo(points.first());
</span><span class="cx">
</span><span class="lines">@@ -70,6 +70,8 @@
</span><span class="cx">
</span><span class="cx"> Path::~Path()
</span><span class="cx"> {
</span><ins>+ if (m_path)
+ m_path->Release();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PlatformPathPtr Path::ensurePlatformPath()
</span><span class="lines">@@ -89,18 +91,24 @@
</span><span class="cx"> unsigned geometryCount = m_path ? m_path->GetSourceGeometryCount() : 0;
</span><span class="cx"> Vector<ID2D1Geometry*> geometries(geometryCount, nullptr);
</span><span class="cx">
</span><ins>+ // Note: 'GetSourceGeometries' returns geometries that have a +1 ref count.
+ // so they must be released before we return.
</ins><span class="cx"> if (geometryCount)
</span><span class="cx"> m_path->GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx">
</span><ins>+ geometry->AddRef();
</ins><span class="cx"> geometries.append(geometry);
</span><span class="cx">
</span><span class="cx"> auto fillMode = m_path ? m_path->GetFillMode() : D2D1_FILL_MODE_WINDING;
</span><span class="cx">
</span><del>- COMPtr<ID2D1GeometryGroup> protectedPath = m_path;
</del><ins>+ COMPtr<ID2D1GeometryGroup> protectedPath = adoptCOM(m_path);
</ins><span class="cx"> m_path = nullptr;
</span><span class="cx">
</span><span class="cx"> HRESULT hr = GraphicsContext::systemFactory()->CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &m_path);
</span><span class="cx"> RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+ for (auto entry : geometries)
+ entry->Release();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Path::createGeometryWithFillMode(WindRule webkitFillMode, COMPtr<ID2D1GeometryGroup>& path) const
</span><span class="lines">@@ -118,10 +126,16 @@
</span><span class="cx">
</span><span class="cx"> Vector<ID2D1Geometry*> geometries(geometryCount, nullptr);
</span><span class="cx"> ASSERT(geometryCount);
</span><ins>+
+ // Note: 'GetSourceGeometries' returns geometries that have a +1 ref count.
+ // so they must be released before we return.
</ins><span class="cx"> m_path->GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx">
</span><span class="cx"> HRESULT hr = GraphicsContext::systemFactory()->CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &path);
</span><span class="cx"> RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+ for (auto entry : geometries)
+ entry->Release();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Path::Path(const Path& other)
</span><span class="lines">@@ -133,15 +147,24 @@
</span><span class="cx">
</span><span class="cx"> Vector<ID2D1Geometry*> geometries(geometryCount, nullptr);
</span><span class="cx"> ASSERT(geometryCount);
</span><ins>+
+ // Note: 'GetSourceGeometries' returns geometries that have a +1 ref count.
+ // so they must be released before we return.
</ins><span class="cx"> otherPath->GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx">
</span><span class="cx"> HRESULT hr = GraphicsContext::systemFactory()->CreateGeometryGroup(other.m_path->GetFillMode(), geometries.data(), geometryCount, &m_path);
</span><span class="cx"> RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+ for (auto entry : geometries)
+ entry->Release();
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Path& Path::operator=(const Path& other)
</span><span class="cx"> {
</span><ins>+ if (m_path)
+ m_path->Release();
+
</ins><span class="cx"> m_path = other.m_path;
</span><span class="cx"> if (m_path)
</span><span class="cx"> m_path->AddRef();
</span><span class="lines">@@ -264,7 +287,7 @@
</span><span class="cx"> if (!SUCCEEDED(m_path->GetBounds(nullptr, &bounds)))
</span><span class="cx"> return FloatRect();
</span><span class="cx">
</span><del>- return FloatRect(bounds.left, bounds.bottom, bounds.right - bounds.left, bounds.top - bounds.bottom);
</del><ins>+ return bounds;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> FloatRect Path::fastBoundingRect() const
</span><span class="lines">@@ -276,7 +299,7 @@
</span><span class="cx"> if (!SUCCEEDED(m_path->GetBounds(nullptr, &bounds)))
</span><span class="cx"> return FloatRect();
</span><span class="cx">
</span><del>- return FloatRect(bounds.left, bounds.bottom, bounds.right - bounds.left, bounds.top - bounds.bottom);
</del><ins>+ return bounds;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
</span><span class="lines">@@ -284,9 +307,14 @@
</span><span class="cx"> if (isNull())
</span><span class="cx"> return FloatRect();
</span><span class="cx">
</span><ins>+ if (!applier)
+ return boundingRect();
+
</ins><span class="cx"> UNUSED_PARAM(applier);
</span><span class="cx"> notImplemented();
</span><del>- return FloatRect();
</del><ins>+
+ // Just return regular bounding rect for now.
+ return boundingRect();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Path::moveTo(const FloatPoint& point)
</span><span class="lines">@@ -380,8 +408,17 @@
</span><span class="cx"> m_activePath->EndFigure(D2D1_FIGURE_END_OPEN);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void drawArcSection(ID2D1GeometrySink* sink, FloatPoint center, float radius, float startAngle, float endAngle, bool clockwise)
</del><ins>+static FloatPoint arcStart(const FloatPoint& center, float radius, float startAngle)
</ins><span class="cx"> {
</span><ins>+ FloatPoint startingPoint = center;
+ float startX = radius * std::cos(startAngle);
+ float startY = radius * std::sin(startAngle);
+ startingPoint.move(startX, startY);
+ return startingPoint;
+}
+
+static void drawArcSection(ID2D1GeometrySink* sink, const FloatPoint& center, float radius, float startAngle, float endAngle, bool clockwise)
+{
</ins><span class="cx"> // Direct2D wants us to specify the end point of the arc, not the center. It will be drawn from
</span><span class="cx"> // whatever the current point in the 'm_activePath' is.
</span><span class="cx"> FloatPoint p = center;
</span><span class="lines">@@ -396,13 +433,13 @@
</span><span class="cx">
</span><span class="cx"> void Path::addArc(const FloatPoint& center, float radius, float startAngle, float endAngle, bool clockwise)
</span><span class="cx"> {
</span><del>- if (!m_activePath) {
- float startX = radius * std::cos(startAngle);
- float startY = radius * std::sin(startAngle);
-
- FloatPoint start = center;
- start.move(startX, startY);
- moveTo(start);
</del><ins>+ auto arcStartPoint = arcStart(center, radius, startAngle);
+ if (!m_activePath)
+ moveTo(arcStartPoint);
+ else if (!areEssentiallyEqual(currentPoint(), arcStartPoint)) {
+ // If the arc defined by the center and radius does not intersect the current position,
+ // we need to draw a line from the current position to the starting point of the arc.
+ addLineTo(arcStartPoint);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Direct2D has problems drawing large arcs. It gets confused if drawing a complete (or
</span><span class="lines">@@ -423,7 +460,7 @@
</span><span class="cx"> void Path::addRect(const FloatRect& r)
</span><span class="cx"> {
</span><span class="cx"> COMPtr<ID2D1RectangleGeometry> rectangle;
</span><del>- HRESULT hr = GraphicsContext::systemFactory()->CreateRectangleGeometry(static_cast<D2D1_RECT_F>(r), &rectangle);
</del><ins>+ HRESULT hr = GraphicsContext::systemFactory()->CreateRectangleGeometry(r, &rectangle);
</ins><span class="cx"> RELEASE_ASSERT(SUCCEEDED(hr));
</span><span class="cx"> appendGeometry(rectangle.get());
</span><span class="cx"> }
</span></span></pre>
</div>
</div>
</body>
</html>