all: move standalone libraries to libs/ subdirectory
The root dir of our repository has grown quite a lot the past few months.
I'd like to make it more clear where the bulk of the engine lives (`src/`) and
also make it more clear which Mach libraries are consumable as standalone projects.
As for the name of this directory, `libs` was my first choice but there's a bit of
a convention of that being external libraries in Zig projects _today_, while these
are libraries maintained as part of Mach in this repository - not external ones.
We will name this directory `libs`, and if we have a need for external libraries
we will use `external` or `deps` for that directory name. I considered other names
such as `components`, `systems`, `modules` (which are bad as they overlap with
major ECS / engine concepts), and it seems likely the official Zig package manager
will break the convention of using a `libs` dir anyway.
Performed via:
```sh
mkdir libs/
git mv freetype libs/
git mv basisu libs/
git mv gamemode libs/
git mv glfw libs/
git mv gpu libs/
git mv gpu-dawn libs/
git mv sysaudio libs/
git mv sysjs libs/
git mv ecs libs/
```
git-subtree-dir: glfw
git-subtree-mainline: 0d5b853443
git-subtree-split: 572d1144f11b353abdb64fff828b25a4f0fbb7ca
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
git mv ecs libs/
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
79ec61396f
commit
0645429df9
240 changed files with 6 additions and 6 deletions
419
libs/freetype/src/Face.zig
Normal file
419
libs/freetype/src/Face.zig
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
const std = @import("std");
|
||||
const utils = @import("utils");
|
||||
const c = @import("c");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const Error = @import("error.zig").Error;
|
||||
const GlyphSlot = @import("freetype.zig").GlyphSlot;
|
||||
const LoadFlags = @import("freetype.zig").LoadFlags;
|
||||
const FaceFlags = @import("freetype.zig").FaceFlags;
|
||||
const StyleFlags = @import("freetype.zig").StyleFlags;
|
||||
const FSType = @import("freetype.zig").FSType;
|
||||
const OpenArgs = @import("freetype.zig").OpenArgs;
|
||||
const KerningMode = @import("freetype.zig").KerningMode;
|
||||
const Encoding = @import("freetype.zig").Encoding;
|
||||
const CharMap = @import("freetype.zig").CharMap;
|
||||
const Size = @import("freetype.zig").Size;
|
||||
const SizeRequest = @import("freetype.zig").SizeRequest;
|
||||
const BitmapSize = @import("freetype.zig").BitmapSize;
|
||||
const Matrix = @import("types.zig").Matrix;
|
||||
const BBox = @import("types.zig").BBox;
|
||||
const Vector = @import("image.zig").Vector;
|
||||
const RootTransform = @import("color.zig").RootTransform;
|
||||
const PaintFormat = @import("color.zig").PaintFormat;
|
||||
const Color = @import("color.zig").Color;
|
||||
const ClipBox = @import("color.zig").ClipBox;
|
||||
const OpaquePaint = @import("color.zig").OpaquePaint;
|
||||
const Paint = @import("color.zig").Paint;
|
||||
const PaletteData = @import("color.zig").PaletteData;
|
||||
const GlyphLayersIterator = @import("color.zig").GlyphLayersIterator;
|
||||
|
||||
pub const CharmapIterator = struct {
|
||||
face: Face,
|
||||
index: u32,
|
||||
charcode: u32,
|
||||
|
||||
pub fn init(face: Face) CharmapIterator {
|
||||
var i: u32 = 0;
|
||||
const cc = c.FT_Get_First_Char(face.handle, &i);
|
||||
return .{
|
||||
.face = face,
|
||||
.index = i,
|
||||
.charcode = @intCast(u32, cc),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn next(self: *CharmapIterator) ?u32 {
|
||||
self.charcode = @intCast(u32, c.FT_Get_Next_Char(self.face.handle, self.charcode, &self.index));
|
||||
return if (self.index != 0)
|
||||
self.charcode
|
||||
else
|
||||
null;
|
||||
}
|
||||
};
|
||||
|
||||
const Face = @This();
|
||||
|
||||
handle: c.FT_Face,
|
||||
|
||||
pub fn deinit(self: Face) void {
|
||||
_ = c.FT_Done_Face(self.handle);
|
||||
}
|
||||
|
||||
pub fn attachFile(self: Face, path: []const u8) Error!void {
|
||||
return self.attachStream(.{
|
||||
.flags = .{ .path = true },
|
||||
.data = .{ .path = path },
|
||||
});
|
||||
}
|
||||
|
||||
pub fn attachMemory(self: Face, bytes: []const u8) Error!void {
|
||||
return self.attachStream(.{
|
||||
.flags = .{ .memory = true },
|
||||
.data = .{ .memory = bytes },
|
||||
});
|
||||
}
|
||||
|
||||
pub fn attachStream(self: Face, args: OpenArgs) Error!void {
|
||||
return intToError(c.FT_Attach_Stream(self.handle, &args.cast()));
|
||||
}
|
||||
|
||||
pub fn loadGlyph(self: Face, index: u32, flags: LoadFlags) Error!void {
|
||||
return intToError(c.FT_Load_Glyph(self.handle, index, flags.cast()));
|
||||
}
|
||||
|
||||
pub fn loadChar(self: Face, char: u32, flags: LoadFlags) Error!void {
|
||||
return intToError(c.FT_Load_Char(self.handle, char, flags.cast()));
|
||||
}
|
||||
|
||||
pub fn setCharSize(self: Face, pt_width: i32, pt_height: i32, horz_resolution: u16, vert_resolution: u16) Error!void {
|
||||
return intToError(c.FT_Set_Char_Size(self.handle, pt_width, pt_height, horz_resolution, vert_resolution));
|
||||
}
|
||||
|
||||
pub fn setPixelSizes(self: Face, pixel_width: u32, pixel_height: u32) Error!void {
|
||||
return intToError(c.FT_Set_Pixel_Sizes(self.handle, pixel_width, pixel_height));
|
||||
}
|
||||
|
||||
pub fn requestSize(self: Face, req: SizeRequest) Error!void {
|
||||
var req_mut = req;
|
||||
return intToError(c.FT_Request_Size(self.handle, &req_mut));
|
||||
}
|
||||
|
||||
pub fn selectSize(self: Face, strike_index: i32) Error!void {
|
||||
return intToError(c.FT_Select_Size(self.handle, strike_index));
|
||||
}
|
||||
|
||||
pub fn setTransform(self: Face, matrix: ?Matrix, delta: ?Vector) Error!void {
|
||||
var matrix_mut = matrix;
|
||||
var delta_mut = delta;
|
||||
return c.FT_Set_Transform(self.handle, if (matrix_mut) |*m| m else null, if (delta_mut) |*d| d else null);
|
||||
}
|
||||
|
||||
pub fn getTransform(self: Face) std.meta.Tuple(&.{ Matrix, Vector }) {
|
||||
var matrix: Matrix = undefined;
|
||||
var delta: Vector = undefined;
|
||||
c.FT_Get_Transform(self.handle, &matrix, &delta);
|
||||
return .{ matrix, delta };
|
||||
}
|
||||
|
||||
pub fn getCharIndex(self: Face, char: u32) ?u32 {
|
||||
const i = c.FT_Get_Char_Index(self.handle, char);
|
||||
return if (i == 0) null else i;
|
||||
}
|
||||
|
||||
pub fn getNameIndex(self: Face, name: [:0]const u8) ?u32 {
|
||||
const i = c.FT_Get_Name_Index(self.handle, name.ptr);
|
||||
return if (i == 0) null else i;
|
||||
}
|
||||
|
||||
pub fn getKerning(self: Face, left_char_index: u32, right_char_index: u32, mode: KerningMode) Error!Vector {
|
||||
var kerning: Vector = undefined;
|
||||
try intToError(c.FT_Get_Kerning(self.handle, left_char_index, right_char_index, @enumToInt(mode), &kerning));
|
||||
return kerning;
|
||||
}
|
||||
|
||||
pub fn getTrackKerning(self: Face, point_size: i32, degree: i32) Error!i32 {
|
||||
var kerning: i32 = 0;
|
||||
try intToError(c.FT_Get_Track_Kerning(self.handle, point_size, degree, &@intCast(c_long, kerning)));
|
||||
return kerning;
|
||||
}
|
||||
|
||||
pub fn getGlyphName(self: Face, index: u32, buf: []u8) Error!void {
|
||||
try intToError(c.FT_Get_Glyph_Name(self.handle, index, buf.ptr, @intCast(c_uint, buf.len)));
|
||||
}
|
||||
|
||||
pub fn getPostscriptName(self: Face) ?[:0]const u8 {
|
||||
return if (c.FT_Get_Postscript_Name(self.handle)) |face_name|
|
||||
std.mem.span(@ptrCast([*:0]const u8, face_name))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn iterateCharmap(self: Face) CharmapIterator {
|
||||
return CharmapIterator.init(self);
|
||||
}
|
||||
|
||||
pub fn selectCharmap(self: Face, encoding: Encoding) Error!void {
|
||||
return intToError(c.FT_Select_Charmap(self.handle, @enumToInt(encoding)));
|
||||
}
|
||||
|
||||
pub fn setCharmap(self: Face, char_map: *CharMap) Error!void {
|
||||
return intToError(c.FT_Set_Charmap(self.handle, char_map));
|
||||
}
|
||||
|
||||
pub fn getFSTypeFlags(self: Face) FSType {
|
||||
return FSType.from(c.FT_Get_FSType_Flags(self.handle));
|
||||
}
|
||||
|
||||
pub fn getCharVariantIndex(self: Face, char: u32, variant_selector: u32) ?u32 {
|
||||
return switch (c.FT_Face_GetCharVariantIndex(self.handle, char, variant_selector)) {
|
||||
0 => null,
|
||||
else => |i| i,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getCharVariantIsDefault(self: Face, char: u32, variant_selector: u32) ?bool {
|
||||
return switch (c.FT_Face_GetCharVariantIsDefault(self.handle, char, variant_selector)) {
|
||||
-1 => null,
|
||||
0 => false,
|
||||
1 => true,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getVariantSelectors(self: Face) ?[]u32 {
|
||||
return if (c.FT_Face_GetVariantSelectors(self.handle)) |chars|
|
||||
@ptrCast([]u32, std.mem.sliceTo(@ptrCast([*:0]u32, chars), 0))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn getVariantsOfChar(self: Face, char: u32) ?[]u32 {
|
||||
return if (c.FT_Face_GetVariantsOfChar(self.handle, char)) |variants|
|
||||
@ptrCast([]u32, std.mem.sliceTo(@ptrCast([*:0]u32, variants), 0))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn getCharsOfVariant(self: Face, variant_selector: u32) ?[]u32 {
|
||||
return if (c.FT_Face_GetCharsOfVariant(self.handle, variant_selector)) |chars|
|
||||
@ptrCast([]u32, std.mem.sliceTo(@ptrCast([*:0]u32, chars), 0))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn getPaletteData(self: Face) Error!PaletteData {
|
||||
var p: c.FT_Palette_Data = undefined;
|
||||
try intToError(c.FT_Palette_Data_Get(self.handle, &p));
|
||||
return PaletteData{ .handle = p };
|
||||
}
|
||||
|
||||
fn selectPalette(self: Face, index: u16) Error!?[]const Color {
|
||||
var color: [*:0]Color = undefined;
|
||||
try intToError(c.FT_Palette_Select(self.handle, index, &color));
|
||||
const pd = try getPaletteData();
|
||||
return self.color[0..pd.numPaletteEntries()];
|
||||
}
|
||||
|
||||
pub fn setPaletteForegroundColor(self: Face, color: Color) Error!void {
|
||||
try intToError(c.FT_Palette_Set_Foreground_Color(self.handle, color));
|
||||
}
|
||||
|
||||
pub fn getGlyphLayersIterator(self: Face, glyph_index: u32) GlyphLayersIterator {
|
||||
return GlyphLayersIterator.init(self, glyph_index);
|
||||
}
|
||||
|
||||
pub fn getColorGlyphPaint(self: Face, base_glyph: u32, root_transform: RootTransform) ?Paint {
|
||||
var opaque_paint: OpaquePaint = undefined;
|
||||
if (c.FT_Get_Color_Glyph_Paint(self.handle, base_glyph, @enumToInt(root_transform), &opaque_paint) == 0)
|
||||
return null;
|
||||
return self.getPaint(opaque_paint);
|
||||
}
|
||||
|
||||
pub fn getColorGlyphClibBox(self: Face, base_glyph: u32) ?ClipBox {
|
||||
var clib_box: ClipBox = undefined;
|
||||
if (c.FT_Get_Color_Glyph_ClipBox(self.handle, base_glyph, &clib_box) == 0)
|
||||
return null;
|
||||
return clib_box;
|
||||
}
|
||||
|
||||
pub fn getPaint(self: Face, opaque_paint: OpaquePaint) ?Paint {
|
||||
var p: c.FT_COLR_Paint = undefined;
|
||||
if (c.FT_Get_Paint(self.handle, opaque_paint, &p) == 0)
|
||||
return null;
|
||||
return switch (@intToEnum(PaintFormat, p.format)) {
|
||||
.color_layers => Paint{ .color_layers = p.u.colr_layers },
|
||||
.glyph => Paint{ .glyph = p.u.glyph },
|
||||
.solid => Paint{ .solid = p.u.solid },
|
||||
.linear_gradient => Paint{ .linear_gradient = p.u.linear_gradient },
|
||||
.radial_gradient => Paint{ .radial_gradient = p.u.radial_gradient },
|
||||
.sweep_gradient => Paint{ .sweep_gradient = p.u.sweep_gradient },
|
||||
.transform => Paint{ .transform = p.u.transform },
|
||||
.translate => Paint{ .translate = p.u.translate },
|
||||
.scale => Paint{ .scale = p.u.scale },
|
||||
.rotate => Paint{ .rotate = p.u.rotate },
|
||||
.skew => Paint{ .skew = p.u.skew },
|
||||
.composite => Paint{ .composite = p.u.composite },
|
||||
.color_glyph => Paint{ .color_glyph = p.u.colr_glyph },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn newSize(self: Face) Error!Size {
|
||||
var s: c.FT_Size = undefined;
|
||||
try intToError(c.FT_New_Size(self.handle, &s));
|
||||
return Size{ .handle = s };
|
||||
}
|
||||
|
||||
pub fn numFaces(self: Face) u32 {
|
||||
return @intCast(u32, self.handle.*.num_faces);
|
||||
}
|
||||
|
||||
pub fn faceIndex(self: Face) u32 {
|
||||
return @intCast(u32, self.handle.*.face_index);
|
||||
}
|
||||
|
||||
pub fn faceFlags(self: Face) FaceFlags {
|
||||
return FaceFlags.from(self.handle.*.face_flags);
|
||||
}
|
||||
|
||||
pub fn styleFlags(self: Face) StyleFlags {
|
||||
return StyleFlags.from(self.handle.*.style_flags);
|
||||
}
|
||||
|
||||
pub fn numGlyphs(self: Face) u32 {
|
||||
return @intCast(u32, self.handle.*.num_glyphs);
|
||||
}
|
||||
|
||||
pub fn familyName(self: Face) ?[:0]const u8 {
|
||||
return if (self.handle.*.family_name) |family|
|
||||
std.mem.span(@ptrCast([*:0]const u8, family))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn styleName(self: Face) ?[:0]const u8 {
|
||||
return if (self.handle.*.style_name) |style_name|
|
||||
std.mem.span(@ptrCast([*:0]const u8, style_name))
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn numFixedSizes(self: Face) u32 {
|
||||
return @intCast(u32, self.handle.*.num_fixed_sizes);
|
||||
}
|
||||
|
||||
pub fn availableSizes(self: Face) ?BitmapSize {
|
||||
return if (self.handle.*.available_sizes != null)
|
||||
self.handle.*.available_sizes.*
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn getAdvance(self: Face, glyph_index: u32, load_flags: LoadFlags) Error!i32 {
|
||||
var a: i32 = 0;
|
||||
try intToError(c.FT_Get_Advance(self.handle, glyph_index, load_flags.cast(), &@intCast(c_long, a)));
|
||||
return a;
|
||||
}
|
||||
|
||||
pub fn getAdvances(self: Face, start: u32, advances_out: []c_long, load_flags: LoadFlags) Error!void {
|
||||
try intToError(c.FT_Get_Advances(self.handle, start, @intCast(c_uint, advances_out.len), load_flags.cast(), advances_out.ptr));
|
||||
}
|
||||
|
||||
pub fn numCharmaps(self: Face) u32 {
|
||||
return @intCast(u32, self.handle.*.num_charmaps);
|
||||
}
|
||||
|
||||
pub fn charmaps(self: Face) []const CharMap {
|
||||
return @ptrCast([*]const CharMap, self.handle.*.charmaps)[0..self.numCharmaps()];
|
||||
}
|
||||
|
||||
pub fn bbox(self: Face) BBox {
|
||||
return self.handle.*.bbox;
|
||||
}
|
||||
|
||||
pub fn unitsPerEM(self: Face) u16 {
|
||||
return self.handle.*.units_per_EM;
|
||||
}
|
||||
|
||||
pub fn ascender(self: Face) i16 {
|
||||
return self.handle.*.ascender;
|
||||
}
|
||||
|
||||
pub fn descender(self: Face) i16 {
|
||||
return self.handle.*.descender;
|
||||
}
|
||||
|
||||
pub fn height(self: Face) i16 {
|
||||
return self.handle.*.height;
|
||||
}
|
||||
|
||||
pub fn maxAdvanceWidth(self: Face) i16 {
|
||||
return self.handle.*.max_advance_width;
|
||||
}
|
||||
|
||||
pub fn maxAdvanceHeight(self: Face) i16 {
|
||||
return self.handle.*.max_advance_height;
|
||||
}
|
||||
|
||||
pub fn underlinePosition(self: Face) i16 {
|
||||
return self.handle.*.underline_position;
|
||||
}
|
||||
|
||||
pub fn underlineThickness(self: Face) i16 {
|
||||
return self.handle.*.underline_thickness;
|
||||
}
|
||||
|
||||
pub fn glyph(self: Face) GlyphSlot {
|
||||
return .{ .handle = self.handle.*.glyph };
|
||||
}
|
||||
|
||||
pub fn size(self: Face) Size {
|
||||
return Size{ .handle = self.handle.*.size };
|
||||
}
|
||||
|
||||
pub fn charmap(self: Face) CharMap {
|
||||
return self.handle.*.charmap.*;
|
||||
}
|
||||
|
||||
pub fn hasHorizontal(self: Face) bool {
|
||||
return c.FT_HAS_HORIZONTAL(self.handle);
|
||||
}
|
||||
|
||||
pub fn hasVertical(self: Face) bool {
|
||||
return c.FT_HAS_VERTICAL(self.handle);
|
||||
}
|
||||
|
||||
pub fn hasKerning(self: Face) bool {
|
||||
return c.FT_HAS_KERNING(self.handle);
|
||||
}
|
||||
|
||||
pub fn hasFixedSizes(self: Face) bool {
|
||||
return c.FT_HAS_FIXED_SIZES(self.handle);
|
||||
}
|
||||
|
||||
pub fn hasGlyphNames(self: Face) bool {
|
||||
return c.FT_HAS_GLYPH_NAMES(self.handle);
|
||||
}
|
||||
|
||||
pub fn hasColor(self: Face) bool {
|
||||
return c.FT_HAS_COLOR(self.handle);
|
||||
}
|
||||
|
||||
pub fn isScalable(self: Face) bool {
|
||||
return c.FT_IS_SCALABLE(self.handle);
|
||||
}
|
||||
|
||||
pub fn isSfnt(self: Face) bool {
|
||||
return c.FT_IS_SFNT(self.handle);
|
||||
}
|
||||
|
||||
pub fn isFixedWidth(self: Face) bool {
|
||||
return c.FT_IS_FIXED_WIDTH(self.handle);
|
||||
}
|
||||
|
||||
pub fn isCidKeyed(self: Face) bool {
|
||||
return c.FT_IS_CID_KEYED(self.handle);
|
||||
}
|
||||
|
||||
pub fn isTricky(self: Face) bool {
|
||||
return c.FT_IS_TRICKY(self.handle);
|
||||
}
|
||||
105
libs/freetype/src/GlyphSlot.zig
Normal file
105
libs/freetype/src/GlyphSlot.zig
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
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("freetype.zig").Library;
|
||||
const Face = @import("freetype.zig").Face;
|
||||
const RenderMode = @import("freetype.zig").RenderMode;
|
||||
const Matrix = @import("types.zig").Matrix;
|
||||
const Outline = @import("image.zig").Outline;
|
||||
const GlyphFormat = @import("image.zig").GlyphFormat;
|
||||
const Vector = @import("image.zig").Vector;
|
||||
const GlyphMetrics = @import("image.zig").GlyphMetrics;
|
||||
const Bitmap = @import("image.zig").Bitmap;
|
||||
|
||||
const GlyphSlot = @This();
|
||||
|
||||
pub const SubGlyphInfo = struct {
|
||||
index: i32,
|
||||
flags: c_uint,
|
||||
arg1: i32,
|
||||
arg2: i32,
|
||||
transform: Matrix,
|
||||
};
|
||||
|
||||
handle: c.FT_GlyphSlot,
|
||||
|
||||
pub fn library(self: GlyphSlot) Library {
|
||||
return .{ .handle = self.handle.*.library };
|
||||
}
|
||||
|
||||
pub fn face(self: GlyphSlot) Face {
|
||||
return .{ .handle = self.handle.*.face };
|
||||
}
|
||||
|
||||
pub fn next(self: GlyphSlot) GlyphSlot {
|
||||
return .{ .handle = self.handle.*.next };
|
||||
}
|
||||
|
||||
pub fn glyphIndex(self: GlyphSlot) u32 {
|
||||
return self.handle.*.glyph_index;
|
||||
}
|
||||
|
||||
pub fn metrics(self: GlyphSlot) GlyphMetrics {
|
||||
return self.handle.*.metrics;
|
||||
}
|
||||
|
||||
pub fn linearHoriAdvance(self: GlyphSlot) i32 {
|
||||
return @intCast(i32, self.handle.*.linearHoriAdvance);
|
||||
}
|
||||
|
||||
pub fn linearVertAdvance(self: GlyphSlot) i32 {
|
||||
return @intCast(i32, self.handle.*.linearVertAdvance);
|
||||
}
|
||||
|
||||
pub fn advance(self: GlyphSlot) Vector {
|
||||
return self.handle.*.advance;
|
||||
}
|
||||
|
||||
pub fn format(self: GlyphSlot) GlyphFormat {
|
||||
return @intToEnum(GlyphFormat, self.handle.*.format);
|
||||
}
|
||||
|
||||
pub fn ownBitmap(self: GlyphSlot) Error!void {
|
||||
try intToError(c.FT_GlyphSlot_Own_Bitmap(self.handle));
|
||||
}
|
||||
|
||||
pub fn bitmap(self: GlyphSlot) Bitmap {
|
||||
return .{ .handle = self.handle.*.bitmap };
|
||||
}
|
||||
|
||||
pub fn bitmapLeft(self: GlyphSlot) i32 {
|
||||
return self.handle.*.bitmap_left;
|
||||
}
|
||||
|
||||
pub fn bitmapTop(self: GlyphSlot) i32 {
|
||||
return self.handle.*.bitmap_top;
|
||||
}
|
||||
|
||||
pub fn outline(self: GlyphSlot) ?Outline {
|
||||
return if (self.format() == .outline) .{ .handle = &self.handle.*.outline } else null;
|
||||
}
|
||||
|
||||
pub fn lsbDelta(self: GlyphSlot) i32 {
|
||||
return @intCast(i32, self.handle.*.lsb_delta);
|
||||
}
|
||||
|
||||
pub fn rsbDelta(self: GlyphSlot) i32 {
|
||||
return @intCast(i32, self.handle.*.rsb_delta);
|
||||
}
|
||||
|
||||
pub fn render(self: GlyphSlot, render_mode: RenderMode) Error!void {
|
||||
return intToError(c.FT_Render_Glyph(self.handle, @enumToInt(render_mode)));
|
||||
}
|
||||
|
||||
pub fn getSubGlyphInfo(self: GlyphSlot, sub_index: u32) Error!SubGlyphInfo {
|
||||
var info: SubGlyphInfo = undefined;
|
||||
try intToError(c.FT_Get_SubGlyph_Info(self.handle, sub_index, &info.index, &info.flags, &info.arg1, &info.arg2, &info.transform));
|
||||
return info;
|
||||
}
|
||||
|
||||
pub fn getGlyph(self: GlyphSlot) Error!Glyph {
|
||||
var res: c.FT_Glyph = undefined;
|
||||
try intToError(c.FT_Get_Glyph(self.handle, &res));
|
||||
return Glyph{ .handle = res };
|
||||
}
|
||||
82
libs/freetype/src/Library.zig
Normal file
82
libs/freetype/src/Library.zig
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const Error = @import("error.zig").Error;
|
||||
const Face = @import("freetype.zig").Face;
|
||||
const Stroker = @import("stroke.zig").Stroker;
|
||||
const OpenArgs = @import("freetype.zig").OpenArgs;
|
||||
const Bitmap = @import("image.zig").Bitmap;
|
||||
const Outline = @import("image.zig").Outline;
|
||||
const RasterParams = @import("image.zig").RasterParams;
|
||||
const LcdFilter = @import("lcdfilter.zig").LcdFilter;
|
||||
|
||||
const Library = @This();
|
||||
|
||||
pub const Version = struct {
|
||||
major: i32,
|
||||
minor: i32,
|
||||
patch: i32,
|
||||
};
|
||||
|
||||
handle: c.FT_Library,
|
||||
|
||||
pub fn init() Error!Library {
|
||||
var lib = Library{ .handle = undefined };
|
||||
try intToError(c.FT_Init_FreeType(&lib.handle));
|
||||
return lib;
|
||||
}
|
||||
|
||||
pub fn deinit(self: Library) void {
|
||||
_ = c.FT_Done_FreeType(self.handle);
|
||||
}
|
||||
|
||||
pub fn createFace(self: Library, path: []const u8, face_index: i32) Error!Face {
|
||||
return self.openFace(.{
|
||||
.flags = .{ .path = true },
|
||||
.data = .{ .path = path },
|
||||
}, face_index);
|
||||
}
|
||||
|
||||
pub fn createFaceMemory(self: Library, bytes: []const u8, face_index: i32) Error!Face {
|
||||
return self.openFace(.{
|
||||
.flags = .{ .memory = true },
|
||||
.data = .{ .memory = bytes },
|
||||
}, face_index);
|
||||
}
|
||||
|
||||
pub fn openFace(self: Library, args: OpenArgs, face_index: i32) Error!Face {
|
||||
var f: c.FT_Face = undefined;
|
||||
try intToError(c.FT_Open_Face(self.handle, &args.cast(), face_index, &f));
|
||||
return Face{ .handle = f };
|
||||
}
|
||||
|
||||
pub fn version(self: Library) Version {
|
||||
var v: Version = undefined;
|
||||
c.FT_Library_Version(
|
||||
self.handle,
|
||||
&v.major,
|
||||
&v.minor,
|
||||
&v.patch,
|
||||
);
|
||||
return v;
|
||||
}
|
||||
|
||||
pub fn createStroker(self: Library) Error!Stroker {
|
||||
var s: c.FT_Stroker = undefined;
|
||||
try intToError(c.FT_Stroker_New(self.handle, &s));
|
||||
return Stroker{ .handle = s };
|
||||
}
|
||||
|
||||
pub fn createOutlineFromBitmap(self: Library, bitmap: Bitmap) Error!Outline {
|
||||
var o: Outline = undefined;
|
||||
try intToError(c.FT_Outline_Get_Bitmap(self.handle, o.handle, &bitmap.handle));
|
||||
return o;
|
||||
}
|
||||
|
||||
pub fn renderOutline(self: Library, outline: Outline, params: *RasterParams) Error!void {
|
||||
try intToError(c.FT_Outline_Render(self.handle, outline.handle, params));
|
||||
}
|
||||
|
||||
pub fn setLcdFilter(self: Library, lcd_filter: LcdFilter) Error!void {
|
||||
return intToError(c.FT_Library_SetLcdFilter(self.handle, @enumToInt(lcd_filter)));
|
||||
}
|
||||
11
libs/freetype/src/c.zig
Normal file
11
libs/freetype/src/c.zig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
pub usingnamespace @cImport({
|
||||
@cInclude("hb-ft.h");
|
||||
@cInclude("freetype/ftadvanc.h");
|
||||
@cInclude("freetype/ftbbox.h");
|
||||
@cInclude("freetype/ftbitmap.h");
|
||||
@cInclude("freetype/ftcolor.h");
|
||||
@cInclude("freetype/ftlcdfil.h");
|
||||
@cInclude("freetype/ftsizes.h");
|
||||
@cInclude("freetype/ftstroke.h");
|
||||
@cInclude("freetype/fttrigon.h");
|
||||
});
|
||||
176
libs/freetype/src/color.zig
Normal file
176
libs/freetype/src/color.zig
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
const utils = @import("utils");
|
||||
const c = @import("c");
|
||||
const Face = @import("freetype.zig").Face;
|
||||
|
||||
pub const Color = c.FT_Color;
|
||||
pub const LayerIterator = c.FT_LayerIterator;
|
||||
pub const ColorStopIterator = c.FT_ColorStopIterator;
|
||||
pub const ColorIndex = c.FT_ColorIndex;
|
||||
pub const ColorStop = c.FT_ColorStop;
|
||||
pub const ColorLine = c.FT_ColorLine;
|
||||
pub const Affine23 = c.FT_Affine23;
|
||||
pub const OpaquePaint = c.FT_OpaquePaint;
|
||||
pub const PaintColrLayers = c.FT_PaintColrLayers;
|
||||
pub const PaintSolid = c.FT_PaintSolid;
|
||||
pub const PaintLinearGradient = c.FT_PaintLinearGradient;
|
||||
pub const PaintRadialGradient = c.FT_PaintRadialGradient;
|
||||
pub const PaintSweepGradient = c.FT_PaintSweepGradient;
|
||||
pub const PaintGlyph = c.FT_PaintGlyph;
|
||||
pub const PaintColrGlyph = c.FT_PaintColrGlyph;
|
||||
pub const PaintTransform = c.FT_PaintTransform;
|
||||
pub const PaintTranslate = c.FT_PaintTranslate;
|
||||
pub const PaintScale = c.FT_PaintScale;
|
||||
pub const PaintRotate = c.FT_PaintRotate;
|
||||
pub const PaintSkew = c.FT_PaintSkew;
|
||||
pub const PaintComposite = c.FT_PaintComposite;
|
||||
pub const ClipBox = c.FT_ClipBox;
|
||||
|
||||
pub const RootTransform = enum(u1) {
|
||||
include_root_transform = c.FT_COLOR_INCLUDE_ROOT_TRANSFORM,
|
||||
no_root_transform = c.FT_COLOR_NO_ROOT_TRANSFORM,
|
||||
};
|
||||
|
||||
pub const PaintExtend = enum(u2) {
|
||||
pad = c.FT_COLR_PAINT_EXTEND_PAD,
|
||||
repeat = c.FT_COLR_PAINT_EXTEND_REPEAT,
|
||||
reflect = c.FT_COLR_PAINT_EXTEND_REFLECT,
|
||||
};
|
||||
|
||||
pub const PaintFormat = enum(u8) {
|
||||
color_layers = c.FT_COLR_PAINTFORMAT_COLR_LAYERS,
|
||||
solid = c.FT_COLR_PAINTFORMAT_SOLID,
|
||||
linear_gradient = c.FT_COLR_PAINTFORMAT_LINEAR_GRADIENT,
|
||||
radial_gradient = c.FT_COLR_PAINTFORMAT_RADIAL_GRADIENT,
|
||||
sweep_gradient = c.FT_COLR_PAINTFORMAT_SWEEP_GRADIENT,
|
||||
glyph = c.FT_COLR_PAINTFORMAT_GLYPH,
|
||||
color_glyph = c.FT_COLR_PAINTFORMAT_COLR_GLYPH,
|
||||
transform = c.FT_COLR_PAINTFORMAT_TRANSFORM,
|
||||
translate = c.FT_COLR_PAINTFORMAT_TRANSLATE,
|
||||
scale = c.FT_COLR_PAINTFORMAT_SCALE,
|
||||
rotate = c.FT_COLR_PAINTFORMAT_ROTATE,
|
||||
skew = c.FT_COLR_PAINTFORMAT_SKEW,
|
||||
composite = c.FT_COLR_PAINTFORMAT_COMPOSITE,
|
||||
};
|
||||
|
||||
pub const CompositeMode = enum(u5) {
|
||||
clear = c.FT_COLR_COMPOSITE_CLEAR,
|
||||
src = c.FT_COLR_COMPOSITE_SRC,
|
||||
dest = c.FT_COLR_COMPOSITE_DEST,
|
||||
src_over = c.FT_COLR_COMPOSITE_SRC_OVER,
|
||||
dest_over = c.FT_COLR_COMPOSITE_DEST_OVER,
|
||||
src_in = c.FT_COLR_COMPOSITE_SRC_IN,
|
||||
dest_in = c.FT_COLR_COMPOSITE_DEST_IN,
|
||||
src_out = c.FT_COLR_COMPOSITE_SRC_OUT,
|
||||
dest_out = c.FT_COLR_COMPOSITE_DEST_OUT,
|
||||
src_atop = c.FT_COLR_COMPOSITE_SRC_ATOP,
|
||||
dest_atop = c.FT_COLR_COMPOSITE_DEST_ATOP,
|
||||
xor = c.FT_COLR_COMPOSITE_XOR,
|
||||
plus = c.FT_COLR_COMPOSITE_PLUS,
|
||||
screen = c.FT_COLR_COMPOSITE_SCREEN,
|
||||
overlay = c.FT_COLR_COMPOSITE_OVERLAY,
|
||||
darken = c.FT_COLR_COMPOSITE_DARKEN,
|
||||
lighten = c.FT_COLR_COMPOSITE_LIGHTEN,
|
||||
color_dodge = c.FT_COLR_COMPOSITE_COLOR_DODGE,
|
||||
color_burn = c.FT_COLR_COMPOSITE_COLOR_BURN,
|
||||
hard_light = c.FT_COLR_COMPOSITE_HARD_LIGHT,
|
||||
soft_light = c.FT_COLR_COMPOSITE_SOFT_LIGHT,
|
||||
difference = c.FT_COLR_COMPOSITE_DIFFERENCE,
|
||||
exclusion = c.FT_COLR_COMPOSITE_EXCLUSION,
|
||||
multiply = c.FT_COLR_COMPOSITE_MULTIPLY,
|
||||
hsl_hue = c.FT_COLR_COMPOSITE_HSL_HUE,
|
||||
hsl_saturation = c.FT_COLR_COMPOSITE_HSL_SATURATION,
|
||||
hsl_color = c.FT_COLR_COMPOSITE_HSL_COLOR,
|
||||
hsl_luminosity = c.FT_COLR_COMPOSITE_HSL_LUMINOSITY,
|
||||
};
|
||||
|
||||
pub const Paint = union(PaintFormat) {
|
||||
color_layers: PaintColrLayers,
|
||||
glyph: PaintGlyph,
|
||||
solid: PaintSolid,
|
||||
linear_gradient: PaintLinearGradient,
|
||||
radial_gradient: PaintRadialGradient,
|
||||
sweep_gradient: PaintSweepGradient,
|
||||
transform: PaintTransform,
|
||||
translate: PaintTranslate,
|
||||
scale: PaintScale,
|
||||
rotate: PaintRotate,
|
||||
skew: PaintSkew,
|
||||
composite: PaintComposite,
|
||||
color_glyph: PaintColrGlyph,
|
||||
};
|
||||
|
||||
pub const PaletteData = struct {
|
||||
handle: c.FT_Palette_Data,
|
||||
|
||||
pub fn numPalettes(self: PaletteData) u16 {
|
||||
return self.handle.num_palettes;
|
||||
}
|
||||
|
||||
pub fn paletteNameIDs(self: PaletteData) ?[]const u16 {
|
||||
return self.handle.palette_name_ids[0..self.numPalettes()];
|
||||
}
|
||||
|
||||
pub fn paletteFlags(self: PaletteData) ?[]const u16 {
|
||||
return self.handle.palette_flags[0..self.numPalettes()];
|
||||
}
|
||||
|
||||
pub fn paletteFlag(self: PaletteData, index: u32) PaletteFlags {
|
||||
return PaletteFlags.from(self.handle.palette_flags[index]);
|
||||
}
|
||||
|
||||
pub fn numPaletteEntries(self: PaletteData) u16 {
|
||||
return self.handle.num_palette_entries;
|
||||
}
|
||||
|
||||
pub fn paletteEntryNameIDs(self: PaletteData) ?[]const u16 {
|
||||
return self.handle.palette_entry_name_ids[0..self.numPaletteEntries()];
|
||||
}
|
||||
};
|
||||
|
||||
pub const PaletteFlags = packed struct {
|
||||
for_light_background: bool = false,
|
||||
for_dark_background: bool = false,
|
||||
|
||||
pub const Flag = enum(u2) {
|
||||
for_light_background = c.FT_PALETTE_FOR_LIGHT_BACKGROUND,
|
||||
for_dark_background = c.FT_PALETTE_FOR_DARK_BACKGROUND,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_int) PaletteFlags {
|
||||
return utils.bitFieldsToStruct(PaletteFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn to(flags: PaletteFlags) c_int {
|
||||
return utils.structToBitFields(c_int, Flag, flags);
|
||||
}
|
||||
};
|
||||
|
||||
pub const GlyphLayersIterator = struct {
|
||||
face: Face,
|
||||
glyph_index: u32,
|
||||
layer_glyph_index: u32,
|
||||
layer_color_index: u32,
|
||||
iterator: LayerIterator,
|
||||
|
||||
pub fn init(face: Face, glyph_index: u32) GlyphLayersIterator {
|
||||
var iterator: LayerIterator = undefined;
|
||||
iterator.p = null;
|
||||
return .{
|
||||
.face = face,
|
||||
.glyph_index = glyph_index,
|
||||
.layer_glyph_index = 0,
|
||||
.layer_color_index = 0,
|
||||
.iterator = iterator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn next(self: *GlyphLayersIterator) bool {
|
||||
return if (c.FT_Get_Color_Glyph_Layer(
|
||||
self.face.handle,
|
||||
self.glyph_index,
|
||||
&self.layer_glyph_index,
|
||||
&self.layer_color_index,
|
||||
&self.iterator,
|
||||
) == 0) false else true;
|
||||
}
|
||||
};
|
||||
71
libs/freetype/src/computations.zig
Normal file
71
libs/freetype/src/computations.zig
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
const _c = @import("c");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const Error = @import("error.zig").Error;
|
||||
|
||||
const Vector = @import("image.zig").Vector;
|
||||
const Matrix = @import("types.zig").Matrix;
|
||||
|
||||
pub const angel_pi = _c.FT_ANGLE_PI;
|
||||
pub const angel_2pi = _c.FT_ANGLE_2PI;
|
||||
pub const angel_pi2 = _c.FT_ANGLE_PI2;
|
||||
pub const angel_pi4 = _c.FT_ANGLE_PI4;
|
||||
|
||||
pub fn mulDiv(a: i32, b: i32, c: i32) i32 {
|
||||
return @intCast(i32, _c.FT_MulDiv(a, b, c));
|
||||
}
|
||||
|
||||
pub fn mulFix(a: i32, b: i32) i32 {
|
||||
return @intCast(i32, _c.FT_MulFix(a, b));
|
||||
}
|
||||
|
||||
pub fn divFix(a: i32, b: i32) i32 {
|
||||
return @intCast(i32, _c.FT_DivFix(a, b));
|
||||
}
|
||||
|
||||
pub fn roundFix(a: i32) i32 {
|
||||
return @intCast(i32, _c.FT_RoundFix(a));
|
||||
}
|
||||
|
||||
pub fn ceilFix(a: i32) i32 {
|
||||
return @intCast(i32, _c.FT_CeilFix(a));
|
||||
}
|
||||
|
||||
pub fn floorFix(a: i32) i32 {
|
||||
return @intCast(i32, _c.FT_FloorFix(a));
|
||||
}
|
||||
|
||||
pub fn vectorTransform(vec: *Vector, matrix: Matrix) void {
|
||||
_c.FT_Vector_Transform(vec, &matrix);
|
||||
}
|
||||
|
||||
pub fn matrixMul(a: Matrix, b: *Matrix) void {
|
||||
_c.FT_Matrix_Multiply(&a, b);
|
||||
}
|
||||
|
||||
pub fn matrixInvert(m: *Matrix) Error!void {
|
||||
try intToError(_c.FT_Matrix_Invert(m));
|
||||
}
|
||||
|
||||
pub fn angleDiff(a: i32, b: i32) i32 {
|
||||
return @intCast(i32, _c.FT_Angle_Diff(a, b));
|
||||
}
|
||||
|
||||
pub fn vectorUnit(vec: *Vector, angle: i32) void {
|
||||
_c.FT_Vector_Unit(vec, angle);
|
||||
}
|
||||
|
||||
pub fn vectorRotate(vec: *Vector, angle: i32) void {
|
||||
_c.FT_Vector_Rotate(vec, angle);
|
||||
}
|
||||
|
||||
pub fn vectorLength(vec: *Vector) i32 {
|
||||
return @intCast(i32, _c.FT_Vector_Length(vec));
|
||||
}
|
||||
|
||||
pub fn vectorPolarize(vec: *Vector, length: *i32, angle: *i32) void {
|
||||
_c.FT_Vector_Polarize(vec, &@intCast(c_long, length.*), &@intCast(c_long, angle.*));
|
||||
}
|
||||
|
||||
pub fn vectorFromPolar(vec: *Vector, length: i32, angle: i32) void {
|
||||
_c.FT_Vector_From_Polar(vec, length, angle);
|
||||
}
|
||||
290
libs/freetype/src/error.zig
Normal file
290
libs/freetype/src/error.zig
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
const c = @import("c");
|
||||
|
||||
pub const Error = error{
|
||||
CannotOpenResource,
|
||||
UnknownFileFormat,
|
||||
InvalidFileFormat,
|
||||
InvalidVersion,
|
||||
LowerModuleVersion,
|
||||
InvalidArgument,
|
||||
UnimplementedFeature,
|
||||
InvalidTable,
|
||||
InvalidOffset,
|
||||
ArrayTooLarge,
|
||||
MissingModule,
|
||||
MissingProperty,
|
||||
InvalidGlyphIndex,
|
||||
InvalidCharacterCode,
|
||||
InvalidGlyphFormat,
|
||||
CannotRenderGlyph,
|
||||
InvalidOutline,
|
||||
InvalidComposite,
|
||||
TooManyHints,
|
||||
InvalidPixelSize,
|
||||
InvalidHandle,
|
||||
InvalidLibraryHandle,
|
||||
InvalidDriverHandle,
|
||||
InvalidFaceHandle,
|
||||
InvalidSizeHandle,
|
||||
InvalidSlotHandle,
|
||||
InvalidCharMapHandle,
|
||||
InvalidCacheHandle,
|
||||
InvalidStreamHandle,
|
||||
TooManyDrivers,
|
||||
TooManyExtensions,
|
||||
OutOfMemory,
|
||||
UnlistedObject,
|
||||
CannotOpenStream,
|
||||
InvalidStreamSeek,
|
||||
InvalidStreamSkip,
|
||||
InvalidStreamRead,
|
||||
InvalidStreamOperation,
|
||||
InvalidFrameOperation,
|
||||
NestedFrameAccess,
|
||||
InvalidFrameRead,
|
||||
RasterUninitialized,
|
||||
RasterCorrupted,
|
||||
RasterOverflow,
|
||||
RasterNegativeHeight,
|
||||
TooManyCaches,
|
||||
InvalidOpcode,
|
||||
TooFewArguments,
|
||||
StackOverflow,
|
||||
CodeOverflow,
|
||||
BadArgument,
|
||||
DivideByZero,
|
||||
InvalidReference,
|
||||
DebugOpCode,
|
||||
ENDFInExecStream,
|
||||
NestedDEFS,
|
||||
InvalidCodeRange,
|
||||
ExecutionTooLong,
|
||||
TooManyFunctionDefs,
|
||||
TooManyInstructionDefs,
|
||||
TableMissing,
|
||||
HorizHeaderMissing,
|
||||
LocationsMissing,
|
||||
NameTableMissing,
|
||||
CMapTableMissing,
|
||||
HmtxTableMissing,
|
||||
PostTableMissing,
|
||||
InvalidHorizMetrics,
|
||||
InvalidCharMapFormat,
|
||||
InvalidPPem,
|
||||
InvalidVertMetrics,
|
||||
CouldNotFindContext,
|
||||
InvalidPostTableFormat,
|
||||
InvalidPostTable,
|
||||
Syntax,
|
||||
StackUnderflow,
|
||||
Ignore,
|
||||
NoUnicodeGlyphName,
|
||||
MissingStartfontField,
|
||||
MissingFontField,
|
||||
MissingSizeField,
|
||||
MissingFontboundingboxField,
|
||||
MissingCharsField,
|
||||
MissingStartcharField,
|
||||
MissingEncodingField,
|
||||
MissingBbxField,
|
||||
BbxTooBig,
|
||||
CorruptedFontHeader,
|
||||
CorruptedFontGlyphs,
|
||||
};
|
||||
|
||||
pub fn intToError(err: c_int) Error!void {
|
||||
return switch (err) {
|
||||
c.FT_Err_Ok => {},
|
||||
c.FT_Err_Cannot_Open_Resource => Error.CannotOpenResource,
|
||||
c.FT_Err_Unknown_File_Format => Error.UnknownFileFormat,
|
||||
c.FT_Err_Invalid_File_Format => Error.InvalidFileFormat,
|
||||
c.FT_Err_Invalid_Version => Error.InvalidVersion,
|
||||
c.FT_Err_Lower_Module_Version => Error.LowerModuleVersion,
|
||||
c.FT_Err_Invalid_Argument => Error.InvalidArgument,
|
||||
c.FT_Err_Unimplemented_Feature => Error.UnimplementedFeature,
|
||||
c.FT_Err_Invalid_Table => Error.InvalidTable,
|
||||
c.FT_Err_Invalid_Offset => Error.InvalidOffset,
|
||||
c.FT_Err_Array_Too_Large => Error.ArrayTooLarge,
|
||||
c.FT_Err_Missing_Module => Error.MissingModule,
|
||||
c.FT_Err_Missing_Property => Error.MissingProperty,
|
||||
c.FT_Err_Invalid_Glyph_Index => Error.InvalidGlyphIndex,
|
||||
c.FT_Err_Invalid_Character_Code => Error.InvalidCharacterCode,
|
||||
c.FT_Err_Invalid_Glyph_Format => Error.InvalidGlyphFormat,
|
||||
c.FT_Err_Cannot_Render_Glyph => Error.CannotRenderGlyph,
|
||||
c.FT_Err_Invalid_Outline => Error.InvalidOutline,
|
||||
c.FT_Err_Invalid_Composite => Error.InvalidComposite,
|
||||
c.FT_Err_Too_Many_Hints => Error.TooManyHints,
|
||||
c.FT_Err_Invalid_Pixel_Size => Error.InvalidPixelSize,
|
||||
c.FT_Err_Invalid_Handle => Error.InvalidHandle,
|
||||
c.FT_Err_Invalid_Library_Handle => Error.InvalidLibraryHandle,
|
||||
c.FT_Err_Invalid_Driver_Handle => Error.InvalidDriverHandle,
|
||||
c.FT_Err_Invalid_Face_Handle => Error.InvalidFaceHandle,
|
||||
c.FT_Err_Invalid_Size_Handle => Error.InvalidSizeHandle,
|
||||
c.FT_Err_Invalid_Slot_Handle => Error.InvalidSlotHandle,
|
||||
c.FT_Err_Invalid_CharMap_Handle => Error.InvalidCharMapHandle,
|
||||
c.FT_Err_Invalid_Cache_Handle => Error.InvalidCacheHandle,
|
||||
c.FT_Err_Invalid_Stream_Handle => Error.InvalidStreamHandle,
|
||||
c.FT_Err_Too_Many_Drivers => Error.TooManyDrivers,
|
||||
c.FT_Err_Too_Many_Extensions => Error.TooManyExtensions,
|
||||
c.FT_Err_Out_Of_Memory => Error.OutOfMemory,
|
||||
c.FT_Err_Unlisted_Object => Error.UnlistedObject,
|
||||
c.FT_Err_Cannot_Open_Stream => Error.CannotOpenStream,
|
||||
c.FT_Err_Invalid_Stream_Seek => Error.InvalidStreamSeek,
|
||||
c.FT_Err_Invalid_Stream_Skip => Error.InvalidStreamSkip,
|
||||
c.FT_Err_Invalid_Stream_Read => Error.InvalidStreamRead,
|
||||
c.FT_Err_Invalid_Stream_Operation => Error.InvalidStreamOperation,
|
||||
c.FT_Err_Invalid_Frame_Operation => Error.InvalidFrameOperation,
|
||||
c.FT_Err_Nested_Frame_Access => Error.NestedFrameAccess,
|
||||
c.FT_Err_Invalid_Frame_Read => Error.InvalidFrameRead,
|
||||
c.FT_Err_Raster_Uninitialized => Error.RasterUninitialized,
|
||||
c.FT_Err_Raster_Corrupted => Error.RasterCorrupted,
|
||||
c.FT_Err_Raster_Overflow => Error.RasterOverflow,
|
||||
c.FT_Err_Raster_Negative_Height => Error.RasterNegativeHeight,
|
||||
c.FT_Err_Too_Many_Caches => Error.TooManyCaches,
|
||||
c.FT_Err_Invalid_Opcode => Error.InvalidOpcode,
|
||||
c.FT_Err_Too_Few_Arguments => Error.TooFewArguments,
|
||||
c.FT_Err_Stack_Overflow => Error.StackOverflow,
|
||||
c.FT_Err_Code_Overflow => Error.CodeOverflow,
|
||||
c.FT_Err_Bad_Argument => Error.BadArgument,
|
||||
c.FT_Err_Divide_By_Zero => Error.DivideByZero,
|
||||
c.FT_Err_Invalid_Reference => Error.InvalidReference,
|
||||
c.FT_Err_Debug_OpCode => Error.DebugOpCode,
|
||||
c.FT_Err_ENDF_In_Exec_Stream => Error.ENDFInExecStream,
|
||||
c.FT_Err_Nested_DEFS => Error.NestedDEFS,
|
||||
c.FT_Err_Invalid_CodeRange => Error.InvalidCodeRange,
|
||||
c.FT_Err_Execution_Too_Long => Error.ExecutionTooLong,
|
||||
c.FT_Err_Too_Many_Function_Defs => Error.TooManyFunctionDefs,
|
||||
c.FT_Err_Too_Many_Instruction_Defs => Error.TooManyInstructionDefs,
|
||||
c.FT_Err_Table_Missing => Error.TableMissing,
|
||||
c.FT_Err_Horiz_Header_Missing => Error.HorizHeaderMissing,
|
||||
c.FT_Err_Locations_Missing => Error.LocationsMissing,
|
||||
c.FT_Err_Name_Table_Missing => Error.NameTableMissing,
|
||||
c.FT_Err_CMap_Table_Missing => Error.CMapTableMissing,
|
||||
c.FT_Err_Hmtx_Table_Missing => Error.HmtxTableMissing,
|
||||
c.FT_Err_Post_Table_Missing => Error.PostTableMissing,
|
||||
c.FT_Err_Invalid_Horiz_Metrics => Error.InvalidHorizMetrics,
|
||||
c.FT_Err_Invalid_CharMap_Format => Error.InvalidCharMapFormat,
|
||||
c.FT_Err_Invalid_PPem => Error.InvalidPPem,
|
||||
c.FT_Err_Invalid_Vert_Metrics => Error.InvalidVertMetrics,
|
||||
c.FT_Err_Could_Not_Find_Context => Error.CouldNotFindContext,
|
||||
c.FT_Err_Invalid_Post_Table_Format => Error.InvalidPostTableFormat,
|
||||
c.FT_Err_Invalid_Post_Table => Error.InvalidPostTable,
|
||||
c.FT_Err_Syntax_Error => Error.Syntax,
|
||||
c.FT_Err_Stack_Underflow => Error.StackUnderflow,
|
||||
c.FT_Err_Ignore => Error.Ignore,
|
||||
c.FT_Err_No_Unicode_Glyph_Name => Error.NoUnicodeGlyphName,
|
||||
c.FT_Err_Missing_Startfont_Field => Error.MissingStartfontField,
|
||||
c.FT_Err_Missing_Font_Field => Error.MissingFontField,
|
||||
c.FT_Err_Missing_Size_Field => Error.MissingSizeField,
|
||||
c.FT_Err_Missing_Fontboundingbox_Field => Error.MissingFontboundingboxField,
|
||||
c.FT_Err_Missing_Chars_Field => Error.MissingCharsField,
|
||||
c.FT_Err_Missing_Startchar_Field => Error.MissingStartcharField,
|
||||
c.FT_Err_Missing_Encoding_Field => Error.MissingEncodingField,
|
||||
c.FT_Err_Missing_Bbx_Field => Error.MissingBbxField,
|
||||
c.FT_Err_Bbx_Too_Big => Error.BbxTooBig,
|
||||
c.FT_Err_Corrupted_Font_Header => Error.CorruptedFontHeader,
|
||||
c.FT_Err_Corrupted_Font_Glyphs => Error.CorruptedFontGlyphs,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn errorToInt(err: Error) c_int {
|
||||
return switch (err) {
|
||||
Error.CannotOpenResource => c.FT_Err_Cannot_Open_Resource,
|
||||
Error.UnknownFileFormat => c.FT_Err_Unknown_File_Format,
|
||||
Error.InvalidFileFormat => c.FT_Err_Invalid_File_Format,
|
||||
Error.InvalidVersion => c.FT_Err_Invalid_Version,
|
||||
Error.LowerModuleVersion => c.FT_Err_Lower_Module_Version,
|
||||
Error.InvalidArgument => c.FT_Err_Invalid_Argument,
|
||||
Error.UnimplementedFeature => c.FT_Err_Unimplemented_Feature,
|
||||
Error.InvalidTable => c.FT_Err_Invalid_Table,
|
||||
Error.InvalidOffset => c.FT_Err_Invalid_Offset,
|
||||
Error.ArrayTooLarge => c.FT_Err_Array_Too_Large,
|
||||
Error.MissingModule => c.FT_Err_Missing_Module,
|
||||
Error.MissingProperty => c.FT_Err_Missing_Property,
|
||||
Error.InvalidGlyphIndex => c.FT_Err_Invalid_Glyph_Index,
|
||||
Error.InvalidCharacterCode => c.FT_Err_Invalid_Character_Code,
|
||||
Error.InvalidGlyphFormat => c.FT_Err_Invalid_Glyph_Format,
|
||||
Error.CannotRenderGlyph => c.FT_Err_Cannot_Render_Glyph,
|
||||
Error.InvalidOutline => c.FT_Err_Invalid_Outline,
|
||||
Error.InvalidComposite => c.FT_Err_Invalid_Composite,
|
||||
Error.TooManyHints => c.FT_Err_Too_Many_Hints,
|
||||
Error.InvalidPixelSize => c.FT_Err_Invalid_Pixel_Size,
|
||||
Error.InvalidHandle => c.FT_Err_Invalid_Handle,
|
||||
Error.InvalidLibraryHandle => c.FT_Err_Invalid_Library_Handle,
|
||||
Error.InvalidDriverHandle => c.FT_Err_Invalid_Driver_Handle,
|
||||
Error.InvalidFaceHandle => c.FT_Err_Invalid_Face_Handle,
|
||||
Error.InvalidSizeHandle => c.FT_Err_Invalid_Size_Handle,
|
||||
Error.InvalidSlotHandle => c.FT_Err_Invalid_Slot_Handle,
|
||||
Error.InvalidCharMapHandle => c.FT_Err_Invalid_CharMap_Handle,
|
||||
Error.InvalidCacheHandle => c.FT_Err_Invalid_Cache_Handle,
|
||||
Error.InvalidStreamHandle => c.FT_Err_Invalid_Stream_Handle,
|
||||
Error.TooManyDrivers => c.FT_Err_Too_Many_Drivers,
|
||||
Error.TooManyExtensions => c.FT_Err_Too_Many_Extensions,
|
||||
Error.OutOfMemory => c.FT_Err_Out_Of_Memory,
|
||||
Error.UnlistedObject => c.FT_Err_Unlisted_Object,
|
||||
Error.CannotOpenStream => c.FT_Err_Cannot_Open_Stream,
|
||||
Error.InvalidStreamSeek => c.FT_Err_Invalid_Stream_Seek,
|
||||
Error.InvalidStreamSkip => c.FT_Err_Invalid_Stream_Skip,
|
||||
Error.InvalidStreamRead => c.FT_Err_Invalid_Stream_Read,
|
||||
Error.InvalidStreamOperation => c.FT_Err_Invalid_Stream_Operation,
|
||||
Error.InvalidFrameOperation => c.FT_Err_Invalid_Frame_Operation,
|
||||
Error.NestedFrameAccess => c.FT_Err_Nested_Frame_Access,
|
||||
Error.InvalidFrameRead => c.FT_Err_Invalid_Frame_Read,
|
||||
Error.RasterUninitialized => c.FT_Err_Raster_Uninitialized,
|
||||
Error.RasterCorrupted => c.FT_Err_Raster_Corrupted,
|
||||
Error.RasterOverflow => c.FT_Err_Raster_Overflow,
|
||||
Error.RasterNegativeHeight => c.FT_Err_Raster_Negative_Height,
|
||||
Error.TooManyCaches => c.FT_Err_Too_Many_Caches,
|
||||
Error.InvalidOpcode => c.FT_Err_Invalid_Opcode,
|
||||
Error.TooFewArguments => c.FT_Err_Too_Few_Arguments,
|
||||
Error.StackOverflow => c.FT_Err_Stack_Overflow,
|
||||
Error.CodeOverflow => c.FT_Err_Code_Overflow,
|
||||
Error.BadArgument => c.FT_Err_Bad_Argument,
|
||||
Error.DivideByZero => c.FT_Err_Divide_By_Zero,
|
||||
Error.InvalidReference => c.FT_Err_Invalid_Reference,
|
||||
Error.DebugOpCode => c.FT_Err_Debug_OpCode,
|
||||
Error.ENDFInExecStream => c.FT_Err_ENDF_In_Exec_Stream,
|
||||
Error.NestedDEFS => c.FT_Err_Nested_DEFS,
|
||||
Error.InvalidCodeRange => c.FT_Err_Invalid_CodeRange,
|
||||
Error.ExecutionTooLong => c.FT_Err_Execution_Too_Long,
|
||||
Error.TooManyFunctionDefs => c.FT_Err_Too_Many_Function_Defs,
|
||||
Error.TooManyInstructionDefs => c.FT_Err_Too_Many_Instruction_Defs,
|
||||
Error.TableMissing => c.FT_Err_Table_Missing,
|
||||
Error.HorizHeaderMissing => c.FT_Err_Horiz_Header_Missing,
|
||||
Error.LocationsMissing => c.FT_Err_Locations_Missing,
|
||||
Error.NameTableMissing => c.FT_Err_Name_Table_Missing,
|
||||
Error.CMapTableMissing => c.FT_Err_CMap_Table_Missing,
|
||||
Error.HmtxTableMissing => c.FT_Err_Hmtx_Table_Missing,
|
||||
Error.PostTableMissing => c.FT_Err_Post_Table_Missing,
|
||||
Error.InvalidHorizMetrics => c.FT_Err_Invalid_Horiz_Metrics,
|
||||
Error.InvalidCharMapFormat => c.FT_Err_Invalid_CharMap_Format,
|
||||
Error.InvalidPPem => c.FT_Err_Invalid_PPem,
|
||||
Error.InvalidVertMetrics => c.FT_Err_Invalid_Vert_Metrics,
|
||||
Error.CouldNotFindContext => c.FT_Err_Could_Not_Find_Context,
|
||||
Error.InvalidPostTableFormat => c.FT_Err_Invalid_Post_Table_Format,
|
||||
Error.InvalidPostTable => c.FT_Err_Invalid_Post_Table,
|
||||
Error.Syntax => c.FT_Err_Syntax_Error,
|
||||
Error.StackUnderflow => c.FT_Err_Stack_Underflow,
|
||||
Error.Ignore => c.FT_Err_Ignore,
|
||||
Error.NoUnicodeGlyphName => c.FT_Err_No_Unicode_Glyph_Name,
|
||||
Error.MissingStartfontField => c.FT_Err_Missing_Startfont_Field,
|
||||
Error.MissingFontField => c.FT_Err_Missing_Font_Field,
|
||||
Error.MissingSizeField => c.FT_Err_Missing_Size_Field,
|
||||
Error.MissingFontboundingboxField => c.FT_Err_Missing_Fontboundingbox_Field,
|
||||
Error.MissingCharsField => c.FT_Err_Missing_Chars_Field,
|
||||
Error.MissingStartcharField => c.FT_Err_Missing_Startchar_Field,
|
||||
Error.MissingEncodingField => c.FT_Err_Missing_Encoding_Field,
|
||||
Error.MissingBbxField => c.FT_Err_Missing_Bbx_Field,
|
||||
Error.BbxTooBig => c.FT_Err_Bbx_Too_Big,
|
||||
Error.CorruptedFontHeader => c.FT_Err_Corrupted_Font_Header,
|
||||
Error.CorruptedFontGlyphs => c.FT_Err_Corrupted_Font_Glyphs,
|
||||
};
|
||||
}
|
||||
|
||||
test "error convertion" {
|
||||
const expectError = @import("std").testing.expectError;
|
||||
|
||||
try intToError(c.FT_Err_Ok);
|
||||
try expectError(Error.OutOfMemory, intToError(c.FT_Err_Out_Of_Memory));
|
||||
}
|
||||
289
libs/freetype/src/freetype.zig
Normal file
289
libs/freetype/src/freetype.zig
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
const std = @import("std");
|
||||
const utils = @import("utils");
|
||||
const c = @import("c");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const Error = @import("error.zig").Error;
|
||||
const Generic = @import("types.zig").Generic;
|
||||
|
||||
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;
|
||||
pub const SizeMetrics = c.FT_Size_Metrics;
|
||||
|
||||
pub const KerningMode = enum(u2) {
|
||||
default = c.FT_KERNING_DEFAULT,
|
||||
unfitted = c.FT_KERNING_UNFITTED,
|
||||
unscaled = c.FT_KERNING_UNSCALED,
|
||||
};
|
||||
|
||||
pub const RenderMode = enum(u3) {
|
||||
normal = c.FT_RENDER_MODE_NORMAL,
|
||||
light = c.FT_RENDER_MODE_LIGHT,
|
||||
mono = c.FT_RENDER_MODE_MONO,
|
||||
lcd = c.FT_RENDER_MODE_LCD,
|
||||
lcd_v = c.FT_RENDER_MODE_LCD_V,
|
||||
sdf = c.FT_RENDER_MODE_SDF,
|
||||
};
|
||||
|
||||
pub const SizeRequestType = enum(u3) {
|
||||
nominal = c.FT_SIZE_REQUEST_TYPE_NOMINAL,
|
||||
real_dim = c.FT_SIZE_REQUEST_TYPE_REAL_DIM,
|
||||
bbox = c.FT_SIZE_REQUEST_TYPE_BBOX,
|
||||
cell = c.FT_SIZE_REQUEST_TYPE_CELL,
|
||||
scales = c.FT_SIZE_REQUEST_TYPE_SCALES,
|
||||
max = c.FT_SIZE_REQUEST_TYPE_MAX,
|
||||
};
|
||||
|
||||
pub const Encoding = enum(u31) {
|
||||
none = c.FT_ENCODING_NONE,
|
||||
ms_symbol = c.FT_ENCODING_MS_SYMBOL,
|
||||
unicode = c.FT_ENCODING_UNICODE,
|
||||
sjis = c.FT_ENCODING_SJIS,
|
||||
prc = c.FT_ENCODING_PRC,
|
||||
big5 = c.FT_ENCODING_BIG5,
|
||||
wansung = c.FT_ENCODING_WANSUNG,
|
||||
johab = c.FT_ENCODING_JOHAB,
|
||||
adobe_standard = c.FT_ENCODING_ADOBE_STANDARD,
|
||||
adobe_expert = c.FT_ENCODING_ADOBE_EXPERT,
|
||||
adobe_custom = c.FT_ENCODING_ADOBE_CUSTOM,
|
||||
adobe_latin_1 = c.FT_ENCODING_ADOBE_LATIN_1,
|
||||
old_latin_2 = c.FT_ENCODING_OLD_LATIN_2,
|
||||
apple_roman = c.FT_ENCODING_APPLE_ROMAN,
|
||||
};
|
||||
|
||||
pub const Size = struct {
|
||||
handle: c.FT_Size,
|
||||
|
||||
pub fn face(self: Size) Face {
|
||||
return Face{ .handle = self.handle.*.face };
|
||||
}
|
||||
|
||||
pub fn generic(self: Size) Generic {
|
||||
return self.handle.*.generic;
|
||||
}
|
||||
|
||||
pub fn metrics(self: Size) SizeMetrics {
|
||||
return self.handle.*.metrics;
|
||||
}
|
||||
|
||||
pub fn activate(self: Size) Error!void {
|
||||
try intToError(c.FT_Activate_Size(self.handle));
|
||||
}
|
||||
|
||||
pub fn deinit(self: Size) void {
|
||||
intToError(c.FT_Done_Size(self.handle)) catch |err| {
|
||||
std.log.err("mach/freetype: Failed to destroy Size: {}", .{err});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const LoadFlags = packed struct {
|
||||
no_scale: bool = false,
|
||||
no_hinting: bool = false,
|
||||
render: bool = false,
|
||||
no_bitmap: bool = false,
|
||||
vertical_layout: bool = false,
|
||||
force_autohint: bool = false,
|
||||
crop_bitmap: bool = false,
|
||||
pedantic: bool = false,
|
||||
ignore_global_advance_with: bool = false,
|
||||
no_recurse: bool = false,
|
||||
ignore_transform: bool = false,
|
||||
monochrome: bool = false,
|
||||
linear_design: bool = false,
|
||||
no_autohint: bool = false,
|
||||
target_normal: bool = false,
|
||||
target_light: bool = false,
|
||||
target_mono: bool = false,
|
||||
target_lcd: bool = false,
|
||||
target_lcd_v: bool = false,
|
||||
color: bool = false,
|
||||
|
||||
pub const Flag = enum(u21) {
|
||||
no_scale = c.FT_LOAD_NO_SCALE,
|
||||
no_hinting = c.FT_LOAD_NO_HINTING,
|
||||
render = c.FT_LOAD_RENDER,
|
||||
no_bitmap = c.FT_LOAD_NO_BITMAP,
|
||||
vertical_layout = c.FT_LOAD_VERTICAL_LAYOUT,
|
||||
force_autohint = c.FT_LOAD_FORCE_AUTOHINT,
|
||||
crop_bitmap = c.FT_LOAD_CROP_BITMAP,
|
||||
pedantic = c.FT_LOAD_PEDANTIC,
|
||||
ignore_global_advance_with = c.FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH,
|
||||
no_recurse = c.FT_LOAD_NO_RECURSE,
|
||||
ignore_transform = c.FT_LOAD_IGNORE_TRANSFORM,
|
||||
monochrome = c.FT_LOAD_MONOCHROME,
|
||||
linear_design = c.FT_LOAD_LINEAR_DESIGN,
|
||||
no_autohint = c.FT_LOAD_NO_AUTOHINT,
|
||||
target_normal = c.FT_LOAD_TARGET_NORMAL,
|
||||
target_light = c.FT_LOAD_TARGET_LIGHT,
|
||||
target_mono = c.FT_LOAD_TARGET_MONO,
|
||||
target_lcd = c.FT_LOAD_TARGET_LCD,
|
||||
target_lcd_v = c.FT_LOAD_TARGET_LCD_V,
|
||||
color = c.FT_LOAD_COLOR,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_int) LoadFlags {
|
||||
return utils.bitFieldsToStruct(LoadFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: LoadFlags) c_int {
|
||||
return utils.structToBitFields(c_int, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FaceFlags = packed struct {
|
||||
scalable: bool = false,
|
||||
fixed_sizes: bool = false,
|
||||
fixed_width: bool = false,
|
||||
sfnt: bool = false,
|
||||
horizontal: bool = false,
|
||||
vertical: bool = false,
|
||||
kerning: bool = false,
|
||||
fast_glyphs: bool = false,
|
||||
multiple_masters: bool = false,
|
||||
glyph_names: bool = false,
|
||||
external_stream: bool = false,
|
||||
hinter: bool = false,
|
||||
cid_keyed: bool = false,
|
||||
tricky: bool = false,
|
||||
color: bool = false,
|
||||
variation: bool = false,
|
||||
svg: bool = false,
|
||||
sbix: bool = false,
|
||||
sbix_overlay: bool = false,
|
||||
|
||||
pub const Flag = enum(u19) {
|
||||
scalable = c.FT_FACE_FLAG_SCALABLE,
|
||||
fixed_sizes = c.FT_FACE_FLAG_FIXED_SIZES,
|
||||
fixed_width = c.FT_FACE_FLAG_FIXED_WIDTH,
|
||||
sfnt = c.FT_FACE_FLAG_SFNT,
|
||||
horizontal = c.FT_FACE_FLAG_HORIZONTAL,
|
||||
vertical = c.FT_FACE_FLAG_VERTICAL,
|
||||
kerning = c.FT_FACE_FLAG_KERNING,
|
||||
fast_glyphs = c.FT_FACE_FLAG_FAST_GLYPHS,
|
||||
multiple_masters = c.FT_FACE_FLAG_MULTIPLE_MASTERS,
|
||||
glyph_names = c.FT_FACE_FLAG_GLYPH_NAMES,
|
||||
external_stream = c.FT_FACE_FLAG_EXTERNAL_STREAM,
|
||||
hinter = c.FT_FACE_FLAG_HINTER,
|
||||
cid_keyed = c.FT_FACE_FLAG_CID_KEYED,
|
||||
tricky = c.FT_FACE_FLAG_TRICKY,
|
||||
color = c.FT_FACE_FLAG_COLOR,
|
||||
variation = c.FT_FACE_FLAG_VARIATION,
|
||||
svg = c.FT_FACE_FLAG_SVG,
|
||||
sbix = c.FT_FACE_FLAG_SBIX,
|
||||
sbix_overlay = c.FT_FACE_FLAG_SBIX_OVERLAY,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_long) FaceFlags {
|
||||
return utils.bitFieldsToStruct(FaceFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: FaceFlags) c_long {
|
||||
return utils.structToBitFields(c_long, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FSType = packed struct {
|
||||
installable_embedding: bool = false,
|
||||
restriced_license_embedding: bool = false,
|
||||
preview_and_print_embedding: bool = false,
|
||||
editable_embedding: bool = false,
|
||||
no_subsetting: bool = false,
|
||||
bitmap_embedding_only: bool = false,
|
||||
|
||||
pub const Flag = enum(u10) {
|
||||
installable_embedding = c.FT_FSTYPE_INSTALLABLE_EMBEDDING,
|
||||
restriced_license_embedding = c.FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING,
|
||||
preview_and_print_embedding = c.FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING,
|
||||
editable_embedding = c.FT_FSTYPE_EDITABLE_EMBEDDING,
|
||||
no_subsetting = c.FT_FSTYPE_NO_SUBSETTING,
|
||||
bitmap_embedding_only = c.FT_FSTYPE_BITMAP_EMBEDDING_ONLY,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_int) FSType {
|
||||
return utils.bitFieldsToStruct(FSType, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: FSType) c_int {
|
||||
return utils.structToBitFields(c_int, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const StyleFlags = packed struct {
|
||||
italic: bool = false,
|
||||
bold: bool = false,
|
||||
|
||||
pub const Flag = enum(u2) {
|
||||
italic = c.FT_STYLE_FLAG_ITALIC,
|
||||
bold = c.FT_STYLE_FLAG_BOLD,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_long) StyleFlags {
|
||||
return utils.bitFieldsToStruct(StyleFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: StyleFlags) c_long {
|
||||
return utils.structToBitFields(c_long, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const OpenFlags = packed struct {
|
||||
memory: bool = false,
|
||||
stream: bool = false,
|
||||
path: bool = false,
|
||||
driver: bool = false,
|
||||
params: bool = false,
|
||||
|
||||
pub const Flag = enum(u5) {
|
||||
memory = c.FT_OPEN_MEMORY,
|
||||
stream = c.FT_OPEN_STREAM,
|
||||
path = c.FT_OPEN_PATHNAME,
|
||||
driver = c.FT_OPEN_DRIVER,
|
||||
params = c.FT_OPEN_PARAMS,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_uint) OpenFlags {
|
||||
return utils.bitFieldsToStruct(OpenFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(flags: OpenFlags) c_uint {
|
||||
return utils.structToBitFields(c_uint, Flag, flags);
|
||||
}
|
||||
};
|
||||
pub const OpenArgs = struct {
|
||||
flags: OpenFlags,
|
||||
data: union(enum) {
|
||||
memory: []const u8,
|
||||
path: []const u8,
|
||||
stream: c.FT_Stream,
|
||||
driver: c.FT_Module,
|
||||
params: []const c.FT_Parameter,
|
||||
},
|
||||
|
||||
pub fn cast(self: OpenArgs) c.FT_Open_Args {
|
||||
var oa: c.FT_Open_Args = undefined;
|
||||
oa.flags = self.flags.cast();
|
||||
switch (self.data) {
|
||||
.memory => |d| {
|
||||
oa.memory_base = d.ptr;
|
||||
oa.memory_size = @intCast(u31, d.len);
|
||||
},
|
||||
.path => |*d| oa.pathname = @intToPtr(*u8, @ptrToInt(d.ptr)),
|
||||
.stream => |d| oa.stream = d,
|
||||
.driver => |d| oa.driver = d,
|
||||
.params => |*d| {
|
||||
oa.params = @intToPtr(*c.FT_Parameter, @ptrToInt(d.ptr));
|
||||
oa.num_params = @intCast(u31, d.len);
|
||||
},
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn getCharmapIndex(self: [*c]CharMap) ?u32 {
|
||||
const i = c.FT_Get_Charmap_Index(self);
|
||||
return if (i == -1) null else @intCast(u32, i);
|
||||
}
|
||||
172
libs/freetype/src/glyph.zig
Normal file
172
libs/freetype/src/glyph.zig
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
const std = @import("std");
|
||||
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("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("image.zig").Outline;
|
||||
const GlyphFormat = @import("image.zig").GlyphFormat;
|
||||
const Vector = @import("image.zig").Vector;
|
||||
const Bitmap = @import("image.zig").Bitmap;
|
||||
|
||||
pub const BBoxMode = enum(u2) {
|
||||
// https://freetype.org/freetype2/docs/reference/ft2-glyph_management.html#ft_glyph_bbox_mode
|
||||
// both `unscaled` and `subpixel` are set to 0
|
||||
unscaled_or_subpixels = c.FT_GLYPH_BBOX_UNSCALED,
|
||||
gridfit = c.FT_GLYPH_BBOX_GRIDFIT,
|
||||
truncate = c.FT_GLYPH_BBOX_TRUNCATE,
|
||||
pixels = c.FT_GLYPH_BBOX_PIXELS,
|
||||
};
|
||||
|
||||
pub const Glyph = struct {
|
||||
handle: c.FT_Glyph,
|
||||
|
||||
pub fn deinit(self: Glyph) void {
|
||||
c.FT_Done_Glyph(self.handle);
|
||||
}
|
||||
|
||||
pub fn newGlyph(library: Library, glyph_format: GlyphFormat) Glyph {
|
||||
var g: c.FT_Glyph = undefined;
|
||||
return .{
|
||||
.handle = c.FT_New_Glyph(library.handle, @enumToInt(glyph_format), &g),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn copy(self: Glyph) Error!Glyph {
|
||||
var g: c.FT_Glyph = undefined;
|
||||
try intToError(c.FT_Glyph_Copy(self.handle, &g));
|
||||
return Glyph{ .handle = g };
|
||||
}
|
||||
|
||||
pub fn transform(self: Glyph, matrix: ?Matrix, delta: ?Vector) Error!void {
|
||||
try intToError(c.FT_Glyph_Transform(self.handle, if (matrix) |m| &m else null, if (delta) |d| &d else null));
|
||||
}
|
||||
|
||||
pub fn getCBox(self: Glyph, bbox_mode: BBoxMode) BBox {
|
||||
var b: BBox = undefined;
|
||||
c.FT_Glyph_Get_CBox(self.handle, @enumToInt(bbox_mode), &b);
|
||||
return b;
|
||||
}
|
||||
|
||||
pub fn toBitmapGlyph(self: *Glyph, render_mode: RenderMode, origin: ?Vector) Error!BitmapGlyph {
|
||||
try intToError(c.FT_Glyph_To_Bitmap(&self.handle, @enumToInt(render_mode), if (origin) |o| &o else null, 1));
|
||||
return BitmapGlyph{ .handle = @ptrCast(c.FT_BitmapGlyph, self.handle) };
|
||||
}
|
||||
|
||||
pub fn copyBitmapGlyph(self: *Glyph, render_mode: RenderMode, origin: ?Vector) Error!BitmapGlyph {
|
||||
try intToError(c.FT_Glyph_To_Bitmap(&self.handle, @enumToInt(render_mode), if (origin) |o| &o else null, 0));
|
||||
return BitmapGlyph{ .handle = @ptrCast(c.FT_BitmapGlyph, self.handle) };
|
||||
}
|
||||
|
||||
pub fn castBitmapGlyph(self: Glyph) Error!BitmapGlyph {
|
||||
return BitmapGlyph{ .handle = @ptrCast(c.FT_BitmapGlyph, self.handle) };
|
||||
}
|
||||
|
||||
pub fn castOutlineGlyph(self: Glyph) Error!OutlineGlyph {
|
||||
return OutlineGlyph{ .handle = @ptrCast(c.FT_OutlineGlyph, self.handle) };
|
||||
}
|
||||
|
||||
pub fn castSvgGlyph(self: Glyph) Error!SvgGlyph {
|
||||
return SvgGlyph{ .handle = @ptrCast(c.FT_SvgGlyph, self.handle) };
|
||||
}
|
||||
|
||||
pub fn stroke(self: *Glyph, stroker: Stroker) Error!void {
|
||||
try intToError(c.FT_Glyph_Stroke(&self.handle, stroker.handle, 0));
|
||||
}
|
||||
|
||||
pub fn strokeBorder(self: *Glyph, stroker: Stroker, inside: bool) Error!void {
|
||||
try intToError(c.FT_Glyph_StrokeBorder(&self.handle, stroker.handle, if (inside) 1 else 0, 0));
|
||||
}
|
||||
|
||||
pub fn format(self: Glyph) GlyphFormat {
|
||||
return @intToEnum(GlyphFormat, self.handle.*.format);
|
||||
}
|
||||
|
||||
pub fn advanceX(self: Glyph) isize {
|
||||
return self.handle.*.advance.x;
|
||||
}
|
||||
|
||||
pub fn advanceY(self: Glyph) isize {
|
||||
return self.handle.*.advance.y;
|
||||
}
|
||||
};
|
||||
|
||||
const SvgGlyph = struct {
|
||||
handle: c.FT_SvgGlyph,
|
||||
|
||||
pub fn deinit(self: SvgGlyph) void {
|
||||
c.FT_Done_Glyph(@ptrCast(c.FT_Glyph, self.handle));
|
||||
}
|
||||
|
||||
pub fn svgBuffer(self: SvgGlyph) []const u8 {
|
||||
return self.handle.*.svg_document[0..self.svgBufferLen()];
|
||||
}
|
||||
|
||||
pub fn svgBufferLen(self: SvgGlyph) u32 {
|
||||
return self.handle.*.svg_document_length;
|
||||
}
|
||||
|
||||
pub fn glyphIndex(self: SvgGlyph) u32 {
|
||||
return self.handle.*.glyph_index;
|
||||
}
|
||||
|
||||
pub fn metrics(self: SvgGlyph) SizeMetrics {
|
||||
return self.handle.*.metrics;
|
||||
}
|
||||
|
||||
pub fn unitsPerEM(self: SvgGlyph) u16 {
|
||||
return self.handle.*.units_per_EM;
|
||||
}
|
||||
|
||||
pub fn startGlyphID(self: SvgGlyph) u16 {
|
||||
return self.handle.*.start_glyph_id;
|
||||
}
|
||||
|
||||
pub fn endGlyphID(self: SvgGlyph) u16 {
|
||||
return self.handle.*.end_glyph_id;
|
||||
}
|
||||
|
||||
pub fn transform(self: SvgGlyph) Matrix {
|
||||
return self.handle.*.transform;
|
||||
}
|
||||
|
||||
pub fn delta(self: SvgGlyph) Vector {
|
||||
return self.handle.*.delta;
|
||||
}
|
||||
};
|
||||
|
||||
pub const BitmapGlyph = struct {
|
||||
handle: c.FT_BitmapGlyph,
|
||||
|
||||
pub fn deinit(self: BitmapGlyph) void {
|
||||
c.FT_Done_Glyph(@ptrCast(c.FT_Glyph, self.handle));
|
||||
}
|
||||
|
||||
pub fn left(self: BitmapGlyph) i32 {
|
||||
return self.handle.*.left;
|
||||
}
|
||||
|
||||
pub fn top(self: BitmapGlyph) i32 {
|
||||
return self.handle.*.top;
|
||||
}
|
||||
|
||||
pub fn bitmap(self: BitmapGlyph) Bitmap {
|
||||
return .{ .handle = self.handle.*.bitmap };
|
||||
}
|
||||
};
|
||||
|
||||
pub const OutlineGlyph = struct {
|
||||
handle: c.FT_OutlineGlyph,
|
||||
|
||||
pub fn deinit(self: OutlineGlyph) void {
|
||||
c.FT_Done_Glyph(@ptrCast(c.FT_Glyph, self.handle));
|
||||
}
|
||||
|
||||
pub fn outline(self: OutlineGlyph) Outline {
|
||||
return .{ .handle = &self.handle.*.outline };
|
||||
}
|
||||
};
|
||||
95
libs/freetype/src/harfbuzz/blob.zig
Normal file
95
libs/freetype/src/harfbuzz/blob.zig
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
|
||||
pub const MemoryMode = enum(u2) {
|
||||
duplicate = c.HB_MEMORY_MODE_DUPLICATE,
|
||||
readonly = c.HB_MEMORY_MODE_READONLY,
|
||||
writable = c.HB_MEMORY_MODE_WRITABLE,
|
||||
readonly_may_make_writable = c.HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
|
||||
};
|
||||
|
||||
pub const Blob = struct {
|
||||
handle: *c.hb_blob_t,
|
||||
|
||||
pub fn init(data: []u8, mode: MemoryMode) ?Blob {
|
||||
return Blob{
|
||||
.handle = c.hb_blob_create_or_fail(&data[0], @intCast(c_uint, data.len), @enumToInt(mode), null, null) orelse return null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initOrEmpty(data: []u8, mode: MemoryMode) Blob {
|
||||
return .{
|
||||
.handle = c.hb_blob_create(&data[0], @intCast(c_uint, data.len), @enumToInt(mode), null, null).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initFromFile(path: [*:0]const u8) ?Blob {
|
||||
return Blob{
|
||||
.handle = c.hb_blob_create_from_file_or_fail(path) orelse return null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initFromFileOrEmpty(path: [*:0]const u8) Blob {
|
||||
return .{
|
||||
.handle = c.hb_blob_create_from_file(path).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initEmpty() Blob {
|
||||
return .{ .handle = c.hb_blob_get_empty().? };
|
||||
}
|
||||
|
||||
pub fn createSubBlobOrEmpty(self: Blob, offset: u32, len: u32) Blob {
|
||||
return .{
|
||||
.handle = c.hb_blob_create_sub_blob(self.handle, offset, len).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn copyWritable(self: Blob) ?Blob {
|
||||
return Blob{
|
||||
.handle = c.hb_blob_copy_writable_or_fail(self.handle) orelse return null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Blob) void {
|
||||
c.hb_blob_destroy(self.handle);
|
||||
}
|
||||
|
||||
pub fn getData(self: Blob, len: ?u32) []const u8 {
|
||||
var l = len;
|
||||
const data = c.hb_blob_get_data(self.handle, if (l) |_| &l.? else null);
|
||||
return if (l) |_|
|
||||
data[0..l.?]
|
||||
else
|
||||
std.mem.sliceTo(data, 0);
|
||||
}
|
||||
|
||||
pub fn getDataWritable(self: Blob, len: ?u32) ?[]const u8 {
|
||||
var l = len;
|
||||
const data = c.hb_blob_get_data(self.handle, if (l) |_| &l.? else null);
|
||||
return if (data == null)
|
||||
null
|
||||
else if (l) |_|
|
||||
data[0..l.?]
|
||||
else
|
||||
std.mem.sliceTo(data, 0);
|
||||
}
|
||||
|
||||
pub fn getLength(self: Blob) u32 {
|
||||
return c.hb_blob_get_length(self.handle);
|
||||
}
|
||||
|
||||
pub fn isImmutable(self: Blob) bool {
|
||||
return c.hb_blob_is_immutable(self.handle) > 0;
|
||||
}
|
||||
|
||||
pub fn makeImmutable(self: Blob) void {
|
||||
c.hb_blob_make_immutable(self.handle);
|
||||
}
|
||||
|
||||
pub fn reference(self: Blob) Blob {
|
||||
return .{
|
||||
.handle = c.hb_blob_reference(self.handle).?,
|
||||
};
|
||||
}
|
||||
};
|
||||
397
libs/freetype/src/harfbuzz/buffer.zig
Normal file
397
libs/freetype/src/harfbuzz/buffer.zig
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
const std = @import("std");
|
||||
const utils = @import("utils");
|
||||
const c = @import("c");
|
||||
const Direction = @import("common.zig").Direction;
|
||||
const Script = @import("common.zig").Script;
|
||||
const Language = @import("common.zig").Language;
|
||||
const Font = @import("font.zig").Font;
|
||||
|
||||
pub const ContentType = enum(u2) {
|
||||
invalid = c.HB_BUFFER_CONTENT_TYPE_INVALID,
|
||||
unicode = c.HB_BUFFER_CONTENT_TYPE_UNICODE,
|
||||
glyphs = c.HB_BUFFER_CONTENT_TYPE_GLYPHS,
|
||||
};
|
||||
|
||||
pub const ClusterLevel = enum(u2) {
|
||||
monotone_graphemes = c.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES,
|
||||
monotone_characters = c.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS,
|
||||
characters = c.HB_BUFFER_CLUSTER_LEVEL_CHARACTERS,
|
||||
};
|
||||
|
||||
pub const SerializeFormat = enum(u31) {
|
||||
text = c.HB_BUFFER_SERIALIZE_FORMAT_TEXT,
|
||||
json = c.HB_BUFFER_SERIALIZE_FORMAT_JSON,
|
||||
invalid = c.HB_BUFFER_SERIALIZE_FORMAT_INVALID,
|
||||
};
|
||||
|
||||
pub const GlyphInfo = extern struct {
|
||||
codepoint: u32,
|
||||
mask: u32,
|
||||
cluster: u32,
|
||||
var1: u32,
|
||||
var2: u32,
|
||||
|
||||
pub fn getFlags(self: GlyphInfo) GlyphFlags {
|
||||
return GlyphFlags.from(hb_glyph_info_get_glyph_flags(&self));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Position = extern struct {
|
||||
x_advance: i32,
|
||||
y_advance: i32,
|
||||
x_offset: i32,
|
||||
y_offset: i32,
|
||||
};
|
||||
|
||||
pub const GlyphFlags = packed struct {
|
||||
unsafe_to_break: bool = false,
|
||||
unsafe_to_concat: bool = false,
|
||||
|
||||
pub const Flag = enum(u2) {
|
||||
unsafe_to_break = c.HB_GLYPH_FLAG_UNSAFE_TO_BREAK,
|
||||
unsafe_to_concat = c.HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_uint) GlyphFlags {
|
||||
return utils.bitFieldsToStruct(GlyphFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: GlyphFlags) c_uint {
|
||||
return utils.structToBitFields(c_uint, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const SegmentProps = struct {
|
||||
direction: Direction,
|
||||
script: Script,
|
||||
language: Language,
|
||||
|
||||
pub fn from(c_struct: c.hb_segment_properties_t) SegmentProps {
|
||||
return .{
|
||||
.direction = @intToEnum(Direction, c_struct.direction),
|
||||
.script = @intToEnum(Script, c_struct.script),
|
||||
.language = Language{ .handle = c_struct.language },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn cast(self: SegmentProps) c.hb_segment_properties_t {
|
||||
return .{
|
||||
.reserved1 = undefined,
|
||||
.reserved2 = undefined,
|
||||
.direction = @enumToInt(self.direction),
|
||||
.script = @enumToInt(self.script),
|
||||
.language = self.language.handle,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn compare(a: SegmentProps, b: SegmentProps) bool {
|
||||
return c.hb_segment_properties_equal(&a.cast(), &b.cast()) > 0;
|
||||
}
|
||||
|
||||
pub fn hash(self: SegmentProps) u32 {
|
||||
return c.hb_segment_properties_hash(&self.cast());
|
||||
}
|
||||
|
||||
pub fn overlay(self: SegmentProps, src: SegmentProps) void {
|
||||
c.hb_segment_properties_overlay(&self.cast(), &src.cast());
|
||||
}
|
||||
};
|
||||
|
||||
pub const SerializeFlags = packed struct {
|
||||
no_clusters: bool = false,
|
||||
no_positions: bool = false,
|
||||
no_glyph_names: bool = false,
|
||||
glyph_extents: bool = false,
|
||||
glyph_flags: bool = false,
|
||||
no_advances: bool = false,
|
||||
|
||||
pub const Flag = enum(u6) {
|
||||
no_clusters = c.HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS,
|
||||
no_positions = c.HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS,
|
||||
no_glyph_names = c.HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES,
|
||||
glyph_extents = c.HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS,
|
||||
glyph_flags = c.HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS,
|
||||
no_advances = c.HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES,
|
||||
};
|
||||
|
||||
pub fn from(bits: u6) SerializeFlags {
|
||||
return utils.bitFieldsToStruct(SerializeFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: SerializeFlags) u6 {
|
||||
return utils.structToBitFields(u6, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const DiffFlags = packed struct {
|
||||
equal: bool = false,
|
||||
content_type_mismatch: bool = false,
|
||||
length_mismatch: bool = false,
|
||||
notdef_present: bool = false,
|
||||
dotted_circle_present: bool = false,
|
||||
codepoint_mismatch: bool = false,
|
||||
cluster_mismatch: bool = false,
|
||||
glyph_flags_mismatch: bool = false,
|
||||
position_mismatch: bool = false,
|
||||
|
||||
pub const Flag = enum(u8) {
|
||||
equal = c.HB_BUFFER_DIFF_FLAG_EQUAL,
|
||||
content_type_mismatch = c.HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH,
|
||||
length_mismatch = c.HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH,
|
||||
notdef_present = c.HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT,
|
||||
dotted_circle_present = c.HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT,
|
||||
codepoint_mismatch = c.HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH,
|
||||
cluster_mismatch = c.HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH,
|
||||
glyph_flags_mismatch = c.HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH,
|
||||
position_mismatch = c.HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_uint) DiffFlags {
|
||||
return utils.bitFieldsToStruct(DiffFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: DiffFlags) c_uint {
|
||||
return utils.structToBitFields(c_uint, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Buffer = struct {
|
||||
pub const Flags = packed struct {
|
||||
bot: bool = false,
|
||||
eot: bool = false,
|
||||
preserve_default_ignorables: bool = false,
|
||||
remove_default_ignorables: bool = false,
|
||||
do_not_insert_dotted_circle: bool = false,
|
||||
verify: bool = false,
|
||||
produce_unsafe_to_concat: bool = false,
|
||||
|
||||
pub const Flag = enum(u7) {
|
||||
bot = c.HB_BUFFER_FLAG_BOT,
|
||||
eot = c.HB_BUFFER_FLAG_EOT,
|
||||
preserve_default_ignorables = c.HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES,
|
||||
remove_default_ignorables = c.HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES,
|
||||
do_not_insert_dotted_circle = c.HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE,
|
||||
verify = c.HB_BUFFER_FLAG_VERIFY,
|
||||
produce_unsafe_to_concat = c.HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_uint) Flags {
|
||||
return utils.bitFieldsToStruct(Flags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: Flags) c_uint {
|
||||
return utils.structToBitFields(c_uint, Flag, self);
|
||||
}
|
||||
};
|
||||
|
||||
handle: *c.hb_buffer_t,
|
||||
|
||||
pub fn init() ?Buffer {
|
||||
var b = c.hb_buffer_create();
|
||||
if (c.hb_buffer_allocation_successful(b) < 1)
|
||||
return null;
|
||||
return Buffer{ .handle = b.? };
|
||||
}
|
||||
|
||||
pub fn initEmpty() Buffer {
|
||||
return .{ .handle = c.hb_buffer_get_empty().? };
|
||||
}
|
||||
|
||||
pub fn initSimilar(self: Buffer) ?Buffer {
|
||||
var b = c.hb_buffer_create_similar(self.handle);
|
||||
if (c.hb_buffer_allocation_successful(b) < 1)
|
||||
return null;
|
||||
return Buffer{ .handle = b.? };
|
||||
}
|
||||
|
||||
pub fn reference(self: Buffer) Buffer {
|
||||
return .{
|
||||
.handle = c.hb_buffer_reference(self.handle).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Buffer) void {
|
||||
c.hb_buffer_destroy(self.handle);
|
||||
}
|
||||
|
||||
pub fn reset(self: Buffer) void {
|
||||
c.hb_buffer_reset(self.handle);
|
||||
}
|
||||
|
||||
pub fn clearContents(self: Buffer) void {
|
||||
c.hb_buffer_clear_contents(self.handle);
|
||||
}
|
||||
|
||||
pub fn preAllocate(self: Buffer, size: u32) error{OutOfMemory}!void {
|
||||
if (c.hb_buffer_pre_allocate(self.handle, size) < 1)
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn allocationSuccessful(self: Buffer) bool {
|
||||
return c.hb_buffer_allocation_successful(self.handle) > 0;
|
||||
}
|
||||
|
||||
pub fn add(self: Buffer, codepoint: u32, cluster: u32) void {
|
||||
c.hb_buffer_add(self.handle, codepoint, cluster);
|
||||
}
|
||||
|
||||
pub fn addCodepoints(self: Buffer, text: []const u32, item_offset: u32, item_length: ?u31) void {
|
||||
c.hb_buffer_add_codepoints(self.handle, &text[0], @intCast(c_int, text.len), item_offset, if (item_length) |l| l else @intCast(c_int, text.len));
|
||||
}
|
||||
|
||||
pub fn addUTF32(self: Buffer, text: []const u32, item_offset: u32, item_length: ?u31) void {
|
||||
c.hb_buffer_add_utf32(self.handle, &text[0], @intCast(c_int, text.len), item_offset, if (item_length) |l| l else @intCast(c_int, text.len));
|
||||
}
|
||||
|
||||
pub fn addUTF16(self: Buffer, text: []const u16, item_offset: u32, item_length: ?u31) void {
|
||||
c.hb_buffer_add_utf16(self.handle, &text[0], @intCast(c_int, text.len), item_offset, if (item_length) |l| l else @intCast(c_int, text.len));
|
||||
}
|
||||
|
||||
pub fn addUTF8(self: Buffer, text: []const u8, item_offset: u32, item_length: ?u31) void {
|
||||
c.hb_buffer_add_utf8(self.handle, &text[0], @intCast(c_int, text.len), item_offset, if (item_length) |l| l else @intCast(c_int, text.len));
|
||||
}
|
||||
|
||||
pub fn addLatin1(self: Buffer, text: []const u8, item_offset: u32, item_length: ?u31) void {
|
||||
c.hb_buffer_add_latin1(self.handle, &text[0], @intCast(c_int, text.len), item_offset, if (item_length) |l| l else @intCast(c_int, text.len));
|
||||
}
|
||||
|
||||
pub fn append(self: Buffer, source: Buffer, start: u32, end: u32) void {
|
||||
c.hb_buffer_append(self.handle, source.handle, start, end);
|
||||
}
|
||||
|
||||
pub fn getContentType(self: Buffer) ContentType {
|
||||
return @intToEnum(ContentType, c.hb_buffer_get_content_type(self.handle));
|
||||
}
|
||||
|
||||
pub fn setContentType(self: Buffer, content_type: ContentType) void {
|
||||
c.hb_buffer_set_content_type(self.handle, @enumToInt(content_type));
|
||||
}
|
||||
|
||||
pub fn getDirection(self: Buffer) Direction {
|
||||
return @intToEnum(Direction, c.hb_buffer_get_direction(self.handle));
|
||||
}
|
||||
|
||||
pub fn setDirection(self: Buffer, direction: Direction) void {
|
||||
c.hb_buffer_set_direction(self.handle, @enumToInt(direction));
|
||||
}
|
||||
|
||||
pub fn getScript(self: Buffer) Script {
|
||||
return @intToEnum(Script, c.hb_buffer_get_script(self.handle));
|
||||
}
|
||||
|
||||
pub fn setScript(self: Buffer, script: Script) void {
|
||||
c.hb_buffer_set_script(self.handle, @enumToInt(script));
|
||||
}
|
||||
|
||||
pub fn getLanguage(self: Buffer) Language {
|
||||
return Language{ .handle = c.hb_buffer_get_language(self.handle) };
|
||||
}
|
||||
|
||||
pub fn setLanguage(self: Buffer, lang: Language) void {
|
||||
c.hb_buffer_set_language(self.handle, lang.handle);
|
||||
}
|
||||
|
||||
pub fn getFlags(self: Buffer) Flags {
|
||||
return Flags.from(c.hb_buffer_get_flags(self.handle));
|
||||
}
|
||||
|
||||
pub fn setFlags(self: Buffer, flags: Flags) void {
|
||||
c.hb_buffer_set_flags(self.handle, flags.cast());
|
||||
}
|
||||
|
||||
pub fn getClusterLevel(self: Buffer) ClusterLevel {
|
||||
return @intToEnum(ClusterLevel, c.hb_buffer_get_cluster_level(self.handle));
|
||||
}
|
||||
|
||||
pub fn setClusterLevel(self: Buffer, level: ClusterLevel) void {
|
||||
c.hb_buffer_set_cluster_level(self.handle, @enumToInt(level));
|
||||
}
|
||||
|
||||
pub fn getLength(self: Buffer) u32 {
|
||||
return c.hb_buffer_get_length(self.handle);
|
||||
}
|
||||
|
||||
pub fn setLength(self: Buffer, new_len: u32) error{OutOfMemory}!void {
|
||||
if (c.hb_buffer_set_length(self.handle, new_len) < 1)
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn getSegmentProps(self: Buffer) SegmentProps {
|
||||
var props: c.hb_segment_properties_t = undefined;
|
||||
c.hb_buffer_get_segment_properties(self.handle, &props);
|
||||
return SegmentProps.from(props);
|
||||
}
|
||||
|
||||
pub fn setSegmentProps(self: Buffer, props: SegmentProps) void {
|
||||
c.hb_buffer_set_segment_properties(self.handle, &props.cast());
|
||||
}
|
||||
|
||||
pub fn guessSegmentProps(self: Buffer) void {
|
||||
c.hb_buffer_guess_segment_properties(self.handle);
|
||||
}
|
||||
|
||||
pub fn getGlyphInfos(self: Buffer) []GlyphInfo {
|
||||
var length: u32 = 0;
|
||||
return hb_buffer_get_glyph_infos(self.handle, &length)[0..length];
|
||||
}
|
||||
|
||||
pub fn getGlyphPositions(self: Buffer) ?[]Position {
|
||||
var length: u32 = 0;
|
||||
return if (hb_buffer_get_glyph_positions(self.handle, &length)) |positions|
|
||||
@ptrCast([*]Position, positions)[0..length]
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn hasPositions(self: Buffer) bool {
|
||||
return c.hb_buffer_has_positions(self.handle) > 0;
|
||||
}
|
||||
|
||||
pub fn getInvisibleGlyph(self: Buffer) u32 {
|
||||
return c.hb_buffer_get_invisible_glyph(self.handle);
|
||||
}
|
||||
|
||||
pub fn setInvisibleGlyph(self: Buffer, codepoint: u32) void {
|
||||
c.hb_buffer_set_invisible_glyph(self.handle, codepoint);
|
||||
}
|
||||
|
||||
pub fn getGlyphNotFound(self: Buffer) u32 {
|
||||
return c.hb_buffer_get_not_found_glyph(self.handle);
|
||||
}
|
||||
|
||||
pub fn setGlyphNotFound(self: Buffer, codepoint: u32) void {
|
||||
c.hb_buffer_set_not_found_glyph(self.handle, codepoint);
|
||||
}
|
||||
|
||||
pub fn getReplacementCodepoint(self: Buffer) u32 {
|
||||
return c.hb_buffer_get_replacement_codepoint(self.handle);
|
||||
}
|
||||
|
||||
pub fn setReplacementCodepoint(self: Buffer, codepoint: u32) void {
|
||||
c.hb_buffer_set_replacement_codepoint(self.handle, codepoint);
|
||||
}
|
||||
|
||||
pub fn normalizeGlyphs(self: Buffer) void {
|
||||
c.hb_buffer_normalize_glyphs(self.handle);
|
||||
}
|
||||
|
||||
pub fn reverse(self: Buffer) void {
|
||||
c.hb_buffer_reverse(self.handle);
|
||||
}
|
||||
|
||||
pub fn reverseRange(self: Buffer, start: u32, end: u32) void {
|
||||
c.hb_buffer_reverse_range(self.handle, start, end);
|
||||
}
|
||||
|
||||
pub fn reverseClusters(self: Buffer) void {
|
||||
c.hb_buffer_reverse_clusters(self.handle);
|
||||
}
|
||||
|
||||
pub fn diff(self: Buffer, ref: Buffer, dottedcircle_glyph: u32, position_fuzz: u32) DiffFlags {
|
||||
return DiffFlags.from(c.hb_buffer_diff(self.handle, ref.handle, dottedcircle_glyph, position_fuzz));
|
||||
}
|
||||
};
|
||||
|
||||
pub extern fn hb_glyph_info_get_glyph_flags(info: [*c]const GlyphInfo) c.hb_glyph_flags_t;
|
||||
pub extern fn hb_buffer_get_glyph_infos(buffer: ?*c.hb_buffer_t, length: [*c]c_uint) [*c]GlyphInfo;
|
||||
pub extern fn hb_buffer_get_glyph_positions(buffer: ?*c.hb_buffer_t, length: [*c]c_uint) [*c]Position;
|
||||
282
libs/freetype/src/harfbuzz/common.zig
Normal file
282
libs/freetype/src/harfbuzz/common.zig
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
|
||||
pub const Direction = enum(u3) {
|
||||
invalid = c.HB_DIRECTION_INVALID,
|
||||
ltr = c.HB_DIRECTION_LTR,
|
||||
rtl = c.HB_DIRECTION_RTL,
|
||||
ttb = c.HB_DIRECTION_TTB,
|
||||
bit = c.HB_DIRECTION_BTT,
|
||||
|
||||
pub fn fromString(str: []const u8) Direction {
|
||||
return @intToEnum(Direction, c.hb_direction_from_string(str.ptr, @intCast(c_int, str.len)));
|
||||
}
|
||||
|
||||
pub fn toString(self: Direction) [:0]const u8 {
|
||||
return std.mem.span(@ptrCast([*:0]const u8, c.hb_direction_to_string(@enumToInt(self))));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Script = enum(u31) {
|
||||
common = c.HB_SCRIPT_COMMON,
|
||||
inherited = c.HB_SCRIPT_INHERITED,
|
||||
unknown = c.HB_SCRIPT_UNKNOWN,
|
||||
arabic = c.HB_SCRIPT_ARABIC,
|
||||
armenian = c.HB_SCRIPT_ARMENIAN,
|
||||
bengali = c.HB_SCRIPT_BENGALI,
|
||||
cyrillic = c.HB_SCRIPT_CYRILLIC,
|
||||
devanagari = c.HB_SCRIPT_DEVANAGARI,
|
||||
georgian = c.HB_SCRIPT_GEORGIAN,
|
||||
greek = c.HB_SCRIPT_GREEK,
|
||||
gujarati = c.HB_SCRIPT_GUJARATI,
|
||||
gurmukhi = c.HB_SCRIPT_GURMUKHI,
|
||||
hangul = c.HB_SCRIPT_HANGUL,
|
||||
han = c.HB_SCRIPT_HAN,
|
||||
hebrew = c.HB_SCRIPT_HEBREW,
|
||||
hiragana = c.HB_SCRIPT_HIRAGANA,
|
||||
kannada = c.HB_SCRIPT_KANNADA,
|
||||
katakana = c.HB_SCRIPT_KATAKANA,
|
||||
lao = c.HB_SCRIPT_LAO,
|
||||
latin = c.HB_SCRIPT_LATIN,
|
||||
malayalam = c.HB_SCRIPT_MALAYALAM,
|
||||
oriya = c.HB_SCRIPT_ORIYA,
|
||||
tamil = c.HB_SCRIPT_TAMIL,
|
||||
telugu = c.HB_SCRIPT_TELUGU,
|
||||
thai = c.HB_SCRIPT_THAI,
|
||||
tibetan = c.HB_SCRIPT_TIBETAN,
|
||||
bopomofo = c.HB_SCRIPT_BOPOMOFO,
|
||||
braille = c.HB_SCRIPT_BRAILLE,
|
||||
canadian_syllabics = c.HB_SCRIPT_CANADIAN_SYLLABICS,
|
||||
cherokee = c.HB_SCRIPT_CHEROKEE,
|
||||
ethiopic = c.HB_SCRIPT_ETHIOPIC,
|
||||
khmer = c.HB_SCRIPT_KHMER,
|
||||
mongolian = c.HB_SCRIPT_MONGOLIAN,
|
||||
myanmar = c.HB_SCRIPT_MYANMAR,
|
||||
ogham = c.HB_SCRIPT_OGHAM,
|
||||
runic = c.HB_SCRIPT_RUNIC,
|
||||
sinhala = c.HB_SCRIPT_SINHALA,
|
||||
syriac = c.HB_SCRIPT_SYRIAC,
|
||||
thaana = c.HB_SCRIPT_THAANA,
|
||||
yi = c.HB_SCRIPT_YI,
|
||||
deseret = c.HB_SCRIPT_DESERET,
|
||||
gothic = c.HB_SCRIPT_GOTHIC,
|
||||
old_italic = c.HB_SCRIPT_OLD_ITALIC,
|
||||
buhid = c.HB_SCRIPT_BUHID,
|
||||
hanunoo = c.HB_SCRIPT_HANUNOO,
|
||||
tagalog = c.HB_SCRIPT_TAGALOG,
|
||||
tagbanwa = c.HB_SCRIPT_TAGBANWA,
|
||||
cypriot = c.HB_SCRIPT_CYPRIOT,
|
||||
limbu = c.HB_SCRIPT_LIMBU,
|
||||
linear_b = c.HB_SCRIPT_LINEAR_B,
|
||||
osmanya = c.HB_SCRIPT_OSMANYA,
|
||||
shavian = c.HB_SCRIPT_SHAVIAN,
|
||||
tai_le = c.HB_SCRIPT_TAI_LE,
|
||||
ugaritic = c.HB_SCRIPT_UGARITIC,
|
||||
buginese = c.HB_SCRIPT_BUGINESE,
|
||||
coptic = c.HB_SCRIPT_COPTIC,
|
||||
glagolitic = c.HB_SCRIPT_GLAGOLITIC,
|
||||
kharoshthi = c.HB_SCRIPT_KHAROSHTHI,
|
||||
new_tai_lue = c.HB_SCRIPT_NEW_TAI_LUE,
|
||||
old_persian = c.HB_SCRIPT_OLD_PERSIAN,
|
||||
syloti_nagri = c.HB_SCRIPT_SYLOTI_NAGRI,
|
||||
tifinagh = c.HB_SCRIPT_TIFINAGH,
|
||||
balinese = c.HB_SCRIPT_BALINESE,
|
||||
cuneiform = c.HB_SCRIPT_CUNEIFORM,
|
||||
nko = c.HB_SCRIPT_NKO,
|
||||
phags_pa = c.HB_SCRIPT_PHAGS_PA,
|
||||
phoenician = c.HB_SCRIPT_PHOENICIAN,
|
||||
carian = c.HB_SCRIPT_CARIAN,
|
||||
cham = c.HB_SCRIPT_CHAM,
|
||||
kayah_li = c.HB_SCRIPT_KAYAH_LI,
|
||||
lepcha = c.HB_SCRIPT_LEPCHA,
|
||||
lycian = c.HB_SCRIPT_LYCIAN,
|
||||
lydian = c.HB_SCRIPT_LYDIAN,
|
||||
ol_chiki = c.HB_SCRIPT_OL_CHIKI,
|
||||
rejang = c.HB_SCRIPT_REJANG,
|
||||
saurashtra = c.HB_SCRIPT_SAURASHTRA,
|
||||
sundanese = c.HB_SCRIPT_SUNDANESE,
|
||||
vai = c.HB_SCRIPT_VAI,
|
||||
avestan = c.HB_SCRIPT_AVESTAN,
|
||||
bamum = c.HB_SCRIPT_BAMUM,
|
||||
egyptian_hieroglyphs = c.HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
|
||||
imperial_aramaic = c.HB_SCRIPT_IMPERIAL_ARAMAIC,
|
||||
inscriptional_pahlavi = c.HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
|
||||
inscriptional_parthian = c.HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
|
||||
javanese = c.HB_SCRIPT_JAVANESE,
|
||||
kaithi = c.HB_SCRIPT_KAITHI,
|
||||
lisu = c.HB_SCRIPT_LISU,
|
||||
meetei_mayek = c.HB_SCRIPT_MEETEI_MAYEK,
|
||||
old_south_arabian = c.HB_SCRIPT_OLD_SOUTH_ARABIAN,
|
||||
old_turkic = c.HB_SCRIPT_OLD_TURKIC,
|
||||
samaritan = c.HB_SCRIPT_SAMARITAN,
|
||||
tai_tham = c.HB_SCRIPT_TAI_THAM,
|
||||
tai_viet = c.HB_SCRIPT_TAI_VIET,
|
||||
batak = c.HB_SCRIPT_BATAK,
|
||||
brahmi = c.HB_SCRIPT_BRAHMI,
|
||||
mandaic = c.HB_SCRIPT_MANDAIC,
|
||||
chakma = c.HB_SCRIPT_CHAKMA,
|
||||
meroitic_cursive = c.HB_SCRIPT_MEROITIC_CURSIVE,
|
||||
meroitic_hieroglyphs = c.HB_SCRIPT_MEROITIC_HIEROGLYPHS,
|
||||
miao = c.HB_SCRIPT_MIAO,
|
||||
sharada = c.HB_SCRIPT_SHARADA,
|
||||
sora_sompeng = c.HB_SCRIPT_SORA_SOMPENG,
|
||||
takri = c.HB_SCRIPT_TAKRI,
|
||||
bassa_vah = c.HB_SCRIPT_BASSA_VAH,
|
||||
caucasian_albanian = c.HB_SCRIPT_CAUCASIAN_ALBANIAN,
|
||||
duployan = c.HB_SCRIPT_DUPLOYAN,
|
||||
elbasan = c.HB_SCRIPT_ELBASAN,
|
||||
grantha = c.HB_SCRIPT_GRANTHA,
|
||||
khojki = c.HB_SCRIPT_KHOJKI,
|
||||
khudawadi = c.HB_SCRIPT_KHUDAWADI,
|
||||
linear_a = c.HB_SCRIPT_LINEAR_A,
|
||||
mahajani = c.HB_SCRIPT_MAHAJANI,
|
||||
manichaean = c.HB_SCRIPT_MANICHAEAN,
|
||||
mende_kikakui = c.HB_SCRIPT_MENDE_KIKAKUI,
|
||||
modi = c.HB_SCRIPT_MODI,
|
||||
mro = c.HB_SCRIPT_MRO,
|
||||
nabataean = c.HB_SCRIPT_NABATAEAN,
|
||||
old_north_arabian = c.HB_SCRIPT_OLD_NORTH_ARABIAN,
|
||||
old_permic = c.HB_SCRIPT_OLD_PERMIC,
|
||||
pahawh_hmong = c.HB_SCRIPT_PAHAWH_HMONG,
|
||||
palmyrene = c.HB_SCRIPT_PALMYRENE,
|
||||
pau_cin_hau = c.HB_SCRIPT_PAU_CIN_HAU,
|
||||
psalter_pahlavi = c.HB_SCRIPT_PSALTER_PAHLAVI,
|
||||
siddham = c.HB_SCRIPT_SIDDHAM,
|
||||
tirhuta = c.HB_SCRIPT_TIRHUTA,
|
||||
warang_citi = c.HB_SCRIPT_WARANG_CITI,
|
||||
ahom = c.HB_SCRIPT_AHOM,
|
||||
anatolian_hieroglyphs = c.HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
|
||||
hatran = c.HB_SCRIPT_HATRAN,
|
||||
multani = c.HB_SCRIPT_MULTANI,
|
||||
old_hungarian = c.HB_SCRIPT_OLD_HUNGARIAN,
|
||||
signwriting = c.HB_SCRIPT_SIGNWRITING,
|
||||
adlam = c.HB_SCRIPT_ADLAM,
|
||||
bhaiksuki = c.HB_SCRIPT_BHAIKSUKI,
|
||||
marchen = c.HB_SCRIPT_MARCHEN,
|
||||
osage = c.HB_SCRIPT_OSAGE,
|
||||
tangut = c.HB_SCRIPT_TANGUT,
|
||||
newa = c.HB_SCRIPT_NEWA,
|
||||
masaram_gondi = c.HB_SCRIPT_MASARAM_GONDI,
|
||||
nushu = c.HB_SCRIPT_NUSHU,
|
||||
soyombo = c.HB_SCRIPT_SOYOMBO,
|
||||
zanabazar_square = c.HB_SCRIPT_ZANABAZAR_SQUARE,
|
||||
dogra = c.HB_SCRIPT_DOGRA,
|
||||
gunjala_gondi = c.HB_SCRIPT_GUNJALA_GONDI,
|
||||
hanifi_rohingya = c.HB_SCRIPT_HANIFI_ROHINGYA,
|
||||
makasar = c.HB_SCRIPT_MAKASAR,
|
||||
medefaidrin = c.HB_SCRIPT_MEDEFAIDRIN,
|
||||
old_sogdian = c.HB_SCRIPT_OLD_SOGDIAN,
|
||||
sogdian = c.HB_SCRIPT_SOGDIAN,
|
||||
elymaic = c.HB_SCRIPT_ELYMAIC,
|
||||
nandinagari = c.HB_SCRIPT_NANDINAGARI,
|
||||
nyiakeng_puachue_hmong = c.HB_SCRIPT_NYIAKENG_PUACHUE_HMONG,
|
||||
wancho = c.HB_SCRIPT_WANCHO,
|
||||
chorasmian = c.HB_SCRIPT_CHORASMIAN,
|
||||
dives_akuru = c.HB_SCRIPT_DIVES_AKURU,
|
||||
khitan_small_script = c.HB_SCRIPT_KHITAN_SMALL_SCRIPT,
|
||||
yezidi = c.HB_SCRIPT_YEZIDI,
|
||||
cypro_minoan = c.HB_SCRIPT_CYPRO_MINOAN,
|
||||
old_uyghur = c.HB_SCRIPT_OLD_UYGHUR,
|
||||
tangsa = c.HB_SCRIPT_TANGSA,
|
||||
toto = c.HB_SCRIPT_TOTO,
|
||||
vithkuqi = c.HB_SCRIPT_VITHKUQI,
|
||||
math = c.HB_SCRIPT_MATH,
|
||||
invalid = c.HB_SCRIPT_INVALID,
|
||||
|
||||
pub fn fromISO15924Tag(tag: Tag) Script {
|
||||
return @intToEnum(Script, c.hb_script_from_iso15924_tag(tag.handle));
|
||||
}
|
||||
|
||||
pub fn fromString(str: []const u8) Script {
|
||||
return @intToEnum(Script, c.hb_script_from_string(str.ptr, @intCast(c_int, str.len)));
|
||||
}
|
||||
|
||||
pub fn toISO15924Tag(self: Script) Tag {
|
||||
return .{ .handle = c.hb_script_to_iso15924_tag(@enumToInt(self)) };
|
||||
}
|
||||
|
||||
pub fn getHorizontalDirection(self: Script) Direction {
|
||||
return @intToEnum(Direction, c.hb_script_get_horizontal_direction(@enumToInt(self)));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Language = struct {
|
||||
handle: c.hb_language_t,
|
||||
|
||||
pub fn fromString(name: []const u8) Language {
|
||||
return .{
|
||||
.handle = c.hb_language_from_string(name.ptr, @intCast(c_int, name.len)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toString(self: Language) [:0]const u8 {
|
||||
return std.mem.span(@ptrCast([*:0]const u8, c.hb_language_to_string(self.handle)));
|
||||
}
|
||||
|
||||
pub fn getDefault() Language {
|
||||
return .{ .handle = c.hb_language_get_default() };
|
||||
}
|
||||
};
|
||||
|
||||
pub const Feature = extern struct {
|
||||
tag: c.hb_tag_t,
|
||||
value: u32,
|
||||
start: c_uint,
|
||||
end: c_uint,
|
||||
|
||||
pub fn fromString(str: []const u8) ?Feature {
|
||||
var f: Feature = undefined;
|
||||
return if (hb_feature_from_string(str.ptr, @intCast(c_int, str.len), &f) > 1)
|
||||
f
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn toString(self: *Feature, buf: []u8) void {
|
||||
hb_feature_to_string(self, buf.ptr, @intCast(c_uint, buf.len));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Variation = extern struct {
|
||||
tag: u32,
|
||||
value: f32,
|
||||
|
||||
pub fn fromString(str: []const u8) ?Variation {
|
||||
var v: Variation = undefined;
|
||||
return if (hb_variation_from_string(str.ptr, @intCast(c_int, str.len), &v) > 1)
|
||||
v
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn toString(self: *Variation, buf: []u8) void {
|
||||
hb_variation_to_string(self, buf.ptr, @intCast(c_uint, buf.len));
|
||||
}
|
||||
|
||||
pub fn tag(self: Variation) Tag {
|
||||
return .{ .handle = self.tag };
|
||||
}
|
||||
|
||||
pub fn value(self: Variation) f32 {
|
||||
return self.value;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Tag = struct {
|
||||
handle: u32,
|
||||
|
||||
pub fn fromString(str: []const u8) Tag {
|
||||
return .{ .handle = c.hb_tag_from_string(str.ptr, @intCast(c_int, str.len)) };
|
||||
}
|
||||
|
||||
pub fn toString(self: Tag) []const u8 {
|
||||
var str: [4]u8 = undefined;
|
||||
c.hb_tag_to_string(self.handle, &str[0]);
|
||||
return &str;
|
||||
}
|
||||
};
|
||||
|
||||
pub extern fn hb_feature_from_string(str: [*c]const u8, len: c_int, feature: [*c]Feature) u8;
|
||||
pub extern fn hb_feature_to_string(feature: [*c]Feature, buf: [*c]u8, size: c_uint) void;
|
||||
pub extern fn hb_variation_from_string(str: [*c]const u8, len: c_int, variation: [*c]Variation) u8;
|
||||
pub extern fn hb_variation_to_string(variation: [*c]Variation, buf: [*c]u8, size: c_uint) void;
|
||||
80
libs/freetype/src/harfbuzz/face.zig
Normal file
80
libs/freetype/src/harfbuzz/face.zig
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
const freetype = @import("freetype");
|
||||
const c = @import("c");
|
||||
const Blob = @import("blob.zig").Blob;
|
||||
|
||||
pub const UnicodeIterator = struct {
|
||||
set: *c.hb_set_t,
|
||||
prev_codepoint: u32 = 0,
|
||||
|
||||
pub fn next(self: *UnicodeIterator) ?u32 {
|
||||
var codepoint: u32 = c.HB_SET_VALUE_INVALID;
|
||||
return if (c.hb_set_next(self.set, &codepoint) > 1) b: {
|
||||
self.prev_codepoint = codepoint;
|
||||
break :b codepoint;
|
||||
} else null;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Face = struct {
|
||||
handle: *c.hb_face_t,
|
||||
|
||||
pub fn init(blob: Blob, index: u16) Face {
|
||||
return .{ .handle = c.hb_face_create(blob.handle, index).? };
|
||||
}
|
||||
|
||||
pub fn fromFtFace(face: freetype.Face) Face {
|
||||
return .{ .handle = c.hb_ft_face_create_referenced(face.handle).? };
|
||||
}
|
||||
|
||||
pub fn initEmpty() Face {
|
||||
return .{ .handle = c.hb_face_get_empty().? };
|
||||
}
|
||||
|
||||
pub fn getCount(blob: Blob) u32 {
|
||||
return c.hb_face_count(blob.handle);
|
||||
}
|
||||
|
||||
pub fn deinit(self: Face) void {
|
||||
c.hb_face_destroy(self.handle);
|
||||
}
|
||||
|
||||
pub fn getGlyphcount(self: Face) u32 {
|
||||
return c.hb_face_get_glyph_count(self.handle);
|
||||
}
|
||||
|
||||
pub fn setGlyphcount(self: Face, count: u32) void {
|
||||
return c.hb_face_set_glyph_count(self.handle, count);
|
||||
}
|
||||
|
||||
pub fn getUnitsPerEM(self: Face) u32 {
|
||||
return c.hb_face_get_upem(self.handle);
|
||||
}
|
||||
|
||||
pub fn setUnitsPerEM(self: Face, upem: u32) void {
|
||||
return c.hb_face_set_upem(self.handle, upem);
|
||||
}
|
||||
|
||||
pub fn setIndex(self: Face, index: u32) void {
|
||||
return c.hb_face_set_index(self.handle, index);
|
||||
}
|
||||
|
||||
pub fn isImmutable(self: Face) bool {
|
||||
return c.hb_face_is_immutable(self.handle) > 0;
|
||||
}
|
||||
|
||||
pub fn makeImmutable(self: Face) void {
|
||||
c.hb_face_make_immutable(self.handle);
|
||||
}
|
||||
|
||||
pub fn reference(self: Face) Face {
|
||||
return .{
|
||||
.handle = c.hb_face_reference(self.handle).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn collectUnicodes(self: Face) UnicodeIterator {
|
||||
var set: *c.hb_set_t = undefined;
|
||||
c.hb_face_collect_unicodes(self.handle, set);
|
||||
return .{ .set = set };
|
||||
}
|
||||
};
|
||||
100
libs/freetype/src/harfbuzz/font.zig
Normal file
100
libs/freetype/src/harfbuzz/font.zig
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
const freetype = @import("freetype");
|
||||
const c = @import("c");
|
||||
const Face = @import("face.zig").Face;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const Feature = @import("common.zig").Feature;
|
||||
const SegmentProps = @import("buffer.zig").SegmentProps;
|
||||
|
||||
pub const Font = struct {
|
||||
handle: *c.hb_font_t,
|
||||
|
||||
pub fn init(face: Face) Font {
|
||||
return .{ .handle = c.hb_font_create(face.handle).? };
|
||||
}
|
||||
|
||||
pub fn fromFtFace(face: freetype.Face) Font {
|
||||
return .{ .handle = c.hb_ft_font_create_referenced(face.handle).? };
|
||||
}
|
||||
|
||||
pub fn createSubFont(self: Font) Font {
|
||||
return .{
|
||||
.handle = c.hb_font_create_sub_font(self.handle).?,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Font) void {
|
||||
c.hb_font_destroy(self.handle);
|
||||
}
|
||||
|
||||
pub fn ftFaceChanged(self: Font) void {
|
||||
c.hb_ft_font_changed(self.handle);
|
||||
}
|
||||
|
||||
pub fn setFtLoadFlags(self: Font, flags: freetype.LoadFlags) void {
|
||||
c.hb_ft_font_set_load_flags(self.handle, flags.cast());
|
||||
}
|
||||
|
||||
pub fn getFace(self: Font) Face {
|
||||
return .{ .handle = c.hb_font_get_face(self.handle).? };
|
||||
}
|
||||
|
||||
pub fn getFreetypeFace(self: Font) freetype.Face {
|
||||
return .{ .handle = c.hb_ft_font_get_face(self.handle) };
|
||||
}
|
||||
|
||||
pub fn getGlyph(self: Font, unicode: u32, variation_selector: u32) ?u32 {
|
||||
var g: u32 = 0;
|
||||
return if (c.hb_font_get_glyph(self.handle, unicode, variation_selector, &g) > 0)
|
||||
g
|
||||
else
|
||||
null;
|
||||
}
|
||||
|
||||
pub fn getParent(self: Font) ?Font {
|
||||
return Font{ .handle = c.hb_font_get_parent(self.handle) orelse return null };
|
||||
}
|
||||
|
||||
pub fn getPPEM(self: Font) @Vector(2, u32) {
|
||||
var x: u32 = 0;
|
||||
var y: u32 = 0;
|
||||
c.hb_font_get_ppem(self.handle, &@intCast(c_uint, x), &@intCast(c_uint, y));
|
||||
return @Vector(2, u32){ x, y };
|
||||
}
|
||||
|
||||
pub fn getPTEM(self: Font) f32 {
|
||||
return c.hb_font_get_ptem(self.handle);
|
||||
}
|
||||
|
||||
pub fn getScale(self: Font) @Vector(2, u32) {
|
||||
var x: u32 = 0;
|
||||
var y: u32 = 0;
|
||||
c.hb_font_get_scale(self.handle, &@intCast(c_int, x), &@intCast(c_int, y));
|
||||
return @Vector(2, u32){ x, y };
|
||||
}
|
||||
|
||||
pub fn setFace(self: Font, face: Face) void {
|
||||
return c.hb_font_set_face(self.handle, face.handle);
|
||||
}
|
||||
|
||||
pub fn shape(self: Font, buf: Buffer, features: ?[]const Feature) void {
|
||||
hb_shape(
|
||||
self.handle,
|
||||
buf.handle,
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn shapeFull(self: Font, buf: Buffer, features: ?[]const Feature, shapers: []const []const u8) error{ShapingFailed}!void {
|
||||
if (hb_shape_full(
|
||||
self.handle,
|
||||
buf.handle,
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
@ptrCast([*c]const [*c]const u8, shapers),
|
||||
) < 1) return error.ShapingFailed;
|
||||
}
|
||||
};
|
||||
|
||||
pub extern fn hb_shape(font: ?*c.hb_font_t, buffer: ?*c.hb_buffer_t, features: [*c]const Feature, num_features: c_uint) void;
|
||||
pub extern fn hb_shape_full(font: ?*c.hb_font_t, buffer: ?*c.hb_buffer_t, features: [*c]const Feature, num_features: c_uint, shaper_list: [*c]const [*c]const u8) u8;
|
||||
14
libs/freetype/src/harfbuzz/main.zig
Normal file
14
libs/freetype/src/harfbuzz/main.zig
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
pub usingnamespace @import("blob.zig");
|
||||
pub usingnamespace @import("buffer.zig");
|
||||
pub usingnamespace @import("common.zig");
|
||||
pub usingnamespace @import("face.zig");
|
||||
pub usingnamespace @import("font.zig");
|
||||
pub usingnamespace @import("shape.zig");
|
||||
pub usingnamespace @import("shape_plan.zig");
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
// Remove once the stage2 compiler fixes pkg std not found
|
||||
comptime {
|
||||
_ = @import("utils");
|
||||
}
|
||||
19
libs/freetype/src/harfbuzz/shape.zig
Normal file
19
libs/freetype/src/harfbuzz/shape.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
|
||||
pub const ListShapers = struct {
|
||||
index: usize,
|
||||
list: [*c][*c]const u8,
|
||||
|
||||
pub fn init() ListShapers {
|
||||
return .{ .index = 0, .list = c.hb_shape_list_shapers() };
|
||||
}
|
||||
|
||||
pub fn next(self: *ListShapers) ?[:0]const u8 {
|
||||
self.index += 1;
|
||||
return std.mem.span(@ptrCast(
|
||||
?[*:0]const u8,
|
||||
self.list[self.index - 1] orelse return null,
|
||||
));
|
||||
}
|
||||
};
|
||||
79
libs/freetype/src/harfbuzz/shape_plan.zig
Normal file
79
libs/freetype/src/harfbuzz/shape_plan.zig
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const Font = @import("font.zig").Font;
|
||||
const Face = @import("face.zig").Face;
|
||||
const SegmentProps = @import("buffer.zig").SegmentProps;
|
||||
const Feature = @import("common.zig").Feature;
|
||||
|
||||
pub const ShapePlan = struct {
|
||||
handle: *c.hb_shape_plan_t,
|
||||
|
||||
pub fn init(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan {
|
||||
return .{ .handle = hb_shape_plan_create(
|
||||
face.handle,
|
||||
&props.cast(),
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
@ptrCast([*c]const [*c]const u8, shapers),
|
||||
).? };
|
||||
}
|
||||
|
||||
pub fn initCached(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan {
|
||||
return .{ .handle = hb_shape_plan_create_cached(
|
||||
face.handle,
|
||||
&props.cast(),
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
@ptrCast([*c]const [*c]const u8, shapers),
|
||||
).? };
|
||||
}
|
||||
|
||||
pub fn init2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan {
|
||||
return .{ .handle = hb_shape_plan_create2(
|
||||
face.handle,
|
||||
&props.cast(),
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
cords.ptr,
|
||||
@intCast(c_uint, cords.len),
|
||||
@ptrCast([*c]const [*c]const u8, shapers),
|
||||
).? };
|
||||
}
|
||||
|
||||
pub fn initCached2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan {
|
||||
return .{ .handle = hb_shape_plan_create_cached2(
|
||||
face.handle,
|
||||
&props.cast(),
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
cords.ptr,
|
||||
@intCast(c_uint, cords.len),
|
||||
@ptrCast([*c]const [*c]const u8, shapers),
|
||||
).? };
|
||||
}
|
||||
|
||||
pub fn deinit(self: ShapePlan) void {
|
||||
c.hb_shape_plan_destroy(self.handle);
|
||||
}
|
||||
|
||||
pub fn execute(self: ShapePlan, font: Font, buffer: Buffer, features: ?[]Feature) error{ShapingFailed}!void {
|
||||
if (hb_shape_plan_execute(
|
||||
self.handle,
|
||||
font.handle,
|
||||
buffer.handle,
|
||||
if (features) |f| f.ptr else null,
|
||||
if (features) |f| @intCast(c_uint, f.len) else 0,
|
||||
) < 1) return error.ShapingFailed;
|
||||
}
|
||||
|
||||
pub fn getShaper(self: ShapePlan) [:0]const u8 {
|
||||
return std.mem.span(@ptrCast([*:0]const u8, c.hb_shape_plan_get_shaper(self.handle)));
|
||||
}
|
||||
};
|
||||
|
||||
pub extern fn hb_shape_plan_create(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t;
|
||||
pub extern fn hb_shape_plan_create_cached(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t;
|
||||
pub extern fn hb_shape_plan_create2(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, coords: [*c]const c_int, num_coords: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t;
|
||||
pub extern fn hb_shape_plan_create_cached2(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, coords: [*c]const c_int, num_coords: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t;
|
||||
pub extern fn hb_shape_plan_execute(shape_plan: ?*c.hb_shape_plan_t, font: ?*c.hb_font_t, buffer: ?*c.hb_buffer_t, features: [*c]const Feature, num_features: c_uint) u8;
|
||||
309
libs/freetype/src/image.zig
Normal file
309
libs/freetype/src/image.zig
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
const utils = @import("utils.zig");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const errorToInt = @import("error.zig").errorToInt;
|
||||
const Error = @import("error.zig").Error;
|
||||
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;
|
||||
pub const RasterParams = c.FT_Raster_Params_;
|
||||
|
||||
pub const PixelMode = enum(u3) {
|
||||
none = c.FT_PIXEL_MODE_NONE,
|
||||
mono = c.FT_PIXEL_MODE_MONO,
|
||||
gray = c.FT_PIXEL_MODE_GRAY,
|
||||
gray2 = c.FT_PIXEL_MODE_GRAY2,
|
||||
gray4 = c.FT_PIXEL_MODE_GRAY4,
|
||||
lcd = c.FT_PIXEL_MODE_LCD,
|
||||
lcd_v = c.FT_PIXEL_MODE_LCD_V,
|
||||
bgra = c.FT_PIXEL_MODE_BGRA,
|
||||
};
|
||||
|
||||
pub const GlyphFormat = enum(u32) {
|
||||
none = c.FT_GLYPH_FORMAT_NONE,
|
||||
composite = c.FT_GLYPH_FORMAT_COMPOSITE,
|
||||
bitmap = c.FT_GLYPH_FORMAT_BITMAP,
|
||||
outline = c.FT_GLYPH_FORMAT_OUTLINE,
|
||||
plotter = c.FT_GLYPH_FORMAT_PLOTTER,
|
||||
svg = c.FT_GLYPH_FORMAT_SVG,
|
||||
};
|
||||
|
||||
pub const Bitmap = struct {
|
||||
handle: c.FT_Bitmap,
|
||||
|
||||
pub fn init() Bitmap {
|
||||
var b: c.FT_Bitmap = undefined;
|
||||
c.FT_Bitmap_Init(&b);
|
||||
return .{ .handle = b };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Bitmap, lib: Library) void {
|
||||
_ = c.FT_Bitmap_Done(lib.handle, &self.handle);
|
||||
}
|
||||
|
||||
pub fn copy(self: Bitmap, lib: Library) Error!Bitmap {
|
||||
var b: c.FT_Bitmap = undefined;
|
||||
try intToError(c.FT_Bitmap_Copy(lib.handle, &self.handle, &b));
|
||||
return Bitmap{ .handle = b };
|
||||
}
|
||||
|
||||
pub fn embolden(self: *Bitmap, lib: Library, x_strength: i32, y_strength: i32) Error!void {
|
||||
try intToError(c.FT_Bitmap_Embolden(lib.handle, &self.handle, x_strength, y_strength));
|
||||
}
|
||||
|
||||
pub fn convert(self: Bitmap, lib: Library, alignment: u29) Error!Bitmap {
|
||||
var b: c.FT_Bitmap = undefined;
|
||||
try intToError(c.FT_Bitmap_Convert(lib.handle, &self.handle, &b, alignment));
|
||||
return Bitmap{ .handle = b };
|
||||
}
|
||||
|
||||
pub fn blend(self: *Bitmap, lib: Library, source_offset: Vector, target_offset: *Vector, color: Color) Error!void {
|
||||
var b: c.FT_Bitmap = undefined;
|
||||
c.FT_Bitmap_Init(&b);
|
||||
try intToError(c.FT_Bitmap_Blend(lib.handle, &self.handle, source_offset, &b, target_offset, color));
|
||||
}
|
||||
|
||||
pub fn width(self: Bitmap) u32 {
|
||||
return self.handle.width;
|
||||
}
|
||||
|
||||
pub fn pitch(self: Bitmap) i32 {
|
||||
return self.handle.pitch;
|
||||
}
|
||||
|
||||
pub fn rows(self: Bitmap) u32 {
|
||||
return self.handle.rows;
|
||||
}
|
||||
|
||||
pub fn pixelMode(self: Bitmap) PixelMode {
|
||||
return @intToEnum(PixelMode, self.handle.pixel_mode);
|
||||
}
|
||||
|
||||
pub fn buffer(self: Bitmap) ?[]const u8 {
|
||||
const buffer_size = std.math.absCast(self.pitch()) * self.rows();
|
||||
return if (self.handle.buffer == null)
|
||||
// freetype returns a null pointer for zero-length allocations
|
||||
// https://github.com/hexops/freetype/blob/bbd80a52b7b749140ec87d24b6c767c5063be356/freetype/src/base/ftutil.c#L135
|
||||
null
|
||||
else
|
||||
self.handle.buffer[0..buffer_size];
|
||||
}
|
||||
};
|
||||
|
||||
pub const Outline = struct {
|
||||
pub const Orientation = enum(u2) {
|
||||
truetype = c.FT_ORIENTATION_TRUETYPE,
|
||||
postscript = c.FT_ORIENTATION_POSTSCRIPT,
|
||||
none = c.FT_ORIENTATION_NONE,
|
||||
};
|
||||
|
||||
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 flags(self: Outline) OutlineFlags {
|
||||
return OutlineFlags.from(self.handle.*.flags);
|
||||
}
|
||||
|
||||
pub fn copy(self: Outline) Error!Outline {
|
||||
var o: c.FT_Outline = undefined;
|
||||
try intToError(c.FT_Outline_Copy(self.handle, &o));
|
||||
return Outline{ .handle = &o };
|
||||
}
|
||||
|
||||
pub fn translate(self: Outline, x_offset: i32, y_offset: i32) void {
|
||||
c.FT_Outline_Translate(self.handle, x_offset, y_offset);
|
||||
}
|
||||
|
||||
pub fn transform(self: Outline, matrix: ?Matrix) void {
|
||||
c.FT_Outline_Transform(self.handle, if (matrix) |m| &m else null);
|
||||
}
|
||||
|
||||
pub fn embolden(self: Outline, strength: i32) Error!void {
|
||||
try intToError(c.FT_Outline_Embolden(self.handle, strength));
|
||||
}
|
||||
|
||||
pub fn emboldenXY(self: Outline, x_strength: i32, y_strength: i32) Error!void {
|
||||
try intToError(c.FT_Outline_EmboldenXY(self.handle, x_strength, y_strength));
|
||||
}
|
||||
|
||||
pub fn reverse(self: Outline) void {
|
||||
c.FT_Outline_Reverse(self.handle);
|
||||
}
|
||||
|
||||
pub fn check(self: Outline) Error!void {
|
||||
try intToError(c.FT_Outline_Check(self.handle));
|
||||
}
|
||||
|
||||
pub fn cbox(self: Outline) BBox {
|
||||
var b: BBox = undefined;
|
||||
c.FT_Outline_Get_CBox(self.handle, &b);
|
||||
return b;
|
||||
}
|
||||
|
||||
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 orientation(self: Outline) Orientation {
|
||||
return @intToEnum(Orientation, c.FT_Outline_Get_Orientation(self.handle));
|
||||
}
|
||||
|
||||
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 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,
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
pub const OutlineFlags = packed struct {
|
||||
none: bool = false,
|
||||
owner: bool = false,
|
||||
even_odd_fill: bool = false,
|
||||
reverse_fill: bool = false,
|
||||
ignore_dropouts: bool = false,
|
||||
smart_dropouts: bool = false,
|
||||
include_stubs: bool = false,
|
||||
overlap: bool = false,
|
||||
high_precision: bool = false,
|
||||
single_pass: bool = false,
|
||||
|
||||
pub const Flag = enum(u21) {
|
||||
none = c.FT_OUTLINE_NONE,
|
||||
owner = c.FT_OUTLINE_OWNER,
|
||||
even_odd_fill = c.FT_OUTLINE_EVEN_ODD_FILL,
|
||||
reverse_fill = c.FT_OUTLINE_REVERSE_FILL,
|
||||
ignore_dropouts = c.FT_OUTLINE_IGNORE_DROPOUTS,
|
||||
smart_dropouts = c.FT_OUTLINE_SMART_DROPOUTS,
|
||||
include_stubs = c.FT_OUTLINE_INCLUDE_STUBS,
|
||||
overlap = c.FT_OUTLINE_OVERLAP,
|
||||
high_precision = c.FT_OUTLINE_HIGH_PRECISION,
|
||||
single_pass = c.FT_OUTLINE_SINGLE_PASS,
|
||||
};
|
||||
|
||||
pub fn from(bits: c_int) OutlineFlags {
|
||||
return utils.bitFieldsToStruct(OutlineFlags, Flag, bits);
|
||||
}
|
||||
|
||||
pub fn cast(self: OutlineFlags) c_int {
|
||||
return utils.structToBitFields(c_int, Flag, self);
|
||||
}
|
||||
};
|
||||
8
libs/freetype/src/lcdfilter.zig
Normal file
8
libs/freetype/src/lcdfilter.zig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
const c = @import("c");
|
||||
|
||||
pub const LcdFilter = enum(u5) {
|
||||
none = c.FT_LCD_FILTER_NONE,
|
||||
default = c.FT_LCD_FILTER_DEFAULT,
|
||||
light = c.FT_LCD_FILTER_LIGHT,
|
||||
legacy = c.FT_LCD_FILTER_LEGACY,
|
||||
};
|
||||
106
libs/freetype/src/main.zig
Normal file
106
libs/freetype/src/main.zig
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
pub usingnamespace @import("color.zig");
|
||||
pub usingnamespace @import("freetype.zig");
|
||||
pub usingnamespace @import("glyph.zig");
|
||||
pub usingnamespace @import("image.zig");
|
||||
pub usingnamespace @import("lcdfilter.zig");
|
||||
pub usingnamespace @import("stroke.zig");
|
||||
pub usingnamespace @import("types.zig");
|
||||
pub usingnamespace @import("computations.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 {
|
||||
_ = @import("utils");
|
||||
}
|
||||
|
||||
test {
|
||||
std.testing.refAllDeclsRecursive(@import("color.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("error.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("freetype.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("glyph.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("image.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("lcdfilter.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("stroke.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("types.zig"));
|
||||
std.testing.refAllDeclsRecursive(@import("computations.zig"));
|
||||
std.testing.refAllDeclsRecursive(harfbuzz);
|
||||
}
|
||||
|
||||
const firasans_font_path = thisDir() ++ "/../upstream/assets/FiraSans-Regular.ttf";
|
||||
const firasans_font_data = @embedFile(thisDir() ++ "/../upstream/assets/FiraSans-Regular.ttf");
|
||||
|
||||
fn thisDir() []const u8 {
|
||||
return std.fs.path.dirname(@src().file) orelse ".";
|
||||
}
|
||||
|
||||
test "create face from file" {
|
||||
const lib = try ft.Library.init();
|
||||
_ = try lib.createFace(firasans_font_path, 0);
|
||||
}
|
||||
|
||||
test "create face from memory" {
|
||||
const lib = try ft.Library.init();
|
||||
_ = try lib.createFaceMemory(firasans_font_data, 0);
|
||||
}
|
||||
|
||||
test "create stroker" {
|
||||
const lib = try ft.Library.init();
|
||||
_ = try lib.createStroker();
|
||||
}
|
||||
|
||||
test "load glyph" {
|
||||
const lib = try ft.Library.init();
|
||||
const face = try lib.createFace(firasans_font_path, 0);
|
||||
|
||||
try face.setPixelSizes(100, 100);
|
||||
try face.setCharSize(10 * 10, 0, 72, 0);
|
||||
|
||||
try face.loadGlyph(205, .{});
|
||||
try face.loadChar('A', .{});
|
||||
|
||||
face.deinit();
|
||||
}
|
||||
|
||||
test "attach file" {
|
||||
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 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 ft.Library.init();
|
||||
const face = try lib.createFace(firasans_font_path, 0);
|
||||
var iterator = face.iterateCharmap();
|
||||
var old_char: u32 = 0;
|
||||
while (iterator.next()) |char| {
|
||||
try testing.expect(old_char != char);
|
||||
old_char = char;
|
||||
}
|
||||
}
|
||||
|
||||
test "get name index" {
|
||||
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 ft.Library.init();
|
||||
const face = try lib.createFace(firasans_font_path, 0);
|
||||
var buf: [32]u8 = undefined;
|
||||
try face.getGlyphName(1120, &buf);
|
||||
try testing.expectEqualStrings(std.mem.sliceTo(&buf, 0), "summation");
|
||||
}
|
||||
88
libs/freetype/src/stroke.zig
Normal file
88
libs/freetype/src/stroke.zig
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
const c = @import("c");
|
||||
const intToError = @import("error.zig").intToError;
|
||||
const Error = @import("error.zig").Error;
|
||||
const Outline = @import("image.zig").Outline;
|
||||
const Vector = @import("image.zig").Vector;
|
||||
|
||||
pub const LineCap = enum(u2) {
|
||||
butt = c.FT_STROKER_LINECAP_BUTT,
|
||||
round = c.FT_STROKER_LINECAP_ROUND,
|
||||
square = c.FT_STROKER_LINECAP_SQUARE,
|
||||
};
|
||||
|
||||
pub const LineJoin = enum(u2) {
|
||||
round = c.FT_STROKER_LINEJOIN_ROUND,
|
||||
bevel = c.FT_STROKER_LINEJOIN_BEVEL,
|
||||
miter_variable = c.FT_STROKER_LINEJOIN_MITER_VARIABLE,
|
||||
miter_fixed = c.FT_STROKER_LINEJOIN_MITER_FIXED,
|
||||
};
|
||||
|
||||
pub const Stroker = struct {
|
||||
pub const Border = enum(u1) {
|
||||
left,
|
||||
right,
|
||||
};
|
||||
|
||||
pub const BorderCounts = struct {
|
||||
points: u32,
|
||||
contours: u32,
|
||||
};
|
||||
|
||||
handle: c.FT_Stroker,
|
||||
|
||||
pub fn set(self: Stroker, radius: i32, line_cap: LineCap, line_join: LineJoin, miter_limit: i32) void {
|
||||
c.FT_Stroker_Set(self.handle, radius, @enumToInt(line_cap), @enumToInt(line_join), miter_limit);
|
||||
}
|
||||
|
||||
pub fn rewind(self: Stroker) void {
|
||||
c.FT_Stroker_Rewind(self.handle);
|
||||
}
|
||||
|
||||
pub fn parseOutline(self: Stroker, outline: Outline, opened: bool) Error!void {
|
||||
try intToError(c.FT_Stroker_ParseOutline(self.handle, outline.handle, if (opened) 1 else 0));
|
||||
}
|
||||
|
||||
pub fn beginSubPath(self: Stroker, to: *Vector, open: bool) Error!void {
|
||||
try intToError(c.FT_Stroker_BeginSubPath(self.handle, to, if (open) 1 else 0));
|
||||
}
|
||||
|
||||
pub fn endSubPath(self: Stroker) Error!void {
|
||||
try intToError(c.FT_Stroker_EndSubPath(self.handle));
|
||||
}
|
||||
|
||||
pub fn lineTo(self: Stroker, to: *Vector) Error!void {
|
||||
try intToError(c.FT_Stroker_LineTo(self.handle, to));
|
||||
}
|
||||
|
||||
pub fn conicTo(self: Stroker, control: *Vector, to: *Vector) Error!void {
|
||||
try intToError(c.FT_Stroker_ConicTo(self.handle, control, to));
|
||||
}
|
||||
|
||||
pub fn cubicTo(self: Stroker, control_0: *Vector, control_1: *Vector, to: *Vector) Error!void {
|
||||
try intToError(c.FT_Stroker_CubicTo(self.handle, control_0, control_1, to));
|
||||
}
|
||||
|
||||
pub fn getBorderCounts(self: Stroker, border: Border) Error!BorderCounts {
|
||||
var counts: BorderCounts = undefined;
|
||||
try intToError(c.FT_Stroker_GetBorderCounts(self.handle, @enumToInt(border), &counts.points, &counts.contours));
|
||||
return counts;
|
||||
}
|
||||
|
||||
pub fn exportBorder(self: Stroker, border: Border, outline: *Outline) void {
|
||||
c.FT_Stroker_ExportBorder(self.handle, @enumToInt(border), outline.handle);
|
||||
}
|
||||
|
||||
pub fn getCounts(self: Stroker) Error!BorderCounts {
|
||||
var counts: BorderCounts = undefined;
|
||||
try intToError(c.FT_Stroker_GetCounts(self.handle, &counts.points, &counts.contours));
|
||||
return counts;
|
||||
}
|
||||
|
||||
pub fn exportAll(self: Stroker, outline: *Outline) void {
|
||||
c.FT_Stroker_Export(self.handle, outline.handle);
|
||||
}
|
||||
|
||||
pub fn deinit(self: Stroker) void {
|
||||
c.FT_Stroker_Done(self.handle);
|
||||
}
|
||||
};
|
||||
5
libs/freetype/src/types.zig
Normal file
5
libs/freetype/src/types.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const c = @import("c");
|
||||
|
||||
pub const Matrix = c.FT_Matrix;
|
||||
pub const Generic = c.FT_Generic;
|
||||
pub const BBox = c.FT_BBox;
|
||||
21
libs/freetype/src/utils.zig
Normal file
21
libs/freetype/src/utils.zig
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn structToBitFields(comptime IntType: type, comptime EnumDataType: type, flags: anytype) IntType {
|
||||
var value: IntType = 0;
|
||||
inline for (comptime std.meta.fieldNames(EnumDataType)) |field_name| {
|
||||
if (@field(flags, field_name)) {
|
||||
value |= @enumToInt(@field(EnumDataType, field_name));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
pub fn bitFieldsToStruct(comptime StructType: type, comptime EnumDataType: type, flags: anytype) StructType {
|
||||
var value = std.mem.zeroes(StructType);
|
||||
inline for (comptime std.meta.fieldNames(EnumDataType)) |field_name| {
|
||||
if (flags & (@enumToInt(@field(EnumDataType, field_name))) != 0) {
|
||||
@field(value, field_name) = true;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue