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_svtools.hxx" 26 27 #include "winmtf.hxx" 28 #include <osl/endian.h> 29 #include <basegfx/matrix/b2dhommatrix.hxx> 30 31 //=========================== GDI-Array =================================== 32 33 #define EMR_HEADER 1 34 #define EMR_POLYBEZIER 2 35 #define EMR_POLYGON 3 36 #define EMR_POLYLINE 4 37 #define EMR_POLYBEZIERTO 5 38 #define EMR_POLYLINETO 6 39 #define EMR_POLYPOLYLINE 7 40 #define EMR_POLYPOLYGON 8 41 #define EMR_SETWINDOWEXTEX 9 42 #define EMR_SETWINDOWORGEX 10 43 #define EMR_SETVIEWPORTEXTEX 11 44 #define EMR_SETVIEWPORTORGEX 12 45 #define EMR_SETBRUSHORGEX 13 46 #define EMR_EOF 14 47 #define EMR_SETPIXELV 15 48 #define EMR_SETMAPPERFLAGS 16 49 #define EMR_SETMAPMODE 17 50 #define EMR_SETBKMODE 18 51 #define EMR_SETPOLYFILLMODE 19 52 #define EMR_SETROP2 20 53 #define EMR_SETSTRETCHBLTMODE 21 54 #define EMR_SETTEXTALIGN 22 55 #define EMR_SETCOLORADJUSTMENT 23 56 #define EMR_SETTEXTCOLOR 24 57 #define EMR_SETBKCOLOR 25 58 #define EMR_OFFSETCLIPRGN 26 59 #define EMR_MOVETOEX 27 60 #define EMR_SETMETARGN 28 61 #define EMR_EXCLUDECLIPRECT 29 62 #define EMR_INTERSECTCLIPRECT 30 63 #define EMR_SCALEVIEWPORTEXTEX 31 64 #define EMR_SCALEWINDOWEXTEX 32 65 #define EMR_SAVEDC 33 66 #define EMR_RESTOREDC 34 67 #define EMR_SETWORLDTRANSFORM 35 68 #define EMR_MODIFYWORLDTRANSFORM 36 69 #define EMR_SELECTOBJECT 37 70 #define EMR_CREATEPEN 38 71 #define EMR_CREATEBRUSHINDIRECT 39 72 #define EMR_DELETEOBJECT 40 73 #define EMR_ANGLEARC 41 74 #define EMR_ELLIPSE 42 75 #define EMR_RECTANGLE 43 76 #define EMR_ROUNDRECT 44 77 #define EMR_ARC 45 78 #define EMR_CHORD 46 79 #define EMR_PIE 47 80 #define EMR_SELECTPALETTE 48 81 #define EMR_CREATEPALETTE 49 82 #define EMR_SETPALETTEENTRIES 50 83 #define EMR_RESIZEPALETTE 51 84 #define EMR_REALIZEPALETTE 52 85 #define EMR_EXTFLOODFILL 53 86 #define EMR_LINETO 54 87 #define EMR_ARCTO 55 88 #define EMR_POLYDRAW 56 89 #define EMR_SETARCDIRECTION 57 90 #define EMR_SETMITERLIMIT 58 91 #define EMR_BEGINPATH 59 92 #define EMR_ENDPATH 60 93 #define EMR_CLOSEFIGURE 61 94 #define EMR_FILLPATH 62 95 #define EMR_STROKEANDFILLPATH 63 96 #define EMR_STROKEPATH 64 97 #define EMR_FLATTENPATH 65 98 #define EMR_WIDENPATH 66 99 #define EMR_SELECTCLIPPATH 67 100 #define EMR_ABORTPATH 68 101 102 #define EMR_GDICOMMENT 70 103 #define EMR_FILLRGN 71 104 #define EMR_FRAMERGN 72 105 #define EMR_INVERTRGN 73 106 #define EMR_PAINTRGN 74 107 #define EMR_EXTSELECTCLIPRGN 75 108 #define EMR_BITBLT 76 109 #define EMR_STRETCHBLT 77 110 #define EMR_MASKBLT 78 111 #define EMR_PLGBLT 79 112 #define EMR_SETDIBITSTODEVICE 80 113 #define EMR_STRETCHDIBITS 81 114 #define EMR_EXTCREATEFONTINDIRECTW 82 115 #define EMR_EXTTEXTOUTA 83 116 #define EMR_EXTTEXTOUTW 84 117 #define EMR_POLYBEZIER16 85 118 #define EMR_POLYGON16 86 119 #define EMR_POLYLINE16 87 120 #define EMR_POLYBEZIERTO16 88 121 #define EMR_POLYLINETO16 89 122 #define EMR_POLYPOLYLINE16 90 123 #define EMR_POLYPOLYGON16 91 124 #define EMR_POLYDRAW16 92 125 #define EMR_CREATEMONOBRUSH 93 126 #define EMR_CREATEDIBPATTERNBRUSHPT 94 127 #define EMR_EXTCREATEPEN 95 128 #define EMR_POLYTEXTOUTA 96 129 #define EMR_POLYTEXTOUTW 97 130 131 // WINDOWS VERSION >= 0x400 132 #define EMR_SETICMMODE 98 133 #define EMR_CREATECOLORSPACE 99 134 #define EMR_SETCOLORSPACE 100 135 #define EMR_DELETECOLORSPACE 101 136 #define EMR_GLSRECORD 102 137 #define EMR_GLSBOUNDEDRECORD 103 138 #define EMR_PIXELFORMAT 104 139 140 // WINDOWS VERSION >= 0x500 141 #define EMR_DRAWESCAPE 105 142 #define EMR_EXTESCAPE 106 143 #define EMR_STARTDOC 107 144 #define EMR_SMALLTEXTOUT 108 145 #define EMR_FORCEUFIMAPPING 109 146 #define EMR_NAMEDESCAPE 110 147 #define EMR_COLORCORRECTPALETTE 111 148 #define EMR_SETICMPROFILEA 112 149 #define EMR_SETICMPROFILEW 113 150 #define EMR_ALPHABLEND 114 151 #define EMR_ALPHADIBBLEND 115 152 #define EMR_TRANSPARENTBLT 116 153 #define EMR_TRANSPARENTDIB 117 154 #define EMR_GRADIENTFILL 118 155 #define EMR_SETLINKEDUFIS 119 156 #define EMR_SETTEXTJUSTIFICATION 120 157 158 159 //----------------------------------------------------------------------------------- 160 161 #ifdef OSL_BIGENDIAN 162 // currently unused 163 static float GetSwapFloat( SvStream& rSt ) 164 { 165 float fTmp; 166 sal_Int8* pPtr = (sal_Int8*)&fTmp; 167 rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch 168 return fTmp; 169 } 170 #endif 171 172 struct BLENDFUNCTION{ 173 unsigned char aBlendOperation; 174 unsigned char aBlendFlags; 175 unsigned char aSrcConstantAlpha; 176 unsigned char aAlphaFormat; 177 178 friend SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ); 179 }; 180 181 SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ) 182 { 183 rIn >> rBlendFun.aBlendOperation >> rBlendFun.aBlendFlags >> 184 rBlendFun.aSrcConstantAlpha >> rBlendFun.aAlphaFormat; 185 return rIn; 186 } 187 SvStream& operator>>( SvStream& rIn, XForm& rXForm ) 188 { 189 if ( sizeof( float ) != 4 ) 190 { 191 DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" ); 192 rXForm = XForm(); 193 } 194 else 195 { 196 #ifdef OSL_BIGENDIAN 197 rXForm.eM11 = GetSwapFloat( rIn ); 198 rXForm.eM12 = GetSwapFloat( rIn ); 199 rXForm.eM21 = GetSwapFloat( rIn ); 200 rXForm.eM22 = GetSwapFloat( rIn ); 201 rXForm.eDx = GetSwapFloat( rIn ); 202 rXForm.eDy = GetSwapFloat( rIn ); 203 #else 204 rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22 205 >> rXForm.eDx >> rXForm.eDy; 206 #endif 207 } 208 return rIn; 209 } 210 211 static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen ) 212 { 213 sal_Bool bOk = sal_False; 214 if ( nLen ) 215 { 216 sal_uInt32 nHdSize, nType, nCount, nRgnSize, i; 217 rSt >> nHdSize 218 >> nType 219 >> nCount 220 >> nRgnSize; 221 222 if ( nCount && ( nType == RDH_RECTANGLES ) && 223 ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) ) 224 { 225 sal_Int32 nx1, ny1, nx2, ny2; 226 227 for ( i = 0; i < nCount; i++ ) 228 { 229 rSt >> nx1 >> ny1 >> nx2 >> ny2; 230 231 Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) ); 232 Polygon aPolygon( aRect ); 233 PolyPolygon aPolyPolyOr1( aPolygon ); 234 PolyPolygon aPolyPolyOr2( rPolyPoly ); 235 rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 ); 236 rPolyPoly = aPolyPolyOr2; 237 } 238 bOk = sal_True; 239 } 240 } 241 return bOk; 242 } 243 244 sal_Bool EnhWMFReader::ReadEnhWMF() 245 { 246 sal_uInt32 nStretchBltMode = 0; 247 sal_uInt32 nRecType, nRecSize, nNextPos, 248 nW, nH, nPoints, nColor, nIndex, 249 nDat32, nNom1, nDen1, nNom2, nDen2; 250 sal_Int32 nX32, nY32, nx32, ny32; 251 sal_Int16 nX16, nY16; 252 253 sal_Bool bFlag, bStatus = ReadHeader(); 254 255 while( bStatus && nRecordCount-- ) 256 { 257 *pWMF >> nRecType >> nRecSize; 258 259 if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar 260 { 261 bStatus = sal_False; 262 break; 263 } 264 265 nNextPos = pWMF->Tell() + ( nRecSize - 8 ); 266 267 if ( nNextPos > nEndPos ) 268 { 269 bStatus = sal_False; 270 break; 271 } 272 273 if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) ) 274 pOut->ResolveBitmapActions( aBmpSaveList ); 275 276 bFlag = sal_False; 277 278 switch( nRecType ) 279 { 280 case EMR_POLYBEZIERTO : 281 bFlag = sal_True; 282 case EMR_POLYBEZIER : 283 { 284 pWMF->SeekRel( 16 ); 285 *pWMF >> nPoints; 286 sal_uInt16 i = 0; 287 if ( bFlag ) 288 { 289 i++; 290 nPoints++; 291 } 292 Polygon aPoly( (sal_uInt16)nPoints ); 293 for( ; i < (sal_uInt16)nPoints; i++ ) 294 { 295 *pWMF >> nX32 >> nY32; 296 aPoly[ i ] = Point( nX32, nY32 ); 297 } 298 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); 299 } 300 break; 301 302 case EMR_POLYGON : 303 { 304 pWMF->SeekRel( 16 ); 305 *pWMF >> nPoints; 306 Polygon aPoly( (sal_uInt16)nPoints ); 307 for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) 308 { 309 *pWMF >> nX32 >> nY32; 310 aPoly[ k ] = Point( nX32, nY32 ); 311 } 312 pOut->DrawPolygon( aPoly, bRecordPath ); 313 } 314 break; 315 316 case EMR_POLYLINETO : 317 bFlag = sal_True; 318 case EMR_POLYLINE : 319 { 320 pWMF->SeekRel( 0x10 ); 321 *pWMF >> nPoints; 322 sal_uInt16 i = 0; 323 if ( bFlag ) 324 { 325 i++; 326 nPoints++; 327 } 328 Polygon aPolygon( (sal_uInt16)nPoints ); 329 for ( ; i < (sal_uInt16)nPoints; i++ ) 330 { 331 *pWMF >> nX32 >> nY32; 332 aPolygon[ i ] = Point( nX32, nY32 ); 333 } 334 pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath ); 335 } 336 break; 337 338 case EMR_POLYPOLYLINE : 339 { 340 sal_Int32 i, nPoly; 341 pWMF->SeekRel( 0x10 ); 342 343 // Anzahl der Polygone: 344 *pWMF >> nPoly >> i; 345 346 // taking the amount of points of each polygon, retrieving the total number of points 347 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) 348 { 349 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 350 { 351 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 352 353 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 354 { 355 *pWMF >> nPoints; 356 pnPoints[ i ] = (sal_uInt16)nPoints; 357 } 358 359 // Polygonpunkte holen: 360 361 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) 362 { 363 Polygon aPoly( pnPoints[ i ] ); 364 for( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) 365 { 366 *pWMF >> nX32 >> nY32; 367 aPoly[ k ] = Point( nX32, nY32 ); 368 } 369 pOut->DrawPolyLine( aPoly, sal_False, bRecordPath ); 370 } 371 delete[] pnPoints; 372 } 373 } 374 } 375 break; 376 377 case EMR_POLYPOLYGON : 378 { 379 sal_uInt32 nPoly(0); 380 sal_uInt32 nGesPoints(0); 381 sal_uInt32 nReadPoints(0); 382 pWMF->SeekRel( 0x10 ); 383 384 // Anzahl der Polygone: 385 *pWMF >> nPoly >> nGesPoints; 386 387 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) 388 { 389 if ( ( nPoly * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 390 { 391 sal_uInt32 i(0); 392 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 393 394 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 395 { 396 *pWMF >> nPoints; 397 pnPoints[ i ] = (sal_uInt16)nPoints; 398 } 399 400 if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof()) 401 { 402 PolyPolygon aPolyPoly(nPoly, nPoly); 403 404 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 405 { 406 const sal_uInt16 nPointCount(pnPoints[i]); 407 Point* pPtAry = new Point[nPointCount]; 408 409 for(sal_uInt16 j(0); j < nPointCount && !pWMF->IsEof(); j++) 410 { 411 *pWMF >> nX32 >> nY32; 412 pPtAry[ j ] = Point( nX32, nY32 ); 413 nReadPoints++; 414 } 415 416 aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); 417 delete[] pPtAry; 418 } 419 420 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); 421 } 422 423 delete[] pnPoints; 424 } 425 } 426 427 OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)"); 428 } 429 break; 430 431 case EMR_SETWINDOWEXTEX : 432 { // #75383# 433 *pWMF >> nW >> nH; 434 pOut->SetWinExt( Size( nW, nH ) ); 435 } 436 break; 437 438 case EMR_SETWINDOWORGEX : 439 { 440 *pWMF >> nX32 >> nY32; 441 pOut->SetWinOrg( Point( nX32, nY32 ) ); 442 } 443 break; 444 445 case EMR_SCALEWINDOWEXTEX : 446 { 447 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; 448 pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); 449 } 450 break; 451 452 case EMR_SETVIEWPORTORGEX : 453 { 454 *pWMF >> nX32 >> nY32; 455 pOut->SetDevOrg( Point( nX32, nY32 ) ); 456 } 457 break; 458 459 case EMR_SCALEVIEWPORTEXTEX : 460 { 461 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; 462 pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); 463 } 464 break; 465 466 case EMR_SETVIEWPORTEXTEX : 467 { 468 *pWMF >> nW >> nH; 469 pOut->SetDevExt( Size( nW, nH ) ); 470 } 471 break; 472 473 case EMR_EOF : 474 nRecordCount = 0; // #76846# 475 break; 476 477 case EMR_SETPIXELV : 478 { 479 *pWMF >> nX32 >> nY32; 480 pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() ); 481 } 482 break; 483 484 case EMR_SETMAPMODE : 485 { 486 sal_uInt32 nMapMode; 487 *pWMF >> nMapMode; 488 pOut->SetMapMode( nMapMode ); 489 } 490 break; 491 492 case EMR_SETBKMODE : 493 { 494 *pWMF >> nDat32; 495 pOut->SetBkMode( nDat32 ); 496 } 497 break; 498 499 case EMR_SETPOLYFILLMODE : 500 break; 501 502 case EMR_SETROP2 : 503 { 504 *pWMF >> nDat32; 505 pOut->SetRasterOp( nDat32 ); 506 } 507 break; 508 509 case EMR_SETSTRETCHBLTMODE : 510 { 511 *pWMF >> nStretchBltMode; 512 } 513 break; 514 515 case EMR_SETTEXTALIGN : 516 { 517 *pWMF >> nDat32; 518 pOut->SetTextAlign( nDat32 ); 519 } 520 break; 521 522 case EMR_SETTEXTCOLOR : 523 { 524 pOut->SetTextColor( ReadColor() ); 525 } 526 break; 527 528 case EMR_SETBKCOLOR : 529 { 530 pOut->SetBkColor( ReadColor() ); 531 } 532 break; 533 534 case EMR_OFFSETCLIPRGN : 535 { 536 *pWMF >> nX32 >> nY32; 537 pOut->MoveClipRegion( Size( nX32, nY32 ) ); 538 } 539 break; 540 541 case EMR_MOVETOEX : 542 { 543 *pWMF >> nX32 >> nY32; 544 pOut->MoveTo( Point( nX32, nY32 ), bRecordPath ); 545 } 546 break; 547 548 case EMR_INTERSECTCLIPRECT : 549 { 550 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 551 pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 552 } 553 break; 554 555 case EMR_SAVEDC : 556 { 557 pOut->Push(); 558 } 559 break; 560 561 case EMR_RESTOREDC : 562 { 563 pOut->Pop(); 564 } 565 break; 566 567 case EMR_SETWORLDTRANSFORM : 568 { 569 XForm aTempXForm; 570 *pWMF >> aTempXForm; 571 pOut->SetWorldTransform( aTempXForm ); 572 } 573 break; 574 575 case EMR_MODIFYWORLDTRANSFORM : 576 { 577 sal_uInt32 nMode; 578 XForm aTempXForm; 579 *pWMF >> aTempXForm >> nMode; 580 pOut->ModifyWorldTransform( aTempXForm, nMode ); 581 } 582 break; 583 584 case EMR_SELECTOBJECT : 585 { 586 *pWMF >> nIndex; 587 pOut->SelectObject( nIndex ); 588 } 589 break; 590 591 case EMR_CREATEPEN : 592 { 593 *pWMF >> nIndex; 594 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 595 { 596 597 LineInfo aLineInfo; 598 sal_uInt32 nStyle; 599 Size aSize; 600 601 *pWMF >> nStyle >> aSize.Width() >> aSize.Height(); 602 603 if ( aSize.Width() ) 604 aLineInfo.SetWidth( aSize.Width() ); 605 606 sal_Bool bTransparent = sal_False; 607 sal_uInt16 nDashCount = 0; 608 sal_uInt16 nDotCount = 0; 609 switch( nStyle ) 610 { 611 case PS_DASHDOTDOT : 612 nDotCount++; 613 case PS_DASHDOT : 614 nDashCount++; 615 case PS_DOT : 616 nDotCount++; 617 break; 618 case PS_DASH : 619 nDashCount++; 620 break; 621 case PS_NULL : 622 bTransparent = sal_True; 623 aLineInfo.SetStyle( LINE_NONE ); 624 break; 625 default : 626 case PS_INSIDEFRAME : 627 case PS_SOLID : 628 aLineInfo.SetStyle( LINE_SOLID ); 629 } 630 if ( nDashCount | nDotCount ) 631 { 632 aLineInfo.SetStyle( LINE_DASH ); 633 aLineInfo.SetDashCount( nDashCount ); 634 aLineInfo.SetDotCount( nDotCount ); 635 } 636 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) ); 637 } 638 } 639 break; 640 641 case EMR_EXTCREATEPEN : 642 { 643 sal_Int32 elpHatch; 644 sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; 645 Color aColorRef; 646 647 *pWMF >> nIndex; 648 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 649 { 650 *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle; 651 aColorRef = ReadColor(); 652 *pWMF >> elpHatch >> elpNumEntries; 653 654 LineInfo aLineInfo; 655 if ( nWidth ) 656 aLineInfo.SetWidth( nWidth ); 657 658 sal_Bool bTransparent = sal_False; 659 sal_uInt16 nDashCount = 0; 660 sal_uInt16 nDotCount = 0; 661 662 switch( nStyle & PS_STYLE_MASK ) 663 { 664 case PS_DASHDOTDOT : 665 nDotCount++; 666 case PS_DASHDOT : 667 nDashCount++; 668 case PS_DOT : 669 nDotCount++; 670 break; 671 case PS_DASH : 672 nDashCount++; 673 break; 674 case PS_NULL : 675 bTransparent = sal_True; 676 aLineInfo.SetStyle( LINE_NONE ); 677 break; 678 679 default : 680 case PS_INSIDEFRAME : 681 case PS_SOLID : 682 aLineInfo.SetStyle( LINE_SOLID ); 683 } 684 if ( nDashCount | nDotCount ) 685 { 686 aLineInfo.SetStyle( LINE_DASH ); 687 aLineInfo.SetDashCount( nDashCount ); 688 aLineInfo.SetDotCount( nDotCount ); 689 } 690 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) ); 691 } 692 } 693 break; 694 695 case EMR_CREATEBRUSHINDIRECT : 696 { 697 sal_uInt32 nStyle; 698 *pWMF >> nIndex; 699 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 700 { 701 *pWMF >> nStyle; 702 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? sal_True : sal_False ) ); 703 } 704 } 705 break; 706 707 case EMR_DELETEOBJECT : 708 { 709 *pWMF >> nIndex; 710 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 711 pOut->DeleteObject( nIndex ); 712 } 713 break; 714 715 case EMR_ELLIPSE : 716 { 717 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 718 pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 719 } 720 break; 721 722 case EMR_RECTANGLE : 723 { 724 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 725 pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 726 } 727 break; 728 729 case EMR_ROUNDRECT : 730 { 731 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH; 732 Size aSize( Size( nW, nH ) ); 733 pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize ); 734 } 735 break; 736 737 case EMR_ARC : 738 { 739 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 740 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 741 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 742 } 743 break; 744 745 case EMR_CHORD : 746 { 747 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 748 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 749 pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 750 } 751 break; 752 753 case EMR_PIE : 754 { 755 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 756 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 757 const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 )); 758 759 // #i73608# OutputDevice deviates from WMF 760 // semantics. start==end means full ellipse here. 761 if( nStartX == nEndX && nStartY == nEndY ) 762 pOut->DrawEllipse( aRect ); 763 else 764 pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 765 } 766 break; 767 768 case EMR_LINETO : 769 { 770 *pWMF >> nX32 >> nY32; 771 pOut->LineTo( Point( nX32, nY32 ), bRecordPath ); 772 } 773 break; 774 775 case EMR_ARCTO : 776 { 777 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 778 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 779 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), sal_True ); 780 } 781 break; 782 783 case EMR_BEGINPATH : 784 { 785 pOut->ClearPath(); 786 bRecordPath = sal_True; 787 } 788 break; 789 790 case EMR_ABORTPATH : 791 pOut->ClearPath(); 792 case EMR_ENDPATH : 793 bRecordPath = sal_False; 794 break; 795 796 case EMR_CLOSEFIGURE : 797 pOut->ClosePath(); 798 break; 799 800 case EMR_FILLPATH : 801 pOut->StrokeAndFillPath( sal_False, sal_True ); 802 break; 803 804 case EMR_STROKEANDFILLPATH : 805 pOut->StrokeAndFillPath( sal_True, sal_True ); 806 break; 807 808 case EMR_STROKEPATH : 809 pOut->StrokeAndFillPath( sal_True, sal_False ); 810 break; 811 812 case EMR_SELECTCLIPPATH : 813 { 814 sal_Int32 nClippingMode; 815 *pWMF >> nClippingMode; 816 pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True ); 817 } 818 break; 819 820 case EMR_EXTSELECTCLIPRGN : 821 { 822 sal_Int32 iMode, cbRgnData; 823 *pWMF >> cbRgnData 824 >> iMode; 825 826 PolyPolygon aPolyPoly; 827 if ( cbRgnData ) 828 ImplReadRegion( aPolyPoly, *pWMF, nRecSize ); 829 pOut->SetClipPath( aPolyPoly, iMode, sal_False ); 830 } 831 break; 832 case EMR_ALPHABLEND: 833 { 834 sal_Int32 xDest, yDest, cxDest, cyDest; 835 836 BLENDFUNCTION aFunc; 837 sal_Int32 xSrc, ySrc; 838 XForm xformSrc; 839 sal_uInt32 BkColorSrc,iUsageSrc ,offBmiSrc,cbBmiSrc,offBitsSrc,cbBitsSrc ,cxSrc,cySrc ; 840 841 sal_uInt32 nStart = pWMF->Tell() - 8; 842 pWMF->SeekRel( 0x10 ); 843 844 *pWMF >> xDest >> yDest >> cxDest >> cyDest >> aFunc >> xSrc >> ySrc 845 >> xformSrc >> BkColorSrc >> iUsageSrc >> offBmiSrc >> cbBmiSrc 846 >> offBitsSrc >> cbBitsSrc >>cxSrc>>cySrc ; 847 848 sal_uInt32 dwRop = SRCAND|SRCINVERT; 849 850 Bitmap aBitmap; 851 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 852 853 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 854 bStatus = sal_False; 855 else 856 { 857 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 858 if ( nSize <= ( nEndPos - nStartPos ) ) 859 { 860 char* pBuf = new char[ nSize ]; 861 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 862 aTmp.ObjectOwnsMemory( sal_True ); 863 aTmp << (sal_uInt8)'B' 864 << (sal_uInt8)'M' 865 << (sal_uInt32)cbBitsSrc 866 << (sal_uInt16)0 867 << (sal_uInt16)0 868 << (sal_uInt32)cbBmiSrc + 14; 869 pWMF->Seek( nStart + offBmiSrc ); 870 pWMF->Read( pBuf + 14, cbBmiSrc ); 871 pWMF->Seek( nStart + offBitsSrc ); 872 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 873 aTmp.Seek( 0 ); 874 aBitmap.Read( aTmp, sal_True ); 875 // test if it is sensible to crop 876 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 877 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 878 ( xSrc + static_cast< sal_Int32 >(cxSrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Width()) ) && 879 ( ySrc + static_cast< sal_Int32 >(cySrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Height()) ) ) 880 { 881 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 882 aBitmap.Crop( aCropRect ); 883 } 884 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 885 } 886 } 887 } 888 break; 889 case EMR_BITBLT : // PASSTHROUGH INTENDED 890 case EMR_STRETCHBLT : 891 { 892 sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc; 893 sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; 894 XForm xformSrc; 895 896 sal_uInt32 nStart = pWMF->Tell() - 8; 897 898 pWMF->SeekRel( 0x10 ); 899 *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc 900 >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc 901 >> offBitsSrc >> cbBitsSrc; 902 903 if ( nRecType == EMR_STRETCHBLT ) 904 *pWMF >> cxSrc >> cySrc; 905 else 906 cxSrc = cySrc = 0; 907 908 Bitmap aBitmap; 909 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 910 911 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative 912 cyDest = abs( (int)cyDest ); // and also 122889 913 914 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 915 bStatus = sal_False; 916 else 917 { 918 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 919 if ( nSize <= ( nEndPos - nStartPos ) ) 920 { 921 char* pBuf = new char[ nSize ]; 922 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 923 aTmp.ObjectOwnsMemory( sal_True ); 924 aTmp << (sal_uInt8)'B' 925 << (sal_uInt8)'M' 926 << (sal_uInt32)cbBitsSrc 927 << (sal_uInt16)0 928 << (sal_uInt16)0 929 << (sal_uInt32)cbBmiSrc + 14; 930 pWMF->Seek( nStart + offBmiSrc ); 931 pWMF->Read( pBuf + 14, cbBmiSrc ); 932 pWMF->Seek( nStart + offBitsSrc ); 933 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 934 aTmp.Seek( 0 ); 935 aBitmap.Read( aTmp, sal_True ); 936 937 // test if it is sensible to crop 938 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 939 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 940 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && 941 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) 942 { 943 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 944 aBitmap.Crop( aCropRect ); 945 } 946 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 947 } 948 } 949 } 950 break; 951 952 case EMR_STRETCHDIBITS : 953 { 954 sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; 955 sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; 956 sal_uInt32 nStart = pWMF->Tell() - 8; 957 958 pWMF->SeekRel( 0x10 ); 959 *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc 960 >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest; 961 962 Bitmap aBitmap; 963 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 964 965 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative 966 cyDest = abs( (int)cyDest ); // and also 122889 967 968 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 969 bStatus = sal_False; 970 else 971 { 972 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 973 if ( nSize <= ( nEndPos - nStartPos ) ) 974 { 975 char* pBuf = new char[ nSize ]; 976 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 977 aTmp.ObjectOwnsMemory( sal_True ); 978 aTmp << (sal_uInt8)'B' 979 << (sal_uInt8)'M' 980 << (sal_uInt32)cbBitsSrc 981 << (sal_uInt16)0 982 << (sal_uInt16)0 983 << (sal_uInt32)cbBmiSrc + 14; 984 pWMF->Seek( nStart + offBmiSrc ); 985 pWMF->Read( pBuf + 14, cbBmiSrc ); 986 pWMF->Seek( nStart + offBitsSrc ); 987 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 988 aTmp.Seek( 0 ); 989 aBitmap.Read( aTmp, sal_True ); 990 991 // test if it is sensible to crop 992 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 993 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 994 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && 995 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) 996 { 997 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 998 aBitmap.Crop( aCropRect ); 999 } 1000 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 1001 } 1002 } 1003 } 1004 break; 1005 1006 case EMR_EXTCREATEFONTINDIRECTW : 1007 { 1008 *pWMF >> nIndex; 1009 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 1010 { 1011 LOGFONTW aLogFont; 1012 *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic 1013 >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision 1014 >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily; 1015 1016 sal_Unicode lfFaceName[ LF_FACESIZE ]; 1017 1018 for ( int i = 0; i < LF_FACESIZE; i++ ) 1019 { 1020 sal_uInt16 nChar; 1021 *pWMF >> nChar; 1022 lfFaceName[ i ] = nChar; 1023 } 1024 aLogFont.alfFaceName = UniString( lfFaceName ); 1025 1026 // #121382# Need to apply WorldTransform to FontHeight/Width; this should be completely 1027 // chnaged to basegfx::B2DHomMatrix instead of 'struct XForm', but not now due to time 1028 // constraints and dangers 1029 const XForm& rXF = pOut->GetWorldTransform(); 1030 const basegfx::B2DHomMatrix aWT(rXF.eM11, rXF.eM21, rXF.eDx, rXF.eM12, rXF.eM22, rXF.eDy); 1031 const basegfx::B2DVector aTransVec(aWT * basegfx::B2DVector(aLogFont.lfWidth, aLogFont.lfHeight)); 1032 aLogFont.lfWidth = aTransVec.getX(); 1033 aLogFont.lfHeight = aTransVec.getY(); 1034 1035 pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) ); 1036 } 1037 } 1038 break; 1039 1040 case EMR_EXTTEXTOUTA : 1041 bFlag = sal_True; 1042 case EMR_EXTTEXTOUTW : 1043 { 1044 sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale; 1045 sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx; 1046 sal_Int32* pDX = NULL; 1047 1048 nCurPos = pWMF->Tell() - 8; 1049 1050 *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale 1051 >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions; 1052 1053 pWMF->SeekRel( 0x10 ); 1054 *pWMF >> offDx; 1055 1056 sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT; 1057 if ( nOptions & ETO_RTLREADING ) 1058 nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; 1059 pOut->SetTextLayoutMode( nTextLayoutMode ); 1060 DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" ); 1061 1062 Point aPos( ptlReferenceX, ptlReferenceY ); 1063 if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) ) 1064 { 1065 if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) ) 1066 { 1067 pWMF->Seek( nCurPos + offDx ); 1068 if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) ) 1069 { 1070 pDX = new sal_Int32[ nLen ]; 1071 sal_uInt32 i; 1072 for ( i = 0; i < nLen; i++ ) 1073 *pWMF >> pDX[ i ]; 1074 } 1075 } 1076 pWMF->Seek( nCurPos + nOffString ); 1077 String aText; 1078 if ( bFlag ) 1079 { 1080 if ( nLen <= ( nEndPos - pWMF->Tell() ) ) 1081 { 1082 sal_Char* pBuf = new sal_Char[ nLen ]; 1083 pWMF->Read( pBuf, nLen ); 1084 aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() ); 1085 delete[] pBuf; 1086 1087 if ( aText.Len() != nLen ) 1088 { 1089 sal_uInt16 i, j, k; 1090 sal_Int32* pOldDx = pDX; 1091 pDX = new sal_Int32[ aText.Len() ]; 1092 for ( i = 0, j = 0; i < aText.Len(); i++ ) 1093 { 1094 ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() ); 1095 pDX[ i ] = 0; 1096 for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ ) 1097 pDX[ i ] += pOldDx[ j++ ]; 1098 } 1099 delete[] pOldDx; 1100 } 1101 } 1102 } 1103 else 1104 { 1105 if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) ) 1106 { 1107 sal_Unicode* pBuf = new sal_Unicode[ nLen ]; 1108 pWMF->Read( pBuf, nLen << 1 ); 1109 #ifdef OSL_BIGENDIAN 1110 sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen ); 1111 while ( pTmp-- != (sal_Char*)pBuf ) 1112 { 1113 nTmp = *pTmp--; 1114 pTmp[ 1 ] = *pTmp; 1115 *pTmp = nTmp; 1116 } 1117 #endif 1118 aText = String( pBuf, (xub_StrLen)nLen ); 1119 delete[] pBuf; 1120 } 1121 } 1122 pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode ); 1123 } 1124 delete[] pDX; 1125 } 1126 break; 1127 1128 case EMR_POLYBEZIERTO16 : 1129 bFlag = sal_True; 1130 case EMR_POLYBEZIER16 : 1131 { 1132 pWMF->SeekRel( 16 ); 1133 *pWMF >> nPoints; 1134 sal_uInt16 i = 0; 1135 if ( bFlag ) 1136 { 1137 i++; 1138 nPoints++; 1139 } 1140 Polygon aPoly( (sal_uInt16)nPoints ); 1141 for( ; i < (sal_uInt16)nPoints; i++ ) 1142 { 1143 *pWMF >> nX16 >> nY16; 1144 aPoly[ i ] = Point( nX16, nY16 ); 1145 } 1146 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag ); 1147 } 1148 break; 1149 1150 case EMR_POLYGON16 : 1151 { 1152 pWMF->SeekRel( 16 ); 1153 *pWMF >> nPoints; 1154 Polygon aPoly( (sal_uInt16)nPoints ); 1155 for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) 1156 { 1157 *pWMF >> nX16 >> nY16; 1158 aPoly[ k ] = Point( nX16, nY16 ); 1159 } 1160 pOut->DrawPolygon( aPoly, bRecordPath ); 1161 } 1162 break; 1163 1164 case EMR_POLYLINETO16 : 1165 bFlag = sal_True; 1166 case EMR_POLYLINE16 : 1167 { 1168 pWMF->SeekRel( 16 ); 1169 *pWMF >> nPoints; 1170 sal_uInt16 i = 0; 1171 if ( bFlag ) 1172 { 1173 i++; 1174 nPoints++; 1175 } 1176 1177 Polygon aPoly( (sal_uInt16)nPoints ); 1178 for( ; i < (sal_uInt16)nPoints; i++ ) 1179 { 1180 *pWMF >> nX16 >> nY16; 1181 aPoly[ i ] = Point( nX16, nY16 ); 1182 } 1183 pOut->DrawPolyLine( aPoly, bFlag, bRecordPath ); 1184 } 1185 break; 1186 1187 case EMR_POLYPOLYLINE16 : 1188 { 1189 sal_uInt16* pnPoints; 1190 1191 sal_Int32 i, nPoly, nGesPoints; 1192 pWMF->SeekRel( 0x10 ); 1193 // Anzahl der Polygone: 1194 *pWMF >> nPoly >> nGesPoints; 1195 1196 // taking the amount of points of each polygon, retrieving the total number of points 1197 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) 1198 { 1199 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 1200 { 1201 pnPoints = new sal_uInt16[ nPoly ]; 1202 for ( i = 0; i < nPoly; i++ ) 1203 { 1204 *pWMF >> nPoints; 1205 pnPoints[ i ] = (sal_uInt16)nPoints; 1206 } 1207 // Polygonpunkte holen: 1208 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) 1209 { 1210 Polygon aPolygon( pnPoints[ i ] ); 1211 for ( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) 1212 { 1213 *pWMF >> nX16 >> nY16; 1214 aPolygon[ k ] = Point( nX16, nY16 ); 1215 } 1216 pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath ); 1217 } 1218 delete[] pnPoints; 1219 } 1220 } 1221 } 1222 break; 1223 1224 case EMR_POLYPOLYGON16 : 1225 { 1226 sal_uInt32 nPoly(0); 1227 sal_uInt32 nGesPoints(0); 1228 pWMF->SeekRel( 0x10 ); 1229 // Anzahl der Polygone: 1230 *pWMF >> nPoly >> nGesPoints; 1231 sal_uInt32 nReadPoints(0); 1232 1233 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) 1234 { 1235 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) ) 1236 { 1237 sal_uInt32 i(0); 1238 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 1239 1240 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 1241 { 1242 *pWMF >> nPoints; 1243 pnPoints[ i ] = (sal_uInt16)nPoints; 1244 } 1245 1246 if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof() ) 1247 { 1248 PolyPolygon aPolyPoly(nPoly, nPoly); 1249 1250 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 1251 { 1252 const sal_uInt16 nPointCount(pnPoints[i]); 1253 Point* pPtAry = new Point[nPointCount]; 1254 1255 for(sal_uInt16 b(0); b < nPointCount && !pWMF->IsEof(); b++) 1256 { 1257 *pWMF >> nX16 >> nY16; 1258 pPtAry[b] = Point( nX16, nY16 ); 1259 nReadPoints++; 1260 } 1261 1262 aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); 1263 delete[] pPtAry; 1264 } 1265 1266 // create PolyPolygon actions 1267 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); 1268 } 1269 1270 delete[] pnPoints; 1271 } 1272 } 1273 1274 OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON16 is unequal imported number (!)"); 1275 } 1276 break; 1277 1278 case EMR_FILLRGN : 1279 { 1280 sal_uInt32 nLen; 1281 PolyPolygon aPolyPoly; 1282 pWMF->SeekRel( 0x10 ); 1283 *pWMF >> nLen >> nIndex; 1284 1285 if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) ) 1286 { 1287 pOut->Push(); 1288 pOut->SelectObject( nIndex ); 1289 pOut->DrawPolyPolygon( aPolyPoly, sal_False ); 1290 pOut->Pop(); 1291 } 1292 } 1293 break; 1294 case EMR_CREATEDIBPATTERNBRUSHPT : 1295 { 1296 sal_uInt32 nTmp32; 1297 sal_uInt32 nOffset; 1298 *pWMF >> nIndex; 1299 Bitmap aBmp; 1300 BitmapReadAccess* pBmp; 1301 sal_uInt32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1; 1302 1303 *pWMF >> nTmp32; 1304 *pWMF >> nOffset; 1305 for ( sal_uInt32 i = 0; i < (nOffset - 20)/4; i ++ ) 1306 { 1307 *pWMF >> nTmp32; 1308 } 1309 1310 aBmp.Read( *pWMF, sal_False ); 1311 pBmp = aBmp.AcquireReadAccess(); 1312 if ( pBmp ) 1313 { 1314 for ( sal_Int32 y = 0; y < pBmp->Height(); y++ ) 1315 { 1316 for ( sal_Int32 x = 0; x < pBmp->Width(); x++ ) 1317 { 1318 const BitmapColor aColor( pBmp->GetColor( y, x ) ); 1319 1320 nRed += aColor.GetRed(); 1321 nGreen += aColor.GetGreen(); 1322 nBlue += aColor.GetBlue(); 1323 } 1324 } 1325 nCount = pBmp->Height() * pBmp->Width(); 1326 if ( !nCount ) 1327 nCount++; 1328 aBmp.ReleaseAccess( pBmp ); 1329 } 1330 Color aColor( (sal_Char)( nRed / nCount ), (sal_Char)( nGreen / nCount ), (sal_Char)( nBlue / nCount ) ); 1331 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aColor, sal_False ) ); 1332 } 1333 break; 1334 1335 #ifdef WIN_MTF_ASSERT 1336 default : WinMtfAssertHandler( "Unknown Meta Action" ); break; 1337 case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break; 1338 case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break; 1339 case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break; 1340 case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break; 1341 case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break; 1342 case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break; 1343 case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break; 1344 case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break; 1345 case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break; 1346 case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break; 1347 case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break; 1348 case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break; 1349 case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break; 1350 case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break; 1351 case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break; 1352 case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break; 1353 case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break; 1354 case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break; 1355 case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break; 1356 case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break; 1357 case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break; 1358 case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break; 1359 case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break; 1360 case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break; 1361 case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break; 1362 case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break; 1363 case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break; 1364 case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break; 1365 case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break; 1366 case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break; 1367 case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break; 1368 case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break; 1369 case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break; 1370 case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break; 1371 case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break; 1372 case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break; 1373 case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break; 1374 1375 case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break; 1376 case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break; 1377 case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break; 1378 case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break; 1379 case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break; 1380 case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break; 1381 case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break; 1382 case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break; 1383 case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break; 1384 case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break; 1385 case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break; 1386 case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break; 1387 1388 case EMR_GDICOMMENT : 1389 case EMR_HEADER : // has already been read at ReadHeader() 1390 break; 1391 #endif 1392 } 1393 pWMF->Seek( nNextPos ); 1394 } 1395 if( aBmpSaveList.Count() ) 1396 pOut->ResolveBitmapActions( aBmpSaveList ); 1397 1398 if ( bStatus ) 1399 pWMF->Seek(nEndPos); 1400 1401 return bStatus; 1402 }; 1403 1404 //----------------------------------------------------------------------------------- 1405 1406 sal_Bool EnhWMFReader::ReadHeader() 1407 { 1408 sal_uInt32 nsal_uInt32, nHeaderSize, nPalEntries; 1409 sal_Int32 nLeft, nTop, nRight, nBottom; 1410 1411 // METAFILEHEADER SPARE ICH MIR HIER 1412 // Einlesen des METAHEADER 1413 *pWMF >> nsal_uInt32 >> nHeaderSize; 1414 if ( nsal_uInt32 != 1 ) // Typ 1415 return sal_False; 1416 1417 // bound size 1418 Rectangle rclBounds; // rectangle in logical units 1/100th mm 1419 *pWMF >> nLeft >> nTop >> nRight >> nBottom; 1420 rclBounds.Left() = nLeft; 1421 rclBounds.Top() = nTop; 1422 rclBounds.Right() = nRight; 1423 rclBounds.Bottom() = nBottom; 1424 1425 // picture frame size 1426 Rectangle rclFrame; // rectangle in device units 1427 *pWMF >> nLeft >> nTop >> nRight >> nBottom; 1428 rclFrame.Left() = nLeft; 1429 rclFrame.Top() = nTop; 1430 rclFrame.Right() = nRight; 1431 rclFrame.Bottom() = nBottom; 1432 1433 *pWMF >> nsal_uInt32; // signature 1434 1435 if ( nsal_uInt32 != 0x464d4520 ) 1436 return sal_False; 1437 1438 *pWMF >> nsal_uInt32; // nVersion 1439 *pWMF >> nEndPos; // size of metafile 1440 nEndPos += nStartPos; 1441 1442 sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid 1443 pWMF->Seek( STREAM_SEEK_TO_END ); 1444 if ( pWMF->Tell() < nEndPos ) 1445 nEndPos = pWMF->Tell(); 1446 pWMF->Seek( nStrmPos ); 1447 1448 *pWMF >> nRecordCount; 1449 1450 if ( !nRecordCount ) 1451 return sal_False; 1452 1453 pWMF->SeekRel( 0xc ); 1454 1455 sal_Int32 nPixX, nPixY, nMillX, nMillY; 1456 *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY; 1457 1458 pOut->SetrclFrame( rclFrame ); 1459 pOut->SetrclBounds( rclBounds ); 1460 pOut->SetRefPix( Size( nPixX, nPixY ) ); 1461 pOut->SetRefMill( Size( nMillX, nMillY ) ); 1462 1463 pWMF->Seek( nStartPos + nHeaderSize ); 1464 return sal_True; 1465 } 1466 1467 //----------------------------------------------------------------------------------- 1468 1469 Rectangle EnhWMFReader::ReadRectangle( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) 1470 { 1471 Point aTL ( Point( x1, y1 ) ); 1472 Point aBR( Point( --x2, --y2 ) ); 1473 return Rectangle( aTL, aBR ); 1474 } 1475 1476 EnhWMFReader::~EnhWMFReader() 1477 { 1478 1479 }; 1480