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