Patch written mostly by Ken Kraisler, but also by me.
authorbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Oct 2006 01:12:32 +0000 (01:12 +0000)
committerbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Oct 2006 01:12:32 +0000 (01:12 +0000)
        Reviewed by Hyatt.

        Fix for http://bugs.webkit.org/show_bug.cgi?id=10216 and <rdar://
        problem/3391162> PDF created by printing should have live
        hyperlinks

        * platform/GraphicsContext.cpp:
        (WebCore::GraphicsContext::focusRingBoundingRect):
        * platform/GraphicsContext.h:
        * platform/cairo/GraphicsContextCairo.cpp:
        (WebCore::GraphicsContext::setURLForRect):
        * platform/cg/GraphicsContextCG.cpp:
        (WebCore::GraphicsContext::setURLForRect): Implement method to add
        URL link to PDF document.
        * rendering/InlineFlowBox.cpp:
        (WebCore::InlineFlowBox::paint): Ask hasOutline() instead of
        querying the outline width
        * rendering/RenderBlock.cpp:
        (WebCore::RenderBlock::paintObject): Same as above.
        * rendering/RenderFlow.cpp:
        (WebCore::RenderFlow::paintLines): Call the new paintOutline()
        (WebCore::RenderFlow::paintOutline): Take care of focus ring and
        pdf url rects, and outline painting.
        * rendering/RenderFlow.h:
        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::addPDFURLRect): Declaration to apply a PDF
        link to a rectanglular region.
        (WebCore::RenderObject::paintOutline): Take care of pdf rects as
        well as focus ring painting.
        * rendering/RenderObject.h:
        (WebCore::RenderObject::hasOutlineAnnotation): Returns true is the
        element is a link and we are printing.
        (WebCore::RenderObject::hasOutline): Returns true is the style has
        an outline and hasOutlineAnnotation() is true.
        * rendering/RenderStyle.h:
        (WebCore::RenderStyle::hasOutline): Returns true if outlineWidth is
        greater than 0 and outlineStyle is greater than BHIDDEN.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@17052 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/ChangeLog
WebCore/platform/GraphicsContext.cpp
WebCore/platform/GraphicsContext.h
WebCore/platform/cairo/GraphicsContextCairo.cpp
WebCore/platform/cg/GraphicsContextCG.cpp
WebCore/rendering/InlineFlowBox.cpp
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderFlow.cpp
WebCore/rendering/RenderFlow.h
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderStyle.h

index c25b2d9f661cad17018d632a77ca0c9613ee357d..20f9eb714e667f035fd66055973b28e979f2f190 100644 (file)
@@ -1,3 +1,45 @@
+2006-10-13  Beth Dakin  <bdakin@apple.com>
+
+        Patch written mostly by Ken Kraisler, but also by me.
+
+        Reviewed by Hyatt.
+
+        Fix for http://bugs.webkit.org/show_bug.cgi?id=10216 and <rdar://
+        problem/3391162> PDF created by printing should have live 
+        hyperlinks
+
+        * platform/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::focusRingBoundingRect):
+        * platform/GraphicsContext.h:
+        * platform/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::setURLForRect):
+        * platform/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::setURLForRect): Implement method to add 
+        URL link to PDF document.
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::paint): Ask hasOutline() instead of 
+        querying the outline width
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject): Same as above.
+        * rendering/RenderFlow.cpp:
+        (WebCore::RenderFlow::paintLines): Call the new paintOutline()
+        (WebCore::RenderFlow::paintOutline): Take care of focus ring and 
+        pdf url rects, and outline painting.
+        * rendering/RenderFlow.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::addPDFURLRect): Declaration to apply a PDF 
+        link to a rectanglular region.
+        (WebCore::RenderObject::paintOutline): Take care of pdf rects as 
+        well as focus ring painting.
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::hasOutlineAnnotation): Returns true is the 
+        element is a link and we are printing.
+        (WebCore::RenderObject::hasOutline): Returns true is the style has 
+        an outline and hasOutlineAnnotation() is true.
+        * rendering/RenderStyle.h:
+        (WebCore::RenderStyle::hasOutline): Returns true if outlineWidth is 
+        greater than 0 and outlineStyle is greater than BHIDDEN.
+
 2006-10-13  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by ggaren and harrison
