mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
implemented symbol font
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@81 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -137,7 +137,10 @@ class ChoiceStyle : public Style {
|
||||
/// The Value in a ChoiceField
|
||||
class ChoiceValue : public Value {
|
||||
public:
|
||||
inline ChoiceValue(const ChoiceFieldP& field) : Value(field) {}
|
||||
inline ChoiceValue(const ChoiceFieldP& field)
|
||||
: Value(field)
|
||||
, value(field->initial, true)
|
||||
{}
|
||||
DECLARE_HAS_FIELD(Choice)
|
||||
|
||||
Defaultable<String> value; /// The name of the selected choice
|
||||
|
||||
@@ -55,12 +55,14 @@ TextStyle::TextStyle(const TextFieldP& field)
|
||||
{}
|
||||
|
||||
bool TextStyle::update(Context& ctx) {
|
||||
return Style::update(ctx)
|
||||
| font.update(ctx);
|
||||
return Style ::update(ctx)
|
||||
| font .update(ctx)
|
||||
| symbol_font.update(ctx);
|
||||
}
|
||||
void TextStyle::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
Style::initDependencies(ctx, dep);
|
||||
font.initDependencies(ctx, dep);
|
||||
Style ::initDependencies(ctx, dep);
|
||||
font .initDependencies(ctx, dep);
|
||||
symbol_font.initDependencies(ctx, dep);
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(TextStyle) {
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ class Set::Styling {
|
||||
};
|
||||
|
||||
IndexMap<FieldP, ValueP>& Set::stylingDataFor(const StyleSheet& stylesheet) {
|
||||
StylingP& styling = styling_data[stylesheet.stylesheetName()];
|
||||
StylingP& styling = styling_data[stylesheet.name()];
|
||||
if (!styling) {
|
||||
styling = new_shared<Styling>();
|
||||
styling->data.init(stylesheet.styling_fields);
|
||||
|
||||
+220
-13
@@ -9,7 +9,13 @@
|
||||
#include <data/symbol_font.hpp>
|
||||
#include <util/dynamic_arg.hpp>
|
||||
#include <util/io/package_manager.hpp>
|
||||
#include <util/rotation.hpp>
|
||||
#include <render/text/element.hpp> // fot CharInfo
|
||||
#include <script/image.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(SymbolFont::DrawableSymbol);
|
||||
DECLARE_TYPEOF_COLLECTION(SymbolInFontP);
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont
|
||||
|
||||
@@ -34,13 +40,6 @@ SymbolFontP SymbolFont::byName(const String& name) {
|
||||
return packages.open<SymbolFont>(name + _(".mse-symbol-font"));
|
||||
}
|
||||
|
||||
void SymbolFont::split(const String& text, SplitSymbols& out) {
|
||||
for (size_t pos = 0 ; pos < text.size() ; ) {
|
||||
// read a single symbol
|
||||
pos = pos + 1; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(SymbolFont) {
|
||||
tag.addAlias(300, _("text align"), _("text alignment"));
|
||||
|
||||
@@ -60,7 +59,7 @@ IMPLEMENT_REFLECTION(SymbolFont) {
|
||||
REFLECT(text_alignment);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont::Symbol
|
||||
// ----------------------------------------------------------------------------- : SymbolInFont
|
||||
|
||||
/// A symbol in a symbol font
|
||||
class SymbolInFont {
|
||||
@@ -68,16 +67,16 @@ class SymbolInFont {
|
||||
SymbolInFont();
|
||||
|
||||
/// Get a shrunk, zoomed bitmap
|
||||
Bitmap getBitmap(Context& ctx, double size);
|
||||
Bitmap getBitmap(Context& ctx, Package& pkg, double size);
|
||||
|
||||
/// Size of a (zoomed) bitmap
|
||||
/** This is the size of the resulting image, it does NOT convert back to internal coordinates */
|
||||
RealSize size(Context& ctx, double size);
|
||||
RealSize size(Context& ctx, Package& pkg, double size);
|
||||
|
||||
private:
|
||||
String code; ///< Code for this symbol
|
||||
private:
|
||||
ScriptableImage image; ///< The image for this symbol
|
||||
UInt img_size; ///< Font size used by the image
|
||||
double img_size; ///< Font size used by the image
|
||||
wxSize actual_size; ///< Actual image size, only known after loading the image
|
||||
/// Cached bitmaps for different sizes
|
||||
map<double, Bitmap> bitmaps;
|
||||
@@ -86,9 +85,40 @@ class SymbolInFont {
|
||||
};
|
||||
|
||||
SymbolInFont::SymbolInFont()
|
||||
: actual_size(0,0)
|
||||
{
|
||||
assert(symbol_font_for_reading());
|
||||
img_size = symbol_font_for_reading()->img_size;
|
||||
if (img_size <= 0) img_size = 1;
|
||||
}
|
||||
|
||||
Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, double size) {
|
||||
// is this bitmap already loaded/generated?
|
||||
Bitmap& bmp = bitmaps[size];
|
||||
if (!bmp.Ok()) {
|
||||
// generate new bitmap
|
||||
if (!image) {
|
||||
throw Error(_("No image specified for symbol with code '") + code + _("' in symbol font."));
|
||||
}
|
||||
Image img = image.generate(ctx, pkg)->image;
|
||||
actual_size = wxSize(img.GetWidth(), img.GetHeight());
|
||||
// scale to match expected size
|
||||
Image resampled_image(actual_size.GetWidth() * size / img_size,
|
||||
actual_size.GetHeight() * size / img_size, false);
|
||||
if (!resampled_image.Ok()) return Bitmap(1,1);
|
||||
resample(img, resampled_image);
|
||||
// convert to bitmap, store for later use
|
||||
bmp = Bitmap(resampled_image);
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) {
|
||||
if (actual_size.GetWidth() == 0) {
|
||||
// we don't know what size the image will be
|
||||
getBitmap(ctx, pkg, size);
|
||||
}
|
||||
return wxSize(actual_size * size / img_size);
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(SymbolInFont) {
|
||||
@@ -97,6 +127,162 @@ IMPLEMENT_REFLECTION(SymbolInFont) {
|
||||
REFLECT_N("image font size", img_size);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont : splitting
|
||||
|
||||
class SymbolFont::DrawableSymbol {
|
||||
public:
|
||||
DrawableSymbol(const String& text, SymbolInFont* symbol)
|
||||
: text(text), symbol(symbol)
|
||||
{}
|
||||
|
||||
String text; ///< Original text
|
||||
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
||||
};
|
||||
|
||||
void SymbolFont::split(const String& text, SplitSymbols& out) const {
|
||||
// read a single symbol until we are done with the text
|
||||
for (size_t pos = 0 ; pos < text.size() ; ) {
|
||||
// 1. check merged numbers
|
||||
if (merge_numbers && pos + 1 < text.size()) {
|
||||
size_t num_count = text.find_first_not_of(_("0123456789"), pos);
|
||||
if (num_count >= 2) {
|
||||
// draw single symbol for the whole number
|
||||
out.push_back(DrawableSymbol(text.substr(0, num_count), 0));
|
||||
pos += num_count;
|
||||
goto next_symbol;
|
||||
}
|
||||
}
|
||||
// 2. check symbol list
|
||||
FOR_EACH_CONST(sym, symbols) {
|
||||
if (!sym->code.empty() && is_substr(text, pos, sym->code)) { // symbol matches
|
||||
out.push_back(DrawableSymbol(sym->code, sym.get()));
|
||||
pos += sym->code.size();
|
||||
goto next_symbol; // continue two levels
|
||||
}
|
||||
}
|
||||
// 3. unknown code, draw single character as text
|
||||
out.push_back(DrawableSymbol(text.substr(pos, 1), 0));
|
||||
pos += 1;
|
||||
next_symbol:;
|
||||
}
|
||||
}
|
||||
|
||||
SymbolInFont* SymbolFont::defaultSymbol() const {
|
||||
FOR_EACH_CONST(sym, symbols) {
|
||||
if (sym->code.empty()) return sym.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont : drawing
|
||||
|
||||
void SymbolFont::draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||
SplitSymbols symbols;
|
||||
split(text, symbols);
|
||||
draw(dc, ctx, rect, font_size, align, symbols);
|
||||
}
|
||||
|
||||
void SymbolFont::draw(RotatedDC& dc, Context& ctx, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text) {
|
||||
FOR_EACH_CONST(sym, text) {
|
||||
RealSize size = dc.trInvS(symbolSize(ctx, dc.trS(font_size), sym));
|
||||
RealRect sym_rect = split_left(rect, size);
|
||||
if (sym.symbol) {
|
||||
drawSymbol( dc, ctx, sym_rect, font_size, align, *sym.symbol);
|
||||
} else {
|
||||
drawWithText(dc, ctx, sym_rect, font_size, align, sym.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolFont::drawSymbol (RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym) {
|
||||
// find bitmap
|
||||
Bitmap bmp = sym.getBitmap(ctx, *this, dc.trS(font_size));
|
||||
// draw aligned in the rectangle
|
||||
dc.DrawBitmap(bmp, align_in_rect(align, dc.trInvS(RealSize(bmp.GetWidth(), bmp.GetHeight())), rect));
|
||||
}
|
||||
|
||||
void SymbolFont::drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||
// 1. draw background bitmap
|
||||
// Size and position of symbol
|
||||
RealRect sym_rect = rect;
|
||||
// find and draw background bitmap
|
||||
SymbolInFont* def = defaultSymbol();
|
||||
if (def) {
|
||||
Bitmap bmp = def->getBitmap(ctx, *this, dc.trS(font_size));
|
||||
// align symbol
|
||||
sym_rect.size = dc.trInvS(RealSize(bmp.GetWidth(), bmp.GetHeight()));
|
||||
sym_rect.position = align_in_rect(align, sym_rect.size, rect);
|
||||
// draw
|
||||
dc.DrawBitmap(bmp, sym_rect.position);
|
||||
}
|
||||
|
||||
// 2. draw text
|
||||
if (!text_font) return;
|
||||
// subtract margins from size
|
||||
sym_rect.position.x += text_margin_left;
|
||||
sym_rect.position.y += text_margin_top;
|
||||
sym_rect.size.width -= text_margin_left + text_margin_right;
|
||||
sym_rect.size.height -= text_margin_top + text_margin_bottom;
|
||||
// setup text, shrink it
|
||||
double size = text_font->size; // TODO : incorporate shrink factor?
|
||||
RealSize ts;
|
||||
while (true) {
|
||||
if (size <= 0) return; // text too small
|
||||
dc.SetFont(text_font->font, size);
|
||||
ts = dc.GetTextExtent(text);
|
||||
if (ts.width <= sym_rect.size.width && ts.height <= sym_rect.size.height) {
|
||||
break; // text fits
|
||||
} else {
|
||||
// text doesn't fit
|
||||
size -= dc.getFontSizeStep();
|
||||
}
|
||||
}
|
||||
// align text
|
||||
RealPoint text_pos = align_in_rect(text_alignment, ts, sym_rect);
|
||||
// draw text
|
||||
if (text_font->hasShadow()) {
|
||||
dc.SetTextForeground(text_font->shadow_color);
|
||||
dc.DrawText(text, text_pos + text_font->shadow_displacement);
|
||||
}
|
||||
dc.SetTextForeground(text_font->color);
|
||||
dc.DrawText(text, text_pos);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont : sizes
|
||||
|
||||
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out) {
|
||||
SplitSymbols symbols;
|
||||
split(text, symbols);
|
||||
getCharInfo(dc, ctx, font_size, symbols, out);
|
||||
}
|
||||
|
||||
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const SplitSymbols& text, vector<CharInfo>& out) {
|
||||
FOR_EACH_CONST(sym, text) {
|
||||
size_t count = sym.text.size();
|
||||
RealSize size = dc.trInvS(symbolSize(ctx, dc.trS(font_size), sym));
|
||||
out.insert(out.end(), count, RealSize(size.width / count, size.height)); // divide into count parts
|
||||
}
|
||||
}
|
||||
|
||||
RealSize SymbolFont::symbolSize(Context& ctx, double font_size, const DrawableSymbol& sym) {
|
||||
if (sym.symbol) {
|
||||
return addDiagonal(sym.symbol->size(ctx, *this, font_size), spacing);
|
||||
} else {
|
||||
return defaultSymbolSize(ctx, font_size);
|
||||
}
|
||||
}
|
||||
|
||||
RealSize SymbolFont::defaultSymbolSize(Context& ctx, double font_size) {
|
||||
SymbolInFont* def = defaultSymbol();
|
||||
if (def) {
|
||||
return addDiagonal(def->size(ctx, *this, font_size), spacing);
|
||||
} else {
|
||||
return addDiagonal(RealSize(1,1), spacing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFontRef
|
||||
|
||||
SymbolFontRef::SymbolFontRef()
|
||||
@@ -106,9 +292,30 @@ SymbolFontRef::SymbolFontRef()
|
||||
{}
|
||||
|
||||
bool SymbolFontRef::valid() const {
|
||||
return !!font; //TODO: does this make sense?
|
||||
return !!font;
|
||||
}
|
||||
|
||||
bool SymbolFontRef::update(Context& ctx) {
|
||||
if (name.update(ctx)) {
|
||||
// font name changed, load another font
|
||||
loadFont();
|
||||
return true;
|
||||
} else {
|
||||
if (!font) loadFont();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void SymbolFontRef::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
name.initDependencies(ctx, dep);
|
||||
}
|
||||
|
||||
void SymbolFontRef::loadFont() {
|
||||
if (name().empty()) {
|
||||
font = SymbolFontP();
|
||||
} else {
|
||||
font = SymbolFont::byName(name);
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(SymbolFontRef) {
|
||||
REFLECT(name);
|
||||
|
||||
+28
-13
@@ -18,6 +18,7 @@ DECLARE_POINTER_TYPE(Font);
|
||||
DECLARE_POINTER_TYPE(SymbolFont);
|
||||
DECLARE_POINTER_TYPE(SymbolInFont);
|
||||
class RotatedDC;
|
||||
struct CharInfo;
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFont
|
||||
|
||||
@@ -29,20 +30,20 @@ class SymbolFont : public Packaged {
|
||||
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
||||
static SymbolFontP byName(const String& name);
|
||||
|
||||
class DrawableSymbol {
|
||||
public:
|
||||
// TODO: anything?
|
||||
private:
|
||||
String text; ///< Original text
|
||||
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
||||
};
|
||||
class DrawableSymbol;
|
||||
typedef vector<DrawableSymbol> SplitSymbols;
|
||||
|
||||
/// Split a string into separate symbols for drawing and for determining their size
|
||||
void split(const String& text, SplitSymbols& out);
|
||||
void split(const String& text, SplitSymbols& out) const;
|
||||
|
||||
/// Draw a piece of text prepared using split
|
||||
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const SplitSymbols& text);
|
||||
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||
/// Get information on characters in a string
|
||||
void getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out);
|
||||
|
||||
/// Draw a piece of text prepared using split
|
||||
void draw(RotatedDC& dc, Context& ctx, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text);
|
||||
/// Get information on characters in a string
|
||||
void getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const SplitSymbols& text, vector<CharInfo>& out);
|
||||
|
||||
static String typeNameStatic();
|
||||
virtual String typeName() const;
|
||||
@@ -64,9 +65,24 @@ class SymbolFont : public Packaged {
|
||||
friend class SymbolInFont;
|
||||
vector<SymbolInFontP> symbols; ///< The individual symbols
|
||||
|
||||
/// Find the default symbol
|
||||
/** may return nullptr */
|
||||
SymbolInFont* defaultSymbol() const;
|
||||
|
||||
/// Draws a single symbol inside the given rectangle
|
||||
void drawSymbol (RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym);
|
||||
/// Draw the default bitmap to a dc and overlay a string of text
|
||||
void drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||
|
||||
/// Size of a single symbol
|
||||
RealSize symbolSize (Context& ctx, double font_size, const DrawableSymbol& sym);
|
||||
/// Size of the default symbol
|
||||
RealSize defaultSymbolSize(Context& ctx, double font_size);
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolFontRef
|
||||
|
||||
/// A reference to an actual symbol font
|
||||
@@ -76,12 +92,11 @@ class SymbolFontRef {
|
||||
|
||||
// Script update
|
||||
bool update(Context& ctx);
|
||||
void initDependencies(Context&, Dependency& dep);
|
||||
void initDependencies(Context&, const Dependency&) const;
|
||||
|
||||
/// Is a font loaded?
|
||||
bool valid() const;
|
||||
|
||||
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
|
||||
|
||||
@@ -104,7 +104,7 @@ struct TextElementsFromString {
|
||||
} else {
|
||||
// add a new element for this text
|
||||
if (symbol > 0 && style.symbol_font.valid()) {
|
||||
te.elements.push_back(new_shared4<SymbolTextElement>(text, pos, pos + 1, style.symbol_font));
|
||||
te.elements.push_back(new_shared5<SymbolTextElement>(text, pos, pos + 1, style.symbol_font, &ctx));
|
||||
} else {
|
||||
te.elements.push_back(new_shared4<FontTextElement> (text, pos, pos + 1, style.font.make(bold > 0, italic > 0)));
|
||||
}
|
||||
|
||||
@@ -142,9 +142,9 @@ class FontTextElement : public SimpleTextElement {
|
||||
/// A text element that uses a symbol font
|
||||
class SymbolTextElement : public SimpleTextElement {
|
||||
public:
|
||||
SymbolTextElement(const String& text, size_t start ,size_t end, const SymbolFontRef& font)
|
||||
SymbolTextElement(const String& text, size_t start ,size_t end, const SymbolFontRef& font, Context* ctx)
|
||||
: SimpleTextElement(text, start, end)
|
||||
, font(font)
|
||||
, font(font), ctx(*ctx)
|
||||
{}
|
||||
|
||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||
@@ -152,6 +152,7 @@ class SymbolTextElement : public SimpleTextElement {
|
||||
virtual double minScale() const;
|
||||
private:
|
||||
const SymbolFontRef& font; // owned by TextStyle
|
||||
Context& ctx;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : CompoundTextElement
|
||||
|
||||
@@ -7,17 +7,22 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <render/text/element.hpp>
|
||||
#include <data/symbol_font.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : SymbolTextElement
|
||||
|
||||
void SymbolTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const {
|
||||
// TODO
|
||||
if (font.font) {
|
||||
font.font->draw(dc, ctx, rect, font.size * scale, font.alignment, text.substr(start, end-start));
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const {
|
||||
// TODO
|
||||
if (font.font) {
|
||||
font.font->getCharInfo(dc, ctx, font.size * scale, text.substr(start, end-start), out);
|
||||
}
|
||||
}
|
||||
|
||||
double SymbolTextElement::minScale() const {
|
||||
return 1; // TODO
|
||||
return font.size / min(0.001, min(font.size, font.scale_down_to));
|
||||
}
|
||||
|
||||
@@ -129,7 +129,12 @@ const TextViewer::Line& TextViewer::findLine(size_t index) const {
|
||||
// ----------------------------------------------------------------------------- : Elements
|
||||
|
||||
void TextViewer::prepareElements(const String& text, const TextStyle& style, Context& ctx) {
|
||||
elements.fromString(text, 0, text.size(), style, ctx);
|
||||
if (style.always_symbol) {
|
||||
elements.elements.clear();
|
||||
elements.elements.push_back(new_shared5<SymbolTextElement>(text, 0, text.size(), style.symbol_font, &ctx));
|
||||
} else {
|
||||
elements.fromString(text, 0, text.size(), style, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ class ScriptableImage {
|
||||
inline operator bool() const { return script; }
|
||||
|
||||
/// Generate an image, doesn't cache, and doesn't scale
|
||||
/** Image files are loaded from the given package */
|
||||
/** Image files are loaded from the given package.
|
||||
* The result is always valid. */
|
||||
ScriptImageP generate(Context& ctx, Package&) const;
|
||||
/// Generate an image, scaling it and optionally saturating it
|
||||
ScriptImageP generate(Context& ctx, Package&, UInt width, UInt height, PreserveAspect preserve_aspect = ASPECT_STRETCH, bool saturate = false) const;
|
||||
|
||||
@@ -93,7 +93,8 @@ class Scriptable {
|
||||
Scriptable() : value() {}
|
||||
Scriptable(const T& value) : value(value) {}
|
||||
|
||||
inline operator const T& () const { return value; }
|
||||
inline operator const T& () const { return value; }
|
||||
inline const T& operator ()() const { return value; }
|
||||
inline bool isScripted() const { return script; }
|
||||
|
||||
/// Updates the value by executing the script, returns true if the value has changed
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <util/io/package_manager.hpp>
|
||||
#include <util/error.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/symbol_font.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- : IncludePackage
|
||||
|
||||
@@ -68,10 +70,10 @@ PackagedP PackageManager::openAny(const String& name) {
|
||||
} else {
|
||||
// load with the right type, based on extension
|
||||
if (fn.GetExt() == _("mse-game")) p = new_shared<Game>();
|
||||
// else if (fn.GetExt() == _("mse-style")) p = new_shared<CardStyle>();
|
||||
else if (fn.GetExt() == _("mse-style")) p = new_shared<StyleSheet>();
|
||||
// else if (fn.GetExt() == _("mse-locale")) p = new_shared<Locale>();
|
||||
else if (fn.GetExt() == _("mse-include")) p = new_shared<IncludePackage>();
|
||||
// else if (fn.GetExt() == _("mse-symbol-font")) p = new_shared<SymbolFont>();
|
||||
else if (fn.GetExt() == _("mse-symbol-font")) p = new_shared<SymbolFont>();
|
||||
else {
|
||||
throw PackageError(_("Unrecognized package type: '") + fn.GetExt() + _("'\nwhile trying to open: ") + name);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,17 @@ inline RealSize addVertical(const RealSize& a, const RealSize& b) {
|
||||
return RealSize(max(a.width, b.width), a.height + b.height);
|
||||
}
|
||||
|
||||
/// Add two sizes diagonally
|
||||
/** #### $$$ ####...
|
||||
* #### + $$$ = ####...
|
||||
* #### ####...
|
||||
* ....$$$
|
||||
* ....$$$
|
||||
*/
|
||||
inline RealSize addDiagonal(const RealSize& a, const RealSize& b) {
|
||||
return RealSize(a.width + b.width, a.height + b.height);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Rectangle using doubles
|
||||
|
||||
/// A rectangle (postion and size) using real (double) coordinats
|
||||
@@ -136,6 +147,30 @@ class RealRect {
|
||||
}
|
||||
};
|
||||
|
||||
/// Split a rectangle horizontally
|
||||
/** Returns a section from the left of this rectangle witht the given width
|
||||
* The rectangle will change to become the part remaining to the right
|
||||
* For example given a rectangle:
|
||||
* +------------+
|
||||
* | R |
|
||||
* +------------+
|
||||
* A = split_left(R,5)
|
||||
* +----+-------+
|
||||
* | A | R |
|
||||
* +----+-------+
|
||||
*/
|
||||
inline RealRect split_left(RealRect& r, double w) {
|
||||
RealRect result(r.position.x, r.position.y, w, r.size.height);
|
||||
r.size.width -= w;
|
||||
r.position.x += w;
|
||||
return result;
|
||||
}
|
||||
/// Split a rectangle horizontally
|
||||
inline RealRect split_left(RealRect& r, const RealSize& s) {
|
||||
return split_left(r, s.width);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : Operators
|
||||
|
||||
inline RealPoint operator + (const RealSize& s, const RealPoint& p) {
|
||||
|
||||
@@ -171,6 +171,11 @@ void RotatedDC::SetFont(wxFont font, double size) {
|
||||
dc.SetFont(font);
|
||||
}
|
||||
|
||||
double RotatedDC::getFontSizeStep() const {
|
||||
return 1; // TODO
|
||||
// return 1. / (high_quality ? text_scaling : 1);
|
||||
}
|
||||
|
||||
RealSize RotatedDC::GetTextExtent(const String& text) const {
|
||||
int w, h;
|
||||
dc.GetTextExtent(text, &w, &h);
|
||||
|
||||
@@ -56,7 +56,9 @@ class Rotation {
|
||||
RealRect trNoNegNoZoom(const RealRect& r) const;
|
||||
|
||||
/// Translate a size or length back to internal 'coordinates'
|
||||
inline double trInvS(double s) const { return s / zoom; }
|
||||
inline double trInvS(double s) const { return s / zoom; }
|
||||
/// Translate a size back to internal 'coordinates', doesn't rotate
|
||||
inline RealSize trInvS(const RealSize& s) const { return RealSize(s.width / zoom, s.height / zoom); }
|
||||
|
||||
/// Translate a point back to internal coordinates
|
||||
RealPoint trInv(const RealPoint& p) const;
|
||||
@@ -142,6 +144,9 @@ class RotatedDC : public Rotation {
|
||||
/** The font will get the given (internal) point size */
|
||||
void SetFont(wxFont font, double size);
|
||||
|
||||
/// Steps to use when decrementing font size
|
||||
double getFontSizeStep() const;
|
||||
|
||||
RealSize GetTextExtent(const String& text) const;
|
||||
double GetCharHeight() const;
|
||||
|
||||
|
||||
@@ -58,6 +58,16 @@ template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
inline shared_ptr<T> new_shared4(const A0& a0, const A1& a1, const A2& a2, const A3& a3) {
|
||||
return shared_ptr<T>(new T(a0, a1, a2, a3));
|
||||
}
|
||||
/// Allocate a new shared-pointed object, given five arguments to pass to the ctor of T
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4>
|
||||
inline shared_ptr<T> new_shared5(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4) {
|
||||
return shared_ptr<T>(new T(a0, a1, a2, a3, a4));
|
||||
}
|
||||
/// Allocate a new shared-pointed object, given six arguments to pass to the ctor of T
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
inline shared_ptr<T> new_shared6(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) {
|
||||
return shared_ptr<T>(new T(a0, a1, a2, a3, a4, a5));
|
||||
}
|
||||
/// Allocate a new shared-pointed object, given seven arguments to pass to the ctor of T
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
inline shared_ptr<T> new_shared7(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) {
|
||||
|
||||
@@ -195,6 +195,9 @@ bool is_substr(const String& str, size_t pos, const Char* cmp) {
|
||||
}
|
||||
return *cmp == _('\0');
|
||||
}
|
||||
bool is_substr(const String& str, size_t pos, const String& cmp) {
|
||||
return is_substr(str, pos, cmp.c_str());
|
||||
}
|
||||
|
||||
bool cannocial_name_compare(const String& as, const Char* b) {
|
||||
const Char* a = as.c_str();
|
||||
|
||||
@@ -126,6 +126,8 @@ bool starts_with(const String& str, const String& start);
|
||||
|
||||
/// Return whether str contains the string cmp at position pos
|
||||
bool is_substr(const String& str, size_t pos, const Char* cmp);
|
||||
/// Return whether str contains the string cmp at position pos
|
||||
bool is_substr(const String& str, size_t pos, const String& cmp);
|
||||
|
||||
/// Compare two strings for equality, b may contain '_' where a contains ' '
|
||||
bool cannocial_name_compare(const String& a, const Char* b);
|
||||
|
||||
Reference in New Issue
Block a user