Replace global oversampling with overrideable per-viewport oversampling.

This commit is contained in:
Pāvels Nadtočajevs 2025-03-30 14:20:25 +03:00
parent 215acd52e8
commit 4afeca3bcf
No known key found for this signature in database
GPG key ID: 8413210218EF35D2
38 changed files with 1235 additions and 557 deletions

View file

@ -56,8 +56,9 @@
<param index="2" name="char" type="String" />
<param index="3" name="font_size" type="int" default="16" />
<param index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<param index="5" name="oversampling" type="float" default="0.0" />
<description>
Draws a string first character using a custom font.
Draws a string first character using a custom font. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_char_outline" qualifiers="const">
@ -68,8 +69,9 @@
<param index="3" name="font_size" type="int" default="16" />
<param index="4" name="size" type="int" default="-1" />
<param index="5" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<param index="6" name="oversampling" type="float" default="0.0" />
<description>
Draws a string first character outline using a custom font.
Draws a string first character outline using a custom font. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_circle">
@ -214,8 +216,9 @@
<param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="12" name="oversampling" type="float" default="0.0" />
<description>
Breaks [param text] into lines and draws it using the specified [param font] at the [param pos] (top-left corner). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
Breaks [param text] into lines and draws it using the specified [param font] at the [param pos] (top-left corner). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_multiline_string_outline" qualifiers="const">
@ -233,8 +236,9 @@
<param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="13" name="oversampling" type="float" default="0.0" />
<description>
Breaks [param text] to the lines and draws text outline using the specified [param font] at the [param pos] (top-left corner). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
Breaks [param text] to the lines and draws text outline using the specified [param font] at the [param pos] (top-left corner). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_multimesh">
@ -332,8 +336,9 @@
<param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="10" name="oversampling" type="float" default="0.0" />
<description>
Draws [param text] using the specified [param font] at the [param pos] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
Draws [param text] using the specified [param font] at the [param pos] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
[b]Example:[/b] Draw "Hello world", using the project's default font:
[codeblocks]
[gdscript]
@ -369,8 +374,9 @@
<param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="11" name="oversampling" type="float" default="0.0" />
<description>
Draws [param text] outline using the specified [param font] at the [param pos] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
Draws [param text] outline using the specified [param font] at the [param pos] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_style_box">

View file

@ -16,8 +16,9 @@
<param index="2" name="char" type="int" />
<param index="3" name="font_size" type="int" />
<param index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<param index="5" name="oversampling" type="float" default="0.0" />
<description>
Draw a single Unicode character [param char] into a canvas item using the font, at a given position, with [param modulate] color. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Draw a single Unicode character [param char] into a canvas item using the font, at a given position, with [param modulate] color. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
[b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead.
</description>
</method>
@ -29,8 +30,9 @@
<param index="3" name="font_size" type="int" />
<param index="4" name="size" type="int" default="-1" />
<param index="5" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<param index="6" name="oversampling" type="float" default="0.0" />
<description>
Draw a single Unicode character [param char] outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Draw a single Unicode character [param char] outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
[b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead.
</description>
</method>
@ -48,8 +50,9 @@
<param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="12" name="oversampling" type="float" default="0.0" />
<description>
Breaks [param text] into lines using rules specified by [param brk_flags] and draws it into a canvas item using the font, at a given position, with [param modulate] color, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Breaks [param text] into lines using rules specified by [param brk_flags] and draws it into a canvas item using the font, at a given position, with [param modulate] color, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
See also [method CanvasItem.draw_multiline_string].
</description>
</method>
@ -68,8 +71,9 @@
<param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="13" name="oversampling" type="float" default="0.0" />
<description>
Breaks [param text] to the lines using rules specified by [param brk_flags] and draws text outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Breaks [param text] to the lines using rules specified by [param brk_flags] and draws text outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
See also [method CanvasItem.draw_multiline_string_outline].
</description>
</method>
@ -85,8 +89,9 @@
<param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="10" name="oversampling" type="float" default="0.0" />
<description>
Draw [param text] into a canvas item using the font, at a given position, with [param modulate] color, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Draw [param text] into a canvas item using the font, at a given position, with [param modulate] color, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
See also [method CanvasItem.draw_string].
</description>
</method>
@ -103,8 +108,9 @@
<param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<param index="11" name="oversampling" type="float" default="0.0" />
<description>
Draw [param text] outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
Draw [param text] outline into a canvas item using the font, at a given position, with [param modulate] color and [param size] outline size, optionally clipping the width and aligning horizontally. [param pos] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
See also [method CanvasItem.draw_string_outline].
</description>
</method>

View file

@ -651,8 +651,8 @@
<member name="opentype_feature_overrides" type="Dictionary" setter="set_opentype_feature_overrides" getter="get_opentype_feature_overrides" default="{}">
Font OpenType feature set override.
</member>
<member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" default="0.0">
Font oversampling factor. If set to [code]0.0[/code], the global oversampling factor is used instead. Used by dynamic fonts only (MSDF fonts ignore oversampling).
<member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" deprecated="Use the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
Deprecated. This property does nothing.
</member>
<member name="style_name" type="String" setter="set_font_style_name" getter="get_font_style_name" default="&quot;&quot;">
Font style name.

View file

@ -67,7 +67,7 @@
The OpenType features to enable, disable or set a value for this font. This can be used to enable optional features provided by the font, such as ligatures or alternative glyphs. The list of supported OpenType features varies on a per-font basis.
</member>
<member name="oversampling" type="float" setter="" getter="" default="0.0">
If set to a value greater than [code]0.0[/code], overrides the oversampling factor for the font. This can be used to render the font at a higher or lower resolution than intended without affecting its physical size. In most cases, this should be left at [code]0.0[/code].
Deprecated. This property does nothing.
</member>
<member name="preload" type="Array" setter="" getter="" default="[]">
The glyph ranges to prerender. This can avoid stuttering during gameplay when new characters need to be rendered, especially if [member subpixel_positioning] is enabled. The downside of using preloading is that initial project load times will increase, as well as memory usage.

View file

@ -58,8 +58,8 @@
<member name="multichannel_signed_distance_field" type="bool" setter="set_multichannel_signed_distance_field" getter="is_multichannel_signed_distance_field" default="false">
If set to [code]true[/code], glyphs of all sizes are rendered using single multichannel signed distance field generated from the dynamic font vector data.
</member>
<member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" default="0.0">
Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead.
<member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" deprecated="Use the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
Deprecated. This property does nothing.
</member>
<member name="subpixel_positioning" type="int" setter="set_subpixel_positioning" getter="get_subpixel_positioning" enum="TextServer.SubpixelPositioning" default="1">
Font glyph subpixel positioning mode. Subpixel positioning provides shaper text and better kerning for smaller font sizes, at the cost of memory usage and font rasterization speed. Use [constant TextServer.SUBPIXEL_POSITIONING_AUTO] to automatically enable it based on the font size.

View file

@ -42,8 +42,9 @@
<param index="0" name="canvas" type="RID" />
<param index="1" name="pos" type="Vector2" />
<param index="2" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="3" name="oversampling" type="float" default="0.0" />
<description>
Draw text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_outline" qualifiers="const">
@ -52,8 +53,9 @@
<param index="1" name="pos" type="Vector2" />
<param index="2" name="outline_size" type="int" default="1" />
<param index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="oversampling" type="float" default="0.0" />
<description>
Draw text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="get_inferred_direction" qualifiers="const">

View file

@ -49,8 +49,9 @@
<param index="1" name="pos" type="Vector2" />
<param index="2" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="3" name="dc_color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="oversampling" type="float" default="0.0" />
<description>
Draw all lines of the text and drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw all lines of the text and drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_dropcap" qualifiers="const">
@ -58,8 +59,9 @@
<param index="0" name="canvas" type="RID" />
<param index="1" name="pos" type="Vector2" />
<param index="2" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="3" name="oversampling" type="float" default="0.0" />
<description>
Draw drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_dropcap_outline" qualifiers="const">
@ -68,8 +70,9 @@
<param index="1" name="pos" type="Vector2" />
<param index="2" name="outline_size" type="int" default="1" />
<param index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="oversampling" type="float" default="0.0" />
<description>
Draw drop cap outline into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw drop cap outline into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_line" qualifiers="const">
@ -78,8 +81,9 @@
<param index="1" name="pos" type="Vector2" />
<param index="2" name="line" type="int" />
<param index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="oversampling" type="float" default="0.0" />
<description>
Draw single line of text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw single line of text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_line_outline" qualifiers="const">
@ -89,8 +93,9 @@
<param index="2" name="line" type="int" />
<param index="3" name="outline_size" type="int" default="1" />
<param index="4" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="5" name="oversampling" type="float" default="0.0" />
<description>
Draw outline of the single line of text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw outline of the single line of text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="draw_outline" qualifiers="const">
@ -100,8 +105,9 @@
<param index="2" name="outline_size" type="int" default="1" />
<param index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="4" name="dc_color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="5" name="oversampling" type="float" default="0.0" />
<description>
Draw outlines of all lines of the text and drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box.
Draw outlines of all lines of the text and drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="get_dropcap_lines" qualifiers="const">

View file

@ -77,6 +77,12 @@
Removes all font sizes from the cache entry.
</description>
</method>
<method name="font_clear_system_fallback_cache">
<return type="void" />
<description>
Frees all automatically loaded system fonts.
</description>
</method>
<method name="font_clear_textures">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
@ -94,8 +100,9 @@
<param index="3" name="pos" type="Vector2" />
<param index="4" name="index" type="int" />
<param index="5" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="6" name="oversampling" type="float" default="0.0" />
<description>
Draws single glyph into a canvas item at the position, using [param font_rid] at the size [param size].
Draws single glyph into a canvas item at the position, using [param font_rid] at the size [param size]. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
[b]Note:[/b] Glyph index is specific to the font, use glyphs indices returned by [method shaped_text_get_glyphs] or [method font_get_glyph_index].
[b]Note:[/b] If there are pending glyphs to render, calling this function might trigger the texture cache update.
</description>
@ -109,8 +116,9 @@
<param index="4" name="pos" type="Vector2" />
<param index="5" name="index" type="int" />
<param index="6" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="7" name="oversampling" type="float" default="0.0" />
<description>
Draws single glyph outline of size [param outline_size] into a canvas item at the position, using [param font_rid] at the size [param size].
Draws single glyph outline of size [param outline_size] into a canvas item at the position, using [param font_rid] at the size [param size]. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
[b]Note:[/b] Glyph index is specific to the font, use glyphs indices returned by [method shaped_text_get_glyphs] or [method font_get_glyph_index].
[b]Note:[/b] If there are pending glyphs to render, calling this function might trigger the texture cache update.
</description>
@ -203,10 +211,10 @@
Returns [code]true[/code] if font texture mipmap generation is enabled.
</description>
</method>
<method name="font_get_global_oversampling" qualifiers="const">
<method name="font_get_global_oversampling" qualifiers="const" deprecated="Use [Viewport] oversampling, or the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
<return type="float" />
<description>
Returns the font oversampling factor, shared by all fonts in the TextServer.
Deprecated. This method always returns [code]1.0[/code].
</description>
</method>
<method name="font_get_glyph_advance" qualifiers="const">
@ -391,11 +399,11 @@
Returns [Dictionary] with OpenType font name strings (localized font names, version, description, license information, sample text, etc.).
</description>
</method>
<method name="font_get_oversampling" qualifiers="const">
<method name="font_get_oversampling" qualifiers="const" deprecated="Use [Viewport] oversampling, or the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
<return type="float" />
<param index="0" name="font_rid" type="RID" />
<description>
Returns font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only.
Deprecated. This method always returns [code]1.0[/code].
</description>
</method>
<method name="font_get_scale" qualifiers="const">
@ -421,6 +429,13 @@
Returns list of script support overrides.
</description>
</method>
<method name="font_get_size_cache_info" qualifiers="const">
<return type="Dictionary[]" />
<param index="0" name="font_rid" type="RID" />
<description>
Returns font cache information, each entry contains the following fields: [code]Vector2i size_px[/code] - font size in pixels, [code]float viewport_oversampling[/code] - viewport oversampling factor, [code]int glyphs[/code] - number of rendered glyphs, [code]int textures[/code] - number of used textures, [code]int textures_size[/code] - size of texture data in bytes.
</description>
</method>
<method name="font_get_size_cache_list" qualifiers="const">
<return type="Vector2i[]" />
<param index="0" name="font_rid" type="RID" />
@ -771,12 +786,11 @@
If set to [code]true[/code] font texture mipmap generation is enabled.
</description>
</method>
<method name="font_set_global_oversampling">
<method name="font_set_global_oversampling" deprecated="Use [Viewport] oversampling, or the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
<return type="void" />
<param index="0" name="oversampling" type="float" />
<description>
Sets oversampling factor, shared by all font in the TextServer.
[b]Note:[/b] This value can be automatically changed by display server.
Deprecated. This method does nothing.
</description>
</method>
<method name="font_set_glyph_advance">
@ -914,12 +928,12 @@
Sets font OpenType feature set override.
</description>
</method>
<method name="font_set_oversampling">
<method name="font_set_oversampling" deprecated="Use [Viewport] oversampling, or the [code skip-lint]oversampling[/code] argument of the [code skip-lint]draw_*[/code] methods instead.">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="oversampling" type="float" />
<description>
Sets font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only.
Deprecated. This method does nothing.
</description>
</method>
<method name="font_set_scale">
@ -1383,8 +1397,9 @@
<param index="3" name="clip_l" type="float" default="-1" />
<param index="4" name="clip_r" type="float" default="-1" />
<param index="5" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="6" name="oversampling" type="float" default="0.0" />
<description>
Draw shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout).
Draw shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="shaped_text_draw_outline" qualifiers="const">
@ -1396,8 +1411,9 @@
<param index="4" name="clip_r" type="float" default="-1" />
<param index="5" name="outline_size" type="int" default="1" />
<param index="6" name="color" type="Color" default="Color(1, 1, 1, 1)" />
<param index="7" name="oversampling" type="float" default="0.0" />
<description>
Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout).
Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="shaped_text_fit_to_width">

View file

@ -78,6 +78,13 @@
Removes all font sizes from the cache entry.
</description>
</method>
<method name="_font_clear_system_fallback_cache" qualifiers="virtual">
<return type="void" />
<description>
[b]Optional.[/b]
Frees all automatically loaded system fonts.
</description>
</method>
<method name="_font_clear_textures" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
@ -95,9 +102,10 @@
<param index="3" name="pos" type="Vector2" />
<param index="4" name="index" type="int" />
<param index="5" name="color" type="Color" />
<param index="6" name="oversampling" type="float" />
<description>
[b]Required.[/b]
Draws single glyph into a canvas item at the position, using [param font_rid] at the size [param size].
Draws single glyph into a canvas item at the position, using [param font_rid] at the size [param size]. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="_font_draw_glyph_outline" qualifiers="virtual const">
@ -109,9 +117,10 @@
<param index="4" name="pos" type="Vector2" />
<param index="5" name="index" type="int" />
<param index="6" name="color" type="Color" />
<param index="7" name="oversampling" type="float" />
<description>
[b]Required.[/b]
Draws single glyph outline of size [param outline_size] into a canvas item at the position, using [param font_rid] at the size [param size].
Draws single glyph outline of size [param outline_size] into a canvas item at the position, using [param font_rid] at the size [param size]. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="_font_get_antialiasing" qualifiers="virtual const">
@ -447,6 +456,14 @@
Returns list of script support overrides.
</description>
</method>
<method name="_font_get_size_cache_info" qualifiers="virtual const">
<return type="Dictionary[]" />
<param index="0" name="font_rid" type="RID" />
<description>
[b]Optional.[/b]
Returns font cache information, each entry contains the following fields: [code]Vector2i size_px[/code] - font size in pixels, [code]float viewport_oversampling[/code] - viewport oversampling factor, [code]int glyphs[/code] - number of rendered glyphs, [code]int textures[/code] - number of used textures, [code]int textures_size[/code] - size of texture data in bytes.
</description>
</method>
<method name="_font_get_size_cache_list" qualifiers="virtual const">
<return type="Vector2i[]" />
<param index="0" name="font_rid" type="RID" />
@ -1315,6 +1332,14 @@
Returns percent sign used in the [param language].
</description>
</method>
<method name="_reference_oversampling_level" qualifiers="virtual">
<return type="void" />
<param index="0" name="oversampling" type="float" />
<description>
[b]Required.[/b]
Increases the reference count of the specified oversampling level. This method is called by [Viewport], and should not be used directly.
</description>
</method>
<method name="_save_support_data" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="filename" type="String" />
@ -1510,9 +1535,10 @@
<param index="3" name="clip_l" type="float" />
<param index="4" name="clip_r" type="float" />
<param index="5" name="color" type="Color" />
<param index="6" name="oversampling" type="float" />
<description>
[b]Optional.[/b]
Draw shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout).
Draw shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="_shaped_text_draw_outline" qualifiers="virtual const">
@ -1524,9 +1550,10 @@
<param index="4" name="clip_r" type="float" />
<param index="5" name="outline_size" type="int" />
<param index="6" name="color" type="Color" />
<param index="7" name="oversampling" type="float" />
<description>
[b]Optional.[/b]
Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout).
Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
</description>
</method>
<method name="_shaped_text_fit_to_width" qualifiers="virtual">
@ -2109,5 +2136,13 @@
Converts OpenType tag to readable feature, variation, script, or language name.
</description>
</method>
<method name="_unreference_oversampling_level" qualifiers="virtual">
<return type="void" />
<param index="0" name="oversampling" type="float" />
<description>
[b]Required.[/b]
Decreases the reference count of the specified oversampling level, and frees the font cache for oversampling level when the reference count reaches zero. This method is called by [Viewport], and should not be used directly.
</description>
</method>
</methods>
</class>

