<commit_before>package vectorx.font;

import types.Vector2;
import types.Color4F;
import vectorx.font.StringAttributes;
import types.Range;

class AttributedSpan
{
    public var range(default, null): AttributedRange = new AttributedRange();
    public var font: Font = null;
    public var backgroundColor: Color4F = null;
    public var foregroundColor: Color4F = null;
    public var baselineOffset:  Null<Float>;
    public var kern: Null<Float> = null;
    public var size: Null<Int>;
    public var strokeWidth: Null<Float> = null;
    public var strokeColor: Color4F = null;
    public var shadow: FontShadow = null;
    public var attachment: FontAttachment = null;
    public var attachmentId: String = null;
    public var extraLineSpacing: Null<Float> = null;

    public var baseString(default, null): String;
    public var string(default, null): String;
    public var bboxHeight: Float;

    private var measure: Vector2 = new Vector2();
    private var measured: Bool = false;

    private var id(default, null): Int;

    private static var nextId: Int = 0;

    public function setFromSpan(other: AttributedSpan)
    {
        this.range.index = other.range.index;
        this.range.length = other.range.length;
        this.font = other.font;
        this.backgroundColor = other.backgroundColor;
        this.foregroundColor = other.foregroundColor;
        this.baselineOffset = other.baselineOffset;
        this.kern = other.kern;
        this.strokeWidth = other.strokeWidth;
        this.strokeColor = other.strokeColor;
        this.shadow = other.shadow;
        this.attachment = other.attachment;
        this.attachmentId = other.attachmentId;
        this.baseString = other.baseString;
        this.string = other.string;
        this.size = other.size;
        this.extraLineSpacing = other.extraLineSpacing;
        this.measured = false;
    }

    public function new(string: String, index: Int = 0, len: Int = 0)
    {
        this.range.index = index;
        this.range.length = len;

        if (this.range.length == -1)
        {
            this.range.length = string.length;
        }

        id = nextId++;

        baseString = string;
        updateString();
    }

    public function updateString()
    {
        this.string = baseString.substr(range.index, range.length);
    }

    public function toString(): String
    {
        //return '{id: $id, range: ${range.index}[${range.length}] str: $string font: $font backgroud: $backgroundColor measure: {x: ${measure.x} y: ${measure.y}} attachment: $attachment}';
        return '{id: $id, range: ${range.index}[${range.length}] str: $string font: $font attachment: $attachmentId}';
    }

    private inline function choose<T>(dst: T, src: T)
    {<commit_msg>fixed crash on unicode symbols<commit_after>package vectorx.font;

import haxe.Utf8;
import types.Vector2;
import types.Color4F;
import vectorx.font.StringAttributes;
import types.Range;

class AttributedSpan
{
    public var range(default, null): AttributedRange = new AttributedRange();
    public var font: Font = null;
    public var backgroundColor: Color4F = null;
    public var foregroundColor: Color4F = null;
    public var baselineOffset:  Null<Float>;
    public var kern: Null<Float> = null;
    public var size: Null<Int>;
    public var strokeWidth: Null<Float> = null;
    public var strokeColor: Color4F = null;
    public var shadow: FontShadow = null;
    public var attachment: FontAttachment = null;
    public var attachmentId: String = null;
    public var extraLineSpacing: Null<Float> = null;

    public var baseString(default, null): String;
    public var string(default, null): String;
    public var bboxHeight: Float;

    private var measure: Vector2 = new Vector2();
    private var measured: Bool = false;

    private var id(default, null): Int;

    private static var nextId: Int = 0;

    public function setFromSpan(other: AttributedSpan)
    {
        this.range.index = other.range.index;
        this.range.length = other.range.length;
        this.font = other.font;
        this.backgroundColor = other.backgroundColor;
        this.foregroundColor = other.foregroundColor;
        this.baselineOffset = other.baselineOffset;
        this.kern = other.kern;
        this.strokeWidth = other.strokeWidth;
        this.strokeColor = other.strokeColor;
        this.shadow = other.shadow;
        this.attachment = other.attachment;
        this.attachmentId = other.attachmentId;
        this.baseString = other.baseString;
        this.string = other.string;
        this.size = other.size;
        this.extraLineSpacing = other.extraLineSpacing;
        this.measured = false;
    }

    public function new(string: String, index: Int = 0, len: Int = 0)
    {
        this.range.index = index;
        this.range.length = len;

        if (this.range.length == -1)
        {
            this.range.length = string.length;
        }

        id = nextId++;

        baseString = string;
        updateString();
    }

    public function updateString()
    {
        this.string = Utf8.sub(baseString, range.index, range.length);
    }

    public function toString(): String
    {
        //return '{id: $id, range: ${range.index}[${range.length}] str: $string font: $font backgroud: $backgroundColor measure: {x: ${measure.x} y: ${measure.y}} attachment: $attachment}';
        return '{id: $id, range: ${range.index}[${range.length}] str: $string font: $font attachment: $attachmentId}';
    }

    private inline function choose<T>(dst: T, src: T)
    {
{'fraction_non_alphanumeric': 0.11057173678532901, 'fraction_numerical': 0.004314994606256742, 'mean_word_length': 2.8181194234728895, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2862167', 'n_tokens_mistral': 1630, 'n_tokens_neox': 1579, 'n_words': 449}