diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2013-04-30 12:39:26 +0200 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-05-06 12:04:47 +0100 |
commit | 4048032f4a2226f3b54a68840dac39440c5428aa (patch) | |
tree | 2111c7360fa3b185e8a8ae22b772479437fb9890 | |
parent | 2234da7e8f30720467e05b14b578c8f3a082b75a (diff) | |
download | mupdf-4048032f4a2226f3b54a68840dac39440c5428aa.tar.xz |
Use linked list for text spans.
-rw-r--r-- | apps/pdfapp.c | 12 | ||||
-rw-r--r-- | fitz/fitz.h | 5 | ||||
-rw-r--r-- | fitz/text_extract.c | 40 | ||||
-rw-r--r-- | fitz/text_output.c | 22 | ||||
-rw-r--r-- | fitz/text_paragraph.c | 214 | ||||
-rw-r--r-- | fitz/text_search.c | 24 |
6 files changed, 154 insertions, 163 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c index ff23c4b2..4320ba6a 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -768,16 +768,15 @@ static int textlen(fz_text_page *page) { fz_text_line *line; fz_text_block *block; + fz_text_span *span; if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT) continue; block = page->blocks[block_num].u.text; for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; len += span->len; } len++; /* pseudo-newline */ @@ -1616,6 +1615,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen) { fz_text_line *line; fz_text_block *block; + fz_text_span *span; if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT) continue; @@ -1623,10 +1623,8 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen) for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; if (seen) { #ifdef _WIN32 @@ -1654,7 +1652,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen) } } - seen = (seen && span_num + 1 == line->len); + seen = (seen && span == line->last_span); } } } diff --git a/fitz/fitz.h b/fitz/fitz.h index ac3bb246..30075c5d 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1983,8 +1983,7 @@ struct fz_image_block_s */ struct fz_text_line_s { - int len, cap; - fz_text_span **spans; + fz_text_span *first_span, *last_span; /* Cached information */ float distance; /* Perpendicular distance from previous line */ @@ -2018,6 +2017,8 @@ struct fz_text_span_s float column_width; /* Percentage */ int align; /* 0 = left, 1 = centre, 2 = right */ float indent; /* The indent position for this column. */ + + fz_text_span *next; }; /* diff --git a/fitz/text_extract.c b/fitz/text_extract.c index a2c3947a..44acdc48 100644 --- a/fitz/text_extract.c +++ b/fitz/text_extract.c @@ -199,9 +199,8 @@ push_span(fz_context *ctx, fz_text_device *tdev, fz_text_span *span, int new_lin block->lines = fz_resize_array(ctx, block->lines, newcap, sizeof(*block->lines)); block->cap = newcap; } - block->lines[block->len].cap = 0; - block->lines[block->len].len = 0; - block->lines[block->len].spans = NULL; + block->lines[block->len].first_span = NULL; + block->lines[block->len].last_span = NULL; block->lines[block->len].distance = distance; block->lines[block->len].bbox = fz_empty_rect; block->len++; @@ -211,16 +210,21 @@ push_span(fz_context *ctx, fz_text_device *tdev, fz_text_span *span, int new_lin block = page->blocks[page->len-1].u.text; line = &block->lines[block->len-1]; - if (line->len == line->cap) - { - int newcap = (line->cap ? line->cap*2 : 4); - line->spans = fz_resize_array(ctx, line->spans, newcap, sizeof(*line->spans)); - line->cap = newcap; - } fz_union_rect(&block->lines[block->len-1].bbox, &span->bbox); fz_union_rect(&block->bbox, &span->bbox); span->base_offset = (new_line ? 0 : distance); - line->spans[line->len++] = span; + + if (!line->first_span) + { + line->first_span = line->last_span = span; + span->next = NULL; + } + else + { + line->last_span->next = span; + line->last_span = span; + } + return line; } @@ -286,8 +290,8 @@ strain_soup(fz_context *ctx, fz_text_device *tdev) } #endif - p.x = last_line->spans[0]->max.x - last_line->spans[0]->min.x; - p.y = last_line->spans[0]->max.y - last_line->spans[0]->min.y; + p.x = last_line->first_span->max.x - last_line->first_span->min.x; + p.y = last_line->first_span->max.y - last_line->first_span->min.y; fz_normalize_vector(&p); q.x = span->max.x - span->min.x; q.y = span->max.y - span->min.y; @@ -296,8 +300,8 @@ strain_soup(fz_context *ctx, fz_text_device *tdev) printf("last_span=%g %g -> %g %g = %g %g\n", last_span->min.x, last_span->min.y, last_span->max.x, last_span->max.y, p.x, p.y); printf("span =%g %g -> %g %g = %g %g\n", span->min.x, span->min.y, span->max.x, span->max.y, q.x, q.y); #endif - perp_r.y = last_line->spans[0]->min.x - span->min.x; - perp_r.x = -(last_line->spans[0]->min.y - span->min.y); + perp_r.y = last_line->first_span->min.x - span->min.x; + perp_r.x = -(last_line->first_span->min.y - span->min.y); /* Check if p and q are parallel. If so, then this * line is parallel with the last one. */ dot = p.x * q.x + p.y * q.y; @@ -437,14 +441,13 @@ fz_new_text_page(fz_context *ctx, const fz_rect *mediabox) static void fz_free_text_line_contents(fz_context *ctx, fz_text_line *line) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + fz_text_span *span, *next; + for (span = line->first_span; span; span=next) { - fz_text_span *span = line->spans[span_num]; + next = span->next; fz_free(ctx, span->text); fz_free(ctx, span); } - fz_free(ctx, line->spans); } static void @@ -507,6 +510,7 @@ fz_new_text_span(fz_context *ctx, const fz_point *p, int wmode, const fz_matrix span->transform.e = 0; span->transform.f = 0; span->text = NULL; + span->next = NULL; return span; } diff --git a/fitz/text_output.c b/fitz/text_output.c index 3ed45c7c..74e8d2b5 100644 --- a/fitz/text_output.c +++ b/fitz/text_output.c @@ -113,9 +113,10 @@ send_data_base64(fz_output *out, fz_buffer *buffer) void fz_print_text_page_html(fz_context *ctx, fz_output *out, fz_text_page *page) { - int block_n, line_n, span_n, ch_n; + int block_n, line_n, ch_n; fz_text_style *style = NULL; fz_text_line *line; + fz_text_span *span; void *last_region = NULL; fz_printf(out, "<div class=\"page\">\n"); @@ -147,9 +148,8 @@ fz_print_text_page_html(fz_context *ctx, fz_output *out, fz_text_page *page) fz_printf(out, " region=\"%x\"", line->region); #endif fz_printf(out, ">"); - for (span_n = 0; span_n < line->len; span_n++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_n]; float size = fz_matrix_expansion(&span->transform); float base_offset = span->base_offset / size; @@ -169,10 +169,10 @@ fz_print_text_page_html(fz_context *ctx, fz_output *out, fz_text_page *page) /* Now output the span to contain this entire column */ fz_printf(out, "<div class=\"cell\" style=\""); { - int sn; - for (sn = span_n+1; sn < line->len; sn++) + fz_text_span *sn; + for (sn = span->next; sn; sn = sn->next) { - if (line->spans[sn]->column != lastcol) + if (sn->column != lastcol) break; } fz_printf(out, "width:%g%%;align:%s", span->column_width, (span->align == 0 ? "left" : (span->align == 1 ? "center" : "right"))); @@ -299,12 +299,11 @@ fz_print_text_page_xml(fz_context *ctx, fz_output *out, fz_text_page *page) block->bbox.x0, block->bbox.y0, block->bbox.x1, block->bbox.y1); for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; + fz_text_span *span; fz_printf(out, "<line bbox=\"%g %g %g %g\">\n", line->bbox.x0, line->bbox.y0, line->bbox.x1, line->bbox.y1); - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; fz_text_style *style = NULL; int char_num; for (char_num = 0; char_num < span->len; char_num++) @@ -381,10 +380,9 @@ fz_print_text_page(fz_context *ctx, fz_output *out, fz_text_page *page) for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + fz_text_span *span; + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; for (ch = span->text; ch < span->text + span->len; ch++) { n = fz_runetochar(utf, ch->c); diff --git a/fitz/text_paragraph.c b/fitz/text_paragraph.c index b7828a81..893b0aa4 100644 --- a/fitz/text_paragraph.c +++ b/fitz/text_paragraph.c @@ -250,7 +250,7 @@ is_roman(int c) } static int -is_list_entry(fz_text_span *span, int *char_num_ptr, int span_num) +is_list_entry(fz_text_line *line, fz_text_span *span, int *char_num_ptr) { int char_num; fz_text_char *chr; @@ -264,7 +264,7 @@ is_list_entry(fz_text_span *span, int *char_num_ptr, int span_num) } *char_num_ptr = char_num; - if (span_num != 0 || char_num >= span->len) + if (span != line->first_span || char_num >= span->len) return 0; /* Now we check for various special cases, which we consider to mean @@ -992,6 +992,7 @@ static void fz_text_analysis_paragraph(fz_context *ctx, fz_text_sheet *sheet, fz_text_page *page) { fz_text_line *line; + fz_text_span *span; line_heights *lh; region_masks *rms; int block_num; @@ -1016,18 +1017,16 @@ fz_text_analysis_paragraph(fz_context *ctx, fz_text_sheet *sheet, fz_text_page * /* For every style in the line, add lineheight to the * record for that style. FIXME: This is a nasty n^2 * algorithm at the moment. */ - int span_num; fz_text_style *style = NULL; if (line->distance == 0) continue; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; int char_num; - if (is_list_entry(span, &char_num, span_num)) + if (is_list_entry(line, span, &char_num)) goto list_entry; for (; char_num < span->len; char_num++) @@ -1042,10 +1041,9 @@ fz_text_analysis_paragraph(fz_context *ctx, fz_text_sheet *sheet, fz_text_page * { /* Have we had this style before? */ int match = 0; - int span_num2; - for (span_num2 = 0; span_num2 < span_num; span_num2++) + fz_text_span *span2; + for (span2 = line->first_span; span2; span2 = span2->next) { - fz_text_span *span2 = line->spans[span_num2]; int char_num2; for (char_num2 = 0; char_num2 < span2->len; char_num2++) { @@ -1059,7 +1057,7 @@ fz_text_analysis_paragraph(fz_context *ctx, fz_text_sheet *sheet, fz_text_page * } if (char_num > 0 && match == 0) { - fz_text_span *span2 = line->spans[span_num]; + fz_text_span *span2 = span; int char_num2; for (char_num2 = 0; char_num2 < char_num; char_num2++) { @@ -1101,7 +1099,6 @@ list_entry: /* For every style in the line, check to see if lineheight * is correct for that style. FIXME: We check each style * more than once, currently. */ - int span_num; int ok = 0; /* -1 = early exit, split now. 0 = split. 1 = don't split. */ fz_text_style *style = NULL; line = &block->lines[line_num]; @@ -1112,12 +1109,11 @@ list_entry: #ifdef DEBUG_LINE_HEIGHTS printf("line height=%g nspans=%d\n", line->distance, line->len); #endif - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; int char_num; - if (is_list_entry(span, &char_num, span_num)) + if (is_list_entry(line, span, &char_num)) goto force_paragraph; /* Now we do the rest of the line */ @@ -1164,6 +1160,7 @@ force_paragraph: * Otherwise split into tables. */ rms = new_region_masks(ctx); + /* Step 1: Form the region masks and store them into a list with the * normalised baseline vectors. */ for (block_num = 0; block_num < page->len; block_num++) @@ -1178,29 +1175,26 @@ force_paragraph: { fz_point blv; region_mask *rm; - int span_num; #ifdef DEBUG_MASKS printf("Line: "); dump_line(line); #endif - blv = line->spans[0]->max; - blv.x -= line->spans[0]->min.x; - blv.y -= line->spans[0]->min.y; + blv = line->first_span->max; + blv.x -= line->first_span->min.x; + blv.y -= line->first_span->min.y; fz_normalize_vector(&blv); rm = new_region_mask(ctx, &blv); - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; fz_point *region_min = &span->min; fz_point *region_max = &span->max; /* Treat adjacent spans as one big region */ - while (span_num+1 < line->len && line->spans[span_num+1]->spacing < 1.5) + while (span->next && span->next->spacing < 1.5) { - span_num++; - span = line->spans[span_num]; + span = span->next; region_max = &span->max; } @@ -1266,29 +1260,26 @@ force_paragraph: { fz_point blv; region_mask *rm; - int span_num; region_mask *match; - blv = line->spans[0]->max; - blv.x -= line->spans[0]->min.x; - blv.y -= line->spans[0]->min.y; + blv = line->first_span->max; + blv.x -= line->first_span->min.x; + blv.y -= line->first_span->min.y; fz_normalize_vector(&blv); #ifdef DEBUG_MASKS dump_line(line); #endif rm = new_region_mask(ctx, &blv); - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; fz_point *region_min = &span->min; fz_point *region_max = &span->max; /* Treat adjacent spans as one big region */ - while (span_num+1 < line->len && line->spans[span_num+1]->spacing < 1.5) + while (span->next && span->next->spacing < 1.5) { - span_num++; - span = line->spans[span_num]; + span = span->next; region_max = &span->max; } @@ -1305,24 +1296,24 @@ force_paragraph: dump_region_mask(match); #endif free_region_mask(rm); - for (span_num = 0; span_num < line->len; ) + span = line->first_span; + while (span) { - fz_text_span *span = line->spans[span_num]; fz_point *region_min = &span->min; fz_point *region_max = &span->max; - int sn; + fz_text_span *sn; int col, align; float colw, left; /* Treat adjacent spans as one big region */ #ifdef DEBUG_ALIGN - dump_span(line->spans[span_num]); + dump_span(span); #endif - for (sn = span_num+1; sn < line->len && line->spans[sn]->spacing < 1.5; sn++) + for (sn = span->next; sn && sn->spacing < 1.5; sn = sn->next) { - region_max = &line->spans[sn]->max; + region_max = &sn->max; #ifdef DEBUG_ALIGN - dump_span(line->spans[sn]); + dump_span(sn); #endif } col = region_mask_column(match, region_min, region_max, &align, &colw, &left); @@ -1331,13 +1322,16 @@ force_paragraph: #endif do { - line->spans[span_num]->column = col; - line->spans[span_num]->align = align; - line->spans[span_num]->indent = left; - line->spans[span_num]->column_width = colw; - span_num++; + span->column = col; + span->align = align; + span->indent = left; + span->column_width = colw; + span = span->next; } - while (span_num < sn); + while (span != sn); + + if (span) + span = span->next; } line->region = match; } @@ -1351,7 +1345,6 @@ force_paragraph: { int line_num; int prev_line_num; - int last_from = -1; fz_text_block *block; @@ -1364,125 +1357,126 @@ force_paragraph: { fz_text_line *prev_line; line = &block->lines[line_num]; - if (line->len == 0) + if (!line->first_span) continue; prev_line = &block->lines[prev_line_num]; if (prev_line->region == line->region) { - int in1, in2, newlen, i, col; - float indent; - /* We only merge lines if the second line * only uses 1 of the columns. */ - col = line->spans[0]->column; + int col = line->first_span->column; /* Copy the left value for the first span * in the first column in this line forward * for all the rest of the spans in the same * column. */ - indent = line->spans[0]->indent; - for (i = 1; i < line->len; i++) + float indent = line->first_span->indent; + for (span = line->first_span->next; span; span = span->next) { - if (col != line->spans[i]->column) + if (col != span->column) break; - line->spans[i]->indent = indent; + span->indent = indent; } - if (i != line->len) + if (span) { prev_line_num = line_num; continue; } /* Merge line into prev_line */ - newlen = prev_line->len + line->len; - if (newlen > prev_line->cap) - { - int newcap = prev_line->cap ? prev_line->cap : 2; - do - { - newcap *= 2; - } - while (newcap < newlen); - - prev_line->spans = fz_resize_array(ctx, prev_line->spans, newcap, sizeof(*prev_line->spans)); - prev_line->cap = newcap; - } - - in1 = prev_line->len-1; - in2 = line->len-1; - prev_line->len = newlen; - for (; in1 >= 0 || in2 >= 0; ) { - newlen--; - if (in1 < 0 || (in2 >= 0 && line->spans[in2]->column >= prev_line->spans[in1]->column)) - { - prev_line->spans[newlen] = line->spans[in2]; - in2--; - last_from = 1; - } - else + fz_text_span **prev_line_span = &prev_line->first_span; + int try_dehyphen = -1; + fz_text_span *prev_span = NULL; + span = line->first_span; + while (span) { - prev_line->spans[newlen] = prev_line->spans[in1]; - in1--; - if (last_from == 1) + /* Skip forwards through the original + * line, until we find a place where + * span should go. */ + if ((*prev_line_span)->column <= span->column) + { + /* The current span we are considering + * in prev_line is earlier than span. + * Just skip forwards in prev_line. */ + prev_span = (*prev_line_span); + prev_line_span = &prev_span->next; + try_dehyphen = span->column; + } + else { - prev_line->spans[newlen+1]->spacing = 1; - dehyphenate(prev_line->spans[newlen], prev_line->spans[newlen+1]); - last_from = 0; + /* We want to copy span into prev_line. */ + fz_text_span *next = (*prev_line_span)->next; + + if (prev_line_span == &prev_line->first_span) + prev_line->first_span = span; + if (next == NULL) + prev_line->last_span = span; + if (try_dehyphen == span->column) + dehyphenate(prev_span, span); + try_dehyphen = -1; + prev_span = *prev_line_span = span; + span = span->next; + (*prev_line_span)->next = next; + prev_line_span = &span->next; } } + while (span || *prev_line_span); + line->first_span = NULL; + line->last_span = NULL; } - - /* Leave line empty */ - line->len = 0; } else prev_line_num = line_num; } + /* Now get rid of the empty lines */ for (prev_line_num = 0, line_num = 0; line_num < block->len; line_num++) { line = &block->lines[line_num]; - if (line->len == 0) - fz_free(ctx, line->spans); - else + if (line->first_span) block->lines[prev_line_num++] = *line; } block->len = prev_line_num; + /* Now try to spot indents */ for (line_num = 0; line_num < block->len; line_num++) { - int span_num, sn, col; + fz_text_span *span_num, *sn; + int col, count; line = &block->lines[line_num]; + /* Run through the spans... */ - span_num = 0; + span_num = line->first_span; { float indent = 0; /* For each set of spans that share the same * column... */ - col = line->spans[span_num]->column; + col = span_num->column; #ifdef DEBUG_INDENTS - printf("Indent %g: ", line->spans[span_num]->indent); - dump_span(line->spans[span_num]); + printf("Indent %g: ", span_num->indent); + dump_span(span_num); printf("\n"); #endif + /* find the average indent of all but the first.. */ - for (sn = span_num+1; sn < line->len && line->spans[sn]->column == col; sn++) + for (sn = span_num->next, count = 0; sn && sn->column == col; sn = sn->next, count++) { #ifdef DEBUG_INDENTS - printf("Indent %g: ", line->spans[sn]->indent); - dump_span(line->spans[sn]); + printf("Indent %g: ", sn->indent); + dump_span(sn); printf("\n"); #endif - indent += line->spans[sn]->indent; - line->spans[sn]->indent = 0; + indent += sn->indent; + sn->indent = 0; } - if (sn > span_num+1) - indent /= sn-(span_num+1); + if (sn != span_num->next) + indent /= count; + /* And compare this indent with the first one... */ #ifdef DEBUG_INDENTS printf("Average indent %g ", indent); #endif - indent -= line->spans[span_num]->indent; + indent -= span_num->indent; #ifdef DEBUG_INDENTS printf("delta %g ", indent); #endif @@ -1494,12 +1488,12 @@ force_paragraph: #ifdef DEBUG_INDENTS printf("recorded %g\n", indent); #endif - line->spans[span_num]->indent = indent; + span_num->indent = indent; span_num = sn; } - for (; span_num < line->len; span_num++) + for (; span_num; span_num = span_num->next) { - line->spans[span_num]->indent = 0; + span_num->indent = 0; } } } diff --git a/fitz/text_search.c b/fitz/text_search.c index 2d4233c2..7952caf8 100644 --- a/fitz/text_search.c +++ b/fitz/text_search.c @@ -14,19 +14,18 @@ fz_char_and_box *fz_text_char_at(fz_char_and_box *cab, fz_text_page *page, int i for (block_num = 0; block_num < page->len; block_num++) { + fz_text_block *block; fz_text_line *line; + fz_text_span *span; int ofs = 0; - fz_text_block *block; if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT) continue; block = page->blocks[block_num].u.text; for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; if (idx < ofs + span->len) { cab->c = span->text[idx - ofs].c; @@ -73,16 +72,15 @@ static int textlen(fz_text_page *page) { fz_text_block *block; fz_text_line *line; + fz_text_span *span; if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT) continue; block = page->blocks[block_num].u.text; for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; len += span->len; } len++; /* pseudo-newline */ @@ -161,6 +159,7 @@ fz_highlight_selection(fz_context *ctx, fz_text_page *page, fz_rect rect, fz_rec fz_rect linebox, charbox; fz_text_block *block; fz_text_line *line; + fz_text_span *span; int i, block_num, hit_count; float x0 = rect.x0; @@ -177,11 +176,9 @@ fz_highlight_selection(fz_context *ctx, fz_text_page *page, fz_rect rect, fz_rec block = page->blocks[block_num].u.text; for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; linebox = fz_empty_rect; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; for (i = 0; i < span->len; i++) { fz_text_char_bbox(&charbox, span, i); @@ -227,16 +224,15 @@ fz_copy_selection(fz_context *ctx, fz_text_page *page, fz_rect rect) { fz_text_block *block; fz_text_line *line; + fz_text_span *span; if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT) continue; block = page->blocks[block_num].u.text; for (line = block->lines; line < block->lines + block->len; line++) { - int span_num; - for (span_num = 0; span_num < line->len; span_num++) + for (span = line->first_span; span; span = span->next) { - fz_text_span *span = line->spans[span_num]; if (seen) { fz_write_buffer_byte(ctx, buffer, '\n'); @@ -257,7 +253,7 @@ fz_copy_selection(fz_context *ctx, fz_text_page *page, fz_rect rect) } } - seen = (seen && span_num + 1 == line->len); + seen = (seen && span == line->last_span); } } } |