Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #ifndef SVGMarkerData_h
     21 #define SVGMarkerData_h
     22 
     23 #if ENABLE(SVG)
     24 #include "FloatConversion.h"
     25 #include "Path.h"
     26 #include <wtf/MathExtras.h>
     27 
     28 namespace WebCore {
     29 
     30 class RenderSVGResourceMarker;
     31 
     32 class SVGMarkerData {
     33 public:
     34     enum Type {
     35         Unknown = 0,
     36         Start,
     37         Mid,
     38         End
     39     };
     40 
     41     SVGMarkerData(const Type& type = Unknown, RenderSVGResourceMarker* marker = 0)
     42         : m_type(type)
     43         , m_marker(marker)
     44     {
     45     }
     46 
     47     FloatPoint origin() const { return m_origin; }
     48     RenderSVGResourceMarker* marker() const { return m_marker; }
     49 
     50     float currentAngle() const
     51     {
     52         FloatSize inslopeChange = m_inslopePoints[1] - m_inslopePoints[0];
     53         FloatSize outslopeChange = m_outslopePoints[1] - m_outslopePoints[0];
     54 
     55         double inslope = rad2deg(atan2(inslopeChange.height(), inslopeChange.width()));
     56         double outslope = rad2deg(atan2(outslopeChange.height(), outslopeChange.width()));
     57 
     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;
     72         }
     73 
     74         return narrowPrecisionToFloat(angle);
     75     }
     76 
     77     void updateTypeAndMarker(const Type& type, RenderSVGResourceMarker* marker)
     78     {
     79         m_type = type;
     80         m_marker = marker;
     81     }
     82 
     83     void updateOutslope(const FloatPoint& point)
     84     {
     85         m_outslopePoints[0] = m_origin;
     86         m_outslopePoints[1] = point;
     87     }
     88 
     89     void updateMarkerDataForPathElement(const PathElement* element)
     90     {
     91         FloatPoint* points = element->points;
     92 
     93         switch (element->type) {
     94         case PathElementAddQuadCurveToPoint:
     95             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=33115 (PathElementAddQuadCurveToPoint not handled for <marker>)
     96             m_origin = points[1];
     97             break;
     98         case PathElementAddCurveToPoint:
     99             m_inslopePoints[0] = points[1];
    100             m_inslopePoints[1] = points[2];
    101             m_origin = points[2];
    102             break;
    103         case PathElementMoveToPoint:
    104             m_subpathStart = points[0];
    105         case PathElementAddLineToPoint:
    106             updateInslope(points[0]);
    107             m_origin = points[0];
    108             break;
    109         case PathElementCloseSubpath:
    110             updateInslope(points[0]);
    111             m_origin = m_subpathStart;
    112             m_subpathStart = FloatPoint();
    113         }
    114     }
    115 
    116 private:
    117     void updateInslope(const FloatPoint& point)
    118     {
    119         m_inslopePoints[0] = m_origin;
    120         m_inslopePoints[1] = point;
    121     }
    122 
    123     Type m_type;
    124     RenderSVGResourceMarker* m_marker;
    125     FloatPoint m_origin;
    126     FloatPoint m_subpathStart;
    127     FloatPoint m_inslopePoints[2];
    128     FloatPoint m_outslopePoints[2];
    129 };
    130 
    131 }
    132 
    133 #endif // ENABLE(SVG)
    134 #endif // SVGMarkerData_h
    135