1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GRAPHIC_LITE_DRAW_UTILS_H
17 #define GRAPHIC_LITE_DRAW_UTILS_H
18 
19 #include "common/text.h"
20 #include "font/ui_font_header.h"
21 #include "gfx_utils/color.h"
22 #include "gfx_utils/geometry2d.h"
23 #include "gfx_utils/graphic_buffer.h"
24 #include "gfx_utils/graphic_types.h"
25 #include "gfx_utils/list.h"
26 #include "gfx_utils/style.h"
27 #include "gfx_utils/transform.h"
28 
29 namespace OHOS {
30 #define SWAP_INT16(x, y)    \
31     do {                    \
32         int16_t temp = (x); \
33         (x) = (y);          \
34         (y) = temp;         \
35     } while (0)
36 
37 #define SWAP_POINTS(x1, x2, y1, y2) \
38     SWAP_INT16(x1, x2);             \
39     SWAP_INT16(y1, y2);
40 
41 // FixedPointed Related definition.
42 #define FIXED_NUM_1 1048576
43 #define FIXED_Q_NUM 20
44 #define FO_TRANS_FLOAT_TO_FIXED(f) (static_cast<int64_t>((f) * FIXED_NUM_1))
45 #define FO_TRANS_INTEGER_TO_FIXED(f) ((static_cast<int64_t>(f)) << FIXED_Q_NUM)
46 #define FO_DIV(n1, n2) ((static_cast<int64_t>(n1) << FIXED_Q_NUM) / (n2))
47 #define FO_TO_INTEGER(n) ((n) >= 0 ? ((n) >> FIXED_Q_NUM) : (((n) >> FIXED_Q_NUM) + 1))
48 #define FO_DECIMAL(n) ((n) >= 0 ? ((n) & (FIXED_NUM_1 - 1)) : ((n) | (-FIXED_NUM_1)))
49 #define FO_MUL(n1, n2) ((static_cast<int64_t>(n1) * (n2)) >> FIXED_Q_NUM)
50 
51 struct EdgeSides {
52     int16_t left;
53     int16_t right;
54     int16_t top;
55     int16_t bottom;
56 };
57 
58 struct LabelLineInfo {
59     Point& pos;
60     Point& offset;
61     const Rect& mask;
62     int16_t lineHeight;
63     uint16_t lineLength;
64     uint8_t shapingId;
65     uint8_t opaScale;
66     const Style& style;
67     const char* text;
68     uint16_t length;
69     uint16_t start;
70     uint16_t fontId;
71     uint8_t fontSize;
72     uint8_t txtFlag;
73     UITextLanguageDirect direct;
74     uint32_t* codePoints;
75     bool baseLine;
76 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
77     TextStyle* textStyles;
78 #endif
79     List<BackgroundColor>*  backgroundColor;
80     List<ForegroundColor>*  foregroundColor;
81     List<LineBackgroundColor>*  linebackgroundColor;
82     SpannableString* spannableString;
83     uint16_t ellipsisOssetY;
84 };
85 
86 struct LabelLetterInfo {
87     const Point& pos;
88     Rect mask;
89     const ColorType& color;
90     OpacityType opa;
91     int8_t offsetX;
92     int8_t offsetY;
93 
94     const uint32_t& letter;
95     UITextLanguageDirect direct;
96     uint16_t fontId;
97     uint8_t shapingId;
98     uint8_t fontSize;
99 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
100     TextStyle textStyle;
101 #endif
102     bool baseLine;
103     int16_t letterSpace_;
104     int16_t lineSpace_;
105     bool havebackgroundColor;
106     ColorType& backgroundColor;
107     bool haveLineBackgroundColor;
108     ColorType& lineBackgroundColor;
109 };
110 
111 struct TransformInitState {
112 #if defined(ENABLE_FIXED_POINT) && ENABLE_FIXED_POINT
113     // parameters below are Q15 fixed-point number
114     int64_t verticalU;
115     int64_t verticalV;
116     int64_t duHorizon;
117     int64_t dvHorizon;
118     int64_t duVertical;
119     int64_t dvVertical;
120     // parameters above are Q15 fixed-point number
121 #else
122     float verticalU;
123     float verticalV;
124     float duHorizon;
125     float dvHorizon;
126     float duVertical;
127     float dvVertical;
128 #endif
129 };
130 
131 struct TriangleEdge {
TriangleEdgeTriangleEdge132     TriangleEdge() {}
133     TriangleEdge(int16_t x1, int16_t y1, int16_t duInt, int16_t dvInt);
134     ~TriangleEdge();
135 #if defined(ENABLE_FIXED_POINT) && ENABLE_FIXED_POINT
136     // parameters below are Q15 fixed-point number
137     int64_t curX = 0;
138     int64_t curY = 0;
139     int64_t du = 0;
140     int64_t dv = 0;
141     // parameters above are Q15 fixed-point number
142 #else
143     float curX = 0.0f;
144     float curY = 0.0f;
145     float du = 0.0f;
146     float dv = 0.0f;
147 #endif
148 };
149 
150 struct TriangleTransformDataInfo {
151     const TransformDataInfo& info;
152     Point p1;
153     Point p2;
154     Point p3;
155     bool isRightPart;
156     bool ignoreJunctionPoint;
157 };
158 
159 struct TriangleScanInfo {
160     int16_t yMin;
161     int16_t yMax;
162     TriangleEdge& edge1;
163     TriangleEdge& edge2;
164     uint8_t* screenBuffer;
165     uint8_t bufferPxSize;
166     const ColorType& color;
167     const OpacityType opaScale;
168     TransformInitState& init;
169     uint16_t screenBufferWidth;
170     uint8_t pixelSize;
171     const int32_t srcLineWidth;
172     const TransformDataInfo& info;
173     const Rect& mask;
174     bool isRightPart;
175     bool ignoreJunctionPoint;
176     Matrix3<float> matrix;
177 };
178 
179 struct TrianglePartInfo {
180     const Rect& mask;
181     const TransformMap& transMap;
182     const Point& position;
183     TriangleEdge& edge1;
184     TriangleEdge& edge2;
185     int16_t yMin;
186     int16_t yMax;
187     const TransformDataInfo& info;
188     const ColorType& color;
189     const OpacityType opaScale;
190     bool isRightPart;
191     bool ignoreJunctionPoint;
192 };
193 
194 enum {
195     IMG_SRC_VARIABLE,
196     IMG_SRC_FILE,
197     IMG_SRC_UNKNOWN,
198 };
199 
200 class DrawUtils : public HeapBase {
201 public:
202     static DrawUtils* GetInstance();
203 
204     void DrawColorArea(BufferInfo& gfxDstBuffer, const Rect& area, const Rect& mask,
205                        const ColorType& color, OpacityType opa) const;
206 
207     void DrawColorAreaBySides(BufferInfo& gfxDstBuffer, const Rect& mask, const ColorType& color,
208                               OpacityType opa, const EdgeSides& sides) const;
209 
210     void DrawPixel(BufferInfo& gfxDstBuffer, int16_t x, int16_t y, const Rect& mask,
211                    const ColorType& color, OpacityType opa) const;
212 
213     void DrawColorLetter(BufferInfo& gfxDstBuffer,
214                          const LabelLetterInfo& letterInfo,
215                          uint8_t* fontMap,
216                          GlyphNode node,
217                          int16_t lineHeight) const;
218     void DrawNormalLetter(BufferInfo& gfxDstBuffer,
219                           const LabelLetterInfo& letterInfo,
220                           uint8_t* fontMap,
221                           GlyphNode node,
222                           uint8_t maxLetterSize) const;
223 
224     void DrawLetter(BufferInfo& gfxDstBuffer,
225                     const uint8_t* fontMap,
226                     const Rect& fontRect,
227                     const Rect& subRect,
228                     const uint8_t fontWeight,
229                     const ColorType& color,
230                     const OpacityType opa) const;
231 
232     void DrawImage(BufferInfo& gfxDstBuffer, const Rect& area, const Rect& mask,
233                    const uint8_t* image, OpacityType opa, uint8_t pxBitSize, ColorMode colorMode) const;
234 
235     static void
236         GetXAxisErrForJunctionLine(bool ignoreJunctionPoint, bool isRightPart, int16_t& xMinErr, int16_t& xMaxErr);
237 
238     static void GetTransformInitState(const TransformMap& transMap,
239                                       const Point& position,
240                                       const Rect& trans,
241                                       TransformInitState& init);
242 
243     static void DrawTriangleTransform(BufferInfo& gfxDstBuffer,
244                                       const Rect& mask,
245                                       const Point& position,
246                                       const ColorType& color,
247                                       OpacityType opaScale,
248                                       const TransformMap& transMap,
249                                       const TriangleTransformDataInfo& dataInfo);
250 
251     void DrawTransform(BufferInfo& gfxDstBuffer,
252                        const Rect& mask,
253                        const Point& position,
254                        const ColorType& color,
255                        OpacityType opaScale,
256                        const TransformMap& transMap,
257                        const TransformDataInfo& dataInfo) const;
258 
259     void DrawTranspantArea(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& mask);
260 
261     void DrawWithBuffer(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& mask, const ColorType* colorBuf);
262 
263     static uint8_t GetPxSizeByColorMode(uint8_t colorMode);
264 
265     static uint8_t GetByteSizeByColorMode(uint8_t colorMode);
266 
GetMixOpacity(OpacityType opa1,OpacityType opa2)267     static OpacityType GetMixOpacity(OpacityType opa1, OpacityType opa2)
268     {
269         // 8: Shift right 8 bits
270         OpacityType opaMix = (opa1 == OPA_OPAQUE) ? opa2 : ((static_cast<uint16_t>(opa1) * opa2) >> 8);
271         return opaMix;
272     }
273 
274     void DrawAdjPixelInLine(BufferInfo& gfxDstBuffer,
275                             int16_t x1,
276                             int16_t y1,
277                             int16_t x2,
278                             int16_t y2,
279                             const Rect& mask,
280                             const ColorType& color,
281                             OpacityType opa,
282                             uint16_t w) const;
283 
284     void DrawPixelInLine(BufferInfo& gfxDstBuffer, int16_t x, int16_t y, const Rect& mask,
285                          const ColorType& color, OpacityType opa, uint16_t w) const;
286 
287     void DrawVerPixelInLine(BufferInfo& gfxDstBuffer,
288                             int16_t x,
289                             int16_t y,
290                             int8_t dir,
291                             const Rect& mask,
292                             const ColorType& color,
293                             OpacityType opa,
294                             uint16_t weight) const;
295 
296     void DrawHorPixelInLine(BufferInfo& gfxDstBuffer,
297                             int16_t x,
298                             int16_t y,
299                             int8_t dir,
300                             const Rect& mask,
301                             const ColorType& color,
302                             OpacityType opa,
303                             uint16_t weight) const;
304 
305     void BlendWithSoftWare(const uint8_t* src1,
306                            const Rect& srcRect,
307                            uint32_t srcStride,
308                            uint32_t srcLineNumber,
309                            ColorMode srcMode,
310                            uint32_t color,
311                            OpacityType opa,
312                            uint8_t* dst,
313                            uint32_t destStride,
314                            ColorMode destMode,
315                            uint32_t x,
316                            uint32_t y) const;
317 
318     void FillAreaWithSoftWare(BufferInfo& gfxDstBuffer,
319                               const Rect& fillArea,
320                               const ColorType& color,
321                               const OpacityType& opa) const;
322 #ifdef ARM_NEON_OPT
323 
324     void BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue,
325                       uint8_t alpha, uint8_t cover);
326     void BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue,
327                       uint8_t alpha);
328     void BlendLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t srcCover);
329     void BlendLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t* srcCovers);
330     void BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t* covers);
331     void BlendPreLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue,
332                          uint8_t alpha, uint8_t cover);
333     void BlendPreLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue,
334                          uint8_t alpha);
335     void BlendPreLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t srcCover);
336     void BlendPreLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t* srcCovers);
337     void BlendPreLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t* covers);
338 #endif
339 private:
340     using DrawTriangleTransformFuc = void (*)(const TriangleScanInfo& triangle, const ColorMode bufferMode);
341 
342     static void DrawTriangleTrueColorNearest(const TriangleScanInfo& triangle, const ColorMode bufferMode);
343 
344     static void DrawTriangleAlphaBilinear(const TriangleScanInfo& triangle, const ColorMode bufferMode);
345 
346     static void DrawTriangleTrueColorBilinear565(const TriangleScanInfo& triangle, const ColorMode bufferMode);
347 
348     static void DrawTriangleTrueColorBilinear888(const TriangleScanInfo& triangle, const ColorMode bufferMode);
349 
350     static void Draw3DTriangleTrueColorBilinear8888(const TriangleScanInfo& triangle, const ColorMode bufferMode);
351 
352     static void DrawTriangleTrueColorBilinear8888(const TriangleScanInfo& triangle, const ColorMode bufferMode);
353 
354     inline static void StepToNextLine(TriangleEdge& edg1, TriangleEdge& edg2);
355 
356     static void DrawTriangleTransformPart(BufferInfo& gfxDstBuffer, const TrianglePartInfo& part);
357 
358     static OpacityType GetPxAlphaForAlphaImg(const TransformDataInfo& dataInfo, const Point& point);
359 
360     static void AddBorderToImageData(TransformDataInfo& newDataInfo, ImageInfo& imageinfo);
361 
362     static void UpdateTransMap(int16_t width, int16_t height, TransformMap& transMap);
363 
364     void FillArea(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& mask,
365                   bool isTransparent, const ColorType* colorBuf);
366 
367 #ifdef ARM_NEON_OPT
368     void SetDestAndSrc(ColorMode& srcMode, ColorMode& destMode, uint32_t height, uint8_t* src,
369                        uint32_t width, OpacityType opa, uint8_t* dest, uint32_t destStride,
370                        uint32_t srcStride, uint8_t destByteSize, uint8_t srcByteSize) const;
371 #endif
372 
373     void SetFucInfo(BufferInfo& gfxDstBuffer, const TrianglePartInfo& part,
374                     uint8_t* screenBuffer, TransformInitState& init);
375     void SetPartEdge(BufferInfo& gfxDstBuffer, const TriangleTransformDataInfo& triangleInfo,
376                      TriangleEdge& edge1, TriangleEdge& edge2, bool p3IsInRight,
377                      const Rect& mask, uint8_t yErr, TrianglePartInfo& part) const;
378 };
379 } // namespace OHOS
380 #endif // GRAPHIC_LITE_DRAW_UTILS_H
381