Skip to content

Commit

Permalink
Fixed|libappfw: DocumentWidget content overflowing the right edge
Browse files Browse the repository at this point in the history
Fixes a layout issue with DocumentWidget where it was possible that
tabbed lines would extend beyond the predetermined bounds for the
text content. This was occurring for instance in the About -> GL popup
when the first set of tabbed lines were shorter than the second set.

Todo for later: Improve FontLineWrapping to precalculate tab stop
alignment so this can be known before vertex generation.
  • Loading branch information
skyjake committed Mar 17, 2015
1 parent d09976a commit 11e1b98
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 12 deletions.
15 changes: 15 additions & 0 deletions doomsday/libappfw/include/de/framework/gltextcomposer.h
Expand Up @@ -108,6 +108,21 @@ class LIBAPPFW_PUBLIC GLTextComposer : public Asset
ui::Alignment const &lineAlign,
Vector4f const &color = Vector4f(1, 1, 1, 1));

/**
* Returns the maximum width of the generated vertices. This is only valid after
* makeVertices() has been called.
*
* This may be larger than the maximum width as determined by FontLineWrapping if
* tabbed lines are used in the text. This is because text segments are aligned
* with tab stops only during makeVertices().
*
* @todo Ideally tap stop alignment should be done in FontLineWrapping, so that the
* maximum width would be known prior to generating the vertices.
*
* @return Maximum width of the generated vertices.
*/
int verticesMaxWidth() const;

private:
DENG2_PRIVATE(d)
};
Expand Down
2 changes: 1 addition & 1 deletion doomsday/libappfw/src/fontlinewrapping.cpp
Expand Up @@ -575,7 +575,7 @@ void FontLineWrapping::wrapTextToWidth(String const &text, Font::RichFormat cons
pos = wholeLine.end + 1;
}

// Process the content is distinct ranges divided by untabbed content.
// Process the content in distinct ranges divided by untabbed content.
Rangei tabRange = d->findNextTabbedRange(0);
forever
{
Expand Down
30 changes: 19 additions & 11 deletions doomsday/libappfw/src/gltextcomposer.cpp
Expand Up @@ -28,13 +28,14 @@ static Rangei const MAX_VISIBLE_RANGE(0, 0x7fffffff);

DENG2_PIMPL(GLTextComposer)
{
Font const *font;
Atlas *atlas;
Font const *font = nullptr;
Atlas *atlas = nullptr;
String text;
FontLineWrapping const *wraps;
FontLineWrapping const *wraps = nullptr;
Font::RichFormat format;
bool needRedo;
Rangei visibleLineRange; ///< Only these lines will be updated/drawn.
bool needRedo = false;
Rangei visibleLineRange { MAX_VISIBLE_RANGE }; ///< Only these lines will be updated/drawn.
int maxGeneratedWidth = 0;

struct Line {
struct Segment {
Expand All @@ -53,10 +54,7 @@ DENG2_PIMPL(GLTextComposer)
typedef QList<Line> Lines;
Lines lines;

Instance(Public *i)
: Base(i), font(0), atlas(0), wraps(0), needRedo(false),
visibleLineRange(MAX_VISIBLE_RANGE)
{}
Instance(Public *i) : Base(i) {}

~Instance()
{
Expand Down Expand Up @@ -489,6 +487,8 @@ void GLTextComposer::makeVertices(Vertices &triStrip,
}
}

d->maxGeneratedWidth = 0;

// Generate vertices for each line.
for(int i = 0; i < d->wraps->height(); ++i)
{
Expand Down Expand Up @@ -528,13 +528,21 @@ void GLTextComposer::makeVertices(Vertices &triStrip,

Rectanglef const uv = d->atlas->imageRectf(seg.id);

triStrip.makeQuad(Rectanglef::fromSize(linePos + Vector2f(seg.x, 0), size),
color, uv);
auto const segRect = Rectanglef::fromSize(linePos + Vector2f(seg.x, 0), size);
triStrip.makeQuad(segRect, color, uv);

// Keep track of how wide the geometry really is.
d->maxGeneratedWidth = de::max(d->maxGeneratedWidth, int(segRect.right() - p.x));
}
}

p.y += d->font->lineSpacing().value();
}
}

int GLTextComposer::verticesMaxWidth() const
{
return d->maxGeneratedWidth;
}

} // namespace de
3 changes: 3 additions & 0 deletions doomsday/libappfw/src/widgets/documentwidget.cpp
Expand Up @@ -223,6 +223,9 @@ public Font::RichFormat::IStyle
VertexBuf::Builder verts;
glText.makeVertices(verts, Vector2i(0, 0), ui::AlignLeft);
drawable.buffer<VertexBuf>(ID_TEXT).setVertices(gl::TriangleStrip, verts, gl::Static);

// Update content size to match the generated vertices exactly.
self.setContentWidth(glText.verticesMaxWidth());
}

uScrollMvpMatrix = root().projMatrix2D() *
Expand Down

0 comments on commit 11e1b98

Please sign in to comment.