index 104dfcf9cc0135d7d4f8df959ef28bb33d0c4643..c65a42218f449b1024fc076ef1cc085bb81703fc 100644 (file)
@@ -216,6 +216,18 @@ void GraphicsContext::clearFocusRing()
     m_common->m_focusRingRects.clear();
 }
 
+IntRect GraphicsContext::focusRingBoundingRect()
+{
+    IntRect result = IntRect(0, 0, 0, 0);
+    
+    const Vector<IntRect>& rects = focusRingRects();
+    unsigned rectCount = rects.size();
+    for (unsigned i = 0; i < rectCount; i++)
+        result.unite(rects[i]);
+        
+    return result;
+}
+
 void GraphicsContext::addFocusRingRect(const IntRect& rect)
 {
     if (paintingDisabled() || rect.isEmpty())
index eb5cf41db4fbbd2a7beebb9791145063a3744268..21c34cec221b5f2384320c7a0a2a9bd61e0a3519 100644 (file)
@@ -60,6 +60,7 @@ namespace WebCore {
     class Font;
     class GraphicsContextPrivate;
     class GraphicsContextPlatformPrivate;
+    class KURL;
     class Path;
     class TextRun;
     class TextStyle;
@@ -145,6 +146,7 @@ namespace WebCore {
         void addFocusRingRect(const IntRect&);
         void drawFocusRing(const Color&);
         void clearFocusRing();
+        IntRect focusRingBoundingRect();
 
         void setLineWidth(float);
         void setLineCap(LineCap);
@@ -161,6 +163,8 @@ namespace WebCore {
         void rotate(float angleInRadians);
         void translate(float x, float y);
         IntPoint origin();
+        
+        void setURLForRect(const KURL&, const IntRect&);
 
         void concatCTM(const AffineTransform&);
 
index 6cbf27359b151132e9e98985f71028e4a33aa608..33eb505a8927b732f8597878c28d0a72cd2b03b0 100644 (file)
@@ -460,6 +460,10 @@ IntPoint GraphicsContext::origin()
     return IntPoint(matrix.x0, matrix.y0);
 }
 
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+}
+
 } // namespace WebCore
 
 #endif // PLATFORM(CAIRO)
index 42885e8ebb623e31d82367e34e7ec4a13c9139a9..4d8a701456c2c7ad53e3d137fb982d84e4e00efa 100644 (file)
@@ -30,6 +30,7 @@
 #if PLATFORM(CG)
 
 #include "AffineTransform.h"
+#include "KURL.h"
 #include "Path.h"
 #include <wtf/MathExtras.h>
 
@@ -777,6 +778,29 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int yOffset, int wi
     CGContextRestoreGState(platformContext());
 }
 
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+    if (paintingDisabled())
+        return;
+        
+    CFURLRef urlRef = link.createCFURL();
+    if (urlRef) {
+        CGContextRef context = platformContext();
+        
+        // Get the bounding box to handle clipping.
+        CGRect box = CGContextGetClipBoundingBox(context);
+
+        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,
+            CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
+
+        CFRelease(urlRef);
+    }
+}
+
 }
 
 #endif // PLATFORM(CG)
index 1f8d65e3262d2c9e13ec69f6b50d2fd466fb4ec0..32ef2790fb651657adb2a427c44271b16aa72476 100644 (file)
@@ -550,7 +550,7 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
         if (i.phase == PaintPhaseOutline || i.phase == PaintPhaseSelfOutline) {
             // Add ourselves to the paint info struct's list of inlines that need to paint their
             // outlines.
-            if (object()->style()->visibility() == VISIBLE && object()->style()->outlineWidth() > 0 &&
+            if (object()->style()->visibility() == VISIBLE && object()->hasOutline() &&
                 !object()->isInlineContinuation() && !isRootInlineBox()) {
                 i.outlineObjects->add(flowObject());
             }
index 9ada1ac5ee64f96e30cbdf71ec948112983c987e..ea3e53d511269413f3b596b4ceecb5fdfb613791 100644 (file)
@@ -1363,8 +1363,8 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
 
     // 5. paint outline.
     if (!inlineFlow && (paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) 
-        && style()->outlineWidth() && style()->visibility() == VISIBLE)
-        paintOutline(i.p, _tx, _ty, width(), height(), style());
+        && hasOutline() && style()->visibility() == VISIBLE)
+        RenderObject::paintOutline(i.p, _tx, _ty, width(), height(), style());
 
     // 6. paint caret.
     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
index 209504c1684052730ebfd92ac5ffbc2c77a9fab0..08c0db82b82c9e70086642acfdafcb2c725707e2 100644 (file)
@@ -410,10 +410,7 @@ void RenderFlow::paintLines(PaintInfo& i, int _tx, int _ty)
         RenderFlowSequencedSet::iterator end = info.outlineObjects->end();
         for (RenderFlowSequencedSet::iterator it = info.outlineObjects->begin(); it != end; ++it) {
             RenderFlow* flow = *it;
-            if (flow->style()->outlineStyleIsAuto())
-                flow->paintFocusRing(info.p, _tx, _ty);
-            else
-                flow->paintOutlines(info.p, _tx, _ty);
+            flow->paintOutline(info.p, _tx, _ty);
         }
         info.outlineObjects->clear();
     }
