Changeset 117971 in webkit


Ignore:
Timestamp:
May 22, 2012 7:42:10 AM (12 years ago)
Author:
Nikolas Zimmermann
Message:

Crash in WebCore::RenderSVGContainer::paint
https://bugs.webkit.org/show_bug.cgi?id=86392

Reviewed by Rob Buis.

Source/WebCore:

Modernize the <marker> code, switch to the same design pattern used for handling zero-length subpaths.
Decouple the generation of the marker start/mid/end positions from the actual usage of these information.
Only generate those marker positions if the underlying Path changes, and never else.

When figuring out the bounds for a shape, access to current set of RenderSVGResourceMarker start/mid/end resources
and ask the marker resources for their bounds using the previously figured out marker positions on the Path.
Drawing markers is handled in the same way.

Remove SVGMarkerLayoutInfo alltogether which stored raw pointers to the RenderSVGResourceMarkers.
We assumed that those objects would stay alive from layout() to paint(), but that assumption is wrong.

Tests: svg/custom/bug86392.html

svg/custom/marker-zero-length-linecaps-expected.svg
svg/custom/marker-zero-length-linecaps.svg

  • CMakeLists.txt: Remove SVGMarkerLayoutInfo.*.
  • GNUmakefile.list.am: Ditto.
  • Target.pri: Ditto.
  • WebCore.gypi: Ditto.
  • WebCore.order: Ditto.
  • WebCore.vcproj/WebCore.vcproj: Ditto.
  • WebCore.xcodeproj/project.pbxproj: Ditto.
  • rendering/svg/RenderSVGAllInOne.cpp: Ditto.
  • rendering/svg/RenderSVGShape.cpp: Handle markers just like the existing zero leng subpath code, which is superior.

(WebCore::RenderSVGShape::createShape):
(WebCore::RenderSVGShape::layout):
(WebCore::RenderSVGShape::shouldGenerateMarkerPositions):
(WebCore::RenderSVGShape::paint):
(WebCore::markerForType):
(WebCore::RenderSVGShape::markerRect):
(WebCore::RenderSVGShape::inflateWithStrokeAndMarkerBounds):
(WebCore::RenderSVGShape::drawMarkers):
(WebCore::RenderSVGShape::processMarkerPositions):

  • rendering/svg/RenderSVGShape.h:

(RenderSVGShape):

  • rendering/svg/SVGMarkerData.h:

(WebCore::MarkerPosition::MarkerPosition):
(MarkerPosition):
(WebCore::SVGMarkerData::SVGMarkerData):
(WebCore::SVGMarkerData::updateFromPathElement):
(WebCore::SVGMarkerData::pathIsDone):
(SVGMarkerData):
(WebCore::SVGMarkerData::currentAngle):

  • rendering/svg/SVGMarkerLayoutInfo.cpp: Removed.
  • rendering/svg/SVGMarkerLayoutInfo.h: Removed.
  • rendering/svg/SVGResourcesCache.cpp:

(WebCore::resourcesCacheFromRenderObject):
(WebCore::SVGResourcesCache::cachedResourcesForRenderObject):

  • rendering/svg/SVGResourcesCache.h:

(SVGResourcesCache):

LayoutTests:

  • svg/custom/bug86392-expected.txt: Added.
  • svg/custom/bug86392.html: Added.
  • svg/custom/marker-zero-length-linecaps-expected.svg: Added.
  • svg/custom/marker-zero-length-linecaps.svg: Added.
