pkg/harfbuzz: buffer init, add

This commit is contained in:
Mitchell Hashimoto
2022-08-28 11:42:57 -07:00
parent 5d42e2711f
commit 3c077ee19b
2 changed files with 165 additions and 0 deletions

164
pkg/harfbuzz/buffer.zig Normal file
View File

@ -0,0 +1,164 @@
const std = @import("std");
const c = @import("c.zig");
const Error = @import("errors.zig").Error;
/// Buffers serve a dual role in HarfBuzz; before shaping, they hold the
/// input characters that are passed to hb_shape(), and after shaping they
/// hold the output glyphs.
pub const Buffer = struct {
handle: *c.hb_buffer_t,
/// Creates a new hb_buffer_t with all properties to defaults.
pub fn create() Error!Buffer {
const handle = c.hb_buffer_create() orelse return Error.HarfbuzzFailed;
return Buffer{ .handle = handle };
}
/// Deallocate the buffer . Decreases the reference count on buffer by one.
/// If the result is zero, then buffer and all associated resources are
/// freed. See hb_buffer_reference().
pub fn destroy(self: *Buffer) void {
c.hb_buffer_destroy(self.handle);
}
/// Resets the buffer to its initial status, as if it was just newly
/// created with hb_buffer_create().
pub fn reset(self: Buffer) void {
c.hb_buffer_reset(self.handle);
}
/// Sets the type of buffer contents. Buffers are either empty, contain
/// characters (before shaping), or contain glyphs (the result of shaping).
pub fn setContentType(self: Buffer, ct: ContentType) void {
c.hb_buffer_set_content_type(self.handle, @enumToInt(ct));
}
/// Fetches the type of buffer contents. Buffers are either empty, contain
/// characters (before shaping), or contain glyphs (the result of shaping).
pub fn getContentType(self: Buffer) ContentType {
return @intToEnum(ContentType, c.hb_buffer_get_content_type(self.handle));
}
/// Appends a character with the Unicode value of codepoint to buffer,
/// and gives it the initial cluster value of cluster . Clusters can be
/// any thing the client wants, they are usually used to refer to the
/// index of the character in the input text stream and are output in
/// hb_glyph_info_t.cluster field.
///
/// This function does not check the validity of codepoint, it is up to
/// the caller to ensure it is a valid Unicode code point.
pub fn add(self: Buffer, cp: u32, cluster: u32) void {
c.hb_buffer_add(self.handle, cp, cluster);
}
/// Appends characters from text array to buffer . The item_offset is the
/// position of the first character from text that will be appended, and
/// item_length is the number of character. When shaping part of a larger
/// text (e.g. a run of text from a paragraph), instead of passing just
/// the substring corresponding to the run, it is preferable to pass the
/// whole paragraph and specify the run start and length as item_offset and
/// item_length , respectively, to give HarfBuzz the full context to be
/// able, for example, to do cross-run Arabic shaping or properly handle
/// combining marks at stat of run.
///
/// This function does not check the validity of text , it is up to the
/// caller to ensure it contains a valid Unicode code points.
pub fn addCodepoints(self: Buffer, text: []const u32) void {
c.hb_buffer_add_codepoints(
self.handle,
text.ptr,
@intCast(c_int, text.len),
0,
@intCast(c_int, text.len),
);
}
/// See hb_buffer_add_codepoints().
///
/// Replaces invalid UTF-32 characters with the buffer replacement code
/// point, see hb_buffer_set_replacement_codepoint().
pub fn addUTF32(self: Buffer, text: []const u32) void {
c.hb_buffer_add_utf32(
self.handle,
text.ptr,
@intCast(c_int, text.len),
0,
@intCast(c_int, text.len),
);
}
/// See hb_buffer_add_codepoints().
///
/// Replaces invalid UTF-16 characters with the buffer replacement code
/// point, see hb_buffer_set_replacement_codepoint().
pub fn addUTF16(self: Buffer, text: []const u16) void {
c.hb_buffer_add_utf16(
self.handle,
text.ptr,
@intCast(c_int, text.len),
0,
@intCast(c_int, text.len),
);
}
/// See hb_buffer_add_codepoints().
///
/// Replaces invalid UTF-8 characters with the buffer replacement code
/// point, see hb_buffer_set_replacement_codepoint().
pub fn addUTF8(self: Buffer, text: []const u8) void {
c.hb_buffer_add_utf8(
self.handle,
text.ptr,
@intCast(c_int, text.len),
0,
@intCast(c_int, text.len),
);
}
/// Similar to hb_buffer_add_codepoints(), but allows only access to first
/// 256 Unicode code points that can fit in 8-bit strings.
pub fn addLatin1(self: Buffer, text: []const u8) void {
c.hb_buffer_add_latin1(
self.handle,
text.ptr,
@intCast(c_int, text.len),
0,
@intCast(c_int, text.len),
);
}
};
/// The type of hb_buffer_t contents.
pub const ContentType = enum(u2) {
/// Initial value for new buffer.
invalid = c.HB_BUFFER_CONTENT_TYPE_INVALID,
/// The buffer contains input characters (before shaping).
unicode = c.HB_BUFFER_CONTENT_TYPE_UNICODE,
/// The buffer contains output glyphs (after shaping).
glyphs = c.HB_BUFFER_CONTENT_TYPE_GLYPHS,
};
test "create" {
const testing = std.testing;
var buffer = try Buffer.create();
defer buffer.destroy();
buffer.reset();
// Content type
buffer.setContentType(.unicode);
try testing.expectEqual(ContentType.unicode, buffer.getContentType());
// Try add functions
buffer.add('🥹', 27);
var utf32 = [_]u32{ 'A', 'B', 'C' };
var utf16 = [_]u16{ 'A', 'B', 'C' };
var utf8 = [_]u8{ 'A', 'B', 'C' };
buffer.addCodepoints(&utf32);
buffer.addUTF32(&utf32);
buffer.addUTF16(&utf16);
buffer.addUTF8(&utf8);
buffer.addLatin1(&utf8);
}

View File

@ -1,5 +1,6 @@
pub const c = @import("c.zig");
pub usingnamespace @import("blob.zig");
pub usingnamespace @import("buffer.zig");
pub usingnamespace @import("errors.zig");
pub usingnamespace @import("face.zig");
pub usingnamespace @import("font.zig");