Use font list (#269)

* add icons

* place text vertically center in qsynedit

* use font list
This commit is contained in:
Cyano Hao 2024-03-13 19:17:25 +08:00 committed by GitHub
parent 19eeb5a1f8
commit e67e329ef1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 615 additions and 474 deletions

View File

@ -204,6 +204,7 @@ SOURCES += \
systemconsts.cpp \ systemconsts.cpp \
utils.cpp \ utils.cpp \
utils/escape.cpp \ utils/escape.cpp \
utils/font.cpp \
utils/parsearg.cpp \ utils/parsearg.cpp \
widgets/coloredit.cpp \ widgets/coloredit.cpp \
widgets/compileargumentswidget.cpp \ widgets/compileargumentswidget.cpp \
@ -336,6 +337,7 @@ HEADERS += \
systemconsts.h \ systemconsts.h \
utils.h \ utils.h \
utils/escape.h \ utils/escape.h \
utils/font.h \
utils/parsearg.h \ utils/parsearg.h \
common.h \ common.h \
widgets/coloredit.h \ widgets/coloredit.h \

View File

@ -5258,7 +5258,7 @@ void Editor::applySettings()
QFont f=QFont(); QFont f=QFont();
f.setFamily(pSettings->editor().fontName()); f.setFamily(pSettings->editor().fontName());
f.setFamilies(pSettings->editor().fontFamilies()); f.setFamilies(pSettings->editor().fontFamiliesWithControlFont());
f.setPixelSize(pointToPixel(pSettings->editor().fontSize())); f.setPixelSize(pointToPixel(pSettings->editor().fontSize()));
f.setStyleStrategy(QFont::PreferAntialias); f.setStyleStrategy(QFont::PreferAntialias);
setFont(f); setFont(f);

View File

@ -97,6 +97,9 @@ void IconsManager::updateActionIcons(const QString& iconSet, int size)
mIconPixmaps.insert(ACTION_MISC_RENAME, createSVGIcon(iconFolder+"00Misc-11Rename.svg",size,size)); mIconPixmaps.insert(ACTION_MISC_RENAME, createSVGIcon(iconFolder+"00Misc-11Rename.svg",size,size));
mIconPixmaps.insert(ACTION_MISC_HELP, createSVGIcon(iconFolder+"00Misc-12Help.svg",size,size)); mIconPixmaps.insert(ACTION_MISC_HELP, createSVGIcon(iconFolder+"00Misc-12Help.svg",size,size));
mIconPixmaps.insert(ACTION_MISC_FILTER, createSVGIcon(iconFolder+"00Misc-13Filter.svg",size,size)); mIconPixmaps.insert(ACTION_MISC_FILTER, createSVGIcon(iconFolder+"00Misc-13Filter.svg",size,size));
mIconPixmaps.insert(ACTION_MISC_MOVEUP, createSVGIcon(iconFolder+"00Misc-14MoveUp.svg",size,size));
mIconPixmaps.insert(ACTION_MISC_MOVEDOWN, createSVGIcon(iconFolder+"00Misc-15MoveDown.svg",size,size));
mIconPixmaps.insert(ACTION_MISC_RESET, createSVGIcon(iconFolder+"00Misc-16Reset.svg",size,size));
mIconPixmaps.insert(ACTION_FILE_NEW, createSVGIcon(iconFolder+"01File-01New.svg",size,size)); mIconPixmaps.insert(ACTION_FILE_NEW, createSVGIcon(iconFolder+"01File-01New.svg",size,size));
mIconPixmaps.insert(ACTION_FILE_OPEN, createSVGIcon(iconFolder+"01File-02Open.svg",size,size)); mIconPixmaps.insert(ACTION_FILE_OPEN, createSVGIcon(iconFolder+"01File-02Open.svg",size,size));

View File

@ -113,6 +113,9 @@ public:
ACTION_MISC_RENAME, ACTION_MISC_RENAME,
ACTION_MISC_HELP, ACTION_MISC_HELP,
ACTION_MISC_FILTER, ACTION_MISC_FILTER,
ACTION_MISC_MOVEUP,
ACTION_MISC_MOVEDOWN,
ACTION_MISC_RESET,
ACTION_FILE_NEW, ACTION_FILE_NEW,
ACTION_FILE_OPEN, ACTION_FILE_OPEN,

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#90b9ff" stroke="#1f74fe" stroke-width="3" stroke-linejoin="round"/><path d="M16 28L24 20L32 28" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 512 B

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#90b9ff" stroke="#1f74fe" stroke-width="3" stroke-linejoin="round"/><path d="M16 20L24 28L32 20" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 512 B

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#90b9ff" stroke="#1f74fe" stroke-width="3" stroke-linejoin="round"/><path d="M18 14L17 19L21 20M18 18C21 15 27 15 30 18C33 21 33 27 30 30C27 33 21 33 18 30" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 572 B

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><rect x="6" y="6" width="36" height="36" rx="3" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="round"/><path d="M16 28L24 20L32 28" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><rect x="6" y="6" width="36" height="36" rx="3" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="round"/><path d="M16 20L24 28L32 20" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="35" height="35" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><rect x="6" y="6" width="36" height="36" rx="3" fill="none" stroke="#ffffff" stroke-width="3" stroke-linejoin="round"/><path d="M18 14L17 19L21 20M18 18C21 15 27 15 30 18C33 21 33 27 30 30C27 33 21 33 18 30" stroke="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 493 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path fill="#FFF200" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="m50 15 45 40v35L50 50 5 90V55Zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 186 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path fill="#FFF200" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="m50 85 45-40V10L50 50 5 10v35Zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 186 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path fill="#00ADEF" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M16 16a48 48 0 1 1 0 68l16-16a26 26 0 1 0 0-36l11 11H5V5Zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@ -20,6 +20,7 @@
#include <algorithm> #include <algorithm>
#include "utils.h" #include "utils.h"
#include "utils/escape.h" #include "utils/escape.h"
#include "utils/font.h"
#include "utils/parsearg.h" #include "utils/parsearg.h"
#include <QDir> #include <QDir>
#include "systemconsts.h" #include "systemconsts.h"
@ -669,65 +670,19 @@ void Settings::Editor::setEnableLigaturesSupport(bool newEnableLigaturesSupport)
mEnableLigaturesSupport = newEnableLigaturesSupport; mEnableLigaturesSupport = newEnableLigaturesSupport;
} }
const QString &Settings::Editor::fallbackFontName() const
{
return mFallbackFontName;
}
void Settings::Editor::setFallbackFontName(const QString &newFontName)
{
mFallbackFontName = newFontName;
}
const QString &Settings::Editor::fallbackFontName2() const
{
return mFallbackFontName2;
}
void Settings::Editor::setFallbackFontName2(const QString &newFontName)
{
mFallbackFontName2 = newFontName;
}
const QString &Settings::Editor::fallbackFontName3() const
{
return mFallbackFontName3;
}
void Settings::Editor::setFallbackFontName3(const QString &newFontName)
{
mFallbackFontName3 = newFontName;
}
bool Settings::Editor::useFallbackFont2() const {
return mUseFallbackFont2;
}
void Settings::Editor::setUseFallbackFont2(bool useFont) {
mUseFallbackFont2 = useFont;
}
bool Settings::Editor::useFallbackFont3() const {
return mUseFallbackFont3;
}
void Settings::Editor::setUseFallbackFont3(bool useFont) {
mUseFallbackFont3 = useFont;
}
QStringList Settings::Editor::fontFamilies() const QStringList Settings::Editor::fontFamilies() const
{ {
QStringList result { return mFontFamilies;
//QString("%1 [%2]").arg(mFontName,mFallbackFontName), }
mFontName,
mFallbackFontName, void Settings::Editor::setFontFamilies(const QStringList &newFontFamilies)
}; {
if (mUseFallbackFont2) mFontFamilies = newFontFamilies;
result.append(mFallbackFontName2); }
if (mUseFallbackFont3)
result.append(mFallbackFontName3); QStringList Settings::Editor::fontFamiliesWithControlFont() const
result.append("Red Panda Control"); {
return result; return mFontFamilies + QStringList{"Red Panda Control"};
} }
int Settings::Editor::mouseSelectionScrollSpeed() const int Settings::Editor::mouseSelectionScrollSpeed() const
@ -1300,16 +1255,6 @@ void Settings::Editor::setGutterVisible(bool gutterVisible)
mGutterVisible = gutterVisible; mGutterVisible = gutterVisible;
} }
bool Settings::Editor::fontOnlyMonospaced() const
{
return mFontOnlyMonospaced;
}
void Settings::Editor::setFontOnlyMonospaced(bool fontOnlyMonospaced)
{
mFontOnlyMonospaced = fontOnlyMonospaced;
}
int Settings::Editor::fontSize() const int Settings::Editor::fontSize() const
{ {
return mFontSize; return mFontSize;
@ -1322,12 +1267,7 @@ void Settings::Editor::setFontSize(int fontSize)
QString Settings::Editor::fontName() const QString Settings::Editor::fontName() const
{ {
return mFontName; return mFontFamilies.length() > 0 ? mFontFamilies[0] : "";
}
void Settings::Editor::setFontName(const QString &fontName)
{
mFontName = fontName;
} }
bool Settings::Editor::scrollByOneLess() const bool Settings::Editor::scrollByOneLess() const
@ -1410,15 +1350,8 @@ void Settings::Editor::doSave()
//Font //Font
//font //font
saveValue("font_name", mFontName); saveValue("font_families", mFontFamilies);
saveValue("fallback_font_name", mFallbackFontName);
saveValue("fallback_font_name2", mFallbackFontName2);
saveValue("fallback_font_name3", mFallbackFontName3);
saveValue("use_fallback_font2", mUseFallbackFont2);
saveValue("use_fallback_font3", mUseFallbackFont3);
saveValue("font_size", mFontSize); saveValue("font_size", mFontSize);
saveValue("font_only_monospaced", mFontOnlyMonospaced);
saveValue("line_spacing",mLineSpacing); saveValue("line_spacing",mLineSpacing);
saveValue("enable_ligatures_support", mEnableLigaturesSupport); saveValue("enable_ligatures_support", mEnableLigaturesSupport);
saveValue("force_fixed_font_width", mForceFixedFontWidth); saveValue("force_fixed_font_width", mForceFixedFontWidth);
@ -1549,32 +1482,22 @@ void Settings::Editor::doLoad()
mRightEdgeLineColor = colorValue("right_edge_line_color",Qt::yellow); mRightEdgeLineColor = colorValue("right_edge_line_color",Qt::yellow);
//Editor font //Editor font
mFontName = stringValue("font_name",DEFAULT_MONO_FONT); QStringList fontFamilies = stringListValue("font_families", QStringList());
QString defaultCjkFontName = DEFAULT_MONO_FONT; if (fontFamilies.empty()) {
QString defaultLocaleName = QLocale::system().name(); // backward compatibility: try old font settings
bool isCNJP = QString fontName = stringValue("font_name", "");
defaultLocaleName.startsWith("zh_") if (!fontName.isEmpty())
|| defaultLocaleName.startsWith("ja_") fontFamilies.append(fontName);
|| defaultLocaleName==("zh") QString nonAsciiFontName = stringValue("non_ascii_font_name", "");
|| defaultLocaleName == ("ja"); if (!nonAsciiFontName.isEmpty())
fontFamilies.append(nonAsciiFontName);
if (defaultLocaleName == "zh_TW") mFontFamilies = fontFamilies.empty() ? defaultEditorFonts() : fontFamilies;
defaultCjkFontName = CJK_MONO_FONT_TC; } else {
else if (defaultLocaleName == "ja_JP") mFontFamilies = fontFamilies;
defaultCjkFontName = CJK_MONO_FONT_J; }
else if (defaultLocaleName == "ko_KR")
defaultCjkFontName = CJK_MONO_FONT_K;
else if (defaultLocaleName == "zh_CN")
defaultCjkFontName = CJK_MONO_FONT_SC;
mFallbackFontName = stringValue("fallback_font_name",defaultCjkFontName);
mFallbackFontName2 = stringValue("fallback_font_name2",DEFAULT_MONO_FONT);
mFallbackFontName3 = stringValue("fallback_font_name3",DEFAULT_MONO_FONT);
mUseFallbackFont2 = boolValue("use_fallback_font2", false);
mUseFallbackFont3 = boolValue("use_fallback_font3", false);
mFontSize = intValue("font_size",12); mFontSize = intValue("font_size",12);
mFontOnlyMonospaced = boolValue("font_only_monospaced",true);
mLineSpacing = doubleValue("line_spacing",1.1); mLineSpacing = doubleValue("line_spacing",1.1);
mForceFixedFontWidth = boolValue("force_fixed_font_width", isCNJP); mForceFixedFontWidth = boolValue("force_fixed_font_width", isCjk());
// if (mForceFixedFontWidth) // if (mForceFixedFontWidth)
// mEnableLigaturesSupport = false; // mEnableLigaturesSupport = false;
// else // else
@ -1598,7 +1521,7 @@ void Settings::Editor::doLoad()
mGutterLineNumbersStartZero = boolValue("gutter_line_numbers_start_zero",false); mGutterLineNumbersStartZero = boolValue("gutter_line_numbers_start_zero",false);
mGutterUseCustomFont = boolValue("gutter_use_custom_font",false); mGutterUseCustomFont = boolValue("gutter_use_custom_font",false);
mGutterFontName = stringValue("gutter_font_name",DEFAULT_MONO_FONT); mGutterFontName = stringValue("gutter_font_name", defaultMonoFont());
mGutterFontSize = intValue("gutter_font_size",12); mGutterFontSize = intValue("gutter_font_size",12);
mGutterFontOnlyMonospaced = boolValue("gutter_font_only_monospaced",true); mGutterFontOnlyMonospaced = boolValue("gutter_font_only_monospaced",true);
@ -3879,29 +3802,10 @@ void Settings::Environment::doLoad()
{ {
//Appearance //Appearance
mTheme = stringValue("theme","dark"); mTheme = stringValue("theme","dark");
QString defaultFontName = DEFAULT_UI_FONT; mInterfaceFont = stringValue("interface_font", defaultUiFont());
QString defaultLocaleName = QLocale::system().name();
{
QString fontName;
if (defaultLocaleName == "zh_CN")
fontName = CJK_UI_FONT_SC;
else if (defaultLocaleName == "zh_TW")
fontName = CJK_UI_FONT_TC;
else if (defaultLocaleName == "ja_JP")
fontName = CJK_UI_FONT_J;
else if (defaultLocaleName == "ko_KR")
fontName = CJK_UI_FONT_K;
else
fontName = DEFAULT_UI_FONT;
QFont font(fontName);
if (font.exactMatch()) {
defaultFontName = fontName;
}
}
mInterfaceFont = stringValue("interface_font",defaultFontName);
mInterfaceFontSize = intValue("interface_font_size",11); mInterfaceFontSize = intValue("interface_font_size",11);
mIconZoomFactor = doubleValue("icon_zoom_factor",1.0); mIconZoomFactor = doubleValue("icon_zoom_factor",1.0);
mLanguage = stringValue("language", defaultLocaleName); mLanguage = stringValue("language", QLocale::system().name());
mIconSet = stringValue("icon_set","contrast"); mIconSet = stringValue("icon_set","contrast");
mUseCustomIconSet = boolValue("use_custom_icon_set", false); mUseCustomIconSet = boolValue("use_custom_icon_set", false);
mUseCustomTheme = boolValue("use_custom_theme", false); mUseCustomTheme = boolValue("use_custom_theme", false);
@ -4515,7 +4419,7 @@ void Settings::Executor::doLoad()
mProblemCaseValidateType =(ProblemCaseValidateType)intValue("problem_case_validate_type", (int)ProblemCaseValidateType::Exact); mProblemCaseValidateType =(ProblemCaseValidateType)intValue("problem_case_validate_type", (int)ProblemCaseValidateType::Exact);
mRedirectStderrToToolLog = boolValue("redirect_stderr_to_toollog", false); mRedirectStderrToToolLog = boolValue("redirect_stderr_to_toollog", false);
mCaseEditorFontName = stringValue("case_editor_font_name",DEFAULT_MONO_FONT); mCaseEditorFontName = stringValue("case_editor_font_name", defaultMonoFont());
mCaseEditorFontSize = intValue("case_editor_font_size",11); mCaseEditorFontSize = intValue("case_editor_font_size",11);
mCaseEditorFontOnlyMonospaced = boolValue("case_editor_font_only_monospaced",true); mCaseEditorFontOnlyMonospaced = boolValue("case_editor_font_only_monospaced",true);
int case_timeout = intValue("case_timeout", -1); int case_timeout = intValue("case_timeout", -1);
@ -4744,11 +4648,7 @@ void Settings::Debugger::doLoad()
{ {
mEnableDebugConsole = boolValue("enable_debug_console",true); mEnableDebugConsole = boolValue("enable_debug_console",true);
mShowDetailLog = boolValue("show_detail_log",false); mShowDetailLog = boolValue("show_detail_log",false);
#ifdef Q_OS_WIN mFontName = stringValue("font_name", defaultMonoFont());
mFontName = stringValue("font_name","Consolas");
#else
mFontName = stringValue("font_name","Dejavu Sans Mono");
#endif
mOnlyShowMono = boolValue("only_show_mono",true); mOnlyShowMono = boolValue("only_show_mono",true);
mFontSize = intValue("font_size",14); mFontSize = intValue("font_size",14);
mUseIntelStyle = boolValue("use_intel_style",false); mUseIntelStyle = boolValue("use_intel_style",false);

View File

@ -26,6 +26,7 @@
#include "qsynedit/qsynedit.h" #include "qsynedit/qsynedit.h"
#include "compiler/compilerinfo.h" #include "compiler/compilerinfo.h"
#include "utils.h" #include "utils.h"
#include "utils/font.h"
/** /**
* use the following command to get gcc's default bin/library folders: * use the following command to get gcc's default bin/library folders:
@ -171,7 +172,6 @@ public:
void setHalfPageScroll(bool halfPageScroll); void setHalfPageScroll(bool halfPageScroll);
QString fontName() const; QString fontName() const;
void setFontName(const QString &fontName);
int fontSize() const; int fontSize() const;
void setFontSize(int fontSize); void setFontSize(int fontSize);
@ -355,22 +355,9 @@ public:
bool enableLigaturesSupport() const; bool enableLigaturesSupport() const;
void setEnableLigaturesSupport(bool newEnableLigaturesSupport); void setEnableLigaturesSupport(bool newEnableLigaturesSupport);
const QString &fallbackFontName() const;
void setFallbackFontName(const QString &newFontName);
const QString &fallbackFontName2() const;
void setFallbackFontName2(const QString &newFontName);
const QString &fallbackFontName3() const;
void setFallbackFontName3(const QString &newFontName);
bool useFallbackFont2() const;
void setUseFallbackFont2(bool useFont);
bool useFallbackFont3() const;
void setUseFallbackFont3(bool useFont);
QStringList fontFamilies() const; QStringList fontFamilies() const;
void setFontFamilies(const QStringList &newFontFamilies);
QStringList fontFamiliesWithControlFont() const;
int mouseSelectionScrollSpeed() const; int mouseSelectionScrollSpeed() const;
void setMouseSelectionScrollSpeed(int newMouseSelectionScrollSpeed); void setMouseSelectionScrollSpeed(int newMouseSelectionScrollSpeed);
@ -462,14 +449,8 @@ public:
//Font //Font
//font //font
QString mFontName; QStringList mFontFamilies;
QString mFallbackFontName;
QString mFallbackFontName2;
QString mFallbackFontName3;
bool mUseFallbackFont2;
bool mUseFallbackFont3;
int mFontSize; int mFontSize;
bool mFontOnlyMonospaced;
double mLineSpacing; double mLineSpacing;
bool mEnableLigaturesSupport; bool mEnableLigaturesSupport;
bool mForceFixedFontWidth; bool mForceFixedFontWidth;

View File

@ -15,21 +15,114 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "editorfontwidget.h" #include "editorfontwidget.h"
#include "editor.h"
#include "ui_editorfontwidget.h" #include "ui_editorfontwidget.h"
#include "../settings.h" #include "../settings.h"
#include "../mainwindow.h" #include "../mainwindow.h"
#include "../iconsmanager.h"
#include "utils.h"
#include "utils/font.h"
void EditorFontModel::addFont(const QString& font)
{
beginInsertRows(QModelIndex(),mFonts.size(),mFonts.size());
mFonts.append(font);
endInsertRows();
}
void EditorFontModel::remove(int index)
{
beginRemoveRows(QModelIndex(),index,index);
mFonts.removeAt(index);
endRemoveRows();
}
void EditorFontModel::clear()
{
beginResetModel();
mFonts.clear();
endResetModel();
}
void EditorFontModel::moveUp(int index)
{
if (index == 0)
return;
beginMoveRows(QModelIndex(),index,index,QModelIndex(),index - 1);
mFonts.move(index,index - 1);
endMoveRows();
}
void EditorFontModel::moveDown(int index)
{
if (index == mFonts.size() - 1)
return;
beginMoveRows(QModelIndex(),index,index,QModelIndex(),index + 2);
mFonts.move(index,index + 1);
endMoveRows();
}
QModelIndex EditorFontModel::lastFont()
{
return index(mFonts.size() - 1,0);
}
const QStringList &EditorFontModel::fonts() const
{
return mFonts;
}
void EditorFontModel::updateFonts(const QStringList& fonts)
{
beginResetModel();
mFonts = fonts;
endResetModel();
}
int EditorFontModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return mFonts.size();
}
int EditorFontModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return 1;
}
QVariant EditorFontModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole)
return mFonts.at(index.row());
return QVariant();
}
bool EditorFontModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
if (role == Qt::EditRole) {
mFonts[index.row()] = value.toString();
emit dataChanged(index,index);
return true;
}
return false;
}
EditorFontWidget::EditorFontWidget(const QString& name, const QString& group, QWidget *parent) : EditorFontWidget::EditorFontWidget(const QString& name, const QString& group, QWidget *parent) :
SettingsWidget(name,group,parent), SettingsWidget(name,group,parent),
ui(new Ui::EditorFontWidget) ui(new Ui::EditorFontWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->cbFallbackFont2->setEnabled(false);
ui->cbFallbackFont3->setEnabled(false); QItemSelectionModel *m = ui->lstFontList->selectionModel();
connect(ui->chkFallbackFont2, &QCheckBox::stateChanged, ui->lstFontList->setModel(&mModel);
this, &EditorFontWidget::onFallbackFontsCheckStateChanged); delete m;
connect(ui->chkFallbackFont3, &QCheckBox::stateChanged,
this, &EditorFontWidget::onFallbackFontsCheckStateChanged);
} }
EditorFontWidget::~EditorFontWidget() EditorFontWidget::~EditorFontWidget()
@ -37,16 +130,6 @@ EditorFontWidget::~EditorFontWidget()
delete ui; delete ui;
} }
void EditorFontWidget::on_chkOnlyMonospacedFonts_stateChanged(int)
{
if (ui->chkOnlyMonospacedFonts->isChecked()) {
ui->cbFont->setFontFilters(QFontComboBox::FontFilter::MonospacedFonts);
} else {
ui->cbFont->setFontFilters(QFontComboBox::FontFilter::AllFonts);
}
}
void EditorFontWidget::on_chkGutterOnlyMonospacedFonts_stateChanged(int) void EditorFontWidget::on_chkGutterOnlyMonospacedFonts_stateChanged(int)
{ {
if (ui->chkGutterOnlyMonospacedFonts->isChecked()) { if (ui->chkGutterOnlyMonospacedFonts->isChecked()) {
@ -56,17 +139,46 @@ void EditorFontWidget::on_chkGutterOnlyMonospacedFonts_stateChanged(int)
} }
} }
void EditorFontWidget::on_btnAddFont_clicked()
{
mModel.addFont(ui->cbNewFont->currentFont().family());
}
void EditorFontWidget::on_btnRemoveFont_clicked()
{
QModelIndex index = ui->lstFontList->currentIndex();
if (!index.isValid())
return;
mModel.remove(index.row());
}
void EditorFontWidget::on_btnMoveFontUp_clicked()
{
QModelIndex index = ui->lstFontList->currentIndex();
if (!index.isValid())
return;
mModel.moveUp(index.row());
}
void EditorFontWidget::on_btnMoveFontDown_clicked()
{
QModelIndex index = ui->lstFontList->currentIndex();
if (!index.isValid())
return;
mModel.moveDown(index.row());
}
void EditorFontWidget::on_btnResetFonts_clicked()
{
mModel.updateFonts(defaultEditorFonts());
}
void EditorFontWidget::doLoad() void EditorFontWidget::doLoad()
{ {
//pSettings->editor().load(); //pSettings->editor().load();
//font //font
ui->chkOnlyMonospacedFonts->setChecked(pSettings->editor().fontOnlyMonospaced()); ui->cbNewFont->setCurrentFont(QFont(defaultMonoFont()));
ui->cbFont->setCurrentFont(QFont(pSettings->editor().fontName())); mModel.updateFonts(pSettings->editor().fontFamilies());
ui->cbFallbackFont->setCurrentFont(QFont(pSettings->editor().fallbackFontName()));
ui->cbFallbackFont2->setCurrentFont(QFont(pSettings->editor().fallbackFontName2()));
ui->cbFallbackFont3->setCurrentFont(QFont(pSettings->editor().fallbackFontName3()));
ui->chkFallbackFont2->setChecked(pSettings->editor().useFallbackFont2());
ui->chkFallbackFont3->setChecked(pSettings->editor().useFallbackFont3());
ui->spinFontSize->setValue(pSettings->editor().fontSize()); ui->spinFontSize->setValue(pSettings->editor().fontSize());
ui->spinLineSpacing->setValue(pSettings->editor().lineSpacing()); ui->spinLineSpacing->setValue(pSettings->editor().lineSpacing());
@ -94,13 +206,7 @@ void EditorFontWidget::doLoad()
void EditorFontWidget::doSave() void EditorFontWidget::doSave()
{ {
//font //font
pSettings->editor().setFontOnlyMonospaced(ui->chkOnlyMonospacedFonts->isChecked()); pSettings->editor().setFontFamilies(mModel.fonts());
pSettings->editor().setFontName(ui->cbFont->currentFont().family());
pSettings->editor().setFallbackFontName(ui->cbFallbackFont->currentFont().family());
pSettings->editor().setFallbackFontName2(ui->cbFallbackFont2->currentFont().family());
pSettings->editor().setFallbackFontName3(ui->cbFallbackFont3->currentFont().family());
pSettings->editor().setUseFallbackFont2(ui->chkFallbackFont2->isChecked());
pSettings->editor().setUseFallbackFont3(ui->chkFallbackFont3->isChecked());
pSettings->editor().setFontSize(ui->spinFontSize->value()); pSettings->editor().setFontSize(ui->spinFontSize->value());
pSettings->editor().setLineSpacing(ui->spinLineSpacing->value()); pSettings->editor().setLineSpacing(ui->spinLineSpacing->value());
@ -129,23 +235,10 @@ void EditorFontWidget::doSave()
pMainWindow->updateEditorSettings(); pMainWindow->updateEditorSettings();
} }
void EditorFontWidget::onFallbackFontsCheckStateChanged() void EditorFontWidget::updateIcons(const QSize &/*size*/) {
{ pIconsManager->setIcon(ui->btnAddFont, IconsManager::ACTION_MISC_ADD);
ui->cbFallbackFont2->setEnabled(ui->chkFallbackFont2->isChecked()); pIconsManager->setIcon(ui->btnRemoveFont, IconsManager::ACTION_MISC_REMOVE);
ui->cbFallbackFont3->setEnabled(ui->chkFallbackFont3->isChecked()); pIconsManager->setIcon(ui->btnMoveFontUp, IconsManager::ACTION_MISC_MOVEUP);
pIconsManager->setIcon(ui->btnMoveFontDown, IconsManager::ACTION_MISC_MOVEDOWN);
pIconsManager->setIcon(ui->btnResetFonts, IconsManager::ACTION_MISC_RESET);
} }
// void EditorFontWidget::on_chkLigature_toggled(bool checked)
// {
// if (ui->chkLigature->isChecked())
// ui->chkForceFixedFontWidth->setChecked(false);
// }
// void EditorFontWidget::on_chkForceFixedFontWidth_toggled(bool checked)
// {
// if (ui->chkForceFixedFontWidth->isChecked())
// ui->chkLigature->setChecked(false);
// }

View File

@ -18,12 +18,38 @@
#define EDITORFONTWIDGET_H #define EDITORFONTWIDGET_H
#include <QWidget> #include <QWidget>
#include <QAbstractListModel>
#include "settingswidget.h" #include "settingswidget.h"
#include "utils/font.h"
namespace Ui { namespace Ui {
class EditorFontWidget; class EditorFontWidget;
} }
class EditorFontModel : public QAbstractListModel
{
Q_OBJECT
public:
void addFont(const QString& font);
void remove(int index);
void clear();
void moveUp(int index);
void moveDown(int index);
QModelIndex lastFont();
const QStringList &fonts() const;
void updateFonts(const QStringList& fonts);
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
private:
QStringList mFonts;
};
class EditorFontWidget : public SettingsWidget class EditorFontWidget : public SettingsWidget
{ {
Q_OBJECT Q_OBJECT
@ -33,9 +59,12 @@ public:
private slots: private slots:
void onFallbackFontsCheckStateChanged();
void on_chkOnlyMonospacedFonts_stateChanged(int arg1);
void on_chkGutterOnlyMonospacedFonts_stateChanged(int arg1); void on_chkGutterOnlyMonospacedFonts_stateChanged(int arg1);
void on_btnAddFont_clicked();
void on_btnRemoveFont_clicked();
void on_btnMoveFontUp_clicked();
void on_btnMoveFontDown_clicked();
void on_btnResetFonts_clicked();
// void on_chkLigature_toggled(bool checked); // void on_chkLigature_toggled(bool checked);
@ -43,11 +72,13 @@ private slots:
private: private:
Ui::EditorFontWidget *ui; Ui::EditorFontWidget *ui;
EditorFontModel mModel;
// SettingsWidget interface // SettingsWidget interface
protected: protected:
void doLoad() override; void doLoad() override;
void doSave() override; void doSave() override;
void updateIcons(const QSize &size) override;
}; };
#endif // EDITORFONTWIDGET_H #endif // EDITORFONTWIDGET_H

View File

@ -7,13 +7,80 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>876</width> <width>876</width>
<height>781</height> <height>850</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupFontFamilies">
<property name="title">
<string>Font:</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QFontComboBox" name="cbNewFont"/>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="btnAddFont">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QListView" name="lstFontList"/>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QToolButton" name="btnRemoveFont">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnMoveFontUp">
<property name="text">
<string>Move up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnMoveFontDown">
<property name="text">
<string>Move down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnResetFonts">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
@ -23,16 +90,9 @@
<property name="rightMargin"> <property name="rightMargin">
<number>11</number> <number>11</number>
</property> </property>
<item row="5" column="0"> <item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_9"> <widget class="QWidget" name="widget_11" native="true">
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_12">
<string>Line Spacing:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="panelFallbackFont3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -46,14 +106,21 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QFontComboBox" name="cbFallbackFont3"> <widget class="QCheckBox" name="chkLigature">
<property name="editable"> <property name="text">
<bool>false</bool> <string>Enable ligatures support</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_10"> <widget class="QCheckBox" name="chkForceFixedFontWidth">
<property name="text">
<string>Force fixed width</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -68,7 +135,21 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="2" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Line Spacing:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget_3" native="true"> <widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin"> <property name="leftMargin">
@ -107,171 +188,6 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QWidget" name="panelFallbackFont2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFontComboBox" name="cbFallbackFont2">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="chkFallbackFont3">
<property name="text">
<string>Fallback Font 3:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fallback Font:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkFallbackFont2">
<property name="text">
<string>Fallback Font 2:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Font:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFontComboBox" name="cbFont">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="fontFilters">
<set>QFontComboBox::AllFonts</set>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkOnlyMonospacedFonts">
<property name="text">
<string>Show only monospaced fonts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget_9" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFontComboBox" name="cbFallbackFont">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<widget class="QWidget" name="widget_10" native="true"> <widget class="QWidget" name="widget_10" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8"> <layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin"> <property name="leftMargin">
@ -318,51 +234,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="6" column="0" colspan="2">
<widget class="QWidget" name="widget_11" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="chkLigature">
<property name="text">
<string>Enable ligatures support</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkForceFixedFontWidth">
<property name="text">
<string>Force fixed width</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -20,7 +20,9 @@
#include "../iconsmanager.h" #include "../iconsmanager.h"
#include "../systemconsts.h" #include "../systemconsts.h"
#include "../compiler/executablerunner.h" #include "../compiler/executablerunner.h"
#include "utils.h"
#include "utils/escape.h" #include "utils/escape.h"
#include "utils/font.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
@ -30,7 +32,7 @@ EnvironmentProgramsWidget::EnvironmentProgramsWidget(const QString& name, const
ui(new Ui::EnvironmentProgramsWidget) ui(new Ui::EnvironmentProgramsWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->labelCmdPreviewResult->setFont(QFont(DEFAULT_MONO_FONT)); ui->labelCmdPreviewResult->setFont(defaultMonoFont());
#ifndef Q_OS_WINDOWS #ifndef Q_OS_WINDOWS
ui->grpUseCustomTerminal->setCheckable(false); ui->grpUseCustomTerminal->setCheckable(false);
#endif #endif

View File

@ -19,6 +19,8 @@
#include "../settings.h" #include "../settings.h"
#include "../iconsmanager.h" #include "../iconsmanager.h"
#include "../systemconsts.h" #include "../systemconsts.h"
#include "utils.h"
#include "utils/font.h"
#include "utils/parsearg.h" #include "utils/parsearg.h"
#include <QFileDialog> #include <QFileDialog>
@ -30,7 +32,7 @@ ExecutorGeneralWidget::ExecutorGeneralWidget(const QString& name, const QString&
ui(new Ui::ExecutorGeneralWidget) ui(new Ui::ExecutorGeneralWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->txtParsedArgsInJson->setFont(QFont(DEFAULT_MONO_FONT)); ui->txtParsedArgsInJson->setFont(defaultMonoFont());
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
ui->chkVTSeq->setVisible(true); ui->chkVTSeq->setVisible(true);
#else #else

View File

@ -125,41 +125,6 @@
#define SDCC_HEX_SUFFIX "hex" #define SDCC_HEX_SUFFIX "hex"
#define SDCC_REL_SUFFIX "rel" #define SDCC_REL_SUFFIX "rel"
#if defined(Q_OS_WIN)
# define DEFAULT_UI_FONT "Segoe UI"
# define CJK_UI_FONT_SC "Microsoft YaHei UI"
# define CJK_UI_FONT_TC "Microsoft JhengHei UI"
# define CJK_UI_FONT_J "Yu Gothic UI"
# define CJK_UI_FONT_K "Malgun Gothic"
# define DEFAULT_MONO_FONT "Consolas"
# define CJK_MONO_FONT_SC "Microsoft YaHei"
# define CJK_MONO_FONT_TC "Microsoft JhengHei"
# define CJK_MONO_FONT_J "Yu Gothic"
# define CJK_MONO_FONT_K "Malgun Gothic"
#elif defined(Q_OS_MACOS)
# define DEFAULT_UI_FONT "Helvetica Neue"
# define CJK_UI_FONT_SC "PingFang SC"
# define CJK_UI_FONT_TC "PingFang TC"
# define CJK_UI_FONT_J "Hiragino Sans"
# define CJK_UI_FONT_K "Apple SD Gothic Neo"
# define DEFAULT_MONO_FONT "Menlo"
# define CJK_MONO_FONT_SC CJK_UI_FONT_SC
# define CJK_MONO_FONT_TC CJK_UI_FONT_TC
# define CJK_MONO_FONT_J CJK_UI_FONT_J
# define CJK_MONO_FONT_K CJK_UI_FONT_K
#else // XDG desktop
# define DEFAULT_UI_FONT "Sans" // use fontconfig default
# define CJK_UI_FONT_SC "Noto Sans CJK SC"
# define CJK_UI_FONT_TC "Noto Sans CJK TC"
# define CJK_UI_FONT_J "Noto Sans CJK JP"
# define CJK_UI_FONT_K "Noto Sans CJK KR"
# define DEFAULT_MONO_FONT "Monospace" // use fontconfig default
# define CJK_MONO_FONT_SC CJK_UI_FONT_SC // intentionally: the "Mono" version is not stricly monospaced either, and has less weights
# define CJK_MONO_FONT_TC CJK_UI_FONT_TC
# define CJK_MONO_FONT_J CJK_UI_FONT_J
# define CJK_MONO_FONT_K CJK_UI_FONT_K
#endif
class SystemConsts class SystemConsts
{ {
public: public:

235
RedPandaIDE/utils/font.cpp Normal file
View File

@ -0,0 +1,235 @@
/*
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "utils/font.h"
#include <QFont>
#include <QVersionNumber>
#include <QMap>
#if defined(Q_OS_WIN)
static const QMap<QString, QStringList> uiFontsByLocale = {};
static const QMap<QLocale::Script, QStringList> uiFontsByScript = {
{QLocale::CyrillicScript, {"Segoe UI", "Tahoma"}},
{QLocale::SimplifiedHanScript, {"Microsoft YaHei UI", "Microsoft YaHei", "SimHei"}},
{QLocale::TraditionalHanScript, {"Microsoft JhengHei UI", "Microsoft JhengHei", "SimHei"}},
{QLocale::LatinScript, {"Segoe UI", "Tahoma"}},
{QLocale::GreekScript, {"Segoe UI", "Tahoma"}},
{QLocale::JapaneseScript, {"Yu Gothic UI", "Meiryo UI", "MS UI Gothic"}},
{QLocale::KoreanScript, {"Malgun Gothic", "Dotum"}},
};
#elif defined(Q_OS_MACOS)
static const QMap<QString, QStringList> uiFontsByLocale = {
{"zh_HK", {"PingFang HK"}},
};
static const QMap<QLocale::Script, QStringList> uiFontsByScript = {
{QLocale::CyrillicScript, {"Helvetica Neue"}},
{QLocale::SimplifiedHanScript, {"PingFang SC"}},
{QLocale::TraditionalHanScript, {"PingFang TC"}},
{QLocale::LatinScript, {"Helvetica Neue"}},
{QLocale::GreekScript, {"Helvetica Neue"}},
{QLocale::JapaneseScript, {"Hiragino Sans"}},
{QLocale::KoreanScript, {"Apple SD Gothic Neo"}},
};
#else // XDG desktop
static const QMap<QString, QStringList> uiFontsByLocale = {
{"zh_HK", {"Noto Sans CJK HK"}},
};
static const QMap<QLocale::Script, QStringList> uiFontsByScript = {
{QLocale::CyrillicScript, {"Noto Sans"}},
{QLocale::SimplifiedHanScript, {"Noto Sans CJK SC"}},
{QLocale::TraditionalHanScript, {"Noto Sans CJK TC"}},
{QLocale::LatinScript, {"Noto Sans"}},
{QLocale::GreekScript, {"Noto Sans"}},
{QLocale::JapaneseScript, {"Noto Sans CJK JP"}},
{QLocale::KoreanScript, {"Noto Sans CJK KR"}},
};
#endif
QString defaultUiFont()
{
QString defaultLocaleName = QLocale::system().name();
QLocale::Script defaultScript = QLocale::system().script();
if (uiFontsByLocale.contains(defaultLocaleName)) {
QStringList fonts = uiFontsByLocale[defaultLocaleName];
for (const QString &font : fonts) {
if (QFont(font).exactMatch())
return font;
}
}
if (uiFontsByScript.contains(defaultScript)) {
QStringList fonts = uiFontsByScript[defaultScript];
for (const QString &font : fonts) {
if (QFont(font).exactMatch())
return font;
}
}
// final fallback
#if defined(Q_OS_WIN)
return "Microsoft Sans Serif";
#elif defined(Q_OS_MACOS)
return "Helvetica Neue";
#else // XDG desktop
return "Sans Serif";
#endif
}
QString defaultMonoFont()
{
#if defined(Q_OS_WIN)
QFont font("Consolas");
if (font.exactMatch())
return "Consolas";
else
return "Courier New";
#elif defined(Q_OS_MACOS)
return "Menlo";
#else // XDG desktop
QFont font("Noto Sans Mono");
if (font.exactMatch())
return "Noto Sans Mono";
else
return "DejaVu Sans Mono";
#endif
}
QString defaultEmojiFont()
{
#if defined(Q_OS_WIN)
return "Segoe UI Emoji";
#elif defined(Q_OS_MACOS)
return "Apple Color Emoji";
#else // XDG desktop
return "Noto Color Emoji";
#endif
}
bool isCjk(const QString &locale)
{
return locale.startsWith("zh_") || locale == "zh" ||
locale.startsWith("ja_") || locale == "ja" ||
locale.startsWith("ko_") || locale == "ko";
}
QStringList defaultCjkEditorFonts(const QString &locale)
{
#if defined(Q_OS_WIN)
QVersionNumber currentVersion = QVersionNumber::fromString(QSysInfo::kernelVersion());
const QVersionNumber vista(6, 0);
if (locale == "zh_TW" || locale == "zh_HK"){
if (currentVersion >= vista)
return {"Microsoft JhengHei"};
else
return {"SimHei"};
} else if (locale == "ja_JP") {
if (currentVersion >= vista)
// prefer Meiryo over Yu Gothic, and YaHei over JhengHei
// they are bolder and more readable
return {"Meiryo", "Microsoft YaHei"};
else
return {"MS Gothic", "SimHei"};
} else if (locale == "ko_KR") {
if (currentVersion >= vista)
return {"Malgun Gothic", "Microsoft YaHei"};
else
return {"Dotum", "SimHei"};
} else {
// finally fallback to zh_CN
// with largest coverage, CJK ideographs have uniform look
if (currentVersion >= vista)
return {"Microsoft YaHei"};
else
return {"SimHei"};
}
#elif defined(Q_OS_MACOS)
// TODO: coverage is not verified
if (locale == "zh_TW")
return {"PingFang TC"};
else if (locale == "zh_HK")
return {"PingFang HK"};
else if (locale == "ja_JP")
// prefer Hiragino Sans GB for uniform look of CJK ideographs
return {"Hiragino Sans", "Hiragino Sans GB"};
else if (locale == "ko_KR")
return {"Apple SD Gothic Neo", "PingFang SC"};
else
return {"PingFang SC"};
#else // XDG desktop
// Noto Sans CJK have same coverage, add one of them is enough
// intentionally: the "Mono" variant is not strictly monospaced either, and has less weights
if (locale == "zh_TW")
return {"Noto Sans CJK TC"};
else if (locale == "zh_HK")
return {"Noto Sans CJK HK"};
else if (locale == "ja_JP")
return {"Noto Sans CJK JP"};
else if (locale == "ko_KR")
return {"Noto Sans CJK KR"};
else
return {"Noto Sans CJK SC"};
#endif
}
QStringList defaultFallbackEditorFonts()
{
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
// use system fallback fonts
return {};
#else // XDG desktop
// There is a limit of 256 fallback fonts in Qt:
// https://bugreports.qt.io/browse/QTBUG-80434
// As a result, on systems with Noto installed (~1000 fonts), fallback will fail.
// Here we recommend use merged Noto fonts to reduce the number of required fonts.
// https://github.com/notofonts/notofonts.github.io/tree/main/megamerge
return {
"Noto Sans Living",
"Noto Sans Historical",
"Noto Serif Living",
"Noto Serif Historical",
};
#endif
}
QStringList defaultEditorFonts()
{
QStringList result = {
defaultMonoFont(),
};
// special handling CJK fonts: they share same code points
QString defaultLocaleName = QLocale::system().name();
if (isCjk(defaultLocaleName)) {
result += defaultCjkEditorFonts(defaultLocaleName);
result += defaultFallbackEditorFonts();
} else {
result += defaultFallbackEditorFonts();
result += defaultCjkEditorFonts(defaultLocaleName);
}
result.append(defaultEmojiFont());
return result;
}

40
RedPandaIDE/utils/font.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FONT_H
#define FONT_H
#include <QString>
#include <QStringList>
#include <QLocale>
enum class UnicodeSupportLevel {
BmpOnly = 0,
FullCodePoint = 1,
Contextual = 2,
Grapheme = 3,
Bidirectional = 4,
};
QString defaultUiFont();
QString defaultMonoFont();
QString defaultEmojiFont();
bool isCjk(const QString &locale = QLocale::system().name());
QStringList defaultCjkEditorFonts(const QString &locale);
QStringList defaultFallbackEditorFonts();
QStringList defaultEditorFonts();
#endif // FONT_H

View File

@ -146,7 +146,7 @@ void CPUDialog::resetEditorFont(float dpi)
ui->txtCode->setOptions(options); ui->txtCode->setOptions(options);
QFont f=QFont(); QFont f=QFont();
f.setFamily(pSettings->editor().fontName()); f.setFamily(pSettings->editor().fontName());
f.setFamilies(pSettings->editor().fontFamilies()); f.setFamilies(pSettings->editor().fontFamiliesWithControlFont());
f.setPixelSize(pointToPixel(pSettings->editor().fontSize(),dpi)); f.setPixelSize(pointToPixel(pSettings->editor().fontSize(),dpi));
f.setStyleStrategy(QFont::PreferAntialias); f.setStyleStrategy(QFont::PreferAntialias);
ui->txtCode->setFont(f); ui->txtCode->setFont(f);

View File

@ -53,6 +53,7 @@ target("RedPandaIDE")
"problems/ojproblemset.cpp", "problems/ojproblemset.cpp",
"problems/problemcasevalidator.cpp", "problems/problemcasevalidator.cpp",
"utils/escape.cpp", "utils/escape.cpp",
"utils/font.cpp",
"utils/parsearg.cpp") "utils/parsearg.cpp")
add_moc_classes( add_moc_classes(

View File

@ -152,7 +152,7 @@ void QSynEditPainter::paintGutter(const QRect& clip)
textRect = mPainter->boundingRect(textRect, Qt::AlignLeft,s); textRect = mPainter->boundingRect(textRect, Qt::AlignLeft,s);
mPainter->drawText( mPainter->drawText(
(mEdit->mGutterWidth - mEdit->mGutter.rightOffset() - 2) - textRect.width(), (mEdit->mGutterWidth - mEdit->mGutter.rightOffset() - 2) - textRect.width(),
rcLine.bottom() + ((mEdit->mTextHeight - int(textRect.height())) / 2 - mPainter->fontMetrics().descent()), rcLine.bottom() - (mEdit->mTextHeight - int(textRect.height())) / 2 - mPainter->fontMetrics().descent(),
s s
); );
} }
@ -351,7 +351,10 @@ void QSynEditPainter::paintToken(
if (last >= first && mRcToken.right() > mRcToken.left()) { if (last >= first && mRcToken.right() > mRcToken.left()) {
int nX = fixXValue(first); int nX = fixXValue(first);
int nY = mRcToken.bottom()-mPainter->fontMetrics().descent(); int lineHeight = mRcToken.height();
int fontHeight = mPainter->fontMetrics().descent() + mPainter->fontMetrics().ascent();
int linePadding = (lineHeight - fontHeight) / 2;
int nY = mRcToken.bottom() - linePadding - mPainter->fontMetrics().descent();
first -= tokenLeft; first -= tokenLeft;
last -= tokenLeft; last -= tokenLeft;
QRect rcTokenBack = mRcToken; QRect rcTokenBack = mRcToken;