1 /************************************************************************/
2 /* */
3 /* Draw Scalable Vector Graphics. */
4 /* */
5 /************************************************************************/
6
7 # include "docHtmlConfig.h"
8
9 # include <stddef.h>
10 # include <stdio.h>
11 # include <string.h>
12
13 # include <docDraw.h>
14 # include <docShape.h>
15 # include <docLayout.h>
16 # include "docSvgDrawImpl.h"
17 # include "docWriteCss.h"
18 # include "docSvgDraw.h"
19 # include <psShading.h>
20 # include <docTreeNode.h>
21
22 # include <appDebugon.h>
23
24 /************************************************************************/
25 /* */
26 /* Cause subsequent drawing to be done in a certain color. */
27 /* */
28 /* NOTE that background drawing with color= 0 is against the RTF idea */
29 /* of the default background color: transparent. */
30 /* */
31 /************************************************************************/
32
docSvgSetColorRgb(DrawingContext * dc,void * vsw,const RGB8Color * rgb8)33 static int docSvgSetColorRgb( DrawingContext * dc,
34 void * vsw,
35 const RGB8Color * rgb8 )
36 {
37 return 0;
38 }
39
docSvgSetFont(DrawingContext * dc,void * vsw,int textAttrNumber,const TextAttribute * ta)40 static int docSvgSetFont( DrawingContext * dc,
41 void * vsw,
42 int textAttrNumber,
43 const TextAttribute * ta )
44 {
45 const LayoutContext * lc= &(dc->dcLayoutContext);
46 BufferDocument * bd= lc->lcDocument;
47 DocumentFontList * dfl= bd->bdProperties.dpFontList;
48 const AfmFontInfo * afi;
49 const IndexSet * unicodesWanted;
50
51 const PostScriptFontList * psfl= lc->lcPostScriptFontList;
52
53 afi= (*lc->lcGetFontForAttribute)( &unicodesWanted, ta, dfl, psfl );
54 if ( ! afi )
55 { LDEB(textAttrNumber); return -1; }
56
57 return 0;
58 }
59
60 /************************************************************************/
61 /* */
62 /* Printing of borders. */
63 /* */
64 /* 1) The border is around paragraphs. Both the border and its */
65 /* are outside the frame. */
66 /* */
67 /************************************************************************/
68
docSvgWriteBorderAttributes(SvgWriter * sw,const BufferDocument * bd,const BorderProperties * bp,int thick)69 static void docSvgWriteBorderAttributes(
70 SvgWriter * sw,
71 const BufferDocument * bd,
72 const BorderProperties * bp,
73 int thick )
74 {
75 RGB8Color rgb8;
76 XmlWriter * xw= &(sw->swXmlWriter);
77
78 if ( thick < 8 )
79 { thick= 8; }
80
81 docGetColorByNumber( &rgb8, bd, bp->bpColor );
82
83 xmlWriteRgb8Attribute( xw, "stroke", &rgb8 );
84 xmlWriteIntAttribute( xw, "stroke-width", thick );
85
86 return;
87 }
88
docSvgDrawHorizontalBorder(SvgWriter * sw,const BufferDocument * bd,const BorderProperties * bp,const DocumentRectangle * drBorder)89 static void docSvgDrawHorizontalBorder(
90 SvgWriter * sw,
91 const BufferDocument * bd,
92 const BorderProperties * bp,
93 const DocumentRectangle * drBorder )
94 {
95 XmlWriter * xw= &(sw->swXmlWriter);
96
97 sioOutPutString( "<line", xw->xwSos );
98
99 xmlWriteIntAttribute( xw, "x1", drBorder->drX0 );
100 xmlWriteIntAttribute( xw, "x2", drBorder->drX1 );
101 xmlWriteIntAttribute( xw, "y1", ( drBorder->drY0+ drBorder->drY1 )/ 2 );
102 xmlWriteIntAttribute( xw, "y2", ( drBorder->drY0+ drBorder->drY1 )/ 2 );
103 docSvgWriteBorderAttributes( sw, bd, bp,
104 drBorder->drY1- drBorder->drY0+ 1 );
105
106 sioOutPutString( "/>", xw->xwSos );
107 return;
108 }
109
docSvgDrawVerticalBorder(SvgWriter * sw,const BufferDocument * bd,const BorderProperties * bp,const DocumentRectangle * drBorder)110 static void docSvgDrawVerticalBorder(
111 SvgWriter * sw,
112 const BufferDocument * bd,
113 const BorderProperties * bp,
114 const DocumentRectangle * drBorder )
115 {
116 XmlWriter * xw= &(sw->swXmlWriter);
117
118 sioOutPutString( "<line", xw->xwSos );
119
120 xmlWriteIntAttribute( xw, "x1", ( drBorder->drX0+ drBorder->drX1 )/ 2 );
121 xmlWriteIntAttribute( xw, "x2", ( drBorder->drX0+ drBorder->drX1 )/ 2 );
122 xmlWriteIntAttribute( xw, "y1", drBorder->drY0 );
123 xmlWriteIntAttribute( xw, "y2", drBorder->drY1 );
124 docSvgWriteBorderAttributes( sw, bd, bp,
125 drBorder->drX1- drBorder->drX0+ 1 );
126
127 sioOutPutString( "/>", xw->xwSos );
128 return;
129 }
130
131 /************************************************************************/
132 /* */
133 /* Draw background ornaments. */
134 /* */
135 /************************************************************************/
136
docSvgDrawOrnaments(const BlockOrnaments * bo,int page,const DocumentRectangle * drOutside,const DocumentRectangle * drInside,void * through,struct DrawingContext * dc)137 static int docSvgDrawOrnaments( const BlockOrnaments * bo,
138 int page,
139 const DocumentRectangle * drOutside,
140 const DocumentRectangle * drInside,
141 void * through,
142 struct DrawingContext * dc )
143 {
144 SvgWriter * sw= (SvgWriter *)through;
145 XmlWriter * xw= &(sw->swXmlWriter);
146 const LayoutContext * lc= &(dc->dcLayoutContext);
147 const BufferDocument * bd= lc->lcDocument;
148
149 int rectBorder= 0;
150 DocumentRectangle drRectBorder;
151
152 drRectBorder.drX0= ( 3* drOutside->drX0- drInside->drX0 )/ 2;
153 drRectBorder.drX1= ( 3* drOutside->drX1- drInside->drX1 )/ 2;
154 drRectBorder.drY0= ( 3* drOutside->drY0- drInside->drY0 )/ 2;
155 drRectBorder.drY1= ( 3* drOutside->drY1- drInside->drY1 )/ 2;
156
157 # if 0
158 if ( PROPmaskISSET( &(bo->boPropMask), ORNdrawTOP_BORDER ) &&
159 PROPmaskISSET( &(bo->boPropMask), ORNdrawLEFT_BORDER ) &&
160 PROPmaskISSET( &(bo->boPropMask), ORNdrawRIGHT_BORDER ) &&
161 PROPmaskISSET( &(bo->boPropMask), ORNdrawBOTTOM_BORDER ) &&
162 bo->boLeftBorderNumber == bo->boTopBorderNumber &&
163 bo->boRightBorderNumber == bo->boTopBorderNumber &&
164 bo->boBottomBorderNumber == bo->boTopBorderNumber )
165 { rectBorder= 1; }
166 # endif
167
168 if ( PROPmaskISSET( &(bo->boPropMask), ORNdrawSHADE ) )
169 {
170 int isFilled= 0;
171 RGB8Color rgb8;
172 const DocumentRectangle * drShade= drInside;
173
174 if ( rectBorder )
175 { drShade= &drRectBorder; }
176
177 if ( docGetSolidRgbShadeOfItem( &isFilled, &rgb8,
178 bd, &(bo->boShading) ) )
179 { LDEB(1); }
180
181 if ( isFilled )
182 {
183 sioOutPutString( "<rect", xw->xwSos );
184 svgWriteRectangleAttributes( sw, drShade );
185 xmlWriteRgb8Attribute( xw, "fill", &rgb8 );
186
187 if ( rectBorder )
188 {
189 docSvgWriteBorderAttributes( sw, bd, &(bo->boTopBorder),
190 drOutside->drY0- drInside->drY0 );
191 }
192
193 sioOutPutString( "/>", xw->xwSos );
194 xmlNewLine( xw );
195 }
196
197 if ( bo->boShading.isPattern != DOCspSOLID )
198 { LDEB(bo->boShading.isPattern); }
199 }
200 else{
201 if ( rectBorder )
202 {
203 sioOutPutString( "<rect", xw->xwSos );
204 svgWriteRectangleAttributes( sw, &drRectBorder );
205 xmlWriteStringAttribute( xw, "fill", "none" );
206 docSvgWriteBorderAttributes( sw, bd, &(bo->boTopBorder),
207 drOutside->drY0- drInside->drY0 );
208 sioOutPutString( "/>", xw->xwSos );
209 xmlNewLine( xw );
210 }
211 }
212
213 if ( ! rectBorder &&
214 PROPmaskISSET( &(bo->boPropMask), ORNdrawTOP_BORDER ) )
215 {
216 DocumentRectangle drBorder= *drOutside;
217
218 drBorder.drY1= drInside->drY0- 1;
219
220 docSvgDrawHorizontalBorder( sw, bd, &(bo->boTopBorder), &drBorder );
221 xmlNewLine( xw );
222 /*done= 1;*/
223 }
224
225 if ( ! rectBorder &&
226 PROPmaskISSET( &(bo->boPropMask), ORNdrawLEFT_BORDER ) )
227 {
228 DocumentRectangle drBorder= *drOutside;
229
230 drBorder.drY0= drInside->drY0;
231 drBorder.drY1= drInside->drY1;
232 drBorder.drX1= drInside->drX0- 1;
233
234 docSvgDrawVerticalBorder( sw, bd, &(bo->boLeftBorder), &drBorder );
235 /*done= 1;*/
236 }
237
238 if ( ! rectBorder &&
239 PROPmaskISSET( &(bo->boPropMask), ORNdrawRIGHT_BORDER ) )
240 {
241 DocumentRectangle drBorder= *drOutside;
242
243 drBorder.drY0= drInside->drY0;
244 drBorder.drY1= drInside->drY1;
245 drBorder.drX0= drInside->drX1+ 1;
246
247 docSvgDrawVerticalBorder( sw, bd, &(bo->boRightBorder), &drBorder );
248 /*done= 1;*/
249 }
250
251 if ( ! rectBorder &&
252 PROPmaskISSET( &(bo->boPropMask), ORNdrawBOTTOM_BORDER ) )
253 {
254 DocumentRectangle drBorder= *drOutside;
255
256 drBorder.drY0= drInside->drY1+ 1;
257
258 docSvgDrawHorizontalBorder( sw, bd, &(bo->boBottomBorder), &drBorder );
259 /*done= 1;*/
260 }
261
262 return 0;
263 }
264
265 /************************************************************************/
266
docSvgEmitFill(SvgWriter * sw,const struct DrawingShape * ds)267 int docSvgEmitFill( SvgWriter * sw,
268 const struct DrawingShape * ds )
269 {
270 XmlWriter * xw= &(sw->swXmlWriter);
271 RGB8Color rgb8Fill;
272 int fill;
273
274 if ( docShapeGetFill( &fill, &rgb8Fill, ds ) )
275 { LDEB(ds->dsDrawing.sdShapeType); return -1; }
276
277 if ( fill )
278 { xmlWriteRgb8Attribute( xw, "fill", &rgb8Fill ); }
279 else{ xmlWriteStringAttribute( xw, "fill", "none" ); }
280
281 return 0;
282 }
283
docSvgEmitStroke(SvgWriter * sw,const DrawingShape * ds)284 int docSvgEmitStroke( SvgWriter * sw,
285 const DrawingShape * ds )
286 {
287 const ShapeDrawing * sd= &(ds->dsDrawing);
288 XmlWriter * xw= &(sw->swXmlWriter);
289 RGB8Color rgb8Stroke;
290 int stroke;
291
292 if ( docShapeGetLine( &stroke, &rgb8Stroke, ds ) )
293 { LDEB(sd->sdShapeType); return -1; }
294
295 if ( stroke )
296 {
297 int widthTwips= EMUtoTWIPS( sd->sdLineWidthEmu );
298 char dashArray[100];
299
300 xmlWriteRgb8Attribute( xw, "stroke", &rgb8Stroke );
301 xmlWriteIntAttribute( xw, "stroke-width", widthTwips );
302
303 dashArray[0]= '\0';
304
305 switch( sd->sdLineDashing )
306 {
307 case DSdashSOLID:
308 break;
309
310 case DSdashDASHED:
311 case DSdashDASHED_X:
312 case DSdashDASHED_L:
313 sprintf( dashArray, "%d %d", 6* widthTwips, 4* widthTwips );
314 break;
315
316 case DSdashDOT:
317 case DSdashDOT_X:
318 sprintf( dashArray, "%d %d", 1* widthTwips, 2* widthTwips );
319 break;
320
321 case DSdashDASHDOT:
322 case DSdashDASHDOT_X:
323 case DSdashDASHDOT_L:
324 sprintf( dashArray, "%d %d %d %d",
325 6* widthTwips, 2* widthTwips,
326 1* widthTwips, 2* widthTwips );
327 break;
328
329 case DSdashDASHDOTDOT:
330 case DSdashDASHDOTDOT_L:
331 sprintf( dashArray, "%d %d %d %d %d %d",
332 6* widthTwips,
333 2* widthTwips,
334 1* widthTwips,
335 2* widthTwips,
336 1* widthTwips,
337 2* widthTwips );
338 break;
339
340 default:
341 LDEB(sd->sdLineDashing);
342 }
343
344 if ( dashArray[0] )
345 { xmlWriteStringAttribute( xw, "dash-array", dashArray ); }
346 }
347
348 return 0;
349 }
350
351 /************************************************************************/
352 /* */
353 /* Skip to the next page. */
354 /* */
355 /************************************************************************/
356
docSvgFinishPage(void * vsw,DrawingContext * dc,BufferItem * bodySectNode,int page,int asLast)357 static int docSvgFinishPage( void * vsw,
358 DrawingContext * dc,
359 BufferItem * bodySectNode,
360 int page,
361 int asLast )
362 {
363 SvgWriter * sw= (SvgWriter *)vsw;
364 XmlWriter * xw= &(sw->swXmlWriter);
365
366 # if 0
367 if ( sw->swMultiPage )
368 {
369 xmlPutString( "</page>", xw );
370 xmlNewLine( xw );
371 }
372 # else
373 if ( sw->swMultiPage )
374 {
375 xmlPutString( "</g>", xw );
376 xmlNewLine( xw );
377 }
378 # endif
379
380 return 0;
381 }
382
docSvgDrawStartPage(void * vsw,const DocumentGeometry * dgPage,DrawingContext * dc,int page)383 static int docSvgDrawStartPage( void * vsw,
384 const DocumentGeometry * dgPage,
385 DrawingContext * dc,
386 int page )
387 {
388 SvgWriter * sw= (SvgWriter *)vsw;
389 XmlWriter * xw= &(sw->swXmlWriter);
390
391 char scratch[120];
392
393 sprintf( scratch, "page%d", page+ 1 );
394
395 # if 0
396 if ( sw->swMultiPage )
397 {
398 xmlPutString( "<page", xw );
399 xmlWriteStringAttribute( xw, "id", scratch );
400 xmlPutString( ">", xw );
401 xmlNewLine( xw );
402 }
403 # else
404 if ( sw->swMultiPage )
405 {
406 xmlPutString( "<g", xw );
407 xmlWriteStringAttribute( xw, "id", scratch );
408 if ( page != dc->dcFirstPage )
409 { xmlWriteStringAttribute( xw, "visibility", "hidden" ); }
410 xmlPutString( ">", xw );
411 xmlNewLine( xw );
412
413 xmlPutString( "<path", xw );
414 xmlWriteStringAttribute( xw, "d",
415 "M75,225 l225,-150 l0,300 l-225,-150z" );
416 if ( page > dc->dcFirstPage )
417 {
418 sprintf( scratch, "switchPage( evt, \"page%d\", \"page%d\" );",
419 page+ 1, page );
420
421 xmlWriteStringAttribute( xw, "fill", "#000000" );
422 xmlWriteStringAttribute( xw, "onclick", scratch );
423 }
424 else{
425 xmlWriteStringAttribute( xw, "fill", "#cccccc" );
426 }
427 xmlPutString( "/>", xw );
428 xmlNewLine( xw );
429
430 xmlPutString( "<path", xw );
431 xmlWriteStringAttribute( xw, "d",
432 "M625,225 l-225,-150 l0,300 l225,-150z" );
433 if ( page < dc->dcLastPage )
434 {
435 sprintf( scratch, "switchPage( evt, \"page%d\", \"page%d\" );",
436 page+ 1, page+ 2 );
437
438 xmlWriteStringAttribute( xw, "fill", "#000000" );
439 xmlWriteStringAttribute( xw, "onclick", scratch );
440 }
441 else{
442 xmlWriteStringAttribute( xw, "fill", "#cccccc" );
443 }
444 xmlPutString( "/>", xw );
445 xmlNewLine( xw );
446 }
447 # endif
448
449 return 0;
450 }
451
452 /************************************************************************/
453 /* */
454 /* Save a range of pages in a document. */
455 /* */
456 /************************************************************************/
457
docSvgDrawPageRange(SvgWriter * sw,DrawingContext * dc,BufferItem * bodyBi,int firstPage,int lastPage,int asLast)458 static int docSvgDrawPageRange( SvgWriter * sw,
459 DrawingContext * dc,
460 BufferItem * bodyBi,
461 int firstPage,
462 int lastPage,
463 int asLast )
464 {
465 int i;
466 LayoutPosition lpBelow;
467
468 docInitLayoutPosition( &lpBelow );
469
470 for ( i= 0; i < bodyBi->biChildCount; i++ )
471 {
472 if ( bodyBi->biChildren[i]->biBelowPosition.lpPage >= firstPage )
473 { break; }
474 }
475
476 if ( i >= bodyBi->biChildCount )
477 { LDEB(i); return -1; }
478
479 docSvgDrawStartPage( (void *)sw,
480 &(bodyBi->biChildren[i]->biSectDocumentGeometry), dc, firstPage );
481
482 if ( ! dc->dcPostponeHeadersFooters )
483 {
484 docDrawPageHeader( bodyBi->biChildren[i], (void *)sw, dc, firstPage );
485 }
486
487 if ( docDrawShapesForPage( (void *)sw, dc, 1, firstPage ) )
488 { LDEB(firstPage); }
489
490 docDrawNode( &lpBelow, bodyBi, (void *)sw, dc );
491
492 if ( lastPage < 0 )
493 { lastPage= bodyBi->biBelowPosition.lpPage; }
494
495 for ( i= bodyBi->biChildCount- 1; i >= 0; i-- )
496 {
497 if ( bodyBi->biChildren[i]->biTopPosition.lpPage <= lastPage )
498 { break; }
499 }
500
501 if ( i < 0 )
502 { LDEB(i); return -1; }
503
504 if ( docDrawShapesForPage( (void *)sw, dc, 0, lastPage ) )
505 { LDEB(lastPage); }
506
507 if ( ! dc->dcPostponeHeadersFooters )
508 {
509 docDrawPageFooter( bodyBi->biChildren[i], (void *)sw, dc, lastPage );
510 }
511
512 docSvgFinishPage( (void *)sw, dc, bodyBi->biChildren[i],
513 lastPage, asLast );
514
515 return 0;
516 }
517
518 /************************************************************************/
519
docSvgSetDrawingContext(DrawingContext * dc,const LayoutContext * lc,int firstPage,int lastPage)520 static void docSvgSetDrawingContext( DrawingContext * dc,
521 const LayoutContext * lc,
522 int firstPage,
523 int lastPage )
524 {
525 INIT_LAYOUT_EXTERNAL initLayoutExternal= (INIT_LAYOUT_EXTERNAL)0;
526
527 dc->dcSetColorRgb= docSvgSetColorRgb;
528 dc->dcSetFont= docSvgSetFont;
529 dc->dcDrawShape= docSvgDrawDrawDrawingShape;
530 dc->dcDrawObject= docSvgDrawObject;
531 dc->dcDrawTab= docSvgDrawTab;
532 dc->dcDrawFtnsep= docSvgDrawFtnsep;
533 dc->dcDrawSpan= docSvgDrawSpan;
534
535 dc->dcDrawTextLine= docSvgDrawTextLine;
536 dc->dcDrawOrnaments= docSvgDrawOrnaments;
537 dc->dcFinishPage= docSvgFinishPage;
538 dc->dcStartPage= docSvgDrawStartPage;
539 dc->dcInitLayoutExternal= initLayoutExternal;
540
541 dc->dcLayoutContext= *lc;
542
543 dc->dcFirstPage= firstPage;
544 dc->dcLastPage= lastPage;
545 dc->dcDrawExternalItems= 1;
546 dc->dcPostponeHeadersFooters= 0;
547
548 return;
549 }
550
551
552 /************************************************************************/
553 /* */
554 /* Save a document as a SVG drawing. */
555 /* */
556 /************************************************************************/
557
docSvgDrawDocument(SimpleOutputStream * sos,const char * applicationName,const char * applicationReference,const LayoutContext * lc)558 int docSvgDrawDocument( SimpleOutputStream * sos,
559 const char * applicationName,
560 const char * applicationReference,
561 const LayoutContext * lc )
562 {
563 BufferDocument * bd= lc->lcDocument;
564 DocumentProperties * dp= &(bd->bdProperties);
565 DocumentGeometry * dg= &(dp->dpGeometry);
566 BufferItem * bodyBi= bd->bdBody.dtRoot;
567
568 DrawingContext dc;
569 SvgWriter sw;
570 XmlWriter * xw= &(sw.swXmlWriter);
571
572 docInitDrawingContext( &dc );
573 docSvgSetDrawingContext( &dc, lc, 0, bodyBi->biBelowPosition.lpPage );
574
575 svgInitSvgWriter( &sw );
576 sw.swXmlWriter.xwSos= sos;
577 strcpy( sw.swUnit, "pt" );
578 sw.swWide= ( dg->dgPageWideTwips+ 19 )/ 20;
579 sw.swHigh= ( dg->dgPageHighTwips+ 19 )/ 20;
580 sw.swViewBox.drX0= 0;
581 sw.swViewBox.drY0= 0;
582 sw.swViewBox.drX1= dg->dgPageWideTwips- 1;
583 sw.swViewBox.drY1= dg->dgPageHighTwips- 1;
584 sw.swMultiPage= dc.dcLastPage > dc.dcFirstPage;
585
586 docInquireHeadersFooters( &(dc.dcDocHasPageHeaders),
587 &(dc.dcDocHasPageFooters), bd );
588
589 svgStartDocument( &sw );
590
591 if ( sw.swMultiPage )
592 {
593 # if 0
594 xmlPutString( "<pageSet>", xw );
595 # else
596 xmlPutString( "<script type=\"text/ecmascript\"><![CDATA[", xw );
597 xmlNewLine( xw );
598 xmlPutString( "function switchPage( evt, fr, to ) {", xw );
599 xmlNewLine( xw );
600 xmlPutString( " var efr= document.getElementById( fr );", xw );
601 xmlNewLine( xw );
602 xmlPutString( " var eto= document.getElementById( to );", xw );
603 xmlNewLine( xw );
604 xmlPutString( " eto.removeAttribute( \"visibility\" );", xw );
605 xmlNewLine( xw );
606 xmlPutString( " efr.setAttribute( \"visibility\", \"hidden\" );", xw );
607 xmlNewLine( xw );
608 xmlPutString( "}", xw );
609 xmlNewLine( xw );
610 xmlPutString( "]]></script>", xw );
611 # endif
612 xmlNewLine( xw );
613 }
614
615 if ( docSvgDrawPageRange( &sw, &dc, bodyBi,
616 dc.dcFirstPage, dc.dcLastPage, /* asLast */ 1 ) )
617 { LDEB(dc.dcFirstPage); return -1; }
618
619 # if 0
620 if ( sw.swMultiPage )
621 {
622 xmlPutString( "</pageSet>", xw );
623 xmlNewLine( xw );
624 }
625 # endif
626
627 svgFinishDocument( &sw );
628
629 docResetExternalTreeLayout( bd );
630
631 return 0;
632 }
633
634 /************************************************************************/
635
docSvgSaveShapeObject(SimpleOutputStream * sos,int page,int pixelsWide,int pixelsHigh,const InsertedObject * io,BufferItem * bodySectNode,const LayoutContext * lc)636 int docSvgSaveShapeObject( SimpleOutputStream * sos,
637 int page,
638 int pixelsWide,
639 int pixelsHigh,
640 const InsertedObject * io,
641 BufferItem * bodySectNode,
642 const LayoutContext * lc )
643 {
644 int rval= 0;
645 const DrawingShape * ds= io->ioDrawingShape;
646
647 DrawingContext dc;
648 SvgWriter sw;
649 IndexSet attrUsed;
650 XmlWriter * xw= &(sw.swXmlWriter);
651
652 utilInitIndexSet( &attrUsed );
653
654 svgInitSvgWriter( &sw );
655
656 docInitDrawingContext( &dc );
657 docSvgSetDrawingContext( &dc, lc, page, page );
658
659 sw.swXmlWriter.xwSos= sos;
660
661 if ( docGetAttributesUsedInShape( lc->lcDocument, ds, &attrUsed ) )
662 { LDEB(1); rval= -1; goto ready; }
663
664 /* This is an independent image: Subtract the drawing origin */
665 docPlaceRootShapeRect( &(sw.swViewBox),
666 &(io->ioDrawingShape->dsShapeProperties),
667 io->ioX0Twips, io->ioY0Position.lpPageYTwips );
668 sw.swWide= pixelsWide;
669 sw.swHigh= pixelsHigh;
670
671 svgStartDocument( &sw );
672
673 xmlPutString( "<defs>", xw ); xmlNewLine( xw );
674 xmlPutString( " <style type=\"text/css\"><![CDATA[", xw );
675 xmlNewLine( xw );
676
677 docCssSaveTextAttributeStyles( xw->xwSos, &attrUsed, lc->lcDocument );
678
679 xmlPutString( "div { margin:-2px 0; }", xw ); xmlNewLine( xw );
680
681 xmlPutString( " ]]></style>", xw ); xmlNewLine( xw );
682 xmlPutString( "</defs>", xw ); xmlNewLine( xw );
683
684 if ( docDrawShape( &dc, &sw, bodySectNode, io ) )
685 { LDEB(1); rval= -1; goto ready;; }
686
687 svgFinishDocument( &sw );
688
689 ready:
690
691 utilCleanIndexSet( &attrUsed );
692
693 return rval;
694 }
695
696