1<?php
2
3require_once DOKU_PLUGIN . 'odt/ODT/ODTDocument.php';
4
5/**
6 * ODTImage:
7 * Class containing static code for handling images.
8 *
9 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
10 */
11class ODTImage
12{
13    /**
14     * Adds an image $src to the document.
15     *
16     * @param string  $src        The path to the image file
17     * @param string  $width      Width of the picture (NULL=original size)
18     * @param string  $height     Height of the picture (NULL=original size)
19     * @param string  $align      Alignment
20     * @param string  $title      Title
21     * @param string  $style      Optional "draw:style-name"
22     * @param boolean $returnonly Only return code
23     *
24     * @see ODTImage::addImage for a detailed description
25     */
26    public static function addImage(ODTInternalParams $params, $src, $width = NULL, $height = NULL, $align = NULL, $title = NULL, $style = NULL, $returnonly = false){
27        static $z = 0;
28
29        $encoded = '';
30        if (file_exists($src)) {
31            list($ext,$mime) = mimetype($src);
32            $name = 'Pictures/'.md5($src).'.'.$ext;
33            $params->document->addFile($name, $mime, io_readfile($src,false));
34        } else {
35            $name = $src;
36        }
37        // make sure width and height are available
38        if (!$width && !$height) {
39            list($width, $height) = ODTUtility::getImageSizeString($src, $width, $height, true, $params->units);
40        } else {
41            list($width, $height) = ODTUtility::getImageSizeString($src, $width, $height, false, $params->units);
42        }
43
44        if($align){
45            $anchor = 'paragraph';
46        }else{
47            $anchor = 'as-char';
48        }
49
50        if (empty($style) || !$params->document->styleExists($style)) {
51            if (!empty($align)) {
52                $style = $params->document->getStyleName('media '.$align);
53            } else {
54                $style = $params->document->getStyleName('media');
55            }
56        }
57
58        // Open paragraph if necessary
59        if (!$params->document->state->getInParagraph()) {
60            $params->document->paragraphOpen();
61        }
62
63        if ($title) {
64            $encoded .= '<draw:frame draw:style-name="'.$style.'" draw:name="'.$params->document->replaceXMLEntities($title).' Legend"
65                            text:anchor-type="'.$anchor.'" draw:z-index="0" svg:width="'.$width.'">';
66            $encoded .= '<draw:text-box>';
67            $encoded .= '<text:p text:style-name="'.$params->document->getStyleName('legend center').'">';
68        }
69        if (!empty($title)) {
70            $encoded .= '<draw:frame draw:style-name="'.$style.'" draw:name="'.$params->document->replaceXMLEntities($title).'"
71                            text:anchor-type="'.$anchor.'" draw:z-index="'.$z.'"
72                            svg:width="'.$width.'" svg:height="'.$height.'" >';
73        } else {
74            $encoded .= '<draw:frame draw:style-name="'.$style.'" draw:name="'.$z.'"
75                            text:anchor-type="'.$anchor.'" draw:z-index="'.$z.'"
76                            svg:width="'.$width.'" svg:height="'.$height.'" >';
77        }
78        $encoded .= '<draw:image xlink:href="'.$params->document->replaceXMLEntities($name).'"
79                        xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>';
80        $encoded .= '</draw:frame>';
81        if ($title) {
82            $encoded .= $params->document->replaceXMLEntities($title).'</text:p></draw:text-box></draw:frame>';
83        }
84
85        if($returnonly) {
86            return $encoded;
87        } else {
88            $params->content .= $encoded;
89        }
90
91        $z++;
92    }
93
94    /**
95     * Adds the content of $string as a SVG picture file to the document.
96     * The link name which can be used for the ODT draw:image xlink:href
97     * is returned. The caller is responsible for creating the frame and image tag
98     * but therefore has full control over it. This means he can also set parameters
99     * in the odt frame and image tag which can not be changed using the function _odtAddImage.
100     *
101     * @author LarsDW223
102     *
103     * @param string $string SVG code to add
104     * @return string
105     */
106    public static function addStringAsSVGImageFile(ODTDocument $doc, $string) {
107        if ( empty($string) ) { return; }
108
109        $ext  = '.svg';
110        $mime = '.image/svg+xml';
111        $name = 'Pictures/'.md5($string).'.'.$ext;
112        $doc->addFile($name, $mime, $string);
113        return $name;
114    }
115
116    /**
117     * Adds the content of $string as a SVG picture to the document.
118     * The other parameters behave in the same way as in _odtAddImage.
119     *
120     * @author LarsDW223
121     *
122     * @param string $string
123     * @param  $width
124     * @param  $height
125     * @param  $align
126     * @param  $title
127     * @param  $style
128     */
129    function addStringAsSVGImage(ODTInternalParams $params, $string, $width = NULL, $height = NULL, $align = NULL, $title = NULL, $style = NULL) {
130        if ( empty($string) ) { return; }
131
132        $name = self::addStringAsSVGImageFile($params->document, $string);
133
134        // make sure width and height are available
135        if (!$width || !$height) {
136            list($width, $height) = ODTUtility::getImageSizeString($string, $width, $height, true, $params->units);
137        }
138
139        if($align){
140            $anchor = 'paragraph';
141        }else{
142            $anchor = 'as-char';
143        }
144
145        if (!$style or !$params->document->styleExists($style)) {
146            $style = $params->document->getStyleName('media '.$align);
147        }
148
149        // Open paragraph if necessary
150        if (!$params->document->state->getInParagraph()) {
151            $params->document->paragraphOpen();
152        }
153
154        if ($title) {
155            $params->content .= '<draw:frame draw:style-name="'.$style.'" draw:name="'.$params->document->replaceXMLEntities($title).' Legend"
156                                 text:anchor-type="'.$anchor.'" draw:z-index="0" svg:width="'.$width.'">';
157            $params->content .= '<draw:text-box>';
158            $params->document->paragraphOpen($$params->document->getStyleName('legend center'));
159        }
160        $params->content .= '<draw:frame draw:style-name="'.$style.'" draw:name="'.$params->document->replaceXMLEntities($title).'"
161                             text:anchor-type="'.$anchor.'" draw:z-index="0"
162                             svg:width="'.$width.'" svg:height="'.$height.'" >';
163        $params->content .= '<draw:image xlink:href="'.$params->document->replaceXMLEntities($name).'"
164                             xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>';
165        $params->content .= '</draw:frame>';
166        if ($title) {
167            $params->content .= $params->document->replaceXMLEntities($title);
168            $params->document->paragraphClose();
169            $params->content .= '</draw:text-box></draw:frame>';
170        }
171    }
172
173    /**
174     * Adds an image $src to the document using the parameters set in $properties.
175     * The actually supported properties are:
176     * - width and height
177     * - title
178     * - background-color
179     * - margin-left, margin-right, margin-top, margin-bottom
180     *
181     * @param string  $src        The path to the image file
182     * @param array   $properties Properties (width, height... see ODTImage::addImageUseProperties)
183     * @param boolean $returnonly Only return code
184     */
185    public static function addImageUseProperties(ODTInternalParams $params, $src, array $properties, $returnonly = false){
186        static $z = 0;
187
188        ODTUtility::adjustValuesForODT ($properties, $params->units);
189        $width = $properties ['width'];
190        $height = $properties ['height'];
191        $title = $properties ['title'];
192        $bg_color = $properties ['background-color'];
193
194        $encoded = '';
195        if (file_exists($src)) {
196            list($ext,$mime) = mimetype($src);
197            $name = 'Pictures/'.md5($src).'.'.$ext;
198            $params->document->addFile($name, $mime, io_readfile($src,false));
199        } else {
200            $name = $src;
201        }
202        // make sure width and height are available
203        if (!$width || !$height) {
204            list($width, $height) = ODTUtility::getImageSizeString($src, $width, $height, true, $params->units);
205        } else {
206            // Adjust values for ODT
207            $width = $params->document->toPoints($width, 'x').'pt';
208            $height = $params->document->toPoints($height, 'y').'pt';
209        }
210
211        if($align){
212            $anchor = 'paragraph';
213        }else{
214            $anchor = 'as-char';
215        }
216
217        // Open paragraph if necessary
218        if (!$params->document->state->getInParagraph()) {
219            $params->document->paragraphOpen();
220        }
221
222        // Define graphic style for picture
223        $style_name = ODTStyle::getNewStylename('span_graphic');
224        $image_style  = '<style:style style:name="'.$style_name.'" style:family="graphic" style:parent-style-name="'.$params->document->getStyleName('graphics').'">';
225        $image_style .= '<style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:background-color="'.$bg_color.'" style:flow-with-text="true"';
226        if (!empty($properties ['margin-left'])) {
227            $image_style .= ' fo:margin-left="'.$properties ['margin-left'].'"';
228        }
229        if (!empty($properties ['margin-right'])) {
230            $image_style .= ' fo:margin-right="'.$properties ['margin-right'].'"';
231        }
232        if (!empty($properties ['margin-top'])) {
233            $image_style .= ' fo:margin-top="'.$properties ['margin-top'].'"';
234        }
235        if (!empty($properties ['margin-bottom'])) {
236            $image_style .= ' fo:margin-bottom="'.$properties ['margin-bottom'].'"';
237        }
238        $image_style .= '></style:graphic-properties></style:style>';
239
240        // Add style and image to our document
241        // (as unknown style because style-family graphic is not supported)
242        $style_obj = ODTUnknownStyle::importODTStyle($image_style);
243        $params->document->addAutomaticStyle($style_obj);
244
245        if ($title) {
246            $encoded .= '<draw:frame draw:style-name="'.$style_name.'" draw:name="'.$params->document->replaceXMLEntities($title).' Legend"
247                            text:anchor-type="'.$anchor.'" draw:z-index="0" svg:width="'.$width.'">';
248            $encoded .= '<draw:text-box>';
249            $encoded .= '<text:p text:style-name="'.$params->document->getStyleName('legend center').'">';
250        }
251        if (!empty($title)) {
252            $encoded .= '<draw:frame draw:style-name="'.$style_name.'" draw:name="'.$params->document->replaceXMLEntities($title).'"
253                            text:anchor-type="'.$anchor.'" draw:z-index="'.$z.'"
254                            svg:width="'.$width.'" svg:height="'.$height.'" >';
255        } else {
256            $encoded .= '<draw:frame draw:style-name="'.$style_name.'" draw:name="'.$z.'"
257                            text:anchor-type="'.$anchor.'" draw:z-index="'.$z.'"
258                            svg:width="'.$width.'" svg:height="'.$height.'" >';
259        }
260        $encoded .= '<draw:image xlink:href="'.$params->document->replaceXMLEntities($name).'"
261                        xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/>';
262        $encoded .= '</draw:frame>';
263        if ($title) {
264            $encoded .= $params->document->replaceXMLEntities($title).'</text:p></draw:text-box></draw:frame>';
265        }
266
267        if($returnonly) {
268            return $encoded;
269        } else {
270            $params->content .= $encoded;
271        }
272
273        $z++;
274    }
275}
276