Commit 1a9722fb authored by twanvl's avatar twanvl

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)
parent c8636d46
......@@ -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
......
......@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment