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 THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_MARKER_DATA_H_
21 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_MARKER_DATA_H_
22 
23 #include "third_party/blink/renderer/core/svg/svg_path_consumer.h"
24 #include "third_party/blink/renderer/platform/graphics/path.h"
25 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
26 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
27 
28 namespace blink {
29 
30 enum SVGMarkerType { kStartMarker, kMidMarker, kEndMarker };
31 
32 class LayoutSVGResourceMarker;
33 class SVGPathByteStream;
34 
35 struct MarkerPosition {
36   DISALLOW_NEW();
MarkerPositionMarkerPosition37   MarkerPosition(SVGMarkerType use_type,
38                  const FloatPoint& use_origin,
39                  float use_angle)
40       : type(use_type), origin(use_origin), angle(use_angle) {}
41 
SelectMarkerMarkerPosition42   LayoutSVGResourceMarker* SelectMarker(
43       LayoutSVGResourceMarker* marker_start,
44       LayoutSVGResourceMarker* marker_mid,
45       LayoutSVGResourceMarker* marker_end) const {
46     switch (type) {
47       case kStartMarker:
48         return marker_start;
49       case kMidMarker:
50         return marker_mid;
51       case kEndMarker:
52         return marker_end;
53     }
54     NOTREACHED();
55     return nullptr;
56   }
57 
58   SVGMarkerType type;
59   FloatPoint origin;
60   float angle;
61 };
62 
63 class SVGMarkerDataBuilder : private SVGPathConsumer {
64   STACK_ALLOCATED();
65 
66  public:
SVGMarkerDataBuilder(Vector<MarkerPosition> & positions)67   explicit SVGMarkerDataBuilder(Vector<MarkerPosition>& positions)
68       : positions_(positions),
69         last_moveto_index_(0),
70         last_element_type_(kPathElementMoveToPoint) {}
71 
72   // Build marker data for a Path.
73   void Build(const Path&);
74 
75   // Build marker data for a SVGPathByteStream.
76   //
77   // A SVGPathByteStream is semantically higher-level than a Path, and thus
78   // this allows those higher-level constructs (for example arcs) to be handled
79   // correctly. This should be used in cases where the original path data can
80   // contain such higher-level constructs.
81   void Build(const SVGPathByteStream&);
82 
83  private:
84   // SVGPathConsumer
85   void EmitSegment(const PathSegmentData&) override;
86 
87   static void UpdateFromPathElement(void* info, const PathElement*);
88 
89   enum AngleType {
90     kBisecting,
91     kInbound,
92     kOutbound,
93   };
94 
95   double CurrentAngle(AngleType) const;
96   AngleType DetermineAngleType(bool ends_subpath) const;
97 
98   void UpdateAngle(bool ends_subpath);
99 
100   struct SegmentData {
101     FloatSize start_tangent;  // Tangent in the start point of the segment.
102     FloatSize end_tangent;    // Tangent in the end point of the segment.
103     FloatPoint position;      // The end point of the segment.
104   };
105 
106   static void ComputeQuadTangents(SegmentData&,
107                                   const FloatPoint& start,
108                                   const FloatPoint& control,
109                                   const FloatPoint& end);
110   SegmentData ExtractPathElementFeatures(const PathElement&) const;
111   void UpdateFromPathElement(const PathElement&);
112   void Flush();
113 
114   Vector<MarkerPosition>& positions_;
115   unsigned last_moveto_index_;
116   PathElementType last_element_type_;
117   FloatPoint origin_;
118   FloatPoint subpath_start_;
119   FloatSize in_slope_;
120   FloatSize out_slope_;
121   FloatSize last_moveto_out_slope_;
122 };
123 
124 }  // namespace blink
125 
126 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_MARKER_DATA_H_
127