Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_TESS_SPTESSLINE_H_
25 : #define STAPPLER_TESS_SPTESSLINE_H_
26 :
27 : #include "SPTess.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::geom {
30 :
31 : enum class LineCup {
32 : Butt,
33 : Round,
34 : Square
35 : };
36 :
37 : enum class LineJoin {
38 : Miter,
39 : Round,
40 : Bevel
41 : };
42 :
43 : enum class DrawStyle {
44 : None = 0,
45 : Fill = 1,
46 : Stroke = 2,
47 : FillAndStroke = 3,
48 : };
49 :
50 28332 : SP_DEFINE_ENUM_AS_MASK(DrawStyle)
51 :
52 : // Helper class, that transform lines in SVG notation (bezier2/3, arcs) into series of segments,
53 : // then output this segments to contour in tesselator
54 : struct LineDrawer {
55 : // `e` defines relative error in terms of maximum allowed distance between the point,
56 : // where line should be in perfect implementation, and the segment in output
57 : // For perfect VG quality, it should be around 0.75 of screen pixel
58 : LineDrawer(float e, Rc<Tesselator> &&fill, Rc<Tesselator> &&stroke,
59 : float lineWidth = 1.0f, LineJoin lineJoin = LineJoin::Miter, LineCup lineCup = LineCup::Butt);
60 :
61 : void drawBegin(float x, float y);
62 : void drawLine(float x, float y);
63 : void drawQuadBezier(float x1, float y1, float x2, float y2);
64 : void drawCubicBezier(float x1, float y1, float x2, float y2, float x3, float y3);
65 : void drawArc(float rx, float ry, float angle, bool largeArc, bool sweep, float x, float y);
66 : void drawClose(bool closed);
67 :
68 : void push(float x, float y);
69 : void pushStroke(const Vec2 &v0, const Vec2 &v1, const Vec2 &v2);
70 :
71 : struct BufferNode {
72 : BufferNode *next;
73 : BufferNode *prev;
74 : Vec2 point;
75 : };
76 :
77 : DrawStyle style = DrawStyle::None;
78 : LineJoin lineJoin = LineJoin::Miter;
79 : LineCup lineCup = LineCup::Butt;
80 : float distanceError = 0.0f;
81 : float angularError = 0.0f;
82 : float strokeWidth = 0.0f;
83 : size_t count = 0;
84 : Vec2 origin[2];
85 : BufferNode buffer[3];
86 : BufferNode *target = nullptr;
87 :
88 : Rc<Tesselator> fill;
89 : Tesselator::Cursor fillCursor;
90 :
91 : Rc<Tesselator> stroke;
92 : Tesselator::Cursor strokeCursor;
93 :
94 : float _miterLimit = 4.0f;
95 : };
96 :
97 : }
98 :
99 : #endif /* STAPPLER_TESS_SPTESSLINE_H_ */
|