diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index c46e12d3..36533db0 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -19,6 +19,19 @@ ScriptType GeneratedImage::type() const { return SCRIPT_IMAGE; } String GeneratedImage::typeName() const { return _TYPE_("image"); } +// ----------------------------------------------------------------------------- : BlankImage + +Image BlankImage::generate(const Options& opt) const { + Image img(opt.width, opt.height); + img.InitAlpha(); + memset(img.GetAlpha(), 0, opt.width * opt.height); + return img; +} +bool BlankImage::operator == (const GeneratedImage& that) const { + const BlankImage* that2 = dynamic_cast(&that); + return that2; +} + // ----------------------------------------------------------------------------- : LinearBlendImage Image LinearBlendImage::generate(const Options& opt) const { @@ -145,12 +158,12 @@ SymbolToImage::~SymbolToImage() {} Image SymbolToImage::generate(const Options& opt) const { // TODO : use opt.width and opt.height? - if (!opt.symbol_package) throw ScriptError(_("Can only load images in a context where an image is expected")); + if (!opt.local_package) throw ScriptError(_("Can only load images in a context where an image is expected")); SymbolP the_symbol; if (filename.empty()) { the_symbol = default_symbol(); } else { - the_symbol = opt.symbol_package->readFile(filename); + the_symbol = opt.local_package->readFile(filename); } return render_symbol(the_symbol, *variation->filter, variation->border_radius); } @@ -160,3 +173,29 @@ bool SymbolToImage::operator == (const GeneratedImage& that) const { && age == that2->age && variation == that2->variation; } + +// ----------------------------------------------------------------------------- : ImageValueToImage + +ImageValueToImage::ImageValueToImage(const String& filename, Age age) + : filename(filename), age(age) +{} +ImageValueToImage::~ImageValueToImage() {} + +Image ImageValueToImage::generate(const Options& opt) const { + // TODO : use opt.width and opt.height? + if (!opt.local_package) throw ScriptError(_("Can only load images in a context where an image is expected")); + Image image; + if (!filename.empty()) { + InputStreamP image_file = opt.local_package->openIn(filename); + image.LoadFile(*image_file); + } + if (!image.Ok()) { + image = Image(opt.width, opt.height); + } + return image; +} +bool ImageValueToImage::operator == (const GeneratedImage& that) const { + const ImageValueToImage* that2 = dynamic_cast(&that); + return that2 && filename == that2->filename + && age == that2->age; +} diff --git a/src/gfx/generated_image.hpp b/src/gfx/generated_image.hpp index e4e242dd..7f69b105 100644 --- a/src/gfx/generated_image.hpp +++ b/src/gfx/generated_image.hpp @@ -27,15 +27,15 @@ class GeneratedImage : public ScriptValue { public: /// Options for generating the image struct Options { - Options(int width = 0, int height = 0, Package* package = nullptr, Package* symbol_package = nullptr, PreserveAspect preserve_aspect = ASPECT_STRETCH, bool saturate = false) - : width(width), height(height), preserve_aspect(preserve_aspect), saturate(saturate), package(package), symbol_package(symbol_package) + Options(int width = 0, int height = 0, Package* package = nullptr, Package* local_package = nullptr, PreserveAspect preserve_aspect = ASPECT_STRETCH, bool saturate = false) + : width(width), height(height), preserve_aspect(preserve_aspect), saturate(saturate), package(package), local_package(local_package) {} int width, height; ///< Width to force the image to, or 0 to keep the width of the input PreserveAspect preserve_aspect; bool saturate; - Package* package; ///< Package to load images from - Package* symbol_package; ///< Package to load symbols from + Package* package; ///< Package to load images from + Package* local_package; ///< Package to load symbols and ImageValue images from }; /// Generate the image @@ -47,12 +47,21 @@ class GeneratedImage : public ScriptValue { inline bool operator != (const GeneratedImage& that) const { return !(*this == that); } /// Can this image be generated safely from another thread? - virtual bool threadSafe() const = 0; + virtual bool threadSafe() const { return true; }; virtual ScriptType type() const; virtual String typeName() const; }; +// ----------------------------------------------------------------------------- : BlankImage + +/// An image generator that returns a blank image +class BlankImage : public GeneratedImage { + public: + virtual Image generate(const Options&) const; + virtual bool operator == (const GeneratedImage& that) const; +}; + // ----------------------------------------------------------------------------- : LinearBlendImage /// An image generator that linearly blends two other images @@ -64,8 +73,6 @@ class LinearBlendImage : public GeneratedImage { virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: GeneratedImageP image1, image2; double x1, y1, x2, y2; @@ -82,8 +89,6 @@ class MaskedBlendImage : public GeneratedImage { virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: GeneratedImageP light, dark, mask; }; @@ -99,8 +104,6 @@ class CombineBlendImage : public GeneratedImage { virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: GeneratedImageP image1, image2; ImageCombine image_combine; @@ -117,8 +120,6 @@ class SetMaskImage : public GeneratedImage { virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: GeneratedImageP image, mask; }; @@ -134,8 +135,6 @@ class SetCombineImage : public GeneratedImage { virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const {return true;} private: GeneratedImageP image; ImageCombine image_combine; @@ -151,8 +150,6 @@ class PackagedImage : public GeneratedImage { {} virtual Image generate(const Options& opt) const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: String filename; }; @@ -167,8 +164,6 @@ class BuiltInImage : public GeneratedImage { {} virtual Image generate(const Options& opt) const; virtual bool operator == (const GeneratedImage& that) const; - - virtual bool threadSafe() const { return true; } private: String name; }; @@ -185,8 +180,6 @@ class SymbolToImage : public GeneratedImage { #ifdef __WXGTK__ virtual bool threadSafe() const { return false; } - #else - virtual bool threadSafe() const { return true; } #endif private: SymbolToImage(const SymbolToImage&); // copy ctor @@ -195,5 +188,20 @@ class SymbolToImage : public GeneratedImage { SymbolVariationP variation; }; +// ----------------------------------------------------------------------------- : ImageValueToImage + +/// Use an image from an ImageValue as an image +class ImageValueToImage : public GeneratedImage { + public: + ImageValueToImage(const String& filename, Age age); + ~ImageValueToImage(); + virtual Image generate(const Options& opt) const; + virtual bool operator == (const GeneratedImage& that) const; + private: + ImageValueToImage(const ImageValueToImage&); // copy ctor + String filename; + Age age; ///< Age the symbol was last updated +}; + // ----------------------------------------------------------------------------- : EOF #endif