Location:
trunk
Files:
4 added
2 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r117967 r117971  
     12012-05-22  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Crash in WebCore::RenderSVGContainer::paint
     4        https://bugs.webkit.org/show_bug.cgi?id=86392
     5
     6        Reviewed by Rob Buis.
     7
     8        * svg/custom/bug86392-expected.txt: Added.
     9        * svg/custom/bug86392.html: Added.
     10        * svg/custom/marker-zero-length-linecaps-expected.svg: Added.
     11        * svg/custom/marker-zero-length-linecaps.svg: Added.
     12
    1132012-05-22  Thiago Marcos P. Santos  <thiago.santos@intel.com>
    214
  • trunk/Source/WebCore/CMakeLists.txt

    r117898 r117971  
    18001800        rendering/svg/SVGInlineFlowBox.cpp
    18011801        rendering/svg/SVGInlineTextBox.cpp
    1802         rendering/svg/SVGMarkerLayoutInfo.cpp
    18031802        rendering/svg/SVGPathData.cpp
    18041803        rendering/svg/SVGRenderSupport.cpp
  • trunk/Source/WebCore/ChangeLog

    r117970 r117971  
     12012-05-22  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Crash in WebCore::RenderSVGContainer::paint
     4        https://bugs.webkit.org/show_bug.cgi?id=86392
     5
     6        Reviewed by Rob Buis.
     7
     8        Modernize the <marker> code, switch to the same design pattern used for handling zero-length subpaths.
     9        Decouple the generation of the marker start/mid/end positions from the actual usage of these information.
     10        Only generate those marker positions if the underlying Path changes, and never else.
     11
     12        When figuring out the bounds for a shape, access to current set of RenderSVGResourceMarker start/mid/end resources
     13        and ask the marker resources for their bounds using the previously figured out marker positions on the Path.
     14        Drawing markers is handled in the same way.
     15
     16        Remove SVGMarkerLayoutInfo alltogether which stored raw pointers to the RenderSVGResourceMarkers.
     17        We assumed that those objects would stay alive from layout() to paint(), but that assumption is wrong.
     18
     19        Tests: svg/custom/bug86392.html
     20               svg/custom/marker-zero-length-linecaps-expected.svg
     21               svg/custom/marker-zero-length-linecaps.svg
     22
     23        * CMakeLists.txt: Remove SVGMarkerLayoutInfo.*.
     24        * GNUmakefile.list.am: Ditto.
     25        * Target.pri: Ditto.
     26        * WebCore.gypi: Ditto.
     27        * WebCore.order: Ditto.
     28        * WebCore.vcproj/WebCore.vcproj: Ditto.
     29        * WebCore.xcodeproj/project.pbxproj: Ditto.
     30        * rendering/svg/RenderSVGAllInOne.cpp: Ditto.
     31        * rendering/svg/RenderSVGShape.cpp: Handle markers just like the existing zero leng subpath code, which is superior.
     32        (WebCore::RenderSVGShape::createShape):
     33        (WebCore::RenderSVGShape::layout):
     34        (WebCore::RenderSVGShape::shouldGenerateMarkerPositions):
     35        (WebCore::RenderSVGShape::paint):
     36        (WebCore::markerForType):
     37        (WebCore::RenderSVGShape::markerRect):
     38        (WebCore::RenderSVGShape::inflateWithStrokeAndMarkerBounds):
     39        (WebCore::RenderSVGShape::drawMarkers):
     40        (WebCore::RenderSVGShape::processMarkerPositions):
     41        * rendering/svg/RenderSVGShape.h:
     42        (RenderSVGShape):
     43        * rendering/svg/SVGMarkerData.h:
     44        (WebCore::MarkerPosition::MarkerPosition):
     45        (MarkerPosition):
     46        (WebCore::SVGMarkerData::SVGMarkerData):
     47        (WebCore::SVGMarkerData::updateFromPathElement):
     48        (WebCore::SVGMarkerData::pathIsDone):
     49        (SVGMarkerData):
     50        (WebCore::SVGMarkerData::currentAngle):
     51        * rendering/svg/SVGMarkerLayoutInfo.cpp: Removed.
     52        * rendering/svg/SVGMarkerLayoutInfo.h: Removed.
     53        * rendering/svg/SVGResourcesCache.cpp:
     54        (WebCore::resourcesCacheFromRenderObject):
     55        (WebCore::SVGResourcesCache::cachedResourcesForRenderObject):
     56        * rendering/svg/SVGResourcesCache.h:
     57        (SVGResourcesCache):
     58
    1592012-05-22  Alexander Pavlov  <apavlov@chromium.org>
    260
  • trunk/Source/WebCore/GNUmakefile.list.am

    r117898 r117971  
    40884088        Source/WebCore/rendering/svg/SVGInlineTextBox.h \
    40894089        Source/WebCore/rendering/svg/SVGMarkerData.h \
    4090         Source/WebCore/rendering/svg/SVGMarkerLayoutInfo.cpp \
    4091         Source/WebCore/rendering/svg/SVGMarkerLayoutInfo.h \
    40924090        Source/WebCore/rendering/svg/SVGPathData.cpp \
    40934091        Source/WebCore/rendering/svg/SVGPathData.h \
  • trunk/Source/WebCore/Target.pri

    r117899 r117971  
    25762576    rendering/svg/SVGInlineTextBox.h \
    25772577    rendering/svg/SVGMarkerData.h \
    2578     rendering/svg/SVGMarkerLayoutInfo.h \
    25792578    rendering/svg/SVGPathData.h \
    25802579    rendering/svg/SVGRenderSupport.h \
     
    35393538              rendering/svg/SVGInlineFlowBox.cpp \
    35403539              rendering/svg/SVGInlineTextBox.cpp \
    3541               rendering/svg/SVGMarkerLayoutInfo.cpp \
    35423540              rendering/svg/SVGPathData.cpp \
    35433541              rendering/svg/SVGRenderSupport.cpp \
  • trunk/Source/WebCore/WebCore.gypi

    r117898 r117971  
    49954995            'rendering/svg/SVGInlineTextBox.h',
    49964996            'rendering/svg/SVGMarkerData.h',
    4997             'rendering/svg/SVGMarkerLayoutInfo.cpp',
    4998             'rendering/svg/SVGMarkerLayoutInfo.h',
    49994997            'rendering/svg/SVGPathData.cpp',
    50004998            'rendering/svg/SVGPathData.h',
     
    59245922            'rendering/svg/SVGInlineTextBox.h',
    59255923            'rendering/svg/SVGMarkerData.h',
    5926             'rendering/svg/SVGMarkerLayoutInfo.cpp',
    5927             'rendering/svg/SVGMarkerLayoutInfo.h',
    59285924            'rendering/svg/SVGPathData.cpp',
    59295925            'rendering/svg/SVGPathData.h',
  • trunk/Source/WebCore/WebCore.order

    r117210 r117971  
    2890328903__ZN7WebCore13RenderSVGPath29calculateMarkerBoundsIfNeededEv
    2890428904__ZNK7WebCore14SVGPathElement15supportsMarkersEv
    28905 __ZN7WebCore19SVGMarkerLayoutInfo19calculateBoundariesEPNS_23RenderSVGResourceMarkerES2_S2_fRKNS_4PathE
    2890628905__ZN7WebCoreL25processStartAndMidMarkersEPvPKNS_11PathElementE
    2890728906__ZN7WebCore13SVGMarkerData30updateMarkerDataForPathElementEPKNS_11PathElementE
    28908 __ZN7WebCore19SVGMarkerLayoutInfo17addLayoutedMarkerEPNS_23RenderSVGResourceMarkerERKNS_10FloatPointEf
    2890928907__ZNK7WebCore23RenderSVGResourceMarker20markerTransformationERKNS_10FloatPointEff
    2891028908__ZNK7WebCore8SVGAngle5valueEv
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r117898 r117971  
    4358943589                        </File>
    4359043590                        <File
    43591                                 RelativePath="..\rendering\svg\SVGMarkerLayoutInfo.cpp"
    43592                                 >
    43593                                 <FileConfiguration
    43594                                         Name="Debug|Win32"
    43595                                         ExcludedFromBuild="true"
    43596                                         >
    43597                                         <Tool
    43598                                                 Name="VCCLCompilerTool"
    43599                                         />
    43600                                 </FileConfiguration>
    43601                                 <FileConfiguration
    43602                                         Name="Release|Win32"
    43603                                         ExcludedFromBuild="true"
    43604                                         >
    43605                                         <Tool
    43606                                                 Name="VCCLCompilerTool"
    43607                                         />
    43608                                 </FileConfiguration>
    43609                                 <FileConfiguration
    43610                                         Name="Debug_Cairo_CFLite|Win32"
    43611                                         ExcludedFromBuild="true"
    43612                                         >
    43613                                         <Tool
    43614                                                 Name="VCCLCompilerTool"
    43615                                         />
    43616                                 </FileConfiguration>
    43617                                 <FileConfiguration
    43618                                         Name="Release_Cairo_CFLite|Win32"
    43619                                         ExcludedFromBuild="true"
    43620                                         >
    43621                                         <Tool
    43622                                                 Name="VCCLCompilerTool"
    43623                                         />
    43624                                 </FileConfiguration>
    43625                                 <FileConfiguration
    43626                                         Name="Debug_All|Win32"
    43627                                         ExcludedFromBuild="true"
    43628                                         >
    43629                                         <Tool
    43630                                                 Name="VCCLCompilerTool"
    43631                                         />
    43632                                 </FileConfiguration>
    43633                                 <FileConfiguration
    43634                                         Name="Production|Win32"
    43635                                         ExcludedFromBuild="true"
    43636                                         >
    43637                                         <Tool
    43638                                                 Name="VCCLCompilerTool"
    43639                                         />
    43640                                 </FileConfiguration>
    43641                         </File>
    43642                         <File
    43643                                 RelativePath="..\rendering\svg\SVGMarkerLayoutInfo.h"
    43644                                 >
    43645                         </File>
    43646                         <File
    4364743591                                RelativePath="..\rendering\svg\SVGPathData.cpp"
    4364843592                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r117898 r117971  
    11291129                436708EB12D9CA4B00044234 /* RenderSVGViewportContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */; };
    11301130                436708EE12D9CA4B00044234 /* SVGMarkerData.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AF12D9CA4B00044234 /* SVGMarkerData.h */; };
    1131                 436708F012D9CA4B00044234 /* SVGMarkerLayoutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708B112D9CA4B00044234 /* SVGMarkerLayoutInfo.h */; };
    11321131                436708F212D9CA4B00044234 /* SVGRenderSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708B312D9CA4B00044234 /* SVGRenderSupport.h */; };
    11331132                436708F412D9CA4B00044234 /* SVGRenderTreeAsText.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708B512D9CA4B00044234 /* SVGRenderTreeAsText.h */; };
     
    81138112                436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGViewportContainer.h; sourceTree = "<group>"; };
    81148113                436708AF12D9CA4B00044234 /* SVGMarkerData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMarkerData.h; sourceTree = "<group>"; };
    8115                 436708B012D9CA4B00044234 /* SVGMarkerLayoutInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGMarkerLayoutInfo.cpp; sourceTree = "<group>"; };
    8116                 436708B112D9CA4B00044234 /* SVGMarkerLayoutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMarkerLayoutInfo.h; sourceTree = "<group>"; };
    81178114                436708B212D9CA4B00044234 /* SVGRenderSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGRenderSupport.cpp; sourceTree = "<group>"; };
    81188115                436708B312D9CA4B00044234 /* SVGRenderSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGRenderSupport.h; sourceTree = "<group>"; };
     
    1392813925                                0854B00F1255E4E600B9CDD0 /* SVGInlineTextBox.h */,
    1392913926                                436708AF12D9CA4B00044234 /* SVGMarkerData.h */,
    13930                                 436708B012D9CA4B00044234 /* SVGMarkerLayoutInfo.cpp */,
    13931                                 436708B112D9CA4B00044234 /* SVGMarkerLayoutInfo.h */,
    1393213927                                715379FE146BD9D6008BD615 /* SVGPathData.cpp */,
    1393313928                                715379FF146BD9D6008BD615 /* SVGPathData.h */,
     
    2453324528                                436708EE12D9CA4B00044234 /* SVGMarkerData.h in Headers */,
    2453424529                                B2227A440D00BF220071B782 /* SVGMarkerElement.h in Headers */,
    24535                                 436708F012D9CA4B00044234 /* SVGMarkerLayoutInfo.h in Headers */,
    2453624530                                B2227A470D00BF220071B782 /* SVGMaskElement.h in Headers */,
    2453724531                                0806E57A12893045007CED32 /* SVGMatrix.h in Headers */,
  • trunk/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp

    r112667 r117971  
    5959#include "SVGInlineFlowBox.cpp"
    6060#include "SVGInlineTextBox.cpp"
    61 #include "SVGMarkerLayoutInfo.cpp"
    6261#include "SVGPathData.cpp"
    6362#include "SVGRenderSupport.cpp"
  • trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp

    r117709 r117971  
    4141#include "RenderSVGResourceSolidColor.h"
    4242#include "SVGPathData.h"
    43 #include "SVGPathElement.h"
    4443#include "SVGRenderingContext.h"
    4544#include "SVGResources.h"
     
    7372    ASSERT(isEmpty());
    7473
    75     SVGPathElement* element = static_cast<SVGPathElement*>(node());
     74    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
    7675    updatePathFromGraphicsElement(element, path());
    7776    processZeroLengthSubpaths();
     77    processMarkerPositions();
    7878}
    7979
     
    188188
    189189    // Invalidate all resources of this client if our layout changed.
    190     if (everHadLayout() && selfNeedsLayout()) {
     190    if (everHadLayout() && selfNeedsLayout())
    191191        SVGResourcesCache::clientLayoutChanged(this);
    192         m_markerLayoutInfo.clear();
    193     }
    194192
    195193    // At this point LayoutRepainter already grabbed the old bounds,
     
    239237    // but shall be stroked if the "stroke-linecap" property has a value of round or square
    240238    return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap;
     239}
     240
     241bool RenderSVGShape::shouldGenerateMarkerPositions() const
     242{
     243    if (!style()->svgStyle()->hasMarkers())
     244        return false;
     245
     246    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
     247    if (!element->supportsMarkers())
     248        return false;
     249
     250    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
     251    if (!resources)
     252        return false;
     253
     254    return resources->markerStart() || resources->markerMid() || resources->markerEnd();
    241255}
    242256
     
    354368
    355369                fillAndStrokePath(childPaintInfo.context);
    356 
    357                 if (svgStyle->hasMarkers())
    358                     m_markerLayoutInfo.drawMarkers(childPaintInfo);
     370                if (!m_markerPositions.isEmpty())
     371                    drawMarkers(childPaintInfo);
    359372            }
    360373        }
     
    401414}
    402415
    403 FloatRect RenderSVGShape::calculateMarkerBoundsIfNeeded()
    404 {
    405     SVGElement* svgElement = static_cast<SVGElement*>(node());
    406     ASSERT(svgElement && svgElement->document());
    407     if (!svgElement->isStyled())
    408         return FloatRect();
    409 
    410     SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
    411     if (!styledElement->supportsMarkers())
    412         return FloatRect();
    413 
    414     ASSERT(style()->svgStyle()->hasMarkers());
     416static inline RenderSVGResourceMarker* markerForType(SVGMarkerType type, RenderSVGResourceMarker* markerStart, RenderSVGResourceMarker* markerMid, RenderSVGResourceMarker* markerEnd)
     417{
     418    switch (type) {
     419    case StartMarker:
     420        return markerStart;
     421    case MidMarker:
     422        return markerMid;
     423    case EndMarker:
     424        return markerEnd;
     425    }
     426
     427    ASSERT_NOT_REACHED();
     428    return 0;
     429}
     430
     431FloatRect RenderSVGShape::markerRect(float strokeWidth) const
     432{
     433    ASSERT(!m_markerPositions.isEmpty());
    415434
    416435    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
    417     if (!resources)
    418         return FloatRect();
     436    ASSERT(resources);
    419437
    420438    RenderSVGResourceMarker* markerStart = resources->markerStart();
    421439    RenderSVGResourceMarker* markerMid = resources->markerMid();
    422440    RenderSVGResourceMarker* markerEnd = resources->markerEnd();
    423     if (!markerStart && !markerMid && !markerEnd)
    424         return FloatRect();
    425 
    426     return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, strokeWidth(), path());
     441    ASSERT(markerStart || markerMid || markerEnd);
     442
     443    FloatRect boundaries;
     444    unsigned size = m_markerPositions.size();
     445    for (unsigned i = 0; i < size; ++i) {
     446        if (RenderSVGResourceMarker* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd))
     447            boundaries.unite(marker->markerBoundaries(marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth)));
     448    }
     449    return boundaries;
    427450}
    428451
     
    464487{
    465488    const SVGRenderStyle* svgStyle = style()->svgStyle();
    466     FloatRect strokeRect;
    467489    if (svgStyle->hasStroke()) {
    468490        BoundingRectStrokeStyleApplier strokeStyle(this, style());
     
    480502            m_strokeAndMarkerBoundingBox.unite(path().strokeBoundingRect(&strokeStyle));
    481503    }
    482     if (svgStyle->hasMarkers()) {
    483         FloatRect markerBounds = calculateMarkerBoundsIfNeeded();
    484         if (!markerBounds.isEmpty())
    485             m_strokeAndMarkerBoundingBox.unite(markerBounds);
     504    if (!m_markerPositions.isEmpty())
     505        m_strokeAndMarkerBoundingBox.unite(markerRect(strokeWidth()));
     506}
     507
     508void RenderSVGShape::drawMarkers(PaintInfo& paintInfo)
     509{
     510    ASSERT(!m_markerPositions.isEmpty());
     511
     512    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
     513    if (!resources)
     514        return;
     515
     516    RenderSVGResourceMarker* markerStart = resources->markerStart();
     517    RenderSVGResourceMarker* markerMid = resources->markerMid();
     518    RenderSVGResourceMarker* markerEnd = resources->markerEnd();
     519    if (!markerStart && !markerMid && !markerEnd)
     520        return;
     521
     522    float strokeWidth = this->strokeWidth();
     523    unsigned size = m_markerPositions.size();
     524    for (unsigned i = 0; i < size; ++i) {
     525        if (RenderSVGResourceMarker* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd))
     526            marker->draw(paintInfo, marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth));
    486527    }
    487528}
     
    502543}
    503544
     545void RenderSVGShape::processMarkerPositions()
     546{
     547    m_markerPositions.clear();
     548
     549    if (!shouldGenerateMarkerPositions())
     550        return;
     551
     552    ASSERT(m_path);
     553
     554    SVGMarkerData markerData(m_markerPositions);
     555    m_path->apply(&markerData, SVGMarkerData::updateFromPathElement);
     556    markerData.pathIsDone();
     557}
     558
    504559}
    505560
  • trunk/Source/WebCore/rendering/svg/RenderSVGShape.h

    r117709 r117971  
    3131#include "FloatRect.h"
    3232#include "RenderSVGModelObject.h"
    33 #include "SVGMarkerLayoutInfo.h"
     33#include "SVGMarkerData.h"
    3434#include "StrokeStyleApplier.h"
    3535#include <wtf/OwnPtr.h>
     
    9494    float strokeWidth() const;
    9595    void setIsPaintingFallback(bool isFallback) { m_fillFallback = isFallback; }
    96     FloatRect calculateMarkerBoundsIfNeeded();
    97     void processZeroLengthSubpaths();
    98 
    9996    bool hasPath() const { return m_path.get(); }
    10097    bool hasNonScalingStroke() const { return style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; }
     
    127124    bool shouldStrokeZeroLengthSubpath() const;
    128125    FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const;
     126    void processZeroLengthSubpaths();
     127
     128    bool shouldGenerateMarkerPositions() const;
     129    FloatRect markerRect(float strokeWidth) const;
     130    void processMarkerPositions();
    129131
    130132    void fillShape(RenderStyle*, GraphicsContext*, Path*, RenderSVGShape*);
     
    133135    void fillAndStrokePath(GraphicsContext*);
    134136    void inflateWithStrokeAndMarkerBounds();
     137    void drawMarkers(PaintInfo&);
    135138
    136139private:
     
    138141    FloatRect m_strokeAndMarkerBoundingBox;
    139142    FloatRect m_repaintBoundingBox;
    140     SVGMarkerLayoutInfo m_markerLayoutInfo;
    141143    AffineTransform m_localTransform;
    142144    OwnPtr<Path> m_path;
    143145    Vector<FloatPoint> m_zeroLengthLinecapLocations;
     146    Vector<MarkerPosition> m_markerPositions;
    144147
    145148    bool m_needsBoundariesUpdate : 1;
  • trunk/Source/WebCore/rendering/svg/SVGMarkerData.h

    r95901 r117971  
    3030class RenderSVGResourceMarker;
    3131
    32 class SVGMarkerData {
    33 public:
    34     enum Type {
    35         Unknown = 0,
    36         Start,
    37         Mid,
    38         End
    39     };
     32enum SVGMarkerType {
     33    StartMarker,
     34    MidMarker,
     35    EndMarker
     36};
    4037
    41     SVGMarkerData(const Type& type = Unknown, RenderSVGResourceMarker* marker = 0)
    42         : m_type(type)
    43         , m_marker(marker)
     38struct MarkerPosition {
     39    MarkerPosition(SVGMarkerType useType, const FloatPoint& useOrigin, float useAngle)
     40        : type(useType)
     41        , origin(useOrigin)
     42        , angle(useAngle)
    4443    {
    4544    }
    4645
    47     FloatPoint origin() const { return m_origin; }
    48     RenderSVGResourceMarker* marker() const { return m_marker; }
     46    SVGMarkerType type;
     47    FloatPoint origin;
     48    float angle;
     49};
    4950
    50     float currentAngle() const
     51class SVGMarkerData {
     52public:
     53    SVGMarkerData(Vector<MarkerPosition>& positions)
     54        : m_positions(positions)
     55        , m_elementIndex(0)
     56    {
     57    }
     58
     59    static void updateFromPathElement(void* info, const PathElement* element)
     60    {
     61        SVGMarkerData* markerData = static_cast<SVGMarkerData*>(info);
     62
     63        // First update the outslope for the previous element.
     64        markerData->updateOutslope(element->points[0]);
     65
     66        // Record the marker for the previous element.
     67        if (markerData->m_elementIndex > 0) {
     68            SVGMarkerType markerType = markerData->m_elementIndex == 1 ? StartMarker : MidMarker;
     69            markerData->m_positions.append(MarkerPosition(markerType, markerData->m_origin, markerData->currentAngle(markerType)));
     70        }
     71
     72        // Update our marker data for this element.
     73        markerData->updateMarkerDataForPathElement(element);
     74        ++markerData->m_elementIndex;
     75    }
     76
     77    void pathIsDone()
     78    {
     79        m_positions.append(MarkerPosition(EndMarker, m_origin, currentAngle(EndMarker)));
     80    }
     81
     82private:
     83    float currentAngle(SVGMarkerType type) const
    5184    {
    5285        FloatSize inslopeChange = m_inslopePoints[1] - m_inslopePoints[0];
     
    5689        double outslope = rad2deg(atan2(outslopeChange.height(), outslopeChange.width()));
    5790
    58         double angle = 0;
    59         switch (m_type) {
    60         case Start:
    61             angle = outslope;
    62             break;
    63         case Mid:
    64             angle = (inslope + outslope) / 2;
    65             break;
    66         case End:
    67             angle = inslope;
    68             break;
    69         default:
    70             ASSERT_NOT_REACHED();
    71             break;
     91        switch (type) {
     92        case StartMarker:
     93            return narrowPrecisionToFloat(outslope);
     94        case MidMarker:
     95            return narrowPrecisionToFloat((inslope + outslope) / 2);
     96        case EndMarker:
     97            return narrowPrecisionToFloat(inslope);
    7298        }
    7399
    74         return narrowPrecisionToFloat(angle);
    75     }
    76 
    77     void updateTypeAndMarker(const Type& type, RenderSVGResourceMarker* marker)
    78     {
    79         m_type = type;
    80         m_marker = marker;
     100        ASSERT_NOT_REACHED();
     101        return 0;
    81102    }
    82103
     
    114135    }
    115136
    116 private:
    117137    void updateInslope(const FloatPoint& point)
    118138    {
     
    121141    }
    122142
    123     Type m_type;
    124     RenderSVGResourceMarker* m_marker;
     143    Vector<MarkerPosition>& m_positions;
     144    unsigned m_elementIndex;
    125145    FloatPoint m_origin;
    126146    FloatPoint m_subpathStart;
  • trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp

    r103539 r117971  
    9090}
    9191
    92 static inline SVGResourcesCache* resourcesCacheFromRenderObject(RenderObject* renderer)
     92static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObject* renderer)
    9393{
    9494    Document* document = renderer->document();
     
    104104}
    105105
    106 SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(RenderObject* renderer)
     106SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(const RenderObject* renderer)
    107107{
    108108    ASSERT(renderer);
     
    171171    cache->removeResourcesFromRenderObject(resource);
    172172
    173     HashMap<RenderObject*, SVGResources*>::iterator end = cache->m_cache.end();
    174     for (HashMap<RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it) {
     173    HashMap<const RenderObject*, SVGResources*>::iterator end = cache->m_cache.end();
     174    for (HashMap<const RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it) {
    175175        it->second->resourceDestroyed(resource);
    176176
  • trunk/Source/WebCore/rendering/svg/SVGResourcesCache.h

    r95901 r117971  
    4040    void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
    4141    void removeResourcesFromRenderObject(RenderObject*);
    42     static SVGResources* cachedResourcesForRenderObject(RenderObject*);
     42    static SVGResources* cachedResourcesForRenderObject(const RenderObject*);
    4343
    4444    // Called from all SVG renderers destroy() methods - except for RenderSVGResourceContainer.
     
    5858
    5959private:
    60     HashMap<RenderObject*, SVGResources*> m_cache;
     60    HashMap<const RenderObject*, SVGResources*> m_cache;
    6161};
    6262
Note: See TracChangeset for help on using the changeset viewer.