mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
3cbf2577c1
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@82 0fc631ac-6414-0410-93d0-97cfa31319b6
132 lines
5.5 KiB
C++
132 lines
5.5 KiB
C++
//+----------------------------------------------------------------------------+
|
|
//| 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/text/element.hpp>
|
|
#include <util/tagged_string.hpp>
|
|
#include <data/field/text.hpp>
|
|
|
|
DECLARE_TYPEOF_COLLECTION(TextElementP);
|
|
|
|
// ----------------------------------------------------------------------------- : TextElements
|
|
|
|
void TextElements::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const {
|
|
FOR_EACH_CONST(e, elements) {
|
|
size_t start_ = max(start, e->start);
|
|
size_t end_ = min(end, e->end);
|
|
if (start_ < end_) {
|
|
e->draw(dc, scale,
|
|
RealRect(rect.position.x + xs[start_-start] - xs[0], rect.position.y,
|
|
xs[end_-start] - xs[start_-start], rect.size.height),
|
|
xs + start_ - start, what, start_, end_);
|
|
}
|
|
if (end <= e->end) return; // nothing can be after this
|
|
}
|
|
}
|
|
|
|
void TextElements::getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const {
|
|
FOR_EACH_CONST(e, elements) {
|
|
// characters before this element, after the previous
|
|
while (start + out.size() < e->start) {
|
|
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
|
}
|
|
e->getCharInfo(dc, scale, out);
|
|
}
|
|
while (start + out.size() < end) {
|
|
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
|
}
|
|
}
|
|
|
|
double TextElements::minScale() const {
|
|
double m = 0.0001;
|
|
FOR_EACH_CONST(e, elements) {
|
|
m = max(m, e->minScale());
|
|
}
|
|
return m;
|
|
}
|
|
|
|
// Helper class for TextElements::fromString, to allow persistent formating state accross recusive calls
|
|
struct TextElementsFromString {
|
|
// What formatting is enabled?
|
|
int bold, italic, symbol;
|
|
int soft, kwpph;
|
|
|
|
TextElementsFromString()
|
|
: bold(0), italic(0), symbol(0), soft(0), kwpph(0) {}
|
|
|
|
// read TextElements from a string
|
|
void fromString(TextElements& te, const String& text, size_t start, size_t end, const TextStyle& style, Context& ctx) {
|
|
te.elements.clear();
|
|
// for each character...
|
|
for (size_t pos = start ; pos < end ; ) {
|
|
Char c = text.GetChar(pos);
|
|
if (c == _('<')) {
|
|
size_t tag_start = pos;
|
|
pos = skip_tag(text, tag_start);
|
|
if (is_substr(text, tag_start, _( "<b"))) bold += 1;
|
|
else if (is_substr(text, tag_start, _("</b"))) bold -= 1;
|
|
else if (is_substr(text, tag_start, _( "<i"))) italic += 1;
|
|
else if (is_substr(text, tag_start, _("</i"))) italic -= 1;
|
|
else if (is_substr(text, tag_start, _( "<sym"))) symbol += 1;
|
|
else if (is_substr(text, tag_start, _("</sym"))) symbol -= 1;
|
|
else if (is_substr(text, tag_start, _( "<sep-soft"))) soft += 1;
|
|
else if (is_substr(text, tag_start, _("</sep-soft"))) soft -= 1;
|
|
else if (is_substr(text, tag_start, _( "<atom-kwpph"))) kwpph += 1;
|
|
else if (is_substr(text, tag_start, _("</atom-kwpph"))) kwpph -= 1;
|
|
else if (is_substr(text, tag_start, _("<line"))) {
|
|
// horizontal line
|
|
te.elements.push_back(new_shared3<HorizontalLineTextElement>(text, tag_start, pos));
|
|
/* } else if (is_substr(text, start, _("<error"))) {
|
|
// underline with wavy 'error' indicator
|
|
size_t end = match_close_tag(text, tag_start);
|
|
shared_ptr<ErrorTextElement> e(new ErrorTextElement(text, pos, end));
|
|
fromString(e->elements, text, pos, end, style, ctx);
|
|
pos = skip_tag(text, end);
|
|
} else if (is_substr(text, start, _("<atom"))) {
|
|
// 'atomic' indicator
|
|
size_t end = match_close_tag(text, tag_start);
|
|
shared_ptr<AtomTextElement> e(new AtomTextElement(text, pos, end));
|
|
fromString(e->elements, text, pos, end, style, ctx);
|
|
pos = skip_tag(text, end);
|
|
*/ } else {
|
|
// ignore other tags
|
|
}
|
|
} else {
|
|
// A character of normal text, add to the last text element (if possible)
|
|
SimpleTextElement* e = nullptr;
|
|
if (!te.elements.empty()) e = dynamic_cast<SimpleTextElement*>(te.elements.back().get());
|
|
if (e && e->end == pos) {
|
|
e->end = pos + 1; // just move the end, no need to make a new element
|
|
} else {
|
|
// add a new element for this text
|
|
if (symbol > 0 && style.symbol_font.valid()) {
|
|
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)));
|
|
}
|
|
}
|
|
pos += 1;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
void TextElements::fromString(const String& text, size_t start, size_t end, const TextStyle& style, Context& ctx) {
|
|
TextElementsFromString f;
|
|
f.fromString(*this, text, start, end, style, ctx);
|
|
}
|
|
/*
|
|
// ----------------------------------------------------------------------------- : CompoundTextElement
|
|
|
|
void CompoundTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const {
|
|
elements.draw(dc, scale, rect, what, start, end);
|
|
}
|
|
RealSize CompoundTextElement::charSize(RotatedDC& dc, double scale, size_t index) const {
|
|
return elements.charSize(rot, scale, index);
|
|
}
|
|
|
|
*/ |