1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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(
79 const Rectangle
& rRect
)
91 maLineJoin(basegfx::B2DLINEJOIN_NONE
),
92 maLineCap(com::sun::star::drawing::LineCap_BUTT
),
93 maDash(XDASH_RECT
, 0, 0, 0, 0, 0),
102 mbLastObjWasPolyWithoutLine(false),
105 mbLastObjWasLine(false),
108 maVD
.EnableOutput(false);
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);
118 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
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
);
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
))
207 *pActionsToReport
= 0;
213 sal_uInt32
ImpSdrGDIMetaFileImport::DoImport(
214 const GDIMetaFile
& rMtf
,
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;
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());
250 if(aMtfSize
.Height() != (maScaleRect
.GetHeight() - 1))
252 maScaleY
= Fraction(maScaleRect
.GetHeight() - 1, aMtfSize
.Height());
258 pProgrInfo
->SetActionCount(rMtf
.GetActionSize());
261 sal_uInt32
nActionsToReport(0);
264 DoLoopActions(const_cast< GDIMetaFile
& >(rMtf
), pProgrInfo
, &nActionsToReport
);
268 pProgrInfo
->ReportActions(nActionsToReport
);
269 nActionsToReport
= 0;
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
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
);
307 if(nActionsToReport
>= 32) // update all 32 actions
309 pProgrInfo
->ReportInserts(nActionsToReport
);
310 nActionsToReport
= 0;
315 // report all remaining inserts for the last time
318 pProgrInfo
->ReportInserts(nActionsToReport
);
321 return maTmpList
.size();
324 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject
* pObj
, bool bForceTextAttr
)
328 bool bLine(!bForceTextAttr
);
329 bool bFill(!pObj
|| (pObj
->IsClosedObj() && !bForceTextAttr
));
330 bool bText(bForceTextAttr
|| (pObj
&& pObj
->GetOutlinerParaObject()));
336 mpLineAttr
->Put(XLineWidthItem(mnLineWidth
));
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()));
352 mpLineAttr
->Put(XLineStyleItem(XLINE_NONE
));
357 default : // basegfx::B2DLINEJOIN_NONE
358 mpLineAttr
->Put(XLineJointItem(com::sun::star::drawing::LineJoint_NONE
));
360 case basegfx::B2DLINEJOIN_MIDDLE
:
361 mpLineAttr
->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MIDDLE
));
363 case basegfx::B2DLINEJOIN_BEVEL
:
364 mpLineAttr
->Put(XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL
));
366 case basegfx::B2DLINEJOIN_MITER
:
367 mpLineAttr
->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MITER
));
369 case basegfx::B2DLINEJOIN_ROUND
:
370 mpLineAttr
->Put(XLineJointItem(com::sun::star::drawing::LineJoint_ROUND
));
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
));
383 mpLineAttr
->Put(XLineDashItem(OUString(), XDash(XDASH_RECT
)));
393 if(maVD
.IsFillColor())
395 mpFillAttr
->Put(XFillStyleItem(XFILL_SOLID
));
396 mpFillAttr
->Put(XFillColorItem(OUString(), maVD
.GetFillColor()));
400 mpFillAttr
->Put(XFillStyleItem(XFILL_NONE
));
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
439 pObj
->SetLayer(mnLayer
);
443 pObj
->SetMergedItemSet(*mpLineAttr
);
448 pObj
->SetMergedItemSet(*mpFillAttr
);
453 pObj
->SetMergedItemSet(*mpTextAttr
);
454 pObj
->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT
));
459 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject
* pObj
, bool bScale
)
461 if(bScale
&& !maScaleRect
.IsEmpty())
465 pObj
->NbcResize(Point(), maScaleX
, maScaleY
);
470 pObj
->NbcMove(Size(maOfs
.X(), maOfs
.Y()));
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
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
);
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
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
);
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();
530 InsertObj(pNewClone
, false);
534 OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
538 // cleanup temporary conversion objects
539 SdrObject::Free(pConverted
);
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(
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
,
573 pObj
->SetLayer(aOldLayer
);
574 pObj
->SetMergedItemSet(aOldItemSet
);
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(
600 pObj
->SetMergedItem(XFillStyleItem(XFILL_BITMAP
));
601 pObj
->SetMergedItem(XFillBitmapItem(OUString(), Graphic(aClippedBitmap
)));
602 pObj
->SetMergedItem(XFillBmpTileItem(false));
603 pObj
->SetMergedItem(XFillBmpStretchItem(true));
612 // #i111954# check object for visibility
613 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
614 bool bVisible(false);
616 if(pObj
->HasLineStyle())
621 if(!bVisible
&& pObj
->HasFillStyle())
628 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >(pObj
);
630 if(pTextObj
&& pTextObj
->HasText())
638 SdrGrafObj
* pGrafObj
= dynamic_cast< SdrGrafObj
* >(pObj
);
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
651 SdrObject::Free(pObj
);
655 maTmpList
.push_back(pObj
);
657 if(dynamic_cast< SdrPathObj
* >(pObj
))
659 const bool bClosed(pObj
->IsClosedObj());
661 mbLastObjWasPolyWithoutLine
= mbNoLine
&& bClosed
;
662 mbLastObjWasLine
= !bClosed
;
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
);
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
);
718 maLineJoin
= basegfx::B2DLINEJOIN_NONE
;
720 InsertObj(pPath
, false);
725 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction
& rAct
)
727 SdrRectObj
* pRect
=new SdrRectObj(rAct
.GetRect());
728 SetAttributes(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;
738 SfxItemSet
aSet(*mpLineAttr
->GetPool(), SDRATTR_ECKENRADIUS
, SDRATTR_ECKENRADIUS
, 0, 0);
739 aSet
.Put(SdrEckenradiusItem(nRad
));
740 pRect
->SetMergedItemSet(aSet
);
745 /**************************************************************************************************/
747 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction
& rAct
)
749 SdrCircObj
* pCirc
=new SdrCircObj(OBJ_CIRC
,rAct
.GetRect());
750 SetAttributes(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
);
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
);
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
);
784 /**************************************************************************************************/
786 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon
& rSrcPoly
)
788 // #i102706# Do not merge closed polygons
789 if(rSrcPoly
.isClosed())
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
);
802 if(1L == pLastPoly
->GetPathPoly().count())
805 basegfx::B2DPolygon
aDstPoly(pLastPoly
->GetPathPoly().getB2DPolygon(0L));
807 // #i102706# Do not merge closed polygons
808 if(aDstPoly
.isClosed())
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);
823 else if(aDstPoly
.getB2DPoint(0L) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
825 basegfx::B2DPolygon
aNew(rSrcPoly
);
826 aNew
.append(aDstPoly
, 1L, aDstPoly
.count() - 1L);
830 else if(aDstPoly
.getB2DPoint(0L) == rSrcPoly
.getB2DPoint(0L))
833 aDstPoly
.append(rSrcPoly
, 1L, rSrcPoly
.count() - 1L);
836 else if(aDstPoly
.getB2DPoint(nMaxDstPnt
) == rSrcPoly
.getB2DPoint(nMaxSrcPnt
))
838 basegfx::B2DPolygon
aNew(rSrcPoly
);
840 aDstPoly
.append(aNew
, 1L, aNew
.count() - 1L);
847 pLastPoly
->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly
));
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
);
868 if(pLastPoly
->GetPathPoly() == rPolyPolygon
)
872 if(!mbNoLine
&& mbNoFill
)
874 pLastPoly
->SetMergedItemSet(*mpLineAttr
);
885 void ImpSdrGDIMetaFileImport::checkClip()
887 if(maVD
.IsClipRegion())
889 maClip
= maVD
.GetClipRegion().GetAsB2DPolyPolygon();
893 const basegfx::B2DHomMatrix
aTransform(
894 basegfx::tools::createScaleTranslateB2DHomMatrix(
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());
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
);
948 maLineJoin
= basegfx::B2DLINEJOIN_NONE
;
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());
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());
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
) );
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();
1054 double a
=nWink
*nPi180
;
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
));
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
));
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
));
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
));
1133 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction
& rAct
)
1135 // #i73407# reformulation to use new B2DPolygon classes
1136 basegfx::B2DPolyPolygon
aSource(rAct
.GetPolyPolygon().getB2DPolyPolygon());
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);
1150 switch(rHatch
.GetStyle())
1152 case(HATCH_TRIPLE
) :
1154 eStyle
= XHATCH_TRIPLE
;
1158 case(HATCH_DOUBLE
) :
1160 eStyle
= XHATCH_DOUBLE
;
1166 eStyle
= XHATCH_SINGLE
;
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
)
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);
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());
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
);
1269 aSkipComment
= true;
1275 MetaAction
* pSkipAct
= pMtf
->NextAction();
1278 && ((pSkipAct
->GetType() != META_COMMENT_ACTION
)
1279 || !(((MetaCommentAction
*)pSkipAct
)->GetComment().equalsIgnoreAsciiCase("XGRAD_SEQ_END"))))
1281 pSkipAct
= pMtf
->NextAction();
1286 void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction
& rAct
)
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());
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
));
1310 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction
& rAct
)
1312 Rectangle
aRect(rAct
.GetDestPoint(),rAct
.GetDestSize());
1313 BitmapEx
aBitmapEx(rAct
.GetBitmapEx());
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
));
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
));
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
));
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
));
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(
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(
1414 rGradient
.GetStartColor(),
1415 rGradient
.GetEndColor(),
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());
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());
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(
1483 rGradient
.GetStartColor(),
1484 rGradient
.GetEndColor(),
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
1514 convertMetafileToBitmapEx(
1517 aRect
.Left(), aRect
.Top(),
1518 aRect
.Right(), aRect
.Bottom()),
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);
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;
1561 // 0.0 < transparence < 1.0, apply fixed transparence
1562 bFixedTransparence
= true;
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()));
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
);
1595 // mix existing and new alpha mask
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();
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
));
1634 BitmapReadAccess
* pNew
= aNewMask
.AcquireReadAccess();
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
));
1654 OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1657 aNewMask
.ReleaseAccess(pNew
);
1661 OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1665 aOldMask
.ReleaseAccess(pOld
);
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
));
1690 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */