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>
31static 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
46using SwCoord = signed long;
47using SwFixed = signed long long;
48
49struct 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
95struct SwSize
96{
97 SwCoord w, h;
98};
99
100struct 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
109struct SwSpan
110{
111 uint16_t x, y;
112 uint16_t len;
113 uint8_t coverage;
114};
115
116struct SwRleData
117{
118 SwSpan *spans;
119 uint32_t alloc;
120 uint32_t size;
121};
122
123struct SwBBox
124{
125 SwPoint min, max;
126
127 void reset()
128 {
129 min.x = min.y = max.x = max.y = 0;
130 }
131};
132
133struct 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
159struct 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
169struct 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
195struct 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
207struct 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
219struct 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
238typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha
239typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
240typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
241
242struct SwCompositor;
243
244struct 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
259struct 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
268struct SwMpool
269{
270 SwOutline* outline;
271 SwOutline* strokeOutline;
272 unsigned allocSize;
273};
274
275static inline SwCoord TO_SWCOORD(float val)
276{
277 return SwCoord(val * 64.0f);
278}
279
280static 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
285static 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
291static 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
296static 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
301static inline SwCoord HALF_STROKE(float width)
302{
303 return TO_SWCOORD(width * 0.5f);
304}
305
306static inline uint8_t A(uint32_t c)
307{
308 return ((c) >> 24);
309}
310
311static inline uint8_t IA(uint32_t c)
312{
313 return (~(c) >> 24);
314}
315
316static inline uint8_t C1(uint32_t c)
317{
318 return ((c) >> 16);
319}
320
321static inline uint8_t C2(uint32_t c)
322{
323 return ((c) >> 8);
324}
325
326static inline uint8_t C3(uint32_t c)
327{
328 return (c);
329}
330
331static inline uint32_t opBlendInterp(uint32_t s, uint32_t d, uint8_t a)
332{
333 return INTERPOLATE(s, d, a);
334}
335
336static 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
342static 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
347static 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.
353static 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
363static 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
372static 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
381static 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
391static 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
401static 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
411static 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
420static 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
429static 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
439static 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
449static 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
457static 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
466static inline uint32_t opMaskAdd(uint32_t s, uint32_t d, uint8_t a)
467{
468 return opBlendNormal(s, d, a);
469}
470
471static 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
476static 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
482static 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
487static inline uint32_t opMaskPreAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
488{
489 return opBlendPreNormal(s, d, a);
490}
491
492static 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
497static 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
502static 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
507int64_t mathMultiply(int64_t a, int64_t b);
508int64_t mathDivide(int64_t a, int64_t b);
509int64_t mathMulDiv(int64_t a, int64_t b, int64_t c);
510void mathRotate(SwPoint& pt, SwFixed angle);
511SwFixed mathTan(SwFixed angle);
512SwFixed mathAtan(const SwPoint& pt);
513SwFixed mathCos(SwFixed angle);
514SwFixed mathSin(SwFixed angle);
515void mathSplitCubic(SwPoint* base);
516SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
517SwFixed mathLength(const SwPoint& pt);
518bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
519SwFixed mathMean(SwFixed angle1, SwFixed angle2);
520SwPoint mathTransform(const Point* to, const Matrix* transform);
521bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
522bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee);
523
524void shapeReset(SwShape* shape);
525bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
526bool shapePrepared(const SwShape* shape);
527bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias);
528void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
529void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform);
530bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
531void shapeFree(SwShape* shape);
532void shapeDelStroke(SwShape* shape);
533bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable);
534bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable);
535void shapeResetFill(SwShape* shape);
536void shapeResetStrokeFill(SwShape* shape);
537void shapeDelFill(SwShape* shape);
538void shapeDelStrokeFill(SwShape* shape);
539
540void strokeReset(SwStroke* stroke, const RenderShape* shape, const Matrix* transform);
541bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
542SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
543void strokeFree(SwStroke* stroke);
544
545bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
546bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias);
547void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
548void imageReset(SwImage* image);
549void imageFree(SwImage* image);
550
551bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable);
552void fillReset(SwFill* fill);
553void fillFree(SwFill* fill);
554//OPTIMIZE_ME: Skip the function pointer access
555void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver.
556void 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.
557void 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.
558void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver.
559void 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.
560void 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
562SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
563SwRleData* rleRender(const SwBBox* bbox);
564void rleFree(SwRleData* rle);
565void rleReset(SwRleData* rle);
566void rleMerge(SwRleData* rle, SwRleData* clip1, SwRleData* clip2);
567void rleClipPath(SwRleData* rle, const SwRleData* clip);
568void rleClipRect(SwRleData* rle, const SwBBox* clip);
569
570SwMpool* mpoolInit(uint32_t threads);
571bool mpoolTerm(SwMpool* mpool);
572bool mpoolClear(SwMpool* mpool);
573SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx);
574void mpoolRetOutline(SwMpool* mpool, unsigned idx);
575SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx);
576void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
577
578bool rasterCompositor(SwSurface* surface);
579bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
580bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
581bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity);
582bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
583bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
584bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
585void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
586void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len);
587void rasterUnpremultiply(Surface* surface);
588void rasterPremultiply(Surface* surface);
589bool rasterConvertCS(Surface* surface, ColorSpace to);
590
591#endif /* _TVG_SW_COMMON_H_ */
592