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