Merge pull request #34 from haganbmj/dfc_images

feat: script functions for generating and manipulating card images
This commit is contained in:
Brendan Hagan
2022-08-15 19:50:08 -04:00
committed by GitHub
20 changed files with 203 additions and 23 deletions
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: 关键词 keyword: 关键词
keywords: 关键词 keywords: 关键词
#_ADD pack: pack type #_ADD pack: pack type
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: 图形 shape: 图形
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: 關鍵詞 keyword: 關鍵詞
keywords: 關鍵詞 keywords: 關鍵詞
#_ADD pack: pack type #_ADD pack: pack type
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: 圖形 shape: 圖形
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: keyword keyword: keyword
keywords: keywords keywords: keywords
pack: pack type pack: pack type
card region: card region
card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: shape shape: shape
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: keyword keyword: keyword
keywords: keywords keywords: keywords
pack: pack type pack: pack type
card region: card region
card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: shape shape: shape
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: keyword keyword: keyword
keywords: keywords keywords: keywords
pack: pack type pack: pack type
card region: card region
card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: shape shape: shape
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: palabra clave keyword: palabra clave
keywords: palabras clave keywords: palabras clave
pack: mazo pack: mazo
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: forma shape: forma
+2
View File
@@ -898,6 +898,8 @@ type:
circle: cercle circle: cercle
ellipse: ellipse ellipse: ellipse
pack: type de pack pack: type de pack
#_ADD card region: card region
#_ADD card regions: card regions
square: carré square: carré
rectangle: rectangle rectangle: rectangle
triangle: triangle triangle: triangle
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: parola-chiave keyword: parola-chiave
keywords: parole chiave keywords: parole chiave
pack: tipo busta pack: tipo busta
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: forma shape: forma
+2
View File
@@ -889,6 +889,8 @@ type:
keyword: キーワード keyword: キーワード
keywords: キーワード keywords: キーワード
#_ADD pack: pack type #_ADD pack: pack type
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: 形 shape: 形
+2
View File
@@ -924,6 +924,8 @@ type:
keyword: słowo kluczowe (keyword) keyword: słowo kluczowe (keyword)
keywords: słowa kluczowe (keywords) keywords: słowa kluczowe (keywords)
pack: rodzaj paczki (pack type) pack: rodzaj paczki (pack type)
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: kształt shape: kształt
+2
View File
@@ -891,6 +891,8 @@ type:
keyword: palavra-chave keyword: palavra-chave
keywords: palavras-chaves keywords: palavras-chaves
pack: tipo de pacote pack: tipo de pacote
#_ADD card region: card region
#_ADD card regions: card regions
# Symbol editor shapes # Symbol editor shapes
shape: forma shape: forma
+25
View File
@@ -0,0 +1,25 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#include <util/prec.hpp>
#include <data/card_region.hpp>
CardRegion::CardRegion()
: name("")
, x(0.0)
, y(0.0)
, width(0)
, height(0)
{}
CardRegion::~CardRegion() {}
IMPLEMENT_REFLECTION(CardRegion) {
REFLECT(name);
REFLECT(x);
REFLECT(y);
REFLECT(width);
REFLECT(height);
}
+34
View File
@@ -0,0 +1,34 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#pragma once
#include <util/prec.hpp>
#include <util/reflect.hpp>
#include <script/scriptable.hpp>
DECLARE_POINTER_TYPE(CardRegion);
class CardRegion : public IntrusivePtrBase<CardRegion> {
public:
CardRegion();
virtual ~CardRegion();
String name;
double x, y;
int width, height;
private:
DECLARE_REFLECTION();
};
inline String type_name(const CardRegion&) {
return _TYPE_("card region");
}
inline String type_name(const vector<CardRegionP>&) {
return _TYPE_("card regions");
}
+1 -1
View File
@@ -100,10 +100,10 @@ void export_image(const SetP& set, const CardP& card, const String& filename);
/// Generate a bitmap image of a card /// Generate a bitmap image of a card
Bitmap export_bitmap(const SetP& set, const CardP& card); Bitmap export_bitmap(const SetP& set, const CardP& card);
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians);
/// Export a set to Magic Workstation format /// Export a set to Magic Workstation format
void export_mws(Window* parent, const SetP& set); void export_mws(Window* parent, const SetP& set);
/// Export a set to Apprentice /// Export a set to Apprentice
void export_apprentice(Window* parent, const SetP& set); void export_apprentice(Window* parent, const SetP& set);
+40 -3
View File
@@ -26,14 +26,34 @@ void export_image(const SetP& set, const CardP& card, const String& filename) {
class UnzoomedDataViewer : public DataViewer { class UnzoomedDataViewer : public DataViewer {
public: public:
UnzoomedDataViewer();
UnzoomedDataViewer(double zoom, double angle);
virtual ~UnzoomedDataViewer() {}; virtual ~UnzoomedDataViewer() {};
Rotation getRotation() const override; Rotation getRotation() const override;
private: private:
double angle = 0.0; double zoom;
double angle;
bool declared_values;
}; };
UnzoomedDataViewer::UnzoomedDataViewer()
: zoom(1.0)
, angle(0.0)
, declared_values(false)
{}
UnzoomedDataViewer::UnzoomedDataViewer(const double zoom, const Radians angle = 0.0)
: zoom(zoom)
, angle(angle)
, declared_values(true)
{}
Rotation UnzoomedDataViewer::getRotation() const { Rotation UnzoomedDataViewer::getRotation() const {
if (!stylesheet) stylesheet = set->stylesheet; if (!stylesheet) stylesheet = set->stylesheet;
if (declared_values) {
return Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT);
}
double export_zoom = settings.stylesheetSettingsFor(set->stylesheetFor(card)).export_zoom(); double export_zoom = settings.stylesheetSettingsFor(set->stylesheetFor(card)).export_zoom();
bool use_viewer_rotation = !settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export(); bool use_viewer_rotation = !settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export();
@@ -46,14 +66,31 @@ Rotation UnzoomedDataViewer::getRotation() const {
Bitmap export_bitmap(const SetP& set, const CardP& card) { Bitmap export_bitmap(const SetP& set, const CardP& card) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
// create viewer
UnzoomedDataViewer viewer = UnzoomedDataViewer(); UnzoomedDataViewer viewer = UnzoomedDataViewer();
viewer.setSet(set); viewer.setSet(set);
viewer.setCard(card); viewer.setCard(card);
// size of cards // size of cards
RealSize size = viewer.getRotation().getExternalSize(); RealSize size = viewer.getRotation().getExternalSize();
// create bitmap & dc // create bitmap & dc
Bitmap bitmap((int) size.width, (int) size.height); Bitmap bitmap((int)size.width, (int)size.height);
if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap"));
wxMemoryDC dc;
dc.SelectObject(bitmap);
// draw
viewer.draw(dc);
dc.SelectObject(wxNullBitmap);
return bitmap;
}
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle = 0.0) {
if (!set) throw Error(_("no set"));
UnzoomedDataViewer viewer = UnzoomedDataViewer(zoom, angle);
viewer.setSet(set);
viewer.setCard(card);
// size of cards
RealSize size = viewer.getRotation().getExternalSize();
// create bitmap & dc
Bitmap bitmap((int)size.width, (int)size.height);
if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap")); if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap"));
wxMemoryDC dc; wxMemoryDC dc;
dc.SelectObject(bitmap); dc.SelectObject(bitmap);
+1
View File
@@ -98,6 +98,7 @@ IMPLEMENT_REFLECTION(StyleSheet) {
REFLECT(card_height); REFLECT(card_height);
REFLECT(card_dpi); REFLECT(card_dpi);
REFLECT(card_background); REFLECT(card_background);
REFLECT(card_regions);
REFLECT(init_script); REFLECT(init_script);
// styling // styling
REFLECT(styling_fields); REFLECT(styling_fields);
+6
View File
@@ -12,11 +12,16 @@
#include <util/io/package.hpp> #include <util/io/package.hpp>
#include <util/real_point.hpp> #include <util/real_point.hpp>
#include <script/scriptable.hpp> #include <script/scriptable.hpp>
// This isn't strictly needed for this file,
// but CardRegion needs to be referenced from _somewhere_ in the codebase for compilation reasons.
// Eventually if somewhere else is using the type then this can be removed.
#include <data/card_region.hpp>
DECLARE_POINTER_TYPE(Game); DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet); DECLARE_POINTER_TYPE(StyleSheet);
DECLARE_POINTER_TYPE(Field); DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Style); DECLARE_POINTER_TYPE(Style);
DECLARE_POINTER_TYPE(CardRegion);
// ----------------------------------------------------------------------------- : StyleSheet // ----------------------------------------------------------------------------- : StyleSheet
@@ -34,6 +39,7 @@ public:
double card_height; ///< The height of a card in pixels double card_height; ///< The height of a card in pixels
double card_dpi; ///< The resolution of a card in dots per inch double card_dpi; ///< The resolution of a card in dots per inch
Color card_background; ///< The background color of cards Color card_background; ///< The background color of cards
vector<CardRegionP> card_regions;
/// The styling for card fields /// The styling for card fields
/** The indices should correspond to the card_fields in the Game */ /** The indices should correspond to the card_fields in the Game */
IndexMap<FieldP, StyleP> card_style; IndexMap<FieldP, StyleP> card_style;
+11
View File
@@ -443,6 +443,17 @@ bool BuiltInImage::operator == (const GeneratedImage& that) const {
return that2 && name == that2->name; return that2 && name == that2->name;
} }
// ----------------------------------------------------------------------------- : ArbitraryImage
Image ArbitraryImage::generate(const Options& opt) const {
return image;
}
bool ArbitraryImage::operator == (const GeneratedImage& that) const {
const ArbitraryImage* that2 = dynamic_cast<const ArbitraryImage*>(&that);
return that2 && image.IsSameAs(that2->image);
}
// ----------------------------------------------------------------------------- : SymbolToImage // ----------------------------------------------------------------------------- : SymbolToImage
SymbolToImage::SymbolToImage(bool is_local, const LocalFileName& filename, Age age, const SymbolVariationP& variation) SymbolToImage::SymbolToImage(bool is_local, const LocalFileName& filename, Age age, const SymbolVariationP& variation)
+13
View File
@@ -348,6 +348,19 @@ private:
String name; String name;
}; };
// ----------------------------------------------------------------------------- : Arbitrary
class ArbitraryImage : public GeneratedImage {
public:
inline ArbitraryImage(const Image image)
: image(image)
{}
Image generate(const Options& opt) const override;
bool operator == (const GeneratedImage& that) const override;
private:
Image image;
};
// ----------------------------------------------------------------------------- : SymbolToImage // ----------------------------------------------------------------------------- : SymbolToImage
/// Use a symbol as an image /// Use a symbol as an image
+31
View File
@@ -16,6 +16,7 @@
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
#include <data/symbol.hpp> #include <data/symbol.hpp>
#include <data/field/symbol.hpp> #include <data/field/symbol.hpp>
#include <data/format/formats.hpp>
#include <gfx/generated_image.hpp> #include <gfx/generated_image.hpp>
#include <render/symbol/filter.hpp> #include <render/symbol/filter.hpp>
@@ -28,8 +29,35 @@ SCRIPT_FUNCTION(to_image) {
return input; return input;
} }
SCRIPT_FUNCTION(to_card_image) {
SCRIPT_PARAM(Set*, set);
SCRIPT_PARAM(CardP, input);
SCRIPT_PARAM_DEFAULT(double, zoom, 100);
SCRIPT_PARAM_DEFAULT(Degrees, angle, 0);
SCRIPT_PARAM_DEFAULT(bool, use_user_settings, false);
if (use_user_settings) {
// Use the User's Preferences for Export Zoom and Angle settings.
return make_intrusive<ArbitraryImage>(export_bitmap(set, input).ConvertToImage());
} else {
// Use the provided (or defaulted) Zoom and Angle.
return make_intrusive<ArbitraryImage>(export_bitmap(set, input, (zoom / 100), deg_to_rad(angle)).ConvertToImage());
}
}
// ----------------------------------------------------------------------------- : Image functions // ----------------------------------------------------------------------------- : Image functions
SCRIPT_FUNCTION(width_of) {
SCRIPT_PARAM(GeneratedImageP, input);
Image image = input->generate(GeneratedImage::Options());
SCRIPT_RETURN(image.GetWidth());
}
SCRIPT_FUNCTION(height_of) {
SCRIPT_PARAM(GeneratedImageP, input);
Image image = input->generate(GeneratedImage::Options());
SCRIPT_RETURN(image.GetHeight());
}
SCRIPT_FUNCTION(linear_blend) { SCRIPT_FUNCTION(linear_blend) {
SCRIPT_PARAM(GeneratedImageP, image1); SCRIPT_PARAM(GeneratedImageP, image1);
SCRIPT_PARAM(GeneratedImageP, image2); SCRIPT_PARAM(GeneratedImageP, image2);
@@ -210,6 +238,9 @@ SCRIPT_FUNCTION(built_in_image) {
void init_script_image_functions(Context& ctx) { void init_script_image_functions(Context& ctx) {
ctx.setVariable(_("to_image"), script_to_image); ctx.setVariable(_("to_image"), script_to_image);
ctx.setVariable(_("to_card_image"), script_to_card_image);
ctx.setVariable(_("width_of"), script_width_of);
ctx.setVariable(_("height_of"), script_height_of);
ctx.setVariable(_("linear_blend"), script_linear_blend); ctx.setVariable(_("linear_blend"), script_linear_blend);
ctx.setVariable(_("masked_blend"), script_masked_blend); ctx.setVariable(_("masked_blend"), script_masked_blend);
ctx.setVariable(_("combine_blend"), script_combine_blend); ctx.setVariable(_("combine_blend"), script_combine_blend);