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