signed distance field font support
This commit is contained in:
parent
90a84b4ddb
commit
acc6f3b285
11 changed files with 64 additions and 9 deletions
|
@ -9127,8 +9127,10 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
|
|||
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
|
||||
canvas_modulate=p_modulate;
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,false);
|
||||
|
||||
bool reset_modulate=false;
|
||||
bool prev_distance_field=false;
|
||||
|
||||
while(p_item_list) {
|
||||
|
||||
|
@ -9144,12 +9146,22 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
|
|||
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
|
||||
canvas_modulate=p_modulate;
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,false);
|
||||
prev_distance_field=false;
|
||||
rebind_shader=true;
|
||||
reset_modulate=true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (prev_distance_field!=ci->distance_field) {
|
||||
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,ci->distance_field);
|
||||
prev_distance_field=ci->distance_field;
|
||||
rebind_shader=true;
|
||||
}
|
||||
|
||||
|
||||
if (current_clip!=ci->final_clip_owner) {
|
||||
|
||||
current_clip=ci->final_clip_owner;
|
||||
|
|
|
@ -191,8 +191,16 @@ void main() {
|
|||
vec3 normal = vec3(0.0,0.0,1.0);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_DISTANCE_FIELD
|
||||
const float smoothing = 1.0/32.0;
|
||||
float distance = texture2D(texture, uv_interp).a;
|
||||
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
|
||||
#else
|
||||
color *= texture2D( texture, uv_interp );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ENABLE_SCREEN_UV)
|
||||
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
|
||||
#endif
|
||||
|
|
|
@ -72,6 +72,7 @@ void Label::_notification(int p_what) {
|
|||
if (clip && !autowrap)
|
||||
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
|
||||
|
||||
|
||||
if (word_cache_dirty)
|
||||
regenerate_word_cache();
|
||||
|
||||
|
@ -87,7 +88,8 @@ void Label::_notification(int p_what) {
|
|||
bool use_outlinde = get_constant("shadow_as_outline");
|
||||
Point2 shadow_ofs(get_constant("shadow_offset_x"),get_constant("shadow_offset_y"));
|
||||
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(),font.is_valid() && font->is_distance_field_hint());
|
||||
|
||||
int font_h = font->get_height();
|
||||
int line_from=(int)get_val(); // + p_exposed.pos.y / font_h;
|
||||
int lines_visible = size.y/font_h;
|
||||
|
|
|
@ -398,6 +398,17 @@ int Font::get_kerning_pair(CharType p_A,CharType p_B) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Font::set_distance_field_hint(bool p_distance_field) {
|
||||
|
||||
distance_field_hint=p_distance_field;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
bool Font::is_distance_field_hint() const{
|
||||
|
||||
return distance_field_hint;
|
||||
}
|
||||
|
||||
|
||||
void Font::clear() {
|
||||
|
||||
|
@ -406,6 +417,7 @@ void Font::clear() {
|
|||
char_map.clear();
|
||||
textures.clear();
|
||||
kerning_map.clear();
|
||||
distance_field_hint=false;
|
||||
}
|
||||
|
||||
Size2 Font::get_string_size(const String& p_string) const {
|
||||
|
@ -514,6 +526,9 @@ void Font::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_char_size","char","next"),&Font::get_char_size,DEFVAL(0));
|
||||
ObjectTypeDB::bind_method(_MD("get_string_size","string"),&Font::get_string_size);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_distance_field_hint","enable"),&Font::set_distance_field_hint);
|
||||
ObjectTypeDB::bind_method(_MD("is_distance_field_hint"),&Font::is_distance_field_hint);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("clear"),&Font::clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","string","modulate","clip_w"),&Font::draw,DEFVAL(Color(1,1,1)),DEFVAL(-1));
|
||||
|
@ -535,12 +550,14 @@ void Font::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "height", PROPERTY_HINT_RANGE,"-1024,1024,1" ), _SCS("set_height"), _SCS("get_height") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "ascent", PROPERTY_HINT_RANGE,"-1024,1024,1" ), _SCS("set_ascent"), _SCS("get_ascent") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "distance_field" ), _SCS("set_distance_field_hint"), _SCS("is_distance_field_hint") );
|
||||
|
||||
}
|
||||
|
||||
Font::Font() {
|
||||
|
||||
clear();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ private:
|
|||
|
||||
float height;
|
||||
float ascent;
|
||||
bool distance_field_hint;
|
||||
|
||||
void _set_chars(const DVector<int>& p_chars);
|
||||
DVector<int> _get_chars() const;
|
||||
|
@ -116,6 +117,9 @@ public:
|
|||
Size2 get_string_size(const String& p_string) const;
|
||||
|
||||
void clear();
|
||||
|
||||
void set_distance_field_hint(bool p_distance_field);
|
||||
bool is_distance_field_hint() const;
|
||||
|
||||
void draw(RID p_canvas_item, const Point2& p_pos, const String& p_text,const Color& p_modulate=Color(1,1,1),int p_clip_w=-1) const;
|
||||
void draw_halign(RID p_canvas_item, const Point2& p_pos, HAlign p_align,float p_width,const String& p_text,const Color& p_modulate=Color(1,1,1)) const;
|
||||
|
|
|
@ -783,6 +783,7 @@ public:
|
|||
CanvasItem* final_clip_owner;
|
||||
CanvasItem* material_owner;
|
||||
ViewportRender *vp_render;
|
||||
bool distance_field;
|
||||
|
||||
Rect2 global_rect_cache;
|
||||
|
||||
|
@ -910,7 +911,7 @@ public:
|
|||
}
|
||||
|
||||
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL;}
|
||||
CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; }
|
||||
CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; }
|
||||
virtual ~CanvasItem() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); }
|
||||
};
|
||||
|
||||
|
|
|
@ -3411,6 +3411,14 @@ void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip) {
|
|||
canvas_item->clip=p_clip;
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_distance_field_mode(RID p_item, bool p_distance_field) {
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
canvas_item->distance_field=p_distance_field;
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_item_set_transform(RID p_item, const Matrix32& p_transform) {
|
||||
|
||||
|
|
|
@ -1128,6 +1128,7 @@ public:
|
|||
//virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect);
|
||||
virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform);
|
||||
virtual void canvas_item_set_clip(RID p_item, bool p_clip);
|
||||
virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable);
|
||||
virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2());
|
||||
virtual void canvas_item_set_opacity(RID p_item, float p_opacity);
|
||||
virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const;
|
||||
|
|
|
@ -1109,6 +1109,7 @@ public:
|
|||
//FUNC(canvas_item_set_rect,RID, const Rect2& p_rect);
|
||||
FUNC2(canvas_item_set_transform,RID, const Matrix32& );
|
||||
FUNC2(canvas_item_set_clip,RID, bool );
|
||||
FUNC2(canvas_item_set_distance_field_mode,RID, bool );
|
||||
FUNC3(canvas_item_set_custom_rect,RID, bool ,const Rect2&);
|
||||
FUNC2(canvas_item_set_opacity,RID, float );
|
||||
FUNC2RC(float,canvas_item_get_opacity,RID, float );
|
||||
|
|
|
@ -969,6 +969,7 @@ public:
|
|||
|
||||
virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform)=0;
|
||||
virtual void canvas_item_set_clip(RID p_item, bool p_clip)=0;
|
||||
virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable)=0;
|
||||
virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2())=0;
|
||||
virtual void canvas_item_set_opacity(RID p_item, float p_opacity)=0;
|
||||
virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const=0;
|
||||
|
|
|
@ -984,7 +984,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
{
|
||||
|
||||
bool skip=false;
|
||||
error = FT_Load_Char( face, charcode, FT_LOAD_RENDER );
|
||||
error = FT_Load_Char( face, charcode, font_mode==_EditorFontImportOptions::FONT_BITMAP?FT_LOAD_RENDER:FT_LOAD_MONOCHROME );
|
||||
if (error) skip=true;
|
||||
else error = FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono );
|
||||
if (error) {
|
||||
|
@ -1016,7 +1016,8 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
int w = slot->bitmap.width;
|
||||
int h = slot->bitmap.rows;
|
||||
int p = slot->bitmap.pitch;
|
||||
print_line("pitch "+itos(slot->bitmap.pitch));
|
||||
|
||||
print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch));
|
||||
|
||||
if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) {
|
||||
|
||||
|
@ -1049,8 +1050,6 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
else
|
||||
fdata->advance=slot->advance.x/float(1<<6);
|
||||
|
||||
fdata->advance/=scaler;
|
||||
|
||||
if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) {
|
||||
|
||||
fdata->halign = fdata->halign / scaler - 1.5;
|
||||
|
@ -1150,7 +1149,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
spd->ofs_x=0;
|
||||
spd->ofs_y=0;
|
||||
|
||||
if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, ft_render_mode_normal )) {
|
||||
if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono )) {
|
||||
|
||||
spd->advance = slot->advance.x>>6; //round to nearest or store as float
|
||||
spd->advance/=scaler;
|
||||
|
@ -1498,7 +1497,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
atlas.convert(Image::FORMAT_GRAYSCALE_ALPHA);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
if (0) {
|
||||
//debug the texture
|
||||
Ref<ImageTexture> atlast = memnew( ImageTexture );
|
||||
atlast->create_from_image(atlas);
|
||||
|
@ -1531,6 +1530,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
font->clear();
|
||||
font->set_height(height+bottom_space+top_space);
|
||||
font->set_ascent(ascent+top_space);
|
||||
font->set_distance_field_hint(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD);
|
||||
|
||||
//register texures
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue