Skip to content
This repository was archived by the owner on Sep 7, 2021. It is now read-only.

Commit 47dfdd0

Browse files
[[ Bugfix 14835 ]] Fix word wrapping in fields containing tabs
1 parent af0ecd7 commit 47dfdd0

3 files changed

Lines changed: 64 additions & 26 deletions

File tree

docs/notes/bugfix-14835.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Fix word wrapping in fields containing tabs
2+

engine/src/block.cpp

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -753,27 +753,41 @@ bool MCBlock::fit(coord_t x, coord_t maxwidth, findex_t& r_break_index, bool& r_
753753
codepoint_t t_this_char;
754754
bool t_end_of_block;
755755
t_end_of_block = false;
756-
while(i < m_index + m_size)
757-
{
758-
t_this_char = t_next_char;
759-
760-
i = parent->IncrementIndex(i);
761-
762-
if (i < m_index + m_size)
763-
t_next_char = parent->GetCodepointAtIndex(i);
764-
else
756+
757+
// If this is the first block of a segment that was created by a tab,
758+
// we can use the first position in the block as a break position,
759+
// unless this is the first segment on a line.
760+
if (!t_can_fit
761+
&& this == segment->GetFirstBlock()
762+
&& i == m_index
763+
&& segment->GetParent()->GetFirstSegment() != segment
764+
&& parent->GetCodepointAtIndex(i - 1) == '\t')
765+
{
766+
t_can_fit = t_can_break = true;
767+
}
768+
else
769+
{
770+
while(i < m_index + m_size)
765771
{
766-
t_next_char = t_next_block_char;
767-
t_end_of_block = true;
772+
t_this_char = t_next_char;
773+
774+
i = parent->IncrementIndex(i);
775+
776+
if (i < m_index + m_size)
777+
t_next_char = parent->GetCodepointAtIndex(i);
778+
else
779+
{
780+
t_next_char = t_next_block_char;
781+
t_end_of_block = true;
782+
}
783+
784+
if (t_next_char == -1 ||
785+
MCUnicodeCanBreakBetween(t_this_char, t_next_char))
786+
{
787+
t_can_break = true;
788+
break;
789+
}
768790
}
769-
770-
if (t_this_char == '\t' ||
771-
t_next_char == -1 ||
772-
MCUnicodeCanBreakBetween(t_this_char, t_next_char))
773-
{
774-
t_can_break = true;
775-
break;
776-
}
777791
}
778792

779793
// MW-2013-11-07: [[ Bug 11393 ]] Previous per-platform implementations all fold into the optimized

engine/src/segment.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,30 @@ MCLine *MCSegment::Fit(coord_t p_max_width)
278278
m_LastBlock = m_LastBlock->next();
279279
}
280280

281+
// If this is not the first segment of the line and there were no suitable
282+
// breaking locations before we ran out of space, split the line before
283+
// this segment (assuming the segment was created using a tab)
284+
bool t_need_break_line = false;
285+
if (!t_need_break_segment && !t_need_break_block
286+
&& t_frontier_width > p_max_width && this != m_Parent->GetFirstSegment()
287+
&& prev()->GetLastBlock()->GetCodepointAtIndex(prev()->GetLastBlock()->GetLength() - 1) == '\t')
288+
{
289+
t_need_break_line = true;
290+
}
291+
281292
// Was breaking required?
282293
// FG-2014-10-21: [[ Bugfix 13727 ]] Breaking a block implies breaking a segment
283294
MCLine *t_newline = NULL;
284-
if (t_need_break_segment || t_need_break_block)
295+
if (t_need_break_line || t_need_break_segment || t_need_break_block)
285296
{
286297
// A block was broken and therefore the segment possibly needs to be split
287298
MCSegment *t_split_segment;
288-
if (t_break_block != m_LastBlock)
299+
if (t_need_break_line)
300+
{
301+
t_split_segment = this;
302+
t_break_block = m_FirstBlock->prev();
303+
}
304+
else if (t_break_block != m_LastBlock)
289305
{
290306
// Split this segment
291307
t_split_segment = new MCSegment(this);
@@ -302,16 +318,22 @@ MCLine *MCSegment::Fit(coord_t p_max_width)
302318
t_split_segment = next();
303319
}
304320

305-
// Update the last block pointer
306-
m_LastBlock = t_break_block;
321+
MCLine* t_parent_line;
322+
MCSegment* t_prev_segment;
323+
t_parent_line = m_Parent;
324+
t_prev_segment = t_split_segment->prev();
325+
326+
// Update the last block pointer if we're not taking all of the segment
327+
if (t_split_segment != this)
328+
m_LastBlock = t_break_block;
307329

308330
// Create a new line containing the segments and blocks that don't fit
309331
t_newline = new MCLine(*m_Parent);
310-
t_newline->appendsegments(t_split_segment, m_Parent->lastsegment);
332+
t_newline->appendsegments(t_split_segment, t_parent_line->lastsegment);
311333

312334
// Update the parent line's block and segment pointers
313-
m_Parent->lastblock = t_break_block;
314-
m_Parent->lastsegment = this;
335+
t_parent_line->lastblock = t_break_block;
336+
t_parent_line->lastsegment = t_prev_segment;
315337
}
316338

317339
// Return the new line, if it exists

0 commit comments

Comments
 (0)