1 #include <tools/stream.hxx>
2 #include <vcl/metaact.hxx>
3 #include <svtools/filter.hxx>
4 #include <basegfx/tools/canvastools.hxx>
5 #include <basegfx/tools/tools.hxx>
6 #include <basegfx/numeric/ftools.hxx>
7 #include <basegfx/point/b2dpoint.hxx>
8 #include <basegfx/vector/b2dsize.hxx>
9 #include <basegfx/range/b2drange.hxx>
10 #include <basegfx/range/b2drectangle.hxx>
11 #include <basegfx/polygon/b2dpolygon.hxx>
12 #include <basegfx/polygon/b2dpolypolygon.hxx>
13 #include <basegfx/polygon/b2dpolypolygontools.hxx>
14 #include <vcl/canvastools.hxx>
15 #include <rtl/ustring.hxx>
17 #include <com/sun/star/rendering/XCanvas.hpp>
18 #include <com/sun/star/rendering/TexturingMode.hpp>
19 #include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp>
21 #include <bitmapaction.hxx>
22 #include <implrenderer.hxx>
23 #include <outdevstate.hxx>
24 #include <polypolyaction.hxx>
25 #include <textaction.hxx>
27 #define EmfPlusRecordTypeHeader 16385
28 #define EmfPlusRecordTypeEndOfFile 16386
29 #define EmfPlusRecordTypeGetDC 16388
30 #define EmfPlusRecordTypeObject 16392
31 #define EmfPlusRecordTypeFillRects 16394
32 #define EmfPlusRecordTypeFillPolygon 16396
33 #define EmfPlusRecordTypeDrawLines 16397
34 #define EmfPlusRecordTypeFillPath 16404
35 #define EmfPlusRecordTypeDrawPath 16405
36 #define EmfPlusRecordTypeDrawImagePoints 16411
37 #define EmfPlusRecordTypeDrawString 16412
38 #define EmfPlusRecordTypeSetRenderingOrigin 16413
39 #define EmfPlusRecordTypeSetAntiAliasMode 16414
40 #define EmfPlusRecordTypeSetTextRenderingHint 16415
41 #define EmfPlusRecordTypeSetInterpolationMode 16417
42 #define EmfPlusRecordTypeSetPixelOffsetMode 16418
43 #define EmfPlusRecordTypeSetCompositingQuality 16420
44 #define EmfPlusRecordTypeSave 16421
45 #define EmfPlusRecordTypeSetWorldTransform 16426
46 #define EmfPlusRecordTypeResetWorldTransform 16427
47 #define EmfPlusRecordTypeSetPageTransform 16432
48 #define EmfPlusRecordTypeSetClipPath 16435
49 #define EmfPlusRecordTypeSetClipRegion 16436
50 #define EmfPlusRecordTypeDrawDriverString 16438
52 #define EmfPlusObjectTypeBrush 0x100
53 #define EmfPlusObjectTypePen 0x200
54 #define EmfPlusObjectTypePath 0x300
55 #define EmfPlusObjectTypeRegion 0x400
56 #define EmfPlusObjectTypeImage 0x500
57 #define EmfPlusObjectTypeFont 0x600
58 #define EmfPlusObjectTypeStringFormat 0x700
59 #define EmfPlusObjectTypeImageAttributes 0x800
61 #define EmfPlusRegionInitialStateRectangle 0x10000000
62 #define EmfPlusRegionInitialStatePath 0x10000001
63 #define EmfPlusRegionInitialStateEmpty 0x10000002
64 #define EmfPlusRegionInitialStateInfinite 0x10000003
67 //#define EMFP_DEBUG(x) x
69 using namespace ::com::sun::star
;
76 EMFP_DEBUG (void dumpWords (SvStream
& s
, int i
)
78 sal_uInt32 pos
= s
.Tell ();
82 printf ("EMF+\tdata: %04hX\n", data
);
91 struct EMFPPath
: public EMFPObject
93 ::basegfx::B2DPolyPolygon aPolygon
;
96 sal_uInt8
* pPointTypes
;
99 EMFPPath (sal_Int32 _nPoints
, bool bLines
= false)
101 if( _nPoints
<0 || _nPoints
>SAL_MAX_INT32
/(2*sizeof(float)) )
102 _nPoints
= SAL_MAX_INT32
/(2*sizeof(float));
104 pPoints
= new float [nPoints
*2];
106 pPointTypes
= new sal_uInt8
[_nPoints
];
114 delete [] pPointTypes
;
117 // TODO: remove rR argument when debug code is not longer needed
118 void Read (SvStream
& s
, UINT32 pathFlags
, ImplRenderer
& rR
)
120 for (int i
= 0; i
< nPoints
; i
++) {
121 if (pathFlags
& 0x4000) {
122 // points are stored in short 16bit integer format
126 EMFP_DEBUG (printf ("EMF+\tpoint [x,y]: %hd,%hd\n", x
, y
));
128 pPoints
[i
*2 + 1] = y
;
130 // points are stored in Single (float) format
131 s
>> pPoints
[i
*2] >> pPoints
[i
*2 + 1];
132 EMFP_DEBUG (printf ("EMF+\tpoint [x,y]: %f,%f\n", pPoints
[i
*2], pPoints
[i
*2 + 1]));
137 for (int i
= 0; i
< nPoints
; i
++) {
140 s
>> pPointTypes
[i
];
141 EMFP_DEBUG (printf ("EMF+\tpoint type: %x\n", pPointTypes
[i
]));
147 const ::basegfx::B2DRectangle
aBounds (::basegfx::tools::getRange (GetPolygon (rR
)));
148 EMFP_DEBUG (printf ("EMF+\tpolygon bounding box: %f,%f %fx%f (mapped)\n", aBounds
.getMinX (), aBounds
.getMinY (), aBounds
.getWidth (), aBounds
.getHeight ()));
151 ::basegfx::B2DPolyPolygon
& GetPolygon (ImplRenderer
& rR
, bool bMapIt
= true)
153 ::basegfx::B2DPolygon polygon
;
154 sal_Int32 points
= nPoints
;
158 int last_normal
= 0, p
= 0;
159 ::basegfx::B2DPoint prev
, mapped
;
160 bool hasPrev
= false;
161 for (int i
= 0; i
< nPoints
; i
++) {
162 if (p
&& pPointTypes
&& (pPointTypes
[i
] == 0)) {
163 aPolygon
.append (polygon
);
170 mapped
= rR
.Map (pPoints
[i
*2], pPoints
[i
*2 + 1]);
172 mapped
= ::basegfx::B2DPoint (pPoints
[i
*2], pPoints
[i
*2 + 1]);
173 //EMFP_DEBUG (printf ("polygon point: %f,%f mapped: %f,%f\n", pPoints [i*2], pPoints [i*2 + 1], mapped.getX (), mapped.getY ()));
175 if ((pPointTypes
[i
] & 0x07) == 3) {
176 if (((i
- last_normal
)% 3) == 1) {
177 polygon
.setNextControlPoint (p
- 1, mapped
);
179 } else if (((i
- last_normal
) % 3) == 2) {
187 polygon
.append (mapped
);
189 polygon
.setPrevControlPoint (p
, prev
);
193 if (pPointTypes
&& (pPointTypes
[i
] & 0x80)) { // closed polygon
194 polygon
.setClosed (true);
195 aPolygon
.append (polygon
);
202 if (polygon
.count ())
203 aPolygon
.append (polygon
);
209 struct EMFPRegion
: public EMFPObject
212 sal_Int32
*combineMode
;
213 sal_Int32 initialState
;
214 EMFPPath
*initialPath
;
215 float ix
, iy
, iw
, ih
;
226 delete [] combineMode
;
235 void Read (SvStream
& s
)
239 s
>> header
>> parts
;
241 EMFP_DEBUG (printf ("EMF+\tregion\n"));
242 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x parts: %d\n", header
, parts
));
245 if( parts
<0 || parts
>SAL_MAX_INT32
/sizeof(sal_Int32
) )
246 parts
= SAL_MAX_INT32
/sizeof(sal_Int32
);
248 combineMode
= new sal_Int32
[parts
];
250 for (int i
= 0; i
< parts
; i
++) {
251 s
>> combineMode
[i
];
252 EMFP_DEBUG (printf ("EMF+\tcombine mode [%d]: 0x%08x\n", i
, combineMode
[i
]));
257 EMFP_DEBUG (printf ("EMF+\tinitial state: 0x%08x\n", initialState
));
261 struct EMFPBrush
: public EMFPObject
265 sal_uInt32 additionalFlags
;
267 /* linear gradient */
269 float areaX
, areaY
, areaWidth
, areaHeight
;
270 ::Color secondColor
; // first color is stored in solidColor;
271 XForm transformation
;
272 bool hasTransformation
;
273 sal_Int32 blendPoints
;
274 float* blendPositions
;
276 sal_Int32 colorblendPoints
;
277 float* colorblendPositions
;
278 ::Color
* colorblendColors
;
279 sal_Int32 surroundColorsNumber
;
280 ::Color
* surroundColors
;
286 blendPositions
= NULL
;
287 colorblendPositions
= NULL
;
288 colorblendColors
= NULL
;
289 surroundColors
= NULL
;
291 hasTransformation
= false;
296 if (blendPositions
!= NULL
) {
297 delete[] blendPositions
;
298 blendPositions
= NULL
;
300 if (colorblendPositions
!= NULL
) {
301 delete[] colorblendPositions
;
302 colorblendPositions
= NULL
;
304 if (colorblendColors
!= NULL
) {
305 delete[] colorblendColors
;
306 colorblendColors
= NULL
;
308 if (surroundColors
!= NULL
) {
309 delete[] surroundColors
;
310 surroundColors
= NULL
;
318 UINT32
GetType () { return type
; }
319 const ::Color
& GetColor () { return solidColor
; }
321 void Read (SvStream
& s
, ImplRenderer
& rR
)
327 EMFP_DEBUG (printf ("EMF+\tbrush\nEMF+\theader: 0x%08x type: %d\n", header
, type
));
335 solidColor
= ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
336 EMFP_DEBUG (printf ("EMF+\tsolid color: 0x%08x\n", color
));
343 s
>> additionalFlags
>> wrapMode
;
345 EMFP_DEBUG (printf ("EMF+\tpath gradient, additional flags: 0x%02x\n", additionalFlags
));
350 solidColor
= ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
351 EMFP_DEBUG (printf ("EMF+\tcenter color: 0x%08x\n", color
));
354 EMFP_DEBUG (printf ("EMF+\tcenter point: %f,%f\n", areaX
, areaY
));
356 s
>> surroundColorsNumber
;
357 EMFP_DEBUG (printf ("EMF+\tsurround colors: %d\n", surroundColorsNumber
));
359 if( surroundColorsNumber
<0 || surroundColorsNumber
>SAL_MAX_INT32
/sizeof(::Color
) )
360 surroundColorsNumber
= SAL_MAX_INT32
/sizeof(::Color
);
362 surroundColors
= new ::Color
[surroundColorsNumber
];
363 for (int i
= 0; i
< surroundColorsNumber
; i
++) {
365 surroundColors
[i
] = ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
367 secondColor
= surroundColors
[0];
368 EMFP_DEBUG (printf ("EMF+\tsurround color[%d]: 0x%08x\n", i
, color
));
371 if (additionalFlags
& 0x01) {
372 sal_Int32 pathLength
;
375 EMFP_DEBUG (printf ("EMF+\tpath length: %d\n", pathLength
));
377 sal_uInt32 pos
= s
.Tell ();
378 EMFP_DEBUG (dumpWords (s
, 32));
380 sal_uInt32 pathHeader
;
381 sal_Int32 pathPoints
, pathFlags
;
382 s
>> pathHeader
>> pathPoints
>> pathFlags
;
384 EMFP_DEBUG (printf ("EMF+\tpath (brush path gradient)\n"));
385 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%08x\n", pathHeader
, pathPoints
, pathFlags
));
387 path
= new EMFPPath (pathPoints
);
388 path
->Read (s
, pathFlags
, rR
);
390 s
.Seek (pos
+ pathLength
);
392 const ::basegfx::B2DRectangle
aBounds (::basegfx::tools::getRange (path
->GetPolygon (rR
, false)));
393 areaWidth
= aBounds
.getWidth ();
394 areaHeight
= aBounds
.getHeight ();
396 EMFP_DEBUG (printf ("EMF+\tpolygon bounding box: %f,%f %fx%f\n", aBounds
.getMinX (), aBounds
.getMinY (), aBounds
.getWidth (), aBounds
.getHeight ()));
399 if (additionalFlags
& 0x02) {
400 EMFP_DEBUG (printf ("EMF+\tuse transformation\n", color
));
402 hasTransformation
= true;
403 EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
404 transformation
.eM11
, transformation
.eM12
,
405 transformation
.eM21
, transformation
.eM22
,
406 transformation
.eDx
, transformation
.eDy
));
408 if (additionalFlags
& 0x08) {
410 EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints
));
411 if( blendPoints
<0 || blendPoints
>SAL_MAX_INT32
/(2*sizeof(float)) )
412 blendPoints
= SAL_MAX_INT32
/(2*sizeof(float));
413 blendPositions
= new float [2*blendPoints
];
414 blendFactors
= blendPositions
+ blendPoints
;
415 for (int i
=0; i
< blendPoints
; i
++) {
416 s
>> blendPositions
[i
];
417 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i
, blendPositions
[i
]));
419 for (int i
=0; i
< blendPoints
; i
++) {
420 s
>> blendFactors
[i
];
421 EMFP_DEBUG (printf ("EMF+\tfactor[%d]: %f\n", i
, blendFactors
[i
]));
425 if (additionalFlags
& 0x04) {
426 s
>> colorblendPoints
;
427 EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints
));
428 if( colorblendPoints
<0 || colorblendPoints
>SAL_MAX_INT32
/sizeof(float) )
429 colorblendPoints
= SAL_MAX_INT32
/sizeof(float);
430 if( colorblendPoints
>SAL_MAX_INT32
/sizeof(::Color
) )
431 colorblendPoints
= SAL_MAX_INT32
/sizeof(::Color
);
432 colorblendPositions
= new float [colorblendPoints
];
433 colorblendColors
= new ::Color
[colorblendPoints
];
434 for (int i
=0; i
< colorblendPoints
; i
++) {
435 s
>> colorblendPositions
[i
];
436 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i
, colorblendPositions
[i
]));
438 for (int i
=0; i
< colorblendPoints
; i
++) {
440 colorblendColors
[i
] = ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
441 EMFP_DEBUG (printf ("EMF+\tcolor[%d]: 0x%08x\n", i
, color
));
445 EMFP_DEBUG (dumpWords (s
, 1024));
452 s
>> additionalFlags
>> wrapMode
;
454 EMFP_DEBUG (printf ("EMF+\tlinear gradient, additional flags: 0x%02x\n", additionalFlags
));
456 s
>> areaX
>> areaY
>> areaWidth
>> areaHeight
;
458 EMFP_DEBUG (printf ("EMF+\tarea: %f,%f - %fx%f\n", areaX
, areaY
, areaWidth
, areaHeight
));
463 solidColor
= ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
464 EMFP_DEBUG (printf ("EMF+\tfirst color: 0x%08x\n", color
));
467 secondColor
= ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
468 EMFP_DEBUG (printf ("EMF+\tsecond color: 0x%08x\n", color
));
470 // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
474 if (additionalFlags
& 0x02) {
475 EMFP_DEBUG (printf ("EMF+\tuse transformation\n", color
));
477 hasTransformation
= true;
478 EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
479 transformation
.eM11
, transformation
.eM12
,
480 transformation
.eM21
, transformation
.eM22
,
481 transformation
.eDx
, transformation
.eDy
));
483 if (additionalFlags
& 0x08) {
485 EMFP_DEBUG (printf ("EMF+\tuse blend, points: %d\n", blendPoints
));
486 if( blendPoints
<0 || blendPoints
>SAL_MAX_INT32
/(2*sizeof(float)) )
487 blendPoints
= SAL_MAX_INT32
/(2*sizeof(float));
488 blendPositions
= new float [2*blendPoints
];
489 blendFactors
= blendPositions
+ blendPoints
;
490 for (int i
=0; i
< blendPoints
; i
++) {
491 s
>> blendPositions
[i
];
492 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i
, blendPositions
[i
]));
494 for (int i
=0; i
< blendPoints
; i
++) {
495 s
>> blendFactors
[i
];
496 EMFP_DEBUG (printf ("EMF+\tfactor[%d]: %f\n", i
, blendFactors
[i
]));
500 if (additionalFlags
& 0x04) {
501 s
>> colorblendPoints
;
502 EMFP_DEBUG (printf ("EMF+\tuse color blend, points: %d\n", colorblendPoints
));
503 if( colorblendPoints
<0 || colorblendPoints
>SAL_MAX_INT32
/sizeof(float) )
504 colorblendPoints
= SAL_MAX_INT32
/sizeof(float);
505 if( colorblendPoints
>SAL_MAX_INT32
/sizeof(::Color
) )
506 colorblendPoints
= SAL_MAX_INT32
/sizeof(::Color
);
507 colorblendPositions
= new float [colorblendPoints
];
508 colorblendColors
= new ::Color
[colorblendPoints
];
509 for (int i
=0; i
< colorblendPoints
; i
++) {
510 s
>> colorblendPositions
[i
];
511 EMFP_DEBUG (printf ("EMF+\tposition[%d]: %f\n", i
, colorblendPositions
[i
]));
513 for (int i
=0; i
< colorblendPoints
; i
++) {
515 colorblendColors
[i
] = ::Color (0xff - (color
>> 24), (color
>> 16) & 0xff, (color
>> 8) & 0xff, color
& 0xff);
516 EMFP_DEBUG (printf ("EMF+\tcolor[%d]: 0x%08x\n", i
, color
));
523 EMFP_DEBUG (printf ("EMF+\tunhandled brush type: %d\n", type
));
528 struct EMFPPen
: public EMFPBrush
530 XForm transformation
;
539 sal_Int32 dashPatternLen
;
542 sal_Int32 compoundArrayLen
;
543 float *compoundArray
;
544 sal_Int32 customStartCapLen
;
545 sal_uInt8
*customStartCap
;
546 sal_Int32 customEndCapLen
;
547 sal_uInt8
*customEndCap
;
550 EMFPPen () : EMFPBrush ()
554 void SetStrokeAttributes (rendering::StrokeAttributes
& rStrokeAttributes
, ImplRenderer
& rR
, const OutDevState
& rState
)
556 rStrokeAttributes
.StrokeWidth
= (rState
.mapModeTransform
* rR
.MapSize (width
, 0)).getX ();
559 void Read (SvStream
& s
, ImplRenderer
& rR
, sal_Int32 nHDPI
, sal_Int32 nVDPI
)
561 UINT32 header
, unknown
, penFlags
, unknown2
;
564 s
>> header
>> unknown
>> penFlags
>> unknown2
>> width
;
566 EMFP_DEBUG (printf ("EMF+\tpen\nEMF+\theader: 0x%08x unknown: 0x%08x additional flags: 0x%08x unknown: 0x%08x width: %f\n", header
, unknown
, penFlags
, unknown2
, width
));
606 if (penFlags
& 256) {
608 if( dashPatternLen
<0 || dashPatternLen
>SAL_MAX_INT32
/sizeof(float) )
609 dashPatternLen
= SAL_MAX_INT32
/sizeof(float);
610 dashPattern
= new float [dashPatternLen
];
611 for (i
= 0; i
< dashPatternLen
; i
++)
612 s
>> dashPattern
[i
];
621 if (penFlags
& 1024) {
622 s
>> compoundArrayLen
;
623 if( compoundArrayLen
<0 || compoundArrayLen
>SAL_MAX_INT32
/sizeof(float) )
624 compoundArrayLen
= SAL_MAX_INT32
/sizeof(float);
625 compoundArray
= new float [compoundArrayLen
];
626 for (i
= 0; i
< compoundArrayLen
; i
++)
627 s
>> compoundArray
[i
];
629 compoundArrayLen
= 0;
631 if (penFlags
& 2048) {
632 s
>> customStartCapLen
;
633 if( customStartCapLen
<0 )
635 customStartCap
= new sal_uInt8
[customStartCapLen
];
636 for (i
= 0; i
< customStartCapLen
; i
++)
637 s
>> customStartCap
[i
];
639 customStartCapLen
= 0;
641 if (penFlags
& 4096) {
642 s
>> customEndCapLen
;
643 if( customEndCapLen
<0 )
645 customEndCap
= new sal_uInt8
[customEndCapLen
];
646 for (i
= 0; i
< customEndCapLen
; i
++)
647 s
>> customEndCap
[i
];
651 EMFPBrush::Read (s
, rR
);
655 struct EMFPImage
: public EMFPObject
661 sal_Int32 pixelFormat
;
665 void Read (SvMemoryStream
&s
)
667 sal_uInt32 header
, unknown
;
671 EMFP_DEBUG (printf ("EMF+\timage\nEMF+\theader: 0x%08x type: 0x%08x\n", header
, type
));
673 if (type
== 1) { // bitmap
674 s
>> width
>> height
>> stride
>> pixelFormat
>> unknown
;
675 EMFP_DEBUG (printf ("EMF+\tbitmap width: %d height: %d stride: %d pixelFormat: 0x%08x\n", width
, height
, stride
, pixelFormat
));
676 if (width
== 0) { // non native formats
677 GraphicFilter filter
;
679 filter
.ImportGraphic (graphic
, String (), s
);
680 EMFP_DEBUG (printf ("EMF+\tbitmap width: %d height: %d\n", graphic
.GetBitmap ().GetSizePixel ().Width (), graphic
.GetBitmap ().GetSizePixel ().Height ()));
683 } else if (type
== 2) {
684 sal_Int32 mfType
, mfSize
;
686 s
>> mfType
>> mfSize
;
687 EMFP_DEBUG (printf ("EMF+\tmetafile type: %d dataSize: %d\n", mfType
, mfSize
));
689 GraphicFilter filter
;
690 SvMemoryStream
mfStream (((char *)s
.GetData()) + s
.Tell(), mfSize
, STREAM_READ
);
692 filter
.ImportGraphic (graphic
, String (), mfStream
);
694 // debug code - write the stream to debug file /tmp/emf-stream.emf
695 EMFP_DEBUG(mfStream
.Seek(0);
696 SvFileStream
file( UniString::CreateFromAscii( "/tmp/emf-embedded-stream.emf" ), STREAM_WRITE
| STREAM_TRUNC
);
705 struct EMFPFont
: public EMFPObject
711 rtl::OUString family
;
713 void Read (SvMemoryStream
&s
)
719 s
>> header
>> emSize
>> sizeUnit
>> fontFlags
>> reserved
>> length
;
721 OSL_ASSERT( ( header
>> 12 ) == 0xdbc01 );
723 EMFP_DEBUG (printf ("EMF+\tfont\nEMF+\theader: 0x%08x version: 0x%08x size: %f unit: 0x%08x\n", header
>> 12, header
& 0x1fff, emSize
, sizeUnit
));
724 EMFP_DEBUG (printf ("EMF+\tflags: 0x%08x reserved: 0x%08x length: 0x%08x\n", fontFlags
, reserved
, length
));
726 if( length
> 0 && length
< 0x4000 ) {
727 sal_Unicode chars
[ length
];
729 for( int i
= 0; i
< length
; i
++ )
732 family
= ::rtl::OUString( chars
, length
);
733 EMFP_DEBUG (printf ("EMF+\tfamily: %s\n", rtl::OUStringToOString( family
, RTL_TEXTENCODING_UTF8
).getStr()));
738 void ImplRenderer::ReadRectangle (SvStream
& s
, float& x
, float& y
, float &width
, float& height
, sal_uInt32 flags
)
740 if (flags
& 0x4000) {
741 sal_Int16 ix
, iy
, iw
, ih
;
743 s
>> ix
>> iy
>> iw
>> ih
;
750 s
>> x
>> y
>> width
>> height
;
753 void ImplRenderer::ReadPoint (SvStream
& s
, float& x
, float& y
, sal_uInt32 flags
)
755 if (flags
& 0x4000) {
766 void ImplRenderer::MapToDevice (double& x
, double& y
)
769 x
= 100*nMmX
*x
/nPixX
;
770 y
= 100*nMmY
*y
/nPixY
;
773 ::basegfx::B2DPoint
ImplRenderer::Map (::basegfx::B2DPoint
& p
)
775 return Map (p
.getX (), p
.getY ());
778 ::basegfx::B2DPoint
ImplRenderer::Map (double ix
, double iy
)
782 x
= ix
*aWorldTransform
.eM11
+ iy
*aWorldTransform
.eM21
+ aWorldTransform
.eDx
;
783 y
= ix
*aWorldTransform
.eM12
+ iy
*aWorldTransform
.eM22
+ aWorldTransform
.eDy
;
790 x
*= aBaseTransform
.eM11
;
791 y
*= aBaseTransform
.eM22
;
793 return ::basegfx::B2DPoint (x
, y
);
796 ::basegfx::B2DSize
ImplRenderer::MapSize (double iwidth
, double iheight
)
800 w
= iwidth
*aWorldTransform
.eM11
+ iheight
*aWorldTransform
.eM21
;
801 h
= iwidth
*aWorldTransform
.eM12
+ iheight
*aWorldTransform
.eM22
;
805 w
*= aBaseTransform
.eM11
;
806 h
*= aBaseTransform
.eM22
;
808 return ::basegfx::B2DSize (w
, h
);
811 ::basegfx::B2DRange
ImplRenderer::MapRectangle (double ix
, double iy
, double iwidth
, double iheight
)
815 x
= ix
*aWorldTransform
.eM11
+ iy
*aWorldTransform
.eM21
+ aWorldTransform
.eDx
;
816 y
= ix
*aWorldTransform
.eM12
+ iy
*aWorldTransform
.eM22
+ aWorldTransform
.eDy
;
817 w
= iwidth
*aWorldTransform
.eM11
+ iheight
*aWorldTransform
.eM21
;
818 h
= iwidth
*aWorldTransform
.eM12
+ iheight
*aWorldTransform
.eM22
;
826 x
*= aBaseTransform
.eM11
;
827 y
*= aBaseTransform
.eM22
;
828 w
*= aBaseTransform
.eM11
;
829 h
*= aBaseTransform
.eM22
;
831 return ::basegfx::B2DRange (x
, y
, x
+ w
, y
+ h
);
835 ::vcl::unotools::colorToDoubleSequence( ::Color (0xff - (x >> 24), \
839 rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
840 #define SET_FILL_COLOR(x) \
841 rState.fillColor = COLOR(x);
842 #define SET_LINE_COLOR(x) \
843 rState.lineColor = COLOR(x);
844 #define SET_TEXT_COLOR(x) \
845 rState.textColor = COLOR(x);
847 void ImplRenderer::EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon
& polygon
, const ActionFactoryParameters
& rParms
,
848 OutDevState
& rState
, const CanvasSharedPtr
& rCanvas
, bool isColor
, sal_uInt32 brushIndexOrColor
)
850 ::basegfx::B2DPolyPolygon
localPolygon (polygon
);
852 EMFP_DEBUG (printf ("EMF+\tfill polygon\n"));
854 localPolygon
.transform( rState
.mapModeTransform
);
856 ActionSharedPtr pPolyAction
;
859 EMFP_DEBUG (printf ("EMF+\t\tcolor fill\n"));
861 rState
.isFillColorSet
= true;
862 rState
.isLineColorSet
= false;
863 SET_FILL_COLOR(brushIndexOrColor
);
865 pPolyAction
= ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon
, rParms
.mrCanvas
, rState
) );
868 rState
.isFillColorSet
= true;
870 EMFPBrush
* brush
= (EMFPBrush
*) aObjects
[brushIndexOrColor
];
871 EMFP_DEBUG (printf ("EMF+\tbrush fill slot: %d (type: %d)\n", brushIndexOrColor
, brush
->GetType ()));
873 // give up in case something wrong happened
877 rState
.isFillColorSet
= false;
878 rState
.isLineColorSet
= false;
880 if (brush
->type
== 3 || brush
->type
== 4) {
882 if (brush
->type
== 3 && !(brush
->additionalFlags
& 0x1))
883 return; // we are unable to parse these brushes yet
885 ::basegfx::B2DHomMatrix aTextureTransformation
;
886 ::basegfx::B2DHomMatrix aWorldTransformation
;
887 ::basegfx::B2DHomMatrix aBaseTransformation
;
888 rendering::Texture aTexture
;
889 double nRotation( 0.0 );
890 const ::basegfx::B2DRectangle
aBounds( ::basegfx::tools::getRange( localPolygon
) );
891 const double nScale( ::basegfx::pruneScaleValue( fabs( aBounds
.getHeight()*sin(nRotation
) ) +
892 fabs( aBounds
.getWidth()*cos(nRotation
) )));
894 aWorldTransformation
.set (0, 0, aWorldTransform
.eM11
);
895 aWorldTransformation
.set (0, 1, aWorldTransform
.eM21
);
896 aWorldTransformation
.set (0, 2, aWorldTransform
.eDx
);
897 aWorldTransformation
.set (1, 0, aWorldTransform
.eM12
);
898 aWorldTransformation
.set (1, 1, aWorldTransform
.eM22
);
899 aWorldTransformation
.set (1, 2, aWorldTransform
.eDy
);
901 aBaseTransformation
.set (0, 0, aBaseTransform
.eM11
);
902 aBaseTransformation
.set (0, 1, aBaseTransform
.eM21
);
903 aBaseTransformation
.set (0, 2, aBaseTransform
.eDx
);
904 aBaseTransformation
.set (1, 0, aBaseTransform
.eM12
);
905 aBaseTransformation
.set (1, 1, aBaseTransform
.eM22
);
906 aBaseTransformation
.set (1, 2, aBaseTransform
.eDy
);
908 if (brush
->type
== 4) {
909 aTextureTransformation
.scale (brush
->areaWidth
, brush
->areaHeight
);
910 aTextureTransformation
.translate (brush
->areaX
, brush
->areaY
);
912 aTextureTransformation
.translate (-0.5, -0.5);
913 aTextureTransformation
.scale (brush
->areaWidth
, brush
->areaHeight
);
914 aTextureTransformation
.translate (brush
->areaX
,brush
->areaY
);
917 if (brush
->hasTransformation
) {
918 ::basegfx::B2DHomMatrix aTransformation
;
920 aTransformation
.set (0, 0, brush
->transformation
.eM11
);
921 aTransformation
.set (0, 1, brush
->transformation
.eM21
);
922 aTransformation
.set (0, 2, brush
->transformation
.eDx
);
923 aTransformation
.set (1, 0, brush
->transformation
.eM12
);
924 aTransformation
.set (1, 1, brush
->transformation
.eM22
);
925 aTransformation
.set (1, 2, brush
->transformation
.eDy
);
927 aTextureTransformation
*= aTransformation
;
930 aTextureTransformation
*= aWorldTransformation
;
931 aTextureTransformation
.scale (100.0*nMmX
/nPixX
, 100.0*nMmY
/nPixY
);
932 aTextureTransformation
.translate (-nFrameLeft
, -nFrameTop
);
933 aTextureTransformation
*= rState
.mapModeTransform
;
934 aTextureTransformation
*= aBaseTransformation
;
936 aTexture
.RepeatModeX
= rendering::TexturingMode::CLAMP
;
937 aTexture
.RepeatModeY
= rendering::TexturingMode::CLAMP
;
938 aTexture
.Alpha
= 1.0;
940 uno::Reference
< rendering::XParametricPolyPolygon2DFactory
> xFactory(
941 rParms
.mrCanvas
->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
943 if( xFactory
.is() ) {
944 const uno::Sequence
< double > aStartColor(
945 ::vcl::unotools::colorToDoubleSequence( brush
->solidColor
,
946 rParms
.mrCanvas
->getUNOCanvas()->getDevice()->getDeviceColorSpace() ) );
947 const uno::Sequence
< double > aEndColor(
948 ::vcl::unotools::colorToDoubleSequence( brush
->secondColor
,
949 rParms
.mrCanvas
->getUNOCanvas()->getDevice()->getDeviceColorSpace() ) );
950 uno::Sequence
< uno::Sequence
< double > > aColors (2);
951 uno::Sequence
< double > aStops (2);
953 if (brush
->blendPositions
) {
954 EMFP_DEBUG (printf ("EMF+\t\tuse blend\n"));
955 aColors
.realloc (brush
->blendPoints
);
956 aStops
.realloc (brush
->blendPoints
);
957 int length
= aStartColor
.getLength ();
958 uno::Sequence
< double > aColor (length
);
960 OSL_ASSERT (length
== aEndColor
.getLength());
962 for (int i
= 0; i
< brush
->blendPoints
; i
++) {
963 aStops
[i
] = brush
->blendPositions
[i
];
965 for (int j
= 0; j
< length
; j
++) {
966 if (brush
->type
== 4) {
967 // // gamma correction
968 // if (brush->additionalFlags & 0x80)
969 // aColor [j] = pow (aStartColor [j]*(1 - brush->blendFactors[i]) + aEndColor [j]*brush->blendFactors[i], 1/2.2);
971 aColor
[j
] = aStartColor
[j
]*(1 - brush
->blendFactors
[i
]) + aEndColor
[j
]*brush
->blendFactors
[i
];
973 aColor
[j
] = aStartColor
[j
]*brush
->blendFactors
[i
] + aEndColor
[j
]*(1 - brush
->blendFactors
[i
]);
978 } else if (brush
->colorblendPositions
) {
979 EMFP_DEBUG (printf ("EMF+\t\tuse color blend\n"));
980 aColors
.realloc (brush
->colorblendPoints
);
981 aStops
.realloc (brush
->colorblendPoints
);
983 for (int i
= 0; i
< brush
->colorblendPoints
; i
++) {
984 aStops
[i
] = brush
->colorblendPositions
[i
];
985 aColors
[(brush
->type
== 4) ? i
: brush
->colorblendPoints
- 1 - i
] = ::vcl::unotools::colorToDoubleSequence( brush
->colorblendColors
[i
],
986 rParms
.mrCanvas
->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
992 if (brush
->type
== 4) {
993 aColors
[0] = aStartColor
;
994 aColors
[1] = aEndColor
;
996 aColors
[1] = aStartColor
;
997 aColors
[0] = aEndColor
;
1001 EMFP_DEBUG (printf ("EMF+\t\tset gradient\n"));
1002 if (brush
->type
== 4)
1003 aTexture
.Gradient
= xFactory
->createLinearHorizontalGradient( aColors
,
1006 geometry::RealRectangle2D
aBoundsRectangle (0, 0, 1, 1);
1007 aTexture
.Gradient
= xFactory
->createEllipticalGradient( aColors
,
1013 ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture
.AffineTransform
,
1014 aTextureTransformation
);
1017 ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon
,
1026 EMFP_DEBUG (printf ("EMF+\t\tadd poly action\n"));
1028 maActions
.push_back(
1031 rParms
.mrCurrActionIndex
) );
1033 rParms
.mrCurrActionIndex
+= pPolyAction
->getActionCount()-1;
1037 void ImplRenderer::processObjectRecord(SvMemoryStream
& rObjectStream
, UINT16 flags
)
1042 EMFP_DEBUG (printf ("EMF+ Object slot: %hd flags: %hx\n", flags
& 0xff, flags
& 0xff00));
1044 index
= flags
& 0xff;
1045 if (aObjects
[index
] != NULL
) {
1046 delete aObjects
[index
];
1047 aObjects
[index
] = NULL
;
1050 switch (flags
& 0x7f00) {
1051 case EmfPlusObjectTypeBrush
:
1054 aObjects
[index
] = brush
= new EMFPBrush ();
1055 brush
->Read (rObjectStream
, *this);
1059 case EmfPlusObjectTypePen
:
1062 aObjects
[index
] = pen
= new EMFPPen ();
1063 pen
->Read (rObjectStream
, *this, nHDPI
, nVDPI
);
1067 case EmfPlusObjectTypePath
:
1068 sal_uInt32 header
, pathFlags
;
1071 rObjectStream
>> header
>> points
>> pathFlags
;
1073 EMFP_DEBUG (printf ("EMF+\tpath\n"));
1074 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x points: %d additional flags: 0x%08x\n", header
, points
, pathFlags
));
1077 aObjects
[index
] = path
= new EMFPPath (points
);
1078 path
->Read (rObjectStream
, pathFlags
, *this);
1081 case EmfPlusObjectTypeRegion
: {
1084 aObjects
[index
] = region
= new EMFPRegion ();
1085 region
->Read (rObjectStream
);
1089 case EmfPlusObjectTypeImage
:
1092 aObjects
[index
] = image
= new EMFPImage ();
1093 image
->Read (rObjectStream
);
1097 case EmfPlusObjectTypeFont
:
1100 aObjects
[index
] = font
= new EMFPFont ();
1101 font
->Read (rObjectStream
);
1106 EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags
& 0xff00));
1111 void ImplRenderer::processEMFPlus( MetaCommentAction
* pAct
, const ActionFactoryParameters
& rFactoryParms
,
1112 OutDevState
& rState
, const CanvasSharedPtr
& rCanvas
)
1114 sal_uInt32 length
= pAct
->GetDataSize ();
1115 SvMemoryStream
rMF ((void*) pAct
->GetData (), length
, STREAM_READ
);
1119 while (length
> 0) {
1121 UINT32 size
, dataSize
;
1124 rMF
>> type
>> flags
>> size
>> dataSize
;
1126 next
= rMF
.Tell() + ( size
- 12 );
1128 EMFP_DEBUG (printf ("EMF+ record size: %d type: %04hx flags: %04hx data size: %d\n", size
, type
, flags
, dataSize
));
1130 if (type
== EmfPlusRecordTypeObject
&& (mbMultipart
&& flags
& 0x7fff == mMFlags
& 0x7fff || flags
& 0x8000)) {
1137 // 1st 4 bytes are unknown
1138 mMStream
.Write (((const char *)rMF
.GetData()) + rMF
.Tell() + 4, dataSize
- 4);
1139 EMFP_DEBUG (printf ("EMF+ read next object part size: %d type: %04hx flags: %04hx data size: %d\n", size
, type
, flags
, dataSize
));
1142 EMFP_DEBUG (printf ("EMF+ multipart record flags: %04hx\n", mMFlags
));
1144 processObjectRecord (mMStream
, mMFlags
);
1146 mbMultipart
= false;
1149 if (type
!= EmfPlusRecordTypeObject
|| !(flags
& 0x8000))
1151 case EmfPlusRecordTypeHeader
:
1152 UINT32 header
, version
;
1154 rMF
>> header
>> version
>> nHDPI
>> nVDPI
;
1156 EMFP_DEBUG (printf ("EMF+ Header\n"));
1157 EMFP_DEBUG (printf ("EMF+\theader: 0x%08x version: %d horizontal DPI: %d vertical DPI: %d dual: %d\n", header
, version
, nHDPI
, nVDPI
, flags
& 1));
1160 case EmfPlusRecordTypeEndOfFile
:
1161 EMFP_DEBUG (printf ("EMF+ EndOfFile\n"));
1163 case EmfPlusRecordTypeGetDC
:
1164 EMFP_DEBUG (printf ("EMF+ GetDC\n"));
1165 EMFP_DEBUG (printf ("EMF+\talready used in svtools wmf/emf filter parser\n"));
1167 case EmfPlusRecordTypeObject
:
1168 processObjectRecord (rMF
, flags
);
1170 case EmfPlusRecordTypeFillPath
:
1172 sal_uInt32 index
= flags
& 0xff;
1173 sal_uInt32 brushIndexOrColor
;
1175 rMF
>> brushIndexOrColor
;
1177 EMFP_DEBUG (printf ("EMF+ FillPath slot: %d\n", index
));
1179 EMFPPlusFillPolygon (((EMFPPath
*) aObjects
[index
])->GetPolygon (*this), rFactoryParms
, rState
, rCanvas
, flags
& 0x8000, brushIndexOrColor
);
1182 case EmfPlusRecordTypeFillRects
:
1184 EMFP_DEBUG (printf ("EMF+ FillRects\n"));
1186 sal_uInt32 brushIndexOrColor
;
1187 sal_Int32 rectangles
;
1188 ::basegfx::B2DPolygon polygon
;
1190 rMF
>> brushIndexOrColor
>> rectangles
;
1192 EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags
& 0x8000) ? "color" : "brush index", brushIndexOrColor
));
1194 for (int i
=0; i
< rectangles
; i
++) {
1195 if (flags
& 0x4000) {
1196 /* 16bit integers */
1197 sal_Int16 x
, y
, width
, height
;
1199 rMF
>> x
>> y
>> width
>> height
;
1201 polygon
.append (Map (x
, y
));
1202 polygon
.append (Map (x
+ width
, y
));
1203 polygon
.append (Map (x
+ width
, y
+ height
));
1204 polygon
.append (Map (x
, y
+ height
));
1206 EMFP_DEBUG (printf ("EMF+\trectangle: %d,%d %dx%d\n", x
, y
, width
, height
));
1209 float x
, y
, width
, height
;
1211 rMF
>> x
>> y
>> width
>> height
;
1213 polygon
.append (Map (x
, y
));
1214 polygon
.append (Map (x
+ width
, y
));
1215 polygon
.append (Map (x
+ width
, y
+ height
));
1216 polygon
.append (Map (x
, y
+ height
));
1218 EMFP_DEBUG (printf ("EMF+\trectangle: %f,%f %fx%f\n", x
, y
, width
, height
));
1221 ::basegfx::B2DPolyPolygon
polyPolygon (polygon
);
1223 EMFPPlusFillPolygon (polyPolygon
, rFactoryParms
, rState
, rCanvas
, flags
& 0x8000, brushIndexOrColor
);
1227 case EmfPlusRecordTypeFillPolygon
:
1229 sal_uInt8 index
= flags
& 0xff;
1230 sal_uInt32 brushIndexOrColor
;
1231 sal_Int32 brushIndex
;
1234 USHORT transparency
= 0;
1236 rMF
>> brushIndexOrColor
;
1239 EMFP_DEBUG (printf ("EMF+ FillPolygon in slot: %d points: %d\n", index
, points
));
1240 EMFP_DEBUG (printf ("EMF+\twith solid color (ARGB): 0x%08X\n", color
));
1242 EMFPPath
path (points
, true);
1243 path
.Read (rMF
, flags
, *this);
1246 EMFPPlusFillPolygon (path
.GetPolygon (*this), rFactoryParms
, rState
, rCanvas
, flags
& 0x8000, brushIndexOrColor
);
1250 case EmfPlusRecordTypeDrawLines
:
1252 sal_uInt32 index
= flags
& 0xff;
1257 EMFP_DEBUG (printf ("EMF+ DrawLines in slot: %d points: %d\n", index
, points
));
1259 EMFPPath
path (points
, true);
1260 path
.Read (rMF
, flags
, *this);
1262 EMFPPen
* pen
= (EMFPPen
*) aObjects
[index
];
1264 rState
.isFillColorSet
= false;
1265 rState
.isLineColorSet
= true;
1266 rState
.lineColor
= ::vcl::unotools::colorToDoubleSequence (pen
->GetColor (),
1267 rCanvas
->getUNOCanvas ()->getDevice()->getDeviceColorSpace() );
1268 ::basegfx::B2DPolyPolygon
& polygon (path
.GetPolygon (*this));
1270 polygon
.transform( rState
.mapModeTransform
);
1272 rendering::StrokeAttributes aStrokeAttributes
;
1274 pen
->SetStrokeAttributes (aStrokeAttributes
, *this, rState
);
1276 ActionSharedPtr
pPolyAction(
1277 internal::PolyPolyActionFactory::createPolyPolyAction(
1278 polygon
, rFactoryParms
.mrCanvas
, rState
, aStrokeAttributes
) );
1282 maActions
.push_back(
1285 rFactoryParms
.mrCurrActionIndex
) );
1287 rFactoryParms
.mrCurrActionIndex
+= pPolyAction
->getActionCount()-1;
1292 case EmfPlusRecordTypeDrawPath
:
1298 EMFP_DEBUG (printf ("EMF+ DrawPath\n"));
1299 EMFP_DEBUG (printf ("EMF+\tpen: %d\n", penIndex
));
1301 EMFPPath
* path
= (EMFPPath
*) aObjects
[flags
& 0xff];
1302 EMFPPen
* pen
= (EMFPPen
*) aObjects
[penIndex
];
1304 rState
.isFillColorSet
= false;
1305 rState
.isLineColorSet
= true;
1306 rState
.lineColor
= ::vcl::unotools::colorToDoubleSequence (pen
->GetColor (),
1307 rCanvas
->getUNOCanvas ()->getDevice()->getDeviceColorSpace());
1308 ::basegfx::B2DPolyPolygon
& polygon (path
->GetPolygon (*this));
1310 polygon
.transform( rState
.mapModeTransform
);
1311 rendering::StrokeAttributes aStrokeAttributes
;
1313 pen
->SetStrokeAttributes (aStrokeAttributes
, *this, rState
);
1315 ActionSharedPtr
pPolyAction(
1316 internal::PolyPolyActionFactory::createPolyPolyAction(
1317 polygon
, rFactoryParms
.mrCanvas
, rState
, aStrokeAttributes
) );
1321 maActions
.push_back(
1324 rFactoryParms
.mrCurrActionIndex
) );
1326 rFactoryParms
.mrCurrActionIndex
+= pPolyAction
->getActionCount()-1;
1330 case EmfPlusRecordTypeDrawImagePoints
:
1332 sal_uInt32 attrIndex
;
1333 sal_Int32 sourceUnit
;
1335 rMF
>> attrIndex
>> sourceUnit
;
1337 EMFP_DEBUG (printf ("EMF+ DrawImagePoints attributes index: %d source unit: %d\n", attrIndex
, sourceUnit
));
1338 EMFP_DEBUG (printf ("EMF+\tTODO: use image attributes\n"));
1340 if (sourceUnit
== 2 && aObjects
[flags
& 0xff]) { // we handle only GraphicsUnit.Pixel now
1341 EMFPImage
& image
= *(EMFPImage
*) aObjects
[flags
& 0xff];
1342 float sx
, sy
, sw
, sh
;
1345 ReadRectangle (rMF
, sx
, sy
, sw
, sh
);
1349 EMFP_DEBUG (printf ("EMF+ DrawImagePoints source rectangle: %f,%f %fx%f unknown: 0x%08x\n", sx
, sy
, sw
, sh
, unknown
));
1351 if (unknown
== 3) { // it probably means number of points defining destination rectangle
1352 float x1
, y1
, x2
, y2
, x3
, y3
;
1354 ReadPoint (rMF
, x1
, y1
);
1355 ReadPoint (rMF
, x2
, y2
);
1356 ReadPoint (rMF
, x3
, y3
);
1358 BitmapEx
aBmp( image
.graphic
.GetBitmapEx () );
1359 const Rectangle
aCropRect (::vcl::unotools::pointFromB2DPoint (Map (sx
, sy
)),
1360 ::vcl::unotools::sizeFromB2DSize (MapSize(sw
, sh
)));
1361 aBmp
.Crop( aCropRect
);
1364 ActionSharedPtr
pBmpAction (
1365 internal::BitmapActionFactory::createBitmapAction (
1367 rState
.mapModeTransform
* Map (x1
, y1
),
1368 rState
.mapModeTransform
* MapSize(x2
- x1
, y3
- y1
),
1373 maActions
.push_back( MtfAction( pBmpAction
,
1374 rFactoryParms
.mrCurrActionIndex
) );
1376 rFactoryParms
.mrCurrActionIndex
+= pBmpAction
->getActionCount()-1;
1379 EMFP_DEBUG (printf ("EMF+ DrawImagePoints TODO (fixme)\n"));
1383 case EmfPlusRecordTypeDrawString
:
1384 EMFP_DEBUG (printf ("EMF+ DrawString\n"));
1385 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1387 case EmfPlusRecordTypeSetPageTransform
:
1390 EMFP_DEBUG (printf ("EMF+ SetPageTransform\n"));
1391 EMFP_DEBUG (printf ("EMF+\tscale: %f unit: %d\n", fPageScale
, flags
));
1392 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1394 case EmfPlusRecordTypeSetRenderingOrigin
:
1395 rMF
>> nOriginX
>> nOriginY
;
1396 EMFP_DEBUG (printf ("EMF+ SetRenderingOrigin\n"));
1397 EMFP_DEBUG (printf ("EMF+\torigin [x,y]: %d,%d\n", nOriginX
, nOriginY
));
1399 case EmfPlusRecordTypeSetTextRenderingHint
:
1400 EMFP_DEBUG (printf ("EMF+ SetTextRenderingHint\n"));
1401 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1403 case EmfPlusRecordTypeSetAntiAliasMode
:
1404 EMFP_DEBUG (printf ("EMF+ SetAntiAliasMode\n"));
1405 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1407 case EmfPlusRecordTypeSetInterpolationMode
:
1408 EMFP_DEBUG (printf ("EMF+ InterpolationMode\n"));
1409 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1411 case EmfPlusRecordTypeSetPixelOffsetMode
:
1412 EMFP_DEBUG (printf ("EMF+ SetPixelOffsetMode\n"));
1413 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1415 case EmfPlusRecordTypeSetCompositingQuality
:
1416 EMFP_DEBUG (printf ("EMF+ SetCompositingQuality\n"));
1417 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1419 case EmfPlusRecordTypeSave
:
1420 EMFP_DEBUG (printf ("EMF+ Save\n"));
1421 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1423 case EmfPlusRecordTypeSetWorldTransform
: {
1424 EMFP_DEBUG (printf ("EMF+ SetWorldTransform\n"));
1427 aWorldTransform
.Set (transform
);
1428 EMFP_DEBUG (printf ("EMF+\tm11: %f m12: %f\nEMF+\tm21: %f m22: %f\nEMF+\tdx: %f dy: %f\n",
1429 aWorldTransform
.eM11
, aWorldTransform
.eM12
,
1430 aWorldTransform
.eM21
, aWorldTransform
.eM22
,
1431 aWorldTransform
.eDx
, aWorldTransform
.eDy
));
1434 case EmfPlusRecordTypeResetWorldTransform
:
1435 EMFP_DEBUG (printf ("EMF+ ResetWorldTransform\n"));
1436 aWorldTransform
.SetIdentity ();
1438 case EmfPlusRecordTypeSetClipPath
:
1440 EMFP_DEBUG (printf ("EMF+ SetClipPath\n"));
1441 EMFP_DEBUG (printf ("EMF+\tpath in slot: %d\n", flags
& 0xff));
1443 EMFPPath
& path
= *(EMFPPath
*) aObjects
[flags
& 0xff];
1444 ::basegfx::B2DPolyPolygon
& clipPoly (path
.GetPolygon (*this));
1446 clipPoly
.transform (rState
.mapModeTransform
);
1447 updateClipping (clipPoly
, rFactoryParms
, false);
1451 case EmfPlusRecordTypeSetClipRegion
: {
1452 EMFP_DEBUG (printf ("EMF+ SetClipRegion\n"));
1453 EMFP_DEBUG (printf ("EMF+\tregion in slot: %d combine mode: %d\n", flags
& 0xff, (flags
& 0xff00) >> 8));
1454 EMFPRegion
& region
= *(EMFPRegion
*) aObjects
[flags
& 0xff];
1457 if (region
.parts
== 0 && region
.initialState
== EmfPlusRegionInitialStateInfinite
) {
1458 updateClipping (::basegfx::B2DPolyPolygon (), rFactoryParms
, false);
1460 EMFP_DEBUG (printf ("EMF+\tTODO\n"));
1463 case EmfPlusRecordTypeDrawDriverString
: {
1464 EMFP_DEBUG (printf ("EMF+ DrawDriverString, flags: 0x%04x\n", flags
));
1465 sal_uInt32 brushIndexOrColor
;
1466 sal_uInt32 optionFlags
;
1467 sal_uInt32 hasMatrix
;
1468 sal_uInt32 glyphsCount
;
1470 rMF
>> brushIndexOrColor
>> optionFlags
>> hasMatrix
>> glyphsCount
;
1472 EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags
& 0x8000) ? "color" : "brush index", brushIndexOrColor
));
1473 EMFP_DEBUG (printf ("EMF+\toption flags: 0x%08x\n", optionFlags
));
1474 EMFP_DEBUG (printf ("EMF+\thas matrix: %d\n", hasMatrix
));
1475 EMFP_DEBUG (printf ("EMF+\tglyphs: %d\n", glyphsCount
));
1477 if( ( optionFlags
& 1 ) && glyphsCount
> 0 ) {
1478 sal_uInt16 chars
[ glyphsCount
];
1479 float charsPosX
[ glyphsCount
];
1480 float charsPosY
[ glyphsCount
];
1482 for( int i
=0; i
<glyphsCount
; i
++) {
1484 EMFP_DEBUG (printf ("EMF+\tglyph[%d]: 0x%04x\n",
1487 for( int i
=0; i
<glyphsCount
; i
++) {
1488 rMF
>> charsPosX
[i
] >> charsPosY
[i
];
1489 EMFP_DEBUG (printf ("EMF+\tglyphPosition[%d]: %f, %f\n", i
, charsPosX
[i
], charsPosY
[i
]));
1495 EMFP_DEBUG (printf ("EMF+\tmatrix:: %f, %f, %f, %f, %f, %f\n", transform
.eM11
, transform
.eM12
, transform
.eM21
, transform
.eM22
, transform
.eDx
, transform
.eDy
));
1498 // create and add the text action
1499 XubString
text( chars
, glyphsCount
);
1501 EMFPFont
*font
= (EMFPFont
*) aObjects
[ flags
& 0xff ];
1503 rendering::FontRequest aFontRequest
;
1504 aFontRequest
.FontDescription
.FamilyName
= font
->family
;
1505 aFontRequest
.CellSize
= (rState
.mapModeTransform
*MapSize( font
->emSize
, 0 )).getX();
1506 rState
.xFont
= rFactoryParms
.mrCanvas
->getUNOCanvas()->createFont( aFontRequest
,
1507 uno::Sequence
< beans::PropertyValue
>(),
1508 geometry::Matrix2D() );
1509 if( flags
& 0x8000 )
1510 SET_TEXT_COLOR(brushIndexOrColor
);
1512 ActionSharedPtr
pTextAction(
1513 TextActionFactory::createTextAction(
1514 ::vcl::unotools::pointFromB2DPoint ( Map( charsPosX
[0], charsPosY
[0] ) ),
1523 rFactoryParms
.mrVDev
,
1524 rFactoryParms
.mrCanvas
,
1526 rFactoryParms
.mrParms
,
1531 EMFP_DEBUG (printf ("EMF+\t\tadd text action\n"));
1533 maActions
.push_back(
1536 rFactoryParms
.mrCurrActionIndex
) );
1538 rFactoryParms
.mrCurrActionIndex
+= pTextAction
->getActionCount()-1;
1541 EMFP_DEBUG (printf ("EMF+\tTODO: fonts (non-unicode glyphs chars)\n"));
1547 EMFP_DEBUG (printf ("EMF+ unhandled record type: %d\n", type
));
1548 EMFP_DEBUG (printf ("EMF+\tTODO\n"));