bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdfmtf.cxx
blob0789a39f3af5293ccfbb9daba1a275fb2cadcf6d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "svdfmtf.hxx"
21 #include <editeng/editdata.hxx>
22 #include <math.h>
23 #include <svx/xpoly.hxx>
24 #include <vcl/svapp.hxx>
25 #include <editeng/editdata.hxx>
26 #include <editeng/eeitem.hxx>
27 #include <editeng/fhgtitem.hxx>
28 #include <editeng/wghtitem.hxx>
29 #include <editeng/postitem.hxx>
30 #include <editeng/udlnitem.hxx>
31 #include <editeng/crossedoutitem.hxx>
32 #include <editeng/shdditem.hxx>
33 #include <svx/xlnclit.hxx>
34 #include <svx/xlncapit.hxx>
35 #include <svx/xlnwtit.hxx>
36 #include <svx/xflclit.hxx>
37 #include <svx/xgrad.hxx>
38 #include <svx/xflgrit.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/autokernitem.hxx>
41 #include <editeng/wrlmitem.hxx>
42 #include <editeng/contouritem.hxx>
43 #include <editeng/colritem.hxx>
44 #include <vcl/metric.hxx>
45 #include <editeng/charscaleitem.hxx>
46 #include <svx/xflhtit.hxx>
47 #include <svx/svdattr.hxx>
48 #include <svx/svdmodel.hxx>
49 #include <svx/svdpage.hxx>
50 #include <svx/svdobj.hxx>
51 #include <svx/svdotext.hxx>
52 #include <svx/svdorect.hxx>
53 #include <svx/svdocirc.hxx>
54 #include <svx/svdograf.hxx>
55 #include <svx/svdopath.hxx>
56 #include <svx/svdetc.hxx>
57 #include <svl/itemset.hxx>
58 #include <basegfx/polygon/b2dpolygon.hxx>
59 #include <tools/helpers.hxx>
60 #include <basegfx/matrix/b2dhommatrix.hxx>
61 #include <basegfx/matrix/b2dhommatrixtools.hxx>
62 #include <svx/xlinjoit.hxx>
63 #include <svx/xlndsit.hxx>
64 #include <basegfx/polygon/b2dpolygonclipper.hxx>
65 #include <svx/xbtmpit.hxx>
66 #include <svx/xfltrit.hxx>
67 #include <vcl/bmpacc.hxx>
68 #include <svx/xflbmtit.hxx>
69 #include <svx/xflbstit.hxx>
70 #include <svx/svdpntv.hxx>
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
74 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(
75 SdrModel& rModel,
76 SdrLayerID nLay,
77 const Rectangle& rRect)
78 : maTmpList(),
79 maVD(),
80 maScaleRect(rRect),
81 mnMapScalingOfs(0),
82 mpLineAttr(0),
83 mpFillAttr(0),
84 mpTextAttr(0),
85 mpModel(&rModel),
86 mnLayer(nLay),
87 maOldLineColor(),
88 mnLineWidth(0),
89 maLineJoin(basegfx::B2DLINEJOIN_NONE),
90 maLineCap(com::sun::star::drawing::LineCap_BUTT),
91 maDash(XDASH_RECT, 0, 0, 0, 0, 0),
92 mbMov(false),
93 mbSize(false),
94 maOfs(0, 0),
95 mfScaleX(1.0),
96 mfScaleY(1.0),
97 maScaleX(1.0),
98 maScaleY(1.0),
99 mbFntDirty(true),
100 mbLastObjWasPolyWithoutLine(false),
101 mbNoLine(false),
102 mbNoFill(false),
103 mbLastObjWasLine(false),
104 maClip()
106 maVD.EnableOutput(false);
107 maVD.SetLineColor();
108 maVD.SetFillColor();
109 maOldLineColor.SetRed( maVD.GetLineColor().GetRed() + 1 );
110 mpLineAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_LINE_FIRST, XATTR_LINE_LAST, 0, 0);
111 mpFillAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
112 mpTextAttr = new SfxItemSet(rModel.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END, 0, 0);
113 checkClip();
116 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
118 delete mpLineAttr;
119 delete mpFillAttr;
120 delete mpTextAttr;
123 void ImpSdrGDIMetaFileImport::DoLoopActions(GDIMetaFile& rMtf, SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport)
125 for( MetaAction* pAct = rMtf.FirstAction(); pAct; pAct = rMtf.NextAction() )
127 switch (pAct->GetType())
129 case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
130 case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
131 case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
132 case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
133 case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
134 case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
135 case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
136 case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
137 case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
138 case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
139 case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
140 case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
141 case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
142 case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
143 case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
144 case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
145 case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
146 case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
147 case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
148 case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
149 case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
150 case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
151 case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
152 case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
153 case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
154 case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
155 case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
156 case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
157 case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
158 case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
159 case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
160 case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
161 case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
162 case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
163 case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, &rMtf); break;
165 // missing actions added
166 case META_TEXTRECT_ACTION : DoAction((MetaTextRectAction&)*pAct); break;
167 case META_BMPSCALEPART_ACTION : DoAction((MetaBmpScalePartAction&)*pAct); break;
168 case META_BMPEXSCALEPART_ACTION : DoAction((MetaBmpExScalePartAction&)*pAct); break;
169 case META_MASK_ACTION : DoAction((MetaMaskAction&)*pAct); break;
170 case META_MASKSCALE_ACTION : DoAction((MetaMaskScaleAction&)*pAct); break;
171 case META_MASKSCALEPART_ACTION : DoAction((MetaMaskScalePartAction&)*pAct); break;
172 case META_GRADIENT_ACTION : DoAction((MetaGradientAction&)*pAct); break;
173 case META_WALLPAPER_ACTION : DoAction((MetaWallpaperAction&)*pAct); break;
174 case META_TRANSPARENT_ACTION : DoAction((MetaTransparentAction&)*pAct); break;
175 case META_EPS_ACTION : DoAction((MetaEPSAction&)*pAct); break;
176 case META_REFPOINT_ACTION : DoAction((MetaRefPointAction&)*pAct); break;
177 case META_TEXTLINECOLOR_ACTION : DoAction((MetaTextLineColorAction&)*pAct); break;
178 case META_TEXTLINE_ACTION : DoAction((MetaTextLineAction&)*pAct); break;
179 case META_FLOATTRANSPARENT_ACTION : DoAction((MetaFloatTransparentAction&)*pAct); break;
180 case META_GRADIENTEX_ACTION : DoAction((MetaGradientExAction&)*pAct); break;
181 case META_LAYOUTMODE_ACTION : DoAction((MetaLayoutModeAction&)*pAct); break;
182 case META_TEXTLANGUAGE_ACTION : DoAction((MetaTextLanguageAction&)*pAct); break;
183 case META_OVERLINECOLOR_ACTION : DoAction((MetaOverlineColorAction&)*pAct); break;
186 if(pProgrInfo && pActionsToReport)
188 (*pActionsToReport)++;
190 if(*pActionsToReport >= 16) // update all 16 actions
192 if(!pProgrInfo->ReportActions(*pActionsToReport))
193 break;
195 *pActionsToReport = 0;
201 sal_uInt32 ImpSdrGDIMetaFileImport::DoImport(
202 const GDIMetaFile& rMtf,
203 SdrObjList& rOL,
204 sal_uLong nInsPos,
205 SvdProgressInfo* pProgrInfo)
207 // setup some global scale parameter
208 // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
209 mfScaleX = mfScaleY = 1.0;
210 const Size aMtfSize(rMtf.GetPrefSize());
212 if(aMtfSize.Width() & aMtfSize.Height() && (!maScaleRect.IsEmpty()))
214 maOfs = maScaleRect.TopLeft();
216 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
218 mfScaleX = (double)( maScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
221 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
223 mfScaleY = (double)( maScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
227 mbMov = maOfs.X()!=0 || maOfs.Y()!=0;
228 mbSize = false;
229 maScaleX = Fraction( 1, 1 );
230 maScaleY = Fraction( 1, 1 );
232 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
234 maScaleX = Fraction(maScaleRect.GetWidth() - 1, aMtfSize.Width());
235 mbSize = true;
238 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
240 maScaleY = Fraction(maScaleRect.GetHeight() - 1, aMtfSize.Height());
241 mbSize = true;
244 if(pProgrInfo)
246 pProgrInfo->SetActionCount(rMtf.GetActionSize());
249 sal_uInt32 nActionsToReport(0);
251 // execute
252 DoLoopActions(const_cast< GDIMetaFile& >(rMtf), pProgrInfo, &nActionsToReport);
254 if(pProgrInfo)
256 pProgrInfo->ReportActions(nActionsToReport);
257 nActionsToReport = 0;
260 // MapMode scaling
261 MapScaling();
263 // To calculate the progress meter, we use GetActionSize()*3.
264 // However, maTmpList has a lower entry count limit than GetActionSize(),
265 // so the actions that were assumed were too much have to be re-added.
266 nActionsToReport = (rMtf.GetActionSize() - maTmpList.size()) * 2;
268 // announce all currently unannounced rescales
269 if(pProgrInfo)
271 pProgrInfo->ReportRescales(nActionsToReport);
272 pProgrInfo->SetInsertCount(maTmpList.size());
275 nActionsToReport = 0;
277 // insert all objects cached in aTmpList now into rOL from nInsPos
278 if(nInsPos > rOL.GetObjCount())
280 nInsPos = rOL.GetObjCount();
283 SdrInsertReason aReason(SDRREASON_VIEWCALL);
285 for(sal_uInt32 i(0); i < maTmpList.size(); i++)
287 SdrObject* pObj = maTmpList[i];
288 rOL.NbcInsertObject(pObj, nInsPos, &aReason);
289 nInsPos++;
291 if(pProgrInfo)
293 nActionsToReport++;
295 if(nActionsToReport >= 32) // update all 32 actions
297 pProgrInfo->ReportInserts(nActionsToReport);
298 nActionsToReport = 0;
303 // report all remaining inserts for the last time
304 if(pProgrInfo)
306 pProgrInfo->ReportInserts(nActionsToReport);
309 return maTmpList.size();
312 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
314 mbNoLine = false;
315 mbNoFill = false;
316 bool bLine(!bForceTextAttr);
317 bool bFill(!pObj || (pObj->IsClosedObj() && !bForceTextAttr));
318 bool bText(bForceTextAttr || (pObj && pObj->GetOutlinerParaObject()));
320 if(bLine)
322 if(mnLineWidth)
324 mpLineAttr->Put(XLineWidthItem(mnLineWidth));
326 else
328 mpLineAttr->Put(XLineWidthItem(0));
331 maOldLineColor = maVD.GetLineColor();
333 if(maVD.IsLineColor())
335 mpLineAttr->Put(XLineStyleItem(XLINE_SOLID));
336 mpLineAttr->Put(XLineColorItem(String(), maVD.GetLineColor()));
338 else
340 mpLineAttr->Put(XLineStyleItem(XLINE_NONE));
343 switch(maLineJoin)
345 default : // basegfx::B2DLINEJOIN_NONE
346 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_NONE));
347 break;
348 case basegfx::B2DLINEJOIN_MIDDLE:
349 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MIDDLE));
350 break;
351 case basegfx::B2DLINEJOIN_BEVEL:
352 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL));
353 break;
354 case basegfx::B2DLINEJOIN_MITER:
355 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MITER));
356 break;
357 case basegfx::B2DLINEJOIN_ROUND:
358 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_ROUND));
359 break;
362 // Add LineCap support
363 mpLineAttr->Put(XLineCapItem(maLineCap));
365 if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
367 mpLineAttr->Put(XLineDashItem(String(), maDash));
369 else
371 mpLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
374 else
376 mbNoLine = true;
379 if(bFill)
381 if(maVD.IsFillColor())
383 mpFillAttr->Put(XFillStyleItem(XFILL_SOLID));
384 mpFillAttr->Put(XFillColorItem(String(), maVD.GetFillColor()));
386 else
388 mpFillAttr->Put(XFillStyleItem(XFILL_NONE));
391 else
393 mbNoFill = true;
396 if(bText && mbFntDirty)
398 Font aFnt(maVD.GetFont());
399 const sal_uInt32 nHeight(FRound(aFnt.GetSize().Height() * mfScaleY));
401 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
402 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
403 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
404 mpTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
405 mpTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
406 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
407 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
408 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
409 mpTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
410 mpTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
411 mpTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
412 mpTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
413 mpTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
415 // #i118485# Setting this item leads to problems (written #i118498# for this)
416 // mpTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
418 mpTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
419 mpTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
420 mpTextAttr->Put(SvxColorItem(maVD.GetTextColor(), EE_CHAR_COLOR));
421 //... svxfont textitem svditext
422 mbFntDirty = false;
425 if(pObj)
427 pObj->SetLayer(mnLayer);
429 if(bLine)
431 pObj->SetMergedItemSet(*mpLineAttr);
434 if(bFill)
436 pObj->SetMergedItemSet(*mpFillAttr);
439 if(bText)
441 pObj->SetMergedItemSet(*mpTextAttr);
442 pObj->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
447 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
449 if(bScale && !maScaleRect.IsEmpty())
451 if(mbSize)
453 pObj->NbcResize(Point(), maScaleX, maScaleY);
456 if(mbMov)
458 pObj->NbcMove(Size(maOfs.X(), maOfs.Y()));
462 if(isClip())
464 const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
465 const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
466 const SdrLayerID aOldLayer(pObj->GetLayer());
467 const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
468 const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
469 BitmapEx aBitmapEx;
471 if(pSdrGrafObj)
473 aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
476 SdrObject::Free(pObj);
478 if(!aOldRange.isEmpty())
480 // clip against ClipRegion
481 const basegfx::B2DPolyPolygon aNewPoly(
482 basegfx::tools::clipPolyPolygonOnPolyPolygon(
483 aPoly,
484 maClip,
485 true,
486 aPoly.isClosed() ? false : true));
487 const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
489 if(!aNewRange.isEmpty())
491 pObj = new SdrPathObj(
492 aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
493 aNewPoly);
495 pObj->SetLayer(aOldLayer);
496 pObj->SetMergedItemSet(aOldItemSet);
498 if(!!aBitmapEx)
500 // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
501 const double fLclScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
502 const double fLclScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
503 basegfx::B2DRange aPixel(aNewRange);
504 basegfx::B2DHomMatrix aTrans;
506 aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
507 aTrans.scale(fLclScaleX, fLclScaleY);
508 aPixel.transform(aTrans);
510 const BitmapEx aClippedBitmap(
511 aBitmapEx,
512 Point(floor(std::max(0.0, aPixel.getMinX())), floor(std::max(0.0, aPixel.getMinY()))),
513 Size(ceil(aPixel.getWidth()), ceil(aPixel.getHeight())));
515 pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
516 pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
517 pObj->SetMergedItem(XFillBmpTileItem(false));
518 pObj->SetMergedItem(XFillBmpStretchItem(true));
524 if(pObj)
526 // #i111954# check object for visibility
527 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
528 bool bVisible(false);
530 if(pObj->HasLineStyle())
532 bVisible = true;
535 if(!bVisible && pObj->HasFillStyle())
537 bVisible = true;
540 if(!bVisible)
542 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
544 if(pTextObj && pTextObj->HasText())
546 bVisible = true;
550 if(!bVisible)
552 SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
554 if(pGrafObj)
556 // this may be refined to check if the graphic really is visible. It
557 // is here to ensure that graphic objects without fill, line and text
558 // get created
559 bVisible = true;
563 if(!bVisible)
565 SdrObject::Free(pObj);
567 else
569 maTmpList.push_back(pObj);
571 if(dynamic_cast< SdrPathObj* >(pObj))
573 const bool bClosed(pObj->IsClosedObj());
575 mbLastObjWasPolyWithoutLine = mbNoLine && bClosed;
576 mbLastObjWasLine = !bClosed;
578 else
580 mbLastObjWasPolyWithoutLine = false;
581 mbLastObjWasLine = false;
587 /**************************************************************************************************/
588 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/) const
592 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/) const
596 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
598 // #i73407# reformulation to use new B2DPolygon classes
599 const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
600 const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
602 if(!aStart.equal(aEnd))
604 basegfx::B2DPolygon aLine;
605 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
607 aLine.append(aStart);
608 aLine.append(aEnd);
609 aLine.transform(aTransform);
611 const LineInfo& rLineInfo = rAct.GetLineInfo();
612 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
613 bool bCreateLineObject(true);
615 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aLine))
617 bCreateLineObject = false;
620 if(bCreateLineObject)
622 SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
623 mnLineWidth = nNewLineWidth;
624 maLineJoin = rLineInfo.GetLineJoin();
625 maLineCap = rLineInfo.GetLineCap();
626 maDash = XDash(XDASH_RECT,
627 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
628 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
629 rLineInfo.GetDistance());
630 SetAttributes(pPath);
631 mnLineWidth = 0;
632 maLineJoin = basegfx::B2DLINEJOIN_NONE;
633 maDash = XDash();
634 InsertObj(pPath, false);
639 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
641 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
642 SetAttributes(pRect);
643 InsertObj(pRect);
646 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
648 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
649 SetAttributes(pRect);
650 long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
651 if (nRad!=0) {
652 SfxItemSet aSet(*mpLineAttr->GetPool(), SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 0, 0);
653 aSet.Put(SdrEckenradiusItem(nRad));
654 pRect->SetMergedItemSet(aSet);
656 InsertObj(pRect);
659 /**************************************************************************************************/
661 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
663 SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
664 SetAttributes(pCirc);
665 InsertObj(pCirc);
668 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
670 Point aCenter(rAct.GetRect().Center());
671 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
672 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
673 SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
674 SetAttributes(pCirc);
675 InsertObj(pCirc);
678 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
680 Point aCenter(rAct.GetRect().Center());
681 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
682 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
683 SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
684 SetAttributes(pCirc);
685 InsertObj(pCirc);
688 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
690 Point aCenter(rAct.GetRect().Center());
691 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
692 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
693 SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
694 SetAttributes(pCirc);
695 InsertObj(pCirc);
698 /**************************************************************************************************/
700 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
702 // #i102706# Do not merge closed polygons
703 if(rSrcPoly.isClosed())
705 return false;
708 // #i73407# reformulation to use new B2DPolygon classes
709 if(mbLastObjWasLine && (maOldLineColor == maVD.GetLineColor()) && rSrcPoly.count())
711 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
712 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
714 if(pLastPoly)
716 if(1L == pLastPoly->GetPathPoly().count())
718 bool bOk(false);
719 basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
721 // #i102706# Do not merge closed polygons
722 if(aDstPoly.isClosed())
724 return false;
727 if(aDstPoly.count())
729 const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
730 const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
732 if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
734 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
735 bOk = true;
737 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
739 basegfx::B2DPolygon aNew(rSrcPoly);
740 aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
741 aDstPoly = aNew;
742 bOk = true;
744 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
746 aDstPoly.flip();
747 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
748 bOk = true;
750 else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
752 basegfx::B2DPolygon aNew(rSrcPoly);
753 aNew.flip();
754 aDstPoly.append(aNew, 1L, aNew.count() - 1L);
755 bOk = true;
759 if(bOk)
761 pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
764 return bOk;
769 return false;
772 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
774 // #i73407# reformulation to use new B2DPolygon classes
775 if(mbLastObjWasPolyWithoutLine)
777 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
778 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
780 if(pLastPoly)
782 if(pLastPoly->GetPathPoly() == rPolyPolygon)
784 SetAttributes(NULL);
786 if(!mbNoLine && mbNoFill)
788 pLastPoly->SetMergedItemSet(*mpLineAttr);
790 return true;
796 return false;
799 void ImpSdrGDIMetaFileImport::checkClip()
801 if(maVD.IsClipRegion())
803 Region aRegion(maVD.GetClipRegion());
805 maClip = aRegion.ConvertToB2DPolyPolygon();
807 if(isClip())
809 const basegfx::B2DHomMatrix aTransform(
810 basegfx::tools::createScaleTranslateB2DHomMatrix(
811 mfScaleX,
812 mfScaleY,
813 maOfs.X(),
814 maOfs.Y()));
816 maClip.transform(aTransform);
821 bool ImpSdrGDIMetaFileImport::isClip() const
823 return !maClip.getB2DRange().isEmpty();
826 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
828 // #i73407# reformulation to use new B2DPolygon classes
829 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
831 if(aSource.count())
833 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
834 aSource.transform(aTransform);
837 const LineInfo& rLineInfo = rAct.GetLineInfo();
838 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
839 bool bCreateLineObject(true);
841 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aSource))
843 bCreateLineObject = false;
845 else if(mbLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
847 bCreateLineObject = false;
850 if(bCreateLineObject)
852 SdrPathObj* pPath = new SdrPathObj(
853 aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
854 basegfx::B2DPolyPolygon(aSource));
855 mnLineWidth = nNewLineWidth;
856 maLineJoin = rLineInfo.GetLineJoin();
857 maLineCap = rLineInfo.GetLineCap();
858 maDash = XDash(XDASH_RECT,
859 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
860 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
861 rLineInfo.GetDistance());
862 SetAttributes(pPath);
863 mnLineWidth = 0;
864 maLineJoin = basegfx::B2DLINEJOIN_NONE;
865 maDash = XDash();
866 InsertObj(pPath, false);
870 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
872 // #i73407# reformulation to use new B2DPolygon classes
873 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
875 if(aSource.count())
877 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
878 aSource.transform(aTransform);
880 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
882 // #i73407# make sure polygon is closed, it's a filled primitive
883 aSource.setClosed(true);
884 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
885 SetAttributes(pPath);
886 InsertObj(pPath, false);
891 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
893 // #i73407# reformulation to use new B2DPolygon classes
894 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
896 if(aSource.count())
898 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
899 aSource.transform(aTransform);
901 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
903 // #i73407# make sure polygon is closed, it's a filled primitive
904 aSource.setClosed(true);
905 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
906 SetAttributes(pPath);
907 InsertObj(pPath, false);
912 /**************************************************************************************************/
914 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
916 // calc text box size, add 5% to make it fit safely
918 FontMetric aFontMetric( maVD.GetFontMetric() );
919 Font aFnt( maVD.GetFont() );
920 FontAlign eAlg( aFnt.GetAlign() );
922 sal_Int32 nTextWidth = (sal_Int32)( maVD.GetTextWidth( rStr ) * mfScaleX );
923 sal_Int32 nTextHeight = (sal_Int32)( maVD.GetTextHeight() * mfScaleY );
925 Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) );
926 Size aSize( nTextWidth, nTextHeight );
928 if ( eAlg == ALIGN_BASELINE )
929 aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
930 else if ( eAlg == ALIGN_BOTTOM )
931 aPos.Y() -= nTextHeight;
933 Rectangle aTextRect( aPos, aSize );
934 SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
936 if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
938 pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
939 pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
940 // don't let the margins eat the space needed for the text
941 pText->SetMergedItem ( SdrTextUpperDistItem (0));
942 pText->SetMergedItem ( SdrTextLowerDistItem (0));
943 pText->SetMergedItem ( SdrTextRightDistItem (0));
944 pText->SetMergedItem ( SdrTextLeftDistItem (0));
945 pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
947 else
948 pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
950 pText->SetModel(mpModel);
951 pText->SetLayer(mnLayer);
952 pText->NbcSetText( rStr );
953 SetAttributes( pText, true );
954 pText->SetSnapRect( aTextRect );
956 if (!aFnt.IsTransparent())
958 SfxItemSet aAttr(*mpFillAttr->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
959 aAttr.Put(XFillStyleItem(XFILL_SOLID));
960 aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
961 pText->SetMergedItemSet(aAttr);
963 sal_uInt32 nWink = aFnt.GetOrientation();
964 if ( nWink )
966 nWink*=10;
967 double a=nWink*nPi180;
968 double nSin=sin(a);
969 double nCos=cos(a);
970 pText->NbcRotate(aPos,nWink,nSin,nCos);
972 InsertObj( pText, false );
975 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
977 XubString aStr(rAct.GetText());
978 aStr.Erase(0,rAct.GetIndex());
979 aStr.Erase(rAct.GetLen());
980 ImportText( rAct.GetPoint(), aStr, rAct );
983 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
985 XubString aStr(rAct.GetText());
986 aStr.Erase(0,rAct.GetIndex());
987 aStr.Erase(rAct.GetLen());
988 ImportText( rAct.GetPoint(), aStr, rAct );
991 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
993 XubString aStr(rAct.GetText());
994 aStr.Erase(0,rAct.GetIndex());
995 aStr.Erase(rAct.GetLen());
996 ImportText( rAct.GetPoint(), aStr, rAct );
999 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
1001 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
1002 aRect.Right()++; aRect.Bottom()++;
1003 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1004 InsertObj(pGraf);
1007 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
1009 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1010 aRect.Right()++; aRect.Bottom()++;
1011 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1012 InsertObj(pGraf);
1015 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
1017 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
1018 aRect.Right()++; aRect.Bottom()++;
1019 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1020 InsertObj(pGraf);
1023 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
1025 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1026 aRect.Right()++; aRect.Bottom()++;
1027 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1028 InsertObj(pGraf);
1031 ////////////////////////////////////////////////////////////////////////////////////////////////////
1033 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
1035 // #i73407# reformulation to use new B2DPolygon classes
1036 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1038 if(aSource.count())
1040 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1041 aSource.transform(aTransform);
1043 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1045 const Hatch& rHatch = rAct.GetHatch();
1046 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1047 SfxItemSet aHatchAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0);
1048 XHatchStyle eStyle;
1050 switch(rHatch.GetStyle())
1052 case(HATCH_TRIPLE) :
1054 eStyle = XHATCH_TRIPLE;
1055 break;
1058 case(HATCH_DOUBLE) :
1060 eStyle = XHATCH_DOUBLE;
1061 break;
1064 default:
1066 eStyle = XHATCH_SINGLE;
1067 break;
1071 SetAttributes(pPath);
1072 aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
1073 aHatchAttr.Put(XFillHatchItem(&mpModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1074 pPath->SetMergedItemSet(aHatchAttr);
1076 InsertObj(pPath, false);
1081 ////////////////////////////////////////////////////////////////////////////////////////////////////
1083 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1085 rAct.Execute(&maVD);
1088 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1090 MapScaling();
1091 rAct.Execute(&maVD);
1092 mbLastObjWasPolyWithoutLine = false;
1093 mbLastObjWasLine = false;
1096 void ImpSdrGDIMetaFileImport::MapScaling()
1098 const size_t nAnz(maTmpList.size());
1099 const MapMode& rMap = maVD.GetMapMode();
1100 Point aMapOrg( rMap.GetOrigin() );
1101 bool bMov2(aMapOrg.X() != 0 || aMapOrg.Y() != 0);
1103 if(bMov2)
1105 for(size_t i = mnMapScalingOfs; i < nAnz; i++)
1107 SdrObject* pObj = maTmpList[i];
1109 pObj->NbcMove(Size(aMapOrg.X(), aMapOrg.Y()));
1113 mnMapScalingOfs = nAnz;
1116 ////////////////////////////////////////////////////////////////////////////////////////////////////
1118 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
1120 bool aSkipComment = false;
1122 if (rAct.GetComment().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("XGRAD_SEQ_BEGIN")))
1124 MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
1126 if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
1128 // #i73407# reformulation to use new B2DPolygon classes
1129 basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1131 if(aSource.count())
1133 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1135 const Gradient& rGrad = pAct->GetGradient();
1136 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1137 SfxItemSet aGradAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1138 XGradient aXGradient;
1140 aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
1141 aXGradient.SetStartColor(rGrad.GetStartColor());
1142 aXGradient.SetEndColor(rGrad.GetEndColor());
1143 aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1144 aXGradient.SetBorder(rGrad.GetBorder());
1145 aXGradient.SetXOffset(rGrad.GetOfsX());
1146 aXGradient.SetYOffset(rGrad.GetOfsY());
1147 aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1148 aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1149 aXGradient.SetSteps(rGrad.GetSteps());
1151 if(maVD.IsLineColor())
1153 // switch line off; if there was one, there will be a
1154 // META_POLYLINE_ACTION following creating another object
1155 const Color aLineColor(maVD.GetLineColor());
1156 maVD.SetLineColor();
1157 SetAttributes(pPath);
1158 maVD.SetLineColor(aLineColor);
1160 else
1162 SetAttributes(pPath);
1165 aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1166 aGradAttr.Put(XFillGradientItem(aXGradient));
1167 pPath->SetMergedItemSet(aGradAttr);
1169 InsertObj(pPath);
1173 aSkipComment = true;
1177 if(aSkipComment)
1179 MetaAction* pSkipAct = pMtf->NextAction();
1181 while( pSkipAct
1182 && ((pSkipAct->GetType() != META_COMMENT_ACTION )
1183 || !(((MetaCommentAction*)pSkipAct)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1185 pSkipAct = pMtf->NextAction();
1190 void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction& rAct)
1192 GDIMetaFile aTemp;
1194 maVD.AddTextRectActions(rAct.GetRect(), rAct.GetText(), rAct.GetStyle(), aTemp);
1195 DoLoopActions(aTemp, 0, 0);
1198 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction& rAct)
1200 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1201 Bitmap aBitmap(rAct.GetBitmap());
1203 aRect.Right()++;
1204 aRect.Bottom()++;
1205 aBitmap.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1207 SdrGrafObj* pGraf = new SdrGrafObj(aBitmap, aRect);
1209 InsertObj(pGraf);
1212 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction& rAct)
1214 Rectangle aRect(rAct.GetDestPoint(),rAct.GetDestSize());
1215 BitmapEx aBitmapEx(rAct.GetBitmapEx());
1217 aRect.Right()++;
1218 aRect.Bottom()++;
1219 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1221 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1223 InsertObj(pGraf);
1226 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction& rAct)
1228 Rectangle aRect(rAct.GetPoint(), rAct.GetBitmap().GetSizePixel());
1229 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1231 aRect.Right()++;
1232 aRect.Bottom()++;
1234 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1236 InsertObj(pGraf);
1239 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction& rAct)
1241 Rectangle aRect(rAct.GetPoint(), rAct.GetSize());
1242 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1244 aRect.Right()++;
1245 aRect.Bottom()++;
1247 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1249 InsertObj(pGraf);
1252 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction& rAct)
1254 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1255 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1257 aRect.Right()++;
1258 aRect.Bottom()++;
1259 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1261 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1263 InsertObj(pGraf);
1266 namespace
1268 XGradientStyle getXGradientStyleFromGradientStyle(const GradientStyle& rGradientStyle)
1270 XGradientStyle aXGradientStyle(XGRAD_LINEAR);
1272 switch(rGradientStyle)
1274 case GradientStyle_LINEAR: aXGradientStyle = XGRAD_LINEAR; break;
1275 case GradientStyle_AXIAL: aXGradientStyle = XGRAD_AXIAL; break;
1276 case GradientStyle_RADIAL: aXGradientStyle = XGRAD_RADIAL; break;
1277 case GradientStyle_ELLIPTICAL: aXGradientStyle = XGRAD_ELLIPTICAL; break;
1278 case GradientStyle_SQUARE: aXGradientStyle = XGRAD_SQUARE; break;
1279 case GradientStyle_RECT: aXGradientStyle = XGRAD_RECT; break;
1281 // Needed due to GradientStyle_FORCE_EQUAL_SIZE; this again is needed
1282 // to force the enum defines in VCL to a defined size for the compilers,
1283 // so despite it is never used it cannot be removed (would break the
1284 // API implementation probably).
1285 case GradientStyle_FORCE_EQUAL_SIZE: break;
1288 return aXGradientStyle;
1292 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction& rAct)
1294 basegfx::B2DRange aRange(rAct.GetRect().Left(), rAct.GetRect().Top(), rAct.GetRect().Right(), rAct.GetRect().Bottom());
1296 if(!aRange.isEmpty())
1298 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1299 aRange.transform(aTransform);
1300 const Gradient& rGradient = rAct.GetGradient();
1301 SdrRectObj* pRect = new SdrRectObj(
1302 Rectangle(
1303 floor(aRange.getMinX()),
1304 floor(aRange.getMinY()),
1305 ceil(aRange.getMaxX()),
1306 ceil(aRange.getMaxY())));
1307 SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1308 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1309 const XFillGradientItem aXFillGradientItem(
1310 XGradient(
1311 rGradient.GetStartColor(),
1312 rGradient.GetEndColor(),
1313 aXGradientStyle,
1314 rGradient.GetAngle(),
1315 rGradient.GetOfsX(),
1316 rGradient.GetOfsY(),
1317 rGradient.GetBorder(),
1318 rGradient.GetStartIntensity(),
1319 rGradient.GetEndIntensity(),
1320 rGradient.GetSteps()));
1322 SetAttributes(pRect);
1323 aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1324 aGradientAttr.Put(aXFillGradientItem);
1325 pRect->SetMergedItemSet(aGradientAttr);
1327 InsertObj(pRect, false);
1331 void ImpSdrGDIMetaFileImport::DoAction(MetaWallpaperAction&)
1333 OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)");
1336 void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction& rAct)
1338 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1340 if(aSource.count())
1342 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1343 aSource.transform(aTransform);
1344 aSource.setClosed(true);
1346 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1347 SetAttributes(pPath);
1348 pPath->SetMergedItem(XFillTransparenceItem(rAct.GetTransparence()));
1349 InsertObj(pPath, false);
1353 void ImpSdrGDIMetaFileImport::DoAction(MetaEPSAction&)
1355 OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)");
1358 void ImpSdrGDIMetaFileImport::DoAction(MetaTextLineAction&)
1360 OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)");
1363 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction& rAct)
1365 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1367 if(aSource.count())
1369 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1370 aSource.transform(aTransform);
1372 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1374 const Gradient& rGradient = rAct.GetGradient();
1375 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1376 SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1377 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1378 const XFillGradientItem aXFillGradientItem(
1379 XGradient(
1380 rGradient.GetStartColor(),
1381 rGradient.GetEndColor(),
1382 aXGradientStyle,
1383 rGradient.GetAngle(),
1384 rGradient.GetOfsX(),
1385 rGradient.GetOfsY(),
1386 rGradient.GetBorder(),
1387 rGradient.GetStartIntensity(),
1388 rGradient.GetEndIntensity(),
1389 rGradient.GetSteps()));
1391 SetAttributes(pPath);
1392 aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1393 aGradientAttr.Put(aXFillGradientItem);
1394 pPath->SetMergedItemSet(aGradientAttr);
1396 InsertObj(pPath, false);
1401 void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction& rAct)
1403 const GDIMetaFile& rMtf = rAct.GetGDIMetaFile();
1405 if(rMtf.GetActionSize())
1407 const Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1409 // convert metafile sub-content to BitmapEx
1410 BitmapEx aBitmapEx(
1411 convertMetafileToBitmapEx(
1412 rMtf,
1413 basegfx::B2DRange(
1414 aRect.Left(), aRect.Top(),
1415 aRect.Right(), aRect.Bottom()),
1416 125000));
1418 // handle colors
1419 const Gradient& rGradient = rAct.GetGradient();
1420 basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
1421 basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
1423 if(100 != rGradient.GetStartIntensity())
1425 aStart *= (double)rGradient.GetStartIntensity() / 100.0;
1428 if(100 != rGradient.GetEndIntensity())
1430 aEnd *= (double)rGradient.GetEndIntensity() / 100.0;
1433 const bool bEqualColors(aStart == aEnd);
1434 const bool bNoSteps(1 == rGradient.GetSteps());
1435 bool bCreateObject(true);
1436 bool bHasNewMask(false);
1437 AlphaMask aNewMask;
1438 double fTransparence(0.0);
1439 bool bFixedTransparence(false);
1441 if(bEqualColors || bNoSteps)
1443 // single transparence
1444 const basegfx::BColor aMedium(basegfx::average(aStart, aEnd));
1445 fTransparence = aMedium.luminance();
1447 if(basegfx::fTools::lessOrEqual(fTransparence, 0.0))
1449 // no transparence needed, all done
1451 else if(basegfx::fTools::moreOrEqual(fTransparence, 1.0))
1453 // all transparent, no object
1454 bCreateObject = false;
1456 else
1458 // 0.0 < transparence < 1.0, apply fixed transparence
1459 bFixedTransparence = true;
1462 else
1464 // gradient transparence
1465 VirtualDevice aVDev;
1467 aVDev.SetOutputSizePixel(aBitmapEx.GetBitmap().GetSizePixel());
1468 aVDev.DrawGradient(Rectangle(Point(0, 0), aVDev.GetOutputSizePixel()), rGradient);
1470 aNewMask = AlphaMask(aVDev.GetBitmap(Point(0, 0), aVDev.GetOutputSizePixel()));
1471 bHasNewMask = true;
1474 if(bCreateObject)
1476 if(bHasNewMask || bFixedTransparence)
1478 if(!aBitmapEx.IsAlpha() && !aBitmapEx.IsTransparent())
1480 // no transparence yet, apply new one
1481 if(bFixedTransparence)
1483 sal_uInt8 aAlpha(basegfx::fround(fTransparence * 255.0));
1485 aNewMask = AlphaMask(aBitmapEx.GetBitmap().GetSizePixel(), &aAlpha);
1488 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aNewMask);
1490 else
1492 // mix existing and new alpha mask
1493 AlphaMask aOldMask;
1495 if(aBitmapEx.IsAlpha())
1497 aOldMask = aBitmapEx.GetAlpha();
1499 else if(TRANSPARENT_BITMAP == aBitmapEx.GetTransparentType())
1501 aOldMask = aBitmapEx.GetMask();
1503 else if(TRANSPARENT_COLOR == aBitmapEx.GetTransparentType())
1505 aOldMask = aBitmapEx.GetBitmap().CreateMask(aBitmapEx.GetTransparentColor());
1508 BitmapWriteAccess* pOld = aOldMask.AcquireWriteAccess();
1510 if(pOld)
1512 const double fFactor(1.0 / 255.0);
1514 if(bFixedTransparence)
1516 const double fOpNew(1.0 - fTransparence);
1518 for(int y(0); y < pOld->Height(); y++)
1520 for(int x(0); x < pOld->Width(); x++)
1522 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1523 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1525 pOld->SetPixel(y, x, BitmapColor(aCol));
1529 else
1531 BitmapReadAccess* pNew = aNewMask.AcquireReadAccess();
1533 if(pNew)
1535 if(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height())
1537 for(int y(0); y < pOld->Height(); y++)
1539 for(int x(0); x < pOld->Width(); x++)
1541 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1542 const double fOpNew(1.0 - (pNew->GetPixel(y, x).GetIndex() * fFactor));
1543 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1545 pOld->SetPixel(y, x, BitmapColor(aCol));
1549 else
1551 OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1554 aNewMask.ReleaseAccess(pNew);
1556 else
1558 OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1562 aOldMask.ReleaseAccess(pOld);
1564 else
1566 OSL_ENSURE(false, "Got no access to old alpha mask (!)");
1569 // apply combined bitmap as mask
1570 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aOldMask);
1574 // create and add object
1575 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1577 InsertObj(pGraf);
1582 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */