From 9c6b001a10851a32e99809926c91974937021025 Mon Sep 17 00:00:00 2001 From: Brian Ewins Date: Fri, 6 Mar 2009 11:33:27 +0000 Subject: [PATCH] Fix bug 3188, text selection across table cells Bug 3188. When selecting text, poppler goes across the whole page then down, rather than across each cell, down that cell, then across to the next cell. This leads to illegible paste results. Teach TextPage to visit the selection in flow order rather than block order. --- poppler/TextOutputDev.cc | 102 +++++++++++++++++++++++++-------------------- 1 files changed, 57 insertions(+), 45 deletions(-) diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 721ce45..ef9a5d4 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -3933,73 +3933,85 @@ void TextPage::visitSelection(TextSelectionVisitor *visitor, PDFRectangle *selection, SelectionStyle style) { - int i, begin, end; PDFRectangle child_selection; double start_x, start_y, stop_x, stop_y; - TextBlock *b; + TextFlow *first_flow, *last_flow; + TextBlock *blk, *first_block, *last_block; - begin = nBlocks; - end = 0; start_x = selection->x1; start_y = selection->y1; stop_x = selection->x2; stop_y = selection->y2; - for (i = 0; i < nBlocks; i++) { - b = blocks[i]; - - if (selection->x1 < b->xMax && selection->y1 < b->yMax && - selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { - begin = i; - if (selection->y1 < selection->y2) { + for (flow = text->flows; flow; flow = flow->next) { + if (!first_block) { + first_flow = flow; + } + for (blk = flow->blocks; blk; b = blk->next) { + if (selection->x1 < blk->xMax && selection->y1 < blk->yMax && + selection->x2 < blk->xMax && selection->y2 < blk->yMax && !first_block) { + first_block = blk; + if (selection->y1 < selection->y2) { + start_x = selection->x1; + start_y = selection->y1; + stop_x = selection->x2; + stop_y = selection->y2; + } else { + start_x = selection->x2; + start_y = selection->y2; + stop_x = selection->x1; + stop_y = selection->y1; + } + } else if (selection->x1 < blk->xMax && selection->y1 < blk->yMax && !first_block) { + first_block = blk; start_x = selection->x1; start_y = selection->y1; stop_x = selection->x2; stop_y = selection->y2; - } else { + } else if (selection->x2 < blk->xMax && selection->y2 < blk->yMax && !first_block) { + first_block = blk; start_x = selection->x2; start_y = selection->y2; stop_x = selection->x1; stop_y = selection->y1; } - } else if (selection->x1 < b->xMax && selection->y1 < b->yMax && i < begin) { - begin = i; - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - } else if (selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { - begin = i; - start_x = selection->x2; - start_y = selection->y2; - stop_x = selection->x1; - stop_y = selection->y1; - } - if ((selection->x1 > b->xMin && selection->y1 > b->yMin) || - (selection->x2 > b->xMin && selection->y2 > b->yMin)) - end = i + 1; + if (((selection->x1 > blk->xMin && selection->y1 > blk->yMin) || + (selection->x2 > blk->xMin && selection->y2 > blk->yMin)) && first_block) { + last_flow = flow->next; + last_block = blk ->next; + if (last_flow && !last_block) { + last_block = last_flow->blocks; + } + } + } } - for (i = begin; i < end; i++) { - if (blocks[i]->xMin < start_x && start_x < blocks[i]->xMax && - blocks[i]->yMin < start_y && start_y < blocks[i]->yMax) { - child_selection.x1 = start_x; - child_selection.y1 = start_y; - } else { - child_selection.x1 = 0; - child_selection.y1 = 0; - } - if (blocks[i]->xMin < stop_x && stop_x < blocks[i]->xMax && - blocks[i]->yMin < stop_y && stop_y < blocks[i]->yMax) { - child_selection.x2 = stop_x; - child_selection.y2 = stop_y; - } else { - child_selection.x2 = pageWidth; - child_selection.y2 = pageHeight; + for (flow = first_flow; flow && flow != last_flow; flow = flow->next) { + TextBlock start_block = flow->blocks; + if (flow == first_flow) { + start_block = first_block; } + for (blk = start_block; blk && blk != last_block; blk = blk->next) { + if (blk->xMin < start_x && start_x < blk->xMax && + blk->yMin < start_y && start_y < blk->yMax) { + child_selection.x1 = start_x; + child_selection.y1 = start_y; + } else { + child_selection.x1 = 0; + child_selection.y1 = 0; + } + if (blk->xMin < stop_x && stop_x < blk->xMax && + blk->yMin < stop_y && stop_y < blk->yMax) { + child_selection.x2 = stop_x; + child_selection.y2 = stop_y; + } else { + child_selection.x2 = pageWidth; + child_selection.y2 = pageHeight; + } - blocks[i]->visitSelection(visitor, &child_selection, style); + blk->visitSelection(visitor, &child_selection, style); + } } } -- 1.6.1.2