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, fontInfo = FontInfo(FontInfo::Type::File,
pref.textTool.fontFace(), pref.textTool.fontFace(),
pref.textTool.fontSize(), pref.textTool.fontSize(),
text::FontStyle(),
pref.textTool.antialias()); pref.textTool.antialias());
} }
// New configuration // New configuration

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019 Igara Studio S.A. // Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -42,7 +42,7 @@ namespace app {
OneOrMore, // One click selects one button, ctrl+click multiple selections 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, ui::Style* style);
Item* addItem(const std::string& text, int hspan = 1, int vspan = 1, ui::Style* style = nullptr); 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(); Change();
} }
FontEntry::FontStyle::FontStyle()
: ButtonSet(2, true)
{
addItem("B");
addItem("I");
setMultiMode(MultiMode::Set);
}
FontEntry::FontEntry() FontEntry::FontEntry()
: m_antialias("Antialias") : m_antialias("Antialias")
{ {
m_face.setExpansive(true); m_face.setExpansive(true);
m_size.setExpansive(false); m_size.setExpansive(false);
m_style.setExpansive(false);
m_antialias.setExpansive(false); m_antialias.setExpansive(false);
addChild(&m_face); addChild(&m_face);
addChild(&m_size); addChild(&m_size);
addChild(&m_style);
addChild(&m_antialias); addChild(&m_antialias);
m_face.FontChange.connect([this](const FontInfo& newTypeName) { m_face.FontChange.connect([this](const FontInfo& newTypeName) {
setInfo(FontInfo(newTypeName, setInfo(FontInfo(newTypeName,
m_info.size(), m_info.size(),
m_info.style(),
m_info.antialias()), m_info.antialias()),
From::Face); From::Face);
invalidate(); invalidate();
@ -157,13 +168,45 @@ FontEntry::FontEntry()
const float newSize = std::strtof(m_size.getValue().c_str(), nullptr); const float newSize = std::strtof(m_size.getValue().c_str(), nullptr);
setInfo(FontInfo(m_info, setInfo(FontInfo(m_info,
newSize, newSize,
m_info.style(),
m_info.antialias()), m_info.antialias()),
From::Size); 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](){ m_antialias.Click.connect([this](){
setInfo(FontInfo(m_info, setInfo(FontInfo(m_info,
m_info.size(), m_info.size(),
m_info.style(),
m_antialias.isSelected()), m_antialias.isSelected()),
From::Antialias); From::Antialias);
}); });
@ -179,6 +222,11 @@ void FontEntry::setInfo(const FontInfo& info,
if (fromField != From::Size) if (fromField != From::Size)
m_size.setValue(fmt::format("{}", info.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) if (fromField != From::Antialias)
m_antialias.setSelected(info.antialias()); m_antialias.setSelected(info.antialias());

View File

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

View File

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