From b3996a9109a32eb83f877ba7cd1b1271c5cbe975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaroslav=20de=20la=20Pe=C3=B1a=20Smirnov?= Date: Sat, 14 Sep 2024 23:58:53 +0300 Subject: improve pango and cairo bindings --- src/pangocairo.zig | 203 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 114 insertions(+), 89 deletions(-) (limited to 'src/pangocairo.zig') diff --git a/src/pangocairo.zig b/src/pangocairo.zig index 3995ba7..24bbfd6 100644 --- a/src/pangocairo.zig +++ b/src/pangocairo.zig @@ -3,140 +3,165 @@ const c = @cImport({ }); pub const pango = struct { - pub const Layout = struct { - layout: *c.PangoLayout, - - pub fn createForCairo(s: *cairo.Surface) !Layout { - const layout = c.pango_cairo_create_layout( - s.cairo, - ) orelse return error.PangoCairoError; - return .{ .layout = layout }; - } + pub const scale = c.PANGO_SCALE; - pub fn setFont(l: Layout, f: FontDescription) void { - c.pango_layout_set_font_description(l.layout, f.font); + pub const Layout = opaque { + extern fn pango_cairo_create_layout(s: *cairo.Context) ?*Layout; + pub fn createForCairo(s: *cairo.Context) !*Layout { + return pango_cairo_create_layout(s) orelse return error.OutOfMemory; } - pub fn setFontFromString(l: Layout, font: [*:0]const u8) !void { - const pfont = c.pango_font_description_from_string( - font, - ) orelse return error.BadFont; - defer c.pango_font_description_free(pfont); - c.pango_layout_set_font_description(l.layout, pfont); - } + extern fn pango_layout_set_font_description(l: *Layout, f: *FontDescription) void; + pub const setFontDescription = pango_layout_set_font_description; - pub fn setText(l: Layout, text: [*:0]const u8, len: i32) void { - c.pango_layout_set_text(l.layout, text, len); - } - - pub fn show(l: Layout, s: *cairo.Surface) void { - c.pango_cairo_show_layout(s.cairo, l.layout); - } + extern fn pango_layout_set_text(l: *Layout, text: [*:0]const u8, len: i32) void; + pub const setText = pango_layout_set_text; - pub fn unref(l: Layout) void { - c.g_object_unref(l.layout); + pub fn unref(l: *Layout) void { + c.g_object_unref(l); } }; - pub const FontDescription = struct { - font: *c.PangoFontDescription, - - pub fn create() !FontDescription { - const font = c.pango_font_description_new() orelse return error.PangoError; - return .{ .font = font }; + pub const FontDescription = opaque { + extern fn pango_font_description_new() ?*FontDescription; + pub fn create() !*FontDescription { + return pango_font_description_new() orelse return error.OutOfMemory; } - pub fn fromString(str: [*:0]const u8) !FontDescription { - const font = c.pango_font_description_from_string(str) orelse return error.PangoError; - return .{ .font= font }; + extern fn pango_font_description_from_string(str: [*:0]const u8) ?*FontDescription; + pub fn fromString(str: [*:0]const u8) !*FontDescription { + return c.pango_font_description_from_string(str) orelse return error.OutOfMemory; } - pub fn setFamily(f: FontDescription, name: [*:0]const u8) void { - c.pango_font_description_set_family(f.font, name); - } + extern fn pango_font_description_set_family( + f: *FontDescription, + name: [*:0]const u8, + ) void; + pub const setFamily = pango_font_description_set_family; - pub fn setWeight(f: FontDescription, weight: u32) void { - c.pango_font_description_set_weight(f.font, weight); - } + extern fn pango_font_description_set_weight(f: *FontDescription, weight: u32) void; + pub const setWeight = pango_font_description_set_weight; - pub fn setSize(f: FontDescription, size: i32) void { - c.pango_font_description_set_size(f.font, size); - } + extern fn pango_font_description_set_size(f: *FontDescription, size: i32) void; + pub const setSize = pango_font_description_set_size; - pub fn setSizePt(f: FontDescription, pt: i32) void { - c.pango_font_description_set_size(f.font, pt * c.PANGO_SCALE); + pub fn setSizePt(f: *FontDescription, pt: i32) void { + f.setSize(pt * scale); } - pub fn destroy(f: FontDescription) void { - c.pango_font_description_free(f.font); - } + extern fn pango_font_description_free(f: *FontDescription) void; + pub const destroy = pango_font_description_free; }; }; pub const cairo = struct { + pub const Error = error{ + Unknown, + NullPtr, + NoMemory, + ReadError, + InvalidContent, + InvalidFormat, + InvalidVisual, + }; + fn statusToError(status: c_int) Error!void { + switch (status) { + c.CAIRO_STATUS_SUCCESS => return, + c.CAIRO_STATUS_NULL_POINTER => return Error.NullPtr, + c.CAIRO_STATUS_NO_MEMORY => return Error.NoMemory, + c.CAIRO_STATUS_READ_ERROR => return Error.ReadError, + c.CAIRO_STATUS_INVALID_CONTENT => return Error.InvalidContent, + c.CAIRO_STATUS_INVALID_FORMAT => return Error.InvalidFormat, + c.CAIRO_STATUS_INVALID_VISUAL => return Error.InvalidVisual, + else => return Error.Unknown, + } + } + pub const Format = enum(c_int) { invalid = -1, argb32, rgb24, + + extern fn cairo_format_stride_for_width(format: Format, width: i32) i32; + pub const strideForWidth = cairo_format_stride_for_width; }; - pub const Surface = struct { - cairo: *c.cairo_t, - surface: *c.cairo_surface_t, + pub const Context = opaque { + extern fn cairo_status(ctx: ?*Context) c_int; + fn checkStatus(ctx: ?*Context) Error!void { + return statusToError(cairo_status(ctx)); + } + + extern fn cairo_create(surface: *Surface) ?*Context; + pub fn create(surface: *Surface) !*Context { + const ctx = cairo_create(surface); + try checkStatus(ctx); + return ctx orelse unreachable; + } + + extern fn cairo_move_to(ctx: *Context, x: f64, y: f64) void; + pub const moveTo = cairo_move_to; + + extern fn cairo_set_source_rgba(ctx: *Context, green: f64, blue: f64, red: f64, alpha: f64) void; + pub const setSourceRgba = cairo_set_source_rgba; - pub fn formatStrideForWidth(format: Format, width: i32) i32 { - return c.cairo_format_stride_for_width(@intFromEnum(format), width); + extern fn cairo_paint(ctx: *Context) void; + pub const paint = cairo_paint; + + extern fn pango_cairo_show_layout(ctx: *Context, layout: *pango.Layout) void; + pub const showPangoLayout = pango_cairo_show_layout; + + extern fn cairo_destroy(ctx: *Context) void; + pub const destroy = cairo_destroy; + }; + + pub const Surface = opaque { + extern fn cairo_surface_status(surface: ?*Surface) c_int; + fn checkStatus(surface: ?*Surface) Error!void { + return statusToError(cairo_surface_status(surface)); } - pub fn createImage(format: Format, width: i32, height: i32) !Surface { - const surface = c.cairo_image_surface_create( - @intFromEnum(format), + extern fn cairo_image_surface_create( + format: Format, + width: i32, + height: i32, + ) ?*Surface; + pub fn createImage(format: Format, width: i32, height: i32) Error!*Surface { + const surface = cairo_image_surface_create( + format, width, height, - ) orelse return error.CairoError; - const cr = c.cairo_create(surface) orelse return error.CairoError; - return .{ .cairo = cr, .surface = surface }; + ); + try checkStatus(surface); + return surface orelse unreachable; } + extern fn cairo_image_surface_create_for_data( + data: [*c]u8, + format: Format, + width: i32, + height: i32, + stride: i32, + ) ?*Surface; pub fn createImageForData( data: []u8, format: Format, width: i32, height: i32, stride: i32, - ) !Surface { - const surface = c.cairo_image_surface_create_for_data( + ) Error!*Surface { + const s = cairo_image_surface_create_for_data( data.ptr, - @intFromEnum(format), + format, width, height, stride, - ) orelse return error.CairoError; - const cr = c.cairo_create(surface) orelse return error.CairoError; - return .{ .cairo = cr, .surface = surface }; + ); + try checkStatus(s); + return s orelse unreachable; } - pub fn moveTo(s: Surface, x: f64, y: f64) void { - c.cairo_move_to(s.cairo, x, y); - } - - pub fn setSourceRgba( - s: Surface, - red: f64, - green: f64, - blue: f64, - alpha: f64, - ) void { - c.cairo_set_source_rgba(s.cairo, red, green, blue, alpha); - } - - pub fn paint(s: Surface) void { - c.cairo_paint(s.cairo); - } - - pub fn destroy(s: Surface) void { - c.cairo_destroy(s.cairo); - c.cairo_surface_destroy(s.surface); - } + extern fn cairo_surface_destroy(s: *Surface) void; + pub const destroy = cairo_surface_destroy; }; }; -- cgit v1.2.3