diff --git a/data/magic-new.mse-style/style b/data/magic-new.mse-style/style index b14badba..bed33e5e 100644 --- a/data/magic-new.mse-style/style +++ b/data/magic-new.mse-style/style @@ -199,10 +199,10 @@ card style: type: left: 35 top : 298 - width: 286 + width: { 308 - max(22,card_style.rarity.content_width) } height: 20 alignment: top shrink-overflow - z index: 1 + z index: 2 padding top: 2 font: name: Matrix @@ -211,12 +211,13 @@ card style: separator color: rgb(128,128,128) rarity: - left: 320 + right: 342 top : 297 - width: 22 + width: 44 height: 22 z index: 1 render style: image + alignment: middle right choice images: # Images based on the set symbol basic land: script: symbol_variation(symbol: set.symbol, variation: "common") diff --git a/src/data/field.cpp b/src/data/field.cpp index 28ed6311..c678a166 100644 --- a/src/data/field.cpp +++ b/src/data/field.cpp @@ -170,7 +170,11 @@ void Style::checkContentDependencies(Context& ctx, const Dependency& dep) const } void Style::markDependencyMember(const String& name, const Dependency& dep) const { - // no content specific properties here + // mark dependencies on content + if (dep.type == DEP_DUMMY && dep.index == false && starts_with(name, _("content "))) { + // anything that starts with "content_" is a content property + const_cast(dep).index = true; + } } void mark_dependency_member(const Style& style, const String& name, const Dependency& dep) { diff --git a/src/data/field/choice.cpp b/src/data/field/choice.cpp index 7129a81d..39472a0e 100644 --- a/src/data/field/choice.cpp +++ b/src/data/field/choice.cpp @@ -283,6 +283,12 @@ IMPLEMENT_REFLECTION_ENUM(ChoiceRenderStyle) { VALUE_N("both list", RENDER_BOTH_LIST); } +template void reflect_content(T& tag, const ChoiceStyle& cs) {} +template <> void reflect_content(GetMember& tag, const ChoiceStyle& cs) { + REFLECT_N("content_width", cs.content_width); + REFLECT_N("content_height", cs.content_height); +} + IMPLEMENT_REFLECTION(ChoiceStyle) { REFLECT_ALIAS(300, "card list colors", "colors card list"); REFLECT_BASE(Style); @@ -295,6 +301,7 @@ IMPLEMENT_REFLECTION(ChoiceStyle) { REFLECT(font); REFLECT(image); REFLECT(choice_images); + reflect_content(tag, *this); } // ----------------------------------------------------------------------------- : ChoiceValue diff --git a/src/data/field/choice.hpp b/src/data/field/choice.hpp index 6961ac1b..dcb9fa00 100644 --- a/src/data/field/choice.hpp +++ b/src/data/field/choice.hpp @@ -155,6 +155,8 @@ class ChoiceStyle : public Style { int angle; ///< Angle by which the images are rotated wxImageList* thumbnails; ///< Thumbnails for the choices vector thumbnails_status; ///< Which thumbnails are up to date? + // information from image rendering + double content_width, content_height; ///< Size of the rendered image/text /// Load the mask image, if it's not already done void loadMask(Package& pkg); diff --git a/src/data/field/text.cpp b/src/data/field/text.cpp index 824942ea..df70d3f4 100644 --- a/src/data/field/text.cpp +++ b/src/data/field/text.cpp @@ -81,14 +81,6 @@ void TextStyle::checkContentDependencies(Context& ctx, const Dependency& dep) co Style ::checkContentDependencies(ctx, dep); alignment.initDependencies(ctx, dep); } -void TextStyle::markDependencyMember(const String& name, const Dependency& dep) const { - Style::markDependencyMember(name, dep); - // mark dependencies on content - if (dep.type == DEP_DUMMY && dep.index == false && - (name == _("content width") || name == _("content height") || name == _("content lines"))) { - const_cast(dep).index = true; - } -} template void reflect_content(T& tag, const TextStyle& ts) {} template <> void reflect_content(GetMember& tag, const TextStyle& ts) { diff --git a/src/data/field/text.hpp b/src/data/field/text.hpp index ce0f1573..c2a41a33 100644 --- a/src/data/field/text.hpp +++ b/src/data/field/text.hpp @@ -75,7 +75,6 @@ class TextStyle : public Style { virtual bool update(Context&); virtual void initDependencies(Context&, const Dependency&) const; virtual void checkContentDependencies(Context&, const Dependency&) const; - virtual void markDependencyMember(const String& name, const Dependency&) const; /// The rotation to use when drawing inline Rotation getRotation() const { diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index f1046eee..89f593e9 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -387,7 +387,13 @@ Image SymbolToImage::generate(const Options& opt) const { the_symbol = opt.local_package->readFile(filename); } int size = max(100, 3*max(opt.width,opt.height)); - return render_symbol(the_symbol, *variation->filter, variation->border_radius, size, size); + if (opt.width <= 1 || opt.height <= 1) { + return render_symbol(the_symbol, *variation->filter, variation->border_radius, size, size); + } else { + int width = size * opt.width / max(opt.width,opt.height); + int height = size * opt.height / max(opt.width,opt.height); + return render_symbol(the_symbol, *variation->filter, variation->border_radius, width, height, false, true); + } } bool SymbolToImage::operator == (const GeneratedImage& that) const { const SymbolToImage* that2 = dynamic_cast(&that); diff --git a/src/render/symbol/filter.cpp b/src/render/symbol/filter.cpp index 4e818d9b..c3a38680 100644 --- a/src/render/symbol/filter.cpp +++ b/src/render/symbol/filter.cpp @@ -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 width, int height, bool edit_hints) { - Image i = render_symbol(symbol, border_radius, width, height, edit_hints); +Image render_symbol(const SymbolP& symbol, const SymbolFilter& filter, double border_radius, int width, int height, bool edit_hints, bool allow_smaller) { + Image i = render_symbol(symbol, border_radius, width, height, edit_hints, allow_smaller); filter_symbol(i, filter); return i; } diff --git a/src/render/symbol/filter.hpp b/src/render/symbol/filter.hpp index 4fd5392d..ccab4e04 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 width = 100, int height = 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, bool allow_smaller = false); /// Is a point inside a symbol? enum SymbolSet diff --git a/src/render/symbol/viewer.cpp b/src/render/symbol/viewer.cpp index d52c25be..3b5924a1 100644 --- a/src/render/symbol/viewer.cpp +++ b/src/render/symbol/viewer.cpp @@ -14,14 +14,14 @@ DECLARE_TYPEOF_COLLECTION(SymbolPartP); // ----------------------------------------------------------------------------- : Simple rendering -Image render_symbol(const SymbolP& symbol, double border_radius, int width, int height, bool editing_hints) { +Image render_symbol(const SymbolP& symbol, double border_radius, int width, int height, bool editing_hints, bool allow_smaller) { 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) { + if (par > ar && (ar > 1 || (allow_smaller && height < width))) { width = height * ar; - } else if (par < ar && ar < 1) { + } else if (par < ar && (ar < 1 || (allow_smaller && width < height))) { height = width / ar; } if (width > height) { diff --git a/src/render/symbol/viewer.hpp b/src/render/symbol/viewer.hpp index b3f38840..0be13b31 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 width = 100, int height = 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, bool allow_smaller = false); // ----------------------------------------------------------------------------- : Symbol Viewer diff --git a/src/render/value/choice.cpp b/src/render/value/choice.cpp index 8b9d72cc..ab2f9540 100644 --- a/src/render/value/choice.cpp +++ b/src/render/value/choice.cpp @@ -12,6 +12,40 @@ // ----------------------------------------------------------------------------- : ChoiceValueViewer +bool ChoiceValueViewer::prepare(RotatedDC& dc) { + if (style().render_style & RENDER_IMAGE) { + style().initImage(); + ScriptableImage& img = style().image; + Context& ctx = viewer.getContext(); + ctx.setVariable(_("input"), to_script(value().value())); + img.update(ctx); + //generate + if (img.isReady()) { + GeneratedImage::Options img_options(0,0, viewer.stylesheet.get(), &getSet()); + if (nativeLook()) { + img_options.width = img_options.height = 16; + img_options.preserve_aspect = ASPECT_BORDER; + } else if(style().render_style & RENDER_TEXT) { + // also drawing text, use original size + } else { + img_options.width = (int) dc.trX(style().width); + img_options.height = (int) dc.trY(style().height); + img_options.preserve_aspect = (style().alignment & ALIGN_STRETCH) ? ASPECT_STRETCH : ASPECT_FIT; + } + // don't worry we cache the image + Image image = img.generate(img_options, true); + // store content properties + if (style().content_width != image.GetWidth() || + style().content_height != image.GetHeight()) { + style().content_width = image.GetWidth(); + style().content_height = image.GetHeight(); + return true; + } + } + } + return false; +} + void ChoiceValueViewer::draw(RotatedDC& dc) { drawFieldBorder(dc); if (style().render_style & RENDER_HIDDEN) return; @@ -19,14 +53,7 @@ void ChoiceValueViewer::draw(RotatedDC& dc) { double margin = 0; if (style().render_style & RENDER_IMAGE) { // draw image -// map::iterator it = style().choice_images.find(cannocial_name_form(value().value())); -// if (it != style().choice_images.end() && it->second.isReady()) { -// ScriptableImage& img = it->second; - style().initImage(); ScriptableImage& img = style().image; - Context& ctx = viewer.getContext(); - ctx.setVariable(_("input"), to_script(value().value())); - img.update(ctx); if (img.isReady()) { GeneratedImage::Options img_options(0,0, viewer.stylesheet.get(), &getSet()); if (nativeLook()) { diff --git a/src/render/value/choice.hpp b/src/render/value/choice.hpp index 2f13b147..287f8c9d 100644 --- a/src/render/value/choice.hpp +++ b/src/render/value/choice.hpp @@ -20,6 +20,7 @@ class ChoiceValueViewer : public ValueViewer { public: DECLARE_VALUE_VIEWER(Choice) : ValueViewer(parent,style) {} + virtual bool prepare(RotatedDC& dc); virtual void draw(RotatedDC& dc); virtual void onStyleChange(bool); }; diff --git a/src/render/value/symbol.cpp b/src/render/value/symbol.cpp index c27f4d5c..686f1740 100644 --- a/src/render/value/symbol.cpp +++ b/src/render/value/symbol.cpp @@ -32,7 +32,7 @@ void SymbolValueViewer::draw(RotatedDC& dc) { 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, 100 * ar, 100); + Image img = render_symbol(symbol, *variation->filter, variation->border_radius, 200 * ar, 200); Image resampled((int) (wh * ar), (int) wh, false); resample(img, resampled); symbols.push_back(Bitmap(resampled));