1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: epict.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include <vcl/metaact.hxx>
35 #include <svtools/filter.hxx>
36 #include <svtools/solar.hrc>
37 #include <svtools/fltcall.hxx>
40 #include <vcl/bmpacc.hxx>
41 #include <vcl/metaact.hxx>
42 #include <vcl/graph.hxx>
43 #include <vcl/bmpacc.hxx>
44 #include <vcl/gradient.hxx>
45 #include <vcl/hatch.hxx>
46 #include <vcl/metric.hxx>
47 #include <vcl/font.hxx>
48 #include <vcl/virdev.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/msgbox.hxx>
51 #include <vcl/gdimtf.hxx>
53 #include <tools/bigint.hxx>
54 #include "strings.hrc"
55 #include "dlgepct.hrc"
56 #include "dlgepct.hxx"
58 //============================== PictWriter ===================================
60 struct PictWriterAttrStackMember
{
61 struct PictWriterAttrStackMember
* pSucc
;
71 enum PictDrawingMethod
{
72 PDM_FRAME
, PDM_PAINT
, PDM_ERASE
, PDM_INVERT
, PDM_FILL
86 ULONG nLastPercent
; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
87 com::sun::star::uno::Reference
< com::sun::star::task::XStatusIndicator
> xStatusIndicator
;
91 // Aktuelle Attribute im Quell-Metafile:
94 RasterOp eSrcRasterOp
;
97 MapMode aTargetMapMode
;
99 PictWriterAttrStackMember
* pAttrStack
;
101 // Aktuelle Attribute im Ziel-Metafile, und ob sie gueltig sind
102 BOOL bDstBkPatVisible
; BOOL bDstBkPatValid
;
103 BYTE nDstTxFace
; BOOL bDstTxFaceValid
;
104 RasterOp eDstTxMode
; BOOL bDstTxModeValid
;
105 USHORT nDstPnSize
; BOOL bDstPnSizeValid
;
106 RasterOp eDstPnMode
; BOOL bDstPnModeValid
;
107 PictPattern aDstPnPat
; BOOL bDstPnPatValid
;
108 BOOL bDstFillPatVisible
; BOOL bDstFillPatValid
;
109 USHORT nDstTxSize
; BOOL bDstTxSizeValid
;
110 Color aDstFgCol
; BOOL bDstFgColValid
;
111 Color aDstBkCol
; BOOL bDstBkColValid
;
112 Point aDstPenPosition
; BOOL bDstPenPositionValid
;
113 Point aDstTextPosition
; BOOL bDstTextPositionValid
;
114 String aDstFontName
; USHORT nDstFontNameId
; BOOL bDstFontNameValid
;
116 ULONG nNumberOfActions
; // Anzahl der Actions im GDIMetafile
117 ULONG nNumberOfBitmaps
; // Anzahl der Bitmaps
118 ULONG nWrittenActions
; // Anzahl der bereits verarbeiteten Actions beim Schreiben der Opcodes
119 ULONG nWrittenBitmaps
; // Anzahl der bereits geschriebenen Bitmaps
120 ULONG nActBitmapPercent
; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
123 // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
124 // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
127 void CountActionsAndBitmaps(const GDIMetaFile
& rMTF
);
128 // Zaehlt die Bitmaps und Actions (nNumberOfActions und nNumberOfBitmaps muessen
129 // zu Anfang auf 0 gesetzt werden, weil diese Methode rekursiv ist)
131 Polygon
PolyPolygonToPolygon(const PolyPolygon
& rPoly
);
132 // Macht aus einem PolyPolygon ein halbwegs vernuenftiges Polygon
134 Rectangle
MapRectangle( const Rectangle
& rRect
);
135 void WritePoint(const Point
& rPoint
);
136 void WriteSize(const Size
& rSize
);
137 void WriteRGBColor(const Color
& rColor
);
138 void WriteString( const String
& rString
);
139 void WriteRectangle(const Rectangle
& rRect
);
140 void WritePolygon(const Polygon
& rPoly
);
141 void WriteArcAngles(const Rectangle
& rRect
, const Point
& rStartPt
, const Point
& rEndPt
);
143 void ConvertLinePattern(PictPattern
& rPat
, BOOL bVisible
);
144 void ConvertFillPattern(PictPattern
& rPat
, BOOL bVisible
);
146 void WriteOpcode_TxFace(const Font
& rFont
);
147 void WriteOpcode_TxMode(RasterOp eMode
);
148 void WriteOpcode_PnSize(USHORT nSize
);
149 void WriteOpcode_PnMode(RasterOp eMode
);
150 void WriteOpcode_PnLinePat(BOOL bVisible
);
151 void WriteOpcode_PnFillPat(BOOL bVisible
);
152 void WriteOpcode_OvSize(const Size
& rSize
);
153 void WriteOpcode_TxSize(USHORT nSize
);
154 void WriteOpcode_RGBFgCol(const Color
& rColor
);
155 void WriteOpcode_RGBBkCol(const Color
& rColor
);
156 void WriteOpcode_Line(const Point
& rLocPt
, const Point
& rNewPt
);
157 void WriteOpcode_LineFrom(const Point
& rNewPt
);
158 void WriteOpcode_Text(const Point
& rPoint
, const String
& rString
, BOOL bDelta
);
159 void WriteOpcode_FontName(const Font
& rFont
);
160 void WriteOpcode_ClipRect( const Rectangle
& rRect
);
161 void WriteOpcode_Rect(PictDrawingMethod eMethod
, const Rectangle
& rRect
);
162 void WriteOpcode_SameRect(PictDrawingMethod eMethod
);
163 void WriteOpcode_RRect(PictDrawingMethod eMethod
, const Rectangle
& rRect
);
164 void WriteOpcode_SameRRect(PictDrawingMethod eMethod
);
165 void WriteOpcode_Oval(PictDrawingMethod eMethod
, const Rectangle
& rRect
);
166 void WriteOpcode_SameOval(PictDrawingMethod eMethod
);
167 void WriteOpcode_Arc(PictDrawingMethod eMethod
, const Rectangle
& rRect
,
168 const Point
& rStartPt
, const Point
& rEndPt
);
169 void WriteOpcode_SameArc(PictDrawingMethod eMethod
, const Rectangle
& rRect
,
170 const Point
& rStartPt
, const Point
& rEndPt
);
171 void WriteOpcode_Poly(PictDrawingMethod eMethod
, const Polygon
& rPoly
);
172 void WriteOpcode_BitsRect(const Point
& rPoint
, const Size
& rSize
, const Bitmap
& rBitmap
);
173 void WriteOpcode_EndOfFile();
175 void SetAttrForPaint();
176 void SetAttrForFrame();
177 void SetAttrForText();
179 void WriteTextArray(Point
& rPoint
, const String
& rString
, const sal_Int32
* pDXAry
);
181 void WriteOpcodes(const GDIMetaFile
& rMTF
);
183 void WriteHeader(const GDIMetaFile
& rMTF
);
188 BOOL
WritePict( const GDIMetaFile
& rMTF
, SvStream
& rTargetStream
, FilterConfigItem
* pFilterConfigItem
);
192 //========================== Methoden von PictWriter ==========================
195 void PictWriter::MayCallback()
197 if ( xStatusIndicator
.is() )
200 nPercent
=((nWrittenBitmaps
<<14)+(nActBitmapPercent
<<14)/100+nWrittenActions
)
202 /((nNumberOfBitmaps
<<14)+nNumberOfActions
);
204 if (nPercent
>=nLastPercent
+3)
206 nLastPercent
=nPercent
;
208 xStatusIndicator
->setValue( nPercent
);
213 void PictWriter::CountActionsAndBitmaps(const GDIMetaFile
& rMTF
)
215 ULONG nAction
, nActionCount
;
216 const MetaAction
* pMA
;
218 nActionCount
= rMTF
.GetActionCount();
220 for (nAction
=0; nAction
<nActionCount
; nAction
++)
222 pMA
= rMTF
.GetAction( nAction
);
224 switch( pMA
->GetType() )
226 case META_BMP_ACTION
:
227 case META_BMPSCALE_ACTION
:
228 case META_BMPSCALEPART_ACTION
:
229 case META_BMPEX_ACTION
:
230 case META_BMPEXSCALE_ACTION
:
231 case META_BMPEXSCALEPART_ACTION
:
241 Polygon
PictWriter::PolyPolygonToPolygon(const PolyPolygon
& rPolyPoly
)
243 USHORT nCount
,nSize1
,nSize2
,np
,i1
,i2
,i3
,nBestIdx1
,nBestIdx2
;
244 long nDistSqr
,nBestDistSqr
, nCountdownTests
;
246 Polygon aPoly1
, aPoly2
, aPoly3
;
248 nCount
=rPolyPoly
.Count();
249 if (nCount
==0) return Polygon(0);
251 aPoly1
=rPolyPoly
.GetObject(0);
252 for (np
=1; np
<nCount
; np
++) {
253 aPoly2
=rPolyPoly
.GetObject(np
);
255 //-----------------Folgendes verschmilzt aPoly1 und aPoly2 zu aPoly1-----------------
257 nSize1
=aPoly1
.GetSize();
258 nSize2
=aPoly2
.GetSize();
260 // Zunaechst werden ein Punkt in aPoly1 (referenziert durch nBestIdx1) und ein
261 // Punkt in aPoly2 (referenziert durch nBestIdx2) gesucht, die moeglichst dicht
262 // beieinander liegen. Da dies mit quadratischem Aufwand einher geht, und somit
263 // manche Bilder Ewigkeiten benoetigen, um exportiert zu werden, begrenzen wir
264 // die Anzahl der Tests auf 1000, und brechen die Suche ggf. schon vorher ab.
265 // Dadruch wird das Ergebnis nicht falsch, sondern eventuell nicht so schoen.
266 nCountdownTests
=1000;
267 nBestDistSqr
=0x7fffffff;
270 for (i1
=0; i1
<nSize1
; i1
++) {
271 aP1
=aPoly1
.GetPoint(i1
);
272 for (i2
=0; i2
<nSize2
; i2
++) {
273 aPRel
=aPoly2
.GetPoint(i2
); aPRel
-=aP1
;
274 nDistSqr
=aPRel
.X()*aPRel
.X()+aPRel
.Y()*aPRel
.Y();
275 if (nDistSqr
<nBestDistSqr
) {
278 nBestDistSqr
=nDistSqr
;
280 if (nCountdownTests
<=0) break;
283 if (nCountdownTests
<=0) break;
286 // Nun werden aPoly1 und aPoly2 zu einem Polygon aPoly3 (spaeter aPoly1) zusammengefuegt.
287 // Die beiden Polygone werden verbunden durch zwei zusaetzliche Kanten zwischen den oben
288 // gefundenen Punkten.
290 aPoly3
.SetSize(nSize1
+nSize2
+2);
292 for (i1
=nBestIdx1
; i1
<nSize1
; i1
++) aPoly3
.SetPoint(aPoly1
.GetPoint(i1
),i3
++);
293 for (i1
=0; i1
<=nBestIdx1
; i1
++) aPoly3
.SetPoint(aPoly1
.GetPoint(i1
),i3
++);
294 for (i2
=nBestIdx2
; i2
<nSize2
; i2
++) aPoly3
.SetPoint(aPoly2
.GetPoint(i2
),i3
++);
295 for (i2
=0; i2
<=nBestIdx2
; i2
++) aPoly3
.SetPoint(aPoly2
.GetPoint(i2
),i3
++);
299 //-----------------------------------------------------------------------------------
306 void PictWriter::WritePoint(const Point
& rPoint
)
308 Point aPoint
= OutputDevice::LogicToLogic( rPoint
, aSrcMapMode
, aTargetMapMode
);
309 *pPict
<< ((short)aPoint
.Y()) << ((short)aPoint
.X());
313 void PictWriter::WriteSize(const Size
& rSize
)
315 OutputDevice::LogicToLogic( rSize
, aSrcMapMode
, aTargetMapMode
); // -Wall is this needed.
316 *pPict
<< ((short)rSize
.Height()) << ((short)rSize
.Width());
320 void PictWriter::WriteRGBColor(const Color
& rColor
)
322 const UINT16 nR
= ( (UINT16
) rColor
.GetRed() << 8 ) | (UINT16
) rColor
.GetRed();
323 const UINT16 nG
= ( (UINT16
) rColor
.GetGreen() << 8 ) | (UINT16
) rColor
.GetGreen();
324 const UINT16 nB
= ( (UINT16
) rColor
.GetBlue() << 8 ) | (UINT16
) rColor
.GetBlue();
326 *pPict
<< nR
<< nG
<< nB
;
330 void PictWriter::WriteString( const String
& rString
)
334 ByteString
aByteString( rString
, gsl_getSystemTextEncoding() );
335 nLen
= aByteString
.Len();
338 *pPict
<< ( (BYTE
)nLen
);
339 for ( i
= 0; i
< nLen
; i
++ )
340 *pPict
<< aByteString
.GetChar( i
);
343 Rectangle
PictWriter::MapRectangle( const Rectangle
& rRect
)
345 Point aPoint
= OutputDevice::LogicToLogic( rRect
.TopLeft(), aSrcMapMode
, aTargetMapMode
);
346 Size aSize
= OutputDevice::LogicToLogic( rRect
.GetSize(), aSrcMapMode
, aTargetMapMode
);
347 Rectangle
aRect( aPoint
, aSize
);
354 void PictWriter::WriteRectangle(const Rectangle
& rRect
)
356 Rectangle
aRect( MapRectangle( rRect
) );
357 *pPict
<< (sal_Int16
)aRect
.Top() << (sal_Int16
)aRect
.Left()
358 << (sal_Int16
)aRect
.Bottom() << (sal_Int16
)aRect
.Right();
361 void PictWriter::WritePolygon(const Polygon
& rPoly
)
363 USHORT nDataSize
,i
,nSize
;
364 short nMinX
= 0, nMinY
= 0, nMaxX
= 0, nMaxY
= 0;
366 Polygon
aPoly(rPoly
);
368 nSize
=aPoly
.GetSize();
370 if (aPoly
.GetPoint(0) != aPoly
.GetPoint(nSize
-1))
373 aPoly
.SetSize(nSize
);
374 aPoly
.SetPoint(aPoly
.GetPoint(0),nSize
-1);
377 nDataSize
=nSize
*4+10;
378 for (i
=0; i
<nSize
; i
++)
380 Point aPoint
= OutputDevice::LogicToLogic( aPoly
.GetPoint( i
),
384 nx
= (short) aPoint
.X();
385 ny
= (short) aPoint
.Y();
387 if ( i
==0 || nMinX
>nx
)
389 if ( i
==0 || nMinY
>ny
)
391 if ( i
==0 || nMaxX
<nx
)
393 if ( i
==0 || nMaxY
<ny
)
397 *pPict
<< nDataSize
<< nMinY
<< nMinX
<< nMaxY
<< nMaxX
;
399 for (i
=0; i
<nSize
; i
++)
400 WritePoint( aPoly
.GetPoint(i
) );
404 void PictWriter::WriteArcAngles(const Rectangle
& rRect
, const Point
& rStartPt
, const Point
& rEndPt
)
406 Point aStartPt
= OutputDevice::LogicToLogic( rStartPt
,
409 Point aEndPt
= OutputDevice::LogicToLogic( rEndPt
,
412 Rectangle
aRect( OutputDevice::LogicToLogic( rRect
.TopLeft(),
415 OutputDevice::LogicToLogic( rRect
.GetSize(),
419 double fAngS
, fAngE
, fdx
, fdy
;
420 short nStartAngle
, nArcAngle
;
423 aCenter
=Point( ( aRect
.Left() + aRect
.Right() ) >> 1,
424 ( aRect
.Top() + aRect
.Bottom() ) >> 1 );
426 fdx
=(double)(aStartPt
.X()-aCenter
.X());
427 fdy
=(double)(aStartPt
.Y()-aCenter
.Y());
428 if ( fdx
==0.0 && fdy
==0.0 )
430 fAngE
=atan2(fdx
,-fdy
);
432 fdx
=(double)(aEndPt
.X()-aCenter
.X());
433 fdy
=(double)(aEndPt
.Y()-aCenter
.Y());
434 if ( fdx
==0.0 && fdy
==0.0 )
436 fAngS
=atan2(fdx
,-fdy
);
438 nStartAngle
=(short)(fAngS
*180.0/3.14159265359);
439 nArcAngle
=((short)(fAngE
*180.0/3.14159265359))-nStartAngle
;
442 *pPict
<< nStartAngle
<< nArcAngle
;
446 void PictWriter::ConvertLinePattern(PictPattern
& rPat
, BOOL bVisible
)
460 void PictWriter::ConvertFillPattern(PictPattern
& rPat
, BOOL bVisible
)
475 void PictWriter::WriteOpcode_TxFace(const Font
& rFont
)
481 eWeight
=rFont
.GetWeight();
482 if (eWeight
==WEIGHT_BOLD
||
483 eWeight
==WEIGHT_SEMIBOLD
||
484 eWeight
==WEIGHT_ULTRABOLD
||
485 eWeight
==WEIGHT_BLACK
) nFace
|=0x01;
486 if (rFont
.GetItalic()!=ITALIC_NONE
) nFace
|=0x02;
487 if (rFont
.GetUnderline()!=UNDERLINE_NONE
) nFace
|=0x04;
488 if (rFont
.IsOutline()==TRUE
) nFace
|=0x08;
489 if (rFont
.IsShadow()==TRUE
) nFace
|=0x10;
491 if (bDstTxFaceValid
==FALSE
|| nDstTxFace
!=nFace
) {
492 *pPict
<< (USHORT
)0x0004 << nFace
<< (BYTE
)0;
494 bDstTxFaceValid
=TRUE
;
499 void PictWriter::WriteOpcode_TxMode(RasterOp eMode
)
503 if (bDstTxModeValid
==FALSE
|| eDstTxMode
!=eMode
) {
505 case ROP_INVERT
: nVal
=0x000c; break;
506 case ROP_XOR
: nVal
=0x000a; break;
507 default: nVal
=0x0008;
509 *pPict
<< (USHORT
)0x0005 << nVal
;
511 bDstTxModeValid
=TRUE
;
516 void PictWriter::WriteOpcode_PnSize(USHORT nSize
)
518 if (nSize
==0) nSize
=1;
519 if (bDstPnSizeValid
==FALSE
|| nDstPnSize
!=nSize
) {
520 *pPict
<< (USHORT
)0x0007 << nSize
<< nSize
;
522 bDstPnSizeValid
=TRUE
;
527 void PictWriter::WriteOpcode_PnMode(RasterOp eMode
)
531 if (bDstPnModeValid
==FALSE
|| eDstPnMode
!=eMode
) {
534 case ROP_INVERT
: nVal
=0x000c; break;
535 case ROP_XOR
: nVal
=0x000a; break;
536 default: nVal
=0x0008;
538 *pPict
<< (USHORT
)0x0008 << nVal
;
540 bDstPnModeValid
=TRUE
;
545 void PictWriter::WriteOpcode_PnLinePat(BOOL bVisible
)
549 ConvertLinePattern(aPat
,bVisible
);
550 if (bDstPnPatValid
==FALSE
|| aDstPnPat
.nHi
!=aPat
.nHi
|| aDstPnPat
.nLo
!=aPat
.nLo
) {
551 *pPict
<< (USHORT
)0x0009 << aPat
.nHi
<< aPat
.nLo
;
558 void PictWriter::WriteOpcode_PnFillPat(BOOL bVisible
)
562 ConvertFillPattern(aPat
,bVisible
);
563 if (bDstPnPatValid
==FALSE
|| aDstPnPat
.nHi
!=aPat
.nHi
|| aDstPnPat
.nLo
!=aPat
.nLo
) {
564 *pPict
<< (USHORT
)0x0009 << aPat
.nHi
<< aPat
.nLo
;
571 void PictWriter::WriteOpcode_OvSize(const Size
& rSize
)
573 *pPict
<< (USHORT
)0x000b;
578 void PictWriter::WriteOpcode_TxSize(USHORT nSize
)
580 if (bDstTxSizeValid
==FALSE
|| nDstTxSize
!=nSize
) {
582 nDstTxSize
= (USHORT
) OutputDevice::LogicToLogic( Size( 0, nSize
),
583 aSrcMapMode
, aTargetMapMode
).Height();
585 *pPict
<< (USHORT
)0x000d << nDstTxSize
;
586 bDstTxSizeValid
=TRUE
;
591 void PictWriter::WriteOpcode_RGBFgCol(const Color
& rColor
)
593 if (bDstFgColValid
==FALSE
|| aDstFgCol
!=rColor
) {
594 *pPict
<< (USHORT
)0x001a;
595 WriteRGBColor(rColor
);
602 void PictWriter::WriteOpcode_RGBBkCol(const Color
& rColor
)
604 if (bDstBkColValid
==FALSE
|| aDstBkCol
!=rColor
) {
605 *pPict
<< (USHORT
)0x001b;
606 WriteRGBColor(rColor
);
613 void PictWriter::WriteOpcode_Line(const Point
& rLocPt
, const Point
& rNewPt
)
615 Point aLocPt
= OutputDevice::LogicToLogic( rLocPt
,
618 Point aNewPt
= OutputDevice::LogicToLogic( rNewPt
,
623 dh
=aNewPt
.X()-aLocPt
.X();
624 dv
=aNewPt
.Y()-aLocPt
.Y();
625 if (dh
<=127 && dh
>=-128 && dv
<=127 && dv
>=-128)
627 *pPict
<< (USHORT
)0x0022;
629 *pPict
<< (char)dh
<< (char)dv
;
633 *pPict
<< (USHORT
)0x0020;
637 aDstPenPosition
=rNewPt
;
638 bDstPenPositionValid
=TRUE
;
642 void PictWriter::WriteOpcode_LineFrom(const Point
& rNewPt
)
644 Point aNewPt
= OutputDevice::LogicToLogic( rNewPt
,
649 dh
= aNewPt
.X()-aDstPenPosition
.X();
650 dv
= aNewPt
.Y()-aDstPenPosition
.Y();
652 if (dh
<=127 && dh
>=-128 && dv
<=127 && dv
>=-128)
654 *pPict
<< (USHORT
)0x0023;
655 *pPict
<< (char)dh
<< (char)dv
;
659 *pPict
<< (USHORT
)0x0021;
662 aDstPenPosition
=rNewPt
;
663 bDstPenPositionValid
=TRUE
;
667 void PictWriter::WriteOpcode_Text(const Point
& rPoint
, const String
& rString
, BOOL bDelta
)
669 Point aPoint
= OutputDevice::LogicToLogic( rPoint
,
675 nPos
= pPict
->Tell();
676 dh
= aPoint
.X()-aDstTextPosition
.X();
677 dv
= aPoint
.Y()-aDstTextPosition
.Y();
679 if (bDstTextPositionValid
==FALSE
|| dh
<0 || dh
>255 || dv
<0 || dv
>0 || bDelta
==FALSE
)
681 *pPict
<< (USHORT
)0x0028;
686 *pPict
<< (USHORT
)0x0029 << (BYTE
)dh
;
690 *pPict
<< (USHORT
)0x002a << (BYTE
)dv
;
694 *pPict
<< (USHORT
)0x002b << (BYTE
)dh
<< (BYTE
)dv
;
697 WriteString( rString
);
698 if (((pPict
->Tell()-nPos
)&1)!=0)
701 aDstTextPosition
= aPoint
;
702 bDstTextPositionValid
=TRUE
;
706 void PictWriter::WriteOpcode_FontName(const Font
& rFont
)
708 USHORT nDataLen
,nFontId
;
710 switch (rFont
.GetFamily()) {
711 case FAMILY_MODERN
: nFontId
=22; break;
712 case FAMILY_ROMAN
: nFontId
=20; break;
713 case FAMILY_SWISS
: nFontId
=21; break;
717 if (bDstFontNameValid
==FALSE
|| nDstFontNameId
!=nFontId
|| aDstFontName
!=rFont
.GetName())
719 ByteString
aByteString( rFont
.GetName(), gsl_getSystemTextEncoding() );
720 sal_uInt16 nFontNameLen
= aByteString
.Len();
723 nDataLen
= 3 + nFontNameLen
;
724 *pPict
<< (USHORT
)0x002c << nDataLen
<< nFontId
;
725 WriteString( rFont
.GetName() );
726 if ( ( nFontNameLen
& 1 ) == 0 )
729 *pPict
<< (USHORT
)0x0003 << nFontId
;
730 aDstFontName
=rFont
.GetName();
731 nDstFontNameId
=nFontId
;
732 bDstFontNameValid
=TRUE
;
736 void PictWriter::WriteOpcode_ClipRect( const Rectangle
& rRect
)
738 Rectangle
aRect( MapRectangle( rRect
) );
741 *pPict
<< (sal_uInt16
)1 // opcode 1
742 << (sal_uInt16
)10 // data size
743 << (sal_Int16
)aRect
.Top() << (sal_Int16
)aRect
.Left()
744 << (sal_Int16
)aRect
.Bottom() << (sal_Int16
)aRect
.Right();
748 void PictWriter::WriteOpcode_Rect(PictDrawingMethod eMethod
, const Rectangle
& rRect
)
752 case PDM_FRAME
: oc
=0x0030; break;
753 case PDM_PAINT
: oc
=0x0031; break;
754 case PDM_ERASE
: oc
=0x0032; break;
755 case PDM_INVERT
: oc
=0x0033; break;
756 case PDM_FILL
: oc
=0x0034; break;
757 default: oc
=0; break; // -Wall a default for oc...
760 WriteRectangle(rRect
);
764 void PictWriter::WriteOpcode_SameRect(PictDrawingMethod eMethod
)
768 case PDM_FRAME
: oc
=0x0038; break;
769 case PDM_PAINT
: oc
=0x0039; break;
770 case PDM_ERASE
: oc
=0x003a; break;
771 case PDM_INVERT
: oc
=0x003b; break;
772 case PDM_FILL
: oc
=0x003c; break;
773 default: oc
=0; break; // -Wall a default for oc...
779 void PictWriter::WriteOpcode_RRect(PictDrawingMethod eMethod
, const Rectangle
& rRect
)
783 case PDM_FRAME
: oc
=0x0040; break;
784 case PDM_PAINT
: oc
=0x0041; break;
785 case PDM_ERASE
: oc
=0x0042; break;
786 case PDM_INVERT
: oc
=0x0043; break;
787 case PDM_FILL
: oc
=0x0044; break;
788 default: oc
=0; break; // -Wall a default for oc...
791 WriteRectangle(rRect
);
795 void PictWriter::WriteOpcode_SameRRect(PictDrawingMethod eMethod
)
799 case PDM_FRAME
: oc
=0x0048; break;
800 case PDM_PAINT
: oc
=0x0049; break;
801 case PDM_ERASE
: oc
=0x004a; break;
802 case PDM_INVERT
: oc
=0x004b; break;
803 case PDM_FILL
: oc
=0x004c; break;
804 default: oc
=0; break; // -Wall a default for oc...
810 void PictWriter::WriteOpcode_Oval(PictDrawingMethod eMethod
, const Rectangle
& rRect
)
814 case PDM_FRAME
: oc
=0x0050; break;
815 case PDM_PAINT
: oc
=0x0051; break;
816 case PDM_ERASE
: oc
=0x0052; break;
817 case PDM_INVERT
: oc
=0x0053; break;
818 case PDM_FILL
: oc
=0x0054; break;
819 default: oc
=0; break; // -Wall a default for oc...
822 WriteRectangle(rRect
);
826 void PictWriter::WriteOpcode_SameOval(PictDrawingMethod eMethod
)
830 case PDM_FRAME
: oc
=0x0058; break;
831 case PDM_PAINT
: oc
=0x0059; break;
832 case PDM_ERASE
: oc
=0x005a; break;
833 case PDM_INVERT
: oc
=0x005b; break;
834 case PDM_FILL
: oc
=0x005c; break;
835 default: oc
=0; break; // -Wall a default for oc...
841 void PictWriter::WriteOpcode_Arc(PictDrawingMethod eMethod
, const Rectangle
& rRect
,
842 const Point
& rStartPt
, const Point
& rEndPt
)
846 case PDM_FRAME
: oc
=0x0060; break;
847 case PDM_PAINT
: oc
=0x0061; break;
848 case PDM_ERASE
: oc
=0x0062; break;
849 case PDM_INVERT
: oc
=0x0063; break;
850 case PDM_FILL
: oc
=0x0064; break;
851 default: oc
=0; break; // -Wall a default for oc...
854 WriteRectangle(rRect
);
855 WriteArcAngles(rRect
,rStartPt
,rEndPt
);
859 void PictWriter::WriteOpcode_SameArc(PictDrawingMethod eMethod
, const Rectangle
& rRect
,
860 const Point
& rStartPt
, const Point
& rEndPt
)
864 case PDM_FRAME
: oc
=0x0068; break;
865 case PDM_PAINT
: oc
=0x0069; break;
866 case PDM_ERASE
: oc
=0x006a; break;
867 case PDM_INVERT
: oc
=0x006b; break;
868 case PDM_FILL
: oc
=0x006c; break;
869 default: oc
=0; break; // -Wall a default for oc...
872 WriteArcAngles(rRect
,rStartPt
,rEndPt
);
876 void PictWriter::WriteOpcode_Poly(PictDrawingMethod eMethod
, const Polygon
& rPoly
)
880 if (rPoly
.GetSize()<3) return;
882 case PDM_FRAME
: oc
=0x0070; break;
883 case PDM_PAINT
: oc
=0x0071; break;
884 case PDM_ERASE
: oc
=0x0072; break;
885 case PDM_INVERT
: oc
=0x0073; break;
886 case PDM_FILL
: oc
=0x0074; break;
887 default: oc
=0; break; // -Wall a default for oc...
894 void PictWriter::WriteOpcode_BitsRect(const Point
& rPoint
, const Size
& rSize
, const Bitmap
& rBitmap
)
896 BitmapReadAccess
* pAcc
= NULL
;
897 Bitmap
aBitmap( rBitmap
);
899 ULONG nWidth
, nHeight
, nDstRowBytes
, nx
, nc
, ny
, nCount
, nColTabSize
, i
;
900 ULONG nDstRowPos
, nSrcRowBytes
, nEqu3
, nPos
, nDstMapPos
;
901 USHORT nBitsPerPixel
, nPackType
;
902 BYTE
*pComp
[4], *pPix
, *pTemp
;
904 BYTE nFlagCounterByte
, nRed
, nGreen
, nBlue
;
908 // temopraere Windows-BMP-Datei erzeugen:
909 nActBitmapPercent
=30;
912 if ( bStatus
== FALSE
)
914 if ( ( pAcc
= aBitmap
.AcquireReadAccess() ) == NULL
)
917 nBitsPerPixel
= aBitmap
.GetBitCount();
919 // export code below only handles four discrete cases
921 nBitsPerPixel
<= 1 ? 1 : nBitsPerPixel
<= 4 ? 4 : nBitsPerPixel
<= 8 ? 8 : 24;
923 nWidth
= pAcc
->Width();
924 nHeight
= pAcc
->Height();
926 // Wenn 24-Bit, dann den Opcode 'DirectBitsRect' erzeugen:
927 if ( nBitsPerPixel
== 24 )
930 // Anzahl Bytes einer (ungepackten) Zeile in Quelle und Ziel berechnen:
931 nSrcRowBytes
=( ( 3 * nWidth
) + 0x0003 ) & 0xfffc;
932 nDstRowBytes
= nWidth
* 4;
934 // Opcode und BaseAddr (?) schreiben:
935 *pPict
<< (USHORT
)0x009a << (sal_uInt32
)0x000000ff;
937 // Normalerweise wollen wir den Packing-Type 4 (Run length encoding
938 // for 32-Bit Pixels) erzeugen. Wenn aber RowBytes<8 gilt, sind die Daten
939 // grundsaetzlich ungepackt, auch wenn der Packing-Type 4 angegeben ist,
940 // was etwas komisch erscheint. Daher wollen wir in so einem Fall lieber
941 // gleich den Packing-Type 1 (ungepackt) angeben:
943 if ( nDstRowBytes
< 8 )
948 // PixMap-Struktur schreiben:
949 *pPict
<< (USHORT
)(nDstRowBytes
|0x8000) // Bytes pro Zeile und dass es eine 'PixMap' ist
950 << (USHORT
)0x0000 // Y1-Position der Bitmap in der Quelle
951 << (USHORT
)0x0000 // X1-Position der Bitmap in der Quelle
952 << (USHORT
)nHeight
// Y2-Position der Bitmap in der Quelle
953 << (USHORT
)nWidth
// X2-Position der Bitmap in der Quelle
954 << (USHORT
)0x0000 // Version
955 << (USHORT
)nPackType
// Packing type
956 << (sal_uInt32
) 0x00000000 // Packing size (?)
957 << (sal_uInt32
) 0x00480000 // H-Res
958 << (sal_uInt32
) 0x00480000 // V-Res
959 << (USHORT
)0x0010 // Pixel type (?)
960 << (USHORT
)0x0020 // Pixel size: 32 bit
961 << (USHORT
)0x0004 // CmpCount: 4 Komponenten
962 << (USHORT
)0x0008 // CmpSize: 8 Bits
963 << (sal_uInt32
) 0x00000000 // PlaneBytes (?)
964 << (sal_uInt32
) 0x00000000 // (?)
965 << (sal_uInt32
) 0x00000000; // (?)
967 // Source-Rectangle schreiben:
968 *pPict
<< (USHORT
)0x0000 // Y1-Position auf der Bitmap
969 << (USHORT
)0x0000 // X1-Position auf der Bitmap
970 << (USHORT
)nHeight
// Y2-Position auf der Bitmap
971 << (USHORT
)nWidth
; // X2-Position auf der Bitmap
973 // Destination-Rectangle schreiben:
974 WritePoint( rPoint
);
975 WritePoint( Point( rPoint
.X() + rSize
.Width(), rPoint
.Y() + rSize
.Height() ) );
977 // Transfer mode schreiben:
978 *pPict
<< (USHORT
)0x0000; // (?)
980 // Position der Map-Daten in Ziel merken:
981 nDstMapPos
=pPict
->Tell();
983 if ( nPackType
== 1 ) // bei 24 bits nWidth == 1 !!
985 for ( ny
= 0; ny
< nHeight
; ny
++ )
988 *pPict
<< (BYTE
)pAcc
->GetPixel( ny
, 0 ).GetRed();
989 *pPict
<< (BYTE
)pAcc
->GetPixel( ny
, 0 ).GetGreen();
990 *pPict
<< (BYTE
)pAcc
->GetPixel( ny
, 0 ).GetBlue();
991 // Prozente zaehlen, Callback, Fehler pruefen:
992 nActBitmapPercent
= ( ny
* 70 / nHeight
) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
996 else // packen ( PackType == 4 )
998 // Speicher fuer Zeilen-Zwischen-Datenstruktur allozieren:
999 for ( nc
= 0; nc
< 4; nc
++ )
1000 pComp
[ nc
] = new BYTE
[ nWidth
];
1002 // Schleife ueber Zeilen:
1003 for ( ny
= 0; ny
< nHeight
; ny
++ )
1005 // Zeil ny der Quelle in die Zwischen-Datenstrktur einlesen:
1007 for ( nx
= 0; nx
< nWidth
; nx
++ )
1009 pComp
[ 1 ][ nx
] = (BYTE
)pAcc
->GetPixel( ny
, nx
) .GetRed();
1010 pComp
[ 2 ][ nx
] = (BYTE
)pAcc
->GetPixel( ny
, nx
) .GetGreen();
1011 pComp
[ 3 ][ nx
] = (BYTE
)pAcc
->GetPixel( ny
, nx
) .GetBlue();
1012 pComp
[ 0 ][ nx
] = 0;
1015 // Anfang der Zeile im Ziel merken:
1016 nDstRowPos
= pPict
->Tell();
1018 // ByteCount (das ist die Groesse der gepackten Zeile) zunaechst 0 (wird spaeter berichtigt):
1019 if ( nDstRowBytes
> 250 )
1020 *pPict
<< (USHORT
)0;
1024 // Schleife ueber Componenten:
1025 for ( nc
= 0; nc
< 4; nc
++ )
1027 // Schleife ueber x:
1029 while ( nx
< nWidth
)
1031 // Die Position von 3 gleichen Bytes suchen und in nEqu3 merken.
1032 // wenn nicht gefunden, dann nEqu3=nWidth setzten.
1033 // Wenn doch gefunden, dann in nEquData den Wert der Bytes merken.
1037 if ( nEqu3
+ 2 >= nWidth
)
1042 nEquData
= pComp
[nc
][nEqu3
];
1043 if ( nEquData
== pComp
[nc
][nEqu3
+1] && nEquData
==pComp
[nc
][nEqu3
+2] )
1048 // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1049 while ( nEqu3
> nx
)
1051 nCount
= nEqu3
- nx
;
1054 nFlagCounterByte
= (BYTE
)(nCount
-1);
1055 *pPict
<< nFlagCounterByte
;
1058 *pPict
<< pComp
[nc
][nx
++];
1061 while ( nCount
> 0 );
1064 // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1065 // gleiche Bytes gefunden):
1067 { // Hinweis: es gilt nx==nEqu3 (hoffentlich)
1068 nCount
=3; // Drei Bytes sind gleich, wie weiter oben herausgefunden.
1069 // Pruefen, ob es weitere gleiche Bytes gibts (dabei Max.-Record-Groesse beachten):
1070 while ( nx
+ nCount
< nWidth
&& nCount
< 128 )
1072 if ( nEquData
!= pComp
[ nc
][ nx
+ nCount
] )
1076 // nCount gleiche Bytes komprimiert schreiben:
1077 nFlagCounterByte
= (BYTE
)( 1 - (long)nCount
);
1078 *pPict
<< nFlagCounterByte
<< nEquData
;
1083 // ByteCount berichtigen:
1084 nPos
= pPict
->Tell();
1085 pPict
->Seek( nDstRowPos
);
1086 if ( nDstRowBytes
> 250 )
1087 *pPict
<< ( (USHORT
)( nPos
- nDstRowPos
- 2 ) );
1089 *pPict
<< ( (BYTE
)( nPos
- nDstRowPos
- 1 ) );
1090 pPict
->Seek( nPos
);
1092 // Prozente zaehlen, Callback, Fehler pruefen:
1093 nActBitmapPercent
= ( ny
* 70 / nHeight
) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1097 for ( nc
= 0; nc
< 4; nc
++ )
1102 { // nicht 24-Bit also Opcode 'PackBitsRect' erzeugen:
1104 // Bei 1-Bit-Bildern ignorieren manche Import-Filter die Palette und nehmen statt
1105 // dessen die Vorder- und Hintergrundfarbe:
1106 if ( nBitsPerPixel
== 1 )
1108 WriteOpcode_RGBBkCol( pAcc
->GetPaletteColor( 0 ) );
1109 WriteOpcode_RGBFgCol( pAcc
->GetPaletteColor( 1 ) );
1113 WriteOpcode_RGBBkCol( Color( COL_BLACK
) );
1114 WriteOpcode_RGBFgCol( Color( COL_WHITE
) );
1117 // Anzahl Bytes einer (ungepackten) Zeile in Ziel und Quelle berechnen:
1118 nDstRowBytes
= ( nWidth
* nBitsPerPixel
+ 7 ) >> 3;
1119 nSrcRowBytes
= ( nDstRowBytes
+ 3 ) & 0xfffffffc;
1121 // Opcode schreiben:
1122 *pPict
<< (USHORT
)0x0098;
1124 // Normalerweise wollen wir den Packing-Type 0 (default Packing) erzeugen.
1125 // Wenn aber RowBytes<8 gilt, sind die Daten grundsaetzlich ungepackt,
1126 // auch wenn der Packing-Type 0 angegeben ist, was etwas komisch erscheint.
1127 // Daher wollen wir in so einem Fall lieber gleich den Packing-Type 1 (ungepackt)
1129 if ( nDstRowBytes
< 8 )
1134 // PixMap-Struktur schreiben:
1135 *pPict
<< (USHORT
)(nDstRowBytes
|0x8000) // Bytes pro Zeile und dass es eine 'PixMap' ist
1136 << (USHORT
)0x0000 // Y1-Position der Bitmap in der Quelle
1137 << (USHORT
)0x0000 // X1-Position der Bitmap in der Quelle
1138 << (USHORT
)nHeight
// Y2-Position der Bitmap in der Quelle
1139 << (USHORT
)nWidth
// X2-Position der Bitmap in der Quelle
1140 << (USHORT
)0x0000 // Version
1141 << (USHORT
)nPackType
// Packing type
1142 << (sal_uInt32
) 0x00000000 // Packing size (?)
1143 << (sal_uInt32
) 0x00480000 // H-Res
1144 << (sal_uInt32
) 0x00480000 // V-Res
1145 << (USHORT
)0x0000 // Pixel type (?)
1146 << (USHORT
)nBitsPerPixel
// Pixel size
1147 << (USHORT
)0x0001 // CmpCount: 1 Komponente
1148 << (USHORT
)nBitsPerPixel
// CmpSize
1149 << (sal_uInt32
) 0x00000000 // PlaneBytes (?)
1150 << (sal_uInt32
) 0x00000000 // (?)
1151 << (sal_uInt32
) 0x00000000; // (?)
1153 // Palette lesen und schreiben:
1154 nColTabSize
= pAcc
->GetPaletteEntryCount();
1155 *pPict
<< (sal_uInt32
)0 << (USHORT
)0x8000 << (USHORT
)( nColTabSize
- 1 );
1157 for ( i
= 0; i
< nColTabSize
; i
++ )
1159 nRed
= (BYTE
)pAcc
->GetPaletteColor( (USHORT
)i
).GetRed();
1160 nGreen
= (BYTE
)pAcc
->GetPaletteColor( (USHORT
)i
).GetGreen();
1161 nBlue
= (BYTE
)pAcc
->GetPaletteColor( (USHORT
)i
).GetBlue();
1162 *pPict
<< (UINT16
)0 << nRed
<< nRed
<< nGreen
<< nGreen
<< nBlue
<< nBlue
;
1165 // Source-Rectangle schreiben:
1166 *pPict
<< (USHORT
)0 << (USHORT
)0 << (USHORT
)nHeight
<< (USHORT
)nWidth
;
1168 // Destination-Rectangle schreiben:
1169 WritePoint( rPoint
);
1170 WritePoint( Point( rPoint
.X() + rSize
.Width(), rPoint
.Y() + rSize
.Height() ) );
1172 // Transfer mode schreiben:
1173 *pPict
<< (USHORT
)0; // (?)
1175 // Speicher fuer eine Zeile allozieren:
1176 pPix
= new BYTE
[ nSrcRowBytes
];
1178 // Position der Map-Daten in Ziel merken:
1179 nDstMapPos
=pPict
->Tell();
1181 // Schleife ueber Zeilen:
1182 for ( ny
= 0; ny
< nHeight
; ny
++ )
1185 // Zeile ny der Quelle in den Zwischenspeicher einlesen:
1187 switch ( nBitsPerPixel
)
1190 for ( pTemp
= pPix
, i
= 0; i
< nSrcRowBytes
; i
++ )
1192 for ( i
= 0; i
< nWidth
; i
++ )
1193 pPix
[ ( i
>> 3 ) ] |= (BYTE
)( pAcc
->GetPixel( ny
, i
) & 1 ) << ( ( i
& 7 ) ^ 7 );
1196 for ( pTemp
= pPix
, i
= 0; i
< nSrcRowBytes
; i
++ )
1198 for ( i
= 0; i
< nWidth
; i
++ )
1199 pPix
[ ( i
>> 1 ) ] |= (BYTE
)( pAcc
->GetPixel( ny
, i
) & 15 ) << ( ( i
& 1 ) << 2 ) ;
1202 for ( i
= 0; i
< nWidth
; i
++ )
1203 pPix
[ i
] = (BYTE
)pAcc
->GetPixel( ny
, i
);
1207 if ( nPackType
== 1 )
1209 pPict
->Write( pPix
, nDstRowBytes
);
1212 { // Packen (nPackType==0)
1214 // Anfang der Zeile im Ziel merken:
1215 nDstRowPos
= pPict
->Tell();
1217 // ByteCount (das ist die Groesse der gepackten Zeile) zunaechst 0 (wird spaeter berichtigt):
1218 if ( nDstRowBytes
> 250 )
1219 *pPict
<< (USHORT
)0;
1223 // Schleife ueber Bytes der Zeile:
1225 while ( nx
< nDstRowBytes
&& bStatus
)
1227 // Die Position von 3 gleichen Bytes suchen und in nEqu3 merken.
1228 // wenn nicht gefunden, dann nEqu3=nDstRowBytes setzten.
1229 // Wenn doch gefunden, dann in nEquData den Wert der Bytes merken.
1233 if ( nEqu3
+ 2 >= nDstRowBytes
)
1235 nEqu3
= nDstRowBytes
;
1238 nEquData
= pPix
[ nEqu3
];
1239 if ( nEquData
== pPix
[ nEqu3
+ 1 ] && nEquData
== pPix
[ nEqu3
+ 2 ] )
1244 // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1245 while ( nEqu3
> nx
)
1247 nCount
= nEqu3
- nx
;
1250 nFlagCounterByte
= (BYTE
)( nCount
- 1 );
1251 *pPict
<< nFlagCounterByte
;
1254 *pPict
<< pPix
[ nx
++ ];
1256 } while ( nCount
> 0 );
1259 // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1260 // gleiche Bytes gefunden):
1261 if ( nx
< nDstRowBytes
)
1262 { // Hinweis: es gilt nx==nEqu3 (hoffentlich)
1263 nCount
= 3; // Drei Bytes sind gleich, wie weiter oben herausgefunden.
1264 // Pruefen, ob es weitere gleiche Bytes gibts (dabei Max.-Record-Groesse beachten):
1265 while ( nx
+ nCount
< nDstRowBytes
&& nCount
< 128 )
1267 if ( nEquData
!= pPix
[ nx
+ nCount
] )
1271 // nCount gleiche Bytes komprimiert schreiben:
1272 nFlagCounterByte
= (BYTE
)( 1 - (long)nCount
);
1273 *pPict
<< nFlagCounterByte
<< nEquData
;
1278 // ByteCount berichtigen:
1279 nPos
= pPict
->Tell();
1280 pPict
->Seek( nDstRowPos
);
1281 if ( nDstRowBytes
> 250 )
1282 *pPict
<< ( (USHORT
)( nPos
- nDstRowPos
- 2 ) );
1284 *pPict
<< ( (BYTE
)( nPos
- nDstRowPos
- 1 ) );
1285 pPict
->Seek( nPos
);
1288 // Prozente zaehlen, Callback, Fehler pruefen:
1289 nActBitmapPercent
=( ny
* 70 / nHeight
) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1291 if ( pPict
->GetError() )
1298 // Map-Daten muessen gerade Anzahl von Bytes sein:
1299 if ( ( ( pPict
->Tell() - nDstMapPos
) & 1 ) != 0 )
1304 nActBitmapPercent
= 0;
1306 aBitmap
.ReleaseAccess( pAcc
);
1309 void PictWriter::WriteOpcode_EndOfFile()
1311 *pPict
<< (USHORT
)0x00ff;
1315 void PictWriter::SetAttrForPaint()
1317 WriteOpcode_PnMode(eSrcRasterOp
);
1318 WriteOpcode_RGBFgCol(aFillColor
);
1319 WriteOpcode_RGBBkCol(aFillColor
);
1320 WriteOpcode_PnFillPat(aFillColor
!=Color( COL_TRANSPARENT
));
1324 void PictWriter::SetAttrForFrame()
1326 WriteOpcode_PnMode(eSrcRasterOp
);
1327 WriteOpcode_PnSize(0);
1328 WriteOpcode_RGBFgCol(aLineColor
);
1329 WriteOpcode_PnLinePat(aLineColor
!=Color( COL_TRANSPARENT
));
1333 void PictWriter::SetAttrForText()
1335 WriteOpcode_RGBFgCol(aSrcFont
.GetColor());
1336 WriteOpcode_RGBBkCol(aSrcFont
.GetFillColor());
1337 WriteOpcode_PnLinePat(TRUE
);
1338 WriteOpcode_FontName(aSrcFont
);
1339 WriteOpcode_TxSize((USHORT
)(aSrcFont
.GetSize().Height()));
1340 WriteOpcode_TxMode(eSrcRasterOp
);
1341 WriteOpcode_TxFace(aSrcFont
);
1345 void PictWriter::WriteTextArray(Point
& rPoint
, const String
& rString
, const sal_Int32
* pDXAry
)
1352 if ( pDXAry
== NULL
)
1353 WriteOpcode_Text( rPoint
, rString
, FALSE
);
1357 nLen
= rString
.Len();
1358 for ( i
= 0; i
< nLen
; i
++ )
1360 c
= rString
.GetChar( i
);
1361 if ( c
&& ( c
!= 0x20 ) )
1365 aPt
.X() += pDXAry
[ i
- 1 ];
1367 WriteOpcode_Text( aPt
, String( c
), bDelta
);
1375 void PictWriter::WriteOpcodes( const GDIMetaFile
& rMTF
)
1378 const MetaAction
* pMA
;
1383 nACount
=rMTF
.GetActionCount();
1385 for (nA
=0; nA
<nACount
; nA
++)
1387 pMA
= rMTF
.GetAction(nA
);
1389 switch (pMA
->GetType())
1391 case META_PIXEL_ACTION
:
1393 const MetaPixelAction
* pA
= (const MetaPixelAction
*) pMA
;
1394 WriteOpcode_PnMode(eSrcRasterOp
);
1395 WriteOpcode_PnSize(1);
1396 WriteOpcode_RGBFgCol(pA
->GetColor());
1397 WriteOpcode_PnLinePat(TRUE
);
1398 WriteOpcode_Line(pA
->GetPoint(),pA
->GetPoint());
1402 case META_POINT_ACTION
:
1404 const MetaPointAction
* pA
= (const MetaPointAction
*) pMA
;
1406 if( aLineColor
!= Color( COL_TRANSPARENT
) )
1409 WriteOpcode_Line( pA
->GetPoint(),pA
->GetPoint() );
1414 case META_LINE_ACTION
:
1416 const MetaLineAction
* pA
= (const MetaLineAction
*) pMA
;
1418 if( aLineColor
!= Color( COL_TRANSPARENT
) )
1421 WriteOpcode_Line( pA
->GetStartPoint(),pA
->GetEndPoint() );
1426 case META_RECT_ACTION
:
1428 const MetaRectAction
* pA
= (const MetaRectAction
*) pMA
;
1430 if (aFillColor
!=Color( COL_TRANSPARENT
))
1433 WriteOpcode_Rect(PDM_PAINT
,pA
->GetRect());
1434 if (aLineColor
!=Color( COL_TRANSPARENT
))
1437 WriteOpcode_SameRect(PDM_FRAME
);
1440 else if (aLineColor
!=Color( COL_TRANSPARENT
))
1443 WriteOpcode_Rect(PDM_FRAME
,pA
->GetRect());
1448 case META_ROUNDRECT_ACTION
:
1450 const MetaRoundRectAction
* pA
= (const MetaRoundRectAction
*) pMA
;
1452 WriteOpcode_OvSize( Size( pA
->GetHorzRound(), pA
->GetVertRound() ) );
1454 if (aFillColor
!=Color( COL_TRANSPARENT
))
1457 WriteOpcode_RRect(PDM_PAINT
,pA
->GetRect());
1458 if (aLineColor
!=Color( COL_TRANSPARENT
))
1461 WriteOpcode_SameRRect(PDM_FRAME
);
1464 else if (aLineColor
!=Color( COL_TRANSPARENT
))
1467 WriteOpcode_RRect(PDM_FRAME
,pA
->GetRect());
1472 case META_ELLIPSE_ACTION
:
1474 const MetaEllipseAction
* pA
= (const MetaEllipseAction
*) pMA
;
1476 if (aFillColor
!=Color( COL_TRANSPARENT
))
1479 WriteOpcode_Oval(PDM_PAINT
,pA
->GetRect());
1480 if (aLineColor
!=Color( COL_TRANSPARENT
))
1483 WriteOpcode_SameOval(PDM_FRAME
);
1486 else if (aLineColor
!=Color( COL_TRANSPARENT
))
1489 WriteOpcode_Oval(PDM_FRAME
,pA
->GetRect());
1494 case META_ARC_ACTION
:
1496 const MetaArcAction
* pA
= (const MetaArcAction
*) pMA
;
1498 if (aLineColor
!=Color( COL_TRANSPARENT
))
1501 WriteOpcode_Arc(PDM_FRAME
,pA
->GetRect(),pA
->GetStartPoint(),pA
->GetEndPoint());
1506 case META_PIE_ACTION
:
1508 const MetaPieAction
* pA
= (const MetaPieAction
*) pMA
;
1510 if (aFillColor
!=Color( COL_TRANSPARENT
))
1513 WriteOpcode_Arc(PDM_PAINT
,pA
->GetRect(),pA
->GetStartPoint(),pA
->GetEndPoint());
1515 if (aLineColor
!=Color( COL_TRANSPARENT
))
1518 WriteOpcode_SameArc(PDM_FRAME
,pA
->GetRect(),pA
->GetStartPoint(),pA
->GetEndPoint());
1521 else if (aLineColor
!=Color( COL_TRANSPARENT
))
1524 WriteOpcode_Arc(PDM_FRAME
,pA
->GetRect(),pA
->GetStartPoint(),pA
->GetEndPoint());
1527 if (aLineColor
!=Color( COL_TRANSPARENT
))
1529 double fxc
,fyc
,fxr
,fyr
,fx1
,fy1
,fx2
,fy2
,l1
,l2
;
1531 fxc
=((double)(pA
->GetRect().Left()+pA
->GetRect().Right()))/2.0;
1532 fyc
=((double)(pA
->GetRect().Top()+pA
->GetRect().Bottom()))/2.0;
1533 fxr
=((double)pA
->GetRect().GetWidth())/2.0;
1534 fyr
=((double)pA
->GetRect().GetHeight())/2.0;
1535 fx1
=((double)pA
->GetStartPoint().X())-fxc
;
1536 fy1
=((double)pA
->GetStartPoint().Y())-fyc
;
1537 fx2
=((double)pA
->GetEndPoint().X())-fxc
;
1538 fy2
=((double)pA
->GetEndPoint().Y())-fyc
;
1539 l1
=sqrt(fx1
*fx1
+fy1
*fy1
);
1540 l2
=sqrt(fx2
*fx2
+fy2
*fy2
);
1553 fx1
+=fxc
; fy1
+=fyc
; fx2
+=fxc
; fy2
+=fyc
;
1554 WriteOpcode_Line(Point((long)(fx1
+0.5),(long)(fy1
+0.5)), Point((long)(fxc
+0.5),(long)(fyc
+0.5)));
1555 WriteOpcode_LineFrom(Point((long)(fx2
+0.5),(long)(fy2
+0.5)));
1560 case META_CHORD_ACTION
:
1562 // DBG_ERROR( "Unsupported PICT-Action: META_CHORD_ACTION!" );
1566 case META_POLYLINE_ACTION
:
1568 const MetaPolyLineAction
* pA
= (const MetaPolyLineAction
*) pMA
;
1570 if( aLineColor
!=Color( COL_TRANSPARENT
) )
1572 const Polygon
& rPoly
= pA
->GetPolygon();
1574 Polygon aSimplePoly
;
1575 if ( rPoly
.HasFlags() )
1576 rPoly
.GetSimple( aSimplePoly
);
1578 aSimplePoly
= rPoly
;
1580 const USHORT nSize
= aSimplePoly
.GetSize();
1586 aLast
= aSimplePoly
[0];
1588 for ( USHORT i
= 1; i
< nSize
; i
++ )
1590 WriteOpcode_Line( aLast
, aSimplePoly
[i
] );
1591 aLast
= aSimplePoly
[i
];
1598 case META_POLYGON_ACTION
:
1600 const MetaPolygonAction
* pA
= (const MetaPolygonAction
*) pMA
;
1602 const Polygon
& rPoly
= pA
->GetPolygon();
1604 Polygon aSimplePoly
;
1605 if ( rPoly
.HasFlags() )
1606 rPoly
.GetSimple( aSimplePoly
);
1608 aSimplePoly
= rPoly
;
1610 if (aFillColor
!=Color( COL_TRANSPARENT
))
1613 WriteOpcode_Poly( PDM_PAINT
, aSimplePoly
);
1615 if (aLineColor
!=Color( COL_TRANSPARENT
))
1618 WriteOpcode_Poly( PDM_FRAME
, aSimplePoly
);
1623 case META_POLYPOLYGON_ACTION
:
1625 const MetaPolyPolygonAction
* pA
= (const MetaPolyPolygonAction
*) pMA
;
1627 const PolyPolygon
& rPolyPoly
= pA
->GetPolyPolygon();
1628 sal_uInt16 nPolyCount
= rPolyPoly
.Count();
1629 PolyPolygon
aSimplePolyPoly( rPolyPoly
);
1630 for ( sal_uInt16 i
= 0; i
< nPolyCount
; i
++ )
1632 if ( aSimplePolyPoly
[ i
].HasFlags() )
1634 Polygon aSimplePoly
;
1635 aSimplePolyPoly
[ i
].GetSimple( aSimplePoly
);
1636 aSimplePolyPoly
[ i
] = aSimplePoly
;
1639 if (aFillColor
!=Color( COL_TRANSPARENT
))
1642 WriteOpcode_Poly( PDM_PAINT
, PolyPolygonToPolygon( aSimplePolyPoly
));
1645 if (aLineColor
!=Color( COL_TRANSPARENT
))
1649 nCount
= aSimplePolyPoly
.Count();
1650 for ( i
= 0; i
< nCount
; i
++ )
1651 WriteOpcode_Poly( PDM_FRAME
, aSimplePolyPoly
.GetObject( i
) );
1656 case META_TEXT_ACTION
:
1658 const MetaTextAction
* pA
= (const MetaTextAction
*) pMA
;
1659 Point
aPt( pA
->GetPoint() );
1661 if ( aSrcFont
.GetAlign() != ALIGN_BASELINE
)
1663 VirtualDevice aVirDev
;
1665 if (aSrcFont
.GetAlign()==ALIGN_TOP
)
1666 aPt
.Y()+=(long)aVirDev
.GetFontMetric(aSrcFont
).GetAscent();
1668 aPt
.Y()-=(long)aVirDev
.GetFontMetric(aSrcFont
).GetDescent();
1672 String
aStr( pA
->GetText(),pA
->GetIndex(),pA
->GetLen() );
1673 WriteOpcode_Text( aPt
, aStr
, FALSE
);
1677 case META_TEXTARRAY_ACTION
:
1679 const MetaTextArrayAction
* pA
= (const MetaTextArrayAction
*) pMA
;
1680 Point
aPt( pA
->GetPoint() );
1682 if (aSrcFont
.GetAlign()!=ALIGN_BASELINE
)
1684 VirtualDevice aVirDev
;
1686 if (aSrcFont
.GetAlign()==ALIGN_TOP
)
1687 aPt
.Y()+=(long)aVirDev
.GetFontMetric(aSrcFont
).GetAscent();
1689 aPt
.Y()-=(long)aVirDev
.GetFontMetric(aSrcFont
).GetDescent();
1692 String
aStr( pA
->GetText(),pA
->GetIndex(),pA
->GetLen() );
1693 WriteTextArray( aPt
, aStr
, pA
->GetDXArray() );
1697 case META_STRETCHTEXT_ACTION
:
1699 const MetaStretchTextAction
* pA
= (const MetaStretchTextAction
*) pMA
;
1700 Point
aPt( pA
->GetPoint() );
1701 String
aStr( pA
->GetText(),pA
->GetIndex(),pA
->GetLen() );
1702 VirtualDevice aVirDev
;
1703 sal_Int32
* pDXAry
= new sal_Int32
[ aStr
.Len() ];
1704 sal_Int32
nNormSize( aVirDev
.GetTextArray( aStr
,pDXAry
) );
1707 if (aSrcFont
.GetAlign()!=ALIGN_BASELINE
)
1709 if (aSrcFont
.GetAlign()==ALIGN_TOP
)
1710 aPt
.Y()+=(long)aVirDev
.GetFontMetric(aSrcFont
).GetAscent();
1712 aPt
.Y()-=(long)aVirDev
.GetFontMetric(aSrcFont
).GetDescent();
1715 for ( i
= 0; i
< aStr
.Len() - 1; i
++ )
1716 pDXAry
[ i
] = pDXAry
[ i
] * ( (long)pA
->GetWidth() ) / nNormSize
;
1719 WriteTextArray( aPt
, aStr
, pDXAry
);
1724 case META_TEXTRECT_ACTION
:
1726 // DBG_ERROR( "Unsupported PICT-Action: META_TEXTRECT_ACTION!" );
1730 case META_BMP_ACTION
:
1732 const MetaBmpAction
* pA
= (const MetaBmpAction
*) pMA
;
1733 WriteOpcode_BitsRect( pA
->GetPoint(),pA
->GetBitmap().GetSizePixel(), pA
->GetBitmap() );
1737 case META_BMPSCALE_ACTION
:
1739 const MetaBmpScaleAction
* pA
= (const MetaBmpScaleAction
*) pMA
;
1740 WriteOpcode_BitsRect( pA
->GetPoint(), pA
->GetSize(), pA
->GetBitmap() );
1744 case META_BMPSCALEPART_ACTION
:
1746 const MetaBmpScalePartAction
* pA
= (const MetaBmpScalePartAction
*) pMA
;
1747 Bitmap
aBmp( pA
->GetBitmap() );
1749 aBmp
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) );
1750 WriteOpcode_BitsRect( pA
->GetDestPoint(), pA
->GetDestSize(), aBmp
);
1754 case META_BMPEX_ACTION
:
1756 const MetaBmpExAction
* pA
= (const MetaBmpExAction
*) pMA
;
1757 const Bitmap
aBmp( Graphic( pA
->GetBitmapEx() ).GetBitmap() );
1759 WriteOpcode_BitsRect( pA
->GetPoint(), aBmp
.GetSizePixel(), aBmp
);
1763 case META_BMPEXSCALE_ACTION
:
1765 const MetaBmpExScaleAction
* pA
= (const MetaBmpExScaleAction
*) pMA
;
1766 const Bitmap
aBmp( Graphic( pA
->GetBitmapEx() ).GetBitmap() );
1768 WriteOpcode_BitsRect( pA
->GetPoint(), pA
->GetSize(), aBmp
);
1772 case META_BMPEXSCALEPART_ACTION
:
1774 const MetaBmpExScalePartAction
* pA
= (const MetaBmpExScalePartAction
*) pMA
;
1775 Bitmap
aBmp( Graphic( pA
->GetBitmapEx() ).GetBitmap() );
1777 aBmp
.Crop( Rectangle( pA
->GetSrcPoint(), pA
->GetSrcSize() ) );
1778 WriteOpcode_BitsRect( pA
->GetDestPoint(), pA
->GetDestSize(), aBmp
);
1782 case META_EPS_ACTION
:
1784 const MetaEPSAction
* pA
= (const MetaEPSAction
*)pMA
;
1785 const GDIMetaFile
aGDIMetaFile( pA
->GetSubstitute() );
1787 INT32 nCount
= aGDIMetaFile
.GetActionCount();
1788 for ( INT32 i
= 0; i
< nCount
; i
++ )
1790 const MetaAction
* pMetaAct
= aGDIMetaFile
.GetAction( i
);
1791 if ( pMetaAct
->GetType() == META_BMPSCALE_ACTION
)
1793 const MetaBmpScaleAction
* pBmpScaleAction
= (const MetaBmpScaleAction
*)pMetaAct
;
1794 WriteOpcode_BitsRect( pA
->GetPoint(), pA
->GetSize(), pBmpScaleAction
->GetBitmap() );
1801 case META_MASK_ACTION
:
1802 case META_MASKSCALE_ACTION
:
1803 case META_MASKSCALEPART_ACTION
:
1805 // DBG_ERROR( "Unsupported PICT-Action: META_MASK..._ACTION!" );
1809 case META_GRADIENT_ACTION
:
1811 VirtualDevice aVDev
;
1812 GDIMetaFile aTmpMtf
;
1813 const MetaGradientAction
* pA
= (const MetaGradientAction
*) pMA
;
1815 aVDev
.SetMapMode( aTargetMapMode
);
1816 aVDev
.AddGradientActions( pA
->GetRect(), pA
->GetGradient(), aTmpMtf
);
1817 WriteOpcodes( aTmpMtf
);
1821 case META_HATCH_ACTION
:
1823 VirtualDevice aVDev
;
1824 GDIMetaFile aTmpMtf
;
1825 const MetaHatchAction
* pA
= (const MetaHatchAction
*) pMA
;
1827 aVDev
.SetMapMode( aTargetMapMode
);
1828 aVDev
.AddHatchActions( pA
->GetPolyPolygon(), pA
->GetHatch(), aTmpMtf
);
1829 WriteOpcodes( aTmpMtf
);
1833 case META_WALLPAPER_ACTION
:
1835 // DBG_ERROR( "Unsupported PICT-Action: META_WALLPAPER_ACTION!" );
1839 case META_CLIPREGION_ACTION
:
1841 // DBG_ERROR( "Unsupported PICT-Action: META_CLIPREGION_ACTION!" );
1845 case META_ISECTRECTCLIPREGION_ACTION
:
1847 const MetaISectRectClipRegionAction
* pA
= (const MetaISectRectClipRegionAction
*) pMA
;
1848 WriteOpcode_ClipRect( pA
->GetRect() );
1852 case META_ISECTREGIONCLIPREGION_ACTION
:
1854 // DBG_ERROR( "Unsupported PICT-Action: META_ISECTREGIONCLIPREGION_ACTION!" );
1858 case META_MOVECLIPREGION_ACTION
:
1860 // DBG_ERROR( "Unsupported PICT-Action: META_MOVECLIPREGION_ACTION!" );
1864 case META_LINECOLOR_ACTION
:
1866 const MetaLineColorAction
* pA
= (const MetaLineColorAction
*) pMA
;
1868 if( pA
->IsSetting() )
1869 aLineColor
= pA
->GetColor();
1871 aLineColor
= Color( COL_TRANSPARENT
);
1875 case META_FILLCOLOR_ACTION
:
1877 const MetaFillColorAction
* pA
= (const MetaFillColorAction
*) pMA
;
1879 if( pA
->IsSetting() )
1880 aFillColor
= pA
->GetColor();
1882 aFillColor
= Color( COL_TRANSPARENT
);
1886 case META_TEXTCOLOR_ACTION
:
1888 const MetaTextColorAction
* pA
= (const MetaTextColorAction
*) pMA
;
1889 aSrcFont
.SetColor( pA
->GetColor() );
1893 case META_TEXTFILLCOLOR_ACTION
:
1895 const MetaTextFillColorAction
* pA
= (const MetaTextFillColorAction
*) pMA
;
1897 if( pA
->IsSetting() )
1898 aSrcFont
.SetFillColor( pA
->GetColor() );
1900 aSrcFont
.SetFillColor( Color( COL_TRANSPARENT
) );
1904 case META_TEXTALIGN_ACTION
:
1906 // DBG_ERROR( "Unsupported PICT-Action: META_TEXTALIGN_ACTION!" );
1910 case META_MAPMODE_ACTION
:
1912 const MetaMapModeAction
* pA
= (const MetaMapModeAction
*) pMA
;
1914 if (aSrcMapMode
!=pA
->GetMapMode())
1916 if( pA
->GetMapMode().GetMapUnit() == MAP_RELATIVE
)
1918 MapMode aMM
= pA
->GetMapMode();
1919 Fraction aScaleX
= aMM
.GetScaleX();
1920 Fraction aScaleY
= aMM
.GetScaleY();
1922 Point aOrigin
= aSrcMapMode
.GetOrigin();
1923 BigInt
aX( aOrigin
.X() );
1924 aX
*= BigInt( aScaleX
.GetDenominator() );
1925 if( aOrigin
.X() >= 0 )
1927 if( aScaleX
.GetNumerator() >= 0 )
1928 aX
+= BigInt( aScaleX
.GetNumerator()/2 );
1930 aX
-= BigInt( (aScaleX
.GetNumerator()+1)/2 );
1934 if( aScaleX
.GetNumerator() >= 0 )
1935 aX
-= BigInt( (aScaleX
.GetNumerator()-1)/2 );
1937 aX
+= BigInt( aScaleX
.GetNumerator()/2 );
1940 aX
/= BigInt( aScaleX
.GetNumerator() );
1941 aOrigin
.X() = (long)aX
+ aMM
.GetOrigin().X();
1942 BigInt
aY( aOrigin
.Y() );
1943 aY
*= BigInt( aScaleY
.GetDenominator() );
1945 if( aOrigin
.Y() >= 0 )
1947 if( aScaleY
.GetNumerator() >= 0 )
1948 aY
+= BigInt( aScaleY
.GetNumerator()/2 );
1950 aY
-= BigInt( (aScaleY
.GetNumerator()+1)/2 );
1954 if( aScaleY
.GetNumerator() >= 0 )
1955 aY
-= BigInt( (aScaleY
.GetNumerator()-1)/2 );
1957 aY
+= BigInt( aScaleY
.GetNumerator()/2 );
1960 aY
/= BigInt( aScaleY
.GetNumerator() );
1961 aOrigin
.Y() = (long)aY
+ aMM
.GetOrigin().Y();
1962 aSrcMapMode
.SetOrigin( aOrigin
);
1964 aScaleX
*= aSrcMapMode
.GetScaleX();
1965 aScaleY
*= aSrcMapMode
.GetScaleY();
1966 aSrcMapMode
.SetScaleX( aScaleX
);
1967 aSrcMapMode
.SetScaleY( aScaleY
);
1970 aSrcMapMode
= pA
->GetMapMode();
1975 case META_FONT_ACTION
:
1977 const MetaFontAction
* pA
= (const MetaFontAction
*) pMA
;
1978 aSrcFont
=pA
->GetFont();
1982 case META_PUSH_ACTION
:
1984 PictWriterAttrStackMember
* pAt
= new PictWriterAttrStackMember
;
1985 pAt
->aLineColor
=aLineColor
;
1986 pAt
->aFillColor
=aFillColor
;
1987 pAt
->eRasterOp
=eSrcRasterOp
;
1988 pAt
->aFont
=aSrcFont
;
1989 pAt
->aMapMode
=aSrcMapMode
;
1990 pAt
->aClipRect
=aClipRect
;
1991 pAt
->pSucc
=pAttrStack
;
1996 case META_POP_ACTION
:
1998 PictWriterAttrStackMember
* pAt
=pAttrStack
;
2002 aLineColor
=pAt
->aLineColor
;
2003 aFillColor
=pAt
->aFillColor
;
2004 eSrcRasterOp
=pAt
->eRasterOp
;
2005 aSrcFont
=pAt
->aFont
;
2006 aSrcMapMode
=pAt
->aMapMode
;
2007 if ( pAt
->aClipRect
!= aClipRect
)
2009 Rectangle
aRect( pAt
->aClipRect
);
2010 *pPict
<< (sal_uInt16
)1 // opcode 1
2011 << (sal_uInt16
)10 // data size
2012 << (sal_Int16
)aRect
.Top() << (sal_Int16
)aRect
.Left()
2013 << (sal_Int16
)aRect
.Bottom() << (sal_Int16
)aRect
.Right();
2015 aClipRect
=pAt
->aClipRect
;
2016 pAttrStack
=pAt
->pSucc
;
2022 case META_RASTEROP_ACTION
:
2024 const MetaRasterOpAction
* pA
= (const MetaRasterOpAction
*) pMA
;
2025 eSrcRasterOp
=pA
->GetRasterOp();
2029 case META_TRANSPARENT_ACTION
:
2031 const PolyPolygon
& rPolyPoly
= ( (const MetaTransparentAction
*) pMA
)->GetPolyPolygon();
2033 if (aFillColor
!=Color( COL_TRANSPARENT
))
2036 WriteOpcode_Poly( PDM_PAINT
, PolyPolygonToPolygon( rPolyPoly
) );
2039 if (aLineColor
!=Color( COL_TRANSPARENT
))
2042 for( USHORT i
= 0, nCount
= rPolyPoly
.Count(); i
< nCount
; i
++ )
2043 WriteOpcode_Poly( PDM_FRAME
, rPolyPoly
.GetObject( i
) );
2048 case META_FLOATTRANSPARENT_ACTION
:
2050 const MetaFloatTransparentAction
* pA
= (const MetaFloatTransparentAction
*) pMA
;
2052 GDIMetaFile
aTmpMtf( pA
->GetGDIMetaFile() );
2053 Point
aSrcPt( aTmpMtf
.GetPrefMapMode().GetOrigin() );
2054 const Size
aSrcSize( aTmpMtf
.GetPrefSize() );
2055 const Point
aDestPt( pA
->GetPoint() );
2056 const Size
aDestSize( pA
->GetSize() );
2057 const double fScaleX
= aSrcSize
.Width() ? (double) aDestSize
.Width() / aSrcSize
.Width() : 1.0;
2058 const double fScaleY
= aSrcSize
.Height() ? (double) aDestSize
.Height() / aSrcSize
.Height() : 1.0;
2059 long nMoveX
, nMoveY
;
2061 if( fScaleX
!= 1.0 || fScaleY
!= 1.0 )
2063 aTmpMtf
.Scale( fScaleX
, fScaleY
);
2064 aSrcPt
.X() = FRound( aSrcPt
.X() * fScaleX
), aSrcPt
.Y() = FRound( aSrcPt
.Y() * fScaleY
);
2067 nMoveX
= aDestPt
.X() - aSrcPt
.X(), nMoveY
= aDestPt
.Y() - aSrcPt
.Y();
2069 if( nMoveX
|| nMoveY
)
2070 aTmpMtf
.Move( nMoveX
, nMoveY
);
2072 WriteOpcodes( aTmpMtf
);
2080 if (pPict
->GetError())
2089 void PictWriter::WriteHeader(const GDIMetaFile
& rMTF
)
2092 Size
aSize( rMTF
.GetPrefSize() );
2094 Rectangle
aRect( aPoint
, aSize
);
2096 // 512 Bytes "Muell" am Anfang:
2097 for (i
=0;i
<128;i
++) *pPict
<< (sal_uInt32
)0;
2099 // Lo-16-Bits der Groesse der Datei ohne die 512 Bytes Muell:
2100 *pPict
<< (USHORT
)0; // wird spaeter durch UpdateHeader() berichtigt
2102 // Das Bounding-Rectangle (y1,x1,y2,x2 !):
2103 WriteRectangle( aRect
);
2106 *pPict
<< (sal_uInt32
)0x001102ff;
2108 // Extended-Version-2-Header:
2109 *pPict
<< (USHORT
)0x0c00 // Opcode
2110 << (USHORT
)0xfffe // Version (?)
2111 << (USHORT
)0x0000 // Reserved
2112 << (sal_uInt32
) 0x00480000 // hRes
2113 << (sal_uInt32
) 0x00480000;
2114 WriteRectangle( aRect
);
2115 *pPict
<< (sal_uInt32
)0x00000000; // Reserved
2117 // viele Import-Filter verlangen die Angabe eines
2118 // Clipping-Bereichs am Anfang
2120 WriteOpcode_ClipRect( aRect
);
2124 void PictWriter::UpdateHeader()
2128 // Lo-16-Bits der Groesse der Datei ohne die 512 Bytes Muell berichtigen:
2131 *pPict
<< (USHORT
)((nPos
-512)&0x0000ffff);
2136 BOOL
PictWriter::WritePict(const GDIMetaFile
& rMTF
, SvStream
& rTargetStream
, FilterConfigItem
* pFilterConfigItem
)
2138 PictWriterAttrStackMember
* pAt
;
2139 MapMode
aMap72( MAP_INCH
);
2140 Fraction
aDPIFrac( 1, 72 );
2145 if ( pFilterConfigItem
)
2147 xStatusIndicator
= pFilterConfigItem
->GetStatusIndicator();
2148 if ( xStatusIndicator
.is() )
2151 xStatusIndicator
->start( aMsg
, 100 );
2155 pPict
=&rTargetStream
;
2156 pPict
->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN
);
2158 aLineColor
=Color( COL_BLACK
);
2159 aFillColor
=Color( COL_WHITE
);
2160 eSrcRasterOp
=ROP_OVERPAINT
;
2162 aSrcMapMode
= rMTF
.GetPrefMapMode();
2164 aMap72
.SetScaleX( aDPIFrac
);
2165 aMap72
.SetScaleY( aDPIFrac
);
2166 aTargetMapMode
= aMap72
;
2170 bDstBkPatValid
=FALSE
;
2171 bDstTxFaceValid
=FALSE
;
2172 bDstTxModeValid
=FALSE
;
2173 bDstPnSizeValid
=FALSE
;
2174 bDstPnModeValid
=FALSE
;
2175 bDstPnPatValid
=FALSE
;
2176 bDstFillPatValid
=FALSE
;
2177 bDstTxSizeValid
=FALSE
;
2178 bDstFgColValid
=FALSE
;
2179 bDstBkColValid
=FALSE
;
2180 bDstPenPositionValid
=FALSE
;
2181 bDstTextPositionValid
=FALSE
;
2182 bDstFontNameValid
=FALSE
;
2188 nActBitmapPercent
=0;
2190 CountActionsAndBitmaps(rMTF
);
2194 WriteOpcode_EndOfFile();
2197 while (pAttrStack
!=NULL
) {
2199 pAttrStack
=pAt
->pSucc
;
2203 if ( xStatusIndicator
.is() )
2204 xStatusIndicator
->end();
2209 //================== GraphicExport - die exportierte Funktion ================
2211 extern "C" BOOL __LOADONCALLAPI
GraphicExport(SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
* pFilterConfigItem
, BOOL
)
2213 PictWriter aPictWriter
;
2215 if (rGraphic
.GetType()==GRAPHIC_GDIMETAFILE
)
2217 GDIMetaFile
aScaledMtf( rGraphic
.GetGDIMetaFile() );
2220 MapMode aMap72( MAP_INCH );
2221 Fraction aDPIFrac( 1, 72 );
2222 Size aOldSize = aScaledMtf.GetPrefSize();
2224 aMap72.SetScaleX( aDPIFrac );
2225 aMap72.SetScaleY( aDPIFrac );
2227 Size aNewSize = OutputDevice::LogicToLogic( aOldSize,
2228 aScaledMtf.GetPrefMapMode(),
2231 aScaledMtf.Scale( Fraction( aNewSize.Width(), aOldSize.Width() ),
2232 Fraction( aNewSize.Height(), aOldSize.Height() ) );
2233 aScaledMtf.SetPrefMapMode( aMap72 );
2234 aScaledMtf.SetPrefSize( aNewSize );
2237 return aPictWriter
.WritePict( aScaledMtf
, rStream
, pFilterConfigItem
);
2241 Bitmap aBmp
=rGraphic
.GetBitmap();
2243 VirtualDevice aVirDev
;
2245 aMTF
.Record(&aVirDev
);
2246 aVirDev
.DrawBitmap(Point(),aBmp
);
2248 aMTF
.SetPrefSize(aBmp
.GetSizePixel());
2249 return aPictWriter
.WritePict( aMTF
, rStream
, pFilterConfigItem
);
2253 //================== GraphicDialog - die exportierte Funktion ================
2255 extern "C" BOOL SAL_CALL
DoExportDialog( FltCallDialogParameter
& rPara
)
2259 if ( rPara
.pWindow
)
2261 ByteString
aResMgrName( "ept" );
2264 pResMgr
= ResMgr::CreateResMgr( aResMgrName
.GetBuffer(), Application::GetSettings().GetUILocale() );
2268 rPara
.pResMgr
= pResMgr
;
2269 bRet
= ( DlgExportEPCT( rPara
).Execute() == RET_OK
);
2280 //=============================== fuer Windows ==============================
2286 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
2288 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
2300 extern "C" int CALLBACK
WEP( int )