Changeset 39427 in webkit


Ignore:
Timestamp:
Dec 21, 2008 3:44:16 PM (15 years ago)
Author:
krit@webkit.org
Message:

2008-12-21 Dirk Schulze <krit@webkit.org>

Reviewed by Darin Adler, Nikolas Zimmermann.

Move the the platform dependent strokeBBox functionality out of RenderPath
into Path with strokeBoundingRect.

RenderPath clean-up for strokeBoundingBox
https://bugs.webkit.org/show_bug.cgi?id=22902

  • GNUmakefile.am:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/GraphicsContext.h:
  • platform/graphics/Path.h:
  • platform/graphics/StrokeStyleApplier.h: Added. (WebCore::StrokeStyleApplier::~StrokeStyleApplier):
  • platform/graphics/cairo/PathCairo.cpp: (WebCore::Path::strokeBoundingRect):
  • platform/graphics/cg/PathCG.cpp: (WebCore::createScratchContext): (WebCore::scratchContext): (WebCore::Path::strokeBoundingRect):
  • platform/graphics/qt/GraphicsContextQt.cpp: (WebCore::GraphicsContext::pen):
  • platform/graphics/qt/PathQt.cpp: (WebCore::Path::strokeBoundingRect):
  • rendering/RenderPath.cpp: (WebCore::StrokeBoundingRectStyleApplier::StrokeBoundingRectStyleApplier): (WebCore::StrokeBoundingRectStyleApplier::strokeStyle): (WebCore::RenderPath::relativeBBox):
  • rendering/RenderPath.h:
  • svg/graphics/cairo/RenderPathCairo.cpp:
  • svg/graphics/cg/RenderPathCg.cpp:
  • svg/graphics/qt/RenderPathQt.cpp:
