+ /*
+ * XXX: I assume that the in-margin print won't exceed
+ * PS_BUFSLOP (128 bytes), which is reasonable but still an
+ * assumption that will cause pukeage if it's not the case.
+ */
+
+ PS_GROWBUF(p, PS_BUFSLOP);
+
+ pos = (int)p->engine.ps.psmargcur;
+ len = vsnprintf(&p->engine.ps.psmarg[pos], PS_BUFSLOP, fmt, ap);
+
+ va_end(ap);
+
+ p->engine.ps.psmargcur = strlen(p->engine.ps.psmarg);
+ p->engine.ps.pdfbytes += /* LINTED */
+ len < 0 ? 0 : (size_t)len;
+}
+
+
+static void
+ps_putchar(struct termp *p, char c)
+{
+ int pos;
+
+ /* See ps_printf(). */
+
+ if ( ! (PS_MARGINS & p->engine.ps.flags)) {
+ putchar(c);
+ p->engine.ps.pdfbytes++;
+ return;
+ }
+
+ PS_GROWBUF(p, 2);
+
+ pos = (int)p->engine.ps.psmargcur++;
+ p->engine.ps.psmarg[pos++] = c;
+ p->engine.ps.psmarg[pos] = '\0';
+}
+
+
+static void
+ps_closepage(struct termp *p)
+{
+ int i;
+ size_t len;
+
+ assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]);
+ ps_printf(p, "%s", p->engine.ps.psmarg);
+
+ if (TERMTYPE_PS == p->type) {
+ ps_printf(p, "showpage\n");
+ } else {
+ ps_printf(p, "ET\n");
+ len = p->engine.ps.pdfbytes - p->engine.ps.pdflastpg;
+ ps_printf(p, "endstream\n");
+ ps_printf(p, "endobj\n");
+ ps_printf(p, "%zu 0 obj\n",
+ p->engine.ps.pdfbody +
+ (p->engine.ps.pages + 1) * 4 + 1);
+ ps_printf(p, "%zu\n", len);
+ ps_printf(p, "endobj\n");
+ ps_printf(p, "%zu 0 obj\n",
+ p->engine.ps.pdfbody +
+ (p->engine.ps.pages + 1) * 4 + 2);
+ ps_printf(p, "<<\n");
+ ps_printf(p, "/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");
+ ps_printf(p, ">>\n");
+ ps_printf(p, "%zu 0 obj\n",
+ p->engine.ps.pdfbody +
+ (p->engine.ps.pages + 1) * 4 + 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",
+ p->engine.ps.pdfbody +
+ (p->engine.ps.pages + 1) * 4 + 2);
+ ps_printf(p, "/Contents %zu 0 R\n",
+ p->engine.ps.pdfbody +
+ (p->engine.ps.pages + 1) * 4);
+ ps_printf(p, ">>\n");
+ ps_printf(p, "endobj\n");
+ }
+
+ p->engine.ps.pages++;
+ p->engine.ps.psrow = p->engine.ps.top;
+ assert( ! (PS_NEWPAGE & p->engine.ps.flags));
+ p->engine.ps.flags |= PS_NEWPAGE;