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