Location:
trunk/WebCore
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r39424 r39427  
     12008-12-21  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Darin Adler, Nikolas Zimmermann.
     4
     5        Move the the platform dependent strokeBBox functionality out of RenderPath
     6        into Path with strokeBoundingRect.
     7
     8        RenderPath clean-up for strokeBoundingBox
     9        [https://bugs.webkit.org/show_bug.cgi?id=22902]
     10
     11        * GNUmakefile.am:
     12        * WebCore.xcodeproj/project.pbxproj:
     13        * platform/graphics/GraphicsContext.h:
     14        * platform/graphics/Path.h:
     15        * platform/graphics/StrokeStyleApplier.h: Added.
     16        (WebCore::StrokeStyleApplier::~StrokeStyleApplier):
     17        * platform/graphics/cairo/PathCairo.cpp:
     18        (WebCore::Path::strokeBoundingRect):
     19        * platform/graphics/cg/PathCG.cpp:
     20        (WebCore::createScratchContext):
     21        (WebCore::scratchContext):
     22        (WebCore::Path::strokeBoundingRect):
     23        * platform/graphics/qt/GraphicsContextQt.cpp:
     24        (WebCore::GraphicsContext::pen):
     25        * platform/graphics/qt/PathQt.cpp:
     26        (WebCore::Path::strokeBoundingRect):
     27        * rendering/RenderPath.cpp:
     28        (WebCore::StrokeBoundingRectStyleApplier::StrokeBoundingRectStyleApplier):
     29        (WebCore::StrokeBoundingRectStyleApplier::strokeStyle):
     30        (WebCore::RenderPath::relativeBBox):
     31        * rendering/RenderPath.h:
     32        * svg/graphics/cairo/RenderPathCairo.cpp:
     33        * svg/graphics/cg/RenderPathCg.cpp:
     34        * svg/graphics/qt/RenderPathQt.cpp:
     35
    1362008-12-20  David Kilzer  <ddkilzer@apple.com>
    237
  • trunk/WebCore/GNUmakefile.am

    r39408 r39427  
    13271327        WebCore/platform/graphics/StringTruncator.cpp \
    13281328        WebCore/platform/graphics/StringTruncator.h \
     1329        WebCore/platform/graphics/StrokeStyleApplier.h \
    13291330        WebCore/platform/graphics/TextRun.h \
    13301331        WebCore/platform/graphics/UnitBezier.h \
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r39388 r39427  
    874874                75793ED40D0CE85B007FC0AC /* DOMMessageEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 75793ED10D0CE85B007FC0AC /* DOMMessageEvent.mm */; };
    875875                75793ED50D0CE85B007FC0AC /* DOMMessageEventInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 75793ED20D0CE85B007FC0AC /* DOMMessageEventInternal.h */; };
     876                849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */ = {isa = PBXBuildFile; fileRef = 849F77750EFEC6200090849D /* StrokeStyleApplier.h */; };
    876877                85004D940ACEEAEF00C438F6 /* DOMSVGDefsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 85004D880ACEEAEF00C438F6 /* DOMSVGDefsElement.h */; };
    877878                85004D950ACEEAEF00C438F6 /* DOMSVGDefsElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85004D890ACEEAEF00C438F6 /* DOMSVGDefsElement.mm */; };
     
    57535754                75793ED10D0CE85B007FC0AC /* DOMMessageEvent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMMessageEvent.mm; sourceTree = "<group>"; };
    57545755                75793ED20D0CE85B007FC0AC /* DOMMessageEventInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMMessageEventInternal.h; sourceTree = "<group>"; };
     5756                849F77750EFEC6200090849D /* StrokeStyleApplier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrokeStyleApplier.h; sourceTree = "<group>"; };
    57555757                84B2B1F7056BEF3A00D2B771 /* WebCoreKeyGenerator.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreKeyGenerator.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
    57565758                84B2B1F8056BEF3A00D2B771 /* WebCoreKeyGenerator.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebCoreKeyGenerator.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
     
    95759577                                49E911BB0EF86D47009D0CAF /* ScaleTransformOperation.h */,
    95769578                                49E911BC0EF86D47009D0CAF /* SkewTransformOperation.cpp */,
     9579                                849F77750EFEC6200090849D /* StrokeStyleApplier.h */,
    95779580                                49E911BD0EF86D47009D0CAF /* SkewTransformOperation.h */,
    95789581                                49E911BE0EF86D47009D0CAF /* TransformOperation.h */,
     
    1645616459                                49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */,
    1645716460                                49E912AE0EFAC906009D0CAF /* TimingFunction.h in Headers */,
     16461                                849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */,
    1645816462                        );
    1645916463                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/platform/graphics/GraphicsContext.h

    r39105 r39427  
    313313        bool inTransparencyLayer() const;
    314314        PlatformPath* currentPath();
     315        QPen pen();
    315316#endif
    316317
  • trunk/WebCore/platform/graphics/Path.h

    r35966 r39427  
    5757    class FloatSize;
    5858    class FloatRect;
     59    class GraphicsContext;
    5960    class String;
     61    class StrokeStyleApplier;
    6062
    6163    enum WindRule {
     
    8991        bool contains(const FloatPoint&, WindRule rule = RULE_NONZERO) const;
    9092        FloatRect boundingRect() const;
     93        FloatRect strokeBoundingRect(StrokeStyleApplier* applier = 0);
    9194       
    9295        float length();
  • trunk/WebCore/platform/graphics/cairo/PathCairo.cpp

    r38794 r39427  
    2828#include "CairoPath.h"
    2929#include "FloatRect.h"
     30#include "GraphicsContext.h"
    3031#include "NotImplemented.h"
    3132#include "PlatformString.h"
     33#include "StrokeStyleApplier.h"
    3234
    3335#include <cairo.h>
     
    189191}
    190192
     193FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
     194{
     195    cairo_t* cr = platformPath()->m_cr;
     196    GraphicsContext gc(cr);
     197    if (applier)
     198        applier->strokeStyle(&gc);
     199
     200    double x0, x1, y0, y1;
     201    cairo_stroke_extents(cr, &x0, &y0, &x1, &y1);
     202    return FloatRect(x0, y0, x1 - x0, y1 - y0);
     203}
     204
    191205bool Path::contains(const FloatPoint& point, WindRule rule) const
    192206{
  • trunk/WebCore/platform/graphics/cg/PathCG.cpp

    r38794 r39427  
    3333#include <ApplicationServices/ApplicationServices.h>
    3434#include "FloatRect.h"
     35#include "GraphicsContext.h"
    3536#include "IntRect.h"
    3637#include "PlatformString.h"
     38#include "StrokeStyleApplier.h"
    3739
    3840#include <wtf/MathExtras.h>
     
    6365}
    6466
     67static CGContextRef createScratchContext()
     68{
     69    CFMutableDataRef empty = CFDataCreateMutable(NULL, 0);
     70    CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(empty);
     71    CGContextRef contextRef = CGPDFContextCreate(consumer, NULL, NULL);
     72    CGDataConsumerRelease(consumer);
     73    CFRelease(empty);
     74
     75    CGFloat black[4] = {0, 0, 0, 1};
     76    CGContextSetFillColor(contextRef, black);
     77    CGContextSetStrokeColor(contextRef, black);
     78    return contextRef;
     79}
     80
     81static inline CGContextRef scratchContext()
     82{
     83    static CGContextRef context = createScratchContext();
     84    return context;
     85}
    6586
    6687static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element)
     
    122143{
    123144    return CGPathGetBoundingBox(m_path);
     145}
     146
     147FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
     148{
     149    CGContextRef context = scratchContext();
     150
     151    CGContextSaveGState(context);
     152    CGContextBeginPath(context);
     153    CGContextAddPath(context, platformPath());
     154
     155    GraphicsContext gc(context);
     156    if (applier)
     157        applier->strokeStyle(&gc);
     158
     159    CGContextReplacePathWithStrokedPath(context);
     160    if (CGContextIsPathEmpty(context)) {
     161        CGContextRestoreGState(context);
     162        return FloatRect();
     163    }
     164    CGRect box = CGContextGetPathBoundingBox(context);
     165    CGContextRestoreGState(context);
     166
     167    return box;
    124168}
    125169
  • trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

    r38785 r39427  
    526526}
    527527
     528QPen GraphicsContext::pen()
     529{
     530    if (paintingDisabled())
     531        return QPen();
     532
     533    QPainter *p = m_data->p();
     534    return p->pen();
     535}
     536
    528537void GraphicsContext::fillPath()
    529538{
  • trunk/WebCore/platform/graphics/qt/PathQt.cpp

    r38618 r39427  
    3030#include "Path.h"
    3131
     32#include "AffineTransform.h"
    3233#include "FloatRect.h"
     34#include "GraphicsContext.h"
     35#include "ImageBuffer.h"
    3336#include "PlatformString.h"
    34 #include "AffineTransform.h"
     37#include "StrokeStyleApplier.h"
    3538#include <QPainterPath>
    3639#include <QMatrix>
     
    9295{
    9396    return m_path->boundingRect();
     97}
     98
     99FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
     100{
     101    // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer
     102    // on each call.
     103    std::auto_ptr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1), false);
     104    GraphicsContext* gc = scratchImage->context();
     105    QPainterPathStroker stroke;
     106    if (applier) {
     107        applier->strokeStyle(gc);
     108
     109        QPen pen = gc->pen();
     110        stroke.setWidth(pen.widthF());
     111        stroke.setCapStyle(pen.capStyle());
     112        stroke.setJoinStyle(pen.joinStyle());
     113        stroke.setMiterLimit(pen.miterLimit());
     114        stroke.setDashPattern(pen.dashPattern());
     115        stroke.setDashOffset(pen.dashOffset());
     116    }
     117    return (stroke.createStroke(*platformPath())).boundingRect();
    94118}
    95119
  • trunk/WebCore/rendering/RenderPath.cpp

    r38353 r39427  
    3333#include "PointerEventsHitRules.h"
    3434#include "RenderSVGContainer.h"
     35#include "StrokeStyleApplier.h"
    3536#include "SVGPaintServer.h"
    3637#include "SVGRenderSupport.h"
     
    4647namespace WebCore {
    4748
     49class BoundingRectStrokeStyleApplier : public StrokeStyleApplier {
     50public:
     51    BoundingRectStrokeStyleApplier(const RenderObject* object, RenderStyle* style)
     52        : m_object(object)
     53        , m_style(style)
     54    {
     55        ASSERT(style);
     56        ASSERT(object);
     57    }
     58
     59    void strokeStyle(GraphicsContext* gc)
     60    {
     61        applyStrokeStyleToContext(gc, m_style, m_object);
     62    }
     63
     64private:
     65    const RenderObject* m_object;
     66    RenderStyle* m_style;
     67};
     68
    4869// RenderPath
    4970RenderPath::RenderPath(RenderStyle* style, SVGStyledTransformableElement* node)
     
    90111
    91112    if (includeStroke) {
    92         if (m_strokeBbox.isEmpty())
    93             m_strokeBbox = strokeBBox();
     113        if (m_strokeBbox.isEmpty()) {
     114            if (style()->svgStyle()->hasStroke()) {
     115                BoundingRectStrokeStyleApplier strokeStyle(this, style());
     116                m_strokeBbox = m_path.strokeBoundingRect(&strokeStyle);
     117            } else {
     118                if (m_fillBBox.isEmpty())
     119                    m_fillBBox = m_path.boundingRect();
     120
     121                m_strokeBbox = m_fillBBox;
     122            }
     123        }
    94124
    95125        return m_strokeBbox;
  • trunk/WebCore/rendering/RenderPath.h

    r38346 r39427  
    4747
    4848    // Hit-detection seperated for the fill and the stroke
    49     virtual bool fillContains(const FloatPoint&, bool requiresFill = true) const;
    50     virtual bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
     49    bool fillContains(const FloatPoint&, bool requiresFill = true) const;
     50    bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
    5151
    5252    // Returns an unscaled bounding box (not even including localTransform()) for this vector path
     
    7676
    7777    FloatRect drawMarkersIfNeeded(GraphicsContext*, const FloatRect&, const Path&) const;
    78     virtual FloatRect strokeBBox() const;
    7978   
    8079private:
  • trunk/WebCore/svg/graphics/cairo/RenderPathCairo.cpp

    r29663 r39427  
    3737}
    3838
    39 FloatRect RenderPath::strokeBBox() const
    40 {
    41     // TODO: this implementation is naive
    42 
    43     cairo_t* cr = path().platformPath()->m_cr;
    44 
    45     double x0, x1, y0, y1;
    46     cairo_stroke_extents(cr, &x0, &y0, &x1, &y1);
    47     FloatRect bbox = FloatRect(x0, y0, x1 - x0, y1 - y0);
    48 
    49     return bbox;
    5039}
    51 
    52 }
  • trunk/WebCore/svg/graphics/cg/RenderPathCg.cpp

    r29216 r39427  
    4141namespace WebCore {
    4242
    43 FloatRect RenderPath::strokeBBox() const
    44 {
    45     if (style()->svgStyle()->hasStroke())
    46         return strokeBoundingBox(path(), style(), this);
    47 
    48     return path().boundingRect();
    49 }
    50 
    51 
    5243bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
    5344{
  • trunk/WebCore/svg/graphics/qt/RenderPathQt.cpp

    r29663 r39427  
    4343}
    4444
    45 static QPainterPath getPathStroke(const QPainterPath &path, const RenderObject* object, const RenderStyle* style)
    46 {
    47     QPainterPathStroker s;
    48     s.setWidth(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0));
    49 
    50     if (style->svgStyle()->capStyle() == ButtCap)
    51         s.setCapStyle(Qt::FlatCap);
    52     else if (style->svgStyle()->capStyle() == RoundCap)
    53         s.setCapStyle(Qt::RoundCap);
    54 
    55     if (style->svgStyle()->joinStyle() == MiterJoin) {
    56         s.setJoinStyle(Qt::MiterJoin);
    57         s.setMiterLimit((qreal) style->svgStyle()->strokeMiterLimit());
    58     } else if(style->svgStyle()->joinStyle() == RoundJoin)
    59         s.setJoinStyle(Qt::RoundJoin);
    60 
    61     const DashArray& dashes = WebCore::dashArrayFromRenderingStyle(style);
    62     double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0);
    63 
    64     unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0;
    65     if(dashLength) {
    66         QVector<qreal> pattern;
    67         unsigned int count = (dashLength % 2) == 0 ? dashLength : dashLength * 2;
    68 
    69         for(unsigned int i = 0; i < count; i++)
    70             pattern.append(dashes[i % dashLength] / (float)s.width());
    71 
    72         s.setDashPattern(pattern);
    73    
    74         Q_UNUSED(dashOffset);
    75         // TODO: dash-offset, does/will qt4 API allow it? (Rob)
    76     }
    77 
    78     return s.createStroke(path);
    79 }
    80 
    81 FloatRect RenderPath::strokeBBox() const
    82 {
    83     QPainterPath outline = getPathStroke(*(path().platformPath()), this, style());
    84     return outline.boundingRect();
    85 }
    86 
    8745}
    8846
Note: See TracChangeset for help on using the changeset viewer.