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