<!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>[208347] trunk/Source</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/208347">208347</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2016-11-03 14:07:51 -0700 (Thu, 03 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Printing to PDF should produce internal links when HTML has internal links
https://bugs.webkit.org/show_bug.cgi?id=112081
&lt;rdar://problem/5955705&gt;

Reviewed by Simon Fraser.
Patch originally by David Lattimore.

No new tests, as it's unclear how to test PDF output.

* dom/Element.cpp:
(WebCore::Element::findAnchorElementForLink):
* dom/Element.h:
Add findAnchorElementForLink, which looks up the anchor element corresponding
to the current element's href, and also returns the fragment name as an out parameter.

* page/PrintContext.cpp:
(WebCore::PrintContext::PrintContext):
(WebCore::PrintContext::spoolPage):
(WebCore::PrintContext::spoolRect):
(WebCore::PrintContext::end):
(WebCore::PrintContext::collectLinkedDestinations):
(WebCore::PrintContext::outputLinkedDestinations):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::addPDFURLRect):
Plumb internal links (fragment links) through to GraphicsContext, using
the fragment name from the page.

* page/PrintContext.h:
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::supportsInternalLinks):
(WebCore::GraphicsContext::setDestinationForRect):
(WebCore::GraphicsContext::addDestinationAtPoint):
* platform/graphics/GraphicsContext.h:
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContext::supportsInternalLinks):
(WebCore::GraphicsContext::setDestinationForRect):
(WebCore::GraphicsContext::addDestinationAtPoint):
Plumb internal links through to the CGContext. Apply the CTM, because
these functions expect positions in global coordinates.

* platform/graphics/win/GraphicsContextDirect2D.cpp:
(WebCore::GraphicsContext::setURLForRect):
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::setURLForRect):
Adjust setURLForRect to take a FloatRect, like everything else, and
stop rounding.

