updated copyright.
[platform/core/graphics/tizenvg.git] / src / lib / sw_engine / tvgSwRasterTexmapInternal.h
1 /*
2  * Copyright (c) 2021 - 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 {
24     float _dudx = dudx, _dvdx = dvdx;
25     float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
26     float _xa = xa, _xb = xb, _ua = ua, _va = va;
27     auto sbuf = image->data;
28     auto dbuf = surface->buffer;
29     int32_t sw = static_cast<int32_t>(image->stride);
30     int32_t sh = image->h;
31     int32_t dw = surface->stride;
32     int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
33     int32_t vv = 0, uu = 0;
34     int32_t minx = INT32_MAX, maxx = INT32_MIN;
35     float dx, u, v, iptr;
36     uint32_t* buf;
37     SwSpan* span = nullptr;         //used only when rle based.
38
39 #ifdef TEXMAP_MASKING
40     uint32_t* cmp;
41 #endif
42
43     if (!_arrange(image, region, yStart, yEnd)) return;
44
45     //Loop through all lines in the segment
46     uint32_t spanIdx = 0;
47
48     if (region) {
49         minx = region->min.x;
50         maxx = region->max.x;
51     } else {
52         span = image->rle->spans;
53         while (span->y < yStart) {
54             ++span;
55             ++spanIdx;
56         }
57     }
58
59     y = yStart;
60
61     while (y < yEnd) {
62         x1 = (int32_t)_xa;
63         x2 = (int32_t)_xb;
64
65         if (!region) {
66             minx = INT32_MAX;
67             maxx = INT32_MIN;
68             //one single row, could be consisted of multiple spans.
69             while (span->y == y && spanIdx < image->rle->size) {
70                 if (minx > span->x) minx = span->x;
71                 if (maxx < span->x + span->len) maxx = span->x + span->len;
72                 ++span;
73                 ++spanIdx;
74             }
75         }
76         if (x1 < minx) x1 = minx;
77         if (x2 > maxx) x2 = maxx;
78
79         //Anti-Aliasing frames
80         ay = y - aaSpans->yStart;
81         if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1;
82         if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2;
83
84         //Range exception
85         if ((x2 - x1) < 1 || (x1 >= maxx) || (x2 <= minx)) goto next;
86
87         //Perform subtexel pre-stepping on UV
88         dx = 1 - (_xa - x1);
89         u = _ua + dx * _dudx;
90         v = _va + dx * _dvdx;
91
92         buf = dbuf + ((y * dw) + x1);
93
94         x = x1;
95
96 #ifdef TEXMAP_MASKING
97         cmp = &surface->compositor->image.data[y * surface->compositor->image.stride + x1];
98 #endif
99         //Draw horizontal line
100         while (x++ < x2) {
101             uu = (int) u;
102             vv = (int) v;
103
104             ar = (int)(255 * (1 - modff(u, &iptr)));
105             ab = (int)(255 * (1 - modff(v, &iptr)));
106             iru = uu + 1;
107             irv = vv + 1;
108
109             if (vv >= sh) continue;
110
111             px = *(sbuf + (vv * sw) + uu);
112
113             /* horizontal interpolate */
114             if (iru < sw) {
115                 /* right pixel */
116                 int px2 = *(sbuf + (vv * sw) + iru);
117                 px = INTERPOLATE(ar, px, px2);
118             }
119             /* vertical interpolate */
120             if (irv < sh) {
121                 /* bottom pixel */
122                 int px2 = *(sbuf + (irv * sw) + uu);
123
124                 /* horizontal interpolate */
125                 if (iru < sw) {
126                     /* bottom right pixel */
127                     int px3 = *(sbuf + (irv * sw) + iru);
128                     px2 = INTERPOLATE(ar, px2, px3);
129                 }
130                 px = INTERPOLATE(ab, px, px2);
131             }
132 #if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT)
133             auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blendMethod(*cmp)));
134 #elif defined(TEXMAP_MASKING)
135             auto src = ALPHA_BLEND(px, blendMethod(*cmp));
136 #elif defined(TEXMAP_TRANSLUCENT)
137             auto src = ALPHA_BLEND(px, opacity);
138 #else
139             auto src = px;
140 #endif
141             *buf = src + ALPHA_BLEND(*buf, _ialpha(src));
142             ++buf;
143 #ifdef TEXMAP_MASKING
144             ++cmp;
145 #endif
146             //Step UV horizontally
147             u += _dudx;
148             v += _dvdx;
149             //range over?
150             if ((uint32_t)v >= image->h) break;
151         }
152 next:
153         //Step along both edges
154         _xa += _dxdya;
155         _xb += _dxdyb;
156         _ua += _dudya;
157         _va += _dvdya;
158
159         if (!region && spanIdx >= image->rle->size) break;
160
161         ++y;
162     }
163     xa = _xa;
164     xb = _xb;
165     ua = _ua;
166     va = _va;
167 }