@ -29,12 +29,12 @@
/*************************************************************************/
# include "text_server_adv.h"
# include "core/object/worker_thread_pool.h"
# ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.
# include <godot_cpp/classes/file.hpp>
# include <godot_cpp/classes/project_settings.hpp>
# include <godot_cpp/classes/rendering_server.hpp>
# include <godot_cpp/classes/translation_server.hpp>
# include <godot_cpp/core/error_macros.hpp>
@ -44,8 +44,10 @@ using namespace godot;
# else
// Headers for building as built-in module.
# include "core/config/project_settings.h"
# include "core/core_bind.h"
# include "core/error/error_macros.h"
# include "core/object/worker_thread_pool.h"
# include "core/string/print_string.h"
# include "core/string/translation.h"
@ -791,6 +793,10 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
for ( int i = 0 ; i < p_data - > textures . size ( ) ; i + + ) {
const FontTexture & ct = p_data - > textures [ i ] ;
if ( p_image_format ! = ct . format ) {
continue ;
}
if ( mw > ct . texture_w | | mh > ct . texture_h ) { // Too big for this texture.
continue ;
}
@ -1082,9 +1088,28 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
# endif
# ifdef MODULE_FREETYPE_ENABLED
_FORCE_INLINE_ TextServerAdvanced : : FontGlyph TextServerAdvanced : : rasterize_bitmap ( FontForSizeAdvanced * p_data , int p_rect_margin , FT_Bitmap bitmap , int yofs , int xofs , const Vector2 & advance ) const {
_FORCE_INLINE_ TextServerAdvanced : : FontGlyph TextServerAdvanced : : rasterize_bitmap ( FontForSizeAdvanced * p_data , int p_rect_margin , FT_Bitmap bitmap , int yofs , int xofs , const Vector2 & advance , bool p_bgra ) const {
int w = bitmap . width ;
int h = bitmap . rows ;
int color_size = 2 ;
switch ( bitmap . pixel_mode ) {
case FT_PIXEL_MODE_MONO :
case FT_PIXEL_MODE_GRAY : {
color_size = 2 ;
} break ;
case FT_PIXEL_MODE_BGRA : {
color_size = 4 ;
} break ;
case FT_PIXEL_MODE_LCD : {
color_size = 4 ;
w / = 3 ;
} break ;
case FT_PIXEL_MODE_LCD_V : {
color_size = 4 ;
h / = 3 ;
} break ;
}
int mw = w + p_rect_margin * 4 ;
int mh = h + p_rect_margin * 4 ;
@ -1092,7 +1117,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
ERR_FAIL_COND_V ( mw > 4096 , FontGlyph ( ) ) ;
ERR_FAIL_COND_V ( mh > 4096 , FontGlyph ( ) ) ;
int color_size = bitmap . pixel_mode = = FT_PIXEL_MODE_BGRA ? 4 : 2 ;
Image : : Format require_format = color_size = = 4 ? Image : : FORMAT_RGBA8 : Image : : FORMAT_LA8 ;
FontTexturePosition tex_pos = find_texture_pos_for_glyph ( p_data , color_size , require_format , mw , mh , false ) ;
@ -1127,6 +1151,34 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
wr [ ofs + 0 ] = bitmap . buffer [ ofs_color + 2 ] ;
wr [ ofs + 3 ] = bitmap . buffer [ ofs_color + 3 ] ;
} break ;
case FT_PIXEL_MODE_LCD : {
int ofs_color = i * bitmap . pitch + ( j * 3 ) ;
if ( p_bgra ) {
wr [ ofs + 0 ] = bitmap . buffer [ ofs_color + 0 ] ;
wr [ ofs + 1 ] = bitmap . buffer [ ofs_color + 1 ] ;
wr [ ofs + 2 ] = bitmap . buffer [ ofs_color + 2 ] ;
wr [ ofs + 3 ] = 255 ;
} else {
wr [ ofs + 0 ] = bitmap . buffer [ ofs_color + 2 ] ;
wr [ ofs + 1 ] = bitmap . buffer [ ofs_color + 1 ] ;
wr [ ofs + 2 ] = bitmap . buffer [ ofs_color + 0 ] ;
wr [ ofs + 3 ] = 255 ;
}
} break ;
case FT_PIXEL_MODE_LCD_V : {
int ofs_color = i * bitmap . pitch * 3 + j ;
if ( p_bgra ) {
wr [ ofs + 0 ] = bitmap . buffer [ ofs_color + bitmap . pitch * 2 ] ;
wr [ ofs + 1 ] = bitmap . buffer [ ofs_color + bitmap . pitch ] ;
wr [ ofs + 2 ] = bitmap . buffer [ ofs_color + 0 ] ;
wr [ ofs + 3 ] = 255 ;
} else {
wr [ ofs + 0 ] = bitmap . buffer [ ofs_color + 0 ] ;
wr [ ofs + 1 ] = bitmap . buffer [ ofs_color + bitmap . pitch ] ;
wr [ ofs + 2 ] = bitmap . buffer [ ofs_color + bitmap . pitch * 2 ] ;
wr [ ofs + 3 ] = 255 ;
}
} break ;
default :
ERR_FAIL_V_MSG ( FontGlyph ( ) , " Font uses unsupported pixel format: " + String : : num_int64 ( bitmap . pixel_mode ) + " . " ) ;
break ;
@ -1230,9 +1282,44 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
FT_Outline_Transform ( & fd - > face - > glyph - > outline , & mat ) ;
}
FT_Render_Mode aa_mode = FT_RENDER_MODE_NORMAL ;
bool bgra = false ;
switch ( p_font_data - > antialiasing ) {
case FONT_ANTIALIASING_NONE : {
aa_mode = FT_RENDER_MODE_MONO ;
} break ;
case FONT_ANTIALIASING_GRAY : {
aa_mode = FT_RENDER_MODE_NORMAL ;
} break ;
case FONT_ANTIALIASING_LCD : {
int aa_layout = ( int ) ( ( p_glyph > > 24 ) & 7 ) ;
switch ( aa_layout ) {
case FONT_LCD_SUBPIXEL_LAYOUT_HRGB : {
aa_mode = FT_RENDER_MODE_LCD ;
bgra = false ;
} break ;
case FONT_LCD_SUBPIXEL_LAYOUT_HBGR : {
aa_mode = FT_RENDER_MODE_LCD ;
bgra = true ;
} break ;
case FONT_LCD_SUBPIXEL_LAYOUT_VRGB : {
aa_mode = FT_RENDER_MODE_LCD_V ;
bgra = false ;
} break ;
case FONT_LCD_SUBPIXEL_LAYOUT_VBGR : {
aa_mode = FT_RENDER_MODE_LCD_V ;
bgra = true ;
} break ;
default : {
aa_mode = FT_RENDER_MODE_NORMAL ;
} break ;
}
} break ;
}
if ( ! outline ) {
if ( ! p_font_data - > msdf ) {
error = FT_Render_Glyph ( fd - > face - > glyph , p_font_data - > antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO ) ;
error = FT_Render_Glyph ( fd - > face - > glyph , aa_mode ) ;
}
FT_GlyphSlot slot = fd - > face - > glyph ;
if ( ! error ) {
@ -1244,7 +1331,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
ERR_FAIL_V_MSG ( false , " Compiled without MSDFGEN support! " ) ;
# endif
} else {
gl = rasterize_bitmap ( fd , rect_range , slot - > bitmap , slot - > bitmap_top , slot - > bitmap_left , Vector2 ( ( h + ( 1 < < 9 ) ) > > 10 , ( v + ( 1 < < 9 ) ) > > 10 ) / 64.0 );
gl = rasterize_bitmap ( fd , rect_range , slot - > bitmap , slot - > bitmap_top , slot - > bitmap_left , Vector2 ( ( h + ( 1 < < 9 ) ) > > 10 , ( v + ( 1 < < 9 ) ) > > 10 ) / 64.0 , bgra );
}
}
} else {
@ -1264,11 +1351,11 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
if ( FT_Glyph_Stroke ( & glyph , stroker , 1 ) ! = 0 ) {
goto cleanup_glyph ;
}
if ( FT_Glyph_To_Bitmap ( & glyph , p_font_data- > antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO , nullptr , 1 ) ! = 0 ) {
if ( FT_Glyph_To_Bitmap ( & glyph , aa_mode , nullptr , 1 ) ! = 0 ) {
goto cleanup_glyph ;
}
glyph_bitmap = ( FT_BitmapGlyph ) glyph ;
gl = rasterize_bitmap ( fd , rect_range , glyph_bitmap - > bitmap , glyph_bitmap - > top , glyph_bitmap - > left , Vector2 ( ) );
gl = rasterize_bitmap ( fd , rect_range , glyph_bitmap - > bitmap , glyph_bitmap - > top , glyph_bitmap - > left , Vector2 ( ) , bgra );
cleanup_glyph :
FT_Done_Glyph ( glyph ) ;
@ -1925,23 +2012,23 @@ String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
return fd - > font_name ;
}
void TextServerAdvanced : : font_set_antialias ed( const RID & p_font_rid , bool p_antialiased ) {
void TextServerAdvanced : : font_set_antialias ing( RID p_font_rid , TextServer : : FontAntialiasing p_antialiasing ) {
FontAdvanced * fd = font_owner . get_or_null ( p_font_rid ) ;
ERR_FAIL_COND ( ! fd ) ;
MutexLock lock ( fd - > mutex ) ;
if ( fd - > antialias ed ! = p_antialiased ) {
if ( fd - > antialias ing ! = p_antialiasing ) {
_font_clear_cache ( fd ) ;
fd - > antialias ed = p_antialiased ;
fd - > antialias ing = p_antialiasing ;
}
}
bool TextServerAdvanced : : font_is_antialiased ( const RID & p_font_rid ) const {
TextServer : : FontAntialiasing TextServerAdvanced : : font_get_antialiasing ( RID p_font_rid ) const {
FontAdvanced * fd = font_owner . get_or_null ( p_font_rid ) ;
ERR_FAIL_COND_V ( ! fd , false ) ;
ERR_FAIL_COND_V ( ! fd , TextServer : : FONT_ANTIALIASING_NONE ) ;
MutexLock lock ( fd - > mutex ) ;
return fd - > antialias ed ;
return fd - > antialias ing ;
}
void TextServerAdvanced : : font_set_generate_mipmaps ( const RID & p_font_rid , bool p_generate_mipmaps ) {
@ -2514,7 +2601,16 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
Vector2i size = _get_size ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , Vector2 ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return Vector2 ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2557,7 +2653,16 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , Vector2 ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return Vector2 ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2593,7 +2698,16 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , Vector2 ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return Vector2 ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2629,7 +2743,16 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , Rect2 ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return Rect2 ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2660,7 +2783,16 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , - 1 ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return - 1 ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2691,7 +2823,16 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , RID ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return RID ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2730,7 +2871,16 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
Vector2i size = _get_size_outline ( fd , p_size ) ;
ERR_FAIL_COND_V ( ! _ensure_cache_for_size ( fd , size ) , Size2 ( ) ) ;
if ( ! _ensure_glyph ( fd , size , p_glyph ) ) {
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
if ( ! _ensure_glyph ( fd , size , p_glyph | mod ) ) {
return Size2 ( ) ; // Invalid or non graphicl glyph, do not display errors.
}
@ -2986,16 +3136,18 @@ void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i
if ( fd - > msdf ) {
_ensure_glyph ( fd , size , ( int32_t ) idx ) ;
} else {
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 2 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 3 < < 27 ) ) ;
} else if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_HALF ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) ) ;
} else {
_ensure_glyph ( fd , size , ( int32_t ) idx ) ;
for ( int aa = 0 ; aa < ( ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1 ) ; aa + + ) {
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 2 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 3 < < 27 ) | ( aa < < 24 ) ) ;
} else if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_HALF ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) | ( aa < < 24 ) ) ;
} else {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( aa < < 24 ) ) ;
}
}
}
}
@ -3016,16 +3168,18 @@ void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i
if ( fd - > msdf ) {
_ensure_glyph ( fd , size , ( int32_t ) idx ) ;
} else {
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 2 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 3 < < 27 ) ) ;
} else if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_HALF ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) ) ;
} else {
_ensure_glyph ( fd , size , ( int32_t ) idx ) ;
for ( int aa = 0 ; aa < ( ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1 ) ; aa + + ) {
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 2 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 3 < < 27 ) | ( aa < < 24 ) ) ;
} else if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_HALF ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE ) ) {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 1 < < 27 ) | ( aa < < 24 ) ) ;
_ensure_glyph ( fd , size , ( int32_t ) idx | ( 0 < < 27 ) | ( aa < < 24 ) ) ;
} else {
_ensure_glyph ( fd , size , ( int32_t ) idx | ( aa < < 24 ) ) ;
}
}
}
}
@ -3041,9 +3195,19 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
ERR_FAIL_COND ( ! _ensure_cache_for_size ( fd , size ) ) ;
int32_t index = p_index & 0xffffff ; // Remove subpixel shifts.
bool lcd_aa = false ;
# ifdef MODULE_FREETYPE_ENABLED
if ( ! fd - > msdf & & fd - > cache [ size ] - > face ) {
// LCD layout, bits 24, 25, 26
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
lcd_aa = true ;
index = index | ( layout < < 24 ) ;
}
}
// Subpixel X-shift, bits 27, 28
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
int xshift = ( int ) ( Math : : floor ( 4 * ( p_pos . x + 0.125 ) ) - 4 * Math : : floor ( p_pos . x + 0.125 ) ) ;
index = index | ( xshift < < 27 ) ;
@ -3065,7 +3229,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
if ( gl . texture_idx ! = - 1 ) {
Color modulate = p_color ;
# ifdef MODULE_FREETYPE_ENABLED
if ( fd - > cache [ size ] - > face & & fd - > cache [ size ] - > textures [ gl . texture_idx ] . format = = Image : : FORMAT_RGBA8 ) {
if ( fd - > cache [ size ] - > face & & ( fd - > cache [ size ] - > textures [ gl . texture_idx ] . format = = Image : : FORMAT_RGBA8 ) & & ! lcd_aa ) {
modulate . r = modulate . g = modulate . b = 1.0 ;
}
# endif
@ -3103,7 +3267,11 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
cpos + = gl . rect . position ;
Size2 csize = gl . rect . size ;
RenderingServer : : get_singleton ( ) - > canvas_item_add_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate , false , false ) ;
if ( lcd_aa ) {
RenderingServer : : get_singleton ( ) - > canvas_item_add_lcd_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate ) ;
} else {
RenderingServer : : get_singleton ( ) - > canvas_item_add_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate , false , false ) ;
}
}
}
}
@ -3119,9 +3287,19 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
ERR_FAIL_COND ( ! _ensure_cache_for_size ( fd , size ) ) ;
int32_t index = p_index & 0xffffff ; // Remove subpixel shifts.
bool lcd_aa = false ;
# ifdef MODULE_FREETYPE_ENABLED
if ( ! fd - > msdf & & fd - > cache [ size ] - > face ) {
// LCD layout, bits 24, 25, 26
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
lcd_aa = true ;
index = index | ( layout < < 24 ) ;
}
}
// Subpixel X-shift, bits 27, 28
if ( ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_ONE_QUARTER ) | | ( fd - > subpixel_positioning = = SUBPIXEL_POSITIONING_AUTO & & size . x < = SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE ) ) {
int xshift = ( int ) ( Math : : floor ( 4 * ( p_pos . x + 0.125 ) ) - 4 * Math : : floor ( p_pos . x + 0.125 ) ) ;
index = index | ( xshift < < 27 ) ;
@ -3181,7 +3359,11 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
cpos + = gl . rect . position ;
Size2 csize = gl . rect . size ;
RenderingServer : : get_singleton ( ) - > canvas_item_add_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate , false , false ) ;
if ( lcd_aa ) {
RenderingServer : : get_singleton ( ) - > canvas_item_add_lcd_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate ) ;
} else {
RenderingServer : : get_singleton ( ) - > canvas_item_add_texture_rect_region ( p_canvas , Rect2 ( cpos , csize ) , texture , gl . uv_rect , modulate , false , false ) ;
}
}
}
}
@ -4947,6 +5129,14 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
hb_glyph_info_t * glyph_info = hb_buffer_get_glyph_infos ( p_sd - > hb_buffer , & glyph_count ) ;
hb_glyph_position_t * glyph_pos = hb_buffer_get_glyph_positions ( p_sd - > hb_buffer , & glyph_count ) ;
int mod = 0 ;
if ( fd - > antialiasing = = FONT_ANTIALIASING_LCD ) {
TextServer : : FontLCDSubpixelLayout layout = ( TextServer : : FontLCDSubpixelLayout ) ( int ) GLOBAL_GET ( " gui/theme/lcd_subpixel_layout " ) ;
if ( layout ! = FONT_LCD_SUBPIXEL_LAYOUT_NONE ) {
mod = ( layout < < 24 ) ;
}
}
// Process glyphs.
if ( glyph_count > 0 ) {
Glyph * w = ( Glyph * ) memalloc ( glyph_count * sizeof ( Glyph ) ) ;
@ -5000,7 +5190,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
gl . index = glyph_info [ i ] . codepoint ;
if ( gl . index ! = 0 ) {
_ensure_glyph ( fd , fss , gl . index ) ;
_ensure_glyph ( fd , fss , gl . index | mod ) ;
if ( p_sd - > orientation = = ORIENTATION_HORIZONTAL ) {
if ( subpos ) {
gl . advance = glyph_pos [ i ] . x_advance / ( 64.0 / scale ) + ea ;