Basic text rendering working;

Added Font (done) and SymbolFont (skeleton);
Added styling to set;
Added CountourMap;
Some script fixes

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@73 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2006-11-17 17:57:04 +00:00
parent ea5be88bdb
commit ce6a83e34b
45 changed files with 1595 additions and 84 deletions
+2 -2
View File
@@ -93,7 +93,7 @@ IMPLEMENT_REFLECTION(Style) {
}
void init_object(const FieldP& field, StyleP& style) {
style = field->newStyle(field);
if (!style) style = field->newStyle(field);
}
template <> StyleP read_new<Style>(Reader&) {
throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already"));
@@ -123,7 +123,7 @@ IMPLEMENT_REFLECTION_NAMELESS(Value) {
}
void init_object(const FieldP& field, ValueP& value) {
value = field->newValue(field);
if (!value) value = field->newValue(field);
}
template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
+1 -1
View File
@@ -99,7 +99,7 @@ class Style {
/// Update scripted values of this style, return true if anything has changed
virtual bool update(Context&);
/// Add the given dependency to the dependet_scripts list for the variables this style depends on
/// Add the given dependency to the dependent_scripts list for the variables this style depends on
virtual void initDependencies(Context&, const Dependency&) const;
private:
+22 -2
View File
@@ -22,6 +22,12 @@ String TextField::typeName() const {
return _("text");
}
void TextField::initDependencies(Context& ctx, const Dependency& dep) const {
Field ::initDependencies(ctx, dep);
script .initDependencies(ctx, dep);
default_script.initDependencies(ctx, dep);
}
IMPLEMENT_REFLECTION(TextField) {
REFLECT_BASE(Field);
@@ -48,10 +54,19 @@ TextStyle::TextStyle(const TextFieldP& field)
, line_height_line(1.0)
{}
bool TextStyle::update(Context& ctx) {
return Style::update(ctx)
| font.update(ctx);
}
void TextStyle::initDependencies(Context& ctx, const Dependency& dep) const {
Style::initDependencies(ctx, dep);
font.initDependencies(ctx, dep);
}
IMPLEMENT_REFLECTION(TextStyle) {
REFLECT_BASE(Style);
// REFLECT(font);
// REFLECT(symbol_font);
REFLECT(font);
REFLECT(symbol_font);
REFLECT(always_symbol);
REFLECT(allow_formating);
REFLECT(alignment);
@@ -75,6 +90,11 @@ IMPLEMENT_REFLECTION(TextStyle) {
String TextValue::toString() const {
return value();
}
bool TextValue::update(Context& ctx) {
Value::update(ctx);
return field().default_script.invokeOnDefault(ctx, value)
| field(). script.invokeOn(ctx, value);
}
IMPLEMENT_REFLECTION_NAMELESS(TextValue) {
REFLECT_NAMELESS(value);
+23 -12
View File
@@ -12,7 +12,10 @@
#include <util/prec.hpp>
#include <util/defaultable.hpp>
#include <data/field.hpp>
#include <data/font.hpp>
#include <data/symbol_font.hpp>
#include <script/scriptable.hpp>
#include <gfx/gfx.hpp>
// ----------------------------------------------------------------------------- : TextField
@@ -31,7 +34,9 @@ class TextField : public Field {
bool multi_line; ///< Are newlines allowed in the text?
bool move_cursor_with_sort; ///< When the text is reordered by a script should the cursor position be updated?
String default_name; ///< Name of "default" value
virtual void initDependencies(Context&, const Dependency&) const;
private:
DECLARE_REFLECTION();
};
@@ -44,21 +49,25 @@ class TextStyle : public Style {
TextStyle(const TextFieldP&);
DECLARE_STYLE_TYPE(Text);
// FontInfo font; ///< Font to use for the text
// SymbolFontInfo symbol_font; ///< Symbol font for symbols in the text
bool always_symbol; ///< Should everything be drawn as symbols?
bool allow_formating; ///< Is formating (bold/italic/..) allowed?
Alignment alignment; ///< Alignment inside the box
int angle; ///< Angle of the text inside the box
Font font; ///< Font to use for the text
SymbolFontRef symbol_font; ///< Symbol font for symbols in the text
bool always_symbol; ///< Should everything be drawn as symbols?
bool allow_formating; ///< Is formating (bold/italic/..) allowed?
Alignment alignment; ///< Alignment inside the box
int angle; ///< Angle of the text inside the box
double padding_left, padding_left_min; ///< Padding
double padding_right, padding_right_min; ///< Padding
double padding_top, padding_top_min; ///< Padding
double padding_bottom, padding_bottom_min; ///< Padding
double line_height_soft; ///< Line height for soft linebreaks
double line_height_hard; ///< Line height for hard linebreaks
double line_height_line; ///< Line height for <line> tags
String mask_filename; ///< Filename of the mask
// ContourMaskP mask; ///< Mask to fit the text to (may be null)
double line_height_soft; ///< Line height for soft linebreaks
double line_height_hard; ///< Line height for hard linebreaks
double line_height_line; ///< Line height for <line> tags
String mask_filename; ///< Filename of the mask
ContourMask mask; ///< Mask to fit the text to (may be null)
virtual bool update(Context&);
virtual void initDependencies(Context&, const Dependency&) const;
private:
DECLARE_REFLECTION();
};
@@ -74,6 +83,8 @@ class TextValue : public Value {
Defaultable<String> value; ///< The text of this value
virtual String toString() const;
virtual bool update(Context&);
private:
DECLARE_REFLECTION();
};
+73
View File
@@ -0,0 +1,73 @@
//+----------------------------------------------------------------------------+
//| 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 <data/font.hpp>
// ----------------------------------------------------------------------------- : Font
Font::Font()
: font(*wxNORMAL_FONT)
, size(font.GetPointSize())
, scale_down_to(100000)
, shadow_displacement(0,0)
, separator_color(128,128,128)
{}
bool Font::update(Context& ctx) {
return color .update(ctx)
| shadow_color.update(ctx);
}
void Font::initDependencies(Context& ctx, const Dependency& dep) const {
color .initDependencies(ctx, dep);
shadow_color.initDependencies(ctx, dep);
}
FontP Font::make(bool bold, bool italic) const {
FontP f(new Font(*this));
if (bold) f->font.SetWeight(wxBOLD);
if (italic) {
if (!italic_name.empty()) {
f->font.SetFaceName(italic_name);
} else {
f->font.SetWeight(wxBOLD);
}
}
return f;
}
void reflect_font(Reader& tag, Font& font) {
String name, weight, style;
double size = -1;
REFLECT(name);
REFLECT(size);
REFLECT(weight);
REFLECT(style);
if (!name.empty()) font.font.SetFaceName(name);
if (size > 0) font.font.SetPointSize(font.size = size);
if (!weight.empty()) font.font.SetWeight(weight == _("bold") ? wxBOLD : wxNORMAL);
if (!style.empty()) font.font.SetWeight(style == _("italic") ? wxITALIC : wxNORMAL);
}
template <typename Tag>
void reflect_font(Tag& tag, const Font& font) {
REFLECT_N("name", font.font.GetFaceName());
REFLECT_N("size", font.size);
REFLECT_N("weight", font.font.GetWeight() == wxBOLD ? _("bold") : _("normal"));
REFLECT_N("style", font.font.GetStyle() == wxITALIC ? _("italic") : _("normal"));
}
IMPLEMENT_REFLECTION(Font) {
reflect_font(tag, *this);
REFLECT(italic_name);
REFLECT(color);
REFLECT(scale_down_to);
REFLECT_N("shadow_displacement_x", shadow_displacement.width);
REFLECT_N("shadow_displacement_y", shadow_displacement.height);
REFLECT(shadow_color);
REFLECT(separator_color);
}
+52
View File
@@ -0,0 +1,52 @@
//+----------------------------------------------------------------------------+
//| 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_DATA_FONT
#define HEADER_DATA_FONT
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/real_point.hpp>
#include <script/scriptable.hpp>
DECLARE_POINTER_TYPE(Font);
// ----------------------------------------------------------------------------- : Font
/// A font for rendering text
/** Contains additional information about scaling, color and shadow */
class Font {
public:
wxFont font; ///< The actual wxFont to use
double size; ///< Size of the font
double scale_down_to; ///< Smallest size to scale down to
Scriptable<Color> color; ///< Color to use
Scriptable<Color> shadow_color; ///< Color for shadow
RealSize shadow_displacement; ///< Position of the shadow
String italic_name; ///< Font name for italic text (optional)
Color separator_color; ///< Color for <sep> text
Font();
/// Update the scritables, returns true if there is a change
bool update(Context& ctx);
/// Add the given dependency to the dependent_scripts list for the variables this font depends on
virtual void initDependencies(Context&, const Dependency&) const;
/// Does this font have a shadow?
inline bool hasShadow() { return shadow_displacement.width != 0 || shadow_displacement.height != 0; }
/// Make a bold/italic version of this font
FontP make(bool bold, bool italic) const;
private:
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : EOF
#endif
+56 -1
View File
@@ -14,6 +14,7 @@
#include <data/field/text.hpp> // for 0.2.7 fix
#include <script/value.hpp>
#include <script/script_manager.hpp>
#include <wx/sstream.h>
DECLARE_TYPEOF_COLLECTION(CardP);
typedef IndexMap<FieldP,ValueP> IndexMap_FieldP_ValueP;
@@ -45,6 +46,9 @@ Context& Set::getContext() {
Context& Set::getContext(const Card& card) {
return script_manager->getContext(card.stylesheet ? card.stylesheet : stylesheet);
}
void Set::updateFor(const CardP& card) {
script_manager->updateStyles(card);
}
StyleSheetP Set::stylesheetFor(const CardP& card) {
if (card && card->stylesheet) return card->stylesheet;
@@ -90,8 +94,16 @@ void Set::validate(Version file_app_version) {
*/ }
}
// in scripts, set.something is read from the set_info
template <typename Tag>
void reflect_set_info_get_member(Tag& tag, const IndexMap<FieldP, ValueP>& data) {}
void reflect_set_info_get_member(GetMember& tag, const IndexMap<FieldP, ValueP>& data) {
REFLECT_NAMELESS(data);
}
IMPLEMENT_REFLECTION(Set) {
tag.addAlias(300, _("style"), _("stylesheet")); // < 0.3.0 used style instead of stylesheet
tag.addAlias(300, _("style"), _("stylesheet")); // < 0.3.0 used style instead of stylesheet
tag.addAlias(300, _("extra set info"), _("styling"));
REFLECT(game);
if (game) {
if (tag.reading()) {
@@ -100,11 +112,54 @@ IMPLEMENT_REFLECTION(Set) {
WITH_DYNAMIC_ARG(game_for_reading, game.get());
REFLECT(stylesheet);
REFLECT_N("set_info", data);
if (stylesheet) {
REFLECT_N("styling", styling_data);
}
REFLECT(cards);
}
reflect_set_info_get_member(tag,data);
REFLECT(apprentice_code);
}
// ----------------------------------------------------------------------------- : Styling
// Extra set data, for a specific stylesheet
/* The data is not read immediatly, because we do not know the stylesheet */
class Set::Styling {
public:
IndexMap<FieldP, ValueP> data;
String unread_data;
DECLARE_REFLECTION();
};
IndexMap<FieldP, ValueP>& Set::stylingDataFor(const StyleSheet& stylesheet) {
StylingP& styling = styling_data[stylesheet.stylesheetName()];
if (!styling) {
styling = new_shared<Styling>();
styling->data.init(stylesheet.styling_fields);
} else if (!styling->unread_data.empty()) {
// we delayed the reading of the data, read it now
styling->data.init(stylesheet.styling_fields);
Reader reader(new_shared1<wxStringInputStream>(styling->unread_data), _("styling data of ") + stylesheet.stylesheetName());
reader.handle(styling->data);
styling->unread_data.clear();
}
return styling->data;
}
// custom reflection : read into unread_data
template <> void Reader::handle(Set::Styling& s) {
handle(s.unread_data);
}
template <> void Writer::handle(const Set::Styling& s) {
handle(s.data);
}
template <> void GetMember::handle(const Set::Styling& s) {
handle(s.data);
}
template <> void GetDefaultMember::handle(const Set::Styling& s) {
handle(s.data);
}
// ----------------------------------------------------------------------------- : SetView
+12
View File
@@ -19,6 +19,7 @@ DECLARE_POINTER_TYPE(Card);
DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet);
DECLARE_POINTER_TYPE(Styling);
DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Value);
class ScriptManager;
@@ -44,6 +45,9 @@ class Set : public Packaged {
/// The values on the fields of the set
/** The indices should correspond to the set_fields in the Game */
IndexMap<FieldP, ValueP> data;
/// Extra values for specitic stylesheets, indexed by stylesheet name
DECLARE_POINTER_TYPE(Styling);
map<String, StylingP> styling_data;
/// The cards in the set
vector<CardP> cards;
/// Code to use for apprentice (Magic only)
@@ -57,10 +61,15 @@ class Set : public Packaged {
/// A context for performing scripts on a particular card
/** Should only be used from the main thread! */
Context& getContext(const Card& card);
/// Update styles for a card
void updateFor(const CardP& card);
/// Stylesheet to use for a particular card
StyleSheetP stylesheetFor(const CardP& card);
/// Styling information for a particular stylesheet
IndexMap<FieldP, ValueP>& stylingDataFor(const StyleSheet&);
protected:
virtual String typeName() const;
virtual void validate(Version);
@@ -71,6 +80,9 @@ class Set : public Packaged {
scoped_ptr<ScriptManager> script_manager;
};
inline int item_count(const Set& set) {
return (int)set.cards.size();
}
// ----------------------------------------------------------------------------- : SetView
+14 -3
View File
@@ -24,6 +24,14 @@ StyleSheet::StyleSheet()
StyleSheetP StyleSheet::byGameAndName(const Game& game, const String& name) {
return packages.open<StyleSheet>(game.name() + _("-") + name + _(".mse-style"));
}
String StyleSheet::stylesheetName() const {
String sn = name(), gn = game->name();
if (sn.size() + 1 > gn.size()) {
return sn.substr(gn.size() + 1); // remove "gamename-"
} else {
return sn;
}
}
String StyleSheet::typeNameStatic() { return _("style"); }
String StyleSheet::typeName() const { return _("style"); }
@@ -36,6 +44,7 @@ InputStreamP StyleSheet::openIconFile() {
return game->openIconFile(); // use game icon by default
}
}
IMPLEMENT_REFLECTION(StyleSheet) {
// < 0.3.0 didn't use card_ prefix
tag.addAlias(300, _("width"), _("card width"));
@@ -44,6 +53,8 @@ IMPLEMENT_REFLECTION(StyleSheet) {
tag.addAlias(300, _("background"), _("card background"));
tag.addAlias(300, _("info style"), _("set info style"));
tag.addAlias(300, _("align"), _("alignment"));
tag.addAlias(300, _("extra field"),_("styling field"));
tag.addAlias(300, _("extra style"),_("styling style"));
REFLECT(game);
REFLECT(full_name);
@@ -61,9 +72,9 @@ IMPLEMENT_REFLECTION(StyleSheet) {
REFLECT(card_style);
REFLECT(set_info_style);
}
// io(_("extra field"), extraSetFields);
// extraInfoStyle.init(extraSetFields);
// io(_("extra style"), extraInfoStyle);
REFLECT(styling_fields);
if (tag.reading()) styling_style.init(styling_fields);
REFLECT(styling_style);
}
void StyleSheet::validate(Version) {
+7 -2
View File
@@ -34,18 +34,23 @@ class StyleSheet : public Packaged {
double card_dpi; ///< The resolution of a card in dots per inch
Color card_background; ///< The background color of cards
/// The styling for card fields
/** The indices should correspond to the set_fields in the Game */
/** The indices should correspond to the card_fields in the Game */
IndexMap<FieldP, StyleP> card_style;
/// The styling for set info fields
/** The indices should correspond to the set_fields in the Game */
IndexMap<FieldP, StyleP> set_info_style;
/// Extra fields for styling
vector<FieldP> styling_fields;
/// The styling for the extra set fields
/** The indices should correspond to the styling_fields */
IndexMap<FieldP, StyleP> styling_style;
bool dependencies_initialized; ///< are the script dependencies comming from this stylesheet all initialized?
/// Load a StyleSheet, given a Game and the name of the StyleSheet
static StyleSheetP byGameAndName(const Game& game, const String& name);
/// name of the package without the game name
String styleName();
String stylesheetName() const;
static String typeNameStatic();
virtual String typeName() const;
+25
View File
@@ -0,0 +1,25 @@
//+----------------------------------------------------------------------------+
//| 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 <data/symbol_font.hpp>
// ----------------------------------------------------------------------------- : SymbolFont
// ----------------------------------------------------------------------------- : SymbolFontRef
SymbolFontRef::SymbolFontRef()
: size(12)
, scale_down_to(1)
, alignment(ALIGN_MIDDLE_CENTER)
{}
IMPLEMENT_REFLECTION(SymbolFontRef) {
REFLECT(name);
REFLECT(size);
REFLECT(scale_down_to);
REFLECT(alignment);
}
+79
View File
@@ -0,0 +1,79 @@
//+----------------------------------------------------------------------------+
//| 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_DATA_SYMBOL_FONT
#define HEADER_DATA_SYMBOL_FONT
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/alignment.hpp>
#include <util/io/package.hpp>
#include <data/font.hpp>
DECLARE_POINTER_TYPE(Font);
DECLARE_POINTER_TYPE(SymbolFont);
DECLARE_POINTER_TYPE(SymbolInFont);
// ----------------------------------------------------------------------------- : SymbolFont
// A font that is drawn using images
class SymbolFont : Packaged {
public:
/// Loads the symbol font with a given name, for example "magic-mana-large"
static SymbolFontP byName(const String& name);
private:
UInt imgSize; ///< Font size that the images use
UInt minSize; ///< Minimum font size
RealSize spacing; ///< Spacing between sybmols (for the default font size)
// writing text
bool scale_text; ///< Should text be scaled down to fit in a symbol?
FontP text_font; ///< Font to use for missing symbols
double text_margin_left;
double text_margin_right;
double text_margin_rop;
double text_margin_bottom;
Alignment text_align;
bool merge_numbers; ///< Merge numbers? e.g. "11" is a single symbol ('1' must not exist as a symbol)
public:
class Symbol;
private:
vector<SymbolInFontP> symbols; ///< The individual symbols
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : SymbolFontRef
/// A reference to an actual symbol font
class SymbolFontRef {
public:
SymbolFontRef();
// Script update
bool update(Context& ctx);
void initDependencies(Context&, Dependency& dep);
/// Is a font loaded?
bool valid();
private:
Scriptable<String> name; ///< Font package name, can be changed with script
double size; ///< Size of the font
double scale_down_to; ///< Mimumum size of the font
Alignment alignment; ///< Alignment of symbols in a line of text
SymbolFontP font; ///< The font, if it is loaded
/// (re)load the symbol font based on name
void loadFont();
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : EOF
#endif