From bfc70139347781252b7d6860cde5722ed9d5a487 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 7 Sep 2017 18:00:25 +0200 Subject: Fix infinite loop when rendering text inside a shape under very special conditions. (When a line does not fit due to its height but when refitted with a larger height it is broken into multiple chunks and no text fits into the first chunk.) Fixes bug #1715442. --- src/libnrtype/Layout-TNG-Compute.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index d9ab8694b..1bc035856 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -253,8 +253,7 @@ class Layout::Calculator UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height, - FontMetrics const *strut_height) const; + FontMetrics *line_height) const; bool _measureUnbrokenSpan(ParagraphInfo const ¶, BrokenSpan *span, @@ -1472,8 +1471,8 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, TRACE((" initial line_box_height (em size): %f\n", line_box_height->emSize() )); UnbrokenSpanPosition span_pos; + static int trys = 0; for( ; ; ) { - // Get regions where one can place one line of text (can be more than one, if filling a // donut for example). std::vector scan_runs; @@ -1495,10 +1494,9 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, unsigned scan_run_index; span_pos = *start_span_pos; for (scan_run_index = 0 ; scan_run_index < scan_runs.size() ; scan_run_index++) { - // Returns false if some text in line requires a taller line_box_height. // (We try again with a larger line_box_height.) - if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height, strut_height)) { + if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height)) { break; } @@ -1534,11 +1532,12 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height, - FontMetrics const *strut_height) const + FontMetrics *line_height) const { TRACE((" begin _buildChunksInScanRun: chunks: %lu, em size: %f\n", chunk_info->size(), line_height->emSize() )); + FontMetrics line_height_saved = *line_height; // Store for recalculating line height if chunks are backed out + ChunkInfo new_chunk; new_chunk.text_width = 0.0; new_chunk.whitespace_count = 0; @@ -1647,7 +1646,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } // Recalculate line_box_height after backing out chunks - *line_height = *strut_height; + *line_height = line_height_saved; for (std::vector::const_iterator it_chunk = chunk_info->begin() ; it_chunk != chunk_info->end() ; it_chunk++) { for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { FontMetrics span_height = it_span->start.iter_span->line_height; -- cgit v1.2.3