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