From a291b72dc3458db914753d96f18b0a9870885d71 Mon Sep 17 00:00:00 2001 From: Brian Ewins Date: Fri, 6 Mar 2009 11:45:14 +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..cf8abb4 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