Example #1
0
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;
				}
			}
		}
	}
}
Example #2
0
/*!
  \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;
}