View file

@ -83,6 +83,12 @@
Returns the mouse's position in this [Viewport] using the coordinate system of this [Viewport].
</description>
</method>
<method name="get_oversampling" qualifiers="const">
<return type="float" />
<description>
Returns viewport oversampling factor.
</description>
</method>
<method name="get_positional_shadow_atlas_quadrant_subdiv" qualifiers="const">
<return type="int" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" />
<param index="0" name="quadrant" type="int" />
@ -359,6 +365,12 @@
The multisample antialiasing mode for 3D rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of [constant Viewport.MSAA_2X] or [constant Viewport.MSAA_4X] is best unless targeting very high-end systems. See also bilinear scaling 3D [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing.
See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_3d] and [method RenderingServer.viewport_set_msaa_3d].
</member>
<member name="oversampling" type="bool" setter="set_use_oversampling" getter="is_using_oversampling" default="true">
If [code]true[/code] and one of the following conditions is true: [member SubViewport.size_2d_override_stretch] and [member SubViewport.size_2d_override] are set, [member Window.content_scale_factor] is set and scaling is enabled, [member oversampling_override] is set, font oversampling is enabled.
</member>
<member name="oversampling_override" type="float" setter="set_oversampling_override" getter="get_oversampling_override" default="0.0">
If greater than zero, this value is used as the font oversampling factor, otherwise oversampling is equal to viewport scale.
</member>
<member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false">
If [code]true[/code], the viewport will use a unique copy of the [World3D] defined in [member world_3d].
</member>

View file

@ -4401,7 +4401,7 @@ int Main::start() {
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
bool font_oversampling = GLOBAL_GET("gui/fonts/dynamic_fonts/use_oversampling");
sml->get_root()->set_use_font_oversampling(font_oversampling);
sml->get_root()->set_use_oversampling(font_oversampling);
int texture_filter = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_filter");
int texture_repeat = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_repeat");

View file

@ -48,3 +48,37 @@ GH-71542
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/EditorExportPlatform/methods/get_forced_export_files': arguments
Optional argument added. Compatibility methods registered.
GH-104872
---------
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_char/arguments': size changed value in new API, from 5 to 6.
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_char_outline/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_multiline_string/arguments': size changed value in new API, from 12 to 13.
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_multiline_string_outline/arguments': size changed value in new API, from 13 to 14.
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_string/arguments': size changed value in new API, from 10 to 11.
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_string_outline/arguments': size changed value in new API, from 11 to 12.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_char/arguments': size changed value in new API, from 5 to 6.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_char_outline/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_multiline_string/arguments': size changed value in new API, from 12 to 13.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_multiline_string_outline/arguments': size changed value in new API, from 13 to 14.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_string/arguments': size changed value in new API, from 10 to 11.
Validate extension JSON: Error: Field 'classes/Font/methods/draw_string_outline/arguments': size changed value in new API, from 11 to 12.
Validate extension JSON: Error: Field 'classes/TextLine/methods/draw/arguments': size changed value in new API, from 3 to 4.
Validate extension JSON: Error: Field 'classes/TextLine/methods/draw_outline/arguments': size changed value in new API, from 4 to 5.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw/arguments': size changed value in new API, from 4 to 5.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw_dropcap/arguments': size changed value in new API, from 3 to 4.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw_dropcap_outline/arguments': size changed value in new API, from 4 to 5.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw_line/arguments': size changed value in new API, from 4 to 5.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw_line_outline/arguments': size changed value in new API, from 5 to 6.
Validate extension JSON: Error: Field 'classes/TextParagraph/methods/draw_outline/arguments': size changed value in new API, from 5 to 6.
Validate extension JSON: Error: Field 'classes/TextServer/methods/font_draw_glyph/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/TextServer/methods/font_draw_glyph_outline/arguments': size changed value in new API, from 7 to 8.
Validate extension JSON: Error: Field 'classes/TextServer/methods/shaped_text_draw/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/TextServer/methods/shaped_text_draw_outline/arguments': size changed value in new API, from 7 to 8.
Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_font_draw_glyph/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_font_draw_glyph_outline/arguments': size changed value in new API, from 7 to 8.
Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_shaped_text_draw/arguments': size changed value in new API, from 6 to 7.
Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_shaped_text_draw_outline/arguments': size changed value in new API, from 7 to 8.
Optional "oversmpling" argument added. Compatibility methods registered.

View file

@ -845,7 +845,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
if (ret.index == -1) {
// Could not find texture to fit, create one.
int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
int texsize = MAX(p_data->size.x * 0.125, 256);
texsize = next_power_of_2(texsize);
if (p_msdf) {
@ -1079,7 +1079,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
#ifdef MODULE_FREETYPE_ENABLED
_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap p_bitmap, int p_yofs, int p_xofs, const Vector2 &p_advance, bool p_bgra) const {
FontGlyph chr;
chr.advance = p_advance * p_data->scale / p_data->oversampling;
chr.advance = p_advance * p_data->scale;
chr.found = true;
int w = p_bitmap.width;
@ -1192,8 +1192,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
chr.texture_idx = tex_pos.index;
chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2);
chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale / p_data->oversampling;
chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling;
chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale;
chr.rect.size = chr.uv_rect.size * p_data->scale;
return chr;
}
#endif
@ -1202,9 +1202,9 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
/* Font Cache */
/*************************************************************************/
_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph) const {
_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph, uint32_t p_oversampling) const {
FontForSizeAdvanced *fd = nullptr;
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd, false, p_oversampling), false);
int32_t glyph_index = p_glyph & 0xffffff; // Remove subpixel shifts.
@ -1258,17 +1258,17 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
}
if (!p_font_data->msdf) {
if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 4;
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
} else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 5;
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
}
}
if (p_font_data->embolden != 0.f) {
FT_Pos strength = p_font_data->embolden * p_size.x * fd->oversampling * 4; // 26.6 fractional units (1 / 64).
FT_Pos strength = p_font_data->embolden * p_size.x / 16; // 26.6 fractional units (1 / 64).
FT_Outline_Embolden(&fd->face->glyph->outline, strength);
}
@ -1337,7 +1337,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph stroker.");
}
FT_Stroker_Set(stroker, (int)(fd->size.y * fd->oversampling * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Stroker_Set(stroker, (int)(fd->size.y * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Glyph glyph;
FT_BitmapGlyph glyph_bitmap;
@ -1369,12 +1369,19 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
return false;
}
_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent) const {
_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent, uint32_t p_oversampling) const {
ERR_FAIL_COND_V(p_size.x <= 0, false);
HashMap<Vector2i, FontForSizeAdvanced *>::Iterator E = p_font_data->cache.find(p_size);
if (E) {
r_cache_for_size = E->value;
// Size used directly, remove from oversampling list.
if (p_oversampling == 0 && E->value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E->value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E->value);
}
}
return true;
}
@ -1428,41 +1435,44 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
}
}
double sz = double(fd->size.x) / 64.0;
if (p_font_data->msdf) {
fd->oversampling = 1.0;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0) {
fd->oversampling = _font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
sz = p_font_data->msdf_source_size;
}
if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) {
int best_match = 0;
int diff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
int diff = Math::abs(sz - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = sz / fd->face->available_sizes[0].width;
for (int i = 1; i < fd->face->num_fixed_sizes; i++) {
int ndiff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[i].width));
int ndiff = Math::abs(sz - ((int64_t)fd->face->available_sizes[i].width));
if (ndiff < diff) {
best_match = i;
diff = ndiff;
fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
fd->scale = sz / fd->face->available_sizes[i].width;
}
}
FT_Select_Size(fd->face, best_match);
} else {
FT_Set_Pixel_Sizes(fd->face, 0, double(fd->size.x * fd->oversampling));
FT_Size_RequestRec req;
req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
req.width = sz * 64.0;
req.height = sz * 64.0;
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(fd->face, &req);
if (fd->face->size->metrics.y_ppem != 0) {
fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem;
fd->scale = sz / (double)fd->face->size->metrics.y_ppem;
}
}
fd->hb_handle = hb_ft_font_create(fd->face, nullptr);
fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale;
fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->oversampling * fd->scale;
fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->scale;
fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->scale;
fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
#if HB_VERSION_ATLEAST(3, 3, 0)
hb_font_set_synthetic_slant(fd->hb_handle, p_font_data->transform[0][1]);
@ -1869,11 +1879,53 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
// Init bitmap font.
fd->hb_handle = _bmp_font_create(fd, nullptr);
}
fd->owner = p_font_data;
p_font_data->cache.insert(p_size, fd);
r_cache_for_size = fd;
if (p_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(p_oversampling);
if (ol) {
fd->viewport_oversampling = p_oversampling;
ol->fonts.insert(fd);
}
}
return true;
}
void TextServerAdvanced::_reference_oversampling_level(double p_oversampling) {
uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
if (oversampling == 64) {
return;
}
OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
if (ol) {
ol->refcount++;
} else {
OversamplingLevel new_ol;
oversampling_levels.insert(oversampling, new_ol);
}
}
void TextServerAdvanced::_unreference_oversampling_level(double p_oversampling) {
uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
if (oversampling == 64) {
return;
}
OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
if (ol) {
ol->refcount--;
if (ol->refcount == 0) {
for (FontForSizeAdvanced *fd : ol->fonts) {
fd->owner->cache.erase(fd->size);
memdelete(fd);
}
ol->fonts.clear();
oversampling_levels.erase(oversampling);
}
}
}
_FORCE_INLINE_ bool TextServerAdvanced::_font_validate(const RID &p_font_rid) const {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, false);
@ -1888,6 +1940,12 @@ _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontAdvanced *p_font_d
MutexLock ftlock(ft_mutex);
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : p_font_data->cache) {
if (E.value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E.value);
}
}
memdelete(E.value);
}
p_font_data->cache.clear();
@ -2623,25 +2681,6 @@ Dictionary TextServerAdvanced::_font_get_variation_coordinates(const RID &p_font
return fd->variation_coordinates;
}
void TextServerAdvanced::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
if (fd->oversampling != p_oversampling) {
_font_clear_cache(fd);
fd->oversampling = p_oversampling;
}
}
double TextServerAdvanced::_font_get_oversampling(const RID &p_font_rid) const {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, 0.0);
MutexLock lock(fd->mutex);
return fd->oversampling;
}
TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_font_rid) const {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, TypedArray<Vector2i>());
@ -2649,8 +2688,35 @@ TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_
MutexLock lock(fd->mutex);
TypedArray<Vector2i> ret;
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
ret.push_back(E.key);
if ((E.key.x % 64 == 0) && (E.value->viewport_oversampling == 0)) {
ret.push_back(Vector2i(E.key.x / 64, E.key.y));
}
}
return ret;
}
TypedArray<Dictionary> TextServerAdvanced::_font_get_size_cache_info(const RID &p_font_rid) const {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, TypedArray<Dictionary>());
MutexLock lock(fd->mutex);
TypedArray<Dictionary> ret;
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
Dictionary size_info;
size_info["size_px"] = Vector2i(E.key.x / 64, E.key.y);
if (E.value->viewport_oversampling) {
size_info["viewport_oversampling"] = double(E.value->viewport_oversampling) / 64.0;
}
size_info["glyphs"] = E.value->glyph_map.size();
size_info["textures"] = E.value->textures.size();
uint64_t sz = 0;
for (const ShelfPackTexture &tx : E.value->textures) {
sz += tx.image->get_data_size() * 2;
}
size_info["textures_size"] = sz;
ret.push_back(size_info);
}
return ret;
}
@ -2661,6 +2727,12 @@ void TextServerAdvanced::_font_clear_size_cache(const RID &p_font_rid) {
MutexLock lock(fd->mutex);
MutexLock ftlock(ft_mutex);
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
if (E.value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E.value);
}
}
memdelete(E.value);
}
fd->cache.clear();
@ -2672,9 +2744,16 @@ void TextServerAdvanced::_font_remove_size_cache(const RID &p_font_rid, const Ve
MutexLock lock(fd->mutex);
MutexLock ftlock(ft_mutex);
if (fd->cache.has(p_size)) {
memdelete(fd->cache[p_size]);
fd->cache.erase(p_size);
Vector2i size = Vector2i(p_size.x * 64, p_size.y);
if (fd->cache.has(size)) {
if (fd->cache[size]->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(fd->cache[size]->viewport_oversampling);
if (ol) {
ol->fonts.erase(fd->cache[size]);
}
}
memdelete(fd->cache[size]);
fd->cache.erase(size);
}
}
@ -2702,7 +2781,7 @@ double TextServerAdvanced::_font_get_ascent(const RID &p_font_rid, int64_t p_siz
if (fd->msdf) {
return ffsd->ascent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->ascent * (double)p_size / (double)fd->fixed_size;
} else {
@ -2736,7 +2815,7 @@ double TextServerAdvanced::_font_get_descent(const RID &p_font_rid, int64_t p_si
if (fd->msdf) {
return ffsd->descent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->descent * (double)p_size / (double)fd->fixed_size;
} else {
@ -2771,7 +2850,7 @@ double TextServerAdvanced::_font_get_underline_position(const RID &p_font_rid, i
if (fd->msdf) {
return ffsd->underline_position * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->underline_position * (double)p_size / (double)fd->fixed_size;
} else {
@ -2806,7 +2885,7 @@ double TextServerAdvanced::_font_get_underline_thickness(const RID &p_font_rid,
if (fd->msdf) {
return ffsd->underline_thickness * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->underline_thickness * (double)p_size / (double)fd->fixed_size;
} else {
@ -2847,14 +2926,14 @@ double TextServerAdvanced::_font_get_scale(const RID &p_font_rid, int64_t p_size
if (fd->msdf) {
return ffsd->scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->scale * (double)p_size / (double)fd->fixed_size;
} else {
return ffsd->scale * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return ffsd->scale / ffsd->oversampling;
return ffsd->scale;
}
}
@ -3034,7 +3113,7 @@ double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) c
Vector2i size = _get_size(fd, p_font_size);
if (fd->embolden != 0.0) {
return fd->embolden * double(size.x) / 64.0;
return fd->embolden * double(size.x) / 4096.0;
} else {
return 0.0;
}
@ -3065,19 +3144,19 @@ Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64
Vector2 ea;
if (fd->embolden != 0.0) {
ea.x = fd->embolden * double(size.x) / 64.0;
ea.x = fd->embolden * double(size.x) / 4096.0;
}
double scale = _font_get_scale(p_font_rid, p_size);
if (fd->msdf) {
return (fgl.advance + ea) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return (fgl.advance + ea) * (double)p_size / (double)fd->fixed_size;
} else {
return (fgl.advance + ea) * Math::round((double)p_size / (double)fd->fixed_size);
}
} else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) {
} else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64))) {
return (fgl.advance + ea).round();
} else {
return fgl.advance + ea;
@ -3125,7 +3204,7 @@ Vector2 TextServerAdvanced::_font_get_glyph_offset(const RID &p_font_rid, const
if (fd->msdf) {
return fgl.rect.position * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fgl.rect.position * (double)p_size.x / (double)fd->fixed_size;
} else {
@ -3177,7 +3256,7 @@ Vector2 TextServerAdvanced::_font_get_glyph_size(const RID &p_font_rid, const Ve
if (fd->msdf) {
return fgl.rect.size * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fgl.rect.size * (double)p_size.x / (double)fd->fixed_size;
} else {
@ -3412,7 +3491,7 @@ Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, i
ERR_FAIL_COND_V(error, Dictionary());
if (fd->embolden != 0.f) {
FT_Pos strength = fd->embolden * p_size * 4; // 26.6 fractional units (1 / 64).
FT_Pos strength = fd->embolden * size.x / 16; // 26.6 fractional units (1 / 64).
FT_Outline_Embolden(&ffsd->face->glyph->outline, strength);
}
@ -3421,10 +3500,10 @@ Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, i
FT_Outline_Transform(&ffsd->face->glyph->outline, &mat);
}
double scale = (1.0 / 64.0) / ffsd->oversampling * ffsd->scale;
double scale = (1.0 / 64.0) * ffsd->scale;
if (fd->msdf) {
scale = scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
scale = scale * (double)p_size / (double)fd->fixed_size;
} else {
@ -3517,7 +3596,7 @@ Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_s
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->fixed_size;
} else {
@ -3533,7 +3612,7 @@ Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_s
FT_Get_Kerning(ffsd->face, p_glyph_pair.x, p_glyph_pair.y, FT_KERNING_DEFAULT, &delta);
if (fd->msdf) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->fixed_size;
} else {
@ -3616,7 +3695,7 @@ bool TextServerAdvanced::_font_has_char(const RID &p_font_rid, int64_t p_char) c
MutexLock lock(fd->mutex);
FontForSizeAdvanced *ffsd = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), false);
} else {
ffsd = fd->cache.begin()->value;
}
@ -3636,7 +3715,7 @@ String TextServerAdvanced::_font_get_supported_chars(const RID &p_font_rid) cons
MutexLock lock(fd->mutex);
FontForSizeAdvanced *ffsd = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), String());
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), String());
} else {
ffsd = fd->cache.begin()->value;
}
@ -3669,7 +3748,7 @@ PackedInt32Array TextServerAdvanced::_font_get_supported_glyphs(const RID &p_fon
MutexLock lock(fd->mutex);
FontForSizeAdvanced *at_size = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), at_size), PackedInt32Array());
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), at_size), PackedInt32Array());
} else {
at_size = fd->cache.begin()->value;
}
@ -3714,12 +3793,12 @@ void TextServerAdvanced::_font_render_range(const RID &p_font_rid, const Vector2
_ensure_glyph(fd, size, (int32_t)idx, fgl);
} else {
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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
} else {
@ -3748,12 +3827,12 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2
_ensure_glyph(fd, size, (int32_t)idx, fgl);
} else {
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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
} else {
@ -3765,7 +3844,7 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2
#endif
}
void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
if (p_index == 0) {
return; // Non visual character, skip.
}
@ -3773,9 +3852,31 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size(fd, p_size);
// Oversampling.
bool viewport_oversampling = false;
float oversampling_factor = p_oversampling;
if (p_oversampling <= 0.0) {
if (vp_oversampling > 0.0) {
oversampling_factor = vp_oversampling;
viewport_oversampling = true;
} else {
oversampling_factor = 1.0;
}
}
bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
oversampling_factor = double(oversampling_level) / 64.0;
Vector2i size;
if (skip_oversampling) {
size = _get_size(fd, p_size);
} else {
size = Vector2i(p_size * 64 * oversampling_factor, 0);
}
FontForSizeAdvanced *ffsd = nullptr;
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
bool lcd_aa = false;
@ -3791,10 +3892,10 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
}
// 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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
index = index | (xshift << 27);
}
@ -3802,7 +3903,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
#endif
FontGlyph fgl;
if (!_ensure_glyph(fd, size, index, fgl)) {
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
}
@ -3842,11 +3943,11 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
Size2 csize = fgl.rect.size * (double)p_size / (double)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, 0, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
} else {
double scale = _font_get_scale(p_font_rid, p_size);
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
Point2 cpos = p_pos;
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
cpos.x = cpos.x + 0.25;
}
if (scale == 1.0) {
@ -3855,7 +3956,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
Vector2 gpos = fgl.rect.position;
Size2 csize = fgl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
@ -3865,6 +3966,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
gpos *= gl_scale;
csize *= gl_scale;
}
} else {
gpos /= oversampling_factor;
csize /= oversampling_factor;
}
cpos += gpos;
if (lcd_aa) {
@ -3878,7 +3982,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
}
void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
if (p_index == 0) {
return; // Non visual character, skip.
}
@ -3886,9 +3990,31 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
// Oversampling.
bool viewport_oversampling = false;
float oversampling_factor = p_oversampling;
if (p_oversampling <= 0.0) {
if (vp_oversampling > 0.0) {
oversampling_factor = vp_oversampling;
viewport_oversampling = true;
} else {
oversampling_factor = 1.0;
}
}
bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
oversampling_factor = double(oversampling_level) / 64.0;
Vector2i size;
if (skip_oversampling) {
size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
} else {
size = Vector2i(p_size * 64 * oversampling_factor, p_outline_size);
}
FontForSizeAdvanced *ffsd = nullptr;
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
bool lcd_aa = false;
@ -3904,10 +4030,10 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
}
}
// 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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
index = index | (xshift << 27);
}
@ -3915,7 +4041,7 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
#endif
FontGlyph fgl;
if (!_ensure_glyph(fd, size, index, fgl)) {
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
}
@ -3952,10 +4078,10 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, p_outline_size, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
} else {
Point2 cpos = p_pos;
double scale = _font_get_scale(p_font_rid, p_size);
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
cpos.x = cpos.x + 0.25;
}
if (scale == 1.0) {
@ -3964,7 +4090,7 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
}
Vector2 gpos = fgl.rect.position;
Size2 csize = fgl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
@ -3974,6 +4100,9 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
gpos *= gl_scale;
csize *= gl_scale;
}
} else {
gpos /= oversampling_factor;
csize /= oversampling_factor;
}
cpos += gpos;
if (lcd_aa) {
@ -4127,34 +4256,6 @@ Dictionary TextServerAdvanced::_font_supported_variation_list(const RID &p_font_
return fd->supported_varaitions;
}
double TextServerAdvanced::_font_get_global_oversampling() const {
return oversampling;
}
void TextServerAdvanced::_font_set_global_oversampling(double p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
List<RID> fonts;
font_owner.get_owned_list(&fonts);
bool font_cleared = false;
for (const RID &E : fonts) {
if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
_font_clear_size_cache(E);
font_cleared = true;
}
}
if (font_cleared) {
List<RID> text_bufs;
shaped_owner.get_owned_list(&text_bufs);
for (const RID &E : text_bufs) {
invalidate(shaped_owner.get_or_null(E), false);
}
}
}
}
/*************************************************************************/
/* Shaped text buffer interface */
/*************************************************************************/
@ -5514,7 +5615,6 @@ RID TextServerAdvanced::_find_sys_font_for_text(const RID &p_fdef, const String
_font_set_subpixel_positioning(sysf.rid, key.subpixel_positioning);
_font_set_keep_rounding_remainders(sysf.rid, key.keep_rounding_remainders);
_font_set_variation_coordinates(sysf.rid, var);
_font_set_oversampling(sysf.rid, key.oversampling);
_font_set_embolden(sysf.rid, key.embolden);
_font_set_transform(sysf.rid, key.transform);
_font_set_spacing(sysf.rid, SPACING_TOP, key.extra_spacing[SPACING_TOP]);
@ -7931,7 +8031,7 @@ TextServerAdvanced::TextServerAdvanced() {
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &TextServerAdvanced::_update_settings));
}
void TextServerAdvanced::_cleanup() {
void TextServerAdvanced::_font_clear_system_fallback_cache() {
_THREAD_SAFE_METHOD_
for (const KeyValue<SystemFontKey, SystemFontCache> &E : system_fonts) {
const Vector<SystemFontCacheRec> &sysf_cache = E.value.var;
@ -7943,6 +8043,10 @@ void TextServerAdvanced::_cleanup() {
system_font_data.clear();
}
void TextServerAdvanced::_cleanup() {
font_clear_system_fallback_cache();
}
TextServerAdvanced::~TextServerAdvanced() {
_bmp_free_font_funcs();
#ifdef MODULE_FREETYPE_ENABLED

View file

@ -269,13 +269,16 @@ class TextServerAdvanced : public TextServerExtension {
bool from_svg = false;
};
struct FontAdvanced;
struct FontForSizeAdvanced {
double ascent = 0.0;
double descent = 0.0;
double underline_position = 0.0;
double underline_thickness = 0.0;
double scale = 1.0;
double oversampling = 1.0;
FontAdvanced *owner = nullptr;
uint32_t viewport_oversampling = 0;
Vector2i size;
@ -302,6 +305,13 @@ class TextServerAdvanced : public TextServerExtension {
}
};
struct OversamplingLevel {
HashSet<FontForSizeAdvanced *> fonts;
int32_t refcount = 1;
};
mutable HashMap<uint32_t, OversamplingLevel> oversampling_levels;
struct FontAdvancedLinkedVariation {
RID base_font;
int extra_spacing[4] = { 0, 0, 0, 0 };
@ -326,7 +336,6 @@ class TextServerAdvanced : public TextServerExtension {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
Dictionary variation_coordinates;
double oversampling = 0.0;
double embolden = 0.0;
Transform2D transform;
@ -370,29 +379,29 @@ class TextServerAdvanced : public TextServerExtension {
#ifdef MODULE_FREETYPE_ENABLED
_FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap p_bitmap, int p_yofs, int p_xofs, const Vector2 &p_advance, bool p_bgra) const;
#endif
_FORCE_INLINE_ bool _ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent = false) const;
_FORCE_INLINE_ bool _ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph, uint32_t p_oversampling = 0) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent = false, uint32_t p_oversampling = 0) const;
_FORCE_INLINE_ bool _font_validate(const RID &p_font_rid) const;
_FORCE_INLINE_ void _font_clear_cache(FontAdvanced *p_font_data);
static void _generateMTSDF_threaded(void *p_td, uint32_t p_y);
_FORCE_INLINE_ Vector2i _get_size(const FontAdvanced *p_font_data, int p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
return Vector2i(p_font_data->msdf_source_size * 64, 0);
} else if (p_font_data->fixed_size > 0) {
return Vector2i(p_font_data->fixed_size, 0);
return Vector2i(p_font_data->fixed_size * 64, 0);
} else {
return Vector2i(p_size, 0);
return Vector2i(p_size * 64, 0);
}
}
_FORCE_INLINE_ Vector2i _get_size_outline(const FontAdvanced *p_font_data, const Vector2i &p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
return Vector2i(p_font_data->msdf_source_size * 64, 0);
} else if (p_font_data->fixed_size > 0) {
return Vector2i(p_font_data->fixed_size, MIN(p_size.y, 1));
return Vector2i(p_font_data->fixed_size * 64, MIN(p_size.y, 1));
} else {
return p_size;
return Vector2i(p_size.x * 64, p_size.y);
}
}
@ -569,7 +578,6 @@ class TextServerAdvanced : public TextServerExtension {
// Common data.
double oversampling = 1.0;
mutable RID_PtrOwner<FontAdvancedLinkedVariation> font_var_owner;
mutable RID_PtrOwner<FontAdvanced> font_owner;
mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
@ -600,14 +608,13 @@ class TextServerAdvanced : public TextServerExtension {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
Dictionary variation_coordinates;
double oversampling = 0.0;
double embolden = 0.0;
Transform2D transform;
int extra_spacing[4] = { 0, 0, 0, 0 };
double baseline_offset = 0.0;
bool operator==(const SystemFontKey &p_b) const {
return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (keep_rounding_remainders == p_b.keep_rounding_remainders) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset);
return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (keep_rounding_remainders == p_b.keep_rounding_remainders) && (variation_coordinates == p_b.variation_coordinates) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset);
}
SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerAdvanced *p_fb) {
@ -627,7 +634,6 @@ class TextServerAdvanced : public TextServerExtension {
subpixel_positioning = p_fb->_font_get_subpixel_positioning(p_font);
keep_rounding_remainders = p_fb->_font_get_keep_rounding_remainders(p_font);
variation_coordinates = p_fb->_font_get_variation_coordinates(p_font);
oversampling = p_fb->_font_get_oversampling(p_font);
embolden = p_fb->_font_get_embolden(p_font);
transform = p_fb->_font_get_transform(p_font);
extra_spacing[SPACING_TOP] = p_fb->_font_get_spacing(p_font, SPACING_TOP);
@ -657,7 +663,6 @@ class TextServerAdvanced : public TextServerExtension {
hash = hash_murmur3_one_32(p_a.msdf_range, hash);
hash = hash_murmur3_one_32(p_a.msdf_source_size, hash);
hash = hash_murmur3_one_32(p_a.fixed_size, hash);
hash = hash_murmur3_one_double(p_a.oversampling, hash);
hash = hash_murmur3_one_double(p_a.embolden, hash);
hash = hash_murmur3_one_real(p_a.transform[0].x, hash);
hash = hash_murmur3_one_real(p_a.transform[0].y, hash);
@ -807,6 +812,7 @@ public:
MODBIND2(font_set_allow_system_fallback, const RID &, bool);
MODBIND1RC(bool, font_is_allow_system_fallback, const RID &);
MODBIND0(font_clear_system_fallback_cache);
MODBIND2(font_set_force_autohinter, const RID &, bool);
MODBIND1RC(bool, font_is_force_autohinter, const RID &);
@ -838,12 +844,10 @@ public:
MODBIND2(font_set_hinting, const RID &, TextServer::Hinting);
MODBIND1RC(TextServer::Hinting, font_get_hinting, const RID &);
MODBIND2(font_set_oversampling, const RID &, double);
MODBIND1RC(double, font_get_oversampling, const RID &);
MODBIND1RC(TypedArray<Vector2i>, font_get_size_cache_list, const RID &);
MODBIND1(font_clear_size_cache, const RID &);
MODBIND2(font_remove_size_cache, const RID &, const Vector2i &);
MODBIND1RC(TypedArray<Dictionary>, font_get_size_cache_info, const RID &);
MODBIND3(font_set_ascent, const RID &, int64_t, double);
MODBIND2RC(double, font_get_ascent, const RID &, int64_t);
@ -911,8 +915,8 @@ public:
MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
MODBIND3(font_render_glyph, const RID &, const Vector2i &, int64_t);
MODBIND6C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &);
MODBIND7C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
MODBIND7C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &, float);
MODBIND8C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float);
MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
@ -932,8 +936,8 @@ public:
MODBIND1RC(Dictionary, font_supported_feature_list, const RID &);
MODBIND1RC(Dictionary, font_supported_variation_list, const RID &);
MODBIND0RC(double, font_get_global_oversampling);
MODBIND1(font_set_global_oversampling, double);
MODBIND1(reference_oversampling_level, double);
MODBIND1(unreference_oversampling_level, double);
/* Shaped text buffer interface */