@@ -687,33 +684,38 @@ void RenderFlow::addFocusRingRects(GraphicsContext* p, int _tx, int _ty)
                                           _ty - containingBlock()->yPos() + continuation()->yPos());
 }
 
-void RenderFlow::paintFocusRing(GraphicsContext* p, int tx, int ty)
+void RenderFlow::paintOutline(GraphicsContext* p, int _tx, int _ty)
 {
-    int ow = style()->outlineWidth();
-    Color oc = style()->outlineColor();
-    if (!oc.isValid())
-        oc = style()->color();
+    if (!hasOutline())
+        return;
     
-    p->initFocusRing(ow, style()->outlineOffset());
-    addFocusRingRects(p, tx, ty);
-    p->drawFocusRing(oc);
-    p->clearFocusRing();
-}
+    if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
+        int ow = style()->outlineWidth();
+        Color oc = style()->outlineColor();
+        if (!oc.isValid())
+            oc = style()->color();
+        
+        p->initFocusRing(ow, style()->outlineOffset());
+        addFocusRingRects(p, _tx, _ty);
+        if (style()->outlineStyleIsAuto())
+            p->drawFocusRing(oc);
+        else
+            addPDFURLRect(p, p->focusRingBoundingRect());
+        p->clearFocusRing();
+    }
 
-void RenderFlow::paintOutlines(GraphicsContext* p, int _tx, int _ty)
-{
-    if (style()->outlineStyle() <= BHIDDEN)
+    if (style()->outlineStyleIsAuto() || style()->outlineStyle() <= BHIDDEN)
         return;
-    
+
     DeprecatedPtrList <IntRect> rects;
     rects.setAutoDelete(true);
-    
+
     rects.append(new IntRect);
-    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
+    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
         rects.append(new IntRect(curr->xPos(), curr->yPos(), curr->width(), curr->height()));
-    }
+
     rects.append(new IntRect);
-    
+
     for (unsigned int i = 1; i < rects.count() - 1; i++)
         paintOutlineForLine(p, _tx, _ty, *rects.at(i-1), *rects.at(i), *rects.at(i+1));
 }
index 22242163c096c43e191df267e1f4b77b5a328eee..0779b604ff8e112798801cb1f2bf0c1bef466dc9 100644 (file)
@@ -87,9 +87,8 @@ public:
     virtual IntRect caretRect(int offset, EAffinity affinity = UPSTREAM, int *extraWidthToEndOfLine = 0);
 
     virtual void addFocusRingRects(GraphicsContext*, int _tx, int _ty);
-    void paintFocusRing(GraphicsContext*, int tx, int ty);
     void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect &prevLine, const IntRect &thisLine, const IntRect &nextLine);
-    void paintOutlines(GraphicsContext*, int tx, int ty);
+    void paintOutline(GraphicsContext*, int tx, int ty);
 
 protected:
     // An inline can be split with blocks occurring in between the inline content.
index e01086878dd68b2c9cc4f06cdcc47737a8f46e7e..759406650b013d391a93e30ba8fa33413afe6cbe 100644 (file)
@@ -33,7 +33,6 @@
 #include "CounterNode.h"
 #include "CounterResetNode.h"
 #include "Decoder.h"
-#include "Document.h"
 #include "Element.h"
 #include "EventNames.h"
 #include "FloatRect.h"
