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
16 #include "core/components_ng/pattern/text/span/tlv_util.h"
17
18
19 namespace OHOS::Ace {
WriteString(std::vector<uint8_t> & buff,const std::string & value)20 void TLVUtil::WriteString(std::vector<uint8_t>& buff, const std::string& value)
21 {
22 WriteUint8(buff, TLV_STRING_TAG);
23 WriteInt32(buff, value.length());
24 for (char ch: value) {
25 WriteUint8(buff, static_cast<uint8_t>(ch));
26 }
27 }
28
ReadString(std::vector<uint8_t> & buff,int32_t & cursor)29 std::string TLVUtil::ReadString(std::vector<uint8_t>& buff, int32_t& cursor)
30 {
31 if (ReadUint8(buff, cursor) != TLV_STRING_TAG) {
32 return "";
33 }
34 int32_t strLen = ReadInt32(buff, cursor);
35 if (strLen == TLV_END || strLen <= 0) {
36 return "";
37 }
38 std::stringstream ss;
39 for (auto i = 0; i < strLen; ++i) {
40 uint8_t chVal = ReadUint8(buff, cursor);
41 if (chVal == TLV_END) {
42 return "";
43 }
44 ss << static_cast<char>(chVal);
45 }
46 return ss.str();
47 }
48
WriteDouble(std::vector<uint8_t> & buff,double value)49 void TLVUtil::WriteDouble(std::vector<uint8_t>& buff, double value)
50 {
51 WriteUint8(buff, TLV_DOUBLE_TAG);
52 std::vector<uint8_t> bytes(sizeof(double));
53 auto valuePtr = reinterpret_cast<uint8_t*>(&value);
54 std::copy(valuePtr, valuePtr + sizeof(double), bytes.begin());
55 buff.insert(buff.end(), bytes.begin(), bytes.end());
56 }
57
ReadDouble(std::vector<uint8_t> & buff,int32_t & cursor)58 double TLVUtil::ReadDouble(std::vector<uint8_t>& buff, int32_t& cursor)
59 {
60 if (ReadUint8(buff, cursor) != TLV_DOUBLE_TAG) {
61 return 0.0;
62 }
63 auto start = buff.begin() + cursor;
64 auto end = start + sizeof(double);
65 double value;
66 std::copy(start, end, reinterpret_cast<uint8_t*>(&value));
67 cursor += sizeof(double);
68 return value;
69 }
70
WriteColor(std::vector<uint8_t> & buff,Color & value)71 void TLVUtil::WriteColor(std::vector<uint8_t>& buff, Color& value)
72 {
73 WriteUint8(buff, TLV_COLOR_TAG);
74 WriteUint8(buff, value.GetAlpha());
75 WriteUint8(buff, value.GetRed());
76 WriteUint8(buff, value.GetGreen());
77 WriteUint8(buff, value.GetBlue());
78 }
79
ReadColor(std::vector<uint8_t> & buff,int32_t & cursor)80 Color TLVUtil::ReadColor(std::vector<uint8_t>& buff, int32_t& cursor)
81 {
82 if (ReadUint8(buff, cursor) != TLV_COLOR_TAG) {
83 return Color();
84 }
85 auto alpha = ReadUint8(buff, cursor);
86 auto red = ReadUint8(buff, cursor);
87 auto green = ReadUint8(buff, cursor);
88 auto blue = ReadUint8(buff, cursor);
89 return Color::FromARGB(alpha, red, green, blue);
90 }
91
WriteDimension(std::vector<uint8_t> & buff,const Dimension & value)92 void TLVUtil::WriteDimension(std::vector<uint8_t>& buff, const Dimension& value)
93 {
94 WriteUint8(buff, TLV_DIMENSION_TAG);
95 WriteDouble(buff, value.Value());
96 WriteInt32(buff, static_cast<int32_t>(value.Unit()));
97 }
98
ReadDimension(std::vector<uint8_t> & buff,int32_t & cursor)99 Dimension TLVUtil::ReadDimension(std::vector<uint8_t>& buff, int32_t& cursor)
100 {
101 if (ReadUint8(buff, cursor) != TLV_DIMENSION_TAG) {
102 return Dimension();
103 }
104 auto val = ReadDouble(buff, cursor);
105 auto unit = static_cast<DimensionUnit>(ReadInt32(buff, cursor));
106 return Dimension(val, unit);
107 }
108
WriteFontFamily(std::vector<uint8_t> & buff,std::vector<std::string> & value)109 void TLVUtil::WriteFontFamily(std::vector<uint8_t>& buff, std::vector<std::string>& value)
110 {
111 WriteUint8(buff, TLV_FONTFAMILIES_TAG);
112 WriteInt32(buff, value.size());
113 for (auto& fontFamily: value) {
114 WriteString(buff, fontFamily);
115 }
116 }
117
ReadFontFamily(std::vector<uint8_t> & buff,int32_t & cursor)118 std::vector<std::string> TLVUtil::ReadFontFamily(std::vector<uint8_t>& buff, int32_t& cursor)
119 {
120 std::vector<std::string> fontFamilies;
121 if (ReadUint8(buff, cursor) != TLV_FONTFAMILIES_TAG) {
122 return fontFamilies;
123 }
124 int32_t fontFamilySize = ReadInt32(buff, cursor);
125 for (auto i = 0; i < fontFamilySize; i++) {
126 auto fontFamily = ReadString(buff, cursor);
127 fontFamilies.emplace_back(fontFamily);
128 }
129 return fontFamilies;
130 }
131
WriteTextShadow(std::vector<uint8_t> & buff,Shadow & value)132 void TLVUtil::WriteTextShadow(std::vector<uint8_t>& buff, Shadow& value)
133 {
134 WriteUint8(buff, TLV_TEXTSHADOW_TAG);
135 WriteDouble(buff, value.GetBlurRadius());
136 auto color = value.GetColor();
137 WriteColor(buff, color);
138 WriteInt32(buff, static_cast<int32_t>(value.GetShadowType()));
139 Offset offset = value.GetOffset();
140 WriteDouble(buff, offset.GetX());
141 WriteDouble(buff, offset.GetY());
142 }
143
ReadTextShadow(std::vector<uint8_t> & buff,int32_t & cursor)144 Shadow TLVUtil::ReadTextShadow(std::vector<uint8_t>& buff, int32_t& cursor)
145 {
146 Shadow shadow;
147 if (ReadUint8(buff, cursor) != TLV_TEXTSHADOW_TAG) {
148 return shadow;
149 }
150 double blurRadius = ReadDouble(buff, cursor);
151 Color color = ReadColor(buff, cursor);
152 ShadowType type = static_cast<ShadowType>(ReadInt32(buff, cursor));
153 double offsetX = ReadDouble(buff, cursor);
154 double offsetY = ReadDouble(buff, cursor);
155 shadow.SetBlurRadius(blurRadius);
156 shadow.SetColor(color);
157 shadow.SetShadowType(type);
158 shadow.SetOffset({offsetX, offsetY});
159 shadow.SetIsFilled(false);
160 return shadow;
161 }
162
WriteTextShadows(std::vector<uint8_t> & buff,std::vector<Shadow> & value)163 void TLVUtil::WriteTextShadows(std::vector<uint8_t>& buff, std::vector<Shadow>& value)
164 {
165 WriteUint8(buff, TLV_TEXTSHADOWS_TAG);
166 WriteInt32(buff, value.size());
167 for (auto& shadow: value) {
168 WriteTextShadow(buff, shadow);
169 }
170 }
171
ReadTextShadows(std::vector<uint8_t> & buff,int32_t & cursor)172 std::vector<Shadow> TLVUtil::ReadTextShadows(std::vector<uint8_t>& buff, int32_t& cursor)
173 {
174 std::vector<Shadow> shadows;
175 if (ReadUint8(buff, cursor) != TLV_TEXTSHADOWS_TAG) {
176 return shadows;
177 }
178 int32_t shadowSize = ReadInt32(buff, cursor);
179 for (auto i = 0; i < shadowSize; i ++) {
180 shadows.emplace_back(ReadTextShadow(buff, cursor));
181 }
182 return shadows;
183 }
184
WriteFontFeature(std::vector<uint8_t> & buff,std::list<std::pair<std::string,int32_t>> & value)185 void TLVUtil::WriteFontFeature(std::vector<uint8_t>& buff, std::list<std::pair<std::string, int32_t>>& value)
186 {
187 WriteUint8(buff, TLV_FONTFEATURE_TAG);
188 WriteInt32(buff, value.size());
189 for (auto& fontFeature : value) {
190 WriteString(buff, fontFeature.first);
191 WriteInt32(buff, fontFeature.second);
192 }
193 }
194
ReadFontFeature(std::vector<uint8_t> & buff,int32_t & cursor)195 std::list<std::pair<std::string, int32_t>> TLVUtil::ReadFontFeature(std::vector<uint8_t>& buff, int32_t& cursor)
196 {
197 std::list<std::pair<std::string, int32_t>> fontFeatureList;
198 if (ReadUint8(buff, cursor) != TLV_FONTFEATURE_TAG) {
199 return fontFeatureList;
200 }
201 int32_t len = ReadInt32(buff, cursor);
202 for (auto i = 0; i < len; i++) {
203 std::string first = ReadString(buff, cursor);
204 int32_t second = ReadInt32(buff, cursor);
205 fontFeatureList.push_back({first, second});
206 }
207 return fontFeatureList;
208 }
209
WriteBorderRadiusProperty(std::vector<uint8_t> & buff,NG::BorderRadiusProperty & value)210 void TLVUtil::WriteBorderRadiusProperty(std::vector<uint8_t>& buff, NG::BorderRadiusProperty& value)
211 {
212 WriteUint8(buff, TLV_BORDERRADIUS_TAG);
213
214 WriteDimension(buff, value.radiusTopLeft.value_or(ILLEGAL_DIMENSION_VALUE));
215 WriteDimension(buff, value.radiusTopRight.value_or(ILLEGAL_DIMENSION_VALUE));
216 WriteDimension(buff, value.radiusBottomLeft.value_or(ILLEGAL_DIMENSION_VALUE));
217 WriteDimension(buff, value.radiusBottomRight.value_or(ILLEGAL_DIMENSION_VALUE));
218 }
219
ReadBorderRadiusProperty(std::vector<uint8_t> & buff,int32_t & cursor)220 NG::BorderRadiusProperty TLVUtil::ReadBorderRadiusProperty(std::vector<uint8_t>& buff, int32_t& cursor)
221 {
222 NG::BorderRadiusProperty br;
223 if (ReadUint8(buff, cursor) != TLV_BORDERRADIUS_TAG) {
224 return br;
225 }
226
227 Dimension radiusTopLeft = ReadDimension(buff, cursor);
228 if (radiusTopLeft.IsNonNegative()) {
229 br.radiusTopLeft = radiusTopLeft;
230 }
231 Dimension radiusTopRight = ReadDimension(buff, cursor);
232 if (radiusTopRight.IsNonNegative()) {
233 br.radiusTopRight = radiusTopRight;
234 }
235 Dimension radiusBottomLeft = ReadDimension(buff, cursor);
236 if (radiusBottomLeft.IsNonNegative()) {
237 br.radiusBottomLeft = radiusBottomLeft;
238 }
239 Dimension radiusBottomRight = ReadDimension(buff, cursor);
240 if (radiusBottomRight.IsNonNegative()) {
241 br.radiusBottomRight = radiusBottomRight;
242 }
243 return br;
244 }
245
WritePixelMap(std::vector<uint8_t> & buff,RefPtr<Ace::PixelMap> & pixelMap)246 void TLVUtil::WritePixelMap(std::vector<uint8_t>& buff, RefPtr<Ace::PixelMap>& pixelMap)
247 {
248 WriteUint8(buff, TLV_PIXEL_MAP_TAG);
249 std::vector<uint8_t> tmpPixel;
250 if (pixelMap) {
251 pixelMap->EncodeTlv(tmpPixel);
252 WriteInt32(buff, static_cast<int32_t>(tmpPixel.size()));
253 buff.insert(buff.end(), tmpPixel.begin(), tmpPixel.end());
254 } else {
255 WriteInt32(buff, 0);
256 }
257 }
258
ReadPixelMap(std::vector<uint8_t> & buff,int32_t & cursor)259 RefPtr<Ace::PixelMap> TLVUtil::ReadPixelMap(std::vector<uint8_t>& buff, int32_t& cursor)
260 {
261 if (ReadUint8(buff, cursor) != TLV_PIXEL_MAP_TAG) {
262 return nullptr;
263 }
264 auto pixelMapLength = ReadInt32(buff, cursor);
265 if (pixelMapLength == 0) {
266 return nullptr;
267 }
268 std::vector<uint8_t> pixelMapSubVec(buff.begin() + cursor, buff.begin() + cursor + pixelMapLength);
269 RefPtr<Ace::PixelMap> p = Ace::PixelMap::DecodeTlv(pixelMapSubVec);
270 cursor += pixelMapLength;
271 return p;
272 }
273
WriteCalcDimension(std::vector<uint8_t> & buff,CalcDimension & value)274 void TLVUtil::WriteCalcDimension(std::vector<uint8_t>& buff, CalcDimension& value)
275 {
276 WriteUint8(buff, TLV_CALCDIMENSION_TAG);
277 WriteDimension(buff, value);
278 }
279
ReadCalcDimension(std::vector<uint8_t> & buff,int32_t & cursor)280 CalcDimension TLVUtil::ReadCalcDimension(std::vector<uint8_t>& buff, int32_t& cursor)
281 {
282 CalcDimension i;
283 if (ReadUint8(buff, cursor) != TLV_CALCDIMENSION_TAG) {
284 return i;
285 }
286 Dimension dim = ReadDimension(buff, cursor);
287 return CalcDimension(dim);
288 }
289
WriteCalcLength(std::vector<uint8_t> & buff,NG::CalcLength & value)290 void TLVUtil::WriteCalcLength(std::vector<uint8_t>& buff, NG::CalcLength& value)
291 {
292 WriteUint8(buff, TLV_CALCLENGTH_TAG);
293 WriteString(buff, value.CalcValue());
294 WriteDimension(buff, value.GetDimension());
295 }
296
ReadCalcLength(std::vector<uint8_t> & buff,int32_t & cursor)297 NG::CalcLength TLVUtil::ReadCalcLength(std::vector<uint8_t>& buff, int32_t& cursor)
298 {
299 NG::CalcLength calcL;
300 if (ReadUint8(buff, cursor) != TLV_CALCLENGTH_TAG) {
301 return calcL;
302 }
303 std::string calcValue = ReadString(buff, cursor);
304 Dimension dim = ReadDimension(buff, cursor);
305 calcL = NG::CalcLength(dim);
306 calcL.SetCalcValue(calcValue);
307 return calcL;
308 }
309
WriteImageSpanSize(std::vector<uint8_t> & buff,ImageSpanSize & value)310 void TLVUtil::WriteImageSpanSize(std::vector<uint8_t>& buff, ImageSpanSize& value)
311 {
312 WriteUint8(buff, TLV_IMAGESPANSIZE_TAG);
313 if (value.width.has_value()) {
314 WriteUint8(buff, TLV_IMAGESPANSIZE_WIDTH_TAG);
315 WriteCalcDimension(buff, value.width.value());
316 }
317 if (value.height.has_value()) {
318 WriteUint8(buff, TLV_IMAGESPANSIZE_HEIGHT_TAG);
319 WriteCalcDimension(buff, value.height.value());
320 }
321 WriteUint8(buff, TLV_IMAGESPANSIZE_END_TAG);
322 }
323
ReadImageSpanSize(std::vector<uint8_t> & buff,int32_t & cursor)324 ImageSpanSize TLVUtil::ReadImageSpanSize(std::vector<uint8_t>& buff, int32_t& cursor)
325 {
326 ImageSpanSize imageSpanSize;
327 if (ReadUint8(buff, cursor) != TLV_IMAGESPANSIZE_TAG) {
328 return imageSpanSize;
329 }
330 for (uint8_t tag = TLVUtil::ReadUint8(buff, cursor);
331 tag != TLV_IMAGESPANSIZE_END_TAG; tag = TLVUtil::ReadUint8(buff, cursor)) {
332 switch (tag) {
333 case TLV_IMAGESPANSIZE_WIDTH_TAG: {
334 imageSpanSize.width = ReadCalcDimension(buff, cursor);
335 break;
336 }
337 case TLV_IMAGESPANSIZE_HEIGHT_TAG: {
338 imageSpanSize.height = ReadCalcDimension(buff, cursor);
339 break;
340 }
341 default:
342 break;
343 }
344 }
345 return imageSpanSize;
346 }
347
WritePaddingProperty(std::vector<uint8_t> & buff,NG::PaddingProperty & value)348 void TLVUtil::WritePaddingProperty(std::vector<uint8_t>& buff, NG::PaddingProperty& value)
349 {
350 WriteUint8(buff, TLV_PADDINGPROPERTY_TAG);
351 if (value.left.has_value()) {
352 WriteUint8(buff, TLV_PADDINGPROPERTY_LEFT_TAG);
353 WriteCalcLength(buff, value.left.value());
354 }
355 if (value.right.has_value()) {
356 WriteUint8(buff, TLV_PADDINGPROPERTY_RIGHT_TAG);
357 WriteCalcLength(buff, value.right.value());
358 }
359 if (value.top.has_value()) {
360 WriteUint8(buff, TLV_PADDINGPROPERTY_TOP_TAG);
361 WriteCalcLength(buff, value.top.value());
362 }
363 if (value.bottom.has_value()) {
364 WriteUint8(buff, TLV_PADDINGPROPERTY_BOTTOM_TAG);
365 WriteCalcLength(buff, value.bottom.value());
366 }
367 WriteUint8(buff, TLV_PADDINGPROPERTY_END_TAG);
368 }
369
ReadPaddingProperty(std::vector<uint8_t> & buff,int32_t & cursor)370 NG::PaddingProperty TLVUtil::ReadPaddingProperty(std::vector<uint8_t>& buff, int32_t& cursor)
371 {
372 NG::PaddingProperty pad;
373 if (ReadUint8(buff, cursor) != TLV_PADDINGPROPERTY_TAG) {
374 return pad;
375 }
376 for (uint8_t tag = TLVUtil::ReadUint8(buff, cursor);
377 tag != TLV_PADDINGPROPERTY_END_TAG; tag = TLVUtil::ReadUint8(buff, cursor)) {
378 switch (tag) {
379 case TLV_PADDINGPROPERTY_LEFT_TAG: {
380 pad.left = ReadCalcLength(buff, cursor);
381 break;
382 }
383 case TLV_PADDINGPROPERTY_TOP_TAG: {
384 pad.top = ReadCalcLength(buff, cursor);
385 break;
386 }
387 case TLV_PADDINGPROPERTY_BOTTOM_TAG: {
388 pad.bottom = ReadCalcLength(buff, cursor);
389 break;
390 }
391 case TLV_PADDINGPROPERTY_RIGHT_TAG: {
392 pad.right = ReadCalcLength(buff, cursor);
393 break;
394 }
395 default:
396 break;
397 }
398 }
399 return pad;
400 }
401
WriteImageSpanAttribute(std::vector<uint8_t> & buff,ImageSpanAttribute & value)402 void TLVUtil::WriteImageSpanAttribute(std::vector<uint8_t>& buff, ImageSpanAttribute& value)
403 {
404 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_TAG);
405 if (value.size.has_value()) {
406 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_SIZE_TAG);
407 WriteImageSpanSize(buff, value.size.value());
408 }
409 if (value.verticalAlign.has_value()) {
410 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_VERTICALALIGN_TAG);
411 WriteVerticalAlign(buff, value.verticalAlign.value());
412 }
413 if (value.objectFit.has_value()) {
414 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_OBJECTFIT_TAG);
415 WriteImageFit(buff, value.objectFit.value());
416 }
417 if (value.marginProp.has_value()) {
418 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_MARGINPROP_TAG);
419 WritePaddingProperty(buff, value.marginProp.value());
420 }
421 if (value.borderRadius.has_value()) {
422 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_BORDERRADIUS_TAG);
423 WriteBorderRadiusProperty(buff, value.borderRadius.value());
424 }
425 if (value.paddingProp.has_value()) {
426 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_PADDINGPROP_TAG);
427 WritePaddingProperty(buff, value.paddingProp.value());
428 }
429 WriteUint8(buff, TLV_IMAGESPANATTRIBUTE_END_TAG);
430 }
431
ReadImageSpanAttribute(std::vector<uint8_t> & buff,int32_t & cursor)432 ImageSpanAttribute TLVUtil::ReadImageSpanAttribute(std::vector<uint8_t>& buff, int32_t& cursor)
433 {
434 ImageSpanAttribute l;
435 if (ReadUint8(buff, cursor) != TLV_IMAGESPANATTRIBUTE_TAG) {
436 return l;
437 }
438 for (uint8_t tag = TLVUtil::ReadUint8(buff, cursor);
439 tag != TLV_IMAGESPANATTRIBUTE_END_TAG; tag = TLVUtil::ReadUint8(buff, cursor)) {
440 switch (tag) {
441 case TLV_IMAGESPANATTRIBUTE_SIZE_TAG: {
442 l.size = ReadImageSpanSize(buff, cursor);
443 break;
444 }
445 case TLV_IMAGESPANATTRIBUTE_VERTICALALIGN_TAG: {
446 l.verticalAlign = ReadVerticalAlign(buff, cursor);
447 break;
448 }
449 case TLV_IMAGESPANATTRIBUTE_OBJECTFIT_TAG: {
450 l.objectFit = ReadImageFit(buff, cursor);
451 break;
452 }
453 case TLV_IMAGESPANATTRIBUTE_MARGINPROP_TAG: {
454 l.marginProp = ReadPaddingProperty(buff, cursor);
455 break;
456 }
457 case TLV_IMAGESPANATTRIBUTE_BORDERRADIUS_TAG: {
458 l.borderRadius = ReadBorderRadiusProperty(buff, cursor);
459 break;
460 }
461 case TLV_IMAGESPANATTRIBUTE_PADDINGPROP_TAG: {
462 l.paddingProp = ReadPaddingProperty(buff, cursor);
463 break;
464 }
465 default:
466 break;
467 }
468 }
469 return l;
470 }
471
WriteLeadingMargin(std::vector<uint8_t> & buff,NG::LeadingMargin & value)472 void TLVUtil::WriteLeadingMargin(std::vector<uint8_t>& buff, NG::LeadingMargin& value)
473 {
474 WriteUint8(buff, TLV_LEADINGMARGIN_TAG);
475 WriteDimension(buff, value.size.Width());
476 WriteDimension(buff, value.size.Height());
477 if (value.pixmap) {
478 WriteUint8(buff, TLV_LEADINGMARGIN_HASPIXEL_TAG);
479 WritePixelMap(buff, value.pixmap);
480 } else {
481 WriteUint8(buff, TLV_LEADINGMARGIN_NOPIXEL_TAG);
482 }
483 }
484
ReadLeadingMargin(std::vector<uint8_t> & buff,int32_t & cursor)485 NG::LeadingMargin TLVUtil::ReadLeadingMargin(std::vector<uint8_t>& buff, int32_t& cursor)
486 {
487 NG::LeadingMargin l;
488 if (ReadUint8(buff, cursor) != TLV_LEADINGMARGIN_TAG) {
489 return l;
490 }
491 auto width = ReadDimension(buff, cursor);
492 auto height = ReadDimension(buff, cursor);
493 l.size = NG::LeadingMarginSize(width, height);
494 auto tag = ReadUint8(buff, cursor);
495 if (tag == TLV_LEADINGMARGIN_HASPIXEL_TAG) {
496 l.pixmap = ReadPixelMap(buff, cursor);
497 }
498 return l;
499 }
500 } // namespace OHOS::Ace