You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-29 16:16:38 +00:00
Base accessibility API.
This commit is contained in:
@@ -3105,6 +3105,8 @@ void TextServerFallback::invalidate(ShapedTextDataFallback *p_shaped) {
|
||||
p_shaped->uthk = 0.0;
|
||||
p_shaped->glyphs.clear();
|
||||
p_shaped->glyphs_logical.clear();
|
||||
p_shaped->runs.clear();
|
||||
p_shaped->runs_dirty = true;
|
||||
}
|
||||
|
||||
void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
|
||||
@@ -3339,6 +3341,212 @@ Variant TextServerFallback::_shaped_get_span_embedded_object(const RID &p_shaped
|
||||
}
|
||||
}
|
||||
|
||||
String TextServerFallback::_shaped_get_span_text(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, String());
|
||||
ShapedTextDataFallback *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 TextServerFallback::_shaped_get_span_object(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, Variant());
|
||||
ShapedTextDataFallback *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 TextServerFallback::_generate_runs(ShapedTextDataFallback *p_sd) const {
|
||||
ERR_FAIL_NULL(p_sd);
|
||||
p_sd->runs.clear();
|
||||
|
||||
ShapedTextDataFallback *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();
|
||||
Glyph *sd_gl = p_sd->glyphs.ptrw();
|
||||
|
||||
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) {
|
||||
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.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 TextServerFallback::_shaped_get_run_count(const RID &p_shaped) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
|
||||
}
|
||||
if (sd->runs_dirty) {
|
||||
_generate_runs(sd);
|
||||
}
|
||||
return sd->runs.size();
|
||||
}
|
||||
|
||||
String TextServerFallback::_shaped_get_run_text(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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 TextServerFallback::_shaped_get_run_range(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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 TextServerFallback::_shaped_get_run_font_rid(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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 TextServerFallback::_shaped_get_run_font_size(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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 TextServerFallback::_shaped_get_run_language(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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;
|
||||
ShapedTextDataFallback *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 TextServerFallback::_shaped_get_run_direction(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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 TextServer::DIRECTION_LTR;
|
||||
}
|
||||
|
||||
Variant TextServerFallback::_shaped_get_run_object(const RID &p_shaped, int64_t p_index) const {
|
||||
ShapedTextDataFallback *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<TextServerFallback *>(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;
|
||||
ShapedTextDataFallback *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 TextServerFallback::_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) {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL(sd);
|
||||
@@ -3450,6 +3658,13 @@ bool TextServerFallback::_shaped_text_add_object(const RID &p_shaped, const Vari
|
||||
return true;
|
||||
}
|
||||
|
||||
String TextServerFallback::_shaped_get_text(const RID &p_shaped) const {
|
||||
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, String());
|
||||
|
||||
return sd->text;
|
||||
}
|
||||
|
||||
bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, false);
|
||||
@@ -4385,6 +4600,8 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
|
||||
sd->descent = 0.0;
|
||||
sd->width = 0.0;
|
||||
sd->glyphs.clear();
|
||||
sd->runs.clear();
|
||||
sd->runs_dirty = true;
|
||||
|
||||
if (sd->text.length() == 0) {
|
||||
sd->valid.set();
|
||||
|
||||
Reference in New Issue
Block a user