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