Add Bold/Italic buttons to select a font

This commit is contained in:
David Capello 2024-04-15 18:52:36 -03:00
parent 455a67111a
commit 53f045a369
8 changed files with 112 additions and 35 deletions

View File

@ -82,6 +82,7 @@ void PasteTextCommand::onExecute(Context* ctx)
fontInfo = FontInfo(FontInfo::Type::File,
pref.textTool.fontFace(),
pref.textTool.fontSize(),
text::FontStyle(),
pref.textTool.antialias());
}
// New configuration

View File

@ -24,11 +24,13 @@ namespace app {
FontInfo::FontInfo(Type type,
const std::string& name,
const float size,
const text::FontStyle style,
const bool antialias,
const text::TypefaceRef& typeface)
: m_type(type)
, m_name(name)
, m_size(size)
, m_style(style)
, m_antialias(antialias)
, m_typeface(typeface)
{
@ -36,10 +38,12 @@ FontInfo::FontInfo(Type type,
FontInfo::FontInfo(const FontInfo& other,
const float size,
const text::FontStyle style,
const bool antialias)
: m_type(other.type())
, m_name(other.name())
, m_size(size)
, m_style(style)
, m_antialias(antialias)
, m_typeface(other.typeface())
{
@ -71,8 +75,10 @@ void FontInfo::findTypeface(const text::FontMgrRef& fontMgr) const
}
const text::FontStyleSetRef set = fontMgr->matchFamily(m_name);
if (set && set->typeface(0))
m_typeface = set->typeface(0);
if (set) {
if (auto newTypeface = set->matchStyle(m_style))
m_typeface = newTypeface;
}
}
} // namespace app
@ -87,6 +93,8 @@ template<> app::FontInfo convert_to(const std::string& from)
app::FontInfo::Type type = app::FontInfo::Type::Unknown;
std::string name;
float size = 0.0f;
bool bold = false;
bool italic = false;
bool antialias = false;
if (!parts.empty()) {
@ -105,12 +113,22 @@ template<> app::FontInfo convert_to(const std::string& from)
for (int i=1; i<parts.size(); ++i) {
if (parts[i] == "antialias")
antialias = true;
else if (parts[i] == "bold")
bold = true;
else if (parts[i] == "italic")
italic = true;
else if (parts[i].compare(0, 5, "size=") == 0) {
size = std::strtof(parts[i].substr(5).c_str(), nullptr);
}
}
}
return app::FontInfo(type, name, size, antialias);
text::FontStyle style;
if (bold && italic) style = text::FontStyle::BoldItalic();
else if (bold) style = text::FontStyle::Bold();
else if (italic) style = text::FontStyle::Italic();
return app::FontInfo(type, name, size, style, antialias);
}
template<> std::string convert_to(const app::FontInfo& from)
@ -133,6 +151,10 @@ template<> std::string convert_to(const app::FontInfo& from)
if (!result.empty()) {
if (from.size() > 0.0f)
result += fmt::format(",size={}", from.size());
if (from.style().weight() >= text::FontStyle::Weight::SemiBold)
result += ",bold";
if (from.style().slant() != text::FontStyle::Slant::Upright)
result += ",italic";
if (from.antialias())
result += ",antialias";
}

View File

