mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 07:46:12 +03:00
Merge pull request #2147 from ghostty-org/ft-italic
freetype: synthetic italic
This commit is contained in:
@ -14,6 +14,11 @@ pub const Face = struct {
|
||||
_ = c.FT_Done_Face(self.handle);
|
||||
}
|
||||
|
||||
/// Increment the counter of the face.
|
||||
pub fn ref(self: Face) void {
|
||||
_ = c.FT_Reference_Face(self.handle);
|
||||
}
|
||||
|
||||
/// A macro that returns true whenever a face object contains some
|
||||
/// embedded bitmaps. See the available_sizes field of the FT_FaceRec structure.
|
||||
pub fn hasFixedSizes(self: Face) bool {
|
||||
@ -170,6 +175,20 @@ pub const Face = struct {
|
||||
);
|
||||
return intToError(res);
|
||||
}
|
||||
|
||||
/// Set the transformation that is applied to glyph images when they are
|
||||
/// loaded into a glyph slot through FT_Load_Glyph.
|
||||
pub fn setTransform(
|
||||
self: Face,
|
||||
matrix: ?*const c.FT_Matrix,
|
||||
delta: ?*const c.FT_Vector,
|
||||
) void {
|
||||
c.FT_Set_Transform(
|
||||
self.handle,
|
||||
@constCast(@ptrCast(matrix)),
|
||||
@constCast(@ptrCast(delta)),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/// An enumeration to specify indices of SFNT tables loaded and parsed by
|
||||
|
@ -37,6 +37,17 @@ pub const Face = struct {
|
||||
/// Set quirks.disableDefaultFontFeatures
|
||||
quirks_disable_default_font_features: bool = false,
|
||||
|
||||
/// Set to true to apply a synthetic italic to the face.
|
||||
synthetic_italic: bool = false,
|
||||
|
||||
/// The matrix applied to a regular font to create a synthetic italic.
|
||||
const italic_matrix: freetype.c.FT_Matrix = .{
|
||||
.xx = 0x10000,
|
||||
.xy = 0x044ED, // approx. tan(15)
|
||||
.yx = 0,
|
||||
.yy = 0x10000,
|
||||
};
|
||||
|
||||
/// Initialize a new font face with the given source in-memory.
|
||||
pub fn initFile(lib: Library, path: [:0]const u8, index: i32, opts: font.face.Options) !Face {
|
||||
const face = try lib.lib.initFace(path, index);
|
||||
@ -119,6 +130,24 @@ pub const Face = struct {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Return a new face that is the same as this but has a transformation
|
||||
/// matrix applied to italicize it.
|
||||
pub fn syntheticItalic(self: *const Face, opts: font.face.Options) !Face {
|
||||
// Increase face ref count
|
||||
self.face.ref();
|
||||
errdefer self.face.deinit();
|
||||
|
||||
var f = try initFace(
|
||||
.{ .lib = self.lib },
|
||||
self.face,
|
||||
opts,
|
||||
);
|
||||
errdefer f.deinit();
|
||||
f.synthetic_italic = true;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
/// Resize the font in-place. If this succeeds, the caller is responsible
|
||||
/// for clearing any glyph caches, font atlas data, etc.
|
||||
pub fn setSize(self: *Face, opts: font.face.Options) !void {
|
||||
@ -246,6 +275,12 @@ pub const Face = struct {
|
||||
) !Glyph {
|
||||
const metrics = opts.grid_metrics orelse self.metrics;
|
||||
|
||||
// If we have synthetic italic, then we apply a transformation matrix.
|
||||
// We have to undo this because synthetic italic works by increasing
|
||||
// the ref count of the base face.
|
||||
if (self.synthetic_italic) self.face.setTransform(&italic_matrix, null);
|
||||
defer if (self.synthetic_italic) self.face.setTransform(null, null);
|
||||
|
||||
// If our glyph has color, we want to render the color
|
||||
try self.face.loadGlyph(glyph_index, .{
|
||||
.render = true,
|
||||
@ -265,7 +300,7 @@ pub const Face = struct {
|
||||
|
||||
// This bitmap is blank. I've seen it happen in a font, I don't know why.
|
||||
// If it is empty, we just return a valid glyph struct that does nothing.
|
||||
if (bitmap_ft.rows == 0) return Glyph{
|
||||
if (bitmap_ft.rows == 0) return .{
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.offset_x = 0,
|
||||
|
Reference in New Issue
Block a user