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
29namespace 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
51struct EdgeSides {
52    int16_t left;
53    int16_t right;
54    int16_t top;
55    int16_t bottom;
56};
57
58struct 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
86struct 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
111struct 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
131struct TriangleEdge {
132    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
150struct TriangleTransformDataInfo {
151    const TransformDataInfo& info;
152    Point p1;
153    Point p2;
154    Point p3;
155    bool isRightPart;
156    bool ignoreJunctionPoint;
157};
158
159struct 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
179struct 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
194enum {
195    IMG_SRC_VARIABLE,
196    IMG_SRC_FILE,
197    IMG_SRC_UNKNOWN,
198};
199
200class DrawUtils : public HeapBase {
201public:
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
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
339private:
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