@@ -42,6 +42,12 @@ public function write(): void
42
42
if (!$ element instanceof ImageElement) {
43
43
return ;
44
44
}
45
+ $ ext = strtolower (pathinfo ($ element ->getSource (), PATHINFO_EXTENSION ));
46
+ if ($ ext === 'svg ' ) {
47
+ $ this ->writeSvgDrawing ($ xmlWriter , $ element );
48
+
49
+ return ;
50
+ }
45
51
46
52
if ($ element ->isWatermark ()) {
47
53
$ this ->writeWatermark ($ xmlWriter , $ element );
@@ -127,4 +133,136 @@ private function writeWatermark(XMLWriter $xmlWriter, ImageElement $element): vo
127
133
$ xmlWriter ->endElement (); // w:p
128
134
}
129
135
}
136
+
137
+ private function writeSvgDrawing (XMLWriter $ xmlWriter , ImageElement $ element ): void
138
+ {
139
+ $ rId = $ element ->getRelationId () + ($ element ->isInSection () ? 6 : 0 );
140
+
141
+ $ style = $ element ->getStyle ();
142
+ // dimensions px, fallback sur getSvgDimensions()
143
+ $ pxW = $ style ->getWidth () ?: 0 ;
144
+ $ pxH = $ style ->getHeight () ?: 0 ;
145
+ if ($ pxW <= 0 || $ pxH <= 0 ) {
146
+ [$ pxW , $ pxH ] = $ element ->getSvgDimensions ($ element ->getSource ());
147
+ }
148
+ $ cx = \PhpOffice \PhpWord \Shared \Drawing::pixelsToEmu ($ pxW );
149
+ $ cy = \PhpOffice \PhpWord \Shared \Drawing::pixelsToEmu ($ pxH );
150
+
151
+ // <w:p> + align
152
+ if (!$ this ->withoutP ) {
153
+ $ xmlWriter ->startElement ('w:p ' );
154
+ (new ImageStyleWriter ($ xmlWriter , $ style ))->writeAlignment ();
155
+ }
156
+ // <w:r>
157
+ $ xmlWriter ->startElement ('w:r ' );
158
+ // <w:drawing>
159
+ $ xmlWriter ->startElement ('w:drawing ' );
160
+
161
+ // <wp:inline> avec déclarations xmlns comme python-docx-oss
162
+ $ xmlWriter ->startElement ('wp:inline ' );
163
+ $ xmlWriter ->writeAttribute ('xmlns:a ' , 'http://schemas.openxmlformats.org/drawingml/2006/main ' );
164
+ $ xmlWriter ->writeAttribute ('xmlns:pic ' , 'http://schemas.openxmlformats.org/drawingml/2006/picture ' );
165
+ $ xmlWriter ->writeAttribute ('xmlns:asvg ' , 'http://schemas.microsoft.com/office/drawing/2016/SVG/main ' );
166
+
167
+ // <wp:extent>
168
+ $ xmlWriter ->startElement ('wp:extent ' );
169
+ $ xmlWriter ->writeAttribute ('cx ' , (string ) $ cx );
170
+ $ xmlWriter ->writeAttribute ('cy ' , (string ) $ cy );
171
+ $ xmlWriter ->endElement ();
172
+
173
+ // <wp:docPr>
174
+ $ xmlWriter ->startElement ('wp:docPr ' );
175
+ $ xmlWriter ->writeAttribute ('id ' , '1 ' );
176
+ $ xmlWriter ->writeAttribute ('name ' , 'Picture 1 ' );
177
+ $ xmlWriter ->endElement ();
178
+
179
+ // <wp:cNvGraphicFramePr>
180
+ $ xmlWriter ->startElement ('wp:cNvGraphicFramePr ' );
181
+ $ xmlWriter ->startElement ('a:graphicFrameLocks ' );
182
+ $ xmlWriter ->writeAttribute ('noChangeAspect ' , '1 ' );
183
+ $ xmlWriter ->endElement ();
184
+ $ xmlWriter ->endElement ();
185
+
186
+ // <a:graphic>
187
+ $ xmlWriter ->startElement ('a:graphic ' );
188
+ // <a:graphicData uri=".../picture">
189
+ $ xmlWriter ->startElement ('a:graphicData ' );
190
+ $ xmlWriter ->writeAttribute (
191
+ 'uri ' ,
192
+ 'http://schemas.openxmlformats.org/drawingml/2006/picture '
193
+ );
194
+
195
+ // <pic:pic>
196
+ $ xmlWriter ->startElement ('pic:pic ' );
197
+
198
+ // <pic:nvPicPr>
199
+ $ xmlWriter ->startElement ('pic:nvPicPr ' );
200
+ $ xmlWriter ->startElement ('pic:cNvPr ' );
201
+ $ xmlWriter ->writeAttribute ('id ' , '0 ' );
202
+ $ xmlWriter ->writeAttribute ('name ' , basename ($ element ->getSource ()));
203
+ $ xmlWriter ->endElement ();
204
+ $ xmlWriter ->startElement ('pic:cNvPicPr ' );
205
+ $ xmlWriter ->endElement ();
206
+ $ xmlWriter ->endElement ();
207
+
208
+ // <pic:blipFill>
209
+ $ xmlWriter ->startElement ('pic:blipFill ' );
210
+ $ xmlWriter ->startElement ('a:blip ' );
211
+ // uniquement extLst avec svgBlip
212
+ $ xmlWriter ->startElement ('a:extLst ' );
213
+ $ xmlWriter ->startElement ('a:ext ' );
214
+ $ xmlWriter ->writeAttribute (
215
+ 'uri ' ,
216
+ '{96DAC541-7B7A-43D3-8B79-37D633B846F1} '
217
+ );
218
+ $ xmlWriter ->startElement ('asvg:svgBlip ' );
219
+ $ xmlWriter ->writeAttribute (
220
+ 'r:embed ' ,
221
+ 'rId ' . $ rId
222
+ );
223
+ $ xmlWriter ->endElement (); // asvg:svgBlip
224
+ $ xmlWriter ->endElement (); // a:ext
225
+ $ xmlWriter ->endElement (); // a:extLst
226
+ $ xmlWriter ->endElement (); // a:blip
227
+
228
+ // <a:stretch><a:fillRect/>
229
+ $ xmlWriter ->startElement ('a:stretch ' );
230
+ $ xmlWriter ->startElement ('a:fillRect ' );
231
+ $ xmlWriter ->endElement ();
232
+ $ xmlWriter ->endElement ();
233
+
234
+ $ xmlWriter ->endElement (); // pic:blipFill
235
+
236
+ // <pic:spPr>
237
+ $ xmlWriter ->startElement ('pic:spPr ' );
238
+ $ xmlWriter ->startElement ('a:xfrm ' );
239
+ $ xmlWriter ->startElement ('a:off ' );
240
+ $ xmlWriter ->writeAttribute ('x ' , '0 ' );
241
+ $ xmlWriter ->writeAttribute ('y ' , '0 ' );
242
+ $ xmlWriter ->endElement ();
243
+ $ xmlWriter ->startElement ('a:ext ' );
244
+ $ xmlWriter ->writeAttribute ('cx ' , (string ) $ cx );
245
+ $ xmlWriter ->writeAttribute ('cy ' , (string ) $ cy );
246
+ $ xmlWriter ->endElement ();
247
+ $ xmlWriter ->endElement ();
248
+ $ xmlWriter ->startElement ('a:prstGeom ' );
249
+ $ xmlWriter ->writeAttribute ('prst ' , 'rect ' );
250
+ $ xmlWriter ->endElement ();
251
+ $ xmlWriter ->endElement (); // pic:spPr
252
+
253
+ $ xmlWriter ->endElement (); // pic:pic
254
+
255
+ $ xmlWriter ->endElement (); // a:graphicData
256
+ $ xmlWriter ->endElement (); // a:graphic
257
+
258
+ $ xmlWriter ->endElement (); // wp:inline
259
+
260
+ $ xmlWriter ->endElement (); // w:drawing
261
+ $ xmlWriter ->endElement (); // w:r
262
+
263
+ // </w:p>
264
+ if (!$ this ->withoutP ) {
265
+ $ xmlWriter ->endElement ();
266
+ }
267
+ }
130
268
}
0 commit comments