1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include "svdfmtf.hxx" 32 #include <editeng/editdata.hxx> 33 #include <math.h> 34 #include <svx/xpoly.hxx> 35 #include <vcl/svapp.hxx> 36 #include <editeng/eeitem.hxx> 37 #include <editeng/fhgtitem.hxx> 38 #include <editeng/wghtitem.hxx> 39 #include <editeng/postitem.hxx> 40 #include <editeng/udlnitem.hxx> 41 #include <editeng/crsditem.hxx> 42 #include <editeng/shdditem.hxx> 43 #include <svx/xlnclit.hxx> 44 #include <svx/xlnwtit.hxx> 45 #include <svx/xflclit.hxx> 46 #include <svx/xgrad.hxx> 47 #include <svx/xflgrit.hxx> 48 #include <editeng/fontitem.hxx> 49 #include <editeng/akrnitem.hxx> 50 #include <editeng/wrlmitem.hxx> 51 #include <editeng/cntritem.hxx> 52 #include <editeng/colritem.hxx> 53 #include <vcl/metric.hxx> 54 #include <editeng/charscaleitem.hxx> 55 #include <svx/xflhtit.hxx> 56 #include <svx/svdattr.hxx> 57 #include <svx/svdmodel.hxx> 58 #include <svx/svdpage.hxx> 59 #include <svx/svdobj.hxx> 60 #include "svx/svditext.hxx" 61 #include <svx/svdotext.hxx> 62 #include <svx/svdorect.hxx> 63 #include <svx/svdocirc.hxx> 64 #include <svx/svdograf.hxx> 65 #include <svx/svdopath.hxx> 66 #include <svx/svdetc.hxx> 67 #include <svl/itemset.hxx> 68 #include <basegfx/polygon/b2dpolygon.hxx> 69 #include <vcl/salbtype.hxx> // FRound 70 #include <basegfx/matrix/b2dhommatrix.hxx> 71 #include <basegfx/matrix/b2dhommatrixtools.hxx> 72 #include <svx/xlinjoit.hxx> 73 #include <svx/xlndsit.hxx> 74 75 //////////////////////////////////////////////////////////////////////////////////////////////////// 76 77 ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel): 78 nMapScalingOfs(0), 79 pLineAttr(NULL),pFillAttr(NULL),pTextAttr(NULL), 80 pPage(NULL),pModel(NULL),nLayer(0), 81 nLineWidth(0), 82 maLineJoin(basegfx::B2DLINEJOIN_NONE), 83 maDash(XDASH_RECT, 0, 0, 0, 0, 0), 84 bFntDirty(sal_True), 85 bLastObjWasPolyWithoutLine(sal_False),bNoLine(sal_False),bNoFill(sal_False),bLastObjWasLine(sal_False) 86 { 87 aVD.EnableOutput(sal_False); 88 89 // #i111954# init to no fill and no line initially 90 aVD.SetLineColor(); 91 aVD.SetFillColor(); 92 93 aOldLineColor.SetRed( aVD.GetLineColor().GetRed() + 1 ); // invalidate old line color 94 pLineAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_LINE_FIRST,XATTR_LINE_LAST); 95 pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST); 96 pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END); 97 pModel=&rModel; 98 } 99 100 ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport() 101 { 102 delete pLineAttr; 103 delete pFillAttr; 104 delete pTextAttr; 105 } 106 107 sal_uIntPtr ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf, 108 SdrObjList& rOL, 109 sal_uIntPtr nInsPos, 110 SvdProgressInfo *pProgrInfo) 111 { 112 pPage = rOL.GetPage(); 113 GDIMetaFile* pTmpMtf=NULL; 114 GDIMetaFile* pMtf = (GDIMetaFile*) &rMtf; 115 sal_uIntPtr nActionAnz=pMtf->GetActionCount(); 116 sal_Bool bError = sal_False; 117 118 119 // setup some global scale parameter 120 // fScaleX, fScaleY, aScaleX, aScaleY, bMov, bSize 121 fScaleX = fScaleY = 1.0; 122 Size aMtfSize( pMtf->GetPrefSize() ); 123 if ( aMtfSize.Width() & aMtfSize.Height() && ( aScaleRect.IsEmpty() == sal_False ) ) 124 { 125 aOfs = aScaleRect.TopLeft(); 126 if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) ) 127 fScaleX = (double)( aScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width(); 128 if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) ) 129 fScaleY = (double)( aScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height(); 130 } 131 132 bMov = aOfs.X()!=0 || aOfs.Y()!=0; 133 bSize = sal_False; 134 135 aScaleX = Fraction( 1, 1 ); 136 aScaleY = Fraction( 1, 1 ); 137 if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) ) 138 { 139 aScaleX = Fraction( aScaleRect.GetWidth() - 1, aMtfSize.Width() ); 140 bSize = sal_True; 141 } 142 if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) ) 143 { 144 aScaleY = Fraction( aScaleRect.GetHeight() - 1, aMtfSize.Height() ); 145 bSize = sal_True; 146 } 147 148 if(65000 < nActionAnz) 149 { 150 nActionAnz = 65000; 151 bError = sal_True; 152 } 153 154 if(pProgrInfo) 155 pProgrInfo->SetActionCount(nActionAnz); 156 157 sal_uIntPtr nActionsToReport = 0; 158 159 for( MetaAction* pAct = pMtf->FirstAction(); pAct; pAct = pMtf->NextAction() ) 160 { 161 switch (pAct->GetType()) 162 { 163 case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break; 164 case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break; 165 case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break; 166 case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break; 167 case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break; 168 case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break; 169 case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break; 170 case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break; 171 case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break; 172 case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break; 173 case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break; 174 case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break; 175 case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break; 176 case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break; 177 case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break; 178 case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break; 179 case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break; 180 case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break; 181 case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break; 182 case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break; 183 case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break; 184 case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break; 185 case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break; 186 case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break; 187 case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break; 188 case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break; 189 case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break; 190 case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break; 191 case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break; 192 case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break; 193 case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break; 194 case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break; 195 case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break; 196 case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break; 197 case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, pMtf); break; 198 case META_RENDERGRAPHIC_ACTION : DoAction((MetaRenderGraphicAction &)*pAct); break; 199 } 200 201 if(pProgrInfo != NULL) 202 { 203 nActionsToReport++; 204 if(nActionsToReport >= 16) // Alle 16 Action updaten 205 { 206 if(!pProgrInfo->ReportActions(nActionsToReport)) 207 break; 208 nActionsToReport = 0; 209 } 210 } 211 } 212 213 if(pProgrInfo != NULL) 214 { 215 pProgrInfo->ReportActions(nActionsToReport); 216 nActionsToReport = 0; 217 } 218 219 // MapMode-Scaling vornehmen 220 MapScaling(); 221 // Objekte in vorgegebenes Rechteck hineinskalieren 222 sal_uIntPtr nAnz=aTmpList.GetObjCount(); 223 224 // Beim berechnen der Fortschrittsanzeige wird GetActionCount()*3 benutzt. 225 // Da in aTmpList allerdings weniger eintraege als GetActionCount() 226 // existieren koennen, muessen hier die zuviel vermuteten Actionen wieder 227 // hinzugefuegt werden. 228 nActionsToReport = (pMtf->GetActionCount() - nAnz)*2; 229 230 231 // Alle noch nicht gemeldeten Rescales melden 232 if(pProgrInfo) 233 { 234 pProgrInfo->ReportRescales(nActionsToReport); 235 pProgrInfo->SetInsertCount(nAnz); 236 } 237 nActionsToReport = 0; 238 239 // alle in aTmpList zwischengespeicherten Objekte nun in rOL ab der Position nInsPos einfuegen 240 if (nInsPos>rOL.GetObjCount()) nInsPos=rOL.GetObjCount(); 241 SdrInsertReason aReason(SDRREASON_VIEWCALL); 242 for (sal_uIntPtr i=0; i<nAnz; i++) 243 { 244 SdrObject* pObj=aTmpList.GetObj(i); 245 rOL.NbcInsertObject(pObj,nInsPos,&aReason); 246 nInsPos++; 247 248 if(pProgrInfo != NULL) 249 { 250 nActionsToReport++; 251 if(nActionsToReport >= 32) // Alle 32 Action updaten 252 { 253 pProgrInfo->ReportInserts(nActionsToReport); 254 nActionsToReport = 0; 255 } 256 } 257 } 258 if (pTmpMtf!=NULL) delete pTmpMtf; 259 260 // ein letztesmal alle verbliebennen Inserts reporten 261 if(pProgrInfo != NULL) 262 { 263 pProgrInfo->ReportInserts(nActionsToReport); 264 if(bError) 265 pProgrInfo->ReportError(); 266 } 267 268 return aTmpList.GetObjCount(); 269 } 270 271 void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr) 272 { 273 bNoLine = sal_False; bNoFill = sal_False; 274 FASTBOOL bLine=sal_True && !bForceTextAttr; 275 FASTBOOL bFill=pObj==NULL || ( pObj->IsClosedObj() && !bForceTextAttr ); 276 FASTBOOL bText=bForceTextAttr || (pObj!=NULL && pObj->GetOutlinerParaObject()!=NULL); 277 278 if ( bLine ) 279 { 280 if ( nLineWidth ) 281 pLineAttr->Put( XLineWidthItem( nLineWidth ) ); 282 else 283 pLineAttr->Put( XLineWidthItem( 0 ) ); 284 285 aOldLineColor = aVD.GetLineColor(); 286 if( aVD.IsLineColor() ) 287 { 288 pLineAttr->Put(XLineStyleItem(XLINE_SOLID)); 289 pLineAttr->Put(XLineColorItem(String(), aVD.GetLineColor())); 290 } 291 else 292 pLineAttr->Put(XLineStyleItem(XLINE_NONE)); 293 294 switch(maLineJoin) 295 { 296 default : // basegfx::B2DLINEJOIN_NONE 297 pLineAttr->Put(XLineJointItem(XLINEJOINT_NONE)); 298 break; 299 case basegfx::B2DLINEJOIN_MIDDLE: 300 pLineAttr->Put(XLineJointItem(XLINEJOINT_MIDDLE)); 301 break; 302 case basegfx::B2DLINEJOIN_BEVEL: 303 pLineAttr->Put(XLineJointItem(XLINEJOINT_BEVEL)); 304 break; 305 case basegfx::B2DLINEJOIN_MITER: 306 pLineAttr->Put(XLineJointItem(XLINEJOINT_MITER)); 307 break; 308 case basegfx::B2DLINEJOIN_ROUND: 309 pLineAttr->Put(XLineJointItem(XLINEJOINT_ROUND)); 310 break; 311 } 312 313 if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance()) 314 { 315 pLineAttr->Put(XLineDashItem(String(), maDash)); 316 } 317 else 318 { 319 pLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT))); 320 } 321 } 322 else 323 bNoLine = sal_True; 324 325 if ( bFill ) 326 { 327 if( aVD.IsFillColor() ) 328 { 329 pFillAttr->Put(XFillStyleItem(XFILL_SOLID)); 330 pFillAttr->Put(XFillColorItem(String(), aVD.GetFillColor())); 331 } 332 else 333 pFillAttr->Put(XFillStyleItem(XFILL_NONE)); 334 } 335 else 336 bNoFill = sal_True; 337 338 if ( bText && bFntDirty ) 339 { 340 Font aFnt(aVD.GetFont()); 341 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), 342 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) ); 343 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), 344 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) ); 345 pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(), 346 aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) ); 347 pTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC)); 348 pTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT)); 349 sal_uInt32 nHeight = FRound(aFnt.GetSize().Height() * fScaleY); 350 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) ); 351 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) ); 352 pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) ); 353 pTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH)); 354 pTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE)); 355 pTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE)); 356 pTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT)); 357 pTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW)); 358 pTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING)); 359 pTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM)); 360 pTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE)); 361 pTextAttr->Put(SvxColorItem(aFnt.GetColor(), EE_CHAR_COLOR)); 362 //... svxfont textitem svditext 363 bFntDirty=sal_False; 364 } 365 if (pObj!=NULL) 366 { 367 pObj->SetLayer(nLayer); 368 if (bLine) pObj->SetMergedItemSet(*pLineAttr); 369 if (bFill) pObj->SetMergedItemSet(*pFillAttr); 370 if (bText) 371 { 372 pObj->SetMergedItemSet(*pTextAttr); 373 pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT ) ); 374 } 375 } 376 } 377 378 void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale ) 379 { 380 if ( bScale && !aScaleRect.IsEmpty() ) 381 { 382 if ( bSize ) 383 pObj->NbcResize( Point(), aScaleX, aScaleY ); 384 if ( bMov ) 385 pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) ); 386 } 387 388 // #i111954# check object for visibility 389 // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj 390 bool bVisible(false); 391 392 if(pObj->HasLineStyle()) 393 { 394 bVisible = true; 395 } 396 397 if(!bVisible && pObj->HasFillStyle()) 398 { 399 bVisible = true; 400 } 401 402 if(!bVisible) 403 { 404 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj); 405 406 if(pTextObj && pTextObj->HasText()) 407 { 408 bVisible = true; 409 } 410 } 411 412 if(!bVisible) 413 { 414 SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj); 415 416 if(pGrafObj) 417 { 418 // this may be refined to check if the graphic really is visible. It 419 // is here to ensure that graphic objects without fill, line and text 420 // get created 421 bVisible = true; 422 } 423 } 424 425 if(!bVisible) 426 { 427 SdrObject::Free(pObj); 428 } 429 else 430 { 431 aTmpList.InsertObject( pObj ); 432 if ( HAS_BASE( SdrPathObj, pObj ) ) 433 { 434 FASTBOOL bClosed=pObj->IsClosedObj(); 435 bLastObjWasPolyWithoutLine=bNoLine && bClosed; 436 bLastObjWasLine=!bClosed; 437 } 438 else 439 { 440 bLastObjWasPolyWithoutLine = sal_False; 441 bLastObjWasLine = sal_False; 442 } 443 } 444 } 445 446 /**************************************************************************************************/ 447 448 void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/) 449 { 450 } 451 452 void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/) 453 { 454 } 455 456 void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct) 457 { 458 // #i73407# reformulation to use new B2DPolygon classes 459 const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y()); 460 const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y()); 461 462 if(!aStart.equal(aEnd)) 463 { 464 basegfx::B2DPolygon aLine; 465 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y())); 466 467 aLine.append(aStart); 468 aLine.append(aEnd); 469 aLine.transform(aTransform); 470 471 const LineInfo& rLineInfo = rAct.GetLineInfo(); 472 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth()); 473 bool bCreateLineObject(true); 474 475 if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aLine)) 476 { 477 bCreateLineObject = false; 478 } 479 480 if(bCreateLineObject) 481 { 482 SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine)); 483 nLineWidth = nNewLineWidth; 484 maLineJoin = rLineInfo.GetLineJoin(); 485 maDash = XDash(XDASH_RECT, 486 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(), 487 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(), 488 rLineInfo.GetDistance()); 489 SetAttributes(pPath); 490 nLineWidth = 0; 491 maLineJoin = basegfx::B2DLINEJOIN_NONE; 492 maDash = XDash(); 493 InsertObj(pPath, false); 494 } 495 } 496 } 497 498 void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct) 499 { 500 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect()); 501 SetAttributes(pRect); 502 InsertObj(pRect); 503 } 504 505 void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct) 506 { 507 SdrRectObj* pRect=new SdrRectObj(rAct.GetRect()); 508 SetAttributes(pRect); 509 long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2; 510 if (nRad!=0) { 511 SfxItemSet aSet(*pLineAttr->GetPool(),SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS); 512 aSet.Put(SdrEckenradiusItem(nRad)); 513 pRect->SetMergedItemSet(aSet); 514 } 515 InsertObj(pRect); 516 } 517 518 /**************************************************************************************************/ 519 520 void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct) 521 { 522 SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect()); 523 SetAttributes(pCirc); 524 InsertObj(pCirc); 525 } 526 527 void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct) 528 { 529 Point aCenter(rAct.GetRect().Center()); 530 long nStart=GetAngle(rAct.GetStartPoint()-aCenter); 531 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter); 532 SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd); 533 SetAttributes(pCirc); 534 InsertObj(pCirc); 535 } 536 537 void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct) 538 { 539 Point aCenter(rAct.GetRect().Center()); 540 long nStart=GetAngle(rAct.GetStartPoint()-aCenter); 541 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter); 542 SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd); 543 SetAttributes(pCirc); 544 InsertObj(pCirc); 545 } 546 547 void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct) 548 { 549 Point aCenter(rAct.GetRect().Center()); 550 long nStart=GetAngle(rAct.GetStartPoint()-aCenter); 551 long nEnd=GetAngle(rAct.GetEndPoint()-aCenter); 552 SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd); 553 SetAttributes(pCirc); 554 InsertObj(pCirc); 555 } 556 557 /**************************************************************************************************/ 558 559 bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly) 560 { 561 // #i102706# Do not merge closed polygons 562 if(rSrcPoly.isClosed()) 563 { 564 return false; 565 } 566 567 // #i73407# reformulation to use new B2DPolygon classes 568 if(bLastObjWasLine && (aOldLineColor == aVD.GetLineColor()) && rSrcPoly.count()) 569 { 570 SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1); 571 SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj); 572 573 if(pLastPoly) 574 { 575 if(1L == pLastPoly->GetPathPoly().count()) 576 { 577 bool bOk(false); 578 basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L)); 579 580 // #i102706# Do not merge closed polygons 581 if(aDstPoly.isClosed()) 582 { 583 return false; 584 } 585 586 if(aDstPoly.count()) 587 { 588 const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L); 589 const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L); 590 591 if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L)) 592 { 593 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L); 594 bOk = true; 595 } 596 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt)) 597 { 598 basegfx::B2DPolygon aNew(rSrcPoly); 599 aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L); 600 aDstPoly = aNew; 601 bOk = true; 602 } 603 else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L)) 604 { 605 aDstPoly.flip(); 606 aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L); 607 bOk = true; 608 } 609 else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt)) 610 { 611 basegfx::B2DPolygon aNew(rSrcPoly); 612 aNew.flip(); 613 aDstPoly.append(aNew, 1L, aNew.count() - 1L); 614 bOk = true; 615 } 616 } 617 618 if(bOk) 619 { 620 pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly)); 621 } 622 623 return bOk; 624 } 625 } 626 } 627 628 return false; 629 } 630 631 bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon) 632 { 633 // #i73407# reformulation to use new B2DPolygon classes 634 if(bLastObjWasPolyWithoutLine) 635 { 636 SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1); 637 SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj); 638 639 if(pLastPoly) 640 { 641 if(pLastPoly->GetPathPoly() == rPolyPolygon) 642 { 643 SetAttributes(NULL); 644 645 if(!bNoLine && bNoFill) 646 { 647 pLastPoly->SetMergedItemSet(*pLineAttr); 648 649 return true; 650 } 651 } 652 } 653 } 654 655 return false; 656 } 657 658 659 void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct ) 660 { 661 // #i73407# reformulation to use new B2DPolygon classes 662 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon()); 663 664 if(aSource.count()) 665 { 666 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y())); 667 aSource.transform(aTransform); 668 } 669 670 const LineInfo& rLineInfo = rAct.GetLineInfo(); 671 const sal_Int32 nNewLineWidth(rLineInfo.GetWidth()); 672 bool bCreateLineObject(true); 673 674 if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aSource)) 675 { 676 bCreateLineObject = false; 677 } 678 else if(bLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource))) 679 { 680 bCreateLineObject = false; 681 } 682 683 if(bCreateLineObject) 684 { 685 SdrPathObj* pPath = new SdrPathObj( 686 aSource.isClosed() ? OBJ_POLY : OBJ_PLIN, 687 basegfx::B2DPolyPolygon(aSource)); 688 nLineWidth = nNewLineWidth; 689 maLineJoin = rLineInfo.GetLineJoin(); 690 maDash = XDash(XDASH_RECT, 691 rLineInfo.GetDotCount(), rLineInfo.GetDotLen(), 692 rLineInfo.GetDashCount(), rLineInfo.GetDashLen(), 693 rLineInfo.GetDistance()); 694 SetAttributes(pPath); 695 nLineWidth = 0; 696 maLineJoin = basegfx::B2DLINEJOIN_NONE; 697 maDash = XDash(); 698 InsertObj(pPath, false); 699 } 700 } 701 702 void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct ) 703 { 704 // #i73407# reformulation to use new B2DPolygon classes 705 basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon()); 706 707 if(aSource.count()) 708 { 709 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y())); 710 aSource.transform(aTransform); 711 712 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource))) 713 { 714 // #i73407# make sure polygon is closed, it's a filled primitive 715 aSource.setClosed(true); 716 717 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource)); 718 SetAttributes(pPath); 719 InsertObj(pPath, false); 720 } 721 } 722 } 723 724 void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct) 725 { 726 // #i73407# reformulation to use new B2DPolygon classes 727 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon()); 728 729 if(aSource.count()) 730 { 731 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y())); 732 aSource.transform(aTransform); 733 734 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource)) 735 { 736 // #i73407# make sure polygon is closed, it's a filled primitive 737 aSource.setClosed(true); 738 739 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource); 740 SetAttributes(pPath); 741 InsertObj(pPath, false); 742 } 743 } 744 } 745 746 /**************************************************************************************************/ 747 748 void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct ) 749 { 750 // calc text box size, add 5% to make it fit safely 751 752 FontMetric aFontMetric( aVD.GetFontMetric() ); 753 Font aFnt( aVD.GetFont() ); 754 FontAlign eAlg( aFnt.GetAlign() ); 755 756 sal_Int32 nTextWidth = (sal_Int32)( aVD.GetTextWidth( rStr ) * fScaleX ); 757 sal_Int32 nTextHeight = (sal_Int32)( aVD.GetTextHeight() * fScaleY ); 758 //sal_Int32 nDxWidth = 0; 759 //sal_Int32 nLen = rStr.Len(); 760 761 Point aPos( FRound(rPos.X() * fScaleX + aOfs.X()), FRound(rPos.Y() * fScaleY + aOfs.Y()) ); 762 Size aSize( nTextWidth, nTextHeight ); 763 764 if ( eAlg == ALIGN_BASELINE ) 765 aPos.Y() -= FRound(aFontMetric.GetAscent() * fScaleY); 766 else if ( eAlg == ALIGN_BOTTOM ) 767 aPos.Y() -= nTextHeight; 768 769 Rectangle aTextRect( aPos, aSize ); 770 SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect ); 771 772 if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) ) 773 { 774 pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH ); 775 pText->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) ); 776 // don't let the margins eat the space needed for the text 777 pText->SetMergedItem ( SdrTextUpperDistItem (0)); 778 pText->SetMergedItem ( SdrTextLowerDistItem (0)); 779 pText->SetMergedItem ( SdrTextRightDistItem (0)); 780 pText->SetMergedItem ( SdrTextLeftDistItem (0)); 781 pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) ); 782 } 783 else 784 pText->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) ); 785 786 pText->SetModel( pModel ); 787 pText->SetLayer( nLayer ); 788 pText->NbcSetText( rStr ); 789 SetAttributes( pText, sal_True ); 790 pText->SetSnapRect( aTextRect ); 791 792 if (!aFnt.IsTransparent()) 793 { 794 SfxItemSet aAttr(*pFillAttr->GetPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST); 795 aAttr.Put(XFillStyleItem(XFILL_SOLID)); 796 aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor())); 797 pText->SetMergedItemSet(aAttr); 798 } 799 sal_uInt32 nWink = aFnt.GetOrientation(); 800 if ( nWink ) 801 { 802 nWink*=10; 803 double a=nWink*nPi180; 804 double nSin=sin(a); 805 double nCos=cos(a); 806 pText->NbcRotate(aPos,nWink,nSin,nCos); 807 } 808 InsertObj( pText, sal_False ); 809 } 810 811 void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct) 812 { 813 XubString aStr(rAct.GetText()); 814 aStr.Erase(0,rAct.GetIndex()); 815 aStr.Erase(rAct.GetLen()); 816 ImportText( rAct.GetPoint(), aStr, rAct ); 817 } 818 819 void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct) 820 { 821 XubString aStr(rAct.GetText()); 822 aStr.Erase(0,rAct.GetIndex()); 823 aStr.Erase(rAct.GetLen()); 824 ImportText( rAct.GetPoint(), aStr, rAct ); 825 } 826 827 void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct) 828 { 829 XubString aStr(rAct.GetText()); 830 aStr.Erase(0,rAct.GetIndex()); 831 aStr.Erase(rAct.GetLen()); 832 ImportText( rAct.GetPoint(), aStr, rAct ); 833 } 834 835 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct) 836 { 837 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel()); 838 aRect.Right()++; aRect.Bottom()++; 839 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect); 840 InsertObj(pGraf); 841 } 842 843 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct) 844 { 845 Rectangle aRect(rAct.GetPoint(),rAct.GetSize()); 846 aRect.Right()++; aRect.Bottom()++; 847 SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect); 848 InsertObj(pGraf); 849 } 850 851 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct) 852 { 853 Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel()); 854 aRect.Right()++; aRect.Bottom()++; 855 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect ); 856 InsertObj(pGraf); 857 } 858 859 void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct) 860 { 861 Rectangle aRect(rAct.GetPoint(),rAct.GetSize()); 862 aRect.Right()++; aRect.Bottom()++; 863 SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect ); 864 InsertObj(pGraf); 865 } 866 867 //////////////////////////////////////////////////////////////////////////////////////////////////// 868 869 void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct ) 870 { 871 // #i73407# reformulation to use new B2DPolygon classes 872 basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon()); 873 874 if(aSource.count()) 875 { 876 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y())); 877 aSource.transform(aTransform); 878 879 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource)) 880 { 881 const Hatch& rHatch = rAct.GetHatch(); 882 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource); 883 SfxItemSet aHatchAttr(pModel->GetItemPool(), 884 XATTR_FILLSTYLE, XATTR_FILLSTYLE, 885 XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0 ); 886 XHatchStyle eStyle; 887 888 switch(rHatch.GetStyle()) 889 { 890 case(HATCH_TRIPLE) : 891 { 892 eStyle = XHATCH_TRIPLE; 893 break; 894 } 895 896 case(HATCH_DOUBLE) : 897 { 898 eStyle = XHATCH_DOUBLE; 899 break; 900 } 901 902 default: 903 { 904 eStyle = XHATCH_SINGLE; 905 break; 906 } 907 } 908 909 SetAttributes(pPath); 910 aHatchAttr.Put(XFillStyleItem(XFILL_HATCH)); 911 aHatchAttr.Put(XFillHatchItem(&pModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle()))); 912 pPath->SetMergedItemSet(aHatchAttr); 913 914 InsertObj(pPath, false); 915 } 916 } 917 } 918 919 //////////////////////////////////////////////////////////////////////////////////////////////////// 920 921 void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct) 922 { 923 rAct.Execute(&aVD); 924 } 925 926 void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct) 927 { 928 MapScaling(); 929 rAct.Execute(&aVD); 930 bLastObjWasPolyWithoutLine=sal_False; 931 bLastObjWasLine=sal_False; 932 } 933 934 void ImpSdrGDIMetaFileImport::MapScaling() 935 { 936 sal_uInt32 i, nAnz = aTmpList.GetObjCount(); 937 const MapMode& rMap = aVD.GetMapMode(); 938 Point aMapOrg( rMap.GetOrigin() ); 939 sal_Bool bMov2 = aMapOrg.X() != 0 || aMapOrg.Y() != 0; 940 if ( bMov2 ) 941 { 942 for ( i = nMapScalingOfs; i < nAnz; i++ ) 943 { 944 SdrObject* pObj = aTmpList.GetObj(i); 945 if ( bMov2 ) 946 pObj->NbcMove( Size( aMapOrg.X(), aMapOrg.Y() ) ); 947 } 948 } 949 nMapScalingOfs = nAnz; 950 } 951 952 //////////////////////////////////////////////////////////////////////////////////////////////////// 953 954 void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf ) 955 { 956 ByteString aSkipComment; 957 958 if( rAct.GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) 959 { 960 MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction(); 961 962 if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION ) 963 { 964 // #i73407# reformulation to use new B2DPolygon classes 965 basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon()); 966 967 if(aSource.count()) 968 { 969 if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource)) 970 { 971 const Gradient& rGrad = pAct->GetGradient(); 972 SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource); 973 SfxItemSet aGradAttr(pModel->GetItemPool(), 974 XATTR_FILLSTYLE, XATTR_FILLSTYLE, 975 XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0 ); 976 XGradient aXGradient; 977 978 aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle()); 979 aXGradient.SetStartColor(rGrad.GetStartColor()); 980 aXGradient.SetEndColor(rGrad.GetEndColor()); 981 aXGradient.SetAngle((sal_uInt16)rGrad.GetAngle()); 982 aXGradient.SetBorder(rGrad.GetBorder()); 983 aXGradient.SetXOffset(rGrad.GetOfsX()); 984 aXGradient.SetYOffset(rGrad.GetOfsY()); 985 aXGradient.SetStartIntens(rGrad.GetStartIntensity()); 986 aXGradient.SetEndIntens(rGrad.GetEndIntensity()); 987 aXGradient.SetSteps(rGrad.GetSteps()); 988 989 if(aVD.IsLineColor()) 990 { 991 // switch line off; when there was one there will be a 992 // META_POLYLINE_ACTION following creating another object 993 const Color aLineColor(aVD.GetLineColor()); 994 aVD.SetLineColor(); 995 SetAttributes(pPath); 996 aVD.SetLineColor(aLineColor); 997 } 998 else 999 { 1000 SetAttributes(pPath); 1001 } 1002 1003 aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT)); 1004 aGradAttr.Put(XFillGradientItem(&pModel->GetItemPool(), aXGradient)); 1005 pPath->SetMergedItemSet(aGradAttr); 1006 1007 InsertObj(pPath); 1008 } 1009 } 1010 1011 aSkipComment = "XGRAD_SEQ_END"; 1012 } 1013 } 1014 1015 if(aSkipComment.Len()) 1016 { 1017 MetaAction* pSkipAct = pMtf->NextAction(); 1018 1019 while( pSkipAct 1020 && ((pSkipAct->GetType() != META_COMMENT_ACTION ) 1021 || (((MetaCommentAction*)pSkipAct)->GetComment().CompareIgnoreCaseToAscii(aSkipComment.GetBuffer()) != COMPARE_EQUAL))) 1022 { 1023 pSkipAct = pMtf->NextAction(); 1024 } 1025 } 1026 } 1027 1028 //////////////////////////////////////////////////////////////////////////////////////////////////// 1029 1030 void ImpSdrGDIMetaFileImport::DoAction(MetaRenderGraphicAction& rAct) 1031 { 1032 GDIMetaFile aMtf; 1033 const ::vcl::RenderGraphic& rRenderGraphic = rAct.GetRenderGraphic(); 1034 Rectangle aRect( rAct.GetPoint(), rAct.GetSize() ); 1035 const Point aPos; 1036 const Size aPrefSize( rRenderGraphic.GetPrefSize() ); 1037 1038 aRect.Right()++; aRect.Bottom()++; 1039 1040 aMtf.SetPrefMapMode( rRenderGraphic.GetPrefMapMode() ); 1041 aMtf.SetPrefSize( aPrefSize ); 1042 aMtf.AddAction( new MetaRenderGraphicAction( aPos, aPrefSize, rRenderGraphic ) ); 1043 aMtf.WindStart(); 1044 1045 SdrGrafObj* pGraf=new SdrGrafObj( aMtf, aRect ); 1046 InsertObj( pGraf ); 1047 } 1048 1049 // eof 1050