static void fixup_text_block(fz_context *ctx, fz_text_block *block) { fz_text_line *line; fz_text_span *span; int i; /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=734 */ /* remove duplicate character sequences in (almost) the same spot */ for (line = block->lines; line < block->lines + block->len; line++) { for (span = line->spans; span < line->spans + line->len; span++) { if (span->style && span->style->size < 5) /* do_glyphs_overlap fails too often for small fonts */ continue; for (i = 0; i < span->len; i++) { fz_text_span *span2 = span; fz_text_line *line2 = line; int j = i + 1; for (; span2 <= line2->spans + line2->len; span2++, j = 0) { if (span2 == line2->spans + line2->len) { if (line2 + 1 == block->lines + block->len || line2 != line) break; span2 = (++line2)->spans; } for (; j < span2->len; j++) { int c = span->text[i].c; if (c != 32 && c == span2->text[j].c && do_glyphs_overlap(span, i, span2, j, 1)) goto fixup_delete_duplicates; } } continue; fixup_delete_duplicates: do { delete_character(span, i); if (span != span2) j++; } while (do_glyphs_overlap(span, i, span2, j, 0)); if (i < span->len && span->text[i].c == 32) delete_character(span, i); else if (i == span->len && span == line->spans + line->len - 1) { int len = line->len; merge_lines(ctx, block, line); span = line->spans + len - 1; } } } } }
/*! \brief Merge lines/boundaries At least two lines need to be given. \param Map pointer to Map_info \param List list of selected lines \return number of merged lines \return -1 on error */ int Vedit_merge_lines(struct Map_info *Map, struct ilist *List) { struct ilist *List_in_box; struct line_pnts *Points1, *Points2, *Points; struct line_cats *Cats1, *Cats2; int line_i, i, j; int line, line1, type1, line2; int do_merge; /* number of lines (original, selected, merged) */ int nlines, nlines_merged; nlines_merged = 0; if (List->n_values < 2) { return 0; } Points1 = Vect_new_line_struct(); Cats1 = Vect_new_cats_struct(); Points2 = Vect_new_line_struct(); Cats2 = Vect_new_cats_struct(); Points = Vect_new_line_struct(); List_in_box = Vect_new_list(); nlines = Vect_get_num_lines(Map); /* merge lines */ for (line_i = 0; line_i < List->n_values; line_i++) { line1 = List->value[line_i]; if (!Vect_line_alive(Map, line1)) continue; type1 = Vect_read_line(Map, Points1, Cats1, line1); if (!(type1 & GV_LINES)) continue; Vect_reset_line(Points); for (i = 0; i < Points1->n_points; i += Points1->n_points - 1) { Vect_reset_list(List_in_box); /* define searching region */ Vect_reset_line(Points2); /* Vect_append_point (Points2, Points1 -> x[i] - thresh, Points1 -> y[i] + thresh, Points1 -> z[i]); Vect_append_point (Points2, Points1 -> x[i] + thresh, Points1 -> y[i] + thresh, Points1 -> z[i]); Vect_append_point (Points2, Points1 -> x[i] + thresh, Points1 -> y[i] - thresh, Points1 -> z[i]); Vect_append_point (Points2, Points1 -> x[i] - thresh, Points1 -> y[i] - thresh, Points1 -> z[i]); */ Vect_append_point(Points2, Points1->x[i], Points1->y[i], Points1->z[i]); /* * merge lines only if two lines found in the region * i.e. the current line and an adjacent line */ if (1 < Vect_select_lines_by_polygon(Map, Points2, 0, NULL, GV_LINES, List_in_box)) { do_merge = 1; line2 = -1; for (j = 0; do_merge && j < List->n_values; j++) { if (List->value[j] == line1 || !Vect_line_alive(Map, List->value[j])) continue; if (Vect_val_in_list(List_in_box, List->value[j])) { if (line2 > 0) { /* three lines found * selected lines will be not merged */ do_merge = 0; } else { line2 = List->value[j]; } } } if (!do_merge || line2 < 0) continue; Vect_read_line(Map, Points2, Cats2, line2); merge_lines(Points1, Cats1, Points2, Cats2, -1.0, &Points); /* do not use threshold value */ G_debug(3, "Vedit_merge_lines(): lines=%d,%d", line1, line2); if (Points->n_points > 0) { if (Vect_delete_line(Map, line2) == -1) { return -1; } if (line2 <= nlines) nlines_merged++; } } } /* for each node */ if (Points->n_points > 0) { line = Vect_rewrite_line(Map, line1, type1, Points, Cats1); if (line < 0) { return -1; } if (line1 <= nlines) nlines_merged++; /* update number of lines */ Vect_list_append(List, line); } } /* for each line */ /* destroy stuctures */ Vect_destroy_line_struct(Points1); Vect_destroy_line_struct(Points2); Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats1); Vect_destroy_cats_struct(Cats2); return nlines_merged; }