1 | /* |
2 | * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. |
3 | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | * of this software and associated documentation files (the "Software"), to deal |
6 | * in the Software without restriction, including without limitation the rights |
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
8 | * copies of the Software, and to permit persons to whom the Software is |
9 | * furnished to do so, subject to the following conditions: |
10 | |
11 | * The above copyright notice and this permission notice shall be included in all |
12 | * copies or substantial portions of the Software. |
13 | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
20 | * SOFTWARE. |
21 | */ |
22 | |
23 | #ifndef _TVG_SW_COMMON_H_ |
24 | #define _TVG_SW_COMMON_H_ |
25 | |
26 | #include "tvgCommon.h" |
27 | #include "tvgRender.h" |
28 | |
29 | #if 0 |
30 | #include <sys/time.h> |
31 | static double timeStamp() |
32 | { |
33 | struct timeval tv; |
34 | gettimeofday(&tv, NULL); |
35 | return (tv.tv_sec + tv.tv_usec / 1000000.0); |
36 | } |
37 | #endif |
38 | |
39 | #define SW_CURVE_TYPE_POINT 0 |
40 | #define SW_CURVE_TYPE_CUBIC 1 |
41 | #define SW_ANGLE_PI (180L << 16) |
42 | #define SW_ANGLE_2PI (SW_ANGLE_PI << 1) |
43 | #define SW_ANGLE_PI2 (SW_ANGLE_PI >> 1) |
44 | #define SW_ANGLE_PI4 (SW_ANGLE_PI >> 2) |
45 | |
46 | using SwCoord = signed long; |
47 | using SwFixed = signed long long; |
48 | |
49 | struct SwPoint |
50 | { |
51 | SwCoord x, y; |
52 | |
53 | SwPoint& operator+=(const SwPoint& rhs) |
54 | { |
55 | x += rhs.x; |
56 | y += rhs.y; |
57 | return *this; |
58 | } |
59 | |
60 | SwPoint operator+(const SwPoint& rhs) const |
61 | { |
62 | return {x + rhs.x, y + rhs.y}; |
63 | } |
64 | |
65 | SwPoint operator-(const SwPoint& rhs) const |
66 | { |
67 | return {x - rhs.x, y - rhs.y}; |
68 | } |
69 | |
70 | bool operator==(const SwPoint& rhs) const |
71 | { |
72 | return (x == rhs.x && y == rhs.y); |
73 | } |
74 | |
75 | bool operator!=(const SwPoint& rhs) const |
76 | { |
77 | return (x != rhs.x || y != rhs.y); |
78 | } |
79 | |
80 | bool zero() const |
81 | { |
82 | if (x == 0 && y == 0) return true; |
83 | else return false; |
84 | } |
85 | |
86 | bool small() const |
87 | { |
88 | //2 is epsilon... |
89 | if (abs(x) < 2 && abs(y) < 2) return true; |
90 | else return false; |
91 | } |
92 | |
93 | }; |
94 | |
95 | struct SwSize |
96 | { |
97 | SwCoord w, h; |
98 | }; |
99 | |
100 | struct SwOutline |
101 | { |
102 | Array<SwPoint> pts; //the outline's points |
103 | Array<uint32_t> cntrs; //the contour end points |
104 | Array<uint8_t> types; //curve type |
105 | Array<bool> closed; //opened or closed path? |
106 | FillRule fillRule; |
107 | }; |
108 | |
109 | struct SwSpan |
110 | { |
111 | uint16_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 | void reset() |
128 | { |
129 | min.x = min.y = max.x = max.y = 0; |
130 | } |
131 | }; |
132 | |
133 | struct SwFill |
134 | { |
135 | struct SwLinear { |
136 | float dx, dy; |
137 | float len; |
138 | float offset; |
139 | }; |
140 | |
141 | struct SwRadial { |
142 | float a11, a12, shiftX; |
143 | float a21, a22, shiftY; |
144 | float detSecDeriv; |
145 | float a; |
146 | }; |
147 | |
148 | union { |
149 | SwLinear linear; |
150 | SwRadial radial; |
151 | }; |
152 | |
153 | uint32_t* ctable; |
154 | FillSpread spread; |
155 | |
156 | bool translucent; |
157 | }; |
158 | |
159 | struct SwStrokeBorder |
160 | { |
161 | uint32_t ptsCnt; |
162 | uint32_t maxPts; |
163 | SwPoint* pts; |
164 | uint8_t* tags; |
165 | int32_t start; //index of current sub-path start point |
166 | bool movable; //true: for ends of lineto borders |
167 | }; |
168 | |
169 | struct SwStroke |
170 | { |
171 | SwFixed angleIn; |
172 | SwFixed angleOut; |
173 | SwPoint center; |
174 | SwFixed lineLength; |
175 | SwFixed subPathAngle; |
176 | SwPoint ptStartSubPath; |
177 | SwFixed subPathLineLength; |
178 | SwFixed width; |
179 | SwFixed miterlimit; |
180 | |
181 | StrokeCap cap; |
182 | StrokeJoin join; |
183 | StrokeJoin joinSaved; |
184 | SwFill* fill = nullptr; |
185 | |
186 | SwStrokeBorder borders[2]; |
187 | |
188 | float sx, sy; |
189 | |
190 | bool firstPt; |
191 | bool closedSubPath; |
192 | bool handleWideStrokes; |
193 | }; |
194 | |
195 | struct SwDashStroke |
196 | { |
197 | SwOutline* outline; |
198 | float curLen; |
199 | int32_t curIdx; |
200 | Point ptStart; |
201 | Point ptCur; |
202 | float* pattern; |
203 | uint32_t cnt; |
204 | bool curOpGap; |
205 | }; |
206 | |
207 | struct SwShape |
208 | { |
209 | SwOutline* outline = nullptr; |
210 | SwStroke* stroke = nullptr; |
211 | SwFill* fill = nullptr; |
212 | SwRleData* rle = nullptr; |
213 | SwRleData* strokeRle = nullptr; |
214 | SwBBox bbox; //Keep it boundary without stroke region. Using for optimal filling. |
215 | |
216 | bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips? |
217 | }; |
218 | |
219 | struct SwImage |
220 | { |
221 | SwOutline* outline = nullptr; |
222 | SwRleData* rle = nullptr; |
223 | union { |
224 | pixel_t* data; //system based data pointer |
225 | uint32_t* buf32; //for explicit 32bits channels |
226 | uint8_t* buf8; //for explicit 8bits grayscale |
227 | }; |
228 | uint32_t w, h, stride; |
229 | int32_t ox = 0; //offset x |
230 | int32_t oy = 0; //offset y |
231 | float scale; |
232 | uint8_t channelSize; |
233 | |
234 | bool direct = false; //draw image directly (with offset) |
235 | bool scaled = false; //draw scaled image |
236 | }; |
237 | |
238 | typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha |
239 | typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join |
240 | typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha |
241 | |
242 | struct SwCompositor; |
243 | |
244 | struct SwSurface : Surface |
245 | { |
246 | SwJoin join; |
247 | SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5 |
248 | SwBlender blender = nullptr; //blender (optional) |
249 | SwCompositor* compositor = nullptr; //compositor (optional) |
250 | BlendMethod blendMethod; //blending method (uint8_t) |
251 | |
252 | SwAlpha alpha(CompositeMethod method) |
253 | { |
254 | auto idx = (int)(method) - 2; //0: None, 1: ClipPath |
255 | return alphas[idx > 3 ? 0 : idx]; //CompositeMethod has only four Matting methods. |
256 | } |
257 | }; |
258 | |
259 | struct SwCompositor : Compositor |
260 | { |
261 | SwSurface* recoverSfc; //Recover surface when composition is started |
262 | SwCompositor* recoverCmp; //Recover compositor when composition is done |
263 | SwImage image; |
264 | SwBBox bbox; |
265 | bool valid; |
266 | }; |
267 | |
268 | struct SwMpool |
269 | { |
270 | SwOutline* outline; |
271 | SwOutline* strokeOutline; |
272 | unsigned allocSize; |
273 | }; |
274 | |
275 | static inline SwCoord TO_SWCOORD(float val) |
276 | { |
277 | return SwCoord(val * 64.0f); |
278 | } |
279 | |
280 | static inline uint32_t JOIN(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) |
281 | { |
282 | return (c0 << 24 | c1 << 16 | c2 << 8 | c3); |
283 | } |
284 | |
285 | static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a) |
286 | { |
287 | return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) + |
288 | ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff)); |
289 | } |
290 | |
291 | static inline uint32_t INTERPOLATE(uint32_t s, uint32_t d, uint8_t a) |
292 | { |
293 | return (((((((s >> 8) & 0xff00ff) - ((d >> 8) & 0xff00ff)) * a) + (d & 0xff00ff00)) & 0xff00ff00) + ((((((s & 0xff00ff) - (d & 0xff00ff)) * a) >> 8) + (d & 0xff00ff)) & 0xff00ff)); |
294 | } |
295 | |
296 | static inline uint8_t INTERPOLATE8(uint8_t s, uint8_t d, uint8_t a) |
297 | { |
298 | return ((s * a + 0xff) >> 8) + ((d * ~a + 0xff) >> 8); |
299 | } |
300 | |
301 | static inline SwCoord HALF_STROKE(float width) |
302 | { |
303 | return TO_SWCOORD(width * 0.5f); |
304 | } |
305 | |
306 | static inline uint8_t A(uint32_t c) |
307 | { |
308 | return ((c) >> 24); |
309 | } |
310 | |
311 | static inline uint8_t IA(uint32_t c) |
312 | { |
313 | return (~(c) >> 24); |
314 | } |
315 | |
316 | static inline uint8_t C1(uint32_t c) |
317 | { |
318 | return ((c) >> 16); |
319 | } |
320 | |
321 | static inline uint8_t C2(uint32_t c) |
322 | { |
323 | return ((c) >> 8); |
324 | } |
325 | |
326 | static inline uint8_t C3(uint32_t c) |
327 | { |
328 | return (c); |
329 | } |
330 | |
331 | static inline uint32_t opBlendInterp(uint32_t s, uint32_t d, uint8_t a) |
332 | { |
333 | return INTERPOLATE(s, d, a); |
334 | } |
335 | |
336 | static inline uint32_t opBlendNormal(uint32_t s, uint32_t d, uint8_t a) |
337 | { |
338 | auto t = ALPHA_BLEND(s, a); |
339 | return t + ALPHA_BLEND(d, IA(t)); |
340 | } |
341 | |
342 | static inline uint32_t opBlendPreNormal(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
343 | { |
344 | return s + ALPHA_BLEND(d, IA(s)); |
345 | } |
346 | |
347 | static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNUSED uint8_t a) |
348 | { |
349 | return s; |
350 | } |
351 | |
352 | //TODO: BlendMethod could remove the alpha parameter. |
353 | static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
354 | { |
355 | //if (s > d) => s - d |
356 | //else => d - s |
357 | auto c1 = (C1(s) > C1(d)) ? (C1(s) - C1(d)) : (C1(d) - C1(s)); |
358 | auto c2 = (C2(s) > C2(d)) ? (C2(s) - C2(d)) : (C2(d) - C2(s)); |
359 | auto c3 = (C3(s) > C3(d)) ? (C3(s) - C3(d)) : (C3(d) - C3(s)); |
360 | return JOIN(255, c1, c2, c3); |
361 | } |
362 | |
363 | static inline uint32_t opBlendExclusion(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
364 | { |
365 | //A + B - 2AB |
366 | auto c1 = min(255, C1(s) + C1(d) - min(255, (C1(s) * C1(d)) << 1)); |
367 | auto c2 = min(255, C2(s) + C2(d) - min(255, (C2(s) * C2(d)) << 1)); |
368 | auto c3 = min(255, C3(s) + C3(d) - min(255, (C3(s) * C3(d)) << 1)); |
369 | return JOIN(255, c1, c2, c3); |
370 | } |
371 | |
372 | static inline uint32_t opBlendAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
373 | { |
374 | // s + d |
375 | auto c1 = min(C1(s) + C1(d), 255); |
376 | auto c2 = min(C2(s) + C2(d), 255); |
377 | auto c3 = min(C3(s) + C3(d), 255); |
378 | return JOIN(255, c1, c2, c3); |
379 | } |
380 | |
381 | static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
382 | { |
383 | // s + d - s * d |
384 | auto c1 = C1(s) + C1(d) - MULTIPLY(C1(s), C1(d)); |
385 | auto c2 = C2(s) + C2(d) - MULTIPLY(C2(s), C2(d)); |
386 | auto c3 = C3(s) + C3(d) - MULTIPLY(C3(s), C3(d)); |
387 | return JOIN(255, c1, c2, c3); |
388 | } |
389 | |
390 | |
391 | static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
392 | { |
393 | // s * d |
394 | auto c1 = MULTIPLY(C1(s), C1(d)); |
395 | auto c2 = MULTIPLY(C2(s), C2(d)); |
396 | auto c3 = MULTIPLY(C3(s), C3(d)); |
397 | return JOIN(255, c1, c2, c3); |
398 | } |
399 | |
400 | |
401 | static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
402 | { |
403 | // if (2 * d < da) => 2 * s * d, |
404 | // else => 1 - 2 * (1 - s) * (1 - d) |
405 | auto c1 = (C1(d) < 128) ? min(255, 2 * MULTIPLY(C1(s), C1(d))) : (255 - min(255, 2 * MULTIPLY(255 - C1(s), 255 - C1(d)))); |
406 | auto c2 = (C2(d) < 128) ? min(255, 2 * MULTIPLY(C2(s), C2(d))) : (255 - min(255, 2 * MULTIPLY(255 - C2(s), 255 - C2(d)))); |
407 | auto c3 = (C3(d) < 128) ? min(255, 2 * MULTIPLY(C3(s), C3(d))) : (255 - min(255, 2 * MULTIPLY(255 - C3(s), 255 - C3(d)))); |
408 | return JOIN(255, c1, c2, c3); |
409 | } |
410 | |
411 | static inline uint32_t opBlendDarken(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
412 | { |
413 | // min(s, d) |
414 | auto c1 = min(C1(s), C1(d)); |
415 | auto c2 = min(C2(s), C2(d)); |
416 | auto c3 = min(C3(s), C3(d)); |
417 | return JOIN(255, c1, c2, c3); |
418 | } |
419 | |
420 | static inline uint32_t opBlendLighten(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
421 | { |
422 | // max(s, d) |
423 | auto c1 = max(C1(s), C1(d)); |
424 | auto c2 = max(C2(s), C2(d)); |
425 | auto c3 = max(C3(s), C3(d)); |
426 | return JOIN(255, c1, c2, c3); |
427 | } |
428 | |
429 | static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
430 | { |
431 | // d / (1 - s) |
432 | auto is = 0xffffffff - s; |
433 | auto c1 = (C1(is) > 0) ? (C1(d) / C1(is)) : C1(d); |
434 | auto c2 = (C2(is) > 0) ? (C2(d) / C2(is)) : C2(d); |
435 | auto c3 = (C3(is) > 0) ? (C3(d) / C3(is)) : C3(d); |
436 | return JOIN(255, c1, c2, c3); |
437 | } |
438 | |
439 | static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
440 | { |
441 | // 1 - (1 - d) / s |
442 | auto id = 0xffffffff - d; |
443 | auto c1 = 255 - ((C1(s) > 0) ? (C1(id) / C1(s)) : C1(id)); |
444 | auto c2 = 255 - ((C2(s) > 0) ? (C2(id) / C2(s)) : C2(id)); |
445 | auto c3 = 255 - ((C3(s) > 0) ? (C3(id) / C3(s)) : C3(id)); |
446 | return JOIN(255, c1, c2, c3); |
447 | } |
448 | |
449 | static inline uint32_t opBlendHardLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
450 | { |
451 | auto c1 = (C1(s) < 128) ? min(255, 2 * MULTIPLY(C1(s), C1(d))) : (255 - min(255, 2 * MULTIPLY(255 - C1(s), 255 - C1(d)))); |
452 | auto c2 = (C2(s) < 128) ? min(255, 2 * MULTIPLY(C2(s), C2(d))) : (255 - min(255, 2 * MULTIPLY(255 - C2(s), 255 - C2(d)))); |
453 | auto c3 = (C3(s) < 128) ? min(255, 2 * MULTIPLY(C3(s), C3(d))) : (255 - min(255, 2 * MULTIPLY(255 - C3(s), 255 - C3(d)))); |
454 | return JOIN(255, c1, c2, c3); |
455 | } |
456 | |
457 | static inline uint32_t opBlendSoftLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
458 | { |
459 | //(255 - 2 * s) * (d * d) + (2 * s * b) |
460 | auto c1 = min(255, MULTIPLY(255 - min(255, 2 * C1(s)), MULTIPLY(C1(d), C1(d))) + 2 * MULTIPLY(C1(s), C1(d))); |
461 | auto c2 = min(255, MULTIPLY(255 - min(255, 2 * C2(s)), MULTIPLY(C2(d), C2(d))) + 2 * MULTIPLY(C2(s), C2(d))); |
462 | auto c3 = min(255, MULTIPLY(255 - min(255, 2 * C3(s)), MULTIPLY(C3(d), C3(d))) + 2 * MULTIPLY(C3(s), C3(d))); |
463 | return JOIN(255, c1, c2, c3); |
464 | } |
465 | |
466 | static inline uint32_t opMaskAdd(uint32_t s, uint32_t d, uint8_t a) |
467 | { |
468 | return opBlendNormal(s, d, a); |
469 | } |
470 | |
471 | static inline uint32_t opMaskSubtract(uint32_t s, uint32_t d, uint8_t a) |
472 | { |
473 | return ALPHA_BLEND(d, MULTIPLY(IA(s), a)); |
474 | } |
475 | |
476 | static inline uint32_t opMaskDifference(uint32_t s, uint32_t d, uint8_t a) |
477 | { |
478 | auto t = ALPHA_BLEND(s, a); |
479 | return ALPHA_BLEND(t, IA(d)) + ALPHA_BLEND(d, IA(t)); |
480 | } |
481 | |
482 | static inline uint32_t opMaskIntersect(uint32_t s, uint32_t d, uint8_t a) |
483 | { |
484 | return ALPHA_BLEND(d, MULTIPLY(IA(s), a)); |
485 | } |
486 | |
487 | static inline uint32_t opMaskPreAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
488 | { |
489 | return opBlendPreNormal(s, d, a); |
490 | } |
491 | |
492 | static inline uint32_t opMaskPreSubtract(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
493 | { |
494 | return ALPHA_BLEND(d, IA(s)); |
495 | } |
496 | |
497 | static inline uint32_t opMaskPreDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
498 | { |
499 | return ALPHA_BLEND(s, IA(d)) + ALPHA_BLEND(d, IA(s)); |
500 | } |
501 | |
502 | static inline uint32_t opMaskPreIntersect(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) |
503 | { |
504 | return ALPHA_BLEND(d, MULTIPLY(a, IA(s))); |
505 | } |
506 | |
507 | int64_t mathMultiply(int64_t a, int64_t b); |
508 | int64_t mathDivide(int64_t a, int64_t b); |
509 | int64_t mathMulDiv(int64_t a, int64_t b, int64_t c); |
510 | void mathRotate(SwPoint& pt, SwFixed angle); |
511 | SwFixed mathTan(SwFixed angle); |
512 | SwFixed mathAtan(const SwPoint& pt); |
513 | SwFixed mathCos(SwFixed angle); |
514 | SwFixed mathSin(SwFixed angle); |
515 | void mathSplitCubic(SwPoint* base); |
516 | SwFixed mathDiff(SwFixed angle1, SwFixed angle2); |
517 | SwFixed mathLength(const SwPoint& pt); |
518 | bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); |
519 | SwFixed mathMean(SwFixed angle1, SwFixed angle2); |
520 | SwPoint mathTransform(const Point* to, const Matrix* transform); |
521 | bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack); |
522 | bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee); |
523 | |
524 | void shapeReset(SwShape* shape); |
525 | bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite); |
526 | bool shapePrepared(const SwShape* shape); |
527 | bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias); |
528 | void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid); |
529 | void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform); |
530 | bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); |
531 | void shapeFree(SwShape* shape); |
532 | void shapeDelStroke(SwShape* shape); |
533 | bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); |
534 | bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); |
535 | void shapeResetFill(SwShape* shape); |
536 | void shapeResetStrokeFill(SwShape* shape); |
537 | void shapeDelFill(SwShape* shape); |
538 | void shapeDelStrokeFill(SwShape* shape); |
539 | |
540 | void strokeReset(SwStroke* stroke, const RenderShape* shape, const Matrix* transform); |
541 | bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); |
542 | SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); |
543 | void strokeFree(SwStroke* stroke); |
544 | |
545 | bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); |
546 | bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias); |
547 | void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); |
548 | void imageReset(SwImage* image); |
549 | void imageFree(SwImage* image); |
550 | |
551 | bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); |
552 | void fillReset(SwFill* fill); |
553 | void fillFree(SwFill* fill); |
554 | //OPTIMIZE_ME: Skip the function pointer access |
555 | void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. |
556 | void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. |
557 | void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver. |
558 | void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. |
559 | void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. |
560 | void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //masking ver. |
561 | |
562 | SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias); |
563 | SwRleData* rleRender(const SwBBox* bbox); |
564 | void rleFree(SwRleData* rle); |
565 | void rleReset(SwRleData* rle); |
566 | void rleMerge(SwRleData* rle, SwRleData* clip1, SwRleData* clip2); |
567 | void rleClipPath(SwRleData* rle, const SwRleData* clip); |
568 | void rleClipRect(SwRleData* rle, const SwBBox* clip); |
569 | |
570 | SwMpool* mpoolInit(uint32_t threads); |
571 | bool mpoolTerm(SwMpool* mpool); |
572 | bool mpoolClear(SwMpool* mpool); |
573 | SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx); |
574 | void mpoolRetOutline(SwMpool* mpool, unsigned idx); |
575 | SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx); |
576 | void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx); |
577 | |
578 | bool rasterCompositor(SwSurface* surface); |
579 | bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id); |
580 | bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); |
581 | bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity); |
582 | bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); |
583 | bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id); |
584 | bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); |
585 | void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len); |
586 | void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len); |
587 | void rasterUnpremultiply(Surface* surface); |
588 | void rasterPremultiply(Surface* surface); |
589 | bool rasterConvertCS(Surface* surface, ColorSpace to); |
590 | |
591 | #endif /* _TVG_SW_COMMON_H_ */ |
592 | |