Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/metaact.hxx>
31 : : #include <svtools/filter.hxx>
32 : : #include <svl/solar.hrc>
33 : : #include <svtools/fltcall.hxx>
34 : :
35 : : #include <math.h>
36 : : #include <vcl/bmpacc.hxx>
37 : : #include <vcl/graph.hxx>
38 : : #include <vcl/gradient.hxx>
39 : : #include <vcl/hatch.hxx>
40 : : #include <vcl/metric.hxx>
41 : : #include <vcl/font.hxx>
42 : : #include <vcl/virdev.hxx>
43 : : #include <vcl/svapp.hxx>
44 : : #include <vcl/msgbox.hxx>
45 : : #include <vcl/gdimtf.hxx>
46 : : #include <vcl/rendergraphicrasterizer.hxx>
47 : :
48 : : #include <tools/bigint.hxx>
49 : :
50 : : #include <basegfx/polygon/b2dpolygon.hxx>
51 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
52 : :
53 : : //============================== PictWriter ===================================
54 : :
55 : 0 : struct PictWriterAttrStackMember {
56 : : struct PictWriterAttrStackMember * pSucc;
57 : : Color aLineColor;
58 : : Color aFillColor;
59 : : RasterOp eRasterOp;
60 : : Font aFont;
61 : : MapMode aMapMode;
62 : : Rectangle aClipRect;
63 : : };
64 : :
65 : :
66 : : enum PictDrawingMethod {
67 : : PDM_FRAME, PDM_PAINT, PDM_ERASE, PDM_INVERT, PDM_FILL
68 : : };
69 : :
70 : :
71 : : struct PictPattern {
72 : : sal_uInt32 nLo, nHi;
73 : : };
74 : :
75 : 0 : class PictWriter {
76 : :
77 : : private:
78 : :
79 : : sal_Bool bStatus;
80 : : sal_uLong nLastPercent; // with wich number pCallback has been called the last time
81 : : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
82 : :
83 : : SvStream * pPict;
84 : :
85 : : // current attributes in the source-metafile:
86 : : Color aLineColor;
87 : : Color aFillColor;
88 : : RasterOp eSrcRasterOp;
89 : : Font aSrcFont;
90 : : MapMode aSrcMapMode;
91 : : MapMode aTargetMapMode;
92 : : Rectangle aClipRect;
93 : : PictWriterAttrStackMember * pAttrStack;
94 : :
95 : : // current attributes in the target-metafile and whether they are valid
96 : : sal_Bool bDstBkPatVisible; sal_Bool bDstBkPatValid;
97 : : sal_uInt8 nDstTxFace; sal_Bool bDstTxFaceValid;
98 : : RasterOp eDstTxMode; sal_Bool bDstTxModeValid;
99 : : sal_uInt16 nDstPnSize; sal_Bool bDstPnSizeValid;
100 : : RasterOp eDstPnMode; sal_Bool bDstPnModeValid;
101 : : PictPattern aDstPnPat; sal_Bool bDstPnPatValid;
102 : : sal_Bool bDstFillPatVisible; sal_Bool bDstFillPatValid;
103 : : sal_uInt16 nDstTxSize; sal_Bool bDstTxSizeValid;
104 : : Color aDstFgCol; sal_Bool bDstFgColValid;
105 : : Color aDstBkCol; sal_Bool bDstBkColValid;
106 : : Point aDstPenPosition; sal_Bool bDstPenPositionValid;
107 : : Point aDstTextPosition; sal_Bool bDstTextPositionValid;
108 : : String aDstFontName; sal_uInt16 nDstFontNameId; sal_Bool bDstFontNameValid;
109 : :
110 : : sal_uLong nNumberOfActions; // number of actions in the GDIMetafile
111 : : sal_uLong nNumberOfBitmaps; // number of bitmaps
112 : : sal_uLong nWrittenActions; // number of already processed actions during writing the Opcodes
113 : : sal_uLong nWrittenBitmaps; // number of already written Bitmaps
114 : : sal_uLong nActBitmapPercent; // what percentage of the next bitmap is already written
115 : :
116 : : void MayCallback();
117 : : // calculates a percentage on the basis of the 5 parameters above
118 : : // and then does a Callback should the situation arise. Sets bStatus to sal_False
119 : : // if the user wants to cancel
120 : :
121 : : void CountActionsAndBitmaps(const GDIMetaFile & rMTF);
122 : : // counts the bitmaps and actions (nNumberOfActions and nNumberOfBitmaps
123 : : // have to be set to 0 at the beginning, since this method is recursive)
124 : :
125 : : Polygon PolyPolygonToPolygon(const PolyPolygon & rPoly);
126 : : // generates a relatively sane polygon on the basis of a PolyPolygon
127 : :
128 : : Rectangle MapRectangle( const Rectangle& rRect );
129 : : void WritePoint(const Point & rPoint);
130 : : void WriteSize(const Size & rSize);
131 : : void WriteRGBColor(const Color & rColor);
132 : : void WriteString( const String & rString );
133 : : void WriteRectangle(const Rectangle & rRect);
134 : : void WritePolygon(const Polygon & rPoly);
135 : : void WriteArcAngles(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
136 : :
137 : : void ConvertLinePattern(PictPattern & rPat, sal_Bool bVisible) const;
138 : : void ConvertFillPattern(PictPattern & rPat, sal_Bool bVisible) const;
139 : :
140 : : void WriteOpcode_TxFace(const Font & rFont);
141 : : void WriteOpcode_TxMode(RasterOp eMode);
142 : : void WriteOpcode_PnSize(sal_uInt16 nSize);
143 : : void WriteOpcode_PnMode(RasterOp eMode);
144 : : void WriteOpcode_PnLinePat(sal_Bool bVisible);
145 : : void WriteOpcode_PnFillPat(sal_Bool bVisible);
146 : : void WriteOpcode_OvSize(const Size & rSize);
147 : : void WriteOpcode_TxSize(sal_uInt16 nSize);
148 : : void WriteOpcode_RGBFgCol(const Color & rColor);
149 : : void WriteOpcode_RGBBkCol(const Color & rColor);
150 : : void WriteOpcode_Line(const Point & rLocPt, const Point & rNewPt);
151 : : void WriteOpcode_LineFrom(const Point & rNewPt);
152 : : void WriteOpcode_Text(const Point & rPoint, const String& rString, sal_Bool bDelta);
153 : : void WriteOpcode_FontName(const Font & rFont);
154 : : void WriteOpcode_ClipRect( const Rectangle& rRect );
155 : : void WriteOpcode_Rect(PictDrawingMethod eMethod, const Rectangle & rRect);
156 : : void WriteOpcode_SameRect(PictDrawingMethod eMethod);
157 : : void WriteOpcode_RRect(PictDrawingMethod eMethod, const Rectangle & rRect);
158 : : void WriteOpcode_SameRRect(PictDrawingMethod eMethod);
159 : : void WriteOpcode_Oval(PictDrawingMethod eMethod, const Rectangle & rRect);
160 : : void WriteOpcode_SameOval(PictDrawingMethod eMethod);
161 : : void WriteOpcode_Arc(PictDrawingMethod eMethod, const Rectangle & rRect,
162 : : const Point & rStartPt, const Point & rEndPt);
163 : : void WriteOpcode_SameArc(PictDrawingMethod eMethod, const Rectangle & rRect,
164 : : const Point & rStartPt, const Point & rEndPt);
165 : : void WriteOpcode_Poly(PictDrawingMethod eMethod, const Polygon & rPoly);
166 : : void WriteOpcode_BitsRect(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap);
167 : : void WriteOpcode_EndOfFile();
168 : :
169 : : void SetAttrForPaint();
170 : : void SetAttrForFrame();
171 : : void SetAttrForText();
172 : :
173 : : void WriteTextArray(Point & rPoint, const String& rString, const sal_Int32 * pDXAry);
174 : :
175 : : void HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
176 : : void WriteOpcodes(const GDIMetaFile & rMTF);
177 : :
178 : : void WriteHeader(const GDIMetaFile & rMTF);
179 : : void UpdateHeader();
180 : :
181 : : public:
182 : :
183 : : sal_Bool WritePict( const GDIMetaFile & rMTF, SvStream & rTargetStream, FilterConfigItem* pFilterConfigItem );
184 : : };
185 : :
186 : :
187 : : //========================== Methods of PictWriter ==========================
188 : :
189 : :
190 : 0 : void PictWriter::MayCallback()
191 : : {
192 : 0 : if ( xStatusIndicator.is() )
193 : : {
194 : : sal_uLong nPercent;
195 : : nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
196 : : *100
197 : 0 : /((nNumberOfBitmaps<<14)+nNumberOfActions);
198 : :
199 : 0 : if (nPercent>=nLastPercent+3)
200 : : {
201 : 0 : nLastPercent=nPercent;
202 : 0 : if( nPercent<=100 )
203 : 0 : xStatusIndicator->setValue( nPercent );
204 : : }
205 : : }
206 : 0 : }
207 : :
208 : 0 : void PictWriter::CountActionsAndBitmaps(const GDIMetaFile & rMTF)
209 : : {
210 : : size_t nAction, nActionCount;
211 : : const MetaAction* pMA;
212 : :
213 : 0 : nActionCount = rMTF.GetActionSize();
214 : :
215 : 0 : for (nAction=0; nAction < nActionCount; nAction++)
216 : : {
217 : 0 : pMA = rMTF.GetAction( nAction );
218 : :
219 : 0 : switch( pMA->GetType() )
220 : : {
221 : : case META_BMP_ACTION:
222 : : case META_BMPSCALE_ACTION:
223 : : case META_BMPSCALEPART_ACTION:
224 : : case META_BMPEX_ACTION:
225 : : case META_BMPEXSCALE_ACTION:
226 : : case META_BMPEXSCALEPART_ACTION:
227 : : case META_RENDERGRAPHIC_ACTION:
228 : 0 : nNumberOfBitmaps++;
229 : 0 : break;
230 : : }
231 : :
232 : 0 : nNumberOfActions++;
233 : : }
234 : 0 : }
235 : :
236 : :
237 : 0 : Polygon PictWriter::PolyPolygonToPolygon(const PolyPolygon & rPolyPoly)
238 : : {
239 : : sal_uInt16 nCount,nSize1,nSize2,np,i1,i2,i3,nBestIdx1,nBestIdx2;
240 : : long nDistSqr,nBestDistSqr, nCountdownTests;
241 : 0 : Point aP1,aPRel;
242 : 0 : Polygon aPoly1, aPoly2, aPoly3;
243 : :
244 : 0 : nCount=rPolyPoly.Count();
245 : 0 : if (nCount==0) return Polygon(0);
246 : :
247 : 0 : aPoly1=rPolyPoly.GetObject(0);
248 : 0 : for (np=1; np<nCount; np++) {
249 : 0 : aPoly2=rPolyPoly.GetObject(np);
250 : :
251 : : //-----------------The following code merges aPoly1 and aPoly2 to aPoly1-----------------
252 : :
253 : 0 : nSize1=aPoly1.GetSize();
254 : 0 : nSize2=aPoly2.GetSize();
255 : :
256 : : // At first we look for a point in aPoly1 (referenced by nBestIdx1) and a
257 : : // point in aPoly2 (referenced by nBestid2), which
258 : : // Zunaechst werden ein Punkt in aPoly1 (referenziert durch nBestIdx1) und ein
259 : : // Punkt in aPoly2 (referenziert durch nBestIdx2) gesucht, die moeglichst dicht
260 : : // beieinander liegen. Da dies mit quadratischem Aufwand einher geht, und somit
261 : : // manche Bilder Ewigkeiten benoetigen, um exportiert zu werden, begrenzen wir
262 : : // die Anzahl der Tests auf 1000, und brechen die Suche ggf. schon vorher ab.
263 : : // Dadruch wird das Ergebnis nicht falsch, sondern eventuell nicht so schoen.
264 : 0 : nCountdownTests=1000;
265 : 0 : nBestDistSqr=0x7fffffff;
266 : 0 : nBestIdx1=0;
267 : 0 : nBestIdx2=0;
268 : 0 : for (i1=0; i1<nSize1; i1++) {
269 : 0 : aP1=aPoly1.GetPoint(i1);
270 : 0 : for (i2=0; i2<nSize2; i2++) {
271 : 0 : aPRel=aPoly2.GetPoint(i2); aPRel-=aP1;
272 : 0 : nDistSqr=aPRel.X()*aPRel.X()+aPRel.Y()*aPRel.Y();
273 : 0 : if (nDistSqr<nBestDistSqr) {
274 : 0 : nBestIdx1=i1;
275 : 0 : nBestIdx2=i2;
276 : 0 : nBestDistSqr=nDistSqr;
277 : : }
278 : 0 : if (nCountdownTests<=0) break;
279 : 0 : nCountdownTests--;
280 : : }
281 : 0 : if (nCountdownTests<=0) break;
282 : : }
283 : :
284 : : // Now aPoly1 and aPoly2 are being merged to a polygon aPoly3 (later aPoly1)
285 : : // Both polygons are being connected by two additional edges between the points found above
286 : 0 : aPoly3.Clear();
287 : 0 : aPoly3.SetSize(nSize1+nSize2+2);
288 : 0 : i3=0;
289 : 0 : for (i1=nBestIdx1; i1<nSize1; i1++) aPoly3.SetPoint(aPoly1.GetPoint(i1),i3++);
290 : 0 : for (i1=0; i1<=nBestIdx1; i1++) aPoly3.SetPoint(aPoly1.GetPoint(i1),i3++);
291 : 0 : for (i2=nBestIdx2; i2<nSize2; i2++) aPoly3.SetPoint(aPoly2.GetPoint(i2),i3++);
292 : 0 : for (i2=0; i2<=nBestIdx2; i2++) aPoly3.SetPoint(aPoly2.GetPoint(i2),i3++);
293 : :
294 : 0 : aPoly1=aPoly3;
295 : :
296 : : //-----------------------------------------------------------------------------------
297 : :
298 : : }
299 : 0 : return aPoly1;
300 : : }
301 : :
302 : :
303 : 0 : void PictWriter::WritePoint(const Point & rPoint)
304 : : {
305 : 0 : Point aPoint = OutputDevice::LogicToLogic( rPoint, aSrcMapMode, aTargetMapMode );
306 : 0 : *pPict << ((short)aPoint.Y()) << ((short)aPoint.X());
307 : 0 : }
308 : :
309 : :
310 : 0 : void PictWriter::WriteSize(const Size & rSize)
311 : : {
312 : 0 : OutputDevice::LogicToLogic( rSize, aSrcMapMode, aTargetMapMode ); // -Wall is this needed.
313 : 0 : *pPict << ((short)rSize.Height()) << ((short)rSize.Width());
314 : 0 : }
315 : :
316 : :
317 : 0 : void PictWriter::WriteRGBColor(const Color & rColor)
318 : : {
319 : 0 : const sal_uInt16 nR = ( (sal_uInt16) rColor.GetRed() << 8 ) | (sal_uInt16) rColor.GetRed();
320 : 0 : const sal_uInt16 nG = ( (sal_uInt16) rColor.GetGreen() << 8 ) | (sal_uInt16) rColor.GetGreen();
321 : 0 : const sal_uInt16 nB = ( (sal_uInt16) rColor.GetBlue() << 8 ) | (sal_uInt16) rColor.GetBlue();
322 : :
323 : 0 : *pPict << nR << nG << nB;
324 : 0 : }
325 : :
326 : 0 : void PictWriter::WriteString( const String & rString )
327 : : {
328 : 0 : rtl::OString aString(rtl::OUStringToOString(rString, osl_getThreadTextEncoding()));
329 : 0 : sal_Int32 nLen = aString.getLength();
330 : 0 : if ( nLen > 255 )
331 : 0 : nLen = 255;
332 : 0 : *pPict << ( (sal_uInt8)nLen );
333 : 0 : for (sal_Int32 i = 0; i < nLen; ++i)
334 : 0 : *pPict << aString[i];
335 : 0 : }
336 : :
337 : 0 : Rectangle PictWriter::MapRectangle( const Rectangle& rRect )
338 : : {
339 : 0 : Point aPoint = OutputDevice::LogicToLogic( rRect.TopLeft(), aSrcMapMode, aTargetMapMode );
340 : 0 : Size aSize = OutputDevice::LogicToLogic( rRect.GetSize(), aSrcMapMode, aTargetMapMode );
341 : 0 : Rectangle aRect( aPoint, aSize );
342 : 0 : aRect.Justify();
343 : 0 : aRect.nBottom++;
344 : 0 : aRect.nRight++;
345 : 0 : return aRect;
346 : : }
347 : :
348 : 0 : void PictWriter::WriteRectangle(const Rectangle & rRect)
349 : : {
350 : 0 : Rectangle aRect( MapRectangle( rRect ) );
351 : 0 : *pPict << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
352 : 0 : << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
353 : 0 : }
354 : :
355 : 0 : void PictWriter::WritePolygon(const Polygon & rPoly)
356 : : {
357 : : sal_uInt16 nDataSize,i,nSize;
358 : 0 : short nMinX = 0, nMinY = 0, nMaxX = 0, nMaxY = 0;
359 : : short nx,ny;
360 : 0 : Polygon aPoly(rPoly);
361 : :
362 : 0 : nSize=aPoly.GetSize();
363 : :
364 : 0 : if (aPoly.GetPoint(0) != aPoly.GetPoint(nSize-1))
365 : : {
366 : 0 : nSize++;
367 : 0 : aPoly.SetSize(nSize);
368 : 0 : aPoly.SetPoint(aPoly.GetPoint(0),nSize-1);
369 : : }
370 : :
371 : 0 : nDataSize=nSize*4+10;
372 : 0 : for (i=0; i<nSize; i++)
373 : : {
374 : 0 : Point aPoint = OutputDevice::LogicToLogic( aPoly.GetPoint( i ),
375 : : aSrcMapMode,
376 : 0 : aTargetMapMode );
377 : :
378 : 0 : nx = (short) aPoint.X();
379 : 0 : ny = (short) aPoint.Y();
380 : :
381 : 0 : if ( i==0 || nMinX>nx )
382 : 0 : nMinX=nx;
383 : 0 : if ( i==0 || nMinY>ny )
384 : 0 : nMinY=ny;
385 : 0 : if ( i==0 || nMaxX<nx )
386 : 0 : nMaxX=nx;
387 : 0 : if ( i==0 || nMaxY<ny )
388 : 0 : nMaxY=ny;
389 : : }
390 : :
391 : 0 : *pPict << nDataSize << nMinY << nMinX << nMaxY << nMaxX;
392 : :
393 : 0 : for (i=0; i<nSize; i++)
394 : 0 : WritePoint( aPoly.GetPoint(i) );
395 : 0 : }
396 : :
397 : :
398 : 0 : void PictWriter::WriteArcAngles(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
399 : : {
400 : : Point aStartPt = OutputDevice::LogicToLogic( rStartPt,
401 : : aSrcMapMode,
402 : 0 : aTargetMapMode );
403 : : Point aEndPt = OutputDevice::LogicToLogic( rEndPt,
404 : : aSrcMapMode,
405 : 0 : aTargetMapMode );
406 : : Rectangle aRect( OutputDevice::LogicToLogic( rRect.TopLeft(),
407 : : aSrcMapMode,
408 : 0 : aTargetMapMode ),
409 : : OutputDevice::LogicToLogic( rRect.GetSize(),
410 : : aSrcMapMode,
411 : 0 : aTargetMapMode ) );
412 : 0 : Point aCenter;
413 : : double fAngS, fAngE, fdx, fdy;
414 : : short nStartAngle, nArcAngle;
415 : :
416 : :
417 : 0 : aCenter=Point( ( aRect.Left() + aRect.Right() ) >> 1,
418 : 0 : ( aRect.Top() + aRect.Bottom() ) >> 1 );
419 : :
420 : 0 : fdx=(double)(aStartPt.X()-aCenter.X());
421 : 0 : fdy=(double)(aStartPt.Y()-aCenter.Y());
422 : 0 : if ( fdx==0.0 && fdy==0.0 )
423 : 0 : fdx=1.0;
424 : 0 : fAngE=atan2(fdx,-fdy);
425 : :
426 : 0 : fdx=(double)(aEndPt.X()-aCenter.X());
427 : 0 : fdy=(double)(aEndPt.Y()-aCenter.Y());
428 : 0 : if ( fdx==0.0 && fdy==0.0 )
429 : 0 : fdx=1.0;
430 : 0 : fAngS=atan2(fdx,-fdy);
431 : :
432 : 0 : nStartAngle=(short)(fAngS*180.0/3.14159265359);
433 : 0 : nArcAngle=((short)(fAngE*180.0/3.14159265359))-nStartAngle;
434 : 0 : if (nArcAngle<0)
435 : 0 : nArcAngle += 360;
436 : 0 : *pPict << nStartAngle << nArcAngle;
437 : 0 : }
438 : :
439 : :
440 : 0 : void PictWriter::ConvertLinePattern(PictPattern & rPat, sal_Bool bVisible) const
441 : : {
442 : 0 : if( bVisible )
443 : : {
444 : 0 : rPat.nHi=0xffffffff;
445 : 0 : rPat.nLo=0xffffffff;
446 : : }
447 : : else
448 : : {
449 : 0 : rPat.nHi=0x00000000;
450 : 0 : rPat.nLo=0x00000000;
451 : : }
452 : 0 : }
453 : :
454 : 0 : void PictWriter::ConvertFillPattern(PictPattern & rPat, sal_Bool bVisible) const
455 : : {
456 : 0 : if( bVisible )
457 : : {
458 : 0 : rPat.nHi=0xffffffff;
459 : 0 : rPat.nLo=0xffffffff;
460 : : }
461 : : else
462 : : {
463 : 0 : rPat.nHi=0x00000000;
464 : 0 : rPat.nLo=0x00000000;
465 : : }
466 : 0 : }
467 : :
468 : :
469 : 0 : void PictWriter::WriteOpcode_TxFace(const Font & rFont)
470 : : {
471 : : sal_uInt8 nFace;
472 : : FontWeight eWeight;
473 : :
474 : 0 : nFace=0;
475 : 0 : eWeight=rFont.GetWeight();
476 : 0 : if (eWeight==WEIGHT_BOLD ||
477 : : eWeight==WEIGHT_SEMIBOLD ||
478 : : eWeight==WEIGHT_ULTRABOLD ||
479 : 0 : eWeight==WEIGHT_BLACK) nFace|=0x01;
480 : 0 : if (rFont.GetItalic()!=ITALIC_NONE) nFace|=0x02;
481 : 0 : if (rFont.GetUnderline()!=UNDERLINE_NONE) nFace|=0x04;
482 : 0 : if (rFont.IsOutline()==sal_True) nFace|=0x08;
483 : 0 : if (rFont.IsShadow()==sal_True) nFace|=0x10;
484 : :
485 : 0 : if (bDstTxFaceValid==sal_False || nDstTxFace!=nFace) {
486 : 0 : *pPict << (sal_uInt16)0x0004 << nFace << (sal_uInt8)0;
487 : 0 : nDstTxFace=nFace;
488 : 0 : bDstTxFaceValid=sal_True;
489 : : }
490 : 0 : }
491 : :
492 : :
493 : 0 : void PictWriter::WriteOpcode_TxMode(RasterOp eMode)
494 : : {
495 : : sal_uInt16 nVal;
496 : :
497 : 0 : if (bDstTxModeValid==sal_False || eDstTxMode!=eMode) {
498 : 0 : switch (eMode) {
499 : 0 : case ROP_INVERT: nVal=0x000c; break;
500 : 0 : case ROP_XOR: nVal=0x000a; break;
501 : 0 : default: nVal=0x0008;
502 : : }
503 : 0 : *pPict << (sal_uInt16)0x0005 << nVal;
504 : 0 : eDstTxMode=eMode;
505 : 0 : bDstTxModeValid=sal_True;
506 : : }
507 : 0 : }
508 : :
509 : :
510 : 0 : void PictWriter::WriteOpcode_PnSize(sal_uInt16 nSize)
511 : : {
512 : 0 : if (nSize==0) nSize=1;
513 : 0 : if (bDstPnSizeValid==sal_False || nDstPnSize!=nSize) {
514 : 0 : *pPict << (sal_uInt16)0x0007 << nSize << nSize;
515 : 0 : nDstPnSize=nSize;
516 : 0 : bDstPnSizeValid=sal_True;
517 : : }
518 : 0 : }
519 : :
520 : :
521 : 0 : void PictWriter::WriteOpcode_PnMode(RasterOp eMode)
522 : : {
523 : : sal_uInt16 nVal;
524 : :
525 : 0 : if (bDstPnModeValid==sal_False || eDstPnMode!=eMode) {
526 : 0 : switch (eMode)
527 : : {
528 : 0 : case ROP_INVERT: nVal=0x000c; break;
529 : 0 : case ROP_XOR: nVal=0x000a; break;
530 : 0 : default: nVal=0x0008;
531 : : }
532 : 0 : *pPict << (sal_uInt16)0x0008 << nVal;
533 : 0 : eDstPnMode=eMode;
534 : 0 : bDstPnModeValid=sal_True;
535 : : }
536 : 0 : }
537 : :
538 : :
539 : 0 : void PictWriter::WriteOpcode_PnLinePat(sal_Bool bVisible)
540 : : {
541 : : PictPattern aPat;
542 : :
543 : 0 : ConvertLinePattern(aPat,bVisible);
544 : 0 : if (bDstPnPatValid==sal_False || aDstPnPat.nHi!=aPat.nHi || aDstPnPat.nLo!=aPat.nLo) {
545 : 0 : *pPict << (sal_uInt16)0x0009 << aPat.nHi << aPat.nLo;
546 : 0 : aDstPnPat=aPat;
547 : 0 : bDstPnPatValid=sal_True;
548 : : }
549 : 0 : }
550 : :
551 : :
552 : 0 : void PictWriter::WriteOpcode_PnFillPat(sal_Bool bVisible)
553 : : {
554 : : PictPattern aPat;
555 : :
556 : 0 : ConvertFillPattern(aPat,bVisible);
557 : 0 : if (bDstPnPatValid==sal_False || aDstPnPat.nHi!=aPat.nHi || aDstPnPat.nLo!=aPat.nLo) {
558 : 0 : *pPict << (sal_uInt16)0x0009 << aPat.nHi << aPat.nLo;
559 : 0 : aDstPnPat=aPat;
560 : 0 : bDstPnPatValid=sal_True;
561 : : }
562 : 0 : }
563 : :
564 : :
565 : 0 : void PictWriter::WriteOpcode_OvSize(const Size & rSize)
566 : : {
567 : 0 : *pPict << (sal_uInt16)0x000b;
568 : 0 : WriteSize(rSize);
569 : 0 : }
570 : :
571 : :
572 : 0 : void PictWriter::WriteOpcode_TxSize(sal_uInt16 nSize)
573 : : {
574 : 0 : if (bDstTxSizeValid==sal_False || nDstTxSize!=nSize) {
575 : :
576 : : nDstTxSize = (sal_uInt16) OutputDevice::LogicToLogic( Size( 0, nSize ),
577 : 0 : aSrcMapMode, aTargetMapMode ).Height();
578 : :
579 : 0 : *pPict << (sal_uInt16)0x000d << nDstTxSize;
580 : 0 : bDstTxSizeValid=sal_True;
581 : : }
582 : 0 : }
583 : :
584 : :
585 : 0 : void PictWriter::WriteOpcode_RGBFgCol(const Color & rColor)
586 : : {
587 : 0 : if (bDstFgColValid==sal_False || aDstFgCol!=rColor) {
588 : 0 : *pPict << (sal_uInt16)0x001a;
589 : 0 : WriteRGBColor(rColor);
590 : 0 : aDstFgCol=rColor;
591 : 0 : bDstFgColValid=sal_True;
592 : : }
593 : 0 : }
594 : :
595 : :
596 : 0 : void PictWriter::WriteOpcode_RGBBkCol(const Color & rColor)
597 : : {
598 : 0 : if (bDstBkColValid==sal_False || aDstBkCol!=rColor) {
599 : 0 : *pPict << (sal_uInt16)0x001b;
600 : 0 : WriteRGBColor(rColor);
601 : 0 : aDstBkCol=rColor;
602 : 0 : bDstBkColValid=sal_True;
603 : : }
604 : 0 : }
605 : :
606 : :
607 : 0 : void PictWriter::WriteOpcode_Line(const Point & rLocPt, const Point & rNewPt)
608 : : {
609 : : Point aLocPt = OutputDevice::LogicToLogic( rLocPt,
610 : : aSrcMapMode,
611 : 0 : aTargetMapMode );
612 : : Point aNewPt = OutputDevice::LogicToLogic( rNewPt,
613 : : aSrcMapMode,
614 : 0 : aTargetMapMode );
615 : : long dh,dv;
616 : :
617 : 0 : dh=aNewPt.X()-aLocPt.X();
618 : 0 : dv=aNewPt.Y()-aLocPt.Y();
619 : 0 : if (dh<=127 && dh>=-128 && dv<=127 && dv>=-128)
620 : : { // ShortLine
621 : 0 : *pPict << (sal_uInt16)0x0022;
622 : 0 : WritePoint(rLocPt);
623 : 0 : *pPict << (char)dh << (char)dv;
624 : : }
625 : : else
626 : : {
627 : 0 : *pPict << (sal_uInt16)0x0020;
628 : 0 : WritePoint(rLocPt);
629 : 0 : WritePoint(rNewPt);
630 : : }
631 : 0 : aDstPenPosition=rNewPt;
632 : 0 : bDstPenPositionValid=sal_True;
633 : 0 : }
634 : :
635 : :
636 : 0 : void PictWriter::WriteOpcode_LineFrom(const Point & rNewPt)
637 : : {
638 : : Point aNewPt = OutputDevice::LogicToLogic( rNewPt,
639 : : aSrcMapMode,
640 : 0 : aTargetMapMode );
641 : : long dh,dv;
642 : :
643 : 0 : dh = aNewPt.X()-aDstPenPosition.X();
644 : 0 : dv = aNewPt.Y()-aDstPenPosition.Y();
645 : :
646 : 0 : if (dh<=127 && dh>=-128 && dv<=127 && dv>=-128)
647 : : { // ShortLine
648 : 0 : *pPict << (sal_uInt16)0x0023;
649 : 0 : *pPict << (char)dh << (char)dv;
650 : : }
651 : : else
652 : : {
653 : 0 : *pPict << (sal_uInt16)0x0021;
654 : 0 : WritePoint(rNewPt);
655 : : }
656 : 0 : aDstPenPosition=rNewPt;
657 : 0 : bDstPenPositionValid=sal_True;
658 : 0 : }
659 : :
660 : :
661 : 0 : void PictWriter::WriteOpcode_Text(const Point & rPoint, const String& rString, sal_Bool bDelta)
662 : : {
663 : : Point aPoint = OutputDevice::LogicToLogic( rPoint,
664 : : aSrcMapMode,
665 : 0 : aTargetMapMode );
666 : : long dh,dv;
667 : : sal_uLong nPos;
668 : :
669 : 0 : nPos = pPict->Tell();
670 : 0 : dh = aPoint.X()-aDstTextPosition.X();
671 : 0 : dv = aPoint.Y()-aDstTextPosition.Y();
672 : :
673 : 0 : if (bDstTextPositionValid==sal_False || dh<0 || dh>255 || dv<0 || dv>0 || bDelta==sal_False)
674 : : {
675 : 0 : *pPict << (sal_uInt16)0x0028;
676 : 0 : WritePoint(rPoint);
677 : : }
678 : 0 : else if (dv==0)
679 : : {
680 : 0 : *pPict << (sal_uInt16)0x0029 << (sal_uInt8)dh;
681 : : }
682 : 0 : else if (dh==0)
683 : : {
684 : 0 : *pPict << (sal_uInt16)0x002a << (sal_uInt8)dv;
685 : : }
686 : : else
687 : : {
688 : 0 : *pPict << (sal_uInt16)0x002b << (sal_uInt8)dh << (sal_uInt8)dv;
689 : : }
690 : :
691 : 0 : WriteString( rString );
692 : 0 : if (((pPict->Tell()-nPos)&1)!=0)
693 : 0 : *pPict << (sal_uInt8)0;
694 : :
695 : 0 : aDstTextPosition = aPoint;
696 : 0 : bDstTextPositionValid=sal_True;
697 : 0 : }
698 : :
699 : :
700 : 0 : void PictWriter::WriteOpcode_FontName(const Font & rFont)
701 : : {
702 : : sal_uInt16 nDataLen,nFontId;
703 : :
704 : 0 : switch (rFont.GetFamily()) {
705 : 0 : case FAMILY_MODERN: nFontId=22; break;
706 : 0 : case FAMILY_ROMAN: nFontId=20; break;
707 : 0 : case FAMILY_SWISS: nFontId=21; break;
708 : 0 : default: nFontId=1;
709 : : }
710 : :
711 : 0 : if (bDstFontNameValid==sal_False || nDstFontNameId!=nFontId || aDstFontName!=rFont.GetName())
712 : : {
713 : 0 : rtl::OString aString(rtl::OUStringToOString(rFont.GetName(), osl_getThreadTextEncoding()));
714 : 0 : sal_uInt16 nFontNameLen = aString.getLength();
715 : 0 : if ( nFontNameLen )
716 : : {
717 : 0 : nDataLen = 3 + nFontNameLen;
718 : 0 : *pPict << (sal_uInt16)0x002c << nDataLen << nFontId;
719 : 0 : WriteString( rFont.GetName() );
720 : 0 : if ( ( nFontNameLen & 1 ) == 0 )
721 : 0 : *pPict << (sal_uInt8)0;
722 : : }
723 : 0 : *pPict << (sal_uInt16)0x0003 << nFontId;
724 : 0 : aDstFontName=rFont.GetName();
725 : 0 : nDstFontNameId=nFontId;
726 : 0 : bDstFontNameValid=sal_True;
727 : : }
728 : 0 : }
729 : :
730 : 0 : void PictWriter::WriteOpcode_ClipRect( const Rectangle& rRect )
731 : : {
732 : 0 : Rectangle aRect( MapRectangle( rRect ) );
733 : 0 : aRect.nBottom++;
734 : 0 : aRect.nRight++;
735 : 0 : *pPict << (sal_uInt16)1 // opcode 1
736 : 0 : << (sal_uInt16)10 // data size
737 : 0 : << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
738 : 0 : << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
739 : 0 : aClipRect = aRect;
740 : 0 : }
741 : :
742 : 0 : void PictWriter::WriteOpcode_Rect(PictDrawingMethod eMethod, const Rectangle & rRect)
743 : : {
744 : : sal_uInt16 oc;
745 : 0 : switch (eMethod) {
746 : 0 : case PDM_FRAME: oc=0x0030; break;
747 : 0 : case PDM_PAINT: oc=0x0031; break;
748 : 0 : case PDM_ERASE: oc=0x0032; break;
749 : 0 : case PDM_INVERT: oc=0x0033; break;
750 : 0 : case PDM_FILL: oc=0x0034; break;
751 : 0 : default: oc=0; break; // -Wall a default for oc...
752 : : }
753 : 0 : *pPict << oc;
754 : 0 : WriteRectangle(rRect);
755 : 0 : }
756 : :
757 : :
758 : 0 : void PictWriter::WriteOpcode_SameRect(PictDrawingMethod eMethod)
759 : : {
760 : : sal_uInt16 oc;
761 : 0 : switch (eMethod) {
762 : 0 : case PDM_FRAME: oc=0x0038; break;
763 : 0 : case PDM_PAINT: oc=0x0039; break;
764 : 0 : case PDM_ERASE: oc=0x003a; break;
765 : 0 : case PDM_INVERT: oc=0x003b; break;
766 : 0 : case PDM_FILL: oc=0x003c; break;
767 : 0 : default: oc=0; break; // -Wall a default for oc...
768 : : }
769 : 0 : *pPict << oc;
770 : 0 : }
771 : :
772 : :
773 : 0 : void PictWriter::WriteOpcode_RRect(PictDrawingMethod eMethod, const Rectangle & rRect)
774 : : {
775 : : sal_uInt16 oc;
776 : 0 : switch (eMethod) {
777 : 0 : case PDM_FRAME: oc=0x0040; break;
778 : 0 : case PDM_PAINT: oc=0x0041; break;
779 : 0 : case PDM_ERASE: oc=0x0042; break;
780 : 0 : case PDM_INVERT: oc=0x0043; break;
781 : 0 : case PDM_FILL: oc=0x0044; break;
782 : 0 : default: oc=0; break; // -Wall a default for oc...
783 : : }
784 : 0 : *pPict << oc;
785 : 0 : WriteRectangle(rRect);
786 : 0 : }
787 : :
788 : :
789 : 0 : void PictWriter::WriteOpcode_SameRRect(PictDrawingMethod eMethod)
790 : : {
791 : : sal_uInt16 oc;
792 : 0 : switch (eMethod) {
793 : 0 : case PDM_FRAME: oc=0x0048; break;
794 : 0 : case PDM_PAINT: oc=0x0049; break;
795 : 0 : case PDM_ERASE: oc=0x004a; break;
796 : 0 : case PDM_INVERT: oc=0x004b; break;
797 : 0 : case PDM_FILL: oc=0x004c; break;
798 : 0 : default: oc=0; break; // -Wall a default for oc...
799 : : }
800 : 0 : *pPict << oc;
801 : 0 : }
802 : :
803 : :
804 : 0 : void PictWriter::WriteOpcode_Oval(PictDrawingMethod eMethod, const Rectangle & rRect)
805 : : {
806 : : sal_uInt16 oc;
807 : 0 : switch (eMethod) {
808 : 0 : case PDM_FRAME: oc=0x0050; break;
809 : 0 : case PDM_PAINT: oc=0x0051; break;
810 : 0 : case PDM_ERASE: oc=0x0052; break;
811 : 0 : case PDM_INVERT: oc=0x0053; break;
812 : 0 : case PDM_FILL: oc=0x0054; break;
813 : 0 : default: oc=0; break; // -Wall a default for oc...
814 : : }
815 : 0 : *pPict << oc;
816 : 0 : WriteRectangle(rRect);
817 : 0 : }
818 : :
819 : :
820 : 0 : void PictWriter::WriteOpcode_SameOval(PictDrawingMethod eMethod)
821 : : {
822 : : sal_uInt16 oc;
823 : 0 : switch (eMethod) {
824 : 0 : case PDM_FRAME: oc=0x0058; break;
825 : 0 : case PDM_PAINT: oc=0x0059; break;
826 : 0 : case PDM_ERASE: oc=0x005a; break;
827 : 0 : case PDM_INVERT: oc=0x005b; break;
828 : 0 : case PDM_FILL: oc=0x005c; break;
829 : 0 : default: oc=0; break; // -Wall a default for oc...
830 : : }
831 : 0 : *pPict << oc;
832 : 0 : }
833 : :
834 : :
835 : 0 : void PictWriter::WriteOpcode_Arc(PictDrawingMethod eMethod, const Rectangle & rRect,
836 : : const Point & rStartPt, const Point & rEndPt)
837 : : {
838 : : sal_uInt16 oc;
839 : 0 : switch (eMethod) {
840 : 0 : case PDM_FRAME: oc=0x0060; break;
841 : 0 : case PDM_PAINT: oc=0x0061; break;
842 : 0 : case PDM_ERASE: oc=0x0062; break;
843 : 0 : case PDM_INVERT: oc=0x0063; break;
844 : 0 : case PDM_FILL: oc=0x0064; break;
845 : 0 : default: oc=0; break; // -Wall a default for oc...
846 : : }
847 : 0 : *pPict << oc;
848 : 0 : WriteRectangle(rRect);
849 : 0 : WriteArcAngles(rRect,rStartPt,rEndPt);
850 : 0 : }
851 : :
852 : :
853 : 0 : void PictWriter::WriteOpcode_SameArc(PictDrawingMethod eMethod, const Rectangle & rRect,
854 : : const Point & rStartPt, const Point & rEndPt)
855 : : {
856 : : sal_uInt16 oc;
857 : 0 : switch (eMethod) {
858 : 0 : case PDM_FRAME: oc=0x0068; break;
859 : 0 : case PDM_PAINT: oc=0x0069; break;
860 : 0 : case PDM_ERASE: oc=0x006a; break;
861 : 0 : case PDM_INVERT: oc=0x006b; break;
862 : 0 : case PDM_FILL: oc=0x006c; break;
863 : 0 : default: oc=0; break; // -Wall a default for oc...
864 : : }
865 : 0 : *pPict << oc;
866 : 0 : WriteArcAngles(rRect,rStartPt,rEndPt);
867 : 0 : }
868 : :
869 : :
870 : 0 : void PictWriter::WriteOpcode_Poly(PictDrawingMethod eMethod, const Polygon & rPoly)
871 : : {
872 : : sal_uInt16 oc;
873 : :
874 : 0 : if (rPoly.GetSize()<3) return;
875 : 0 : switch (eMethod) {
876 : 0 : case PDM_FRAME: oc=0x0070; break;
877 : 0 : case PDM_PAINT: oc=0x0071; break;
878 : 0 : case PDM_ERASE: oc=0x0072; break;
879 : 0 : case PDM_INVERT: oc=0x0073; break;
880 : 0 : case PDM_FILL: oc=0x0074; break;
881 : 0 : default: oc=0; break; // -Wall a default for oc...
882 : : }
883 : 0 : *pPict << oc;
884 : 0 : WritePolygon(rPoly);
885 : : }
886 : :
887 : :
888 : 0 : void PictWriter::WriteOpcode_BitsRect(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap)
889 : : {
890 : 0 : BitmapReadAccess* pAcc = NULL;
891 : 0 : Bitmap aBitmap( rBitmap );
892 : :
893 : : sal_uLong nWidth, nHeight, nDstRowBytes, nx, nc, ny, nCount, nColTabSize, i;
894 : : sal_uLong nDstRowPos, nSrcRowBytes, nEqu3, nPos, nDstMapPos;
895 : : sal_uInt16 nBitsPerPixel, nPackType;
896 : : sal_uInt8 *pComp[4], *pPix, *pTemp;
897 : 0 : sal_uInt8 nEquData = 0;
898 : : sal_uInt8 nFlagCounterByte, nRed, nGreen, nBlue;
899 : :
900 : 0 : SetAttrForPaint();
901 : :
902 : : // generating a temporary Windows-BMP-File:
903 : 0 : nActBitmapPercent=30;
904 : 0 : MayCallback();
905 : :
906 : 0 : if ( bStatus == sal_False )
907 : : return;
908 : 0 : if ( ( pAcc = aBitmap.AcquireReadAccess() ) == NULL )
909 : : return;
910 : :
911 : 0 : nBitsPerPixel = aBitmap.GetBitCount();
912 : :
913 : : // export code below only handles four discrete cases
914 : : nBitsPerPixel =
915 : 0 : nBitsPerPixel <= 1 ? 1 : nBitsPerPixel <= 4 ? 4 : nBitsPerPixel <= 8 ? 8 : 24;
916 : :
917 : 0 : nWidth = pAcc->Width();
918 : 0 : nHeight = pAcc->Height();
919 : :
920 : : // If 24-Bit, then create the Opcode 'DirectBitsRect':
921 : 0 : if ( nBitsPerPixel == 24 )
922 : : {
923 : : // Anzahl Bytes einer (ungepackten) Zeile in Quelle und Ziel berechnen:
924 : 0 : nSrcRowBytes =( ( 3 * nWidth ) + 0x0003 ) & 0xfffc;
925 : 0 : nDstRowBytes = nWidth * 4;
926 : :
927 : : // writing Opcode and BaseAddr (?):
928 : 0 : *pPict << (sal_uInt16)0x009a << (sal_uInt32)0x000000ff;
929 : :
930 : : // Normalerweise wollen wir den Packing-Type 4 (Run length encoding
931 : : // for 32-Bit Pixels) erzeugen. Wenn aber RowBytes<8 gilt, sind die Daten
932 : : // grundsaetzlich ungepackt, auch wenn der Packing-Type 4 angegeben ist,
933 : : // was etwas komisch erscheint. Daher wollen wir in so einem Fall lieber
934 : : // gleich den Packing-Type 1 (ungepackt) angeben:
935 : :
936 : 0 : if ( nDstRowBytes < 8 )
937 : 0 : nPackType = 1;
938 : : else
939 : 0 : nPackType = 4;
940 : :
941 : : // writing PixMap-Structure:
942 : 0 : *pPict << (sal_uInt16)(nDstRowBytes|0x8000) // Bytes per row and the fact that it's a 'PixMap'
943 : 0 : << (sal_uInt16)0x0000 // Y1-position of the bitmap in the source
944 : 0 : << (sal_uInt16)0x0000 // X1-position of the bitmap in the source
945 : 0 : << (sal_uInt16)nHeight // Y2-position of the bitmap in the source
946 : 0 : << (sal_uInt16)nWidth // X2-position of the bitmap in the source
947 : 0 : << (sal_uInt16)0x0000 // Version
948 : 0 : << (sal_uInt16)nPackType // Packing type
949 : 0 : << (sal_uInt32) 0x00000000 // Packing size (?)
950 : 0 : << (sal_uInt32) 0x00480000 // H-Res
951 : 0 : << (sal_uInt32) 0x00480000 // V-Res
952 : 0 : << (sal_uInt16)0x0010 // Pixel type (?)
953 : 0 : << (sal_uInt16)0x0020 // Pixel size: 32 bit
954 : 0 : << (sal_uInt16)0x0004 // CmpCount: 4 components
955 : 0 : << (sal_uInt16)0x0008 // CmpSize: 8 bits
956 : 0 : << (sal_uInt32) 0x00000000 // PlaneBytes (?)
957 : 0 : << (sal_uInt32) 0x00000000 // (?)
958 : 0 : << (sal_uInt32) 0x00000000; // (?)
959 : :
960 : : // Source-Rectangle schreiben:
961 : 0 : *pPict << (sal_uInt16)0x0000 // Y1-position on the bitmap
962 : 0 : << (sal_uInt16)0x0000 // X1-position on the bitmap
963 : 0 : << (sal_uInt16)nHeight // Y2-position on the bitmap
964 : 0 : << (sal_uInt16)nWidth; // X2-position on the bitmap
965 : :
966 : : // writing the Destination-Rectangle:
967 : 0 : WritePoint( rPoint );
968 : 0 : WritePoint( Point( rPoint.X() + rSize.Width(), rPoint.Y() + rSize.Height() ) );
969 : :
970 : : // writing the Transfer mode:
971 : 0 : *pPict << (sal_uInt16)0x0000; // (?)
972 : :
973 : : // remember position of the Map-data in the target:
974 : 0 : nDstMapPos=pPict->Tell();
975 : :
976 : 0 : if ( nPackType == 1 ) // when 24 bits nWidth == 1 !!
977 : : { // don't pack
978 : 0 : for ( ny = 0; ny < nHeight; ny++ )
979 : : {
980 : 0 : *pPict << (sal_uInt8)0;
981 : 0 : *pPict << (sal_uInt8)pAcc->GetPixel( ny, 0 ).GetRed();
982 : 0 : *pPict << (sal_uInt8)pAcc->GetPixel( ny, 0 ).GetGreen();
983 : 0 : *pPict << (sal_uInt8)pAcc->GetPixel( ny, 0 ).GetBlue();
984 : : // count percentages, Callback, check errors:
985 : 0 : nActBitmapPercent = ( ny * 70 / nHeight ) + 30; // (30% already added up to the writing of the Win-BMP file)
986 : 0 : MayCallback();
987 : : }
988 : : }
989 : : else // packing ( PackType == 4 )
990 : : {
991 : : // Speicher fuer Zeilen-Zwischen-Datenstruktur allozieren:
992 : 0 : for ( nc = 0; nc < 4; nc++ )
993 : 0 : pComp[ nc ] = new sal_uInt8[ nWidth ];
994 : :
995 : : // loop trough rows:
996 : 0 : for ( ny = 0; ny < nHeight; ny++ )
997 : : {
998 : : // Zeil ny der Quelle in die Zwischen-Datenstrktur einlesen:
999 : :
1000 : 0 : for ( nx = 0; nx < nWidth; nx++ )
1001 : : {
1002 : 0 : pComp[ 1 ][ nx ] = (sal_uInt8)pAcc->GetPixel( ny, nx ) .GetRed();
1003 : 0 : pComp[ 2 ][ nx ] = (sal_uInt8)pAcc->GetPixel( ny, nx ) .GetGreen();
1004 : 0 : pComp[ 3 ][ nx ] = (sal_uInt8)pAcc->GetPixel( ny, nx ) .GetBlue();
1005 : 0 : pComp[ 0 ][ nx ] = 0;
1006 : : }
1007 : :
1008 : : // remember start of the row in the target:
1009 : 0 : nDstRowPos = pPict->Tell();
1010 : :
1011 : : // ByteCount (that's the size of the packed row) is at first 0 (will be corrected later):
1012 : 0 : if ( nDstRowBytes > 250 )
1013 : 0 : *pPict << (sal_uInt16)0;
1014 : : else
1015 : 0 : *pPict << (sal_uInt8)0;
1016 : :
1017 : : // loop trough components:
1018 : 0 : for ( nc = 0; nc < 4; nc++ )
1019 : : {
1020 : : // loop through x:
1021 : 0 : nx = 0;
1022 : 0 : while ( nx < nWidth )
1023 : : {
1024 : : // look up the position of 3 equal bytes and seve it in nEqu3
1025 : : // if it's not found, set nEqu3=nWidth
1026 : : // if it's found save the value of the bytes in nEquData
1027 : 0 : nEqu3 = nx;
1028 : 0 : for (;;)
1029 : : {
1030 : 0 : if ( nEqu3 + 2 >= nWidth )
1031 : : {
1032 : 0 : nEqu3 = nWidth;
1033 : 0 : break;
1034 : : }
1035 : 0 : nEquData = pComp[nc][nEqu3];
1036 : 0 : if ( nEquData == pComp[nc][nEqu3+1] && nEquData==pComp[nc][nEqu3+2] )
1037 : 0 : break;
1038 : 0 : nEqu3++;
1039 : : }
1040 : :
1041 : : // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1042 : 0 : while ( nEqu3 > nx )
1043 : : {
1044 : 0 : nCount = nEqu3 - nx;
1045 : 0 : if ( nCount > 128 )
1046 : 0 : nCount=128;
1047 : 0 : nFlagCounterByte = (sal_uInt8)(nCount-1);
1048 : 0 : *pPict << nFlagCounterByte;
1049 : 0 : do
1050 : : {
1051 : 0 : *pPict << pComp[nc][nx++];
1052 : 0 : nCount--;
1053 : : }
1054 : : while ( nCount > 0 );
1055 : : }
1056 : :
1057 : : // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1058 : : // gleiche Bytes gefunden):
1059 : 0 : if ( nx < nWidth )
1060 : : { // Hint: Then one has nx==nEqu3 (hopefully)
1061 : 0 : nCount=3; // Three bytes are equal, as we found out above
1062 : : // Check, whether there are further equal bytes (and pay attention to Max.-Record-Size):
1063 : 0 : while ( nx + nCount < nWidth && nCount < 128 )
1064 : : {
1065 : 0 : if ( nEquData != pComp[ nc ][ nx + nCount ] )
1066 : 0 : break;
1067 : 0 : nCount++;
1068 : : }
1069 : : // nCount write equal Bytes compressed:
1070 : 0 : nFlagCounterByte = (sal_uInt8)( 1 - (long)nCount );
1071 : 0 : *pPict << nFlagCounterByte << nEquData;
1072 : 0 : nx += nCount;
1073 : : }
1074 : : }
1075 : : }
1076 : : // correct ByteCount:
1077 : 0 : nPos = pPict->Tell();
1078 : 0 : pPict->Seek( nDstRowPos );
1079 : 0 : if ( nDstRowBytes > 250 )
1080 : 0 : *pPict << ( (sal_uInt16)( nPos - nDstRowPos - 2 ) );
1081 : : else
1082 : 0 : *pPict << ( (sal_uInt8)( nPos - nDstRowPos - 1 ) );
1083 : 0 : pPict->Seek( nPos );
1084 : :
1085 : : // count percentages, Callback, check errors:
1086 : 0 : nActBitmapPercent = ( ny * 70 / nHeight ) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1087 : 0 : MayCallback();
1088 : : }
1089 : : // clean up:
1090 : 0 : for ( nc = 0; nc < 4; nc++ )
1091 : 0 : delete pComp[ nc ];
1092 : : }
1093 : : }
1094 : : else
1095 : : { // don't generate 24-bit i.e. Opcode 'PackBitsRect':
1096 : :
1097 : : // Bei 1-Bit-Bildern ignorieren manche Import-Filter die Palette und nehmen statt
1098 : : // dessen die Vorder- und Hintergrundfarbe:
1099 : 0 : if ( nBitsPerPixel == 1 )
1100 : : {
1101 : 0 : WriteOpcode_RGBBkCol( pAcc->GetPaletteColor( 0 ) );
1102 : 0 : WriteOpcode_RGBFgCol( pAcc->GetPaletteColor( 1 ) );
1103 : : }
1104 : : else
1105 : : {
1106 : 0 : WriteOpcode_RGBBkCol( Color( COL_BLACK ) );
1107 : 0 : WriteOpcode_RGBFgCol( Color( COL_WHITE ) );
1108 : : }
1109 : :
1110 : : // Anzahl Bytes einer (ungepackten) Zeile in Ziel und Quelle berechnen:
1111 : 0 : nDstRowBytes = ( nWidth * nBitsPerPixel + 7 ) >> 3;
1112 : 0 : nSrcRowBytes = ( nDstRowBytes + 3 ) & 0xfffffffc;
1113 : :
1114 : : // writing Opcode:
1115 : 0 : *pPict << (sal_uInt16)0x0098;
1116 : :
1117 : : // Normalerweise wollen wir den Packing-Type 0 (default Packing) erzeugen.
1118 : : // Wenn aber RowBytes<8 gilt, sind die Daten grundsaetzlich ungepackt,
1119 : : // auch wenn der Packing-Type 0 angegeben ist, was etwas komisch erscheint.
1120 : : // Daher wollen wir in so einem Fall lieber gleich den Packing-Type 1 (ungepackt)
1121 : : // angeben:
1122 : 0 : if ( nDstRowBytes < 8 )
1123 : 0 : nPackType = 1;
1124 : : else
1125 : 0 : nPackType = 0;
1126 : :
1127 : : // write PixMap-Structure:
1128 : 0 : *pPict << (sal_uInt16)(nDstRowBytes|0x8000) // Bytes per row and the fact that it's a 'PixMap'
1129 : 0 : << (sal_uInt16)0x0000 // Y1-position of the bitmap in the source
1130 : 0 : << (sal_uInt16)0x0000 // X1-position of the bitmap in the source
1131 : 0 : << (sal_uInt16)nHeight // Y2-position of the bitmap in the source
1132 : 0 : << (sal_uInt16)nWidth // X2-position of the bitmap in the source
1133 : 0 : << (sal_uInt16)0x0000 // Version
1134 : 0 : << (sal_uInt16)nPackType // Packing type
1135 : 0 : << (sal_uInt32) 0x00000000 // Packing size (?)
1136 : 0 : << (sal_uInt32) 0x00480000 // H-Res
1137 : 0 : << (sal_uInt32) 0x00480000 // V-Res
1138 : 0 : << (sal_uInt16)0x0000 // Pixel type (?)
1139 : 0 : << (sal_uInt16)nBitsPerPixel // Pixel size
1140 : 0 : << (sal_uInt16)0x0001 // CmpCount: 1 component
1141 : 0 : << (sal_uInt16)nBitsPerPixel // CmpSize
1142 : 0 : << (sal_uInt32) 0x00000000 // PlaneBytes (?)
1143 : 0 : << (sal_uInt32) 0x00000000 // (?)
1144 : 0 : << (sal_uInt32) 0x00000000; // (?)
1145 : :
1146 : : // writing and reading the palette:
1147 : 0 : nColTabSize = pAcc->GetPaletteEntryCount();
1148 : 0 : *pPict << (sal_uInt32)0 << (sal_uInt16)0x8000 << (sal_uInt16)( nColTabSize - 1 );
1149 : :
1150 : 0 : for ( i = 0; i < nColTabSize; i++ )
1151 : : {
1152 : 0 : nRed = (sal_uInt8)pAcc->GetPaletteColor( (sal_uInt16)i ).GetRed();
1153 : 0 : nGreen = (sal_uInt8)pAcc->GetPaletteColor( (sal_uInt16)i ).GetGreen();
1154 : 0 : nBlue = (sal_uInt8)pAcc->GetPaletteColor( (sal_uInt16)i ).GetBlue();
1155 : 0 : *pPict << (sal_uInt16)0 << nRed << nRed << nGreen << nGreen << nBlue << nBlue;
1156 : : }
1157 : :
1158 : : // writing Source-Rectangle:
1159 : 0 : *pPict << (sal_uInt16)0 << (sal_uInt16)0 << (sal_uInt16)nHeight << (sal_uInt16)nWidth;
1160 : :
1161 : : // writing Destination-Rectangle:
1162 : 0 : WritePoint( rPoint );
1163 : 0 : WritePoint( Point( rPoint.X() + rSize.Width(), rPoint.Y() + rSize.Height() ) );
1164 : :
1165 : : // writing Transfer mode:
1166 : 0 : *pPict << (sal_uInt16)0; // (?)
1167 : :
1168 : : // allocate memory for a row:
1169 : 0 : pPix = new sal_uInt8[ nSrcRowBytes ];
1170 : :
1171 : : // Position der Map-Daten in Ziel merken:
1172 : 0 : nDstMapPos=pPict->Tell();
1173 : :
1174 : : // loop trough rows:
1175 : 0 : for ( ny = 0; ny < nHeight; ny++ )
1176 : : {
1177 : :
1178 : : // Zeile ny der Quelle in den Zwischenspeicher einlesen:
1179 : :
1180 : 0 : switch ( nBitsPerPixel )
1181 : : {
1182 : : case 1 :
1183 : 0 : for ( pTemp = pPix, i = 0; i < nSrcRowBytes; i++ )
1184 : 0 : *pTemp++ = (sal_uInt8)0;
1185 : 0 : for ( i = 0; i < nWidth; i++ )
1186 : 0 : pPix[ ( i >> 3 ) ] |= (sal_uInt8)( pAcc->GetPixel( ny, i ) & 1 ) << ( ( i & 7 ) ^ 7 );
1187 : 0 : break;
1188 : : case 4 :
1189 : 0 : for ( pTemp = pPix, i = 0; i < nSrcRowBytes; i++ )
1190 : 0 : *pTemp++ = (sal_uInt8)0;
1191 : 0 : for ( i = 0; i < nWidth; i++ )
1192 : 0 : pPix[ ( i >> 1 ) ] |= (sal_uInt8)( pAcc->GetPixel( ny, i ) & 15 ) << ( ( i & 1 ) << 2 ) ;
1193 : 0 : break;
1194 : : case 8 :
1195 : 0 : for ( i = 0; i < nWidth; i++ )
1196 : 0 : pPix[ i ] = (sal_uInt8)pAcc->GetPixel( ny, i );
1197 : 0 : break;
1198 : : }
1199 : :
1200 : 0 : if ( nPackType == 1 )
1201 : : { // don't pack
1202 : 0 : pPict->Write( pPix, nDstRowBytes );
1203 : : }
1204 : : else
1205 : : { // Ppacking (nPackType==0)
1206 : :
1207 : : // remeber start of the row in the target:
1208 : 0 : nDstRowPos = pPict->Tell();
1209 : :
1210 : : // ByteCount (das ist die Groesse der gepackten Zeile) zunaechst 0 (wird spaeter berichtigt):
1211 : 0 : if ( nDstRowBytes > 250 )
1212 : 0 : *pPict << (sal_uInt16)0;
1213 : : else
1214 : 0 : *pPict << (sal_uInt8)0;
1215 : :
1216 : : // loop trough bytes of the row:
1217 : 0 : nx=0;
1218 : 0 : while ( nx < nDstRowBytes && bStatus )
1219 : : {
1220 : : // Die Position von 3 gleichen Bytes suchen und in nEqu3 merken.
1221 : : // wenn nicht gefunden, dann nEqu3=nDstRowBytes setzten.
1222 : : // Wenn doch gefunden, dann in nEquData den Wert der Bytes merken.
1223 : 0 : nEqu3 = nx;
1224 : 0 : for (;;)
1225 : : {
1226 : 0 : if ( nEqu3 + 2 >= nDstRowBytes )
1227 : : {
1228 : 0 : nEqu3 = nDstRowBytes;
1229 : 0 : break;
1230 : : }
1231 : 0 : nEquData = pPix[ nEqu3 ];
1232 : 0 : if ( nEquData == pPix[ nEqu3 + 1 ] && nEquData == pPix[ nEqu3 + 2 ] )
1233 : 0 : break;
1234 : 0 : nEqu3++;
1235 : : }
1236 : :
1237 : : // Die Daten von nx bis nEqu3 unkomprimiert schreiben (ggf. in mehreren Records):
1238 : 0 : while ( nEqu3 > nx )
1239 : : {
1240 : 0 : nCount = nEqu3 - nx;
1241 : 0 : if ( nCount > 128 )
1242 : 0 : nCount = 128;
1243 : 0 : nFlagCounterByte = (sal_uInt8)( nCount - 1 );
1244 : 0 : *pPict << nFlagCounterByte;
1245 : 0 : do
1246 : : {
1247 : 0 : *pPict << pPix[ nx++ ];
1248 : 0 : nCount--;
1249 : : } while ( nCount > 0 );
1250 : : }
1251 : :
1252 : : // Jetzt einen Komprimierungs-Record erzeugen (falls oben mindestens 3
1253 : : // gleiche Bytes gefunden):
1254 : 0 : if ( nx < nDstRowBytes )
1255 : : { // Hinweis: es gilt nx==nEqu3 (hoffentlich)
1256 : 0 : nCount = 3; // Drei Bytes sind gleich, wie weiter oben herausgefunden.
1257 : : // Pruefen, ob es weitere gleiche Bytes gibts (dabei Max.-Record-Groesse beachten):
1258 : 0 : while ( nx + nCount < nDstRowBytes && nCount < 128 )
1259 : : {
1260 : 0 : if ( nEquData != pPix[ nx + nCount ] )
1261 : 0 : break;
1262 : 0 : nCount++;
1263 : : }
1264 : : // nCount gleiche Bytes komprimiert schreiben:
1265 : 0 : nFlagCounterByte = (sal_uInt8)( 1 - (long)nCount );
1266 : 0 : *pPict << nFlagCounterByte << nEquData;
1267 : 0 : nx += nCount;
1268 : : }
1269 : : }
1270 : :
1271 : : // correct ByteCount:
1272 : 0 : nPos = pPict->Tell();
1273 : 0 : pPict->Seek( nDstRowPos );
1274 : 0 : if ( nDstRowBytes > 250 )
1275 : 0 : *pPict << ( (sal_uInt16)( nPos - nDstRowPos - 2 ) );
1276 : : else
1277 : 0 : *pPict << ( (sal_uInt8)( nPos - nDstRowPos - 1 ) );
1278 : 0 : pPict->Seek( nPos );
1279 : : }
1280 : :
1281 : : // count percentages, Callback, check errors:
1282 : 0 : nActBitmapPercent =( ny * 70 / nHeight ) + 30; // (30% machten schon das Schreiben der Win-BMP-Datei aus)
1283 : 0 : MayCallback();
1284 : 0 : if ( pPict->GetError() )
1285 : 0 : bStatus = sal_False;
1286 : : }
1287 : : // cleaning up:
1288 : 0 : delete[] pPix;
1289 : : }
1290 : :
1291 : : // Map-Data has to be an even number of bytes:
1292 : 0 : if ( ( ( pPict->Tell() - nDstMapPos ) & 1 ) != 0 )
1293 : 0 : *pPict << (sal_uInt8)0;
1294 : :
1295 : : // counting Bitmaps:
1296 : 0 : nWrittenBitmaps++;
1297 : 0 : nActBitmapPercent = 0;
1298 : 0 : if ( pAcc )
1299 : 0 : aBitmap.ReleaseAccess( pAcc );
1300 : : }
1301 : :
1302 : 0 : void PictWriter::WriteOpcode_EndOfFile()
1303 : : {
1304 : 0 : *pPict << (sal_uInt16)0x00ff;
1305 : 0 : }
1306 : :
1307 : :
1308 : 0 : void PictWriter::SetAttrForPaint()
1309 : : {
1310 : 0 : WriteOpcode_PnMode(eSrcRasterOp);
1311 : 0 : WriteOpcode_RGBFgCol(aFillColor);
1312 : 0 : WriteOpcode_RGBBkCol(aFillColor);
1313 : 0 : WriteOpcode_PnFillPat(aFillColor!=Color( COL_TRANSPARENT ));
1314 : 0 : }
1315 : :
1316 : :
1317 : 0 : void PictWriter::SetAttrForFrame()
1318 : : {
1319 : 0 : WriteOpcode_PnMode(eSrcRasterOp);
1320 : 0 : WriteOpcode_PnSize(0);
1321 : 0 : WriteOpcode_RGBFgCol(aLineColor);
1322 : 0 : WriteOpcode_PnLinePat(aLineColor!=Color( COL_TRANSPARENT ));
1323 : 0 : }
1324 : :
1325 : :
1326 : 0 : void PictWriter::SetAttrForText()
1327 : : {
1328 : 0 : WriteOpcode_RGBFgCol(aSrcFont.GetColor());
1329 : 0 : WriteOpcode_RGBBkCol(aSrcFont.GetFillColor());
1330 : 0 : WriteOpcode_PnLinePat(sal_True);
1331 : 0 : WriteOpcode_FontName(aSrcFont);
1332 : 0 : WriteOpcode_TxSize((sal_uInt16)(aSrcFont.GetSize().Height()));
1333 : 0 : WriteOpcode_TxMode(eSrcRasterOp);
1334 : 0 : WriteOpcode_TxFace(aSrcFont);
1335 : 0 : }
1336 : :
1337 : :
1338 : 0 : void PictWriter::WriteTextArray(Point & rPoint, const String& rString, const sal_Int32 * pDXAry)
1339 : : {
1340 : : sal_uInt16 i,nLen;
1341 : : sal_Unicode c;
1342 : : sal_Bool bDelta;
1343 : 0 : Point aPt;
1344 : :
1345 : 0 : if ( pDXAry == NULL )
1346 : 0 : WriteOpcode_Text( rPoint, rString, sal_False );
1347 : : else
1348 : : {
1349 : 0 : bDelta = sal_False;
1350 : 0 : nLen = rString.Len();
1351 : 0 : for ( i = 0; i < nLen; i++ )
1352 : : {
1353 : 0 : c = rString.GetChar( i );
1354 : 0 : if ( c && ( c != 0x20 ) )
1355 : : {
1356 : 0 : aPt = rPoint;
1357 : 0 : if ( i > 0 )
1358 : 0 : aPt.X() += pDXAry[ i - 1 ];
1359 : :
1360 : 0 : WriteOpcode_Text( aPt, rtl::OUString( c ), bDelta );
1361 : 0 : bDelta = sal_True;
1362 : : }
1363 : : }
1364 : : }
1365 : 0 : }
1366 : :
1367 : 0 : void PictWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
1368 : : {
1369 : 0 : if(rLinePolygon.count())
1370 : : {
1371 : 0 : basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
1372 : 0 : basegfx::B2DPolyPolygon aFillPolyPolygon;
1373 : :
1374 : 0 : rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
1375 : :
1376 : 0 : if(aLinePolyPolygon.count())
1377 : : {
1378 : 0 : aLinePolyPolygon = aLinePolyPolygon.getDefaultAdaptiveSubdivision();
1379 : 0 : const sal_uInt32 nPolyCount(aLinePolyPolygon.count());
1380 : 0 : SetAttrForFrame();
1381 : :
1382 : 0 : for(sal_uInt32 a(0); a < nPolyCount; a++)
1383 : : {
1384 : 0 : const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
1385 : 0 : const sal_uInt32 nPointCount(aCandidate.count());
1386 : :
1387 : 0 : if(nPointCount)
1388 : : {
1389 : 0 : const sal_uInt32 nEdgeCount(aCandidate.isClosed() ? nPointCount + 1 : nPointCount);
1390 : 0 : const basegfx::B2DPoint aCurr(aCandidate.getB2DPoint(0));
1391 : 0 : Point nCurr(basegfx::fround(aCurr.getX()), basegfx::fround(aCurr.getY()));
1392 : :
1393 : 0 : for(sal_uInt32 b(0); b < nEdgeCount; b++)
1394 : : {
1395 : 0 : const sal_uInt32 nNextIndex((b + 1) % nPointCount);
1396 : 0 : const basegfx::B2DPoint aNext(aCandidate.getB2DPoint(nNextIndex));
1397 : 0 : const Point nNext(basegfx::fround(aNext.getX()), basegfx::fround(aNext.getY()));
1398 : :
1399 : 0 : WriteOpcode_Line(nCurr, nNext);
1400 : 0 : nCurr = nNext;
1401 : 0 : }
1402 : : }
1403 : 0 : }
1404 : : }
1405 : :
1406 : 0 : if(aFillPolyPolygon.count())
1407 : : {
1408 : 0 : const Color aOldLineColor(aLineColor);
1409 : 0 : const Color aOldFillColor(aFillColor);
1410 : :
1411 : 0 : aLineColor = Color( COL_TRANSPARENT );
1412 : 0 : aFillColor = aOldLineColor;
1413 : 0 : SetAttrForPaint();
1414 : :
1415 : 0 : for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
1416 : : {
1417 : 0 : const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a).getDefaultAdaptiveSubdivision());
1418 : 0 : WriteOpcode_Poly(PDM_PAINT, aPolygon);
1419 : 0 : }
1420 : :
1421 : 0 : aLineColor = aOldLineColor;
1422 : 0 : aFillColor = aOldFillColor;
1423 : 0 : }
1424 : : }
1425 : 0 : }
1426 : :
1427 : 0 : void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
1428 : : {
1429 : : size_t nA, nACount;
1430 : : const MetaAction* pMA;
1431 : :
1432 : 0 : if( !bStatus)
1433 : 0 : return;
1434 : :
1435 : 0 : nACount = rMTF.GetActionSize();
1436 : :
1437 : 0 : for (nA=0; nA < nACount; nA++)
1438 : : {
1439 : 0 : pMA = rMTF.GetAction(nA);
1440 : :
1441 : 0 : switch (pMA->GetType())
1442 : : {
1443 : : case META_PIXEL_ACTION:
1444 : : {
1445 : 0 : const MetaPixelAction* pA = (const MetaPixelAction*) pMA;
1446 : 0 : WriteOpcode_PnMode(eSrcRasterOp);
1447 : 0 : WriteOpcode_PnSize(1);
1448 : 0 : WriteOpcode_RGBFgCol(pA->GetColor());
1449 : 0 : WriteOpcode_PnLinePat(sal_True);
1450 : 0 : WriteOpcode_Line(pA->GetPoint(),pA->GetPoint());
1451 : : }
1452 : 0 : break;
1453 : :
1454 : : case META_POINT_ACTION:
1455 : : {
1456 : 0 : const MetaPointAction* pA = (const MetaPointAction*) pMA;
1457 : :
1458 : 0 : if( aLineColor != Color( COL_TRANSPARENT ) )
1459 : : {
1460 : 0 : SetAttrForFrame();
1461 : 0 : WriteOpcode_Line( pA->GetPoint(),pA->GetPoint() );
1462 : : }
1463 : : }
1464 : 0 : break;
1465 : :
1466 : : case META_LINE_ACTION:
1467 : : {
1468 : 0 : const MetaLineAction* pA = (const MetaLineAction*) pMA;
1469 : :
1470 : 0 : if( aLineColor != Color( COL_TRANSPARENT ) )
1471 : : {
1472 : 0 : if(pA->GetLineInfo().IsDefault())
1473 : : {
1474 : 0 : SetAttrForFrame();
1475 : 0 : WriteOpcode_Line( pA->GetStartPoint(),pA->GetEndPoint() );
1476 : : }
1477 : : else
1478 : : {
1479 : : // LineInfo used; handle Dash/Dot and fat lines
1480 : 0 : basegfx::B2DPolygon aPolygon;
1481 : 0 : aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
1482 : 0 : aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
1483 : 0 : HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
1484 : : }
1485 : : }
1486 : 0 : break;
1487 : : }
1488 : :
1489 : : case META_RECT_ACTION:
1490 : : {
1491 : 0 : const MetaRectAction* pA = (const MetaRectAction*) pMA;
1492 : :
1493 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1494 : : {
1495 : 0 : SetAttrForPaint();
1496 : 0 : WriteOpcode_Rect(PDM_PAINT,pA->GetRect());
1497 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1498 : : {
1499 : 0 : SetAttrForFrame();
1500 : 0 : WriteOpcode_SameRect(PDM_FRAME);
1501 : : }
1502 : : }
1503 : 0 : else if (aLineColor!=Color( COL_TRANSPARENT ))
1504 : : {
1505 : 0 : SetAttrForFrame();
1506 : 0 : WriteOpcode_Rect(PDM_FRAME,pA->GetRect());
1507 : : }
1508 : : }
1509 : 0 : break;
1510 : :
1511 : : case META_ROUNDRECT_ACTION:
1512 : : {
1513 : 0 : const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
1514 : :
1515 : 0 : WriteOpcode_OvSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
1516 : :
1517 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1518 : : {
1519 : 0 : SetAttrForPaint();
1520 : 0 : WriteOpcode_RRect(PDM_PAINT,pA->GetRect());
1521 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1522 : : {
1523 : 0 : SetAttrForFrame();
1524 : 0 : WriteOpcode_SameRRect(PDM_FRAME);
1525 : : }
1526 : : }
1527 : 0 : else if (aLineColor!=Color( COL_TRANSPARENT ))
1528 : : {
1529 : 0 : SetAttrForFrame();
1530 : 0 : WriteOpcode_RRect(PDM_FRAME,pA->GetRect());
1531 : : }
1532 : : }
1533 : 0 : break;
1534 : :
1535 : : case META_ELLIPSE_ACTION:
1536 : : {
1537 : 0 : const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
1538 : :
1539 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1540 : : {
1541 : 0 : SetAttrForPaint();
1542 : 0 : WriteOpcode_Oval(PDM_PAINT,pA->GetRect());
1543 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1544 : : {
1545 : 0 : SetAttrForFrame();
1546 : 0 : WriteOpcode_SameOval(PDM_FRAME);
1547 : : }
1548 : : }
1549 : 0 : else if (aLineColor!=Color( COL_TRANSPARENT ))
1550 : : {
1551 : 0 : SetAttrForFrame();
1552 : 0 : WriteOpcode_Oval(PDM_FRAME,pA->GetRect());
1553 : : }
1554 : : }
1555 : 0 : break;
1556 : :
1557 : : case META_ARC_ACTION:
1558 : : {
1559 : 0 : const MetaArcAction* pA = (const MetaArcAction*) pMA;
1560 : :
1561 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1562 : : {
1563 : 0 : SetAttrForFrame();
1564 : 0 : WriteOpcode_Arc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1565 : : }
1566 : : }
1567 : 0 : break;
1568 : :
1569 : : case META_PIE_ACTION:
1570 : : {
1571 : 0 : const MetaPieAction* pA = (const MetaPieAction *) pMA;
1572 : :
1573 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1574 : : {
1575 : 0 : SetAttrForPaint();
1576 : 0 : WriteOpcode_Arc(PDM_PAINT,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1577 : :
1578 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1579 : : {
1580 : 0 : SetAttrForFrame();
1581 : 0 : WriteOpcode_SameArc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1582 : : }
1583 : : }
1584 : 0 : else if (aLineColor!=Color( COL_TRANSPARENT ))
1585 : : {
1586 : 0 : SetAttrForFrame();
1587 : 0 : WriteOpcode_Arc(PDM_FRAME,pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint());
1588 : : }
1589 : :
1590 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1591 : : {
1592 : : double fxc,fyc,fxr,fyr,fx1,fy1,fx2,fy2,l1,l2;
1593 : :
1594 : 0 : fxc=((double)(pA->GetRect().Left()+pA->GetRect().Right()))/2.0;
1595 : 0 : fyc=((double)(pA->GetRect().Top()+pA->GetRect().Bottom()))/2.0;
1596 : 0 : fxr=((double)pA->GetRect().GetWidth())/2.0;
1597 : 0 : fyr=((double)pA->GetRect().GetHeight())/2.0;
1598 : 0 : fx1=((double)pA->GetStartPoint().X())-fxc;
1599 : 0 : fy1=((double)pA->GetStartPoint().Y())-fyc;
1600 : 0 : fx2=((double)pA->GetEndPoint().X())-fxc;
1601 : 0 : fy2=((double)pA->GetEndPoint().Y())-fyc;
1602 : 0 : l1=sqrt(fx1*fx1+fy1*fy1);
1603 : 0 : l2=sqrt(fx2*fx2+fy2*fy2);
1604 : :
1605 : 0 : if (l1>0)
1606 : : {
1607 : 0 : fx1=fx1/l1*fxr;
1608 : 0 : fy1=fy1/l1*fyr;
1609 : : }
1610 : :
1611 : 0 : if (l2>0)
1612 : : {
1613 : 0 : fx2=fx2/l2*fxr;
1614 : 0 : fy2=fy2/l2*fyr;
1615 : : }
1616 : 0 : fx1+=fxc; fy1+=fyc; fx2+=fxc; fy2+=fyc;
1617 : 0 : WriteOpcode_Line(Point((long)(fx1+0.5),(long)(fy1+0.5)), Point((long)(fxc+0.5),(long)(fyc+0.5)));
1618 : 0 : WriteOpcode_LineFrom(Point((long)(fx2+0.5),(long)(fy2+0.5)));
1619 : : }
1620 : : }
1621 : 0 : break;
1622 : :
1623 : : case META_CHORD_ACTION:
1624 : : {
1625 : : // OSL_FAIL( "Unsupported PICT-Action: META_CHORD_ACTION!" );
1626 : : }
1627 : 0 : break;
1628 : :
1629 : : case META_POLYLINE_ACTION:
1630 : : {
1631 : 0 : const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
1632 : :
1633 : 0 : if( aLineColor!=Color( COL_TRANSPARENT ) )
1634 : : {
1635 : 0 : const Polygon& rPoly = pA->GetPolygon();
1636 : :
1637 : 0 : if( rPoly.GetSize() )
1638 : : {
1639 : 0 : if(pA->GetLineInfo().IsDefault())
1640 : : {
1641 : 0 : Polygon aSimplePoly;
1642 : 0 : if ( rPoly.HasFlags() )
1643 : 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
1644 : : else
1645 : 0 : aSimplePoly = rPoly;
1646 : :
1647 : 0 : const sal_uInt16 nSize = aSimplePoly.GetSize();
1648 : 0 : Point aLast;
1649 : :
1650 : 0 : if ( nSize )
1651 : : {
1652 : 0 : SetAttrForFrame();
1653 : 0 : aLast = aSimplePoly[0];
1654 : :
1655 : 0 : for ( sal_uInt16 i = 1; i < nSize; i++ )
1656 : : {
1657 : 0 : WriteOpcode_Line( aLast, aSimplePoly[i] );
1658 : 0 : aLast = aSimplePoly[i];
1659 : : }
1660 : 0 : }
1661 : : }
1662 : : else
1663 : : {
1664 : : // LineInfo used; handle Dash/Dot and fat lines
1665 : 0 : HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
1666 : : }
1667 : : }
1668 : : }
1669 : : }
1670 : 0 : break;
1671 : :
1672 : : case META_POLYGON_ACTION:
1673 : : {
1674 : 0 : const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
1675 : :
1676 : 0 : const Polygon& rPoly = pA->GetPolygon();
1677 : :
1678 : 0 : Polygon aSimplePoly;
1679 : 0 : if ( rPoly.HasFlags() )
1680 : 0 : rPoly.AdaptiveSubdivide( aSimplePoly );
1681 : : else
1682 : 0 : aSimplePoly = rPoly;
1683 : :
1684 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1685 : : {
1686 : 0 : SetAttrForPaint();
1687 : 0 : WriteOpcode_Poly( PDM_PAINT, aSimplePoly );
1688 : : }
1689 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1690 : : {
1691 : 0 : SetAttrForFrame();
1692 : 0 : WriteOpcode_Poly( PDM_FRAME, aSimplePoly );
1693 : 0 : }
1694 : : }
1695 : 0 : break;
1696 : :
1697 : : case META_POLYPOLYGON_ACTION:
1698 : : {
1699 : 0 : const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
1700 : :
1701 : 0 : const PolyPolygon& rPolyPoly = pA->GetPolyPolygon();
1702 : 0 : sal_uInt16 nPolyCount = rPolyPoly.Count();
1703 : 0 : PolyPolygon aSimplePolyPoly( rPolyPoly );
1704 : 0 : for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
1705 : : {
1706 : 0 : if ( aSimplePolyPoly[ i ].HasFlags() )
1707 : : {
1708 : 0 : Polygon aSimplePoly;
1709 : 0 : aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
1710 : 0 : aSimplePolyPoly[ i ] = aSimplePoly;
1711 : : }
1712 : : }
1713 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
1714 : : {
1715 : 0 : SetAttrForPaint();
1716 : 0 : WriteOpcode_Poly( PDM_PAINT, PolyPolygonToPolygon( aSimplePolyPoly ));
1717 : : }
1718 : :
1719 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
1720 : : {
1721 : : sal_uInt16 nCount,i;
1722 : 0 : SetAttrForFrame();
1723 : 0 : nCount = aSimplePolyPoly.Count();
1724 : 0 : for ( i = 0; i < nCount; i++ )
1725 : 0 : WriteOpcode_Poly( PDM_FRAME, aSimplePolyPoly.GetObject( i ) );
1726 : 0 : }
1727 : : }
1728 : 0 : break;
1729 : :
1730 : : case META_TEXT_ACTION:
1731 : : {
1732 : 0 : const MetaTextAction* pA = (const MetaTextAction*) pMA;
1733 : 0 : Point aPt( pA->GetPoint() );
1734 : :
1735 : 0 : if ( aSrcFont.GetAlign() != ALIGN_BASELINE )
1736 : : {
1737 : 0 : VirtualDevice aVirDev;
1738 : :
1739 : 0 : if (aSrcFont.GetAlign()==ALIGN_TOP)
1740 : 0 : aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1741 : : else
1742 : 0 : aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1743 : : }
1744 : :
1745 : 0 : SetAttrForText();
1746 : 0 : String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1747 : 0 : WriteOpcode_Text( aPt, aStr, sal_False );
1748 : : }
1749 : 0 : break;
1750 : :
1751 : : case META_TEXTARRAY_ACTION:
1752 : : {
1753 : 0 : const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
1754 : 0 : Point aPt( pA->GetPoint() );
1755 : :
1756 : 0 : if (aSrcFont.GetAlign()!=ALIGN_BASELINE)
1757 : : {
1758 : 0 : VirtualDevice aVirDev;
1759 : :
1760 : 0 : if (aSrcFont.GetAlign()==ALIGN_TOP)
1761 : 0 : aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1762 : : else
1763 : 0 : aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1764 : : }
1765 : 0 : SetAttrForText();
1766 : 0 : String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1767 : 0 : WriteTextArray( aPt, aStr, pA->GetDXArray() );
1768 : 0 : break;
1769 : : }
1770 : :
1771 : : case META_STRETCHTEXT_ACTION:
1772 : : {
1773 : 0 : const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pMA;
1774 : 0 : Point aPt( pA->GetPoint() );
1775 : 0 : String aStr( pA->GetText(),pA->GetIndex(),pA->GetLen() );
1776 : 0 : VirtualDevice aVirDev;
1777 : 0 : sal_Int32* pDXAry = new sal_Int32[ aStr.Len() ];
1778 : 0 : sal_Int32 nNormSize( aVirDev.GetTextArray( aStr,pDXAry ) );
1779 : : sal_uInt16 i;
1780 : :
1781 : 0 : if (aSrcFont.GetAlign()!=ALIGN_BASELINE)
1782 : : {
1783 : 0 : if (aSrcFont.GetAlign()==ALIGN_TOP)
1784 : 0 : aPt.Y()+=(long)aVirDev.GetFontMetric(aSrcFont).GetAscent();
1785 : : else
1786 : 0 : aPt.Y()-=(long)aVirDev.GetFontMetric(aSrcFont).GetDescent();
1787 : : }
1788 : :
1789 : 0 : for ( i = 0; i < aStr.Len() - 1; i++ )
1790 : 0 : pDXAry[ i ] = pDXAry[ i ] * ( (long)pA->GetWidth() ) / nNormSize;
1791 : :
1792 : 0 : SetAttrForText();
1793 : 0 : WriteTextArray( aPt, aStr, pDXAry );
1794 : 0 : delete[] pDXAry;
1795 : : }
1796 : 0 : break;
1797 : :
1798 : : case META_TEXTRECT_ACTION:
1799 : : {
1800 : : // OSL_FAIL( "Unsupported PICT-Action: META_TEXTRECT_ACTION!" );
1801 : : }
1802 : 0 : break;
1803 : :
1804 : : case META_BMP_ACTION:
1805 : : {
1806 : 0 : const MetaBmpAction* pA = (const MetaBmpAction*) pMA;
1807 : 0 : const Bitmap aBmp( pA->GetBitmap() );
1808 : 0 : VirtualDevice aVirDev;
1809 : :
1810 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), aVirDev.PixelToLogic( aBmp.GetSizePixel(), aSrcMapMode ), aBmp );
1811 : : }
1812 : 0 : break;
1813 : :
1814 : : case META_BMPSCALE_ACTION:
1815 : : {
1816 : 0 : const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
1817 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
1818 : : }
1819 : 0 : break;
1820 : :
1821 : : case META_BMPSCALEPART_ACTION:
1822 : : {
1823 : 0 : const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
1824 : 0 : Bitmap aBmp( pA->GetBitmap() );
1825 : :
1826 : 0 : aBmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1827 : 0 : WriteOpcode_BitsRect( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
1828 : : }
1829 : 0 : break;
1830 : :
1831 : : case META_BMPEX_ACTION:
1832 : : {
1833 : 0 : const MetaBmpExAction* pA = (const MetaBmpExAction*) pMA;
1834 : 0 : const Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1835 : 0 : VirtualDevice aVirDev;
1836 : :
1837 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), aVirDev.PixelToLogic( aBmp.GetSizePixel(), aSrcMapMode ), aBmp );
1838 : : }
1839 : 0 : break;
1840 : :
1841 : : case META_BMPEXSCALE_ACTION:
1842 : : {
1843 : 0 : const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
1844 : 0 : const Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1845 : :
1846 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), aBmp );
1847 : : }
1848 : 0 : break;
1849 : :
1850 : : case META_BMPEXSCALEPART_ACTION:
1851 : : {
1852 : 0 : const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
1853 : 0 : Bitmap aBmp( Graphic( pA->GetBitmapEx() ).GetBitmap() );
1854 : :
1855 : 0 : aBmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
1856 : 0 : WriteOpcode_BitsRect( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
1857 : : }
1858 : 0 : break;
1859 : :
1860 : : case META_EPS_ACTION :
1861 : : {
1862 : 0 : const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
1863 : 0 : const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
1864 : :
1865 : 0 : size_t nCount = aGDIMetaFile.GetActionSize();
1866 : 0 : for ( size_t i = 0; i < nCount; i++ )
1867 : : {
1868 : 0 : const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
1869 : 0 : if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
1870 : : {
1871 : 0 : const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
1872 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
1873 : 0 : break;
1874 : : }
1875 : 0 : }
1876 : : }
1877 : 0 : break;
1878 : :
1879 : : case META_MASK_ACTION:
1880 : : case META_MASKSCALE_ACTION:
1881 : : case META_MASKSCALEPART_ACTION:
1882 : : {
1883 : : // OSL_FAIL( "Unsupported PICT-Action: META_MASK..._ACTION!" );
1884 : : }
1885 : 0 : break;
1886 : :
1887 : : case META_GRADIENT_ACTION:
1888 : : {
1889 : 0 : VirtualDevice aVDev;
1890 : 0 : GDIMetaFile aTmpMtf;
1891 : 0 : const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
1892 : :
1893 : 0 : aVDev.SetMapMode( aTargetMapMode );
1894 : 0 : aVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
1895 : 0 : WriteOpcodes( aTmpMtf );
1896 : : }
1897 : 0 : break;
1898 : :
1899 : : case META_HATCH_ACTION:
1900 : : {
1901 : 0 : VirtualDevice aVDev;
1902 : 0 : GDIMetaFile aTmpMtf;
1903 : 0 : const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
1904 : :
1905 : 0 : aVDev.SetMapMode( aTargetMapMode );
1906 : 0 : aVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
1907 : 0 : WriteOpcodes( aTmpMtf );
1908 : : }
1909 : 0 : break;
1910 : :
1911 : : case META_WALLPAPER_ACTION:
1912 : : {
1913 : : // OSL_FAIL( "Unsupported PICT-Action: META_WALLPAPER_ACTION!" );
1914 : : }
1915 : 0 : break;
1916 : :
1917 : : case META_CLIPREGION_ACTION:
1918 : : {
1919 : : // OSL_FAIL( "Unsupported PICT-Action: META_CLIPREGION_ACTION!" );
1920 : : }
1921 : 0 : break;
1922 : :
1923 : : case META_ISECTRECTCLIPREGION_ACTION:
1924 : : {
1925 : 0 : const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
1926 : 0 : WriteOpcode_ClipRect( pA->GetRect() );
1927 : : }
1928 : 0 : break;
1929 : :
1930 : : case META_ISECTREGIONCLIPREGION_ACTION:
1931 : : {
1932 : : // OSL_FAIL( "Unsupported PICT-Action: META_ISECTREGIONCLIPREGION_ACTION!" );
1933 : : }
1934 : 0 : break;
1935 : :
1936 : : case META_MOVECLIPREGION_ACTION:
1937 : : {
1938 : : // OSL_FAIL( "Unsupported PICT-Action: META_MOVECLIPREGION_ACTION!" );
1939 : : }
1940 : 0 : break;
1941 : :
1942 : : case META_LINECOLOR_ACTION:
1943 : : {
1944 : 0 : const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
1945 : :
1946 : 0 : if( pA->IsSetting() )
1947 : 0 : aLineColor = pA->GetColor();
1948 : : else
1949 : 0 : aLineColor = Color( COL_TRANSPARENT );
1950 : : }
1951 : 0 : break;
1952 : :
1953 : : case META_FILLCOLOR_ACTION:
1954 : : {
1955 : 0 : const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
1956 : :
1957 : 0 : if( pA->IsSetting() )
1958 : 0 : aFillColor = pA->GetColor();
1959 : : else
1960 : 0 : aFillColor = Color( COL_TRANSPARENT );
1961 : : }
1962 : 0 : break;
1963 : :
1964 : : case META_TEXTCOLOR_ACTION:
1965 : : {
1966 : 0 : const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
1967 : 0 : aSrcFont.SetColor( pA->GetColor() );
1968 : : }
1969 : 0 : break;
1970 : :
1971 : : case META_TEXTFILLCOLOR_ACTION:
1972 : : {
1973 : 0 : const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
1974 : :
1975 : 0 : if( pA->IsSetting() )
1976 : 0 : aSrcFont.SetFillColor( pA->GetColor() );
1977 : : else
1978 : 0 : aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
1979 : : }
1980 : 0 : break;
1981 : :
1982 : : case META_TEXTALIGN_ACTION:
1983 : : {
1984 : : // OSL_FAIL( "Unsupported PICT-Action: META_TEXTALIGN_ACTION!" );
1985 : : }
1986 : 0 : break;
1987 : :
1988 : : case META_MAPMODE_ACTION:
1989 : : {
1990 : 0 : const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
1991 : :
1992 : 0 : if (aSrcMapMode!=pA->GetMapMode())
1993 : : {
1994 : 0 : if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
1995 : : {
1996 : 0 : MapMode aMM = pA->GetMapMode();
1997 : 0 : Fraction aScaleX = aMM.GetScaleX();
1998 : 0 : Fraction aScaleY = aMM.GetScaleY();
1999 : :
2000 : 0 : Point aOrigin = aSrcMapMode.GetOrigin();
2001 : 0 : BigInt aX( aOrigin.X() );
2002 : 0 : aX *= BigInt( aScaleX.GetDenominator() );
2003 : 0 : if( aOrigin.X() >= 0 )
2004 : : {
2005 : 0 : if( aScaleX.GetNumerator() >= 0 )
2006 : 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
2007 : : else
2008 : 0 : aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
2009 : : }
2010 : : else
2011 : : {
2012 : 0 : if( aScaleX.GetNumerator() >= 0 )
2013 : 0 : aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
2014 : : else
2015 : 0 : aX += BigInt( aScaleX.GetNumerator()/2 );
2016 : : }
2017 : :
2018 : 0 : aX /= BigInt( aScaleX.GetNumerator() );
2019 : 0 : aOrigin.X() = (long)aX + aMM.GetOrigin().X();
2020 : 0 : BigInt aY( aOrigin.Y() );
2021 : 0 : aY *= BigInt( aScaleY.GetDenominator() );
2022 : :
2023 : 0 : if( aOrigin.Y() >= 0 )
2024 : : {
2025 : 0 : if( aScaleY.GetNumerator() >= 0 )
2026 : 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
2027 : : else
2028 : 0 : aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
2029 : : }
2030 : : else
2031 : : {
2032 : 0 : if( aScaleY.GetNumerator() >= 0 )
2033 : 0 : aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
2034 : : else
2035 : 0 : aY += BigInt( aScaleY.GetNumerator()/2 );
2036 : : }
2037 : :
2038 : 0 : aY /= BigInt( aScaleY.GetNumerator() );
2039 : 0 : aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
2040 : 0 : aSrcMapMode.SetOrigin( aOrigin );
2041 : :
2042 : 0 : aScaleX *= aSrcMapMode.GetScaleX();
2043 : 0 : aScaleY *= aSrcMapMode.GetScaleY();
2044 : 0 : aSrcMapMode.SetScaleX( aScaleX );
2045 : 0 : aSrcMapMode.SetScaleY( aScaleY );
2046 : : }
2047 : : else
2048 : 0 : aSrcMapMode = pA->GetMapMode();
2049 : : }
2050 : : }
2051 : 0 : break;
2052 : :
2053 : : case META_FONT_ACTION:
2054 : : {
2055 : 0 : const MetaFontAction* pA = (const MetaFontAction*) pMA;
2056 : 0 : aSrcFont=pA->GetFont();
2057 : : }
2058 : 0 : break;
2059 : :
2060 : : case META_PUSH_ACTION:
2061 : : {
2062 : 0 : PictWriterAttrStackMember * pAt = new PictWriterAttrStackMember;
2063 : 0 : pAt->aLineColor=aLineColor;
2064 : 0 : pAt->aFillColor=aFillColor;
2065 : 0 : pAt->eRasterOp=eSrcRasterOp;
2066 : 0 : pAt->aFont=aSrcFont;
2067 : 0 : pAt->aMapMode=aSrcMapMode;
2068 : 0 : pAt->aClipRect=aClipRect;
2069 : 0 : pAt->pSucc=pAttrStack;
2070 : 0 : pAttrStack=pAt;
2071 : : }
2072 : 0 : break;
2073 : :
2074 : : case META_POP_ACTION:
2075 : : {
2076 : 0 : PictWriterAttrStackMember* pAt=pAttrStack;
2077 : :
2078 : 0 : if( pAt )
2079 : : {
2080 : 0 : aLineColor=pAt->aLineColor;
2081 : 0 : aFillColor=pAt->aFillColor;
2082 : 0 : eSrcRasterOp=pAt->eRasterOp;
2083 : 0 : aSrcFont=pAt->aFont;
2084 : 0 : aSrcMapMode=pAt->aMapMode;
2085 : 0 : if ( pAt->aClipRect != aClipRect )
2086 : : {
2087 : 0 : Rectangle aRect( pAt->aClipRect );
2088 : 0 : *pPict << (sal_uInt16)1 // opcode 1
2089 : 0 : << (sal_uInt16)10 // data size
2090 : 0 : << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left()
2091 : 0 : << (sal_Int16)aRect.Bottom() << (sal_Int16)aRect.Right();
2092 : : }
2093 : 0 : aClipRect=pAt->aClipRect;
2094 : 0 : pAttrStack=pAt->pSucc;
2095 : 0 : delete pAt;
2096 : : }
2097 : : }
2098 : 0 : break;
2099 : :
2100 : : case META_RASTEROP_ACTION:
2101 : : {
2102 : 0 : const MetaRasterOpAction* pA = (const MetaRasterOpAction*) pMA;
2103 : 0 : eSrcRasterOp=pA->GetRasterOp();
2104 : : }
2105 : 0 : break;
2106 : :
2107 : : case META_TRANSPARENT_ACTION:
2108 : : {
2109 : 0 : const PolyPolygon& rPolyPoly = ( (const MetaTransparentAction*) pMA )->GetPolyPolygon();
2110 : :
2111 : 0 : if (aFillColor!=Color( COL_TRANSPARENT ))
2112 : : {
2113 : 0 : SetAttrForPaint();
2114 : 0 : WriteOpcode_Poly( PDM_PAINT, PolyPolygonToPolygon( rPolyPoly ) );
2115 : : }
2116 : :
2117 : 0 : if (aLineColor!=Color( COL_TRANSPARENT ))
2118 : : {
2119 : 0 : SetAttrForFrame();
2120 : 0 : for( sal_uInt16 i = 0, nCount = rPolyPoly.Count(); i < nCount; i++ )
2121 : 0 : WriteOpcode_Poly( PDM_FRAME, rPolyPoly.GetObject( i ) );
2122 : : }
2123 : : }
2124 : 0 : break;
2125 : :
2126 : : case META_FLOATTRANSPARENT_ACTION:
2127 : : {
2128 : 0 : const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
2129 : :
2130 : 0 : GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
2131 : 0 : Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
2132 : 0 : const Size aSrcSize( aTmpMtf.GetPrefSize() );
2133 : 0 : const Point aDestPt( pA->GetPoint() );
2134 : 0 : const Size aDestSize( pA->GetSize() );
2135 : 0 : const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
2136 : 0 : const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
2137 : : long nMoveX, nMoveY;
2138 : :
2139 : 0 : if( fScaleX != 1.0 || fScaleY != 1.0 )
2140 : : {
2141 : 0 : aTmpMtf.Scale( fScaleX, fScaleY );
2142 : 0 : aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
2143 : : }
2144 : :
2145 : 0 : nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
2146 : :
2147 : 0 : if( nMoveX || nMoveY )
2148 : 0 : aTmpMtf.Move( nMoveX, nMoveY );
2149 : :
2150 : 0 : WriteOpcodes( aTmpMtf );
2151 : : }
2152 : 0 : break;
2153 : :
2154 : : case( META_RENDERGRAPHIC_ACTION ):
2155 : : {
2156 : 0 : const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA;
2157 : 0 : const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() );
2158 : 0 : VirtualDevice aVirDev;
2159 : : const Bitmap aBmp( Graphic( aRasterizer.Rasterize(
2160 : 0 : aVirDev.LogicToPixel( pA->GetSize() ) ) ).GetBitmap() );
2161 : :
2162 : 0 : WriteOpcode_BitsRect( pA->GetPoint(), pA->GetSize(), aBmp );
2163 : : }
2164 : 0 : break;
2165 : : }
2166 : :
2167 : 0 : nWrittenActions++;
2168 : 0 : MayCallback();
2169 : :
2170 : 0 : if (pPict->GetError())
2171 : 0 : bStatus=sal_False;
2172 : :
2173 : 0 : if (bStatus==sal_False)
2174 : 0 : break;
2175 : : }
2176 : : }
2177 : :
2178 : :
2179 : 0 : void PictWriter::WriteHeader(const GDIMetaFile & rMTF)
2180 : : {
2181 : : sal_uInt16 i;
2182 : 0 : Size aSize( rMTF.GetPrefSize() );
2183 : 0 : Point aPoint;
2184 : 0 : Rectangle aRect( aPoint, aSize );
2185 : :
2186 : : // 512 Bytes "trash" at the beginning:
2187 : 0 : for (i=0;i<128;i++) *pPict << (sal_uInt32)0;
2188 : :
2189 : : // Lo-16-Bits of the file size without the 512 bytes trash:
2190 : 0 : *pPict << (sal_uInt16)0; // gets corrected later on by UpdateHeader()
2191 : :
2192 : : // The Bounding-Rectangle (y1,x1,y2,x2 !):
2193 : 0 : WriteRectangle( aRect );
2194 : :
2195 : : // Version 2:
2196 : 0 : *pPict << (sal_uInt32)0x001102ff;
2197 : :
2198 : : // Extended-Version-2-Header:
2199 : 0 : *pPict << (sal_uInt16)0x0c00 // Opcode
2200 : 0 : << (sal_uInt16)0xfffe // Version (?)
2201 : 0 : << (sal_uInt16)0x0000 // Reserved
2202 : 0 : << (sal_uInt32) 0x00480000 // hRes
2203 : 0 : << (sal_uInt32) 0x00480000;
2204 : 0 : WriteRectangle( aRect );
2205 : 0 : *pPict << (sal_uInt32)0x00000000; // Reserved
2206 : :
2207 : : // many import filters demand the declaration
2208 : : // of a clipping area at the beginning
2209 : :
2210 : 0 : WriteOpcode_ClipRect( aRect );
2211 : 0 : }
2212 : :
2213 : :
2214 : 0 : void PictWriter::UpdateHeader()
2215 : : {
2216 : : sal_uLong nPos;
2217 : :
2218 : : // correct the Lo-16-Bits of the file size without the 512 bytes trash:
2219 : 0 : nPos=pPict->Tell();
2220 : 0 : pPict->Seek(512);
2221 : 0 : *pPict << (sal_uInt16)((nPos-512)&0x0000ffff);
2222 : 0 : pPict->Seek(nPos);
2223 : 0 : }
2224 : :
2225 : :
2226 : 0 : sal_Bool PictWriter::WritePict(const GDIMetaFile & rMTF, SvStream & rTargetStream, FilterConfigItem* pFilterConfigItem )
2227 : : {
2228 : : PictWriterAttrStackMember* pAt;
2229 : 0 : MapMode aMap72( MAP_INCH );
2230 : 0 : Fraction aDPIFrac( 1, 72 );
2231 : :
2232 : 0 : bStatus=sal_True;
2233 : 0 : nLastPercent=0;
2234 : :
2235 : 0 : if ( pFilterConfigItem )
2236 : : {
2237 : 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
2238 : 0 : if ( xStatusIndicator.is() )
2239 : : {
2240 : 0 : rtl::OUString aMsg;
2241 : 0 : xStatusIndicator->start( aMsg, 100 );
2242 : : }
2243 : : }
2244 : :
2245 : 0 : pPict=&rTargetStream;
2246 : 0 : pPict->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
2247 : :
2248 : 0 : aLineColor=Color( COL_BLACK );
2249 : 0 : aFillColor=Color( COL_WHITE );
2250 : 0 : eSrcRasterOp=ROP_OVERPAINT;
2251 : 0 : aSrcFont=Font();
2252 : 0 : aSrcMapMode = rMTF.GetPrefMapMode();
2253 : :
2254 : 0 : aMap72.SetScaleX( aDPIFrac );
2255 : 0 : aMap72.SetScaleY( aDPIFrac );
2256 : 0 : aTargetMapMode = aMap72;
2257 : :
2258 : 0 : pAttrStack=NULL;
2259 : :
2260 : 0 : bDstBkPatValid=sal_False;
2261 : 0 : bDstTxFaceValid=sal_False;
2262 : 0 : bDstTxModeValid=sal_False;
2263 : 0 : bDstPnSizeValid=sal_False;
2264 : 0 : bDstPnModeValid=sal_False;
2265 : 0 : bDstPnPatValid=sal_False;
2266 : 0 : bDstFillPatValid=sal_False;
2267 : 0 : bDstTxSizeValid=sal_False;
2268 : 0 : bDstFgColValid=sal_False;
2269 : 0 : bDstBkColValid=sal_False;
2270 : 0 : bDstPenPositionValid=sal_False;
2271 : 0 : bDstTextPositionValid=sal_False;
2272 : 0 : bDstFontNameValid=sal_False;
2273 : :
2274 : 0 : nNumberOfActions=0;
2275 : 0 : nNumberOfBitmaps=0;
2276 : 0 : nWrittenActions=0;
2277 : 0 : nWrittenBitmaps=0;
2278 : 0 : nActBitmapPercent=0;
2279 : :
2280 : 0 : CountActionsAndBitmaps(rMTF);
2281 : :
2282 : 0 : WriteHeader(rMTF);
2283 : 0 : WriteOpcodes(rMTF);
2284 : 0 : WriteOpcode_EndOfFile();
2285 : 0 : UpdateHeader();
2286 : :
2287 : 0 : while (pAttrStack!=NULL) {
2288 : 0 : pAt=pAttrStack;
2289 : 0 : pAttrStack=pAt->pSucc;
2290 : 0 : delete pAt;
2291 : : }
2292 : :
2293 : 0 : if ( xStatusIndicator.is() )
2294 : 0 : xStatusIndicator->end();
2295 : :
2296 : 0 : return bStatus;
2297 : : }
2298 : :
2299 : : //================== GraphicExport - the exported Function ================
2300 : :
2301 : : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
2302 : 0 : GraphicExport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool)
2303 : : {
2304 : 0 : PictWriter aPictWriter;
2305 : :
2306 : 0 : if (rGraphic.GetType()==GRAPHIC_GDIMETAFILE)
2307 : : {
2308 : 0 : GDIMetaFile aScaledMtf( rGraphic.GetGDIMetaFile() );
2309 : 0 : return aPictWriter.WritePict( aScaledMtf, rStream, pFilterConfigItem );
2310 : : }
2311 : : else
2312 : : {
2313 : 0 : Bitmap aBmp=rGraphic.GetBitmap();
2314 : 0 : GDIMetaFile aMTF;
2315 : 0 : VirtualDevice aVirDev;
2316 : :
2317 : 0 : aMTF.Record(&aVirDev);
2318 : 0 : aVirDev.DrawBitmap(Point(),aBmp);
2319 : 0 : aMTF.Stop();
2320 : 0 : aMTF.SetPrefSize(aBmp.GetSizePixel());
2321 : 0 : return aPictWriter.WritePict( aMTF, rStream, pFilterConfigItem );
2322 : 0 : }
2323 : : }
2324 : :
2325 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|