summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-04-30 12:39:26 +0200
committerRobin Watts <robin.watts@artifex.com>2013-05-06 12:04:47 +0100
commit4048032f4a2226f3b54a68840dac39440c5428aa (patch)
tree2111c7360fa3b185e8a8ae22b772479437fb9890
parent2234da7e8f30720467e05b14b578c8f3a082b75a (diff)
downloadmupdf-4048032f4a2226f3b54a68840dac39440c5428aa.tar.xz
Use linked list for text spans.
-rw-r--r--apps/pdfapp.c12
-rw-r--r--fitz/fitz.h5
-rw-r--r--fitz/text_extract.c40
-rw-r--r--fitz/text_output.c22
-rw-r--r--fitz/text_paragraph.c214
-rw-r--r--fitz/text_search.c24
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);
}
}
}