Ejemplo n.º 1
0
/*
 * Load predefined CMap from system.
 */
fz_error
pdf_loadsystemcmap(pdf_cmap **cmapp, char *cmapname)
{
	fz_error error;
	fz_stream *stream;
	pdf_cmap *usecmap;
	pdf_cmap *cmap;
	unsigned char *data;
	unsigned int len;
	int i;

	pdf_logfont("loading system cmap %s\n", cmapname);

	error = pdf_getcmapbuffer(cmapname, &data, &len);
	if(error)
		return fz_rethrow(error, "no builtin cmap file: %s", cmapname);

	stream = fz_openrmemory(data, len);
	error = pdf_parsecmap(&cmap, stream);
	fz_dropstream(stream);
	if(error)
		return fz_rethrow(error, "cannot parse cmap data");

	if (cmap->usecmapname[0] && !cmap->usecmap)
	{
		pdf_logfont("charmap depends on other charmap (%s), loading it\n", cmap->usecmapname);
		error = pdf_loadsystemcmap(&usecmap, cmap->usecmapname);
		if (error)
			return fz_rethrow(error, "could not load usecmap: %s", cmap->usecmapname);
		pdf_setusecmap(cmap, usecmap);
	}

	*cmapp = cmap;
	return fz_okay;
}
/*
 * Load CMap stream in PDF file
 */
fz_error
pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
{
    fz_error error = fz_okay;
    fz_obj *stmobj;
    fz_stream *file = nil;
    pdf_cmap *cmap = nil;
    pdf_cmap *usecmap;
    fz_obj *wmode;
    fz_obj *obj;

    if ((*cmapp = pdf_finditem(xref->store, PDF_KCMAP, stmref)))
    {
	pdf_keepcmap(*cmapp);
	return fz_okay;
    }

    pdf_logfont("load embedded cmap (%d %d R) {\n", fz_tonum(stmref), fz_togen(stmref));

    stmobj = fz_resolveindirect(stmref);

    error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref));
    if (error)
    {
	error = fz_rethrow(error, "cannot open cmap stream");
	goto cleanup;
    }

    error = pdf_parsecmap(&cmap, file);
    if (error)
    {
	error = fz_rethrow(error, "cannot parse cmap stream");
	goto cleanup;
    }

    fz_dropstream(file);

    wmode = fz_dictgets(stmobj, "WMode");
    if (fz_isint(wmode))
    {
	pdf_logfont("wmode %d\n", wmode);
	pdf_setwmode(cmap, fz_toint(wmode));
    }

    obj = fz_dictgets(stmobj, "UseCMap");
    if (fz_isname(obj))
    {
	pdf_logfont("usecmap /%s\n", fz_toname(obj));
	error = pdf_loadsystemcmap(&usecmap, fz_toname(obj));
	if (error)
	{
	    error = fz_rethrow(error, "cannot load system usecmap '%s'", fz_toname(obj));
	    goto cleanup;
	}
	pdf_setusecmap(cmap, usecmap);
	pdf_dropcmap(usecmap);
    }
    else if (fz_isindirect(obj))
    {
	pdf_logfont("usecmap (%d %d R)\n", fz_tonum(obj), fz_togen(obj));
	error = pdf_loadembeddedcmap(&usecmap, xref, obj);
	if (error)
	{
	    error = fz_rethrow(error, "cannot load embedded usecmap");
	    goto cleanup;
	}
	pdf_setusecmap(cmap, usecmap);
	pdf_dropcmap(usecmap);
    }

    pdf_logfont("}\n");

    error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap);
    if (error)
    {
	error = fz_rethrow(error, "cannot store cmap resource");
	goto cleanup;
    }

    *cmapp = cmap;
    return fz_okay;

