mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
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
This commit is contained in:
@@ -26,6 +26,8 @@ IMPLEMENT_REFLECTION(SymbolField) {
|
||||
|
||||
IMPLEMENT_REFLECTION(SymbolStyle) {
|
||||
REFLECT_BASE(Style);
|
||||
REFLECT(min_aspect_ratio);
|
||||
REFLECT(max_aspect_ratio);
|
||||
REFLECT(variations);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<SymbolVariationP> variations; ///< Different variantions of the same symbol
|
||||
|
||||
|
||||
@@ -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 <data/format/image_to_symbol.hpp>
|
||||
#include <gfx/bezier.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -371,7 +371,8 @@ Image SymbolToImage::generate(const Options& opt) const {
|
||||
} else {
|
||||
the_symbol = opt.local_package->readFile<SymbolP>(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<const SymbolToImage*>(&that);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -104,10 +104,6 @@ class CardViewer::OverdrawDC : private wxClientDC, public wxBufferedDC {
|
||||
: wxClientDC(window)
|
||||
{
|
||||
wxBufferedDC::Init((wxClientDC*)this, window->buffer);
|
||||
wxBufferedDC::BeginDrawing();
|
||||
}
|
||||
~OverdrawDC() {
|
||||
wxBufferedDC::EndDrawing();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+17
-15
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,10 +27,13 @@ void SymbolValueViewer::draw(RotatedDC& dc) {
|
||||
try {
|
||||
// load symbol
|
||||
SymbolP symbol = getSet().readFile<SymbolP>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
// <a>ty-<b>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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user