diff --git a/core/templates/lru.h b/core/templates/lru.h index 48ba318b1213..1611693bf4ce 100644 --- a/core/templates/lru.h +++ b/core/templates/lru.h @@ -102,6 +102,7 @@ class LRUCache { } _FORCE_INLINE_ size_t get_capacity() const { return capacity; } + _FORCE_INLINE_ size_t get_size() const { return _map.size(); } void set_capacity(size_t p_capacity) { if (capacity > 0) { diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index 4ece57fa8141..cb20a3a34645 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -40,29 +40,6 @@ https://godotengine.org/asset-library/asset/515 https://godotengine.org/asset-library/asset/677 - - - - - Removes all OpenType features. - - - - - - - Returns OpenType feature [code]tag[/code]. - - - - - - - - Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - - Text alignment policy for the button's text, use one of the [enum @GlobalScope.HorizontalAlignment] constants. @@ -142,8 +119,8 @@ The size of the text outline. - - [Font] of the [Button]'s text. + + [FontConfig] of the [Button]'s text. Font size of the [Button]'s text. diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 98a498d71920..4c3d05b29f63 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -48,17 +48,26 @@ - - + + + + + + + + Draws a string first character using a custom font. + + + + + - - + + - - - Draws a string character using a custom font. Returns the advance, depending on the character width and kerning with an optional next character. + Draws a string first character outline using a custom font. @@ -127,7 +136,7 @@ - Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [member FontData.multichannel_signed_distance_field] for more information and caveats about MSDF font rendering. + Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [member Font.multichannel_signed_distance_field] for more information and caveats about MSDF font rendering. If [code]outline[/code] is positive, each alpha channel value of pixel in region is set to maximum value of true distance in the [code]outline[/code] radius. Value of the [code]pixel_range[/code] should the same that was used during distance field texture generation. @@ -152,21 +161,39 @@ - + - - + + - - - + + + Breaks [code]text[/code] to the lines and draws it using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. + + + + + + + + + + + + + + + + Breaks [code]text[/code] to the lines and draws text outline using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. + + @@ -245,16 +272,16 @@ - + - + - - - + + + Draws [code]text[/code] using the specified [code]font[/code] at the [code]position[/code] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. [b]Example using the default project font:[/b] @@ -276,7 +303,24 @@ DrawString(defaultFont, new Vector2(64, 64), "Hello world", HORIZONTAL_ALIGNMENT_LEFT, -1, defaultFontSize); [/csharp] [/codeblocks] - See also [method Font.draw_string]. + See also [method FontConfig.draw_string]. + + + + + + + + + + + + + + + + + Draws [code]text[/code] outline using the specified [code]font[/code] at the [code]position[/code] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index 6483faf7632b..70e3164ed7e3 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -44,8 +44,8 @@ The size of the text outline. - - The [Font] to use for the [CheckBox] text. + + The [FontConfig] to use for the [CheckBox] text. Font size of the [CheckBox]'s text. diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index 51b0411f4e54..717c272ee54f 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -44,8 +44,8 @@ The size of the text outline. - - The [Font] to use for the [CheckButton] text. + + The [FontConfig] to use for the [CheckButton] text. Font size of the [CheckButton]'s text. diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml index 7ca27a35feb1..2e6d8b402e97 100644 --- a/doc/classes/CodeEdit.xml +++ b/doc/classes/CodeEdit.xml @@ -649,8 +649,8 @@ The size of the text outline. - - Sets the default [Font]. + + Sets the default [FontConfig]. Sets default font size. diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index 53d35c1a3d27..33ebdf2be193 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -80,8 +80,8 @@ The size of the text outline. - - [Font] of the [ColorPickerButton]'s text. + + [FontConfig] of the [ColorPickerButton]'s text. Font size of the [ColorPickerButton]'s text. diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 2828896eacd9..99795600d2f6 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -250,9 +250,9 @@ - + - Creates a local override for a theme [Font] with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_font_override]. + Creates a local override for a theme [FontConfig] with the specified [code]name[/code]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_font_override]. See also [method get_theme_font]. @@ -474,7 +474,7 @@ - + Returns the default font from the first matching [Theme] in the tree if that [Theme] has a valid [member Theme.default_font] value. See [method get_theme_color] for details. @@ -488,11 +488,11 @@ - + - Returns a [Font] from the first matching [Theme] in the tree if that [Theme] has a font item with the specified [code]name[/code] and [code]theme_type[/code]. + Returns a [FontConfig] from the first matching [Theme] in the tree if that [Theme] has a font item with the specified [code]name[/code] and [code]theme_type[/code]. See [method get_theme_color] for details. @@ -607,7 +607,7 @@ - Returns [code]true[/code] if there is a local override for a theme [Font] with the specified [code]name[/code] in this [Control] node. + Returns [code]true[/code] if there is a local override for a theme [FontConfig] with the specified [code]name[/code] in this [Control] node. See [method add_theme_font_override]. @@ -699,7 +699,7 @@ - Removes a local override for a theme [Font] with the specified [code]name[/code] previously added by [method add_theme_font_override] or via the Inspector dock. + Removes a local override for a theme [FontConfig] with the specified [code]name[/code] previously added by [method add_theme_font_override] or via the Inspector dock. diff --git a/doc/classes/EditorFontPicker.xml b/doc/classes/EditorFontPicker.xml new file mode 100644 index 000000000000..b7c139549e90 --- /dev/null +++ b/doc/classes/EditorFontPicker.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index dae42ddf3461..bca3b298d934 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -1,243 +1,315 @@ - Font class is set of font data sources used to draw text. + Font source data and prerendered glyph cache, imported from dynamic or bitmap font. - Font contains a set of glyphs to represent Unicode characters, as well as the ability to draw it with variable width, ascent, descent and kerning. + [Font] contains a set of glyphs to represent Unicode characters imported from a font file, as well as a cache of rasterized glyphs, and a set of fallback [Font]s to use. + Use [FontConfig] to access specific OpenType variation of the font, create simulated bold / slanted version, and draw lines of text. + For more complex text processing, use [FontConfig] in conjunction with [TextLine] or [TextParagraph]. + Supported font formats: + - Dynamic font importer: TrueType (.ttf), TrueType collection (.ttc), OpenType (.otf), OpenType collection (.otc), WOFF (.woff), WOFF2 (.woff2), Type 1 (.pfb, .pfm). + - Bitmap font importer: AngelCode BMFont (.fnt, .font), text and binary (version 3) format variants. + - Monospace image font importer: All supported image formats. [b]Note:[/b] A character is a symbol that represents an item (letter, digit etc.) in an abstract way. [b]Note:[/b] A glyph is a bitmap or shape used to draw a one or more characters in a context-dependent manner. Glyph indices are bound to the specific font data source. - [b]Note:[/b] If a non of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code. - [codeblocks] - [gdscript] - var font = Font.new() - font.add_data(load("res://BarlowCondensed-Bold.ttf")) - $"Label".set("custom_fonts/font", font) - $"Label".set("custom_fonts/font_size", 64) - [/gdscript] - [csharp] - var font = new Font(); - font.AddData(ResourceLoader.Load<FontData>("res://BarlowCondensed-Bold.ttf")); - GetNode("Label").Set("custom_fonts/font", font); - GetNode("Label").Set("custom_font_sizes/font_size", 64); - [/csharp] - [/codeblocks] - To control font substitution priority use [FontData] language and script support. - Use language overrides to use same [Font] stack for multiple languages: - [codeblocks] - [gdscript] - # Use Naskh font for Persian and Nastaʼlīq font for Urdu text. - var font_data_fa = load("res://NotoNaskhArabicUI_Regular.ttf"); - font_data_fa.set_language_support_override("fa", true); - font_data_fa.set_language_support_override("ur", false); - - var font_data_ur = load("res://NotoNastaliqUrdu_Regular.ttf"); - font_data_ur.set_language_support_override("fa", false); - font_data_ur.set_language_support_override("ur", true); - [/gdscript] - [csharp] - // Use Naskh font for Persian and Nastaʼlīq font for Urdu text. - var fontDataFA = ResourceLoader.Load<FontData>("res://NotoNaskhArabicUI_Regular.ttf"); - fontDataFA.SetLanguageSupportOverride("fa", true); - fontDataFA.SetLanguageSupportOverride("ur", false); - - var fontDataUR = ResourceLoader.Load<FontData>("res://NotoNastaliqUrdu_Regular.ttf"); - fontDataUR.SetLanguageSupportOverride("fa", false); - fontDataUR.SetLanguageSupportOverride("ur", true); - [/csharp] - [/codeblocks] - Use script overrides to specify supported scripts for bitmap font or for less common scripts not directly supported by TrueType format: - [codeblocks] - [gdscript] - # Use specified font for Egyptian hieroglyphs. - var font_data = load("res://unifont.ttf"); - font_data.set_script_support_override("Egyp", true); - [/gdscript] - [csharp] - // Use specified font for Egyptian hieroglyphs. - var fontData = ResourceLoader.Load<FontData>("res://unifont.ttf"); - fontData.SetScriptSupportOverride("Egyp", true); - [/csharp] - [/codeblocks] + [b]Note:[/b] If a none of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code. - + - - Add font data source to the set. + Removes all font cache entries. - + + + - Removes all font data sourcers for the set. + Removes all rendered glyphs information from the cache entry. + [b]Note:[/b] This function will not remove textures associated with the glyphs, use [method remove_texture] to remove them manually. - - - - - - - - - - - - Draw a single Unicode character [code]char[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color, and optionally kerning if [code]next[/code] is passed. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. - [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead. - - - - - - - - - - - - - - - - - Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws it into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] 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. - See also [method CanvasItem.draw_multiline_string]. - - - - - - - - - - - - - - - - Draw [code]text[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. - See also [method CanvasItem.draw_string]. + + + + + + Removes all kerning overrides. - - - + + + - Returns the average font ascent (number of pixels above the baseline). - [b]Note:[/b] Real ascent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the ascent of empty line). + Removes all font sizes from the cache entry - - - - - + + + + - Returns the size of a character, optionally taking kerning into account if the next character is provided. - [b]Note:[/b] Do not use this function to calculate width of the string character by character, use [method get_string_size] or [TextLine] instead. The height returned is the font height (see also [method get_height]) and has no relation to the glyph height. + Removes all textures from font cache entry. + [b]Note:[/b] This function will not remove glyphs associated with the texture, use [method remove_glyph] to remove them manually. - - - + + + + + + - Returns the font data source at index [code]idx[/code]. If the index does not exist, returns [code]null[/code]. + Returns existing or creates a new font cache entry for the specified variation. - + + + + + + Returns the font ascent (number of pixels above the baseline). + + + - Returns the number of font data sources. + Returns number of the font cache entries. - + - + - Returns TextServer RID of the font data resources. + Returns text server font cache entry resource id. - + + - Returns the average font descent (number of pixels below the baseline). - [b]Note:[/b] Real descent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the descent of empty line). + Returns font descent (number of pixels below the baseline). - + - + - Returns the total average font height (ascent plus descent) in pixels. - [b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the height of empty line). + Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. - + + + + Returns number of faces in the TrueType / OpenType collection. + + + + + + + Recturns an active face index in the TrueType / OpenType collection. + + + - - - - + + + + + Returns glyph advance (offset of the next glyph). + [b]Note:[/b] Advance for glyphs outlines is the same as the base glyph advance and is not saved. + + + + + + + - Returns the size of a bounding box of a string broken into the lines, taking kerning and advance into account. - See also [method draw_multiline_string]. + Returns the glyph index of a [code]char[/code], optionally modified by the [code]variation_selector[/code]. - + + + - Returns [Array] of valid [FontData] [RID]s, which can be passed to the [TextServer] methods. + Returns list of rendered glyphs in the cache entry. - + + + + + + + Returns glyph offset from the baseline. + + + + + + + + + Returns glyph size. + + + - + + + + + Returns index of the cache texture containing the glyph. + + + + + + + - Returns the spacing for the given [code]type[/code] (see [enum TextServer.SpacingType]). + Returns rectangle in the cache texture containing the glyph. - + - - - - - + + + + + Returns kerning for the pair of glyphs. + + + + + + + + Returns list of the kerning overrides. + + + + + + + Returns [code]true[/code] if support override is enabled for the [code]language[/code]. + + + + + + Returns list of language support overrides. + + + + + + - Returns the size of a bounding box of a string, taking kerning and advance into account. - [b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by [method get_height]. - See also [method draw_string]. + Returns scaling factor of the color bitmap font. + + + + + + + Returns [code]true[/code] if support override is enabled for the [code]script[/code]. + + + + + + Returns list of script support overrides. + + + + + + + Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. Returns a string containing all the characters available in the font. - If a given character is included in more than one font data source, it appears only once in the returned string. + + + + + + Returns list of OpenType features supported by font. + + + + + + Returns list of supported [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url], each coordinate is returned as [code]tag: Vector3i(min_value,max_value,default_value)[/code]. + Font variations allow for continuous change of glyph characteristics along some given design axis, such as weight, width or slant. + + + + + + + + Returns number of textures used by font cache entry. + + + + + + + + + Returns a copy of the font cache texture image. + + + + + + + + + Returns a copy of the array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty. + + + + + + + Returns 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs. - + + - Returns average pixel offset of the underline below the baseline. - [b]Note:[/b] Real underline position of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate. + Returns pixel offset of the underline below the baseline. - + + + + Returns thickness of the underline in pixels. + + + + + - Returns average thickness of the underline. - [b]Note:[/b] Real underline thickness of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate. + Returns variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info. @@ -247,45 +319,336 @@ Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font. - + + + + + Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code). + + + + + + + Returns [code]true[/code], if font supports given script ([url=https://en.wikipedia.org/wiki/ISO_15924]ISO 15924[/url] code). + + + + + + + Loads an AngelCode BMFont (.fnt, .font) bitmap font from file [code]path[/code]. + [b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external fonts at run-time, such as fonts located at the [code]user://[/code] directory. + + + + + + + Loads a TrueType (.ttf), OpenType (.otf), WOFF (.woff), WOFF2 (.woff2) or Type 1 (.pfb, .pfm) dynamic font from file [code]path[/code]. + [b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external fonts at run-time, such as fonts located at the [code]user://[/code] directory. + + + + + + + Removes specified font cache entry. + + + - + + + - Removes the font data source at index [code]idx[/code]. If the index does not exist, nothing happens. + Removes specified rendered glyph information from the cache entry. + [b]Note:[/b] This function will not remove textures associated with the glyphs, use [method remove_texture] to remove them manually. - + - - + + + - Sets the font data source at index [code]idx[/code]. If the index does not exist, nothing happens. + Removes kerning override for the pair of glyphs. - + - - + - Sets the spacing for [code]type[/code] (see [enum TextServer.SpacingType]) to [code]value[/code] in pixels (not relative to the font size). + Remove language support override. - + + - After editing a font (changing data sources, etc.). Call this function to propagate changes to controls that might use it. + Removes script support override. + + + + + + + + Removes specified font size from the cache entry. + + + + + + + + + Removes specified texture from the cache entry. + [b]Note:[/b] This function will not remove glyphs associated with the texture. Remove them manually using [method remove_glyph]. + + + + + + + + + Renders specified glyph to the font cache texture. + + + + + + + + + + Renders the range of characters to the font cache texture. + + + + + + + + + Sets the font ascent (number of pixels above the baseline). + + + + + + + + + Sets the font descent (number of pixels below the baseline). + + + + + + + + Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. + + + + + + + + Sets an active face index in the TrueType / OpenType collection. + + + + + + + + + + Sets glyph advance (offset of the next glyph). + [b]Note:[/b] Advance for glyphs outlines is the same as the base glyph advance and is not saved. + + + + + + + + + + Sets glyph offset from the baseline. + + + + + + + + + + Sets glyph size. + + + + + + + + + + Sets index of the cache texture containing the glyph. + + + + + + + + + + Sets rectangle in the cache texture containing the glyph. + + + + + + + + + + Sets kerning for the pair of glyphs. + + + + + + + + Adds override for [method is_language_supported]. + + + + + + + + + Sets scaling factor of the color bitmap font. + + + + + + + + Adds override for [method is_script_supported]. + + + + + + + + + + Sets font cache texture image. + + + + + + + + + + Sets array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty (for the fonts without dynamic glyph generation support). + + + + + + + + Sets 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs. + + + + + + + + + Sets pixel offset of the underline below the baseline. + + + + + + + + + Sets thickness of the underline in pixels. + + + + + + + + Sets variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info. - - Extra spacing at the bottom of the line in pixels. + + If set to [code]true[/code], font 8-bit anitialiased glyph rendering is supported and enabled. + + + Contents of the dynamic font source file. + + + Array of fallback [Font]s. + + + Font size, used only for the bitmap fonts. + + + Font family name. + + + Font style flags, see [enum TextServer.FontStyle]. + + + If set to [code]true[/code], auto-hinting is supported and preferred over font built-in hinting. Used by dynamic fonts only. + + + If set to [code]true[/code], generate mipmaps for the font textures. + + + Font hinting mode. Used by dynamic fonts only. + + + The width of the range around the shape between the minimum and maximum representable signed distance. + + + Source font size used to generate MSDF textures. + + + 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. + + + Font OpenType feature set override. + + + Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only. - - Extra spacing at the top of the line in pixels. + + Font style name. - - Default font [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url]. + + Font glyph sub-pixel 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. diff --git a/doc/classes/FontConfig.xml b/doc/classes/FontConfig.xml new file mode 100644 index 000000000000..034a2b1e89d8 --- /dev/null +++ b/doc/classes/FontConfig.xml @@ -0,0 +1,301 @@ + + + + Font configuration resource used to draw text. + + + Font configuration contains font properties that can be set without reloading [Font], like OpenType variations/features and simulated bold / slant and extra spacing, as well as methods to draw lines of text. + [FontConfig] can be used to easily access multiple variants of the [Font] without duplicating cached font data. + [codeblocks] + [gdscript] + var fc = FontConfig.new() + fc.set_font(load("res://BarlowCondensed-Bold.ttf")) + $"Label".set("custom_fonts/font", fc) + $"Label".set("custom_fonts/font_size", 64) + [/gdscript] + [csharp] + var fc = new FontConfig(); + fc.SetFont(ResourceLoader.Load<Font>("res://BarlowCondensed-Bold.ttf")); + GetNode("Label").Set("custom_fonts/font", fc); + GetNode("Label").Set("custom_font_sizes/font_size", 64); + [/csharp] + [/codeblocks] + To use simulated bold font variant: + [codeblocks] + [gdscript] + var fc = FontConfig.new() + fc.set_font(load("res://BarlowCondensed-Regular.ttf")) + fc.set_variation_embolden(1.2); + $"Label".set("custom_fonts/font", fc) + $"Label".set("custom_fonts/font_size", 64) + [/gdscript] + [csharp] + var fc = new FontConfig(); + fc.SetFont(ResourceLoader.Load<Font>("res://BarlowCondensed-Regular.ttf")); + fc.SetVariationEmbolden(1.2); + GetNode("Label").Set("custom_fonts/font", fc); + GetNode("Label").Set("custom_font_sizes/font_size", 64); + [/csharp] + [/codeblocks] + + + + + + + + + + + + + Draw a single Unicode character [code]char[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. + [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead. + + + + + + + + + + + + Draw a single Unicode character [code]char[/code] outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. + [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead. + + + + + + + + + + + + + + + + + Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws it into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] 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. + See also [method CanvasItem.draw_multiline_string]. + + + + + + + + + + + + + + + + + + Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws text outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size, optionally clipping the width and aligning horizontally. [code]position[/code] 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. + See also [method CanvasItem.draw_multiline_string_outline]. + + + + + + + + + + + + + + + + Draw [code]text[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. + See also [method CanvasItem.draw_string]. + + + + + + + + + + + + + + + + + Draw [code]text[/code] outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. + See also [method CanvasItem.draw_string_outline]. + + + + + + + Returns the average font ascent (number of pixels above the baseline). + [b]Note:[/b] Real ascent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the ascent of empty line). + + + + + + + + Returns the size of a character, optionally taking kerning into account if the next character is provided. + [b]Note:[/b] Do not use this function to calculate width of the string character by character, use [method get_string_size] or [TextLine] instead. The height returned is the font height (see also [method get_height]) and has no relation to the glyph height. + + + + + + + Returns the average font descent (number of pixels below the baseline). + [b]Note:[/b] Real descent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the descent of empty line). + + + + + + + Returns the total average font height (ascent plus descent) in pixels. + [b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the height of empty line). + + + + + + + + + + + + + + Returns the size of a bounding box of a string broken into the lines, taking kerning and advance into account. + See also [method draw_multiline_string]. + + + + + + Returns [Array] of valid [Font] [RID]s, which can be passed to the [TextServer] methods. + + + + + + + Returns the spacing for the given [code]type[/code] (see [enum TextServer.SpacingType]). + + + + + + + + + + + + + Returns the size of a bounding box of a string, taking kerning and advance into account. + [b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by [method get_height]. + See also [method draw_string]. + + + + + + Returns a string containing all the characters available in the font. + If a given character is included in more than one font data source, it appears only once in the returned string. + + + + + + + Returns average pixel offset of the underline below the baseline. + [b]Note:[/b] Real underline position of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate. + + + + + + + Returns average thickness of the underline. + [b]Note:[/b] Real underline thickness of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate. + + + + + + + Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font. + + + + + + + + Sets LRU cache capacity for [code]draw_*[/code] methods. + + + + + + + + Sets the spacing for [code]type[/code] (see [enum TextServer.SpacingType]) to [code]value[/code] in pixels (not relative to the font size). + + + + + + Font, imported from a TrueType, OpenType, WOFF, WOFF2, Type 1, AngelCode BMFont font file or image. + + + A set of OpenType feature tags. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. + + + Extra spacing at the bottom of the line in pixels. + + + Extra spacing between graphical glyphs. + + + Extra width of the space glyphs. + + + Extra spacing at the top of the line in pixels. + + + If set to [code]true[/code], different set of variations can be set for each fallback font. + + + If is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. + [b]Note:[/b] Emboldened fonts might have self-intersecting outlines, which will prevent MSDF fonts and [TextMesh] from working correctly. + + + Active face index in the TrueType / OpenType collection file. + + + Font OpenType variation coordinates. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]OpenType variation tags[/url]. + + + 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs. + For example, to simulate italic typeface by slanting, apply the following transform [code]Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0)[/code]. + + + diff --git a/doc/classes/FontData.xml b/doc/classes/FontData.xml deleted file mode 100644 index d32e7b3a9475..000000000000 --- a/doc/classes/FontData.xml +++ /dev/null @@ -1,627 +0,0 @@ - - - - Font source data and prerendered glyph cache, imported from dynamic or bitmap font. - Supported font formats: - - Dynamic font importer: TrueType (.ttf), TrueType collection (.ttc), OpenType (.otf), OpenType collection (.otc), WOFF (.woff), WOFF2 (.woff2), Type 1 (.pfb, .pfm). - - Bitmap font importer: AngelCode BMFont (.fnt, .font), text and binary (version 3) format variants. - - Monospace image font importer: All supported image formats. - - - - - - - - - - Removes all font cache entries. - - - - - - - - Removes all rendered glyphs information from the cache entry. - [b]Note:[/b] This function will not remove textures associated with the glyphs, use [method remove_texture] to remove them manually. - - - - - - - - Removes all kerning overrides. - - - - - - - Removes all font sizes from the cache entry - - - - - - - - Removes all textures from font cache entry. - [b]Note:[/b] This function will not remove glyphs associated with the texture, use [method remove_glyph] to remove them manually. - - - - - - - Returns existing or creates a new font cache entry for the specified variation coordinates. - - - - - - - - Returns the font ascent (number of pixels above the baseline). - - - - - - Returns number of the font cache entries. - - - - - - - Returns text server font cache entry resource id. - - - - - - - - Returns font descent (number of pixels below the baseline). - - - - - - Returns number of faces in the TrueType / OpenType collection. - - - - - - - - - Returns glyph advance (offset of the next glyph). - [b]Note:[/b] Advance for glyphs outlines is the same as the base glyph advance and is not saved. - - - - - - - - - Returns the glyph index of a [code]char[/code], optionally modified by the [code]variation_selector[/code]. - - - - - - - - Returns list of rendered glyphs in the cache entry. - - - - - - - - - Returns glyph offset from the baseline. - - - - - - - - - Returns glyph size. - - - - - - - - - Returns index of the cache texture containing the glyph. - - - - - - - - - Returns rectangle in the cache texture containing the glyph. - - - - - - - - - Returns kerning for the pair of glyphs. - - - - - - - - Returns list of the kerning overrides. - - - - - - - Returns [code]true[/code] if support override is enabled for the [code]language[/code]. - - - - - - Returns list of language support overrides. - - - - - - - - Returns scaling factor of the color bitmap font. - - - - - - - Returns [code]true[/code] if support override is enabled for the [code]script[/code]. - - - - - - Returns list of script support overrides. - - - - - - - Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. - - - - - - - - - Returns extra spacing added between glyphs in pixels. - - - - - - Returns a string containing all the characters available in the font. - - - - - - Returns list of OpenType features supported by font. - - - - - - Returns list of supported [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url], each coordinate is returned as [code]tag: Vector3i(min_value,max_value,default_value)[/code]. - Font variations allow for continuous change of glyph characteristics along some given design axis, such as weight, width or slant. - - - - - - - - Returns number of textures used by font cache entry. - - - - - - - - - Returns a copy of the font cache texture image. - - - - - - - - - Returns a copy of the array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty. - - - - - - - - Returns pixel offset of the underline below the baseline. - - - - - - - - Returns thickness of the underline in pixels. - - - - - - - Returns variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info. - - - - - - - Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font. - - - - - - - Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code). - - - - - - - Returns [code]true[/code], if font supports given script ([url=https://en.wikipedia.org/wiki/ISO_15924]ISO 15924[/url] code). - - - - - - - Loads an AngelCode BMFont (.fnt, .font) bitmap font from file [code]path[/code]. - [b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external fonts at run-time, such as fonts located at the [code]user://[/code] directory. - - - - - - - Loads a TrueType (.ttf), TrueType collection (.ttc), OpenType (.otf), OpenType collection (.otc), WOFF (.woff), WOFF2 (.woff2) or Type 1 (.pfb, .pfm) dynamic font from file [code]path[/code]. - [b]Note:[/b] Use [member face_index] to select specific face from the collection file. - [b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external fonts at run-time, such as fonts located at the [code]user://[/code] directory. - - - - - - - Removes specified font cache entry. - - - - - - - - - Removes specified rendered glyph information from the cache entry. - [b]Note:[/b] This function will not remove textures associated with the glyphs, use [method remove_texture] to remove them manually. - - - - - - - - - Removes kerning override for the pair of glyphs. - - - - - - - Remove language support override. - - - - - - - Removes script support override. - - - - - - - - Removes specified font size from the cache entry. - - - - - - - - - Removes specified texture from font cache entry. - [b]Note:[/b] This function will not remove glyphs associated with the texture, remove them manually, using [method remove_glyph]. - - - - - - - - - Renders specified glyph the the font cache texture. - - - - - - - - - - Renders the range of characters to the font cache texture. - - - - - - - - - Sets the font ascent (number of pixels above the baseline). - - - - - - - - - Sets the font descent (number of pixels below the baseline). - - - - - - - - - - Sets glyph advance (offset of the next glyph). - [b]Note:[/b] Advance for glyphs outlines is the same as the base glyph advance and is not saved. - - - - - - - - - - Sets glyph offset from the baseline. - - - - - - - - - - Sets glyph size. - - - - - - - - - - Sets index of the cache texture containing the glyph. - - - - - - - - - - Sets rectangle in the cache texture containing the glyph. - - - - - - - - - - Sets kerning for the pair of glyphs. - - - - - - - - Adds override for [method is_language_supported]. - - - - - - - - - Sets scaling factor of the color bitmap font. - - - - - - - - Adds override for [method is_script_supported]. - - - - - - - - - - Sets extra spacing added between glyphs in pixels. - - - - - - - - - - Sets font cache texture image. - - - - - - - - - - Sets array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty (for the fonts without dynamic glyph generation support). - - - - - - - - - Sets pixel offset of the underline below the baseline. - - - - - - - - - Sets thickness of the underline in pixels. - - - - - - - - Sets variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info. - - - - - - If set to [code]true[/code], font 8-bit anitialiased glyph rendering is supported and enabled. - - - Contents of the dynamic font source file. - - - If is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. - - - Active face index in the TrueType / OpenType collection file. - - - Font size, used only for the bitmap fonts. - - - Font family name. - - - Font style flags, see [enum TextServer.FontStyle]. - - - If set to [code]true[/code], auto-hinting is supported and preferred over font built-in hinting. Used by dynamic fonts only. - - - If set to [code]true[/code], generate mipmaps for the font textures. - - - Font hinting mode. Used by dynamic fonts only. - - - The width of the range around the shape between the minimum and maximum representable signed distance. - - - Source font size used to generate MSDF textures. - - - 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. - - - Font OpenType feature set override. - - - Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only. - - - Font style name. - - - Font glyph sub-pixel 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. - - - 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs. - For example, to simulate italic typeface by slanting, apply the following transform [code]Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0)[/code]. - - - diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index f261da8413e1..fc7e4c5ef3b6 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -17,12 +17,6 @@ Disables all input and output slots of the GraphNode. - - - - Removes all OpenType features. - - @@ -98,13 +92,6 @@ Returns the type of the output connection [code]idx[/code]. - - - - - Returns OpenType feature [code]tag[/code]. - - @@ -154,14 +141,6 @@ Returns [code]true[/code] if right (output) side of the slot [code]idx[/code] is enabled. - - - - - - Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -345,7 +324,7 @@ Vertical offset of the title text. - + Font used for the title text. diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 83e7eba5e57d..4c50ecaba621 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -37,13 +37,6 @@ Removes all items from the list. - - - - - Removes all OpenType features from the item's text. - - @@ -121,14 +114,6 @@ Returns the metadata value of the specified index. - - - - - - Returns OpenType feature [code]tag[/code] of the item's text. - - @@ -301,15 +286,6 @@ Sets a value (of any type) to be stored with the item associated with the specified index. - - - - - - - Sets OpenType feature [code]tag[/code] for the item's text. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -486,8 +462,8 @@ The vertical spacing between items. - - [Font] of the item's text. + + [FontConfig] of the item's text. Font size of the item's text. diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index d5744bbc42b2..b9355837b218 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -11,12 +11,6 @@ https://godotengine.org/asset-library/asset/515 - - - - Removes all OpenType features. - - @@ -32,13 +26,6 @@ If there're no lines returns font size in pixels. - - - - - Returns OpenType feature [code]tag[/code]. - - @@ -51,14 +38,6 @@ Returns the number of lines shown. Useful if the [Label]'s height cannot currently display all lines. - - - - - - Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -163,7 +142,7 @@ Default text [Color] of the [Label]. - The tint of [Font]'s outline. + The tint of text outline. [Color] of the text's shadow effect. @@ -183,8 +162,8 @@ The size of the shadow outline. - - [Font] used for the [Label]'s text. + + [FontConfig] used for the [Label]'s text. Font size of the [Label]'s text. diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index c4d02e61013a..76df4ed64baf 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -9,12 +9,6 @@ - - - - Removes all OpenType features. - - @@ -28,13 +22,6 @@ Returns the value of the specified flag. - - - - - Returns OpenType feature [code]tag[/code]. - - @@ -43,14 +30,6 @@ If [code]true[/code], the specified flag will be enabled. See [enum Label3D.DrawFlags] for a list of flags. - - - - - - Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -71,8 +50,8 @@ If [code]true[/code], the label is rendered at the same size regardless of distance. - - [Font] used for the [Label3D]'s text. + + Font configuration used to display text. Font size of the [Label3D]'s text. @@ -96,7 +75,7 @@ The text drawing offset (in pixels). - The tint of [Font]'s outline. + The tint of text outline. Sets the render priority for the text outline. Higher priority objects will be sorted in front of lower priority objects. diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 55e012ee0c4c..66514da1efd5 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -37,12 +37,6 @@ Erases the [LineEdit]'s [member text]. - - - - Removes all OpenType features. - - @@ -70,13 +64,6 @@ [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member Window.visible] property. - - - - - Returns OpenType feature [code]tag[/code]. - - @@ -149,14 +136,6 @@ Selects the whole [String]. - - - - - - Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -415,7 +394,7 @@ The size of the text outline. - + Font used for the text. diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index ba80504caf1b..7ce58d550bf3 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -9,29 +9,6 @@ - - - - - Removes all OpenType features. - - - - - - - Returns OpenType feature [code]tag[/code]. - - - - - - - - Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - - Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. @@ -85,8 +62,8 @@ The vertical space between the baseline of text and the underline. - - [Font] of the [LinkButton]'s text. + + [FontConfig] of the [LinkButton]'s text. Font size of the [LinkButton]'s text. diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index bec567b3efc3..dbf07591687e 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -70,8 +70,8 @@ The size of the text outline. - - [Font] of the [MenuButton]'s text. + + [FontConfig] of the [MenuButton]'s text. Font size of the [MenuButton]'s text. diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index a7b1f0ea33b0..1735188abbd5 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -244,8 +244,8 @@ The size of the text outline. - - [Font] of the [OptionButton]'s text. + + [FontConfig] of the [OptionButton]'s text. Font size of the [OptionButton]'s text. diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index eb2b6810719c..f4950def12ab 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -181,13 +181,6 @@ Removes all items from the [PopupMenu]. - - - - - Removes all OpenType features form the item's text. - - @@ -243,14 +236,6 @@ Returns the metadata of the specified item, which might be of any type. You can set it with [method set_item_metadata], which provides a simple way of assigning context data to items. - - - - - - Returns OpenType feature [code]tag[/code] of the item's text. - - @@ -451,15 +436,6 @@ Sets the state of a multistate item. See [method add_multistate_item] for details. - - - - - - - Sets OpenType feature [code]tag[/code] for the item's text. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -602,11 +578,11 @@ The vertical space between each menu item. - - [Font] used for the menu items. + + [FontConfig] used for the menu items. - - [Font] used for the labeled separator. + + [FontConfig] used for the labeled separator. Font size of the labeled separator. diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index 8a781c51fb53..cfa5021922c6 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -43,7 +43,7 @@ The size of the text outline. - + Font used to draw the fill percentage if [member percent_visible] is [code]true[/code]. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 25f0a997bad1..171c8e03804a 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -587,7 +587,7 @@ Path to a custom [Font] resource to use as default for all GUI elements of the project. - If set to [code]true[/code], default font uses 8-bit anitialiased glyph rendering. See [member FontData.antialiased]. + If set to [code]true[/code], default font uses 8-bit anitialiased glyph rendering. See [member Font.antialiased]. If set to [code]true[/code], the default font will have mipmaps generated. This prevents text from looking grainy when a [Control] is scaled down, or when a [Label3D] is viewed from a long distance (if [member Label3D.texture_filter] is set to a mode that displays mipmaps). @@ -595,7 +595,7 @@ [b]Note:[/b] This setting does not affect custom [Font]s used within the project. - Default font hinting mode. See [member FontData.hinting]. + Default font hinting mode. See [member Font.hinting]. If set to [code]true[/code], the default font will use multichannel signed distance field (MSDF) for crisp rendering at any size. Since this approach does not rely on rasterizing the font every time its size changes, this allows for resizing the font in real-time without any performance penalty. Text will also not look grainy for [Control]s that are scaled down (or for [Label3D]s viewed from a long distance). @@ -603,7 +603,7 @@ [b]Note:[/b] This setting does not affect custom [Font]s used within the project. - Default font glyph sub-pixel positioning mode. See [member FontData.subpixel_positioning]. + Default font glyph sub-pixel positioning mode. See [member Font.subpixel_positioning]. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index c5cc343fac03..1c11d5075481 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -252,7 +252,7 @@ - + @@ -271,23 +271,15 @@ - + Adds a [code][font][/code] tag to the tag stack. Overrides default fonts for its duration. - - - - - Adds a [code][ot_feature][/code] tag to the tag stack. Overrides default OpenType font feature for its duration. - - - Adds a [code][font_size][/code] tag to the tag stack. Overrides default font size for its duration. @@ -700,19 +692,19 @@ The vertical separation of elements in a table. - + The font used for bold text. - + The font used for bold italics text. - + The font used for italics text. - + The font used for monospace text. - + The default text font. diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml index a8ed0d428694..a0ac27d8e470 100644 --- a/doc/classes/TabBar.xml +++ b/doc/classes/TabBar.xml @@ -17,13 +17,6 @@ Adds a new tab. - - - - - Removes all OpenType features from the tab title. - - @@ -77,14 +70,6 @@ Returns the number of hidden tabs offsetted to the left. - - - - - - Returns OpenType feature [code]tag[/code] of the tab title. - - @@ -175,15 +160,6 @@ Sets language code of tab title used for line-breaking and text shaping algorithms, if left empty current locale is used instead. - - - - - - - Sets OpenType feature [code]tag[/code] for the tab title. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -344,7 +320,7 @@ The size of the tab text outline. - + The font used to draw tab names. diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 10b5f730ad41..db9518904d15 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -219,7 +219,7 @@ The space at the left or right edges of the tab bar, accordingly with the current [member tab_alignment]. The margin is ignored with [code]ALIGNMENT_RIGHT[/code] if the tabs are clipped (see [member clip_tabs]) or a popup has been set (see [method set_popup]). The margin is always ignored with [code]ALIGNMENT_CENTER[/code]. - + The font used to draw tab names. diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 58fdd2d058c8..3f0f15ff4e75 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -85,12 +85,6 @@ Performs a full reset of [TextEdit], including undo history. - - - - Removes all OpenType features. - - @@ -355,13 +349,6 @@ Returns the count to the next visible line from [code]line[/code] to [code]line + visible_amount[/code]. Can also count backwards. For example if a [TextEdit] has 5 lines with lines 2 and 3 hidden, calling this with [code]line = 1, visible_amount = 1[/code] would return 3. - - - - - Returns OpenType feature [code]tag[/code]. - - @@ -859,14 +846,6 @@ Sets the text for [code]gutter[/code] on [code]line[/code]. - - - - - - Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - @@ -1264,8 +1243,8 @@ The size of the text outline. - - Sets the default [Font]. + + Sets the default [FontConfig]. Sets default font size. diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml index 5359937db592..71883e0face3 100644 --- a/doc/classes/TextLine.xml +++ b/doc/classes/TextLine.xml @@ -22,11 +22,10 @@ - - - - - + + + + Adds text span and font to draw it. diff --git a/doc/classes/TextMesh.xml b/doc/classes/TextMesh.xml index 5a1501d2caa0..fc13046d7190 100644 --- a/doc/classes/TextMesh.xml +++ b/doc/classes/TextMesh.xml @@ -10,29 +10,6 @@ - - - - - Removes all OpenType features. - - - - - - - Returns OpenType feature [code]tag[/code]. - - - - - - - - Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. - - - Step (in pixels) used to approximate Bézier curves. @@ -40,8 +17,8 @@ Depths of the mesh, if set to [code]0.0[/code] only front surface, is generated, and UV layout is changed to use full texture for the front face only. - - [Font] used for the [TextMesh]'s text. + + Font configuration used to display text. Font size of the [TextMesh]'s text. diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index 964e2c771f73..59a4c3689783 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -22,11 +22,10 @@ - - - - - + + + + Adds text span and font to draw it. @@ -217,18 +216,6 @@ Returns the size of the bounding box of the paragraph. - - - - Returns extra spacing at the bottom of the line. See [member Font.spacing_bottom]. - - - - - - Returns extra spacing at the top of the line. See [member Font.spacing_top]. - - @@ -256,11 +243,10 @@ - - + + - - + Sets drop cap, overrides previously set drop cap. Drop cap (dropped capital) is a decorative element at the beginning of a paragraph that is larger than the rest of the text. diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 19be38b32367..823642417d97 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -355,15 +355,6 @@ Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. - - - - - - - Returns extra spacing added between glyphs in pixels. - - @@ -542,7 +533,7 @@ - Removes specified texture from font cache entry. + Removes specified texture from the cache entry. [b]Note:[/b] This function will not remove glyphs associated with the texture, remove them manually, using [method font_remove_glyph]. @@ -792,16 +783,6 @@ Adds override for [method font_is_script_supported]. - - - - - - - - Sets extra spacing added between glyphs in pixels. - - @@ -1286,6 +1267,14 @@ Returns size of the text. + + + + + + Returns extra spacing added between glyphs or lines in pixels. + + @@ -1431,6 +1420,15 @@ If set to [code]true[/code] text buffer will display invalid characters as hexadecimal codes, otherwise nothing is displayed. + + + + + + + Sets extra spacing added between glyphs or lines in pixels. + + diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index b3be858ca109..2f7b31b6636a 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -345,15 +345,6 @@ Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. - - - - - - - Returns extra spacing added between glyphs in pixels. - - @@ -531,7 +522,7 @@ - Removes specified texture from font cache entry. + Removes specified texture from the cache entry. @@ -788,16 +779,6 @@ Adds override for [method font_is_script_supported]. - - - - - - - - Sets extra spacing added between glyphs in pixels. - - @@ -1288,6 +1269,14 @@ Returns size of the text. + + + + + + Returns extra spacing added between glyphs or lines in pixels. + + @@ -1436,6 +1425,15 @@ If set to [code]true[/code] text buffer will display invalid characters as hexadecimal codes, otherwise nothing is displayed. + + + + + + + Sets extra spacing added between glyphs or lines in pixels. + + diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 5270da9588bf..7c30bdc41888 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -50,7 +50,7 @@ - Removes the [Font] property defined by [code]name[/code] and [code]theme_type[/code], if it exists. + Removes the [FontConfig] property defined by [code]name[/code] and [code]theme_type[/code], if it exists. Fails if it doesn't exist. Use [method has_font] to check for existence. @@ -144,11 +144,11 @@ - + - Returns the [Font] property defined by [code]name[/code] and [code]theme_type[/code], if it exists. + Returns the [FontConfig] property defined by [code]name[/code] and [code]theme_type[/code], if it exists. Returns the default theme font if the property doesn't exist and the default theme font is set up (see [member default_font]). Use [method has_font] to check for existence of the property and [method has_default_font] to check for existence of the default theme font. Returns the engine fallback font value, if neither exist. @@ -157,7 +157,7 @@ - Returns a list of names for [Font] properties defined with [code]theme_type[/code]. Use [method get_font_type_list] to get a list of possible theme type names. + Returns a list of names for [FontConfig] properties defined with [code]theme_type[/code]. Use [method get_font_type_list] to get a list of possible theme type names. @@ -186,7 +186,7 @@ - Returns a list of all unique theme type names for [Font] properties. Use [method get_type_list] to get a list of all unique theme types. + Returns a list of all unique theme type names for [FontConfig] properties. Use [method get_type_list] to get a list of all unique theme types. @@ -325,7 +325,7 @@ - Returns [code]true[/code] if the [Font] property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font is set up (see [method has_default_font]). + Returns [code]true[/code] if the [FontConfig] property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font is set up (see [method has_default_font]). Returns [code]false[/code] if neither exist. Use [method set_font] to define the property. @@ -334,8 +334,8 @@ - Returns [code]true[/code] if the font size property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font size is set up (see [method has_default_font_size]). - Returns [code]false[/code] if neither exist. Use [method set_font_size] to define the property. + Returns [code]true[/code] if [member default_font_size] has a valid value. + Returns [code]false[/code] if it doesn't. The value must be greater than [code]0[/code] to be considered valid. @@ -416,7 +416,7 @@ - Renames the [Font] property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists. + Renames the [FontConfig] property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists. Fails if it doesn't exist, or if a similar property with the new name already exists. Use [method has_font] to check for existence, and [method clear_font] to remove the existing property. @@ -426,8 +426,8 @@ - Renames the font size property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists. - Fails if it doesn't exist, or if a similar property with the new name already exists. Use [method has_font_size] to check for existence, and [method clear_font_size] to remove the existing property. + Returns [code]true[/code] if the font size property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font size is set up (see [method has_default_font_size]). + Returns [code]false[/code] if neither exist. Use [method set_font_size] to define the property. @@ -484,9 +484,9 @@ - + - Creates or changes the value of the [Font] property defined by [code]name[/code] and [code]theme_type[/code]. Use [method clear_font] to remove the property. + Creates or changes the value of the [FontConfig] property defined by [code]name[/code] and [code]theme_type[/code]. Use [method clear_font] to remove the property. @@ -495,7 +495,8 @@ - Creates or changes the value of the font size property defined by [code]name[/code] and [code]theme_type[/code]. Use [method clear_font_size] to remove the property. + Renames the font size property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists. + Fails if it doesn't exist, or if a similar property with the new name already exists. Use [method has_font_size] to check for existence, and [method clear_font_size] to remove the existing property. @@ -545,7 +546,7 @@ The default base scale factor of this theme resource. Used by some controls to scale their visual properties based on the global scale factor. If this value is set to [code]0.0[/code], the global scale factor is used. Use [method has_default_base_scale] to check if this value is valid. - + The default font of this theme resource. Used as the default value when trying to fetch a font resource that doesn't exist in this theme or is in invalid state. If the default font is also missing or invalid, the engine fallback value is used. Use [method has_default_font] to check if this value is valid. @@ -562,7 +563,7 @@ Theme's constant item type. - Theme's [Font] item type. + Theme's [FontConfig] item type. Theme's font size item type. diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 6ae85ad242db..2b62f4678b88 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -41,13 +41,6 @@ Clears the tree. This removes all items. - - - - - Removes all OpenType features from the item's text. - - @@ -113,14 +106,6 @@ Returns column title language code. - - - - - - Returns OpenType feature [code]tag[/code] of the column title. - - @@ -307,15 +292,6 @@ Sets language code of column title used for line-breaking and text shaping algorithms, if left empty current locale is used instead. - - - - - - - Sets OpenType feature [code]tag[/code] for the column title. - - @@ -547,11 +523,11 @@ The vertical padding inside each item, i.e. the distance between the item's content and top/bottom border. - - [Font] of the item's text. + + [FontConfig] of the item's text. - - [Font] of the title button's text. + + [FontConfig] of the title button's text. Font size of the item's text. diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 0a680b9627af..c761c310fd68 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -42,13 +42,6 @@ Resets the color for the given column to default. - - - - - Removes all OpenType features. - - @@ -153,7 +146,7 @@ - + Returns custom font used to draw text in the column [code]column[/code]. @@ -241,14 +234,6 @@ If [code]wrap[/code] is enabled, the method will wrap around to the first visible element in the tree when called on the last visible element, otherwise it returns [code]null[/code]. - - - - - - Returns OpenType feature [code]tag[/code] of the item's text. - - @@ -494,7 +479,7 @@ - + Sets custom font used to draw text in the column [code]column[/code]. @@ -580,15 +565,6 @@ Sets the metadata value for the given column, which can be retrieved later using [method get_metadata]. This can be used, for example, to store a reference to the original data. - - - - - - - Sets OpenType feature [code]tag[/code] for the item's text. - - diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 5ce870a8996a..d3be782da8f3 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -65,7 +65,7 @@ - + @@ -75,11 +75,11 @@ - + - Returns the [Font] at [code]name[/code] if the theme has [code]theme_type[/code]. + Returns the [FontConfig] at [code]name[/code] if the theme has [code]theme_type[/code]. @@ -135,7 +135,7 @@ - Returns [code]true[/code] if [Font] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]true[/code] if [FontConfig] with [code]name[/code] is in [code]theme_type[/code]. Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. @@ -480,7 +480,7 @@ The size of the title outline. - + The size of the title font. diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index f0650ee44696..69dfbabdb3f2 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -247,7 +247,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { draw_rect(Rect2(Point2(), get_size()), accent, false, Math::round(EDSCALE)); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); int hsep = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index d81d62978003..ce74aea1af83 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1493,7 +1493,7 @@ void AnimationTimelineEdit::_notification(int p_what) { return; } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); @@ -1577,10 +1577,10 @@ void AnimationTimelineEdit::_notification(int p_what) { int decimals = 2; bool step_found = false; - const float period_width = font->get_char_size('.', 0, font_size).width; - float max_digit_width = font->get_char_size('0', 0, font_size).width; + const float period_width = font->get_char_size('.', font_size).width; + float max_digit_width = font->get_char_size('0', font_size).width; for (int i = 1; i <= 9; i++) { - const float digit_width = font->get_char_size('0' + i, 0, font_size).width; + const float digit_width = font->get_char_size('0' + i, font_size).width; max_digit_width = MAX(digit_width, max_digit_width); } const int max_sc = int(Math::ceil(zoomw / scale)); @@ -1628,7 +1628,7 @@ void AnimationTimelineEdit::_notification(int p_what) { draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE)); draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec); - prev_frame_ofs = i + font->get_string_size(itos(frame), font_size).x + 5 * EDSCALE; + prev_frame_ofs = i + font->get_string_size(itos(frame), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + 5 * EDSCALE; } } } @@ -1672,7 +1672,7 @@ void AnimationTimelineEdit::set_animation(const Ref &p_animation) { Size2 AnimationTimelineEdit::get_minimum_size() const { Size2 ms = add_track->get_minimum_size(); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); ms.height = MAX(ms.height, font->get_height(font_size)); ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_theme_icon(SNAME("Hsize"), SNAME("EditorIcons"))->get_width() + 2; @@ -1974,7 +1974,7 @@ void AnimationTrackEdit::_notification(int p_what) { draw_style_box(get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles")), Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); int hsep = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); @@ -2333,7 +2333,7 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool Vector2 ofs(p_x - icon_to_draw->get_width() / 2, int(get_size().height - icon_to_draw->get_height()) / 2); if (animation->track_get_type(track) == Animation::TYPE_METHOD) { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); color.a = 0.5; @@ -2456,7 +2456,7 @@ NodePath AnimationTrackEdit::get_path() const { Size2 AnimationTrackEdit::get_minimum_size() const { Ref texture = get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); @@ -3265,7 +3265,7 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_animation_track_edit(Object void AnimationTrackEditGroup::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int separation = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); Color color = get_theme_color(SNAME("font_color"), SNAME("Label")); @@ -3311,7 +3311,7 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref &p_type, co } Size2 AnimationTrackEditGroup::get_minimum_size() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index cd40b5391982..929d79602fa5 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -80,13 +80,13 @@ void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x, /// COLOR /// int AnimationTrackEditColor::get_key_height() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return font->get_height(font_size) * 0.8; } Rect2 AnimationTrackEditColor::get_key_rect(int p_index, float p_pixels_sec) { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; return Rect2(-fh / 2, 0, fh, get_size().height); @@ -97,7 +97,7 @@ bool AnimationTrackEditColor::is_key_selectable_by_distance() const { } void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = (font->get_height(font_size) * 0.8); @@ -166,7 +166,7 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) { Color color = get_animation()->track_get_key_value(get_track(), p_index); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; @@ -205,7 +205,7 @@ int AnimationTrackEditAudio::get_key_height() const { return AnimationTrackEdit::get_key_height(); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return int(font->get_height(font_size) * 1.5); } @@ -238,7 +238,7 @@ Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) { return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); @@ -302,7 +302,7 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, return; } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float fh = int(font->get_height(font_size) * 1.5); Rect2 rect = Rect2(from_x, (get_size().height - fh) / 2, to_x - from_x, fh); @@ -333,7 +333,7 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, draw_rect(rect, accent, false); } } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); @@ -366,7 +366,7 @@ int AnimationTrackEditSpriteFrame::get_key_height() const { return AnimationTrackEdit::get_key_height(); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return int(font->get_height(font_size) * 2); } @@ -434,7 +434,7 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se size = size.floor(); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int height = int(font->get_height(font_size) * 2); int width = height * size.width / size.height; @@ -525,7 +525,7 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in region.size = texture->get_size(); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int height = int(font->get_height(font_size) * 2); @@ -569,7 +569,7 @@ int AnimationTrackEditSubAnim::get_key_height() const { return AnimationTrackEdit::get_key_height(); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return int(font->get_height(font_size) * 1.5); } @@ -598,7 +598,7 @@ Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) { return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); @@ -653,7 +653,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ return; } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 1.5; @@ -706,7 +706,7 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ draw_rect(rect, accent, false); } } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); @@ -805,7 +805,7 @@ void AnimationTrackEditTypeAudio::_preview_changed(ObjectID p_which) { } int AnimationTrackEditTypeAudio::get_key_height() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return int(font->get_height(font_size) * 1.5); } @@ -870,7 +870,7 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int } } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float fh = int(font->get_height(font_size) * 1.5); @@ -1143,7 +1143,7 @@ int AnimationTrackEditTypeAnimation::get_key_height() const { return AnimationTrackEdit::get_key_height(); } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return int(font->get_height(font_size) * 1.5); } @@ -1172,7 +1172,7 @@ Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_ return Rect2(0, 0, len * p_pixels_sec, get_size().height); } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; return Rect2(0, 0, fh, get_size().height); @@ -1227,7 +1227,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, return; } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 1.5; @@ -1280,7 +1280,7 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, draw_rect(rect, accent, false); } } else { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int fh = font->get_height(font_size) * 0.8; Rect2 rect(Vector2(p_x, int(get_size().height - fh) / 2), Size2(fh, fh)); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 7c00cf351cdd..ec7519271ede 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1612,7 +1612,7 @@ void CodeTextEditor::_update_text_editor_theme() { error->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); error->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); - Ref status_bar_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts")); + Ref status_bar_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts")); int status_bar_font_size = get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")); error->add_theme_font_override("font", status_bar_font); error->add_theme_font_size_override("font_size", status_bar_font_size); @@ -1639,25 +1639,25 @@ void CodeTextEditor::_apply_settings_change() { int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures"); switch (ot_mode) { case 1: { // Disable ligatures. - text_editor->clear_opentype_features(); - text_editor->set_opentype_feature("calt", 0); + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(Dictionary()); } break; case 2: { // Custom. - text_editor->clear_opentype_features(); Vector subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(","); Dictionary ftrs; for (int i = 0; i < subtag.size(); i++) { Vector subtag_a = subtag[i].split("="); if (subtag_a.size() == 2) { - text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int()); + ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int(); } else if (subtag_a.size() == 1) { - text_editor->set_opentype_feature(subtag_a[0], 1); + ftrs[TS->name_to_tag(subtag_a[0])] = 1; } } + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(ftrs); } break; default: { // Default. - text_editor->clear_opentype_features(); - text_editor->set_opentype_feature("calt", 1); + Dictionary ftrs; + ftrs[TS->name_to_tag("calt")] = 1; + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(ftrs); } break; } @@ -1863,25 +1863,25 @@ CodeTextEditor::CodeTextEditor() { int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures"); switch (ot_mode) { case 1: { // Disable ligatures. - text_editor->clear_opentype_features(); - text_editor->set_opentype_feature("calt", 0); + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(Dictionary()); } break; case 2: { // Custom. - text_editor->clear_opentype_features(); Vector subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(","); Dictionary ftrs; for (int i = 0; i < subtag.size(); i++) { Vector subtag_a = subtag[i].split("="); if (subtag_a.size() == 2) { - text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int()); + ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int(); } else if (subtag_a.size() == 1) { - text_editor->set_opentype_feature(subtag_a[0], 1); + ftrs[TS->name_to_tag(subtag_a[0])] = 1; } } + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(ftrs); } break; default: { // Default. - text_editor->clear_opentype_features(); - text_editor->set_opentype_feature("calt", 1); + Dictionary ftrs; + ftrs[TS->name_to_tag("calt")] = 1; + text_editor->get_theme_font(SNAME("font"))->set_opentype_features(ftrs); } break; } diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index ed451ed68ebd..f998ff342841 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -111,7 +111,7 @@ void EditorPerformanceProfiler::_monitor_draw() { info_message->hide(); Ref graph_style_box = get_theme_stylebox(SNAME("normal"), SNAME("TextEdit")); - Ref graph_font = get_theme_font(SNAME("font"), SNAME("TextEdit")); + Ref graph_font = get_theme_font(SNAME("font"), SNAME("TextEdit")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("TextEdit")); int columns = int(Math::ceil(Math::sqrt(float(active.size())))); @@ -136,7 +136,7 @@ void EditorPerformanceProfiler::_monitor_draw() { monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color); draw_color.a = 0.9f; - float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), font_size).width; + float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width; if (value_position < 0) { value_position = 0; } @@ -184,7 +184,7 @@ void EditorPerformanceProfiler::_monitor_draw() { monitor_draw->draw_line(rect.position + Point2(from, 0), rect.position + Point2(from, rect.size.y), line_color, Math::round(EDSCALE)); String label = _create_label(e->get(), current.type); - Size2 size = graph_font->get_string_size(label, font_size); + Size2 size = graph_font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); Vector2 text_top_left_position = Vector2(from, h2) - (size + Vector2(MARKER_MARGIN, MARKER_MARGIN)); if (text_top_left_position.x < 0) { text_top_left_position.x = from + MARKER_MARGIN; diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 9def646f3feb..8ad2f66e75df 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -443,7 +443,7 @@ void EditorVisualProfiler::_graph_tex_draw() { return; } - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); const Color color = get_theme_color(SNAME("font_color"), SNAME("Editor")); @@ -469,7 +469,7 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(0, frame_y), Vector2(half_width, frame_y), color * Color(1, 1, 1, 0.5)); const String limit_str = String::num(graph_limit, 2) + " ms"; - graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75)); + graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75)); } if (graph_height_gpu > 0) { @@ -480,11 +480,11 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(half_width, frame_y), Vector2(graph->get_size().x, frame_y), color * Color(1, 1, 1, 0.5)); const String limit_str = String::num(graph_limit, 2) + " ms"; - graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75)); + graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75)); } - graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1)); - graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1)); + graph->draw_string(font, Vector2(font->get_string_size("X", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1)); + graph->draw_string(font, Vector2(font->get_string_size("X", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1)); } void EditorVisualProfiler::_graph_tex_mouse_exit() { diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index e6cd1e0b4821..eec154be8cf5 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -608,7 +608,7 @@ void DocTools::generate(bool p_basic_types) { for (const StringName &E : l) { DocData::ThemeItemDoc tid; tid.name = E; - tid.type = "Font"; + tid.type = "FontConfig"; tid.data_type = "font"; c.theme_properties.push_back(tid); } diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 6fafb2d91a85..c511a2ec84ef 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -39,7 +39,7 @@ static const String META_TEXT_TO_COPY = "text_to_copy"; void EditorAbout::_theme_changed() { - const Ref font = get_theme_font(SNAME("source"), SNAME("EditorFonts")); + const Ref font = get_theme_font(SNAME("source"), SNAME("EditorFonts")); const int font_size = get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts")); _tpl_text->add_theme_font_override("normal_font", font); _tpl_text->add_theme_font_size_override("normal_font_size", font_size); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 89dc106717c1..084ba5104782 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1385,7 +1385,7 @@ void EditorAudioMeterNotches::add_notch(float p_normalized_offset, float p_db_va } Size2 EditorAudioMeterNotches::get_minimum_size() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float font_height = font->get_height(font_size); @@ -1394,7 +1394,7 @@ Size2 EditorAudioMeterNotches::get_minimum_size() const { for (int i = 0; i < notches.size(); i++) { if (notches[i].render_db_value) { - width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", font_size).x); + width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x); height += font_height; } } @@ -1421,7 +1421,7 @@ void EditorAudioMeterNotches::_notification(int p_what) { } void EditorAudioMeterNotches::_draw_audio_notches() { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float font_height = font->get_height(font_size); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 51d4d474c55e..d1faf7659e10 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -37,212 +37,8 @@ #include "scene/resources/default_theme/default_theme.h" #include "scene/resources/font.h" -#define MAKE_FALLBACKS(m_name) \ - m_name->add_data(FontArabic); \ - m_name->add_data(FontBengali); \ - m_name->add_data(FontDevanagari); \ - m_name->add_data(FontGeorgian); \ - m_name->add_data(FontHebrew); \ - m_name->add_data(FontMalayalam); \ - m_name->add_data(FontOriya); \ - m_name->add_data(FontSinhala); \ - m_name->add_data(FontTamil); \ - m_name->add_data(FontTelugu); \ - m_name->add_data(FontThai); \ - m_name->add_data(FontJapanese); \ - m_name->add_data(FontFallback); - -// Note: In some languages, the use of italic/slanted fonts is controversial. Therefore, we are limiting simulated slant to the main font (Latin, Cyrillic, and Greek) and using bold fonts for the rest. - -#define MAKE_FALLBACKS_SLANTED(m_name) \ - m_name->add_data(FontArabicBold); \ - m_name->add_data(FontBengaliBold); \ - m_name->add_data(FontDevanagariBold); \ - m_name->add_data(FontGeorgianBold); \ - m_name->add_data(FontHebrewBold); \ - m_name->add_data(FontMalayalamBold); \ - m_name->add_data(FontOriyaBold); \ - m_name->add_data(FontSinhalaBold); \ - m_name->add_data(FontTamilBold); \ - m_name->add_data(FontTeluguBold); \ - m_name->add_data(FontThaiBold); \ - m_name->add_data(FontJapaneseBold); \ - m_name->add_data(FontFallbackBold); - -#define MAKE_FALLBACKS_BOLD(m_name) \ - m_name->add_data(FontArabicBold); \ - m_name->add_data(FontBengaliBold); \ - m_name->add_data(FontDevanagariBold); \ - m_name->add_data(FontGeorgianBold); \ - m_name->add_data(FontHebrewBold); \ - m_name->add_data(FontMalayalamBold); \ - m_name->add_data(FontOriyaBold); \ - m_name->add_data(FontSinhalaBold); \ - m_name->add_data(FontTamilBold); \ - m_name->add_data(FontTeluguBold); \ - m_name->add_data(FontThaiBold); \ - m_name->add_data(FontJapaneseBold); \ - m_name->add_data(FontFallbackBold); - -#define MAKE_DEFAULT_FONT(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - if (CustomFont.is_valid()) { \ - m_name->add_data(CustomFont); \ - m_name->add_data(DefaultFont); \ - } else { \ - m_name->add_data(DefaultFont); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS(m_name); - -#define MAKE_DEFAULT_FONT_MSDF(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - if (CustomFont.is_valid()) { \ - m_name->add_data(CustomFontMSDF); \ - m_name->add_data(DefaultFontMSDF); \ - } else { \ - m_name->add_data(DefaultFontMSDF); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS(m_name); - -#define MAKE_SLANTED_FONT(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - m_name.instantiate(); \ - if (CustomFontSlanted.is_valid()) { \ - m_name->add_data(CustomFontSlanted); \ - m_name->add_data(DefaultFontSlanted); \ - } else { \ - m_name->add_data(DefaultFontSlanted); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS_SLANTED(m_name); - -#define MAKE_BOLD_FONT(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - if (CustomFontBold.is_valid()) { \ - m_name->add_data(CustomFontBold); \ - m_name->add_data(DefaultFontBold); \ - } else { \ - m_name->add_data(DefaultFontBold); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS_BOLD(m_name); - -#define MAKE_BOLD_FONT_MSDF(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - if (CustomFontBold.is_valid()) { \ - m_name->add_data(CustomFontBoldMSDF); \ - m_name->add_data(DefaultFontBoldMSDF); \ - } else { \ - m_name->add_data(DefaultFontBoldMSDF); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS_BOLD(m_name); - -#define MAKE_SOURCE_FONT(m_name, m_variations) \ - Ref m_name; \ - m_name.instantiate(); \ - if (CustomFontSource.is_valid()) { \ - m_name->add_data(CustomFontSource); \ - m_name->add_data(dfmono); \ - } else { \ - m_name->add_data(dfmono); \ - } \ - { \ - Dictionary variations; \ - if (!m_variations.is_empty()) { \ - Vector variation_tags = m_variations.split(","); \ - for (int i = 0; i < variation_tags.size(); i++) { \ - Vector tokens = variation_tags[i].split("="); \ - if (tokens.size() == 2) { \ - variations[tokens[0]] = tokens[1].to_float(); \ - } \ - } \ - } \ - m_name->set_variation_coordinates(variations); \ - } \ - m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \ - m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \ - MAKE_FALLBACKS(m_name); - -Ref load_cached_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) { - Ref font; +Ref load_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) { + Ref font; font.instantiate(); Vector data = FileAccess::get_file_as_array(p_path); @@ -257,8 +53,8 @@ Ref load_cached_external_font(const String &p_path, TextServer::Hintin return font; } -Ref load_cached_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) { - Ref font; +Ref load_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) { + Ref font; font.instantiate(); font->set_data_ptr(p_data, p_size); @@ -274,8 +70,6 @@ Ref load_cached_internal_font(const uint8_t *p_data, size_t p_size, Te void editor_register_fonts(Ref p_theme) { Ref dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - /* Custom font */ - bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/font_antialiased"); int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting"); TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)EditorSettings::get_singleton()->get("interface/editor/font_subpixel_positioning"); @@ -304,184 +98,268 @@ void editor_register_fonts(Ref p_theme) { break; } + // Load built-in fonts. + + Ref default_font = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref default_font_msdf = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); + + Ref default_font_bold = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref default_font_bold_msdf = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); + + Ref default_font_mono = load_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + Dictionary opentype_features_mono; + opentype_features_mono["calt"] = 0; + default_font_mono->set_opentype_feature_overrides(opentype_features_mono); // Disable contextual alternates (coding ligatures). + } + + TypedArray fallback; + fallback.push_back(load_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 0 + fallback.push_back(load_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 1 + fallback.push_back(load_internal_font(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 2 + fallback.push_back(load_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 3 + fallback.push_back(load_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 4 + fallback.push_back(load_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 5 + fallback.push_back(load_internal_font(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 6 + fallback.push_back(load_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 7 + fallback.push_back(load_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 8 + fallback.push_back(load_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 9 + fallback.push_back(load_internal_font(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 10 + fallback.push_back(load_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 11 + fallback.push_back(load_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 12 + default_font->set_fallbacks(fallback); + default_font_msdf->set_fallbacks(fallback); + default_font_mono->set_fallbacks(fallback); + + TypedArray fallback_bold; + fallback_bold.push_back(load_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 0 + fallback_bold.push_back(load_internal_font(_font_NotoSansBengaliUI_Bold, _font_NotoSansBengaliUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 1 + fallback_bold.push_back(load_internal_font(_font_NotoSansDevanagariUI_Bold, _font_NotoSansDevanagariUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 2 + fallback_bold.push_back(load_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 3 + fallback_bold.push_back(load_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 4 + fallback_bold.push_back(load_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 5 + fallback_bold.push_back(load_internal_font(_font_NotoSansOriyaUI_Bold, _font_NotoSansOriyaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 6 + fallback_bold.push_back(load_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 7 + fallback_bold.push_back(load_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 8 + fallback_bold.push_back(load_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 9 + fallback_bold.push_back(load_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 10 + fallback_bold.push_back(load_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 11 + fallback_bold.push_back(load_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiased, true, font_subpixel_positioning)); // 12 + default_font_bold->set_fallbacks(fallback_bold); + default_font_bold_msdf->set_fallbacks(fallback_bold); + + // Init base font configs and load custom fonts. + String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); + String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold"); + String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); + const int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE; const float embolden_strength = 0.6; - String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); - Ref CustomFont; + Ref default_fc; + default_fc.instantiate(); + default_fc->set_variation_customize_fallbacks(true); // Apply variations to each of the fallback individually, some languages do not use bold and italic.. if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { - CustomFont = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font); + custom_font->set_fallbacks(fallback_custom); + } + default_fc->set_font(custom_font); } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font", ""); + default_fc->set_font(default_font); } + default_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE); + default_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); - Ref CustomFontMSDF; + Ref default_fc_msdf; + default_fc_msdf.instantiate(); + default_fc_msdf->set_variation_customize_fallbacks(true); // Apply variations to each of the fallback individually, some languages do not use bold and italic.. if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { - CustomFontMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true); + Ref custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_msdf); + custom_font->set_fallbacks(fallback_custom); + } + default_fc_msdf->set_font(custom_font); } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font", ""); + default_fc_msdf->set_font(default_font_msdf); } + default_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE); + default_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); - Ref CustomFontSlanted; - if (CustomFont.is_valid()) { - CustomFontSlanted = CustomFont->duplicate(); - CustomFontSlanted->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0)); - } - - /* Custom Bold font */ - - String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold"); - Ref CustomFontBold; + Ref bold_fc; + bold_fc.instantiate(); + bold_fc->set_variation_customize_fallbacks(true); // Apply variations to each of the fallback individually, some languages do not use bold and italic.. if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) { - CustomFontBold = load_cached_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_bold); + custom_font->set_fallbacks(fallback_custom); + } + bold_fc->set_font(custom_font); + bold_fc->set("variation_fallback/0/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc->set("variation_fallback/0/12/variation_embolden", embolden_strength); // DroidSansJapanese + } else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { + Ref custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_bold); + custom_font->set_fallbacks(fallback_custom); + } + bold_fc->set_font(custom_font); + bold_fc->set_variation_embolden(embolden_strength); + bold_fc->set("variation_fallback/0/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc->set("variation_fallback/0/12/variation_embolden", embolden_strength); // DroidSansJapanese } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", ""); + bold_fc->set_font(default_font_bold); + bold_fc->set("variation_fallback/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc->set("variation_fallback/12/variation_embolden", embolden_strength); // DroidSansJapanese } + bold_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE); + bold_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); - if (CustomFont.is_valid() && !CustomFontBold.is_valid()) { - CustomFontBold = CustomFont->duplicate(); - CustomFontBold->set_embolden(embolden_strength); - } - - Ref CustomFontBoldMSDF; - if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { - CustomFontBoldMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true); + Ref bold_fc_msdf; + bold_fc_msdf.instantiate(); + bold_fc_msdf->set_variation_customize_fallbacks(true); // Apply variations to each of the fallback individually, some languages do not use bold and italic.. + if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) { + Ref custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_bold_msdf); + custom_font->set_fallbacks(fallback_custom); + } + bold_fc_msdf->set_font(custom_font); + bold_fc_msdf->set("variation_fallback/0/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc_msdf->set("variation_fallback/0/12/variation_embolden", embolden_strength); // DroidSansJapanese + } else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { + Ref custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_bold_msdf); + custom_font->set_fallbacks(fallback_custom); + } + bold_fc_msdf->set_font(custom_font); + bold_fc_msdf->set_variation_embolden(embolden_strength); + bold_fc_msdf->set("variation_fallback/0/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc_msdf->set("variation_fallback/0/12/variation_embolden", embolden_strength); // DroidSansJapanese } else { EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", ""); + bold_fc_msdf->set_font(default_font_bold_msdf); + bold_fc_msdf->set("variation_fallback/11/variation_embolden", embolden_strength); // DroidSansFallback + bold_fc_msdf->set("variation_fallback/12/variation_embolden", embolden_strength); // DroidSansJapanese } + bold_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE); + bold_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); - /* Custom source code font */ - - String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); - Ref CustomFontSource; + Ref mono_fc; + mono_fc.instantiate(); + mono_fc->set_variation_customize_fallbacks(true); // Apply variations to each of the fallback individually, some languages do not use bold and italic.. if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) { - CustomFontSource = load_cached_external_font(custom_font_path_source, font_hinting, font_antialiased, true, font_subpixel_positioning); + Ref custom_font = load_external_font(custom_font_path_source, font_hinting, font_antialiased, true, font_subpixel_positioning); + { + TypedArray fallback_custom; + fallback_custom.push_back(default_font_mono); + custom_font->set_fallbacks(fallback_custom); + } + mono_fc->set_font(custom_font); } else { EditorSettings::get_singleton()->set_manually("interface/editor/code_font", ""); + mono_fc->set_font(default_font_mono); } + String code_font_custom_variations = EditorSettings::get_singleton()->get("interface/editor/code_font_custom_variations"); + Dictionary variations_mono; + if (!code_font_custom_variations.is_empty()) { + Vector variation_tags = code_font_custom_variations.split(","); + for (int i = 0; i < variation_tags.size(); i++) { + Vector subtag_a = variation_tags[i].split("="); + if (subtag_a.size() == 2) { + variations_mono[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_float(); + } else if (subtag_a.size() == 1) { + variations_mono[TS->name_to_tag(subtag_a[0])] = 1; + } + } + mono_fc->set_variation_opentype(variations_mono); + } + mono_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE); + mono_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); + + Ref italic_fc = default_fc->duplicate(); + italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0)); + + // Setup theme. - /* Noto Sans */ - - Ref DefaultFont = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref DefaultFontMSDF = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); - Ref DefaultFontBold = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref DefaultFontBoldMSDF = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true); - Ref FontArabic = load_cached_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontArabicBold = load_cached_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontBengali = load_cached_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontBengaliBold = load_cached_internal_font(_font_NotoSansBengaliUI_Bold, _font_NotoSansBengaliUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontDevanagari = load_cached_internal_font(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontDevanagariBold = load_cached_internal_font(_font_NotoSansDevanagariUI_Bold, _font_NotoSansDevanagariUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontGeorgian = load_cached_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontGeorgianBold = load_cached_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontHebrew = load_cached_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontHebrewBold = load_cached_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontMalayalam = load_cached_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontMalayalamBold = load_cached_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontOriya = load_cached_internal_font(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontOriyaBold = load_cached_internal_font(_font_NotoSansOriyaUI_Bold, _font_NotoSansOriyaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontSinhala = load_cached_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontSinhalaBold = load_cached_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontTamil = load_cached_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontTamilBold = load_cached_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontTelugu = load_cached_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontTeluguBold = load_cached_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontThai = load_cached_internal_font(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontThaiBold = load_cached_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - - Ref DefaultFontSlanted = DefaultFont->duplicate(); - DefaultFontSlanted->set_transform(Transform2D(1.0, 0.3, 0.0, 1.0, 0.0, 0.0)); - - /* Droid Sans */ - - Ref FontFallback = load_cached_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Ref FontJapanese = load_cached_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - - Ref FontFallbackBold = FontFallback->duplicate(); - FontFallbackBold->set_embolden(embolden_strength); - Ref FontJapaneseBold = FontJapanese->duplicate(); - FontJapaneseBold->set_embolden(embolden_strength); - - /* Hack */ - - Ref dfmono = load_cached_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning); - Dictionary opentype_features; - opentype_features["calt"] = 0; - dfmono->set_opentype_feature_overrides(opentype_features); // Disable contextual alternates (coding ligatures). - - // Default font - MAKE_DEFAULT_FONT(df, String()); - p_theme->set_default_font(df); // Default theme font + p_theme->set_default_font(default_fc); // Default theme font config. p_theme->set_default_font_size(default_font_size); - p_theme->set_font_size("main_size", "EditorFonts", default_font_size); - p_theme->set_font("main", "EditorFonts", df); + // Main font. - MAKE_DEFAULT_FONT_MSDF(df_msdf, String()); - p_theme->set_font("main_msdf", "EditorFonts", df_msdf); + p_theme->set_font("main", "EditorFonts", default_fc); + p_theme->set_font("main_msdf", "EditorFonts", default_fc_msdf); + p_theme->set_font_size("main_size", "EditorFonts", default_font_size); - // Bold font - MAKE_BOLD_FONT(df_bold, String()); - MAKE_SLANTED_FONT(df_italic, String()); + p_theme->set_font("bold", "EditorFonts", bold_fc); + p_theme->set_font("main_bold_msdf", "EditorFonts", bold_fc_msdf); p_theme->set_font_size("bold_size", "EditorFonts", default_font_size); - p_theme->set_font("bold", "EditorFonts", df_bold); - MAKE_BOLD_FONT_MSDF(df_bold_msdf, String()); - p_theme->set_font("main_bold_msdf", "EditorFonts", df_bold_msdf); + // Title font. - // Title font + p_theme->set_font("title", "EditorFonts", bold_fc); p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 1 * EDSCALE); - p_theme->set_font("title", "EditorFonts", df_bold); + p_theme->set_font("main_button_font", "EditorFonts", bold_fc); p_theme->set_font_size("main_button_font_size", "EditorFonts", default_font_size + 1 * EDSCALE); - p_theme->set_font("main_button_font", "EditorFonts", df_bold); - p_theme->set_font("font", "Label", df); + p_theme->set_font("font", "Label", default_fc); p_theme->set_type_variation("HeaderSmall", "Label"); - p_theme->set_font("font", "HeaderSmall", df_bold); + p_theme->set_font("font", "HeaderSmall", bold_fc); p_theme->set_font_size("font_size", "HeaderSmall", default_font_size); p_theme->set_type_variation("HeaderMedium", "Label"); - p_theme->set_font("font", "HeaderMedium", df_bold); + p_theme->set_font("font", "HeaderMedium", bold_fc); p_theme->set_font_size("font_size", "HeaderMedium", default_font_size + 1 * EDSCALE); p_theme->set_type_variation("HeaderLarge", "Label"); - p_theme->set_font("font", "HeaderLarge", df_bold); + p_theme->set_font("font", "HeaderLarge", bold_fc); p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE); // Documentation fonts - String code_font_custom_variations = EditorSettings::get_singleton()->get("interface/editor/code_font_custom_variations"); - MAKE_SOURCE_FONT(df_code, code_font_custom_variations); p_theme->set_font_size("doc_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); - p_theme->set_font("doc", "EditorFonts", df); - p_theme->set_font("doc_bold", "EditorFonts", df_bold); - p_theme->set_font("doc_italic", "EditorFonts", df_italic); + p_theme->set_font("doc", "EditorFonts", default_fc); + p_theme->set_font("doc_bold", "EditorFonts", bold_fc); + p_theme->set_font("doc_italic", "EditorFonts", italic_fc); p_theme->set_font_size("doc_title_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE); - p_theme->set_font("doc_title", "EditorFonts", df_bold); + p_theme->set_font("doc_title", "EditorFonts", bold_fc); p_theme->set_font_size("doc_source_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE); - p_theme->set_font("doc_source", "EditorFonts", df_code); + p_theme->set_font("doc_source", "EditorFonts", mono_fc); p_theme->set_font_size("doc_keyboard_size", "EditorFonts", (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE); - p_theme->set_font("doc_keyboard", "EditorFonts", df_code); + p_theme->set_font("doc_keyboard", "EditorFonts", mono_fc); // Ruler font p_theme->set_font_size("rulers_size", "EditorFonts", 8 * EDSCALE); - p_theme->set_font("rulers", "EditorFonts", df); + p_theme->set_font("rulers", "EditorFonts", default_fc); // Rotation widget font p_theme->set_font_size("rotation_control_size", "EditorFonts", 14 * EDSCALE); - p_theme->set_font("rotation_control", "EditorFonts", df); + p_theme->set_font("rotation_control", "EditorFonts", default_fc); // Code font p_theme->set_font_size("source_size", "EditorFonts", int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE); - p_theme->set_font("source", "EditorFonts", df_code); + p_theme->set_font("source", "EditorFonts", mono_fc); p_theme->set_font_size("expression_size", "EditorFonts", (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE); - p_theme->set_font("expression", "EditorFonts", df_code); + p_theme->set_font("expression", "EditorFonts", mono_fc); p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE); - p_theme->set_font("output_source", "EditorFonts", df_code); + p_theme->set_font("output_source", "EditorFonts", mono_fc); p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size); - p_theme->set_font("status_source", "EditorFonts", df_code); + p_theme->set_font("status_source", "EditorFonts", mono_fc); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index b4325f09c54c..cb4a0e342645 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -179,9 +179,9 @@ void EditorHelp::_class_desc_input(const Ref &p_input) { void EditorHelp::_class_desc_resized(bool p_force_update_theme) { // Add extra horizontal margins for better readability. // The margins increase as the width of the editor help container increases. - Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts")); - real_t char_width = doc_code_font->get_char_size('x', 0, font_size).width; + real_t char_width = doc_code_font->get_char_size('x', font_size).width; const int new_display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5; if (display_margin != new_display_margin || p_force_update_theme) { display_margin = new_display_margin; @@ -361,7 +361,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { } void EditorHelp::_update_method_list(const Vector p_methods, bool &r_method_descrpitons) { - Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); class_desc->pop(); class_desc->pop(); @@ -427,9 +427,9 @@ void EditorHelp::_update_method_list(const Vector p_methods, } void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector p_methods, const String &p_method_type) { - Ref doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); - Ref doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); - Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); + Ref doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); + Ref doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); String link_color_text = title_color.to_html(false); class_desc->pop(); class_desc->pop(); @@ -1502,11 +1502,11 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { DocTools *doc = EditorHelp::get_doc_data(); String base_path; - Ref doc_font = p_rt->get_theme_font(SNAME("doc"), SNAME("EditorFonts")); - Ref doc_bold_font = p_rt->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); - Ref doc_italic_font = p_rt->get_theme_font(SNAME("doc_italic"), SNAME("EditorFonts")); - Ref doc_code_font = p_rt->get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); - Ref doc_kbd_font = p_rt->get_theme_font(SNAME("doc_keyboard"), SNAME("EditorFonts")); + Ref doc_font = p_rt->get_theme_font(SNAME("doc"), SNAME("EditorFonts")); + Ref doc_bold_font = p_rt->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); + Ref doc_italic_font = p_rt->get_theme_font(SNAME("doc_italic"), SNAME("EditorFonts")); + Ref doc_code_font = p_rt->get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref doc_kbd_font = p_rt->get_theme_font(SNAME("doc_keyboard"), SNAME("EditorFonts")); Color link_color = p_rt->get_theme_color(SNAME("link_color"), SNAME("EditorHelp")); Color code_color = p_rt->get_theme_color(SNAME("code_color"), SNAME("EditorHelp")); @@ -1737,7 +1737,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { } else if (tag.begins_with("font=")) { String fnt = tag.substr(5, tag.length()); - Ref font = ResourceLoader::load(base_path.plus_file(fnt), "Font"); + Ref font = ResourceLoader::load(base_path.plus_file(fnt), "FontConfig"); if (font.is_valid()) { p_rt->push_font(font); } else { diff --git a/editor/editor_help.h b/editor/editor_help.h index 766a09f48593..8321c5f206ba 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -135,10 +135,10 @@ class EditorHelp : public VBoxContainer { Color qualifier_color; Color type_color; - Ref doc_font; - Ref doc_bold_font; - Ref doc_title_font; - Ref doc_code_font; + Ref doc_font; + Ref doc_bold_font; + Ref doc_title_font; + Ref doc_code_font; int scroll_to = -1; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 0f31e3e7bb5d..eba4a815fa21 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -60,7 +60,7 @@ static bool _property_path_matches(const String &p_property_path, const String & Size2 EditorProperty::get_minimum_size() const { Size2 ms; - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); ms.height = font->get_height(font_size) + 4 * EDSCALE; @@ -130,7 +130,7 @@ void EditorProperty::_notification(int p_what) { { int child_room = size.width * (1.0 - split_ratio); - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); int height = font->get_height(font_size) + 4 * EDSCALE; bool no_children = true; @@ -234,7 +234,7 @@ void EditorProperty::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); bool rtl = is_layout_rtl(); @@ -322,7 +322,7 @@ void EditorProperty::_notification(int p_what) { Ref pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")); int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2; int total_icon_w = margin_w + pinned_icon->get_width(); - int text_w = font->get_string_size(label, font_size, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w).x; + int text_w = font->get_string_size(label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w, font_size).x; int y = (size.height - pinned_icon->get_height()) / 2; if (rtl) { draw_texture(pinned_icon, Vector2(size.width - ofs - text_w - total_icon_w, y), color); @@ -1073,12 +1073,12 @@ void EditorInspectorCategory::_notification(int p_what) { draw_style_box(sb, Rect2(Vector2(), get_size())); - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); int hs = get_theme_constant(SNAME("h_separation"), SNAME("Tree")); - int w = font->get_string_size(label, font_size).width; + int w = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width; if (icon.is_valid()) { w += hs + icon->get_width(); } @@ -1102,7 +1102,7 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons } Size2 EditorInspectorCategory::get_minimum_size() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); Size2 ms; @@ -1149,7 +1149,7 @@ void EditorInspectorSection::_notification(int p_what) { return; } // Get the section header font. - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); // Get the right direction arrow texture, if the section is foldable. @@ -1200,7 +1200,7 @@ void EditorInspectorSection::_notification(int p_what) { case NOTIFICATION_DRAW: { // Get the section header font. - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); // Get the right direction arrow texture, if the section is foldable. @@ -1351,7 +1351,7 @@ Size2 EditorInspectorSection::get_minimum_size() const { ms.height = MAX(ms.height, minsize.height); } - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); ms.height += font->get_height(font_size) + get_theme_constant(SNAME("v_separation"), SNAME("Tree")); ms.width += get_theme_constant(SNAME("inspector_margin"), SNAME("Editor")); @@ -1401,7 +1401,7 @@ void EditorInspectorSection::gui_input(const Ref &p_event) { Ref mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); + Ref font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); if (mb->get_position().y > font->get_height(font_size)) { //clicked outside return; @@ -3420,6 +3420,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { if (editor_property_map.has(p_path)) { for (EditorProperty *E : editor_property_map[p_path]) { + E->set_checked(p_checked); E->update_property(); E->update_revert_and_pin_status(); E->update_cache(); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index dbe44aee1b86..4f7680aa46dd 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -62,7 +62,7 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f } void EditorLog::_update_theme() { - Ref normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts")); + Ref normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts")); if (normal_font.is_valid()) { log->add_theme_font_override("normal_font", normal_font); } @@ -70,7 +70,7 @@ void EditorLog::_update_theme() { log->add_theme_font_size_override("normal_font_size", get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); log->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); - Ref bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); if (bold_font.is_valid()) { log->add_theme_font_override("bold_font", bold_font); } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e0a5cab16775..e2d2015d0028 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -145,7 +145,7 @@ #include "editor/plugins/debugger_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" -#include "editor/plugins/font_editor_plugin.h" +#include "editor/plugins/font_config_plugin.h" #include "editor/plugins/gdextension_export_plugin.h" #include "editor/plugins/gpu_particles_2d_editor_plugin.h" #include "editor/plugins/gpu_particles_3d_editor_plugin.h" @@ -164,7 +164,6 @@ #include "editor/plugins/navigation_polygon_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/plugins/occluder_instance_3d_editor_plugin.h" -#include "editor/plugins/ot_features_plugin.h" #include "editor/plugins/packed_scene_translation_parser_plugin.h" #include "editor/plugins/path_2d_editor_plugin.h" #include "editor/plugins/path_3d_editor_plugin.h" @@ -186,7 +185,6 @@ #include "editor/plugins/sprite_frames_editor_plugin.h" #include "editor/plugins/style_box_editor_plugin.h" #include "editor/plugins/sub_viewport_preview_editor_plugin.h" -#include "editor/plugins/text_control_editor_plugin.h" #include "editor/plugins/text_editor.h" #include "editor/plugins/texture_3d_editor_plugin.h" #include "editor/plugins/texture_editor_plugin.h" @@ -906,6 +904,31 @@ void EditorNode::_resources_changed(const Vector &p_resources) { } } +const Vector> &EditorNode::get_project_fonts() const { + return fonts; +} + +void EditorNode::_find_font_resources(EditorFileSystemDirectory *p_dir) { + for (int i = 0; i < p_dir->get_subdir_count(); i++) { + _find_font_resources(p_dir->get_subdir(i)); + } + + for (int i = 0; i < p_dir->get_file_count(); i++) { + if (p_dir->get_file_type(i) == "Font") { + Ref fd = ResourceLoader::load(p_dir->get_file_path(i)); + if (fd.is_valid()) { + String name = fd->get_font_name(); + String sty = fd->get_font_style_name(); + if (sty.is_empty()) { + fonts.push_back(Pair(vformat("%s", name), p_dir->get_file_path(i))); + } else { + fonts.push_back(Pair(vformat("%s (%s)", name, sty), p_dir->get_file_path(i))); + } + } + } + } +} + void EditorNode::_fs_changed() { for (FileDialog *E : file_dialogs) { E->invalidate(); @@ -915,6 +938,9 @@ void EditorNode::_fs_changed() { E->invalidate(); } + fonts.clear(); + _find_font_resources(EditorFileSystem::get_singleton()->get_filesystem()); + _mark_unsaved_scenes(); // FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed. @@ -3926,6 +3952,7 @@ void EditorNode::register_editor_types() { GDREGISTER_CLASS(ScriptCreateDialog); GDREGISTER_CLASS(EditorFeatureProfile); GDREGISTER_CLASS(EditorSpinSlider); + GDREGISTER_CLASS(EditorFontPicker); GDREGISTER_CLASS(EditorResourcePicker); GDREGISTER_CLASS(EditorScriptPicker); @@ -7073,8 +7100,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(GradientEditorPlugin)); add_editor_plugin(memnew(CollisionShape2DEditorPlugin)); add_editor_plugin(memnew(CurveEditorPlugin)); - add_editor_plugin(memnew(FontEditorPlugin)); - add_editor_plugin(memnew(OpenTypeFeaturesEditorPlugin)); + add_editor_plugin(memnew(FontConfigEditorPlugin)); add_editor_plugin(memnew(TextureEditorPlugin)); add_editor_plugin(memnew(TextureLayeredEditorPlugin)); add_editor_plugin(memnew(Texture3DEditorPlugin)); @@ -7089,7 +7115,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin)); add_editor_plugin(memnew(InputEventEditorPlugin)); add_editor_plugin(memnew(SubViewportPreviewEditorPlugin)); - add_editor_plugin(memnew(TextControlEditorPlugin)); add_editor_plugin(memnew(ControlEditorPlugin)); add_editor_plugin(memnew(GradientTexture2DEditorPlugin)); add_editor_plugin(memnew(BitMapEditorPlugin)); diff --git a/editor/editor_node.h b/editor/editor_node.h index 48df76756255..ad7a6b10953c 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -474,6 +474,8 @@ class EditorNode : public Node { HashSet file_dialogs; HashSet editor_file_dialogs; + Vector> fonts; + Vector> resource_conversion_plugins; PrintHandlerList print_handler; @@ -673,6 +675,8 @@ class EditorNode : public Node { void _bottom_panel_switch(bool p_enable, int p_idx); void _bottom_panel_raise_toggled(bool); + void _find_font_resources(EditorFileSystemDirectory *p_dir); + protected: friend class FileSystemDock; @@ -698,6 +702,8 @@ class EditorNode : public Node { static EditorFolding &get_editor_folding() { return singleton->editor_folding; } static UndoRedo *get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } + const Vector> &get_project_fonts() const; + static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } static VSplitContainer *get_top_split() { return singleton->top_split; } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index a5c02c70d9d1..8575557c28b5 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -161,7 +161,7 @@ void EditorPropertyMultilineText::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { Ref df = get_theme_icon(SNAME("DistractionFree"), SNAME("EditorIcons")); open_big_text->set_icon(df); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); text->set_custom_minimum_size(Vector2(0, font->get_height(font_size) * 6)); } break; @@ -837,7 +837,7 @@ EditorPropertyLayersGrid::EditorPropertyLayersGrid() { } Size2 EditorPropertyLayersGrid::get_grid_size() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); return Vector2(0, font->get_height(font_size) * 3); } @@ -978,7 +978,7 @@ void EditorPropertyLayersGrid::_notification(int p_what) { draw_rect(rect2, color); flag_rects.push_back(rect2); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Vector2 offset; offset.y = rect2.size.y * 0.75; @@ -1450,7 +1450,7 @@ void EditorPropertyEasing::_draw_easing() { const float exp = get_edited_object()->get(get_edited_property()); - const Ref f = get_theme_font(SNAME("font"), SNAME("Label")); + const Ref f = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); const Color font_color = get_theme_color(is_read_only() ? SNAME("font_uneditable_color") : SNAME("font_color"), SNAME("LineEdit")); Color line_color; @@ -3411,6 +3411,9 @@ void EditorPropertyResource::setup(Object *p_object, const String &p_path, const EditorScriptPicker *script_picker = memnew(EditorScriptPicker); script_picker->set_script_owner(Object::cast_to(p_object)); resource_picker = script_picker; + } else if (p_base_type == "Font") { + EditorFontPicker *font_picker = memnew(EditorFontPicker); + resource_picker = font_picker; } else if (p_path == "shader" && p_base_type == "Shader" && Object::cast_to(p_object)) { EditorShaderPicker *shader_picker = memnew(EditorShaderPicker); shader_picker->set_edited_material(Object::cast_to(p_object)); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 4d53ddb344f0..86566249a705 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -534,8 +534,8 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSetinsert("Texture2D"); } else if (base == "ShaderMaterial") { p_vector->insert("Shader"); - } else if (base == "Font") { - p_vector->insert("FontData"); + } else if (base == "FontConfig") { + p_vector->insert("Font"); } else if (base == "Texture2D") { p_vector->insert("Image"); } @@ -675,12 +675,12 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ break; } - if (at == "Font" && Ref(dropped_resource).is_valid()) { - Ref font = edited_resource; + if (at == "FontConfig" && Ref(dropped_resource).is_valid()) { + Ref font = edited_resource; if (!font.is_valid()) { font.instantiate(); } - font->add_data(dropped_resource); + font->set_font(dropped_resource); dropped_resource = font; break; } @@ -907,6 +907,45 @@ EditorResourcePicker::EditorResourcePicker() { add_theme_constant_override("separation", 0); } +// EditorFontPicker + +void EditorFontPicker::set_create_options(Object *p_menu_node) { + PopupMenu *menu_node = Object::cast_to(p_menu_node); + if (!menu_node) { + return; + } + + const Vector> &fonts = EditorNode::get_singleton()->get_project_fonts(); + + for (int i = 0; i < fonts.size(); i++) { + menu_node->add_icon_item(get_theme_icon(SNAME("Font"), SNAME("EditorIcons")), fonts[i].first, OBJ_MENU_USER_FONT + i); + } + if (fonts.size() > 0) { + menu_node->add_separator(); + } +} + +bool EditorFontPicker::handle_menu_selected(int p_which) { + if (p_which >= OBJ_MENU_USER_FONT) { + const Vector> &fonts = EditorNode::get_singleton()->get_project_fonts(); + int idx = p_which - OBJ_MENU_USER_FONT; + if (idx >= 0 && idx < fonts.size()) { + Ref fd = ResourceLoader::load(fonts[idx].second); + set_edited_resource(fd); + emit_signal(SNAME("resource_changed"), get_edited_resource()); + } + return true; + } + + return false; +} + +void EditorFontPicker::_bind_methods() { +} + +EditorFontPicker::EditorFontPicker() { +} + // EditorScriptPicker void EditorScriptPicker::set_create_options(Object *p_menu_node) { diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 8e26e1f4c01d..895ddbf0069a 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -129,6 +129,23 @@ class EditorResourcePicker : public HBoxContainer { EditorResourcePicker(); }; +class EditorFontPicker : public EditorResourcePicker { + GDCLASS(EditorFontPicker, EditorResourcePicker); + + enum ExtraMenuOption { + OBJ_MENU_USER_FONT = 100, + }; + +protected: + static void _bind_methods(); + +public: + virtual void set_create_options(Object *p_menu_node) override; + virtual bool handle_menu_selected(int p_which) override; + + EditorFontPicker(); +}; + class EditorScriptPicker : public EditorResourcePicker { GDCLASS(EditorScriptPicker, EditorResourcePicker); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index db9193db06e7..6e87a7cdf596 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -444,6 +444,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { // Inspector EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/inspector/max_array_dictionary_items_per_page", 20, "10,100,1") + EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/inspector/show_low_level_opentype_features", false, "") // Theme EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/preset", "Default", "Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Custom") diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index a0c818ba8431..8e25fa9caf9b 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -281,12 +281,12 @@ void EditorSpinSlider::_draw_spin_slider() { if (!flat) { draw_style_box(sb, Rect2(Vector2(), size)); } - Ref font = get_theme_font(SNAME("font"), SNAME("LineEdit")); + Ref font = get_theme_font(SNAME("font"), SNAME("LineEdit")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("LineEdit")); int sep_base = 4 * EDSCALE; int sep = sep_base + sb->get_offset().x; //make it have the same margin on both sides, looks better - int label_width = font->get_string_size(label, font_size).width; + int label_width = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width; int number_width = size.width - sb->get_minimum_size().width - label_width - sep; Ref updown = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox")); @@ -324,7 +324,10 @@ void EditorSpinSlider::_draw_spin_slider() { int suffix_start = numstr.length(); RID num_rid = TS->create_shaped_text(); - TS->shaped_text_add_string(num_rid, numstr + U"\u2009" + suffix, font->get_rids(), font_size); + TS->shaped_text_add_string(num_rid, numstr + U"\u2009" + suffix, font->get_rids(), font_size, font->get_opentype_features()); + for (int i = 0; i < TextServer::SPACING_MAX; i++) { + TS->shaped_text_set_spacing(num_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); + } float text_start = rtl ? Math::round(sb->get_offset().x) : Math::round(sb->get_offset().x + label_width + sep); Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs); @@ -480,7 +483,7 @@ LineEdit *EditorSpinSlider::get_line_edit() { Size2 EditorSpinSlider::get_minimum_size() const { Ref sb = get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")); - Ref font = get_theme_font(SNAME("font"), SNAME("LineEdit")); + Ref font = get_theme_font(SNAME("font"), SNAME("LineEdit")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("LineEdit")); Size2 ms = sb->get_minimum_size(); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index e1c9689f73ce..8b53239b0c33 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -760,12 +760,12 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) { } Result r = E->value; String item_text = item->get_text(_with_replace ? 1 : 0); - Ref font = _results_display->get_theme_font(SNAME("font")); + Ref font = _results_display->get_theme_font(SNAME("font")); int font_size = _results_display->get_theme_font_size(SNAME("font_size")); Rect2 match_rect = rect; - match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), font_size).x; - match_rect.size.x = font->get_string_size(_search_text_label->get_text(), font_size).x; + match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x; + match_rect.size.x = font->get_string_size(_search_text_label->get_text(), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x; match_rect.position.y += 1 * EDSCALE; match_rect.size.y -= 2 * EDSCALE; diff --git a/editor/icons/Font.svg b/editor/icons/Font.svg index 2c8d7cb43edf..4cb64120819d 100644 --- a/editor/icons/Font.svg +++ b/editor/icons/Font.svg @@ -1 +1 @@ - + diff --git a/editor/icons/FontConfig.svg b/editor/icons/FontConfig.svg new file mode 100644 index 000000000000..2c8d7cb43edf --- /dev/null +++ b/editor/icons/FontConfig.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/FontData.svg b/editor/icons/FontData.svg deleted file mode 100644 index 4cb64120819d..000000000000 --- a/editor/icons/FontData.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index 5e203a3e3909..22f6038d1f3f 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -41,50 +41,44 @@ /* Settings data */ /*************************************************************************/ -class DynamicFontImportSettingsData : public RefCounted { - GDCLASS(DynamicFontImportSettingsData, RefCounted) - friend class DynamicFontImportSettings; - - HashMap settings; - HashMap defaults; - List options; - DynamicFontImportSettings *owner = nullptr; - - bool _set(const StringName &p_name, const Variant &p_value) { - if (defaults.has(p_name) && defaults[p_name] == p_value) { - settings.erase(p_name); - } else { - settings[p_name] = p_value; - } - return true; +bool DynamicFontImportSettingsData::_set(const StringName &p_name, const Variant &p_value) { + if (defaults.has(p_name) && defaults[p_name] == p_value) { + settings.erase(p_name); + } else { + settings[p_name] = p_value; } + return true; +} - bool _get(const StringName &p_name, Variant &r_ret) const { - if (settings.has(p_name)) { - r_ret = settings[p_name]; - return true; - } - if (defaults.has(p_name)) { - r_ret = defaults[p_name]; - return true; - } - return false; +bool DynamicFontImportSettingsData::_get(const StringName &p_name, Variant &r_ret) const { + if (settings.has(p_name)) { + r_ret = settings[p_name]; + return true; + } + if (defaults.has(p_name)) { + r_ret = defaults[p_name]; + return true; } + return false; +} - void _get_property_list(List *p_list) const { - for (const List::Element *E = options.front(); E; E = E->next()) { - if (owner && owner->import_settings_data.is_valid()) { - if (owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "size" || E->get().option.name == "outline_size" || E->get().option.name == "oversampling")) { - continue; - } - if (!owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "msdf_pixel_range" || E->get().option.name == "msdf_size")) { - continue; - } +void DynamicFontImportSettingsData::_get_property_list(List *p_list) const { + for (const List::Element *E = options.front(); E; E = E->next()) { + if (owner && owner->import_settings_data.is_valid()) { + if (owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "size" || E->get().option.name == "outline_size" || E->get().option.name == "oversampling")) { + continue; + } + if (!owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "msdf_pixel_range" || E->get().option.name == "msdf_size")) { + continue; } - p_list->push_back(E->get().option); } + p_list->push_back(E->get().option); } -}; +} + +Ref DynamicFontImportSettingsData::get_font() const { + return fd; +} /*************************************************************************/ /* Glyph ranges */ @@ -454,58 +448,32 @@ void DynamicFontImportSettings::_add_glyph_range_item(int32_t p_start, int32_t p void DynamicFontImportSettings::_main_prop_changed(const String &p_edited_property) { // Update font preview. - if (p_edited_property == "face_index") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_face_index(import_settings_data->get("face_index")); - } - } else if (p_edited_property == "antialiased") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_antialiased(import_settings_data->get("antialiased")); - } - } else if (p_edited_property == "generate_mipmaps") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_generate_mipmaps(import_settings_data->get("generate_mipmaps")); - } - } else if (p_edited_property == "multichannel_signed_distance_field") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field")); - } - _variation_selected(); - _variations_validate(); - } else if (p_edited_property == "msdf_pixel_range") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range")); - } - } else if (p_edited_property == "msdf_size") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_msdf_size(import_settings_data->get("msdf_size")); - } - } else if (p_edited_property == "force_autohinter") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_force_autohinter(import_settings_data->get("force_autohinter")); - } - } else if (p_edited_property == "hinting") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); - } - } else if (p_edited_property == "subpixel_positioning") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int()); - } - } else if (p_edited_property == "embolden") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_embolden(import_settings_data->get("embolden")); - } - } else if (p_edited_property == "transform") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_transform(import_settings_data->get("transform")); - } - } else if (p_edited_property == "oversampling") { - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling")); + if (font_preview->get_font().is_valid()) { + if (p_edited_property == "antialiased") { + font_preview->get_font()->set_antialiased(import_settings_data->get("antialiased")); + } else if (p_edited_property == "generate_mipmaps") { + font_preview->get_font()->set_generate_mipmaps(import_settings_data->get("generate_mipmaps")); + } else if (p_edited_property == "multichannel_signed_distance_field") { + font_preview->get_font()->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field")); + _variation_selected(); + _variations_validate(); + } else if (p_edited_property == "msdf_pixel_range") { + font_preview->get_font()->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range")); + } else if (p_edited_property == "msdf_size") { + font_preview->get_font()->set_msdf_size(import_settings_data->get("msdf_size")); + } else if (p_edited_property == "force_autohinter") { + font_preview->get_font()->set_force_autohinter(import_settings_data->get("force_autohinter")); + } else if (p_edited_property == "hinting") { + font_preview->get_font()->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); + } else if (p_edited_property == "subpixel_positioning") { + font_preview->get_font()->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int()); + } else if (p_edited_property == "oversampling") { + font_preview->get_font()->set_oversampling(import_settings_data->get("oversampling")); } } + font_preview_label->add_theme_font_override("font", font_preview); + font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); font_preview_label->update(); } @@ -534,6 +502,7 @@ void DynamicFontImportSettings::_variation_add() { import_variation_data->options = options_variations; inspector_vars->edit(import_variation_data.ptr()); import_variation_data->notify_property_list_changed(); + import_variation_data->fd = font_main->get_font(); vars_item->set_metadata(0, import_variation_data); @@ -548,6 +517,10 @@ void DynamicFontImportSettings::_variation_selected() { inspector_vars->edit(import_variation_data.ptr()); import_variation_data->notify_property_list_changed(); + + label_glyphs->set_text(TTR("Preloaded glyphs: ") + itos(import_variation_data->selected_glyphs.size())); + _range_selected(); + _change_text_opts(); } } @@ -611,63 +584,91 @@ void DynamicFontImportSettings::_variations_validate() { } /*************************************************************************/ -/* Page 3 callbacks: Text to select glyphs */ +/* Page 2.1 callbacks: Text to select glyphs */ /*************************************************************************/ void DynamicFontImportSettings::_change_text_opts() { - Vector ftr = ftr_edit->get_text().split(","); - for (int i = 0; i < ftr.size(); i++) { - Vector tokens = ftr[i].split("="); - if (tokens.size() == 2) { - text_edit->set_opentype_feature(tokens[0], tokens[1].to_int()); - } else if (tokens.size() == 1) { - text_edit->set_opentype_feature(tokens[0], 1); - } + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; } - text_edit->set_language(lang_edit->get_text()); + + Ref font_main_text; + font_main_text.instantiate(); + font_main_text->set_font(font_main->get_font()); + font_main_text->set_opentype_features(text_settings_data->get("opentype_features")); + font_main_text->set_variation_opentype(import_variation_data->get("variation_opentype")); + font_main_text->set_variation_embolden(import_variation_data->get("variation_embolden")); + font_main_text->set_variation_face_index(import_variation_data->get("variation_face_index")); + font_main_text->set_variation_transform(import_variation_data->get("variation_transform")); + + text_edit->add_theme_font_override("font", font_main_text); } void DynamicFontImportSettings::_glyph_clear() { - selected_glyphs.clear(); - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size())); + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + + import_variation_data->selected_glyphs.clear(); + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); _range_selected(); } void DynamicFontImportSettings::_glyph_text_selected() { - Dictionary ftrs; - Vector ftr = ftr_edit->get_text().split(","); - for (int i = 0; i < ftr.size(); i++) { - Vector tokens = ftr[i].split("="); - if (tokens.size() == 2) { - ftrs[tokens[0]] = tokens[1].to_int(); - } else if (tokens.size() == 1) { - ftrs[tokens[0]] = 1; - } - } + Ref import_variation_data; + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } RID text_rid = TS->create_shaped_text(); if (text_rid.is_valid()) { - TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, ftrs, text_edit->get_language()); + TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, text_settings_data->get("opentype_features"), text_settings_data->get("language")); TS->shaped_text_shape(text_rid); const Glyph *gl = TS->shaped_text_get_glyphs(text_rid); const int gl_size = TS->shaped_text_get_glyph_count(text_rid); for (int i = 0; i < gl_size; i++) { if (gl[i].font_rid.is_valid() && gl[i].index != 0) { - selected_glyphs.insert(gl[i].index); + import_variation_data->selected_glyphs.insert(gl[i].index); } } TS->free_rid(text_rid); - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size())); + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); } _range_selected(); } /*************************************************************************/ -/* Page 4 callbacks: Character map */ +/* Page 2.2 callbacks: Character map */ /*************************************************************************/ void DynamicFontImportSettings::_glyph_selected() { + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + TreeItem *item = glyph_table->get_selected(); ERR_FAIL_NULL(item); @@ -685,7 +686,7 @@ void DynamicFontImportSettings::_glyph_selected() { item->clear_custom_bg_color(glyph_table->get_selected_column()); } } - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size())); + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); item = glyph_tree->get_selected(); ERR_FAIL_NULL(item); @@ -698,7 +699,7 @@ void DynamicFontImportSettings::_glyph_selected() { total_chars--; } - if (selected_chars.has(i)) { + if (import_variation_data->selected_chars.has(i)) { selected_count++; } } @@ -728,6 +729,16 @@ void DynamicFontImportSettings::_range_selected() { } void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + glyph_table->clear(); TreeItem *root = glyph_table->create_item(); @@ -740,6 +751,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { TreeItem *item = nullptr; int col = 0; + Ref font_main_big = font_main->duplicate(); + for (int32_t c = p_start; c <= p_end; c++) { if (col == 0) { item = glyph_table->create_item(root); @@ -752,7 +765,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { if (font_main->has_char(c)) { item->set_text(col + 1, String::chr(c)); item->set_custom_color(col + 1, Color(1, 1, 1)); - if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, c)))) { + if (import_variation_data->selected_chars.has(c) || import_variation_data->selected_glyphs.has(font_main->get_font()->get_glyph_index(16, c))) { item->set_custom_color(col + 1, fcol); item->set_custom_bg_color(col + 1, scol); } else { @@ -765,7 +778,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { item->set_metadata(col + 1, c); item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER); item->set_selectable(col + 1, true); - item->set_custom_font(col + 1, font_main); + + item->set_custom_font(col + 1, font_main_big); item->set_custom_font_size(col + 1, get_theme_font_size(SNAME("font_size")) * 2); col++; @@ -773,41 +787,61 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { col = 0; } } - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size())); + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); } bool DynamicFontImportSettings::_char_update(int32_t p_char) { - if (selected_chars.has(p_char)) { - selected_chars.erase(p_char); + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return false; + } + + if (import_variation_data->selected_chars.has(p_char)) { + import_variation_data->selected_chars.erase(p_char); return false; - } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char))) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char)); + } else if (font_main.is_valid() && font_main->get_font().is_valid() && import_variation_data->selected_glyphs.has(font_main->get_font()->get_glyph_index(16, p_char))) { + import_variation_data->selected_glyphs.erase(font_main->get_font()->get_glyph_index(16, p_char)); return false; } else { - selected_chars.insert(p_char); + import_variation_data->selected_chars.insert(p_char); return true; } } void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { + Ref import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + bool all_selected = true; for (int32_t i = p_start; i <= p_end; i++) { if (font_main->has_char(i)) { - if (font_main->get_data(0).is_valid()) { - all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)))); + if (font_main->get_font().is_valid()) { + all_selected = all_selected && (import_variation_data->selected_chars.has(i) || import_variation_data->selected_glyphs.has(font_main->get_font()->get_glyph_index(16, i))); } else { - all_selected = all_selected && selected_chars.has(i); + all_selected = all_selected && import_variation_data->selected_chars.has(i); } } } for (int32_t i = p_start; i <= p_end; i++) { if (font_main->has_char(i)) { if (!all_selected) { - selected_chars.insert(i); + import_variation_data->selected_chars.insert(i); } else { - selected_chars.erase(i); - if (font_main->get_data(0).is_valid()) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)); + import_variation_data->selected_chars.erase(i); + if (font_main->get_font().is_valid()) { + import_variation_data->selected_glyphs.erase(font_main->get_font()->get_glyph_index(16, i)); } } } @@ -819,106 +853,6 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { item->set_checked(0, !all_selected); } -/*************************************************************************/ -/* Page 5 callbacks: CMetadata override */ -/*************************************************************************/ - -void DynamicFontImportSettings::_lang_add() { - locale_select->popup_locale_dialog(); -} - -void DynamicFontImportSettings::_lang_add_item(const String &p_locale) { - TreeItem *lang_item = lang_list->create_item(lang_list_root); - ERR_FAIL_NULL(lang_item); - - lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - lang_item->set_editable(0, true); - lang_item->set_checked(0, false); - lang_item->set_text(1, p_locale); - lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - lang_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); -} - -void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) { - if (p_button != MouseButton::LEFT) { - return; - } - - TreeItem *lang_item = (TreeItem *)p_item; - ERR_FAIL_NULL(lang_item); - - lang_list_root->remove_child(lang_item); - memdelete(lang_item); -} - -void DynamicFontImportSettings::_ot_add() { - menu_ot->set_position(ot_list->get_screen_transform().xform(ot_list->get_local_mouse_position())); - menu_ot->set_size(Vector2(1, 1)); - menu_ot->popup(); -} - -void DynamicFontImportSettings::_ot_add_item(int p_option) { - String name = TS->tag_to_name(p_option); - for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) { - if (ot_item->get_text(0) == name) { - return; - } - } - TreeItem *ot_item = ot_list->create_item(ot_list_root); - ERR_FAIL_NULL(ot_item); - - ot_item->set_text(0, name); - ot_item->set_editable(0, false); - ot_item->set_text(1, "1"); - ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); -} - -void DynamicFontImportSettings::_ot_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) { - if (p_button != MouseButton::LEFT) { - return; - } - - TreeItem *ot_item = (TreeItem *)p_item; - ERR_FAIL_NULL(ot_item); - - ot_list_root->remove_child(ot_item); - memdelete(ot_item); -} - -void DynamicFontImportSettings::_script_add() { - menu_scripts->set_position(script_list->get_screen_position() + script_list->get_local_mouse_position()); - menu_scripts->reset_size(); - menu_scripts->popup(); -} - -void DynamicFontImportSettings::_script_add_item(int p_option) { - TreeItem *script_item = script_list->create_item(script_list_root); - ERR_FAIL_NULL(script_item); - - script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - script_item->set_editable(0, true); - script_item->set_checked(0, false); - script_item->set_text(1, script_codes[p_option]); - script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - script_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); -} - -void DynamicFontImportSettings::_script_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) { - if (p_button != MouseButton::LEFT) { - return; - } - - TreeItem *script_item = (TreeItem *)p_item; - ERR_FAIL_NULL(script_item); - - script_list_root->remove_child(script_item); - memdelete(script_item); -} - /*************************************************************************/ /* Common */ /*************************************************************************/ @@ -938,10 +872,7 @@ void DynamicFontImportSettings::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } break; } } @@ -958,90 +889,40 @@ void DynamicFontImportSettings::_re_import() { main_settings["force_autohinter"] = import_settings_data->get("force_autohinter"); main_settings["hinting"] = import_settings_data->get("hinting"); main_settings["subpixel_positioning"] = import_settings_data->get("subpixel_positioning"); - main_settings["embolden"] = import_settings_data->get("embolden"); - main_settings["transform"] = import_settings_data->get("transform"); main_settings["oversampling"] = import_settings_data->get("oversampling"); + main_settings["fallbacks"] = import_settings_data->get("fallbacks"); main_settings["compress"] = import_settings_data->get("compress"); - Vector variations; + Array configurations; for (TreeItem *vars_item = vars_list_root->get_first_child(); vars_item; vars_item = vars_item->get_next()) { - String variation; Ref import_variation_data = vars_item->get_metadata(0); ERR_FAIL_NULL(import_variation_data); - String name = vars_item->get_text(0); - variation += ("name=" + name); + Dictionary preload_config; + preload_config["name"] = vars_item->get_text(0); + for (const KeyValue &E : import_variation_data->settings) { - if (!variation.is_empty()) { - variation += ","; - } - variation += (String(E.key) + "=" + String(E.value)); - } - variations.push_back(variation); - } - main_settings["preload/configurations"] = variations; - - Vector langs_enabled; - Vector langs_disabled; - for (TreeItem *lang_item = lang_list_root->get_first_child(); lang_item; lang_item = lang_item->get_next()) { - bool selected = lang_item->is_checked(0); - String name = lang_item->get_text(1); - if (selected) { - langs_enabled.push_back(name); - } else { - langs_disabled.push_back(name); + preload_config[E.key] = E.value; } - } - main_settings["support_overrides/language_enabled"] = langs_enabled; - main_settings["support_overrides/language_disabled"] = langs_disabled; - - Vector scripts_enabled; - Vector scripts_disabled; - for (TreeItem *script_item = script_list_root->get_first_child(); script_item; script_item = script_item->get_next()) { - bool selected = script_item->is_checked(0); - String name = script_item->get_text(1); - if (selected) { - scripts_enabled.push_back(name); - } else { - scripts_disabled.push_back(name); - } - } - main_settings["support_overrides/script_enabled"] = scripts_enabled; - main_settings["support_overrides/script_disabled"] = scripts_disabled; - - if (!selected_chars.is_empty()) { - Vector ranges; - char32_t start = selected_chars.front()->get(); - for (RBSet::Element *E = selected_chars.front()->next(); E; E = E->next()) { - if (E->prev() && ((E->prev()->get() + 1) != E->get())) { - ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(E->prev()->get(), 16)); - start = E->get(); - } + + Array chars; + for (const char32_t &E : import_variation_data->selected_chars) { + chars.push_back(E); } - ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(selected_chars.back()->get(), 16)); - main_settings["preload/char_ranges"] = ranges; - } + preload_config["chars"] = chars; - if (!selected_glyphs.is_empty()) { - Vector ranges; - int32_t start = selected_glyphs.front()->get(); - for (RBSet::Element *E = selected_glyphs.front()->next(); E; E = E->next()) { - if (E->prev() && ((E->prev()->get() + 1) != E->get())) { - ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(E->prev()->get(), 16)); - start = E->get(); - } + Array glyphs; + for (const int32_t &E : import_variation_data->selected_glyphs) { + glyphs.push_back(E); } - ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(selected_glyphs.back()->get(), 16)); - main_settings["preload/glyph_ranges"] = ranges; - } + preload_config["glyphs"] = glyphs; - Dictionary ot_ov; - for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) { - String tag = ot_item->get_text(0); - int32_t value = ot_item->get_text(1).to_int(); - ot_ov[tag] = value; + configurations.push_back(preload_config); } - main_settings["opentype_feature_overrides"] = ot_ov; + main_settings["preload"] = configurations; + main_settings["language_support"] = import_settings_data->get("language_support"); + main_settings["script_support"] = import_settings_data->get("script_support"); + main_settings["opentype_features"] = import_settings_data->get("opentype_features"); if (OS::get_singleton()->is_stdout_verbose()) { print_line("Import settings:"); @@ -1058,33 +939,41 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { Vector data = FileAccess::get_file_as_array(p_path); // Load font for preview. - Ref dfont_prev; - dfont_prev.instantiate(); - dfont_prev->set_data(data); + Ref dfont_preview; + dfont_preview.instantiate(); + dfont_preview->set_data(data); font_preview.instantiate(); - font_preview->add_data(dfont_prev); + font_preview->set_font(dfont_preview); + String font_name = vformat("%s (%s)", dfont_preview->get_font_name(), dfont_preview->get_font_style_name()); String sample; static const String sample_base = U"12漢字ԱբΑαАбΑαאבابܐܒހށआআਆઆଆஆఆಆആආกิກິༀကႠა한글ሀᎣᐁᚁᚠᜀᜠᝀᝠកᠠᤁᥐAb😀"; for (int i = 0; i < sample_base.length(); i++) { - if (dfont_prev->has_char(sample_base[i])) { + if (font_preview->has_char(sample_base[i])) { sample += sample_base[i]; } } if (sample.is_empty()) { - sample = dfont_prev->get_supported_chars().substr(0, 6); + sample = font_preview->get_supported_chars().substr(0, 6); } font_preview_label->set_text(sample); + Ref bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + if (bold_font.is_valid() && bold_font->get_font().is_valid()) { + font_name_label->add_theme_font_override("bold_font", bold_font); + } + font_name_label->set_text(font_name); + // Load second copy of font with MSDF disabled for the glyph table and metadata extraction. - Ref dfont_main; + Ref dfont_main; dfont_main.instantiate(); dfont_main->set_data(data); dfont_main->set_multichannel_signed_distance_field(false); font_main.instantiate(); - font_main->add_data(dfont_main); + font_main->set_font(dfont_main); + text_edit->add_theme_font_override("font", font_main); base_path = p_path; @@ -1092,35 +981,27 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { inspector_vars->edit(nullptr); inspector_general->edit(nullptr); - int gww = get_theme_font(SNAME("font"))->get_string_size("00000", get_theme_font_size(SNAME("font_size"))).x + 50; + text_settings_data.instantiate(); + ERR_FAIL_NULL(text_settings_data); + + text_settings_data->owner = this; + + for (List::Element *F = options_text.front(); F; F = F->next()) { + text_settings_data->defaults[F->get().option.name] = F->get().default_value; + } + + text_settings_data->fd = font_main->get_font(); + text_settings_data->options = options_text; + + inspector_text->edit(text_settings_data.ptr()); + + int gww = get_theme_font(SNAME("font"))->get_string_size("00000").x + 50; glyph_table->set_column_custom_minimum_width(0, gww); glyph_table->clear(); vars_list->clear(); - lang_list->clear(); - script_list->clear(); - ot_list->clear(); - - selected_chars.clear(); - selected_glyphs.clear(); - text_edit->set_text(String()); vars_list_root = vars_list->create_item(); - lang_list_root = lang_list->create_item(); - script_list_root = script_list->create_item(); - ot_list_root = ot_list->create_item(); - - options_variations.clear(); - Dictionary var_list = dfont_main->get_supported_variation_list(); - for (int i = 0; i < var_list.size(); i++) { - int32_t tag = var_list.get_key_at_index(i); - Vector3i value = var_list.get_value_at_index(i); - options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, TS->tag_to_name(tag), PROPERTY_HINT_RANGE, itos(value.x) + "," + itos(value.y) + ",1"), value.z)); - } - options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "0,127,1"), 16)); - options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1"), 0)); - options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "extra_spacing_glyph"), 0)); - options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "extra_spacing_space"), 0)); import_settings_data->defaults.clear(); for (List::Element *E = options_general.front(); E; E = E->next()) { @@ -1139,157 +1020,58 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { for (List::Element *E = keys.front(); E; E = E->next()) { String key = E->get(); print_verbose(String(" ") + key + " == " + String(config->get_value("params", key))); - if (key == "preload/char_ranges") { - Vector ranges = config->get_value("params", key); - for (int i = 0; i < ranges.size(); i++) { - int32_t start, end; - Vector tokens = ranges[i].split("-"); - if (tokens.size() == 2) { - if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start) || !ResourceImporterDynamicFont::_decode_range(tokens[1], end)) { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - } else if (tokens.size() == 1) { - if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start)) { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - end = start; - } else { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - for (int32_t j = start; j <= end; j++) { - selected_chars.insert(j); - } - } - } else if (key == "preload/glyph_ranges") { - Vector ranges = config->get_value("params", key); - for (int i = 0; i < ranges.size(); i++) { - int32_t start, end; - Vector tokens = ranges[i].split("-"); - if (tokens.size() == 2) { - if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start) || !ResourceImporterDynamicFont::_decode_range(tokens[1], end)) { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - } else if (tokens.size() == 1) { - if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start)) { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - end = start; - } else { - WARN_PRINT("Invalid range: \"" + ranges[i] + "\""); - continue; - } - for (int32_t j = start; j <= end; j++) { - selected_glyphs.insert(j); - } - } - } else if (key == "preload/configurations") { - Vector variations = config->get_value("params", key); - for (int i = 0; i < variations.size(); i++) { + if (key == "preload") { + Array preload_configurations = config->get_value("params", key); + for (int i = 0; i < preload_configurations.size(); i++) { + Dictionary preload_config = preload_configurations[i]; + + Dictionary variation = preload_config.has("variation_opentype") ? preload_config["variation_opentype"].operator Dictionary() : Dictionary(); + double embolden = preload_config.has("variation_embolden") ? preload_config["variation_embolden"].operator double() : 0; + int face_index = preload_config.has("variation_face_index") ? preload_config["variation_face_index"].operator int() : 0; + Transform2D transform = preload_config.has("variation_transform") ? preload_config["variation_transform"].operator Transform2D() : Transform2D(); + Vector2i size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0); + String cfg_name = preload_config.has("name") ? preload_config["name"].operator String() : vformat("Configuration %d", i); + TreeItem *vars_item = vars_list->create_item(vars_list_root); ERR_FAIL_NULL(vars_item); - vars_item->set_text(0, TTR("Configuration") + " " + itos(i)); + vars_item->set_text(0, cfg_name); vars_item->set_editable(0, true); vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref import_variation_data_custom; import_variation_data_custom.instantiate(); - import_variation_data_custom->owner = this; ERR_FAIL_NULL(import_variation_data_custom); + import_variation_data_custom->owner = this; for (List::Element *F = options_variations.front(); F; F = F->next()) { import_variation_data_custom->defaults[F->get().option.name] = F->get().default_value; } - import_variation_data_custom->options = options_variations; + import_variation_data_custom->fd = font_main->get_font(); + import_variation_data_custom->options = options_variations; vars_item->set_metadata(0, import_variation_data_custom); - Vector variation_tags = variations[i].split(","); - for (int j = 0; j < variation_tags.size(); j++) { - Vector tokens = variation_tags[j].split("="); - if (tokens[0] == "name") { - vars_item->set_text(0, tokens[1]); - } else if (tokens[0] == "size" || tokens[0] == "outline_size" || tokens[0] == "extra_spacing_space" || tokens[0] == "extra_spacing_glyph") { - import_variation_data_custom->set(tokens[0], tokens[1].to_int()); - } else { - import_variation_data_custom->set(tokens[0], tokens[1].to_float()); - } + + import_variation_data_custom->set("size", size.x); + import_variation_data_custom->set("outline_size", size.y); + import_variation_data_custom->set("variation_opentype", variation); + import_variation_data_custom->set("variation_embolden", embolden); + import_variation_data_custom->set("variation_face_index", face_index); + import_variation_data_custom->set("variation_transform", transform); + + Array chars = preload_config["chars"]; + for (int j = 0; j < chars.size(); j++) { + char32_t c = chars[j].operator int(); + import_variation_data_custom->selected_chars.insert(c); } - } - } else if (key == "support_overrides/language_enabled") { - PackedStringArray _langs = config->get_value("params", key); - for (int i = 0; i < _langs.size(); i++) { - TreeItem *lang_item = lang_list->create_item(lang_list_root); - ERR_FAIL_NULL(lang_item); - - lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - lang_item->set_editable(0, true); - lang_item->set_checked(0, true); - lang_item->set_text(1, _langs[i]); - lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - } - } else if (key == "support_overrides/language_disabled") { - PackedStringArray _langs = config->get_value("params", key); - for (int i = 0; i < _langs.size(); i++) { - TreeItem *lang_item = lang_list->create_item(lang_list_root); - ERR_FAIL_NULL(lang_item); - - lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - lang_item->set_editable(0, true); - lang_item->set_checked(0, false); - lang_item->set_text(1, _langs[i]); - lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - } - } else if (key == "support_overrides/script_enabled") { - PackedStringArray _scripts = config->get_value("params", key); - for (int i = 0; i < _scripts.size(); i++) { - TreeItem *script_item = script_list->create_item(script_list_root); - ERR_FAIL_NULL(script_item); - - script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - script_item->set_editable(0, true); - script_item->set_checked(0, true); - script_item->set_text(1, _scripts[i]); - script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - } - } else if (key == "support_overrides/script_disabled") { - PackedStringArray _scripts = config->get_value("params", key); - for (int i = 0; i < _scripts.size(); i++) { - TreeItem *script_item = script_list->create_item(script_list_root); - ERR_FAIL_NULL(script_item); - - script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - script_item->set_editable(0, true); - script_item->set_checked(0, false); - script_item->set_text(1, _scripts[i]); - script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - } - } else if (key == "opentype_feature_overrides") { - Dictionary features = config->get_value("params", key); - for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) { - TreeItem *ot_item = ot_list->create_item(ot_list_root); - ERR_FAIL_NULL(ot_item); - int32_t value = features[*ftr]; - if (ftr->get_type() == Variant::STRING) { - ot_item->set_text(0, *ftr); - } else { - ot_item->set_text(0, TS->tag_to_name(*ftr)); + + Array glyphs = preload_config["glyphs"]; + for (int j = 0; j < glyphs.size(); j++) { + int32_t c = glyphs[j]; + import_variation_data_custom->selected_glyphs.insert(c); } - ot_item->set_editable(0, false); - ot_item->set_text(1, itos(value)); - ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); - ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } } else { Variant value = config->get_value("params", key); @@ -1297,61 +1079,26 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { } } } - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size())); + import_settings_data->fd = font_main->get_font(); import_settings_data->options = options_general; inspector_general->edit(import_settings_data.ptr()); import_settings_data->notify_property_list_changed(); - if (font_preview->get_data_count() > 0) { - font_preview->get_data(0)->set_face_index(import_settings_data->get("face_index")); - font_preview->get_data(0)->set_antialiased(import_settings_data->get("antialiased")); - font_preview->get_data(0)->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field")); - font_preview->get_data(0)->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range")); - font_preview->get_data(0)->set_msdf_size(import_settings_data->get("msdf_size")); - font_preview->get_data(0)->set_force_autohinter(import_settings_data->get("force_autohinter")); - font_preview->get_data(0)->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); - font_preview->get_data(0)->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int()); - font_preview->get_data(0)->set_embolden(import_settings_data->get("embolden")); - font_preview->get_data(0)->set_transform(import_settings_data->get("transform")); - font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling")); + if (font_preview->get_font().is_valid()) { + font_preview->get_font()->set_antialiased(import_settings_data->get("antialiased")); + font_preview->get_font()->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field")); + font_preview->get_font()->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range")); + font_preview->get_font()->set_msdf_size(import_settings_data->get("msdf_size")); + font_preview->get_font()->set_force_autohinter(import_settings_data->get("force_autohinter")); + font_preview->get_font()->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); + font_preview->get_font()->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int()); + font_preview->get_font()->set_oversampling(import_settings_data->get("oversampling")); } font_preview_label->add_theme_font_override("font", font_preview); + font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); font_preview_label->update(); - menu_ot->clear(); - menu_ot_ss->clear(); - menu_ot_cv->clear(); - menu_ot_cu->clear(); - bool have_ss = false; - bool have_cv = false; - bool have_cu = false; - Dictionary features = font_preview->get_feature_list(); - for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) { - String ftr_name = TS->tag_to_name(*ftr); - if (ftr_name.begins_with("stylistic_set_")) { - menu_ot_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr); - have_ss = true; - } else if (ftr_name.begins_with("character_variant_")) { - menu_ot_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr); - have_cv = true; - } else if (ftr_name.begins_with("custom_")) { - menu_ot_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr); - have_cu = true; - } else { - menu_ot->add_item(ftr_name.capitalize(), (int32_t)*ftr); - } - } - if (have_ss) { - menu_ot->add_submenu_item(RTR("Stylistic Sets"), "SSMenu"); - } - if (have_cv) { - menu_ot->add_submenu_item(RTR("Character Variants"), "CVMenu"); - } - if (have_cu) { - menu_ot->add_submenu_item(RTR("Custom"), "CUMenu"); - } - _variations_validate(); popup_centered_ratio(); @@ -1366,7 +1113,8 @@ DynamicFontImportSettings *DynamicFontImportSettings::get_singleton() { DynamicFontImportSettings::DynamicFontImportSettings() { singleton = this; - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "face_index"), 0)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "antialiased"), true)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); @@ -1375,44 +1123,29 @@ DynamicFontImportSettings::DynamicFontImportSettings() { options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1)); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0.f)); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::TRANSFORM2D, "transform"), Transform2D())); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0)); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, ""), false)); - - // Popup menus - - locale_select = memnew(EditorLocaleDialog); - locale_select->connect("locale_selected", callable_mp(this, &DynamicFontImportSettings::_lang_add_item)); - add_child(locale_select); - menu_scripts = memnew(PopupMenu); - menu_scripts->set_name("Script"); - script_codes = TranslationServer::get_singleton()->get_all_scripts(); - for (int i = 0; i < script_codes.size(); i++) { - menu_scripts->add_item(TranslationServer::get_singleton()->get_script_name(script_codes[i]) + " (" + script_codes[i] + ")", i); - } - add_child(menu_scripts); - menu_scripts->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_script_add_item)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Metadata Overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "language_support"), Dictionary())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "script_support"), Dictionary())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features"), Dictionary())); - menu_ot = memnew(PopupMenu); - add_child(menu_ot); - menu_ot->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); - menu_ot_cv = memnew(PopupMenu); - menu_ot_cv->set_name("CVMenu"); - menu_ot->add_child(menu_ot_cv); - menu_ot_cv->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, ""), false)); - menu_ot_ss = memnew(PopupMenu); - menu_ot_ss->set_name("SSMenu"); - menu_ot->add_child(menu_ot_ss); - menu_ot_ss->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); + options_text.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features"), Dictionary())); + options_text.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "")); - menu_ot_cu = memnew(PopupMenu); - menu_ot_cu->set_name("CUMenu"); - menu_ot->add_child(menu_ot_cu); - menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "0,127,1"), 16)); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1"), 0)); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Variation", PROPERTY_HINT_NONE, "variation", PROPERTY_USAGE_GROUP), Variant())); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "variation_opentype"), Dictionary())); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "variation_embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0)); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "variation_face_index"), 0)); + options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::TRANSFORM2D, "variation_transform"), Transform2D())); Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")) : Color(1, 1, 0); @@ -1442,7 +1175,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { main_pages->add_child(page1_vb); page1_description = memnew(Label); - page1_description->set_text(TTR("Select font rendering options:")); + page1_description->set_text(TTR("Select font rendering options, fallback font, and metadata override:")); page1_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); page1_vb->add_child(page1_description); @@ -1451,15 +1184,25 @@ DynamicFontImportSettings::DynamicFontImportSettings() { page1_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); page1_vb->add_child(page1_hb); + VBoxContainer *page1_lbl_vb = memnew(VBoxContainer); + page1_lbl_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL); + page1_lbl_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page1_hb->add_child(page1_lbl_vb); + + font_name_label = memnew(Label); + font_name_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + font_name_label->set_clip_text(true); + font_name_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page1_lbl_vb->add_child(font_name_label); + font_preview_label = memnew(Label); - font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); font_preview_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); font_preview_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); font_preview_label->set_autowrap_mode(Label::AUTOWRAP_ARBITRARY); font_preview_label->set_clip_text(true); font_preview_label->set_v_size_flags(Control::SIZE_EXPAND_FILL); font_preview_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page1_hb->add_child(font_preview_label); + page1_lbl_vb->add_child(font_preview_label); inspector_general = memnew(EditorInspector); inspector_general->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -1469,11 +1212,11 @@ DynamicFontImportSettings::DynamicFontImportSettings() { // Page 2 layout: Configurations VBoxContainer *page2_vb = memnew(VBoxContainer); - page2_vb->set_name(TTR("Sizes and Variations")); + page2_vb->set_name(TTR("Pre-render configurations")); main_pages->add_child(page2_vb); page2_description = memnew(Label); - page2_description->set_text(TTR("Add font size, variation coordinates, and extra spacing combinations to pre-render:")); + page2_description->set_text(TTR("Add font size, and variation coordinates, and select glyphs to pre-render:")); page2_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); page2_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); page2_vb->add_child(page2_description); @@ -1517,48 +1260,44 @@ DynamicFontImportSettings::DynamicFontImportSettings() { inspector_vars = memnew(EditorInspector); inspector_vars->set_v_size_flags(Control::SIZE_EXPAND_FILL); inspector_vars->connect("property_edited", callable_mp(this, &DynamicFontImportSettings::_variation_changed)); - page2_hb->add_child(inspector_vars); - - // Page 3 layout: Text to select glyphs - VBoxContainer *page3_vb = memnew(VBoxContainer); - page3_vb->set_name(TTR("Glyphs from the Text")); - main_pages->add_child(page3_vb); + page2_side_vb->add_child(inspector_vars); - page3_description = memnew(Label); - page3_description->set_text(TTR("Enter a text to shape and add all required glyphs to pre-render list:")); - page3_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page3_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); - page3_vb->add_child(page3_description); + preload_pages = memnew(TabContainer); + preload_pages->set_tab_alignment(TabBar::ALIGNMENT_CENTER); + preload_pages->set_v_size_flags(Control::SIZE_EXPAND_FILL); + preload_pages->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page2_hb->add_child(preload_pages); - HBoxContainer *ot_hb = memnew(HBoxContainer); - page3_vb->add_child(ot_hb); - ot_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + // Page 2.1 layout: Text to select glyphs + VBoxContainer *page2_1_vb = memnew(VBoxContainer); + page2_1_vb->set_name(TTR("Glyphs from the Text")); + preload_pages->add_child(page2_1_vb); - Label *label_ed_ftr = memnew(Label); - ot_hb->add_child(label_ed_ftr); - label_ed_ftr->set_text(TTR("OpenType features:")); + page2_1_description = memnew(Label); + page2_1_description->set_text(TTR("Enter a text to shape and add all required glyphs to pre-render list:")); + page2_1_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page2_1_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); + page2_1_vb->add_child(page2_1_description); - ftr_edit = memnew(LineEdit); - ot_hb->add_child(ftr_edit); - ftr_edit->connect("text_changed", callable_mp(this, &DynamicFontImportSettings::_change_text_opts)); - ftr_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); + HSplitContainer *page2_1_hb = memnew(HSplitContainer); + page2_1_vb->add_child(page2_1_hb); + page2_1_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page2_1_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL); - Label *label_ed_lang = memnew(Label); - ot_hb->add_child(label_ed_lang); - label_ed_lang->set_text(TTR("Text language:")); + inspector_text = memnew(EditorInspector); - lang_edit = memnew(LineEdit); - ot_hb->add_child(lang_edit); - lang_edit->connect("text_changed", callable_mp(this, &DynamicFontImportSettings::_change_text_opts)); - lang_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); + inspector_text->set_v_size_flags(Control::SIZE_EXPAND_FILL); + inspector_text->set_custom_minimum_size(Size2(300 * EDSCALE, 250 * EDSCALE)); + inspector_text->connect("property_edited", callable_mp(this, &DynamicFontImportSettings::_change_text_opts)); + page2_1_hb->add_child(inspector_text); text_edit = memnew(TextEdit); - page3_vb->add_child(text_edit); + page2_1_hb->add_child(text_edit); text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL); text_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL); HBoxContainer *text_hb = memnew(HBoxContainer); - page3_vb->add_child(text_hb); + page2_1_vb->add_child(text_hb); text_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); label_glyphs = memnew(Label); @@ -1576,21 +1315,21 @@ DynamicFontImportSettings::DynamicFontImportSettings() { btn_clear->set_text(TTR("Clear glyph list")); btn_clear->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_glyph_clear)); - // Page 4 layout: Character map - VBoxContainer *page4_vb = memnew(VBoxContainer); - page4_vb->set_name(TTR("Glyphs from the Character Map")); - main_pages->add_child(page4_vb); + // Page 2.2 layout: Character map + VBoxContainer *page2_2_vb = memnew(VBoxContainer); + page2_2_vb->set_name(TTR("Glyphs from the Character Map")); + preload_pages->add_child(page2_2_vb); - page4_description = memnew(Label); - page4_description->set_text(TTR("Add or remove additional glyphs from the character map to pre-render list:\nNote: Some stylistic alternatives and glyph variants do not have one-to-one correspondence to character, and not shown in this map, use \"Glyphs from the text\" to add these.")); - page4_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page4_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); - page4_vb->add_child(page4_description); + page2_2_description = memnew(Label); + page2_2_description->set_text(TTR("Add or remove glyphs from the character map to pre-render list:\nNote: Some stylistic alternatives and glyph variants do not have one-to-one correspondence to character, and not shown in this map, use \"Glyphs from the text\" tab to add these.")); + page2_2_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page2_2_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); + page2_2_vb->add_child(page2_2_description); HSplitContainer *glyphs_split = memnew(HSplitContainer); glyphs_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); glyphs_split->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page4_vb->add_child(glyphs_split); + page2_2_vb->add_child(glyphs_split); glyph_table = memnew(Tree); glyphs_split->add_child(glyph_table); @@ -1627,101 +1366,6 @@ DynamicFontImportSettings::DynamicFontImportSettings() { _add_glyph_range_item(unicode_ranges[i].start, unicode_ranges[i].end, unicode_ranges[i].name); } - // Page 4 layout: Metadata override - VBoxContainer *page5_vb = memnew(VBoxContainer); - page5_vb->set_name(TTR("Metadata Override")); - main_pages->add_child(page5_vb); - - page5_description = memnew(Label); - page5_description->set_text(TTR("Add or remove language and script support overrides, to control fallback font selection order:")); - page5_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page5_description->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); - page5_vb->add_child(page5_description); - - HBoxContainer *hb_lang = memnew(HBoxContainer); - page5_vb->add_child(hb_lang); - - label_langs = memnew(Label); - label_langs->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - label_langs->set_h_size_flags(Control::SIZE_EXPAND_FILL); - label_langs->set_text(TTR("Language support overrides")); - hb_lang->add_child(label_langs); - - add_lang = memnew(Button); - hb_lang->add_child(add_lang); - add_lang->set_tooltip(TTR("Add language override")); - add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - add_lang->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_lang_add)); - - lang_list = memnew(Tree); - page5_vb->add_child(lang_list); - lang_list->set_hide_root(true); - lang_list->set_columns(3); - lang_list->set_column_expand(0, false); // Check - lang_list->set_column_custom_minimum_width(0, 50 * EDSCALE); - lang_list->set_column_expand(1, true); - lang_list->set_column_custom_minimum_width(1, 80 * EDSCALE); - lang_list->set_column_expand(2, false); - lang_list->set_column_custom_minimum_width(2, 50 * EDSCALE); - lang_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_lang_remove)); - lang_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); - - HBoxContainer *hb_script = memnew(HBoxContainer); - page5_vb->add_child(hb_script); - - label_script = memnew(Label); - label_script->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - label_script->set_h_size_flags(Control::SIZE_EXPAND_FILL); - label_script->set_text(TTR("Script support overrides")); - hb_script->add_child(label_script); - - add_script = memnew(Button); - hb_script->add_child(add_script); - add_script->set_tooltip(TTR("Add script override")); - add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - add_script->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_script_add)); - - script_list = memnew(Tree); - page5_vb->add_child(script_list); - script_list->set_hide_root(true); - script_list->set_columns(3); - script_list->set_column_expand(0, false); - script_list->set_column_custom_minimum_width(0, 50 * EDSCALE); - script_list->set_column_expand(1, true); - script_list->set_column_custom_minimum_width(1, 80 * EDSCALE); - script_list->set_column_expand(2, false); - script_list->set_column_custom_minimum_width(2, 50 * EDSCALE); - script_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_script_remove)); - script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); - - HBoxContainer *hb_ot = memnew(HBoxContainer); - page5_vb->add_child(hb_ot); - - label_ot = memnew(Label); - label_ot->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - label_ot->set_h_size_flags(Control::SIZE_EXPAND_FILL); - label_ot->set_text(TTR("OpenType feature overrides")); - hb_ot->add_child(label_ot); - - add_ot = memnew(Button); - hb_ot->add_child(add_ot); - add_ot->set_tooltip(TTR("Add feature override")); - add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add)); - - ot_list = memnew(Tree); - page5_vb->add_child(ot_list); - ot_list->set_hide_root(true); - ot_list->set_columns(3); - ot_list->set_column_expand(0, true); - ot_list->set_column_custom_minimum_width(0, 80 * EDSCALE); - ot_list->set_column_expand(1, true); - ot_list->set_column_custom_minimum_width(1, 80 * EDSCALE); - ot_list->set_column_expand(2, false); - ot_list->set_column_custom_minimum_width(2, 50 * EDSCALE); - ot_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_ot_remove)); - ot_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); - // Common import_settings_data.instantiate(); diff --git a/editor/import/dynamic_font_import_settings.h b/editor/import/dynamic_font_import_settings.h index ba75c98057a8..f151a0a37ca5 100644 --- a/editor/import/dynamic_font_import_settings.h +++ b/editor/import/dynamic_font_import_settings.h @@ -45,7 +45,30 @@ #include "scene/resources/font.h" #include "servers/text_server.h" -class DynamicFontImportSettingsData; +class DynamicFontImportSettings; + +class DynamicFontImportSettingsData : public RefCounted { + GDCLASS(DynamicFontImportSettingsData, RefCounted) + friend class DynamicFontImportSettings; + + HashMap settings; + HashMap defaults; + List options; + DynamicFontImportSettings *owner = nullptr; + + HashSet selected_chars; + HashSet selected_glyphs; + + Ref fd; + +public: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List *p_list) const; + + Ref get_font() const; +}; + class EditorFileDialog; class EditorInspector; class EditorLocaleDialog; @@ -67,21 +90,19 @@ class DynamicFontImportSettings : public ConfirmationDialog { List options_variations; List options_general; - EditorLocaleDialog *locale_select = nullptr; - Vector script_codes; - // Root layout Label *label_warn = nullptr; TabContainer *main_pages = nullptr; // Page 1 layout: Rendering Options Label *page1_description = nullptr; + Label *font_name_label = nullptr; Label *font_preview_label = nullptr; EditorInspector *inspector_general = nullptr; void _main_prop_changed(const String &p_edited_property); - // Page 2 layout: Configurations + // Page 2 layout: Preload Configurations Label *page2_description = nullptr; Label *label_vars = nullptr; Button *add_var = nullptr; @@ -95,19 +116,23 @@ class DynamicFontImportSettings : public ConfirmationDialog { void _variation_changed(const String &p_edited_property); void _variations_validate(); - // Page 3 layout: Text to select glyphs - Label *page3_description = nullptr; + TabContainer *preload_pages = nullptr; + + // Page 2.1 layout: Text to select glyphs + Label *page2_1_description = nullptr; Label *label_glyphs = nullptr; TextEdit *text_edit = nullptr; - LineEdit *ftr_edit = nullptr; - LineEdit *lang_edit = nullptr; + EditorInspector *inspector_text = nullptr; + + List options_text; + Ref text_settings_data; void _change_text_opts(); void _glyph_text_selected(); void _glyph_clear(); - // Page 4 layout: Character map - Label *page4_description = nullptr; + // Page 2.2 layout: Character map + Label *page2_2_description = nullptr; Tree *glyph_table = nullptr; Tree *glyph_tree = nullptr; TreeItem *glyph_root = nullptr; @@ -119,51 +144,12 @@ class DynamicFontImportSettings : public ConfirmationDialog { bool _char_update(int32_t p_char); void _range_update(int32_t p_start, int32_t p_end); - // Page 5 layout: Metadata override - Label *page5_description = nullptr; - Button *add_lang = nullptr; - Button *add_script = nullptr; - Button *add_ot = nullptr; - - PopupMenu *menu_scripts = nullptr; - PopupMenu *menu_ot = nullptr; - PopupMenu *menu_ot_ss = nullptr; - PopupMenu *menu_ot_cv = nullptr; - PopupMenu *menu_ot_cu = nullptr; - - Tree *lang_list = nullptr; - TreeItem *lang_list_root = nullptr; - Label *label_langs = nullptr; - - Tree *script_list = nullptr; - TreeItem *script_list_root = nullptr; - Label *label_script = nullptr; - - Tree *ot_list = nullptr; - TreeItem *ot_list_root = nullptr; - Label *label_ot = nullptr; - - void _lang_add(); - void _lang_add_item(const String &p_locale); - void _lang_remove(Object *p_item, int p_column, int p_id, MouseButton p_button); - - void _script_add(); - void _script_add_item(int p_option); - void _script_remove(Object *p_item, int p_column, int p_id, MouseButton p_button); - - void _ot_add(); - void _ot_add_item(int p_option); - void _ot_remove(Object *p_item, int p_column, int p_id, MouseButton p_button); - // Common void _add_glyph_range_item(int32_t p_start, int32_t p_end, const String &p_name); - Ref font_preview; - Ref font_main; - - RBSet selected_chars; - RBSet selected_glyphs; + Ref font_preview; + Ref font_main; void _re_import(); diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp index 8a40b113b9a8..5e1c3795944f 100644 --- a/editor/import/resource_importer_bmfont.cpp +++ b/editor/import/resource_importer_bmfont.cpp @@ -52,7 +52,7 @@ String ResourceImporterBMFont::get_save_extension() const { } String ResourceImporterBMFont::get_resource_type() const { - return "FontData"; + return "Font"; } bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap &p_options) const { @@ -60,19 +60,25 @@ bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const S } void ResourceImporterBMFont::get_import_options(const String &p_path, List *r_options, int p_preset) const { + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); } Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const HashMap &p_options, List *r_platform_variants, List *r_gen_files, Variant *r_metadata) { print_verbose("Importing BMFont font from: " + p_source_file); - Ref font; + Array fallbacks = p_options["fallbacks"]; + + Ref font; font.instantiate(); Error err = font->load_bitmap_font(p_source_file); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load font to file \"" + p_source_file + "\"."); - int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + font->set_fallbacks(fallbacks); + + int flg = 0; if ((bool)p_options["compress"]) { flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS; } diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index a92b0fe280b9..38633e11505e 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -66,7 +66,7 @@ String ResourceImporterDynamicFont::get_save_extension() const { } String ResourceImporterDynamicFont::get_resource_type() const { - return "FontData"; + return "Font"; } bool ResourceImporterDynamicFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap &p_options) const { @@ -103,7 +103,7 @@ String ResourceImporterDynamicFont::get_preset_name(int p_idx) const { void ResourceImporterDynamicFont::get_import_options(const String &p_path, List *r_options, int p_preset) const { bool msdf = p_preset == PRESET_MSDF; - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "face_index"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "antialiased"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false)); @@ -114,63 +114,19 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List< r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0.f)); - r_options->push_back(ImportOption(PropertyInfo(Variant::TRANSFORM2D, "transform"), Transform2D())); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides"), Dictionary())); - - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/char_ranges"), Vector())); - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/glyph_ranges"), Vector())); - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/configurations"), Vector())); - - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/language_enabled"), Vector())); - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/language_disabled"), Vector())); + r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/script_enabled"), Vector())); - r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/script_disabled"), Vector())); -} + r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); -bool ResourceImporterDynamicFont::_decode_variation(const String &p_token, Dictionary &r_variations, Vector2i &r_size, String &r_name, Vector2i &r_spacing) { - Vector tokens = p_token.split("="); - if (tokens.size() == 2) { - if (tokens[0] == "name") { - r_name = tokens[1]; - } else if (tokens[0] == "size") { - r_size.x = tokens[1].to_int(); - } else if (tokens[0] == "outline_size") { - r_size.y = tokens[1].to_int(); - } else if (tokens[0] == "spacing_space") { - r_spacing.x = tokens[1].to_int(); - } else if (tokens[0] == "spacing_glyph") { - r_spacing.y = tokens[1].to_int(); - } else { - r_variations[tokens[0]] = tokens[1].to_float(); - } - return true; - } else { - WARN_PRINT("Invalid variation: '" + p_token + "'."); - return false; - } -} - -bool ResourceImporterDynamicFont::_decode_range(const String &p_token, int32_t &r_pos) { - if (p_token.begins_with("U+") || p_token.begins_with("u+") || p_token.begins_with("0x")) { - // Unicode character hex index. - r_pos = p_token.substr(2).hex_to_int(); - return true; - } else if (p_token.length() == 3 && p_token[0] == '\'' && p_token[2] == '\'') { - // Unicode character. - r_pos = p_token.unicode_at(1); - return true; - } else if (p_token.is_numeric()) { - // Unicode character decimal index. - r_pos = p_token.to_int(); - return true; - } else { - return false; - } + // Hide from the main UI, only for advanced import dialog. + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "preload", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "language_support", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary())); + r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "script_support", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary())); + r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary())); } bool ResourceImporterDynamicFont::has_advanced_options() const { @@ -183,30 +139,26 @@ void ResourceImporterDynamicFont::show_advanced_options(const String &p_path) { Error ResourceImporterDynamicFont::import(const String &p_source_file, const String &p_save_path, const HashMap &p_options, List *r_platform_variants, List *r_gen_files, Variant *r_metadata) { print_verbose("Importing dynamic font from: " + p_source_file); - int face_index = p_options["face_index"]; - bool antialiased = p_options["antialiased"]; bool generate_mipmaps = p_options["generate_mipmaps"]; bool msdf = p_options["multichannel_signed_distance_field"]; int px_range = p_options["msdf_pixel_range"]; int px_size = p_options["msdf_size"]; - Dictionary ot_ov = p_options["opentype_feature_overrides"]; + Dictionary ot_ov = p_options["opentype_features"]; bool autohinter = p_options["force_autohinter"]; int hinting = p_options["hinting"]; int subpixel_positioning = p_options["subpixel_positioning"]; real_t oversampling = p_options["oversampling"]; - real_t embolden = p_options["embolden"]; - Transform2D transform = p_options["transform"]; + Array fallbacks = p_options["fallbacks"]; // Load base font data. Vector data = FileAccess::get_file_as_array(p_source_file); // Create font. - Ref font; + Ref font; font.instantiate(); font->set_data(data); - font->set_face_index(face_index); font->set_antialiased(antialiased); font->set_generate_mipmaps(generate_mipmaps); font->set_multichannel_signed_distance_field(msdf); @@ -216,105 +168,52 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str font->set_fixed_size(0); font->set_force_autohinter(autohinter); font->set_subpixel_positioning((TextServer::SubpixelPositioning)subpixel_positioning); - font->set_embolden(embolden); - font->set_transform(transform); font->set_hinting((TextServer::Hinting)hinting); font->set_oversampling(oversampling); + font->set_fallbacks(fallbacks); - Vector lang_en = p_options["support_overrides/language_enabled"]; - for (int i = 0; i < lang_en.size(); i++) { - font->set_language_support_override(lang_en[i], true); + Dictionary langs = p_options["language_support"]; + for (int i = 0; i < langs.size(); i++) { + String key = langs.get_key_at_index(i); + bool enabled = langs.get_value_at_index(i); + font->set_language_support_override(key, enabled); } - Vector lang_dis = p_options["support_overrides/language_disabled"]; - for (int i = 0; i < lang_dis.size(); i++) { - font->set_language_support_override(lang_dis[i], false); + Dictionary scripts = p_options["script_support"]; + for (int i = 0; i < scripts.size(); i++) { + String key = scripts.get_key_at_index(i); + bool enabled = scripts.get_value_at_index(i); + font->set_script_support_override(key, enabled); } - Vector scr_en = p_options["support_overrides/script_enabled"]; - for (int i = 0; i < scr_en.size(); i++) { - font->set_script_support_override(scr_en[i], true); - } + Array preload_configurations = p_options["preload"]; - Vector scr_dis = p_options["support_overrides/script_disabled"]; - for (int i = 0; i < scr_dis.size(); i++) { - font->set_script_support_override(scr_dis[i], false); - } + for (int i = 0; i < preload_configurations.size(); i++) { + Dictionary preload_config = preload_configurations[i]; - Vector variations = p_options["preload/configurations"]; - Vector char_ranges = p_options["preload/char_ranges"]; - Vector gl_ranges = p_options["preload/glyph_ranges"]; - - for (int i = 0; i < variations.size(); i++) { - String name; - Dictionary var; - Vector2i size = Vector2(16, 0); - Vector2i spacing; - - Vector variation_tags = variations[i].split(","); - for (int j = 0; j < variation_tags.size(); j++) { - if (!_decode_variation(variation_tags[j], var, size, name, spacing)) { - WARN_PRINT(vformat(TTR("Invalid variation: \"%s\""), variations[i])); - continue; - } - } - RID conf = font->find_cache(var); - - for (int j = 0; j < char_ranges.size(); j++) { - int32_t start, end; - Vector tokens = char_ranges[j].split("-"); - if (tokens.size() == 2) { - if (!_decode_range(tokens[0], start) || !_decode_range(tokens[1], end)) { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j])); - continue; - } - } else if (tokens.size() == 1) { - if (!_decode_range(tokens[0], start)) { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j])); - continue; - } - end = start; - } else { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j])); - continue; - } - - // Preload character ranges for each variations / sizes. - print_verbose(vformat(TTR("Pre-rendering range U+%s...%s from configuration \"%s\" (%d / %d)..."), String::num_int64(start, 16), String::num_int64(end, 16), name, i + 1, variations.size())); - TS->font_render_range(conf, size, start, end); - } + Dictionary variation = preload_config.has("variation_opentype") ? preload_config["variation_opentype"].operator Dictionary() : Dictionary(); + double embolden = preload_config.has("variation_embolden") ? preload_config["variation_embolden"].operator double() : 0; + int face_index = preload_config.has("variation_face_index") ? preload_config["variation_face_index"].operator int() : 0; + Transform2D transform = preload_config.has("variation_transform") ? preload_config["variation_transform"].operator Transform2D() : Transform2D(); + Vector2i size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0); + String name = preload_config.has("name") ? preload_config["name"].operator String() : vformat("Configuration %d", i); - for (int j = 0; j < gl_ranges.size(); j++) { - int32_t start, end; - Vector tokens = gl_ranges[j].split("-"); - if (tokens.size() == 2) { - if (!_decode_range(tokens[0], start) || !_decode_range(tokens[1], end)) { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j])); - continue; - } - } else if (tokens.size() == 1) { - if (!_decode_range(tokens[0], start)) { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j])); - continue; - } - end = start; - } else { - WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j])); - continue; - } - - // Preload glyph range for each variations / sizes. - print_verbose(vformat(TTR("Pre-rendering glyph range 0x%s...%s from configuration \"%s\" (%d / %d)..."), String::num_int64(start, 16), String::num_int64(end, 16), name, i + 1, variations.size())); - for (int32_t k = start; k <= end; k++) { - TS->font_render_glyph(conf, size, k); - } + RID conf_rid = font->find_cache(variation, face_index, embolden, transform); + + Array chars = preload_config["chars"]; + for (int j = 0; j < chars.size(); j++) { + char32_t c = chars[j].operator int(); + TS->font_render_range(conf_rid, size, c, c); } - TS->font_set_spacing(conf, size.x, TextServer::SPACING_SPACE, spacing.x); - TS->font_set_spacing(conf, size.x, TextServer::SPACING_GLYPH, spacing.y); + Array glyphs = preload_config["glyphs"]; + for (int j = 0; j < glyphs.size(); j++) { + int32_t c = glyphs[j]; + TS->font_render_glyph(conf_rid, size, c); + } } - int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + int flg = 0; if ((bool)p_options["compress"]) { flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS; } diff --git a/editor/import/resource_importer_dynamic_font.h b/editor/import/resource_importer_dynamic_font.h index c0b6c094b0bd..a05c8bab05d2 100644 --- a/editor/import/resource_importer_dynamic_font.h +++ b/editor/import/resource_importer_dynamic_font.h @@ -43,9 +43,6 @@ class ResourceImporterDynamicFont : public ResourceImporter { }; public: - static bool _decode_range(const String &p_token, int32_t &r_pos); - static bool _decode_variation(const String &p_token, Dictionary &r_variations, Vector2i &r_size, String &r_name, Vector2i &r_spacing); - virtual String get_importer_name() const override; virtual String get_visible_name() const override; virtual void get_recognized_extensions(List *p_extensions) const override; diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index 30c349d0f27c..77b2cce6bd5a 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -52,7 +52,7 @@ String ResourceImporterImageFont::get_save_extension() const { } String ResourceImporterImageFont::get_resource_type() const { - return "FontData"; + return "Font"; } bool ResourceImporterImageFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap &p_options) const { @@ -64,6 +64,9 @@ void ResourceImporterImageFont::get_import_options(const String &p_path, Listpush_back(ImportOption(PropertyInfo(Variant::INT, "columns"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "font_size"), 14)); + + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); } @@ -92,8 +95,9 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin int rows = p_options["rows"]; int base_size = p_options["font_size"]; Vector ranges = p_options["character_ranges"]; + Array fallbacks = p_options["fallbacks"]; - Ref font; + Ref font; font.instantiate(); font->set_antialiased(false); font->set_generate_mipmaps(false); @@ -103,6 +107,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin font->set_force_autohinter(false); font->set_hinting(TextServer::HINTING_NONE); font->set_oversampling(1.0f); + font->set_fallbacks(fallbacks); Ref img; img.instantiate(); @@ -148,7 +153,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin font->set_ascent(0, base_size, 0.5 * chr_height); font->set_descent(0, base_size, 0.5 * chr_height); - int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + int flg = 0; if ((bool)p_options["compress"]) { flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS; } diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index ad6d8e6379f4..21d1a61d4792 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -562,10 +562,10 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, modulate); if (vertex == hover_point) { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); String num = String::num(vertex.vertex); - Size2 num_size = font->get_string_size(num, font_size); + Size2 num_size = font->get_string_size(num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); p_overlay->draw_string(font, point - num_size * 0.5, num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5)); } } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 2e4dcab20312..76df86d9e887 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -203,7 +203,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { Color linecolor_soft = linecolor; linecolor_soft.a *= 0.5; - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Ref icon = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")); Ref icon_selected = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons")); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 86addde87b7e..b9ded50d135c 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -396,7 +396,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label")); Color linecolor_soft = linecolor; linecolor_soft.a *= 0.5; - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Ref icon = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")); Ref icon_selected = get_theme_icon(SNAME("KeySelected"), SNAME("EditorIcons")); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 2ba246664679..c45fee0a31c5 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -1162,7 +1162,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); Ref style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); - Ref font = get_theme_font(SNAME("title_font"), SNAME("GraphNode")); + Ref font = get_theme_font(SNAME("title_font"), SNAME("GraphNode")); int font_size = get_theme_font_size(SNAME("title_font_size"), SNAME("GraphNode")); Color font_color = get_theme_color(SNAME("title_color"), SNAME("GraphNode")); Ref play = get_theme_icon(SNAME("Play"), SNAME("EditorIcons")); @@ -1224,7 +1224,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref sb = selected_nodes.has(E) ? style_selected : style; Size2 s = sb->get_minimum_size(); - int strsize = font->get_string_size(name, font_size).width; + int strsize = font->get_string_size(name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width; s.width += strsize; s.height += MAX(font->get_height(font_size), play->get_height()); s.width += sep + play->get_width(); @@ -1379,7 +1379,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { Ref anode = state_machine->get_node(name); bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode); Ref sb = selected_nodes.has(name) ? style_selected : style; - int strsize = font->get_string_size(name, font_size).width; + int strsize = font->get_string_size(name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width; NodeRect &nr = node_rects.write[i]; Vector2 offset = nr.node.position; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 1ea0299d4eeb..66938ea33d0a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2667,9 +2667,9 @@ void CanvasItemEditor::_update_cursor() { void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string, Side p_side) { Color color = get_theme_color(SNAME("font_color"), SNAME("Editor")); color.a = 0.8; - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); - Size2 text_size = font->get_string_size(p_string, font_size); + Size2 text_size = font->get_string_size(p_string, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); switch (p_side) { case SIDE_LEFT: p_position += Vector2(-text_size.x - 5, text_size.y / 2); @@ -2739,18 +2739,20 @@ void CanvasItemEditor::_draw_guides() { const float outline_size = 2; if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x))); - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); - Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color, outline_size, outline_color); + Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); + viewport->draw_string_outline(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color); viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y))); - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); - Size2 text_size = font->get_string_size(str, font_size); - viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color, outline_size, outline_color); + Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); + viewport->draw_string_outline(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color); viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE)); } } @@ -2774,7 +2776,7 @@ void CanvasItemEditor::_draw_rulers() { Color graduation_color = get_theme_color(SNAME("font_color"), SNAME("Editor")).lerp(bg_color, 0.5); Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); font_color.a = 0.8; - Ref font = get_theme_font(SNAME("rulers"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("rulers"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("rulers_size"), SNAME("EditorFonts")); // The rule transform @@ -2945,7 +2947,7 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 corner = Point2(begin.x, end.y); Vector2 length_vector = (begin - end).abs() / zoom; - Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + Ref font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); Color font_secondary_color = font_color; @@ -2962,13 +2964,15 @@ void CanvasItemEditor::_draw_ruler_tool() { text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5); if (begin.is_equal_approx(end)) { - viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); Ref position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")); viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2); return; } - viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x)); @@ -2986,16 +2990,19 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 text_pos2 = text_pos; text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); - viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); Point2 v_angle_text_pos = Point2(); v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5); - viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); text_pos2 = text_pos; text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2); - viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); Point2 h_angle_text_pos = Point2(); h_angle_text_pos.x = CLAMP(end.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); @@ -3012,7 +3019,8 @@ void CanvasItemEditor::_draw_ruler_tool() { h_angle_text_pos.y = MIN(text_pos.y - height_multiplier * text_height, MIN(end.y - text_height * 0.5, text_pos2.y - height_multiplier * text_height)); } } - viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); // Angle arcs int arc_point_count = 8; @@ -3047,17 +3055,21 @@ void CanvasItemEditor::_draw_ruler_tool() { text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2); if (draw_secondary_lines) { - viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); Point2 text_pos2 = text_pos; text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); - viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); text_pos2 = text_pos; text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2); - viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); } else { - viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color); + viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); + viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color); } } } else { @@ -3601,9 +3613,9 @@ void CanvasItemEditor::_draw_hover() { Ref node_icon = hovering_results[i].icon; String node_name = hovering_results[i].name; - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); - Size2 node_name_size = font->get_string_size(node_name, font_size); + Size2 node_name_size = font->get_string_size(node_name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size); Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3)); Point2 pos = transform.xform(hovering_results[i].position) - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 6d1a86765ab9..1e403df0aa5c 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -523,7 +523,7 @@ void CurveEditor::set_hover_point_index(int index) { } void CurveEditor::update_view_transform() { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); const real_t margin = font->get_height(font_size) + 2 * EDSCALE; @@ -669,7 +669,7 @@ void CurveEditor::_draw() { draw_set_transform_matrix(Transform2D()); - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float font_height = font->get_height(font_size); Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index bb0cfcba2579..380c7e84396a 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -812,19 +812,15 @@ void EditorFontPreviewPlugin::_preview_done() { } bool EditorFontPreviewPlugin::handles(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "FontData") || ClassDB::is_parent_class(p_type, "Font"); + return ClassDB::is_parent_class(p_type, "Font"); } Ref EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { Ref res = ResourceLoader::load(p_path); ERR_FAIL_COND_V(res.is_null(), Ref()); - Ref sampled_font; - if (res->is_class("Font")) { - sampled_font = res->duplicate(); - } else if (res->is_class("FontData")) { - sampled_font.instantiate(); - sampled_font->add_data(res->duplicate()); - } + Ref sampled_font; + sampled_font.instantiate(); + sampled_font->set_font(res); String sample; static const String sample_base = U"12漢字ԱբΑαАбΑαאבابܐܒހށआআਆઆଆஆఆಆആආกิກິༀကႠა한글ሀᎣᐁᚁᚠᜀᜠᝀᝠកᠠᤁᥐAb😀"; @@ -836,18 +832,16 @@ Ref EditorFontPreviewPlugin::generate_from_path(const String &p_path, if (sample.is_empty()) { sample = sampled_font->get_supported_chars().substr(0, 6); } - Vector2 size = sampled_font->get_string_size(sample, 50); + Vector2 size = sampled_font->get_string_size(sample, HORIZONTAL_ALIGNMENT_LEFT, -1, 50); Vector2 pos; pos.x = 64 - size.x / 2; pos.y = 80; - Ref font = sampled_font; - const Color c = GLOBAL_GET("rendering/environment/defaults/default_clear_color"); const float fg = c.get_luminance() < 0.5 ? 1.0 : 0.0; - font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(fg, fg, fg)); + sampled_font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(fg, fg, fg)); RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector(), Object::CONNECT_ONESHOT); diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp new file mode 100644 index 000000000000..9163124c3c03 --- /dev/null +++ b/editor/plugins/font_config_plugin.cpp @@ -0,0 +1,1008 @@ +/*************************************************************************/ +/* font_config_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "font_config_plugin.h" + +#include "editor/editor_scale.h" +#include "editor/import/dynamic_font_import_settings.h" + +/*************************************************************************/ +/* EditorPropertyFontMetaObject */ +/*************************************************************************/ + +bool EditorPropertyFontMetaObject::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name; + + if (name.begins_with("keys")) { + String key = name.get_slicec('/', 1); + dict[key] = p_value; + return true; + } + + return false; +} + +bool EditorPropertyFontMetaObject::_get(const StringName &p_name, Variant &r_ret) const { + String name = p_name; + + if (name.begins_with("keys")) { + String key = name.get_slicec('/', 1); + r_ret = dict[key]; + return true; + } + + return false; +} + +void EditorPropertyFontMetaObject::_bind_methods() { +} + +void EditorPropertyFontMetaObject::set_dict(const Dictionary &p_dict) { + dict = p_dict; +} + +Dictionary EditorPropertyFontMetaObject::get_dict() { + return dict; +} + +/*************************************************************************/ +/* EditorPropertyFontOTObject */ +/*************************************************************************/ + +bool EditorPropertyFontOTObject::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name; + + if (name.begins_with("keys")) { + int key = name.get_slicec('/', 1).to_int(); + dict[key] = p_value; + return true; + } + + return false; +} + +bool EditorPropertyFontOTObject::_get(const StringName &p_name, Variant &r_ret) const { + String name = p_name; + + if (name.begins_with("keys")) { + int key = name.get_slicec('/', 1).to_int(); + r_ret = dict[key]; + return true; + } + + return false; +} + +void EditorPropertyFontOTObject::_bind_methods() { + ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &EditorPropertyFontOTObject::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorPropertyFontOTObject::property_get_revert); +} + +void EditorPropertyFontOTObject::set_dict(const Dictionary &p_dict) { + dict = p_dict; +} + +Dictionary EditorPropertyFontOTObject::get_dict() { + return dict; +} + +void EditorPropertyFontOTObject::set_defaults(const Dictionary &p_dict) { + defaults_dict = p_dict; +} + +Dictionary EditorPropertyFontOTObject::get_defaults() { + return defaults_dict; +} + +bool EditorPropertyFontOTObject::property_can_revert(const String &p_name) { + String name = p_name; + + if (name.begins_with("keys")) { + int key = name.get_slicec('/', 1).to_int(); + if (defaults_dict.has(key) && dict.has(key)) { + int value = dict[key]; + Vector3i range = defaults_dict[key]; + return range.z != value; + } + } + + return false; +} + +Variant EditorPropertyFontOTObject::property_get_revert(const String &p_name) { + String name = p_name; + + if (name.begins_with("keys")) { + int key = name.get_slicec('/', 1).to_int(); + if (defaults_dict.has(key)) { + Vector3i range = defaults_dict[key]; + return range.z; + } + } + + return Variant(); +} + +/*************************************************************************/ +/* EditorPropertyFontMetaOverride */ +/*************************************************************************/ + +void EditorPropertyFontMetaOverride::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + if (Object::cast_to