Пример #1
0
/*
 * Add a range.
 */
static void
add_range(fz_context *ctx, pdf_cmap *cmap, int low, int high, int flag, int offset)
{
    /* Sanity check ranges */
    if (low < 0 || low > 65535 || high < 0 || high > 65535 || low > high)
    {
        fz_warn(ctx, "range limits out of range in cmap %s", cmap->cmap_name);
        return;
    }
    /* If the range is too large to be represented, split it */
    if (high - low > 0x3fff)
    {
        add_range(ctx, cmap, low, low+0x3fff, flag, offset);
        add_range(ctx, cmap, low+0x3fff, high, flag, offset+0x3fff);
        return;
    }
    if (cmap->rlen + 1 > cmap->rcap)
    {
        int new_cap = cmap->rcap > 1 ? (cmap->rcap * 3) / 2 : 256;
        cmap->ranges = fz_resize_array(ctx, cmap->ranges, new_cap, sizeof(pdf_range));
        cmap->rcap = new_cap;
    }
    cmap->ranges[cmap->rlen].low = low;
    pdf_range_set_high(&cmap->ranges[cmap->rlen], high);
    pdf_range_set_flags(&cmap->ranges[cmap->rlen], flag);
    cmap->ranges[cmap->rlen].offset = offset;
    cmap->rlen ++;
}
Пример #2
0
/*
 * Add a range.
 */
static void
add_range(fz_context *ctx, pdf_cmap *cmap, int low, int high, int flag, int offset)
{
	/* If the range is too large to be represented, split it */
	if (high - low > 0x3fff)
	{
		add_range(ctx, cmap, low, low+0x3fff, flag, offset);
		add_range(ctx, cmap, low+0x3fff, high, flag, offset+0x3fff);
		return;
	}
	if (cmap->rlen + 1 > cmap->rcap)
	{
		cmap->rcap = cmap->rcap > 1 ? (cmap->rcap * 3) / 2 : 256;
		cmap->ranges = fz_resize_array(ctx, cmap->ranges, cmap->rcap, sizeof(pdf_range));
	}
	cmap->ranges[cmap->rlen].low = low;
	pdf_range_set_high(&cmap->ranges[cmap->rlen], high);
	pdf_range_set_flags(&cmap->ranges[cmap->rlen], flag);
	cmap->ranges[cmap->rlen].offset = offset;
	cmap->rlen ++;
}
Пример #3
0
void
pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap)
{
	pdf_range *a;			/* last written range on output */
	pdf_range *b;			/* current range examined on input */

	if (cmap->rlen == 0)
		return;

	qsort(cmap->ranges, cmap->rlen, sizeof(pdf_range), cmprange);

	if (cmap->tlen == USHRT_MAX)
	{
		fz_warn(ctx, "cmap table is full; will not combine ranges");
		return;
	}

	a = cmap->ranges;
	b = cmap->ranges + 1;

	while (b < cmap->ranges + cmap->rlen)
	{
		/* ignore one-to-many mappings */
		if (pdf_range_flags(b) == PDF_CMAP_MULTI)
		{
			*(++a) = *b;
		}

		/* input contiguous */
		else if (pdf_range_high(a) + 1 == b->low)
		{
			/* output contiguous */
			if (pdf_range_high(a) - a->low + a->offset + 1 == b->offset)
			{
				/* SR -> R and SS -> R and RR -> R and RS -> R */
				if ((pdf_range_flags(a) == PDF_CMAP_SINGLE || pdf_range_flags(a) == PDF_CMAP_RANGE) && (pdf_range_high(b) - a->low <= 0x3fff))
				{
					pdf_range_set_flags(a, PDF_CMAP_RANGE);
					pdf_range_set_high(a, pdf_range_high(b));
				}

				/* LS -> L */
				else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_SINGLE && (pdf_range_high(b) - a->low <= 0x3fff))
				{
					pdf_range_set_high(a, pdf_range_high(b));
					add_table(ctx, cmap, b->offset);
				}

				/* LR -> LR */
				else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_RANGE)
				{
					*(++a) = *b;
				}

				/* XX -> XX */
				else
				{
					*(++a) = *b;
				}
			}

			/* output separated */
			else
			{
				/* SS -> L */
				if (pdf_range_flags(a) == PDF_CMAP_SINGLE && pdf_range_flags(b) == PDF_CMAP_SINGLE)
				{
					pdf_range_set_flags(a, PDF_CMAP_TABLE);
					pdf_range_set_high(a, pdf_range_high(b));
					add_table(ctx, cmap, a->offset);
					add_table(ctx, cmap, b->offset);
					a->offset = cmap->tlen - 2;
				}

				/* LS -> L */
				else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_SINGLE && (pdf_range_high(b) - a->low <= 0x3fff))
				{
					pdf_range_set_high(a, pdf_range_high(b));
					add_table(ctx, cmap, b->offset);
				}

				/* XX -> XX */
				else
				{
					*(++a) = *b;
				}
			}
		}

		/* input separated: XX -> XX */
		else
		{
			*(++a) = *b;
		}

		b ++;
	}

	cmap->rlen = a - cmap->ranges + 1;
}