From d5908197620420cc12a19f544fcc13053a14f6f5 Mon Sep 17 00:00:00 2001 From: twanvl Date: Thu, 12 Jul 2007 17:01:07 +0000 Subject: [PATCH] Removed last of the BeginDrawing/EndDrawing calls; Added english_number_ordinal script function; Working on symbols with a different aspect ratio (i.e. wider/smaller symbols) git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@558 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/field/symbol.cpp | 2 ++ src/data/field/symbol.hpp | 7 +++++- src/data/format/image_to_symbol.cpp | 7 ++++++ src/data/symbol.cpp | 11 ++++++++++ src/data/symbol.hpp | 3 +++ src/gfx/generated_image.cpp | 3 ++- src/gui/about_window.cpp | 4 ---- src/gui/control/card_viewer.cpp | 4 ---- src/gui/drop_down_list.cpp | 2 -- src/gui/image_slice_window.cpp | 4 ---- src/gui/set/panel.hpp | 6 ++--- src/gui/set/style_panel.cpp | 4 ++-- src/gui/symbol/control.cpp | 32 ++++++++++++++------------- src/gui/symbol/part_list.cpp | 6 ++--- src/render/symbol/filter.cpp | 8 +++---- src/render/symbol/filter.hpp | 2 +- src/render/symbol/viewer.cpp | 29 ++++++++++++++++++++---- src/render/symbol/viewer.hpp | 3 ++- src/render/text/viewer.cpp | 6 +++-- src/render/value/symbol.cpp | 11 +++++++--- src/script/functions/english.cpp | 34 +++++++++++++++++++++++++++++ src/util/rotation.hpp | 3 +++ 22 files changed, 137 insertions(+), 54 deletions(-) diff --git a/src/data/field/symbol.cpp b/src/data/field/symbol.cpp index c2ffe774..7984fef9 100644 --- a/src/data/field/symbol.cpp +++ b/src/data/field/symbol.cpp @@ -26,6 +26,8 @@ IMPLEMENT_REFLECTION(SymbolField) { IMPLEMENT_REFLECTION(SymbolStyle) { REFLECT_BASE(Style); + REFLECT(min_aspect_ratio); + REFLECT(max_aspect_ratio); REFLECT(variations); } diff --git a/src/data/field/symbol.hpp b/src/data/field/symbol.hpp index 4d37001e..a99c319e 100644 --- a/src/data/field/symbol.hpp +++ b/src/data/field/symbol.hpp @@ -37,8 +37,13 @@ class SymbolField : public Field { /// The Style for a SymbolField class SymbolStyle : public Style { public: - inline SymbolStyle(const SymbolFieldP& field) : Style(field) {} + inline SymbolStyle(const SymbolFieldP& field) + : Style(field) + , min_aspect_ratio(1), max_aspect_ratio(1) + {} DECLARE_STYLE_TYPE(Symbol); + double min_aspect_ratio; + double max_aspect_ratio; ///< Bounds for the symbol's aspect ratio vector variations; ///< Different variantions of the same symbol diff --git a/src/data/format/image_to_symbol.cpp b/src/data/format/image_to_symbol.cpp index cbf2ba2d..1a505b06 100644 --- a/src/data/format/image_to_symbol.cpp +++ b/src/data/format/image_to_symbol.cpp @@ -6,6 +6,13 @@ // ----------------------------------------------------------------------------- : Includes +#if defined(_MSC_VER) && _MSC_VER >= 1400 + // VS 8 has the audacity to give a warning about fill_n + // That is both STUPID and WRONG, so disable that warning + // This has to be done before includes, because the warning is reported in standard headers! + #pragma warning(disable:4996) +#endif + #include #include #include diff --git a/src/data/symbol.cpp b/src/data/symbol.cpp index 17857f66..388999d1 100644 --- a/src/data/symbol.cpp +++ b/src/data/symbol.cpp @@ -280,6 +280,17 @@ IMPLEMENT_REFLECTION(Symbol) { REFLECT_IF_READING calculateBoundsNonRec(); } +double Symbol::aspectRatio() const { + double margin_x = min(0.4999, max(0., min(min_pos.x, 1-max_pos.x))); + double margin_y = min(0.4999, max(0., min(min_pos.y, 1-max_pos.y))); + double delta = 2 * (margin_y - margin_x); + if (delta > 0) { + return 1 / (1 - delta); + } else { + return 1 + delta; + } +} + // ----------------------------------------------------------------------------- : Default symbol // A default symbol part, a square, moved by d diff --git a/src/data/symbol.hpp b/src/data/symbol.hpp index b981bd9b..018fe484 100644 --- a/src/data/symbol.hpp +++ b/src/data/symbol.hpp @@ -257,6 +257,9 @@ class Symbol : public SymbolGroup { /// Actions performed on this symbol and the parts in it ActionStack actions; + /// Determine the aspect ratio best suited for this symbol + double aspectRatio() const; + DECLARE_REFLECTION(); }; diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index 62958d77..d6a8706b 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -371,7 +371,8 @@ Image SymbolToImage::generate(const Options& opt) const { } else { the_symbol = opt.local_package->readFile(filename); } - return render_symbol(the_symbol, *variation->filter, variation->border_radius, max(100, 3*max(opt.width,opt.height))); + int size = max(100, 3*max(opt.width,opt.height)); + return render_symbol(the_symbol, *variation->filter, variation->border_radius, size, size); } bool SymbolToImage::operator == (const GeneratedImage& that) const { const SymbolToImage* that2 = dynamic_cast(&that); diff --git a/src/gui/about_window.cpp b/src/gui/about_window.cpp index 810ce300..bf12344d 100644 --- a/src/gui/about_window.cpp +++ b/src/gui/about_window.cpp @@ -26,9 +26,7 @@ AboutWindow::AboutWindow(Window* parent) void AboutWindow::onPaint(wxPaintEvent& ev) { wxBufferedPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } void AboutWindow::draw(DC& dc) { @@ -151,9 +149,7 @@ void HoverButton::refreshIfNeeded() { void HoverButton::onPaint(wxPaintEvent&) { wxPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } void HoverButton::draw(DC& dc) { // clear background (for transparent button images) diff --git a/src/gui/control/card_viewer.cpp b/src/gui/control/card_viewer.cpp index 7f2e7278..d127e91c 100644 --- a/src/gui/control/card_viewer.cpp +++ b/src/gui/control/card_viewer.cpp @@ -104,10 +104,6 @@ class CardViewer::OverdrawDC : private wxClientDC, public wxBufferedDC { : wxClientDC(window) { wxBufferedDC::Init((wxClientDC*)this, window->buffer); - wxBufferedDC::BeginDrawing(); - } - ~OverdrawDC() { - wxBufferedDC::EndDrawing(); } }; diff --git a/src/gui/drop_down_list.cpp b/src/gui/drop_down_list.cpp index b4148d91..4878800e 100644 --- a/src/gui/drop_down_list.cpp +++ b/src/gui/drop_down_list.cpp @@ -232,9 +232,7 @@ void DropDownList::redrawArrowOnParent() { void DropDownList::onPaint(wxPaintEvent&) { wxBufferedPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } void DropDownList::draw(DC& dc) { diff --git a/src/gui/image_slice_window.cpp b/src/gui/image_slice_window.cpp index f01d37fa..7a62a9e1 100644 --- a/src/gui/image_slice_window.cpp +++ b/src/gui/image_slice_window.cpp @@ -353,9 +353,7 @@ wxSize ImageSlicePreview::DoGetBestSize() const { void ImageSlicePreview::onPaint(wxPaintEvent&) { wxPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } void ImageSlicePreview::draw(DC& dc) { if (!bitmap.Ok()) { @@ -436,9 +434,7 @@ void ImageSliceSelector::onSize(wxSizeEvent&) { void ImageSliceSelector::onPaint(wxPaintEvent&) { wxBufferedPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } void ImageSliceSelector::draw(DC& dc) { if (!bitmap.Ok()) createBitmap(); diff --git a/src/gui/set/panel.hpp b/src/gui/set/panel.hpp index 2c0309bc..0e5edd24 100644 --- a/src/gui/set/panel.hpp +++ b/src/gui/set/panel.hpp @@ -66,9 +66,9 @@ class SetWindowPanel : public wxPanel, public SetView { virtual bool doReplaceAll(wxFindReplaceData&) { return false; } ///< Replace all matches // --------------------------------------------------- : Selection - virtual CardP selectedCard() const; ///< Return the currently selected card, or CardP() - virtual void selectCard(const CardP& card) {} ///< Switch the view to another card - virtual void selectFirstCard() {} ///< Switch the view to the first card + virtual CardP selectedCard() const; ///< Return the currently selected card, or CardP() + virtual void selectCard(const CardP& card) {} ///< Switch the view to another card, can be null + virtual void selectFirstCard() {} ///< Switch the view to the first card }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/set/style_panel.cpp b/src/gui/set/style_panel.cpp index 05646ddc..df5f4530 100644 --- a/src/gui/set/style_panel.cpp +++ b/src/gui/set/style_panel.cpp @@ -84,7 +84,7 @@ void StylePanel::onAction(const Action& action, bool undone) { } use_for_all->Enable(card && card->stylesheet); use_custom_options->Enable(card); - use_custom_options->SetValue(card->has_styling); + use_custom_options->SetValue(card ? card->has_styling : false); } // ----------------------------------------------------------------------------- : Selection @@ -97,7 +97,7 @@ void StylePanel::selectCard(const CardP& card) { list->select(set->stylesheetFor(card).name(), false); use_for_all->Enable(card && card->stylesheet); use_custom_options->Enable(card); - use_custom_options->SetValue(card->has_styling); + use_custom_options->SetValue(card ? card->has_styling : false); } // ----------------------------------------------------------------------------- : Events diff --git a/src/gui/symbol/control.cpp b/src/gui/symbol/control.cpp index bf6c9b91..f958f3fb 100644 --- a/src/gui/symbol/control.cpp +++ b/src/gui/symbol/control.cpp @@ -177,20 +177,18 @@ void SymbolControl::draw(DC& dc) { SymbolViewer::draw(dc); // draw grid if (settings.symbol_grid) { + RotatedDC rdc(dc, rotation, QUALITY_LOW); double lines = settings.symbol_grid_size; - double end = rotation.trS(1); for (int i = 0 ; i <= lines ; ++i) { - int x = (int) floor(rotation.trS(i/lines-0.0001)); - //dc.SetPen(Color(0, i%5 == 0 ? 64 : 31, 0)); - //dc.SetPen(Color(i%5 == 0 ? 64 : 31, 0, 0)); - dc.SetLogicalFunction(wxAND); - dc.SetPen(i%5 == 0 ? Color(191,255,191) : Color(191, 255, 191)); - dc.DrawLine(x, 0, x, end); - dc.DrawLine(0, x, end, x); - dc.SetLogicalFunction(wxOR); - dc.SetPen(i%5 == 0 ? Color(0,63,0) : Color(0, 31, 0)); - dc.DrawLine(x, 0, x, end); - dc.DrawLine(0, x, end, x); + double x = (double)i/lines; + rdc.SetLogicalFunction(wxAND); + rdc.SetPen(i%5 == 0 ? Color(191,255,191) : Color(191, 255, 191)); + rdc.DrawLine(RealPoint(0,x), RealPoint(1,x)); + rdc.DrawLine(RealPoint(x,0), RealPoint(x,1)); + rdc.SetLogicalFunction(wxOR); + rdc.SetPen(i%5 == 0 ? Color(0,63,0) : Color(0, 31, 0)); + rdc.DrawLine(RealPoint(0,x), RealPoint(1,x)); + rdc.DrawLine(RealPoint(x,0), RealPoint(x,1)); } dc.SetLogicalFunction(wxCOPY); } @@ -201,9 +199,7 @@ void SymbolControl::draw(DC& dc) { } void SymbolControl::onPaint(wxPaintEvent&) { wxBufferedPaintDC dc(this); - dc.BeginDrawing(); draw(dc); - dc.EndDrawing(); } // ----------------------------------------------------------------------------- : Events @@ -256,7 +252,13 @@ void SymbolControl::onChar(wxKeyEvent& ev) { void SymbolControl::onSize(wxSizeEvent& ev) { wxSize s = GetClientSize(); - setZoom(min(s.GetWidth(), s.GetHeight())); + int zoom = min(s.x, s.y); + setZoom(zoom); + if (s.x > zoom) { + setOrigin(Vector2D((s.x - zoom) * 0.5, 0)); + } else { + setOrigin(Vector2D(0, (s.y - zoom) * 0.5)); + } Refresh(false); } void SymbolControl::onUpdateUI(wxUpdateUIEvent& ev) { diff --git a/src/gui/symbol/part_list.cpp b/src/gui/symbol/part_list.cpp index 994326c7..41e7a385 100644 --- a/src/gui/symbol/part_list.cpp +++ b/src/gui/symbol/part_list.cpp @@ -497,13 +497,13 @@ const Image& SymbolPartList::itemPreview(int i, const SymbolPartP& part) { if (s->combine == SYMBOL_COMBINE_SUBTRACT) { // temporarily render using subtract instead, otherwise we don't see anything s->combine = SYMBOL_COMBINE_BORDER; - img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, true); + img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, ITEM_HEIGHT * 4, true); s->combine = SYMBOL_COMBINE_SUBTRACT; } else { - img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, true); + img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, ITEM_HEIGHT * 4, true); } } else { - img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, true); + img = render_symbol(sym, filter, 0.08, ITEM_HEIGHT * 4, ITEM_HEIGHT * 4, true); } resample(img, p.image); p.up_to_date = true; diff --git a/src/render/symbol/filter.cpp b/src/render/symbol/filter.cpp index 228d22a2..4e818d9b 100644 --- a/src/render/symbol/filter.cpp +++ b/src/render/symbol/filter.cpp @@ -47,8 +47,8 @@ void filter_symbol(Image& symbol, const SymbolFilter& filter) { alpha = (Byte*) malloc(width * height); symbol.SetAlpha(alpha); } - for (UInt y = 0 ; y < width ; ++y) { - for (UInt x = 0 ; x < height ; ++x) { + for (UInt y = 0 ; y < height ; ++y) { + for (UInt x = 0 ; x < width ; ++x) { // Determine set // green -> border or outside // green+red=white -> border @@ -71,8 +71,8 @@ void filter_symbol(Image& symbol, const SymbolFilter& filter) { } } -Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius, int size, bool edit_hints) { - Image i = render_symbol(symbol, border_radius, size, edit_hints); +Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius, int width, int height, bool edit_hints) { + Image i = render_symbol(symbol, border_radius, width, height, edit_hints); filter_symbol(i, filter); return i; } diff --git a/src/render/symbol/filter.hpp b/src/render/symbol/filter.hpp index 2f213761..4fd5392d 100644 --- a/src/render/symbol/filter.hpp +++ b/src/render/symbol/filter.hpp @@ -35,7 +35,7 @@ class AColor : public Color { void filter_symbol(Image& symbol, const SymbolFilter& filter); /// Render a Symbol to an Image and filter it -Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius = 0.05, int size = 100, bool edit_hints = false); +Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius = 0.05, int width = 100, int height = 100, bool edit_hints = false); /// Is a point inside a symbol? enum SymbolSet diff --git a/src/render/symbol/viewer.cpp b/src/render/symbol/viewer.cpp index c305ff35..7357fc8f 100644 --- a/src/render/symbol/viewer.cpp +++ b/src/render/symbol/viewer.cpp @@ -14,13 +14,29 @@ DECLARE_TYPEOF_COLLECTION(SymbolPartP); // ----------------------------------------------------------------------------- : Simple rendering -Image render_symbol(const SymbolP& symbol, double border_radius, int size, bool editing_hints) { - SymbolViewer viewer(symbol, size, border_radius); - Bitmap bmp(size, size); +Image render_symbol(const SymbolP& symbol, double border_radius, int width, int height, bool editing_hints) { + SymbolViewer viewer(symbol, editing_hints, width, border_radius); + // limit width/height ratio to aspect ratio of symbol + double ar = symbol->aspectRatio(); + double par = (double)width/height; + if (par > ar && ar > 1) { + width = height * ar; + } else if (par < ar && ar < 1) { + height = width / ar; + } + if (width > height) { + viewer.setZoom(width); + viewer.setOrigin(Vector2D(0,-(width-height) * 0.5)); + viewer.border_radius *= (double)height / width; + } else { + viewer.setZoom(height); + viewer.setOrigin(Vector2D(-(height-width) * 0.5,0)); + viewer.border_radius *= (double)width / height; + } + Bitmap bmp(width, height); wxMemoryDC dc; dc.SelectObject(bmp); clearDC(dc, Color(0,128,0)); - viewer.setZoom(size); viewer.draw(dc); dc.SelectObject(wxNullBitmap); return bmp.ConvertToImage(); @@ -40,8 +56,13 @@ SymbolViewer::SymbolViewer(const SymbolP& symbol, bool editing_hints, double siz void SymbolViewer::setZoom(double zoom) { rotation.setZoom(zoom); + rotation.setOrigin(zoom * origin); multiply = Matrix2D(zoom,0, 0,zoom); } +void SymbolViewer::setOrigin(const Vector2D& origin) { + this->origin = origin; + rotation.setOrigin(origin); +} // ----------------------------------------------------------------------------- : Drawing : Combining diff --git a/src/render/symbol/viewer.hpp b/src/render/symbol/viewer.hpp index a7c0d098..b3f38840 100644 --- a/src/render/symbol/viewer.hpp +++ b/src/render/symbol/viewer.hpp @@ -17,7 +17,7 @@ // ----------------------------------------------------------------------------- : Simple rendering /// Render a Symbol to an Image -Image render_symbol(const SymbolP& symbol, double border_radius = 0.05, int size = 100, bool editing_hints = false); +Image render_symbol(const SymbolP& symbol, double border_radius = 0.05, int width = 100, int height = 100, bool editing_hints = false); // ----------------------------------------------------------------------------- : Symbol Viewer @@ -41,6 +41,7 @@ class SymbolViewer : public SymbolView { // --------------------------------------------------- : Point translation void setZoom(double zoom); + void setOrigin(const Vector2D& origin); Rotation rotation; ///< Object that handles rotation, scaling and translation Matrix2D multiply; ///< Scaling/rotation of actual parts diff --git a/src/render/text/viewer.cpp b/src/render/text/viewer.cpp index 59369d94..4a16e527 100644 --- a/src/render/text/viewer.cpp +++ b/src/render/text/viewer.cpp @@ -183,8 +183,10 @@ size_t TextViewer::lineEnd(size_t index) const { } struct CompareTop { - inline bool operator () (const TextViewer::Line& l, double y) const { return l.top < y; } - inline bool operator () (double y, const TextViewer::Line& l) const { return y < l.top; } + inline bool operator () (double a, double b) const { return a < b; } + inline bool operator () (const TextViewer::Line& a, double b) const { return a.top < b; } + inline bool operator () (double a, const TextViewer::Line& b) const { return a < b.top; } + inline bool operator () (const TextViewer::Line& a, const TextViewer::Line& b) const { return a.top < b.top; } }; size_t TextViewer::indexAt(const RealPoint& pos) const { // 1. find the line diff --git a/src/render/value/symbol.cpp b/src/render/value/symbol.cpp index 0ec7336c..c27f4d5c 100644 --- a/src/render/value/symbol.cpp +++ b/src/render/value/symbol.cpp @@ -27,10 +27,13 @@ void SymbolValueViewer::draw(RotatedDC& dc) { try { // load symbol SymbolP symbol = getSet().readFile(value().filename); + // aspect ratio + double ar = symbol->aspectRatio(); + ar = min(style().max_aspect_ratio, max(style().min_aspect_ratio, ar)); // render and filter variations FOR_EACH(variation, style().variations) { - Image img = render_symbol(symbol, *variation->filter, variation->border_radius); - Image resampled((int) wh, (int) wh, false); + Image img = render_symbol(symbol, *variation->filter, variation->border_radius, 100 * ar, 100); + Image resampled((int) (wh * ar), (int) wh, false); resample(img, resampled); symbols.push_back(Bitmap(resampled)); } @@ -39,9 +42,11 @@ void SymbolValueViewer::draw(RotatedDC& dc) { } } // draw image, if any + int x = 0; for (size_t i = 0 ; i < symbols.size() ; ++i) { // todo : labels? - dc.DrawBitmap(symbols[i], style().getPos() + RealSize(i * (wh + 2), 0)); + dc.DrawBitmap(symbols[i], style().getPos() + RealSize(x, 0)); + x += symbols[i].GetWidth() + 2; } } diff --git a/src/script/functions/english.cpp b/src/script/functions/english.cpp index e2daef3d..1bf73c9e 100644 --- a/src/script/functions/english.cpp +++ b/src/script/functions/english.cpp @@ -62,6 +62,35 @@ String english_number(int i) { } } } + +/// Write an ordinal number using words, for example 23 -> "twenty-third" +String english_ordinal(int i) { + switch (i) { + case 1: return _("first"); + case 2: return _("second"); + case 3: return _("third"); + case 5: return _("fifth"); + case 8: return _("eighth"); + case 9: return _("ninth"); + case 11: return _("eleventh"); + case 12: return _("twelfth"); + default: { + if (i <= 0 || i >= 100) { + // number too large, keep as digits + return String::Format(_("%dth"), i); + } else if (i < 20) { + return english_number(i) + _("th"); + } else if (i % 10 == 0) { + String num = english_number(i); + return num.substr(0,num.size()-1) + _("ieth"); // twentieth + } else { + // ty-th + return english_number(i/10*10) + _("-") + english_ordinal(i%10); + } + } + } +} + /// Write a number using words, use "a" for 1 String english_number_a(int i) { if (i == 1) return _("a"); @@ -114,6 +143,10 @@ SCRIPT_FUNCTION(english_number_multiple) { SCRIPT_PARAM(String, input); SCRIPT_RETURN(do_english_num(input, english_number_multiple)); } +SCRIPT_FUNCTION(english_number_ordinal) { + SCRIPT_PARAM(String, input); + SCRIPT_RETURN(do_english_num(input, english_ordinal)); +} // ----------------------------------------------------------------------------- : Singular/plural @@ -284,6 +317,7 @@ void init_script_english_functions(Context& ctx) { ctx.setVariable(_("english number"), script_english_number); ctx.setVariable(_("english number a"), script_english_number_a); ctx.setVariable(_("english number multiple"), script_english_number_multiple); + ctx.setVariable(_("english number ordinal"), script_english_number_ordinal); ctx.setVariable(_("english singular"), script_english_singular); ctx.setVariable(_("english plural"), script_english_plural); ctx.setVariable(_("process english hints"), script_process_english_hints); diff --git a/src/util/rotation.hpp b/src/util/rotation.hpp index 4fb67fa7..f47e66aa 100644 --- a/src/util/rotation.hpp +++ b/src/util/rotation.hpp @@ -34,6 +34,9 @@ class Rotation { inline void setZoom(double z) { zoomX = zoomY = z; } /// Change the angle void setAngle(int a); + /// Change the origin + inline void setOrigin(const RealPoint& o) { origin = o; } + /// The internal size inline RealSize getInternalSize() const { return trInvNoNeg(size); } /// The intarnal rectangle (origin at (0,0))