@@ -4275,7 +4275,13 @@ bool TextServerAdvanced::_font_is_script_supported(const RID &p_font_rid, const
42754275 Vector2i size = _get_size (fd, 16 );
42764276 FontForSizeAdvanced *ffsd = nullptr ;
42774277 ERR_FAIL_COND_V (!_ensure_cache_for_size (fd, size, ffsd), false );
4278- return fd->supported_scripts .has (hb_tag_from_string (p_script.ascii ().get_data (), -1 ));
4278+ char ascii_script[] = { ' ' , ' ' , ' ' , ' ' };
4279+ for (int i = 0 ; i < MIN (4 , p_script.size ()); i++) {
4280+ if (p_script[i] <= 0x7f ) {
4281+ ascii_script[i] = p_script[i];
4282+ }
4283+ }
4284+ return fd->supported_scripts .has (hb_tag_from_string (ascii_script, -1 ));
42794285 }
42804286}
42814287
@@ -5294,6 +5300,14 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
52945300 int32_t bidi_run_start = _convert_pos (p_sd, ov_start + start + _bidi_run_start);
52955301 int32_t bidi_run_end = _convert_pos (p_sd, ov_start + start + _bidi_run_start + _bidi_run_length);
52965302
5303+ bool cache_valid = false ;
5304+ int cached_font_size = -1 ;
5305+ RID cached_font_rid = RID ();
5306+ double cached_font_ascent = 0 ;
5307+ double cached_font_descent = 0 ;
5308+ double cached_font_top_spacing = 0 ;
5309+ double cached_font_bottom_spacing = 0 ;
5310+ p_new_sd->glyphs .reserve (p_new_sd->glyphs .size () + MIN (sd_size, bidi_run_end - bidi_run_start));
52975311 for (int j = 0 ; j < sd_size; j++) {
52985312 int col_key_off = (sd_glyphs[j].start == sd_glyphs[j].end ) ? 1 : 0 ;
52995313 if ((sd_glyphs[j].start >= bidi_run_start) && (sd_glyphs[j].end <= bidi_run_end - col_key_off)) {
@@ -5346,20 +5360,32 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
53465360 } else {
53475361 if (gl.font_rid .is_valid ()) {
53485362 if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) {
5349- p_new_sd->ascent = MAX (p_new_sd->ascent , MAX (_font_get_ascent (gl.font_rid , gl.font_size ) + _font_get_spacing (gl.font_rid , SPACING_TOP), -gl.y_off ));
5350- p_new_sd->descent = MAX (p_new_sd->descent , MAX (_font_get_descent (gl.font_rid , gl.font_size ) + _font_get_spacing (gl.font_rid , SPACING_BOTTOM), gl.y_off ));
5363+ if (!cache_valid || cached_font_rid != gl.font_rid || cached_font_size != gl.font_size ) {
5364+ cache_valid = true ;
5365+ cached_font_rid = gl.font_rid ;
5366+ cached_font_size = gl.font_size ;
5367+ cached_font_ascent = _font_get_ascent (gl.font_rid , gl.font_size );
5368+ cached_font_descent = _font_get_descent (gl.font_rid , gl.font_size );
5369+ cached_font_top_spacing = _font_get_spacing (gl.font_rid , SPACING_TOP);
5370+ cached_font_bottom_spacing = _font_get_spacing (gl.font_rid , SPACING_BOTTOM);
5371+ }
5372+ p_new_sd->ascent = MAX (p_new_sd->ascent , MAX (cached_font_ascent + cached_font_top_spacing, -gl.y_off ));
5373+ p_new_sd->descent = MAX (p_new_sd->descent , MAX (cached_font_descent + cached_font_bottom_spacing, gl.y_off ));
53515374 } else {
5352- p_new_sd->ascent = MAX (p_new_sd->ascent , Math::round (_font_get_glyph_advance (gl.font_rid , gl.font_size , gl.index ).x * 0.5 ));
5353- p_new_sd->descent = MAX (p_new_sd->descent , Math::round (_font_get_glyph_advance (gl.font_rid , gl.font_size , gl.index ).x * 0.5 ));
5375+ double glyph_advance = Math::round (_font_get_glyph_advance (gl.font_rid , gl.font_size , gl.index ).x * 0.5 );
5376+ p_new_sd->ascent = MAX (p_new_sd->ascent , glyph_advance);
5377+ p_new_sd->descent = MAX (p_new_sd->descent , glyph_advance);
53545378 }
53555379 } else if (p_new_sd->preserve_invalid || (p_new_sd->preserve_control && is_control (ch[gl.start - p_sd->start ]))) {
53565380 // Glyph not found, replace with hex code box.
53575381 if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) {
5358- p_new_sd->ascent = MAX (p_new_sd->ascent , get_hex_code_box_size (gl.font_size , gl.index ).y * 0.85 );
5359- p_new_sd->descent = MAX (p_new_sd->descent , get_hex_code_box_size (gl.font_size , gl.index ).y * 0.15 );
5382+ double box_size = get_hex_code_box_size (gl.font_size , gl.index ).y ;
5383+ p_new_sd->ascent = MAX (p_new_sd->ascent , box_size * 0.85 );
5384+ p_new_sd->descent = MAX (p_new_sd->descent , box_size * 0.15 );
53605385 } else {
5361- p_new_sd->ascent = MAX (p_new_sd->ascent , Math::round (get_hex_code_box_size (gl.font_size , gl.index ).x * 0.5 ));
5362- p_new_sd->descent = MAX (p_new_sd->descent , Math::round (get_hex_code_box_size (gl.font_size , gl.index ).x * 0.5 ));
5386+ double box_size = Math::round (get_hex_code_box_size (gl.font_size , gl.index ).x * 0.5 );
5387+ p_new_sd->ascent = MAX (p_new_sd->ascent , box_size);
5388+ p_new_sd->descent = MAX (p_new_sd->descent , box_size);
53635389 }
53645390 }
53655391 p_new_sd->width += gl.advance * gl.repeat ;
@@ -6649,10 +6675,9 @@ UBreakIterator *TextServerAdvanced::_create_line_break_iterator_for_locale(const
66496675 return ubrk_clone (bi, r_err);
66506676}
66516677
6652- void TextServerAdvanced::_shape_run (ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index, int64_t p_prev_start, int64_t p_prev_end, RID p_prev_font) {
6678+ void TextServerAdvanced::_shape_run (ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, FontPriorityList & p_fonts, int64_t p_span, int64_t p_fb_index, int64_t p_prev_start, int64_t p_prev_end, RID p_prev_font) {
66536679 RID f;
66546680 int fs = p_sd->spans [p_span].font_size ;
6655-
66566681 if (p_fb_index >= 0 && p_fb_index < p_fonts.size ()) {
66576682 // Try font from list.
66586683 f = p_fonts[p_fb_index];
@@ -6697,7 +6722,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
66976722 }
66986723
66996724 bool found = false ;
6700- for (int j = 0 ; j <= p_fonts.size (); j++) {
6725+ for (uint32_t j = 0 ; j <= p_fonts.size (); j++) {
67016726 RID f_rid;
67026727 if (j == p_fonts.size ()) {
67036728 f_rid = p_prev_font;
@@ -6848,6 +6873,11 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
68486873 }
68496874 }
68506875
6876+ bool cache_valid = false ;
6877+ RID cached_font_rid = RID ();
6878+ int cached_font_size = 0 ;
6879+ float cached_offset = 0 ;
6880+
68516881 double adv_rem = 0.0 ;
68526882 for (unsigned int i = 0 ; i < glyph_count; i++) {
68536883 if ((i > 0 ) && (last_cluster_id != glyph_info[i].cluster )) {
@@ -6933,10 +6963,16 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
69336963 adv_rem = full_adv + gl.advance ;
69346964 }
69356965 }
6966+ if (!cache_valid || cached_font_rid != gl.font_rid || cached_font_size != gl.font_size ) {
6967+ cache_valid = true ;
6968+ cached_font_size = gl.font_size ;
6969+ cached_font_rid = gl.font_rid ;
6970+ cached_offset = _font_get_baseline_offset (gl.font_rid ) * (double )(_font_get_ascent (gl.font_rid , gl.font_size ) + _font_get_descent (gl.font_rid , gl.font_size ));
6971+ }
69366972 if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
6937- gl.y_off += _font_get_baseline_offset (gl. font_rid ) * ( double )( _font_get_ascent (gl. font_rid , gl. font_size ) + _font_get_descent (gl. font_rid , gl. font_size )) ;
6973+ gl.y_off += cached_offset ;
69386974 } else {
6939- gl.x_off += _font_get_baseline_offset (gl. font_rid ) * ( double )( _font_get_ascent (gl. font_rid , gl. font_size ) + _font_get_descent (gl. font_rid , gl. font_size )) ;
6975+ gl.x_off += cached_offset ;
69406976 }
69416977 }
69426978 if ((!last_run || i < last_non_zero_w) && !Math::is_zero_approx (gl.advance )) {
@@ -6978,6 +7014,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
69787014 failed_subrun_start = p_end + 1 ;
69797015 failed_subrun_end = p_start;
69807016 }
7017+ p_sd->glyphs .reserve (p_sd->glyphs .size () + w[i].count );
69817018 for (int j = 0 ; j < w[i].count ; j++) {
69827019 if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
69837020 p_sd->ascent = MAX (p_sd->ascent , -w[i + j].y_off );
@@ -7222,27 +7259,8 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
72227259 }
72237260 sd->glyphs .push_back (gl);
72247261 } else {
7225- Array fonts;
7226- Array fonts_scr_only;
7227- Array fonts_no_match;
7228- int font_count = span.fonts .size ();
7229- if (font_count > 0 ) {
7230- fonts.push_back (sd->spans [k].fonts [0 ]);
7231- }
7232- for (int l = 1 ; l < font_count; l++) {
7233- if (_font_is_script_supported (span.fonts [l], script_code)) {
7234- if (_font_is_language_supported (span.fonts [l], span.language )) {
7235- fonts.push_back (sd->spans [k].fonts [l]);
7236- } else {
7237- fonts_scr_only.push_back (sd->spans [k].fonts [l]);
7238- }
7239- } else {
7240- fonts_no_match.push_back (sd->spans [k].fonts [l]);
7241- }
7242- }
7243- fonts.append_array (fonts_scr_only);
7244- fonts.append_array (fonts_no_match);
7245- _shape_run (sd, MAX (sd->spans [k].start - sd->start , script_run_start), MIN (sd->spans [k].end - sd->start , script_run_end), sd->script_iter ->script_ranges [j].script , bidi_run_direction, fonts, k, 0 , 0 , 0 , RID ());
7262+ FontPriorityList fonts (this , span.fonts , span.language , script_code);
7263+ _shape_run (sd, MAX (span.start - sd->start , script_run_start), MIN (span.end - sd->start , script_run_end), sd->script_iter ->script_ranges [j].script , bidi_run_direction, fonts, k, 0 , 0 , 0 , RID ());
72467264 }
72477265 }
72487266 }
0 commit comments