@@ -41,6 +40,7 @@
 #include "GraphicsContext.h"
 #include "HTMLNames.h"
 #include "HTMLOListElement.h"
+#include "KURL.h"
 #include "Position.h"
 #include "RenderArena.h"
 #include "RenderFlexibleBox.h"
@@ -1639,6 +1639,28 @@ IntRect RenderObject::paintingRootRect(IntRect& topLevelRect)
     return result;
 }
 
+void RenderObject::addPDFURLRect(GraphicsContext* p, IntRect rect)
+{
+    Node* node = element();
+    if (node) {
+        if (p) {
+            if (rect.width() > 0 && rect.height() > 0) {
+                Element* element = static_cast<Element*>(node);
+                String href;
+                if (element->isLink())
+                    href = element->getAttribute(hrefAttr);
+                    
+                if (!href.isNull()) {
+                    KURL link = element->document()->completeURL(href.deprecatedString());
+                    if (link.isValid())
+                        p->setURLForRect(link, rect);
+                }
+            }
+        }
+    }
+}
+
+
 void RenderObject::addFocusRingRects(GraphicsContext* p, int _tx, int _ty)
 {
     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
@@ -1656,12 +1678,12 @@ void RenderObject::addFocusRingRects(GraphicsContext* p, int _tx, int _ty)
 
 void RenderObject::paintOutline(GraphicsContext* p, int _tx, int _ty, int w, int h, const RenderStyle* style)
 {
+    if (!hasOutline())
+        return;
+    
     int ow = style->outlineWidth();
-    if(!ow) return;
 
     EBorderStyle os = style->outlineStyle();
-    if (os <= BHIDDEN)
-        return;
     
     Color oc = style->outlineColor();
     if (!oc.isValid())
@@ -1669,17 +1691,22 @@ void RenderObject::paintOutline(GraphicsContext* p, int _tx, int _ty, int w, int
     
     int offset = style->outlineOffset();
     
-    if (style->outlineStyleIsAuto()) {
+    if (style->outlineStyleIsAuto() || hasOutlineAnnotation()) {
         if (!theme()->supportsFocusRing(style)) {
             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
             p->initFocusRing(ow, offset);
-            addFocusRingRects(p, _tx, _ty);
+            if (style->outlineStyleIsAuto())
+                addFocusRingRects(p, _tx, _ty);
+            else
+                addPDFURLRect(p, p->focusRingBoundingRect());
             p->drawFocusRing(oc);
             p->clearFocusRing();
         }
-        return;
     }
 
+    if (style->outlineStyleIsAuto() || style->outlineStyle() <= BHIDDEN)
+        return;
+
     _tx -= offset;
     _ty -= offset;
     w += 2*offset;
index 64f09fc295c5a17afabd12e19256183318ee02df..f7a905c3eb35727e6206692796ca3b55bbda7809 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "CachedResourceClient.h"
 #include "DeprecatedValueList.h"
+#include "Document.h"
 #include "RenderStyle.h"
 #include "ScrollBar.h"
 #include "VisiblePosition.h"
@@ -346,6 +347,9 @@ public:
     void setNode(Node* node) { m_node = node; }
     Node* node() const { return m_node; }
     
+    bool hasOutlineAnnotation() { return element() && element()->isLink() && document()->printing(); }
+    bool hasOutline() { return style()->hasOutline() || hasOutlineAnnotation(); }
+   
    /**
      * returns the object containing this one. can be different from parent for
      * positioned elements
@@ -702,6 +706,8 @@ public:
     // the rect that will be painted if this object is passed as the paintingRoot
     IntRect paintingRootRect(IntRect& topLevelRect);
 
+    void addPDFURLRect(GraphicsContext* p, IntRect rect);
+
     virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
 
     virtual int minWidth() const { return 0; }
index 4ce0f94bb14a97db4c5d1a69f534e38413dc67e1..9232abda9e36e28a7b89faa0a7f3856f6d3fb9fc 100644 (file)
@@ -1249,6 +1249,7 @@ public:
             return 0;
         return background->m_outline.width;
     }
+    bool hasOutline() const { return outlineWidth() > 0 && outlineStyle() > BHIDDEN; }
     EBorderStyle   outlineStyle() const {  return background->m_outline.style(); }
     bool outlineStyleIsAuto() const { return background->m_outline._auto; }
     const Color &  outlineColor() const {  return background->m_outline.color; }