@ -9,6 +9,7 @@
#pragma once
#include "base/convert_to.h"
#include "text/font_style.h"
#include "text/fwd.h"
#include "text/typeface.h"
@ -32,11 +33,13 @@ namespace app {
FontInfo(Type type = Type::Unknown,
const std::string& name = {},
float size = kDefaultSize,
text::FontStyle style = text::FontStyle(),
bool antialias = false,
const text::TypefaceRef& typeface = nullptr);
FontInfo(const FontInfo& other,
float size,
text::FontStyle style,
bool antialias);
bool isValid() const { return m_type != Type::Unknown; }
@ -54,6 +57,7 @@ namespace app {
std::string thumbnailId() const;
float size() const { return m_size; }
text::FontStyle style() const { return m_style; }
bool antialias() const { return m_antialias; }
void findTypeface(const text::FontMgrRef& fontMgr) const;
@ -70,6 +74,7 @@ namespace app {
Type m_type = Type::Unknown;
std::string m_name;
float m_size = kDefaultSize;
text::FontStyle m_style;
bool m_antialias = false;
mutable text::TypefaceRef m_typeface;
};

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2018-2024 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -190,8 +190,9 @@ void ButtonSet::Item::onRightClick()
buttonSet()->onRightClick(this);
}
ButtonSet::ButtonSet(int columns)
: Grid(columns, false)
ButtonSet::ButtonSet(const int columns,
const bool same_width_columns)
: Grid(columns, same_width_columns)
, m_offerCapture(true)
, m_triggerOnMouseUp(false)
, m_multiMode(MultiMode::One)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -42,7 +42,7 @@ namespace app {
OneOrMore, // One click selects one button, ctrl+click multiple selections
};
ButtonSet(int columns);
ButtonSet(int columns, bool same_width_columns = false);
Item* addItem(const std::string& text, ui::Style* style);
Item* addItem(const std::string& text, int hspan = 1, int vspan = 1, ui::Style* style = nullptr);

View File

@ -135,19 +135,30 @@ void FontEntry::FontSize::onEntryChange()
Change();
}
FontEntry::FontStyle::FontStyle()
: ButtonSet(2, true)
{
addItem("B");
addItem("I");
setMultiMode(MultiMode::Set);
}
FontEntry::FontEntry()
: m_antialias("Antialias")
{
m_face.setExpansive(true);
m_size.setExpansive(false);
m_style.setExpansive(false);
m_antialias.setExpansive(false);
addChild(&m_face);
addChild(&m_size);
addChild(&m_style);
addChild(&m_antialias);
m_face.FontChange.connect([this](const FontInfo& newTypeName) {
setInfo(FontInfo(newTypeName,
m_info.size(),
m_info.style(),
m_info.antialias()),
From::Face);
invalidate();
@ -157,13 +168,45 @@ FontEntry::FontEntry()
const float newSize = std::strtof(m_size.getValue().c_str(), nullptr);
setInfo(FontInfo(m_info,
newSize,
m_info.style(),
m_info.antialias()),
From::Size);
});
m_style.ItemChange.connect([this](ButtonSet::Item* item){
text::FontStyle style = m_info.style();
switch (m_style.getItemIndex(item)) {
// Bold button changed
case 0: {
const bool bold = m_style.getItem(0)->isSelected();
style = text::FontStyle(bold ? text::FontStyle::Weight::Bold:
text::FontStyle::Weight::Normal,
style.width(),
style.slant());
break;
}
// Italic button changed
case 1: {
const bool italic = m_style.getItem(1)->isSelected();
style = text::FontStyle(style.weight(),
style.width(),
italic ? text::FontStyle::Slant::Italic:
text::FontStyle::Slant::Upright);
break;
}
}
setInfo(FontInfo(m_info,
m_info.size(),
style,
m_info.antialias()),
From::Style);
});
m_antialias.Click.connect([this](){
setInfo(FontInfo(m_info,
m_info.size(),
m_info.style(),
m_antialias.isSelected()),
From::Antialias);
});
@ -179,6 +222,11 @@ void FontEntry::setInfo(const FontInfo& info,
if (fromField != From::Size)
m_size.setValue(fmt::format("{}", info.size()));
if (fromField != From::Style) {
m_style.getItem(0)->setSelected(info.style().weight() >= text::FontStyle::Weight::SemiBold);
m_style.getItem(1)->setSelected(info.style().slant() != text::FontStyle::Slant::Upright);
}
if (fromField != From::Antialias)
m_antialias.setSelected(info.antialias());

View File

@ -9,6 +9,7 @@
#pragma once
#include "app/font_info.h"
#include "app/ui/button_set.h"
#include "app/ui/search_entry.h"
#include "ui/box.h"
#include "ui/button.h"
@ -25,6 +26,7 @@ namespace app {
User,
Face,
Size,
Style,
Antialias,
};
@ -55,9 +57,15 @@ namespace app {
void onEntryChange() override;
};
class FontStyle : public ButtonSet {
public:
FontStyle();
};
FontInfo m_info;
FontFace m_face;
FontSize m_size;
FontStyle m_style;
ui::CheckBox m_antialias;
};

View File

@ -63,22 +63,28 @@ public:
FontItem(const std::string& name, ByName)
: ListItem(name)
, m_fontInfo(FontInfo::Type::Name, name,
FontInfo::kDefaultSize, true) {
FontInfo::kDefaultSize,
text::FontStyle(), true) {
getCachedThumbnail();
}
FontItem(const std::string& fn)
: ListItem(base::get_file_title(fn))
, m_fontInfo(FontInfo::Type::File, fn,
FontInfo::kDefaultSize, true) {
FontInfo::kDefaultSize,
text::FontStyle(), true) {
getCachedThumbnail();
}
FontItem(const std::string& name,
const text::FontStyle& style,
const text::FontStyleSetRef& set,
const text::TypefaceRef& typeface)
: ListItem(name)
, m_fontInfo(FontInfo::Type::System, name,
FontInfo::kDefaultSize, true, typeface) {
FontInfo::kDefaultSize,
style, true, typeface)
, m_set(set) {
getCachedThumbnail();
}
@ -161,6 +167,7 @@ private:
private:
os::SurfaceRef m_thumbnail;
FontInfo m_fontInfo;
text::FontStyleSetRef m_set;
};
bool FontPopup::FontListBox::onProcessMessage(ui::Message* msg)
@ -229,31 +236,16 @@ FontPopup::FontPopup(const FontInfo& fontInfo)
std::string name = fontMgr->familyName(i);
text::FontStyleSetRef set = fontMgr->familyStyleSet(i);
if (set && set->count() > 0) {
// Best style for preview purposes, i.e. the most regular
// style, without bold, italic, etc.
int best;
text::FontStyle bestStyle;
for (int i=0; i<set->count(); ++i) {
text::FontStyle style;
std::string subname;
set->getStyle(i, style, subname);
if ((i == 0) ||
((style.weight() == text::FontStyle::Weight::Normal &&
bestStyle.weight() != text::FontStyle::Weight::Normal) ||
(style.width() == text::FontStyle::Width::Normal &&
bestStyle.width() != text::FontStyle::Width::Normal) ||
(style.slant() == text::FontStyle::Slant::Upright &&
bestStyle.slant() != text::FontStyle::Slant::Upright))) {
best = i;
bestStyle = style;
}
// Match the typeface with the default FontStyle (Normal
// weight, Upright slant, etc.)
auto typeface = set->matchStyle(text::FontStyle());
if (typeface) {
auto* item = new FontItem(name, typeface->fontStyle(),
set, typeface);
item->ThumbnailGenerated.connect([this]{ onThumbnailGenerated(); });
m_listBox.addChild(item);
empty = false;
}
auto* item = new FontItem(name, set->typeface(best));
item->ThumbnailGenerated.connect([this]{ onThumbnailGenerated(); });
m_listBox.addChild(item);
empty = false;
}
}
}