DVUI

textSizeEx

textSizeEx always stops at a newline, use textSize to get multiline sizes

Only valid between Window.beginand Window.end.

Parameters

#
self:Font
Font
text:[]const u8
[]const u8
opts:TextSizeOptions
TextSizeOptions

Source

Implementation

#
pub fn textSizeEx(self: Font, text: []const u8, opts: TextSizeOptions) Size {
    // ask for a font that matches the natural display pixels so we get a more
    // accurate size
    const ss = dvui.parentGet().screenRectScale(Rect{}).s;
    const ask_size = self.size * ss;

    // set some reasonable defaults in case things go bad
    if (opts.ascent_out) |ao| ao.* = 10;
    if (opts.end_idx) |endout| endout.* = text.len;
    if (ask_size == 0.0) {
        // early out here so we don't try to divide by zero later
        if (opts.ascent_out) |ao| ao.* = 0;
        return Size{};
    }

    const sized_font = self.withSize(ask_size);

    const cw = dvui.currentWindow();

    // might give us a slightly smaller font
    const fce = dvui.fontCacheGet(sized_font) catch return .{ .w = 10, .h = 10 };

    // this must be synced with dvui.renderText()
    const target_fraction = if (cw.snap_to_pixels) 1.0 / ss else self.size / fce.em_height;

    var options = opts;
    if (opts.max_width) |mwidth| {
        // convert max_width into font units
        options.max_width = mwidth / target_fraction;
    }
    options.kerning = opts.kerning orelse cw.kerning;

    var s = fce.textSizeRaw(cw.gpa, text, options) catch return .{ .w = 10, .h = 10 };

    if (opts.ascent_out) |ao| {
        ao.* = fce.ascent;
        if (self.line_height_factor < 1.0) {
            ao.* = @round(ao.* * self.line_height_factor);
        }
        ao.* *= target_fraction;
    }

    // convert size back from font units
    return s.scale(target_fraction, Size);
}