summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf/pdfpage.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfpage.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c
new file mode 100644
index 00000000000..211248a02d3
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c
@@ -0,0 +1,290 @@
+/*
+
+Copyright 2006-2012 Taco Hoekwater <taco@luatex.org>
+
+This file is part of LuaTeX.
+
+LuaTeX is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License along
+with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ptexlib.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <math.h>
+
+void init_pdf_pagecalculations(PDF pdf)
+{
+ pdfstructure *p;
+ int decimal_digits = pdf->decimal_digits;
+ if (pdf->pstruct == NULL)
+ pdf->pstruct = xmalloc(sizeof(pdfstructure));
+ p = pdf->pstruct;
+ setpdffloat(p->pdf.h, 0, decimal_digits);
+ setpdffloat(p->pdf.v, 0, decimal_digits);
+ p->cw.e = 1;
+ /*tex |+ 2| makes less corrections inside []TJ */
+ p->fs_cur.e = p->fs.e = (decimal_digits < 4 ? 5 : 6);
+ /*tex for placement outside BT...ET */
+ setpdffloat(p->cm[0], 1, 0);
+ setpdffloat(p->cm[1], 0, 0);
+ setpdffloat(p->cm[2], 0, 0);
+ setpdffloat(p->cm[3], 1, 0);
+ /*tex horizontal movement on page */
+ setpdffloat(p->cm[4], 0, decimal_digits);
+ /*tex vertical movement on page */
+ setpdffloat(p->cm[5], 0, decimal_digits);
+ /*tex for placement inside BT...ET */
+ /*tex mantissa holds HZ expand * ExtendFont */
+ setpdffloat(p->tm0_cur, 0, 6);
+ /*tex mantissa holds HZ expand * ExtendFont */
+ setpdffloat(p->tm[0], ten_pow[6], 6);
+ setpdffloat(p->tm[1], 0, 0);
+ /*tex mantissa holds SlantFont, 0 = default */
+ setpdffloat(p->tm[2], 0, 3);
+ setpdffloat(p->tm[3], ten_pow[6], 6);
+ /*tex mantissa holds delta from |pdf_bt_pos.h| */
+ setpdffloat(p->tm[4], 0, decimal_digits);
+ /*tex mantissa holds delta from |pdf_bt_pos.v| */
+ setpdffloat(p->tm[5], 0, decimal_digits);
+ p->f_pdf_cur = p->f_pdf = null_font;
+ p->fs_cur.m = p->fs.m = 0;
+ p->wmode = WMODE_H;
+ p->mode = PMODE_PAGE;
+ p->ishex = 0;
+ p->need_tf = false;
+ p->need_tm = false;
+ p->done_width = false;
+ p->done_mode = false;
+ p->k1 = ten_pow[p->pdf.h.e] / by_one_bp;
+}
+
+void synch_pos_with_cur(posstructure * pos, posstructure * refpos, scaledpos cur)
+{
+ switch (pos->dir) {
+ case dir_TLT:
+ pos->pos.h = refpos->pos.h + cur.h;
+ pos->pos.v = refpos->pos.v - cur.v;
+ break;
+ case dir_TRT:
+ pos->pos.h = refpos->pos.h - cur.h;
+ pos->pos.v = refpos->pos.v - cur.v;
+ break;
+ case dir_LTL:
+ pos->pos.h = refpos->pos.h + cur.v;
+ pos->pos.v = refpos->pos.v - cur.h;
+ break;
+ case dir_RTT:
+ pos->pos.h = refpos->pos.h - cur.v;
+ pos->pos.v = refpos->pos.v - cur.h;
+ break;
+ default:
+ formatted_warning("pdf backend","forcing bad dir %i to TLT in synch_pos_with_cur",pos->dir);
+ pos->dir = dir_TLT;
+ pos->pos.h = refpos->pos.h + cur.h;
+ pos->pos.v = refpos->pos.v - cur.v;
+ break;
+ }
+}
+
+boolean calc_pdfpos(pdfstructure * p, scaledpos pos)
+{
+ scaledpos new;
+ boolean move_pdfpos = false;
+ switch (p->mode) {
+ case PMODE_PAGE:
+ new.h = i64round(pos.h * p->k1);
+ new.v = i64round(pos.v * p->k1);
+ /*tex cm is concatenated */
+ p->cm[4].m = new.h - p->pdf.h.m;
+ p->cm[5].m = new.v - p->pdf.v.m;
+ if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
+ move_pdfpos = true;
+ break;
+ case PMODE_TEXT:
+ new.h = i64round(pos.h * p->k1);
+ new.v = i64round(pos.v * p->k1);
+ /*tex Tm replaces */
+ p->tm[4].m = new.h - p->pdf_bt_pos.h.m;
+ p->tm[5].m = new.v - p->pdf_bt_pos.v.m;
+ if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
+ move_pdfpos = true;
+ break;
+ case PMODE_CHAR:
+ case PMODE_CHARARRAY:
+ switch (p->wmode) {
+ case WMODE_H:
+ new.h = i64round((pos.h * p->k1 - (double) p->pdf_tj_pos.h.m) * p->k2);
+ new.v = i64round(pos.v * p->k1);
+ p->tj_delta.m = -i64round((double) ((new.h - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e]));
+ /*tex p->tm[4] is meaningless */
+ p->tm[5].m = new.v - p->pdf_bt_pos.v.m;
+ if (p->tj_delta.m != 0 || new.v != p->pdf.v.m)
+ move_pdfpos = true;
+ break;
+ case WMODE_V:
+ new.h = i64round(pos.h * p->k1);
+ new.v = i64round(((double) p->pdf_tj_pos.v.m - pos.v * p->k1) * p->k2);
+ /*tex p->tm[5] is meaningless */
+ p->tm[4].m = new.h - p->pdf_bt_pos.h.m;
+ p->tj_delta.m = -i64round((double) ((new.v - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e]));
+ if (p->tj_delta.m != 0 || new.h != p->pdf.h.m)
+ move_pdfpos = true;
+ break;
+ default:
+ normal_error("pdf backend","unknown mode in char array in calc_pos");
+ break;
+ }
+ break;
+ default:
+ normal_error("pdf backend","unknown mode in calc_pos");
+ }
+ return move_pdfpos;
+}
+
+void print_pdf_matrix(PDF pdf, pdffloat * tm)
+{
+ int i;
+ for (i = 0; i < 5; i++) {
+ print_pdffloat(pdf, tm[i]);
+ pdf_out(pdf, ' ');
+ }
+ print_pdffloat(pdf, tm[i]);
+}
+
+void pdf_print_cm(PDF pdf, pdffloat * cm)
+{
+ print_pdf_matrix(pdf, cm);
+ pdf_puts(pdf, " cm\n");
+}
+
+void pdf_set_pos(PDF pdf, scaledpos pos)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ if (!is_pagemode(p))
+ normal_error("pdf backend","page mode expected in set_pos");
+ move = calc_pdfpos(p, pos);
+ if (move) {
+ pdf_print_cm(pdf, p->cm);
+ p->pdf.h.m += p->cm[4].m;
+ p->pdf.v.m += p->cm[5].m;
+ }
+}
+
+void pdf_set_pos_temp(PDF pdf, scaledpos pos)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ if (!is_pagemode(p))
+ normal_error("pdf backend","page mode expected in set_pos_temp");
+ move = calc_pdfpos(p, pos);
+ if (move) {
+ pdf_print_cm(pdf, p->cm);
+ }
+}
+
+static void begin_text(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ if (!is_pagemode(p))
+ normal_error("pdf backend","page mode expected in begin_text");
+ p->pdf_bt_pos = p->pdf;
+ pdf_puts(pdf, "BT\n");
+ p->mode = PMODE_TEXT;
+ p->need_tf = true;
+ p->need_width = 0;
+ p->need_mode = 0;
+}
+
+static void end_text(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ if (!is_textmode(p))
+ normal_error("pdf backend","text mode expected in end_text");
+
+ if (p->done_width != 0) {
+ pdf_puts(pdf, "0 w\n");
+ p->done_width = 0;
+ }
+ if (p->done_mode != 0) {
+ pdf_puts(pdf, "0 Tr\n");
+ p->done_mode = 0;
+ }
+
+ pdf_puts(pdf, "ET\n");
+ p->pdf = p->pdf_bt_pos;
+ p->mode = PMODE_PAGE;
+}
+
+void pdf_end_string_nl(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+}
+
+void pdf_goto_pagemode(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ if (!is_pagemode(p)) {
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+ if (is_textmode(p))
+ end_text(pdf);
+ if (!is_pagemode(p))
+ normal_error("pdf backend","page mode expected in goto_page_mode");
+ }
+}
+
+void pdf_goto_textmode(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ const scaledpos origin = {
+ 0, 0
+ };
+ if (is_pagemode(p)) {
+ /*tex Reset to the page origin: */
+ pdf_set_pos(pdf, origin);
+ begin_text(pdf);
+ } else if (!is_textmode(p)) {
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+ if (!is_textmode(p))
+ normal_error("pdf backend","text mode expected in goto_text_mode");
+ }
+}
+
+void pdf_goto_fontmode(PDF pdf){
+ pdfstructure *p = pdf->pstruct;
+ const scaledpos origin = {
+ 0, 0
+ };
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+ if (is_textmode(p))
+ end_text(pdf);
+ pdf_set_pos(pdf, origin);
+ p->mode = PMODE_PAGE;
+}