1% pdfimage.w
2%
3% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
4%
5% This file is part of LuaTeX.
6%
7% LuaTeX is free software; you can redistribute it and/or modify it under
8% the terms of the GNU General Public License as published by the Free
9% Software Foundation; either version 2 of the License, or (at your
10% option) any later version.
11%
12% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15% License for more details.
16%
17% You should have received a copy of the GNU General Public License along
18% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
19
20@ @c
21
22
23#include "ptexlib.h"
24
25@ @c
26void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform)
27{
28    float a[6];                 /* transformation matrix */
29    float xoff, yoff, tmp;
30    pdfstructure *p = pdf->pstruct;
31    scaledpos pos = pdf->posstruct->pos;
32    int r;                      /* number of digits after the decimal point */
33    int k;
34    scaledpos tmppos;
35    pdffloat cm[6];
36    int groupref;               /* added from web for 1.40.8 */
37    assert(idict != 0);
38    assert(p != NULL);
39    a[0] = a[3] = 1.0e6;
40    a[1] = a[2] = 0;
41    if (img_type(idict) == IMG_TYPE_PDF
42        || img_type(idict) == IMG_TYPE_PDFSTREAM) {
43        a[0] /= (float) img_xsize(idict);
44        a[3] /= (float) img_ysize(idict);
45        xoff = (float) img_xorig(idict) / (float) img_xsize(idict);
46        yoff = (float) img_yorig(idict) / (float) img_ysize(idict);
47        r = 6;
48    } else {
49        /* added from web for 1.40.8 */
50        if (img_type(idict) == IMG_TYPE_PNG) {
51            groupref = img_group_ref(idict);
52            if ((groupref > 0) && (pdf->img_page_group_val == 0))
53                pdf->img_page_group_val = groupref;
54        }
55        /* /added from web */
56        a[0] /= (float) one_hundred_bp;
57        a[3] = a[0];
58        xoff = yoff = 0;
59        r = 4;
60    }
61    if ((transform & 7) > 3) {  // mirror cases
62        a[0] *= -1;
63        xoff *= -1;
64    }
65    switch ((transform + img_rotation(idict)) & 3) {
66    case 0:                    /* no transform */
67        break;
68    case 1:                    /* rot. 90 deg. (counterclockwise) */
69        a[1] = a[0];
70        a[2] = -a[3];
71        a[3] = a[0] = 0;
72        tmp = yoff;
73        yoff = xoff;
74        xoff = -tmp;
75        break;
76    case 2:                    /* rot. 180 deg. (counterclockwise) */
77        a[0] *= -1;
78        a[3] *= -1;
79        xoff *= -1;
80        yoff *= -1;
81        break;
82    case 3:                    /* rot. 270 deg. (counterclockwise) */
83        a[1] = -a[0];
84        a[2] = a[3];
85        a[3] = a[0] = 0;
86        tmp = yoff;
87        yoff = -xoff;
88        xoff = tmp;
89        break;
90    default:;
91    }
92    xoff *= (float) dim.wd;
93    yoff *= (float) (dim.ht + dim.dp);
94    a[0] *= (float) dim.wd;
95    a[1] *= (float) (dim.ht + dim.dp);
96    a[2] *= (float) dim.wd;
97    a[3] *= (float) (dim.ht + dim.dp);
98    a[4] = (float) pos.h - xoff;
99    a[5] = (float) pos.v - yoff;
100    k = transform + img_rotation(idict);
101    if ((transform & 7) > 3)
102        k++;
103    switch (k & 3) {
104    case 0:                    /* no transform */
105        break;
106    case 1:                    /* rot. 90 deg. (counterclockwise) */
107        a[4] += (float) dim.wd;
108        break;
109    case 2:                    /* rot. 180 deg. */
110        a[4] += (float) dim.wd;
111        a[5] += (float) (dim.ht + dim.dp);
112        break;
113    case 3:                    /* rot. 270 deg. */
114        a[5] += (float) (dim.ht + dim.dp);
115        break;
116    default:;
117    }
118    /* the following is a kludge, TODO: use pdfpage.c functions */
119    setpdffloat(cm[0], i64round(a[0]), r);
120    setpdffloat(cm[1], i64round(a[1]), r);
121    setpdffloat(cm[2], i64round(a[2]), r);
122    setpdffloat(cm[3], i64round(a[3]), r);
123    tmppos.h = round(a[4]);
124    tmppos.v = round(a[5]);
125    pdf_goto_pagemode(pdf);
126    (void) calc_pdfpos(p, tmppos);
127    cm[4] = p->cm[4];
128    cm[5] = p->cm[5];
129    if (pdf->img_page_group_val == 0)
130        pdf->img_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */
131    pdf_puts(pdf, "q\n");
132    pdf_print_cm(pdf, cm);
133    pdf_puts(pdf, "/Im");
134    pdf_print_int(pdf, img_index(idict));
135    pdf_print_resname_prefix(pdf);
136    pdf_puts(pdf, " Do\nQ\n");
137    addto_page_resources(pdf, obj_type_ximage, img_objnum(idict));
138    if (img_state(idict) < DICT_OUTIMG)
139        img_state(idict) = DICT_OUTIMG;
140}
141
142@ for normal output, see \.{pdflistout.w}
143
144@c
145void pdf_place_image(PDF pdf, halfword p)
146{
147    scaled_whd dim;
148    image_dict *idict = idict_array[pdf_ximage_index(p)];
149    assert(idict != NULL);
150    dim.wd = width(p);
151    dim.ht = height(p);
152    dim.dp = depth(p);
153    place_img(pdf, idict, dim, pdf_ximage_transform(p));
154}
155