Commit 6e760ffb authored by bdakin's avatar bdakin
Browse files

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.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@17052 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9763f319
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
......@@ -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())
......
......@@ -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&);
......
......@@ -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)
......@@ -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)
......@@ -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());
}
......
......@@ -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,
......
......@@ -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));
}
......
......@@ -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.
......
......@@ -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;
......
......@@ -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; }
......
......@@ -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; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment