Base accessibility API.

This commit is contained in:
Pāvels Nadtočajevs
2025-03-21 16:42:23 +02:00
parent af2c713971
commit b106dfd4f9
124 changed files with 7631 additions and 181 deletions
+220
View File
@@ -4210,6 +4210,8 @@ void TextServerAdvanced::invalidate(TextServerAdvanced::ShapedTextDataAdvanced *
p_shaped->uthk = 0.0;
p_shaped->glyphs.clear();
p_shaped->glyphs_logical.clear();
p_shaped->runs.clear();
p_shaped->runs_dirty = true;
p_shaped->overrun_trim_data = TrimData();
p_shaped->utf16 = Char16String();
for (int i = 0; i < p_shaped->bidi_iter.size(); i++) {
@@ -4492,6 +4494,213 @@ Variant TextServerAdvanced::_shaped_get_span_embedded_object(const RID &p_shaped
}
}
String TextServerAdvanced::_shaped_get_span_text(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, String());
ShapedTextDataAdvanced *span_sd = sd;
if (sd->parent.is_valid()) {
span_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_NULL_V(span_sd, String());
}
ERR_FAIL_INDEX_V(p_index, span_sd->spans.size(), String());
return span_sd->text.substr(span_sd->spans[p_index].start, span_sd->spans[p_index].end - span_sd->spans[p_index].start);
}
Variant TextServerAdvanced::_shaped_get_span_object(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Variant());
ShapedTextDataAdvanced *span_sd = sd;
if (sd->parent.is_valid()) {
span_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_NULL_V(span_sd, Variant());
}
ERR_FAIL_INDEX_V(p_index, span_sd->spans.size(), Variant());
return span_sd->spans[p_index].embedded_key;
}
void TextServerAdvanced::_generate_runs(ShapedTextDataAdvanced *p_sd) const {
ERR_FAIL_NULL(p_sd);
p_sd->runs.clear();
ShapedTextDataAdvanced *span_sd = p_sd;
if (p_sd->parent.is_valid()) {
span_sd = shaped_owner.get_or_null(p_sd->parent);
ERR_FAIL_NULL(span_sd);
}
int sd_size = p_sd->glyphs.size();
const Glyph *sd_gl = p_sd->glyphs.ptr();
int span_count = span_sd->spans.size();
int span = -1;
int span_start = -1;
int span_end = -1;
TextRun run;
for (int i = 0; i < sd_size; i += sd_gl[i].count) {
const Glyph &gl = sd_gl[i];
if (gl.start < 0 || gl.end < 0) {
continue;
}
if (gl.start < span_start || gl.start >= span_end) {
span = -1;
span_start = -1;
span_end = -1;
for (int j = 0; j < span_count; j++) {
if (gl.start >= span_sd->spans[j].start && gl.end <= span_sd->spans[j].end) {
span = j;
span_start = span_sd->spans[j].start;
span_end = span_sd->spans[j].end;
break;
}
}
}
if (run.font_rid != gl.font_rid || run.font_size != gl.font_size || run.span_index != span || run.rtl != bool(gl.flags & GRAPHEME_IS_RTL)) {
if (run.span_index >= 0) {
p_sd->runs.push_back(run);
}
run.range = Vector2i(gl.start, gl.end);
run.font_rid = gl.font_rid;
run.font_size = gl.font_size;
run.rtl = bool(gl.flags & GRAPHEME_IS_RTL);
run.span_index = span;
}
run.range.x = MIN(run.range.x, gl.start);
run.range.y = MAX(run.range.y, gl.end);
}
if (run.span_index >= 0) {
p_sd->runs.push_back(run);
}
p_sd->runs_dirty = false;
}
int64_t TextServerAdvanced::_shaped_get_run_count(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
return sd->runs.size();
}
String TextServerAdvanced::_shaped_get_run_text(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, String());
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), String());
return sd->text.substr(sd->runs[p_index].range.x - sd->start, sd->runs[p_index].range.y - sd->runs[p_index].range.x);
}
Vector2i TextServerAdvanced::_shaped_get_run_range(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Vector2i());
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), Vector2i());
return sd->runs[p_index].range;
}
RID TextServerAdvanced::_shaped_get_run_font_rid(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, RID());
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), RID());
return sd->runs[p_index].font_rid;
}
int TextServerAdvanced::_shaped_get_run_font_size(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), 0);
return sd->runs[p_index].font_size;
}
String TextServerAdvanced::_shaped_get_run_language(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, String());
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), String());
int span_idx = sd->runs[p_index].span_index;
ShapedTextDataAdvanced *span_sd = sd;
if (sd->parent.is_valid()) {
span_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_NULL_V(span_sd, String());
}
ERR_FAIL_INDEX_V(span_idx, span_sd->spans.size(), String());
return span_sd->spans[span_idx].language;
}
TextServer::Direction TextServerAdvanced::_shaped_get_run_direction(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, TextServer::DIRECTION_LTR);
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), TextServer::DIRECTION_LTR);
return sd->runs[p_index].rtl ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR;
}
Variant TextServerAdvanced::_shaped_get_run_object(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Variant());
MutexLock lock(sd->mutex);
if (!sd->valid.is_set()) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->runs_dirty) {
_generate_runs(sd);
}
ERR_FAIL_INDEX_V(p_index, sd->runs.size(), Variant());
int span_idx = sd->runs[p_index].span_index;
ShapedTextDataAdvanced *span_sd = sd;
if (sd->parent.is_valid()) {
span_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_NULL_V(span_sd, Variant());
}
ERR_FAIL_INDEX_V(span_idx, span_sd->spans.size(), Variant());
return span_sd->spans[span_idx].embedded_key;
}
void TextServerAdvanced::_shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL(sd);
@@ -4575,6 +4784,13 @@ bool TextServerAdvanced::_shaped_text_add_object(const RID &p_shaped, const Vari
return true;
}
String TextServerAdvanced::_shaped_get_text(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, String());
return sd->text;
}
bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, false);
@@ -4771,6 +4987,8 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
p_new_sd->sort_valid = false;
p_new_sd->upos = p_sd->upos;
p_new_sd->uthk = p_sd->uthk;
p_new_sd->runs.clear();
p_new_sd->runs_dirty = true;
if (p_length > 0) {
p_new_sd->text = p_sd->text.substr(p_start - p_sd->start, p_length);
@@ -6560,6 +6778,8 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
} else {
bidi_ranges = sd->bidi_override;
}
sd->runs.clear();
sd->runs_dirty = true;
for (int ov = 0; ov < bidi_ranges.size(); ov++) {
// Create BiDi iterator.