source: mainline/uspace/lib/guigfx/src/canvas.c@ 7b882c1f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7b882c1f was 7b882c1f, checked in by Jiri Svoboda <jiri@…>, 6 years ago

Need some vector operations

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 * Copyright (c) 2019 Jiri Svoboda
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 libguigfx
30 * @{
31 */
32/**
33 * @file GFX canvas backend
34 *
35 * This implements a graphics context over a libgui canvas.
36 * This is just for experimentation purposes and its kind of backwards.
37 */
38
39#include <draw/drawctx.h>
40#include <draw/source.h>
41#include <gfx/color.h>
42#include <gfx/context.h>
43#include <gfx/render.h>
44#include <guigfx/canvas.h>
45#include <io/pixel.h>
46#include <stdlib.h>
47#include <transform.h>
48#include "../private/canvas.h"
49//#include "../../private/color.h"
50
51static errno_t canvas_gc_set_color(void *, gfx_color_t *);
52static errno_t canvas_gc_fill_rect(void *, gfx_rect_t *);
53static errno_t canvas_gc_bitmap_create(void *, gfx_bitmap_params_t *,
54 gfx_bitmap_alloc_t *, void **);
55static errno_t canvas_gc_bitmap_destroy(void *);
56static errno_t canvas_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
57static errno_t canvas_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
58
59gfx_context_ops_t canvas_gc_ops = {
60 .set_color = canvas_gc_set_color,
61 .fill_rect = canvas_gc_fill_rect,
62 .bitmap_create = canvas_gc_bitmap_create,
63 .bitmap_destroy = canvas_gc_bitmap_destroy,
64 .bitmap_render = canvas_gc_bitmap_render,
65 .bitmap_get_alloc = canvas_gc_bitmap_get_alloc
66};
67
68/** Set color on canvas GC.
69 *
70 * Set drawing color on canvas GC.
71 *
72 * @param arg Canvas GC
73 * @param color Color
74 *
75 * @return EOK on success or an error code
76 */
77static errno_t canvas_gc_set_color(void *arg, gfx_color_t *color)
78{
79 canvas_gc_t *cgc = (canvas_gc_t *) arg;
80 uint16_t r, g, b;
81
82 gfx_color_get_rgb_i16(color, &r, &g, &b);
83 cgc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
84 return EOK;
85}
86
87/** Fill rectangle on canvas GC.
88 *
89 * @param arg Canvas GC
90 * @param rect Rectangle
91 *
92 * @return EOK on success or an error code
93 */
94static errno_t canvas_gc_fill_rect(void *arg, gfx_rect_t *rect)
95{
96 canvas_gc_t *cgc = (canvas_gc_t *) arg;
97 gfx_coord_t x, y;
98
99 // XXX We should handle p0.x > p1.x and p0.y > p1.y
100
101 for (y = rect->p0.y; y < rect->p1.y; y++) {
102 for (x = rect->p0.x; x < rect->p1.x; x++) {
103 surface_put_pixel(cgc->surface, x, y, cgc->color);
104 }
105 }
106
107 update_canvas(cgc->canvas, cgc->surface);
108
109 return EOK;
110}
111
112/** Create canvas GC.
113 *
114 * Create graphics context for rendering into a canvas.
115 *
116 * @param con Canvas object
117 * @param fout File to which characters are written (canvas)
118 * @param rgc Place to store pointer to new GC.
119 *
120 * @return EOK on success or an error code
121 */
122errno_t canvas_gc_create(canvas_t *canvas, surface_t *surface,
123 canvas_gc_t **rgc)
124{
125 canvas_gc_t *cgc = NULL;
126 gfx_context_t *gc = NULL;
127 errno_t rc;
128
129 cgc = calloc(1, sizeof(canvas_gc_t));
130 if (cgc == NULL) {
131 rc = ENOMEM;
132 goto error;
133 }
134
135 rc = gfx_context_new(&canvas_gc_ops, cgc, &gc);
136 if (rc != EOK)
137 goto error;
138
139 cgc->gc = gc;
140 cgc->canvas = canvas;
141 cgc->surface = surface;
142 *rgc = cgc;
143 return EOK;
144error:
145 if (cgc != NULL)
146 free(cgc);
147 gfx_context_delete(gc);
148 return rc;
149}
150
151/** Delete canvas GC.
152 *
153 * @param cgc Canvas GC
154 */
155errno_t canvas_gc_delete(canvas_gc_t *cgc)
156{
157 errno_t rc;
158
159 rc = gfx_context_delete(cgc->gc);
160 if (rc != EOK)
161 return rc;
162
163 free(cgc);
164 return EOK;
165}
166
167/** Get generic graphic context from canvas GC.
168 *
169 * @param cgc Canvas GC
170 * @return Graphic context
171 */
172gfx_context_t *canvas_gc_get_ctx(canvas_gc_t *cgc)
173{
174 return cgc->gc;
175}
176
177/** Create bitmap in canvas GC.
178 *
179 * @param arg Canvas GC
180 * @param params Bitmap params
181 * @param alloc Bitmap allocation info or @c NULL
182 * @param rbm Place to store pointer to new bitmap
183 * @return EOK on success or an error code
184 */
185errno_t canvas_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
186 gfx_bitmap_alloc_t *alloc, void **rbm)
187{
188 canvas_gc_t *cgc = (canvas_gc_t *) arg;
189 canvas_gc_bitmap_t *cbm = NULL;
190 gfx_coord2_t dim;
191 errno_t rc;
192
193 cbm = calloc(1, sizeof(canvas_gc_bitmap_t));
194 if (cbm == NULL)
195 return ENOMEM;
196
197 gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
198 cbm->rect = params->rect;
199
200 if (alloc == NULL) {
201 cbm->surface = surface_create(dim.x, dim.y, NULL, 0);
202 if (cbm->surface == NULL) {
203 rc = ENOMEM;
204 goto error;
205 }
206
207 cbm->alloc.pitch = dim.x * sizeof(uint32_t);
208 cbm->alloc.off0 = 0;
209 cbm->alloc.pixels = surface_direct_access(cbm->surface);
210 cbm->myalloc = true;
211 } else {
212 cbm->surface = surface_create(dim.x, dim.y, alloc->pixels, 0);
213 if (cbm->surface == NULL) {
214 rc = ENOMEM;
215 goto error;
216 }
217
218 cbm->alloc = *alloc;
219 }
220
221 cbm->cgc = cgc;
222 *rbm = (void *)cbm;
223 return EOK;
224error:
225 if (cbm != NULL)
226 free(cbm);
227 return rc;
228}
229
230/** Destroy bitmap in canvas GC.
231 *
232 * @param bm Bitmap
233 * @return EOK on success or an error code
234 */
235static errno_t canvas_gc_bitmap_destroy(void *bm)
236{
237 canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
238 if (cbm->myalloc)
239 surface_destroy(cbm->surface);
240 // XXX if !cbm->myalloc, surface is leaked - no way to destroy it
241 // without destroying the pixel buffer
242 free(cbm);
243 return EOK;
244}
245
246/** Render bitmap in canvas GC.
247 *
248 * @param bm Bitmap
249 * @param srect0 Source rectangle or @c NULL
250 * @param offs0 Offset or @c NULL
251 * @return EOK on success or an error code
252 */
253static errno_t canvas_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
254 gfx_coord2_t *offs0)
255{
256 canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
257 gfx_rect_t srect;
258 gfx_rect_t drect;
259 gfx_coord2_t offs;
260 gfx_coord2_t dim;
261
262 if (srect0 != NULL)
263 srect = *srect0;
264 else
265 srect = cbm->rect;
266
267 if (offs0 != NULL) {
268 offs = *offs0;
269 } else {
270 offs.x = 0;
271 offs.y = 0;
272 }
273
274 /* Destination rectangle */
275 gfx_rect_translate(&offs, &srect, &drect);
276
277 gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
278
279 transform_t transform;
280 transform_identity(&transform);
281 transform_translate(&transform, offs.x - cbm->rect.p0.x,
282 offs.y - cbm->rect.p0.y);
283
284 source_t source;
285 source_init(&source);
286 source_set_transform(&source, transform);
287 source_set_texture(&source, cbm->surface,
288 PIXELMAP_EXTEND_TRANSPARENT_BLACK);
289
290 drawctx_t drawctx;
291 drawctx_init(&drawctx, cbm->cgc->surface);
292
293 drawctx_set_source(&drawctx, &source);
294 drawctx_transfer(&drawctx, drect.p0.x, drect.p0.y, dim.x, dim.y);
295
296 update_canvas(cbm->cgc->canvas, cbm->cgc->surface);
297 return EOK;
298}
299
300/** Get allocation info for bitmap in canvas GC.
301 *
302 * @param bm Bitmap
303 * @param alloc Place to store allocation info
304 * @return EOK on success or an error code
305 */
306static errno_t canvas_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
307{
308 canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
309 *alloc = cbm->alloc;
310 return EOK;
311}
312
313/** @}
314 */
Note: See TracBrowser for help on using the repository browser.