initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled

This commit is contained in:
2025-09-16 20:46:46 -04:00
commit 9d30169a8d
13378 changed files with 7050105 additions and 0 deletions

20
editor/themes/SCsub Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
import editor_theme_builders
# Fonts
flist = Glob("#thirdparty/fonts/*.ttf")
flist.extend(Glob("#thirdparty/fonts/*.otf"))
flist.extend(Glob("#thirdparty/fonts/*.woff"))
flist.extend(Glob("#thirdparty/fonts/*.woff2"))
flist.sort()
env.CommandNoCache(
"#editor/themes/builtin_fonts.gen.h",
flist,
env.Run(editor_theme_builders.make_fonts_header),
)
env.add_source_files(env.editor_sources, "*.cpp")

View File

@@ -0,0 +1,229 @@
/**************************************************************************/
/* editor_color_map.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_color_map.h"
HashMap<Color, Color> EditorColorMap::color_conversion_map;
HashSet<StringName> EditorColorMap::color_conversion_exceptions;
void EditorColorMap::add_conversion_color_pair(const String &p_from_color, const String &p_to_color) {
color_conversion_map[Color::html(p_from_color)] = Color::html(p_to_color);
}
void EditorColorMap::add_conversion_exception(const StringName &p_icon_name) {
color_conversion_exceptions.insert(p_icon_name);
}
void EditorColorMap::create() {
// Some of the colors below are listed for completeness sake.
// This can be a basis for proper palette validation later.
// Convert: FROM TO
add_conversion_color_pair("#478cbf", "#478cbf"); // Godot Blue
add_conversion_color_pair("#414042", "#414042"); // Godot Gray
add_conversion_color_pair("#ffffff", "#414141"); // Pure white
add_conversion_color_pair("#fefefe", "#fefefe"); // Forced light color
add_conversion_color_pair("#000000", "#bfbfbf"); // Pure black
add_conversion_color_pair("#010101", "#010101"); // Forced dark color
// Keep pure RGB colors as is, but list them for explicitness.
add_conversion_color_pair("#ff0000", "#ff0000"); // Pure red
add_conversion_color_pair("#00ff00", "#00ff00"); // Pure green
add_conversion_color_pair("#0000ff", "#0000ff"); // Pure blue
// GUI Colors
add_conversion_color_pair("#e0e0e0", "#5a5a5a"); // Common icon color
add_conversion_color_pair("#808080", "#808080"); // GUI disabled color
add_conversion_color_pair("#b3b3b3", "#363636"); // GUI disabled light color
add_conversion_color_pair("#699ce8", "#699ce8"); // GUI highlight color
add_conversion_color_pair("#f9f9f9", "#606060"); // Scrollbar grabber highlight color
add_conversion_color_pair("#c38ef1", "#a85de9"); // Animation
add_conversion_color_pair("#8da5f3", "#3d64dd"); // 2D Node
add_conversion_color_pair("#7582a8", "#6d83c8"); // 2D Node Abstract
add_conversion_color_pair("#fc7f7f", "#cd3838"); // 3D Node
add_conversion_color_pair("#b56d6d", "#be6a6a"); // 3D Node Abstract
add_conversion_color_pair("#99c4ff", "#4589e6"); // 2D Non-Node
add_conversion_color_pair("#869ebf", "#7097cd"); // 2D Non-Node Abstract
add_conversion_color_pair("#ffa6bd", "#e65c7f"); // 3D Non-Node
add_conversion_color_pair("#bf909c", "#cd8b9c"); // 3D Non-Node Abstract
add_conversion_color_pair("#8eef97", "#2fa139"); // GUI Control
add_conversion_color_pair("#76ad7b", "#64a66a"); // GUI Control Abstract
add_conversion_color_pair("#5fb2ff", "#0079f0"); // Selection (blue)
add_conversion_color_pair("#003e7a", "#2b74bb"); // Selection (darker blue)
add_conversion_color_pair("#f7f5cf", "#615f3a"); // Gizmo (yellow)
// Rainbow
add_conversion_color_pair("#ff4545", "#ff2929"); // Red
add_conversion_color_pair("#ffe345", "#ffe337"); // Yellow
add_conversion_color_pair("#80ff45", "#74ff34"); // Green
add_conversion_color_pair("#45ffa2", "#2cff98"); // Aqua
add_conversion_color_pair("#45d7ff", "#22ccff"); // Blue
add_conversion_color_pair("#8045ff", "#702aff"); // Purple
add_conversion_color_pair("#ff4596", "#ff2781"); // Pink
// Audio gradients
add_conversion_color_pair("#e1da5b", "#d6cf4b"); // Yellow
add_conversion_color_pair("#62aeff", "#1678e0"); // Frozen gradient top
add_conversion_color_pair("#75d1e6", "#41acc5"); // Frozen gradient middle
add_conversion_color_pair("#84ffee", "#49ccba"); // Frozen gradient bottom
add_conversion_color_pair("#f70000", "#c91616"); // Color track red
add_conversion_color_pair("#eec315", "#d58c0b"); // Color track orange
add_conversion_color_pair("#dbee15", "#b7d10a"); // Color track yellow
add_conversion_color_pair("#288027", "#218309"); // Color track green
// Other objects
add_conversion_color_pair("#ffca5f", "#fea900"); // Mesh resource (orange)
add_conversion_color_pair("#2998ff", "#68b6ff"); // Shape resource (blue)
add_conversion_color_pair("#a2d2ff", "#4998e3"); // Shape resource (light blue)
add_conversion_color_pair("#69c4d4", "#29a3cc"); // Input event highlight (light blue)
// Animation editor tracks
// The property track icon color is set by the common icon color.
add_conversion_color_pair("#ea7940", "#bd5e2c"); // 3D Position track
add_conversion_color_pair("#ff2b88", "#bd165f"); // 3D Rotation track
add_conversion_color_pair("#eac840", "#bd9d1f"); // 3D Scale track
add_conversion_color_pair("#3cf34e", "#16a827"); // Call Method track
add_conversion_color_pair("#2877f6", "#236be6"); // Bezier Curve track
add_conversion_color_pair("#eae440", "#9f9722"); // Audio Playback track
add_conversion_color_pair("#a448f0", "#9853ce"); // Animation Playback track
add_conversion_color_pair("#5ad5c4", "#0a9c88"); // Blend Shape track
// Control layouts
add_conversion_color_pair("#d6d6d6", "#474747"); // Highlighted part
add_conversion_color_pair("#474747", "#d6d6d6"); // Background part
add_conversion_color_pair("#919191", "#6e6e6e"); // Border part
// TileSet editor icons
add_conversion_color_pair("#fce00e", "#aa8d24"); // New Single Tile
add_conversion_color_pair("#0e71fc", "#0350bd"); // New Autotile
add_conversion_color_pair("#c6ced4", "#828f9b"); // New Atlas
// Variant types
add_conversion_color_pair("#41ecad", "#25e3a0"); // Variant
add_conversion_color_pair("#6f91f0", "#6d8eeb"); // bool
add_conversion_color_pair("#5abbef", "#4fb2e9"); // int/uint
add_conversion_color_pair("#35d4f4", "#27ccf0"); // float
add_conversion_color_pair("#4593ec", "#4690e7"); // String
add_conversion_color_pair("#ee5677", "#ee7991"); // AABB
add_conversion_color_pair("#e0e0e0", "#5a5a5a"); // Array
add_conversion_color_pair("#e1ec41", "#b2bb19"); // Basis
add_conversion_color_pair("#54ed9e", "#57e99f"); // Dictionary
add_conversion_color_pair("#417aec", "#6993ec"); // NodePath
add_conversion_color_pair("#55f3e3", "#12d5c3"); // Object
add_conversion_color_pair("#f74949", "#f77070"); // Plane
add_conversion_color_pair("#44bd44", "#46b946"); // Projection
add_conversion_color_pair("#ec418e", "#ec69a3"); // Quaternion
add_conversion_color_pair("#f1738f", "#ee758e"); // Rect2
add_conversion_color_pair("#41ec80", "#2ce573"); // RID
add_conversion_color_pair("#b9ec41", "#96ce1a"); // Transform2D
add_conversion_color_pair("#f68f45", "#f49047"); // Transform3D
add_conversion_color_pair("#ac73f1", "#ad76ee"); // Vector2
add_conversion_color_pair("#de66f0", "#dc6aed"); // Vector3
add_conversion_color_pair("#f066bd", "#ed6abd"); // Vector4
// Visual shaders
add_conversion_color_pair("#77ce57", "#67c046"); // Vector funcs
add_conversion_color_pair("#ea686c", "#d95256"); // Vector transforms
add_conversion_color_pair("#eac968", "#d9b64f"); // Textures and cubemaps
add_conversion_color_pair("#cf68ea", "#c050dd"); // Functions and expressions
// These icons should not be converted.
add_conversion_exception("EditorPivot");
add_conversion_exception("EditorHandle");
add_conversion_exception("EditorHandleDisabled");
add_conversion_exception("EditorHandleAdd");
add_conversion_exception("EditorCurveHandle");
add_conversion_exception("EditorPathSharpHandle");
add_conversion_exception("EditorPathSmoothHandle");
add_conversion_exception("EditorBoneHandle");
add_conversion_exception("Editor3DHandle");
add_conversion_exception("Godot");
add_conversion_exception("Sky");
add_conversion_exception("EditorControlAnchor");
add_conversion_exception("DefaultProjectIcon");
add_conversion_exception("ZoomMore");
add_conversion_exception("ZoomLess");
add_conversion_exception("ZoomReset");
add_conversion_exception("LockViewport");
add_conversion_exception("GroupViewport");
add_conversion_exception("StatusSuccess");
add_conversion_exception("OverbrightIndicator");
add_conversion_exception("MaterialPreviewCube");
add_conversion_exception("MaterialPreviewSphere");
add_conversion_exception("MaterialPreviewQuad");
add_conversion_exception("MaterialPreviewLight1");
add_conversion_exception("MaterialPreviewLight2");
// Gizmo icons displayed in the 3D editor.
add_conversion_exception("Gizmo3DSamplePlayer");
add_conversion_exception("GizmoAudioListener3D");
add_conversion_exception("GizmoCamera3D");
add_conversion_exception("GizmoCPUParticles3D");
add_conversion_exception("GizmoDecal");
add_conversion_exception("GizmoDirectionalLight");
add_conversion_exception("GizmoFogVolume");
add_conversion_exception("GizmoGPUParticles3D");
add_conversion_exception("GizmoLight");
add_conversion_exception("GizmoLightmapGI");
add_conversion_exception("GizmoLightmapProbe");
add_conversion_exception("GizmoReflectionProbe");
add_conversion_exception("GizmoSpotLight");
add_conversion_exception("GizmoVoxelGI");
// GUI
add_conversion_exception("GuiChecked");
add_conversion_exception("GuiRadioChecked");
add_conversion_exception("GuiIndeterminate");
add_conversion_exception("GuiCloseCustomizable");
add_conversion_exception("GuiGraphNodePort");
add_conversion_exception("GuiResizer");
add_conversion_exception("GuiMiniCheckerboard");
/// Code Editor.
add_conversion_exception("GuiTab");
add_conversion_exception("GuiSpace");
add_conversion_exception("CodeFoldedRightArrow");
add_conversion_exception("CodeFoldDownArrow");
add_conversion_exception("CodeRegionFoldedRightArrow");
add_conversion_exception("CodeRegionFoldDownArrow");
add_conversion_exception("TextEditorPlay");
add_conversion_exception("Breakpoint");
}
void EditorColorMap::finish() {
color_conversion_map.clear();
color_conversion_exceptions.clear();
}

View File

@@ -0,0 +1,57 @@
/**************************************************************************/
/* editor_color_map.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "core/math/color.h"
#include "core/string/string_name.h"
#include "core/templates/hash_map.h"
#include "core/templates/hash_set.h"
// The default icon theme is designed to be used for a dark theme. This map stores
// Color values to convert to other colors for better readability on a light theme.
class EditorColorMap {
// Godot Color values are used to avoid the ambiguity of strings
// (where "#ffffff", "fff", and "white" are all equivalent).
static HashMap<Color, Color> color_conversion_map;
// The names of the icons to never convert, even if one of their colors
// are contained in the color map from above.
static HashSet<StringName> color_conversion_exceptions;
public:
static void add_conversion_color_pair(const String &p_from_color, const String &p_to_color);
static void add_conversion_exception(const StringName &p_icon_name);
static HashMap<Color, Color> &get_color_conversion_map() { return color_conversion_map; }
static HashSet<StringName> &get_color_conversion_exceptions() { return color_conversion_exceptions; }
static void create();
static void finish();
};

View File

@@ -0,0 +1,486 @@
/**************************************************************************/
/* editor_fonts.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_fonts.h"
#include "core/io/dir_access.h"
#include "editor/editor_string_names.h"
#include "editor/settings/editor_settings.h"
#include "editor/themes/builtin_fonts.gen.h"
#include "editor/themes/editor_scale.h"
#include "scene/resources/font.h"
#include "scene/scene_string_names.h"
Ref<FontFile> load_external_font(const String &p_path, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_font_disable_embedded_bitmaps, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
Ref<FontFile> font;
font.instantiate();
Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_path);
font->set_data(data);
font->set_multichannel_signed_distance_field(p_msdf);
font->set_antialiasing(p_aa);
font->set_hinting(p_hinting);
font->set_force_autohinter(p_autohint);
font->set_subpixel_positioning(p_font_subpixel_positioning);
font->set_disable_embedded_bitmaps(p_font_disable_embedded_bitmaps);
if (r_fallbacks != nullptr) {
r_fallbacks->push_back(font);
}
return font;
}
Ref<SystemFont> load_system_font(const PackedStringArray &p_names, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_font_disable_embedded_bitmaps, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
Ref<SystemFont> font;
font.instantiate();
font->set_font_names(p_names);
font->set_multichannel_signed_distance_field(p_msdf);
font->set_antialiasing(p_aa);
font->set_hinting(p_hinting);
font->set_force_autohinter(p_autohint);
font->set_subpixel_positioning(p_font_subpixel_positioning);
font->set_disable_embedded_bitmaps(p_font_disable_embedded_bitmaps);
if (r_fallbacks != nullptr) {
r_fallbacks->push_back(font);
}
return font;
}
Ref<FontFile> load_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_font_disable_embedded_bitmaps, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
Ref<FontFile> font;
font.instantiate();
font->set_data_ptr(p_data, p_size);
font->set_multichannel_signed_distance_field(p_msdf);
font->set_antialiasing(p_aa);
font->set_hinting(p_hinting);
font->set_force_autohinter(p_autohint);
font->set_subpixel_positioning(p_font_subpixel_positioning);
font->set_disable_embedded_bitmaps(p_font_disable_embedded_bitmaps);
if (r_fallbacks != nullptr) {
r_fallbacks->push_back(font);
}
return font;
}
Ref<FontVariation> make_bold_font(const Ref<Font> &p_font, double p_embolden, TypedArray<Font> *r_fallbacks = nullptr) {
Ref<FontVariation> font_var;
font_var.instantiate();
font_var->set_base_font(p_font);
font_var->set_variation_embolden(p_embolden);
if (r_fallbacks != nullptr) {
r_fallbacks->push_back(font_var);
}
return font_var;
}
void editor_register_fonts(const Ref<Theme> &p_theme) {
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)EDITOR_GET("interface/editor/font_antialiasing");
int font_hinting_setting = (int)EDITOR_GET("interface/editor/font_hinting");
TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)EDITOR_GET("interface/editor/font_subpixel_positioning");
bool font_disable_embedded_bitmaps = (bool)EDITOR_GET("interface/editor/font_disable_embedded_bitmaps");
bool font_allow_msdf = (bool)EDITOR_GET("interface/editor/font_allow_msdf");
TextServer::Hinting font_hinting;
TextServer::Hinting font_mono_hinting;
switch (font_hinting_setting) {
case 0:
// The "Auto" setting uses the setting that best matches the OS' font rendering:
// - macOS doesn't use font hinting.
// - Windows uses ClearType, which is in between "Light" and "Normal" hinting.
// - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light".
#ifdef MACOS_ENABLED
font_hinting = TextServer::HINTING_NONE;
font_mono_hinting = TextServer::HINTING_NONE;
#else
font_hinting = TextServer::HINTING_LIGHT;
font_mono_hinting = TextServer::HINTING_LIGHT;
#endif
break;
case 1:
font_hinting = TextServer::HINTING_NONE;
font_mono_hinting = TextServer::HINTING_NONE;
break;
case 2:
font_hinting = TextServer::HINTING_LIGHT;
font_mono_hinting = TextServer::HINTING_LIGHT;
break;
default:
font_hinting = TextServer::HINTING_NORMAL;
font_mono_hinting = TextServer::HINTING_LIGHT;
break;
}
// Load built-in fonts.
const int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE;
const float embolden_strength = 0.6;
Ref<Font> default_font = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false);
Ref<Font> default_font_msdf = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, font_allow_msdf);
String noto_cjk_path;
String noto_cjk_bold_path;
String var_suffix[] = { "HK", "KR", "SC", "TC", "JP" }; // Note: All Noto Sans CJK versions support all glyph variations, it should not match current locale.
for (size_t i = 0; i < std::size(var_suffix); i++) {
if (noto_cjk_path.is_empty()) {
noto_cjk_path = OS::get_singleton()->get_system_font_path("Noto Sans CJK " + var_suffix[i], 400, 100);
}
if (noto_cjk_bold_path.is_empty()) {
noto_cjk_bold_path = OS::get_singleton()->get_system_font_path("Noto Sans CJK " + var_suffix[i], 800, 100);
}
}
TypedArray<Font> fallbacks;
Ref<FontFile> arabic_font = load_internal_font(_font_Vazirmatn_Regular, _font_Vazirmatn_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> bengali_font = load_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> devanagari_font = load_internal_font(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> georgian_font = load_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> hebrew_font = load_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> malayalam_font = load_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> oriya_font = load_internal_font(_font_NotoSansOriya_Regular, _font_NotoSansOriya_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> sinhala_font = load_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> tamil_font = load_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> telugu_font = load_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> thai_font = load_internal_font(_font_NotoSansThai_Regular, _font_NotoSansThai_Regular_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
if (!noto_cjk_path.is_empty()) {
load_external_font(noto_cjk_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
}
Ref<FontFile> fallback_font = load_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
Ref<FontFile> japanese_font = load_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks);
default_font->set_fallbacks(fallbacks);
default_font_msdf->set_fallbacks(fallbacks);
Ref<FontFile> default_font_bold = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false);
Ref<FontFile> default_font_bold_msdf = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, font_allow_msdf);
TypedArray<Font> fallbacks_bold;
Ref<FontFile> arabic_font_bold = load_internal_font(_font_Vazirmatn_Bold, _font_Vazirmatn_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> bengali_font_bold = load_internal_font(_font_NotoSansBengaliUI_Bold, _font_NotoSansBengaliUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> devanagari_font_bold = load_internal_font(_font_NotoSansDevanagariUI_Bold, _font_NotoSansDevanagariUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> georgian_font_bold = load_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> hebrew_font_bold = load_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> malayalam_font_bold = load_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> oriya_font_bold = load_internal_font(_font_NotoSansOriya_Bold, _font_NotoSansOriya_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> sinhala_font_bold = load_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> tamil_font_bold = load_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> telugu_font_bold = load_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThai_Bold, _font_NotoSansThai_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
if (!noto_cjk_bold_path.is_empty()) {
load_external_font(noto_cjk_bold_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false, &fallbacks_bold);
}
Ref<FontVariation> fallback_font_bold = make_bold_font(fallback_font, embolden_strength, &fallbacks_bold);
Ref<FontVariation> japanese_font_bold = make_bold_font(japanese_font, embolden_strength, &fallbacks_bold);
if (OS::get_singleton()->has_feature("system_fonts")) {
PackedStringArray emoji_font_names = {
"Apple Color Emoji",
"Segoe UI Emoji",
"Noto Color Emoji",
"Twitter Color Emoji",
"OpenMoji",
"EmojiOne Color"
};
Ref<SystemFont> emoji_font = load_system_font(emoji_font_names, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, false);
fallbacks.push_back(emoji_font);
fallbacks_bold.push_back(emoji_font);
}
default_font_bold->set_fallbacks(fallbacks_bold);
default_font_bold_msdf->set_fallbacks(fallbacks_bold);
Ref<FontFile> default_font_mono = load_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_mono_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps);
default_font_mono->set_fallbacks(fallbacks);
// Init base font configs and load custom fonts.
String custom_font_path = EDITOR_GET("interface/editor/main_font");
String custom_font_path_bold = EDITOR_GET("interface/editor/main_font_bold");
String custom_font_path_source = EDITOR_GET("interface/editor/code_font");
Ref<FontVariation> default_fc;
default_fc.instantiate();
if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps);
{
TypedArray<Font> fallback_custom = { default_font };
custom_font->set_fallbacks(fallback_custom);
}
default_fc->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
default_fc->set_base_font(default_font);
}
default_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
default_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
Dictionary default_fc_opentype;
default_fc_opentype["weight"] = 400;
default_fc->set_variation_opentype(default_fc_opentype);
Ref<FontVariation> default_fc_msdf;
default_fc_msdf.instantiate();
if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, font_allow_msdf);
{
TypedArray<Font> fallback_custom = { default_font_msdf };
custom_font->set_fallbacks(fallback_custom);
}
default_fc_msdf->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
default_fc_msdf->set_base_font(default_font_msdf);
}
default_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
default_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
default_fc_msdf->set_variation_opentype(default_fc_opentype);
Ref<FontVariation> bold_fc;
bold_fc.instantiate();
if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps);
{
TypedArray<Font> fallback_custom = { default_font_bold };
custom_font->set_fallbacks(fallback_custom);
}
bold_fc->set_base_font(custom_font);
} else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps);
{
TypedArray<Font> fallback_custom = { default_font_bold };
custom_font->set_fallbacks(fallback_custom);
}
bold_fc->set_base_font(custom_font);
bold_fc->set_variation_embolden(embolden_strength);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", "");
bold_fc->set_base_font(default_font_bold);
}
bold_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
bold_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
Dictionary bold_fc_opentype;
bold_fc_opentype["weight"] = 700;
bold_fc->set_variation_opentype(bold_fc_opentype);
Ref<FontVariation> bold_fc_msdf;
bold_fc_msdf.instantiate();
if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, font_allow_msdf);
{
TypedArray<Font> fallback_custom = { default_font_bold_msdf };
custom_font->set_fallbacks(fallback_custom);
}
bold_fc_msdf->set_base_font(custom_font);
} else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps, font_allow_msdf);
{
TypedArray<Font> fallback_custom = { default_font_bold_msdf };
custom_font->set_fallbacks(fallback_custom);
}
bold_fc_msdf->set_base_font(custom_font);
bold_fc_msdf->set_variation_embolden(embolden_strength);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", "");
bold_fc_msdf->set_base_font(default_font_bold_msdf);
}
bold_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
bold_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
bold_fc_msdf->set_variation_opentype(bold_fc_opentype);
Ref<FontVariation> mono_fc;
mono_fc.instantiate();
if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) {
Ref<FontFile> custom_font = load_external_font(custom_font_path_source, font_mono_hinting, font_antialiasing, true, font_subpixel_positioning, font_disable_embedded_bitmaps);
{
TypedArray<Font> fallback_custom = { default_font_mono };
custom_font->set_fallbacks(fallback_custom);
}
mono_fc->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/code_font", "");
mono_fc->set_base_font(default_font_mono);
}
mono_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
mono_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
Ref<FontVariation> mono_other_fc = mono_fc->duplicate();
// Enable contextual alternates (coding ligatures) and custom features for the source editor font.
int ot_mode = EDITOR_GET("interface/editor/code_font_contextual_ligatures");
switch (ot_mode) {
case 1: { // Disable ligatures.
Dictionary ftrs;
ftrs[TS->name_to_tag("calt")] = 0;
mono_fc->set_opentype_features(ftrs);
} break;
case 2: { // Custom.
Vector<String> subtag = String(EDITOR_GET("interface/editor/code_font_custom_opentype_features")).split(",");
Dictionary ftrs;
for (int i = 0; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=");
if (subtag_a.size() == 2) {
ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
} else if (subtag_a.size() == 1) {
ftrs[TS->name_to_tag(subtag_a[0])] = 1;
}
}
mono_fc->set_opentype_features(ftrs);
} break;
default: { // Enabled.
Dictionary ftrs;
ftrs[TS->name_to_tag("calt")] = 1;
mono_fc->set_opentype_features(ftrs);
} break;
}
{
// Disable contextual alternates (coding ligatures).
Dictionary ftrs;
ftrs[TS->name_to_tag("calt")] = 0;
mono_other_fc->set_opentype_features(ftrs);
}
// Use fake bold/italics to style the editor log's `print_rich()` output.
// Use stronger embolden strength to make bold easier to distinguish from regular text.
Ref<FontVariation> mono_other_fc_bold = mono_other_fc->duplicate();
mono_other_fc_bold->set_variation_embolden(0.8);
Ref<FontVariation> mono_other_fc_italic = mono_other_fc->duplicate();
mono_other_fc_italic->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
Ref<FontVariation> mono_other_fc_bold_italic = mono_other_fc->duplicate();
mono_other_fc_bold_italic->set_variation_embolden(0.8);
mono_other_fc_bold_italic->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
Ref<FontVariation> mono_other_fc_mono = mono_other_fc->duplicate();
// Use a different font style to distinguish `[code]` in rich prints.
// This emulates the "faint" styling used in ANSI escape codes by using a slightly thinner font.
mono_other_fc_mono->set_variation_embolden(-0.25);
mono_other_fc_mono->set_variation_transform(Transform2D(1.0, 0.1, 0.0, 1.0, 0.0, 0.0));
Ref<FontVariation> italic_fc = default_fc->duplicate();
italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
Ref<FontVariation> bold_italic_fc = bold_fc->duplicate();
bold_italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
// Setup theme.
p_theme->set_default_font(default_fc); // Default theme font config.
p_theme->set_default_font_size(default_font_size);
// Main font.
p_theme->set_font("main", EditorStringName(EditorFonts), default_fc);
p_theme->set_font("main_msdf", EditorStringName(EditorFonts), default_fc_msdf);
p_theme->set_font_size("main_size", EditorStringName(EditorFonts), default_font_size);
p_theme->set_font("bold", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font("main_bold_msdf", EditorStringName(EditorFonts), bold_fc_msdf);
p_theme->set_font_size("bold_size", EditorStringName(EditorFonts), default_font_size);
p_theme->set_font("italic", EditorStringName(EditorFonts), italic_fc);
p_theme->set_font_size("italic_size", EditorStringName(EditorFonts), default_font_size);
// Title font.
p_theme->set_font("title", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font_size("title_size", EditorStringName(EditorFonts), default_font_size + 1 * EDSCALE);
p_theme->set_type_variation("MainScreenButton", "Button");
p_theme->set_font(SceneStringName(font), "MainScreenButton", bold_fc);
p_theme->set_font_size(SceneStringName(font_size), "MainScreenButton", default_font_size + 2 * EDSCALE);
// Labels.
p_theme->set_font(SceneStringName(font), "Label", default_fc);
p_theme->set_type_variation("HeaderSmall", "Label");
p_theme->set_font(SceneStringName(font), "HeaderSmall", bold_fc);
p_theme->set_font_size(SceneStringName(font_size), "HeaderSmall", default_font_size);
p_theme->set_type_variation("HeaderMedium", "Label");
p_theme->set_font(SceneStringName(font), "HeaderMedium", bold_fc);
p_theme->set_font_size(SceneStringName(font_size), "HeaderMedium", default_font_size + 1 * EDSCALE);
p_theme->set_type_variation("HeaderLarge", "Label");
p_theme->set_font(SceneStringName(font), "HeaderLarge", bold_fc);
p_theme->set_font_size(SceneStringName(font_size), "HeaderLarge", default_font_size + 3 * EDSCALE);
p_theme->set_font("normal_font", "RichTextLabel", default_fc);
p_theme->set_font("bold_font", "RichTextLabel", bold_fc);
p_theme->set_font("italics_font", "RichTextLabel", italic_fc);
p_theme->set_font("bold_italics_font", "RichTextLabel", bold_italic_fc);
// Documentation fonts
p_theme->set_font_size("doc_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
p_theme->set_font("doc", EditorStringName(EditorFonts), default_fc);
p_theme->set_font("doc_bold", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font("doc_italic", EditorStringName(EditorFonts), italic_fc);
p_theme->set_font_size("doc_title_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE);
p_theme->set_font("doc_title", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font_size("doc_source_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE);
p_theme->set_font("doc_source", EditorStringName(EditorFonts), mono_fc);
p_theme->set_font_size("doc_keyboard_size", EditorStringName(EditorFonts), (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE);
p_theme->set_font("doc_keyboard", EditorStringName(EditorFonts), mono_fc);
// Ruler font
p_theme->set_font_size("rulers_size", EditorStringName(EditorFonts), 8 * EDSCALE);
p_theme->set_font("rulers", EditorStringName(EditorFonts), default_fc);
// Rotation widget font
p_theme->set_font_size("rotation_control_size", EditorStringName(EditorFonts), 13 * EDSCALE);
p_theme->set_font("rotation_control", EditorStringName(EditorFonts), default_fc);
// Code font
p_theme->set_font_size("source_size", EditorStringName(EditorFonts), int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE);
p_theme->set_font("source", EditorStringName(EditorFonts), mono_fc);
p_theme->set_font_size("expression_size", EditorStringName(EditorFonts), (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE);
p_theme->set_font("expression", EditorStringName(EditorFonts), mono_other_fc);
p_theme->set_font_size("output_source_size", EditorStringName(EditorFonts), int(EDITOR_GET("run/output/font_size")) * EDSCALE);
p_theme->set_font("output_source", EditorStringName(EditorFonts), mono_other_fc);
p_theme->set_font("output_source_bold", EditorStringName(EditorFonts), mono_other_fc_bold);
p_theme->set_font("output_source_italic", EditorStringName(EditorFonts), mono_other_fc_italic);
p_theme->set_font("output_source_bold_italic", EditorStringName(EditorFonts), mono_other_fc_bold_italic);
p_theme->set_font("output_source_mono", EditorStringName(EditorFonts), mono_other_fc_mono);
p_theme->set_font_size("status_source_size", EditorStringName(EditorFonts), default_font_size);
p_theme->set_font("status_source", EditorStringName(EditorFonts), mono_other_fc);
}

View File

@@ -0,0 +1,35 @@
/**************************************************************************/
/* editor_fonts.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "scene/resources/theme.h"
void editor_register_fonts(const Ref<Theme> &p_theme);

View File

@@ -0,0 +1,251 @@
/**************************************************************************/
/* editor_icons.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_icons.h"
#include "editor/editor_string_names.h"
#include "editor/themes/editor_color_map.h"
#include "editor/themes/editor_icons.gen.h"
#include "editor/themes/editor_scale.h"
#include "scene/resources/dpi_texture.h"
#include "scene/resources/image_texture.h"
#include "modules/svg/image_loader_svg.h"
void editor_configure_icons(bool p_dark_theme) {
if (p_dark_theme) {
ImageLoaderSVG::set_forced_color_map(HashMap<Color, Color>());
} else {
ImageLoaderSVG::set_forced_color_map(EditorColorMap::get_color_conversion_map());
}
}
// See also `generate_icon()` in `scene/theme/default_theme.cpp`.
Ref<DPITexture> editor_generate_icon(int p_index, float p_scale, float p_saturation, const Dictionary &p_convert_colors = Dictionary()) {
return DPITexture::create_from_string(editor_icons_sources[p_index], p_scale, p_saturation, p_convert_colors);
}
float get_gizmo_handle_scale(const String &p_gizmo_handle_name, float p_gizmo_handle_scale) {
if (p_gizmo_handle_scale > 1.0f) {
// The names of the icons that require additional scaling.
static HashSet<StringName> gizmo_to_scale;
if (gizmo_to_scale.is_empty()) {
gizmo_to_scale.insert("EditorHandle");
gizmo_to_scale.insert("EditorHandleAdd");
gizmo_to_scale.insert("EditorHandleDisabled");
gizmo_to_scale.insert("EditorCurveHandle");
gizmo_to_scale.insert("EditorPathSharpHandle");
gizmo_to_scale.insert("EditorPathSmoothHandle");
gizmo_to_scale.insert("EditorControlAnchor");
}
if (gizmo_to_scale.has(p_gizmo_handle_name)) {
return EDSCALE * p_gizmo_handle_scale;
}
}
return EDSCALE;
}
void editor_register_icons(const Ref<Theme> &p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, float p_gizmo_handle_scale) {
// Before we register the icons, we adjust their colors and saturation.
// Most icons follow the standard rules for color conversion to follow the editor
// theme's polarity (dark/light). We also adjust the saturation for most icons,
// following the editor setting.
// Some icons are excluded from this conversion, and instead use the configured
// accent color to replace their innate accent color to match the editor theme.
// And then some icons are completely excluded from the conversion.
// Standard color conversion map.
Dictionary color_conversion_map_light;
Dictionary color_conversion_map_dark;
// Icons by default are set up for the dark theme, so if the theme is light,
// we apply the dark-to-light color conversion map.
for (KeyValue<Color, Color> &E : EditorColorMap::get_color_conversion_map()) {
color_conversion_map_light[E.key] = E.value;
}
// These colors should be converted even if we are using a dark theme.
const Color error_color = p_theme->get_color(SNAME("error_color"), EditorStringName(Editor));
const Color success_color = p_theme->get_color(SNAME("success_color"), EditorStringName(Editor));
const Color warning_color = p_theme->get_color(SNAME("warning_color"), EditorStringName(Editor));
color_conversion_map_dark[Color::html("#ff5f5f")] = error_color;
color_conversion_map_dark[Color::html("#5fff97")] = success_color;
color_conversion_map_dark[Color::html("#ffdd65")] = warning_color;
color_conversion_map_light[Color::html("#ff5f5f")] = error_color;
color_conversion_map_light[Color::html("#5fff97")] = success_color;
color_conversion_map_light[Color::html("#ffdd65")] = warning_color;
Dictionary color_conversion_map = p_dark_theme ? color_conversion_map_dark : color_conversion_map_light;
// The names of the icons used in native menus.
HashSet<StringName> native_menu_icons;
native_menu_icons.insert("HelpSearch");
native_menu_icons.insert("ActionCopy");
native_menu_icons.insert("Heart");
native_menu_icons.insert("PackedScene");
native_menu_icons.insert("FileAccess");
native_menu_icons.insert("Folder");
native_menu_icons.insert("AnimationTrackList");
native_menu_icons.insert("Object");
native_menu_icons.insert("History");
// The names of the icons to exclude from the standard color conversion.
HashSet<StringName> conversion_exceptions = EditorColorMap::get_color_conversion_exceptions();
// The names of the icons to exclude when adjusting for saturation.
HashSet<StringName> saturation_exceptions;
saturation_exceptions.insert("DefaultProjectIcon");
saturation_exceptions.insert("Godot");
saturation_exceptions.insert("Logo");
// Accent color conversion map.
// It is used on some icons (checkbox, radio, toggle, etc.), regardless of the dark
// or light mode.
Dictionary accent_color_map;
HashSet<StringName> accent_color_icons;
const Color accent_color = p_theme->get_color(SNAME("accent_color"), EditorStringName(Editor));
accent_color_map[Color::html("699ce8")] = accent_color;
if (accent_color.get_luminance() > 0.75) {
accent_color_map[Color::html("ffffff")] = Color(0.2, 0.2, 0.2);
}
accent_color_icons.insert("GuiChecked");
accent_color_icons.insert("GuiRadioChecked");
accent_color_icons.insert("GuiIndeterminate");
accent_color_icons.insert("GuiToggleOn");
accent_color_icons.insert("GuiToggleOnMirrored");
accent_color_icons.insert("PlayOverlay");
// Generate icons.
{
for (int i = 0; i < editor_icons_count; i++) {
const String &editor_icon_name = editor_icons_names[i];
if (native_menu_icons.has(editor_icon_name)) {
float saturation = p_icon_saturation;
if (saturation_exceptions.has(editor_icon_name)) {
saturation = 1.0;
}
Ref<DPITexture> icon_dark = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_dark);
Ref<DPITexture> icon_light = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_light);
p_theme->set_icon(editor_icon_name + "Dark", EditorStringName(EditorIcons), icon_dark);
p_theme->set_icon(editor_icon_name + "Light", EditorStringName(EditorIcons), icon_light);
p_theme->set_icon(editor_icon_name, EditorStringName(EditorIcons), p_dark_theme ? icon_dark : icon_light);
} else {
Ref<DPITexture> icon;
if (accent_color_icons.has(editor_icon_name)) {
icon = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), 1.0, accent_color_map);
} else {
float saturation = p_icon_saturation;
if (saturation_exceptions.has(editor_icon_name)) {
saturation = 1.0;
}
if (conversion_exceptions.has(editor_icon_name)) {
icon = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation);
} else {
icon = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map);
}
}
p_theme->set_icon(editor_icon_name, EditorStringName(EditorIcons), icon);
}
}
}
// Generate thumbnail icons with the given thumbnail size.
// See editor\icons\editor_icons_builders.py for the code that determines which icons are thumbnails.
if (p_thumb_size >= 64) {
const float scale = (float)p_thumb_size / 64.0 * EDSCALE;
for (int i = 0; i < editor_bg_thumbs_count; i++) {
const int index = editor_bg_thumbs_indices[i];
Ref<DPITexture> icon;
if (accent_color_icons.has(editor_icons_names[index])) {
icon = editor_generate_icon(index, scale, 1.0, accent_color_map);
} else {
float saturation = p_icon_saturation;
if (saturation_exceptions.has(editor_icons_names[index])) {
saturation = 1.0;
}
if (conversion_exceptions.has(editor_icons_names[index])) {
icon = editor_generate_icon(index, scale, saturation);
} else {
icon = editor_generate_icon(index, scale, saturation, color_conversion_map);
}
}
p_theme->set_icon(editor_icons_names[index], EditorStringName(EditorIcons), icon);
}
} else {
const float scale = (float)p_thumb_size / 32.0 * EDSCALE;
for (int i = 0; i < editor_md_thumbs_count; i++) {
const int index = editor_md_thumbs_indices[i];
Ref<DPITexture> icon;
if (accent_color_icons.has(editor_icons_names[index])) {
icon = editor_generate_icon(index, scale, 1.0, accent_color_map);
} else {
float saturation = p_icon_saturation;
if (saturation_exceptions.has(editor_icons_names[index])) {
saturation = 1.0;
}
if (conversion_exceptions.has(editor_icons_names[index])) {
icon = editor_generate_icon(index, scale, saturation);
} else {
icon = editor_generate_icon(index, scale, saturation, color_conversion_map);
}
}
p_theme->set_icon(editor_icons_names[index], EditorStringName(EditorIcons), icon);
}
}
}
void editor_copy_icons(const Ref<Theme> &p_theme, const Ref<Theme> &p_old_theme) {
for (int i = 0; i < editor_icons_count; i++) {
p_theme->set_icon(editor_icons_names[i], EditorStringName(EditorIcons), p_old_theme->get_icon(editor_icons_names[i], EditorStringName(EditorIcons)));
}
}
// Returns the SVG code for the default project icon.
String get_default_project_icon() {
// FIXME: This icon can probably be predefined in editor_icons.gen.h so we don't have to look up.
for (int i = 0; i < editor_icons_count; i++) {
if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) {
return String(editor_icons_sources[i]);
}
}
return String();
}

View File

@@ -0,0 +1,39 @@
/**************************************************************************/
/* editor_icons.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "scene/resources/theme.h"
void editor_configure_icons(bool p_dark_theme);
void editor_register_icons(const Ref<Theme> &p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, float p_gizmo_handle_scale);
void editor_copy_icons(const Ref<Theme> &p_theme, const Ref<Theme> &p_old_theme);
String get_default_project_icon();

View File

@@ -0,0 +1,41 @@
/**************************************************************************/
/* editor_scale.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_scale.h"
float EditorScale::_scale = 1.0f;
void EditorScale::set_scale(float p_scale) {
_scale = p_scale;
}
float EditorScale::get_scale() {
return _scale;
}

View File

@@ -0,0 +1,41 @@
/**************************************************************************/
/* editor_scale.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
class EditorScale {
static float _scale;
public:
static void set_scale(float p_scale);
static float get_scale();
};
#define EDSCALE (EditorScale::get_scale())

View File

@@ -0,0 +1,131 @@
/**************************************************************************/
/* editor_theme.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_theme.h"
#include "editor/editor_string_names.h"
#include "scene/theme/theme_db.h"
Vector<StringName> EditorTheme::editor_theme_types;
// TODO: Refactor these and corresponding Theme methods to use the bool get_xxx(r_value) pattern internally.
// Keep in sync with Theme::get_color.
Color EditorTheme::get_color(const StringName &p_name, const StringName &p_theme_type) const {
if (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)) {
return color_map[p_theme_type][p_name];
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme color '%s' in '%s'.", p_name, p_theme_type));
}
return Color();
}
}
// Keep in sync with Theme::get_constant.
int EditorTheme::get_constant(const StringName &p_name, const StringName &p_theme_type) const {
if (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)) {
return constant_map[p_theme_type][p_name];
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme constant '%s' in '%s'.", p_name, p_theme_type));
}
return 0;
}
}
// Keep in sync with Theme::get_font.
Ref<Font> EditorTheme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
return font_map[p_theme_type][p_name];
} else if (has_default_font()) {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
}
return default_font;
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
}
return ThemeDB::get_singleton()->get_fallback_font();
}
}
// Keep in sync with Theme::get_font_size.
int EditorTheme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
return font_size_map[p_theme_type][p_name];
} else if (has_default_font_size()) {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
}
return default_font_size;
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
}
return ThemeDB::get_singleton()->get_fallback_font_size();
}
}
// Keep in sync with Theme::get_icon.
Ref<Texture2D> EditorTheme::get_icon(const StringName &p_name, const StringName &p_theme_type) const {
if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
return icon_map[p_theme_type][p_name];
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme icon '%s' in '%s'.", p_name, p_theme_type));
}
return ThemeDB::get_singleton()->get_fallback_icon();
}
}
// Keep in sync with Theme::get_stylebox.
Ref<StyleBox> EditorTheme::get_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
return style_map[p_theme_type][p_name];
} else {
if (editor_theme_types.has(p_theme_type)) {
WARN_PRINT(vformat("Trying to access a non-existing editor theme stylebox '%s' in '%s'.", p_name, p_theme_type));
}
return ThemeDB::get_singleton()->get_fallback_stylebox();
}
}
void EditorTheme::initialize() {
editor_theme_types.append(EditorStringName(Editor));
editor_theme_types.append(EditorStringName(EditorFonts));
editor_theme_types.append(EditorStringName(EditorIcons));
editor_theme_types.append(EditorStringName(EditorStyles));
}
void EditorTheme::finalize() {
editor_theme_types.clear();
}

View File

@@ -0,0 +1,63 @@
/**************************************************************************/
/* editor_theme.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "scene/resources/theme.h"
class EditorTheme : public Theme {
GDCLASS(EditorTheme, Theme);
static Vector<StringName> editor_theme_types;
uint32_t generated_hash = 0;
uint32_t generated_fonts_hash = 0;
uint32_t generated_icons_hash = 0;
public:
virtual Color get_color(const StringName &p_name, const StringName &p_theme_type) const override;
virtual int get_constant(const StringName &p_name, const StringName &p_theme_type) const override;
virtual Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const override;
virtual int get_font_size(const StringName &p_name, const StringName &p_theme_type) const override;
virtual Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const override;
virtual Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const override;
void set_generated_hash(uint32_t p_hash) { generated_hash = p_hash; }
uint32_t get_generated_hash() const { return generated_hash; }
void set_generated_fonts_hash(uint32_t p_hash) { generated_fonts_hash = p_hash; }
uint32_t get_generated_fonts_hash() const { return generated_fonts_hash; }
void set_generated_icons_hash(uint32_t p_hash) { generated_icons_hash = p_hash; }
uint32_t get_generated_icons_hash() const { return generated_icons_hash; }
static void initialize();
static void finalize();
};

View File

@@ -0,0 +1,21 @@
"""Functions used to generate source files during build time"""
import os
import methods
def make_fonts_header(target, source, env):
with methods.generated_wrapper(str(target[0])) as file:
for src in map(str, source):
# Saving uncompressed, since FreeType will reference from memory pointer.
buffer = methods.get_buffer(src)
name = os.path.splitext(os.path.basename(src))[0]
file.write(f"""\
inline constexpr int _font_{name}_size = {len(buffer)};
inline constexpr unsigned char _font_{name}[] = {{
{methods.format_buffer(buffer, 1)}
}};
""")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,173 @@
/**************************************************************************/
/* editor_theme_manager.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "editor/themes/editor_theme.h"
#include "scene/resources/style_box_flat.h"
class EditorThemeManager {
static int benchmark_run;
static inline bool outdated_cache = false;
static inline bool outdated_cache_dirty = true;
static String get_benchmark_key();
enum ColorMode {
AUTO_COLOR,
DARK_COLOR,
LIGHT_COLOR,
};
struct ThemeConfiguration {
// Basic properties.
String preset;
String spacing_preset;
Color base_color;
Color accent_color;
float contrast = 1.0;
float icon_saturation = 1.0;
// Extra properties.
int base_spacing = 4;
int extra_spacing = 0;
Size2 dialogs_buttons_min_size = Size2(105, 34);
int border_width = 0;
int corner_radius = 3;
bool draw_extra_borders = false;
float relationship_line_opacity = 1.0;
int thumb_size = 16;
int class_icon_size = 16;
bool enable_touch_optimizations = false;
float gizmo_handle_scale = 1.0;
int color_picker_button_height = 28;
float subresource_hue_tint = 0.0;
float default_contrast = 1.0;
// Generated properties.
bool dark_theme = false;
int base_margin = 4;
int increased_margin = 4;
int separation_margin = 4;
int popup_margin = 12;
int window_border_margin = 8;
int top_bar_separation = 8;
int forced_even_separation = 0;
Color mono_color;
Color dark_color_1;
Color dark_color_2;
Color dark_color_3;
Color contrast_color_1;
Color contrast_color_2;
Color highlight_color;
Color highlight_disabled_color;
Color success_color;
Color warning_color;
Color error_color;
Color extra_border_color_1;
Color extra_border_color_2;
Color font_color;
Color font_focus_color;
Color font_hover_color;
Color font_pressed_color;
Color font_hover_pressed_color;
Color font_disabled_color;
Color font_readonly_color;
Color font_placeholder_color;
Color font_outline_color;
Color icon_normal_color;
Color icon_focus_color;
Color icon_hover_color;
Color icon_pressed_color;
Color icon_disabled_color;
Color shadow_color;
Color selection_color;
Color disabled_border_color;
Color disabled_bg_color;
Color separator_color;
Ref<StyleBoxFlat> base_style;
Ref<StyleBoxEmpty> base_empty_style;
Ref<StyleBoxFlat> button_style;
Ref<StyleBoxFlat> button_style_disabled;
Ref<StyleBoxFlat> button_style_focus;
Ref<StyleBoxFlat> button_style_pressed;
Ref<StyleBoxFlat> button_style_hover;
Ref<StyleBoxFlat> circle_style_focus;
Ref<StyleBoxFlat> popup_style;
Ref<StyleBoxFlat> popup_border_style;
Ref<StyleBoxFlat> window_style;
Ref<StyleBoxFlat> dialog_style;
Ref<StyleBoxFlat> panel_container_style;
Ref<StyleBoxFlat> content_panel_style;
Ref<StyleBoxFlat> tree_panel_style;
Vector2 widget_margin;
uint32_t hash();
uint32_t hash_fonts();
uint32_t hash_icons();
};
static Ref<EditorTheme> _create_base_theme(const Ref<EditorTheme> &p_old_theme = nullptr);
static ThemeConfiguration _create_theme_config(const Ref<EditorTheme> &p_theme);
static void _create_shared_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_standard_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_text_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _populate_visual_shader_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config);
static void _reset_dirty_flag();
public:
static Ref<EditorTheme> generate_theme(const Ref<EditorTheme> &p_old_theme = nullptr);
static bool is_generated_theme_outdated();
static bool is_dark_theme();
static void initialize();
static void finalize();
};