mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
implemented SymbolFilter
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@70 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <data/field/symbol.hpp>
|
||||
#include <render/symbol/filter.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolField
|
||||
|
||||
@@ -35,7 +36,7 @@ SymbolStyle::Variation::Variation()
|
||||
IMPLEMENT_REFLECTION(SymbolStyle::Variation) {
|
||||
REFLECT(name);
|
||||
REFLECT(border_radius);
|
||||
//REFLECT_NAMELESS(filter);
|
||||
REFLECT_NAMELESS(filter);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolValue
|
||||
|
||||
@@ -109,5 +109,8 @@ inline int bot(int x) { return max(0, x); } ///< bottom range check for color
|
||||
inline int top(int x) { return min(255, x); } ///< top range check for color values
|
||||
inline int col(int x) { return top(bot(x)); } ///< top and bottom range check for color values
|
||||
|
||||
/// Linear interpolation between colors
|
||||
Color lerp(const Color& a, const Color& b, double t);
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
@@ -112,6 +112,7 @@ void GalleryList::onKeyDown(wxKeyEvent& ev) {
|
||||
}
|
||||
|
||||
// Linear interpolation between colors
|
||||
// MOVE ME, declared in gfx.hpp
|
||||
Color lerp(const Color& a, const Color& b, double t) {
|
||||
return Color(a.Red() + (b.Red() - a.Red() ) * t,
|
||||
a.Green() + (b.Green() - a.Green()) * t,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <data/symbol.hpp>
|
||||
#include <gui/symbol/viewer.hpp>
|
||||
#include <render/symbol/viewer.hpp>
|
||||
|
||||
class SymbolWindow;
|
||||
DECLARE_POINTER_TYPE(SymbolEditorBase);
|
||||
|
||||
+40
-18
@@ -508,24 +508,6 @@
|
||||
<File
|
||||
RelativePath=".\gui\symbol\select_editor.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gui\symbol\viewer.cpp">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Unicode|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gui\symbol\viewer.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gui\symbol\window.cpp">
|
||||
<FileConfiguration
|
||||
@@ -1464,6 +1446,46 @@
|
||||
RelativePath=".\render\card\viewer.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="symbol"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\render\symbol\filter.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\render\symbol\filter.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\render\symbol\viewer.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Unicode|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Unicode|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)3.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\render\symbol\viewer.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\code_template.cpp">
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <render/symbol/filter.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Symbol filtering
|
||||
|
||||
void filter_symbol(Image& symbol, const SymbolFilter& filter) {
|
||||
if (!symbol.HasAlpha()) symbol.InitAlpha();
|
||||
Byte* data = symbol.GetData();
|
||||
Byte* alpha = symbol.GetAlpha();
|
||||
UInt width = symbol.GetWidth(), height = symbol.GetHeight();
|
||||
for (UInt y = 0 ; y < width ; ++y) {
|
||||
for (UInt x = 0 ; x < height ; ++x) {
|
||||
// Determine set
|
||||
// green -> border or outside
|
||||
// green+red=white -> border
|
||||
SymbolSet point = data[1] ? (data[0] ? SYMBOL_BORDER : SYMBOL_OUTSIDE) : SYMBOL_INSIDE;
|
||||
// Call filter
|
||||
AColor result = filter.color((double)x / width, (double)y / height, point);
|
||||
// Store color
|
||||
data[0] = result.Red();
|
||||
data[2] = result.Green();
|
||||
data[2] = result.Blue();
|
||||
alpha[0] = result.alpha;
|
||||
// next
|
||||
data += 3;
|
||||
alpha += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFilter
|
||||
|
||||
IMPLEMENT_REFLECTION(SymbolFilter) {
|
||||
if (!tag.reading()) {
|
||||
String fill_type = fillType();
|
||||
REFLECT(fill_type);
|
||||
}
|
||||
}
|
||||
template <> void GetMember::handle(const shared_ptr<SymbolFilter>& f) {
|
||||
handle(*f);
|
||||
}
|
||||
|
||||
template <>
|
||||
shared_ptr<SymbolFilter> read_new<SymbolFilter>(Reader& reader) {
|
||||
// there must be a fill type specified
|
||||
String fill_type;
|
||||
reader.handle(_("fill type"), fill_type);
|
||||
if (fill_type == _("solid")) return new_shared<SolidFillSymbolFilter>();
|
||||
else if (fill_type == _("linear gradient")) return new_shared<LinearGradientSymbolFilter>();
|
||||
else if (fill_type == _("radial gradient")) return new_shared<RadialGradientSymbolFilter>();
|
||||
else {
|
||||
throw ParseError(_("Unsupported fill type: '") + fill_type + _("'"));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SolidFillSymbolFilter
|
||||
|
||||
String SolidFillSymbolFilter::fillType() const { return _("solid"); }
|
||||
|
||||
AColor SolidFillSymbolFilter::color(double x, double y, SymbolSet point) const {
|
||||
if (point == SYMBOL_INSIDE) return fill_color;
|
||||
else if (point == SYMBOL_BORDER) return border_color;
|
||||
else return AColor(0,0,0,0);
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(SolidFillSymbolFilter) {
|
||||
REFLECT_BASE(SymbolFilter);
|
||||
REFLECT(fill_color);
|
||||
REFLECT(border_color);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : GradientSymbolFilter
|
||||
|
||||
template <typename T>
|
||||
AColor GradientSymbolFilter::color(double x, double y, SymbolSet point, const T* t) const {
|
||||
if (point == SYMBOL_INSIDE) return lerp(fill_color_1, fill_color_2, t->t(x,y));
|
||||
else if (point == SYMBOL_BORDER) return lerp(border_color_1, border_color_2, t->t(x,y));
|
||||
else return AColor(0,0,0,0);
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(GradientSymbolFilter) {
|
||||
REFLECT_BASE(SymbolFilter);
|
||||
REFLECT(fill_color_1);
|
||||
REFLECT(fill_color_2);
|
||||
REFLECT(border_color_1);
|
||||
REFLECT(border_color_2);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : LinearGradientSymbolFilter
|
||||
|
||||
String LinearGradientSymbolFilter::fillType() const { return _("linear gradient"); }
|
||||
|
||||
LinearGradientSymbolFilter::LinearGradientSymbolFilter()
|
||||
: center_x(0.5), center_y(0.5)
|
||||
, end_x(1), end_y(1)
|
||||
{}
|
||||
|
||||
AColor LinearGradientSymbolFilter::color(double x, double y, SymbolSet point) const {
|
||||
return GradientSymbolFilter::color(x,y,point,this);
|
||||
}
|
||||
|
||||
double LinearGradientSymbolFilter::t(double x, double y) const {
|
||||
//return abs( int(x - center_x) * dirX + int(y - centerY) * dirY) * scale;
|
||||
return 0; // todo
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(LinearGradientSymbolFilter) {
|
||||
REFLECT_BASE(GradientSymbolFilter);
|
||||
REFLECT(center_x); REFLECT(center_y);
|
||||
REFLECT(end_x); REFLECT(end_y);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : RadialGradientSymbolFilter
|
||||
|
||||
String RadialGradientSymbolFilter::fillType() const { return _("radial gradient"); }
|
||||
|
||||
AColor RadialGradientSymbolFilter::color(double x, double y, SymbolSet point) const {
|
||||
return GradientSymbolFilter::color(x,y,point,this);
|
||||
}
|
||||
|
||||
// TODO: move to some general util header
|
||||
inline double sqr(double x) { return x * x; }
|
||||
|
||||
double RadialGradientSymbolFilter::t(double x, double y) const {
|
||||
return sqrt( (sqr(x - 0.5) + sqr(y - 0.5)) * 2);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||
//+----------------------------------------------------------------------------+
|
||||
|
||||
#ifndef HEADER_RENDER_SYMBOL_FILTER
|
||||
#define HEADER_RENDER_SYMBOL_FILTER
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <util/reflect.hpp>
|
||||
|
||||
class SymbolFilter;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Color
|
||||
|
||||
/// Color with alpha channel
|
||||
class AColor : public Color {
|
||||
public:
|
||||
int alpha; ///< The alpha value, in the range [0..255]
|
||||
inline AColor(int r, int g, int b, int a = 255) : Color(r,g,b), alpha(a) {}
|
||||
inline AColor(const Color& color, int a = 255) : Color(color), alpha(a) {}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Symbol filtering
|
||||
|
||||
/// Filter a symbol-image.
|
||||
/** Filtering means that each pixel will be determined by the specified function.
|
||||
* The result is stored in the symbol parameter.
|
||||
*/
|
||||
void filter_symbol(Image& symbol, const SymbolFilter& filter);
|
||||
|
||||
/// Is a point inside a symbol?
|
||||
enum SymbolSet
|
||||
{ SYMBOL_INSIDE
|
||||
, SYMBOL_BORDER
|
||||
, SYMBOL_OUTSIDE
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFilter
|
||||
|
||||
/// Base class for symbol filters
|
||||
class SymbolFilter {
|
||||
public:
|
||||
virtual ~SymbolFilter() {}
|
||||
/// What color should the symbol have at location (x, y)?
|
||||
/** x,y are in the range [0...1) */
|
||||
virtual AColor color(double x, double y, SymbolSet point) const = 0;
|
||||
/// Name of this fill type
|
||||
virtual String fillType() const = 0;
|
||||
|
||||
DECLARE_REFLECTION_VIRTUAL();
|
||||
};
|
||||
|
||||
template <>
|
||||
shared_ptr<SymbolFilter> read_new<SymbolFilter>(Reader& reader);
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFilter types
|
||||
|
||||
/// Symbol filter that returns solid colors
|
||||
class SolidFillSymbolFilter : public SymbolFilter {
|
||||
public:
|
||||
virtual AColor color(double x, double y, SymbolSet point) const;
|
||||
virtual String fillType() const;
|
||||
private:
|
||||
Color fill_color, border_color;
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
/// Symbol filter that returns some gradient
|
||||
class GradientSymbolFilter : public SymbolFilter {
|
||||
protected:
|
||||
Color fill_color_1, border_color_1;
|
||||
Color fill_color_2, border_color_2;
|
||||
template <typename T>
|
||||
AColor color(double x, double y, SymbolSet point, const T* t) const;
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
/// Symbol filter that returns a linear gradient
|
||||
class LinearGradientSymbolFilter : public GradientSymbolFilter {
|
||||
public:
|
||||
LinearGradientSymbolFilter();
|
||||
|
||||
virtual AColor color(double x, double y, SymbolSet point) const;
|
||||
virtual String fillType() const;
|
||||
|
||||
/// return time on the gradient, used by GradientSymbolFilter::color
|
||||
inline double t(double x, double y) const;
|
||||
|
||||
private:
|
||||
double center_x, center_y;
|
||||
double end_x, end_y;
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
/// Symbol filter that returns a radial gradient
|
||||
class RadialGradientSymbolFilter : public GradientSymbolFilter {
|
||||
public:
|
||||
virtual AColor color(double x, double y, SymbolSet point) const;
|
||||
virtual String fillType() const;
|
||||
|
||||
/// return time on the gradient, used by GradientSymbolFilter::color
|
||||
inline double t(double x, double y) const;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <gui/symbol/viewer.hpp>
|
||||
#include <render/symbol/viewer.hpp>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(SymbolPartP);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Constructor
|
||||
|
||||
SymbolViewer::SymbolViewer(const SymbolP& symbol, double borderRadius)
|
||||
: borderRadius(borderRadius)
|
||||
SymbolViewer::SymbolViewer(const SymbolP& symbol, double border_radius)
|
||||
: border_radius(border_radius)
|
||||
, rotation(0, RealRect(0,0,500,500))
|
||||
{
|
||||
setSymbol(symbol);
|
||||
@@ -176,7 +176,7 @@ void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interi
|
||||
// white/black
|
||||
border->SetBrush(Color(borderCol, borderCol, borderCol));
|
||||
}
|
||||
border->SetPen(wxPen(*wxWHITE, rotation.trS(borderRadius)));
|
||||
border->SetPen(wxPen(*wxWHITE, rotation.trS(border_radius)));
|
||||
border->DrawPolygon((int)points.size(), &points[0]);
|
||||
}
|
||||
// draw interior
|
||||
@@ -186,38 +186,3 @@ void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interi
|
||||
interior->DrawPolygon((int)points.size(), &points[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void SymbolViewer::calcBezierPoint(const ControlPointP& p0, const ControlPointP& p1, Point*& p_out, UInt count) {
|
||||
BezierCurve c(*p0, *p1);
|
||||
// add start point
|
||||
*p_out = toDisplay(*p0);
|
||||
++p_out;
|
||||
// recursively calculate rest of curve
|
||||
calcBezierOpt(c, *p0, *p1, 0.0f, 1.0f, p_out, count-1);
|
||||
}
|
||||
|
||||
|
||||
void SymbolViewer::calcBezierOpt(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1, double t0, double t1, Point*& p_out, mutable UInt count) {
|
||||
if (count <= 0) return;
|
||||
double midtime = (t0+t1) * 0.5f;
|
||||
Vector2D midpoint = c.pointAt(midtime);
|
||||
Vector2D d0 = p0 - midpoint;
|
||||
Vector2D d1 = midpoint - p1;
|
||||
// Determine treshold for subdivision, greater angle -> subdivide
|
||||
// greater size -> subdivide
|
||||
double treshold = fabs( atan2(d0.x,d0.y) - atan2(d1.x,d1.y)) * (p0-p1).lengthSqr();
|
||||
bool subdivide = treshold >= .0001;
|
||||
// subdivide left
|
||||
calcBezierOpt(c, p0, midpoint, t0, midtime, p_out, count/2);
|
||||
// add midpoint
|
||||
if (subdivide) {
|
||||
*p_out = toDisplay(midpoint);
|
||||
++p_out;
|
||||
count -= 1;
|
||||
}
|
||||
// subdivide right
|
||||
calcBezierOpt(c, midpoint, p1, midtime, t1, p_out, count/2);
|
||||
}
|
||||
*/
|
||||
@@ -14,6 +14,11 @@
|
||||
#include <data/symbol.hpp>
|
||||
#include <gfx/bezier.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Simple rendering
|
||||
|
||||
/// Render a Symbol to an Image
|
||||
Image render_symbol(const SymbolP& symbol, double border_radius = 0.05, int size = 100);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Symbol Viewer
|
||||
|
||||
enum HighlightStyle {
|
||||
@@ -25,10 +30,10 @@ enum HighlightStyle {
|
||||
class SymbolViewer : public SymbolView {
|
||||
public:
|
||||
// --------------------------------------------------- : Data
|
||||
SymbolViewer(const SymbolP& symbol, double borderRadius = 0.05);
|
||||
SymbolViewer(const SymbolP& symbol, double border_radius = 0.05);
|
||||
|
||||
// drawing
|
||||
double borderRadius;
|
||||
double border_radius;
|
||||
|
||||
// --------------------------------------------------- : Point translation
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ Context& ScriptManager::getContext(const StyleSheetP& stylesheet) {
|
||||
ctx->setVariable(_("set"), new_intrusive1<ScriptObject<Set*> >(&set));
|
||||
ctx->setVariable(_("game"), toScript(set.game));
|
||||
ctx->setVariable(_("stylesheet"), toScript(stylesheet));
|
||||
ctx->setVariable(_("card"), set.cards.empty() ? script_nil : toScript(set.cards.front())); // dummy value
|
||||
//ctx->setVariable(_("styling"), toScript(set->extraStyleData(style)));
|
||||
try {
|
||||
// perform init scripts
|
||||
|
||||
Reference in New Issue
Block a user