mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Added <soft> tag that takes up no space for alignment purposes;
used this tag for magic creature types; Added correct handling of Tribal sub types; Fixed sort_index use by spoiler export template git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@637 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -147,7 +147,7 @@ script:
|
|||||||
}</ul>"
|
}</ul>"
|
||||||
}
|
}
|
||||||
write_group := {
|
write_group := {
|
||||||
cards := filter_list(set.cards, filter: { sort_index(card:input) == code } )
|
cards := filter_list(set.cards, filter: { contains(match:sort_index(card:input), code } )
|
||||||
count := number_of_items(in:cards)
|
count := number_of_items(in:cards)
|
||||||
if count > 0 then
|
if count > 0 then
|
||||||
"<h2>{title} ({count} {if count == 1 then "card" else "cards"})</h2>" +
|
"<h2>{title} ({count} {if count == 1 then "card" else "cards"})</h2>" +
|
||||||
@@ -194,16 +194,17 @@ script:
|
|||||||
<div class='description'>{ to_html(set.description) }</div>
|
<div class='description'>{ to_html(set.description) }</div>
|
||||||
{ if options.grouping == "group by color" then
|
{ if options.grouping == "group by color" then
|
||||||
# Codes as by sort_index
|
# Codes as by sort_index
|
||||||
write_group(title: "White", code:"A") +
|
write_group(title: "White", code:"A") +
|
||||||
write_group(title: "Blue", code:"B") +
|
write_group(title: "Blue", code:"B") +
|
||||||
write_group(title: "Black", code:"C") +
|
write_group(title: "Black", code:"C") +
|
||||||
write_group(title: "Red", code:"D") +
|
write_group(title: "Red", code:"D") +
|
||||||
write_group(title: "Green", code:"E") +
|
write_group(title: "Green", code:"E") +
|
||||||
write_group(title: "Multicolor", code:"F") +
|
write_group(title: "Multicolor", code:"F") +
|
||||||
write_group(title: "Hybrids", code:"G") +
|
write_group(title: "Hybrids", code:"G") +
|
||||||
write_group(title: "Colorless", code:"I") +
|
write_group(title: "Multicolor split cards", code:"H") +
|
||||||
write_group(title: "Non-basic lands", code:"J") +
|
write_group(title: "Colorless", code:"I") +
|
||||||
write_group(title: "Basic lands", code:"K")
|
write_group(title: "Non-basic lands", code:"K") +
|
||||||
|
write_group(title: "Basic lands", code:"LMNOPQ")
|
||||||
else
|
else
|
||||||
write_cards(cards: set.cards)
|
write_cards(cards: set.cards)
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-22
@@ -1,8 +1,8 @@
|
|||||||
mse version: 0.3.4
|
mse version: 0.3.5
|
||||||
short name: Magic
|
short name: Magic
|
||||||
full name: Magic the Gathering
|
full name: Magic the Gathering
|
||||||
icon: card-back.png
|
icon: card-back.png
|
||||||
version: 2007-07-01
|
version: 2007-08-28
|
||||||
position hint: 01
|
position hint: 01
|
||||||
|
|
||||||
############################################################## Functions & filters
|
############################################################## Functions & filters
|
||||||
@@ -126,7 +126,8 @@ init script:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# The color of a card
|
# The color of a card
|
||||||
is_creature := match_rule(match: "(?i)Creature|Tribal")
|
is_creature := match_rule(match: "(?i)Creature")
|
||||||
|
is_tribal := match_rule(match: "(?i)Tribal")
|
||||||
is_artifact := match_rule(match: "(?i)Artifact")
|
is_artifact := match_rule(match: "(?i)Artifact")
|
||||||
is_land := match_rule(match: "(?i)Land")
|
is_land := match_rule(match: "(?i)Land")
|
||||||
is_enchantment := match_rule(match: "(?i)Enchantment")
|
is_enchantment := match_rule(match: "(?i)Enchantment")
|
||||||
@@ -176,17 +177,17 @@ init script:
|
|||||||
card_color := card.card_color
|
card_color := card.card_color
|
||||||
casting_cost := card.casting_cost
|
casting_cost := card.casting_cost
|
||||||
if card.casting_cost_2 != "" and
|
if card.casting_cost_2 != "" and
|
||||||
card_color != card.card_color_2 then "H" # multicolor splits
|
card_color != card.card_color_2 then "H" # multicolor splits
|
||||||
else if chosen(choice: "land", card_color) then (
|
else if chosen(choice: "land", card_color) then (
|
||||||
# land
|
# land
|
||||||
if card.rarity != "basic land" then "K" # nonbasic land
|
if card.rarity != "basic land" then "K" # nonbasic land
|
||||||
else (
|
else (
|
||||||
if contains(card.name, match:"Plains") then "M"
|
if contains(card.name, match:"Plains") then "M"
|
||||||
else if contains(card.name, match:"Island") then "N"
|
else if contains(card.name, match:"Island") then "N"
|
||||||
else if contains(card.name, match:"Swamp") then "O"
|
else if contains(card.name, match:"Swamp") then "O"
|
||||||
else if contains(card.name, match:"Mountain") then "P"
|
else if contains(card.name, match:"Mountain") then "P"
|
||||||
else if contains(card.name, match:"Forest") then "Q"
|
else if contains(card.name, match:"Forest") then "Q"
|
||||||
else "L" # other basic land
|
else "L" # other basic land
|
||||||
)
|
)
|
||||||
) else if is_null_cost(casting_cost) then (
|
) else if is_null_cost(casting_cost) then (
|
||||||
# no casting cost; use frame
|
# no casting cost; use frame
|
||||||
@@ -368,24 +369,31 @@ init script:
|
|||||||
type_over_type +
|
type_over_type +
|
||||||
{ "<word-list-type>{input}</word-list-type>" }
|
{ "<word-list-type>{input}</word-list-type>" }
|
||||||
|
|
||||||
space_to_wlclass := replace_rule(match:" +", replace:"</word-list-class> <word-list-class>")
|
space_to_wltags := replace_rule(match:"( +|<soft> </soft>)",
|
||||||
|
replace:{"</word-list-{list_type}>{_1}<word-list-{list_type}>"})
|
||||||
sub_type_filter :=
|
sub_type_filter :=
|
||||||
tag_remove_rule(tag: "<word-list-") +
|
tag_remove_rule(tag: "<word-list-") +
|
||||||
{ if is_creature(type) then (
|
replace_rule(match: " </soft>$", replace: "") + # remove trailing soft space
|
||||||
if input == "" then "<word-list-race></word-list-race>"
|
tag_remove_rule(tag: "<soft") +
|
||||||
else (
|
{ list_type := if is_creature(type) then "class"
|
||||||
first := only_first(input);
|
else if is_land(type) then "land"
|
||||||
next := trim(only_next(input));
|
else if is_artifact(type) then "artifact"
|
||||||
if next != "" then next := next + " ";
|
else if is_enchantment(type) then "enchantment"
|
||||||
"<word-list-race>{first}</word-list-race> " +
|
else if is_spell(type) then "spell"
|
||||||
"<word-list-class>" + space_to_wlclass(next) + "</word-list-class>"
|
if is_creature(type) or is_tribal(type) then (
|
||||||
)
|
first := "<word-list-race>{ only_first(input) }</word-list-race>"
|
||||||
|
next := only_next(input)
|
||||||
|
if input == "" then list_type := "" # only edit the race
|
||||||
|
else if next == "" then first := first + "<soft> </soft>"
|
||||||
|
else first := first + " "
|
||||||
|
input := next
|
||||||
|
) else (
|
||||||
|
first := ""
|
||||||
)
|
)
|
||||||
else if is_land(type) then "<word-list-land>{ input}</word-list-land>"
|
if list_type != "" then (
|
||||||
else if is_artifact(type) then "<word-list-artifact>{ input}</word-list-artifact>"
|
if input != "" then input := input + "<soft> </soft>" # Add a new box at the end
|
||||||
else if is_enchantment(type) then "<word-list-enchantment>{input}</word-list-enchantment>"
|
first + "<word-list-{list_type}>{ space_to_wltags(input) }</word-list-{list_type}>"
|
||||||
else if is_spell(type) then "<word-list-spell>{ input}</word-list-spell>"
|
) else first + input
|
||||||
else input
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# all sub types, for word list
|
# all sub types, for word list
|
||||||
@@ -398,7 +406,7 @@ init script:
|
|||||||
}
|
}
|
||||||
all_races := {
|
all_races := {
|
||||||
for each card in set do
|
for each card in set do
|
||||||
if contains(card.super_type, match:"Creature") then
|
if is_creature(card.super_type) or is_tribal(card.super_type) then
|
||||||
"," + only_first(to_text(card.sub_type))
|
"," + only_first(to_text(card.sub_type))
|
||||||
}
|
}
|
||||||
all_classes := {
|
all_classes := {
|
||||||
@@ -1247,7 +1255,9 @@ word list:
|
|||||||
script: all_classes()
|
script: all_classes()
|
||||||
line below: true
|
line below: true
|
||||||
word: Cleric
|
word: Cleric
|
||||||
|
word: Druid
|
||||||
word: Lord
|
word: Lord
|
||||||
|
word: Shaman
|
||||||
word: Soldier
|
word: Soldier
|
||||||
word: Warrior
|
word: Warrior
|
||||||
word:
|
word:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ This is written as the character with code 1 in files.
|
|||||||
Inserting this tag manually will confuse that function!<br/>
|
Inserting this tag manually will confuse that function!<br/>
|
||||||
This tag can never be selected, and its contents can not be edited.
|
This tag can never be selected, and its contents can not be edited.
|
||||||
| @"<sep-soft>"@ Like @"<sep>"@, only hidden. This is inserted by [[fun:combined_editor]]
|
| @"<sep-soft>"@ Like @"<sep>"@, only hidden. This is inserted by [[fun:combined_editor]]
|
||||||
|
| @"<soft>"@ Text who's width is ignored for alignment, similair to @"<sep-soft>"@, but not a separator.
|
||||||
| @"<word-list-?>"@ Indicate that the text inside the tag should be selected from a [[type:word list]].
|
| @"<word-list-?>"@ Indicate that the text inside the tag should be selected from a [[type:word list]].
|
||||||
The <tt>?</tt> must be the name of a word list in the game.
|
The <tt>?</tt> must be the name of a word list in the game.
|
||||||
| any other tag Other tags are ignored.
|
| any other tag Other tags are ignored.
|
||||||
|
|||||||
@@ -1297,7 +1297,7 @@ void TextValueEditor::clearWordListIndicators(RotatedDC& dc) {
|
|||||||
}
|
}
|
||||||
// restore background
|
// restore background
|
||||||
if (wl->behind.Ok()) {
|
if (wl->behind.Ok()) {
|
||||||
dc.DrawBitmap(wl->behind, wl->rect.topRight() + RealSize(0,-1));
|
dc.DrawPreRotatedBitmap(wl->behind, wl->rect.topRight() + RealSize(0,-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ void TextElements::getCharInfo(RotatedDC& dc, double scale, size_t start, size_t
|
|||||||
FOR_EACH_CONST(e, elements) {
|
FOR_EACH_CONST(e, elements) {
|
||||||
// characters before this element, after the previous
|
// characters before this element, after the previous
|
||||||
while (out.size() < e->start) {
|
while (out.size() < e->start) {
|
||||||
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
out.push_back(CharInfo());
|
||||||
}
|
}
|
||||||
e->getCharInfo(dc, scale, out);
|
e->getCharInfo(dc, scale, out);
|
||||||
}
|
}
|
||||||
while (out.size() < end) {
|
while (out.size() < end) {
|
||||||
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
out.push_back(CharInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +100,8 @@ struct TextElementsFromString {
|
|||||||
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, _("</sep-soft"))) soft -= 1;
|
else if (is_substr(text, tag_start, _("</sep-soft"))) soft -= 1;
|
||||||
|
else if (is_substr(text, tag_start, _( "<soft"))) soft += 1;
|
||||||
|
else if (is_substr(text, tag_start, _("</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, _("</atom-kwpph"))) kwpph -= 1;
|
else if (is_substr(text, tag_start, _("</atom-kwpph"))) kwpph -= 1;
|
||||||
else if (is_substr(text, tag_start, _( "<code-kw"))) code_kw += 1;
|
else if (is_substr(text, tag_start, _( "<code-kw"))) code_kw += 1;
|
||||||
|
|||||||
@@ -42,10 +42,16 @@ enum LineBreak
|
|||||||
|
|
||||||
/// Information on a character in a TextElement
|
/// Information on a character in a TextElement
|
||||||
struct CharInfo {
|
struct CharInfo {
|
||||||
RealSize size;
|
RealSize size; ///< Size of this character
|
||||||
LineBreak break_after;
|
LineBreak break_after : 31; ///< How/when to break after it?
|
||||||
|
bool soft : 1; ///< Is this a 'soft' character? soft characters are ignored for alignment
|
||||||
|
|
||||||
inline CharInfo(RealSize size, LineBreak break_after) : size(size), break_after(break_after) {}
|
explicit CharInfo()
|
||||||
|
: break_after(BREAK_NO), soft(true)
|
||||||
|
{}
|
||||||
|
inline CharInfo(RealSize size, LineBreak break_after, bool soft = false)
|
||||||
|
: size(size), break_after(break_after), soft(soft)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A section of text that can be rendered using a TextViewer
|
/// A section of text that can be rendered using a TextViewer
|
||||||
@@ -74,7 +80,7 @@ class TextElement : public IntrusivePtrBase<TextElement> {
|
|||||||
// ----------------------------------------------------------------------------- : TextElements
|
// ----------------------------------------------------------------------------- : TextElements
|
||||||
|
|
||||||
/// A list of text elements
|
/// A list of text elements
|
||||||
class TextElements : public vector<TextElementP> {
|
class TextElements {
|
||||||
public:
|
public:
|
||||||
/// Draw all the elements (as need to show the range start..end)
|
/// Draw all the elements (as need to show the range start..end)
|
||||||
void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const;
|
void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
|
|||||||
@@ -37,13 +37,15 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>&
|
|||||||
for (size_t i = start ; i < end ; ++i) {
|
for (size_t i = start ; i < end ; ++i) {
|
||||||
Char c = content.GetChar(i - this->start);
|
Char c = content.GetChar(i - this->start);
|
||||||
if (c == _('\n')) {
|
if (c == _('\n')) {
|
||||||
out.push_back(CharInfo(RealSize(0, dc.GetCharHeight()), break_style));
|
out.push_back(CharInfo(RealSize(0, dc.GetCharHeight()), break_style, draw_as == DRAW_ACTIVE));
|
||||||
line_start = i + 1;
|
line_start = i + 1;
|
||||||
prev_width = 0;
|
prev_width = 0;
|
||||||
} else {
|
} else {
|
||||||
RealSize s = dc.GetTextExtent(content.substr(line_start - this->start, i - line_start + 1));
|
RealSize s = dc.GetTextExtent(content.substr(line_start - this->start, i - line_start + 1));
|
||||||
out.push_back(CharInfo(RealSize(s.width - prev_width, s.height),
|
out.push_back(CharInfo(
|
||||||
c == _(' ') ? BREAK_SPACE : BREAK_MAYBE
|
RealSize(s.width - prev_width, s.height),
|
||||||
|
c == _(' ') ? BREAK_SPACE : BREAK_MAYBE,
|
||||||
|
draw_as == DRAW_ACTIVE // from <soft> tag
|
||||||
));
|
));
|
||||||
prev_width = s.width;
|
prev_width = s.width;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-17
@@ -16,6 +16,7 @@ DECLARE_TYPEOF_COLLECTION(double);
|
|||||||
|
|
||||||
struct TextViewer::Line {
|
struct TextViewer::Line {
|
||||||
size_t start; ///< Index of the first character in this line
|
size_t start; ///< Index of the first character in this line
|
||||||
|
size_t end_or_soft; ///< Index just beyond the last non-soft character
|
||||||
vector<double> positions; ///< x position of each character in this line, gives the number of characters + 1, never empty
|
vector<double> positions; ///< x position of each character in this line, gives the number of characters + 1, never empty
|
||||||
double top; ///< y position of (the top of) this line
|
double top; ///< y position of (the top of) this line
|
||||||
double line_height; ///< The height of this line in pixels
|
double line_height; ///< The height of this line in pixels
|
||||||
@@ -23,13 +24,13 @@ struct TextViewer::Line {
|
|||||||
//% Alignment alignment; ///< Alignment of this line
|
//% Alignment alignment; ///< Alignment of this line
|
||||||
|
|
||||||
Line()
|
Line()
|
||||||
: start(0), top(0), line_height(0), break_after(BREAK_NO)
|
: start(0), end_or_soft(0), top(0), line_height(0), break_after(BREAK_NO)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// The position (just beyond) the bottom of this line
|
/// The position (just beyond) the bottom of this line
|
||||||
double bottom() const { return top + line_height; }
|
double bottom() const { return top + line_height; }
|
||||||
/// The width of this line
|
/// The width of this line
|
||||||
double width() const { return positions.back() - positions.front(); }
|
double width() const { return positions[end_or_soft-start] - positions.front(); }
|
||||||
/// Index just beyond the last character on this line
|
/// Index just beyond the last character on this line
|
||||||
size_t end() const { return start + positions.size() - 1; }
|
size_t end() const { return start + positions.size() - 1; }
|
||||||
/// Find the index of the character at the given position on this line
|
/// Find the index of the character at the given position on this line
|
||||||
@@ -158,7 +159,7 @@ bool TextViewer::prepare(RotatedDC& dc, const String& text, TextStyle& style, Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TextViewer::reset(bool related) {
|
void TextViewer::reset(bool related) {
|
||||||
elements.clear();
|
elements.elements.clear();
|
||||||
lines.clear();
|
lines.clear();
|
||||||
if (!related) scale = 1.0;
|
if (!related) scale = 1.0;
|
||||||
}
|
}
|
||||||
@@ -169,6 +170,7 @@ bool TextViewer::prepared() const {
|
|||||||
// ----------------------------------------------------------------------------- : Positions
|
// ----------------------------------------------------------------------------- : Positions
|
||||||
|
|
||||||
const TextViewer::Line& TextViewer::findLine(size_t index) const {
|
const TextViewer::Line& TextViewer::findLine(size_t index) const {
|
||||||
|
assert(!lines.empty());
|
||||||
FOR_EACH_CONST(l, lines) {
|
FOR_EACH_CONST(l, lines) {
|
||||||
if (l.end() >= index) return l;
|
if (l.end() >= index) return l;
|
||||||
}
|
}
|
||||||
@@ -295,6 +297,7 @@ void TextViewer::scrollBy(double delta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TextViewer::ensureVisible(double height, size_t char_id) {
|
bool TextViewer::ensureVisible(double height, size_t char_id) {
|
||||||
|
if (lines.empty()) return true;
|
||||||
const Line& line = findLine(char_id);
|
const Line& line = findLine(char_id);
|
||||||
if (line.top < 0) {
|
if (line.top < 0) {
|
||||||
// scroll up
|
// scroll up
|
||||||
@@ -511,6 +514,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
// The word we are currently reading
|
// The word we are currently reading
|
||||||
RealSize word_size;
|
RealSize word_size;
|
||||||
vector<double> positions_word; // positios for this word
|
vector<double> positions_word; // positios for this word
|
||||||
|
size_t word_end_or_soft = 0;
|
||||||
size_t word_start = 0;
|
size_t word_start = 0;
|
||||||
// For each character ...
|
// For each character ...
|
||||||
for(size_t i = 0 ; i < chars.size() ; ++i) {
|
for(size_t i = 0 ; i < chars.size() ; ++i) {
|
||||||
@@ -539,6 +543,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
word_size = add_horizontal(word_size, c.size);
|
word_size = add_horizontal(word_size, c.size);
|
||||||
}
|
}
|
||||||
positions_word.push_back(word_size.width);
|
positions_word.push_back(word_size.width);
|
||||||
|
if (!c.soft) word_end_or_soft = i + 1;
|
||||||
// Did the word become too long?
|
// Did the word become too long?
|
||||||
if (style.field().multi_line && !break_now) {
|
if (style.field().multi_line && !break_now) {
|
||||||
double max_width = lineRight(dc, style, line.top);
|
double max_width = lineRight(dc, style, line.top);
|
||||||
@@ -565,11 +570,13 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
FOR_EACH(p, positions_word) {
|
FOR_EACH(p, positions_word) {
|
||||||
line.positions.push_back(line_size.width + p);
|
line.positions.push_back(line_size.width + p);
|
||||||
}
|
}
|
||||||
// add size; next word
|
if (word_end_or_soft != 0) line.end_or_soft = word_end_or_soft;
|
||||||
line_size = add_horizontal(line_size, word_size);
|
line_size = add_horizontal(line_size, word_size);
|
||||||
|
// next word
|
||||||
word_size = RealSize(0, 0);
|
word_size = RealSize(0, 0);
|
||||||
word_start = i + 1;
|
word_start = i + 1;
|
||||||
positions_word.clear();
|
positions_word.clear();
|
||||||
|
word_end_or_soft = 0;
|
||||||
}
|
}
|
||||||
// Breaking (ending the current line)
|
// Breaking (ending the current line)
|
||||||
if (break_now) {
|
if (break_now) {
|
||||||
@@ -583,10 +590,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
} else {
|
} else {
|
||||||
line.line_height = line_size.height;
|
line.line_height = line_size.height;
|
||||||
}
|
}
|
||||||
// // too low?
|
line.end_or_soft = max(line.start, min(line.end_or_soft, line.end()));
|
||||||
// if (stop_if_too_long && line.bottom() > dc.getInternalSize().height - style.padding_bottom) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// push
|
// push
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
// reset line object for next line
|
// reset line object for next line
|
||||||
@@ -612,6 +616,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
FOR_EACH(p, positions_word) {
|
FOR_EACH(p, positions_word) {
|
||||||
line.positions.push_back(line_size.width + p);
|
line.positions.push_back(line_size.width + p);
|
||||||
}
|
}
|
||||||
|
if (word_end_or_soft != 0) line.end_or_soft = word_end_or_soft;
|
||||||
line_size = add_horizontal(line_size, word_size);
|
line_size = add_horizontal(line_size, word_size);
|
||||||
// the last line
|
// the last line
|
||||||
if (line_size.height < 0.01 && !lines.empty()) {
|
if (line_size.height < 0.01 && !lines.empty()) {
|
||||||
@@ -619,6 +624,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
|
|||||||
} else {
|
} else {
|
||||||
line.line_height = line_size.height;
|
line.line_height = line_size.height;
|
||||||
}
|
}
|
||||||
|
line.end_or_soft = max(line.start, min(line.end_or_soft, line.end()));
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
// does it fit vertically?
|
// does it fit vertically?
|
||||||
return lines.empty() ||
|
return lines.empty() ||
|
||||||
@@ -688,14 +694,14 @@ void TextViewer::alignLines(RotatedDC& dc, const vector<CharInfo>& chars, const
|
|||||||
FOR_EACH(l, lines) {
|
FOR_EACH(l, lines) {
|
||||||
l.top += vdelta;
|
l.top += vdelta;
|
||||||
// amount to shift all characters horizontally
|
// amount to shift all characters horizontally
|
||||||
double width = l.positions.back();
|
double width = l.positions[l.end_or_soft - l.start];
|
||||||
if ((style.alignment & ALIGN_JUSTIFY) ||
|
if ((style.alignment & ALIGN_JUSTIFY) ||
|
||||||
(style.alignment & ALIGN_JUSTIFY_OVERFLOW && width > s.width)) {
|
(style.alignment & ALIGN_JUSTIFY_OVERFLOW && width > s.width)) {
|
||||||
// justify text
|
// justify text
|
||||||
justifying = true;
|
justifying = true;
|
||||||
double hdelta = s.width - width; // amount of space to distribute
|
double hdelta = s.width - width; // amount of space to distribute
|
||||||
int count = (int)l.positions.size() - 1; // distribute it among this many characters
|
int count = (int)(l.end_or_soft - l.start); // distribute it among this many characters
|
||||||
if (count == 0) count = 1; // prevent div by 0
|
if (count <= 0) count = 1; // prevent div by 0
|
||||||
int i = 0;
|
int i = 0;
|
||||||
FOR_EACH(c, l.positions) {
|
FOR_EACH(c, l.positions) {
|
||||||
c += hdelta * i++ / count;
|
c += hdelta * i++ / count;
|
||||||
@@ -703,16 +709,16 @@ void TextViewer::alignLines(RotatedDC& dc, const vector<CharInfo>& chars, const
|
|||||||
} else if (style.alignment & ALIGN_JUSTIFY_WORDS) {
|
} else if (style.alignment & ALIGN_JUSTIFY_WORDS) {
|
||||||
// justify text, by words
|
// justify text, by words
|
||||||
justifying = true;
|
justifying = true;
|
||||||
double hdelta = s.width - width; // amount of space to distribute
|
double hdelta = s.width - width; // amount of space to distribute
|
||||||
int count = 0; // distribute it among this many words
|
int count = 0; // distribute it among this many words
|
||||||
for (size_t k = l.start + 1 ; k < l.end() - 1 ; ++k) {
|
for (size_t k = l.start + 1 ; k < l.end_or_soft - 1 ; ++k) {
|
||||||
if (chars[k].break_after == BREAK_SPACE) ++count;
|
if (chars[k].break_after == BREAK_SPACE) ++count;
|
||||||
}
|
}
|
||||||
if (count == 0) count = 1; // prevent div by 0
|
if (count == 0) count = 1; // prevent div by 0
|
||||||
int i = 0; size_t j = l.start;
|
int i = 0; size_t j = l.start;
|
||||||
FOR_EACH(c, l.positions) {
|
FOR_EACH(c, l.positions) {
|
||||||
c += hdelta * i / count;
|
c += hdelta * i / count;
|
||||||
if (j < l.end() && chars[j++].break_after == BREAK_SPACE) i++;
|
if (j < l.end_or_soft && chars[j++].break_after == BREAK_SPACE) i++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// simple alignment
|
// simple alignment
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ void TokenIterator::readToken() {
|
|||||||
filename = include_file;
|
filename = include_file;
|
||||||
InputStreamP is = packages.openFileFromPackage(include_file);
|
InputStreamP is = packages.openFileFromPackage(include_file);
|
||||||
input = read_utf8_line(*is, true, true);
|
input = read_utf8_line(*is, true, true);
|
||||||
} else if (isAlpha(c)) {
|
} else if (isAlpha(c) || c == _('_')) {
|
||||||
// name
|
// name
|
||||||
size_t start = pos - 1;
|
size_t start = pos - 1;
|
||||||
while (pos < input.size() && isAlnum_(input.GetChar(pos))) ++pos;
|
while (pos < input.size() && isAlnum_(input.GetChar(pos))) ++pos;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ void RotatedDC::DrawText (const String& text, const RealPoint& pos, int blur_ra
|
|||||||
void RotatedDC::DrawBitmap(const Bitmap& bitmap, const RealPoint& pos) {
|
void RotatedDC::DrawBitmap(const Bitmap& bitmap, const RealPoint& pos) {
|
||||||
if (angle == 0) {
|
if (angle == 0) {
|
||||||
RealPoint p_ext = tr(pos);
|
RealPoint p_ext = tr(pos);
|
||||||
dc.DrawBitmap(bitmap, (int) p_ext.x, (int) p_ext.y, true);
|
dc.DrawBitmap(bitmap, to_int(p_ext.x), to_int(p_ext.y), true);
|
||||||
} else {
|
} else {
|
||||||
DrawImage(bitmap.ConvertToImage(), pos);
|
DrawImage(bitmap.ConvertToImage(), pos);
|
||||||
}
|
}
|
||||||
@@ -161,15 +161,15 @@ void RotatedDC::DrawBitmap(const Bitmap& bitmap, const RealPoint& pos) {
|
|||||||
void RotatedDC::DrawImage (const Image& image, const RealPoint& pos, ImageCombine combine, int angle) {
|
void RotatedDC::DrawImage (const Image& image, const RealPoint& pos, ImageCombine combine, int angle) {
|
||||||
Image rotated = rotate_image(image, angle + this->angle);
|
Image rotated = rotate_image(image, angle + this->angle);
|
||||||
wxRect r = trNoNegNoZoom(RealRect(pos, RealSize(image)));
|
wxRect r = trNoNegNoZoom(RealRect(pos, RealSize(image)));
|
||||||
draw_combine_image(dc, r.x, r.y, rotated, combine);
|
draw_combine_image(dc, to_int(r.x), to_int(r.y), rotated, combine);
|
||||||
}
|
}
|
||||||
void RotatedDC::DrawPreRotatedBitmap(const Bitmap& bitmap, const RealPoint& pos) {
|
void RotatedDC::DrawPreRotatedBitmap(const Bitmap& bitmap, const RealPoint& pos) {
|
||||||
RealPoint p_ext = tr(pos) - RealSize(revX()?bitmap.GetWidth():0, revY()?bitmap.GetHeight():0);
|
RealPoint p_ext = tr(pos) - RealSize(revX()?bitmap.GetWidth():0, revY()?bitmap.GetHeight():0);
|
||||||
dc.DrawBitmap(bitmap, (int) p_ext.x, (int) p_ext.y, true);
|
dc.DrawBitmap(bitmap, to_int(p_ext.x), to_int(p_ext.y), true);
|
||||||
}
|
}
|
||||||
void RotatedDC::DrawPreRotatedImage (const Image& image, const RealPoint& pos, ImageCombine combine) {
|
void RotatedDC::DrawPreRotatedImage (const Image& image, const RealPoint& pos, ImageCombine combine) {
|
||||||
RealPoint p_ext = tr(pos) - RealSize(revX()?image.GetWidth():0, revY()?image.GetHeight():0);
|
RealPoint p_ext = tr(pos) - RealSize(revX()?image.GetWidth():0, revY()?image.GetHeight():0);
|
||||||
draw_combine_image(dc, p_ext.x, p_ext.y, image, combine);
|
draw_combine_image(dc, to_int(p_ext.x), to_int(p_ext.y), image, combine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotatedDC::DrawLine (const RealPoint& p1, const RealPoint& p2) {
|
void RotatedDC::DrawLine (const RealPoint& p1, const RealPoint& p2) {
|
||||||
|
|||||||
+1
-1
@@ -166,7 +166,7 @@ String cannocial_name_form(const String& str) {
|
|||||||
bool leading = true;
|
bool leading = true;
|
||||||
FOR_EACH_CONST(c, str) {
|
FOR_EACH_CONST(c, str) {
|
||||||
if ((c == _('_') || c == _(' '))) {
|
if ((c == _('_') || c == _(' '))) {
|
||||||
if (!leading) ret += _(' ');
|
ret += leading ? c : _(' ');
|
||||||
} else {
|
} else {
|
||||||
ret += c;
|
ret += c;
|
||||||
leading = false;
|
leading = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user