microvg  7.0.0
microvg
LLVG_PATH_impl_dual.c
Go to the documentation of this file.
1 /*
2  * C
3  *
4  * Copyright 2022-2024 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 "vg_configuration.h"
22 
23 #if defined(VG_FEATURE_PATH) && defined(VG_FEATURE_PATH_DUAL_ARRAY) && (VG_FEATURE_PATH == VG_FEATURE_PATH_DUAL_ARRAY)
24 
25 // TODO Merge with LLVG_PATH_impl.c
26 
27 // -----------------------------------------------------------------------------
28 // Includes
29 // -----------------------------------------------------------------------------
30 
31 #include <math.h>
32 #include <string.h>
33 
34 #include <LLVG_PATH_impl.h>
35 
36 #include "vg_path.h"
37 #include "vg_helper.h"
38 #include "bsp_util.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(VG_PATH_HEADER_t *path, jint array_length, VG_path_command_t cmd, uint32_t nb_params) {
52  size_t current_size = VG_PATH_get_path_header_size() + (path->param_length * sizeof(VG_path_param_t)) +
53  (path->cmd_length * sizeof(VG_path_command_t));
54  size_t required_size = current_size + VG_PATH_get_path_command_size(cmd, nb_params);
55 
56  int32_t ret;
57 
58  if (required_size > array_length) {
59  ret = array_length - required_size;
60  } else {
61  if (
62  // Parameters would write over the commands
63  // or
64  // Commands would go past the array end
65  ((uint8_t *)VG_PATH_get_path_param_end(path)) + (nb_params * sizeof(VG_path_param_t)) >
66  (uint8_t *)VG_PATH_get_path_command_begin(path)
67  || ((uint8_t *)VG_PATH_get_path_command_end(path)) + sizeof(VG_path_command_t) >
68  ((uint8_t *)path) + array_length
69  ) {
70  size_t new_cmd_offset = array_length - VG_PATH_get_path_header_size() - ((path->cmd_length + 1u) *
71  sizeof(VG_path_command_t));
72  // memmove is used instead of memcpy as the source and destination are likely to overlap.
73  (void)memmove(((uint8_t *)VG_PATH_get_path_param_begin(path)) + new_cmd_offset,
74  VG_PATH_get_path_command_begin(path), path->cmd_length * sizeof(VG_path_command_t));
75  path->cmd_offset = new_cmd_offset;
76  }
77  ret = 0;
78  }
79 
80  return ret;
81 }
82 
83 static int32_t _close_path(VG_PATH_HEADER_t *path, jint length, jfloat x1, jfloat y1, jfloat x2, jfloat y2) {
84  int32_t index = _extend_path(path, length, LLVG_PATH_CMD_CLOSE, 0);
85  int32_t ret = LLVG_SUCCESS;
86  if (index == 0) {
87  // finalizes the path by storing the path's bounds
88  path->bounds_xmin = x1;
89  path->bounds_xmax = x2;
90  path->bounds_ymin = y1;
91  path->bounds_ymax = y2;
92  (void)VG_PATH_append_path_command0((jbyte *)path, (uint32_t)index, LLVG_PATH_CMD_CLOSE);
93  } else {
94  // too small buffer, ret is the required extra size * -1
95  ret = -index;
96  }
97  return ret;
98 }
99 
100 // -----------------------------------------------------------------------------
101 // Specific path format functions [optional]: weak functions
102 // -----------------------------------------------------------------------------
103 
104 // See the header file for the function documentation
105 BSP_DECLARE_WEAK_FCNT void VG_PATH_initialize(void) {
106  // nothing to do
107 }
108 
109 // See the header file for the function documentation
110 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_get_path_header_size(void) {
111  return sizeof(VG_PATH_HEADER_t);
112 }
113 
114 // See the header file for the function documentation
115 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_get_path_command_size(jint command, uint32_t nbParams) {
116  (void)command;
117  return (1u * sizeof(VG_path_command_t)) + (nbParams * sizeof(VG_path_param_t));
118 }
119 
120 // See the header file for the function documentation
121 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_append_path_command0(jbyte *bytes, jint array_length, jint cmd) {
122  (void)array_length;
123 
124  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)bytes;
125 
126  *VG_PATH_get_path_command_end(path) = VG_PATH_convert_path_command(cmd);
127 
128  path->cmd_length += 1u;
129 
130  return LLVG_SUCCESS;
131 }
132 
133 // See the header file for the function documentation
134 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_append_path_command1(jbyte *bytes, jint array_length, jint cmd, jfloat x,
135  jfloat y) {
136  (void)array_length;
137  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)bytes;
138 
139  *VG_PATH_get_path_command_end(path) = VG_PATH_convert_path_command(cmd);
140 
141  VG_path_param_t *param_ptr = VG_PATH_get_path_param_end(path);
142  *(param_ptr++) = x;
143  *(param_ptr++) = y;
144 
145  path->cmd_length += 1u;
146  path->param_length += 2u;
147 
148  return LLVG_SUCCESS;
149 }
150 
151 // See the header file for the function documentation
152 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_append_path_command2(jbyte *bytes, jint array_length, jint cmd, jfloat x1,
153  jfloat y1, jfloat x2, jfloat y2) {
154  (void)array_length;
155  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)bytes;
156 
157  *VG_PATH_get_path_command_end(path) = VG_PATH_convert_path_command(cmd);
158 
159  VG_path_param_t *param_ptr = VG_PATH_get_path_param_end(path);
160  *(param_ptr++) = x1;
161  *(param_ptr++) = y1;
162  *(param_ptr++) = x2;
163  *(param_ptr++) = y2;
164 
165  path->cmd_length += 1u;
166  path->param_length += 4u;
167 
168  return LLVG_SUCCESS;
169 }
170 
171 // See the header file for the function documentation
172 BSP_DECLARE_WEAK_FCNT uint32_t VG_PATH_append_path_command3(jbyte *bytes, jint array_length, jint cmd, jfloat x1,
173  jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) {
174  (void)array_length;
175  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)bytes;
176 
177  *VG_PATH_get_path_command_end(path) = VG_PATH_convert_path_command(cmd);
178 
179  VG_path_param_t *param_ptr = VG_PATH_get_path_param_end(path);
180  *(param_ptr++) = x1;
181  *(param_ptr++) = y1;
182  *(param_ptr++) = x2;
183  *(param_ptr++) = y2;
184  *(param_ptr++) = x3;
185  *(param_ptr++) = y3;
186 
187  path->cmd_length += 1u;
188  path->param_length += 6u;
189 
190  return LLVG_SUCCESS;
191 }
192 
193 // -----------------------------------------------------------------------------
194 // LLVG_PATH_impl.h functions
195 // -----------------------------------------------------------------------------
196 
197 // See the header file for the function documentation
198 jint LLVG_PATH_IMPL_initializePath(jbyte *jpath, jint length) {
199  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)jpath;
200  uint32_t header_size = VG_PATH_get_path_header_size();
201  jint ret = LLVG_SUCCESS;
202 
203  if (length >= header_size) {
204  path->cmd_length = 0;
205  path->param_length = 0;
206  path->cmd_offset = 0;
207  path->format = VG_PATH_get_path_encoder_format();
208  } else {
209  // the given byte array is too small
210  ret = header_size;
211  }
212 
213  return ret;
214 }
215 
216 // See the header file for the function documentation
217 jint LLVG_PATH_IMPL_appendPathCommand1(jbyte *jpath, jint length, jint cmd, jfloat x, jfloat y) {
218  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)jpath;
219  jint ret = LLVG_SUCCESS;
220 
221  int32_t index = _extend_path(path, length, cmd, 2);
222  if (index == 0) {
223  (void)VG_PATH_append_path_command1((jbyte *)path, (uint32_t)length, cmd, x, y);
224  } else {
225  // too small buffer, ret is the required extra size * -1
226  ret = -index;
227  }
228 
229  return ret;
230 }
231 
232 // See the header file for the function documentation
233 jint LLVG_PATH_IMPL_appendPathCommand2(jbyte *jpath, jint length, jint cmd, jfloat x1, jfloat y1, jfloat x2,
234  jfloat y2) {
235  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)jpath;
236  jint ret = LLVG_SUCCESS;
237 
238  if (LLVG_PATH_CMD_CLOSE == cmd) {
239  // parameters are path's bounds
240  ret = _close_path(path, length, x1, y1, x2, y2);
241  } else {
242  int32_t index = _extend_path(path, length, cmd, 4);
243  if (index == 0) {
244  (void)VG_PATH_append_path_command2((jbyte *)path, (uint32_t)length, cmd, x1, y1, x2, y2);
245  } else {
246  // too small buffer, ret is the required extra size * -1
247  ret = -index;
248  }
249  }
250 
251  return ret;
252 }
253 
254 // See the header file for the function documentation
255 jint LLVG_PATH_IMPL_appendPathCommand3(jbyte *jpath, jint length, jint cmd, jfloat x1, jfloat y1, jfloat x2, jfloat y2,
256  jfloat x3, jfloat y3) {
257  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)jpath;
258  jint ret = LLVG_SUCCESS;
259 
260  int32_t index = _extend_path(path, length, cmd, 6);
261  if (index == 0) {
262  (void)VG_PATH_append_path_command3((jbyte *)path, (uint32_t)length, cmd, x1, y1, x2, y2, x3, y3);
263  } else {
264  // too small buffer, ret is the required extra size * -1
265  ret = -index;
266  }
267 
268  return ret;
269 }
270 
271 // See the header file for the function documentation
272 void LLVG_PATH_IMPL_reopenPath(jbyte *jpath) {
273  VG_PATH_HEADER_t *path = (VG_PATH_HEADER_t *)jpath;
274  path->cmd_length -= 1u;
275 }
276 
277 // -----------------------------------------------------------------------------
278 // EOF
279 // -----------------------------------------------------------------------------
280 
281 #endif // VG_FEATURE_PATH
MicroEJ MicroVG library low level API: enable some features according to the hardware capacities.
MicroEJ MicroVG library low level API: helper to implement library natives methods.
MicroEJ MicroVG library low level API: implementation of Path.