View file

@ -267,7 +267,7 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
if (ret.index == -1) {
// Could not find texture to fit, create one.
int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
int texsize = MAX(p_data->size.x * 0.125, 256);
texsize = next_power_of_2(texsize);
@ -500,7 +500,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
#ifdef MODULE_FREETYPE_ENABLED
_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap p_bitmap, int p_yofs, int p_xofs, const Vector2 &p_advance, bool p_bgra) const {
FontGlyph chr;
chr.advance = p_advance * p_data->scale / p_data->oversampling;
chr.advance = p_advance * p_data->scale;
chr.found = true;
int w = p_bitmap.width;
@ -613,8 +613,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
chr.texture_idx = tex_pos.index;
chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2);
chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale / p_data->oversampling;
chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling;
chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale;
chr.rect.size = chr.uv_rect.size * p_data->scale;
return chr;
}
#endif
@ -623,9 +623,9 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
/* Font Cache */
/*************************************************************************/
_FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph) const {
_FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph, uint32_t p_oversampling) const {
FontForSizeFallback *fd = nullptr;
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd, false, p_oversampling), false);
int32_t glyph_index = p_glyph & 0xffffff; // Remove subpixel shifts.
@ -681,17 +681,17 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
}
if (!p_font_data->msdf) {
if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 4;
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
} else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 5;
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
}
}
if (p_font_data->embolden != 0.f) {
FT_Pos strength = p_font_data->embolden * p_size.x * fd->oversampling * 4; // 26.6 fractional units (1 / 64).
FT_Pos strength = p_font_data->embolden * p_size.x / 16; // 26.6 fractional units (1 / 64).
FT_Outline_Embolden(&fd->face->glyph->outline, strength);
}
@ -760,7 +760,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph stroker.");
}
FT_Stroker_Set(stroker, (int)(fd->size.y * fd->oversampling * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Stroker_Set(stroker, (int)(fd->size.y * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Glyph glyph;
FT_BitmapGlyph glyph_bitmap;
@ -792,12 +792,19 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
return false;
}
_FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size, FontForSizeFallback *&r_cache_for_size, bool p_silent) const {
_FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size, FontForSizeFallback *&r_cache_for_size, bool p_silent, uint32_t p_oversampling) const {
ERR_FAIL_COND_V(p_size.x <= 0, false);
HashMap<Vector2i, FontForSizeFallback *>::Iterator E = p_font_data->cache.find(p_size);
if (E) {
r_cache_for_size = E->value;
// Size used directly, remove from oversampling list.
if (p_oversampling == 0 && E->value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E->value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E->value);
}
}
return true;
}
@ -860,39 +867,42 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
}
}
double sz = double(fd->size.x) / 64.0;
if (p_font_data->msdf) {
fd->oversampling = 1.0;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0) {
fd->oversampling = _font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
sz = p_font_data->msdf_source_size;
}
if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) {
int best_match = 0;
int diff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
int diff = Math::abs(sz - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = sz / fd->face->available_sizes[0].width;
for (int i = 1; i < fd->face->num_fixed_sizes; i++) {
int ndiff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[i].width));
int ndiff = Math::abs(sz - ((int64_t)fd->face->available_sizes[i].width));
if (ndiff < diff) {
best_match = i;
diff = ndiff;
fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
fd->scale = sz / fd->face->available_sizes[i].width;
}
}
FT_Select_Size(fd->face, best_match);
} else {
FT_Set_Pixel_Sizes(fd->face, 0, Math::round(fd->size.x * fd->oversampling));
FT_Size_RequestRec req;
req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
req.width = sz * 64.0;
req.height = sz * 64.0;
req.horiResolution = 0;
req.vertResolution = 0;
FT_Request_Size(fd->face, &req);
if (fd->face->size->metrics.y_ppem != 0) {
fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem;
fd->scale = sz / (double)fd->face->size->metrics.y_ppem;
}
}
fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale;
fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->oversampling * fd->scale;
fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->scale;
fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->scale;
fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
if (!p_font_data->face_init) {
// When a font does not provide a `family_name`, FreeType tries to synthesize one based on other names.
@ -999,11 +1009,52 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
#endif
}
fd->owner = p_font_data;
p_font_data->cache.insert(p_size, fd);
r_cache_for_size = fd;
if (p_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(p_oversampling);
if (ol) {
fd->viewport_oversampling = p_oversampling;
ol->fonts.insert(fd);
}
}
return true;
}
void TextServerFallback::_reference_oversampling_level(double p_oversampling) {
uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
if (oversampling == 64) {
return;
}
OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
if (ol) {
ol->refcount++;
} else {
OversamplingLevel new_ol;
oversampling_levels.insert(oversampling, new_ol);
}
}
void TextServerFallback::_unreference_oversampling_level(double p_oversampling) {
uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
if (oversampling == 64) {
return;
}
OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
if (ol) {
ol->refcount--;
if (ol->refcount == 0) {
for (FontForSizeFallback *fd : ol->fonts) {
fd->owner->cache.erase(fd->size);
memdelete(fd);
}
ol->fonts.clear();
oversampling_levels.erase(oversampling);
}
}
}
_FORCE_INLINE_ bool TextServerFallback::_font_validate(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, false);
@ -1018,6 +1069,12 @@ _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontFallback *p_font_d
MutexLock ftlock(ft_mutex);
for (const KeyValue<Vector2i, FontForSizeFallback *> &E : p_font_data->cache) {
if (E.value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E.value);
}
}
memdelete(E.value);
}
@ -1626,25 +1683,6 @@ Dictionary TextServerFallback::_font_get_variation_coordinates(const RID &p_font
return fd->variation_coordinates;
}
void TextServerFallback::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
if (fd->oversampling != p_oversampling) {
_font_clear_cache(fd);
fd->oversampling = p_oversampling;
}
}
double TextServerFallback::_font_get_oversampling(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, 0.0);
MutexLock lock(fd->mutex);
return fd->oversampling;
}
TypedArray<Vector2i> TextServerFallback::_font_get_size_cache_list(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, TypedArray<Vector2i>());
@ -1652,8 +1690,35 @@ TypedArray<Vector2i> TextServerFallback::_font_get_size_cache_list(const RID &p_
MutexLock lock(fd->mutex);
TypedArray<Vector2i> ret;
for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
ret.push_back(E.key);
if ((E.key.x % 64 == 0) && (E.value->viewport_oversampling == 0)) {
ret.push_back(Vector2i(E.key.x / 64, E.key.y));
}
}
return ret;
}
TypedArray<Dictionary> TextServerFallback::_font_get_size_cache_info(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, TypedArray<Dictionary>());
MutexLock lock(fd->mutex);
TypedArray<Dictionary> ret;
for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
Dictionary size_info;
size_info["size_px"] = Vector2i(E.key.x / 64, E.key.y);
if (E.value->viewport_oversampling) {
size_info["viewport_oversampling"] = double(E.value->viewport_oversampling) / 64.0;
}
size_info["glyphs"] = E.value->glyph_map.size();
size_info["textures"] = E.value->textures.size();
uint64_t sz = 0;
for (const ShelfPackTexture &tx : E.value->textures) {
sz += tx.image->get_data_size() * 2;
}
size_info["textures_size"] = sz;
ret.push_back(size_info);
}
return ret;
}
@ -1664,6 +1729,12 @@ void TextServerFallback::_font_clear_size_cache(const RID &p_font_rid) {
MutexLock lock(fd->mutex);
MutexLock ftlock(ft_mutex);
for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
if (E.value->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
if (ol) {
ol->fonts.erase(E.value);
}
}
memdelete(E.value);
}
fd->cache.clear();
@ -1675,9 +1746,16 @@ void TextServerFallback::_font_remove_size_cache(const RID &p_font_rid, const Ve
MutexLock lock(fd->mutex);
MutexLock ftlock(ft_mutex);
if (fd->cache.has(p_size)) {
memdelete(fd->cache[p_size]);
fd->cache.erase(p_size);
Vector2i size = Vector2i(p_size.x * 64, p_size.y);
if (fd->cache.has(size)) {
if (fd->cache[size]->viewport_oversampling != 0) {
OversamplingLevel *ol = oversampling_levels.getptr(fd->cache[size]->viewport_oversampling);
if (ol) {
ol->fonts.erase(fd->cache[size]);
}
}
memdelete(fd->cache[size]);
fd->cache.erase(size);
}
}
@ -1705,7 +1783,7 @@ double TextServerFallback::_font_get_ascent(const RID &p_font_rid, int64_t p_siz
if (fd->msdf) {
return ffsd->ascent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->ascent * (double)p_size / (double)fd->fixed_size;
} else {
@ -1739,7 +1817,7 @@ double TextServerFallback::_font_get_descent(const RID &p_font_rid, int64_t p_si
if (fd->msdf) {
return ffsd->descent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->descent * (double)p_size / (double)fd->fixed_size;
} else {
@ -1774,7 +1852,7 @@ double TextServerFallback::_font_get_underline_position(const RID &p_font_rid, i
if (fd->msdf) {
return ffsd->underline_position * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->underline_position * (double)p_size / (double)fd->fixed_size;
} else {
@ -1809,7 +1887,7 @@ double TextServerFallback::_font_get_underline_thickness(const RID &p_font_rid,
if (fd->msdf) {
return ffsd->underline_thickness * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->underline_thickness * (double)p_size / (double)fd->fixed_size;
} else {
@ -1849,14 +1927,14 @@ double TextServerFallback::_font_get_scale(const RID &p_font_rid, int64_t p_size
if (fd->msdf) {
return ffsd->scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return ffsd->scale * (double)p_size / (double)fd->fixed_size;
} else {
return ffsd->scale * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return ffsd->scale / ffsd->oversampling;
return ffsd->scale;
}
}
@ -2053,19 +2131,19 @@ Vector2 TextServerFallback::_font_get_glyph_advance(const RID &p_font_rid, int64
Vector2 ea;
if (fd->embolden != 0.0) {
ea.x = fd->embolden * double(size.x) / 64.0;
ea.x = fd->embolden * double(size.x) / 4096.0;
}
double scale = _font_get_scale(p_font_rid, p_size);
if (fd->msdf) {
return (fgl.advance + ea) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return (fgl.advance + ea) * (double)p_size / (double)fd->fixed_size;
} else {
return (fgl.advance + ea) * Math::round((double)p_size / (double)fd->fixed_size);
}
} else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) {
} else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64))) {
return (fgl.advance + ea).round();
} else {
return fgl.advance + ea;
@ -2113,7 +2191,7 @@ Vector2 TextServerFallback::_font_get_glyph_offset(const RID &p_font_rid, const
if (fd->msdf) {
return fgl.rect.position * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fgl.rect.position * (double)p_size.x / (double)fd->fixed_size;
} else {
@ -2165,7 +2243,7 @@ Vector2 TextServerFallback::_font_get_glyph_size(const RID &p_font_rid, const Ve
if (fd->msdf) {
return fgl.rect.size * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fgl.rect.size * (double)p_size.x / (double)fd->fixed_size;
} else {
@ -2400,7 +2478,7 @@ Dictionary TextServerFallback::_font_get_glyph_contours(const RID &p_font_rid, i
ERR_FAIL_COND_V(error, Dictionary());
if (fd->embolden != 0.f) {
FT_Pos strength = fd->embolden * p_size * 4; // 26.6 fractional units (1 / 64).
FT_Pos strength = fd->embolden * size.x / 16; // 26.6 fractional units (1 / 64).
FT_Outline_Embolden(&ffsd->face->glyph->outline, strength);
}
@ -2409,10 +2487,10 @@ Dictionary TextServerFallback::_font_get_glyph_contours(const RID &p_font_rid, i
FT_Outline_Transform(&ffsd->face->glyph->outline, &mat);
}
double scale = (1.0 / 64.0) / ffsd->oversampling * ffsd->scale;
double scale = (1.0 / 64.0) * ffsd->scale;
if (fd->msdf) {
scale = scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
scale = scale * (double)p_size / (double)fd->fixed_size;
} else {
@ -2505,7 +2583,7 @@ Vector2 TextServerFallback::_font_get_kerning(const RID &p_font_rid, int64_t p_s
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->fixed_size;
} else {
@ -2523,7 +2601,7 @@ Vector2 TextServerFallback::_font_get_kerning(const RID &p_font_rid, int64_t p_s
FT_Get_Kerning(ffsd->face, glyph_a, glyph_b, FT_KERNING_DEFAULT, &delta);
if (fd->msdf) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->fixed_size;
} else {
@ -2557,7 +2635,7 @@ bool TextServerFallback::_font_has_char(const RID &p_font_rid, int64_t p_char) c
MutexLock lock(fd->mutex);
FontForSizeFallback *ffsd = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), false);
} else {
ffsd = fd->cache.begin()->value;
}
@ -2577,7 +2655,7 @@ String TextServerFallback::_font_get_supported_chars(const RID &p_font_rid) cons
MutexLock lock(fd->mutex);
FontForSizeFallback *ffsd = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), String());
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), String());
} else {
ffsd = fd->cache.begin()->value;
}
@ -2610,7 +2688,7 @@ PackedInt32Array TextServerFallback::_font_get_supported_glyphs(const RID &p_fon
MutexLock lock(fd->mutex);
FontForSizeFallback *at_size = nullptr;
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), at_size), PackedInt32Array());
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), at_size), PackedInt32Array());
} else {
at_size = fd->cache.begin()->value;
}
@ -2655,12 +2733,12 @@ void TextServerFallback::_font_render_range(const RID &p_font_rid, const Vector2
_ensure_glyph(fd, size, (int32_t)idx, fgl);
} else {
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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
} else {
@ -2689,12 +2767,12 @@ void TextServerFallback::_font_render_glyph(const RID &p_font_rid, const Vector2
_ensure_glyph(fd, size, (int32_t)idx, fgl);
} else {
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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
} else {
@ -2706,7 +2784,7 @@ void TextServerFallback::_font_render_glyph(const RID &p_font_rid, const Vector2
#endif
}
void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
if (p_index == 0) {
return; // Non visual character, skip.
}
@ -2714,9 +2792,31 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size(fd, p_size);
// Oversampling.
bool viewport_oversampling = false;
float oversampling_factor = p_oversampling;
if (p_oversampling <= 0.0) {
if (vp_oversampling > 0.0) {
oversampling_factor = vp_oversampling;
viewport_oversampling = true;
} else {
oversampling_factor = 1.0;
}
}
bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
oversampling_factor = double(oversampling_level) / 64.0;
Vector2i size;
if (skip_oversampling) {
size = _get_size(fd, p_size);
} else {
size = Vector2i(p_size * 64 * oversampling_factor, 0);
}
FontForSizeFallback *ffsd = nullptr;
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
bool lcd_aa = false;
@ -2732,10 +2832,10 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
}
// 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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
index = index | (xshift << 27);
}
@ -2743,7 +2843,7 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
#endif
FontGlyph fgl;
if (!_ensure_glyph(fd, size, index, fgl)) {
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
}
@ -2784,7 +2884,7 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, 0, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
} else {
Point2 cpos = p_pos;
double scale = _font_get_scale(p_font_rid, p_size);
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
@ -2796,7 +2896,7 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
Vector2 gpos = fgl.rect.position;
Size2 csize = fgl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
@ -2806,6 +2906,9 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
gpos *= gl_scale;
csize *= gl_scale;
}
} else {
gpos /= oversampling_factor;
csize /= oversampling_factor;
}
cpos += gpos;
if (lcd_aa) {
@ -2819,7 +2922,7 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
}
}
void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
if (p_index == 0) {
return; // Non visual character, skip.
}
@ -2827,9 +2930,31 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
// Oversampling.
bool viewport_oversampling = false;
float oversampling_factor = p_oversampling;
if (p_oversampling <= 0.0) {
if (vp_oversampling > 0.0) {
oversampling_factor = vp_oversampling;
viewport_oversampling = true;
} else {
oversampling_factor = 1.0;
}
}
bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
oversampling_factor = double(oversampling_level) / 64.0;
Vector2i size;
if (skip_oversampling) {
size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
} else {
size = Vector2i(p_size * 64 * oversampling_factor, p_outline_size);
}
FontForSizeFallback *ffsd = nullptr;
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
bool lcd_aa = false;
@ -2845,10 +2970,10 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
}
}
// 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)) {
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
index = index | (xshift << 27);
}
@ -2856,7 +2981,7 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
#endif
FontGlyph fgl;
if (!_ensure_glyph(fd, size, index, fgl)) {
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
}
@ -2893,7 +3018,7 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, p_outline_size, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
} else {
Point2 cpos = p_pos;
double scale = _font_get_scale(p_font_rid, p_size);
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
@ -2905,7 +3030,7 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
}
Vector2 gpos = fgl.rect.position;
Size2 csize = fgl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
@ -2915,6 +3040,9 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
gpos *= gl_scale;
csize *= gl_scale;
}
} else {
gpos /= oversampling_factor;
csize /= oversampling_factor;
}
cpos += gpos;
if (lcd_aa) {
@ -3061,34 +3189,6 @@ Dictionary TextServerFallback::_font_supported_variation_list(const RID &p_font_
return fd->supported_varaitions;
}
double TextServerFallback::_font_get_global_oversampling() const {
return oversampling;
}
void TextServerFallback::_font_set_global_oversampling(double p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
List<RID> fonts;
font_owner.get_owned_list(&fonts);
bool font_cleared = false;
for (const RID &E : fonts) {
if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
_font_clear_size_cache(E);
font_cleared = true;
}
}
if (font_cleared) {
List<RID> text_bufs;
shaped_owner.get_owned_list(&text_bufs);
for (const RID &E : text_bufs) {
invalidate(shaped_owner.get_or_null(E));
}
}
}
}
/*************************************************************************/
/* Shaped text buffer interface */
/*************************************************************************/
@ -4318,7 +4418,6 @@ RID TextServerFallback::_find_sys_font_for_text(const RID &p_fdef, const String
_font_set_subpixel_positioning(sysf.rid, key.subpixel_positioning);
_font_set_keep_rounding_remainders(sysf.rid, key.keep_rounding_remainders);
_font_set_variation_coordinates(sysf.rid, var);
_font_set_oversampling(sysf.rid, key.oversampling);
_font_set_embolden(sysf.rid, key.embolden);
_font_set_transform(sysf.rid, key.transform);
_font_set_spacing(sysf.rid, SPACING_TOP, key.extra_spacing[SPACING_TOP]);
@ -5062,7 +5161,7 @@ TextServerFallback::TextServerFallback() {
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &TextServerFallback::_update_settings));
}
void TextServerFallback::_cleanup() {
void TextServerFallback::_font_clear_system_fallback_cache() {
for (const KeyValue<SystemFontKey, SystemFontCache> &E : system_fonts) {
const Vector<SystemFontCacheRec> &sysf_cache = E.value.var;
for (const SystemFontCacheRec &F : sysf_cache) {
@ -5073,6 +5172,10 @@ void TextServerFallback::_cleanup() {
system_font_data.clear();
}
void TextServerFallback::_cleanup() {
font_clear_system_fallback_cache();
}
TextServerFallback::~TextServerFallback() {
#ifdef MODULE_FREETYPE_ENABLED
if (ft_library != nullptr) {

View file

@ -221,13 +221,16 @@ class TextServerFallback : public TextServerExtension {
bool from_svg = false;
};
struct FontFallback;
struct FontForSizeFallback {
double ascent = 0.0;
double descent = 0.0;
double underline_position = 0.0;
double underline_thickness = 0.0;
double scale = 1.0;
double oversampling = 1.0;
FontFallback *owner = nullptr;
uint32_t viewport_oversampling = 0;
Vector2i size;
@ -249,6 +252,13 @@ class TextServerFallback : public TextServerExtension {
}
};
struct OversamplingLevel {
HashSet<FontForSizeFallback *> fonts;
int32_t refcount = 1;
};
mutable HashMap<uint32_t, OversamplingLevel> oversampling_levels;
struct FontFallbackLinkedVariation {
RID base_font;
int extra_spacing[4] = { 0, 0, 0, 0 };
@ -273,7 +283,6 @@ class TextServerFallback : public TextServerExtension {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
Dictionary variation_coordinates;
double oversampling = 0.0;
double embolden = 0.0;
Transform2D transform;
@ -315,29 +324,29 @@ class TextServerFallback : public TextServerExtension {
#ifdef MODULE_FREETYPE_ENABLED
_FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap p_bitmap, int p_yofs, int p_xofs, const Vector2 &p_advance, bool p_bgra) const;
#endif
_FORCE_INLINE_ bool _ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size, FontForSizeFallback *&r_cache_for_size, bool p_silent = false) const;
_FORCE_INLINE_ bool _ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph, uint32_t p_oversampling = 0) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size, FontForSizeFallback *&r_cache_for_size, bool p_silent = false, uint32_t p_oversampling = 0) const;
_FORCE_INLINE_ bool _font_validate(const RID &p_font_rid) const;
_FORCE_INLINE_ void _font_clear_cache(FontFallback *p_font_data);
static void _generateMTSDF_threaded(void *p_td, uint32_t p_y);
_FORCE_INLINE_ Vector2i _get_size(const FontFallback *p_font_data, int p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
return Vector2i(p_font_data->msdf_source_size * 64, 0);
} else if (p_font_data->fixed_size > 0) {
return Vector2i(p_font_data->fixed_size, 0);
return Vector2i(p_font_data->fixed_size * 64, 0);
} else {
return Vector2i(p_size, 0);
return Vector2i(p_size * 64, 0);
}
}
_FORCE_INLINE_ Vector2i _get_size_outline(const FontFallback *p_font_data, const Vector2i &p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
return Vector2i(p_font_data->msdf_source_size * 64, 0);
} else if (p_font_data->fixed_size > 0) {
return Vector2i(p_font_data->fixed_size, MIN(p_size.y, 1));
return Vector2i(p_font_data->fixed_size * 64, MIN(p_size.y, 1));
} else {
return p_size;
return Vector2i(p_size.x * 64, p_size.y);
}
}
@ -480,7 +489,6 @@ class TextServerFallback : public TextServerExtension {
// Common data.
double oversampling = 1.0;
mutable RID_PtrOwner<FontFallbackLinkedVariation> font_var_owner;
mutable RID_PtrOwner<FontFallback> font_owner;
mutable RID_PtrOwner<ShapedTextDataFallback> shaped_owner;
@ -511,14 +519,13 @@ class TextServerFallback : public TextServerExtension {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
Dictionary variation_coordinates;
double oversampling = 0.0;
double embolden = 0.0;
Transform2D transform;
int extra_spacing[4] = { 0, 0, 0, 0 };
double baseline_offset = 0.0;
bool operator==(const SystemFontKey &p_b) const {
return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (keep_rounding_remainders == p_b.keep_rounding_remainders) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset);
return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (keep_rounding_remainders == p_b.keep_rounding_remainders) && (variation_coordinates == p_b.variation_coordinates) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset);
}
SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerFallback *p_fb) {
@ -538,7 +545,6 @@ class TextServerFallback : public TextServerExtension {
subpixel_positioning = p_fb->_font_get_subpixel_positioning(p_font);
keep_rounding_remainders = p_fb->_font_get_keep_rounding_remainders(p_font);
variation_coordinates = p_fb->_font_get_variation_coordinates(p_font);
oversampling = p_fb->_font_get_oversampling(p_font);
embolden = p_fb->_font_get_embolden(p_font);
transform = p_fb->_font_get_transform(p_font);
extra_spacing[SPACING_TOP] = p_fb->_font_get_spacing(p_font, SPACING_TOP);
@ -568,7 +574,6 @@ class TextServerFallback : public TextServerExtension {
hash = hash_murmur3_one_32(p_a.msdf_range, hash);
hash = hash_murmur3_one_32(p_a.msdf_source_size, hash);
hash = hash_murmur3_one_32(p_a.fixed_size, hash);
hash = hash_murmur3_one_double(p_a.oversampling, hash);
hash = hash_murmur3_one_double(p_a.embolden, hash);
hash = hash_murmur3_one_real(p_a.transform[0].x, hash);
hash = hash_murmur3_one_real(p_a.transform[0].y, hash);
@ -670,6 +675,7 @@ public:
MODBIND2(font_set_allow_system_fallback, const RID &, bool);
MODBIND1RC(bool, font_is_allow_system_fallback, const RID &);
MODBIND0(font_clear_system_fallback_cache);
MODBIND2(font_set_force_autohinter, const RID &, bool);
MODBIND1RC(bool, font_is_force_autohinter, const RID &);
@ -701,12 +707,10 @@ public:
MODBIND2(font_set_hinting, const RID &, TextServer::Hinting);
MODBIND1RC(TextServer::Hinting, font_get_hinting, const RID &);
MODBIND2(font_set_oversampling, const RID &, double);
MODBIND1RC(double, font_get_oversampling, const RID &);
MODBIND1RC(TypedArray<Vector2i>, font_get_size_cache_list, const RID &);
MODBIND1(font_clear_size_cache, const RID &);
MODBIND2(font_remove_size_cache, const RID &, const Vector2i &);
MODBIND1RC(TypedArray<Dictionary>, font_get_size_cache_info, const RID &);
MODBIND3(font_set_ascent, const RID &, int64_t, double);
MODBIND2RC(double, font_get_ascent, const RID &, int64_t);
@ -774,8 +778,8 @@ public:
MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
MODBIND3(font_render_glyph, const RID &, const Vector2i &, int64_t);
MODBIND6C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &);
MODBIND7C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
MODBIND7C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &, float);
MODBIND8C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float);
MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
@ -795,8 +799,8 @@ public:
MODBIND1RC(Dictionary, font_supported_feature_list, const RID &);
MODBIND1RC(Dictionary, font_supported_variation_list, const RID &);
MODBIND0RC(double, font_get_global_oversampling);
MODBIND1(font_set_global_oversampling, double);
MODBIND1(reference_oversampling_level, double);
MODBIND1(unreference_oversampling_level, double);
/* Shaped text buffer interface */

View file

@ -30,6 +30,30 @@
#ifndef DISABLE_DEPRECATED
void CanvasItem::_draw_string_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_string(p_font, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_jst_flags, p_direction, p_orientation, 0.0);
}
void CanvasItem::_draw_multiline_string_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_multiline_string(p_font, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, 0.0);
}
void CanvasItem::_draw_string_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_string_outline(p_font, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_jst_flags, p_direction, p_orientation, 0.0);
}
void CanvasItem::_draw_multiline_string_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_multiline_string_outline(p_font, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, 0.0);
}
void CanvasItem::_draw_char_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, const Color &p_modulate) const {
draw_char(p_font, p_pos, p_char, p_font_size, p_modulate, 0.0);
}
void CanvasItem::_draw_char_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, int p_size, const Color &p_modulate) const {
draw_char_outline(p_font, p_pos, p_char, p_font_size, p_size, p_modulate, 0.0);
}
void CanvasItem::_draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
draw_circle(p_pos, p_radius, p_color, true, -1.0, false);
}
@ -51,6 +75,12 @@ void CanvasItem::_draw_multiline_colors_bind_compat_84523(const Vector<Point2> &
}
void CanvasItem::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation"), &CanvasItem::_draw_string_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &CanvasItem::_draw_multiline_string_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation"), &CanvasItem::_draw_string_outline_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &CanvasItem::_draw_multiline_string_outline_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_char", "font", "pos", "char", "font_size", "modulate"), &CanvasItem::_draw_char_bind_compat_104872, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_compatibility_method(D_METHOD("draw_char_outline", "font", "pos", "char", "font_size", "size", "modulate"), &CanvasItem::_draw_char_outline_bind_compat_104872, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_bind_compat_84472);
ClassDB::bind_compatibility_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::_draw_rect_bind_compat_84523, DEFVAL(true), DEFVAL(-1.0));
ClassDB::bind_compatibility_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::_draw_dashed_line_bind_compat_84523, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true));

