Commit c126e143 authored by twanvl's avatar twanvl

Added <color:???> and <size:???> tags for changing text color/size

parent 9def73bb
...@@ -15,10 +15,12 @@ This is written as the character with code 1 in files. ...@@ -15,10 +15,12 @@ This is written as the character with code 1 in files.
| @"<b>"@ The text inside the tag is bold. | @"<b>"@ The text inside the tag is bold.
| @"<i>"@ The text inside the tag is italic. | @"<i>"@ The text inside the tag is italic.
| @"<sym>"@ The text inside the tag is rendered as symbols, if a [[prop:style:symbol font]] is set for the text box. | @"<sym>"@ The text inside the tag is rendered as symbols, if a [[prop:style:symbol font]] is set for the text box.
| @"<color:???>"@ The text inside the tag is rendered with the given [[type:color]].
| @"<size:???>"@ The text inside the tag is scaled by the a factor, for example @"<size:2>text</size>"@ makes the text twice as large.
| @"<line>"@ Line breaks inside this tag use the [[prop:style:line height line]], and they show a horizontal line. | @"<line>"@ Line breaks inside this tag use the [[prop:style:line height line]], and they show a horizontal line.
| @"<soft-line>"@ Line breaks inside this tag use the [[prop:style:soft line height]]. | @"<soft-line>"@ Line breaks inside this tag use the [[prop:style:soft line height]].
| @"<atom>"@ An atomic piece of text. The cursor can never be inside it; it is selected as a whole. | @"<atom>"@ An atomic piece of text. The cursor can never be inside it; it is selected as a whole.
The program automatically inserts <atom-soft> The program automatically inserts @"<atom-soft>"@.
| @"<code>"@ The text inside the text is rendered in a monospace font. This is used for syntax highlighting script code. | @"<code>"@ The text inside the text is rendered in a monospace font. This is used for syntax highlighting script code.
| @"<code-kw>"@ The text inside the text is highlighted as a keyword in source code. | @"<code-kw>"@ The text inside the text is highlighted as a keyword in source code.
| @"<code-str>"@ The text inside the text is highlighted as a string in source code. | @"<code-str>"@ The text inside the text is highlighted as a string in source code.
......
...@@ -48,7 +48,7 @@ void Font::initDependencies(Context& ctx, const Dependency& dep) const { ...@@ -48,7 +48,7 @@ void Font::initDependencies(Context& ctx, const Dependency& dep) const {
shadow_color.initDependencies(ctx, dep); shadow_color.initDependencies(ctx, dep);
} }
FontP Font::make(int add_flags, Color* other_color) const { FontP Font::make(int add_flags, Color* other_color, double* other_size) const {
FontP f(new Font(*this)); FontP f(new Font(*this));
f->flags |= add_flags; f->flags |= add_flags;
if (add_flags & FONT_CODE_STRING) { if (add_flags & FONT_CODE_STRING) {
...@@ -68,6 +68,9 @@ FontP Font::make(int add_flags, Color* other_color) const { ...@@ -68,6 +68,9 @@ FontP Font::make(int add_flags, Color* other_color) const {
if (other_color) { if (other_color) {
f->color = *other_color; f->color = *other_color;
} }
if (other_size) {
f->size = *other_size;
}
return f; return f;
} }
......
...@@ -58,8 +58,8 @@ class Font : public IntrusivePtrBase<Font> { ...@@ -58,8 +58,8 @@ class Font : public IntrusivePtrBase<Font> {
return shadow_displacement.width != 0 || shadow_displacement.height != 0; return shadow_displacement.width != 0 || shadow_displacement.height != 0;
} }
/// Add style to a font, and optionally change the color /// Add style to a font, and optionally change the color and size
FontP make(int add_flags, Color* other_color) const; FontP make(int add_flags, Color* other_color, double* other_size) const;
/// Convert this font to a wxFont /// Convert this font to a wxFont
wxFont toWxFont(double scale) const; wxFont toWxFont(double scale) const;
......
...@@ -20,12 +20,16 @@ template <> void GetDefaultMember::handle(const AColor& col) { ...@@ -20,12 +20,16 @@ template <> void GetDefaultMember::handle(const AColor& col) {
} }
template <> void Reader::handle(AColor& col) { template <> void Reader::handle(AColor& col) {
UInt r,g,b,a; UInt r,g,b,a;
if (wxSscanf(getValue().c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) { String v = getValue();
if (wxSscanf(v.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
col.Set(r,g,b); col.Set(r,g,b);
col.alpha = 255; col.alpha = 255;
} else if (wxSscanf(getValue().c_str(),_("rgba(%u,%u,%u,%u)"),&r,&g,&b,&a)) { } else if (wxSscanf(v.c_str(),_("rgba(%u,%u,%u,%u)"),&r,&g,&b,&a)) {
col.Set(r,g,b); col.Set(r,g,b);
col.alpha = a; col.alpha = a;
} else {
col = Color(v);
if (!col.Ok()) col = *wxBLACK;
} }
} }
template <> void Writer::handle(const AColor& col) { template <> void Writer::handle(const AColor& col) {
......
...@@ -76,6 +76,8 @@ struct TextElementsFromString { ...@@ -76,6 +76,8 @@ struct TextElementsFromString {
int soft, kwpph, param, line, soft_line; int soft, kwpph, param, line, soft_line;
int code, code_kw, code_string, param_ref, error; int code, code_kw, code_string, param_ref, error;
int param_id; int param_id;
vector<Color> colors;
vector<double> sizes;
/// put angle brackets around the text? /// put angle brackets around the text?
bool bracket; bool bracket;
...@@ -121,6 +123,27 @@ struct TextElementsFromString { ...@@ -121,6 +123,27 @@ struct TextElementsFromString {
else if (is_substr(text, tag_start, _("</code-str"))) code_string -= 1; else if (is_substr(text, tag_start, _("</code-str"))) code_string -= 1;
else if (is_substr(text, tag_start, _( "<code"))) code += 1; else if (is_substr(text, tag_start, _( "<code"))) code += 1;
else if (is_substr(text, tag_start, _("</code"))) code -= 1; else if (is_substr(text, tag_start, _("</code"))) code -= 1;
else if (is_substr(text, tag_start, _( "<color"))) {
size_t colon = text.find_first_of(_(">:"), tag_start);
if (colon < pos - 1 && text.GetChar(colon) == _(':')) {
Color c = parse_color(text.substr(colon+1, pos-colon-2));
if (!c.Ok()) c = style.font.color;
colors.push_back(c);
}
} else if (is_substr(text, tag_start, _("</color"))) {
if (!colors.empty()) colors.pop_back();
}
else if (is_substr(text, tag_start, _( "<size"))) {
size_t colon = text.find_first_of(_(">:"), tag_start);
if (colon < pos - 1 && text.GetChar(colon) == _(':')) {
double size = style.font.size;
String v = text.substr(colon+1, pos-colon-2);
v.ToDouble(&size);
sizes.push_back(size);
}
} else if (is_substr(text, tag_start, _("</size"))) {
if (!sizes.empty()) sizes.pop_back();
}
else if (is_substr(text, tag_start, _( "<ref-param"))) { else if (is_substr(text, tag_start, _( "<ref-param"))) {
// determine the param being referenced // determine the param being referenced
// from a tag <ref-param123> // from a tag <ref-param123>
...@@ -222,7 +245,11 @@ struct TextElementsFromString { ...@@ -222,7 +245,11 @@ struct TextElementsFromString {
(code_string > 0 ? FONT_CODE_STRING : FONT_NORMAL), (code_string > 0 ? FONT_CODE_STRING : FONT_NORMAL),
param > 0 || param_ref > 0 param > 0 || param_ref > 0
? &param_colors[(param_id++) % param_colors_count] ? &param_colors[(param_id++) % param_colors_count]
: nullptr); : !colors.empty()
? &colors.back()
: nullptr,
!sizes.empty() ? &sizes.back() : nullptr
);
} }
}; };
......
...@@ -368,12 +368,15 @@ template <> void Reader::handle(Vector2D& vec) { ...@@ -368,12 +368,15 @@ template <> void Reader::handle(Vector2D& vec) {
} }
template <> void Reader::handle(Color& col) { template <> void Reader::handle(Color& col) {
col = parse_color(getValue());
if (!col.Ok()) col = *wxBLACK;
}
Color parse_color(const String& v) {
UInt r,g,b; UInt r,g,b;
if (wxSscanf(getValue().c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) { if (wxSscanf(v.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
col.Set(r, g, b); return Color(r, g, b);
} else { } else {
col = Color(previous_value); return Color(v);
if (!col.Ok()) col = *wxBLACK;
} }
} }
......
...@@ -251,6 +251,9 @@ void Reader::handle(IndexMap<K,V>& m) { ...@@ -251,6 +251,9 @@ void Reader::handle(IndexMap<K,V>& m) {
// ----------------------------------------------------------------------------- : Reflection for enumerations // ----------------------------------------------------------------------------- : Reflection for enumerations
/// Parse a color
Color parse_color(const String& value);
/// Implement enum reflection as used by Reader /// Implement enum reflection as used by Reader
#define REFLECT_ENUM_READER(Enum) \ #define REFLECT_ENUM_READER(Enum) \
template<> void Reader::handle<Enum>(Enum& enum_) { \ template<> void Reader::handle<Enum>(Enum& enum_) { \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment