<!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 &quot;infinite rect&quot; 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  &lt;bfulgham@apple.com&gt;
+
+        [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 &quot;infinite rect&quot; 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  &lt;wenson_hsieh@apple.com&gt;
</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&amp;);
</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&amp; rect)
+{
+    if (!std::isinf(rect.top) &amp;&amp; rect.top != -std::numeric_limits&lt;float&gt;::max())
+        return false;
+
+    if (!std::isinf(rect.left) &amp;&amp; rect.left != -std::numeric_limits&lt;float&gt;::max())
+        return false;
+
+    if (!std::isinf(rect.bottom) &amp;&amp; rect.bottom != std::numeric_limits&lt;float&gt;::max())
+        return false;
+
+    if (!std::isinf(rect.right) &amp;&amp; rect.right != std::numeric_limits&lt;float&gt;::max())
+        return false;
+
+    return true;
+}
+
</ins><span class="cx"> FloatRect::FloatRect(const D2D1_RECT_F&amp; 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&lt;ID2D1SolidColorBrush&gt; shadowBrush;
-        if (!SUCCEEDED(context-&gt;CreateSolidColorBrush(graphicsContext.colorWithGlobalAlpha(shadowFillColor), &amp;shadowBrush)))
-            return;
-
-        context-&gt;DrawGlyphRun(D2D1::Point2F(shadowTextX, shadowTextY), &amp;glyphRun, shadowBrush.get());
</del><ins>+        auto shadowBrush = graphicsContext.brushWithColor(shadowFillColor);
+        context-&gt;DrawGlyphRun(D2D1::Point2F(shadowTextX, shadowTextY), &amp;glyphRun, shadowBrush);
</ins><span class="cx">         if (font.syntheticBoldOffset())
</span><del>-            context-&gt;DrawGlyphRun(D2D1::Point2F(shadowTextX + font.syntheticBoldOffset(), shadowTextY), &amp;glyphRun, shadowBrush.get());
</del><ins>+            context-&gt;DrawGlyphRun(D2D1::Point2F(shadowTextX + font.syntheticBoldOffset(), shadowTextY), &amp;glyphRun, shadowBrush);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     context-&gt;DrawGlyphRun(D2D1::Point2F(point.x() + translation.width(), point.y() + translation.height()), &amp;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-&gt;GetGlyphs(buffer, bufferLength, fontPlatformData.dwFontFace(), fontPlatformData.orientation() == Vertical, false,
</span><span class="cx">         &amp;helper.m_analysis, nullptr, nullptr, nullptr, nullptr, 0, GlyphPage::size, clusterMap, textProperties.data(),
</span><span class="cx">         localGlyphBuffer, glyphProperties.data(), &amp;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 &lt; 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-&gt;CreateGradientStopCollection(gradientStops.data(), gradientStops.size(), &amp;gradientStopCollection);
</span><span class="cx">     RELEASE_ASSERT(SUCCEEDED(hr));
</span><span class="cx"> 
</span><ins>+    if (m_gradient) {
+        m_gradient-&gt;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&lt;ID2D1SolidColorBrush&gt; colorBrush;
</ins><span class="cx">         m_renderTarget-&gt;CreateSolidColorBrush(color, &amp;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-&gt;value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ID2D1SolidColorBrush* GraphicsContext::brushWithColor(const Color&amp; color)
+{
+    return m_data-&gt;brushWithColor(colorWithGlobalAlpha(color)).get();
+}
+
</ins><span class="cx"> void GraphicsContextPlatformPrivate::clip(const FloatRect&amp; 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-&gt;GetTransform(&amp;currentTransform);
</span><span class="cx"> 
</span><del>-    m_renderTarget-&gt;SetTransform(affineTransform * AffineTransform(currentTransform));
</del><ins>+    D2D1_MATRIX_3X2_F transformToConcat = affineTransform;
+    m_renderTarget-&gt;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-&gt;BeginDraw();
</span><span class="cx">     deviceContext-&gt;DrawImage(compositor.get(), D2D1_INTERPOLATION_MODE_LINEAR);
</span><del>-    deviceContext-&gt;EndDraw();
</del><ins>+    hr = deviceContext-&gt;EndDraw();
+    ASSERT(SUCCEEDED(hr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GraphicsContext::fillPath(const Path&amp; 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-&gt;FillRectangle(&amp;d2dRect, m_data-&gt;brushWithColor(colorWithGlobalAlpha(color)).get());
</del><ins>+        renderTarget-&gt;FillRectangle(&amp;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 &amp;&amp; equalWidths &amp;&amp; equalHeights &amp;&amp; radii.topLeft().width() * 2 == r.width() &amp;&amp; radii.topLeft().height() * 2 == r.height()) {
</span><span class="cx">         auto roundedRect = D2D1::RoundedRect(r, radii.topLeft().width(), radii.topLeft().height());
</span><del>-        COMPtr&lt;ID2D1SolidColorBrush&gt; fillBrush = m_data-&gt;brushWithColor(colorWithGlobalAlpha(color));
-        context-&gt;FillRoundedRectangle(roundedRect, fillBrush.get());
</del><ins>+        context-&gt;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-&gt;SetTags(1, __LINE__);
</span><span class="cx">         rectToClear.intersect(renderTargetRect);
</span><del>-        renderTarget-&gt;FillRectangle(rectToClear, m_data-&gt;brushWithColor(colorWithGlobalAlpha(fillColor())).get());
</del><ins>+        renderTarget-&gt;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-&gt;m_solidStrokeBrush = nullptr;
</span><span class="cx"> 
</span><del>-    m_data-&gt;m_solidStrokeBrush = m_data-&gt;brushWithColor(colorWithGlobalAlpha(strokeColor()));
</del><ins>+    m_data-&gt;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-&gt;m_solidFillBrush = nullptr;
</span><span class="cx"> 
</span><del>-    m_data-&gt;m_solidFillBrush = m_data-&gt;brushWithColor(colorWithGlobalAlpha(fillColor()));
</del><ins>+    m_data-&gt;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&lt;D2D1_POINT_2F, 32&gt; 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-&gt;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-&gt;GetSourceGeometryCount() : 0;
</span><span class="cx">     Vector&lt;ID2D1Geometry*&gt; 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-&gt;GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx"> 
</span><ins>+    geometry-&gt;AddRef();
</ins><span class="cx">     geometries.append(geometry);
</span><span class="cx"> 
</span><span class="cx">     auto fillMode = m_path ? m_path-&gt;GetFillMode() : D2D1_FILL_MODE_WINDING;
</span><span class="cx"> 
</span><del>-    COMPtr&lt;ID2D1GeometryGroup&gt; protectedPath = m_path;
</del><ins>+    COMPtr&lt;ID2D1GeometryGroup&gt; protectedPath = adoptCOM(m_path);
</ins><span class="cx">     m_path = nullptr;
</span><span class="cx"> 
</span><span class="cx">     HRESULT hr = GraphicsContext::systemFactory()-&gt;CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &amp;m_path);
</span><span class="cx">     RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+    for (auto entry : geometries)
+        entry-&gt;Release();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Path::createGeometryWithFillMode(WindRule webkitFillMode, COMPtr&lt;ID2D1GeometryGroup&gt;&amp; path) const
</span><span class="lines">@@ -118,10 +126,16 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;ID2D1Geometry*&gt; 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-&gt;GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx"> 
</span><span class="cx">     HRESULT hr = GraphicsContext::systemFactory()-&gt;CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &amp;path);
</span><span class="cx">     RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+    for (auto entry : geometries)
+        entry-&gt;Release();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Path::Path(const Path&amp; other)
</span><span class="lines">@@ -133,15 +147,24 @@
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;ID2D1Geometry*&gt; 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-&gt;GetSourceGeometries(geometries.data(), geometryCount);
</span><span class="cx"> 
</span><span class="cx">         HRESULT hr = GraphicsContext::systemFactory()-&gt;CreateGeometryGroup(other.m_path-&gt;GetFillMode(), geometries.data(), geometryCount, &amp;m_path);
</span><span class="cx">         RELEASE_ASSERT(SUCCEEDED(hr));
</span><ins>+
+        for (auto entry : geometries)
+            entry-&gt;Release();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Path&amp; Path::operator=(const Path&amp; other)
</span><span class="cx"> {
</span><ins>+    if (m_path)
+        m_path-&gt;Release();
+
</ins><span class="cx">     m_path = other.m_path;
</span><span class="cx">     if (m_path)
</span><span class="cx">         m_path-&gt;AddRef();
</span><span class="lines">@@ -264,7 +287,7 @@
</span><span class="cx">     if (!SUCCEEDED(m_path-&gt;GetBounds(nullptr, &amp;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-&gt;GetBounds(nullptr, &amp;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&amp; point)
</span><span class="lines">@@ -380,8 +408,17 @@
</span><span class="cx">     m_activePath-&gt;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&amp; 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&amp; 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&amp; 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&amp; r)
</span><span class="cx"> {
</span><span class="cx">     COMPtr&lt;ID2D1RectangleGeometry&gt; rectangle;
</span><del>-    HRESULT hr = GraphicsContext::systemFactory()-&gt;CreateRectangleGeometry(static_cast&lt;D2D1_RECT_F&gt;(r), &amp;rectangle);
</del><ins>+    HRESULT hr = GraphicsContext::systemFactory()-&gt;CreateRectangleGeometry(r, &amp;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>