Commit 495425c3 authored by twanvl's avatar twanvl

text scaling

parent 7a60536f
...@@ -19,6 +19,9 @@ void CompoundTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharIn ...@@ -19,6 +19,9 @@ void CompoundTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharIn
double CompoundTextElement::minScale() const { double CompoundTextElement::minScale() const {
return elements.minScale(); return elements.minScale();
} }
double CompoundTextElement::scaleStep() const {
return elements.scaleStep();
}
// ----------------------------------------------------------------------------- : AtomTextElement // ----------------------------------------------------------------------------- : AtomTextElement
......
...@@ -48,6 +48,13 @@ double TextElements::minScale() const { ...@@ -48,6 +48,13 @@ double TextElements::minScale() const {
} }
return m; return m;
} }
double TextElements::scaleStep() const {
double m = 1;
FOR_EACH_CONST(e, elements) {
m = min(m, e->scaleStep());
}
return m;
}
// Helper class for TextElements::fromString, to allow persistent formating state accross recusive calls // Helper class for TextElements::fromString, to allow persistent formating state accross recusive calls
struct TextElementsFromString { struct TextElementsFromString {
......
...@@ -64,30 +64,8 @@ class TextElement { ...@@ -64,30 +64,8 @@ class TextElement {
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const = 0; virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const = 0;
/// Return the minimum scale factor allowed (starts at 1) /// Return the minimum scale factor allowed (starts at 1)
virtual double minScale() const = 0; virtual double minScale() const = 0;
/* /// Return the steps the scale factor should take
// draw the section <start...end) virtual double scaleStep() const = 0;
// drawSeparators indicates what we should draw, separators or normal text
// h is the height of the current line
virtual void draw(RotatedDC& dc, UInt shrink, RealRect rect, size_t start, size_t end, DrawWhat draw) const = 0;
/// Returns the width and height of the character at charId
virtual RealSize charSize(RotatedDC& dc, double scale, size_t charId) const = 0;
/// May the text be broken after char_id?
virtual BreakAfter breakAfter(size_t char_id) const = 0;
// number of characters in this object
abstract size_t size() const;
// maximum shrink factor allowed
// shrink indicates by how much the thing to render should be shrunk, there is no indication
// what it means (probably pixels or points), but size(shrink = k+1) <= size(shrink = k)
abstract UInt maxShrink() const;
// Size of an entire section
RealSize sectionSize(RotatedDC& dc, double scale, size_t start, size_t end) const;
RealSize for::sectionSize(RotatedDC& dc, double scale, size_t start, size_t end) const {
RealSize size;
for(i = start ; i < end ; ++i) {
size = addHorizontal(size, charSize(dc, scale, i));
}
return size;
}*/
}; };
// ----------------------------------------------------------------------------- : TextElements // ----------------------------------------------------------------------------- : TextElements
...@@ -101,6 +79,8 @@ class TextElements : public vector<TextElementP> { ...@@ -101,6 +79,8 @@ class TextElements : public vector<TextElementP> {
void getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const; void getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const;
/// Return the minimum scale factor allowed by all elements /// Return the minimum scale factor allowed by all elements
double minScale() const; double minScale() const;
/// Return the steps the scale factor should take
double scaleStep() const;
/// The actual elements /// The actual elements
/** They must be in order of positions and not overlap, i.e. /** They must be in order of positions and not overlap, i.e.
...@@ -134,6 +114,7 @@ class FontTextElement : public SimpleTextElement { ...@@ -134,6 +114,7 @@ class FontTextElement : public SimpleTextElement {
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const; virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const;
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const; virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
virtual double minScale() const; virtual double minScale() const;
virtual double scaleStep() const;
private: private:
FontP font; FontP font;
DrawWhat draw_as; DrawWhat draw_as;
...@@ -151,6 +132,7 @@ class SymbolTextElement : public SimpleTextElement { ...@@ -151,6 +132,7 @@ class SymbolTextElement : public SimpleTextElement {
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const; virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const;
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const; virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
virtual double minScale() const; virtual double minScale() const;
virtual double scaleStep() const;
private: private:
const SymbolFontRef& font; // owned by TextStyle const SymbolFontRef& font; // owned by TextStyle
Context& ctx; Context& ctx;
...@@ -166,6 +148,7 @@ class CompoundTextElement : public TextElement { ...@@ -166,6 +148,7 @@ class CompoundTextElement : public TextElement {
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const; virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const;
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const; virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
virtual double minScale() const; virtual double minScale() const;
virtual double scaleStep() const;
TextElements elements; ///< the elements TextElements elements; ///< the elements
}; };
......
...@@ -51,3 +51,6 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& ...@@ -51,3 +51,6 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>&
double FontTextElement::minScale() const { double FontTextElement::minScale() const {
return min(font->size, font->scale_down_to) / max(0.01, font->size); return min(font->size, font->scale_down_to) / max(0.01, font->size);
} }
double FontTextElement::scaleStep() const {
return 1. / max(font->size, 1.);
}
...@@ -26,3 +26,6 @@ void SymbolTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo ...@@ -26,3 +26,6 @@ void SymbolTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo
double SymbolTextElement::minScale() const { double SymbolTextElement::minScale() const {
return min(font.size, font.scale_down_to) / max(0.01, font.size); return min(font.size, font.scale_down_to) / max(0.01, font.size);
} }
double SymbolTextElement::scaleStep() const {
return 1. / max(font.size, 1.);
}
...@@ -304,15 +304,26 @@ void TextViewer::prepareElements(const String& text, const TextStyle& style, Con ...@@ -304,15 +304,26 @@ void TextViewer::prepareElements(const String& text, const TextStyle& style, Con
// ----------------------------------------------------------------------------- : Layout // ----------------------------------------------------------------------------- : Layout
void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle& style, Context& ctx) { void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle& style, Context& ctx) {
// find character sizes
vector<CharInfo> chars;
// try to layout, at different scales // try to layout, at different scales
vector<CharInfo> chars;
scale = 1; scale = 1;
// double min_scale = elements.minScale(); double min_scale = elements.minScale();
// while double scale_step = max(0.1,elements.scaleStep());
chars.clear(); while (true) {
elements.getCharInfo(dc, scale, 0, text.size(), chars); double next_scale = scale - scale_step;
prepareLinesScale(dc, chars, style, false); bool last = next_scale < min_scale;
// fits?
chars.clear();
elements.getCharInfo(dc, scale, 0, text.size(), chars);
bool fits = prepareLinesScale(dc, chars, style, last);
if (fits && (lines.empty() || lines.back().bottom() <= dc.getInternalSize().height - style.padding_bottom)) {
break; // text fits in box
}
if (last) break;
// TODO: smarter iteration
scale = next_scale;
}
// no text, find a dummy height for the single line we have // no text, find a dummy height for the single line we have
if (lines.size() == 1 && lines[0].width() < 0.0001) { if (lines.size() == 1 && lines[0].width() < 0.0001) {
if (style.always_symbol && style.symbol_font.valid()) { if (style.always_symbol && style.symbol_font.valid()) {
...@@ -322,8 +333,10 @@ void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle ...@@ -322,8 +333,10 @@ void TextViewer::prepareLines(RotatedDC& dc, const String& text, const TextStyle
lines[0].line_height = dc.GetTextExtent(_(" ")).height; lines[0].line_height = dc.GetTextExtent(_(" ")).height;
} }
} }
// align // align
alignLines(dc, chars, style); alignLines(dc, chars, style);
// HACK : fix empty first line before <line>, do this after align, so layout is not affected // HACK : fix empty first line before <line>, do this after align, so layout is not affected
if (lines.size() > 1 && lines[0].line_height == 0) { if (lines.size() > 1 && lines[0].line_height == 0) {
dc.SetFont(style.font.font); dc.SetFont(style.font.font);
...@@ -338,6 +351,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars, ...@@ -338,6 +351,7 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
// first line // first line
lines.clear(); lines.clear();
Line line; Line line;
line.top = style.padding_top;
// size of the line so far // size of the line so far
RealSize line_size(lineLeft(dc, style, 0), 0); RealSize line_size(lineLeft(dc, style, 0), 0);
line.positions.push_back(line_size.width); line.positions.push_back(line_size.width);
...@@ -462,7 +476,9 @@ void TextViewer::alignLines(RotatedDC& dc, const vector<CharInfo>& chars, const ...@@ -462,7 +476,9 @@ void TextViewer::alignLines(RotatedDC& dc, const vector<CharInfo>& chars, const
if (l.line_height) break; // not an empty line if (l.line_height) break; // not an empty line
} }
// amount to shift all lines vertically // amount to shift all lines vertically
RealSize s = dc.getInternalSize(); RealSize s = addDiagonal(
dc.getInternalSize(),
-RealSize(style.padding_left+style.padding_right, style.padding_top + style.padding_bottom));
double vdelta = align_delta_y(style.alignment, s.height, height); double vdelta = align_delta_y(style.alignment, s.height, height);
// align all lines // align all lines
FOR_EACH(l, lines) { FOR_EACH(l, lines) {
......
...@@ -40,29 +40,11 @@ class RealSize { ...@@ -40,29 +40,11 @@ class RealSize {
: width(s.GetWidth()), height(s.GetHeight()) : width(s.GetWidth()), height(s.GetHeight())
{} {}
/// Addition of two sizes /// Negation of a size, negates both components
/* inline void operator += (const RealSize& s2) {
width += s2.width;
height += s2.height;
}
/// Addition of two sizes
inline RealSize operator + (const RealSize& s2) const {
return RealSize(width + s2.width, height + s2.height);
}
/// Difference of two sizes
inline void operator -= (const RealSize& s2){
width -= s2.width;
height -= s2.height;
}
/// Difference of two sizes
inline RealSize operator - (const RealSize& s2) const {
return RealSize(width - s2.width, height - s2.height);
}
/// Inversion of a size, inverts both components
inline RealSize operator - () const { inline RealSize operator - () const {
return RealSize(-width, -height); return RealSize(-width, -height);
} }
*/
/// Multiplying a size by a scalar r, multiplies both components /// Multiplying a size by a scalar r, multiplies both components
inline void operator *= (double r) { inline void operator *= (double r) {
width *= r; width *= r;
......
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