1 /*
2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #ifndef VDRAWHELPER_H
20 #define VDRAWHELPER_H
21
22 #include <cstring>
23 #include <memory>
24 #include "assert.h"
25 #include "vbitmap.h"
26 #include "vbrush.h"
27 #include "vpainter.h"
28 #include "vrect.h"
29 #include "vrle.h"
30
31 V_USE_NAMESPACE
32
33 struct VSpanData;
34 struct Operator;
35
36 typedef void (*CompositionFunctionSolid)(uint32_t *dest, int length,
37 uint32_t color, uint32_t const_alpha);
38 typedef void (*CompositionFunction)(uint32_t *dest, const uint32_t *src,
39 int length, uint32_t const_alpha);
40 typedef void (*SourceFetchProc)(uint32_t *buffer, const Operator *o,
41 const VSpanData *data, int y, int x,
42 int length);
43 typedef void (*ProcessRleSpan)(size_t count, const VRle::Span *spans,
44 void *userData);
45
46 extern void memfill32(uint32_t *dest, uint32_t value, int count);
47
48 struct LinearGradientValues {
49 float dx;
50 float dy;
51 float l;
52 float off;
53 };
54
55 struct RadialGradientValues {
56 float dx;
57 float dy;
58 float dr;
59 float sqrfr;
60 float a;
61 float inv2a;
62 bool extended;
63 };
64
65 struct Operator {
66 VPainter::CompositionMode mode;
67 SourceFetchProc srcFetch;
68 CompositionFunctionSolid funcSolid;
69 CompositionFunction func;
70 union {
71 LinearGradientValues linear;
72 RadialGradientValues radial;
73 };
74 };
75
76 class VRasterBuffer {
77 public:
78 VBitmap::Format prepare(VBitmap *image);
79 void clear();
80
81 void resetBuffer(int val = 0);
82
scanLine(int y)83 inline uchar *scanLine(int y)
84 {
85 assert(y >= 0);
86 assert(size_t(y) < mHeight);
87 return mBuffer + y * mBytesPerLine;
88 }
89
width()90 size_t width() const { return mWidth; }
height()91 size_t height() const { return mHeight; }
bytesPerLine()92 size_t bytesPerLine() const { return mBytesPerLine; }
bytesPerPixel()93 size_t bytesPerPixel() const { return mBytesPerPixel; }
94
95 VBitmap::Format mFormat{VBitmap::Format::ARGB32_Premultiplied};
96 private:
97 size_t mWidth{0};
98 size_t mHeight{0};
99 size_t mBytesPerLine{0};
100 size_t mBytesPerPixel{0};
101 uchar *mBuffer{nullptr};
102 };
103
104 struct VGradientData {
105 VGradient::Spread mSpread;
106 struct Linear{
107 float x1, y1, x2, y2;
108 };
109 struct Radial{
110 float cx, cy, fx, fy, cradius, fradius;
111 };
112 union {
113 Linear linear;
114 Radial radial;
115 };
116 const uint32_t *mColorTable;
117 bool mColorTableAlpha;
118 };
119
120 struct VBitmapData
121 {
122 const uchar *imageData;
scanLineVBitmapData123 const uchar *scanLine(int y) const { return imageData + y*bytesPerLine; }
124
125 int width;
126 int height;
127 // clip rect
128 int x1;
129 int y1;
130 int x2;
131 int y2;
132 uint bytesPerLine;
133 VBitmap::Format format;
134 bool hasAlpha;
135 enum Type {
136 Plain,
137 Tiled
138 };
139 Type type;
140 int const_alpha;
141 };
142
143 struct VColorTable
144 {
145 uint32_t buffer32[VGradient::colorTableSize];
146 bool alpha{true};
147 };
148
149 struct VSpanData {
150 enum class Type { None, Solid, LinearGradient, RadialGradient, Texture };
151
152 void updateSpanFunc();
153 void init(VRasterBuffer *image);
154 void setup(const VBrush & brush,
155 VPainter::CompositionMode mode = VPainter::CompModeSrcOver,
156 int alpha = 255);
157 void setupMatrix(const VMatrix &matrix);
158
clipRectVSpanData159 VRect clipRect() const
160 {
161 return VRect(0, 0, mDrawableSize.width(), mDrawableSize.height());
162 }
163
setDrawRegionVSpanData164 void setDrawRegion(const VRect ®ion)
165 {
166 mOffset = VPoint(region.left(), region.top());
167 mDrawableSize = VSize(region.width(), region.height());
168 }
169
bufferVSpanData170 uint *buffer(int x, int y) const
171 {
172 return (uint *)(mRasterBuffer->scanLine(y + mOffset.y())) + x + mOffset.x();
173 }
174 void initTexture(const VBitmap *image, int alpha, VBitmapData::Type type, const VRect &sourceRect);
175
176 VPainter::CompositionMode mCompositionMode{VPainter::CompositionMode::CompModeSrcOver};
177 VRasterBuffer * mRasterBuffer;
178 ProcessRleSpan mBlendFunc;
179 ProcessRleSpan mUnclippedBlendFunc;
180 VSpanData::Type mType;
181 std::shared_ptr<const VColorTable> mColorTable{nullptr};
182 VPoint mOffset; // offset to the subsurface
183 VSize mDrawableSize;// suburface size
184 union {
185 uint32_t mSolid;
186 VGradientData mGradient;
187 VBitmapData mBitmap;
188 };
189 float m11, m12, m13, m21, m22, m23, m33, dx, dy; // inverse xform matrix
190 bool fast_matrix{true};
191 VMatrix::MatrixType transformType{VMatrix::MatrixType::None};
192 };
193
194 void vInitDrawhelperFunctions();
195 extern void vInitBlendFunctions();
196
197 #define BYTE_MUL(c, a) \
198 ((((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
199 (((((c)&0x00ff00ff) * (a)) >> 8) & 0x00ff00ff))
200
vRed(uint32_t c)201 inline constexpr int vRed(uint32_t c)
202 {
203 return ((c >> 16) & 0xff);
204 }
205
vGreen(uint32_t c)206 inline constexpr int vGreen(uint32_t c)
207 {
208 return ((c >> 8) & 0xff);
209 }
210
vBlue(uint32_t c)211 inline constexpr int vBlue(uint32_t c)
212 {
213 return (c & 0xff);
214 }
215
vAlpha(uint32_t c)216 inline constexpr int vAlpha(uint32_t c)
217 {
218 return c >> 24;
219 }
220
INTERPOLATE_PIXEL_255(uint x,uint a,uint y,uint b)221 static inline uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b)
222 {
223 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
224 t >>= 8;
225 t &= 0xff00ff;
226 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
227 x &= 0xff00ff00;
228 x |= t;
229 return x;
230 }
231
232 #define LOOP_ALIGNED_U1_A4(DEST, LENGTH, UOP, A4OP) \
233 { \
234 while ((uintptr_t)DEST & 0xF && LENGTH) \
235 UOP \
236 \
237 while (LENGTH) \
238 { \
239 switch (LENGTH) { \
240 case 3: \
241 case 2: \
242 case 1: \
243 UOP break; \
244 default: \
245 A4OP break; \
246 } \
247 } \
248 }
249
250 #endif // QDRAWHELPER_P_H
251