diff --git a/src/font/Collection.zig b/src/font/Collection.zig index cdbd3d84f..1d85d8a28 100644 --- a/src/font/Collection.zig +++ b/src/font/Collection.zig @@ -129,7 +129,6 @@ pub const AdjustSizeError = font.Face.GetMetricsError; // // This returns null if load options is null or if self.load_options is null. // -// // This is very much like the `font-size-adjust` CSS property in how it works. // ref: https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust // @@ -199,8 +198,10 @@ pub fn adjustedSize( primary_ex / face_ex, ); - // Make a copy of our load options and multiply the size by our scale. + // Make a copy of our load options, set the size to the size of + // the provided face, and then multiply that by our scaling factor. var opts = load_options; + opts.size = face.size; opts.size.points *= @as(f32, @floatCast(scale)); return opts; @@ -1089,3 +1090,62 @@ test "metrics" { .cursor_height = 34, }, c.metrics); } + +// TODO: Also test CJK fallback sizing, we don't currently have a CJK test font. +test "adjusted sizes" { + const testing = std.testing; + const alloc = testing.allocator; + const testFont = font.embedded.inconsolata; + const fallback = font.embedded.monaspace_neon; + + var lib = try Library.init(alloc); + defer lib.deinit(); + + var c = init(); + defer c.deinit(alloc); + const size: DesiredSize = .{ .points = 12, .xdpi = 96, .ydpi = 96 }; + c.load_options = .{ .library = lib, .size = size }; + + // Add our primary face. + _ = try c.add(alloc, .regular, .{ .loaded = try .init( + lib, + testFont, + .{ .size = size }, + ) }); + + try c.updateMetrics(); + + // Add the fallback face. + const fallback_idx = try c.add(alloc, .regular, .{ .loaded = try .init( + lib, + fallback, + .{ .size = size }, + ) }); + + // The ex heights should match. + { + const primary_metrics = try (try c.getFace(.{ .idx = 0 })).getMetrics(); + const fallback_metrics = try (try c.getFace(fallback_idx)).getMetrics(); + + try std.testing.expectApproxEqAbs( + primary_metrics.ex_height.?, + fallback_metrics.ex_height.?, + // We accept anything within half a pixel. + 0.5, + ); + } + + // Resize should keep that relationship. + try c.setSize(.{ .points = 37, .xdpi = 96, .ydpi = 96 }); + { + const primary_metrics = try (try c.getFace(.{ .idx = 0 })).getMetrics(); + const fallback_metrics = try (try c.getFace(fallback_idx)).getMetrics(); + + try std.testing.expectApproxEqAbs( + primary_metrics.ex_height.?, + fallback_metrics.ex_height.?, + // We accept anything within half a pixel. + 0.5, + ); + } +} diff --git a/src/font/face/coretext.zig b/src/font/face/coretext.zig index c1f16e025..00cc31b26 100644 --- a/src/font/face/coretext.zig +++ b/src/font/face/coretext.zig @@ -31,6 +31,9 @@ pub const Face = struct { /// tables). color: ?ColorState = null, + /// The current size this font is set to. + size: font.face.DesiredSize, + /// True if our build is using Harfbuzz. If we're not, we can avoid /// some Harfbuzz-specific code paths. const harfbuzz_shaper = font.options.backend.hasHarfbuzz(); @@ -106,6 +109,7 @@ pub const Face = struct { .font = ct_font, .hb_font = hb_font, .color = color, + .size = opts.size, }; result.quirks_disable_default_font_features = quirks.disableDefaultFontFeatures(&result); diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index db5a3622e..ae3bd0968 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -59,6 +59,9 @@ pub const Face = struct { bold: bool = false, } = .{}, + /// The current size this font is set to. + size: font.face.DesiredSize, + /// Initialize a new font face with the given source in-memory. pub fn initFile( lib: Library, @@ -107,6 +110,7 @@ pub const Face = struct { .hb_font = hb_font, .ft_mutex = ft_mutex, .load_flags = opts.freetype_load_flags, + .size = opts.size, }; result.quirks_disable_default_font_features = quirks.disableDefaultFontFeatures(&result); @@ -203,6 +207,7 @@ pub const Face = struct { /// for clearing any glyph caches, font atlas data, etc. pub fn setSize(self: *Face, opts: font.face.Options) !void { try setSize_(self.face, opts.size); + self.size = opts.size; } fn setSize_(face: freetype.Face, size: font.face.DesiredSize) !void {