M canvas.lv2/forge.h => canvas.lv2/forge.h +52 -251
@@ 12,300 12,101 @@
extern "C" {
#endif
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_simple(LV2_Atom_Forge *forge, LV2_URID otype)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_beginPath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_closePath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_vec(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, uint32_t n, const float *vec)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_vector(forge, sizeof(float), forge->Float, n, vec);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_flt(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, float flt)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_float(forge, flt);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_lng(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, int64_t lng)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_long(forge, lng);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_prp(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, LV2_URID prop)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_urid(forge, prop);
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-_lv2_canvas_forge_str(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID otype, const char *text)
-{
- LV2_Atom_Forge_Ref ref;
- LV2_Atom_Forge_Frame frame;
-
- ref = lv2_atom_forge_object(forge, &frame, 0, otype);
- if(ref)
- ref = lv2_atom_forge_key(forge, urid->Canvas_body);
- if(ref)
- ref = lv2_atom_forge_string(forge, text, strlen(text));
- if(ref)
- lv2_atom_forge_pop(forge, &frame);
-
- return ref;
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_beginPath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_BeginPath);
-}
-
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_closePath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_ClosePath);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_arc(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y, float r, float a1, float a2)
-{
- const float vec [5] = {x, y, r, a1, a2};
+ float x, float y, float r, float a1, float a2);
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Arc, 5, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_curveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x1, float y1, float x2, float y2, float x3, float y3)
-{
- const float vec [6] = {x1, y1, x2, y2, x3, y3};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_CurveTo, 6, vec);
-}
+ float x1, float y1, float x2, float y2, float x3, float y3);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_lineTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
+ float x, float y);
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineTo, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_moveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_MoveTo, 2, vec);
-}
+ float x, float y);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_rectangle(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y, float w, float h)
-{
- const float vec [4] = {x, y, w, h};
+ float x, float y, float w, float h);
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Rectangle, 4, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_polyLine(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- uint32_t n, const float *vec)
-{
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_PolyLine, n, vec);
-}
+ uint32_t n, const float *vec);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_style(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- uint32_t style)
-{
- return _lv2_canvas_forge_lng(forge, urid, urid->Canvas_Style, style);
-}
+ uint32_t style);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_lineWidth(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float line_width)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_LineWidth, line_width);
-}
+ float line_width);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_lineDash(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float dash_length, float separator_length)
-{
- const float vec [2] = {dash_length, separator_length};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineDash, 2, vec);
-}
+ float dash_length, float separator_length);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_lineCap(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID line_cap)
-{
- return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineCap, line_cap);
-}
+ LV2_URID line_cap);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_lineJoin(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- LV2_URID line_join)
-{
- return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineJoin, line_join);
-}
+ LV2_URID line_join);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_miterLimit(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float miter_limit)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_MiterLimit, miter_limit);
-}
+ float miter_limit);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_stroke(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Stroke);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_stroke(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_fill(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Fill);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_fill(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_clip(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Clip);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_clip(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_save(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Save);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_save(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_restore(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Restore);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_restore(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_translate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float x, float y)
-{
- const float vec [2] = {x, y};
+ float x, float y);
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Translate, 2, vec);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_scale(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float w, float h)
-{
- const float vec [2] = {w, h};
-
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Scale, 2, vec);
-}
+ float w, float h);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_rotate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float a)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_Rotate, a);
-}
+ float a);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_transform(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float xx, float xy, float x0, float yy, float yx, float y0)
-{
- const float vec [6] = {xx, xy, x0, yy, yx, y0};
+ float xx, float xy, float x0, float yy, float yx, float y0);
- return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Transform, 6, vec);
-}
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_reset(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid);
-static inline LV2_Atom_Forge_Ref
-lv2_canvas_forge_reset(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
-{
- return _lv2_canvas_forge_simple(forge, urid->Canvas_Reset);
-}
-
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_fontSize(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- float size)
-{
- return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_FontSize, size);
-}
+ float size);
-static inline LV2_Atom_Forge_Ref
+LV2_Atom_Forge_Ref
lv2_canvas_forge_fillText(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
- const char *text)
-{
- return _lv2_canvas_forge_str(forge, urid, urid->Canvas_FillText, text);
-}
+ const char *text);
#ifdef __cplusplus
}
M canvas.lv2/idisp.h => canvas.lv2/idisp.h +10 -113
@@ 25,126 25,23 @@ struct _LV2_Canvas_Idisp {
} cairo;
};
-static inline LV2_Inline_Display_Image_Surface *
-_lv2_canvas_idisp_surf_init(LV2_Canvas_Idisp *idisp, int w, int h)
-{
- LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
-
- surf->width = w;
- surf->height = h;
- surf->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, surf->width);
- surf->data = realloc(surf->data, surf->stride * surf->height);
- if(!surf->data)
- {
- return NULL;
- }
-
- idisp->cairo.surface = cairo_image_surface_create_for_data(
- surf->data, CAIRO_FORMAT_ARGB32, surf->width, surf->height, surf->stride);
-
- if(idisp->cairo.surface)
- {
- cairo_surface_set_device_scale(idisp->cairo.surface, surf->width, surf->height);
-
- idisp->cairo.ctx = cairo_create(idisp->cairo.surface);
- if(idisp->cairo.ctx)
- {
- cairo_select_font_face(idisp->cairo.ctx, "cairo:monospace",
- CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
- }
- }
-
- return surf;
-}
-
-static inline void
-_lv2_canvas_idisp_surf_deinit(LV2_Canvas_Idisp *idisp)
-{
- LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
-
- if(idisp->cairo.ctx)
- {
- cairo_destroy(idisp->cairo.ctx);
- idisp->cairo.ctx = NULL;
- }
-
- if(idisp->cairo.surface)
- {
- cairo_surface_finish(idisp->cairo.surface);
- cairo_surface_destroy(idisp->cairo.surface);
- idisp->cairo.surface = NULL;
- }
-
- if(surf->data)
- {
- free(surf->data);
- surf->data = NULL;
- }
-}
-
-static inline LV2_Inline_Display_Image_Surface *
+LV2_Inline_Display_Image_Surface *
lv2_canvas_idisp_surf_configure(LV2_Canvas_Idisp *idisp,
- uint32_t w, uint32_t h, float aspect_ratio)
-{
- LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
- int W;
- int H;
-
- if(aspect_ratio < 1.f)
- {
- W = h * aspect_ratio;
- H = h;
- }
- else if(aspect_ratio > 1.f)
- {
- W = w;
- H = w / aspect_ratio;
- }
- else // aspect_ratio == 1.f
- {
- W = w;
- H = h;
- }
-
- if( (surf->width != W) || (surf->height != H) || !surf->data)
- {
- _lv2_canvas_idisp_surf_deinit(idisp);
- surf = _lv2_canvas_idisp_surf_init(idisp, W, H);
- }
-
- return surf;
-}
+ uint32_t w, uint32_t h, float aspect_ratio);
-static inline void
+int
lv2_canvas_idisp_init(LV2_Canvas_Idisp *idisp, LV2_Inline_Display *queue_draw,
- LV2_URID_Map *map)
-{
- lv2_canvas_init(&idisp->canvas, map);
- idisp->queue_draw = queue_draw;
-}
+ LV2_URID_Map *map);
-static inline void
-lv2_canvas_idisp_deinit(LV2_Canvas_Idisp *idisp)
-{
- _lv2_canvas_idisp_surf_deinit(idisp);
-}
+int
+lv2_canvas_idisp_deinit(LV2_Canvas_Idisp *idisp);
-static inline void
-lv2_canvas_idisp_queue_draw(LV2_Canvas_Idisp *idisp)
-{
- if(idisp->queue_draw)
- {
- idisp->queue_draw->queue_draw(idisp->queue_draw->handle);
- }
-}
+int
+lv2_canvas_idisp_queue_draw(LV2_Canvas_Idisp *idisp);
-static inline bool
+int
lv2_canvas_idisp_render_body(LV2_Canvas_Idisp *idisp, uint32_t type,
- uint32_t size, const LV2_Atom *body)
-{
- return lv2_canvas_render_body(&idisp->canvas, idisp->cairo.ctx,
- type, size, body);
-}
+ uint32_t size, const LV2_Atom *body);
#ifdef __cplusplus
}
M meson.build => meson.build +14 -0
@@ 15,6 15,7 @@ reuse = find_program('reuse', required : false)
add_project_arguments('-D_GNU_SOURCE', language : 'c')
lv2_dep = dependency('lv2', version : '>=1.14.0')
+cairo_dep = dependency('cairo', version : '>=1.16.0')
lib_deps = []
lib_deps += lv2_dep
@@ 24,18 25,31 @@ lib_incs += include_directories('')
lib_srcs = []
lib_srcs += join_paths('src', 'canvas.c')
+lib_srcs += join_paths('src', 'forge.c')
+
+lib_cairo_deps = []
+lib_cairo_deps += cairo_dep
+
+lib_cairo_incs = []
+lib_cairo_src = join_paths('src', 'idisp.c')
canvas_lv2 = declare_dependency(
include_directories : lib_incs,
dependencies : lib_deps,
sources : lib_srcs)
+canvas_idisp_lv2 = declare_dependency(
+ include_directories : lib_incs,
+ dependencies : [lib_deps, lib_cairo_deps],
+ sources : [lib_srcs, lib_cairo_src])
+
test_args = []
test_args += '-fvisibility=hidden'
test_args += '-ffast-math'
test_deps = []
test_deps += canvas_lv2
+test_deps += canvas_idisp_lv2
test_srcs = []
test_srcs += join_paths('test', 'canvas.c')
A src/forge.c => src/forge.c +301 -0
@@ 0,0 1,301 @@
+/*
+ * SPDX-FileCopyrightText: Hanspeter Portner <dev@open-music-kontrollers.ch>
+ * SPDX-License-Identifier: Artistic-2.0
+ */
+
+#include <canvas.lv2/forge.h>
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_simple(LV2_Atom_Forge *forge, LV2_URID otype)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_vec(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID otype, uint32_t n, const float *vec)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ ref = lv2_atom_forge_key(forge, urid->Canvas_body);
+ if(ref)
+ ref = lv2_atom_forge_vector(forge, sizeof(float), forge->Float, n, vec);
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_flt(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID otype, float flt)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ ref = lv2_atom_forge_key(forge, urid->Canvas_body);
+ if(ref)
+ ref = lv2_atom_forge_float(forge, flt);
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_lng(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID otype, int64_t lng)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ ref = lv2_atom_forge_key(forge, urid->Canvas_body);
+ if(ref)
+ ref = lv2_atom_forge_long(forge, lng);
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_prp(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID otype, LV2_URID prop)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ ref = lv2_atom_forge_key(forge, urid->Canvas_body);
+ if(ref)
+ ref = lv2_atom_forge_urid(forge, prop);
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+static inline LV2_Atom_Forge_Ref
+_lv2_canvas_forge_str(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID otype, const char *text)
+{
+ LV2_Atom_Forge_Ref ref;
+ LV2_Atom_Forge_Frame frame;
+
+ ref = lv2_atom_forge_object(forge, &frame, 0, otype);
+ if(ref)
+ ref = lv2_atom_forge_key(forge, urid->Canvas_body);
+ if(ref)
+ ref = lv2_atom_forge_string(forge, text, strlen(text));
+ if(ref)
+ lv2_atom_forge_pop(forge, &frame);
+
+ return ref;
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_beginPath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_BeginPath);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_closePath(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_ClosePath);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_arc(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x, float y, float r, float a1, float a2)
+{
+ const float vec [5] = {x, y, r, a1, a2};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Arc, 5, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_curveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x1, float y1, float x2, float y2, float x3, float y3)
+{
+ const float vec [6] = {x1, y1, x2, y2, x3, y3};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_CurveTo, 6, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_lineTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x, float y)
+{
+ const float vec [2] = {x, y};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineTo, 2, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_moveTo(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x, float y)
+{
+ const float vec [2] = {x, y};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_MoveTo, 2, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_rectangle(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x, float y, float w, float h)
+{
+ const float vec [4] = {x, y, w, h};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Rectangle, 4, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_polyLine(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ uint32_t n, const float *vec)
+{
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_PolyLine, n, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_style(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ uint32_t style)
+{
+ return _lv2_canvas_forge_lng(forge, urid, urid->Canvas_Style, style);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_lineWidth(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float line_width)
+{
+ return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_LineWidth, line_width);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_lineDash(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float dash_length, float separator_length)
+{
+ const float vec [2] = {dash_length, separator_length};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_LineDash, 2, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_lineCap(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID line_cap)
+{
+ return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineCap, line_cap);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_lineJoin(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ LV2_URID line_join)
+{
+ return _lv2_canvas_forge_prp(forge, urid, urid->Canvas_LineJoin, line_join);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_miterLimit(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float miter_limit)
+{
+ return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_MiterLimit, miter_limit);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_stroke(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Stroke);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_fill(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Fill);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_clip(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Clip);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_save(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Save);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_restore(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Restore);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_translate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float x, float y)
+{
+ const float vec [2] = {x, y};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Translate, 2, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_scale(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float w, float h)
+{
+ const float vec [2] = {w, h};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Scale, 2, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_rotate(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float a)
+{
+ return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_Rotate, a);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_transform(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float xx, float xy, float x0, float yy, float yx, float y0)
+{
+ const float vec [6] = {xx, xy, x0, yy, yx, y0};
+
+ return _lv2_canvas_forge_vec(forge, urid, urid->Canvas_Transform, 6, vec);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_reset(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid)
+{
+ return _lv2_canvas_forge_simple(forge, urid->Canvas_Reset);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_fontSize(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ float size)
+{
+ return _lv2_canvas_forge_flt(forge, urid, urid->Canvas_FontSize, size);
+}
+
+LV2_Atom_Forge_Ref
+lv2_canvas_forge_fillText(LV2_Atom_Forge *forge, LV2_Canvas_URID *urid,
+ const char *text)
+{
+ return _lv2_canvas_forge_str(forge, urid, urid->Canvas_FillText, text);
+}
A src/idisp.c => src/idisp.c +142 -0
@@ 0,0 1,142 @@
+/*
+ * SPDX-FileCopyrightText: Hanspeter Portner <dev@open-music-kontrollers.ch>
+ * SPDX-License-Identifier: Artistic-2.0
+ */
+
+#include <stdlib.h>
+
+#include <canvas.lv2/idisp.h>
+
+static inline LV2_Inline_Display_Image_Surface *
+_lv2_canvas_idisp_surf_init(LV2_Canvas_Idisp *idisp, int w, int h)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+
+ surf->width = w;
+ surf->height = h;
+ surf->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, surf->width);
+ surf->data = realloc(surf->data, surf->stride * surf->height);
+ if(!surf->data)
+ {
+ return NULL;
+ }
+
+ idisp->cairo.surface = cairo_image_surface_create_for_data(
+ surf->data, CAIRO_FORMAT_ARGB32, surf->width, surf->height, surf->stride);
+
+ if(idisp->cairo.surface)
+ {
+ cairo_surface_set_device_scale(idisp->cairo.surface, surf->width, surf->height);
+
+ idisp->cairo.ctx = cairo_create(idisp->cairo.surface);
+ if(idisp->cairo.ctx)
+ {
+ cairo_select_font_face(idisp->cairo.ctx, "cairo:monospace",
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ }
+ }
+
+ return surf;
+}
+
+static inline int
+_lv2_canvas_idisp_surf_deinit(LV2_Canvas_Idisp *idisp)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+
+ if(idisp->cairo.ctx)
+ {
+ cairo_destroy(idisp->cairo.ctx);
+ idisp->cairo.ctx = NULL;
+ }
+
+ if(idisp->cairo.surface)
+ {
+ cairo_surface_finish(idisp->cairo.surface);
+ cairo_surface_destroy(idisp->cairo.surface);
+ idisp->cairo.surface = NULL;
+ }
+
+ if(surf->data)
+ {
+ free(surf->data);
+ surf->data = NULL;
+ }
+
+ return 0;
+}
+
+LV2_Inline_Display_Image_Surface *
+lv2_canvas_idisp_surf_configure(LV2_Canvas_Idisp *idisp,
+ uint32_t w, uint32_t h, float aspect_ratio)
+{
+ LV2_Inline_Display_Image_Surface *surf = &idisp->image_surface;
+ int W;
+ int H;
+
+ if(aspect_ratio < 1.f)
+ {
+ W = h * aspect_ratio;
+ H = h;
+ }
+ else if(aspect_ratio > 1.f)
+ {
+ W = w;
+ H = w / aspect_ratio;
+ }
+ else // aspect_ratio == 1.f
+ {
+ W = w;
+ H = h;
+ }
+
+ if( (surf->width != W) || (surf->height != H) || !surf->data)
+ {
+ _lv2_canvas_idisp_surf_deinit(idisp);
+ surf = _lv2_canvas_idisp_surf_init(idisp, W, H);
+ }
+
+ return surf;
+}
+
+int
+lv2_canvas_idisp_init(LV2_Canvas_Idisp *idisp, LV2_Inline_Display *queue_draw,
+ LV2_URID_Map *map)
+{
+ lv2_canvas_init(&idisp->canvas, map);
+ idisp->queue_draw = queue_draw;
+
+ return 0;
+}
+
+int
+lv2_canvas_idisp_deinit(LV2_Canvas_Idisp *idisp)
+{
+ return _lv2_canvas_idisp_surf_deinit(idisp);
+}
+
+int
+lv2_canvas_idisp_queue_draw(LV2_Canvas_Idisp *idisp)
+{
+ if(!idisp->queue_draw || !idisp->queue_draw->queue_draw)
+ {
+ return 0;
+ }
+
+ idisp->queue_draw->queue_draw(idisp->queue_draw->handle);
+
+ return 0;
+}
+
+int
+lv2_canvas_idisp_render_body(LV2_Canvas_Idisp *idisp, uint32_t type,
+ uint32_t size, const LV2_Atom *body)
+{
+ if(!lv2_canvas_render_body(&idisp->canvas, idisp->cairo.ctx,
+ type, size, body))
+ {
+ return 1;
+ }
+
+ return 0;
+}
M test/canvas.c => test/canvas.c +202 -7
@@ 3,28 3,223 @@
* SPDX-License-Identifier: Artistic-2.0
*/
+#include <stdlib.h>
#include <assert.h>
#include <canvas.lv2/canvas.h>
+#include <canvas.lv2/forge.h>
+#include <canvas.lv2/idisp.h>
-void
-test_canvas_urid_init()
+#define MAX_URIDS 128
+
+typedef struct _urid_t urid_t;
+typedef struct _handle_t handle_t;
+
+struct _urid_t {
+ LV2_URID urid;
+ char *uri;
+};
+
+struct _handle_t {
+ LV2_URID_Map map;
+
+ urid_t urids [MAX_URIDS];
+ LV2_URID urid;
+};
+
+static LV2_URID
+_map(LV2_URID_Map_Handle instance, const char *uri)
+{
+ handle_t *handle = instance;
+
+ urid_t *itm;
+ for(itm=handle->urids; itm->urid; itm++)
+ {
+ if(!strcmp(itm->uri, uri))
+ {
+ return itm->urid;
+ }
+ }
+
+ assert(handle->urid + 1 < MAX_URIDS);
+
+ // create new
+ itm->urid = ++handle->urid;
+ itm->uri = strdup(uri);
+
+ return itm->urid;
+}
+
+static void
+_map_free(handle_t *handle)
+{
+ for(unsigned i = 0; i < MAX_URIDS; i++)
+ {
+ urid_t *itm = &handle->urids[i];
+
+ if(itm->uri)
+ {
+ free(itm->uri);
+ }
+
+ memset(itm, 0x0, sizeof(urid_t));
+ }
+}
+
+static void
+test_canvas_urid_init(handle_t *handle)
{
static LV2_Canvas_URID urid;
- static LV2_URID_Map map;
+
+ LV2_URID_Map *map = &handle->map;
assert(lv2_canvas_urid_init(NULL, NULL) == 1);
assert(lv2_canvas_urid_init(&urid, NULL) == 1);
- assert(lv2_canvas_urid_init(NULL, &map) == 1);
- assert(lv2_canvas_urid_init(&urid, &map) == 1);
+ assert(lv2_canvas_urid_init(NULL, map) == 1);
- //FIXME do some real tests
+ assert(lv2_canvas_urid_init(&urid, map) == 0);
+}
+
+void
+test_canvas_forge(handle_t *handle)
+{
+ static LV2_Canvas_URID urid;
+
+ const float vec [3] = {
+ 1.f, 2.f, 3.f
+ };
+
+ LV2_URID_Map *map = &handle->map;
+ uint8_t buf [1024];
+
+ assert(lv2_canvas_urid_init(&urid, map) == 0);
+ LV2_Atom_Forge *forge = &(urid.forge);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_beginPath(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_closePath(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_arc(forge, &urid, 1.f, 2.f, 3.f, 4.f, 5.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_curveTo(forge, &urid, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_lineTo(forge, &urid, 1.f, 2.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_moveTo(forge, &urid, 1.f, 2.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_rectangle(forge, &urid, 1.f, 2.f, 3.f, 4.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_polyLine(forge, &urid, 3, vec) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_style(forge, &urid, 0xff0000ff) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_lineWidth(forge, &urid, 1.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_lineDash(forge, &urid, 1.f, 2.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_lineCap(forge, &urid, urid.Canvas_lineCapButt) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_lineJoin(forge, &urid, urid.Canvas_lineJoinMiter) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_miterLimit(forge, &urid, 1.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_stroke(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_fill(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_clip(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_save(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_restore(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_translate(forge, &urid, 1.f, 2.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_scale(forge, &urid, 1.f, 2.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_rotate(forge, &urid, 1.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_transform(forge, &urid, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_reset(forge, &urid) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_fontSize(forge, &urid, 1.f) != 0);
+
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_canvas_forge_fillText(forge, &urid, "foo") != 0);
+}
+
+static void
+test_canvas_idisp(handle_t *handle)
+{
+ static LV2_Canvas_URID urid;
+ static LV2_Canvas_Idisp idisp;
+ static LV2_Inline_Display queue_draw;
+
+ LV2_URID_Map *map = &handle->map;
+ uint8_t buf [1024];
+
+ assert(lv2_canvas_urid_init(&urid, map) == 0);
+ LV2_Atom_Forge *forge = &(urid.forge);
+
+ assert(lv2_canvas_idisp_init(&idisp, &queue_draw, map) == 0);
+
+ LV2_Inline_Display_Image_Surface *surf =
+ lv2_canvas_idisp_surf_configure(&idisp, 64, 64, 1.f);
+ assert(surf);
+
+ assert(lv2_canvas_idisp_queue_draw(&idisp) == 0);
+
+ LV2_Atom_Forge_Frame frame;
+ lv2_atom_forge_set_buffer(forge, buf, sizeof(buf));
+ assert(lv2_atom_forge_tuple(forge, &frame) != 0);
+ lv2_atom_forge_pop(forge, &frame);
+
+ const LV2_Atom *atom = (const LV2_Atom *)buf;
+ assert(lv2_canvas_idisp_render_body(&idisp, atom->type, atom->size,
+ LV2_ATOM_BODY_CONST(atom)) == 0);
+
+ assert(lv2_canvas_idisp_deinit(&idisp) == 0);
}
int
main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
- test_canvas_urid_init();
+ static handle_t handle;
+
+ handle.map.handle = &handle;
+ handle.map.map = _map;
+
+ test_canvas_urid_init(&handle);
+ test_canvas_forge(&handle);
+ test_canvas_idisp(&handle);
+
+ _map_free(&handle);
return 0;
}