freetype: add a wrapper for outline functions
This commit is contained in:
parent
18369e8c9b
commit
b92770404f
2 changed files with 102 additions and 20 deletions
|
|
@ -53,7 +53,7 @@ const OutlinePrinter = struct {
|
||||||
|
|
||||||
pub fn extractOutline(self: *Self) !void {
|
pub fn extractOutline(self: *Self) !void {
|
||||||
try self.path_stream.writer().writeAll("<path d='");
|
try self.path_stream.writer().writeAll("<path d='");
|
||||||
var callbacks = freetype.C.FT_Outline_Funcs{
|
var callbacks = freetype.Outline.OutlineFuncs(*Self){
|
||||||
.move_to = moveToFunction,
|
.move_to = moveToFunction,
|
||||||
.line_to = lineToFunction,
|
.line_to = lineToFunction,
|
||||||
.conic_to = conicToFunction,
|
.conic_to = conicToFunction,
|
||||||
|
|
@ -61,7 +61,7 @@ const OutlinePrinter = struct {
|
||||||
.shift = 0,
|
.shift = 0,
|
||||||
.delta = 0,
|
.delta = 0,
|
||||||
};
|
};
|
||||||
try self.face.glyph.outline().?.decompose(self, &callbacks);
|
try self.face.glyph.outline().?.decompose(self, callbacks);
|
||||||
try self.path_stream.writer().writeAll("' fill='#000'/>");
|
try self.path_stream.writer().writeAll("' fill='#000'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,28 +83,20 @@ const OutlinePrinter = struct {
|
||||||
, .{ self.xMin, self.yMin, self.width, self.height, self.path_stream.getWritten() });
|
, .{ self.xMin, self.yMin, self.width, self.height, self.path_stream.getWritten() });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moveToFunction(to: [*c]const freetype.Vector, self_ptr: ?*anyopaque) callconv(.C) c_int {
|
pub fn moveToFunction(self: *Self, to: freetype.Vector) freetype.Error!void {
|
||||||
var self = @ptrCast(*Self, @alignCast(std.meta.alignment(Self), self_ptr));
|
self.path_stream.writer().print("M {d} {d}\t", .{ to.x, to.y }) catch unreachable;
|
||||||
self.path_stream.writer().print("M {d} {d}\t", .{ to.*.x, to.*.y }) catch unreachable;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lineToFunction(to: [*c]const freetype.Vector, self_ptr: ?*anyopaque) callconv(.C) c_int {
|
pub fn lineToFunction(self: *Self, to: freetype.Vector) freetype.Error!void {
|
||||||
var self = @ptrCast(*Self, @alignCast(std.meta.alignment(Self), self_ptr));
|
self.path_stream.writer().print("L {d} {d}\t", .{ to.x, to.y }) catch unreachable;
|
||||||
self.path_stream.writer().print("L {d} {d}\t", .{ to.*.x, to.*.y }) catch unreachable;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn conicToFunction(control: [*c]const freetype.Vector, to: [*c]const freetype.Vector, self_ptr: ?*anyopaque) callconv(.C) c_int {
|
pub fn conicToFunction(self: *Self, control: freetype.Vector, to: freetype.Vector) freetype.Error!void {
|
||||||
var self = @ptrCast(*Self, @alignCast(std.meta.alignment(Self), self_ptr));
|
self.path_stream.writer().print("Q {d} {d}, {d} {d}\t", .{ control.x, control.y, to.x, to.y }) catch unreachable;
|
||||||
self.path_stream.writer().print("Q {d} {d}, {d} {d}\t", .{ control.*.x, control.*.y, to.*.x, to.*.y }) catch unreachable;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cubicToFunction(control_0: [*c]const freetype.Vector, control_1: [*c]const freetype.Vector, to: [*c]const freetype.Vector, self_ptr: ?*anyopaque) callconv(.C) c_int {
|
pub fn cubicToFunction(self: *Self, control_0: freetype.Vector, control_1: freetype.Vector, to: freetype.Vector) freetype.Error!void {
|
||||||
var self = @ptrCast(*Self, @alignCast(std.meta.alignment(Self), self_ptr));
|
self.path_stream.writer().print("C {d} {d}, {d} {d}, {d} {d}\t", .{ control_0.x, control_0.y, control_1.x, control_1.y, to.x, to.y }) catch unreachable;
|
||||||
self.path_stream.writer().print("C {d} {d}, {d} {d}, {d} {d}\t", .{ control_0.*.x, control_0.*.y, control_1.*.x, control_1.*.y, to.*.x, to.*.y }) catch unreachable;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(self: *Self, symbol: u8) !void {
|
pub fn run(self: *Self, symbol: u8) !void {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ const types = @import("types.zig");
|
||||||
const Glyph = @import("Glyph.zig");
|
const Glyph = @import("Glyph.zig");
|
||||||
const Error = @import("error.zig").Error;
|
const Error = @import("error.zig").Error;
|
||||||
const convertError = @import("error.zig").convertError;
|
const convertError = @import("error.zig").convertError;
|
||||||
|
const errorToInt = @import("error.zig").errorToInt;
|
||||||
|
|
||||||
const Outline = @This();
|
const Outline = @This();
|
||||||
|
|
||||||
|
|
@ -48,6 +49,95 @@ pub fn bbox(self: Outline) Error!types.BBox {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decompose(self: Outline, callbacks_ctx: anytype, callbacks: *c.FT_Outline_Funcs) Error!void {
|
pub fn OutlineFuncs(comptime Context: type) type {
|
||||||
try convertError(c.FT_Outline_Decompose(self.handle, callbacks, @ptrCast(?*anyopaque, callbacks_ctx)));
|
return struct {
|
||||||
|
move_to: fn (ctx: Context, to: types.Vector) Error!void,
|
||||||
|
line_to: fn (ctx: Context, to: types.Vector) Error!void,
|
||||||
|
conic_to: fn (ctx: Context, control: types.Vector, to: types.Vector) Error!void,
|
||||||
|
cubic_to: fn (ctx: Context, control_0: types.Vector, control_1: types.Vector, to: types.Vector) Error!void,
|
||||||
|
shift: c_int,
|
||||||
|
delta: isize,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn OutlineFuncsWrapper(comptime Context: type) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
ctx: Context,
|
||||||
|
callbacks: OutlineFuncs(Context),
|
||||||
|
|
||||||
|
fn getSelf(ptr: ?*anyopaque) *Self {
|
||||||
|
return @ptrCast(*Self, @alignCast(@alignOf(Self), ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn castVec(vec: [*c]const c.FT_Vector) types.Vector {
|
||||||
|
return @intToPtr(*types.Vector, @ptrToInt(vec)).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_to(to: [*c]const c.FT_Vector, ctx: ?*anyopaque) callconv(.C) c_int {
|
||||||
|
const self = getSelf(ctx);
|
||||||
|
return if (self.callbacks.move_to(self.ctx, castVec(to))) |_|
|
||||||
|
0
|
||||||
|
else |err|
|
||||||
|
errorToInt(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_to(to: [*c]const c.FT_Vector, ctx: ?*anyopaque) callconv(.C) c_int {
|
||||||
|
const self = getSelf(ctx);
|
||||||
|
return if (self.callbacks.line_to(self.ctx, castVec(to))) |_|
|
||||||
|
0
|
||||||
|
else |err|
|
||||||
|
errorToInt(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn conic_to(
|
||||||
|
control: [*c]const c.FT_Vector,
|
||||||
|
to: [*c]const c.FT_Vector,
|
||||||
|
ctx: ?*anyopaque,
|
||||||
|
) callconv(.C) c_int {
|
||||||
|
const self = getSelf(ctx);
|
||||||
|
return if (self.callbacks.conic_to(
|
||||||
|
self.ctx,
|
||||||
|
castVec(control),
|
||||||
|
castVec(to),
|
||||||
|
)) |_|
|
||||||
|
0
|
||||||
|
else |err|
|
||||||
|
errorToInt(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cubic_to(
|
||||||
|
control_0: [*c]const c.FT_Vector,
|
||||||
|
control_1: [*c]const c.FT_Vector,
|
||||||
|
to: [*c]const c.FT_Vector,
|
||||||
|
ctx: ?*anyopaque,
|
||||||
|
) callconv(.C) c_int {
|
||||||
|
const self = getSelf(ctx);
|
||||||
|
return if (self.callbacks.cubic_to(
|
||||||
|
self.ctx,
|
||||||
|
castVec(control_0),
|
||||||
|
castVec(control_1),
|
||||||
|
castVec(to),
|
||||||
|
)) |_|
|
||||||
|
0
|
||||||
|
else |err|
|
||||||
|
errorToInt(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decompose(self: Outline, ctx: anytype, callbacks: OutlineFuncs(@TypeOf(ctx))) Error!void {
|
||||||
|
var wrapper = OutlineFuncsWrapper(@TypeOf(ctx)){ .ctx = ctx, .callbacks = callbacks };
|
||||||
|
try convertError(c.FT_Outline_Decompose(
|
||||||
|
self.handle,
|
||||||
|
&c.FT_Outline_Funcs{
|
||||||
|
.move_to = @TypeOf(wrapper).move_to,
|
||||||
|
.line_to = @TypeOf(wrapper).line_to,
|
||||||
|
.conic_to = @TypeOf(wrapper).conic_to,
|
||||||
|
.cubic_to = @TypeOf(wrapper).cubic_to,
|
||||||
|
.shift = callbacks.shift,
|
||||||
|
.delta = callbacks.delta,
|
||||||
|
},
|
||||||
|
&wrapper,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue