1 /*
2  * Copyright (c) 2024 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 #include "luma_filter.h"
16 
17 #include <native_drawing/drawing_brush.h>
18 #include <native_drawing/drawing_color.h>
19 #include <native_drawing/drawing_color_filter.h>
20 #include <native_drawing/drawing_filter.h>
21 #include <native_drawing/drawing_font.h>
22 #include <native_drawing/drawing_font_mgr.h>
23 #include <native_drawing/drawing_path.h>
24 #include <native_drawing/drawing_pen.h>
25 #include <native_drawing/drawing_point.h>
26 #include <native_drawing/drawing_rect.h>
27 #include <native_drawing/drawing_shader_effect.h>
28 #include <native_drawing/drawing_text_blob.h>
29 #include <native_drawing/drawing_typeface.h>
30 
31 #include "test_common.h"
32 
33 #include "common/log_common.h"
34 
35 enum {
36     K_W = 600, // 600 是位图宽度
37     K_H = 420, // 420 是位图高度
38 };
39 
LumaFilter()40 LumaFilter::LumaFilter()
41 {
42     bitmapWidth_ = K_W;
43     bitmapHeight_ = K_H;
44     fileName_ = "lumafilter";
45 }
46 
ColorSetA(uint32_t c,uint8_t a)47 uint32_t ColorSetA(uint32_t c, uint8_t a)
48 {
49     return (c & 0x00FFFFFF) | (a << 24); // 24  ColorSetA
50 }
51 
52 static float g_kSize = 80;  // 80 是大小
53 static float g_kInset = 10; // 10 用于控制内边距
54 
55 uint32_t kColor1 = 0xFFFFFF00; // 0xFFFFFF00 用于绘制图形
56 uint32_t kColor2 = 0xFF82FF00; // 0xFF82FF00 用于绘制图形
57 
58 OH_Drawing_BlendMode g_modes[] = {
59     OH_Drawing_BlendMode::BLEND_MODE_SRC_OVER,
60     OH_Drawing_BlendMode::BLEND_MODE_DST_OVER,
61     OH_Drawing_BlendMode::BLEND_MODE_SRC_ATOP,
62     OH_Drawing_BlendMode::BLEND_MODE_DST_ATOP,
63     OH_Drawing_BlendMode::BLEND_MODE_SRC_IN,
64     OH_Drawing_BlendMode::BLEND_MODE_DST_IN,
65 };
66 
67 typedef struct {
68     OH_Drawing_ShaderEffect* fShader1;
69     OH_Drawing_ShaderEffect* fShader2;
70 } ST_SHADER;
71 
72 const char* g_modeStrings[] = { "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", "SrcOut", "DstOut",
73     "SrcATop", "DstATop", "Xor", "Plus", "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge",
74     "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", "Multiply", "Hue", "Saturation", "Color",
75     "Luminosity" };
76 
draw_label(OH_Drawing_Canvas * canvas,const char * label,OH_Drawing_Point2D offset)77 void draw_label(OH_Drawing_Canvas* canvas, const char* label, OH_Drawing_Point2D offset)
78 {
79     OH_Drawing_Font* font = OH_Drawing_FontCreate();
80     OH_Drawing_Typeface* type = OH_Drawing_TypefaceCreateDefault();
81     // 默认字体不一致
82     OH_Drawing_FontSetTypeface(font, type);
83     size_t len = strlen(label);
84 
85     // 缺乏计算文本宽度的接口,OH_Drawing_FontCountText临时替代
86     int width = OH_Drawing_FontCountText(font, label, len, TEXT_ENCODING_UTF8);
87     OH_Drawing_TextBlob* blob = OH_Drawing_TextBlobCreateFromText(label, len, font, TEXT_ENCODING_UTF8);
88 
89     OH_Drawing_Pen* pen = OH_Drawing_PenCreate();
90     OH_Drawing_CanvasAttachPen(canvas, pen);
91     OH_Drawing_CanvasDrawTextBlob(canvas, blob, offset.x - width / 2, offset.y); // 2 CanvasDrawTextBlob参数
92 
93     OH_Drawing_FontDestroy(font);
94     OH_Drawing_TypefaceDestroy(type);
95     OH_Drawing_TextBlobDestroy(blob);
96     OH_Drawing_CanvasDetachPen(canvas);
97     OH_Drawing_PenDestroy(pen);
98 }
99 
draw_clip(OH_Drawing_Canvas * canvas,DrawRect & c,OH_Drawing_Rect * rect,uint32_t kColor,OH_Drawing_Brush * brush)100 void draw_clip(OH_Drawing_Canvas* canvas, DrawRect& c, OH_Drawing_Rect* rect, uint32_t kColor, OH_Drawing_Brush* brush)
101 {
102     OH_Drawing_CanvasSave(canvas);
103     OH_Drawing_Rect* cRect = OH_Drawing_RectCreate(c.left, c.top, c.right, c.bottom);
104     OH_Drawing_CanvasClipRect(canvas, cRect, OH_Drawing_CanvasClipOp::INTERSECT, false);
105     OH_Drawing_BrushSetColor(brush, kColor);
106     OH_Drawing_CanvasAttachBrush(canvas, brush);
107     OH_Drawing_CanvasDrawOval(canvas, rect);
108     OH_Drawing_CanvasDetachBrush(canvas);
109     OH_Drawing_CanvasRestore(canvas);
110     OH_Drawing_RectDestroy(cRect);
111 }
112 
draw_scene_oval(OH_Drawing_Canvas * canvas,OH_Drawing_Brush * brush,DrawRect bounds,OH_Drawing_ShaderEffect * s1)113 void draw_scene_oval(OH_Drawing_Canvas* canvas, OH_Drawing_Brush* brush, DrawRect bounds, OH_Drawing_ShaderEffect* s1)
114 {
115     DrawRect r = bounds;
116     OH_Drawing_Rect* rect = OH_Drawing_RectCreate(r.left, r.top, r.right, r.bottom);
117     OH_Drawing_BrushSetAntiAlias(brush, true);
118     OH_Drawing_BrushSetColor(brush, 0x200000FF);
119     OH_Drawing_CanvasAttachBrush(canvas, brush);
120     OH_Drawing_CanvasDrawRect(canvas, rect);
121     OH_Drawing_CanvasDetachBrush(canvas);
122     OH_Drawing_CanvasSaveLayer(canvas, rect, nullptr);
123     OH_Drawing_RectDestroy(rect);
124     r = bounds;
125     r.Inset(g_kInset, 0); // 0 bounds
126     rect = OH_Drawing_RectCreate(r.left, r.top, r.right, r.bottom);
127     OH_Drawing_BrushSetShaderEffect(brush, s1);
128     OH_Drawing_BrushSetColor(brush, s1 ? 0xFF000000 : ColorSetA(kColor1, 0x80));
129     OH_Drawing_BrushSetAntiAlias(brush, true);
130     OH_Drawing_CanvasAttachBrush(canvas, brush);
131     OH_Drawing_CanvasDrawOval(canvas, rect);
132     OH_Drawing_CanvasDetachBrush(canvas);
133     OH_Drawing_RectDestroy(rect);
134 }
135 
draw_scene(OH_Drawing_Canvas * canvas,OH_Drawing_ColorFilter * cFilter,OH_Drawing_BlendMode mode,OH_Drawing_ShaderEffect * s1,OH_Drawing_ShaderEffect * s2)136 void draw_scene(OH_Drawing_Canvas* canvas, OH_Drawing_ColorFilter* cFilter, OH_Drawing_BlendMode mode,
137     OH_Drawing_ShaderEffect* s1, OH_Drawing_ShaderEffect* s2)
138 {
139     DrawRect bounds = { 0, 0, g_kSize, g_kSize }; //  0, 0 bounds
140     DrawRect r = bounds;
141     DrawRect c = bounds;
142     c.right = bounds.CenterX();
143     OH_Drawing_Rect* rect = OH_Drawing_RectCreate(r.left, r.top, r.right, r.bottom);
144     OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
145     draw_scene_oval(canvas, brush, bounds, s1);
146     if (!s1) {
147         draw_clip(canvas, c, rect, kColor1, brush);
148     }
149     OH_Drawing_RectDestroy(rect);
150     OH_Drawing_Brush* xferBrush = OH_Drawing_BrushCreate();
151     r = bounds;
152     rect = OH_Drawing_RectCreate(r.left, r.top, r.right, r.bottom);
153     OH_Drawing_BrushSetBlendMode(xferBrush, mode);
154     OH_Drawing_CanvasSaveLayer(canvas, rect, xferBrush);
155     r = bounds;
156     r.Inset(0, g_kInset);
157     rect = OH_Drawing_RectCreate(r.left, r.top, r.right, r.bottom);
158     OH_Drawing_BrushSetShaderEffect(brush, s2);
159     OH_Drawing_BrushSetColor(brush, s2 ? 0xFF000000 : ColorSetA(kColor2, 0x80));
160     OH_Drawing_Filter* filter = OH_Drawing_FilterCreate();
161     OH_Drawing_FilterSetColorFilter(filter, cFilter);
162     OH_Drawing_BrushSetFilter(brush, filter);
163     OH_Drawing_CanvasAttachBrush(canvas, brush);
164     OH_Drawing_CanvasDrawOval(canvas, rect);
165     OH_Drawing_CanvasDetachBrush(canvas);
166     if (!s2) {
167         draw_clip(canvas, c, rect, kColor2, brush);
168     }
169     OH_Drawing_CanvasDetachBrush(canvas);
170     OH_Drawing_BrushDestroy(brush);
171     OH_Drawing_BrushDestroy(xferBrush);
172     OH_Drawing_RectDestroy(rect);
173     OH_Drawing_FilterDestroy(filter);
174     OH_Drawing_CanvasRestore(canvas);
175     OH_Drawing_CanvasRestore(canvas);
176 }
177 
OnTestFunction(OH_Drawing_Canvas * canvas)178 void LumaFilter::OnTestFunction(OH_Drawing_Canvas* canvas)
179 {
180     uint32_t g1Colors[] = { kColor1, ColorSetA(kColor1, 0x20) };
181     uint32_t g2Colors[] = { kColor2, ColorSetA(kColor2, 0x20) };
182     OH_Drawing_Point* g1Points[] = { OH_Drawing_PointCreate(0, 0),
183         OH_Drawing_PointCreate(0, 100) }; // 0, 0 , 0, 100 PointCreate
184     OH_Drawing_Point* g2Points[] = { OH_Drawing_PointCreate(0, 0),
185         OH_Drawing_PointCreate(g_kSize, 0) }; // 0 PointCreate
186     float pos[] = { 0.2f, 1.0f }; // 0.2f, 1.0f 定义了渐变效果中每种颜色在渐变中的相对位置
187     OH_Drawing_ColorFilter* fFilter = OH_Drawing_ColorFilterCreateLuma();
188     OH_Drawing_ShaderEffect* fGr1 = OH_Drawing_ShaderEffectCreateLinearGradient(
189         g1Points[0], g1Points[1], g1Colors, pos, 2, OH_Drawing_TileMode::CLAMP); // 2 定义渐变效果中颜色的数量。
190     OH_Drawing_ShaderEffect* fGr2 = OH_Drawing_ShaderEffectCreateLinearGradient(
191         g2Points[0], g2Points[1], g2Colors, pos, 2, OH_Drawing_TileMode::CLAMP); // 2 定义渐变效果中颜色的数量。
192 
193     ST_SHADER shaders[] = {
194         { nullptr, nullptr },
195         { nullptr, fGr2 },
196         { fGr1, nullptr },
197         { fGr1, fGr2 },
198     };
199     float gridStep = g_kSize + 2 * g_kInset;
200     size_t modes_size = 6; // 6 定义了modes数组的大小
201     for (size_t i = 0; i < modes_size; ++i) {
202         OH_Drawing_Point2D offset = { gridStep * (0.5f + i), 20 }; // 20 offset
203         draw_label(canvas, g_modeStrings[g_modes[i]], offset);
204     }
205     size_t shaders_size = 4; // 4 定义了shaders数组的大小
206     for (size_t i = 0; i < shaders_size; ++i) {
207         OH_Drawing_CanvasSave(canvas);
208         OH_Drawing_CanvasTranslate(canvas, g_kInset, gridStep * i + 30); // 30 用于控制画布垂直平移的距离
209         for (size_t m = 0; m < modes_size; ++m) {
210             draw_scene(canvas, fFilter, g_modes[m], shaders[i].fShader1, shaders[i].fShader2);
211             OH_Drawing_CanvasTranslate(canvas, gridStep, 0); // 0   CanvasTranslate参数
212         }
213         OH_Drawing_CanvasRestore(canvas);
214     }
215     OH_Drawing_ColorFilterDestroy(fFilter);
216     OH_Drawing_ShaderEffectDestroy(fGr1);
217     OH_Drawing_ShaderEffectDestroy(fGr2);
218     for (int i = 0; i < 2; i++) { // 2 point 数组长度
219         OH_Drawing_PointDestroy(g1Points[i]);
220         OH_Drawing_PointDestroy(g2Points[i]);
221     }
222 }
223