View file

@ -136,15 +136,23 @@ void CanvasItem::_redraw_callback() {
return;
}
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
RID ci = get_canvas_item();
RenderingServer::get_singleton()->canvas_item_clear(ci);
//todo updating = true - only allow drawing here
if (is_visible_in_tree()) {
drawing = true;
Ref<TextServer> ts = TextServerManager::get_singleton()->get_primary_interface();
if (ts.is_valid()) {
ts->set_current_drawn_item_ovrsampling(get_viewport()->get_oversampling());
}
current_item_drawn = this;
notification(NOTIFICATION_DRAW);
emit_signal(SceneStringName(draw));
GDVIRTUAL_CALL(_draw);
current_item_drawn = nullptr;
if (ts.is_valid()) {
ts->set_current_drawn_item_ovrsampling(0.0);
}
drawing = false;
}
//todo updating = false
@ -966,54 +974,54 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
}
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_font.is_null());
p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_jst_flags, p_direction, p_orientation);
p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_jst_flags, p_direction, p_orientation, p_oversampling);
}
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_font.is_null());
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation);
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, p_oversampling);
}
void CanvasItem::draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void CanvasItem::draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_font.is_null());
p_font->draw_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_jst_flags, p_direction, p_orientation);
p_font->draw_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_jst_flags, p_direction, p_orientation, p_oversampling);
}
void CanvasItem::draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void CanvasItem::draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_font.is_null());
p_font->draw_multiline_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation);
p_font->draw_multiline_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, p_oversampling);
}
void CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, const Color &p_modulate) const {
void CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, const Color &p_modulate, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_char.length() != 1);
ERR_FAIL_COND(p_font.is_null());
p_font->draw_char(canvas_item, p_pos, p_char[0], p_font_size, p_modulate);
p_font->draw_char(canvas_item, p_pos, p_char[0], p_font_size, p_modulate, p_oversampling);
}
void CanvasItem::draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, int p_size, const Color &p_modulate) const {
void CanvasItem::draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, int p_size, const Color &p_modulate, float p_oversampling) const {
ERR_THREAD_GUARD;
ERR_DRAW_GUARD;
ERR_FAIL_COND(p_char.length() != 1);
ERR_FAIL_COND(p_font.is_null());
p_font->draw_char_outline(canvas_item, p_pos, p_char[0], p_font_size, p_size, p_modulate);
p_font->draw_char_outline(canvas_item, p_pos, p_char[0], p_font_size, p_size, p_modulate, p_oversampling);
}
void CanvasItem::_notify_transform_deferred() {
@ -1359,12 +1367,12 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation"), &CanvasItem::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &CanvasItem::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "font_size", "modulate"), &CanvasItem::draw_char, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_char_outline", "font", "pos", "char", "font_size", "size", "modulate"), &CanvasItem::draw_char_outline, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation", "oversampling"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation", "oversampling"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation", "oversampling"), &CanvasItem::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation", "oversampling"), &CanvasItem::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "font_size", "modulate", "oversampling"), &CanvasItem::draw_char, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_char_outline", "font", "pos", "char", "font_size", "size", "modulate", "oversampling"), &CanvasItem::draw_char_outline, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh);
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform, DEFVAL(0.0), DEFVAL(Size2(1.0, 1.0)));

