diff --git a/doc/function/to_image.txt b/doc/function/to_image.txt index 2947c05a0..829d30879 100644 --- a/doc/function/to_image.txt +++ b/doc/function/to_image.txt @@ -7,11 +7,13 @@ DOC_MSE_VERSION: since 0.3.8 Convert any value to a [[type:image]]. -A string is interpreted as a [[type:filename]]. +* A string is interpreted as a [[type:filename]]. +* A [[type:card]] will be converted into an image onto which image operations can be done. --Parameters-- ! Parameter Type Description | @input@ ''any type'' Value to convert to an image +| @zoom@ [[type:double]] (optional) A zoom value for the image. Only used when converting cards. This allows you to keep the sharpness of the text at higher resolution. --Examples-- >>> to_image("image1.png") == "image1.png" diff --git a/src/data/format/formats.hpp b/src/data/format/formats.hpp index 4e317ca01..e95683515 100644 --- a/src/data/format/formats.hpp +++ b/src/data/format/formats.hpp @@ -99,7 +99,7 @@ void export_images(const SetP& set, const vector& cards, void export_image(const SetP& set, const CardP& card, const String& filename); /// 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, double zoom = 1.0); /// Export a set to Magic Workstation format void export_mws(Window* parent, const SetP& set); diff --git a/src/data/format/image.cpp b/src/data/format/image.cpp index 3b36ad786..b975884e9 100644 --- a/src/data/format/image.cpp +++ b/src/data/format/image.cpp @@ -24,10 +24,10 @@ void export_image(const SetP& set, const CardP& card, const String& filename) { // but image.saveFile determines it automagicly } -class UnzoomedDataViewer : public DataViewer { +class ZoomOverrideDataViewer : public DataViewer { public: - UnzoomedDataViewer(bool use_zoom_settings) - : use_zoom_settings(use_zoom_settings) + ZoomOverrideDataViewer(bool use_zoom_settings, double zoom = 1.0) + : use_zoom_settings(use_zoom_settings), zoom(zoom) {} Rotation getRotation() const override; private: @@ -35,19 +35,23 @@ class UnzoomedDataViewer : public DataViewer { double zoom = 1.0; double angle = 0.0; }; -Rotation UnzoomedDataViewer::getRotation() const { +Rotation ZoomOverrideDataViewer::getRotation() const { + Rotation rot; if (use_zoom_settings) { - return DataViewer::getRotation(); - } else { + rot = DataViewer::getRotation(); + rot.setZoom(rot.getZoom() * zoom); + } + else { if (!stylesheet) stylesheet = set->stylesheet; - return Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT); + rot = Rotation(angle, stylesheet->getCardRect(), zoom, 1.0, ROTATION_ATTACH_TOP_LEFT); } + return rot; } -Bitmap export_bitmap(const SetP& set, const CardP& card) { +Bitmap export_bitmap(const SetP& set, const CardP& card, double zoom /*= 1.0*/) { if (!set) throw Error(_("no set")); // create viewer - UnzoomedDataViewer viewer(!settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export()); + ZoomOverrideDataViewer viewer(!settings.stylesheetSettingsFor(set->stylesheetFor(card)).card_normal_export(), zoom); viewer.setSet(set); viewer.setCard(card); // size of cards diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index 5465c16f0..91dba5140 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -504,3 +504,21 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const { return that2 && filename == that2->filename && age == that2->age; } + +// ----------------------------------------------------------------------------- : PreGeneratedImage + +PreGeneratedImage::PreGeneratedImage(const Image& image) + : image(image) +{} +PreGeneratedImage::~PreGeneratedImage() {} + +Image PreGeneratedImage::generate(const Options& opt) const { + if (!image.Ok()) { + return Image(max(1, opt.width), max(1, opt.height)); + } + return image; +} +bool PreGeneratedImage::operator == (const GeneratedImage& that) const { + const PreGeneratedImage* that2 = dynamic_cast(&that); + return that2 && image.IsSameAs(that2->image); +} diff --git a/src/gfx/generated_image.hpp b/src/gfx/generated_image.hpp index fd14ccd12..c2682d792 100644 --- a/src/gfx/generated_image.hpp +++ b/src/gfx/generated_image.hpp @@ -386,3 +386,17 @@ class ImageValueToImage : public GeneratedImage { Age age; ///< Age the image was last updated }; +// ----------------------------------------------------------------------------- : PreGeneratedImage + +/// Use an image from an ImageValue as an image +class PreGeneratedImage : public GeneratedImage { +public: + PreGeneratedImage(const Image& image); + ~PreGeneratedImage(); + Image generate(const Options& opt) const override; + bool operator == (const GeneratedImage& that) const override; + bool local() const override { return true; } +private: + PreGeneratedImage(const PreGeneratedImage&); // copy ctor + Image image; +}; diff --git a/src/script/functions/image.cpp b/src/script/functions/image.cpp index 3e9caf65d..26a2a2ff7 100644 --- a/src/script/functions/image.cpp +++ b/src/script/functions/image.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -24,8 +26,15 @@ void parse_enum(const String&, ImageCombine& out); // ----------------------------------------------------------------------------- : Utility SCRIPT_FUNCTION(to_image) { - SCRIPT_PARAM_C(GeneratedImageP, input); - return input; + SCRIPT_PARAM_C(ScriptValueP, input); + ScriptObject* card = dynamic_cast*>(input.get()); + if (card) { + SCRIPT_OPTIONAL_PARAM_(double, zoom); + if (zoom <= 0) zoom = 1; // default + Image image = export_bitmap(export_info()->set, card->getValue(), zoom).ConvertToImage(); + return make_intrusive(image); + } + return input->toImage(); } // ----------------------------------------------------------------------------- : Image functions diff --git a/src/script/value.cpp b/src/script/value.cpp index 1927371ed..ed10eb507 100644 --- a/src/script/value.cpp +++ b/src/script/value.cpp @@ -37,7 +37,7 @@ wxDateTime ScriptValue::toDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date")); } GeneratedImageP ScriptValue::toImage() const { - throw ScriptErrorConversion(typeName(), _TYPE_("image" )); + throw ScriptErrorConversion(typeName(), _TYPE_("image")); } String ScriptValue::toCode() const { return toString();