diff --git a/src/data/font.cpp b/src/data/font.cpp index a83f01c0..1fa1c2ac 100644 --- a/src/data/font.cpp +++ b/src/data/font.cpp @@ -11,36 +11,47 @@ // ----------------------------------------------------------------------------- : Font Font::Font() - : font(*wxNORMAL_FONT) - , size(font.GetPointSize()) + : name() + , size(1) + , underline(false) + , weight_i(wxFONTWEIGHT_NORMAL), style_i(wxFONTSTYLE_NORMAL) , scale_down_to(100000) , shadow_displacement(0,0) , separator_color(128,128,128) {} bool Font::update(Context& ctx) { - return color .update(ctx) + bool changes + = name .update(ctx) + | italic_name .update(ctx) + | size .update(ctx) + | weight .update(ctx) + | style .update(ctx) + | underline .update(ctx) + | color .update(ctx) | shadow_color.update(ctx); + weight_i = weight() == _("bold") ? wxBOLD : wxNORMAL; + style_i = style() == _("italic") ? wxITALIC : wxNORMAL; + return changes; } void Font::initDependencies(Context& ctx, const Dependency& dep) const { + name .initDependencies(ctx, dep); + italic_name .initDependencies(ctx, dep); + size .initDependencies(ctx, dep); + weight .initDependencies(ctx, dep); + style .initDependencies(ctx, dep); + underline .initDependencies(ctx, dep); color .initDependencies(ctx, dep); shadow_color.initDependencies(ctx, dep); } FontP Font::make(bool bold, bool italic, bool placeholder_color, bool code_color, Color* other_color) const { FontP f(new Font(*this)); - if (bold) f->font.SetWeight(wxBOLD); - if (italic) { - if (!italic_name.empty()) { - f->font.SetFaceName(italic_name); - } else { - f->font.SetWeight(wxBOLD); - } - } + if (bold) f->weight_i = wxFONTWEIGHT_BOLD; + if (italic) f->style_i = wxFONTSTYLE_ITALIC; if (code_color) { f->color = Color(128,0,0); - f->font.SetFamily(wxFONTFAMILY_TELETYPE); - f->font.SetFaceName(_("Courier New")); + f->type = TYPEWRITER; } if (placeholder_color) { f->color = f->separator_color; @@ -52,29 +63,27 @@ FontP Font::make(bool bold, bool italic, bool placeholder_color, bool code_color return f; } -void reflect_font(Reader& tag, Font& font) { - String name, weight, style; - double size = -1; +wxFont Font::toWxFont(double scale) const { + int size_i = scale * size; + if (name().empty()) { + wxFont font = *wxNORMAL_FONT; + font.SetPointSize(size > 1 ? size_i : scale * font.GetPointSize()); + return font; + } else if (type == TYPEWRITER) { + return wxFont(size_i, wxFONTFAMILY_TELETYPE, weight_i, underline(), _("Courier New")); + } else if (style_i == wxFONTSTYLE_ITALIC && !italic_name().empty()) { + return wxFont(size_i, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, weight_i, underline(), italic_name()); + } else { + return wxFont(size_i, wxFONTFAMILY_DEFAULT, style_i, weight_i, underline(), name()); + } +} + +IMPLEMENT_REFLECTION(Font) { REFLECT(name); REFLECT(size); REFLECT(weight); REFLECT(style); - if (!name.empty()) font.font.SetFaceName(name); - if (size > 0) font.font.SetPointSize((int) (font.size = size)); - if (!weight.empty()) font.font.SetWeight(weight == _("bold") ? wxBOLD : wxNORMAL); - if (!style.empty()) font.font.SetWeight(style == _("italic") ? wxITALIC : wxNORMAL); -} - -template -void reflect_font(Tag& tag, const Font& font) { - REFLECT_N("name", font.font.GetFaceName()); - REFLECT_N("size", font.size); - REFLECT_N("weight", font.font.GetWeight() == wxBOLD ? _("bold") : _("normal")); - REFLECT_N("style", font.font.GetStyle() == wxITALIC ? _("italic") : _("normal")); -} - -IMPLEMENT_REFLECTION(Font) { - reflect_font(tag, *this); + REFLECT(underline); REFLECT(italic_name); REFLECT(color); REFLECT(scale_down_to); diff --git a/src/data/font.hpp b/src/data/font.hpp index 45bcaee4..23c7f99b 100644 --- a/src/data/font.hpp +++ b/src/data/font.hpp @@ -21,14 +21,21 @@ DECLARE_POINTER_TYPE(Font); /** Contains additional information about scaling, color and shadow */ class Font { public: - wxFont font; ///< The actual wxFont to use - double size; ///< Size of the font - double scale_down_to; ///< Smallest size to scale down to - Scriptable color; ///< Color to use - Scriptable shadow_color; ///< Color for shadow - RealSize shadow_displacement; ///< Position of the shadow - String italic_name; ///< Font name for italic text (optional) - Color separator_color; ///< Color for text + Scriptable name; ///< Name of the font + Scriptable italic_name; ///< Font name for italic text (optional) + Scriptable size; ///< Size of the font + Scriptable weight, style; ///< Weight and style of the font (bold/italic) + Scriptable underline; ///< Underlined? + int weight_i, style_i; ///< wx constants for weight and style + double scale_down_to; ///< Smallest size to scale down to + Scriptable color; ///< Color to use + Scriptable shadow_color; ///< Color for shadow + RealSize shadow_displacement; ///< Position of the shadow + Color separator_color; ///< Color for text + enum { + NORMAL, + TYPEWRITER, ///< Use a typewriter font + } type; Font(); @@ -43,6 +50,9 @@ class Font { /// Make a bold/italic/placeholder version of this font FontP make(bool bold, bool italic, bool placeholder_color, bool code_color, Color* other_color) const; + /// Convert this font to a wxFont + wxFont toWxFont(double scale) const; + private: DECLARE_REFLECTION(); }; diff --git a/src/data/format/apprentice.cpp b/src/data/format/apprentice.cpp index 16f6480a..08743272 100644 --- a/src/data/format/apprentice.cpp +++ b/src/data/format/apprentice.cpp @@ -676,7 +676,7 @@ void ApprenticeExportWindow::onOk(wxCommandEvent& ev) { if (set->apprentice_code != new_set_code) { // changed something in the set set->apprentice_code = new_set_code; - //%%set->actions.atSavePoint = false; // tell the user he needs to save + //set->actions.atSavePoint = false; // TODO: tell the user he needs to save } // Check if apprentice exists if (!wxFileExists(settings.apprentice_location + _("\\appr.exe"))) { diff --git a/src/data/symbol_font.cpp b/src/data/symbol_font.cpp index 1914fbdc..878a42cd 100644 --- a/src/data/symbol_font.cpp +++ b/src/data/symbol_font.cpp @@ -151,6 +151,15 @@ RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) { void SymbolInFont::update(Context& ctx) { enabled.update(ctx); } +void SymbolFont::update(Context& ctx) const { + // update all symbol-in-fonts + FOR_EACH_CONST(sym, symbols) { + sym->update(ctx); + } + if (text_font) { + text_font->update(ctx); + } +} IMPLEMENT_REFLECTION(SymbolInFont) { REFLECT(code); @@ -172,10 +181,7 @@ class SymbolFont::DrawableSymbol { }; void SymbolFont::split(const String& text, Context& ctx, SplitSymbols& out) const { - // update all symbol-in-fonts - FOR_EACH_CONST(sym, symbols) { - sym->update(ctx); - } + update(ctx); // read a single symbol until we are done with the text for (size_t pos = 0 ; pos < text.size() ; ) { // 1. check merged numbers @@ -264,7 +270,7 @@ void SymbolFont::drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect, RealSize ts; while (true) { if (size <= 0) return; // text too small - dc.SetFont(text_font->font, size); + dc.SetFont(*text_font, size / text_font->size); ts = dc.GetTextExtent(text); if (ts.width <= sym_rect.width && ts.height <= sym_rect.height) { break; // text fits @@ -326,10 +332,7 @@ RealSize SymbolFont::defaultSymbolSize(Context& ctx, double font_size) { wxMenu* SymbolFont::insertSymbolMenu(Context& ctx) { if (!processed_insert_symbol_menu && insert_symbol_menu) { - // update all symbol-in-fonts - FOR_EACH_CONST(sym, symbols) { - sym->update(ctx); - } + update(ctx); // Make menu processed_insert_symbol_menu = insert_symbol_menu->makeMenu(ID_INSERT_SYMBOL_MENU_MIN, ctx, *this); } diff --git a/src/data/symbol_font.hpp b/src/data/symbol_font.hpp index 812b7cd2..5093e753 100644 --- a/src/data/symbol_font.hpp +++ b/src/data/symbol_font.hpp @@ -59,7 +59,7 @@ class SymbolFont : public Packaged { /// Process a choice from the insert symbol menu /** Return the code representing the symbol */ String insertSymbolCode(int menu_id) const; - + private: UInt img_size; ///< Font size that the images use UInt min_size; ///< Minimum font size @@ -80,6 +80,9 @@ class SymbolFont : public Packaged { friend class InsertSymbolMenu; vector symbols; ///< The individual symbols + // Script update + void update(Context& ctx) const; + /// Find the default symbol /** may return nullptr */ SymbolInFont* defaultSymbol() const; diff --git a/src/gui/set/keywords_panel.cpp b/src/gui/set/keywords_panel.cpp index 3a3796ee..985553e2 100644 --- a/src/gui/set/keywords_panel.cpp +++ b/src/gui/set/keywords_panel.cpp @@ -231,18 +231,15 @@ void KeywordsPanel::onChangeSet() { // init text controls keyword ->setSet(set); keyword ->getStyle().font.size = 16; - keyword ->getStyle().font.font.SetPointSize(16); keyword ->getStyle().padding_bottom = 1; keyword ->updateSize(); match ->setSet(set); match ->getStyle().font.size = 12; - match ->getStyle().font.font.SetPointSize(12); match ->getStyle().padding_bottom = 1; match ->updateSize(); reminder->setSet(set); reminder->getStyle().padding_bottom = 2; match ->getStyle().font.size = 10; - match ->getStyle().font.font.SetPointSize(10); reminder->updateSize(); rules ->setSet(set); // parameter & mode lists diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index 1e68739c..3b66fd7c 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -446,7 +446,7 @@ void TextValueEditor::showCaret() { if (cursor.height == 0) { wxClientDC dc(&editor()); // TODO : high quality? - dc.SetFont(style().font.font); + dc.SetFont(style().font.toWxFont(1.0)); int hi; dc.GetTextExtent(_(" "), 0, &hi); cursor.height = rot.trS(hi); @@ -678,7 +678,7 @@ void TextValueEditor::determineSize(bool force_fit) { wxMemoryDC dc; Bitmap bmp(1,1); dc.SelectObject(bmp); - dc.SetFont(style().font.font); + dc.SetFont(style().font.toWxFont(1.0)); style().height = dc.GetCharHeight() + 2 + style().padding_top + style().padding_bottom; } } diff --git a/src/render/text/font.cpp b/src/render/text/font.cpp index 16473a78..87e52cc2 100644 --- a/src/render/text/font.cpp +++ b/src/render/text/font.cpp @@ -13,7 +13,7 @@ void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const { if ((what & draw_as) != draw_as) return; // don't draw - dc.SetFont(font->font, font->size * scale); + dc.SetFont(*font, scale); // draw shadow String text = content.substr(start - this->start, end - start); if (!text.empty() && text.GetChar(text.size() - 1) == _('\n')) { @@ -30,7 +30,7 @@ void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, co void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector& out) const { // font - dc.SetFont(font->font, font->size * scale); + dc.SetFont(*font, scale); // find sizes & breaks double prev_width = 0; for (size_t i = start ; i < end ; ++i) { @@ -45,8 +45,8 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector& } double FontTextElement::minScale() const { - return min(font->size, font->scale_down_to) / max(0.01, font->size); + return min(font->size(), font->scale_down_to) / max(0.01, font->size()); } double FontTextElement::scaleStep() const { - return 1. / max(font->size, 1.); + return 1. / max(font->size(), 1.); } diff --git a/src/render/text/viewer.cpp b/src/render/text/viewer.cpp index e8ad1329..17fa636b 100644 --- a/src/render/text/viewer.cpp +++ b/src/render/text/viewer.cpp @@ -368,7 +368,7 @@ void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle if (style.always_symbol && style.symbol_font.valid()) { lines[0].line_height = style.symbol_font.font->defaultSymbolSize(ctx, style.symbol_font.size).height; } else { - dc.SetFont(style.font.font); + dc.SetFont(style.font, scale); lines[0].line_height = dc.GetTextExtent(_(" ")).height; } } @@ -378,7 +378,7 @@ void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle // HACK : fix empty first line before , do this after align, so layout is not affected if (lines.size() > 1 && lines[0].line_height == 0) { - dc.SetFont(style.font.font); + dc.SetFont(style.font, scale); double h = dc.GetCharHeight(); lines[0].line_height = h; lines[0].top -= h; diff --git a/src/render/value/information.cpp b/src/render/value/information.cpp index 833e6813..3df86daf 100644 --- a/src/render/value/information.cpp +++ b/src/render/value/information.cpp @@ -19,7 +19,7 @@ void InfoValueViewer::draw(RotatedDC& dc) { } else { dc.SetTextForeground(style().font.color); dc.SetBrush(style().background_color); - dc.SetFont(style().font.font, style().font.size); + dc.SetFont(style().font, 1.0); } // draw background RealRect rect = style().getRect(); diff --git a/src/util/rotation.cpp b/src/util/rotation.cpp index a7573c6a..78adc6d7 100644 --- a/src/util/rotation.cpp +++ b/src/util/rotation.cpp @@ -8,6 +8,7 @@ #include #include +#include // ----------------------------------------------------------------------------- : Rotation @@ -179,19 +180,20 @@ void RotatedDC::SetTextForeground(const Color& color) { dc.SetTextForeground(col void RotatedDC::SetLogicalFunction(int function) { dc.SetLogicalFunction(function); } void RotatedDC::SetFont(const wxFont& font) { - if (quality == QUALITY_LOW) { + if (quality == QUALITY_LOW && zoom == 1) { dc.SetFont(font); } else { - SetFont(font, font.GetPointSize()); + wxFont scaled = font; + if (quality == QUALITY_LOW) { + scaled.SetPointSize((int) trS(font.GetPointSize())); + } else { + scaled.SetPointSize((int) (trS(font.GetPointSize()) * text_scaling)); + } + dc.SetFont(scaled); } } -void RotatedDC::SetFont(wxFont font, double size) { - if (quality == QUALITY_LOW) { - font.SetPointSize((int) trS(size)); - } else { - font.SetPointSize((int) (trS(size) * text_scaling)); - } - dc.SetFont(font); +void RotatedDC::SetFont(const Font& font, double scale) { + dc.SetFont(font.toWxFont(trS(scale) * (quality == QUALITY_LOW ? 1 : text_scaling))); } double RotatedDC::getFontSizeStep() const { diff --git a/src/util/rotation.hpp b/src/util/rotation.hpp index d3c383b1..583c001c 100644 --- a/src/util/rotation.hpp +++ b/src/util/rotation.hpp @@ -13,6 +13,8 @@ #include #include +class Font; + // ----------------------------------------------------------------------------- : Rotation /// An object that can rotate coordinates inside a specified rectangle @@ -158,8 +160,8 @@ class RotatedDC : public Rotation { void SetFont(const wxFont& font); /// Set the font, scales for zoom and high_quality - /** The font will get the given (internal) point size */ - void SetFont(wxFont font, double size); + /** The font size will be multiplied by 'scale' */ + void SetFont(const Font& font, double scale); /// Steps to use when decrementing font size double getFontSizeStep() const;