View file

@ -175,6 +175,12 @@ protected:
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
void _draw_string_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_multiline_string_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_string_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_multiline_string_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_char_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
void _draw_char_outline_bind_compat_104872(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
void _draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color);
void _draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width);
void _draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned);
@ -311,14 +317,14 @@ public:
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
void draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
void draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
void draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
void draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
void draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), float p_oversampling = 0.0) const;
void draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), float p_oversampling = 0.0) const;
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
void draw_set_transform_matrix(const Transform2D &p_matrix);

View file

@ -1029,22 +1029,69 @@ void Viewport::update_canvas_items() {
_update_canvas_items(this);
}
void Viewport::set_use_oversampling(bool p_oversampling) {
ERR_MAIN_THREAD_GUARD;
if (use_font_oversampling == p_oversampling) {
return;
}
use_font_oversampling = p_oversampling;
_set_size(_get_size(), _get_size_2d_override(), _is_size_allocated());
}
bool Viewport::is_using_oversampling() const {
ERR_READ_THREAD_GUARD_V(false);
return use_font_oversampling;
}
void Viewport::set_oversampling_override(float p_oversampling) {
ERR_MAIN_THREAD_GUARD;
if (font_oversampling_override == p_oversampling) {
return;
}
font_oversampling_override = p_oversampling;
_set_size(_get_size(), _get_size_2d_override(), _is_size_allocated());
}
float Viewport::get_oversampling_override() const {
ERR_READ_THREAD_GUARD_V(0.0);
return font_oversampling_override;
}
bool Viewport::_set_size(const Size2i &p_size, const Size2 &p_size_2d_override, bool p_allocated) {
Transform2D stretch_transform_new = Transform2D();
float new_font_oversampling = 1.0;
if (is_size_2d_override_stretch_enabled() && p_size_2d_override.width > 0 && p_size_2d_override.height > 0) {
Size2 scale = Size2(p_size) / p_size_2d_override;
stretch_transform_new.scale(scale);
if (use_font_oversampling) {
if (font_oversampling_override <= 0.0) {
new_font_oversampling = MAX(scale.x, scale.y);
} else {
new_font_oversampling = font_oversampling_override;
}
} else {
new_font_oversampling = 1.0;
}
} else if (use_font_oversampling && font_oversampling_override > 0.0) {
new_font_oversampling = font_oversampling_override;
}
Size2i new_size = p_size.maxi(2);
if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) {
if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override && new_font_oversampling == font_oversampling) {
return false;
}
if (new_font_oversampling != font_oversampling) {
TS->reference_oversampling_level(new_font_oversampling);
TS->unreference_oversampling_level(font_oversampling);
}
size = new_size;
size_allocated = p_allocated;
size_2d_override = p_size_2d_override;
stretch_transform = stretch_transform_new;
font_oversampling = new_font_oversampling;
#ifndef _3D_DISABLED
if (!use_xr) {
@ -4912,6 +4959,14 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
ClassDB::bind_method(D_METHOD("set_use_oversampling", "enable"), &Viewport::set_use_oversampling);
ClassDB::bind_method(D_METHOD("is_using_oversampling"), &Viewport::is_using_oversampling);
ClassDB::bind_method(D_METHOD("set_oversampling_override", "oversampling"), &Viewport::set_oversampling_override);
ClassDB::bind_method(D_METHOD("get_oversampling_override"), &Viewport::get_oversampling_override);
ClassDB::bind_method(D_METHOD("get_oversampling"), &Viewport::get_oversampling);
ClassDB::bind_method(D_METHOD("get_render_info", "type", "info"), &Viewport::get_render_info);
ClassDB::bind_method(D_METHOD("get_texture"), &Viewport::get_texture);
@ -5120,6 +5175,9 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_canvas_transform", "get_global_canvas_transform");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_canvas_cull_mask", "get_canvas_cull_mask");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oversampling"), "set_use_oversampling", "is_using_oversampling");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling_override"), "set_oversampling_override", "get_oversampling_override");
ADD_SIGNAL(MethodInfo("size_changed"));
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));

View file

@ -239,6 +239,10 @@ private:
HashSet<CanvasLayer *> canvas_layers;
bool use_font_oversampling = true;
float font_oversampling = 1.0;
float font_oversampling_override = 0.0;
RID viewport;
RID current_canvas;
RID subwindow_canvas;
@ -574,6 +578,14 @@ public:
void set_use_taa(bool p_use_taa);
bool is_using_taa() const;
void set_use_oversampling(bool p_oversampling);
bool is_using_oversampling() const;
void set_oversampling_override(float p_oversampling);
float get_oversampling_override() const;
float get_oversampling() const { return font_oversampling; }
void set_scaling_3d_mode(Scaling3DMode p_scaling_3d_mode);
Scaling3DMode get_scaling_3d_mode() const;

View file

