diff --git a/freetype/src/Face.zig b/freetype/src/Face.zig index 1e9f87d5..4f6a521f 100644 --- a/freetype/src/Face.zig +++ b/freetype/src/Face.zig @@ -3,7 +3,7 @@ const utils = @import("utils"); const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; -const GlyphSlot = @import("GlyphSlot.zig"); +const GlyphSlot = @import("freetype.zig").GlyphSlot; const LoadFlags = @import("freetype.zig").LoadFlags; const FaceFlags = @import("freetype.zig").FaceFlags; const StyleFlags = @import("freetype.zig").StyleFlags; @@ -27,8 +27,6 @@ const Paint = @import("color.zig").Paint; const PaletteData = @import("color.zig").PaletteData; const GlyphLayersIterator = @import("color.zig").GlyphLayersIterator; -const Face = @This(); - pub const CharmapIterator = struct { face: Face, index: u32, @@ -53,6 +51,8 @@ pub const CharmapIterator = struct { } }; +const Face = @This(); + handle: c.FT_Face, pub fn deinit(self: Face) void { @@ -148,7 +148,7 @@ pub fn getPostscriptName(self: Face) ?[:0]const u8 { null; } -pub fn getCharmapIterator(self: Face) CharmapIterator { +pub fn iterateCharmap(self: Face) CharmapIterator { return CharmapIterator.init(self); } diff --git a/freetype/src/GlyphSlot.zig b/freetype/src/GlyphSlot.zig index 67f5f18e..30ac1abd 100644 --- a/freetype/src/GlyphSlot.zig +++ b/freetype/src/GlyphSlot.zig @@ -2,11 +2,11 @@ const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const Glyph = @import("glyph.zig").Glyph; -const Library = @import("Library.zig"); -const Face = @import("Face.zig"); +const Library = @import("freetype.zig").Library; +const Face = @import("freetype.zig").Face; const RenderMode = @import("freetype.zig").RenderMode; const Matrix = @import("types.zig").Matrix; -const Outline = @import("Outline.zig"); +const Outline = @import("image.zig").Outline; const GlyphFormat = @import("image.zig").GlyphFormat; const Vector = @import("image.zig").Vector; const GlyphMetrics = @import("image.zig").GlyphMetrics; diff --git a/freetype/src/Library.zig b/freetype/src/Library.zig index d0ddd499..cac4c39b 100644 --- a/freetype/src/Library.zig +++ b/freetype/src/Library.zig @@ -3,7 +3,7 @@ const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const Stroker = @import("stroke.zig").Stroker; -const Face = @import("Face.zig"); +const Face = @import("freetype.zig").Face; const OpenArgs = @import("freetype.zig").OpenArgs; const LcdFilter = @import("lcdfilter.zig").LcdFilter; diff --git a/freetype/src/Outline.zig b/freetype/src/Outline.zig deleted file mode 100644 index 22b1d1f1..00000000 --- a/freetype/src/Outline.zig +++ /dev/null @@ -1,144 +0,0 @@ -const c = @import("c"); -const builtin = @import("builtin"); -const intToError = @import("error.zig").intToError; -const errorToInt = @import("error.zig").errorToInt; -const Error = @import("error.zig").Error; -const Matrix = @import("types.zig").Matrix; -const BBox = @import("types.zig").BBox; -const Vector = @import("image.zig").Vector; -const Stroker = @import("stroke.zig").Stroker; - -const Outline = @This(); - -handle: *c.FT_Outline, - -pub fn numPoints(self: Outline) u15 { - return @intCast(u15, self.handle.*.n_points); -} - -pub fn numContours(self: Outline) u15 { - return @intCast(u15, self.handle.*.n_contours); -} - -pub fn points(self: Outline) []const Vector { - return self.handle.*.points[0..self.numPoints()]; -} - -pub fn tags(self: Outline) []const u8 { - return self.handle.tags[0..@intCast(u15, self.handle.n_points)]; -} - -pub fn contours(self: Outline) []const i16 { - return self.handle.*.contours[0..self.numContours()]; -} - -pub fn check(self: Outline) Error!void { - try intToError(c.FT_Outline_Check(self.handle)); -} - -pub fn transform(self: Outline, matrix: ?Matrix) void { - c.FT_Outline_Transform(self.handle, if (matrix) |m| &m else null); -} - -pub fn getInsideBorder(self: Outline) Stroker.Border { - return @intToEnum(Stroker.Border, c.FT_Outline_GetInsideBorder(self.handle)); -} - -pub fn getOutsideBorder(self: Outline) Stroker.Border { - return @intToEnum(Stroker.Border, c.FT_Outline_GetOutsideBorder(self.handle)); -} - -pub fn bbox(self: Outline) Error!BBox { - var b: BBox = undefined; - try intToError(c.FT_Outline_Get_BBox(self.handle, &b)); - return b; -} - -pub fn Funcs(comptime Context: type) type { - return struct { - move_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, to: Vector) Error!void else *const fn (ctx: Context, to: Vector) Error!void, - line_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, to: Vector) Error!void else *const fn (ctx: Context, to: Vector) Error!void, - conic_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, control: Vector, to: Vector) Error!void else *const fn (ctx: Context, control: Vector, to: Vector) Error!void, - cubic_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, control_0: Vector, control_1: Vector, to: Vector) Error!void else *const fn (ctx: Context, control_0: Vector, control_1: Vector, to: Vector) Error!void, - shift: i32, - delta: i32, - }; -} - -pub fn FuncsWrapper(comptime Context: type) type { - return struct { - const Self = @This(); - ctx: Context, - callbacks: Funcs(Context), - - fn getSelf(ptr: ?*anyopaque) *Self { - return @ptrCast(*Self, @alignCast(@alignOf(Self), ptr)); - } - - 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, 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, 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, - control.*, - 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, - control_0.*, - control_1.*, - to.*, - )) |_| - 0 - else |err| - errorToInt(err); - } - }; -} - -pub fn decompose(self: Outline, ctx: anytype, callbacks: Funcs(@TypeOf(ctx))) Error!void { - var wrapper = FuncsWrapper(@TypeOf(ctx)){ .ctx = ctx, .callbacks = callbacks }; - try intToError(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, - )); -} diff --git a/freetype/src/color.zig b/freetype/src/color.zig index 1f9a6f42..c75dc137 100644 --- a/freetype/src/color.zig +++ b/freetype/src/color.zig @@ -1,6 +1,6 @@ const utils = @import("utils"); const c = @import("c"); -const Face = @import("Face.zig"); +const Face = @import("freetype.zig").Face; pub const Color = c.FT_Color; pub const LayerIterator = c.FT_LayerIterator; diff --git a/freetype/src/freetype.zig b/freetype/src/freetype.zig index 7a5b28d2..f56f888f 100644 --- a/freetype/src/freetype.zig +++ b/freetype/src/freetype.zig @@ -4,8 +4,10 @@ const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const Generic = @import("types.zig").Generic; -const Face = @import("Face.zig"); +pub const Library = @import("Library.zig"); +pub const Face = @import("Face.zig"); +pub const GlyphSlot = @import("GlyphSlot.zig"); pub const SizeRequest = c.FT_Size_RequestRec; pub const BitmapSize = c.FT_Bitmap_Size; pub const CharMap = c.FT_CharMapRec; diff --git a/freetype/src/glyph.zig b/freetype/src/glyph.zig index 87b4353e..14b5dbb5 100644 --- a/freetype/src/glyph.zig +++ b/freetype/src/glyph.zig @@ -3,12 +3,12 @@ const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const Stroker = @import("stroke.zig").Stroker; -const Library = @import("Library.zig"); +const Library = @import("freetype.zig").Library; const RenderMode = @import("freetype.zig").RenderMode; const SizeMetrics = @import("freetype.zig").SizeMetrics; const Matrix = @import("types.zig").Matrix; const BBox = @import("types.zig").BBox; -const Outline = @import("Outline.zig"); +const Outline = @import("image.zig").Outline; const GlyphFormat = @import("image.zig").GlyphFormat; const Vector = @import("image.zig").Vector; const Bitmap = @import("image.zig").Bitmap; diff --git a/freetype/src/image.zig b/freetype/src/image.zig index ffe810b0..42b67f6f 100644 --- a/freetype/src/image.zig +++ b/freetype/src/image.zig @@ -1,9 +1,14 @@ +const builtin = @import("builtin"); const std = @import("std"); const c = @import("c"); const intToError = @import("error.zig").intToError; +const errorToInt = @import("error.zig").errorToInt; const Error = @import("error.zig").Error; -const Library = @import("Library.zig"); +const Library = @import("freetype.zig").Library; const Color = @import("color.zig").Color; +const Stroker = @import("stroke.zig").Stroker; +const Matrix = @import("types.zig").Matrix; +const BBox = @import("types.zig").BBox; pub const Vector = c.FT_Vector; pub const GlyphMetrics = c.FT_Glyph_Metrics; @@ -89,3 +94,138 @@ pub const Bitmap = struct { self.handle.buffer[0..buffer_size]; } }; + +pub const Outline = struct { + handle: *c.FT_Outline, + + pub fn numPoints(self: Outline) u15 { + return @intCast(u15, self.handle.*.n_points); + } + + pub fn numContours(self: Outline) u15 { + return @intCast(u15, self.handle.*.n_contours); + } + + pub fn points(self: Outline) []const Vector { + return self.handle.*.points[0..self.numPoints()]; + } + + pub fn tags(self: Outline) []const u8 { + return self.handle.tags[0..@intCast(u15, self.handle.n_points)]; + } + + pub fn contours(self: Outline) []const i16 { + return self.handle.*.contours[0..self.numContours()]; + } + + pub fn check(self: Outline) Error!void { + try intToError(c.FT_Outline_Check(self.handle)); + } + + pub fn transform(self: Outline, matrix: ?Matrix) void { + c.FT_Outline_Transform(self.handle, if (matrix) |m| &m else null); + } + + pub fn getInsideBorder(self: Outline) Stroker.Border { + return @intToEnum(Stroker.Border, c.FT_Outline_GetInsideBorder(self.handle)); + } + + pub fn getOutsideBorder(self: Outline) Stroker.Border { + return @intToEnum(Stroker.Border, c.FT_Outline_GetOutsideBorder(self.handle)); + } + + pub fn bbox(self: Outline) Error!BBox { + var b: BBox = undefined; + try intToError(c.FT_Outline_Get_BBox(self.handle, &b)); + return b; + } + + pub fn Funcs(comptime Context: type) type { + return struct { + move_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, to: Vector) Error!void else *const fn (ctx: Context, to: Vector) Error!void, + line_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, to: Vector) Error!void else *const fn (ctx: Context, to: Vector) Error!void, + conic_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, control: Vector, to: Vector) Error!void else *const fn (ctx: Context, control: Vector, to: Vector) Error!void, + cubic_to: if (builtin.zig_backend == .stage1 or builtin.zig_backend == .other) fn (ctx: Context, control_0: Vector, control_1: Vector, to: Vector) Error!void else *const fn (ctx: Context, control_0: Vector, control_1: Vector, to: Vector) Error!void, + shift: i32, + delta: i32, + }; + } + + pub fn FuncsWrapper(comptime Context: type) type { + return struct { + const Self = @This(); + ctx: Context, + callbacks: Funcs(Context), + + fn getSelf(ptr: ?*anyopaque) *Self { + return @ptrCast(*Self, @alignCast(@alignOf(Self), ptr)); + } + + 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, 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, 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, + control.*, + 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, + control_0.*, + control_1.*, + to.*, + )) |_| + 0 + else |err| + errorToInt(err); + } + }; + } + + pub fn decompose(self: Outline, ctx: anytype, callbacks: Funcs(@TypeOf(ctx))) Error!void { + var wrapper = FuncsWrapper(@TypeOf(ctx)){ .ctx = ctx, .callbacks = callbacks }; + try intToError(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, + )); + } +}; diff --git a/freetype/src/main.zig b/freetype/src/main.zig index 51bc91cf..8a118433 100644 --- a/freetype/src/main.zig +++ b/freetype/src/main.zig @@ -6,16 +6,13 @@ pub usingnamespace @import("lcdfilter.zig"); pub usingnamespace @import("stroke.zig"); pub usingnamespace @import("types.zig"); pub usingnamespace @import("computations.zig"); -pub const Library = @import("Library.zig"); -pub const Face = @import("Face.zig"); -pub const GlyphSlot = @import("GlyphSlot.zig"); -pub const Error = @import("error.zig").Error; -pub const Outline = @import("Outline.zig"); +pub usingnamespace @import("error.zig"); pub const harfbuzz = @import("harfbuzz/main.zig"); pub const c = @import("c"); const std = @import("std"); const testing = std.testing; +const ft = @import("freetype.zig"); // Remove once the stage2 compiler fixes pkg std not found comptime { @@ -32,10 +29,6 @@ test { std.testing.refAllDeclsRecursive(@import("stroke.zig")); std.testing.refAllDeclsRecursive(@import("types.zig")); std.testing.refAllDeclsRecursive(@import("computations.zig")); - std.testing.refAllDeclsRecursive(Library); - std.testing.refAllDeclsRecursive(Face); - std.testing.refAllDeclsRecursive(GlyphSlot); - std.testing.refAllDeclsRecursive(Outline); std.testing.refAllDeclsRecursive(harfbuzz); } @@ -47,22 +40,22 @@ fn thisDir() []const u8 { } test "create face from file" { - const lib = try Library.init(); + const lib = try ft.Library.init(); _ = try lib.createFace(firasans_font_path, 0); } test "create face from memory" { - const lib = try Library.init(); + const lib = try ft.Library.init(); _ = try lib.createFaceMemory(firasans_font_data, 0); } test "create stroker" { - const lib = try Library.init(); + const lib = try ft.Library.init(); _ = try lib.createStroker(); } test "load glyph" { - const lib = try Library.init(); + const lib = try ft.Library.init(); const face = try lib.createFace(firasans_font_path, 0); try face.setPixelSizes(100, 100); @@ -75,23 +68,23 @@ test "load glyph" { } test "attach file" { - const lib = try Library.init(); - const face = try lib.createFace(thisDir() ++ "/../upstream/assets/DejaVuSans.pfb", 0); - try face.attachFile(thisDir() ++ "/../upstream/assets/DejaVuSans.pfm"); + const lib = try ft.Library.init(); + const face = try lib.createFace(comptime thisDir() ++ "/../upstream/assets/DejaVuSans.pfb", 0); + try face.attachFile(comptime thisDir() ++ "/../upstream/assets/DejaVuSans.pfm"); } test "attach from memory" { - const lib = try Library.init(); - const face = try lib.createFace(thisDir() ++ "/../upstream/assets/DejaVuSans.pfb", 0); - const file = @embedFile(thisDir() ++ "/../upstream/assets/DejaVuSans.pfm"); + const lib = try ft.Library.init(); + const face = try lib.createFace(comptime thisDir() ++ "/../upstream/assets/DejaVuSans.pfb", 0); + const file = @embedFile(comptime thisDir() ++ "/../upstream/assets/DejaVuSans.pfm"); try face.attachMemory(file); } test "charmap iterator" { - const lib = try Library.init(); + const lib = try ft.Library.init(); const face = try lib.createFace(firasans_font_path, 0); - var iterator = face.getCharmapIterator(); - var old_char: usize = 0; + var iterator = face.iterateCharmap(); + var old_char: u32 = 0; while (iterator.next()) |char| { try testing.expect(old_char != char); old_char = char; @@ -99,13 +92,13 @@ test "charmap iterator" { } test "get name index" { - const lib = try Library.init(); + const lib = try ft.Library.init(); const face = try lib.createFace(firasans_font_path, 0); try testing.expectEqual(@as(u32, 1120), face.getNameIndex("summation").?); } test "get index name" { - const lib = try Library.init(); + const lib = try ft.Library.init(); const face = try lib.createFace(firasans_font_path, 0); var buf: [32]u8 = undefined; try face.getGlyphName(1120, &buf); diff --git a/freetype/src/stroke.zig b/freetype/src/stroke.zig index 93c91c2d..883eb27d 100644 --- a/freetype/src/stroke.zig +++ b/freetype/src/stroke.zig @@ -1,7 +1,7 @@ const c = @import("c"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; -const Outline = @import("Outline.zig"); +const Outline = @import("image.zig").Outline; const Vector = @import("image.zig").Vector; pub const LineCap = enum(u2) {