mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
230 lines
8.5 KiB
Zig
230 lines
8.5 KiB
Zig
const std = @import("std");
|
|
const c = @import("c.zig");
|
|
const common = @import("common.zig");
|
|
const Error = @import("errors.zig").Error;
|
|
const Direction = common.Direction;
|
|
const Script = common.Script;
|
|
const Language = common.Language;
|
|
|
|
/// 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),
|
|
);
|
|
}
|
|
|
|
/// Set the text flow direction of the buffer. No shaping can happen
|
|
/// without setting buffer direction, and it controls the visual direction
|
|
/// for the output glyphs; for RTL direction the glyphs will be reversed.
|
|
/// Many layout features depend on the proper setting of the direction,
|
|
/// for example, reversing RTL text before shaping, then shaping with LTR
|
|
/// direction is not the same as keeping the text in logical order and
|
|
/// shaping with RTL direction.
|
|
pub fn setDirection(self: Buffer, dir: Direction) void {
|
|
c.hb_buffer_set_direction(self.handle, @enumToInt(dir));
|
|
}
|
|
|
|
/// See hb_buffer_set_direction()
|
|
pub fn getDirection(self: Buffer) Direction {
|
|
return @intToEnum(Direction, c.hb_buffer_get_direction(self.handle));
|
|
}
|
|
|
|
/// Sets the script of buffer to script.
|
|
///
|
|
/// Script is crucial for choosing the proper shaping behaviour for
|
|
/// scripts that require it (e.g. Arabic) and the which OpenType features
|
|
/// defined in the font to be applied.
|
|
///
|
|
/// You can pass one of the predefined hb_script_t values, or use
|
|
/// hb_script_from_string() or hb_script_from_iso15924_tag() to get the
|
|
/// corresponding script from an ISO 15924 script tag.
|
|
pub fn setScript(self: Buffer, script: Script) void {
|
|
c.hb_buffer_set_script(self.handle, @enumToInt(script));
|
|
}
|
|
|
|
/// See hb_buffer_set_script()
|
|
pub fn getScript(self: Buffer) Script {
|
|
return @intToEnum(Script, c.hb_buffer_get_script(self.handle));
|
|
}
|
|
|
|
/// Sets the language of buffer to language .
|
|
///
|
|
/// Languages are crucial for selecting which OpenType feature to apply to
|
|
/// the buffer which can result in applying language-specific behaviour.
|
|
/// Languages are orthogonal to the scripts, and though they are related,
|
|
/// they are different concepts and should not be confused with each other.
|
|
///
|
|
/// Use hb_language_from_string() to convert from BCP 47 language tags to
|
|
/// hb_language_t.
|
|
pub fn setLanguage(self: Buffer, language: Language) void {
|
|
c.hb_buffer_set_language(self.handle, language.handle);
|
|
}
|
|
|
|
/// See hb_buffer_set_language()
|
|
pub fn getLanguage(self: Buffer) Language {
|
|
return Language{ .handle = c.hb_buffer_get_language(self.handle) };
|
|
}
|
|
};
|
|
|
|
/// 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);
|
|
|
|
// Try to set properties
|
|
buffer.setDirection(.ltr);
|
|
try testing.expectEqual(Direction.ltr, buffer.getDirection());
|
|
|
|
buffer.setScript(.arabic);
|
|
try testing.expectEqual(Script.arabic, buffer.getScript());
|
|
|
|
buffer.setLanguage(Language.fromString("en"));
|
|
}
|