@ -1196,7 +1196,6 @@ void Window::_update_viewport_size() {
Size2i final_size;
Size2 final_size_override;
Rect2i attach_to_screen_rect(Point2i(), size);
double font_oversampling = 1.0;
window_transform = Transform2D();
if (content_scale_stretch == Window::CONTENT_SCALE_STRETCH_INTEGER) {
@ -1211,7 +1210,6 @@ void Window::_update_viewport_size() {
}
if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) {
font_oversampling = content_scale_factor;
final_size = size;
final_size_override = Size2(size) / content_scale_factor;
} else {
@ -1289,14 +1287,11 @@ void Window::_update_viewport_size() {
switch (content_scale_mode) {
case CONTENT_SCALE_MODE_DISABLED: {
// Already handled above
//_update_font_oversampling(1.0);
} break;
case CONTENT_SCALE_MODE_CANVAS_ITEMS: {
final_size = screen_size;
final_size_override = viewport_size / content_scale_factor;
attach_to_screen_rect = Rect2(margin, screen_size);
font_oversampling = (screen_size.x / viewport_size.x) * content_scale_factor;
window_transform.translate_local(margin);
} break;
@ -1315,7 +1310,7 @@ void Window::_update_viewport_size() {
}
bool allocate = is_inside_tree() && visible && (window_id != DisplayServer::INVALID_WINDOW_ID || embedder != nullptr);
bool ci_updated = _set_size(final_size, final_size_override, allocate);
_set_size(final_size, final_size_override, allocate);
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
RenderingServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), attach_to_screen_rect, window_id);
@ -1323,19 +1318,6 @@ void Window::_update_viewport_size() {
RenderingServer::get_singleton()->viewport_attach_to_screen(get_viewport_rid(), Rect2i(), DisplayServer::INVALID_WINDOW_ID);
}
if (window_id == DisplayServer::MAIN_WINDOW_ID) {
if (!use_font_oversampling) {
font_oversampling = 1.0;
}
if (!Math::is_equal_approx(TS->font_get_global_oversampling(), font_oversampling)) {
TS->font_set_global_oversampling(font_oversampling);
if (!ci_updated) {
update_canvas_items();
emit_signal(SNAME("size_changed"));
}
}
}
notification(NOTIFICATION_WM_SIZE_CHANGED);
if (embedder) {
@ -1721,20 +1703,6 @@ real_t Window::get_content_scale_factor() const {
return content_scale_factor;
}
void Window::set_use_font_oversampling(bool p_oversampling) {
ERR_MAIN_THREAD_GUARD;
if (is_inside_tree() && window_id != DisplayServer::MAIN_WINDOW_ID) {
ERR_FAIL_MSG("Only the root window can set and use font oversampling.");
}
use_font_oversampling = p_oversampling;
_update_viewport_size();
}
bool Window::is_using_font_oversampling() const {
ERR_READ_THREAD_GUARD_V(false);
return use_font_oversampling;
}
DisplayServer::WindowID Window::get_window_id() const {
ERR_READ_THREAD_GUARD_V(DisplayServer::INVALID_WINDOW_ID);
if (get_embedder()) {
@ -2955,6 +2923,15 @@ bool Window::is_layout_rtl() const {
}
#ifndef DISABLE_DEPRECATED
void Window::set_use_font_oversampling(bool p_oversampling) {
Viewport::set_use_oversampling(p_oversampling);
}
bool Window::is_using_font_oversampling() const {
return Viewport::is_using_oversampling();
}
void Window::set_auto_translate(bool p_enable) {
ERR_MAIN_THREAD_GUARD;
set_auto_translate_mode(p_enable ? AUTO_TRANSLATE_MODE_ALWAYS : AUTO_TRANSLATE_MODE_DISABLED);
@ -3138,9 +3115,6 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_content_scale_factor", "factor"), &Window::set_content_scale_factor);
ClassDB::bind_method(D_METHOD("get_content_scale_factor"), &Window::get_content_scale_factor);
ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &Window::set_use_font_oversampling);
ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &Window::is_using_font_oversampling);
ClassDB::bind_method(D_METHOD("set_mouse_passthrough_polygon", "polygon"), &Window::set_mouse_passthrough_polygon);
ClassDB::bind_method(D_METHOD("get_mouse_passthrough_polygon"), &Window::get_mouse_passthrough_polygon);
@ -3207,6 +3181,9 @@ void Window::_bind_methods() {
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Window::set_auto_translate);
ClassDB::bind_method(D_METHOD("is_auto_translating"), &Window::is_auto_translating);
ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &Window::set_use_font_oversampling);
ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &Window::is_using_font_oversampling);
#endif
ClassDB::bind_method(D_METHOD("popup", "rect"), &Window::popup, DEFVAL(Rect2i()));

View file

@ -134,7 +134,6 @@ private:
WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
bool force_native = false;
bool use_font_oversampling = false;
bool transient = false;
bool transient_to_focused = false;
bool exclusive = false;
@ -385,9 +384,6 @@ public:
void set_content_scale_factor(real_t p_factor);
real_t get_content_scale_factor() const;
void set_use_font_oversampling(bool p_oversampling);
bool is_using_font_oversampling() const;
void set_mouse_passthrough_polygon(const Vector<Vector2> &p_region);
Vector<Vector2> get_mouse_passthrough_polygon() const;
@ -433,6 +429,9 @@ public:
bool is_layout_rtl() const;
#ifndef DISABLE_DEPRECATED
void set_use_font_oversampling(bool p_oversampling);
bool is_using_font_oversampling() const;
void set_auto_translate(bool p_enable);
bool is_auto_translating() const;
#endif

View file

@ -30,17 +30,50 @@
#ifndef DISABLE_DEPRECATED
RID Font::_find_variation_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
void Font::_draw_string_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_string(p_canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_jst_flags, p_direction, p_orientation, 0.0);
}
void Font::_draw_multiline_string_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_multiline_string(p_canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, 0.0);
}
void Font::_draw_string_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_string_outline(p_canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_jst_flags, p_direction, p_orientation, 0.0);
}
void Font::_draw_multiline_string_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
draw_multiline_string_outline(p_canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation, 0.0);
}
real_t Font::_draw_char_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, const Color &p_modulate) const {
return draw_char(p_canvas_item, p_pos, p_char, p_font_size, p_modulate, 0.0);
}
real_t Font::_draw_char_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, int p_size, const Color &p_modulate) const {
return draw_char_outline(p_canvas_item, p_pos, p_char, p_font_size, p_size, p_modulate, 0.0);
}
RID Font::_find_variation_bind_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
return find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform, 0, 0, 0, 0, 0.0);
}
RID Font::_find_variation_compat_87668(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const {
RID Font::_find_variation_bind_compat_87668(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const {
return find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform, p_spacing_top, p_spacing_bottom, p_spacing_space, p_spacing_glyph, 0.0);
}
void Font::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::_find_variation_compat_80954, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()));
ClassDB::bind_compatibility_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform", "spacing_top", "spacing_bottom", "spacing_space", "spacing_glyph"), &Font::_find_variation_compat_87668, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()), DEFVAL(0), DEFVAL(0), DEFVAL(0), DEFVAL(0));
ClassDB::bind_compatibility_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation"), &Font::_draw_string_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &Font::_draw_multiline_string_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation"), &Font::_draw_string_outline_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &Font::_draw_multiline_string_outline_bind_compat_104872, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_compatibility_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate"), &Font::_draw_char_bind_compat_104872, DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_compatibility_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate"), &Font::_draw_char_outline_bind_compat_104872, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_compatibility_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::_find_variation_bind_compat_80954, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()));
ClassDB::bind_compatibility_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform", "spacing_top", "spacing_bottom", "spacing_space", "spacing_glyph"), &Font::_find_variation_bind_compat_87668, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()), DEFVAL(0), DEFVAL(0), DEFVAL(0), DEFVAL(0));
}
#endif

View file

