Skip to documentation
SLOP

tiny.ui.text.segment

Reference tiny.ui text segment

Defined in text.

API (2)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstextsegment
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callstest sourcelib.ui.src.text.segmenttest: empty text has one mandatory en...test sourcelib.ui.src.text.segmenttest: line boundaries follow selected...test sourcelib.ui.src.text.segmenttest: line boundaries never split a c...text.segmentboundaries
Static calls · unresolved targets: 0 · external targets: 4.

Source: lib/ui/src/text/root.zig:7

zig
pub const segment = @import("segment.zig");

Source: lib/ui/src/text/segment.zig

zig
const std = @import("std");const unicode = @import("unicode");pub const Boundary = struct {    byte_offset: u32,    action: unicode.LineBreakAction,};const Case = struct {    text: []const u8,    actions: []const unicode.LineBreakAction,};pub fn boundaries(    text: []const u8,    output: []Boundary,) error{ OutputTooSmall, TextTooLong }![]Boundary {    if (text.len > std.math.maxInt(u32)) return error.TextTooLong;    std.debug.assert(std.unicode.utf8ValidateSlice(text));    var graphemes = unicode.GraphemeIterator.init(text);    var line: unicode.LineBreakState = .{};    var count: usize = 0;    while (graphemes.next()) |cluster| {        std.debug.assert(cluster.valid_utf8);        var cursor: usize = 0;        var action: unicode.LineBreakAction = .prohibited;        while (cursor < cluster.text.len) {            const len = std.unicode.utf8ByteSequenceLength(cluster.text[cursor]) catch unreachable;            const codepoint = std.unicode.utf8Decode(cluster.text[cursor..][0..len]) catch unreachable;            const next = line.consume(codepoint);            if (cursor == 0) action = next;            cursor += len;        }        if (count >= output.len) return error.OutputTooSmall;        output[count] = .{ .byte_offset = @intCast(cluster.start), .action = action };        count += 1;    }    if (count >= output.len) return error.OutputTooSmall;    output[count] = .{ .byte_offset = @intCast(text.len), .action = line.finish() };    return output[0 .. count + 1];}test "line boundaries follow selected Unicode 17 conformance cases" {    const cases = [_]Case{        .{ .text = "❗ ❗", .actions = &.{ .prohibited, .prohibited, .opportunity, .mandatory } },        .{ .text = "❗\u{0308}❗", .actions = &.{ .prohibited, .prohibited, .mandatory } },        .{            .text = "❗\u{200b}❗",            .actions = &.{ .prohibited, .prohibited, .opportunity, .mandatory },        },        .{ .text = "🇦🇦🇦🇦", .actions = &.{ .prohibited, .opportunity, .mandatory } },        .{ .text = "a b", .actions = &.{ .prohibited, .prohibited, .opportunity, .mandatory } },    };    for (cases) |case| {        var output: [16]Boundary = undefined;        const found = try boundaries(case.text, &output);        try std.testing.expectEqual(case.actions.len, found.len);        for (found, case.actions) |actual, expected| {            try std.testing.expectEqual(expected, actual.action);        }    }}test "line boundaries never split a combining grapheme" {    var output: [4]Boundary = undefined;    const found = try boundaries("a\u{0308}b", &output);    try std.testing.expectEqual(@as(usize, 3), found.len);    try std.testing.expectEqual(@as(u32, 0), found[0].byte_offset);    try std.testing.expectEqual(@as(u32, 3), found[1].byte_offset);    try std.testing.expectEqual(@as(u32, 4), found[2].byte_offset);}test "empty text has one mandatory end boundary" {    var output: [1]Boundary = undefined;    const found = try boundaries("", &output);    try std.testing.expectEqual(@as(usize, 1), found.len);    try std.testing.expectEqual(@as(u32, 0), found[0].byte_offset);    try std.testing.expectEqual(unicode.LineBreakAction.mandatory, found[0].action);}

Audit

Definitions3
Public names3
Members2
Version26.7.0
Revisiondaab053ee433