sw_engine: revise scale transform logic.
[platform/core/graphics/tizenvg.git] / src / lib / sw_engine / tvgSwCommon.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *               http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17 #ifndef _TVG_SW_COMMON_H_
18 #define _TVG_SW_COMMON_H_
19
20 #include "tvgCommon.h"
21
22 #ifdef THORVG_AVX_VECTOR_SUPPORT
23     #include <immintrin.h>
24 #endif
25
26 #if 0
27 #include <sys/time.h>
28 static double timeStamp()
29 {
30    struct timeval tv;
31    gettimeofday(&tv, NULL);
32    return (tv.tv_sec + tv.tv_usec / 1000000.0);
33 }
34 #endif
35
36 using namespace tvg;
37
38 #define SW_CURVE_TYPE_POINT 0
39 #define SW_CURVE_TYPE_CUBIC 1
40 #define SW_OUTLINE_FILL_WINDING 0
41 #define SW_OUTLINE_FILL_EVEN_ODD 1
42 #define SW_ANGLE_PI (180L << 16)
43 #define SW_ANGLE_2PI (SW_ANGLE_PI << 1)
44 #define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1)
45 #define SW_ANGLE_PI4 (SW_ANGLE_PI >> 2)
46
47 using SwCoord = signed long;
48 using SwFixed = signed long long;
49
50 struct SwPoint
51 {
52     SwCoord x, y;
53
54     SwPoint& operator+=(const SwPoint& rhs) {
55         x += rhs.x;
56         y += rhs.y;
57         return *this;
58     }
59
60     SwPoint operator+(const SwPoint& rhs) const {
61         return {x + rhs.x, y + rhs.y};
62     }
63
64     SwPoint operator-(const SwPoint& rhs) const {
65         return {x - rhs.x, y - rhs.y};
66     }
67
68     bool operator==(const SwPoint& rhs ) const {
69         return (x == rhs.x && y == rhs.y);
70     }
71
72     bool operator!=(const SwPoint& rhs) const {
73         return (x != rhs.x || y != rhs.y);
74     }
75
76     bool zero()
77     {
78         if (x == 0 && y == 0) return true;
79         else return false;
80     }
81
82     bool small()
83     {
84         //2 is epsilon...
85         if (abs(x) < 2 && abs(y) < 2) return true;
86         else return false;
87     }
88
89 };
90
91 struct SwSize
92 {
93     SwCoord w, h;
94 };
95
96 struct SwOutline
97 {
98     uint32_t*     cntrs;            //the contour end points
99     uint32_t      cntrsCnt;         //number of contours in glyph
100     uint32_t      reservedCntrsCnt;
101     SwPoint*      pts;              //the outline's points
102     uint32_t      ptsCnt;           //number of points in the glyph
103     uint32_t      reservedPtsCnt;
104     uint8_t*      types;            //curve type
105     uint8_t       fillMode;         //outline fill mode
106     bool          opened;           //opened path?
107 };
108
109 struct SwSpan
110 {
111     int16_t x, y;
112     uint16_t len;
113     uint8_t coverage;
114 };
115
116 struct SwRleData
117 {
118     SwSpan *spans;
119     uint32_t alloc;
120     uint32_t size;
121 };
122
123 struct SwBBox
124 {
125     SwPoint min, max;
126 };
127
128 struct SwStrokeBorder
129 {
130     uint32_t ptsCnt;
131     uint32_t maxPts;
132     SwPoint* pts;
133     uint8_t* tags;
134     int32_t start;     //index of current sub-path start point
135     bool movable;      //true: for ends of lineto borders
136     bool valid;
137 };
138
139 struct SwStroke
140 {
141     SwFixed angleIn;
142     SwFixed angleOut;
143     SwPoint center;
144     SwFixed lineLength;
145     SwFixed subPathAngle;
146     SwPoint ptStartSubPath;
147     SwFixed subPathLineLength;
148     SwFixed width;
149
150     StrokeCap cap;
151     StrokeJoin join;
152     StrokeJoin joinSaved;
153
154     SwStrokeBorder borders[2];
155
156     bool firstPt;
157     bool openSubPath;
158     bool handleWideStrokes;
159     bool preScaled;
160 };
161
162 struct SwDashStroke
163 {
164     SwOutline* outline;
165     int32_t curLen;
166     int32_t curIdx;
167     Point ptStart;
168     Point ptCur;
169     float* pattern;
170     uint32_t cnt;
171     bool curOpGap;
172 };
173
174 struct SwFill
175 {
176     struct SwLinear {
177         float dx, dy;
178         float len;
179         float offset;
180     };
181
182     struct SwRadial {
183         float cx, cy;
184         float a;
185         float inv2a;
186     };
187
188     union {
189         SwLinear linear;
190         SwRadial radial;
191     };
192
193     uint32_t* ctable;
194     FillSpread spread;
195     bool translucent;
196 };
197
198 struct SwShape
199 {
200     SwOutline*   outline;
201     SwStroke*    stroke;
202     SwFill*      fill;
203     SwRleData*   rle;
204     SwRleData*   strokeRle;
205     SwBBox       bbox;
206
207     bool         rect;   //Fast Track: Othogonal rectangle?
208 };
209
210
211 static inline SwCoord TO_SWCOORD(float val)
212 {
213     return SwCoord(val * 64);
214 }
215
216
217 static inline uint32_t COLOR_ALPHA(uint32_t rgba)
218 {
219   return (rgba >> 24) & 0xff;
220 }
221
222
223 static inline uint32_t COLOR_ALPHA_BLEND(uint32_t rgba, uint32_t alpha)
224 {
225   return (((((rgba >> 8) & 0x00ff00ff) * alpha) & 0xff00ff00) +
226           ((((rgba & 0x00ff00ff) * alpha) >> 8) & 0x00ff00ff));
227 }
228
229
230 static inline uint32_t COLOR_INTERPOLATE(uint32_t rgba1, uint32_t a, uint32_t rgba2, uint32_t b)
231 {
232    auto t = (((rgba1 & 0xff00ff) * a + (rgba2 & 0xff00ff) * b) >> 8) & 0xff00ff;
233    rgba1 = (((rgba1 >> 8) & 0xff00ff) * a + ((rgba2 >> 8) & 0xff00ff) * b) & 0xff00ff00;
234    return (rgba1 |= t);
235 }
236
237
238 static inline uint32_t COLOR_ARGB_JOIN(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
239 {
240   return (a << 24 | r << 16 | g << 8 | b);
241 }
242
243
244 int64_t mathMultiply(int64_t a, int64_t b);
245 int64_t mathDivide(int64_t a, int64_t b);
246 int64_t mathMulDiv(int64_t a, int64_t b, int64_t c);
247 void mathRotate(SwPoint& pt, SwFixed angle);
248 SwFixed mathTan(SwFixed angle);
249 SwFixed mathAtan(const SwPoint& pt);
250 SwFixed mathCos(SwFixed angle);
251 SwFixed mathSin(SwFixed angle);
252 void mathSplitCubic(SwPoint* base);
253 SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
254 SwFixed mathLength(SwPoint& pt);
255 bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
256 SwFixed mathMean(SwFixed angle1, SwFixed angle2);
257
258 void shapeReset(SwShape& shape);
259 bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform);
260 bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
261 bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
262 void shapeDelOutline(SwShape& shape);
263 void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform);
264 bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip);
265 void shapeFree(SwShape& shape);
266 void shapeDelStroke(SwShape& shape);
267 bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable);
268 void shapeResetFill(SwShape& shape);
269 void shapeDelFill(SwShape& shape);
270
271 void strokeReset(SwStroke& stroke, const Shape* shape, const Matrix* transform);
272 bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline);
273 SwOutline* strokeExportOutline(SwStroke& stroke);
274 void strokeFree(SwStroke* stroke);
275
276 bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable);
277 void fillReset(SwFill* fill);
278 void fillFree(SwFill* fill);
279 void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len);
280 void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
281
282 SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
283 void rleFree(SwRleData* rle);
284
285 bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id);
286 bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
287 bool rasterStroke(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
288 bool rasterClear(Surface& surface);
289
290 inline void rasterARGB32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
291 {
292 #ifdef THORVG_AVX_VECTOR_SUPPORT
293     int32_t align = (8 - (offset % 8)) % 8;
294     //Vectorization
295     auto avxDst = (__m256i*)(dst + offset + align);
296     int32_t i = (len - align);
297     for (;i > 7; i -= 8, ++avxDst) {
298        *avxDst = _mm256_set1_epi32(val);
299     }
300     //Alignment
301     if (align > 0) {
302         if (align > len) align -= (align - len);
303         auto tmp = dst + offset;
304         for (; align > 0; --align, ++tmp) *tmp = val;
305     }
306     //Pack Leftovers
307     dst += offset + (len - i);
308     while (i-- > 0) *(dst++) = val;
309 #else
310     dst += offset;
311     while (len--) *dst++ = val;
312 #endif
313 }
314
315 #endif /* _TVG_SW_COMMON_H_ */