@ -75,16 +75,16 @@ void Font::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_string_size", "text", "alignment", "width", "font_size", "justification_flags", "direction", "orientation"), &Font::get_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "alignment", "width", "font_size", "max_lines", "brk_flags", "justification_flags", "direction", "orientation"), &Font::get_multiline_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "modulate", "justification_flags", "direction", "orientation", "oversampling"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "justification_flags", "direction", "orientation", "oversampling"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation"), &Font::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("draw_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "justification_flags", "direction", "orientation", "oversampling"), &Font::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "justification_flags", "direction", "orientation", "oversampling"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL), DEFVAL(0.0));
// Drawing char.
ClassDB::bind_method(D_METHOD("get_char_size", "char", "font_size"), &Font::get_char_size);
ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate", "oversampling"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate", "oversampling"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(0.0));
// Helper functions.
ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char);
@ -345,7 +345,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, HorizontalAlignment
return lines_buffer->get_size();
}
void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : BitField(TextServer::JUSTIFICATION_NONE), TextServer::BREAK_NONE, p_direction, p_orientation);
@ -374,10 +374,10 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
buffer->set_flags(p_jst_flags);
}
buffer->draw(p_canvas_item, ofs, p_modulate);
buffer->draw(p_canvas_item, ofs, p_modulate, p_oversampling);
}
void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ShapedTextKey key = ShapedTextKey(p_text, p_font_size, p_width, p_jst_flags, p_brk_flags, p_direction, p_orientation);
Ref<TextParagraph> lines_buffer;
@ -405,10 +405,10 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S
lines_buffer->set_alignment(p_alignment);
lines_buffer->set_max_lines_visible(p_max_lines);
lines_buffer->draw(p_canvas_item, ofs, p_modulate);
lines_buffer->draw(p_canvas_item, ofs, p_modulate, p_modulate, p_oversampling);
}
void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : BitField(TextServer::JUSTIFICATION_NONE), TextServer::BREAK_NONE, p_direction, p_orientation);
@ -437,10 +437,10 @@ void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const Str
buffer->set_flags(p_jst_flags);
}
buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate, p_oversampling);
}
void Font::draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
void Font::draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation, float p_oversampling) const {
ShapedTextKey key = ShapedTextKey(p_text, p_font_size, p_width, p_jst_flags, p_brk_flags, p_direction, p_orientation);
Ref<TextParagraph> lines_buffer;
@ -468,7 +468,7 @@ void Font::draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos,
lines_buffer->set_alignment(p_alignment);
lines_buffer->set_max_lines_visible(p_max_lines);
lines_buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
lines_buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate, p_modulate, p_oversampling);
}
// Drawing char.
@ -485,28 +485,28 @@ Size2 Font::get_char_size(char32_t p_char, int p_font_size) const {
return Size2();
}
real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, const Color &p_modulate) const {
real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, const Color &p_modulate, float p_oversampling) const {
if (dirty_rids) {
_update_rids();
}
for (int i = 0; i < rids.size(); i++) {
if (TS->font_has_char(rids.get(i), p_char)) {
int32_t glyph = TS->font_get_glyph_index(rids.get(i), p_font_size, p_char, 0);
TS->font_draw_glyph(rids.get(i), p_canvas_item, p_font_size, p_pos, glyph, p_modulate);
TS->font_draw_glyph(rids.get(i), p_canvas_item, p_font_size, p_pos, glyph, p_modulate, p_oversampling);
return TS->font_get_glyph_advance(rids.get(i), p_font_size, glyph).x;
}
}
return 0.f;
}
real_t Font::draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, int p_size, const Color &p_modulate) const {
real_t Font::draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, int p_size, const Color &p_modulate, float p_oversampling) const {
if (dirty_rids) {
_update_rids();
}
for (int i = 0; i < rids.size(); i++) {
if (TS->font_has_char(rids.get(i), p_char)) {
int32_t glyph = TS->font_get_glyph_index(rids.get(i), p_font_size, p_char, 0);
TS->font_draw_glyph_outline(rids.get(i), p_canvas_item, p_font_size, p_size, p_pos, glyph, p_modulate);
TS->font_draw_glyph_outline(rids.get(i), p_canvas_item, p_font_size, p_size, p_pos, glyph, p_modulate, p_oversampling);
return TS->font_get_glyph_advance(rids.get(i), p_font_size, glyph).x;
}
}
@ -607,7 +607,6 @@ _FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index, int p_make_linked_f
TS->font_set_hinting(cache[p_cache_index], hinting);
TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
TS->font_set_keep_rounding_remainders(cache[p_cache_index], keep_rounding_remainders);
TS->font_set_oversampling(cache[p_cache_index], oversampling);
}
}
}
@ -942,9 +941,13 @@ void FontFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_keep_rounding_remainders", "keep_rounding_remainders"), &FontFile::set_keep_rounding_remainders);
ClassDB::bind_method(D_METHOD("get_keep_rounding_remainders"), &FontFile::get_keep_rounding_remainders);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontFile::set_oversampling);
ClassDB::bind_method(D_METHOD("get_oversampling"), &FontFile::get_oversampling);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", 0), "set_oversampling", "get_oversampling");
#endif
ClassDB::bind_method(D_METHOD("get_cache_count"), &FontFile::get_cache_count);
ClassDB::bind_method(D_METHOD("clear_cache"), &FontFile::clear_cache);
ClassDB::bind_method(D_METHOD("remove_cache", "cache_index"), &FontFile::remove_cache);
@ -1060,7 +1063,6 @@ void FontFile::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "modulate_color_glyphs", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_modulate_color_glyphs", "is_modulate_color_glyphs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size_scale_mode", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size_scale_mode", "get_fixed_size_scale_mode");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
@ -1079,8 +1081,6 @@ bool FontFile::_set(const StringName &p_name, const Variant &p_value) {
if (tokens.size() == 1 && tokens[0] == "font_path") {
// Compatibility, DynamicFontData.
load_dynamic_font(p_value);
} else if (tokens.size() == 1 && tokens[0] == "override_oversampling") {
set_oversampling(p_value);
}
if (tokens.size() == 1 && tokens[0] == "font_data") {
// Compatibility, DynamicFont.
@ -1427,7 +1427,6 @@ void FontFile::reset_state() {
msdf_size = 128;
fixed_size = 0;
fixed_size_scale_mode = TextServer::FIXED_SIZE_SCALE_DISABLE;
oversampling = 0.f;
Font::reset_state();
}
@ -1462,7 +1461,6 @@ Error FontFile::_load_bitmap_font(const String &p_path, List<String> *r_image_fi
modulate_color_glyphs = false;
allow_system_fallback = true;
hinting = TextServer::HINTING_NONE;
oversampling = 1.0f;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_CREATE, vformat("Cannot open font from file: %s.", p_path));
@ -2338,21 +2336,6 @@ bool FontFile::get_keep_rounding_remainders() const {
return keep_rounding_remainders;
}
void FontFile::set_oversampling(real_t p_oversampling) {
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
for (int i = 0; i < cache.size(); i++) {
_ensure_rid(i);
TS->font_set_oversampling(cache[i], oversampling);
}
emit_changed();
}
}
real_t FontFile::get_oversampling() const {
return oversampling;
}
RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph, float p_baseline_offset) const {
// Find existing variation cache.
const Dictionary &supported_coords = get_supported_variation_list();
@ -3143,9 +3126,13 @@ void SystemFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &SystemFont::set_msdf_size);
ClassDB::bind_method(D_METHOD("get_msdf_size"), &SystemFont::get_msdf_size);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling);
ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", 0), "set_oversampling", "get_oversampling");
#endif
ClassDB::bind_method(D_METHOD("get_font_names"), &SystemFont::get_font_names);
ClassDB::bind_method(D_METHOD("set_font_names", "names"), &SystemFont::set_font_names);
@ -3170,7 +3157,6 @@ void SystemFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field"), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range"), "set_msdf_pixel_range", "get_msdf_pixel_range");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size"), "set_msdf_size", "get_msdf_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling");
}
void SystemFont::_update_rids() const {
@ -3277,7 +3263,6 @@ void SystemFont::_update_base_font() {
file->set_multichannel_signed_distance_field(msdf);
file->set_msdf_pixel_range(msdf_pixel_range);
file->set_msdf_size(msdf_size);
file->set_oversampling(oversampling);
base_font = file;
@ -3319,7 +3304,6 @@ void SystemFont::reset_state() {
hinting = TextServer::HINTING_LIGHT;
subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
keep_rounding_remainders = true;
oversampling = 0.f;
msdf = false;
Font::reset_state();
@ -3542,20 +3526,6 @@ int SystemFont::get_msdf_size() const {
return msdf_size;
}
void SystemFont::set_oversampling(real_t p_oversampling) {
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
if (base_font.is_valid()) {
base_font->set_oversampling(oversampling);
}
emit_changed();
}
}
real_t SystemFont::get_oversampling() const {
return oversampling;
}
void SystemFont::set_font_names(const PackedStringArray &p_names) {
if (names != p_names) {
names = p_names;

View file

@ -100,8 +100,14 @@ protected:
virtual void reset_state() override;
#ifndef DISABLE_DEPRECATED
RID _find_variation_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const;
RID _find_variation_compat_87668(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const;
void _draw_string_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_multiline_string_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_string_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
void _draw_multiline_string_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
real_t _draw_char_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
real_t _draw_char_outline_bind_compat_104872(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
RID _find_variation_bind_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const;
RID _find_variation_bind_compat_87668(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const;
static void _bind_compatibility_methods();
#endif
@ -144,16 +150,16 @@ public:
virtual Size2 get_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual Size2 get_multiline_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
virtual void draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual void draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
virtual void draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
virtual void draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL, float p_oversampling = 0.0) const;
// Drawing char.
virtual Size2 get_char_size(char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE) const;
virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
virtual real_t draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), float p_oversampling = 0.0) const;
virtual real_t draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), float p_oversampling = 0.0) const;
// Helper functions.
virtual bool has_char(char32_t p_char) const;
@ -197,7 +203,6 @@ class FontFile : public Font {
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
real_t oversampling = 0.f;
#ifndef DISABLE_DEPRECATED
real_t bmp_height = 0.0;
@ -286,8 +291,10 @@ public:
virtual void set_keep_rounding_remainders(bool p_keep_rounding_remainders);
virtual bool get_keep_rounding_remainders() const;
virtual void set_oversampling(real_t p_oversampling);
virtual real_t get_oversampling() const;
#ifndef DISABLE_DEPRECATED
virtual void set_oversampling(real_t p_oversampling) {}
virtual real_t get_oversampling() const { return 1.0; }
#endif
// Cache.
virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0, float p_baseline_offset = 0.0) const override;
@ -488,7 +495,6 @@ class SystemFont : public Font {
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
bool keep_rounding_remainders = true;
real_t oversampling = 0.f;
bool msdf = false;
int msdf_pixel_range = 16;
int msdf_size = 48;
@ -532,8 +538,10 @@ public:
virtual void set_keep_rounding_remainders(bool p_keep_rounding_remainders);
virtual bool get_keep_rounding_remainders() const;
virtual void set_oversampling(real_t p_oversampling);
virtual real_t get_oversampling() const;
#ifndef DISABLE_DEPRECATED
virtual void set_oversampling(real_t p_oversampling) {}
virtual real_t get_oversampling() const { return 1.0; }
#endif
virtual void set_multichannel_signed_distance_field(bool p_msdf);
virtual bool is_multichannel_signed_distance_field() const;

View file

@ -0,0 +1,46 @@
/**************************************************************************/
/* text_line.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
void TextLine::_draw_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
draw(p_canvas, p_pos, p_color, 0.0);
}
void TextLine::_draw_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
draw_outline(p_canvas, p_pos, p_outline_size, p_color, 0.0);
}
void TextLine::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("draw", "canvas", "pos", "color"), &TextLine::_draw_bind_compat_104872, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color"), &TextLine::_draw_outline_bind_compat_104872, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
}
#endif

View file

@ -29,6 +29,7 @@
/**************************************************************************/
#include "text_line.h"
#include "text_line.compat.inc"
void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &TextLine::clear);
@ -99,8 +100,8 @@ void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_underline_position"), &TextLine::get_line_underline_position);
ClassDB::bind_method(D_METHOD("get_line_underline_thickness"), &TextLine::get_line_underline_thickness);
ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color"), &TextLine::draw, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color"), &TextLine::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color", "oversampling"), &TextLine::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color", "oversampling"), &TextLine::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("hit_test", "coords"), &TextLine::hit_test);
}
@ -386,7 +387,7 @@ float TextLine::get_line_underline_thickness() const {
return TS->shaped_text_get_underline_thickness(rid);
}
void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color, float p_oversampling) const {
_shape();
Vector2 ofs = p_pos;
@ -430,10 +431,10 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co
ofs.x += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.y - ofs.y);
}
return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color);
return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color, p_oversampling);
}
void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, float p_oversampling) const {
_shape();
Vector2 ofs = p_pos;
@ -477,7 +478,7 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si
ofs.x += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.y - ofs.y);
}
return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color);
return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color, p_oversampling);
}
int TextLine::hit_test(float p_coords) const {

View file

@ -52,6 +52,12 @@ private:
Vector<float> tab_stops;
protected:
#ifndef DISABLE_DEPRECATED
void _draw_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
void _draw_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
static void _bind_compatibility_methods();
#endif
static void _bind_methods();
void _shape() const;
@ -108,8 +114,8 @@ public:
float get_line_underline_position() const;
float get_line_underline_thickness() const;
void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
int hit_test(float p_coords) const;

View file

@ -0,0 +1,68 @@
/**************************************************************************/
/* text_paragraph.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
void TextParagraph::_draw_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color, const Color &p_dc_color) const {
draw(p_canvas, p_pos, p_color, p_dc_color, 0.0);
}
void TextParagraph::_draw_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, const Color &p_dc_color) const {
draw_outline(p_canvas, p_pos, p_outline_size, p_color, p_dc_color, 0.0);
}
void TextParagraph::_draw_line_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color) const {
draw_line(p_canvas, p_pos, p_line, p_color, 0.0);
}
void TextParagraph::_draw_line_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size, const Color &p_color) const {
draw_line_outline(p_canvas, p_pos, p_line, p_outline_size, p_color, 0.0);
}
void TextParagraph::_draw_dropcap_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
draw_dropcap(p_canvas, p_pos, p_color, 0.0);
}
void TextParagraph::_draw_dropcap_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
draw_dropcap_outline(p_canvas, p_pos, p_outline_size, p_color, 0.0);
}
void TextParagraph::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("draw", "canvas", "pos", "color", "dc_color"), &TextParagraph::_draw_bind_compat_104872, DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color", "dc_color"), &TextParagraph::_draw_outline_bind_compat_104872, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_line", "canvas", "pos", "line", "color"), &TextParagraph::_draw_line_bind_compat_104872, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_line_outline", "canvas", "pos", "line", "outline_size", "color"), &TextParagraph::_draw_line_outline_bind_compat_104872, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_dropcap", "canvas", "pos", "color"), &TextParagraph::_draw_dropcap_bind_compat_104872, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("draw_dropcap_outline", "canvas", "pos", "outline_size", "color"), &TextParagraph::_draw_dropcap_outline_bind_compat_104872, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
}
#endif

View file

@ -28,7 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "scene/resources/text_paragraph.h"
#include "text_paragraph.h"
#include "text_paragraph.compat.inc"
void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &TextParagraph::clear);
@ -133,14 +134,14 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color", "dc_color"), &TextParagraph::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color", "dc_color"), &TextParagraph::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color", "dc_color", "oversampling"), &TextParagraph::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color", "dc_color", "oversampling"), &TextParagraph::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_line", "canvas", "pos", "line", "color"), &TextParagraph::draw_line, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_line_outline", "canvas", "pos", "line", "outline_size", "color"), &TextParagraph::draw_line_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_line", "canvas", "pos", "line", "color", "oversampling"), &TextParagraph::draw_line, DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_line_outline", "canvas", "pos", "line", "outline_size", "color", "oversampling"), &TextParagraph::draw_line_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_dropcap", "canvas", "pos", "color"), &TextParagraph::draw_dropcap, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_dropcap_outline", "canvas", "pos", "outline_size", "color"), &TextParagraph::draw_dropcap_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_dropcap", "canvas", "pos", "color", "oversampling"), &TextParagraph::draw_dropcap, DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("draw_dropcap_outline", "canvas", "pos", "outline_size", "color", "oversampling"), &TextParagraph::draw_dropcap_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("hit_test", "coords"), &TextParagraph::hit_test);
}
@ -829,7 +830,7 @@ int TextParagraph::get_dropcap_lines() const {
return dropcap_lines;
}
void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color, const Color &p_dc_color) const {
void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color, const Color &p_dc_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
_shape_lines();
@ -851,7 +852,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
dc_off.y += width - h_offset;
}
}
TS->shaped_text_draw(dropcap_rid, p_canvas, dc_off + Vector2(0, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.size.y + dropcap_margins.position.y / 2), -1, -1, p_dc_color);
TS->shaped_text_draw(dropcap_rid, p_canvas, dc_off + Vector2(0, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.size.y + dropcap_margins.position.y / 2), -1, -1, p_dc_color, p_oversampling);
}
int lines_visible = (max_lines_visible >= 0) ? MIN(max_lines_visible, (int)lines_rid.size()) : (int)lines_rid.size();
@ -921,7 +922,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
} else {
clip_l = MAX(0, p_pos.y - ofs.y);
}
TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color);
TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color, p_oversampling);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
@ -932,7 +933,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
}
}
void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, const Color &p_dc_color) const {
void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, const Color &p_dc_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
_shape_lines();
@ -955,7 +956,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
dc_off.y += width - h_offset;
}
}
TS->shaped_text_draw_outline(dropcap_rid, p_canvas, dc_off + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_dc_color);
TS->shaped_text_draw_outline(dropcap_rid, p_canvas, dc_off + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_dc_color, p_oversampling);
}
for (int i = 0; i < (int)lines_rid.size(); i++) {
@ -1023,7 +1024,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
} else {
clip_l = MAX(0, p_pos.y - ofs.y);
}
TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color);
TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color, p_oversampling);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing;
@ -1068,7 +1069,7 @@ bool TextParagraph::is_dirty() {
return lines_dirty;
}
void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
Vector2 ofs = p_pos;
@ -1088,11 +1089,11 @@ void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color
ofs.y += width - h_offset;
}
}
TS->shaped_text_draw(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_color);
TS->shaped_text_draw(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_color, p_oversampling);
}
}
void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
Vector2 ofs = p_pos;
@ -1112,11 +1113,11 @@ void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int
ofs.y += width - h_offset;
}
}
TS->shaped_text_draw_outline(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_color);
TS->shaped_text_draw_outline(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_color, p_oversampling);
}
}
void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color) const {
void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
_shape_lines();
@ -1129,10 +1130,10 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co
} else {
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
}
return TS->shaped_text_draw(lines_rid[p_line], p_canvas, ofs, -1, -1, p_color);
return TS->shaped_text_draw(lines_rid[p_line], p_canvas, ofs, -1, -1, p_color, p_oversampling);
}
void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size, const Color &p_color) const {
void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size, const Color &p_color, float p_oversampling) const {
_THREAD_SAFE_METHOD_
_shape_lines();
@ -1144,7 +1145,7 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_
} else {
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
}
return TS->shaped_text_draw_outline(lines_rid[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color);
return TS->shaped_text_draw_outline(lines_rid[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color, p_oversampling);
}
TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {

View file

@ -64,6 +64,16 @@ private:
Vector<float> tab_stops;
protected:
#ifndef DISABLE_DEPRECATED
void _draw_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
void _draw_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
void _draw_line_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color = Color(1, 1, 1)) const;
void _draw_line_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
void _draw_dropcap_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
void _draw_dropcap_outline_bind_compat_104872(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
static void _bind_compatibility_methods();
#endif
static void _bind_methods();
void _shape_lines() const;
@ -147,14 +157,14 @@ public:
Size2 get_dropcap_size() const;
int get_dropcap_lines() const;
void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color = Color(1, 1, 1)) const;
void draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
void draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
void draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
void draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
void draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
int hit_test(const Point2 &p_coords) const;

View file

@ -51,6 +51,7 @@ public:
virtual void font_set_fixed_size_scale_mode(const RID &p_font_rid, TextServer::FixedSizeScaleMode p_fixed_size_scale_mode) override {}
virtual TextServer::FixedSizeScaleMode font_get_fixed_size_scale_mode(const RID &p_font_rid) const override { return FIXED_SIZE_SCALE_DISABLE; }
virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override { return TypedArray<Vector2i>(); }
virtual TypedArray<Dictionary> font_get_size_cache_info(const RID &p_font_rid) const override { return TypedArray<Dictionary>(); }
virtual void font_clear_size_cache(const RID &p_font_rid) override {}
virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override {}
virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override {}
@ -88,8 +89,8 @@ public:
virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override { return false; }
virtual String font_get_supported_chars(const RID &p_font_rid) const override { return String(); }
virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const override { return PackedInt32Array(); }
virtual void font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override {}
virtual void font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override {}
virtual void font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const override {}
virtual void font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const override {}
virtual RID create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) override { return RID(); }
virtual void shaped_text_clear(const RID &p_shaped) override {}

View file

@ -104,6 +104,7 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_set_allow_system_fallback, "font_rid", "allow_system_fallback");
GDVIRTUAL_BIND(_font_is_allow_system_fallback, "font_rid");
GDVIRTUAL_BIND(_font_clear_system_fallback_cache);
GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter");
GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid");
@ -135,12 +136,15 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_set_variation_coordinates, "font_rid", "variation_coordinates");
GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid");
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_BIND(_font_set_oversampling, "font_rid", "oversampling");
GDVIRTUAL_BIND(_font_get_oversampling, "font_rid");
#endif
GDVIRTUAL_BIND(_font_get_size_cache_list, "font_rid");
GDVIRTUAL_BIND(_font_clear_size_cache, "font_rid");
GDVIRTUAL_BIND(_font_remove_size_cache, "font_rid", "size");
GDVIRTUAL_BIND(_font_get_size_cache_info, "font_rid");
GDVIRTUAL_BIND(_font_set_ascent, "font_rid", "size", "ascent");
GDVIRTUAL_BIND(_font_get_ascent, "font_rid", "size");
@ -208,8 +212,12 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_render_range, "font_rid", "size", "start", "end");
GDVIRTUAL_BIND(_font_render_glyph, "font_rid", "size", "index");
GDVIRTUAL_BIND(_font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color");
GDVIRTUAL_BIND(_font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color");
GDVIRTUAL_BIND(_font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color", "oversampling");
GDVIRTUAL_BIND(_font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color", "oversampling");
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_BIND_COMPAT(_font_draw_glyph_bind_compat_104872, "font_rid", "canvas", "size", "pos", "index", "color");
GDVIRTUAL_BIND_COMPAT(_font_draw_glyph_outline_bind_compat_104872, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color");
#endif
GDVIRTUAL_BIND(_font_is_language_supported, "font_rid", "language");
GDVIRTUAL_BIND(_font_set_language_support_override, "font_rid", "language", "supported");
@ -229,8 +237,12 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_supported_feature_list, "font_rid");
GDVIRTUAL_BIND(_font_supported_variation_list, "font_rid");
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_BIND(_font_get_global_oversampling);
GDVIRTUAL_BIND(_font_set_global_oversampling, "oversampling");
#endif
GDVIRTUAL_BIND(_reference_oversampling_level, "oversampling");
GDVIRTUAL_BIND(_unreference_oversampling_level, "oversampling");
GDVIRTUAL_BIND(_get_hex_code_box_size, "size", "index");
GDVIRTUAL_BIND(_draw_hex_code_box, "canvas", "size", "pos", "index", "color");
@ -335,8 +347,12 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_shaped_text_hit_test_grapheme, "shaped", "coord");
GDVIRTUAL_BIND(_shaped_text_hit_test_position, "shaped", "coord");
GDVIRTUAL_BIND(_shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color");
GDVIRTUAL_BIND(_shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color");
GDVIRTUAL_BIND(_shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color", "oversampling");
GDVIRTUAL_BIND(_shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color", "oversampling");
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_BIND_COMPAT(_shaped_text_draw_bind_compat_104872, "shaped", "canvas", "pos", "clip_l", "clip_r", "color");
GDVIRTUAL_BIND_COMPAT(_shaped_text_draw_outline_bind_compat_104872, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color");
#endif
GDVIRTUAL_BIND(_shaped_text_get_grapheme_bounds, "shaped", "pos");
GDVIRTUAL_BIND(_shaped_text_next_grapheme_pos, "shaped", "pos");
@ -636,6 +652,10 @@ bool TextServerExtension::font_is_allow_system_fallback(const RID &p_font_rid) c
return ret;
}
void TextServerExtension::font_clear_system_fallback_cache() {
GDVIRTUAL_CALL(_font_clear_system_fallback_cache);
}
void TextServerExtension::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
GDVIRTUAL_CALL(_font_set_force_autohinter, p_font_rid, p_force_autohinter);
}
@ -736,15 +756,15 @@ Dictionary TextServerExtension::font_get_variation_coordinates(const RID &p_font
return ret;
}
#ifndef DISABLE_DEPRECATED
void TextServerExtension::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
GDVIRTUAL_CALL(_font_set_oversampling, p_font_rid, p_oversampling);
// NOP
}
double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const {
double ret = 0;
GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret);
return ret;
return 1.0;
}
#endif
TypedArray<Vector2i> TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const {
TypedArray<Vector2i> ret;
@ -760,6 +780,12 @@ void TextServerExtension::font_remove_size_cache(const RID &p_font_rid, const Ve
GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size);
}
TypedArray<Dictionary> TextServerExtension::font_get_size_cache_info(const RID &p_font_rid) const {
TypedArray<Dictionary> ret;
GDVIRTUAL_CALL(_font_get_size_cache_info, p_font_rid, ret);
return ret;
}
void TextServerExtension::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent);
}
@ -988,12 +1014,18 @@ void TextServerExtension::font_render_glyph(const RID &p_font_rid, const Vector2
GDVIRTUAL_CALL(_font_render_glyph, p_font_rid, p_size, p_index);
}
void TextServerExtension::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color);
void TextServerExtension::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color, p_oversampling);
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_CALL(_font_draw_glyph_bind_compat_104872, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color);
#endif
}
void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color, p_oversampling);
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_CALL(_font_draw_glyph_outline_bind_compat_104872, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
#endif
}
bool TextServerExtension::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
@ -1070,14 +1102,22 @@ Dictionary TextServerExtension::font_supported_variation_list(const RID &p_font_
return ret;
}
#ifndef DISABLE_DEPRECATED
double TextServerExtension::font_get_global_oversampling() const {
double ret = 0;
GDVIRTUAL_CALL(_font_get_global_oversampling, ret);
return ret;
return 1.0;
}
void TextServerExtension::font_set_global_oversampling(double p_oversampling) {
GDVIRTUAL_CALL(_font_set_global_oversampling, p_oversampling);
// NOP
}
#endif
void TextServerExtension::reference_oversampling_level(double p_oversampling) {
GDVIRTUAL_CALL(_reference_oversampling_level, p_oversampling);
}
void TextServerExtension::unreference_oversampling_level(double p_oversampling) {
GDVIRTUAL_CALL(_unreference_oversampling_level, p_oversampling);
}
Vector2 TextServerExtension::get_hex_code_box_size(int64_t p_size, int64_t p_index) const {
@ -1518,18 +1558,28 @@ int64_t TextServerExtension::shaped_text_hit_test_position(const RID &p_shaped,
return TextServer::shaped_text_hit_test_position(p_shaped, p_coords);
}
void TextServerExtension::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const {
if (GDVIRTUAL_CALL(_shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) {
void TextServerExtension::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color, float p_oversampling) const {
if (GDVIRTUAL_CALL(_shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color, p_oversampling)) {
return;
}
TextServer::shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color);
#ifndef DISABLE_DEPRECATED
if (GDVIRTUAL_CALL(_shaped_text_draw_bind_compat_104872, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) {
return;
}
#endif
TextServer::shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color, p_oversampling);
}
void TextServerExtension::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const {
if (GDVIRTUAL_CALL(_shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) {
void TextServerExtension::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color, float p_oversampling) const {
if (GDVIRTUAL_CALL(_shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color, p_oversampling)) {
return;
}
TextServer::shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color);
#ifndef DISABLE_DEPRECATED
if (GDVIRTUAL_CALL(_shaped_text_draw_outline_bind_compat_104872, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) {
return;
}
#endif
TextServer::shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color, p_oversampling);
}
Vector2 TextServerExtension::shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const {

View file

@ -196,8 +196,10 @@ public:
virtual void font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) override;
virtual bool font_is_allow_system_fallback(const RID &p_font_rid) const override;
virtual void font_clear_system_fallback_cache() override;
GDVIRTUAL2(_font_set_allow_system_fallback, RID, bool);
GDVIRTUAL1RC(bool, _font_is_allow_system_fallback, RID);
GDVIRTUAL0(_font_clear_system_fallback_cache);
virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override;
virtual bool font_is_force_autohinter(const RID &p_font_rid) const override;
@ -219,17 +221,21 @@ public:
GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary);
GDVIRTUAL1RC(Dictionary, _font_get_variation_coordinates, RID);
#ifndef DISABLE_DEPRECATED
virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override;
virtual double font_get_oversampling(const RID &p_font_rid) const override;
GDVIRTUAL2(_font_set_oversampling, RID, double);
GDVIRTUAL1RC(double, _font_get_oversampling, RID);
#endif
virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override;
virtual void font_clear_size_cache(const RID &p_font_rid) override;
virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override;
virtual TypedArray<Dictionary> font_get_size_cache_info(const RID &p_font_rid) const override;
GDVIRTUAL1RC_REQUIRED(TypedArray<Vector2i>, _font_get_size_cache_list, RID);
GDVIRTUAL1_REQUIRED(_font_clear_size_cache, RID);
GDVIRTUAL2_REQUIRED(_font_remove_size_cache, RID, const Vector2i &);
GDVIRTUAL1RC(TypedArray<Dictionary>, _font_get_size_cache_info, RID);
virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
@ -344,10 +350,14 @@ public:
GDVIRTUAL4(_font_render_range, RID, const Vector2i &, int64_t, int64_t);
GDVIRTUAL3(_font_render_glyph, RID, const Vector2i &, int64_t);
virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
GDVIRTUAL6C_REQUIRED(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &);
GDVIRTUAL7C_REQUIRED(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
GDVIRTUAL7C_REQUIRED(_font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &, float);
GDVIRTUAL8C_REQUIRED(_font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float);
#ifndef DISABLE_DEPRECATED
GDVIRTUAL6C_COMPAT(_font_draw_glyph_bind_compat_104872, _font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &);
GDVIRTUAL7C_COMPAT(_font_draw_glyph_outline_bind_compat_104872, _font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
#endif
virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
@ -381,10 +391,16 @@ public:
GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID);
GDVIRTUAL1RC(Dictionary, _font_supported_variation_list, RID);
#ifndef DISABLE_DEPRECATED
virtual double font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(double p_oversampling) override;
GDVIRTUAL0RC(double, _font_get_global_oversampling);
GDVIRTUAL1(_font_set_global_oversampling, double);
#endif
virtual void reference_oversampling_level(double p_oversampling) override;
virtual void unreference_oversampling_level(double p_oversampling) override;
GDVIRTUAL1(_reference_oversampling_level, double);
GDVIRTUAL1(_unreference_oversampling_level, double);
virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const override;
virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override;
@ -563,10 +579,14 @@ public:
GDVIRTUAL2RC(int64_t, _shaped_text_hit_test_grapheme, RID, double);
GDVIRTUAL2RC(int64_t, _shaped_text_hit_test_position, RID, double);
virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const override;
virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override;
GDVIRTUAL6C(_shaped_text_draw, RID, RID, const Vector2 &, double, double, const Color &);
GDVIRTUAL7C(_shaped_text_draw_outline, RID, RID, const Vector2 &, double, double, int64_t, const Color &);
virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
GDVIRTUAL7C(_shaped_text_draw, RID, RID, const Vector2 &, double, double, const Color &, float);
GDVIRTUAL8C(_shaped_text_draw_outline, RID, RID, const Vector2 &, double, double, int64_t, const Color &, float);
#ifndef DISABLE_DEPRECATED
GDVIRTUAL6C_COMPAT(_shaped_text_draw_bind_compat_104872, _shaped_text_draw, RID, RID, const Vector2 &, double, double, const Color &);
GDVIRTUAL7C_COMPAT(_shaped_text_draw_outline_bind_compat_104872, _shaped_text_draw_outline, RID, RID, const Vector2 &, double, double, int64_t, const Color &);
#endif
virtual Vector2 shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const override;
virtual int64_t shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const override;

View file

@ -30,11 +30,31 @@
#ifndef DISABLE_DEPRECATED
void TextServer::_font_draw_glyph_bind_compat_104872(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
font_draw_glyph(p_font, p_canvas, p_size, p_pos, p_index, p_color, 0.0);
}
void TextServer::_font_draw_glyph_outline_bind_compat_104872(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
font_draw_glyph_outline(p_font, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color, 0.0);
}
void TextServer::_shaped_text_draw_bind_compat_104872(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const {
shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color, 0.0);
}
void TextServer::_shaped_text_draw_outline_bind_compat_104872(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const {
shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color, 0.0);
}
PackedInt32Array TextServer::_shaped_text_get_word_breaks_bind_compat_90732(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags) const {
return shaped_text_get_word_breaks(p_shaped, p_grapheme_flags, 0);
}
void TextServer::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("font_draw_glyph", "font_rid", "canvas", "size", "pos", "index", "color"), &TextServer::_font_draw_glyph_bind_compat_104872, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("font_draw_glyph_outline", "font_rid", "canvas", "size", "outline_size", "pos", "index", "color"), &TextServer::_font_draw_glyph_outline_bind_compat_104872, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("shaped_text_draw", "shaped", "canvas", "pos", "clip_l", "clip_r", "color"), &TextServer::_shaped_text_draw_bind_compat_104872, DEFVAL(-1), DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("shaped_text_draw_outline", "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"), &TextServer::_shaped_text_draw_outline_bind_compat_104872, DEFVAL(-1), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_compatibility_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags"), &TextServer::_shaped_text_get_word_breaks_bind_compat_90732, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION));
}

View file

@ -260,6 +260,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_allow_system_fallback", "font_rid", "allow_system_fallback"), &TextServer::font_set_allow_system_fallback);
ClassDB::bind_method(D_METHOD("font_is_allow_system_fallback", "font_rid"), &TextServer::font_is_allow_system_fallback);
ClassDB::bind_method(D_METHOD("font_clear_system_fallback_cache"), &TextServer::font_clear_system_fallback_cache);
ClassDB::bind_method(D_METHOD("font_set_force_autohinter", "font_rid", "force_autohinter"), &TextServer::font_set_force_autohinter);
ClassDB::bind_method(D_METHOD("font_is_force_autohinter", "font_rid"), &TextServer::font_is_force_autohinter);
@ -291,12 +292,15 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_variation_coordinates", "font_rid", "variation_coordinates"), &TextServer::font_set_variation_coordinates);
ClassDB::bind_method(D_METHOD("font_get_variation_coordinates", "font_rid"), &TextServer::font_get_variation_coordinates);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("font_set_oversampling", "font_rid", "oversampling"), &TextServer::font_set_oversampling);
ClassDB::bind_method(D_METHOD("font_get_oversampling", "font_rid"), &TextServer::font_get_oversampling);
#endif
ClassDB::bind_method(D_METHOD("font_get_size_cache_list", "font_rid"), &TextServer::font_get_size_cache_list);
ClassDB::bind_method(D_METHOD("font_clear_size_cache", "font_rid"), &TextServer::font_clear_size_cache);
ClassDB::bind_method(D_METHOD("font_remove_size_cache", "font_rid", "size"), &TextServer::font_remove_size_cache);
ClassDB::bind_method(D_METHOD("font_get_size_cache_info", "font_rid"), &TextServer::font_get_size_cache_info);
ClassDB::bind_method(D_METHOD("font_set_ascent", "font_rid", "size", "ascent"), &TextServer::font_set_ascent);
ClassDB::bind_method(D_METHOD("font_get_ascent", "font_rid", "size"), &TextServer::font_get_ascent);
@ -364,8 +368,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_render_range", "font_rid", "size", "start", "end"), &TextServer::font_render_range);
ClassDB::bind_method(D_METHOD("font_render_glyph", "font_rid", "size", "index"), &TextServer::font_render_glyph);
ClassDB::bind_method(D_METHOD("font_draw_glyph", "font_rid", "canvas", "size", "pos", "index", "color"), &TextServer::font_draw_glyph, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("font_draw_glyph_outline", "font_rid", "canvas", "size", "outline_size", "pos", "index", "color"), &TextServer::font_draw_glyph_outline, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("font_draw_glyph", "font_rid", "canvas", "size", "pos", "index", "color", "oversampling"), &TextServer::font_draw_glyph, DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("font_draw_glyph_outline", "font_rid", "canvas", "size", "outline_size", "pos", "index", "color", "oversampling"), &TextServer::font_draw_glyph_outline, DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("font_is_language_supported", "font_rid", "language"), &TextServer::font_is_language_supported);
ClassDB::bind_method(D_METHOD("font_set_language_support_override", "font_rid", "language", "supported"), &TextServer::font_set_language_support_override);
@ -385,8 +389,10 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_supported_feature_list", "font_rid"), &TextServer::font_supported_feature_list);
ClassDB::bind_method(D_METHOD("font_supported_variation_list", "font_rid"), &TextServer::font_supported_variation_list);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("font_get_global_oversampling"), &TextServer::font_get_global_oversampling);
ClassDB::bind_method(D_METHOD("font_set_global_oversampling", "oversampling"), &TextServer::font_set_global_oversampling);
#endif
ClassDB::bind_method(D_METHOD("get_hex_code_box_size", "size", "index"), &TextServer::get_hex_code_box_size);
ClassDB::bind_method(D_METHOD("draw_hex_code_box", "canvas", "size", "pos", "index", "color"), &TextServer::draw_hex_code_box);
@ -494,8 +500,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_prev_character_pos", "shaped", "pos"), &TextServer::shaped_text_prev_character_pos);
ClassDB::bind_method(D_METHOD("shaped_text_closest_character_pos", "shaped", "pos"), &TextServer::shaped_text_closest_character_pos);
ClassDB::bind_method(D_METHOD("shaped_text_draw", "shaped", "canvas", "pos", "clip_l", "clip_r", "color"), &TextServer::shaped_text_draw, DEFVAL(-1), DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("shaped_text_draw_outline", "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"), &TextServer::shaped_text_draw_outline, DEFVAL(-1), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("shaped_text_draw", "shaped", "canvas", "pos", "clip_l", "clip_r", "color", "oversampling"), &TextServer::shaped_text_draw, DEFVAL(-1), DEFVAL(-1), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("shaped_text_draw_outline", "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color", "oversampling"), &TextServer::shaped_text_draw_outline, DEFVAL(-1), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("shaped_text_get_dominant_direction_in_range", "shaped", "start", "end"), &TextServer::shaped_text_get_dominant_direction_in_range);
@ -1706,7 +1712,7 @@ PackedInt32Array TextServer::string_get_character_breaks(const String &p_string,
return ret;
}
void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const {
void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color, float p_oversampling) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped);
@ -1726,7 +1732,7 @@ void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, cons
if (rtl && ellipsis_pos >= 0) {
for (int i = ellipsis_gl_size - 1; i >= 0; i--) {
for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color, p_oversampling);
if (orientation == ORIENTATION_HORIZONTAL) {
ofs.x += ellipsis_glyphs[i].advance;
} else {
@ -1777,7 +1783,7 @@ void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, cons
}
if (glyphs[i].font_rid != RID()) {
font_draw_glyph(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, ofs + p_pos + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color);
font_draw_glyph(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, ofs + p_pos + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color, p_oversampling);
} else if (hex_codes && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL) && ((glyphs[i].flags & GRAPHEME_IS_EMBEDDED_OBJECT) != GRAPHEME_IS_EMBEDDED_OBJECT)) {
TextServer::draw_hex_code_box(p_canvas, glyphs[i].font_size, ofs + p_pos + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color);
}
@ -1792,7 +1798,7 @@ void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, cons
if (!rtl && ellipsis_pos >= 0) {
for (int i = 0; i < ellipsis_gl_size; i++) {
for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color, p_oversampling);
if (orientation == ORIENTATION_HORIZONTAL) {
ofs.x += ellipsis_glyphs[i].advance;
} else {
@ -1803,7 +1809,7 @@ void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, cons
}
}
void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const {
void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color, float p_oversampling) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool rtl = (shaped_text_get_inferred_direction(p_shaped) == DIRECTION_RTL);
@ -1822,7 +1828,7 @@ void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canv
if (rtl && ellipsis_pos >= 0) {
for (int i = ellipsis_gl_size - 1; i >= 0; i--) {
for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
font_draw_glyph_outline(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
font_draw_glyph_outline(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color, p_oversampling);
if (orientation == ORIENTATION_HORIZONTAL) {
ofs.x += ellipsis_glyphs[i].advance;
} else {
@ -1872,7 +1878,7 @@ void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canv
}
}
if (glyphs[i].font_rid != RID()) {
font_draw_glyph_outline(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color);
font_draw_glyph_outline(glyphs[i].font_rid, p_canvas, glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, p_color, p_oversampling);
}
if (orientation == ORIENTATION_HORIZONTAL) {
ofs.x += glyphs[i].advance;
@ -1885,7 +1891,7 @@ void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canv
if (!rtl && ellipsis_pos >= 0) {
for (int i = 0; i < ellipsis_gl_size; i++) {
for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
font_draw_glyph_outline(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
font_draw_glyph_outline(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, p_outline_size, ofs + p_pos + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color, p_oversampling);
if (orientation == ORIENTATION_HORIZONTAL) {
ofs.x += ellipsis_glyphs[i].advance;
} else {

View file

@ -229,6 +229,7 @@ public:
void _draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const;
protected:
double vp_oversampling = 0.0;
HashMap<char32_t, char32_t> diacritics_map;
void _diacritics_map_add(const String &p_from, char32_t p_to);
void _init_diacritics_map();
@ -236,6 +237,10 @@ protected:
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
void _font_draw_glyph_bind_compat_104872(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const;
void _font_draw_glyph_outline_bind_compat_104872(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const;
void _shaped_text_draw_bind_compat_104872(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const;
void _shaped_text_draw_outline_bind_compat_104872(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
PackedInt32Array _shaped_text_get_word_breaks_bind_compat_90732(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
static void _bind_compatibility_methods();
#endif
@ -315,6 +320,8 @@ public:
virtual void font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) = 0;
virtual bool font_is_allow_system_fallback(const RID &p_font_rid) const = 0;
virtual void font_clear_system_fallback_cache() {}
virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) = 0;
virtual bool font_is_force_autohinter(const RID &p_font_rid) const = 0;
@ -345,12 +352,15 @@ public:
virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) = 0;
virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const = 0;
virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) = 0;
virtual double font_get_oversampling(const RID &p_font_rid) const = 0;
#ifndef DISABLE_DEPRECATED
virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) {}
virtual double font_get_oversampling(const RID &p_font_rid) const { return 1.0; }
#endif
virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const = 0;
virtual void font_clear_size_cache(const RID &p_font_rid) = 0;
virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) = 0;
virtual TypedArray<Dictionary> font_get_size_cache_info(const RID &p_font_rid) const = 0;
virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) = 0;
virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const = 0;
@ -417,8 +427,8 @@ public:
virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) = 0;
virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) = 0;
virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const = 0;
virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const = 0;
virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const = 0;
virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) = 0;
@ -438,8 +448,12 @@ public:
virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const = 0;
virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const = 0;
virtual double font_get_global_oversampling() const = 0;
virtual void font_set_global_oversampling(double p_oversampling) = 0;
#ifndef DISABLE_DEPRECATED
virtual double font_get_global_oversampling() const { return 1.0; }
virtual void font_set_global_oversampling(double p_oversampling) {}
#endif
virtual void reference_oversampling_level(double p_oversampling) {}
virtual void unreference_oversampling_level(double p_oversampling) {}
virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const;
virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const;
@ -560,8 +574,8 @@ public:
virtual int64_t shaped_text_closest_character_pos(const RID &p_shaped, int64_t p_pos) const;
// The pen position is always placed on the baseline and moving left to right.
virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const;
virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
#ifdef DEBUG_ENABLED
void debug_print_glyph(int p_idx, const Glyph &p_glyph) const;
@ -591,6 +605,8 @@ public:
TypedArray<Vector3i> parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const;
virtual void set_current_drawn_item_ovrsampling(double p_vp_oversampling) { vp_oversampling = p_vp_oversampling; }
virtual void cleanup() {}
TextServer();