mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Moved mask to Style and mask related drawing to ValueViewer.
Used the same mask also for TextStyles. To keep the text selectable (since the mask is now also used for containsPoint), the future sight cost masks needed to be updated. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1183 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 543 B |
Binary file not shown.
|
Before Width: | Height: | Size: 971 B After Width: | Height: | Size: 403 B |
+6
-5
@@ -76,6 +76,7 @@ Here are some examples:
|
|||||||
| @bottom@ [[type:scriptable]] [[type:double]] ''Required'' Distance between bottom edge of the box and the ''top'' of the card in pixels.
|
| @bottom@ [[type:scriptable]] [[type:double]] ''Required'' Distance between bottom edge of the box and the ''top'' of the card in pixels.
|
||||||
| @angle@ [[type:scriptable]] [[type:int]] @0@ Rotation of this box, in degrees counter clockwise.
|
| @angle@ [[type:scriptable]] [[type:int]] @0@ Rotation of this box, in degrees counter clockwise.
|
||||||
| @visible@ [[type:scriptable]] [[type:boolean]] @true@ Is this field visible at all?
|
| @visible@ [[type:scriptable]] [[type:boolean]] @true@ Is this field visible at all?
|
||||||
|
| @mask@ [[type:image|scriptable image]] ''none'' A mask to apply to the image, black areas in the mask become transparent, similar to [[fun:set_mask]].
|
||||||
|
|
||||||
The rest of the properties depend on the type of [[type:field]] this style is for.
|
The rest of the properties depend on the type of [[type:field]] this style is for.
|
||||||
! Type Property Type Default Description
|
! Type Property Type Default Description
|
||||||
@@ -103,9 +104,11 @@ The rest of the properties depend on the type of [[type:field]] this style is fo
|
|||||||
| ^^^ @line height line max@ ^^^ ^^^ ^^^
|
| ^^^ @line height line max@ ^^^ ^^^ ^^^
|
||||||
| ^^^ @paragraph height@ [[type:double]] ''flexible'' The height of paragraphs. If specified, each paragraph is given this much space, and aligned inside that space as specified by @alignment@.<br/>
|
| ^^^ @paragraph height@ [[type:double]] ''flexible'' The height of paragraphs. If specified, each paragraph is given this much space, and aligned inside that space as specified by @alignment@.<br/>
|
||||||
A paragraph break is any line break that is not soft (i.e. caused by word wrap or a @"<soft>"@ break).
|
A paragraph break is any line break that is not soft (i.e. caused by word wrap or a @"<soft>"@ break).
|
||||||
| ^^^ @mask@ [[type:filename]] ''none'' A mask that indicates where in the box text can be placed.<br/>
|
| ^^^ @mask@ [[type:image|scriptable image]] ''none'' A mask that indicates where in the box text can be placed.<br/>
|
||||||
Text is never put in black areas of the box:<br/>
|
Text is never put in black areas of the box:<br/>
|
||||||
<img src="style-text-mask.png" alt=""/>
|
<img src="style-text-mask.png" alt=""/><br/>
|
||||||
|
The same mask image is also used to determine the size and shape of the box.
|
||||||
|
To include a certain pixel in the size/shape but not allow text to be placed there, it can be made dark gray (a value less than 128).
|
||||||
| ^^^ @content width@ [[type:double]] ''automatic'' When read from a script, gives the width of the current content in this box.
|
| ^^^ @content width@ [[type:double]] ''automatic'' When read from a script, gives the width of the current content in this box.
|
||||||
| ^^^ @content height@ [[type:double]] ''automatic'' When read from a script, gives the height of the current content in this box.
|
| ^^^ @content height@ [[type:double]] ''automatic'' When read from a script, gives the height of the current content in this box.
|
||||||
| ^^^ @content lines@ [[type:int]] ''automatic'' When read from a script, gives the number of lines of the current content in this box.
|
| ^^^ @content lines@ [[type:int]] ''automatic'' When read from a script, gives the number of lines of the current content in this box.
|
||||||
@@ -141,12 +144,10 @@ The rest of the properties depend on the type of [[type:field]] this style is fo
|
|||||||
| ^^^ @right width@ ^^^ ^^^ ^^^
|
| ^^^ @right width@ ^^^ ^^^ ^^^
|
||||||
| ^^^ @top width@ ^^^ ^^^ ^^^
|
| ^^^ @top width@ ^^^ ^^^ ^^^
|
||||||
| ^^^ @bottom width@ ^^^ ^^^ ^^^
|
| ^^^ @bottom width@ ^^^ ^^^ ^^^
|
||||||
| ^^^ @mask@ [[type:scriptable]] [[type:filename]] ''none'' A mask to apply to the box, black areas in the mask become transparent.
|
|
||||||
| ^^^ @combine@ [[type:combine]] @"normal"@ How to combine the color with the background? Only applies when a mask is used.
|
| ^^^ @combine@ [[type:combine]] @"normal"@ How to combine the color with the background? Only applies when a mask is used.
|
||||||
|
|
||||||
! <<< <<< <<< <<<
|
! <<< <<< <<< <<<
|
||||||
| @"image"@ @mask@ [[type:scriptable]] [[type:filename]] ''none'' A mask to apply to the image, black areas in the mask become transparent, similair to [[fun:set_mask]].
|
| @"image"@ @default@ [[type:image|scriptable image]] ''none'' A default image to use when the card has none.
|
||||||
| ^^^ @default@ [[type:image|scriptable image]] ''none'' A default image to use when the card has none.
|
|
||||||
|
|
||||||
! <<< <<< <<< <<<
|
! <<< <<< <<< <<<
|
||||||
| @"symbol"@ @variations@ [[type:list]] of [[type:symbol variation]]s Available variations of the symbol, a variation describes color and border size.
|
| @"symbol"@ @variations@ [[type:list]] of [[type:symbol variation]]s Available variations of the symbol, a variation describes color and border size.
|
||||||
|
|||||||
+9
-6
@@ -118,6 +118,7 @@ IMPLEMENT_REFLECTION(Style) {
|
|||||||
REFLECT(bottom);
|
REFLECT(bottom);
|
||||||
REFLECT(angle);
|
REFLECT(angle);
|
||||||
REFLECT(visible);
|
REFLECT(visible);
|
||||||
|
REFLECT(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_object(const FieldP& field, StyleP& style) {
|
void init_object(const FieldP& field, StyleP& style) {
|
||||||
@@ -135,15 +136,16 @@ inline bool is_setw(const Scriptable<double>& x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Style::update(Context& ctx) {
|
int Style::update(Context& ctx) {
|
||||||
bool changed =
|
int changed =
|
||||||
left .update(ctx)
|
( left .update(ctx)
|
||||||
| width .update(ctx)
|
| width .update(ctx)
|
||||||
| right .update(ctx)
|
| right .update(ctx)
|
||||||
| top .update(ctx)
|
| top .update(ctx)
|
||||||
| height .update(ctx)
|
| height .update(ctx)
|
||||||
| bottom .update(ctx)
|
| bottom .update(ctx)
|
||||||
| angle .update(ctx)
|
| angle .update(ctx) ) * CHANGE_SIZE
|
||||||
| visible.update(ctx);
|
| visible.update(ctx) * CHANGE_OTHER
|
||||||
|
| mask .update(ctx) * CHANGE_MASK;
|
||||||
// determine automatic_side and attachment of rotation point
|
// determine automatic_side and attachment of rotation point
|
||||||
if (automatic_side == AUTO_UNKNOWN) {
|
if (automatic_side == AUTO_UNKNOWN) {
|
||||||
if (!is_set (right)) automatic_side = (AutomaticSide)(automatic_side | AUTO_RIGHT);
|
if (!is_set (right)) automatic_side = (AutomaticSide)(automatic_side | AUTO_RIGHT);
|
||||||
@@ -154,7 +156,7 @@ int Style::update(Context& ctx) {
|
|||||||
else if (!is_setw(height)) automatic_side = (AutomaticSide)(automatic_side | AUTO_HEIGHT);
|
else if (!is_setw(height)) automatic_side = (AutomaticSide)(automatic_side | AUTO_HEIGHT);
|
||||||
else if (!is_set (top)) automatic_side = (AutomaticSide)(automatic_side | AUTO_TOP);
|
else if (!is_set (top)) automatic_side = (AutomaticSide)(automatic_side | AUTO_TOP);
|
||||||
else automatic_side = (AutomaticSide)(automatic_side | AUTO_TB);
|
else automatic_side = (AutomaticSide)(automatic_side | AUTO_TB);
|
||||||
changed = true;
|
changed |= CHANGE_SIZE;
|
||||||
}
|
}
|
||||||
if (!changed) return CHANGE_NONE;
|
if (!changed) return CHANGE_NONE;
|
||||||
// update the automatic_side
|
// update the automatic_side
|
||||||
@@ -181,7 +183,7 @@ int Style::update(Context& ctx) {
|
|||||||
if (width < 0) width = -width;
|
if (width < 0) width = -width;
|
||||||
if (height < 0) height = -height;
|
if (height < 0) height = -height;
|
||||||
// done
|
// done
|
||||||
return CHANGE_OTHER;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Style::isVisible() const {
|
bool Style::isVisible() const {
|
||||||
@@ -214,6 +216,7 @@ void Style::checkContentDependencies(Context& ctx, const Dependency& dep) const
|
|||||||
right .initDependencies(ctx,dep);
|
right .initDependencies(ctx,dep);
|
||||||
bottom .initDependencies(ctx,dep);
|
bottom .initDependencies(ctx,dep);
|
||||||
visible.initDependencies(ctx,dep);
|
visible.initDependencies(ctx,dep);
|
||||||
|
mask .initDependencies(ctx,dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::markDependencyMember(const String& name, const Dependency& dep) const {
|
void Style::markDependencyMember(const String& name, const Dependency& dep) const {
|
||||||
|
|||||||
+14
-9
@@ -16,6 +16,7 @@
|
|||||||
#include <util/rotation.hpp>
|
#include <util/rotation.hpp>
|
||||||
#include <script/scriptable.hpp>
|
#include <script/scriptable.hpp>
|
||||||
#include <script/dependency.hpp>
|
#include <script/dependency.hpp>
|
||||||
|
#include <script/image.hpp>
|
||||||
|
|
||||||
DECLARE_POINTER_TYPE(Field);
|
DECLARE_POINTER_TYPE(Field);
|
||||||
DECLARE_POINTER_TYPE(Style);
|
DECLARE_POINTER_TYPE(Style);
|
||||||
@@ -94,13 +95,16 @@ class Style : public IntrusivePtrVirtualBase {
|
|||||||
Style(const FieldP&);
|
Style(const FieldP&);
|
||||||
virtual ~Style();
|
virtual ~Style();
|
||||||
|
|
||||||
const FieldP fieldP; ///< Field this style is for, should have the right type!
|
const FieldP fieldP; ///< Field this style is for, should have the right type!
|
||||||
int z_index; ///< Stacking of values of this field, higher = on top
|
|
||||||
Scriptable<double> left, top; ///< Position of this field
|
int z_index; ///< Stacking of values of this field, higher = on top
|
||||||
Scriptable<double> width, height; ///< Position of this field
|
Scriptable<double> left, top; ///< Position of this field
|
||||||
Scriptable<double> right, bottom; ///< Position of this field
|
Scriptable<double> width, height; ///< Position of this field
|
||||||
Scriptable<int> angle; ///< Rotation of the box
|
Scriptable<double> right, bottom; ///< Position of this field
|
||||||
Scriptable<bool> visible; ///< Is this field visible?
|
Scriptable<int> angle; ///< Rotation of the box
|
||||||
|
Scriptable<bool> visible; ///< Is this field visible?
|
||||||
|
CachedScriptableMask mask; ///< Mask image
|
||||||
|
|
||||||
enum AutomaticSide {
|
enum AutomaticSide {
|
||||||
AUTO_UNKNOWN = 0x00,
|
AUTO_UNKNOWN = 0x00,
|
||||||
AUTO_LEFT = 0x01, AUTO_WIDTH = 0x02, AUTO_RIGHT = 0x04, AUTO_LR = 0x08,
|
AUTO_LEFT = 0x01, AUTO_WIDTH = 0x02, AUTO_RIGHT = 0x04, AUTO_LR = 0x08,
|
||||||
@@ -166,8 +170,9 @@ class Style : public IntrusivePtrVirtualBase {
|
|||||||
enum StyleChange
|
enum StyleChange
|
||||||
{ CHANGE_NONE = 0x00 // nothing changed
|
{ CHANGE_NONE = 0x00 // nothing changed
|
||||||
, CHANGE_OTHER = 0x01 // some other change (note: result of casting from bool)
|
, CHANGE_OTHER = 0x01 // some other change (note: result of casting from bool)
|
||||||
, CHANGE_DEFAULT = 0x02 // only the 'default' state is affected
|
, CHANGE_SIZE = 0x02 // size/angle changed
|
||||||
, CHANGE_MASK = 0x04 // a mask image changed, must be reloaded
|
, CHANGE_DEFAULT = 0x04 // only the 'default' state is affected
|
||||||
|
, CHANGE_MASK = 0x08 // a mask image changed, must be reloaded
|
||||||
, CHANGE_ALREADY_PREPARED = 0x80 // hint that the change was the result of a content property change, viewers are already prepared
|
, CHANGE_ALREADY_PREPARED = 0x80 // hint that the change was the result of a content property change, viewers are already prepared
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -213,9 +213,8 @@ void ChoiceStyle::initImage() {
|
|||||||
|
|
||||||
int ChoiceStyle::update(Context& ctx) {
|
int ChoiceStyle::update(Context& ctx) {
|
||||||
// Don't update the choice images, leave that to invalidate()
|
// Don't update the choice images, leave that to invalidate()
|
||||||
int change = Style ::update(ctx)
|
int change = Style::update(ctx)
|
||||||
| font .update(ctx) * CHANGE_OTHER
|
| font .update(ctx) * CHANGE_OTHER;
|
||||||
| mask .update(ctx) * CHANGE_MASK;
|
|
||||||
if (!choice_images_initialized) {
|
if (!choice_images_initialized) {
|
||||||
// we only want to do this once because it is rather slow, other updates are handled by dependencies
|
// we only want to do this once because it is rather slow, other updates are handled by dependencies
|
||||||
choice_images_initialized = true;
|
choice_images_initialized = true;
|
||||||
@@ -283,7 +282,6 @@ IMPLEMENT_REFLECTION(ChoiceStyle) {
|
|||||||
REFLECT_BASE(Style);
|
REFLECT_BASE(Style);
|
||||||
REFLECT(popup_style);
|
REFLECT(popup_style);
|
||||||
REFLECT(render_style);
|
REFLECT(render_style);
|
||||||
REFLECT(mask);
|
|
||||||
REFLECT(combine);
|
REFLECT(combine);
|
||||||
REFLECT(alignment);
|
REFLECT(alignment);
|
||||||
REFLECT(font);
|
REFLECT(font);
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ class ChoiceStyle : public Style {
|
|||||||
CachedScriptableImage image; ///< Image to draw (when RENDER_IMAGE)
|
CachedScriptableImage image; ///< Image to draw (when RENDER_IMAGE)
|
||||||
map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE)
|
map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE)
|
||||||
bool choice_images_initialized;
|
bool choice_images_initialized;
|
||||||
CachedScriptableMask mask; ///< Mask image
|
|
||||||
ImageCombine combine; ///< Combining mode for drawing the images
|
ImageCombine combine; ///< Combining mode for drawing the images
|
||||||
Alignment alignment; ///< Alignment of images
|
Alignment alignment; ///< Alignment of images
|
||||||
wxImageList* thumbnails; ///< Thumbnails for the choices
|
wxImageList* thumbnails; ///< Thumbnails for the choices
|
||||||
|
|||||||
@@ -62,13 +62,11 @@ IMPLEMENT_REFLECTION(ColorStyle) {
|
|||||||
REFLECT(right_width);
|
REFLECT(right_width);
|
||||||
REFLECT(top_width);
|
REFLECT(top_width);
|
||||||
REFLECT(bottom_width);
|
REFLECT(bottom_width);
|
||||||
REFLECT(mask);
|
|
||||||
REFLECT(combine);
|
REFLECT(combine);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ColorStyle::update(Context& ctx) {
|
int ColorStyle::update(Context& ctx) {
|
||||||
return Style::update(ctx)
|
return Style::update(ctx);
|
||||||
| mask.update(ctx) * CHANGE_MASK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ColorValue
|
// ----------------------------------------------------------------------------- : ColorValue
|
||||||
|
|||||||
@@ -57,13 +57,12 @@ class ColorStyle : public Style {
|
|||||||
ColorStyle(const ColorFieldP& field);
|
ColorStyle(const ColorFieldP& field);
|
||||||
DECLARE_STYLE_TYPE(Color);
|
DECLARE_STYLE_TYPE(Color);
|
||||||
|
|
||||||
double radius; ///< Radius of round corners
|
double radius; ///< Radius of round corners
|
||||||
double left_width; ///< Width of the colored region on the left side
|
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 right_width; ///< Width of the colored region on the right side
|
||||||
double top_width; ///< Width of the colored region on the top 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
|
double bottom_width; ///< Width of the colored region on the bottom side
|
||||||
CachedScriptableMask mask; ///< Mask image
|
ImageCombine combine; ///< How to combine image with the background
|
||||||
ImageCombine combine; ///< How to combine image with the background
|
|
||||||
|
|
||||||
virtual int update(Context&);
|
virtual int update(Context&);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ IMPLEMENT_REFLECTION(ImageField) {
|
|||||||
|
|
||||||
IMPLEMENT_REFLECTION(ImageStyle) {
|
IMPLEMENT_REFLECTION(ImageStyle) {
|
||||||
REFLECT_BASE(Style);
|
REFLECT_BASE(Style);
|
||||||
REFLECT(mask);
|
|
||||||
REFLECT_N("default", default_image);
|
REFLECT_N("default", default_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImageStyle::update(Context& ctx) {
|
int ImageStyle::update(Context& ctx) {
|
||||||
return Style ::update(ctx)
|
return Style ::update(ctx)
|
||||||
| mask .update(ctx) * CHANGE_MASK
|
|
||||||
| default_image.update(ctx) * CHANGE_DEFAULT;
|
| default_image.update(ctx) * CHANGE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ class ImageStyle : public Style {
|
|||||||
inline ImageStyle(const ImageFieldP& field) : Style(field) {}
|
inline ImageStyle(const ImageFieldP& field) : Style(field) {}
|
||||||
DECLARE_STYLE_TYPE(Image);
|
DECLARE_STYLE_TYPE(Image);
|
||||||
|
|
||||||
CachedScriptableMask mask; ///< Mask image
|
ScriptableImage default_image; ///< Placeholder
|
||||||
ScriptableImage default_image; ///< Placeholder
|
|
||||||
|
|
||||||
virtual int update(Context&);
|
virtual int update(Context&);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ IMPLEMENT_REFLECTION(TextStyle) {
|
|||||||
REFLECT(line_height_hard_max);
|
REFLECT(line_height_hard_max);
|
||||||
REFLECT(line_height_line_max);
|
REFLECT(line_height_line_max);
|
||||||
REFLECT(paragraph_height);
|
REFLECT(paragraph_height);
|
||||||
REFLECT_N("mask", mask_filename);
|
|
||||||
REFLECT(direction);
|
REFLECT(direction);
|
||||||
reflect_content(tag, *this);
|
reflect_content(tag, *this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,6 @@ class TextStyle : public Style {
|
|||||||
double line_height_hard_max; ///< Maximum line height
|
double line_height_hard_max; ///< Maximum line height
|
||||||
double line_height_line_max; ///< Maximum line height
|
double line_height_line_max; ///< Maximum line height
|
||||||
double paragraph_height; ///< Fixed height of paragraphs
|
double paragraph_height; ///< Fixed height of paragraphs
|
||||||
String mask_filename; ///< Filename of the mask
|
|
||||||
AlphaMask mask; ///< Mask to fit the text to (may be null)
|
|
||||||
Direction direction; ///< In what direction is text layed out?
|
Direction direction; ///< In what direction is text layed out?
|
||||||
// information from text rendering
|
// information from text rendering
|
||||||
double content_width, content_height; ///< Size of the rendered text
|
double content_width, content_height; ///< Size of the rendered text
|
||||||
|
|||||||
+16
-7
@@ -60,12 +60,21 @@ void AlphaMask::setAlpha(Bitmap& bmp) const {
|
|||||||
|
|
||||||
bool AlphaMask::isOpaque(int x, int y) const {
|
bool AlphaMask::isOpaque(int x, int y) const {
|
||||||
if (x < 0 || y < 0 || x >= size.x || y >= size.y) return false;
|
if (x < 0 || y < 0 || x >= size.x || y >= size.y) return false;
|
||||||
if (!alpha) return true;
|
if (alpha) {
|
||||||
return alpha[x + y * size.x] >= 20;
|
return alpha[x + y * size.x] >= 20;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool AlphaMask::isOpaque(const RealPoint& p, const RealSize& resize) const {
|
bool AlphaMask::isOpaque(const RealPoint& p, const RealSize& resize) const {
|
||||||
return isOpaque((int)(p.x * size.x / resize.width)
|
if (p.x < 0 || p.y < 0 || p.x >= resize.width || p.y >= resize.height) return false;
|
||||||
,(int)(p.y * size.y / resize.height));
|
if (alpha) {
|
||||||
|
int x = (int)(p.x * size.x / resize.width);
|
||||||
|
int y = (int)(p.y * size.y / resize.height);
|
||||||
|
return alpha[x + y * size.x] >= 20;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do the points form a (counter??)clockwise angle?
|
/// Do the points form a (counter??)clockwise angle?
|
||||||
@@ -141,7 +150,7 @@ void AlphaMask::loadRowSizes() const {
|
|||||||
lefts[y] = size.x;
|
lefts[y] = size.x;
|
||||||
rights[y] = 0;
|
rights[y] = 0;
|
||||||
for (int x = 0 ; x < size.x ; ++x) {
|
for (int x = 0 ; x < size.x ; ++x) {
|
||||||
if (alpha[y * size.x + x] > 64) { // white enough
|
if (alpha[y * size.x + x] >= 128) { // white enough
|
||||||
rights[y] = x;
|
rights[y] = x;
|
||||||
if (x < lefts[y]) lefts[y] = x;
|
if (x < lefts[y]) lefts[y] = x;
|
||||||
}
|
}
|
||||||
@@ -155,7 +164,7 @@ double AlphaMask::rowLeft (double y, const RealSize& resize) const {
|
|||||||
// no mask, or outside it
|
// no mask, or outside it
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return lefts[(int)(y * resize.height / size.y)] * resize.width / size.x;
|
return lefts[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AlphaMask::rowRight(double y, const RealSize& resize) const {
|
double AlphaMask::rowRight(double y, const RealSize& resize) const {
|
||||||
@@ -164,5 +173,5 @@ double AlphaMask::rowRight(double y, const RealSize& resize) const {
|
|||||||
// no mask, or outside it
|
// no mask, or outside it
|
||||||
return resize.width;
|
return resize.width;
|
||||||
}
|
}
|
||||||
return rights[(int)(y * resize.height / size.y)] * resize.width / size.x;
|
return rights[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -661,10 +661,10 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double TextViewer::lineLeft(RotatedDC& dc, const TextStyle& style, double y) const {
|
double TextViewer::lineLeft(RotatedDC& dc, const TextStyle& style, double y) const {
|
||||||
return style.mask.rowLeft(y, dc.getInternalSize()) + style.padding_left;
|
return style.mask.getFromCache().rowLeft(y, dc.getInternalSize()) + style.padding_left;
|
||||||
}
|
}
|
||||||
double TextViewer::lineRight(RotatedDC& dc, const TextStyle& style, double y) const {
|
double TextViewer::lineRight(RotatedDC& dc, const TextStyle& style, double y) const {
|
||||||
return style.mask.rowRight(y, dc.getInternalSize()) - style.padding_right;
|
return style.mask.getFromCache().rowRight(y, dc.getInternalSize()) - style.padding_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,46 +22,16 @@ bool ChoiceValueViewer::prepare(RotatedDC& dc) {
|
|||||||
return prepare_choice_viewer(dc, *this, style(), value().value());
|
return prepare_choice_viewer(dc, *this, style(), value().value());
|
||||||
}
|
}
|
||||||
void ChoiceValueViewer::draw(RotatedDC& dc) {
|
void ChoiceValueViewer::draw(RotatedDC& dc) {
|
||||||
int w = max(0,(int)dc.trX(style().width)), h = max(0,(int)dc.trY(style().height));
|
drawFieldBorder(dc);
|
||||||
const AlphaMask& alpha_mask = getMask(w,h);
|
|
||||||
drawFieldBorder(dc, alpha_mask);
|
|
||||||
if (style().render_style & RENDER_HIDDEN) return;
|
if (style().render_style & RENDER_HIDDEN) return;
|
||||||
draw_choice_viewer(dc, *this, style(), value().value());
|
draw_choice_viewer(dc, *this, style(), value().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChoiceValueViewer::drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask) {
|
|
||||||
if (!alpha_mask.isLoaded()) {
|
|
||||||
ValueViewer::drawFieldBorder(dc);
|
|
||||||
} else if (setFieldBorderPen(dc)) {
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
||||||
vector<wxPoint> points;
|
|
||||||
alpha_mask.convexHull(points);
|
|
||||||
if (points.size() < 3) return;
|
|
||||||
FOR_EACH(p, points) p = dc.trPixelNoZoom(RealPoint(p.x,p.y));
|
|
||||||
dc.getDC().DrawPolygon((int)points.size(), &points[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ChoiceValueViewer::containsPoint(const RealPoint& p) const {
|
|
||||||
// check against mask
|
|
||||||
return getMask(0,0).isOpaque(p, style().getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChoiceValueViewer::onStyleChange(int changes) {
|
void ChoiceValueViewer::onStyleChange(int changes) {
|
||||||
if (changes & CHANGE_MASK) style().image.clearCache();
|
if (changes & CHANGE_MASK) style().image.clearCache();
|
||||||
ValueViewer::onStyleChange(changes);
|
ValueViewer::onStyleChange(changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlphaMask& ChoiceValueViewer::getMask(int w, int h) const {
|
|
||||||
GeneratedImage::Options opts;
|
|
||||||
opts.package = &viewer.getStylePackage();
|
|
||||||
opts.local_package = &viewer.getLocalPackage();
|
|
||||||
opts.angle = 0;
|
|
||||||
opts.width = w;
|
|
||||||
opts.height = h;
|
|
||||||
return style().mask.get(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Generic draw/prepare
|
// ----------------------------------------------------------------------------- : Generic draw/prepare
|
||||||
|
|
||||||
bool prepare_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value) {
|
bool prepare_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value) {
|
||||||
|
|||||||
@@ -23,19 +23,10 @@ class ChoiceValueViewer : public ValueViewer {
|
|||||||
virtual bool prepare(RotatedDC& dc);
|
virtual bool prepare(RotatedDC& dc);
|
||||||
virtual void draw(RotatedDC& dc);
|
virtual void draw(RotatedDC& dc);
|
||||||
virtual void onStyleChange(int);
|
virtual void onStyleChange(int);
|
||||||
|
|
||||||
virtual bool containsPoint(const RealPoint& p) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Draws a border around the field
|
|
||||||
void drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask);
|
|
||||||
/// Load the AlphaMask for this field
|
|
||||||
const AlphaMask& getMask(int w, int h) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool prepare_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value);
|
bool prepare_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value);
|
||||||
void draw_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value);
|
void draw_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, const String& value);
|
||||||
const AlphaMask& get_mask(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style, int w, int h);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ void ColorValueViewer::draw(RotatedDC& dc) {
|
|||||||
dc.DrawText(color_name, RealPoint(43, 3));
|
dc.DrawText(color_name, RealPoint(43, 3));
|
||||||
} else {
|
} else {
|
||||||
// is there a mask?
|
// is there a mask?
|
||||||
int w = max(0,(int)dc.trX(style().width)), h = max(0,(int)dc.trY(style().height));
|
const AlphaMask& alpha_mask = getMask(dc);
|
||||||
const AlphaMask& alpha_mask = getMask(w,h);
|
|
||||||
if (alpha_mask.isLoaded()) {
|
if (alpha_mask.isLoaded()) {
|
||||||
dc.DrawImage(alpha_mask.colorImage(value().value()), RealPoint(0,0), style().combine);
|
dc.DrawImage(alpha_mask.colorImage(value().value()), RealPoint(0,0), style().combine);
|
||||||
} else {
|
} else {
|
||||||
@@ -66,26 +65,13 @@ void ColorValueViewer::draw(RotatedDC& dc) {
|
|||||||
dc.DrawRoundedRectangle(style().getInternalRect(), style().radius);
|
dc.DrawRoundedRectangle(style().getInternalRect(), style().radius);
|
||||||
if (clip) dc.getDC().DestroyClippingRegion();
|
if (clip) dc.getDC().DestroyClippingRegion();
|
||||||
}
|
}
|
||||||
drawFieldBorder(dc, alpha_mask);
|
drawFieldBorder(dc);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ColorValueViewer::drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask) {
|
|
||||||
if (!alpha_mask.isLoaded()) {
|
|
||||||
ValueViewer::drawFieldBorder(dc);
|
|
||||||
} else if (setFieldBorderPen(dc)) {
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
||||||
vector<wxPoint> points;
|
|
||||||
alpha_mask.convexHull(points);
|
|
||||||
if (points.size() < 3) return;
|
|
||||||
FOR_EACH(p, points) p = dc.trPixelNoZoom(RealPoint(p.x,p.y));
|
|
||||||
dc.getDC().DrawPolygon((int)points.size(), &points[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ColorValueViewer::containsPoint(const RealPoint& p) const {
|
bool ColorValueViewer::containsPoint(const RealPoint& p) const {
|
||||||
// check against mask
|
// check against mask
|
||||||
const AlphaMask& alpha_mask = getMask(0,0);
|
const AlphaMask& alpha_mask = getMask();
|
||||||
if (alpha_mask.isLoaded()) {
|
if (alpha_mask.isLoaded()) {
|
||||||
// check against mask
|
// check against mask
|
||||||
return alpha_mask.isOpaque(p, style().getSize());
|
return alpha_mask.isOpaque(p, style().getSize());
|
||||||
@@ -98,13 +84,3 @@ bool ColorValueViewer::containsPoint(const RealPoint& p) const {
|
|||||||
|| top < style().top_width || bottom < style().bottom_width; // inside vertical border
|
|| top < style().top_width || bottom < style().bottom_width; // inside vertical border
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlphaMask& ColorValueViewer::getMask(int w, int h) const {
|
|
||||||
GeneratedImage::Options opts;
|
|
||||||
opts.package = &viewer.getStylePackage();
|
|
||||||
opts.local_package = &viewer.getLocalPackage();
|
|
||||||
opts.angle = 0;
|
|
||||||
opts.width = w;
|
|
||||||
opts.height = h;
|
|
||||||
return style().mask.get(opts);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,12 +24,6 @@ class ColorValueViewer : public ValueViewer {
|
|||||||
|
|
||||||
virtual void draw(RotatedDC& dc);
|
virtual void draw(RotatedDC& dc);
|
||||||
virtual bool containsPoint(const RealPoint& p) const;
|
virtual bool containsPoint(const RealPoint& p) const;
|
||||||
|
|
||||||
private:
|
|
||||||
/// Draws a border around the field
|
|
||||||
void drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask);
|
|
||||||
/// Load the AlphaMask for this field
|
|
||||||
const AlphaMask& getMask(int w, int h) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -74,31 +74,13 @@ void ImageValueViewer::draw(RotatedDC& dc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// border
|
// border
|
||||||
drawFieldBorder(dc, alpha_mask);
|
drawFieldBorder(dc);
|
||||||
// draw image, if any
|
// draw image, if any
|
||||||
if (bitmap.Ok()) {
|
if (bitmap.Ok()) {
|
||||||
dc.DrawPreRotatedBitmap(bitmap, dc.getInternalRect());
|
dc.DrawPreRotatedBitmap(bitmap, dc.getInternalRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageValueViewer::drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask) {
|
|
||||||
if (!alpha_mask.isLoaded()) {
|
|
||||||
ValueViewer::drawFieldBorder(dc);
|
|
||||||
} else if (setFieldBorderPen(dc)) {
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
||||||
vector<wxPoint> points;
|
|
||||||
alpha_mask.convexHull(points);
|
|
||||||
if (points.size() < 3) return;
|
|
||||||
FOR_EACH(p, points) p = dc.trPixelNoZoom(RealPoint(p.x,p.y));
|
|
||||||
dc.getDC().DrawPolygon((int)points.size(), &points[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImageValueViewer::containsPoint(const RealPoint& p) const {
|
|
||||||
// check against mask
|
|
||||||
return getMask(0,0).isOpaque(p, style().getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageValueViewer::onValueChange() {
|
void ImageValueViewer::onValueChange() {
|
||||||
bitmap = Bitmap();
|
bitmap = Bitmap();
|
||||||
}
|
}
|
||||||
@@ -111,16 +93,6 @@ void ImageValueViewer::onStyleChange(int changes) {
|
|||||||
ValueViewer::onStyleChange(changes);
|
ValueViewer::onStyleChange(changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlphaMask& ImageValueViewer::getMask(int w, int h) const {
|
|
||||||
GeneratedImage::Options opts;
|
|
||||||
opts.package = &viewer.getStylePackage();
|
|
||||||
opts.local_package = &viewer.getLocalPackage();
|
|
||||||
opts.angle = 0;
|
|
||||||
opts.width = w;
|
|
||||||
opts.height = h;
|
|
||||||
return style().mask.get(opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// is an image very light?
|
// is an image very light?
|
||||||
bool very_light(const Image& image) {
|
bool very_light(const Image& image) {
|
||||||
int w = image.GetWidth(), h = image.GetHeight();
|
int w = image.GetWidth(), h = image.GetHeight();
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ class ImageValueViewer : public ValueViewer {
|
|||||||
DECLARE_VALUE_VIEWER(Image) : ValueViewer(parent,style) {}
|
DECLARE_VALUE_VIEWER(Image) : ValueViewer(parent,style) {}
|
||||||
|
|
||||||
virtual void draw(RotatedDC& dc);
|
virtual void draw(RotatedDC& dc);
|
||||||
|
|
||||||
virtual bool containsPoint(const RealPoint& p) const;
|
|
||||||
|
|
||||||
virtual void onValueChange();
|
virtual void onValueChange();
|
||||||
virtual void onStyleChange(int);
|
virtual void onStyleChange(int);
|
||||||
|
|
||||||
@@ -37,12 +34,6 @@ class ImageValueViewer : public ValueViewer {
|
|||||||
|
|
||||||
/// Generate a placeholder image
|
/// Generate a placeholder image
|
||||||
static Bitmap imagePlaceholder(const Rotation& rot, UInt w, UInt h, const Image& background, bool editing);
|
static Bitmap imagePlaceholder(const Rotation& rot, UInt w, UInt h, const Image& background, bool editing);
|
||||||
|
|
||||||
/// Draws a border around the field
|
|
||||||
void drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask);
|
|
||||||
|
|
||||||
/// Load the AlphaMask for this field
|
|
||||||
const AlphaMask& getMask(int w, int h) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ bool MultipleChoiceValueViewer::prepare(RotatedDC& dc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
|
void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
|
||||||
int w = max(0,(int)dc.trX(style().width)), h = max(0,(int)dc.trY(style().height));
|
drawFieldBorder(dc);
|
||||||
const AlphaMask& alpha_mask = getMask(w,h);
|
|
||||||
drawFieldBorder(dc, alpha_mask);
|
|
||||||
if (style().render_style & RENDER_HIDDEN) return;
|
if (style().render_style & RENDER_HIDDEN) return;
|
||||||
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), style().getInternalRect());
|
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), style().getInternalRect());
|
||||||
// selected choices
|
// selected choices
|
||||||
@@ -86,35 +84,7 @@ void MultipleChoiceValueViewer::drawChoice(RotatedDC& dc, RealPoint& pos, const
|
|||||||
pos = move_in_direction(style().direction, pos, size, style().spacing);
|
pos = move_in_direction(style().direction, pos, size, style().spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultipleChoiceValueViewer::drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask) {
|
|
||||||
if (!alpha_mask.isLoaded()) {
|
|
||||||
ValueViewer::drawFieldBorder(dc);
|
|
||||||
} else if (setFieldBorderPen(dc)) {
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
||||||
vector<wxPoint> points;
|
|
||||||
alpha_mask.convexHull(points);
|
|
||||||
if (points.size() < 3) return;
|
|
||||||
FOR_EACH(p, points) p = dc.trPixelNoZoom(RealPoint(p.x,p.y));
|
|
||||||
dc.getDC().DrawPolygon((int)points.size(), &points[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MultipleChoiceValueViewer::containsPoint(const RealPoint& p) const {
|
|
||||||
// check against mask
|
|
||||||
return getMask(0,0).isOpaque(p, style().getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleChoiceValueViewer::onStyleChange(int changes) {
|
void MultipleChoiceValueViewer::onStyleChange(int changes) {
|
||||||
if (changes & CHANGE_MASK) style().image.clearCache();
|
if (changes & CHANGE_MASK) style().image.clearCache();
|
||||||
ValueViewer::onStyleChange(changes);
|
ValueViewer::onStyleChange(changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlphaMask& MultipleChoiceValueViewer::getMask(int w, int h) const {
|
|
||||||
GeneratedImage::Options opts;
|
|
||||||
opts.package = &viewer.getStylePackage();
|
|
||||||
opts.local_package = &viewer.getLocalPackage();
|
|
||||||
opts.angle = 0;
|
|
||||||
opts.width = w;
|
|
||||||
opts.height = h;
|
|
||||||
return style().mask.get(opts);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,15 +23,10 @@ class MultipleChoiceValueViewer : public ValueViewer {
|
|||||||
virtual bool prepare(RotatedDC& dc);
|
virtual bool prepare(RotatedDC& dc);
|
||||||
virtual void draw(RotatedDC& dc);
|
virtual void draw(RotatedDC& dc);
|
||||||
virtual void onStyleChange(int);
|
virtual void onStyleChange(int);
|
||||||
virtual bool containsPoint(const RealPoint& p) const;
|
|
||||||
protected:
|
protected:
|
||||||
double item_height; ///< Height of a single item, or 0 if non uniform
|
double item_height; ///< Height of a single item, or 0 if non uniform
|
||||||
private:
|
private:
|
||||||
void drawChoice(RotatedDC& dc, RealPoint& pos, const String& choice, bool active = true);
|
void drawChoice(RotatedDC& dc, RealPoint& pos, const String& choice, bool active = true);
|
||||||
/// Draws a border around the field
|
|
||||||
void drawFieldBorder(RotatedDC& dc, const AlphaMask& alpha_mask);
|
|
||||||
/// Load the AlphaMask for this field
|
|
||||||
const AlphaMask& getMask(int w, int h) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -15,14 +15,7 @@
|
|||||||
IMPLEMENT_VALUE_VIEWER(Text);
|
IMPLEMENT_VALUE_VIEWER(Text);
|
||||||
|
|
||||||
bool TextValueViewer::prepare(RotatedDC& dc) {
|
bool TextValueViewer::prepare(RotatedDC& dc) {
|
||||||
if (!style().mask_filename.empty() && !style().mask.isLoaded()) {
|
getMask(dc); // ensure alpha/contour mask is loaded
|
||||||
// load contour mask
|
|
||||||
Image image;
|
|
||||||
InputStreamP image_file = getStylePackage().openIn(style().mask_filename);
|
|
||||||
if (image.LoadFile(*image_file)) {
|
|
||||||
style().mask.load(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v.prepare(dc, value().value(), style(), viewer.getContext());
|
return v.prepare(dc, value().value(), style(), viewer.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include <render/value/viewer.hpp>
|
#include <render/value/viewer.hpp>
|
||||||
#include <render/card/viewer.hpp>
|
#include <render/card/viewer.hpp>
|
||||||
|
|
||||||
|
DECLARE_TYPEOF_COLLECTION(wxPoint);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ValueViewer
|
// ----------------------------------------------------------------------------- : ValueViewer
|
||||||
|
|
||||||
ValueViewer::ValueViewer(DataViewer& parent, const StyleP& style)
|
ValueViewer::ValueViewer(DataViewer& parent, const StyleP& style)
|
||||||
@@ -27,10 +29,7 @@ void ValueViewer::setValue(const ValueP& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ValueViewer::containsPoint(const RealPoint& p) const {
|
bool ValueViewer::containsPoint(const RealPoint& p) const {
|
||||||
return p.x >= 0
|
return getMask().isOpaque(p, styleP->getSize());
|
||||||
&& p.y >= 0
|
|
||||||
&& p.x < styleP->width
|
|
||||||
&& p.y < styleP->height;
|
|
||||||
}
|
}
|
||||||
RealRect ValueViewer::boundingBox() const {
|
RealRect ValueViewer::boundingBox() const {
|
||||||
return styleP->getExternalRect().grow(1);
|
return styleP->getExternalRect().grow(1);
|
||||||
@@ -54,10 +53,30 @@ bool ValueViewer::setFieldBorderPen(RotatedDC& dc) {
|
|||||||
void ValueViewer::drawFieldBorder(RotatedDC& dc) {
|
void ValueViewer::drawFieldBorder(RotatedDC& dc) {
|
||||||
if (setFieldBorderPen(dc)) {
|
if (setFieldBorderPen(dc)) {
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
dc.DrawRectangle(dc.getInternalRect().grow(dc.trInvS(1)));
|
const AlphaMask& alpha_mask = getMask(dc);
|
||||||
|
if (alpha_mask.isLoaded()) {
|
||||||
|
// from mask
|
||||||
|
vector<wxPoint> points;
|
||||||
|
alpha_mask.convexHull(points);
|
||||||
|
if (points.size() < 3) return;
|
||||||
|
FOR_EACH(p, points) p = dc.trPixelNoZoom(RealPoint(p.x,p.y));
|
||||||
|
dc.getDC().DrawPolygon((int)points.size(), &points[0]);
|
||||||
|
} else {
|
||||||
|
// simple rectangle
|
||||||
|
dc.DrawRectangle(dc.getInternalRect().grow(dc.trInvS(1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AlphaMask& ValueViewer::getMask(int w, int h) const {
|
||||||
|
GeneratedImage::Options opts(w, h, &getStylePackage(), &getLocalPackage());
|
||||||
|
return styleP->mask.get(opts);
|
||||||
|
}
|
||||||
|
const AlphaMask& ValueViewer::getMask(const Rotation& rot) const {
|
||||||
|
return getMask((int)rot.trX(styleP->width), (int)rot.trY(styleP->height));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ValueViewer::redraw() {
|
void ValueViewer::redraw() {
|
||||||
viewer.redraw(*this);
|
viewer.redraw(*this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ class ValueViewer : public StyleListener {
|
|||||||
/// Redraw this viewer
|
/// Redraw this viewer
|
||||||
void redraw();
|
void redraw();
|
||||||
|
|
||||||
|
/// Load the AlphaMask for this field, scaled but not rotated
|
||||||
|
const AlphaMask& getMask(int w = 0, int h = 0) const;
|
||||||
|
const AlphaMask& getMask(const Rotation& rot) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Should this viewer render using a platform native look?
|
/// Should this viewer render using a platform native look?
|
||||||
bool nativeLook() const;
|
bool nativeLook() const;
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ const AlphaMask& CachedScriptableMask::get(const GeneratedImage::Options& img_op
|
|||||||
getNoCache(img_options,mask);
|
getNoCache(img_options,mask);
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
void CachedScriptableMask::getNoCache(const GeneratedImage::Options& img_options, AlphaMask& other_mask) {
|
void CachedScriptableMask::getNoCache(const GeneratedImage::Options& img_options, AlphaMask& other_mask) const {
|
||||||
if (script.isBlank()) {
|
if (script.isBlank()) {
|
||||||
other_mask.clear();
|
other_mask.clear();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+12
-2
@@ -117,12 +117,22 @@ class CachedScriptableMask {
|
|||||||
/// Update the script, returns true if the value has changed
|
/// Update the script, returns true if the value has changed
|
||||||
bool update(Context& ctx);
|
bool update(Context& ctx);
|
||||||
|
|
||||||
|
inline void initDependencies(Context& ctx, const Dependency& dep) const {
|
||||||
|
script.initDependencies(ctx, dep);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the alpha mask; with the given options
|
/// Get the alpha mask; with the given options
|
||||||
/** if img_options.width == 0 and the mask is already loaded, just returns it. */
|
/** if img_options.width == 0 and the mask is already loaded, just returns it.
|
||||||
|
* Returns a reference, so calling again might change earlier results.
|
||||||
|
*/
|
||||||
const AlphaMask& get(const GeneratedImage::Options& img_options);
|
const AlphaMask& get(const GeneratedImage::Options& img_options);
|
||||||
|
|
||||||
/// Get a mask that is not cached
|
/// Get a mask that is not cached
|
||||||
void getNoCache(const GeneratedImage::Options& img_options, AlphaMask& mask);
|
void getNoCache(const GeneratedImage::Options& img_options, AlphaMask& mask) const;
|
||||||
|
|
||||||
|
/// Get the mask directly from the cache, without updating
|
||||||
|
/** Should only be used after get() was called before, otherwise an old mask might be returned */
|
||||||
|
inline const AlphaMask& getFromCache() const { return mask; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScriptableImage script;
|
ScriptableImage script;
|
||||||
|
|||||||
Reference in New Issue
Block a user