mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-01 02:30:25 +03:00
Add configurable OpenType font features to text rendering:
Support explicit liga, calt, clig, and dlig shaping features and include text hints in layout caching, measurement, drawing, and character position calculations. Propagate scene-wide font feature defaults through UI text producers, with granular widget overrides and recursive cache invalidation. Update UICodeEditor and UIConsole to use shaped positioning when font features are enabled, including with monospaced fonts. Add separate UI and editor font feature settings to ecode, persist them as comma-separated OpenType tags, and apply changes immediately. Add localized menu labels, reusable Text feature conversion helpers, and regression coverage for shaping, positioning, propagation, and parsing.
This commit is contained in:
@@ -145,6 +145,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
|
||||
editor.horizontalScrollbar = ini.getValueB( "editor", "horizontal_scrollbar", true );
|
||||
editor.openDocumentsInMainSplit =
|
||||
ini.getValueB( "editor", "open_documents_in_main_split", false );
|
||||
editor.fontFeatures =
|
||||
Graphics::Text::fontFeaturesFromString( ini.getValue( "editor", "font_features" ) );
|
||||
ui.fontSize = ini.getValue( "ui", "font_size", "11dp" );
|
||||
ui.panelFontSize = ini.getValue( "ui", "panel_font_size", "11dp" );
|
||||
ui.showSidePanel = ini.getValueB( "ui", "show_side_panel", true );
|
||||
@@ -169,6 +171,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
|
||||
FontTrueType::fontHintingFromString( ini.getValue( "ui", "font_hinting", "full" ) );
|
||||
ui.fontAntialiasing = FontTrueType::fontAntialiasingFromString(
|
||||
ini.getValue( "ui", "font_antialiasing", "grayscale" ) );
|
||||
ui.fontFeatures =
|
||||
Graphics::Text::fontFeaturesFromString( ini.getValue( "ui", "font_features" ) );
|
||||
ui.editorFontInInputFields = ini.getValueB( "ui", "editor_font_in_input_fields", true );
|
||||
|
||||
doc.trimTrailingWhitespaces = ini.getValueB( "document", "trim_trailing_whitespaces", false );
|
||||
@@ -350,6 +354,8 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
|
||||
ini.setValueB( "editor", "vertical_scrollbar", editor.verticalScrollbar );
|
||||
ini.setValueB( "editor", "horizontal_scrollbar", editor.horizontalScrollbar );
|
||||
ini.setValueB( "editor", "open_documents_in_main_split", editor.openDocumentsInMainSplit );
|
||||
ini.setValue( "editor", "font_features",
|
||||
Graphics::Text::fontFeaturesToString( editor.fontFeatures ) );
|
||||
ini.setValue( "editor", "font_size", editor.fontSize.toString() );
|
||||
|
||||
ini.setValue( "ui", "font_size", ui.fontSize.toString() );
|
||||
@@ -374,6 +380,7 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
|
||||
ini.setValue( "ui", "font_hinting", FontTrueType::fontHintingToString( ui.fontHinting ) );
|
||||
ini.setValue( "ui", "font_antialiasing",
|
||||
FontTrueType::fontAntialiasingToString( ui.fontAntialiasing ) );
|
||||
ini.setValue( "ui", "font_features", Graphics::Text::fontFeaturesToString( ui.fontFeatures ) );
|
||||
ini.setValue( "screenshots", "save_path", screenshot.savePath );
|
||||
ini.setValue( "screenshots", "filename_pattern", screenshot.filenamePattern );
|
||||
ini.setValue( "screenshots", "save_format", screenshot.saveFormat );
|
||||
|
||||
@@ -81,6 +81,7 @@ struct UIConfig {
|
||||
std::string language;
|
||||
FontHinting fontHinting{ FontHinting::Full };
|
||||
FontAntialiasing fontAntialiasing{ FontAntialiasing::Grayscale };
|
||||
Uint32 fontFeatures{ 0 };
|
||||
};
|
||||
|
||||
struct WindowStateConfig {
|
||||
@@ -107,6 +108,7 @@ struct CodeEditorConfig {
|
||||
std::string colorScheme{ "ecode" };
|
||||
StyleSheetLength fontSize{ 11, StyleSheetLength::Dp };
|
||||
StyleSheetLength lineSpacing{ 0, StyleSheetLength::Dp };
|
||||
Uint32 fontFeatures{ 0 };
|
||||
bool showLineNumbers{ true };
|
||||
bool showWhiteSpaces{ true };
|
||||
bool showLineEndings{ false };
|
||||
|
||||
@@ -1981,6 +1981,7 @@ void App::setTheme( const std::string& path ) {
|
||||
->add( theme );
|
||||
|
||||
mUISceneNode->setTheme( theme.get() );
|
||||
mUISceneNode->setDefaultTextHints( mConfig.ui.fontFeatures );
|
||||
|
||||
mUISceneNode->getRoot()->addClass( "appbackground" );
|
||||
|
||||
@@ -2986,6 +2987,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
|
||||
editor->setFoldDrawable( findIcon( "chevron-down", PixelDensity::dpToPxI( 12 ) ) );
|
||||
editor->setFoldedDrawable( findIcon( "chevron-right", PixelDensity::dpToPxI( 12 ) ) );
|
||||
editor->setTabStops( mConfig.doc.tabStops );
|
||||
editor->setLigatureFeatures( mConfig.editor.fontFeatures );
|
||||
editor->setEnableInlineColorBoxes( config.inlineColorBoxes );
|
||||
|
||||
doc.setAutoCloseBrackets( !mConfig.editor.autoCloseBrackets.empty() );
|
||||
|
||||
@@ -3316,6 +3316,64 @@ UIMenu* SettingsMenu::createFontAntiAliasingMenu() {
|
||||
|
||||
UIMenu* SettingsMenu::createFontsMenu() {
|
||||
mFontsMenu = UIPopUpMenu::New();
|
||||
const auto createFontFeaturesMenu = [this]( bool editorFeatures ) {
|
||||
auto* menu = UIPopUpMenu::New();
|
||||
const Uint32 features = editorFeatures ? mApp->getConfig().editor.fontFeatures
|
||||
: mApp->getConfig().ui.fontFeatures;
|
||||
menu->addCheckBox( i18n( "standard_ligatures", "Standard Ligatures (liga)" ),
|
||||
features & TextHints::StandardLigatures )
|
||||
->setTooltipText(
|
||||
i18n( "standard_ligatures_desc",
|
||||
"Typographic combinations such as fi, fl, and ffi, depending on the font." ) )
|
||||
->setId( "liga" );
|
||||
menu->addCheckBox( i18n( "contextual_alternates", "Contextual Alternates (calt)" ),
|
||||
features & TextHints::ContextualAlternates )
|
||||
->setTooltipText(
|
||||
i18n( "contextual_alternates_desc",
|
||||
"Context-dependent alternatives, including many programming ligatures." ) )
|
||||
->setId( "calt" );
|
||||
menu->addCheckBox( i18n( "contextual_ligatures", "Contextual Ligatures (clig)" ),
|
||||
features & TextHints::ContextualLigatures )
|
||||
->setTooltipText(
|
||||
i18n( "contextual_ligatures_desc",
|
||||
"Ligatures applied in specific contexts to improve readability." ) )
|
||||
->setId( "clig" );
|
||||
menu->addCheckBox( i18n( "discretionary_ligatures", "Discretionary Ligatures (dlig)" ),
|
||||
features & TextHints::DiscretionaryLigatures )
|
||||
->setTooltipText(
|
||||
i18n( "discretionary_ligatures_desc",
|
||||
"Optional decorative or stylistic ligatures provided by the font." ) )
|
||||
->setId( "dlig" );
|
||||
menu->on( Event::OnItemClicked, [this, editorFeatures]( const Event* event ) {
|
||||
if ( !event->getNode()->isType( UI_TYPE_MENUCHECKBOX ) )
|
||||
return;
|
||||
auto* item = event->getNode()->asType<UIMenuCheckBox>();
|
||||
const String& id = item->getId();
|
||||
const Uint32 feature = id == "liga" ? TextHints::StandardLigatures
|
||||
: id == "calt" ? TextHints::ContextualAlternates
|
||||
: id == "clig" ? TextHints::ContextualLigatures
|
||||
: id == "dlig" ? TextHints::DiscretionaryLigatures
|
||||
: 0;
|
||||
if ( feature == 0 )
|
||||
return;
|
||||
Uint32& features = editorFeatures ? mApp->getConfig().editor.fontFeatures
|
||||
: mApp->getConfig().ui.fontFeatures;
|
||||
if ( item->isActive() )
|
||||
features |= feature;
|
||||
else
|
||||
features &= ~feature;
|
||||
if ( editorFeatures ) {
|
||||
mSplitter->forEachEditor( [features]( UICodeEditor* editor ) {
|
||||
editor->setLigatureFeatures( features );
|
||||
} );
|
||||
} else {
|
||||
mApp->getUISceneNode()->setDefaultTextHints( features );
|
||||
}
|
||||
} );
|
||||
return menu;
|
||||
};
|
||||
auto* uiFontFeaturesMenu = createFontFeaturesMenu( false );
|
||||
auto* editorFontFeaturesMenu = createFontFeaturesMenu( true );
|
||||
mFontsMenu->addSubMenu( i18n( "ui_font_hint", "Font Hint" ), findIcon( "font-size" ),
|
||||
createFontHintMenu() );
|
||||
mFontsMenu->addSubMenu( i18n( "ui_font_antialiasing", "Font Anti-Aliasing" ),
|
||||
@@ -3325,10 +3383,14 @@ UIMenu* SettingsMenu::createFontsMenu() {
|
||||
mFontsMenu
|
||||
->add( i18n( "ui_font_and_size_ellipsis", "UI Font & Size..." ), findIcon( "font-size" ) )
|
||||
->setId( "sans-serif-font" );
|
||||
mFontsMenu->addSubMenu( i18n( "ui_font_features", "UI Font Features" ), findIcon( "font-size" ),
|
||||
uiFontFeaturesMenu );
|
||||
mFontsMenu
|
||||
->add( i18n( "editor_font_and_size_ellipsis", "Editor Font & Size..." ),
|
||||
findIcon( "font-size" ) )
|
||||
->setId( "editor-font" );
|
||||
mFontsMenu->addSubMenu( i18n( "editor_font_features", "Editor Font Features" ),
|
||||
findIcon( "font-size" ), editorFontFeaturesMenu );
|
||||
mFontsMenu
|
||||
->add( i18n( "terminal_font_and_size_ellipsis", "Terminal Font & Size..." ),
|
||||
findIcon( "font-size" ) )
|
||||
|
||||
Reference in New Issue
Block a user