microui  14.5.5
microui
LLUI_PAINTER_impl.c
1 /*
2  * Copyright 2020-2026 MicroEJ Corp. All rights reserved.
3  * MicroEJ Corp. PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4  *
5  * Build: 7E4D1F7C
6  */
7 
8 /*
9  * @file
10  * @brief This file implements all MicroUI drawing native functions.
11  * @see LLUI_PAINTER_impl.h file comment
12  * @author MicroEJ Developer Team
13  * @version 14.5.5
14  * @since MicroEJ UI Pack 13.0.0
15  */
16 
17 // --------------------------------------------------------------------------------
18 // Includes
19 // --------------------------------------------------------------------------------
20 
21 // implements LLUI_PAINTER_impl functions
22 #include <LLUI_PAINTER_impl.h>
23 
24 // use graphical engine functions to synchronize drawings
25 #include <LLUI_DISPLAY.h>
26 
27 // check UI Pack version
28 #include <LLUI_DISPLAY_impl.h>
29 
30 // calls ui_drawing functions
31 #include "ui_drawing.h"
32 
33 // traces the drawings
34 #include "ui_trace.h"
35 
36 // --------------------------------------------------------------------------------
37 // Macros and Defines
38 // --------------------------------------------------------------------------------
39 
40 #if (defined(LLUI_MAJOR_VERSION) && (LLUI_MAJOR_VERSION != 14)) || (defined(LLUI_MINOR_VERSION) && \
41  (LLUI_MINOR_VERSION < 0))
42 #error "This Abstraction Layer is only compatible with UI Pack [14.0.0,15.0.0["
43 #endif
44 
45 // --------------------------------------------------------------------------------
46 // Private functions
47 // --------------------------------------------------------------------------------
48 
49 /*
50  * Checks given bound to fit in bound limits: 0 and max (excluded). Updates size and
51  * origin in consequence
52  */
53 static inline void _check_bound(jint max, jint *bound, jint *size, jint *origin) {
54  if (*bound < 0) {
55  *size += *bound; // decrease size
56  *origin -= *bound; // increase origin
57  *bound = 0;
58  }
59 
60  if ((*bound + *size) > max) {
61  *size = max - *bound; // decrease size
62  }
63 }
64 
65 // --------------------------------------------------------------------------------
66 // LLUI_PAINTER_impl.h functions
67 // --------------------------------------------------------------------------------
68 
69 // See the header file for the function documentation
70 void LLUI_PAINTER_IMPL_writePixel(MICROUI_GraphicsContext *gc, jint x, jint y) {
71  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_writePixel)) {
72  DRAWING_Status status = DRAWING_DONE;
73  UI_TRACE_DRAW_START(writePixel, gc, x, y);
74  if (LLUI_DISPLAY_isPixelInClip(gc, x, y)) {
75  LLUI_DISPLAY_configureClip(gc, false /* point is in clip */);
76  status = UI_DRAWING_writePixel(gc, x, y);
77  } else {
78  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
79  }
80  LLUI_DISPLAY_setDrawingStatus(status);
81  UI_TRACE_DRAW_END(writePixel, status);
82  }
83 }
84 
85 // See the header file for the function documentation
86 void LLUI_PAINTER_IMPL_drawLine(MICROUI_GraphicsContext *gc, jint startX, jint startY, jint endX, jint endY) {
87  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawLine)) {
88  UI_TRACE_DRAW_START(drawLine, gc, startX, startY, endX, endY);
89  // cannot reduce/clip line: may be endX < startX and / or endY < startY
90  DRAWING_Status status = UI_DRAWING_drawLine(gc, startX, startY, endX, endY);
91  LLUI_DISPLAY_setDrawingStatus(status);
92  UI_TRACE_DRAW_END(drawLine, status);
93  }
94 }
95 
96 // See the header file for the function documentation
97 void LLUI_PAINTER_IMPL_drawHorizontalLine(MICROUI_GraphicsContext *gc, jint x, jint y, jint length) {
98  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawHorizontalLine)) {
99  DRAWING_Status status = DRAWING_DONE;
100  UI_TRACE_DRAW_START(drawHorizontalLine, gc, x, y, length);
101 
102  if (length > 0) {
103  jint x1 = x;
104  jint x2 = x + length - 1;
105  if (LLUI_DISPLAY_clipHorizontalLine(gc, &x1, &x2, y)) {
106  LLUI_DISPLAY_configureClip(gc, false /* line has been clipped */);
107  UI_TRACE_START(DrawnRegion, UI_TRACE_IMAGE(&gc->image), true, x1, y, x2 - x1 + 1, 1);
108  status = UI_DRAWING_drawHorizontalLine(gc, x1, x2, y);
109  } else {
110  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
111  }
112  }
113 
114  LLUI_DISPLAY_setDrawingStatus(status);
115  UI_TRACE_DRAW_END(drawHorizontalLine, status);
116  }
117 }
118 
119 // See the header file for the function documentation
120 void LLUI_PAINTER_IMPL_drawVerticalLine(MICROUI_GraphicsContext *gc, jint x, jint y, jint length) {
121  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawVerticalLine)) {
122  DRAWING_Status status = DRAWING_DONE;
123  UI_TRACE_DRAW_START(drawVerticalLine, gc, x, y, length);
124 
125  if (length > 0) {
126  jint y1 = y;
127  jint y2 = y + length - 1;
128  if (LLUI_DISPLAY_clipVerticalLine(gc, &y1, &y2, x)) {
129  LLUI_DISPLAY_configureClip(gc, false /* line has been clipped */);
130  UI_TRACE_START(DrawnRegion, UI_TRACE_IMAGE(&gc->image), true, x, y1, 1, y2 - y1 + 1);
131  status = UI_DRAWING_drawVerticalLine(gc, x, y1, y2);
132  } else {
133  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
134  }
135  }
136 
137  LLUI_DISPLAY_setDrawingStatus(status);
138  UI_TRACE_DRAW_END(drawVerticalLine, status);
139  }
140 }
141 
142 // See the header file for the function documentation
143 void LLUI_PAINTER_IMPL_drawRectangle(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height) {
144  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawRectangle)) {
145  DRAWING_Status status = DRAWING_DONE;
146  UI_TRACE_DRAW_START(drawRectangle, gc, x, y, width, height);
147 
148  if ((width > 0) && (height > 0)) {
149  jint x1 = x;
150  jint x2 = x + width - 1;
151  jint y1 = y;
152  jint y2 = y + height - 1;
153 
154  // cannot reduce rectangle; can only check if it is fully in clip
155  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRectangleInClip(gc, x1, y1, x2, y2));
156  status = UI_DRAWING_drawRectangle(gc, x1, y1, x2, y2);
157  }
158 
159  LLUI_DISPLAY_setDrawingStatus(status);
160  UI_TRACE_DRAW_END(drawRectangle, status);
161  }
162 }
163 
164 // See the header file for the function documentation
165 void LLUI_PAINTER_IMPL_fillRectangle(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height) {
166  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillRectangle)) {
167  DRAWING_Status status = DRAWING_DONE;
168  UI_TRACE_DRAW_START(fillRectangle, gc, x, y, width, height);
169 
170  if ((width > 0) && (height > 0)) {
171  jint x1 = x;
172  jint x2 = x + width - 1;
173  jint y1 = y;
174  jint y2 = y + height - 1;
175 
176  if (LLUI_DISPLAY_clipRectangle(gc, &x1, &y1, &x2, &y2)) {
177  LLUI_DISPLAY_configureClip(gc, false /* rectangle has been clipped */);
178  UI_TRACE_START(DrawnRegion, UI_TRACE_IMAGE(&gc->image), true, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
179  status = UI_DRAWING_fillRectangle(gc, x1, y1, x2, y2);
180  } else {
181  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
182  }
183  }
184  LLUI_DISPLAY_setDrawingStatus(status);
185  UI_TRACE_DRAW_END(fillRectangle, status);
186  }
187 }
188 
189 // See the header file for the function documentation
190 void LLUI_PAINTER_IMPL_drawRoundedRectangle(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height,
191  jint cornerEllipseWidth, jint cornerEllipseHeight) {
192  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawRoundedRectangle)) {
193  DRAWING_Status status = DRAWING_DONE;
194  UI_TRACE_DRAW_START(drawRoundedRectangle, gc, x, y, width, height, cornerEllipseWidth, cornerEllipseHeight);
195 
196  // tests on size and clip are performed after suspend to prevent to perform it several times
197  if ((width > 0) && (height > 0)) {
198  // cannot reduce rectangle; can only check if it is fully in clip
199  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height));
200  status = UI_DRAWING_drawRoundedRectangle(gc, x, y, width, height, cornerEllipseWidth, cornerEllipseHeight);
201  }
202  LLUI_DISPLAY_setDrawingStatus(status);
203  UI_TRACE_DRAW_END(drawRoundedRectangle, status);
204  }
205 }
206 
207 // See the header file for the function documentation
208 void LLUI_PAINTER_IMPL_fillRoundedRectangle(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height,
209  jint cornerEllipseWidth, jint cornerEllipseHeight) {
210  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillRoundedRectangle)) {
211  DRAWING_Status status = DRAWING_DONE;
212  UI_TRACE_DRAW_START(fillRoundedRectangle, gc, x, y, width, height, cornerEllipseWidth, cornerEllipseHeight);
213 
214  // tests on size and clip are performed after suspend to prevent to perform it several times
215  if ((width > 0) && (height > 0)) {
216  jint x1 = x;
217  jint x2 = x + width - 1;
218  jint y1 = y;
219  jint y2 = y + height - 1;
220 
221  if (LLUI_DISPLAY_clipRectangle(gc, &x1, &y1, &x2, &y2)) {
222  // drawing fully or partially fits the clip
223  // cannot reduce rectangle; can only check if it is fully in clip
224  bool disable_clip = LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height);
225  LLUI_DISPLAY_configureClip(gc, !disable_clip);
226  UI_TRACE_START(DrawnRegion, UI_TRACE_IMAGE(&gc->image), disable_clip, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
227  status = UI_DRAWING_fillRoundedRectangle(gc, x, y, width, height, cornerEllipseWidth,
228  cornerEllipseHeight);
229  } else {
230  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
231  }
232  }
233  LLUI_DISPLAY_setDrawingStatus(status);
234  UI_TRACE_DRAW_END(fillRoundedRectangle, status);
235  }
236 }
237 
238 // See the header file for the function documentation
239 void LLUI_PAINTER_IMPL_drawCircleArc(MICROUI_GraphicsContext *gc, jint x, jint y, jint diameter, jfloat startAngle,
240  jfloat arcAngle) {
241  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawCircleArc)) {
242  DRAWING_Status status = DRAWING_DONE;
243  UI_TRACE_DRAW_START(drawCircleArc, gc, x, y, diameter, (uint32_t)startAngle, (uint32_t)arcAngle);
244 
245  // tests on size and clip are performed after suspend to prevent to perform it several times
246  if ((diameter > 0) && ((int32_t)arcAngle != 0)) {
247  // cannot reduce rectangle; can only check if it is fully in clip
248  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, diameter, diameter));
249  status = UI_DRAWING_drawCircleArc(gc, x, y, diameter, startAngle, arcAngle);
250  }
251  LLUI_DISPLAY_setDrawingStatus(status);
252  UI_TRACE_DRAW_END(drawCircleArc, status);
253  }
254 }
255 
256 // See the header file for the function documentation
257 void LLUI_PAINTER_IMPL_drawEllipseArc(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height,
258  jfloat startAngle, jfloat arcAngle) {
259  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawEllipseArc)) {
260  DRAWING_Status status = DRAWING_DONE;
261  UI_TRACE_DRAW_START(drawEllipseArc, gc, x, y, width, height, (uint32_t)startAngle, (uint32_t)arcAngle);
262 
263  // tests on size and clip are performed after suspend to prevent to perform it several times
264  if ((width > 0) && (height > 0) && ((int32_t)arcAngle != 0)) {
265  // cannot reduce rectangle; can only check if it is fully in clip
266  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height));
267  status = UI_DRAWING_drawEllipseArc(gc, x, y, width, height, startAngle, arcAngle);
268  }
269  LLUI_DISPLAY_setDrawingStatus(status);
270  UI_TRACE_DRAW_END(drawEllipseArc, status);
271  }
272 }
273 
274 // See the header file for the function documentation
275 void LLUI_PAINTER_IMPL_fillCircleArc(MICROUI_GraphicsContext *gc, jint x, jint y, jint diameter, jfloat startAngle,
276  jfloat arcAngle) {
277  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillCircleArc)) {
278  DRAWING_Status status = DRAWING_DONE;
279  UI_TRACE_DRAW_START(fillCircleArc, gc, x, y, diameter, (uint32_t)startAngle, (uint32_t)arcAngle);
280 
281  // tests on size and clip are performed after suspend to prevent to perform it several times
282  if ((diameter > 0) && ((int32_t)arcAngle != 0)) {
283  // cannot reduce rectangle; can only check if it is fully in clip
284  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, diameter, diameter));
285  status = UI_DRAWING_fillCircleArc(gc, x, y, diameter, startAngle, arcAngle);
286  }
287  LLUI_DISPLAY_setDrawingStatus(status);
288  UI_TRACE_DRAW_END(fillCircleArc, status);
289  }
290 }
291 
292 // See the header file for the function documentation
293 void LLUI_PAINTER_IMPL_fillEllipseArc(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height,
294  jfloat startAngle, jfloat arcAngle) {
295  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillEllipseArc)) {
296  DRAWING_Status status = DRAWING_DONE;
297  UI_TRACE_DRAW_START(fillEllipseArc, gc, x, y, width, height, (uint32_t)startAngle, (uint32_t)arcAngle);
298 
299  // tests on size and clip are performed after suspend to prevent to perform it several times
300  if ((width > 0) && (height > 0) && ((int32_t)arcAngle != 0)) {
301  // cannot reduce rectangle; can only check if it is fully in clip
302  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height));
303  status = UI_DRAWING_fillEllipseArc(gc, x, y, width, height, startAngle, arcAngle);
304  }
305  LLUI_DISPLAY_setDrawingStatus(status);
306  UI_TRACE_DRAW_END(fillEllipseArc, status);
307  }
308 }
309 
310 // See the header file for the function documentation
311 void LLUI_PAINTER_IMPL_drawEllipse(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height) {
312  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawEllipse)) {
313  DRAWING_Status status = DRAWING_DONE;
314  UI_TRACE_DRAW_START(drawEllipse, gc, x, y, width, height);
315 
316  // tests on size and clip are performed after suspend to prevent to perform it several times
317  if ((width > 0) && (height > 0)) {
318  // cannot reduce rectangle; can only check if it is fully in clip
319  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height));
320  status = UI_DRAWING_drawEllipse(gc, x, y, width, height);
321  }
322  LLUI_DISPLAY_setDrawingStatus(status);
323  UI_TRACE_DRAW_END(drawEllipse, status);
324  }
325 }
326 
327 // See the header file for the function documentation
328 void LLUI_PAINTER_IMPL_fillEllipse(MICROUI_GraphicsContext *gc, jint x, jint y, jint width, jint height) {
329  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillEllipse)) {
330  DRAWING_Status status = DRAWING_DONE;
331  UI_TRACE_DRAW_START(fillEllipse, gc, x, y, width, height);
332 
333  // tests on size and clip are performed after suspend to prevent to perform it several times
334  if ((width > 0) && (height > 0)) {
335  // cannot reduce rectangle; can only check if it is fully in clip
336  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, width, height));
337  status = UI_DRAWING_fillEllipse(gc, x, y, width, height);
338  }
339  LLUI_DISPLAY_setDrawingStatus(status);
340  UI_TRACE_DRAW_END(fillEllipse, status);
341  }
342 }
343 
344 // See the header file for the function documentation
345 void LLUI_PAINTER_IMPL_drawCircle(MICROUI_GraphicsContext *gc, jint x, jint y, jint diameter) {
346  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawCircle)) {
347  DRAWING_Status status = DRAWING_DONE;
348  UI_TRACE_DRAW_START(drawCircle, gc, x, y, diameter);
349 
350  // tests on size and clip are performed after suspend to prevent to perform it several times
351  if (diameter > 0) {
352  // cannot reduce rectangle; can only check if it is fully in clip
353  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, diameter, diameter));
354  status = UI_DRAWING_drawCircle(gc, x, y, diameter);
355  }
356  LLUI_DISPLAY_setDrawingStatus(status);
357  UI_TRACE_DRAW_END(drawCircle, status);
358  }
359 }
360 
361 // See the header file for the function documentation
362 void LLUI_PAINTER_IMPL_fillCircle(MICROUI_GraphicsContext *gc, jint x, jint y, jint diameter) {
363  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_fillCircle)) {
364  DRAWING_Status status = DRAWING_DONE;
365  UI_TRACE_DRAW_START(fillCircle, gc, x, y, diameter);
366 
367  // tests on size and clip are performed after suspend to prevent to perform it several times
368  if (diameter > 0) {
369  // cannot reduce rectangle; can only check if it is fully in clip
370  LLUI_DISPLAY_configureClip(gc, !LLUI_DISPLAY_isRegionInClip(gc, x, y, diameter, diameter));
371  status = UI_DRAWING_fillCircle(gc, x, y, diameter);
372  }
373  LLUI_DISPLAY_setDrawingStatus(status);
374  UI_TRACE_DRAW_END(fillCircle, status);
375  }
376 }
377 
378 // See the header file for the function documentation
379 void LLUI_PAINTER_IMPL_drawImage(MICROUI_GraphicsContext *gc, MICROUI_Image *img, jint regionX, jint regionY,
380  jint width, jint height, jint x, jint y, jint alpha) {
381  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawImage)) {
382  DRAWING_Status status = DRAWING_DONE;
383  UI_TRACE_DRAW_START(drawImage, gc, UI_TRACE_IMAGE(img), regionX, regionY, width, height, x, y, alpha);
384 
385  // tests on parameters and clip are performed after suspend to prevent to perform it several times
386  if (!LLUI_DISPLAY_isImageClosed(img) && (alpha > 0)) {
387  // sanity check on opacity
388  jint l_alpha = (alpha > 255) ? 255 : alpha;
389 
390  // compute inside image bounds
391  _check_bound(img->width, &regionX, &width, &x);
392  _check_bound(img->height, &regionY, &height, &y);
393 
394  // compute inside graphics context bounds
395  _check_bound(gc->image.width, &x, &width, &regionX);
396  _check_bound(gc->image.height, &y, &height, &regionY);
397 
398  if ((width > 0) && (height > 0)) {
399  if (LLUI_DISPLAY_clipRegion(gc, &regionX, &regionY, &width, &height, &x, &y)) {
400  LLUI_DISPLAY_configureClip(gc, false /* region has been clipped */);
401  UI_TRACE_START(DrawnRegion, UI_TRACE_IMAGE(&gc->image), true, x, y, width, height);
402 
403  if (gc->image.format == img->format) {
404  // source & destination have got the same pixels memory representation
405 
406  MICROUI_Image *image = LLUI_DISPLAY_getSourceImage(img);
407 
408  if ((0xff /* fully opaque */ == l_alpha) && !LLUI_DISPLAY_isTransparent(img)) {
409  // copy source on destination without applying an opacity (beware about the overlapping)
410  status = UI_DRAWING_copyImage(gc, image, regionX, regionY, width, height, x, y);
411  } else if (LLUI_DISPLAY_getBufferAddress(img) == LLUI_DISPLAY_getBufferAddress(&gc->image)) {
412  // blend source on itself applying an opacity (beware about the overlapping)
413  status = UI_DRAWING_drawRegion(gc, regionX, regionY, width, height, x, y, l_alpha);
414  } else {
415  // blend source on destination applying an opacity
416  status = UI_DRAWING_drawImage(gc, image, regionX, regionY, width, height, x, y, l_alpha);
417  }
418  } else {
419  // draw source on destination applying an opacity
420  status = UI_DRAWING_drawImage(gc, img, regionX, regionY, width, height, x, y, l_alpha);
421  }
422  } else {
423  UI_TRACE_START(OutOfClip, UI_TRACE_IMAGE(&gc->image));
424  }
425  }
426  // else: nothing to do
427  }
428  // else: nothing to do
429 
430  // requestDrawing() has been called and accepted: notify the end of empty drawing
431  LLUI_DISPLAY_setDrawingStatus(status);
432  UI_TRACE_DRAW_END(drawImage, status);
433  }
434 }
435 
436 // See the header file for the function documentation
437 void LLUI_PAINTER_IMPL_drawString(MICROUI_GraphicsContext *gc, jchar *chars, jint offset, jint length,
438  MICROUI_Font *font, jint x, jint y) {
439  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawString)) {
440  DRAWING_Status status = DRAWING_DONE;
441  UI_TRACE_DRAW_START(drawString, gc, length, x, y);
442  if (length > 0) {
443  status = UI_DRAWING_drawString(gc, chars + offset, length, font, x, y);
444  }
445  LLUI_DISPLAY_setDrawingStatus(status);
446  UI_TRACE_DRAW_END(drawString, status);
447  }
448 }
449 
450 // See the header file for the function documentation
451 jint LLUI_PAINTER_IMPL_stringWidth(jchar *chars, jint offset, jint length, MICROUI_Font *font) {
452  UI_TRACE_START(stringWidth, length);
453  return (length <= 0) ? 0 : UI_DRAWING_stringWidth(chars + offset, length, font);
454 }
455 
456 // See the header file for the function documentation
457 jint LLUI_PAINTER_IMPL_initializeRenderableStringSNIContext(jchar *chars, jint offset, jint length, MICROUI_Font *font,
458  MICROUI_RenderableString *renderableString) {
459  jint ret = 0;
460  if (length > 0) {
461  ret = UI_DRAWING_initializeRenderableStringSNIContext(chars + offset, length, font, renderableString);
462  }
463  return ret;
464 }
465 
466 // See the header file for the function documentation
467 void LLUI_PAINTER_IMPL_drawRenderableString(MICROUI_GraphicsContext *gc, jchar *chars, jint offset, jint length,
468  MICROUI_Font *font, jint width, MICROUI_RenderableString *renderableString,
469  jint x, jint y) {
470  if (LLUI_DISPLAY_requestDrawing(gc, (SNI_callback)LLUI_PAINTER_IMPL_drawRenderableString)) {
471  DRAWING_Status status = DRAWING_DONE;
472  UI_TRACE_DRAW_START(drawRenderableString, gc, length, x, y);
473  if (length > 0) {
474  status = UI_DRAWING_drawRenderableString(gc, chars + offset, length, font, width, renderableString, x, y);
475  }
476  LLUI_DISPLAY_setDrawingStatus(status);
477  UI_TRACE_DRAW_END(drawRenderableString, status);
478  }
479 }
480 
481 // --------------------------------------------------------------------------------
482 // EOF
483 // --------------------------------------------------------------------------------