From efa1992f4a1a21e08255ae5925c8f74dc6fb0676 Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 6 May 2007 18:15:18 +0000 Subject: [PATCH] Support for masks for color fields git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@325 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/field/color.cpp | 6 ++++ src/data/field/color.hpp | 15 ++++---- src/gfx/color.cpp | 13 +++++++ src/gfx/gfx.hpp | 3 ++ src/gfx/resample_text.cpp | 13 ------- src/render/value/color.cpp | 74 ++++++++++++++++++++++++++++---------- src/render/value/color.hpp | 8 +++++ 7 files changed, 95 insertions(+), 37 deletions(-) diff --git a/src/data/field/color.cpp b/src/data/field/color.cpp index 9cf21dd8..25eb6cc6 100644 --- a/src/data/field/color.cpp +++ b/src/data/field/color.cpp @@ -63,6 +63,12 @@ IMPLEMENT_REFLECTION(ColorStyle) { REFLECT(right_width); REFLECT(top_width); REFLECT(bottom_width); + REFLECT_N("mask", mask_filename); +} + +bool ColorStyle::update(Context& ctx) { + return Style ::update(ctx) + | mask_filename.update(ctx); } // ----------------------------------------------------------------------------- : ColorValue diff --git a/src/data/field/color.hpp b/src/data/field/color.hpp index e30533ba..fa6bf0e6 100644 --- a/src/data/field/color.hpp +++ b/src/data/field/color.hpp @@ -58,12 +58,15 @@ class ColorStyle : public Style { ColorStyle(const ColorFieldP& field); DECLARE_STYLE_TYPE(Color); - int radius; ///< Radius of round corners - UInt left_width; ///< Width of the colored region on the left side - UInt right_width; ///< Width of the colored region on the right side - UInt top_width; ///< Width of the colored region on the top side - UInt bottom_width; ///< Width of the colored region on the bottom side - + double radius; ///< Radius of round corners + double left_width; ///< Width of the colored region on the left side + double right_width; ///< Width of the colored region on the right side + double top_width; ///< Width of the colored region on the top side + double bottom_width; ///< Width of the colored region on the bottom side + Scriptable mask_filename; ///< Filename of an additional mask over the images + + virtual bool update(Context&); + private: DECLARE_REFLECTION(); }; diff --git a/src/gfx/color.cpp b/src/gfx/color.cpp index ec08d7b6..2513414c 100644 --- a/src/gfx/color.cpp +++ b/src/gfx/color.cpp @@ -56,3 +56,16 @@ Color saturate(const Color& c, double amount) { col(static_cast( (b - amount * l) / (1 - amount) )) ); } + + +void fill_image(Image& image, const Color& color) { + Byte* pos = image.GetData(); + Byte* end = pos + image.GetWidth() * image.GetHeight() * 3; + Byte r = color.Red(), g = color.Green(), b = color.Blue(); + // fill the image + while (pos != end) { + *pos++ = r; + *pos++ = g; + *pos++ = b; + } +} diff --git a/src/gfx/gfx.hpp b/src/gfx/gfx.hpp index 1060d243..ee022c2f 100644 --- a/src/gfx/gfx.hpp +++ b/src/gfx/gfx.hpp @@ -189,5 +189,8 @@ Color darken(const Color& c); /// A saturated version of a color Color saturate(const Color& c, double amount); +/// Fills an image with the specified color +void fill_image(Image& image, const Color& color); + // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/gfx/resample_text.cpp b/src/gfx/resample_text.cpp index 4a6163f8..ef886c2f 100644 --- a/src/gfx/resample_text.cpp +++ b/src/gfx/resample_text.cpp @@ -15,19 +15,6 @@ // scaling factor to use when drawing resampled text const int text_scaling = 4; -// Fills an image with the specified color -void fill_image(Image& image, const Color& color) { - Byte* pos = image.GetData(); - Byte* end = pos + image.GetWidth() * image.GetHeight() * 3; - Byte r = color.Red(), g = color.Green(), b = color.Blue(); - // fill the image - while (pos != end) { - *pos++ = r; - *pos++ = g; - *pos++ = b; - } -} - // Downsamples the red channel of the input image to the alpha channel of the output image // img_in must be text_scaling times as large as img_out void downsample_to_alpha(Image& img_in, Image& img_out) { diff --git a/src/render/value/color.cpp b/src/render/value/color.cpp index 9911477b..f3dce6da 100644 --- a/src/render/value/color.cpp +++ b/src/render/value/color.cpp @@ -7,6 +7,8 @@ // ----------------------------------------------------------------------------- : Includes #include +#include +#include DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP); @@ -38,22 +40,31 @@ void ColorValueViewer::draw(RotatedDC& dc) { dc.DrawRectangle(style().getRect().move(40, 0, -40, 0)); dc.DrawText(color_name, style().getPos() + RealSize(43, 3)); } else { - // do we need clipping? - bool clip = style().left_width < style().width && style().right_width < style().width && - style().top_width < style().height && style().bottom_width < style().height; - if (clip) { - // clip away the inside of the rectangle - wxRegion r = dc.tr(style().getRect()).toRect(); - r.Subtract(dc.tr(RealRect( - style().left + style().left_width, - style().top + style().top_width, - style().width - style().left_width - style().right_width, - style().height - style().top_width - style().bottom_width - ))); - dc.getDC().SetClippingRegion(r); + // is there a mask? + loadMask(dc); + if (alpha_mask) { + Image img(alpha_mask->size.x, alpha_mask->size.y); + fill_image(img, value().value()); + alpha_mask->setAlpha(img); + dc.DrawImage(img, style().getPos()); + } else { + // do we need clipping? + bool clip = style().left_width < style().width && style().right_width < style().width && + style().top_width < style().height && style().bottom_width < style().height; + if (clip) { + // clip away the inside of the rectangle + wxRegion r = dc.tr(style().getRect()).toRect(); + r.Subtract(dc.tr(RealRect( + style().left + style().left_width, + style().top + style().top_width, + style().width - style().left_width - style().right_width, + style().height - style().top_width - style().bottom_width + ))); + dc.getDC().SetClippingRegion(r); + } + dc.DrawRoundedRectangle(style().getRect(), style().radius); + if (clip) dc.getDC().DestroyClippingRegion(); } - dc.DrawRoundedRectangle(style().getRect(), style().radius); - if (clip) dc.getDC().DestroyClippingRegion(); } } @@ -61,7 +72,34 @@ bool ColorValueViewer::containsPoint(const RealPoint& p) const { // distance to each side double left = p.x - style().left, right = style().left + style().width - p.x - 1; double top = p.y - style().top, bottom = style().top + style().height - p.y - 1; - return left >= 0 && right >= 0 && top >= 0 && bottom >= 0 && // inside bounding box - (left < style().left_width || right < style().right_width || // inside horizontal border - top < style().top_width || bottom < style().bottom_width); // inside vertical border + if (left < 0 || right < 0 || top < 0 || bottom < 0 || // outside bounding box + (left >= style().left_width && right >= style().right_width && // outside horizontal border + top >= style().top_width && bottom >= style().bottom_width)) { // outside vertical border + return false; + } + // check against mask + if (!style().mask_filename().empty()) { + loadMask(viewer.getRotation()); + return !alpha_mask || !alpha_mask->isTransparent((int)left, (int)top); + } else { + return true; + } +} + +void ColorValueViewer::onStyleChange() { + alpha_mask = AlphaMaskP(); +} + +void ColorValueViewer::loadMask(const Rotation& rot) const { + if (style().mask_filename().empty()) return; // no mask + int w = (int) rot.trS(style().width), h = (int) rot.trS(style().height); + if (alpha_mask && alpha_mask->size == wxSize(w,h)) return; // mask loaded and right size + // (re) load the mask + Image image; + InputStreamP image_file = viewer.stylesheet->openIn(style().mask_filename); + if (image.LoadFile(*image_file)) { + Image resampled(w,h); + resample(image, resampled); + alpha_mask = new_shared1(resampled); + } } diff --git a/src/render/value/color.hpp b/src/render/value/color.hpp index b168e008..4cf39104 100644 --- a/src/render/value/color.hpp +++ b/src/render/value/color.hpp @@ -13,6 +13,8 @@ #include #include +DECLARE_POINTER_TYPE(AlphaMask); + // ----------------------------------------------------------------------------- : ColorValueViewer /// Viewer that displays a color value @@ -22,6 +24,12 @@ class ColorValueViewer : public ValueViewer { virtual void draw(RotatedDC& dc); virtual bool containsPoint(const RealPoint& p) const; + + virtual void onStyleChange(); + + private: + mutable AlphaMaskP alpha_mask; + void loadMask(const Rotation& rot) const; }; // ----------------------------------------------------------------------------- : EOF