mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-09 20:47:00 -04:00
fix bullet indent, add clauses
This commit is contained in:
+14
-8
@@ -38,16 +38,21 @@ IMPLEMENT_REFLECTION(TextField) {
|
||||
// ----------------------------------------------------------------------------- : TextStyle
|
||||
|
||||
TextLayoutP dummy_layout() {
|
||||
auto layout = make_intrusive<TextLayout>();
|
||||
auto line = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::LINE);
|
||||
auto layout = make_intrusive<TextLayout>();
|
||||
auto line = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::LINE);
|
||||
auto clause = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::CLAUSE);
|
||||
auto paragraph = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::PARAGRAPH);
|
||||
auto block = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::BLOCK);
|
||||
auto block = make_intrusive<LineLayout>(0, 0, 0, LineLayout::Type::BLOCK);
|
||||
clause ->lines.push_back(line);
|
||||
paragraph->lines.push_back(line);
|
||||
block->lines.push_back(line);
|
||||
layout->lines.push_back(line);
|
||||
block->paragraphs.push_back(paragraph);
|
||||
layout->paragraphs.push_back(paragraph);
|
||||
layout->blocks.push_back(block);
|
||||
block ->lines.push_back(line);
|
||||
layout ->lines.push_back(line);
|
||||
paragraph->clauses.push_back(clause);
|
||||
block ->clauses.push_back(clause);
|
||||
layout ->clauses.push_back(clause);
|
||||
block ->paragraphs.push_back(paragraph);
|
||||
layout ->paragraphs.push_back(paragraph);
|
||||
layout ->blocks.push_back(block);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@@ -129,6 +134,7 @@ void LineLayout::reflect(GetMember& handler) const {
|
||||
REFLECT_N("bottom", bottom());
|
||||
REFLECT_N("middle", middle());
|
||||
if (type > Type::LINE) REFLECT(lines);
|
||||
if (type > Type::CLAUSE) REFLECT(clauses);
|
||||
if (type > Type::PARAGRAPH) REFLECT(paragraphs);
|
||||
if (type > Type::BLOCK) REFLECT(blocks);
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
class LineLayout : public IntrusivePtrVirtualBase {
|
||||
public:
|
||||
double width, top, height;
|
||||
enum class Type { LINE, PARAGRAPH, BLOCK, ALL } type;
|
||||
vector<LineLayoutP> lines, paragraphs, blocks;
|
||||
enum class Type { LINE, CLAUSE, PARAGRAPH, BLOCK, ALL } type;
|
||||
vector<LineLayoutP> lines, clauses, paragraphs, blocks;
|
||||
|
||||
LineLayout() {}
|
||||
LineLayout(double width, double top, double height, Type type) : width(width), top(top), height(height), type(type) {}
|
||||
|
||||
+33
-22
@@ -46,16 +46,20 @@ struct TextElementsFromString {
|
||||
|
||||
const TextStyle& style;
|
||||
Context& ctx;
|
||||
vector<TextClause>& clauses;
|
||||
vector<TextParagraph>& paragraphs;
|
||||
|
||||
TextElementsFromString(TextElements& out, const String& text, const TextStyle& style, Context& ctx)
|
||||
: style(style), ctx(ctx), paragraphs(out.paragraphs)
|
||||
: style(style), ctx(ctx), clauses(out.clauses), paragraphs(out.paragraphs)
|
||||
{
|
||||
out.start = 0;
|
||||
out.end = text.size();
|
||||
clauses.emplace_back();
|
||||
clauses.back().start = 0;
|
||||
paragraphs.emplace_back();
|
||||
paragraphs.back().start = 0;
|
||||
fromString(out.children, text, 0, text.size());
|
||||
clauses.back().end = text.size();
|
||||
paragraphs.back().end = text.size();
|
||||
}
|
||||
|
||||
@@ -70,7 +74,7 @@ private:
|
||||
if (text_start < pos) {
|
||||
// text element before this tag?
|
||||
addText(elements, text, text_start, pos);
|
||||
addParagraphs(text, text_start, pos);
|
||||
addClausesAndParagraphs(text, text_start, pos);
|
||||
}
|
||||
// a (formatting) tag
|
||||
size_t tag_start = pos;
|
||||
@@ -175,7 +179,8 @@ private:
|
||||
} else if (is_tag(text, tag_start, _("<bullet"))) {
|
||||
// start of bullet point, set margin before bullet here, but only once
|
||||
// subsequent times will align to this one
|
||||
if (paragraphs.back().margin_before_bullet == paragraphs.back().start) {
|
||||
if (!paragraphs.back().before_bullet_found) {
|
||||
paragraphs.back().before_bullet_found = true;
|
||||
paragraphs.back().margin_before_bullet = tag_start;
|
||||
}
|
||||
if (li <= 0) {
|
||||
@@ -184,7 +189,8 @@ private:
|
||||
} else if (is_tag(text, tag_start, _("</bullet"))) {
|
||||
// end of bullet point, set margin after bullet here, but only once
|
||||
// subsequent times will align to this one
|
||||
if (paragraphs.back().margin_after_bullet == paragraphs.back().start) {
|
||||
if (!paragraphs.back().after_bullet_found) {
|
||||
paragraphs.back().after_bullet_found = true;
|
||||
paragraphs.back().margin_after_bullet = pos;
|
||||
}
|
||||
if (li <= 0) {
|
||||
@@ -196,18 +202,18 @@ private:
|
||||
size_t colon2 = text.find_first_of(_(">:"), colon + 1);
|
||||
size_t colon3 = colon2 < pos-1 ? text.find_first_of(_(">:"), colon2 + 1) : colon2;
|
||||
Margins m = {0.,0.,0.};
|
||||
text.substr(colon + 1, colon2 - colon - 2).ToDouble(&m.left);
|
||||
text.substr(colon + 1, colon2 - colon - 2).ToDouble(&m.left);
|
||||
text.substr(colon2 + 1, colon3 - colon2 - 2).ToDouble(&m.right);
|
||||
text.substr(colon3 + 1, pos - colon3 - 2).ToDouble(&m.top);
|
||||
text.substr(colon3 + 1, pos - colon3 - 2).ToDouble(&m.top);
|
||||
if (!margins.empty()) {
|
||||
m.left += margins.back().left;
|
||||
m.right += margins.back().right;
|
||||
m.top += margins.back().top;
|
||||
}
|
||||
margins.emplace_back(m);
|
||||
paragraphs.back().margin_left = m.left;
|
||||
paragraphs.back().margin_right = m.right;
|
||||
paragraphs.back().margin_top = m.top;
|
||||
clauses.back().margin_left = m.left;
|
||||
clauses.back().margin_right = m.right;
|
||||
clauses.back().margin_top = m.top;
|
||||
}
|
||||
} else if (is_tag(text, tag_start, _("</margin"))) {
|
||||
if (!margins.empty()) margins.pop_back();
|
||||
@@ -233,7 +239,7 @@ private:
|
||||
if (text_start < end) {
|
||||
// remaining text at the end
|
||||
addText(elements, text, text_start, end);
|
||||
addParagraphs(text, text_start, end);
|
||||
addClausesAndParagraphs(text, text_start, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,8 +254,9 @@ private:
|
||||
} else {
|
||||
// text, possibly mixed with symbols
|
||||
DrawWhat what = soft > 0 ? DRAW_ACTIVE : DRAW_NORMAL;
|
||||
LineBreak line_break = line > 0 ? LineBreak::LINE :
|
||||
soft_line > 0 ? LineBreak::SOFT : LineBreak::HARD;
|
||||
LineBreak line_break = line > 0 ? LineBreak::LINE :
|
||||
soft_line > 0 ? LineBreak::SOFT :
|
||||
LineBreak::HARD;
|
||||
if (kwpph > 0 || param > 0) {
|
||||
// bracket the text
|
||||
content = String(LEFT_ANGLE_BRACKET) + content + RIGHT_ANGLE_BRACKET;
|
||||
@@ -285,25 +292,28 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find paragraph breaks in text
|
||||
void addParagraphs(const String& text, size_t start, size_t end) {
|
||||
if (line == 0 && soft_line > 0) return;
|
||||
// Find clause and paragraph breaks in text
|
||||
void addClausesAndParagraphs(const String& text, size_t start, size_t end) {
|
||||
for (size_t i = start; i < end; ++i) {
|
||||
wxUniChar c = text.GetChar(i);
|
||||
if (c == '\n') {
|
||||
if (c == '\n') {
|
||||
clauses.back().end = i + 1;
|
||||
clauses.emplace_back();
|
||||
clauses.back().start = i + 1;
|
||||
if (!margins.empty()) {
|
||||
clauses.back().margin_left = margins.back().left;
|
||||
clauses.back().margin_right = margins.back().right;
|
||||
clauses.back().margin_top = margins.back().top;
|
||||
}
|
||||
if (line < 1 && soft_line > 0) continue;
|
||||
paragraphs.back().end = i + 1;
|
||||
paragraphs.emplace_back();
|
||||
paragraphs.back().start = i + 1;
|
||||
paragraphs.back().margin_before_bullet = i + 1;
|
||||
paragraphs.back().margin_after_bullet = i + 1;
|
||||
if (!margins.empty()) {
|
||||
paragraphs.back().margin_left = margins.back().left;
|
||||
paragraphs.back().margin_right = margins.back().right;
|
||||
paragraphs.back().margin_top = margins.back().top;
|
||||
}
|
||||
if (!aligns.empty()) {
|
||||
paragraphs.back().alignment = aligns.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,6 +343,7 @@ private:
|
||||
|
||||
void TextElements::clear() {
|
||||
children.clear();
|
||||
clauses.clear();
|
||||
paragraphs.clear();
|
||||
}
|
||||
|
||||
|
||||
+27
-16
@@ -25,19 +25,20 @@ class SymbolFontRef;
|
||||
/// Information on a linebreak
|
||||
enum class LineBreak {
|
||||
NO, // no line break ever
|
||||
MAYBE, // break here when in "direction:vertical" mode
|
||||
SPACE, // optional line break (' ')
|
||||
SOFT, // always a line break, spacing as a soft break, doesn't end paragraphs
|
||||
HARD, // always a line break ('\n')
|
||||
LINE, // line break with a separator line (<line>)
|
||||
MAYBE, // break here when in "direction:vertical" mode (break as WRAP)
|
||||
SPACE, // optional line break, spacing as a soft break, ends a line, ( )
|
||||
WRAP, // always a line break, spacing as a soft break, ends a line, ( )
|
||||
SOFT, // always a line break, spacing as a soft break, ends a clause, (<soft-line>\n</soft-line>)
|
||||
HARD, // always a line break, spacing as a hard break, ends a paragraph, (\n)
|
||||
LINE, // always a line break, spacing as a line break, ends a block, (<line>\n</line>), has separator
|
||||
};
|
||||
|
||||
/// Information on a character in a TextElement
|
||||
struct CharInfo {
|
||||
RealSize size; ///< Size of this character
|
||||
LineBreak break_after : 16; ///< How/when to break after it?
|
||||
bool soft : 1; ///< Is this a 'soft' character? soft characters are ignored for alignment
|
||||
bool bullet : 1; ///< Is this a bullet point?
|
||||
RealSize size; ///< Size of this character
|
||||
LineBreak break_after; ///< How/when to break after it?
|
||||
bool soft : 1; ///< Is this a 'soft' character? soft characters are ignored for alignment
|
||||
bool bullet : 1; ///< Is this a bullet point?
|
||||
|
||||
explicit CharInfo()
|
||||
: break_after(LineBreak::NO), soft(true), bullet(false)
|
||||
@@ -146,14 +147,20 @@ public:
|
||||
|
||||
// ----------------------------------------------------------------------------- : TextElements
|
||||
|
||||
class TextClause {
|
||||
public:
|
||||
double margin_left = 0., margin_right = 0., margin_top = 0.;
|
||||
size_t start = String::npos, end = String::npos;
|
||||
};
|
||||
|
||||
class TextParagraph {
|
||||
public:
|
||||
optional<Alignment> alignment;
|
||||
double margin_left = 0., margin_right = 0.;
|
||||
double margin_top = 0.; //, margin_bottom = 0.; // TODO: more margin options?
|
||||
size_t start = String::npos, end = String::npos;
|
||||
optional<Alignment> alignment;
|
||||
bool before_bullet_found = false;
|
||||
bool after_bullet_found = false;
|
||||
size_t margin_before_bullet = 0; // position of the bullet tag
|
||||
size_t margin_after_bullet = 0; // position of the first character after the bullet tag
|
||||
size_t margin_after_bullet = 0; // position of the first character after the bullet tag
|
||||
size_t start = String::npos, end = String::npos;
|
||||
};
|
||||
|
||||
/// A list of text elements extracted from a string
|
||||
@@ -161,8 +168,12 @@ class TextElements : public CompoundTextElement {
|
||||
public:
|
||||
TextElements() : CompoundTextElement(String::npos,String::npos) {}
|
||||
|
||||
/// Information on the paragraphs/blocks in the string
|
||||
/// Text segments separated by newlines are considered paragraphs
|
||||
/// Information on the clauses/paragraphs/blocks in the string
|
||||
/// Text segments separated by wrapping are considered lines
|
||||
/// Text segments separated by soft newlines are considered clauses
|
||||
/// Text segments separated by hard newlines are considered paragraphs
|
||||
/// Text segments separated by line newlines are considered blocks
|
||||
vector<TextClause> clauses;
|
||||
vector<TextParagraph> paragraphs;
|
||||
|
||||
void clear();
|
||||
|
||||
+69
-40
@@ -21,9 +21,9 @@ struct TextViewer::Line {
|
||||
LineBreak break_after; ///< Is there a saparator after this line?
|
||||
optional<Alignment> alignment; ///< Alignment of this line
|
||||
bool justifying; ///< Is the text justified? Only true when *really* justifying.
|
||||
double margin_left; ///< Left margin including the margin tag and bullet point
|
||||
double margin_left_before_bullet; ///< Left margin but just before the bullet point
|
||||
double margin_right; ///< Rightmargin
|
||||
double margin_left_after_bullet; ///< Left margin including the margin tag and bullet point
|
||||
double margin_left_before_bullet; ///< Left margin including the margin tag but just before the bullet point
|
||||
double margin_right; ///< Right margin
|
||||
bool bullet; ///< Does this line start with a bullet point?
|
||||
|
||||
Line()
|
||||
@@ -357,7 +357,7 @@ void update_size(LineLayout& layout, TextViewer::Line const& l) {
|
||||
TextLayoutP TextViewer::extractLayoutInfo() const {
|
||||
// store information about the content/layout
|
||||
TextLayoutP layout = make_intrusive<TextLayout>();
|
||||
LineLayoutP paragraph, block;
|
||||
LineLayoutP clause, paragraph, block;
|
||||
for (auto const& l : lines) {
|
||||
LineLayoutP line = make_intrusive<LineLayout>(l.width(), l.top, l.line_height, LineLayout::Type::LINE);
|
||||
if (!block) {
|
||||
@@ -370,19 +370,30 @@ TextLayoutP TextViewer::extractLayoutInfo() const {
|
||||
paragraph->type = LineLayout::Type::PARAGRAPH;
|
||||
block->paragraphs.push_back(paragraph);
|
||||
layout->paragraphs.push_back(paragraph);
|
||||
}
|
||||
if (!clause) {
|
||||
clause = make_intrusive<LineLayout>(*line);
|
||||
clause->type = LineLayout::Type::CLAUSE;
|
||||
paragraph->clauses.push_back(clause);
|
||||
block->clauses.push_back(clause);
|
||||
layout->clauses.push_back(clause);
|
||||
}
|
||||
clause->lines.push_back(line);
|
||||
paragraph->lines.push_back(line);
|
||||
block->lines.push_back(line);
|
||||
layout->lines.push_back(line);
|
||||
if (l.line_height > 0) {
|
||||
update_size(*clause, l);
|
||||
update_size(*paragraph, l);
|
||||
update_size(*block, l);
|
||||
update_size(*layout, l);
|
||||
}
|
||||
if (l.break_after == LineBreak::LINE) {
|
||||
paragraph = block = nullptr;
|
||||
clause = paragraph = block = nullptr;
|
||||
} else if (l.break_after == LineBreak::HARD) {
|
||||
paragraph = nullptr;
|
||||
clause = paragraph = nullptr;
|
||||
} else if (l.break_after == LineBreak::SOFT) {
|
||||
clause = nullptr;
|
||||
}
|
||||
}
|
||||
for (size_t i=0; i+1 < layout->blocks.size() ; ++i) {
|
||||
@@ -547,7 +558,7 @@ void TextViewer::prepareLinesTryScales(RotatedDC& dc, const String& text, const
|
||||
|
||||
// Try to fit a blank line in the masked image, move down until it fits
|
||||
RealSize TextViewer::fitLineWidth(Line& line, RotatedDC& dc, const TextStyle& style) const {
|
||||
double margin_left = line.bullet ? line.margin_left_before_bullet : line.margin_left;
|
||||
double margin_left = line.bullet ? line.margin_left_before_bullet : line.margin_left_after_bullet;
|
||||
RealSize line_size(margin_left + lineLeft(dc, style, line.top), 0);
|
||||
while (line.top < dc.getHeight() && line_size.width + 1 >= dc.getWidth() - style.padding_right - line.margin_right) {
|
||||
// nothing fits on this line, move down one pixel
|
||||
@@ -561,16 +572,20 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
// Try to layout the text at the current scale
|
||||
lines.clear();
|
||||
|
||||
// The current "clause" in the input string
|
||||
size_t i_clause = 0;
|
||||
assert(elements.clauses.size() > 0);
|
||||
|
||||
// The current "paragraph" in the input string
|
||||
size_t i_para = 0;
|
||||
assert(elements.paragraphs.size() > 0);
|
||||
|
||||
// first line
|
||||
Line line;
|
||||
line.top = style.padding_top;
|
||||
line.margin_left = elements.paragraphs[0].margin_left;
|
||||
line.margin_left_before_bullet = elements.paragraphs[0].margin_left;
|
||||
line.margin_right = elements.paragraphs[0].margin_right;
|
||||
line.top = style.padding_top + elements.clauses[0].margin_top;
|
||||
line.margin_left_after_bullet = elements.clauses[0].margin_left;
|
||||
line.margin_left_before_bullet = elements.clauses[0].margin_left;
|
||||
line.margin_right = elements.clauses[0].margin_right;
|
||||
line.alignment = elements.paragraphs[0].alignment;
|
||||
// size of the line so far
|
||||
RealSize line_size = fitLineWidth(line, dc, style);
|
||||
@@ -584,14 +599,26 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
// For each character ...
|
||||
for (size_t i = 0 ; i < chars.size() ; ++i) {
|
||||
const CharInfo& c = chars[i];
|
||||
assert(i_clause < elements.clauses.size());
|
||||
assert(i_para < elements.paragraphs.size());
|
||||
assert(c.size.width == 0 || elements.paragraphs[i_para].start <= i && i < elements.paragraphs[i_para].end);
|
||||
assert(c.size.width == 0 || elements.paragraphs[i_para].start <= i && i < elements.paragraphs[i_para].end);
|
||||
// If we found the paragraph's bullet point, calculate the margins
|
||||
if (i == elements.paragraphs[i_para].margin_after_bullet) {
|
||||
for (size_t j = line.start; j < elements.paragraphs[i_para].margin_after_bullet; ++j) {
|
||||
line.margin_left_after_bullet += chars[j].size.width;
|
||||
}
|
||||
}
|
||||
if (i == elements.paragraphs[i_para].margin_before_bullet) {
|
||||
for (size_t j = line.start; j < elements.paragraphs[i_para].margin_before_bullet; ++j) {
|
||||
line.margin_left_before_bullet += chars[j].size.width;
|
||||
}
|
||||
}
|
||||
// Should we break?
|
||||
bool word_too_long = false;
|
||||
bool break_now = false;
|
||||
bool accept_word = false; // the current word should be added to the line
|
||||
bool hide_breaker = true; // hide the \n or _(' ') that caused a line break
|
||||
if (c.break_after == LineBreak::SOFT || c.break_after == LineBreak::HARD || c.break_after == LineBreak::LINE) {
|
||||
if (c.break_after >= LineBreak::WRAP) {
|
||||
break_now = true;
|
||||
accept_word = true;
|
||||
line.break_after = c.break_after;
|
||||
@@ -599,10 +626,10 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
// Soft break == end of word
|
||||
accept_word = true;
|
||||
} else if (c.break_after == LineBreak::MAYBE && style.direction == TOP_TO_BOTTOM) {
|
||||
break_now = true;
|
||||
accept_word = true;
|
||||
break_now = true;
|
||||
accept_word = true;
|
||||
hide_breaker = false;
|
||||
line.break_after = LineBreak::SOFT;
|
||||
line.break_after = LineBreak::WRAP;
|
||||
}
|
||||
// Add size of the character
|
||||
if (c.break_after != LineBreak::LINE) {
|
||||
@@ -612,12 +639,6 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
}
|
||||
positions_word.push_back(word_size.width);
|
||||
if (!c.soft) word_end_or_soft = i + 1;
|
||||
if (i < elements.paragraphs[i_para].margin_after_bullet) {
|
||||
line.margin_left += c.size.width; // character in left margin
|
||||
if (i < elements.paragraphs[i_para].margin_before_bullet) {
|
||||
line.margin_left_before_bullet += c.size.width;
|
||||
}
|
||||
}
|
||||
// Did the word become too long?
|
||||
if (!break_now) {
|
||||
double max_width = lineRight(dc, style, line.top) - line.margin_right;
|
||||
@@ -635,12 +656,12 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
accept_word = true;
|
||||
hide_breaker = false;
|
||||
word_too_long = true;
|
||||
line.break_after = LineBreak::SOFT;
|
||||
line.break_after = LineBreak::WRAP;
|
||||
}
|
||||
} else {
|
||||
// line would become too long, break before the current word
|
||||
break_now = true;
|
||||
line.break_after = LineBreak::SOFT;
|
||||
line.break_after = LineBreak::WRAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -688,20 +709,28 @@ bool TextViewer::prepareLinesAtScale(RotatedDC& dc, const vector<CharInfo>& char
|
||||
line.top += line.line_height * line_height_multiplier;
|
||||
line.start = word_start;
|
||||
line.positions.clear();
|
||||
if (line.break_after == LineBreak::LINE) line.line_height = 0;
|
||||
if (line.break_after >= LineBreak::SOFT) {
|
||||
// end of clause
|
||||
assert(elements.clauses[i_clause].end == i + 1);
|
||||
assert(i_clause + 1 < elements.clauses.size());
|
||||
if (i_clause + 1 < elements.clauses.size()) ++i_clause;
|
||||
assert(elements.clauses[i_clause].start == i + 1);
|
||||
line.margin_right = elements.clauses[i_clause].margin_right;
|
||||
//if (line.start == elements.clauses[i_clause].start) {
|
||||
line.top += elements.clauses[i_clause].margin_top;
|
||||
//}
|
||||
}
|
||||
if (line.break_after >= LineBreak::HARD) {
|
||||
// end of paragraph
|
||||
// look at next paragraph
|
||||
assert(elements.paragraphs[i_para].end == i + 1);
|
||||
assert(i_para + 1 < elements.paragraphs.size());
|
||||
if (i_para+1 < elements.paragraphs.size()) ++i_para;
|
||||
if (i_para + 1 < elements.paragraphs.size()) ++i_para;
|
||||
assert(elements.paragraphs[i_para].start == i + 1);
|
||||
line.margin_left = elements.paragraphs[i_para].margin_left;
|
||||
line.margin_left_before_bullet = elements.paragraphs[i_para].margin_left;
|
||||
line.margin_right = elements.paragraphs[i_para].margin_right;
|
||||
line.top += elements.paragraphs[i_para].margin_top;
|
||||
line.margin_left_after_bullet = elements.clauses[i_clause].margin_left;
|
||||
line.margin_left_before_bullet = elements.clauses[i_clause].margin_left;
|
||||
line.alignment = elements.paragraphs[i_para].alignment;
|
||||
}
|
||||
}
|
||||
if (line.break_after == LineBreak::LINE) line.line_height = 0;
|
||||
line.break_after = LineBreak::NO;
|
||||
// is the first visible character of the line a bullet point?
|
||||
line.bullet = false;
|
||||
@@ -811,9 +840,9 @@ void TextViewer::alignParagraph(size_t start_line, size_t end_line, const vector
|
||||
double sum = 0;
|
||||
for (size_t li = start_line ; li < end_line ; ++li) {
|
||||
const Line& l = lines[li];
|
||||
if ((soft && l.break_after == LineBreak::SOFT)
|
||||
|| (hard && l.break_after == LineBreak::HARD)
|
||||
|| (line && l.break_after == LineBreak::LINE)) sum += l.line_height;
|
||||
if ((soft && (l.break_after == LineBreak::SOFT || l.break_after == LineBreak::WRAP))
|
||||
|| (hard && l.break_after == LineBreak::HARD)
|
||||
|| (line && l.break_after == LineBreak::LINE)) sum += l.line_height;
|
||||
}
|
||||
if (sum == 0) break;
|
||||
// how much do we need to add?
|
||||
@@ -824,9 +853,9 @@ void TextViewer::alignParagraph(size_t start_line, size_t end_line, const vector
|
||||
Line& l = lines[li];
|
||||
l.top += add;
|
||||
// adjust next line by..
|
||||
if ((soft && l.break_after == LineBreak::SOFT)
|
||||
|| (hard && l.break_after == LineBreak::HARD)
|
||||
|| (line && l.break_after == LineBreak::LINE)) add += to_add * l.line_height;
|
||||
if ((soft && (l.break_after == LineBreak::SOFT || l.break_after == LineBreak::WRAP))
|
||||
|| (hard && l.break_after == LineBreak::HARD)
|
||||
|| (line && l.break_after == LineBreak::LINE)) add += to_add * l.line_height;
|
||||
}
|
||||
height += add;
|
||||
}
|
||||
@@ -847,12 +876,12 @@ void TextViewer::alignParagraph(size_t start_line, size_t end_line, const vector
|
||||
}
|
||||
|
||||
void TextViewer::Line::alignHorizontal(const vector<CharInfo>& chars, const TextStyle& style, const RealRect& s) {
|
||||
double margin_bullet = bullet ? margin_left_before_bullet : margin_left;
|
||||
double margin_bullet = bullet ? margin_left_before_bullet : margin_left_after_bullet;
|
||||
double width = this->width() - margin_bullet;
|
||||
double target_width = s.width - margin_bullet - margin_right;
|
||||
Alignment alignment = this->alignment.value_or(style.alignment);
|
||||
bool should_fill = (alignment & ALIGN_IF_OVERFLOW ? width > target_width : true)
|
||||
&& (alignment & ALIGN_IF_SOFTBREAK ? break_after == LineBreak::SOFT || !style.field().multi_line : true);
|
||||
&& (alignment & ALIGN_IF_SOFTBREAK ? break_after == LineBreak::WRAP || break_after == LineBreak::SOFT || !style.field().multi_line : true);
|
||||
if ((alignment & ALIGN_JUSTIFY_ALL) && should_fill) {
|
||||
// justify text, by characters
|
||||
justifying = true;
|
||||
|
||||
@@ -591,6 +591,7 @@ boost::json::object mse_to_json(const StyleP& style) {
|
||||
layoutv.emplace("content_width", wxString::Format(wxT("%.2f"), s->layout->width));
|
||||
layoutv.emplace("content_height", wxString::Format(wxT("%.2f"), s->layout->height));
|
||||
layoutv.emplace("content_lines", wxString::Format(wxT("%i"), s->layout->lines.size()));
|
||||
layoutv.emplace("content_clauses", wxString::Format(wxT("%i"), s->layout->clauses.size()));
|
||||
layoutv.emplace("content_paragraphs", wxString::Format(wxT("%i"), s->layout->paragraphs.size()));
|
||||
layoutv.emplace("content_blocks", wxString::Format(wxT("%i"), s->layout->blocks.size()));
|
||||
boost::json::array separatorsv;
|
||||
|
||||
@@ -27,7 +27,7 @@ enum Alignment {
|
||||
ALIGN_FILL = ALIGN_STRETCH | ALIGN_JUSTIFY_WORDS | ALIGN_JUSTIFY_ALL,
|
||||
// horizontal fill modifiers
|
||||
ALIGN_IF_OVERFLOW = 0x1000, // only fill if text_width > box_width
|
||||
ALIGN_IF_SOFTBREAK = 0x2000, // only fill before soft line breaks
|
||||
ALIGN_IF_SOFTBREAK = 0x2000, // only fill before soft line breaks and wraps
|
||||
// vertical
|
||||
ALIGN_TOP = 0x100,
|
||||
ALIGN_MIDDLE = 0x200,
|
||||
|
||||
Reference in New Issue
Block a user