source: mainline/uspace/lib/ui/src/paint.c@ 65ec18d

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 65ec18d was 214aefb, checked in by jxsvoboda <5887334+jxsvoboda@…>, 4 years ago

UI menu (WIP)

  • Property mode set to 100644
File size: 7.5 KB
RevLine 
[de9992c]1/*
[7020d1f]2 * Copyright (c) 2021 Jiri Svoboda
[de9992c]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libui
30 * @{
31 */
32/**
33 * @file Painting routines
34 */
35
36#include <errno.h>
37#include <gfx/color.h>
38#include <gfx/context.h>
39#include <gfx/render.h>
40#include <ui/paint.h>
[d70dc1c4]41#include "../private/resource.h"
[de9992c]42
43/** Paint bevel.
44 *
45 * @param gc Graphic context
46 * @param rect Rectangle to paint into
47 * @param tlcolor Top-left color
48 * @param brcolor Bottom-right color
49 * @param thickness Bevel thickness in pixels
50 * @param inside Place to store rectangle of the interior or @c NULL
51 * @reutrn EOK on success or an error code
52 */
53errno_t ui_paint_bevel(gfx_context_t *gc, gfx_rect_t *rect,
54 gfx_color_t *tlcolor, gfx_color_t *brcolor, gfx_coord_t thickness,
55 gfx_rect_t *inside)
56{
57 gfx_rect_t frect;
58 gfx_coord_t i;
59 errno_t rc;
60
61 /* Top left */
62
63 rc = gfx_set_color(gc, tlcolor);
64 if (rc != EOK)
65 goto error;
66
67 for (i = 0; i < thickness; i++) {
68 frect.p0.x = rect->p0.x + i;
69 frect.p0.y = rect->p0.y + i;
70 frect.p1.x = rect->p1.x - i - 1;
71 frect.p1.y = rect->p0.y + i + 1;
72 rc = gfx_fill_rect(gc, &frect);
73 if (rc != EOK)
74 goto error;
75
76 frect.p0.x = rect->p0.x + i;
77 frect.p0.y = rect->p0.y + i + 1;
78 frect.p1.x = rect->p0.x + i + 1;
79 frect.p1.y = rect->p1.y - i - 1;
80 rc = gfx_fill_rect(gc, &frect);
81 if (rc != EOK)
82 goto error;
83 }
84
85 /* Bottom right */
86
87 rc = gfx_set_color(gc, brcolor);
88 if (rc != EOK)
89 goto error;
90
91 for (i = 0; i < thickness; i++) {
92 frect.p0.x = rect->p0.x + i;
93 frect.p0.y = rect->p1.y - i - 1;
94 frect.p1.x = rect->p1.x - i - 1;
95 frect.p1.y = rect->p1.y - i;
96 rc = gfx_fill_rect(gc, &frect);
97 if (rc != EOK)
98 goto error;
99
100 frect.p0.x = rect->p1.x - i - 1;
101 frect.p0.y = rect->p0.y + i;
102 frect.p1.x = rect->p1.x - i;
103 frect.p1.y = rect->p1.y - i;
104 rc = gfx_fill_rect(gc, &frect);
105 if (rc != EOK)
106 goto error;
107 }
108
109 if (inside != NULL) {
110 inside->p0.x = rect->p0.x + thickness;
111 inside->p0.y = rect->p0.y + thickness;
112 inside->p1.x = rect->p1.x - thickness;
113 inside->p1.y = rect->p1.y - thickness;
114 }
115
116 return EOK;
117error:
118 return rc;
119}
120
[d70dc1c4]121/** Paint inset frame.
122 *
123 * @param resource UI resource
124 * @param rect Rectangle to paint onto
125 * @param inside Place to store inside rectangle or @c NULL
126 * @return EOK on success or an error code
127 */
128errno_t ui_paint_inset_frame(ui_resource_t *resource, gfx_rect_t *rect,
129 gfx_rect_t *inside)
130{
131 gfx_rect_t frame;
132 errno_t rc;
133
134 rc = ui_paint_bevel(resource->gc, rect,
135 resource->wnd_shadow_color, resource->wnd_highlight_color,
136 1, &frame);
137 if (rc != EOK)
138 goto error;
139
140 rc = ui_paint_bevel(resource->gc, &frame,
141 resource->wnd_frame_sh_color, resource->wnd_frame_hi_color,
142 1, inside);
143 if (rc != EOK)
144 goto error;
145
146 return EOK;
147error:
148 return rc;
149}
150
[214aefb]151/** Paint outset frame.
152 *
153 * @param resource UI resource
154 * @param rect Rectangle to paint onto
155 * @param inside Place to store inside rectangle or @c NULL
156 * @return EOK on success or an error code
157 */
158errno_t ui_paint_outset_frame(ui_resource_t *resource, gfx_rect_t *rect,
159 gfx_rect_t *inside)
160{
161 gfx_rect_t frame;
162 errno_t rc;
163
164 rc = ui_paint_bevel(resource->gc, rect,
165 resource->wnd_frame_hi_color, resource->wnd_frame_sh_color,
166 1, &frame);
167 if (rc != EOK)
168 goto error;
169
170 rc = ui_paint_bevel(resource->gc, &frame,
171 resource->wnd_highlight_color, resource->wnd_shadow_color,
172 1, inside);
173 if (rc != EOK)
174 goto error;
175
176 return EOK;
177error:
178 return rc;
179}
180
[7020d1f]181/** Paint filled circle vertical scanline.
182 *
183 * @param gc Graphic context
184 * @param center Coordinates of the center of the circle
185 * @param x X-coordinate of the scanline
186 * @param y0 Lowest Y coordinate of the scanline (inclusive)
187 * @param y1 Highest Y coordinate of the scanline (inclusive)
188 * @param part Which part(s) of cicle to paint
189 * @return EOK on success or an error code
190 */
191static errno_t ui_paint_fcircle_line(gfx_context_t *gc, gfx_coord2_t *center,
192 gfx_coord_t x, gfx_coord_t y0, gfx_coord_t y1, ui_fcircle_part_t part)
193{
194 gfx_rect_t rect;
195 gfx_rect_t trect;
196
197 rect.p0.x = x;
198 rect.p0.y = y0;
199 rect.p1.x = x + 1;
200 rect.p1.y = y1;
201
202 /* Clip to upper-left/lower-right half of circle, if required */
203
204 if ((part & ui_fcircle_upleft) == 0) {
205 if (rect.p0.y < -rect.p1.x)
206 rect.p0.y = -rect.p1.x;
207 }
208
209 if ((part & ui_fcircle_lowright) == 0) {
210 if (rect.p1.y > -rect.p1.x)
211 rect.p1.y = -rect.p1.x;
212 }
213
214 /* If coordinates are reversed, there is nothing to do */
215 if (rect.p1.y <= rect.p0.y)
216 return EOK;
217
218 gfx_rect_translate(center, &rect, &trect);
219
220 return gfx_fill_rect(gc, &trect);
221}
222
223/** Paint filled circle scanlines corresponding to octant point.
224 *
225 * Fills the four vertical scanlines lying between the eight reflections
226 * of a circle point.
227 *
228 * @param gc Graphic context
229 * @param center Coordinates of the center
230 * @param r Radius in pixels
231 * @param part Which part(s) of cicle to paint
232 * @return EOK on success or an error code
233 */
234static int ui_paint_fcircle_point(gfx_context_t *gc, gfx_coord2_t *center,
235 gfx_coord2_t *p, ui_fcircle_part_t part)
236{
237 errno_t rc;
238
239 rc = ui_paint_fcircle_line(gc, center, +p->x, -p->y, p->y + 1, part);
240 if (rc != EOK)
241 return rc;
242 rc = ui_paint_fcircle_line(gc, center, -p->x, -p->y, p->y + 1, part);
243 if (rc != EOK)
244 return rc;
245 rc = ui_paint_fcircle_line(gc, center, +p->y, -p->x, p->x + 1, part);
246 if (rc != EOK)
247 return rc;
248 rc = ui_paint_fcircle_line(gc, center, -p->y, -p->x, p->x + 1, part);
249 if (rc != EOK)
250 return rc;
251
252 return EOK;
253}
254
255/** Paint a filled circle.
256 *
257 * @param gc Graphic context
258 * @param center Coordinates of the center
259 * @param r Radius in pixels
260 * @param part Which part(s) of cicle to paint
261 * @return EOK on success or an error code
262 */
263errno_t ui_paint_filled_circle(gfx_context_t *gc, gfx_coord2_t *center,
264 gfx_coord_t r, ui_fcircle_part_t part)
265{
266 gfx_coord2_t p;
267 gfx_coord_t f;
268 errno_t rc;
269
270 /* Run through one octant using circle midpoint algorithm */
271
272 p.x = r;
273 p.y = 0;
274 f = 1 - r;
275
276 rc = ui_paint_fcircle_point(gc, center, &p, part);
277 if (rc != EOK)
278 return rc;
279
280 while (p.x > p.y) {
281 if (f < 0) {
282 f = f + 2 * p.y + 3;
283 } else {
284 f = f + 2 * (p.y - p.x) + 5;
285 --p.x;
286 }
287 ++p.y;
288
289 rc = ui_paint_fcircle_point(gc, center, &p, part);
290 if (rc != EOK)
291 return rc;
292 }
293
294 return EOK;
295}
296
[de9992c]297/** @}
298 */
Note: See TracBrowser for help on using the repository browser.