* UIProcess/mac/WKPrintingView.h:
* UIProcess/mac/WKPrintingView.mm:
(linkDestinationName):
(-[WKPrintingView _drawPDFDocument:page:atPoint:]):
Propagate link-to-destination annotations (and each page's destinations)
into the printed PDF.
Generate a unique destination name based on the page and position, because
we have lost the fragment name information.

(-[WKPrintingView drawRect:]):
Compute all of the destinations for every page, so that we can add them
to the context as we paint the pages (we need the page CTM in order to add them).</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCorepagePrintContextcpp">trunk/Source/WebCore/page/PrintContext.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePrintContexth">trunk/Source/WebCore/page/PrintContext.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContextcpp">trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContexth">trunk/Source/WebCore/platform/graphics/GraphicsContext.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscairoGraphicsContextCairocpp">trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgGraphicsContextCGcpp">trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinGraphicsContextDirect2Dcpp">trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjectcpp">trunk/Source/WebCore/rendering/RenderObject.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWKPrintingViewh">trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWKPrintingViewmm">trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/ChangeLog        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2016-11-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Printing to PDF should produce internal links when HTML has internal links
+        https://bugs.webkit.org/show_bug.cgi?id=112081
+        &lt;rdar://problem/5955705&gt;
+
+        Reviewed by Simon Fraser.
+        Patch originally by David Lattimore.
+
+        No new tests, as it's unclear how to test PDF output.
+
+        * dom/Element.cpp:
+        (WebCore::Element::findAnchorElementForLink):
+        * dom/Element.h:
+        Add findAnchorElementForLink, which looks up the anchor element corresponding
+        to the current element's href, and also returns the fragment name as an out parameter.
+
+        * page/PrintContext.cpp:
+        (WebCore::PrintContext::PrintContext):
+        (WebCore::PrintContext::spoolPage):
+        (WebCore::PrintContext::spoolRect):
+        (WebCore::PrintContext::end):
+        (WebCore::PrintContext::collectLinkedDestinations):
+        (WebCore::PrintContext::outputLinkedDestinations):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::addPDFURLRect):
+        Plumb internal links (fragment links) through to GraphicsContext, using
+        the fragment name from the page.
+
+        * page/PrintContext.h:
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::supportsInternalLinks):
+        (WebCore::GraphicsContext::setDestinationForRect):
+        (WebCore::GraphicsContext::addDestinationAtPoint):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::supportsInternalLinks):
+        (WebCore::GraphicsContext::setDestinationForRect):
+        (WebCore::GraphicsContext::addDestinationAtPoint):
+        Plumb internal links through to the CGContext. Apply the CTM, because
+        these functions expect positions in global coordinates.
+
+        * platform/graphics/win/GraphicsContextDirect2D.cpp:
+        (WebCore::GraphicsContext::setURLForRect):
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::setURLForRect):
+        Adjust setURLForRect to take a FloatRect, like everything else, and
+        stop rounding.
+
</ins><span class="cx"> 2016-11-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r208298.
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/dom/Element.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -3744,4 +3744,26 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Element* Element::findAnchorElementForLink(String&amp; outAnchorName)
+{
+    if (!isLink())
+        return nullptr;
+
+    const AtomicString&amp; href = getAttribute(HTMLNames::hrefAttr);
+    if (href.isNull())
+        return nullptr;
+
+    Document&amp; document = this-&gt;document();
+    URL url = document.completeURL(href);
+    if (!url.isValid())
+        return nullptr;
+
+    if (url.hasFragmentIdentifier() &amp;&amp; equalIgnoringFragmentIdentifier(url, document.baseURL())) {
+        outAnchorName = url.fragmentIdentifier();
+        return document.findAnchor(outAnchorName);
+    }
+
+    return nullptr;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/dom/Element.h        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -576,6 +576,8 @@
</span><span class="cx">     Vector&lt;WebAnimation*&gt; getAnimations();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    Element* findAnchorElementForLink(String&amp; outAnchorName);
+
</ins><span class="cx"> protected:
</span><span class="cx">     Element(const QualifiedName&amp;, Document&amp;, ConstructionType);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagePrintContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PrintContext.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PrintContext.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/page/PrintContext.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -24,6 +24,8 @@
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="cx"> #include &quot;FrameView.h&quot;
</span><ins>+#include &quot;HTMLNames.h&quot;
+#include &quot;NodeTraversal.h&quot;
</ins><span class="cx"> #include &quot;RenderView.h&quot;
</span><span class="cx"> #include &quot;StyleInheritedData.h&quot;
</span><span class="cx"> #include &quot;StyleResolver.h&quot;
</span><span class="lines">@@ -34,7 +36,6 @@
</span><span class="cx"> 
</span><span class="cx"> PrintContext::PrintContext(Frame* frame)
</span><span class="cx">     : m_frame(frame)
</span><del>-    , m_isPrinting(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -190,6 +191,7 @@
</span><span class="cx">     ctx.translate(-pageRect.x(), -pageRect.y());
</span><span class="cx">     ctx.clip(pageRect);
</span><span class="cx">     m_frame-&gt;view()-&gt;paintContents(ctx, pageRect);
</span><ins>+    outputLinkedDestinations(ctx, m_frame-&gt;document(), pageRect);
</ins><span class="cx">     ctx.restore();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -200,6 +202,7 @@
</span><span class="cx">     ctx.translate(-rect.x(), -rect.y());
</span><span class="cx">     ctx.clip(rect);
</span><span class="cx">     m_frame-&gt;view()-&gt;paintContents(ctx, rect);
</span><ins>+    outputLinkedDestinations(ctx, m_frame-&gt;document(), rect);
</ins><span class="cx">     ctx.restore();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -208,6 +211,7 @@
</span><span class="cx">     ASSERT(m_isPrinting);
</span><span class="cx">     m_isPrinting = false;
</span><span class="cx">     m_frame-&gt;setPrinting(false, FloatSize(), FloatSize(), 0, AdjustViewSize);
</span><ins>+    m_linkedDestinations = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline RenderBoxModelObject* enclosingBoxModelObject(RenderElement* renderer)
</span><span class="lines">@@ -246,6 +250,39 @@
</span><span class="cx">     return -1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PrintContext::collectLinkedDestinations(Node&amp; node)
+{
+    for (Node* child = &amp;node; child; child = NodeTraversal::next(*child)) {
+        if (!is&lt;Element&gt;(child))
+            continue;
+
+        String outAnchorName;
+        if (Element* element = downcast&lt;Element&gt;(child)-&gt;findAnchorElementForLink(outAnchorName))
+            m_linkedDestinations-&gt;set(outAnchorName, *element);
+    }
+}
+
+void PrintContext::outputLinkedDestinations(GraphicsContext&amp; graphicsContext, Node* node, const IntRect&amp; pageRect)
+{
+    if (!graphicsContext.supportsInternalLinks())
+        return;
+
+    if (!m_linkedDestinations) {
+        m_linkedDestinations = std::make_unique&lt;HashMap&lt;String, Ref&lt;Element&gt;&gt;&gt;();
+        collectLinkedDestinations(*node);
+    }
+
+    for (const auto&amp; it : *m_linkedDestinations) {
+        FloatPoint point = it.value-&gt;renderer()-&gt;anchorRect().minXMinYCorner();
+        point.expandedTo(FloatPoint());
+
+        if (!pageRect.contains(roundedIntPoint(point)))
+            continue;
+
+        graphicsContext.addDestinationAtPoint(it.key, point);
+    }
+}
+
</ins><span class="cx"> String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pageNumber)
</span><span class="cx"> {
</span><span class="cx">     Document* document = frame-&gt;document();
</span></span></pre></div>
<a id="trunkSourceWebCorepagePrintContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PrintContext.h (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PrintContext.h        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/page/PrintContext.h        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -21,7 +21,9 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><ins>+#include &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -31,6 +33,7 @@
</span><span class="cx"> class FloatSize;
</span><span class="cx"> class GraphicsContext;
</span><span class="cx"> class IntRect;
</span><ins>+class Node;
</ins><span class="cx"> 
</span><span class="cx"> class PrintContext {
</span><span class="cx"> public:
</span><span class="lines">@@ -98,9 +101,13 @@
</span><span class="cx"> private:
</span><span class="cx">     void computePageRectsWithPageSizeInternal(const FloatSize&amp; pageSizeInPixels, bool allowHorizontalTiling);
</span><span class="cx">     bool beginAndComputePageRectsWithPageSize(Frame&amp;, const FloatSize&amp; pageSizeInPixels);
</span><ins>+    void collectLinkedDestinations(Node&amp;);
+    void outputLinkedDestinations(GraphicsContext&amp;, Node*, const IntRect&amp; pageRect);
</ins><span class="cx"> 
</span><span class="cx">     // Used to prevent misuses of begin() and end() (e.g., call end without begin).
</span><del>-    bool m_isPrinting;
</del><ins>+    bool m_isPrinting { false };
+
+    std::unique_ptr&lt;HashMap&lt;String, Ref&lt;Element&gt;&gt;&gt; m_linkedDestinations;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -1178,4 +1178,19 @@
</span><span class="cx">     return { point1, point2 };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !USE(CG)
+bool GraphicsContext::supportsInternalLinks() const
+{
+    return false;
</ins><span class="cx"> }
</span><ins>+
+void GraphicsContext::setDestinationForRect(const String&amp;, const FloatRect&amp;)
+{
+}
+
+void GraphicsContext::addDestinationAtPoint(const String&amp;, const FloatPoint&amp;)
+{
+}
+#endif
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -468,8 +468,11 @@
</span><span class="cx">     void translate(const FloatSize&amp; size) { translate(size.width(), size.height()); }
</span><span class="cx">     WEBCORE_EXPORT void translate(float x, float y);
</span><span class="cx"> 
</span><del>-    void setURLForRect(const URL&amp;, const IntRect&amp;);
</del><ins>+    void setURLForRect(const URL&amp;, const FloatRect&amp;);
</ins><span class="cx"> 
</span><ins>+    void setDestinationForRect(const String&amp; name, const FloatRect&amp;);
+    void addDestinationAtPoint(const String&amp; name, const FloatPoint&amp;);
+
</ins><span class="cx">     void concatCTM(const AffineTransform&amp;);
</span><span class="cx">     void setCTM(const AffineTransform&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -576,6 +579,8 @@
</span><span class="cx"> 
</span><span class="cx">     static void adjustLineToPixelBoundaries(FloatPoint&amp; p1, FloatPoint&amp; p2, float strokeWidth, StrokeStyle);
</span><span class="cx"> 
</span><ins>+    bool supportsInternalLinks() const;
+
</ins><span class="cx"> private:
</span><span class="cx">     void platformInit(PlatformGraphicsContext*);
</span><span class="cx">     void platformDestroy();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoGraphicsContextCairocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -805,7 +805,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GraphicsContext::setURLForRect(const URL&amp;, const IntRect&amp;)
</del><ins>+void GraphicsContext::setURLForRect(const URL&amp;, const FloatRect&amp;)
</ins><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgGraphicsContextCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -1548,7 +1548,7 @@
</span><span class="cx">         setCGFillColor(platformContext(), fillColor());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GraphicsContext::setURLForRect(const URL&amp; link, const IntRect&amp; destRect)
</del><ins>+void GraphicsContext::setURLForRect(const URL&amp; link, const FloatRect&amp; destRect)
</ins><span class="cx"> {
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="cx">     if (paintingDisabled())
</span><span class="lines">@@ -1565,15 +1565,11 @@
</span><span class="cx"> 
</span><span class="cx">     CGContextRef context = platformContext();
</span><span class="cx"> 
</span><ins>+    FloatRect rect = destRect;
</ins><span class="cx">     // Get the bounding box to handle clipping.
</span><del>-    CGRect box = CGContextGetClipBoundingBox(context);
</del><ins>+    rect.intersect(CGContextGetClipBoundingBox(context));
</ins><span class="cx"> 
</span><del>-    IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height);
-    IntRect rect = destRect;
-    rect.intersect(intBox);
-
-    CGPDFContextSetURLForRect(context, urlRef.get(),
-        CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
</del><ins>+    CGPDFContextSetURLForRect(context, urlRef.get(), CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(link);
</span><span class="cx">     UNUSED_PARAM(destRect);
</span><span class="lines">@@ -1902,6 +1898,36 @@
</span><span class="cx">     CGContextStrokeEllipseInRect(context, ellipse);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool GraphicsContext::supportsInternalLinks() const
+{
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void GraphicsContext::setDestinationForRect(const String&amp; name, const FloatRect&amp; destRect)
+{
+    if (paintingDisabled())
+        return;
+
+    CGContextRef context = platformContext();
+
+    FloatRect rect = destRect;
+    rect.intersect(CGContextGetClipBoundingBox(context));
+
+    CGRect transformedRect = CGRectApplyAffineTransform(rect, CGContextGetCTM(context));
+    CGPDFContextSetDestinationForRect(context, name.createCFString().get(), transformedRect);
+}
+
+void GraphicsContext::addDestinationAtPoint(const String&amp; name, const FloatPoint&amp; position)
+{
+    if (paintingDisabled())
+        return;
+
+    CGContextRef context = platformContext();
+
+    CGPoint transformedPoint = CGPointApplyAffineTransform(position, CGContextGetCTM(context));
+    CGPDFContextAddDestinationAtPoint(context, name.createCFString().get(), transformedPoint);
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinGraphicsContextDirect2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -1642,7 +1642,7 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GraphicsContext::setURLForRect(const URL&amp; link, const IntRect&amp; destRect)
</del><ins>+void GraphicsContext::setURLForRect(const URL&amp; link, const FloatRect&amp; destRect)
</ins><span class="cx"> {
</span><span class="cx">     if (paintingDisabled())
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.cpp        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -604,10 +604,22 @@
</span><span class="cx">     Node* node = this-&gt;node();
</span><span class="cx">     if (!is&lt;Element&gt;(node) || !node-&gt;isLink())
</span><span class="cx">         return;
</span><del>-    const AtomicString&amp; href = downcast&lt;Element&gt;(*node).getAttribute(hrefAttr);
</del><ins>+    Element&amp; element = downcast&lt;Element&gt;(*node);
+    const AtomicString&amp; href = element.getAttribute(hrefAttr);
</ins><span class="cx">     if (href.isNull())
</span><span class="cx">         return;
</span><del>-    paintInfo.context().setURLForRect(node-&gt;document().completeURL(href), snappedIntRect(urlRect));
</del><ins>+
+    if (paintInfo.context().supportsInternalLinks()) {
+        String outAnchorName;
+        Element* linkTarget = element.findAnchorElementForLink(outAnchorName);
+        if (linkTarget) {
+            paintInfo.context().setDestinationForRect(outAnchorName, urlRect);
+            return;
+        }
+    }
+
+    paintInfo.context().setURLForRect(node-&gt;document().completeURL(href), urlRect);
+
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebKit2/ChangeLog        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2016-11-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Printing to PDF should produce internal links when HTML has internal links
+        https://bugs.webkit.org/show_bug.cgi?id=112081
+        &lt;rdar://problem/5955705&gt;
+
+        Reviewed by Simon Fraser.
+
+        * UIProcess/mac/WKPrintingView.h:
+        * UIProcess/mac/WKPrintingView.mm:
+        (linkDestinationName):
+        (-[WKPrintingView _drawPDFDocument:page:atPoint:]):
+        Propagate link-to-destination annotations (and each page's destinations)
+        into the printed PDF.
+        Generate a unique destination name based on the page and position, because
+        we have lost the fragment name information.
+
+        (-[WKPrintingView drawRect:]):
+        Compute all of the destinations for every page, so that we can add them
+        to the context as we paint the pages (we need the page CTM in order to add them).
+
</ins><span class="cx"> 2016-11-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r208298.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWKPrintingViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.h (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.h        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.h        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #import &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> @class WKPrintingViewData;
</span><ins>+@class PDFDestination;
</ins><span class="cx"> @class PDFDocument;
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="lines">@@ -52,6 +53,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;uint8_t&gt; _printedPagesData;
</span><span class="cx">     RetainPtr&lt;PDFDocument&gt; _printedPagesPDFDocument;
</span><ins>+    Vector&lt;Vector&lt;RetainPtr&lt;PDFDestination&gt;&gt;&gt; _linkDestinationsPerPage;
</ins><span class="cx"> 
</span><span class="cx">     uint64_t _expectedComputedPagesCallback;
</span><span class="cx">     HashMap&lt;uint64_t, WebCore::IntRect&gt; _expectedPreviewCallbacks;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWKPrintingViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.mm (208346 => 208347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.mm        2016-11-03 21:07:35 UTC (rev 208346)
+++ trunk/Source/WebKit2/UIProcess/mac/WKPrintingView.mm        2016-11-03 21:07:51 UTC (rev 208347)
</span><span class="lines">@@ -427,6 +427,11 @@
</span><span class="cx">     return 0; // Invalid page number.
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static CFStringRef linkDestinationName(PDFDocument *document, PDFDestination *destination)
+{
+    return (CFStringRef)[NSString stringWithFormat:@&quot;%lu-%f-%f&quot;, (unsigned long)[document indexForPage:destination.page], destination.point.x, destination.point.y];
+}
+
</ins><span class="cx"> - (void)_drawPDFDocument:(PDFDocument *)pdfDocument page:(unsigned)page atPoint:(NSPoint)point
</span><span class="cx"> {
</span><span class="cx">     if (!pdfDocument) {
</span><span class="lines">@@ -456,6 +461,11 @@
</span><span class="cx"> 
</span><span class="cx">     CGAffineTransform transform = CGContextGetCTM(context);
</span><span class="cx"> 
</span><ins>+    for (const auto&amp; destination : _linkDestinationsPerPage[page]) {
+        CGPoint destinationPoint = CGPointApplyAffineTransform(NSPointToCGPoint([destination point]), transform);
+        CGPDFContextAddDestinationAtPoint(context, linkDestinationName(pdfDocument, destination.get()), destinationPoint);
+    }
+
</ins><span class="cx">     for (PDFAnnotation *annotation in [pdfPage annotations]) {
</span><span class="cx">         if (![annotation isKindOfClass:pdfAnnotationLinkClass()])
</span><span class="cx">             continue;
</span><span class="lines">@@ -465,11 +475,17 @@
</span><span class="cx">         PDFAnnotationLink *linkAnnotation = (PDFAnnotationLink *)annotation;
</span><span class="cx"> #pragma clang diagnostic pop
</span><span class="cx">         NSURL *url = [linkAnnotation URL];
</span><del>-        if (!url)
</del><ins>+        CGRect transformedRect = CGRectApplyAffineTransform(NSRectToCGRect([linkAnnotation bounds]), transform);
+
+        if (!url) {
+            PDFDestination *destination = [linkAnnotation destination];
+            if (!destination)
+                continue;
+            CGPDFContextSetDestinationForRect(context, linkDestinationName(pdfDocument, destination), transformedRect);
+
</ins><span class="cx">             continue;
</span><ins>+        }
</ins><span class="cx"> 
</span><del>-        CGRect urlRect = NSRectToCGRect([linkAnnotation bounds]);
-        CGRect transformedRect = CGRectApplyAffineTransform(urlRect, transform);
</del><span class="cx">         CGPDFContextSetURLForRect(context, (CFURLRef)url, transformedRect);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -549,6 +565,31 @@
</span><span class="cx">     if (!_printedPagesPDFDocument) {
</span><span class="cx">         RetainPtr&lt;NSData&gt; pdfData = adoptNS([[NSData alloc] initWithBytes:_printedPagesData.data() length:_printedPagesData.size()]);
</span><span class="cx">         _printedPagesPDFDocument = adoptNS([[pdfDocumentClass() alloc] initWithData:pdfData.get()]);
</span><ins>+
+        unsigned pageCount = [_printedPagesPDFDocument pageCount];
+        _linkDestinationsPerPage.clear();
+        _linkDestinationsPerPage.resize(pageCount);
+        for (unsigned i = 0; i &lt; pageCount; i++) {
+            PDFPage *page = [_printedPagesPDFDocument pageAtIndex:i];
+            for (PDFAnnotation *annotation in page.annotations) {
+                if (![annotation isKindOfClass:pdfAnnotationLinkClass()])
+                    continue;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored &quot;-Wdeprecated-declarations&quot;
+                PDFAnnotationLink *linkAnnotation = (PDFAnnotationLink *)annotation;
+#pragma clang diagnostic pop
+                if (linkAnnotation.URL)
+                    continue;
+
+                PDFDestination *destination = linkAnnotation.destination;
+                if (!destination)
+                    continue;
+
+                unsigned destinationPageIndex = [_printedPagesPDFDocument indexForPage:destination.page];
+                _linkDestinationsPerPage[destinationPageIndex].append(destination);
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber];
</span></span></pre>
</div>
</div>

</body>
</html>