cleanup:
    if (file)
	fz_dropstream(file);
    if (cmap)
	pdf_dropcmap(cmap);
    return error; /* already rethrown */
}
Ejemplo n.º 3
0
int
main(int argc, char **argv)
{
	pdf_cmap *cmap;
	fz_error error;
	fz_stream *fi;
	FILE *fo;
	char name[256];
	char *realname;
	int i, k;
	int fd;

	if (argc < 3)
	{
		fprintf(stderr, "usage: cmapdump output.c lots of cmap files\n");
		return 1;
	}

	fo = fopen(argv[1], "wb");
	if (!fo)
	{
		fprintf(stderr, "cmapdump: could not open output file '%s'\n", argv[1]);
		return 1;
	}

	fprintf(fo, "#include \"fitz.h\"\n");
	fprintf(fo, "#include \"mupdf.h\"\n");
	fprintf(fo, "\n");

	for (i = 2; i < argc; i++)
	{
		realname = strrchr(argv[i], '/');
		if (!realname)
			realname = strrchr(argv[i], '\\');
		if (realname)
			realname ++;
		else
			realname = argv[i];

		if (strlen(realname) > (sizeof name - 1))
		{
			fprintf(stderr, "cmapdump: file name too long\n");
			return 1;
		}

		strcpy(name, realname);
		clean(name);

		fd = open(argv[i], O_BINARY | O_RDONLY, 0666);
		if (fd < 0)
		{
			fz_throw("cmapdump: could not open input file '%s'\n", argv[i]);
			return 1;
		}

		fi = fz_openfile(fd);

		error = pdf_parsecmap(&cmap, fi);
		if (error)
		{
			fz_catch(error, "cmapdump: could not parse input cmap '%s'\n", argv[i]);
			return 1;
		}

		fprintf(fo, "/* %s */\n\n", cmap->cmapname);

		fprintf(fo, "static const pdf_range pdf_cmap_%s_ranges[] =\n{\n", name);
		if (cmap->rlen == 0)
		{
			fprintf(fo, "\t/* dummy entry for non-c99 compilers */\n");
			fprintf(fo, "\t{ 0x0, %d, 0 }\n", PDF_CMAP_RANGE);
		}
		for (k = 0; k < cmap->rlen; k++)
		{
			fprintf(fo, "\t{ 0x%04x, 0x%04x, %d },\n",
				cmap->ranges[k].low, cmap->ranges[k].extentflags, cmap->ranges[k].offset);
		}
		fprintf(fo, "};\n\n");

		if (cmap->tlen == 0)
		{
			fprintf(fo, "static const unsigned short pdf_cmap_%s_table[1] = { 0 };\n\n", name);
		}
		else
		{
			fprintf(fo, "static const unsigned short pdf_cmap_%s_table[%d] =\n{",
				name, cmap->tlen);
			for (k = 0; k < cmap->tlen; k++)
			{
				if (k % 8 == 0)
					fprintf(fo, "\n\t");
				fprintf(fo, "%d,", cmap->table[k]);
			}
			fprintf(fo, "\n};\n\n");
		}

		fprintf(fo, "pdf_cmap pdf_cmap_%s =\n", name);
		fprintf(fo, "{\n");
		fprintf(fo, "\t-1, ");
		fprintf(fo, "\"%s\", ", cmap->cmapname);
		fprintf(fo, "\"%s\", nil, ", cmap->usecmapname);
		fprintf(fo, "%d,\n", cmap->wmode);

		fprintf(fo, "\t%d, /* codespace table */\n", cmap->ncspace);
		fprintf(fo, "\t{\n");

		if (cmap->ncspace == 0)
		{
			fprintf(fo, "\t/* dummy entry for non-c99 compilers */\n");
			fprintf(fo, "\t{ 0, 0x0, 0x0 },\n");
		}
		for (k = 0; k < cmap->ncspace; k++)
		{
			fprintf(fo, "\t\t{ %d, 0x%04x, 0x%04x },\n",
				cmap->cspace[k].n, cmap->cspace[k].low, cmap->cspace[k].high);
		}
		fprintf(fo, "\t},\n");

		fprintf(fo, "\t%d, %d, (pdf_range*) pdf_cmap_%s_ranges,\n",
			cmap->rlen, cmap->rlen, name);

		fprintf(fo, "\t%d, %d, (unsigned short*) pdf_cmap_%s_table,\n",
			cmap->tlen, cmap->tlen, name);

		fprintf(fo, "};\n\n");

		fz_close(fi);
	}

	if (fclose(fo))
	{
		fprintf(stderr, "cmapdump: could not close output file '%s'\n", argv[1]);
		return 1;
	}

	return 0;
}