Dialog fix for line breaks in the middle of words.

Issue 1049
Adjust the TypesetBookImpl::Typesetter to not assume a word break
at the end of write() calls.
A word break is assumed if any of the other content insertion methods
are used (section break, add/select content, etc).
openmw-35
Jordan Ayers 10 years ago
parent b44fc1904b
commit 1410819e20

@ -195,8 +195,20 @@ struct TypesetBookImpl : TypesetBook
struct TypesetBookImpl::Typesetter : BookTypesetter
{
struct PartialText {
StyleImpl *mStyle;
Utf8Stream::Point mBegin;
Utf8Stream::Point mEnd;
int mWidth;
PartialText( StyleImpl *style, Utf8Stream::Point begin, Utf8Stream::Point end, int width) :
mStyle(style), mBegin(begin), mEnd(end), mWidth(width)
{}
};
typedef TypesetBookImpl Book;
typedef boost::shared_ptr <Book> BookPtr;
typedef std::vector<PartialText>::const_iterator PartialTextConstIterator;
int mPageWidth;
int mPageHeight;
@ -207,6 +219,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
Run * mRun;
std::vector <Alignment> mSectionAlignment;
std::vector <PartialText> mPartialWhitespace;
std::vector <PartialText> mPartialWord;
Book::Content const * mCurrentContent;
Alignment mCurrentAlignment;
@ -273,6 +287,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
intptr_t addContent (Utf8Span text, bool select)
{
add_partial_text();
Contents::iterator i = mBook->mContents.insert (mBook->mContents.end (), Content (text.first, text.second));
if (select)
@ -283,6 +299,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
void selectContent (intptr_t contentHandle)
{
add_partial_text();
mCurrentContent = reinterpret_cast <Content const *> (contentHandle);
}
@ -302,12 +320,16 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
{
assert (margin == 0); //TODO: figure out proper behavior here...
add_partial_text();
mRun = NULL;
mLine = NULL;
}
void sectionBreak (float margin)
{
add_partial_text();
if (mBook->mSections.size () > 0)
{
mRun = NULL;
@ -321,6 +343,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
void setSectionAlignment (Alignment sectionAlignment)
{
add_partial_text();
if (mSection != NULL)
mSectionAlignment.back () = sectionAlignment;
mCurrentAlignment = sectionAlignment;
@ -331,6 +355,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
int curPageStart = 0;
int curPageStop = 0;
add_partial_text();
std::vector <Alignment>::iterator sa = mSectionAlignment.begin ();
for (Sections::iterator i = mBook->mSections.begin (); i != mBook->mSections.end (); ++i, ++sa)
{
@ -415,23 +441,23 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
void writeImpl (StyleImpl * style, Utf8Stream::Point _begin, Utf8Stream::Point _end)
{
int line_height = style->mFont->getDefaultHeight ();
Utf8Stream stream (_begin, _end);
while (!stream.eof ())
{
if (ucsLineBreak (stream.peek ()))
{
add_partial_text();
stream.consume ();
mLine = NULL, mRun = NULL;
continue;
}
if (ucsBreakingSpace (stream.peek ()) && !mPartialWord.empty())
add_partial_text();
int word_width = 0;
int word_height = 0;
int space_width = 0;
int character_count = 0;
Utf8Stream::Point lead = stream.current ();
@ -450,8 +476,6 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
if (gi)
word_width += gi->advance + gi->bearingX;
word_height = line_height;
++character_count;
stream.consume ();
}
@ -460,21 +484,57 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
if (lead == extent)
break;
int left = mLine ? mLine->mRect.right : 0;
if ( lead != origin )
mPartialWhitespace.push_back (PartialText (style, lead, origin, space_width));
if ( origin != extent )
mPartialWord.push_back (PartialText (style, origin, extent, word_width));
}
}
if (left + space_width + word_width > mPageWidth)
{
mLine = NULL, mRun = NULL;
void add_partial_text ()
{
if (mPartialWhitespace.empty() && mPartialWord.empty())
return;
append_run (style, origin, extent, extent - origin, word_width, mBook->mRect.bottom + word_height);
}
else
int space_width = 0;
int word_width = 0;
for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i)
space_width += i->mWidth;
for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i)
word_width += i->mWidth;
int left = mLine ? mLine->mRect.right : 0;
if (left + space_width + word_width > mPageWidth)
{
mLine = NULL, mRun = NULL, left = 0;
}
else
{
for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i)
{
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
int line_height = i->mStyle->mFont->getDefaultHeight ();
append_run ( i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + line_height);
append_run (style, lead, extent, extent - origin, left + space_width + word_width, top + word_height);
left = mLine->mRect.right;
}
}
for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i)
{
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
int line_height = i->mStyle->mFont->getDefaultHeight ();
append_run (i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + line_height);
left = mLine->mRect.right;
}
mPartialWhitespace.clear();
mPartialWord.clear();
}
void append_run (StyleImpl * style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom)

Loading…
Cancel
Save