Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / svdraw / svdfmtf.cxx
blob070acad5f7717bb6988b88b5313be8625d2d9a7f
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/eeitem.hxx>
26 #include <editeng/fhgtitem.hxx>
27 #include <editeng/wghtitem.hxx>
28 #include <editeng/postitem.hxx>
29 #include <editeng/udlnitem.hxx>
30 #include <editeng/crossedoutitem.hxx>
31 #include <editeng/shdditem.hxx>
32 #include <svx/xlnclit.hxx>
33 #include <svx/xlncapit.hxx>
34 #include <svx/xlnwtit.hxx>
35 #include <svx/xflclit.hxx>
36 #include <svx/xgrad.hxx>
37 #include <svx/xflgrit.hxx>
38 #include <editeng/fontitem.hxx>
39 #include <editeng/autokernitem.hxx>
40 #include <editeng/wrlmitem.hxx>
41 #include <editeng/contouritem.hxx>
42 #include <editeng/colritem.hxx>
43 #include <vcl/metric.hxx>
44 #include <editeng/charscaleitem.hxx>
45 #include <svx/xflhtit.hxx>
46 #include <svx/svdattr.hxx>
47 #include <svx/svdmodel.hxx>
48 #include <svx/svdpage.hxx>
49 #include <svx/svdobj.hxx>
50 #include <svx/svdotext.hxx>
51 #include <svx/svdorect.hxx>
52 #include <svx/svdocirc.hxx>
53 #include <svx/svdograf.hxx>
54 #include <svx/svdopath.hxx>
55 #include <svx/svdetc.hxx>
56 #include <svl/itemset.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <tools/helpers.hxx>
59 #include <basegfx/matrix/b2dhommatrix.hxx>
60 #include <basegfx/matrix/b2dhommatrixtools.hxx>
61 #include <svx/xlinjoit.hxx>
62 #include <svx/xlndsit.hxx>
63 #include <basegfx/polygon/b2dpolygonclipper.hxx>
64 #include <svx/xbtmpit.hxx>
65 #include <svx/xfltrit.hxx>
66 #include <vcl/bmpacc.hxx>
67 #include <svx/xflbmtit.hxx>
68 #include <svx/xflbstit.hxx>
69 #include <svx/svdpntv.hxx>
70 #include <basegfx/polygon/b2dpolypolygontools.hxx>
71 #include <svx/svditer.hxx>
72 #include <svx/svdogrp.hxx>
76 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(
77 SdrModel& rModel,
78 SdrLayerID nLay,
79 const Rectangle& rRect)
80 : maTmpList(),
81 maVD(),
82 maScaleRect(rRect),
83 mnMapScalingOfs(0),
84 mpLineAttr(0),
85 mpFillAttr(0),
86 mpTextAttr(0),
87 mpModel(&rModel),
88 mnLayer(nLay),
89 maOldLineColor(),
90 mnLineWidth(0),
91 maLineJoin(basegfx::B2DLINEJOIN_NONE),
92 maLineCap(com::sun::star::drawing::LineCap_BUTT),
93 maDash(XDASH_RECT, 0, 0, 0, 0, 0),
94 mbMov(false),
95 mbSize(false),
96 maOfs(0, 0),
97 mfScaleX(1.0),
98 mfScaleY(1.0),
99 maScaleX(1.0),
100 maScaleY(1.0),
101 mbFntDirty(true),
102 mbLastObjWasPolyWithoutLine(false),
103 mbNoLine(false),
104 mbNoFill(false),
105 mbLastObjWasLine(false),
106 maClip()
108 maVD.EnableOutput(false);
109 maVD.SetLineColor();
110 maVD.SetFillColor();
111 maOldLineColor.SetRed( maVD.GetLineColor().GetRed() + 1 );
112 mpLineAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_LINE_FIRST, XATTR_LINE_LAST, 0, 0);
113 mpFillAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
114 mpTextAttr = new SfxItemSet(rModel.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END, 0, 0);
115 checkClip();
118 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
120 delete mpLineAttr;
121 delete mpFillAttr;
122 delete mpTextAttr;
125 void ImpSdrGDIMetaFileImport::DoLoopActions(GDIMetaFile& rMtf, SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport)
127 const sal_uLong nCount(rMtf.GetActionSize());
129 for(sal_uLong a(0); a < nCount; a++)
131 MetaAction* pAct = rMtf.GetAction(a);
133 if(!pAct)
135 OSL_ENSURE(false, "OOps, no action at valid position (!)");
136 pAct = rMtf.GetAction(0);
139 switch (pAct->GetType())
141 case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
142 case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
143 case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
144 case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
145 case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
146 case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
147 case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
148 case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
149 case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
150 case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
151 case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
152 case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
153 case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
154 case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
155 case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
156 case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
157 case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
158 case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
159 case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
160 case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
161 case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
162 case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
163 case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
164 case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
165 case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
166 case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
167 case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
168 case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
169 case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
170 case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
171 case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
172 case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
173 case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
174 case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
175 case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, &rMtf); break;
177 // missing actions added
178 case META_TEXTRECT_ACTION : DoAction((MetaTextRectAction&)*pAct); break;
179 case META_BMPSCALEPART_ACTION : DoAction((MetaBmpScalePartAction&)*pAct); break;
180 case META_BMPEXSCALEPART_ACTION : DoAction((MetaBmpExScalePartAction&)*pAct); break;
181 case META_MASK_ACTION : DoAction((MetaMaskAction&)*pAct); break;
182 case META_MASKSCALE_ACTION : DoAction((MetaMaskScaleAction&)*pAct); break;
183 case META_MASKSCALEPART_ACTION : DoAction((MetaMaskScalePartAction&)*pAct); break;
184 case META_GRADIENT_ACTION : DoAction((MetaGradientAction&)*pAct); break;
185 case META_WALLPAPER_ACTION : DoAction((MetaWallpaperAction&)*pAct); break;
186 case META_TRANSPARENT_ACTION : DoAction((MetaTransparentAction&)*pAct); break;
187 case META_EPS_ACTION : DoAction((MetaEPSAction&)*pAct); break;
188 case META_REFPOINT_ACTION : DoAction((MetaRefPointAction&)*pAct); break;
189 case META_TEXTLINECOLOR_ACTION : DoAction((MetaTextLineColorAction&)*pAct); break;
190 case META_TEXTLINE_ACTION : DoAction((MetaTextLineAction&)*pAct); break;
191 case META_FLOATTRANSPARENT_ACTION : DoAction((MetaFloatTransparentAction&)*pAct); break;
192 case META_GRADIENTEX_ACTION : DoAction((MetaGradientExAction&)*pAct); break;
193 case META_LAYOUTMODE_ACTION : DoAction((MetaLayoutModeAction&)*pAct); break;
194 case META_TEXTLANGUAGE_ACTION : DoAction((MetaTextLanguageAction&)*pAct); break;
195 case META_OVERLINECOLOR_ACTION : DoAction((MetaOverlineColorAction&)*pAct); break;
198 if(pProgrInfo && pActionsToReport)
200 (*pActionsToReport)++;
202 if(*pActionsToReport >= 16) // update all 16 actions
204 if(!pProgrInfo->ReportActions(*pActionsToReport))
205 break;
207 *pActionsToReport = 0;
213 sal_uInt32 ImpSdrGDIMetaFileImport::DoImport(
214 const GDIMetaFile& rMtf,
215 SdrObjList& rOL,
216 sal_uLong nInsPos,
217 SvdProgressInfo* pProgrInfo)
219 // setup some global scale parameter
220 // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
221 mfScaleX = mfScaleY = 1.0;
222 const Size aMtfSize(rMtf.GetPrefSize());
224 if(aMtfSize.Width() & aMtfSize.Height() && (!maScaleRect.IsEmpty()))
226 maOfs = maScaleRect.TopLeft();
228 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
230 mfScaleX = (double)( maScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
233 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
235 mfScaleY = (double)( maScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
239 mbMov = maOfs.X()!=0 || maOfs.Y()!=0;
240 mbSize = false;
241 maScaleX = Fraction( 1, 1 );
242 maScaleY = Fraction( 1, 1 );
244 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
246 maScaleX = Fraction(maScaleRect.GetWidth() - 1, aMtfSize.Width());
247 mbSize = true;
250 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
252 maScaleY = Fraction(maScaleRect.GetHeight() - 1, aMtfSize.Height());
253 mbSize = true;
256 if(pProgrInfo)
258 pProgrInfo->SetActionCount(rMtf.GetActionSize());
261 sal_uInt32 nActionsToReport(0);
263 // execute
264 DoLoopActions(const_cast< GDIMetaFile& >(rMtf), pProgrInfo, &nActionsToReport);
266 if(pProgrInfo)
268 pProgrInfo->ReportActions(nActionsToReport);
269 nActionsToReport = 0;
272 // MapMode scaling
273 MapScaling();
275 // To calculate the progress meter, we use GetActionSize()*3.
276 // However, maTmpList has a lower entry count limit than GetActionSize(),
277 // so the actions that were assumed were too much have to be re-added.
278 nActionsToReport = (rMtf.GetActionSize() - maTmpList.size()) * 2;
280 // announce all currently unannounced rescales
281 if(pProgrInfo)
283 pProgrInfo->ReportRescales(nActionsToReport);
284 pProgrInfo->SetInsertCount(maTmpList.size());
287 nActionsToReport = 0;
289 // insert all objects cached in aTmpList now into rOL from nInsPos
290 if(nInsPos > rOL.GetObjCount())
292 nInsPos = rOL.GetObjCount();
295 SdrInsertReason aReason(SDRREASON_VIEWCALL);
297 for(sal_uInt32 i(0); i < maTmpList.size(); i++)
299 SdrObject* pObj = maTmpList[i];
300 rOL.NbcInsertObject(pObj, nInsPos, &aReason);
301 nInsPos++;
303 if(pProgrInfo)
305 nActionsToReport++;
307 if(nActionsToReport >= 32) // update all 32 actions
309 pProgrInfo->ReportInserts(nActionsToReport);
310 nActionsToReport = 0;
315 // report all remaining inserts for the last time
316 if(pProgrInfo)
318 pProgrInfo->ReportInserts(nActionsToReport);
321 return maTmpList.size();
324 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
326 mbNoLine = false;
327 mbNoFill = false;
328 bool bLine(!bForceTextAttr);
329 bool bFill(!pObj || (pObj->IsClosedObj() && !bForceTextAttr));
330 bool bText(bForceTextAttr || (pObj && pObj->GetOutlinerParaObject()));
332 if(bLine)
334 if(mnLineWidth)
336 mpLineAttr->Put(XLineWidthItem(mnLineWidth));
338 else
340 mpLineAttr->Put(XLineWidthItem(0));
343 maOldLineColor = maVD.GetLineColor();
345 if(maVD.IsLineColor())
347 mpLineAttr->Put(XLineStyleItem(XLINE_SOLID));
348 mpLineAttr->Put(XLineColorItem(OUString(), maVD.GetLineColor()));
350 else
352 mpLineAttr->Put(XLineStyleItem(XLINE_NONE));
355 switch(maLineJoin)
357 default : // basegfx::B2DLINEJOIN_NONE
358 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_NONE));
359 break;
360 case basegfx::B2DLINEJOIN_MIDDLE:
361 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MIDDLE));
362 break;
363 case basegfx::B2DLINEJOIN_BEVEL:
364 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL));
365 break;
366 case basegfx::B2DLINEJOIN_MITER:
367 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MITER));
368 break;
369 case basegfx::B2DLINEJOIN_ROUND:
370 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_ROUND));
371 break;
374 // Add LineCap support
375 mpLineAttr->Put(XLineCapItem(maLineCap));
377 if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
379 mpLineAttr->Put(XLineDashItem(OUString(), maDash));
381 else
383 mpLineAttr->Put(XLineDashItem(OUString(), XDash(XDASH_RECT)));
386 else
388 mbNoLine = true;
391 if(bFill)
393 if(maVD.IsFillColor())
395 mpFillAttr->Put(XFillStyleItem(XFILL_SOLID));
396 mpFillAttr->Put(XFillColorItem(OUString(), maVD.GetFillColor()));
398 else
400 mpFillAttr->Put(XFillStyleItem(XFILL_NONE));
403 else
405 mbNoFill = true;
408 if(bText && mbFntDirty)
410 Font aFnt(maVD.GetFont());
411 const sal_uInt32 nHeight(FRound(aFnt.GetSize().Height() * mfScaleY));
413 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
414 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
415 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
416 mpTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
417 mpTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
418 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
419 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
420 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
421 mpTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
422 mpTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
423 mpTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
424 mpTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
425 mpTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
427 // #i118485# Setting this item leads to problems (written #i118498# for this)
428 // mpTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
430 mpTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
431 mpTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
432 mpTextAttr->Put(SvxColorItem(maVD.GetTextColor(), EE_CHAR_COLOR));
433 //... svxfont textitem svditext
434 mbFntDirty = false;
437 if(pObj)
439 pObj->SetLayer(mnLayer);
441 if(bLine)
443 pObj->SetMergedItemSet(*mpLineAttr);
446 if(bFill)
448 pObj->SetMergedItemSet(*mpFillAttr);
451 if(bText)
453 pObj->SetMergedItemSet(*mpTextAttr);
454 pObj->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
459 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
461 if(bScale && !maScaleRect.IsEmpty())
463 if(mbSize)
465 pObj->NbcResize(Point(), maScaleX, maScaleY);
468 if(mbMov)
470 pObj->NbcMove(Size(maOfs.X(), maOfs.Y()));
474 if(isClip())
476 const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
477 const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
478 const SdrLayerID aOldLayer(pObj->GetLayer());
479 const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
480 const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
481 const SdrTextObj* pSdrTextObj = dynamic_cast< SdrTextObj* >(pObj);
483 if(pSdrTextObj && pSdrTextObj->HasText())
485 // all text objects are created from ImportText and have no line or fill attributes, so
486 // it is okay to concentrate on the text itself
487 while(true)
489 const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour());
490 const basegfx::B2DRange aTextRange(aTextContour.getB2DRange());
491 const basegfx::B2DRange aClipRange(maClip.getB2DRange());
493 // no overlap -> completely outside
494 if(!aClipRange.overlaps(aTextRange))
496 SdrObject::Free(pObj);
497 break;
500 // when the clip is a rectangle fast check for inside is possible
501 if(basegfx::tools::isRectangle(maClip) && aClipRange.isInside(aTextRange))
503 // completely inside ClipRect
504 break;
507 // here text needs to be clipped; to do so, convert to SdrObjects with polygons
508 // and add these recursively. Delete original object, do not add in this run
509 SdrObject* pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
510 SdrObject::Free(pObj);
512 if(pConverted)
514 // recursively add created conversion; per definition this shall not
515 // contain further SdrTextObjs. Visit only non-group objects
516 SdrObjListIter aIter(*pConverted, IM_DEEPNOGROUPS);
518 // work with clones; the created conversion may contain group objects
519 // and when working with the original objects the loop itself could
520 // break and the cleanup later would be pretty complicated (only delete group
521 // objects, are these empty, ...?)
522 while(aIter.IsMore())
524 SdrObject* pCandidate = aIter.Next();
525 OSL_ENSURE(pCandidate && 0 == dynamic_cast< SdrObjGroup* >(pCandidate), "SdrObjListIter with IM_DEEPNOGROUPS error (!)");
526 SdrObject* pNewClone = pCandidate->Clone();
528 if(pNewClone)
530 InsertObj(pNewClone, false);
532 else
534 OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
538 // cleanup temporary conversion objects
539 SdrObject::Free(pConverted);
542 break;
545 else
547 BitmapEx aBitmapEx;
549 if(pSdrGrafObj)
551 aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
554 SdrObject::Free(pObj);
556 if(!aOldRange.isEmpty())
558 // clip against ClipRegion
559 const basegfx::B2DPolyPolygon aNewPoly(
560 basegfx::tools::clipPolyPolygonOnPolyPolygon(
561 aPoly,
562 maClip,
563 true,
564 aPoly.isClosed() ? false : true));
565 const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
567 if(!aNewRange.isEmpty())
569 pObj = new SdrPathObj(
570 aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
571 aNewPoly);
573 pObj->SetLayer(aOldLayer);
574 pObj->SetMergedItemSet(aOldItemSet);
576 if(!!aBitmapEx)
578 // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
579 const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
580 const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
581 basegfx::B2DRange aPixel(aNewRange);
582 basegfx::B2DHomMatrix aTrans;
584 aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
585 aTrans.scale(fScaleX, fScaleY);
586 aPixel.transform(aTrans);
588 const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
589 const Point aClipTopLeft(
590 basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
591 basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
592 const Size aClipSize(
593 basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
594 basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
595 const BitmapEx aClippedBitmap(
596 aBitmapEx,
597 aClipTopLeft,
598 aClipSize);
600 pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
601 pObj->SetMergedItem(XFillBitmapItem(OUString(), Graphic(aClippedBitmap)));
602 pObj->SetMergedItem(XFillBmpTileItem(false));
603 pObj->SetMergedItem(XFillBmpStretchItem(true));
610 if(pObj)
612 // #i111954# check object for visibility
613 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
614 bool bVisible(false);
616 if(pObj->HasLineStyle())
618 bVisible = true;
621 if(!bVisible && pObj->HasFillStyle())
623 bVisible = true;
626 if(!bVisible)
628 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
630 if(pTextObj && pTextObj->HasText())
632 bVisible = true;
636 if(!bVisible)
638 SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
640 if(pGrafObj)
642 // this may be refined to check if the graphic really is visible. It
643 // is here to ensure that graphic objects without fill, line and text
644 // get created
645 bVisible = true;
649 if(!bVisible)
651 SdrObject::Free(pObj);
653 else
655 maTmpList.push_back(pObj);
657 if(dynamic_cast< SdrPathObj* >(pObj))
659 const bool bClosed(pObj->IsClosedObj());
661 mbLastObjWasPolyWithoutLine = mbNoLine && bClosed;
662 mbLastObjWasLine = !bClosed;
664 else
666 mbLastObjWasPolyWithoutLine = false;
667 mbLastObjWasLine = false;
673 /**************************************************************************************************/
674 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/) const
678 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/) const
682 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
684 // #i73407# reformulation to use new B2DPolygon classes
685 const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
686 const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
688 if(!aStart.equal(aEnd))
690 basegfx::B2DPolygon aLine;
691 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
693 aLine.append(aStart);
694 aLine.append(aEnd);
695 aLine.transform(aTransform);
697 const LineInfo& rLineInfo = rAct.GetLineInfo();
698 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
699 bool bCreateLineObject(true);
701 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aLine))
703 bCreateLineObject = false;
706 if(bCreateLineObject)
708 SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
709 mnLineWidth = nNewLineWidth;
710 maLineJoin = rLineInfo.GetLineJoin();
711 maLineCap = rLineInfo.GetLineCap();
712 maDash = XDash(XDASH_RECT,
713 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
714 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
715 rLineInfo.GetDistance());
716 SetAttributes(pPath);
717 mnLineWidth = 0;
718 maLineJoin = basegfx::B2DLINEJOIN_NONE;
719 maDash = XDash();
720 InsertObj(pPath, false);
725 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
727 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
728 SetAttributes(pRect);
729 InsertObj(pRect);
732 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
734 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
735 SetAttributes(pRect);
736 long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
737 if (nRad!=0) {
738 SfxItemSet aSet(*mpLineAttr->GetPool(), SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 0, 0);
739 aSet.Put(SdrEckenradiusItem(nRad));
740 pRect->SetMergedItemSet(aSet);
742 InsertObj(pRect);
745 /**************************************************************************************************/
747 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
749 SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
750 SetAttributes(pCirc);
751 InsertObj(pCirc);
754 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
756 Point aCenter(rAct.GetRect().Center());
757 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
758 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
759 SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
760 SetAttributes(pCirc);
761 InsertObj(pCirc);
764 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
766 Point aCenter(rAct.GetRect().Center());
767 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
768 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
769 SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
770 SetAttributes(pCirc);
771 InsertObj(pCirc);
774 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
776 Point aCenter(rAct.GetRect().Center());
777 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
778 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
779 SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
780 SetAttributes(pCirc);
781 InsertObj(pCirc);
784 /**************************************************************************************************/
786 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
788 // #i102706# Do not merge closed polygons
789 if(rSrcPoly.isClosed())
791 return false;
794 // #i73407# reformulation to use new B2DPolygon classes
795 if(mbLastObjWasLine && (maOldLineColor == maVD.GetLineColor()) && rSrcPoly.count())
797 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
798 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
800 if(pLastPoly)
802 if(1L == pLastPoly->GetPathPoly().count())
804 bool bOk(false);
805 basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
807 // #i102706# Do not merge closed polygons
808 if(aDstPoly.isClosed())
810 return false;
813 if(aDstPoly.count())
815 const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
816 const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
818 if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
820 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
821 bOk = true;
823 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
825 basegfx::B2DPolygon aNew(rSrcPoly);
826 aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
827 aDstPoly = aNew;
828 bOk = true;
830 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
832 aDstPoly.flip();
833 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
834 bOk = true;
836 else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
838 basegfx::B2DPolygon aNew(rSrcPoly);
839 aNew.flip();
840 aDstPoly.append(aNew, 1L, aNew.count() - 1L);
841 bOk = true;
845 if(bOk)
847 pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
850 return bOk;
855 return false;
858 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
860 // #i73407# reformulation to use new B2DPolygon classes
861 if(mbLastObjWasPolyWithoutLine)
863 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
864 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
866 if(pLastPoly)
868 if(pLastPoly->GetPathPoly() == rPolyPolygon)
870 SetAttributes(NULL);
872 if(!mbNoLine && mbNoFill)
874 pLastPoly->SetMergedItemSet(*mpLineAttr);
876 return true;
882 return false;
885 void ImpSdrGDIMetaFileImport::checkClip()
887 if(maVD.IsClipRegion())
889 maClip = maVD.GetClipRegion().GetAsB2DPolyPolygon();
891 if(isClip())
893 const basegfx::B2DHomMatrix aTransform(
894 basegfx::tools::createScaleTranslateB2DHomMatrix(
895 mfScaleX,
896 mfScaleY,
897 maOfs.X(),
898 maOfs.Y()));
900 maClip.transform(aTransform);
905 bool ImpSdrGDIMetaFileImport::isClip() const
907 return !maClip.getB2DRange().isEmpty();
910 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
912 // #i73407# reformulation to use new B2DPolygon classes
913 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
915 if(aSource.count())
917 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
918 aSource.transform(aTransform);
921 const LineInfo& rLineInfo = rAct.GetLineInfo();
922 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
923 bool bCreateLineObject(true);
925 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aSource))
927 bCreateLineObject = false;
929 else if(mbLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
931 bCreateLineObject = false;
934 if(bCreateLineObject)
936 SdrPathObj* pPath = new SdrPathObj(
937 aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
938 basegfx::B2DPolyPolygon(aSource));
939 mnLineWidth = nNewLineWidth;
940 maLineJoin = rLineInfo.GetLineJoin();
941 maLineCap = rLineInfo.GetLineCap();
942 maDash = XDash(XDASH_RECT,
943 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
944 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
945 rLineInfo.GetDistance());
946 SetAttributes(pPath);
947 mnLineWidth = 0;
948 maLineJoin = basegfx::B2DLINEJOIN_NONE;
949 maDash = XDash();
950 InsertObj(pPath, false);
954 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
956 // #i73407# reformulation to use new B2DPolygon classes
957 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
959 if(aSource.count())
961 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
962 aSource.transform(aTransform);
964 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
966 // #i73407# make sure polygon is closed, it's a filled primitive
967 aSource.setClosed(true);
968 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
969 SetAttributes(pPath);
970 InsertObj(pPath, false);
975 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
977 // #i73407# reformulation to use new B2DPolygon classes
978 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
980 if(aSource.count())
982 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
983 aSource.transform(aTransform);
985 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
987 // #i73407# make sure polygon is closed, it's a filled primitive
988 aSource.setClosed(true);
989 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
990 SetAttributes(pPath);
991 InsertObj(pPath, false);
996 /**************************************************************************************************/
998 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const OUString& rStr, const MetaAction& rAct )
1000 // calc text box size, add 5% to make it fit safely
1002 FontMetric aFontMetric( maVD.GetFontMetric() );
1003 Font aFnt( maVD.GetFont() );
1004 FontAlign eAlg( aFnt.GetAlign() );
1006 sal_Int32 nTextWidth = (sal_Int32)( maVD.GetTextWidth( rStr ) * mfScaleX );
1007 sal_Int32 nTextHeight = (sal_Int32)( maVD.GetTextHeight() * mfScaleY );
1009 Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) );
1010 Size aSize( nTextWidth, nTextHeight );
1012 if ( eAlg == ALIGN_BASELINE )
1013 aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
1014 else if ( eAlg == ALIGN_BOTTOM )
1015 aPos.Y() -= nTextHeight;
1017 Rectangle aTextRect( aPos, aSize );
1018 SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
1020 pText->SetMergedItem ( SdrTextUpperDistItem (0));
1021 pText->SetMergedItem ( SdrTextLowerDistItem (0));
1022 pText->SetMergedItem ( SdrTextRightDistItem (0));
1023 pText->SetMergedItem ( SdrTextLeftDistItem (0));
1025 if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
1027 pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
1028 pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
1029 // don't let the margins eat the space needed for the text
1030 pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
1032 else
1034 pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
1037 pText->SetModel(mpModel);
1038 pText->SetLayer(mnLayer);
1039 pText->NbcSetText( rStr );
1040 SetAttributes( pText, true );
1041 pText->SetSnapRect( aTextRect );
1043 if (!aFnt.IsTransparent())
1045 SfxItemSet aAttr(*mpFillAttr->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
1046 aAttr.Put(XFillStyleItem(XFILL_SOLID));
1047 aAttr.Put(XFillColorItem(OUString(), aFnt.GetFillColor()));
1048 pText->SetMergedItemSet(aAttr);
1050 sal_uInt32 nWink = aFnt.GetOrientation();
1051 if ( nWink )
1053 nWink*=10;
1054 double a=nWink*nPi180;
1055 double nSin=sin(a);
1056 double nCos=cos(a);
1057 pText->NbcRotate(aPos,nWink,nSin,nCos);
1059 InsertObj( pText, false );
1062 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
1064 OUString aStr(rAct.GetText());
1065 aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1066 ImportText( rAct.GetPoint(), aStr, rAct );
1069 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
1071 OUString aStr(rAct.GetText());
1072 aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1073 ImportText( rAct.GetPoint(), aStr, rAct );
1076 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
1078 OUString aStr(rAct.GetText());
1079 aStr = aStr.copy(rAct.GetIndex(), rAct.GetLen());
1080 ImportText( rAct.GetPoint(), aStr, rAct );
1083 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
1085 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
1086 aRect.Right()++; aRect.Bottom()++;
1087 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1089 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1090 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1091 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1092 InsertObj(pGraf);
1095 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
1097 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1098 aRect.Right()++; aRect.Bottom()++;
1099 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1101 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1102 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1103 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1104 InsertObj(pGraf);
1107 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
1109 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
1110 aRect.Right()++; aRect.Bottom()++;
1111 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1113 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1114 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1115 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1116 InsertObj(pGraf);
1119 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
1121 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1122 aRect.Right()++; aRect.Bottom()++;
1123 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1125 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1126 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1127 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1128 InsertObj(pGraf);
1133 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
1135 // #i73407# reformulation to use new B2DPolygon classes
1136 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1138 if(aSource.count())
1140 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1141 aSource.transform(aTransform);
1143 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1145 const Hatch& rHatch = rAct.GetHatch();
1146 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1147 SfxItemSet aHatchAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0);
1148 XHatchStyle eStyle;
1150 switch(rHatch.GetStyle())
1152 case(HATCH_TRIPLE) :
1154 eStyle = XHATCH_TRIPLE;
1155 break;
1158 case(HATCH_DOUBLE) :
1160 eStyle = XHATCH_DOUBLE;
1161 break;
1164 default:
1166 eStyle = XHATCH_SINGLE;
1167 break;
1171 SetAttributes(pPath);
1172 aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
1173 aHatchAttr.Put(XFillHatchItem(&mpModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1174 pPath->SetMergedItemSet(aHatchAttr);
1176 InsertObj(pPath, false);
1183 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1185 rAct.Execute(&maVD);
1188 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1190 MapScaling();
1191 rAct.Execute(&maVD);
1192 mbLastObjWasPolyWithoutLine = false;
1193 mbLastObjWasLine = false;
1196 void ImpSdrGDIMetaFileImport::MapScaling()
1198 const size_t nAnz(maTmpList.size());
1199 const MapMode& rMap = maVD.GetMapMode();
1200 Point aMapOrg( rMap.GetOrigin() );
1201 bool bMov2(aMapOrg.X() != 0 || aMapOrg.Y() != 0);
1203 if(bMov2)
1205 for(size_t i = mnMapScalingOfs; i < nAnz; i++)
1207 SdrObject* pObj = maTmpList[i];
1209 pObj->NbcMove(Size(aMapOrg.X(), aMapOrg.Y()));
1213 mnMapScalingOfs = nAnz;
1218 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
1220 bool aSkipComment = false;
1222 if (rAct.GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_BEGIN"))
1224 MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
1226 if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
1228 // #i73407# reformulation to use new B2DPolygon classes
1229 basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1231 if(aSource.count())
1233 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1235 const Gradient& rGrad = pAct->GetGradient();
1236 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1237 SfxItemSet aGradAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1238 XGradient aXGradient;
1240 aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
1241 aXGradient.SetStartColor(rGrad.GetStartColor());
1242 aXGradient.SetEndColor(rGrad.GetEndColor());
1243 aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1244 aXGradient.SetBorder(rGrad.GetBorder());
1245 aXGradient.SetXOffset(rGrad.GetOfsX());
1246 aXGradient.SetYOffset(rGrad.GetOfsY());
1247 aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1248 aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1249 aXGradient.SetSteps(rGrad.GetSteps());
1251 // no need to use SetAttributes(..) here since line and fill style
1252 // need to be set individually
1253 // SetAttributes(pPath);
1255 // switch line off; if there was one there will be a
1256 // META_POLYLINE_ACTION following creating another object
1257 aGradAttr.Put(XLineStyleItem(XLINE_NONE));
1259 // add detected gradient fillstyle
1260 aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1261 aGradAttr.Put(XFillGradientItem(aXGradient));
1263 pPath->SetMergedItemSet(aGradAttr);
1265 InsertObj(pPath);
1269 aSkipComment = true;
1273 if(aSkipComment)
1275 MetaAction* pSkipAct = pMtf->NextAction();
1277 while( pSkipAct
1278 && ((pSkipAct->GetType() != META_COMMENT_ACTION )
1279 || !(((MetaCommentAction*)pSkipAct)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1281 pSkipAct = pMtf->NextAction();
1286 void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction& rAct)
1288 GDIMetaFile aTemp;
1290 maVD.AddTextRectActions(rAct.GetRect(), rAct.GetText(), rAct.GetStyle(), aTemp);
1291 DoLoopActions(aTemp, 0, 0);
1294 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction& rAct)
1296 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1297 Bitmap aBitmap(rAct.GetBitmap());
1299 aRect.Right()++;
1300 aRect.Bottom()++;
1301 aBitmap.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1302 SdrGrafObj* pGraf = new SdrGrafObj(aBitmap, aRect);
1304 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1305 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1306 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1307 InsertObj(pGraf);
1310 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction& rAct)
1312 Rectangle aRect(rAct.GetDestPoint(),rAct.GetDestSize());
1313 BitmapEx aBitmapEx(rAct.GetBitmapEx());
1315 aRect.Right()++;
1316 aRect.Bottom()++;
1317 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1318 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1320 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1321 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1322 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1323 InsertObj(pGraf);
1326 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction& rAct)
1328 Rectangle aRect(rAct.GetPoint(), rAct.GetBitmap().GetSizePixel());
1329 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1331 aRect.Right()++; aRect.Bottom()++;
1332 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1334 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1335 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1336 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1337 InsertObj(pGraf);
1340 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction& rAct)
1342 Rectangle aRect(rAct.GetPoint(), rAct.GetSize());
1343 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1345 aRect.Right()++; aRect.Bottom()++;
1346 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1348 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1349 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1350 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1351 InsertObj(pGraf);
1354 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction& rAct)
1356 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1357 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1359 aRect.Right()++; aRect.Bottom()++;
1360 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1361 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1363 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1364 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1365 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1366 InsertObj(pGraf);
1369 namespace
1371 XGradientStyle getXGradientStyleFromGradientStyle(const GradientStyle& rGradientStyle)
1373 XGradientStyle aXGradientStyle(XGRAD_LINEAR);
1375 switch(rGradientStyle)
1377 case GradientStyle_LINEAR: aXGradientStyle = XGRAD_LINEAR; break;
1378 case GradientStyle_AXIAL: aXGradientStyle = XGRAD_AXIAL; break;
1379 case GradientStyle_RADIAL: aXGradientStyle = XGRAD_RADIAL; break;
1380 case GradientStyle_ELLIPTICAL: aXGradientStyle = XGRAD_ELLIPTICAL; break;
1381 case GradientStyle_SQUARE: aXGradientStyle = XGRAD_SQUARE; break;
1382 case GradientStyle_RECT: aXGradientStyle = XGRAD_RECT; break;
1384 // Needed due to GradientStyle_FORCE_EQUAL_SIZE; this again is needed
1385 // to force the enum defines in VCL to a defined size for the compilers,
1386 // so despite it is never used it cannot be removed (would break the
1387 // API implementation probably).
1388 case GradientStyle_FORCE_EQUAL_SIZE: break;
1391 return aXGradientStyle;
1395 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction& rAct)
1397 basegfx::B2DRange aRange(rAct.GetRect().Left(), rAct.GetRect().Top(), rAct.GetRect().Right(), rAct.GetRect().Bottom());
1399 if(!aRange.isEmpty())
1401 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1402 aRange.transform(aTransform);
1403 const Gradient& rGradient = rAct.GetGradient();
1404 SdrRectObj* pRect = new SdrRectObj(
1405 Rectangle(
1406 floor(aRange.getMinX()),
1407 floor(aRange.getMinY()),
1408 ceil(aRange.getMaxX()),
1409 ceil(aRange.getMaxY())));
1410 SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1411 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1412 const XFillGradientItem aXFillGradientItem(
1413 XGradient(
1414 rGradient.GetStartColor(),
1415 rGradient.GetEndColor(),
1416 aXGradientStyle,
1417 rGradient.GetAngle(),
1418 rGradient.GetOfsX(),
1419 rGradient.GetOfsY(),
1420 rGradient.GetBorder(),
1421 rGradient.GetStartIntensity(),
1422 rGradient.GetEndIntensity(),
1423 rGradient.GetSteps()));
1425 SetAttributes(pRect);
1426 aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1427 aGradientAttr.Put(aXFillGradientItem);
1428 pRect->SetMergedItemSet(aGradientAttr);
1430 InsertObj(pRect, false);
1434 void ImpSdrGDIMetaFileImport::DoAction(MetaWallpaperAction&)
1436 OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)");
1439 void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction& rAct)
1441 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1443 if(aSource.count())
1445 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1446 aSource.transform(aTransform);
1447 aSource.setClosed(true);
1449 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1450 SetAttributes(pPath);
1451 pPath->SetMergedItem(XFillTransparenceItem(rAct.GetTransparence()));
1452 InsertObj(pPath, false);
1456 void ImpSdrGDIMetaFileImport::DoAction(MetaEPSAction&)
1458 OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)");
1461 void ImpSdrGDIMetaFileImport::DoAction(MetaTextLineAction&)
1463 OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)");
1466 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction& rAct)
1468 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1470 if(aSource.count())
1472 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1473 aSource.transform(aTransform);
1475 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1477 const Gradient& rGradient = rAct.GetGradient();
1478 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1479 SfxItemSet aGradientAttr(mpModel->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLSTYLE, XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0);
1480 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1481 const XFillGradientItem aXFillGradientItem(
1482 XGradient(
1483 rGradient.GetStartColor(),
1484 rGradient.GetEndColor(),
1485 aXGradientStyle,
1486 rGradient.GetAngle(),
1487 rGradient.GetOfsX(),
1488 rGradient.GetOfsY(),
1489 rGradient.GetBorder(),
1490 rGradient.GetStartIntensity(),
1491 rGradient.GetEndIntensity(),
1492 rGradient.GetSteps()));
1494 SetAttributes(pPath);
1495 aGradientAttr.Put(XFillStyleItem(XFILL_HATCH));
1496 aGradientAttr.Put(aXFillGradientItem);
1497 pPath->SetMergedItemSet(aGradientAttr);
1499 InsertObj(pPath, false);
1504 void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction& rAct)
1506 const GDIMetaFile& rMtf = rAct.GetGDIMetaFile();
1508 if(rMtf.GetActionSize())
1510 const Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1512 // convert metafile sub-content to BitmapEx
1513 BitmapEx aBitmapEx(
1514 convertMetafileToBitmapEx(
1515 rMtf,
1516 basegfx::B2DRange(
1517 aRect.Left(), aRect.Top(),
1518 aRect.Right(), aRect.Bottom()),
1519 125000));
1521 // handle colors
1522 const Gradient& rGradient = rAct.GetGradient();
1523 basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
1524 basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
1526 if(100 != rGradient.GetStartIntensity())
1528 aStart *= (double)rGradient.GetStartIntensity() / 100.0;
1531 if(100 != rGradient.GetEndIntensity())
1533 aEnd *= (double)rGradient.GetEndIntensity() / 100.0;
1536 const bool bEqualColors(aStart == aEnd);
1537 const bool bNoSteps(1 == rGradient.GetSteps());
1538 bool bCreateObject(true);
1539 bool bHasNewMask(false);
1540 AlphaMask aNewMask;
1541 double fTransparence(0.0);
1542 bool bFixedTransparence(false);
1544 if(bEqualColors || bNoSteps)
1546 // single transparence
1547 const basegfx::BColor aMedium(basegfx::average(aStart, aEnd));
1548 fTransparence = aMedium.luminance();
1550 if(basegfx::fTools::lessOrEqual(fTransparence, 0.0))
1552 // no transparence needed, all done
1554 else if(basegfx::fTools::moreOrEqual(fTransparence, 1.0))
1556 // all transparent, no object
1557 bCreateObject = false;
1559 else
1561 // 0.0 < transparence < 1.0, apply fixed transparence
1562 bFixedTransparence = true;
1565 else
1567 // gradient transparence
1568 VirtualDevice aVDev;
1570 aVDev.SetOutputSizePixel(aBitmapEx.GetBitmap().GetSizePixel());
1571 aVDev.DrawGradient(Rectangle(Point(0, 0), aVDev.GetOutputSizePixel()), rGradient);
1573 aNewMask = AlphaMask(aVDev.GetBitmap(Point(0, 0), aVDev.GetOutputSizePixel()));
1574 bHasNewMask = true;
1577 if(bCreateObject)
1579 if(bHasNewMask || bFixedTransparence)
1581 if(!aBitmapEx.IsAlpha() && !aBitmapEx.IsTransparent())
1583 // no transparence yet, apply new one
1584 if(bFixedTransparence)
1586 sal_uInt8 aAlpha(basegfx::fround(fTransparence * 255.0));
1588 aNewMask = AlphaMask(aBitmapEx.GetBitmap().GetSizePixel(), &aAlpha);
1591 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aNewMask);
1593 else
1595 // mix existing and new alpha mask
1596 AlphaMask aOldMask;
1598 if(aBitmapEx.IsAlpha())
1600 aOldMask = aBitmapEx.GetAlpha();
1602 else if(TRANSPARENT_BITMAP == aBitmapEx.GetTransparentType())
1604 aOldMask = aBitmapEx.GetMask();
1606 else if(TRANSPARENT_COLOR == aBitmapEx.GetTransparentType())
1608 aOldMask = aBitmapEx.GetBitmap().CreateMask(aBitmapEx.GetTransparentColor());
1611 BitmapWriteAccess* pOld = aOldMask.AcquireWriteAccess();
1613 if(pOld)
1615 const double fFactor(1.0 / 255.0);
1617 if(bFixedTransparence)
1619 const double fOpNew(1.0 - fTransparence);
1621 for(int y(0); y < pOld->Height(); y++)
1623 for(int x(0); x < pOld->Width(); x++)
1625 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1626 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1628 pOld->SetPixel(y, x, BitmapColor(aCol));
1632 else
1634 BitmapReadAccess* pNew = aNewMask.AcquireReadAccess();
1636 if(pNew)
1638 if(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height())
1640 for(int y(0); y < pOld->Height(); y++)
1642 for(int x(0); x < pOld->Width(); x++)
1644 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1645 const double fOpNew(1.0 - (pNew->GetPixel(y, x).GetIndex() * fFactor));
1646 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1648 pOld->SetPixel(y, x, BitmapColor(aCol));
1652 else
1654 OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1657 aNewMask.ReleaseAccess(pNew);
1659 else
1661 OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1665 aOldMask.ReleaseAccess(pOld);
1667 else
1669 OSL_ENSURE(false, "Got no access to old alpha mask (!)");
1672 // apply combined bitmap as mask
1673 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aOldMask);
1677 // create and add object
1678 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1680 // for MetaFloatTransparentAction, do not use SetAttributes(...)
1681 // since these metafile content is not used to draw line/fill
1682 // dependent of these setting at the device content
1683 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1684 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1685 InsertObj(pGraf);
1690 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */