コード例 #1
0
ファイル: term_ps.c プロジェクト: StarchLinux/mandoc
static void
ps_closepage(struct termp *p)
{
	int		 i;
	size_t		 len, base;

	/*
	 * Close out a page that we've already flushed to output.  In
	 * PostScript, we simply note that the page must be showed.  In
	 * PDF, we must now create the Length, Resource, and Page node
	 * for the page contents.
	 */

	assert(p->ps->psmarg && p->ps->psmarg[0]);
	ps_printf(p, "%s", p->ps->psmarg);

	if (TERMTYPE_PS != p->type) {
		ps_printf(p, "ET\n");

		len = p->ps->pdfbytes - p->ps->pdflastpg;
		base = p->ps->pages * 4 + p->ps->pdfbody;

		ps_printf(p, "endstream\nendobj\n");

		/* Length of content. */
		pdf_obj(p, base + 1);
		ps_printf(p, "%zu\nendobj\n", len);

		/* Resource for content. */
		pdf_obj(p, base + 2);
		ps_printf(p, "<<\n/ProcSet [/PDF /Text]\n");
		ps_printf(p, "/Font <<\n");
		for (i = 0; i < (int)TERMFONT__MAX; i++) 
			ps_printf(p, "/F%d %d 0 R\n", i, 3 + i);
		ps_printf(p, ">>\n>>\n");

		/* Page node. */
		pdf_obj(p, base + 3);
		ps_printf(p, "<<\n");
		ps_printf(p, "/Type /Page\n");
		ps_printf(p, "/Parent 2 0 R\n");
		ps_printf(p, "/Resources %zu 0 R\n", base + 2);
		ps_printf(p, "/Contents %zu 0 R\n", base);
		ps_printf(p, ">>\nendobj\n");
	} else
		ps_printf(p, "showpage\n");

	p->ps->pages++;
	p->ps->psrow = p->ps->top;
	assert( ! (PS_NEWPAGE & p->ps->flags));
	p->ps->flags |= PS_NEWPAGE;
}
コード例 #2
0
ファイル: pdfext.c プロジェクト: litcave/neatpost
/* read and dereference an indirect reference */
int pdf_ref(char *pdf, int len, int pos)
{
	int obj, rev;
	if (pdf_obj(pdf, len, pos, &obj, &rev))
		return -1;
	return pdf_find(pdf, len, obj, rev);
}
コード例 #3
0
ファイル: pdfext.c プロジェクト: litcave/neatpost
/* retrieve and dereference a dictionary entry */
int pdf_dval_val(char *pdf, int len, int pos, char *key)
{
	int val = pdf_dval(pdf, len, pos, key);
	int val_obj, val_rev;
	if (val < 0)
		return -1;
	if (pdf_type(pdf, len, val) == 'r') {
		pdf_obj(pdf, len, val, &val_obj, &val_rev);
		return pdf_find(pdf, len, val_obj, val_rev);
	}
	return val;
}
コード例 #4
0
ファイル: term_ps.c プロジェクト: StarchLinux/mandoc
static void
ps_pletter(struct termp *p, int c)
{
	int		 f;

	/*
	 * If we haven't opened a page context, then output that we're
	 * in a new page and make sure the font is correctly set.
	 */

	if (PS_NEWPAGE & p->ps->flags) {
		if (TERMTYPE_PS == p->type) {
			ps_printf(p, "%%%%Page: %zu %zu\n", 
					p->ps->pages + 1, 
					p->ps->pages + 1);
			ps_printf(p, "/%s %zu selectfont\n", 
					fonts[(int)p->ps->lastf].name, 
					p->ps->scale);
		} else {
			pdf_obj(p, p->ps->pdfbody + 
					p->ps->pages * 4);
			ps_printf(p, "<<\n");
			ps_printf(p, "/Length %zu 0 R\n", 
					p->ps->pdfbody + 1 +
					p->ps->pages * 4);
			ps_printf(p, ">>\nstream\n");
		}
		p->ps->pdflastpg = p->ps->pdfbytes;
		p->ps->flags &= ~PS_NEWPAGE;
	}
	
	/*
	 * If we're not in a PostScript "word" context, then open one
	 * now at the current cursor.
	 */

	if ( ! (PS_INLINE & p->ps->flags)) {
		if (TERMTYPE_PS != p->type) {
			ps_printf(p, "BT\n/F%d %zu Tf\n", 
					(int)p->ps->lastf,
					p->ps->scale);
			ps_printf(p, "%.3f %.3f Td\n(",
					AFM2PNT(p, p->ps->pscol),
					AFM2PNT(p, p->ps->psrow));
		} else
			ps_printf(p, "%.3f %.3f moveto\n(", 
					AFM2PNT(p, p->ps->pscol),
					AFM2PNT(p, p->ps->psrow));
		p->ps->flags |= PS_INLINE;
	}

	assert( ! (PS_NEWPAGE & p->ps->flags));

	/*
	 * We need to escape these characters as per the PostScript
	 * specification.  We would also escape non-graphable characters
	 * (like tabs), but none of them would get to this point and
	 * it's superfluous to abort() on them.
	 */

	switch (c) {
	case ('('):
		/* FALLTHROUGH */
	case (')'):
		/* FALLTHROUGH */
	case ('\\'):
		ps_putchar(p, '\\');
		break;
	default:
		break;
	}

	/* Write the character and adjust where we are on the page. */

	f = (int)p->ps->lastf;

	if (c <= 32 || (c - 32 >= MAXCHAR)) {
		ps_putchar(p, ' ');
		p->ps->pscol += (size_t)fonts[f].gly[0].wx;
		return;
	} 

	ps_putchar(p, (char)c);
	c -= 32;
	p->ps->pscol += (size_t)fonts[f].gly[c].wx;
}
コード例 #5
0
ファイル: term_ps.c プロジェクト: StarchLinux/mandoc
static void
ps_begin(struct termp *p)
{
	time_t		 t;
	int		 i;

	/* 
	 * Print margins into margin buffer.  Nothing gets output to the
	 * screen yet, so we don't need to initialise the primary state.
	 */

	if (p->ps->psmarg) {
		assert(p->ps->psmargsz);
		p->ps->psmarg[0] = '\0';
	}

	/*p->ps->pdfbytes = 0;*/
	p->ps->psmargcur = 0;
	p->ps->flags = PS_MARGINS;
	p->ps->pscol = p->ps->left;
	p->ps->psrow = p->ps->header;

	ps_setfont(p, TERMFONT_NONE);

	(*p->headf)(p, p->argf);
	(*p->endline)(p);

	p->ps->pscol = p->ps->left;
	p->ps->psrow = p->ps->footer;

	(*p->footf)(p, p->argf);
	(*p->endline)(p);

	p->ps->flags &= ~PS_MARGINS;

	assert(0 == p->ps->flags);
	assert(p->ps->psmarg);
	assert('\0' != p->ps->psmarg[0]);

	/* 
	 * Print header and initialise page state.  Following this,
	 * stuff gets printed to the screen, so make sure we're sane.
	 */

	t = time(NULL);

	if (TERMTYPE_PS == p->type) {
		ps_printf(p, "%%!PS-Adobe-3.0\n");
		ps_printf(p, "%%%%CreationDate: %s", ctime(&t));
		ps_printf(p, "%%%%DocumentData: Clean7Bit\n");
		ps_printf(p, "%%%%Orientation: Portrait\n");
		ps_printf(p, "%%%%Pages: (atend)\n");
		ps_printf(p, "%%%%PageOrder: Ascend\n");
		ps_printf(p, "%%%%DocumentMedia: "
				"Default %zu %zu 0 () ()\n",
				(size_t)AFM2PNT(p, p->ps->width),
				(size_t)AFM2PNT(p, p->ps->height));
		ps_printf(p, "%%%%DocumentNeededResources: font");

		for (i = 0; i < (int)TERMFONT__MAX; i++)
			ps_printf(p, " %s", fonts[i].name);

		ps_printf(p, "\n%%%%EndComments\n");
	} else {
		ps_printf(p, "%%PDF-1.1\n");
		pdf_obj(p, 1);
		ps_printf(p, "<<\n");
		ps_printf(p, ">>\n");
		ps_printf(p, "endobj\n");

		for (i = 0; i < (int)TERMFONT__MAX; i++) {
			pdf_obj(p, (size_t)i + 3);
			ps_printf(p, "<<\n");
			ps_printf(p, "/Type /Font\n");
			ps_printf(p, "/Subtype /Type1\n");
			ps_printf(p, "/Name /F%zu\n", i);
			ps_printf(p, "/BaseFont /%s\n", fonts[i].name);
			ps_printf(p, ">>\n");
		}
	}

	p->ps->pdfbody = (size_t)TERMFONT__MAX + 3;
	p->ps->pscol = p->ps->left;
	p->ps->psrow = p->ps->top;
	p->ps->flags |= PS_NEWPAGE;
	ps_setfont(p, TERMFONT_NONE);
}
コード例 #6
0
ファイル: term_ps.c プロジェクト: StarchLinux/mandoc
/* ARGSUSED */
static void
ps_end(struct termp *p)
{
	size_t		 i, xref, base;

	/*
	 * At the end of the file, do one last showpage.  This is the
	 * same behaviour as groff(1) and works for multiple pages as
	 * well as just one.
	 */

	if ( ! (PS_NEWPAGE & p->ps->flags)) {
		assert(0 == p->ps->flags);
		assert('\0' == p->ps->last);
		ps_closepage(p);
	}

	if (TERMTYPE_PS == p->type) {
		ps_printf(p, "%%%%Trailer\n");
		ps_printf(p, "%%%%Pages: %zu\n", p->ps->pages);
		ps_printf(p, "%%%%EOF\n");
		return;
	} 

	pdf_obj(p, 2);
	ps_printf(p, "<<\n/Type /Pages\n");
	ps_printf(p, "/MediaBox [0 0 %zu %zu]\n",
			(size_t)AFM2PNT(p, p->ps->width),
			(size_t)AFM2PNT(p, p->ps->height));

	ps_printf(p, "/Count %zu\n", p->ps->pages);
	ps_printf(p, "/Kids [");

	for (i = 0; i < p->ps->pages; i++)
		ps_printf(p, " %zu 0 R", i * 4 +
				p->ps->pdfbody + 3);

	base = (p->ps->pages - 1) * 4 + 
		p->ps->pdfbody + 4;

	ps_printf(p, "]\n>>\nendobj\n");
	pdf_obj(p, base);
	ps_printf(p, "<<\n");
	ps_printf(p, "/Type /Catalog\n");
	ps_printf(p, "/Pages 2 0 R\n");
	ps_printf(p, ">>\n");
	xref = p->ps->pdfbytes;
	ps_printf(p, "xref\n");
	ps_printf(p, "0 %zu\n", base + 1);
	ps_printf(p, "0000000000 65535 f \n");

	for (i = 0; i < base; i++)
		ps_printf(p, "%.10zu 00000 n \n", 
				p->ps->pdfobjs[(int)i]);

	ps_printf(p, "trailer\n");
	ps_printf(p, "<<\n");
	ps_printf(p, "/Size %zu\n", base + 1);
	ps_printf(p, "/Root %zu 0 R\n", base);
	ps_printf(p, "/Info 1 0 R\n");
	ps_printf(p, ">>\n");
	ps_printf(p, "startxref\n");
	ps_printf(p, "%zu\n", xref);
	ps_printf(p, "%%%%EOF\n");
}