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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_svtools.hxx" 24 25 #include "winmtf.hxx" 26 #include <osl/endian.h> 27 #include <basegfx/matrix/b2dhommatrix.hxx> 28 #include <vcl/dibtools.hxx> 29 30 //=========================== GDI-Array =================================== 31 32 #define EMR_HEADER 1 33 #define EMR_POLYBEZIER 2 34 #define EMR_POLYGON 3 35 #define EMR_POLYLINE 4 36 #define EMR_POLYBEZIERTO 5 37 #define EMR_POLYLINETO 6 38 #define EMR_POLYPOLYLINE 7 39 #define EMR_POLYPOLYGON 8 40 #define EMR_SETWINDOWEXTEX 9 41 #define EMR_SETWINDOWORGEX 10 42 #define EMR_SETVIEWPORTEXTEX 11 43 #define EMR_SETVIEWPORTORGEX 12 44 #define EMR_SETBRUSHORGEX 13 45 #define EMR_EOF 14 46 #define EMR_SETPIXELV 15 47 #define EMR_SETMAPPERFLAGS 16 48 #define EMR_SETMAPMODE 17 49 #define EMR_SETBKMODE 18 50 #define EMR_SETPOLYFILLMODE 19 51 #define EMR_SETROP2 20 52 #define EMR_SETSTRETCHBLTMODE 21 53 #define EMR_SETTEXTALIGN 22 54 #define EMR_SETCOLORADJUSTMENT 23 55 #define EMR_SETTEXTCOLOR 24 56 #define EMR_SETBKCOLOR 25 57 #define EMR_OFFSETCLIPRGN 26 58 #define EMR_MOVETOEX 27 59 #define EMR_SETMETARGN 28 60 #define EMR_EXCLUDECLIPRECT 29 61 #define EMR_INTERSECTCLIPRECT 30 62 #define EMR_SCALEVIEWPORTEXTEX 31 63 #define EMR_SCALEWINDOWEXTEX 32 64 #define EMR_SAVEDC 33 65 #define EMR_RESTOREDC 34 66 #define EMR_SETWORLDTRANSFORM 35 67 #define EMR_MODIFYWORLDTRANSFORM 36 68 #define EMR_SELECTOBJECT 37 69 #define EMR_CREATEPEN 38 70 #define EMR_CREATEBRUSHINDIRECT 39 71 #define EMR_DELETEOBJECT 40 72 #define EMR_ANGLEARC 41 73 #define EMR_ELLIPSE 42 74 #define EMR_RECTANGLE 43 75 #define EMR_ROUNDRECT 44 76 #define EMR_ARC 45 77 #define EMR_CHORD 46 78 #define EMR_PIE 47 79 #define EMR_SELECTPALETTE 48 80 #define EMR_CREATEPALETTE 49 81 #define EMR_SETPALETTEENTRIES 50 82 #define EMR_RESIZEPALETTE 51 83 #define EMR_REALIZEPALETTE 52 84 #define EMR_EXTFLOODFILL 53 85 #define EMR_LINETO 54 86 #define EMR_ARCTO 55 87 #define EMR_POLYDRAW 56 88 #define EMR_SETARCDIRECTION 57 89 #define EMR_SETMITERLIMIT 58 90 #define EMR_BEGINPATH 59 91 #define EMR_ENDPATH 60 92 #define EMR_CLOSEFIGURE 61 93 #define EMR_FILLPATH 62 94 #define EMR_STROKEANDFILLPATH 63 95 #define EMR_STROKEPATH 64 96 #define EMR_FLATTENPATH 65 97 #define EMR_WIDENPATH 66 98 #define EMR_SELECTCLIPPATH 67 99 #define EMR_ABORTPATH 68 100 101 #define EMR_GDICOMMENT 70 102 #define EMR_FILLRGN 71 103 #define EMR_FRAMERGN 72 104 #define EMR_INVERTRGN 73 105 #define EMR_PAINTRGN 74 106 #define EMR_EXTSELECTCLIPRGN 75 107 #define EMR_BITBLT 76 108 #define EMR_STRETCHBLT 77 109 #define EMR_MASKBLT 78 110 #define EMR_PLGBLT 79 111 #define EMR_SETDIBITSTODEVICE 80 112 #define EMR_STRETCHDIBITS 81 113 #define EMR_EXTCREATEFONTINDIRECTW 82 114 #define EMR_EXTTEXTOUTA 83 115 #define EMR_EXTTEXTOUTW 84 116 #define EMR_POLYBEZIER16 85 117 #define EMR_POLYGON16 86 118 #define EMR_POLYLINE16 87 119 #define EMR_POLYBEZIERTO16 88 120 #define EMR_POLYLINETO16 89 121 #define EMR_POLYPOLYLINE16 90 122 #define EMR_POLYPOLYGON16 91 123 #define EMR_POLYDRAW16 92 124 #define EMR_CREATEMONOBRUSH 93 125 #define EMR_CREATEDIBPATTERNBRUSHPT 94 126 #define EMR_EXTCREATEPEN 95 127 #define EMR_POLYTEXTOUTA 96 128 #define EMR_POLYTEXTOUTW 97 129 130 // WINDOWS VERSION >= 0x400 131 #define EMR_SETICMMODE 98 132 #define EMR_CREATECOLORSPACE 99 133 #define EMR_SETCOLORSPACE 100 134 #define EMR_DELETECOLORSPACE 101 135 #define EMR_GLSRECORD 102 136 #define EMR_GLSBOUNDEDRECORD 103 137 #define EMR_PIXELFORMAT 104 138 139 // WINDOWS VERSION >= 0x500 140 #define EMR_DRAWESCAPE 105 141 #define EMR_EXTESCAPE 106 142 #define EMR_STARTDOC 107 143 #define EMR_SMALLTEXTOUT 108 144 #define EMR_FORCEUFIMAPPING 109 145 #define EMR_NAMEDESCAPE 110 146 #define EMR_COLORCORRECTPALETTE 111 147 #define EMR_SETICMPROFILEA 112 148 #define EMR_SETICMPROFILEW 113 149 #define EMR_ALPHABLEND 114 150 #define EMR_ALPHADIBBLEND 115 151 #define EMR_TRANSPARENTBLT 116 152 #define EMR_TRANSPARENTDIB 117 153 #define EMR_GRADIENTFILL 118 154 #define EMR_SETLINKEDUFIS 119 155 #define EMR_SETTEXTJUSTIFICATION 120 156 157 158 //----------------------------------------------------------------------------------- 159 160 #ifdef OSL_BIGENDIAN 161 // currently unused 162 static float GetSwapFloat( SvStream& rSt ) 163 { 164 float fTmp; 165 sal_Int8* pPtr = (sal_Int8*)&fTmp; 166 rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch 167 return fTmp; 168 } 169 #endif 170 171 struct BLENDFUNCTION{ 172 unsigned char aBlendOperation; 173 unsigned char aBlendFlags; 174 unsigned char aSrcConstantAlpha; 175 unsigned char aAlphaFormat; 176 177 friend SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ); 178 }; 179 180 SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun ) 181 { 182 rIn >> rBlendFun.aBlendOperation >> rBlendFun.aBlendFlags >> 183 rBlendFun.aSrcConstantAlpha >> rBlendFun.aAlphaFormat; 184 return rIn; 185 } 186 SvStream& operator>>( SvStream& rIn, XForm& rXForm ) 187 { 188 if ( sizeof( float ) != 4 ) 189 { 190 DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" ); 191 rXForm = XForm(); 192 } 193 else 194 { 195 #ifdef OSL_BIGENDIAN 196 rXForm.eM11 = GetSwapFloat( rIn ); 197 rXForm.eM12 = GetSwapFloat( rIn ); 198 rXForm.eM21 = GetSwapFloat( rIn ); 199 rXForm.eM22 = GetSwapFloat( rIn ); 200 rXForm.eDx = GetSwapFloat( rIn ); 201 rXForm.eDy = GetSwapFloat( rIn ); 202 #else 203 rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22 204 >> rXForm.eDx >> rXForm.eDy; 205 #endif 206 } 207 return rIn; 208 } 209 210 static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen ) 211 { 212 sal_Bool bOk = sal_False; 213 if ( nLen ) 214 { 215 sal_uInt32 nHdSize, nType, nCount, nRgnSize, i; 216 rSt >> nHdSize 217 >> nType 218 >> nCount 219 >> nRgnSize; 220 221 if ( nCount && ( nType == RDH_RECTANGLES ) && 222 ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) ) 223 { 224 sal_Int32 nx1, ny1, nx2, ny2; 225 226 for ( i = 0; i < nCount; i++ ) 227 { 228 rSt >> nx1 >> ny1 >> nx2 >> ny2; 229 230 Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) ); 231 Polygon aPolygon( aRect ); 232 PolyPolygon aPolyPolyOr1( aPolygon ); 233 PolyPolygon aPolyPolyOr2( rPolyPoly ); 234 rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 ); 235 rPolyPoly = aPolyPolyOr2; 236 } 237 bOk = sal_True; 238 } 239 } 240 return bOk; 241 } 242 243 sal_Bool EnhWMFReader::ReadEnhWMF() 244 { 245 sal_uInt32 nStretchBltMode = 0; 246 sal_uInt32 nRecType, nRecSize, nNextPos, 247 nW, nH, nPoints, nColor, nIndex, 248 nDat32, nNom1, nDen1, nNom2, nDen2; 249 sal_Int32 nX32, nY32, nx32, ny32; 250 sal_Int16 nX16, nY16; 251 252 sal_Bool bFlag, bStatus = ReadHeader(); 253 254 while( bStatus && nRecordCount-- ) 255 { 256 *pWMF >> nRecType >> nRecSize; 257 258 if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar 259 { 260 bStatus = sal_False; 261 break; 262 } 263 264 nNextPos = pWMF->Tell() + ( nRecSize - 8 ); 265 266 if ( nNextPos > nEndPos ) 267 { 268 bStatus = sal_False; 269 break; 270 } 271 272 if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) ) 273 pOut->ResolveBitmapActions( aBmpSaveList ); 274 275 bFlag = sal_False; 276 277 switch( nRecType ) 278 { 279 case EMR_POLYBEZIERTO : 280 bFlag = sal_True; 281 case EMR_POLYBEZIER : 282 { 283 pWMF->SeekRel( 16 ); 284 *pWMF >> nPoints; 285 sal_uInt16 i = 0; 286 if ( bFlag ) 287 { 288 i++; 289 nPoints++; 290 } 291 Polygon aPoly( (sal_uInt16)nPoints ); 292 for( ; i < (sal_uInt16)nPoints; i++ ) 293 { 294 *pWMF >> nX32 >> nY32; 295 aPoly[ i ] = Point( nX32, nY32 ); 296 } 297 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); 298 } 299 break; 300 301 case EMR_POLYGON : 302 { 303 pWMF->SeekRel( 16 ); 304 *pWMF >> nPoints; 305 Polygon aPoly( (sal_uInt16)nPoints ); 306 for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) 307 { 308 *pWMF >> nX32 >> nY32; 309 aPoly[ k ] = Point( nX32, nY32 ); 310 } 311 pOut->DrawPolygon( aPoly, bRecordPath ); 312 } 313 break; 314 315 case EMR_POLYLINETO : 316 bFlag = sal_True; 317 case EMR_POLYLINE : 318 { 319 pWMF->SeekRel( 0x10 ); 320 *pWMF >> nPoints; 321 sal_uInt16 i = 0; 322 if ( bFlag ) 323 { 324 i++; 325 nPoints++; 326 } 327 Polygon aPolygon( (sal_uInt16)nPoints ); 328 for ( ; i < (sal_uInt16)nPoints; i++ ) 329 { 330 *pWMF >> nX32 >> nY32; 331 aPolygon[ i ] = Point( nX32, nY32 ); 332 } 333 pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath ); 334 } 335 break; 336 337 case EMR_POLYPOLYLINE : 338 { 339 sal_Int32 i, nPoly; 340 pWMF->SeekRel( 0x10 ); 341 342 // Anzahl der Polygone: 343 *pWMF >> nPoly >> i; 344 345 // taking the amount of points of each polygon, retrieving the total number of points 346 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) 347 { 348 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 349 { 350 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 351 352 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 353 { 354 *pWMF >> nPoints; 355 pnPoints[ i ] = (sal_uInt16)nPoints; 356 } 357 358 // Polygonpunkte holen: 359 360 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) 361 { 362 Polygon aPoly( pnPoints[ i ] ); 363 for( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) 364 { 365 *pWMF >> nX32 >> nY32; 366 aPoly[ k ] = Point( nX32, nY32 ); 367 } 368 pOut->DrawPolyLine( aPoly, sal_False, bRecordPath ); 369 } 370 delete[] pnPoints; 371 } 372 } 373 } 374 break; 375 376 case EMR_POLYPOLYGON : 377 { 378 sal_uInt32 nPoly(0); 379 sal_uInt32 nGesPoints(0); 380 sal_uInt32 nReadPoints(0); 381 pWMF->SeekRel( 0x10 ); 382 383 // Anzahl der Polygone: 384 *pWMF >> nPoly >> nGesPoints; 385 386 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) 387 { 388 if ( ( nPoly * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 389 { 390 sal_uInt32 i(0); 391 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 392 393 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 394 { 395 *pWMF >> nPoints; 396 pnPoints[ i ] = (sal_uInt16)nPoints; 397 } 398 399 if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof()) 400 { 401 PolyPolygon aPolyPoly(nPoly, nPoly); 402 403 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 404 { 405 const sal_uInt16 nPointCount(pnPoints[i]); 406 Point* pPtAry = new Point[nPointCount]; 407 408 for(sal_uInt16 j(0); j < nPointCount && !pWMF->IsEof(); j++) 409 { 410 *pWMF >> nX32 >> nY32; 411 pPtAry[ j ] = Point( nX32, nY32 ); 412 nReadPoints++; 413 } 414 415 aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); 416 delete[] pPtAry; 417 } 418 419 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); 420 } 421 422 delete[] pnPoints; 423 } 424 } 425 426 OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)"); 427 } 428 break; 429 430 case EMR_SETWINDOWEXTEX : 431 { // #75383# 432 *pWMF >> nW >> nH; 433 pOut->SetWinExt( Size( nW, nH ) ); 434 } 435 break; 436 437 case EMR_SETWINDOWORGEX : 438 { 439 *pWMF >> nX32 >> nY32; 440 pOut->SetWinOrg( Point( nX32, nY32 ) ); 441 } 442 break; 443 444 case EMR_SCALEWINDOWEXTEX : 445 { 446 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; 447 pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); 448 } 449 break; 450 451 case EMR_SETVIEWPORTORGEX : 452 { 453 *pWMF >> nX32 >> nY32; 454 pOut->SetDevOrg( Point( nX32, nY32 ) ); 455 } 456 break; 457 458 case EMR_SCALEVIEWPORTEXTEX : 459 { 460 *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; 461 pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); 462 } 463 break; 464 465 case EMR_SETVIEWPORTEXTEX : 466 { 467 *pWMF >> nW >> nH; 468 pOut->SetDevExt( Size( nW, nH ) ); 469 } 470 break; 471 472 case EMR_EOF : 473 nRecordCount = 0; // #76846# 474 break; 475 476 case EMR_SETPIXELV : 477 { 478 *pWMF >> nX32 >> nY32; 479 pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() ); 480 } 481 break; 482 483 case EMR_SETMAPMODE : 484 { 485 sal_uInt32 nMapMode; 486 *pWMF >> nMapMode; 487 pOut->SetMapMode( nMapMode ); 488 } 489 break; 490 491 case EMR_SETBKMODE : 492 { 493 *pWMF >> nDat32; 494 pOut->SetBkMode( nDat32 ); 495 } 496 break; 497 498 case EMR_SETPOLYFILLMODE : 499 break; 500 501 case EMR_SETROP2 : 502 { 503 *pWMF >> nDat32; 504 pOut->SetRasterOp( nDat32 ); 505 } 506 break; 507 508 case EMR_SETSTRETCHBLTMODE : 509 { 510 *pWMF >> nStretchBltMode; 511 } 512 break; 513 514 case EMR_SETTEXTALIGN : 515 { 516 *pWMF >> nDat32; 517 pOut->SetTextAlign( nDat32 ); 518 } 519 break; 520 521 case EMR_SETTEXTCOLOR : 522 { 523 pOut->SetTextColor( ReadColor() ); 524 } 525 break; 526 527 case EMR_SETBKCOLOR : 528 { 529 pOut->SetBkColor( ReadColor() ); 530 } 531 break; 532 533 case EMR_OFFSETCLIPRGN : 534 { 535 *pWMF >> nX32 >> nY32; 536 pOut->MoveClipRegion( Size( nX32, nY32 ) ); 537 } 538 break; 539 540 case EMR_MOVETOEX : 541 { 542 *pWMF >> nX32 >> nY32; 543 pOut->MoveTo( Point( nX32, nY32 ), bRecordPath ); 544 } 545 break; 546 547 case EMR_INTERSECTCLIPRECT : 548 { 549 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 550 pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 551 } 552 break; 553 554 case EMR_SAVEDC : 555 { 556 pOut->Push(); 557 } 558 break; 559 560 case EMR_RESTOREDC : 561 { 562 pOut->Pop(); 563 } 564 break; 565 566 case EMR_SETWORLDTRANSFORM : 567 { 568 XForm aTempXForm; 569 *pWMF >> aTempXForm; 570 pOut->SetWorldTransform( aTempXForm ); 571 } 572 break; 573 574 case EMR_MODIFYWORLDTRANSFORM : 575 { 576 sal_uInt32 nMode; 577 XForm aTempXForm; 578 *pWMF >> aTempXForm >> nMode; 579 pOut->ModifyWorldTransform( aTempXForm, nMode ); 580 } 581 break; 582 583 case EMR_SELECTOBJECT : 584 { 585 *pWMF >> nIndex; 586 pOut->SelectObject( nIndex ); 587 } 588 break; 589 590 case EMR_CREATEPEN : 591 { 592 *pWMF >> nIndex; 593 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 594 { 595 596 LineInfo aLineInfo; 597 sal_uInt32 nStyle; 598 Size aSize; 599 600 *pWMF >> nStyle >> aSize.Width() >> aSize.Height(); 601 602 if ( aSize.Width() ) 603 aLineInfo.SetWidth( aSize.Width() ); 604 605 sal_Bool bTransparent = sal_False; 606 sal_uInt16 nDashCount = 0; 607 sal_uInt16 nDotCount = 0; 608 switch( nStyle ) 609 { 610 case PS_DASHDOTDOT : 611 nDotCount++; 612 case PS_DASHDOT : 613 nDashCount++; 614 case PS_DOT : 615 nDotCount++; 616 break; 617 case PS_DASH : 618 nDashCount++; 619 break; 620 case PS_NULL : 621 bTransparent = sal_True; 622 aLineInfo.SetStyle( LINE_NONE ); 623 break; 624 default : 625 case PS_INSIDEFRAME : 626 case PS_SOLID : 627 aLineInfo.SetStyle( LINE_SOLID ); 628 } 629 if ( nDashCount | nDotCount ) 630 { 631 aLineInfo.SetStyle( LINE_DASH ); 632 aLineInfo.SetDashCount( nDashCount ); 633 aLineInfo.SetDotCount( nDotCount ); 634 } 635 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) ); 636 } 637 } 638 break; 639 640 case EMR_EXTCREATEPEN : 641 { 642 sal_Int32 elpHatch; 643 sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; 644 Color aColorRef; 645 646 *pWMF >> nIndex; 647 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 648 { 649 *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle; 650 aColorRef = ReadColor(); 651 *pWMF >> elpHatch >> elpNumEntries; 652 653 LineInfo aLineInfo; 654 if ( nWidth ) 655 aLineInfo.SetWidth( nWidth ); 656 657 sal_Bool bTransparent = sal_False; 658 sal_uInt16 nDashCount = 0; 659 sal_uInt16 nDotCount = 0; 660 661 switch( nStyle & PS_STYLE_MASK ) 662 { 663 case PS_DASHDOTDOT : 664 nDotCount++; 665 case PS_DASHDOT : 666 nDashCount++; 667 case PS_DOT : 668 nDotCount++; 669 break; 670 case PS_DASH : 671 nDashCount++; 672 break; 673 case PS_NULL : 674 bTransparent = sal_True; 675 aLineInfo.SetStyle( LINE_NONE ); 676 break; 677 678 default : 679 case PS_INSIDEFRAME : 680 case PS_SOLID : 681 aLineInfo.SetStyle( LINE_SOLID ); 682 } 683 if ( nDashCount | nDotCount ) 684 { 685 aLineInfo.SetStyle( LINE_DASH ); 686 aLineInfo.SetDashCount( nDashCount ); 687 aLineInfo.SetDotCount( nDotCount ); 688 } 689 pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) ); 690 } 691 } 692 break; 693 694 case EMR_CREATEBRUSHINDIRECT : 695 { 696 sal_uInt32 nStyle; 697 *pWMF >> nIndex; 698 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 699 { 700 *pWMF >> nStyle; 701 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? sal_True : sal_False ) ); 702 } 703 } 704 break; 705 706 case EMR_DELETEOBJECT : 707 { 708 *pWMF >> nIndex; 709 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 710 pOut->DeleteObject( nIndex ); 711 } 712 break; 713 714 case EMR_ELLIPSE : 715 { 716 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 717 pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 718 } 719 break; 720 721 case EMR_RECTANGLE : 722 { 723 *pWMF >> nX32 >> nY32 >> nx32 >> ny32; 724 pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); 725 } 726 break; 727 728 case EMR_ROUNDRECT : 729 { 730 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH; 731 Size aSize( Size( nW, nH ) ); 732 pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize ); 733 } 734 break; 735 736 case EMR_ARC : 737 { 738 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 739 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 740 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 741 } 742 break; 743 744 case EMR_CHORD : 745 { 746 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 747 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 748 pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 749 } 750 break; 751 752 case EMR_PIE : 753 { 754 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 755 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 756 const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 )); 757 758 // #i73608# OutputDevice deviates from WMF 759 // semantics. start==end means full ellipse here. 760 if( nStartX == nEndX && nStartY == nEndY ) 761 pOut->DrawEllipse( aRect ); 762 else 763 pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); 764 } 765 break; 766 767 case EMR_LINETO : 768 { 769 *pWMF >> nX32 >> nY32; 770 pOut->LineTo( Point( nX32, nY32 ), bRecordPath ); 771 } 772 break; 773 774 case EMR_ARCTO : 775 { 776 sal_uInt32 nStartX, nStartY, nEndX, nEndY; 777 *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; 778 pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), sal_True ); 779 } 780 break; 781 782 case EMR_BEGINPATH : 783 { 784 pOut->ClearPath(); 785 bRecordPath = sal_True; 786 } 787 break; 788 789 case EMR_ABORTPATH : 790 pOut->ClearPath(); 791 case EMR_ENDPATH : 792 bRecordPath = sal_False; 793 break; 794 795 case EMR_CLOSEFIGURE : 796 pOut->ClosePath(); 797 break; 798 799 case EMR_FILLPATH : 800 pOut->StrokeAndFillPath( sal_False, sal_True ); 801 break; 802 803 case EMR_STROKEANDFILLPATH : 804 pOut->StrokeAndFillPath( sal_True, sal_True ); 805 break; 806 807 case EMR_STROKEPATH : 808 pOut->StrokeAndFillPath( sal_True, sal_False ); 809 break; 810 811 case EMR_SELECTCLIPPATH : 812 { 813 sal_Int32 nClippingMode; 814 *pWMF >> nClippingMode; 815 pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True ); 816 } 817 break; 818 819 case EMR_EXTSELECTCLIPRGN : 820 { 821 sal_Int32 iMode, cbRgnData; 822 *pWMF >> cbRgnData 823 >> iMode; 824 825 PolyPolygon aPolyPoly; 826 if ( cbRgnData ) 827 ImplReadRegion( aPolyPoly, *pWMF, nRecSize ); 828 pOut->SetClipPath( aPolyPoly, iMode, sal_False ); 829 } 830 break; 831 case EMR_ALPHABLEND: 832 { 833 sal_Int32 xDest, yDest, cxDest, cyDest; 834 835 BLENDFUNCTION aFunc; 836 sal_Int32 xSrc, ySrc; 837 XForm xformSrc; 838 sal_uInt32 BkColorSrc,iUsageSrc ,offBmiSrc,cbBmiSrc,offBitsSrc,cbBitsSrc ,cxSrc,cySrc ; 839 840 sal_uInt32 nStart = pWMF->Tell() - 8; 841 pWMF->SeekRel( 0x10 ); 842 843 *pWMF >> xDest >> yDest >> cxDest >> cyDest >> aFunc >> xSrc >> ySrc 844 >> xformSrc >> BkColorSrc >> iUsageSrc >> offBmiSrc >> cbBmiSrc 845 >> offBitsSrc >> cbBitsSrc >>cxSrc>>cySrc ; 846 847 sal_uInt32 dwRop = SRCAND|SRCINVERT; 848 849 Bitmap aBitmap; 850 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 851 852 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 853 bStatus = sal_False; 854 else 855 { 856 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 857 if ( nSize <= ( nEndPos - nStartPos ) ) 858 { 859 char* pBuf = new char[ nSize ]; 860 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 861 aTmp.ObjectOwnsMemory( sal_True ); 862 aTmp << (sal_uInt8)'B' 863 << (sal_uInt8)'M' 864 << (sal_uInt32)cbBitsSrc 865 << (sal_uInt16)0 866 << (sal_uInt16)0 867 << (sal_uInt32)cbBmiSrc + 14; 868 pWMF->Seek( nStart + offBmiSrc ); 869 pWMF->Read( pBuf + 14, cbBmiSrc ); 870 pWMF->Seek( nStart + offBitsSrc ); 871 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 872 aTmp.Seek( 0 ); 873 ReadDIB(aBitmap, aTmp, true); 874 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 ReadDIB(aBitmap, aTmp, 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 ReadDIB(aBitmap, aTmp, 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 ReadDIB(aBmp, *pWMF, 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