microvg  2.0.0
microvg
LLVG_PATH_impl.c
Go to the documentation of this file.
1 /*
2  * C
3  *
4  * Copyright 2022 MicroEJ Corp. All rights reserved.
5  * Use of this source code is governed by a BSD-style license that can be found with this software.
6  */
7 
21 #include "microvg_configuration.h"
22 
23 #ifdef VG_FEATURE_PATH
24 
25 // -----------------------------------------------------------------------------
26 // Includes
27 // -----------------------------------------------------------------------------
28 
29 #include <math.h>
30 #include <string.h>
31 
32 #include <LLVG_PATH_impl.h>
33 
34 #include "microvg_path.h"
35 #include "microvg_helper.h"
36 #include "bsp_util.h"
37 
38 #include "mej_math.h"
39 
40 // -----------------------------------------------------------------------------
41 // Private functions
42 // -----------------------------------------------------------------------------
43 
44 /*
45  * @brief Extends the path to be able to store the command and its parameters.
46  *
47  * @return the offset in path buffer where the command will be stored. If the path
48  * buffer is not large enough to contain the requested command, returns a negative
49  * number corresponding to size the buffer must be enlarged for this command.
50  */
51 static int32_t _extend_path(MICROVG_PATH_HEADER_t* path, jint length, jint cmd, uint32_t nb_fields) {
52  uint32_t index = path->data_offset + path->data_size;
53  uint32_t extra_size = MICROVG_PATH_get_path_command_size(cmd, nb_fields);
54  int32_t ret;
55 
56  if (length >= (index + extra_size)) {
57  path->data_size += extra_size;
58 
59  // return next free space (return a positive value)
60  ret = index;
61  }
62  else {
63  // too small buffer, ret is the required extra size
64  // (return a negative value)
65  ret = -extra_size;
66  }
67 
68  return ret;
69 }
70 
71 static int32_t _close_path(MICROVG_PATH_HEADER_t* path, jint length, jfloat x1, jfloat y1, jfloat x2, jfloat y2) {
72  int32_t index = _extend_path(path, length, LLVG_PATH_CMD_CLOSE, 0);
73  int32_t ret = LLVG_SUCCESS;
74  if (index > 0) {
75  // finalizes the path by storing the path's bounds
76  path->bounds_xmin = x1;
77  path->bounds_xmax = x2;
78  path->bounds_ymin = y1;
79  path->bounds_ymax = y2;
80  (void)MICROVG_PATH_append_path_command0((jbyte*)path, (uint32_t)index, LLVG_PATH_CMD_CLOSE);
81  }
82  else {
83  // too small buffer, ret is the required extra size * -1
84  ret = -index;
85  }
86  return ret;
87 }
88 
89 // -----------------------------------------------------------------------------
90 // Specific path format functions [optional]: weak functions
91 // -----------------------------------------------------------------------------
92 
93 // See the header file for the function documentation
94 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_get_path_header_size(void) {
95  return sizeof(MICROVG_PATH_HEADER_t);
96 }
97 
98 // See the header file for the function documentation
99 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_get_path_command_size(jint command, uint32_t nbParams) {
100  (void)command;
101  return (nbParams + (uint32_t)1 /* command */) * sizeof(uint32_t);
102 }
103 
104 // See the header file for the function documentation
105 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_append_path_command0(jbyte* path, uint32_t offset, jint cmd) {
106  uint32_t* data = (uint32_t*)(path + offset);
107  *data = MICROVG_PATH_convert_path_command(cmd);
108  return sizeof(uint32_t);
109 }
110 
111 // See the header file for the function documentation
112 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_append_path_command1(jbyte* path, uint32_t offset, jint cmd, jfloat x, jfloat y) {
113  uint32_t* data = (uint32_t*)(path + offset);
114  *data = MICROVG_PATH_convert_path_command(cmd);
115  ++data;
116  *data = JFLOAT_TO_UINT32_t(x);
117  ++data;
118  *data = JFLOAT_TO_UINT32_t(y);
119  return (uint32_t)3 * sizeof(uint32_t);
120 }
121 
122 // See the header file for the function documentation
123 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_append_path_command2(jbyte* path, uint32_t offset, jint cmd, jfloat x1, jfloat y1, jfloat x2, jfloat y2) {
124  uint32_t* data = (uint32_t*)(path + offset);
125  *data = MICROVG_PATH_convert_path_command(cmd);
126  ++data;
127  *data = JFLOAT_TO_UINT32_t(x1);
128  ++data;
129  *data = JFLOAT_TO_UINT32_t(y1);
130  ++data;
131  *data = JFLOAT_TO_UINT32_t(x2);
132  ++data;
133  *data = JFLOAT_TO_UINT32_t(y2);
134  return (uint32_t)5 * sizeof(uint32_t);
135 }
136 
137 // See the header file for the function documentation
138 BSP_DECLARE_WEAK_FCNT uint32_t MICROVG_PATH_append_path_command3(jbyte* path, uint32_t offset, jint cmd, jfloat x1, jfloat y1, jfloat x2, jfloat y2,
139  jfloat x3, jfloat y3) {
140  uint32_t* data = (uint32_t*)(path + offset);
141  *data = MICROVG_PATH_convert_path_command(cmd);
142  ++data;
143  *data = JFLOAT_TO_UINT32_t(x1);
144  ++data;
145  *data = JFLOAT_TO_UINT32_t(y1);
146  ++data;
147  *data = JFLOAT_TO_UINT32_t(x2);
148  ++data;
149  *data = JFLOAT_TO_UINT32_t(y2);
150  ++data;
151  *data = JFLOAT_TO_UINT32_t(x3);
152  ++data;
153  *data = JFLOAT_TO_UINT32_t(y3);
154  return (uint32_t)7 * sizeof(uint32_t);
155 }
156 
157 // -----------------------------------------------------------------------------
158 // LLVG_PATH_impl.h functions
159 // -----------------------------------------------------------------------------
160 
161 // See the header file for the function documentation
162 jint LLVG_PATH_IMPL_initializePath(jbyte* jpath, jint length) {
163 
165  uint32_t header_size = MICROVG_PATH_get_path_header_size();
166  jint ret = LLVG_SUCCESS;
167 
168  if (length >= header_size) {
169  path->data_size = 0;
170  path->data_offset = header_size;
171  path->format = MICROVG_PATH_get_path_encoder_format();
172  }
173  else {
174  // the given byte array is too small
175  ret = header_size;
176  }
177 
178  return ret;
179 }
180 
181 // See the header file for the function documentation
182 jint LLVG_PATH_IMPL_appendPathCommand1(jbyte* jpath, jint length, jint cmd, jfloat x, jfloat y) {
183 
185  jint ret = LLVG_SUCCESS;
186 
187  int32_t index = _extend_path(path, length, cmd, 2);
188  if (index > 0) {
189  (void)MICROVG_PATH_append_path_command1((jbyte*)path, (uint32_t)index, cmd, x, y);
190  }
191  else {
192  // too small buffer, ret is the required extra size * -1
193  ret = -index;
194  }
195 
196  return ret;
197 }
198 
199 // See the header file for the function documentation
200 jint LLVG_PATH_IMPL_appendPathCommand2(jbyte* jpath, jint length, jint cmd, jfloat x1, jfloat y1, jfloat x2,
201  jfloat y2) {
202 
204  jint ret = LLVG_SUCCESS;
205 
206  if (LLVG_PATH_CMD_CLOSE == cmd) {
207  // parameters are path's bounds
208  ret = _close_path(path, length, x1, y1, x2, y2);
209  }
210  else {
211  int32_t index = _extend_path(path, length, cmd, 4);
212  if (index > 0) {
213  (void)MICROVG_PATH_append_path_command2((jbyte*)path, (uint32_t)index, cmd, x1, y1, x2, y2);
214  }
215  else {
216  // too small buffer, ret is the required extra size * -1
217  ret = -index;
218  }
219  }
220 
221  return ret;
222 }
223 
224 // See the header file for the function documentation
225 jint LLVG_PATH_IMPL_appendPathCommand3(jbyte* jpath, jint length, jint cmd, jfloat x1, jfloat y1, jfloat x2,
226  jfloat y2, jfloat x3, jfloat y3) {
227 
229  jint ret = LLVG_SUCCESS;
230 
231  int32_t index = _extend_path(path, length, cmd, 6);
232  if (index > 0) {
233  (void)MICROVG_PATH_append_path_command3((jbyte*)path, (uint32_t)index, cmd, x1, y1, x2, y2, x3, y3);
234  }
235  else {
236  // too small buffer, ret is the required extra size * -1
237  ret = -index;
238  }
239 
240  return ret;
241 }
242 
243 // See the header file for the function documentation
244 void LLVG_PATH_IMPL_reopenPath(jbyte* jpath) {
246  path->data_size -= MICROVG_PATH_get_path_command_size(LLVG_PATH_CMD_CLOSE, 0);
247 }
248 
249 
250 // See the header file for the function documentation
251 jint LLVG_PATH_IMPL_mergePaths(jbyte* jpathDest, jbyte* jpathSrc1, jbyte* jpathSrc2, jfloat ratio){
252 
253  jint ret = LLVG_SUCCESS;
254  float remaining = (1-ratio);
255 
256  MICROVG_PATH_HEADER_t* pathDest = (MICROVG_PATH_HEADER_t*)jpathDest;
257  MICROVG_PATH_HEADER_t* pathSrc1 = (MICROVG_PATH_HEADER_t*)jpathSrc1;
258  MICROVG_PATH_HEADER_t* pathSrc2 = (MICROVG_PATH_HEADER_t*)jpathSrc2;
259 
260  // Copy header from pathSrc1
261  pathDest->data_size = pathSrc1->data_size;
262  pathDest->data_offset = pathSrc1->data_offset;
263  pathDest->format = pathSrc1->format;
264 
265  // Compute bounds
266  float fSrc1 = pathSrc1->bounds_xmin;
267  float fSrc2 = pathSrc2->bounds_xmin;
268  float fDest = MEJ_MIN(fSrc1, fSrc2);
269  pathDest->bounds_xmin = fDest;
270 
271  fSrc1 = pathSrc1->bounds_ymin;
272  fSrc2 = pathSrc2->bounds_ymin;
273  fDest = MEJ_MIN(fSrc1, fSrc2);
274  pathDest->bounds_ymin = fDest;
275 
276  fSrc1 = pathSrc1->bounds_xmax;
277  fSrc2 = pathSrc2->bounds_xmax;
278  fDest = MEJ_MAX(fSrc1, fSrc2);
279  pathDest->bounds_xmax = fDest;
280 
281  fSrc1 = pathSrc1->bounds_ymax;
282  fSrc2 = pathSrc2->bounds_ymax;
283  fDest = MEJ_MAX(fSrc1, fSrc2);
284  pathDest->bounds_ymax = fDest;
285 
286  // Compute commands
287  uint32_t* dataDest = (uint32_t*)(jpathDest + pathDest->data_offset);
288  uint32_t* dataSrc1 = (uint32_t*)(jpathSrc1 + pathSrc1->data_offset);
289  uint32_t* dataSrc2 = (uint32_t*)(jpathSrc2 + pathSrc2->data_offset);
290 
291  for(uint16_t i=0; i < pathDest->data_size;){
292 
293  uint32_t cmdSrc1 = *dataSrc1;
294 
295  uint32_t nb_parameters = MICROVG_PATH_get_command_parameter_number(cmdSrc1);
296 
297  *dataDest = cmdSrc1;
298  dataSrc1++;
299  dataSrc2++;
300  dataDest++;
301  i += (uint16_t) 4;
302 
303  for(uint32_t j=0; j<nb_parameters;j++ ){
304 
305  // cppcheck-suppress [invalidPointerCast,redundantPointerOp,misra-c2012-11.3] accepted casting macro
306  fSrc1 = UINT32_t_TO_JFLOAT(*dataSrc1);
307  // cppcheck-suppress [invalidPointerCast,redundantPointerOp,misra-c2012-11.3] accepted casting macro
308  fSrc2 = UINT32_t_TO_JFLOAT(*dataSrc2);
309  fDest = (remaining * fSrc1) + (ratio * fSrc2);
310 
311  // cppcheck-suppress [invalidPointerCast,misra-c2012-11.3] accepted casting macro
312  *dataDest = JFLOAT_TO_UINT32_t(fDest);
313 
314  dataSrc1++;
315  dataSrc2++;
316  dataDest++;
317  i += (uint16_t)4;
318  }
319  }
320  return ret;
321 }
322 
323 // -----------------------------------------------------------------------------
324 // EOF
325 // -----------------------------------------------------------------------------
326 
327 #endif // VG_FEATURE_PATH
MicroEJ MicroVG library low level API: helper to implement library natives methods.
MicroEJ MicroVG library low level API: implementation of Path.
MicroEJ MicroVG library low level API: enable some features according to the hardware capacities...