1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #include "svdfmtf.hxx"
28 #include <editeng/editdata.hxx>
29 #include <math.h>
30 #include <svx/xpoly.hxx>
31 #include <vcl/svapp.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/fhgtitem.hxx>
34 #include <editeng/wghtitem.hxx>
35 #include <editeng/postitem.hxx>
36 #include <editeng/udlnitem.hxx>
37 #include <editeng/crsditem.hxx>
38 #include <editeng/shdditem.hxx>
39 #include <svx/xlnclit.hxx>
40 #include <svx/xlncapit.hxx>
41 #include <svx/xlnwtit.hxx>
42 #include <svx/xflclit.hxx>
43 #include <svx/xgrad.hxx>
44 #include <svx/xflgrit.hxx>
45 #include <editeng/fontitem.hxx>
46 #include <editeng/akrnitem.hxx>
47 #include <editeng/wrlmitem.hxx>
48 #include <editeng/cntritem.hxx>
49 #include <editeng/colritem.hxx>
50 #include <vcl/metric.hxx>
51 #include <editeng/charscaleitem.hxx>
52 #include <svx/xflhtit.hxx>
53 #include <svx/svdattr.hxx>
54 #include <svx/svdmodel.hxx>
55 #include <svx/svdpage.hxx>
56 #include <svx/svdobj.hxx>
57 #include "svx/svditext.hxx"
58 #include <svx/svdotext.hxx>
59 #include <svx/svdorect.hxx>
60 #include <svx/svdocirc.hxx>
61 #include <svx/svdograf.hxx>
62 #include <svx/svdopath.hxx>
63 #include <svx/svdetc.hxx>
64 #include <svl/itemset.hxx>
65 #include <basegfx/polygon/b2dpolygon.hxx>
66 #include <vcl/salbtype.hxx> // FRound
67 #include <basegfx/matrix/b2dhommatrix.hxx>
68 #include <basegfx/matrix/b2dhommatrixtools.hxx>
69 #include <svx/xlinjoit.hxx>
70 #include <svx/xlndsit.hxx>
71 #include <basegfx/polygon/b2dpolygonclipper.hxx>
72 #include <svx/xbtmpit.hxx>
73 #include <svx/xfltrit.hxx>
74 #include <vcl/bmpacc.hxx>
75 #include <svx/xflbmtit.hxx>
76 #include <svx/xflbstit.hxx>
77 #include <svx/svdpntv.hxx>
78 #include <basegfx/polygon/b2dpolypolygontools.hxx>
79 #include <svx/svditer.hxx>
80 #include <svx/svdogrp.hxx>
81
82 ////////////////////////////////////////////////////////////////////////////////////////////////////
83
ImpSdrGDIMetaFileImport(SdrModel & rModel,SdrLayerID nLay,const Rectangle & rRect)84 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(
85 SdrModel& rModel,
86 SdrLayerID nLay,
87 const Rectangle& rRect)
88 : maTmpList(),
89 maVD(),
90 maScaleRect(rRect),
91 mnMapScalingOfs(0),
92 mpLineAttr(0),
93 mpFillAttr(0),
94 mpTextAttr(0),
95 mpModel(&rModel),
96 mnLayer(nLay),
97 maOldLineColor(),
98 mnLineWidth(0),
99 maLineJoin(basegfx::B2DLINEJOIN_NONE),
100 maLineCap(com::sun::star::drawing::LineCap_BUTT),
101 maDash(XDASH_RECT, 0, 0, 0, 0, 0),
102 mbMov(false),
103 mbSize(false),
104 maOfs(0, 0),
105 mfScaleX(1.0),
106 mfScaleY(1.0),
107 maScaleX(1.0),
108 maScaleY(1.0),
109 mbFntDirty(true),
110 mbLastObjWasPolyWithoutLine(false),
111 mbNoLine(false),
112 mbNoFill(false),
113 mbLastObjWasLine(false),
114 maClip()
115 {
116 maVD.EnableOutput(false);
117 maVD.SetLineColor();
118 maVD.SetFillColor();
119 maOldLineColor.SetRed( maVD.GetLineColor().GetRed() + 1 );
120 mpLineAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_LINE_FIRST, XATTR_LINE_LAST, 0, 0);
121 mpFillAttr = new SfxItemSet(rModel.GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
122 mpTextAttr = new SfxItemSet(rModel.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END, 0, 0);
123 checkClip();
124 }
125
~ImpSdrGDIMetaFileImport()126 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
127 {
128 delete mpLineAttr;
129 delete mpFillAttr;
130 delete mpTextAttr;
131 }
132
DoLoopActions(GDIMetaFile & rMtf,SvdProgressInfo * pProgrInfo,sal_uInt32 * pActionsToReport)133 void ImpSdrGDIMetaFileImport::DoLoopActions(GDIMetaFile& rMtf, SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport)
134 {
135 const sal_uLong nCount(rMtf.GetActionCount());
136
137 for(sal_uLong a(0); a < nCount; a++)
138 {
139 MetaAction* pAct = rMtf.GetAction(a);
140
141 if(!pAct)
142 {
143 OSL_ENSURE(false, "OOps, no action at valid position (!)");
144 pAct = rMtf.GetAction(0);
145 }
146
147 switch (pAct->GetType())
148 {
149 case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
150 case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
151 case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
152 case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
153 case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
154 case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
155 case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
156 case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
157 case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
158 case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
159 case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
160 case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
161 case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
162 case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
163 case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
164 case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
165 case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
166 case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
167 case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
168 case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
169 case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
170 case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
171 case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
172 case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
173 case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
174 case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
175 case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
176 case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
177 case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
178 case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
179 case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
180 case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
181 case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
182 case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
183
184 // #i125211# MetaCommentAction may change index, thus hand it over
185 case META_COMMENT_ACTION : DoAction((MetaCommentAction&)*pAct, rMtf, a);
186 break;
187
188 // missing actions added
189 case META_TEXTRECT_ACTION : DoAction((MetaTextRectAction&)*pAct); break;
190 case META_BMPSCALEPART_ACTION : DoAction((MetaBmpScalePartAction&)*pAct); break;
191 case META_BMPEXSCALEPART_ACTION : DoAction((MetaBmpExScalePartAction&)*pAct); break;
192 case META_MASK_ACTION : DoAction((MetaMaskAction&)*pAct); break;
193 case META_MASKSCALE_ACTION : DoAction((MetaMaskScaleAction&)*pAct); break;
194 case META_MASKSCALEPART_ACTION : DoAction((MetaMaskScalePartAction&)*pAct); break;
195 case META_GRADIENT_ACTION : DoAction((MetaGradientAction&)*pAct); break;
196 case META_WALLPAPER_ACTION : DoAction((MetaWallpaperAction&)*pAct); break;
197 case META_TRANSPARENT_ACTION : DoAction((MetaTransparentAction&)*pAct); break;
198 case META_EPS_ACTION : DoAction((MetaEPSAction&)*pAct); break;
199 case META_REFPOINT_ACTION : DoAction((MetaRefPointAction&)*pAct); break;
200 case META_TEXTLINECOLOR_ACTION : DoAction((MetaTextLineColorAction&)*pAct); break;
201 case META_TEXTLINE_ACTION : DoAction((MetaTextLineAction&)*pAct); break;
202 case META_FLOATTRANSPARENT_ACTION : DoAction((MetaFloatTransparentAction&)*pAct); break;
203 case META_GRADIENTEX_ACTION : DoAction((MetaGradientExAction&)*pAct); break;
204 case META_LAYOUTMODE_ACTION : DoAction((MetaLayoutModeAction&)*pAct); break;
205 case META_TEXTLANGUAGE_ACTION : DoAction((MetaTextLanguageAction&)*pAct); break;
206 case META_OVERLINECOLOR_ACTION : DoAction((MetaOverlineColorAction&)*pAct); break;
207 }
208
209 if(pProgrInfo && pActionsToReport)
210 {
211 (*pActionsToReport)++;
212
213 if(*pActionsToReport >= 16) // Alle 16 Action updaten
214 {
215 if(!pProgrInfo->ReportActions(*pActionsToReport))
216 break;
217
218 *pActionsToReport = 0;
219 }
220 }
221 }
222 }
223
DoImport(const GDIMetaFile & rMtf,SdrObjList & rOL,sal_uInt32 nInsPos,SvdProgressInfo * pProgrInfo)224 sal_uInt32 ImpSdrGDIMetaFileImport::DoImport(
225 const GDIMetaFile& rMtf,
226 SdrObjList& rOL,
227 sal_uInt32 nInsPos,
228 SvdProgressInfo* pProgrInfo)
229 {
230 // setup some global scale parameter
231 // mfScaleX, mfScaleY, maScaleX, maScaleY, mbMov, mbSize
232 mfScaleX = mfScaleY = 1.0;
233 const Size aMtfSize(rMtf.GetPrefSize());
234
235 if(aMtfSize.Width() & aMtfSize.Height() && (!maScaleRect.IsEmpty()))
236 {
237 maOfs = maScaleRect.TopLeft();
238
239 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
240 {
241 mfScaleX = (double)( maScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
242 }
243
244 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
245 {
246 mfScaleY = (double)( maScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
247 }
248 }
249
250 mbMov = maOfs.X()!=0 || maOfs.Y()!=0;
251 mbSize = false;
252 maScaleX = Fraction( 1, 1 );
253 maScaleY = Fraction( 1, 1 );
254
255 if(aMtfSize.Width() != (maScaleRect.GetWidth() - 1))
256 {
257 maScaleX = Fraction(maScaleRect.GetWidth() - 1, aMtfSize.Width());
258 mbSize = true;
259 }
260
261 if(aMtfSize.Height() != (maScaleRect.GetHeight() - 1))
262 {
263 maScaleY = Fraction(maScaleRect.GetHeight() - 1, aMtfSize.Height());
264 mbSize = true;
265 }
266
267 if(pProgrInfo)
268 {
269 pProgrInfo->SetActionCount(rMtf.GetActionCount());
270 }
271
272 sal_uInt32 nActionsToReport(0);
273
274 // execute
275 DoLoopActions(const_cast< GDIMetaFile& >(rMtf), pProgrInfo, &nActionsToReport);
276
277 if(pProgrInfo)
278 {
279 pProgrInfo->ReportActions(nActionsToReport);
280 nActionsToReport = 0;
281 }
282
283 // MapMode-Scaling vornehmen
284 MapScaling();
285
286 // Beim berechnen der Fortschrittsanzeige wird GetActionCount()*3 benutzt.
287 // Da in maTmpList allerdings weniger eintraege als GetActionCount()
288 // existieren koennen, muessen hier die zuviel vermuteten Actionen wieder
289 // hinzugefuegt werden.
290 nActionsToReport = (rMtf.GetActionCount() - maTmpList.size()) * 2;
291
292 // Alle noch nicht gemeldeten Rescales melden
293 if(pProgrInfo)
294 {
295 pProgrInfo->ReportRescales(nActionsToReport);
296 pProgrInfo->SetInsertCount(maTmpList.size());
297 }
298
299 nActionsToReport = 0;
300
301 // alle in maTmpList zwischengespeicherten Objekte nun in rOL ab der Position nInsPos einfuegen
302 if(nInsPos > rOL.GetObjCount())
303 {
304 nInsPos = rOL.GetObjCount();
305 }
306
307 SdrInsertReason aReason(SDRREASON_VIEWCALL);
308
309 for(sal_uInt32 i(0); i < maTmpList.size(); i++)
310 {
311 SdrObject* pObj = maTmpList[i];
312 rOL.NbcInsertObject(pObj, nInsPos, &aReason);
313 nInsPos++;
314
315 if(pProgrInfo)
316 {
317 nActionsToReport++;
318
319 if(nActionsToReport >= 32) // Alle 32 Action updaten
320 {
321 pProgrInfo->ReportInserts(nActionsToReport);
322 nActionsToReport = 0;
323 }
324 }
325 }
326
327 // ein letztesmal alle verbliebennen Inserts reporten
328 if(pProgrInfo)
329 {
330 pProgrInfo->ReportInserts(nActionsToReport);
331 }
332
333 return maTmpList.size();
334 }
335
SetAttributes(SdrObject * pObj,bool bForceTextAttr)336 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
337 {
338 mbNoLine = false;
339 mbNoFill = false;
340 bool bLine(!bForceTextAttr);
341 bool bFill(!pObj || (pObj->IsClosedObj() && !bForceTextAttr));
342 bool bText(bForceTextAttr || (pObj && pObj->GetOutlinerParaObject()));
343
344 if(bLine)
345 {
346 if(mnLineWidth)
347 {
348 mpLineAttr->Put(XLineWidthItem(mnLineWidth));
349 }
350 else
351 {
352 mpLineAttr->Put(XLineWidthItem(0));
353 }
354
355 maOldLineColor = maVD.GetLineColor();
356
357 if(maVD.IsLineColor())
358 {
359 mpLineAttr->Put(XLineStyleItem(XLINE_SOLID));
360 mpLineAttr->Put(XLineColorItem(String(), maVD.GetLineColor()));
361 }
362 else
363 {
364 mpLineAttr->Put(XLineStyleItem(XLINE_NONE));
365 }
366
367 switch(maLineJoin)
368 {
369 default : // basegfx::B2DLINEJOIN_NONE
370 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_NONE));
371 break;
372 case basegfx::B2DLINEJOIN_MIDDLE:
373 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MIDDLE));
374 break;
375 case basegfx::B2DLINEJOIN_BEVEL:
376 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL));
377 break;
378 case basegfx::B2DLINEJOIN_MITER:
379 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_MITER));
380 break;
381 case basegfx::B2DLINEJOIN_ROUND:
382 mpLineAttr->Put(XLineJointItem(com::sun::star::drawing::LineJoint_ROUND));
383 break;
384 }
385
386 // Add LineCap support
387 mpLineAttr->Put(XLineCapItem(maLineCap));
388
389 if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
390 {
391 mpLineAttr->Put(XLineDashItem(String(), maDash));
392 }
393 else
394 {
395 mpLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
396 }
397 }
398 else
399 {
400 mbNoLine = true;
401 }
402
403 if(bFill)
404 {
405 if(maVD.IsFillColor())
406 {
407 mpFillAttr->Put(XFillStyleItem(XFILL_SOLID));
408 mpFillAttr->Put(XFillColorItem(String(), maVD.GetFillColor()));
409 }
410 else
411 {
412 mpFillAttr->Put(XFillStyleItem(XFILL_NONE));
413 }
414 }
415 else
416 {
417 mbNoFill = true;
418 }
419
420 if(bText && mbFntDirty)
421 {
422 Font aFnt(maVD.GetFont());
423 const sal_uInt32 nHeight(FRound(aFnt.GetSize().Height() * mfScaleY));
424
425 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
426 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
427 mpTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
428 mpTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
429 mpTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
430 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
431 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
432 mpTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
433 mpTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
434 mpTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
435 mpTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
436 mpTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
437 mpTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
438
439 // #i118485# Setting this item leads to problems (written #i118498# for this)
440 // mpTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
441
442 mpTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
443 mpTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
444 mpTextAttr->Put(SvxColorItem(maVD.GetTextColor(), EE_CHAR_COLOR));
445 //... svxfont textitem svditext
446 mbFntDirty = false;
447 }
448
449 if(pObj)
450 {
451 pObj->SetLayer(mnLayer);
452
453 if(bLine)
454 {
455 pObj->SetMergedItemSet(*mpLineAttr);
456 }
457
458 if(bFill)
459 {
460 pObj->SetMergedItemSet(*mpFillAttr);
461 }
462
463 if(bText)
464 {
465 pObj->SetMergedItemSet(*mpTextAttr);
466 pObj->SetMergedItem(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
467 }
468 }
469 }
470
InsertObj(SdrObject * pObj,bool bScale)471 void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj, bool bScale)
472 {
473 if(bScale && !maScaleRect.IsEmpty())
474 {
475 if(mbSize)
476 {
477 pObj->NbcResize(Point(), maScaleX, maScaleY);
478 }
479
480 if(mbMov)
481 {
482 pObj->NbcMove(Size(maOfs.X(), maOfs.Y()));
483 }
484 }
485
486 if(isClip())
487 {
488 const basegfx::B2DPolyPolygon aPoly(pObj->TakeXorPoly());
489 const basegfx::B2DRange aOldRange(aPoly.getB2DRange());
490 const SdrLayerID aOldLayer(pObj->GetLayer());
491 const SfxItemSet aOldItemSet(pObj->GetMergedItemSet());
492 const SdrGrafObj* pSdrGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
493 const SdrTextObj* pSdrTextObj = dynamic_cast< SdrTextObj* >(pObj);
494
495 if(pSdrTextObj && pSdrTextObj->HasText())
496 {
497 // all text objects are created from ImportText and have no line or fill attributes, so
498 // it is okay to concentrate on the text itself
499 while(true)
500 {
501 const basegfx::B2DPolyPolygon aTextContour(pSdrTextObj->TakeContour());
502 const basegfx::B2DRange aTextRange(aTextContour.getB2DRange());
503 const basegfx::B2DRange aClipRange(maClip.getB2DRange());
504
505 // no overlap -> completely outside
506 if(!aClipRange.overlaps(aTextRange))
507 {
508 SdrObject::Free(pObj);
509 break;
510 }
511
512 // when the clip is a rectangle fast check for inside is possible
513 if(basegfx::tools::isRectangle(maClip) && aClipRange.isInside(aTextRange))
514 {
515 // completely inside ClipRect
516 break;
517 }
518
519 // here text needs to be clipped; to do so, convert to SdrObjects with polygons
520 // and add these recursively. Delete original object, do not add in this run
521 SdrObject* pConverted = pSdrTextObj->ConvertToPolyObj(true, true);
522 SdrObject::Free(pObj);
523
524 if(pConverted)
525 {
526 // recursively add created conversion; per definition this shall not
527 // contain further SdrTextObjs. Visit only non-group objects
528 SdrObjListIter aIter(*pConverted, IM_DEEPNOGROUPS);
529
530 // work with clones; the created conversion may contain group objects
531 // and when working with the original objects the loop itself could
532 // break and the cleanup later would be pretty complicated (only delete group
533 // objects, are these empty, ...?)
534 while(aIter.IsMore())
535 {
536 SdrObject* pCandidate = aIter.Next();
537 OSL_ENSURE(pCandidate && 0 == dynamic_cast< SdrObjGroup* >(pCandidate), "SdrObjListIter with IM_DEEPNOGROUPS error (!)");
538 SdrObject* pNewClone = pCandidate->Clone();
539
540 if(pNewClone)
541 {
542 InsertObj(pNewClone, false);
543 }
544 else
545 {
546 OSL_ENSURE(false, "SdrObject::Clone() failed (!)");
547 }
548 }
549
550 // cleanup temporary conversion objects
551 SdrObject::Free(pConverted);
552 }
553
554 break;
555 }
556 }
557 else
558 {
559 BitmapEx aBitmapEx;
560
561 if(pSdrGrafObj)
562 {
563 aBitmapEx = pSdrGrafObj->GetGraphic().GetBitmapEx();
564 }
565
566 SdrObject::Free(pObj);
567
568 if(!aOldRange.isEmpty())
569 {
570 // clip against ClipRegion
571 const basegfx::B2DPolyPolygon aNewPoly(
572 basegfx::tools::clipPolyPolygonOnPolyPolygon(
573 aPoly,
574 maClip,
575 true,
576 aPoly.isClosed() ? false : true));
577 const basegfx::B2DRange aNewRange(aNewPoly.getB2DRange());
578
579 if(!aNewRange.isEmpty())
580 {
581 pObj = new SdrPathObj(
582 aNewPoly.isClosed() ? OBJ_POLY : OBJ_PLIN,
583 aNewPoly);
584
585 pObj->SetLayer(aOldLayer);
586 pObj->SetMergedItemSet(aOldItemSet);
587
588 if(!!aBitmapEx)
589 {
590 // aNewRange is inside of aOldRange and defines which part of aBitmapEx is used
591 const double fScaleX(aBitmapEx.GetSizePixel().Width() / (aOldRange.getWidth() ? aOldRange.getWidth() : 1.0));
592 const double fScaleY(aBitmapEx.GetSizePixel().Height() / (aOldRange.getHeight() ? aOldRange.getHeight() : 1.0));
593 basegfx::B2DRange aPixel(aNewRange);
594 basegfx::B2DHomMatrix aTrans;
595
596 aTrans.translate(-aOldRange.getMinX(), -aOldRange.getMinY());
597 aTrans.scale(fScaleX, fScaleY);
598 aPixel.transform(aTrans);
599
600 const Size aOrigSizePixel(aBitmapEx.GetSizePixel());
601 const Point aClipTopLeft(
602 basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))),
603 basegfx::fround(floor(std::max(0.0, aPixel.getMinY()))));
604 const Size aClipSize(
605 basegfx::fround(ceil(std::min((double)aOrigSizePixel.Width(), aPixel.getWidth()))),
606 basegfx::fround(ceil(std::min((double)aOrigSizePixel.Height(), aPixel.getHeight()))));
607 const BitmapEx aClippedBitmap(
608 aBitmapEx,
609 aClipTopLeft,
610 aClipSize);
611
612 pObj->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
613 pObj->SetMergedItem(XFillBitmapItem(String(), Graphic(aClippedBitmap)));
614 pObj->SetMergedItem(XFillBmpTileItem(false));
615 pObj->SetMergedItem(XFillBmpStretchItem(true));
616 }
617 }
618 }
619 }
620 }
621
622 if(pObj)
623 {
624 // #i111954# check object for visibility
625 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
626 bool bVisible(false);
627
628 if(pObj->HasLineStyle())
629 {
630 bVisible = true;
631 }
632
633 if(!bVisible && pObj->HasFillStyle())
634 {
635 bVisible = true;
636 }
637
638 if(!bVisible)
639 {
640 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
641
642 if(pTextObj && pTextObj->HasText())
643 {
644 bVisible = true;
645 }
646 }
647
648 if(!bVisible)
649 {
650 SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
651
652 if(pGrafObj)
653 {
654 // this may be refined to check if the graphic really is visible. It
655 // is here to ensure that graphic objects without fill, line and text
656 // get created
657 bVisible = true;
658 }
659 }
660
661 if(!bVisible)
662 {
663 SdrObject::Free(pObj);
664 }
665 else
666 {
667 maTmpList.push_back(pObj);
668
669 if(dynamic_cast< SdrPathObj* >(pObj))
670 {
671 const bool bClosed(pObj->IsClosedObj());
672
673 mbLastObjWasPolyWithoutLine = mbNoLine && bClosed;
674 mbLastObjWasLine = !bClosed;
675 }
676 else
677 {
678 mbLastObjWasPolyWithoutLine = false;
679 mbLastObjWasLine = false;
680 }
681 }
682 }
683 }
684
685 /**************************************************************************************************/
686
DoAction(MetaPixelAction &)687 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/)
688 {
689 }
690
DoAction(MetaPointAction &)691 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/)
692 {
693 }
694
DoAction(MetaLineAction & rAct)695 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
696 {
697 // #i73407# reformulation to use new B2DPolygon classes
698 const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
699 const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
700
701 if(!aStart.equal(aEnd))
702 {
703 basegfx::B2DPolygon aLine;
704 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
705
706 aLine.append(aStart);
707 aLine.append(aEnd);
708 aLine.transform(aTransform);
709
710 const LineInfo& rLineInfo = rAct.GetLineInfo();
711 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
712 bool bCreateLineObject(true);
713
714 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aLine))
715 {
716 bCreateLineObject = false;
717 }
718
719 if(bCreateLineObject)
720 {
721 SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
722 mnLineWidth = nNewLineWidth;
723 maLineJoin = rLineInfo.GetLineJoin();
724 maLineCap = rLineInfo.GetLineCap();
725 maDash = XDash(XDASH_RECT,
726 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
727 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
728 rLineInfo.GetDistance());
729 SetAttributes(pPath);
730 mnLineWidth = 0;
731 maLineJoin = basegfx::B2DLINEJOIN_NONE;
732 maDash = XDash();
733 InsertObj(pPath, false);
734 }
735 }
736 }
737
DoAction(MetaRectAction & rAct)738 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
739 {
740 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
741 SetAttributes(pRect);
742 InsertObj(pRect);
743 }
744
DoAction(MetaRoundRectAction & rAct)745 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
746 {
747 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
748 SetAttributes(pRect);
749 long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
750 if (nRad!=0) {
751 SfxItemSet aSet(*mpLineAttr->GetPool(), SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, 0, 0);
752 aSet.Put(SdrEckenradiusItem(nRad));
753 pRect->SetMergedItemSet(aSet);
754 }
755 InsertObj(pRect);
756 }
757
758 /**************************************************************************************************/
759
DoAction(MetaEllipseAction & rAct)760 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
761 {
762 SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
763 SetAttributes(pCirc);
764 InsertObj(pCirc);
765 }
766
DoAction(MetaArcAction & rAct)767 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
768 {
769 Point aCenter(rAct.GetRect().Center());
770 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
771 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
772 SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
773 SetAttributes(pCirc);
774 InsertObj(pCirc);
775 }
776
DoAction(MetaPieAction & rAct)777 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
778 {
779 Point aCenter(rAct.GetRect().Center());
780 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
781 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
782 SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
783 SetAttributes(pCirc);
784 InsertObj(pCirc);
785 }
786
DoAction(MetaChordAction & rAct)787 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
788 {
789 Point aCenter(rAct.GetRect().Center());
790 long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
791 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
792 SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
793 SetAttributes(pCirc);
794 InsertObj(pCirc);
795 }
796
797 /**************************************************************************************************/
798
CheckLastLineMerge(const basegfx::B2DPolygon & rSrcPoly)799 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
800 {
801 // #i102706# Do not merge closed polygons
802 if(rSrcPoly.isClosed())
803 {
804 return false;
805 }
806
807 // #i73407# reformulation to use new B2DPolygon classes
808 if(mbLastObjWasLine && (maOldLineColor == maVD.GetLineColor()) && rSrcPoly.count())
809 {
810 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
811 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
812
813 if(pLastPoly)
814 {
815 if(1L == pLastPoly->GetPathPoly().count())
816 {
817 bool bOk(false);
818 basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
819
820 // #i102706# Do not merge closed polygons
821 if(aDstPoly.isClosed())
822 {
823 return false;
824 }
825
826 if(aDstPoly.count())
827 {
828 const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
829 const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
830
831 if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
832 {
833 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
834 bOk = true;
835 }
836 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
837 {
838 basegfx::B2DPolygon aNew(rSrcPoly);
839 aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
840 aDstPoly = aNew;
841 bOk = true;
842 }
843 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
844 {
845 aDstPoly.flip();
846 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
847 bOk = true;
848 }
849 else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
850 {
851 basegfx::B2DPolygon aNew(rSrcPoly);
852 aNew.flip();
853 aDstPoly.append(aNew, 1L, aNew.count() - 1L);
854 bOk = true;
855 }
856 }
857
858 if(bOk)
859 {
860 pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
861 }
862
863 return bOk;
864 }
865 }
866 }
867
868 return false;
869 }
870
CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)871 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
872 {
873 // #i73407# reformulation to use new B2DPolygon classes
874 if(mbLastObjWasPolyWithoutLine)
875 {
876 SdrObject* pTmpObj = maTmpList.size() ? maTmpList[maTmpList.size() - 1] : 0;
877 SdrPathObj* pLastPoly = dynamic_cast< SdrPathObj* >(pTmpObj);
878
879 if(pLastPoly)
880 {
881 if(pLastPoly->GetPathPoly() == rPolyPolygon)
882 {
883 SetAttributes(NULL);
884
885 if(!mbNoLine && mbNoFill)
886 {
887 pLastPoly->SetMergedItemSet(*mpLineAttr);
888
889 return true;
890 }
891 }
892 }
893 }
894
895 return false;
896 }
897
checkClip()898 void ImpSdrGDIMetaFileImport::checkClip()
899 {
900 if(maVD.IsClipRegion())
901 {
902 maClip = maVD.GetClipRegion().GetAsB2DPolyPolygon();
903
904 if(isClip())
905 {
906 const basegfx::B2DHomMatrix aTransform(
907 basegfx::tools::createScaleTranslateB2DHomMatrix(
908 mfScaleX,
909 mfScaleY,
910 maOfs.X(),
911 maOfs.Y()));
912
913 maClip.transform(aTransform);
914 }
915 }
916 }
917
isClip() const918 bool ImpSdrGDIMetaFileImport::isClip() const
919 {
920 return !maClip.getB2DRange().isEmpty();
921 }
922
DoAction(MetaPolyLineAction & rAct)923 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
924 {
925 // #i73407# reformulation to use new B2DPolygon classes
926 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
927
928 if(aSource.count())
929 {
930 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
931 aSource.transform(aTransform);
932 }
933
934 const LineInfo& rLineInfo = rAct.GetLineInfo();
935 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
936 bool bCreateLineObject(true);
937
938 if(mbLastObjWasLine && (nNewLineWidth == mnLineWidth) && CheckLastLineMerge(aSource))
939 {
940 bCreateLineObject = false;
941 }
942 else if(mbLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
943 {
944 bCreateLineObject = false;
945 }
946
947 if(bCreateLineObject)
948 {
949 SdrPathObj* pPath = new SdrPathObj(
950 aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
951 basegfx::B2DPolyPolygon(aSource));
952 mnLineWidth = nNewLineWidth;
953 maLineJoin = rLineInfo.GetLineJoin();
954 maLineCap = rLineInfo.GetLineCap();
955 maDash = XDash(XDASH_RECT,
956 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
957 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
958 rLineInfo.GetDistance());
959 SetAttributes(pPath);
960 mnLineWidth = 0;
961 maLineJoin = basegfx::B2DLINEJOIN_NONE;
962 maDash = XDash();
963 InsertObj(pPath, false);
964 }
965 }
966
DoAction(MetaPolygonAction & rAct)967 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
968 {
969 // #i73407# reformulation to use new B2DPolygon classes
970 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
971
972 if(aSource.count())
973 {
974 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
975 aSource.transform(aTransform);
976
977 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
978 {
979 // #i73407# make sure polygon is closed, it's a filled primitive
980 aSource.setClosed(true);
981 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
982 SetAttributes(pPath);
983 InsertObj(pPath, false);
984 }
985 }
986 }
987
DoAction(MetaPolyPolygonAction & rAct)988 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
989 {
990 // #i73407# reformulation to use new B2DPolygon classes
991 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
992
993 if(aSource.count())
994 {
995 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
996 aSource.transform(aTransform);
997
998 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
999 {
1000 // #i73407# make sure polygon is closed, it's a filled primitive
1001 aSource.setClosed(true);
1002 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1003 SetAttributes(pPath);
1004 InsertObj(pPath, false);
1005 }
1006 }
1007 }
1008
1009 /**************************************************************************************************/
1010
ImportText(const Point & rPos,const XubString & rStr,const MetaAction & rAct)1011 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
1012 {
1013 // calc text box size, add 5% to make it fit safely
1014
1015 FontMetric aFontMetric( maVD.GetFontMetric() );
1016 Font aFnt( maVD.GetFont() );
1017 FontAlign eAlg( aFnt.GetAlign() );
1018
1019 sal_Int32 nTextWidth = (sal_Int32)( maVD.GetTextWidth( rStr ) * mfScaleX );
1020 sal_Int32 nTextHeight = (sal_Int32)( maVD.GetTextHeight() * mfScaleY );
1021 //sal_Int32 nDxWidth = 0;
1022 //sal_Int32 nLen = rStr.Len();
1023
1024 Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) );
1025 Size aSize( nTextWidth, nTextHeight );
1026
1027 if ( eAlg == ALIGN_BASELINE )
1028 aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
1029 else if ( eAlg == ALIGN_BOTTOM )
1030 aPos.Y() -= nTextHeight;
1031
1032 Rectangle aTextRect( aPos, aSize );
1033 SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
1034
1035 pText->SetMergedItem ( SdrTextUpperDistItem (0));
1036 pText->SetMergedItem ( SdrTextLowerDistItem (0));
1037 pText->SetMergedItem ( SdrTextRightDistItem (0));
1038 pText->SetMergedItem ( SdrTextLeftDistItem (0));
1039
1040 if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
1041 {
1042 pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
1043 pText->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
1044 // don't let the margins eat the space needed for the text
1045 pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
1046 }
1047 else
1048 {
1049 pText->SetMergedItem( SdrTextAutoGrowWidthItem( true ) );
1050 }
1051
1052 pText->SetModel(mpModel);
1053 pText->SetLayer(mnLayer);
1054 pText->NbcSetText( rStr );
1055 SetAttributes( pText, true );
1056 pText->SetSnapRect( aTextRect );
1057
1058 if (!aFnt.IsTransparent())
1059 {
1060 SfxItemSet aAttr(*mpFillAttr->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0, 0);
1061 aAttr.Put(XFillStyleItem(XFILL_SOLID));
1062 aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
1063 pText->SetMergedItemSet(aAttr);
1064 }
1065 sal_uInt32 nWink = aFnt.GetOrientation();
1066 if ( nWink )
1067 {
1068 nWink*=10;
1069 double a=nWink*nPi180;
1070 double nSin=sin(a);
1071 double nCos=cos(a);
1072 pText->NbcRotate(aPos,nWink,nSin,nCos);
1073 }
1074 InsertObj( pText, false );
1075 }
1076
DoAction(MetaTextAction & rAct)1077 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
1078 {
1079 XubString aStr(rAct.GetText());
1080 aStr.Erase(0,rAct.GetIndex());
1081 aStr.Erase(rAct.GetLen());
1082 ImportText( rAct.GetPoint(), aStr, rAct );
1083 }
1084
DoAction(MetaTextArrayAction & rAct)1085 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
1086 {
1087 XubString aStr(rAct.GetText());
1088 aStr.Erase(0,rAct.GetIndex());
1089 aStr.Erase(rAct.GetLen());
1090 ImportText( rAct.GetPoint(), aStr, rAct );
1091 }
1092
DoAction(MetaStretchTextAction & rAct)1093 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
1094 {
1095 XubString aStr(rAct.GetText());
1096 aStr.Erase(0,rAct.GetIndex());
1097 aStr.Erase(rAct.GetLen());
1098 ImportText( rAct.GetPoint(), aStr, rAct );
1099 }
1100
DoAction(MetaBmpAction & rAct)1101 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
1102 {
1103 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
1104 aRect.Right()++; aRect.Bottom()++;
1105 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1106
1107 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1108 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1109 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1110 InsertObj(pGraf);
1111 }
1112
DoAction(MetaBmpScaleAction & rAct)1113 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
1114 {
1115 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1116 aRect.Right()++; aRect.Bottom()++;
1117 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
1118
1119 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1120 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1121 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1122 InsertObj(pGraf);
1123 }
1124
DoAction(MetaBmpExAction & rAct)1125 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
1126 {
1127 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
1128 aRect.Right()++; aRect.Bottom()++;
1129 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1130
1131 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1132 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1133 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1134 InsertObj(pGraf);
1135 }
1136
DoAction(MetaBmpExScaleAction & rAct)1137 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
1138 {
1139 Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1140 aRect.Right()++; aRect.Bottom()++;
1141 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
1142
1143 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1144 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1145 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1146 InsertObj(pGraf);
1147 }
1148
1149 ////////////////////////////////////////////////////////////////////////////////////////////////////
1150
DoAction(MetaHatchAction & rAct)1151 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
1152 {
1153 // #i73407# reformulation to use new B2DPolygon classes
1154 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1155
1156 if(aSource.count())
1157 {
1158 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1159 aSource.transform(aTransform);
1160
1161 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1162 {
1163 const Hatch& rHatch = rAct.GetHatch();
1164 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1165 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1166 SfxItemSet aHatchAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1167 XHatchStyle eStyle;
1168
1169 switch(rHatch.GetStyle())
1170 {
1171 case(HATCH_TRIPLE) :
1172 {
1173 eStyle = XHATCH_TRIPLE;
1174 break;
1175 }
1176
1177 case(HATCH_DOUBLE) :
1178 {
1179 eStyle = XHATCH_DOUBLE;
1180 break;
1181 }
1182
1183 default:
1184 {
1185 eStyle = XHATCH_SINGLE;
1186 break;
1187 }
1188 }
1189
1190 SetAttributes(pPath);
1191 aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
1192 aHatchAttr.Put(XFillHatchItem(&mpModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
1193 pPath->SetMergedItemSet(aHatchAttr);
1194
1195 InsertObj(pPath, false);
1196 }
1197 }
1198 }
1199
1200 ////////////////////////////////////////////////////////////////////////////////////////////////////
1201
DoAction(MetaLineColorAction & rAct)1202 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
1203 {
1204 rAct.Execute(&maVD);
1205 }
1206
DoAction(MetaMapModeAction & rAct)1207 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
1208 {
1209 MapScaling();
1210 rAct.Execute(&maVD);
1211 mbLastObjWasPolyWithoutLine = false;
1212 mbLastObjWasLine = false;
1213 }
1214
MapScaling()1215 void ImpSdrGDIMetaFileImport::MapScaling()
1216 {
1217 const sal_uInt32 nAnz(maTmpList.size());
1218 sal_uInt32 i(0);
1219 const MapMode& rMap = maVD.GetMapMode();
1220 Point aMapOrg( rMap.GetOrigin() );
1221 bool bMov2(aMapOrg.X() != 0 || aMapOrg.Y() != 0);
1222
1223 if(bMov2)
1224 {
1225 for(i = mnMapScalingOfs; i < nAnz; i++)
1226 {
1227 SdrObject* pObj = maTmpList[i];
1228
1229 pObj->NbcMove(Size(aMapOrg.X(), aMapOrg.Y()));
1230 }
1231 }
1232
1233 mnMapScalingOfs = nAnz;
1234 }
1235
1236 ////////////////////////////////////////////////////////////////////////////////////////////////////
1237
DoAction(MetaCommentAction & rAct,GDIMetaFile & rMtf,sal_uLong & a)1238 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile& rMtf, sal_uLong& a) // GDIMetaFile* pMtf )
1239 {
1240 ByteString aSkipComment;
1241
1242 if( a < rMtf.GetActionCount() && rAct.GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL )
1243 {
1244 // #i125211# Check if next action is a MetaGradientExAction
1245 MetaGradientExAction* pAct = dynamic_cast< MetaGradientExAction* >(rMtf.GetAction(a + 1));
1246
1247 if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
1248 {
1249 // #i73407# reformulation to use new B2DPolygon classes
1250 basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
1251
1252 if(aSource.count())
1253 {
1254 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1255 {
1256 const Gradient& rGrad = pAct->GetGradient();
1257 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1258 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1259 SfxItemSet aGradAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1260 XGradient aXGradient;
1261
1262 aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
1263 aXGradient.SetStartColor(rGrad.GetStartColor());
1264 aXGradient.SetEndColor(rGrad.GetEndColor());
1265 aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle());
1266 aXGradient.SetBorder(rGrad.GetBorder());
1267 aXGradient.SetXOffset(rGrad.GetOfsX());
1268 aXGradient.SetYOffset(rGrad.GetOfsY());
1269 aXGradient.SetStartIntens(rGrad.GetStartIntensity());
1270 aXGradient.SetEndIntens(rGrad.GetEndIntensity());
1271 aXGradient.SetSteps(rGrad.GetSteps());
1272
1273 // no need to use SetAttributes(..) here since line and fill style
1274 // need to be set individually
1275 // SetAttributes(pPath);
1276
1277 // switch line off; when there was one there will be a
1278 // META_POLYLINE_ACTION following creating another object
1279 aGradAttr.Put(XLineStyleItem(XLINE_NONE));
1280
1281 // add detected gradient fillstyle
1282 aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
1283 aGradAttr.Put(XFillGradientItem(&mpModel->GetItemPool(), aXGradient));
1284
1285 pPath->SetMergedItemSet(aGradAttr);
1286
1287 InsertObj(pPath);
1288 }
1289 }
1290
1291 aSkipComment = "XGRAD_SEQ_END";
1292 }
1293 }
1294
1295 if(aSkipComment.Len())
1296 {
1297 // #i125211# forward until closing MetaCommentAction
1298 MetaAction* pSkipAct = rMtf.GetAction(++a);
1299
1300 while( pSkipAct
1301 && ((pSkipAct->GetType() != META_COMMENT_ACTION )
1302 || (((MetaCommentAction*)pSkipAct)->GetComment().CompareIgnoreCaseToAscii(aSkipComment.GetBuffer()) != COMPARE_EQUAL)))
1303 {
1304 pSkipAct = rMtf.GetAction(++a);
1305 }
1306 }
1307 }
1308
1309 ////////////////////////////////////////////////////////////////////////////////////////////////////
1310
DoAction(MetaTextRectAction & rAct)1311 void ImpSdrGDIMetaFileImport::DoAction(MetaTextRectAction& rAct)
1312 {
1313 GDIMetaFile aTemp;
1314
1315 maVD.AddTextRectActions(rAct.GetRect(), rAct.GetText(), rAct.GetStyle(), aTemp);
1316 DoLoopActions(aTemp, 0, 0);
1317 }
1318
DoAction(MetaBmpScalePartAction & rAct)1319 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScalePartAction& rAct)
1320 {
1321 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1322 Bitmap aBitmap(rAct.GetBitmap());
1323
1324 aRect.Right()++;
1325 aRect.Bottom()++;
1326 aBitmap.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1327 SdrGrafObj* pGraf = new SdrGrafObj(aBitmap, aRect);
1328
1329 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1330 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1331 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1332 InsertObj(pGraf);
1333 }
1334
DoAction(MetaBmpExScalePartAction & rAct)1335 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScalePartAction& rAct)
1336 {
1337 Rectangle aRect(rAct.GetDestPoint(),rAct.GetDestSize());
1338 BitmapEx aBitmapEx(rAct.GetBitmapEx());
1339
1340 aRect.Right()++;
1341 aRect.Bottom()++;
1342 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1343 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1344
1345 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1346 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1347 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1348 InsertObj(pGraf);
1349 }
1350
DoAction(MetaMaskAction & rAct)1351 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskAction& rAct)
1352 {
1353 Rectangle aRect(rAct.GetPoint(), rAct.GetBitmap().GetSizePixel());
1354 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1355
1356 aRect.Right()++; aRect.Bottom()++;
1357 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1358
1359 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1360 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1361 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1362 InsertObj(pGraf);
1363 }
1364
DoAction(MetaMaskScaleAction & rAct)1365 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScaleAction& rAct)
1366 {
1367 Rectangle aRect(rAct.GetPoint(), rAct.GetSize());
1368 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1369
1370 aRect.Right()++; aRect.Bottom()++;
1371 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1372
1373 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1374 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1375 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1376 InsertObj(pGraf);
1377 }
1378
DoAction(MetaMaskScalePartAction & rAct)1379 void ImpSdrGDIMetaFileImport::DoAction(MetaMaskScalePartAction& rAct)
1380 {
1381 Rectangle aRect(rAct.GetDestPoint(), rAct.GetDestSize());
1382 BitmapEx aBitmapEx(rAct.GetBitmap(), rAct.GetColor());
1383
1384 aRect.Right()++; aRect.Bottom()++;
1385 aBitmapEx.Crop(Rectangle(rAct.GetSrcPoint(), rAct.GetSrcSize()));
1386 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1387
1388 // This action is not creating line and fill, set directly, do not use SetAttributes(..)
1389 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1390 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1391 InsertObj(pGraf);
1392 }
1393
getXGradientStyleFromGradientStyle(const GradientStyle & rGradientStyle)1394 XGradientStyle getXGradientStyleFromGradientStyle(const GradientStyle& rGradientStyle)
1395 {
1396 XGradientStyle aXGradientStyle(XGRAD_LINEAR);
1397
1398 switch(rGradientStyle)
1399 {
1400 case GRADIENT_LINEAR: aXGradientStyle = XGRAD_LINEAR; break;
1401 case GRADIENT_AXIAL: aXGradientStyle = XGRAD_AXIAL; break;
1402 case GRADIENT_RADIAL: aXGradientStyle = XGRAD_RADIAL; break;
1403 case GRADIENT_ELLIPTICAL: aXGradientStyle = XGRAD_ELLIPTICAL; break;
1404 case GRADIENT_SQUARE: aXGradientStyle = XGRAD_SQUARE; break;
1405 case GRADIENT_RECT: aXGradientStyle = XGRAD_RECT; break;
1406
1407 // Needed due to GRADIENT_FORCE_EQUAL_SIZE; this again is needed
1408 // to force the enum defines in VCL to a defined size for the compilers,
1409 // so despite it is never used it cannot be removed (would break the
1410 // API implementation probably).
1411 default: break;
1412 }
1413
1414 return aXGradientStyle;
1415 }
1416
DoAction(MetaGradientAction & rAct)1417 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction& rAct)
1418 {
1419 basegfx::B2DRange aRange(rAct.GetRect().Left(), rAct.GetRect().Top(), rAct.GetRect().Right(), rAct.GetRect().Bottom());
1420
1421 if(!aRange.isEmpty())
1422 {
1423 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1424 aRange.transform(aTransform);
1425 const Gradient& rGradient = rAct.GetGradient();
1426 SdrRectObj* pRect = new SdrRectObj(
1427 Rectangle(
1428 floor(aRange.getMinX()),
1429 floor(aRange.getMinY()),
1430 ceil(aRange.getMaxX()),
1431 ceil(aRange.getMaxY())));
1432 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1433 SfxItemSet aGradientAttr(mpModel->GetItemPool(), pRect->GetMergedItemSet().GetRanges());
1434 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1435 const XFillGradientItem aXFillGradientItem(
1436 &mpModel->GetItemPool(),
1437 XGradient(
1438 rGradient.GetStartColor(),
1439 rGradient.GetEndColor(),
1440 aXGradientStyle,
1441 rGradient.GetAngle(),
1442 rGradient.GetOfsX(),
1443 rGradient.GetOfsY(),
1444 rGradient.GetBorder(),
1445 rGradient.GetStartIntensity(),
1446 rGradient.GetEndIntensity(),
1447 rGradient.GetSteps()));
1448
1449 SetAttributes(pRect);
1450 aGradientAttr.Put(XFillStyleItem(XFILL_GRADIENT)); // #i125211#
1451 aGradientAttr.Put(aXFillGradientItem);
1452 pRect->SetMergedItemSet(aGradientAttr);
1453
1454 InsertObj(pRect, false);
1455 }
1456 }
1457
DoAction(MetaWallpaperAction &)1458 void ImpSdrGDIMetaFileImport::DoAction(MetaWallpaperAction& /*rAct*/)
1459 {
1460 OSL_ENSURE(false, "Tried to construct SdrObject from MetaWallpaperAction: not supported (!)");
1461 }
1462
DoAction(MetaTransparentAction & rAct)1463 void ImpSdrGDIMetaFileImport::DoAction(MetaTransparentAction& rAct)
1464 {
1465 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1466
1467 if(aSource.count())
1468 {
1469 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1470 aSource.transform(aTransform);
1471 aSource.setClosed(true);
1472
1473 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1474 SetAttributes(pPath);
1475 pPath->SetMergedItem(XFillTransparenceItem(rAct.GetTransparence()));
1476 InsertObj(pPath, false);
1477 }
1478 }
1479
DoAction(MetaEPSAction &)1480 void ImpSdrGDIMetaFileImport::DoAction(MetaEPSAction& /*rAct*/)
1481 {
1482 OSL_ENSURE(false, "Tried to construct SdrObject from MetaEPSAction: not supported (!)");
1483 }
1484
DoAction(MetaTextLineAction &)1485 void ImpSdrGDIMetaFileImport::DoAction(MetaTextLineAction& /*rAct*/)
1486 {
1487 OSL_ENSURE(false, "Tried to construct SdrObject from MetaTextLineAction: not supported (!)");
1488 }
1489
DoAction(MetaGradientExAction & rAct)1490 void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction& rAct)
1491 {
1492 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
1493
1494 if(aSource.count())
1495 {
1496 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
1497 aSource.transform(aTransform);
1498
1499 if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
1500 {
1501 const Gradient& rGradient = rAct.GetGradient();
1502 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
1503 // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
1504 SfxItemSet aGradientAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
1505 const XGradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
1506 const XFillGradientItem aXFillGradientItem(
1507 &mpModel->GetItemPool(),
1508 XGradient(
1509 rGradient.GetStartColor(),
1510 rGradient.GetEndColor(),
1511 aXGradientStyle,
1512 rGradient.GetAngle(),
1513 rGradient.GetOfsX(),
1514 rGradient.GetOfsY(),
1515 rGradient.GetBorder(),
1516 rGradient.GetStartIntensity(),
1517 rGradient.GetEndIntensity(),
1518 rGradient.GetSteps()));
1519
1520 SetAttributes(pPath);
1521 aGradientAttr.Put(XFillStyleItem(XFILL_GRADIENT)); // #i125211#
1522 aGradientAttr.Put(aXFillGradientItem);
1523 pPath->SetMergedItemSet(aGradientAttr);
1524
1525 InsertObj(pPath, false);
1526 }
1527 }
1528 }
1529
DoAction(MetaFloatTransparentAction & rAct)1530 void ImpSdrGDIMetaFileImport::DoAction(MetaFloatTransparentAction& rAct)
1531 {
1532 const GDIMetaFile& rMtf = rAct.GetGDIMetaFile();
1533
1534 if(rMtf.GetActionCount())
1535 {
1536 const Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
1537
1538 Rectangle aHairline;
1539 const Rectangle aBoundRect(rMtf.GetBoundRect(*Application::GetDefaultDevice(), &aHairline));
1540
1541 // convert metafile sub-content to BitmapEx
1542 BitmapEx aBitmapEx(
1543 convertMetafileToBitmapEx(
1544 rMtf,
1545 basegfx::B2DRange(
1546 aRect.Left(), aRect.Top(),
1547 aRect.Right(), aRect.Bottom()),
1548 125000));
1549
1550 // handle colors
1551 const Gradient& rGradient = rAct.GetGradient();
1552 basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
1553 basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
1554
1555 if(100 != rGradient.GetStartIntensity())
1556 {
1557 aStart *= (double)rGradient.GetStartIntensity() / 100.0;
1558 }
1559
1560 if(100 != rGradient.GetEndIntensity())
1561 {
1562 aEnd *= (double)rGradient.GetEndIntensity() / 100.0;
1563 }
1564
1565 const bool bEqualColors(aStart == aEnd);
1566 const bool bNoSteps(1 == rGradient.GetSteps());
1567 bool bCreateObject(true);
1568 bool bHasNewMask(false);
1569 AlphaMask aNewMask;
1570 double fTransparence(0.0);
1571 bool bFixedTransparence(false);
1572
1573 if(bEqualColors || bNoSteps)
1574 {
1575 // single transparence
1576 const basegfx::BColor aMedium(basegfx::average(aStart, aEnd));
1577 fTransparence = aMedium.luminance();
1578
1579 if(basegfx::fTools::lessOrEqual(fTransparence, 0.0))
1580 {
1581 // no transparence needed, all done
1582 }
1583 else if(basegfx::fTools::moreOrEqual(fTransparence, 1.0))
1584 {
1585 // all transparent, no object
1586 bCreateObject = false;
1587 }
1588 else
1589 {
1590 // 0.0 < transparence < 1.0, apply fixed transparence
1591 bFixedTransparence = true;
1592 }
1593 }
1594 else
1595 {
1596 // gradient transparence
1597 VirtualDevice aVDev;
1598
1599 aVDev.SetOutputSizePixel(aBitmapEx.GetBitmap().GetSizePixel());
1600 aVDev.DrawGradient(Rectangle(Point(0, 0), aVDev.GetOutputSizePixel()), rGradient);
1601
1602 aNewMask = AlphaMask(aVDev.GetBitmap(Point(0, 0), aVDev.GetOutputSizePixel()));
1603 bHasNewMask = true;
1604 }
1605
1606 if(bCreateObject)
1607 {
1608 if(bHasNewMask || bFixedTransparence)
1609 {
1610 if(!aBitmapEx.IsAlpha() && !aBitmapEx.IsTransparent())
1611 {
1612 // no transparence yet, apply new one
1613 if(bFixedTransparence)
1614 {
1615 sal_uInt8 aAlpha(basegfx::fround(fTransparence * 255.0));
1616
1617 aNewMask = AlphaMask(aBitmapEx.GetBitmap().GetSizePixel(), &aAlpha);
1618 }
1619
1620 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aNewMask);
1621 }
1622 else
1623 {
1624 // mix existing and new alpha mask
1625 AlphaMask aOldMask;
1626
1627 if(aBitmapEx.IsAlpha())
1628 {
1629 aOldMask = aBitmapEx.GetAlpha();
1630 }
1631 else if(TRANSPARENT_BITMAP == aBitmapEx.GetTransparentType())
1632 {
1633 aOldMask = aBitmapEx.GetMask();
1634 }
1635 else if(TRANSPARENT_COLOR == aBitmapEx.GetTransparentType())
1636 {
1637 aOldMask = aBitmapEx.GetBitmap().CreateMask(aBitmapEx.GetTransparentColor());
1638 }
1639
1640 BitmapWriteAccess* pOld = aOldMask.AcquireWriteAccess();
1641
1642 if(pOld)
1643 {
1644 const double fFactor(1.0 / 255.0);
1645
1646 if(bFixedTransparence)
1647 {
1648 const double fOpNew(1.0 - fTransparence);
1649
1650 for(sal_uInt32 y(0); y < static_cast< sal_uInt32 >(pOld->Height()); y++)
1651 {
1652 for(sal_uInt32 x(0); x < static_cast< sal_uInt32 >(pOld->Width()); x++)
1653 {
1654 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1655 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1656
1657 pOld->SetPixel(y, x, BitmapColor(aCol));
1658 }
1659 }
1660 }
1661 else
1662 {
1663 BitmapReadAccess* pNew = aNewMask.AcquireReadAccess();
1664
1665 if(pNew)
1666 {
1667 if(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height())
1668 {
1669 for(sal_uInt32 y(0); y < static_cast< sal_uInt32 >(pOld->Height()); y++)
1670 {
1671 for(sal_uInt32 x(0); x < static_cast< sal_uInt32 >(pOld->Width()); x++)
1672 {
1673 const double fOpOld(1.0 - (pOld->GetPixel(y, x).GetIndex() * fFactor));
1674 const double fOpNew(1.0 - (pNew->GetPixel(y, x).GetIndex() * fFactor));
1675 const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
1676
1677 pOld->SetPixel(y, x, BitmapColor(aCol));
1678 }
1679 }
1680 }
1681 else
1682 {
1683 OSL_ENSURE(false, "Alpha masks have different sizes (!)");
1684 }
1685
1686 aNewMask.ReleaseAccess(pNew);
1687 }
1688 else
1689 {
1690 OSL_ENSURE(false, "Got no access to new alpha mask (!)");
1691 }
1692 }
1693
1694 aOldMask.ReleaseAccess(pOld);
1695 }
1696 else
1697 {
1698 OSL_ENSURE(false, "Got no access to old alpha mask (!)");
1699 }
1700
1701 // apply combined bitmap as mask
1702 aBitmapEx = BitmapEx(aBitmapEx.GetBitmap(), aOldMask);
1703 }
1704 }
1705
1706 // create and add object
1707 SdrGrafObj* pGraf = new SdrGrafObj(aBitmapEx, aRect);
1708
1709 // for MetaFloatTransparentAction, do not use SetAttributes(...)
1710 // since these metafile content is not used to draw line/fill
1711 // dependent of these setting at the device content
1712 pGraf->SetMergedItem(XLineStyleItem(XLINE_NONE));
1713 pGraf->SetMergedItem(XFillStyleItem(XFILL_NONE));
1714 InsertObj(pGraf);
1715 }
1716 }
1717 }
1718
1719 ////////////////////////////////////////////////////////////////////////////////////////////////////
1720 // eof
1721