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 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 aBitmap.Read( aTmp, sal_True ); 874 // test if it is sensible to crop 875 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 876 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 877 ( xSrc + static_cast< sal_Int32 >(cxSrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Width()) ) && 878 ( ySrc + static_cast< sal_Int32 >(cySrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Height()) ) ) 879 { 880 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 881 aBitmap.Crop( aCropRect ); 882 } 883 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 884 } 885 } 886 } 887 break; 888 case EMR_BITBLT : // PASSTHROUGH INTENDED 889 case EMR_STRETCHBLT : 890 { 891 sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc; 892 sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; 893 XForm xformSrc; 894 895 sal_uInt32 nStart = pWMF->Tell() - 8; 896 897 pWMF->SeekRel( 0x10 ); 898 *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc 899 >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc 900 >> offBitsSrc >> cbBitsSrc; 901 902 if ( nRecType == EMR_STRETCHBLT ) 903 *pWMF >> cxSrc >> cySrc; 904 else 905 cxSrc = cySrc = 0; 906 907 Bitmap aBitmap; 908 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 909 910 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative 911 cyDest = abs( (int)cyDest ); // and also 122889 912 913 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 914 bStatus = sal_False; 915 else 916 { 917 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 918 if ( nSize <= ( nEndPos - nStartPos ) ) 919 { 920 char* pBuf = new char[ nSize ]; 921 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 922 aTmp.ObjectOwnsMemory( sal_True ); 923 aTmp << (sal_uInt8)'B' 924 << (sal_uInt8)'M' 925 << (sal_uInt32)cbBitsSrc 926 << (sal_uInt16)0 927 << (sal_uInt16)0 928 << (sal_uInt32)cbBmiSrc + 14; 929 pWMF->Seek( nStart + offBmiSrc ); 930 pWMF->Read( pBuf + 14, cbBmiSrc ); 931 pWMF->Seek( nStart + offBitsSrc ); 932 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 933 aTmp.Seek( 0 ); 934 aBitmap.Read( aTmp, sal_True ); 935 936 // test if it is sensible to crop 937 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 938 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 939 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && 940 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) 941 { 942 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 943 aBitmap.Crop( aCropRect ); 944 } 945 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 946 } 947 } 948 } 949 break; 950 951 case EMR_STRETCHDIBITS : 952 { 953 sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; 954 sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; 955 sal_uInt32 nStart = pWMF->Tell() - 8; 956 957 pWMF->SeekRel( 0x10 ); 958 *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc 959 >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest; 960 961 Bitmap aBitmap; 962 Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); 963 964 cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative 965 cyDest = abs( (int)cyDest ); // and also 122889 966 967 if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) 968 bStatus = sal_False; 969 else 970 { 971 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; 972 if ( nSize <= ( nEndPos - nStartPos ) ) 973 { 974 char* pBuf = new char[ nSize ]; 975 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); 976 aTmp.ObjectOwnsMemory( sal_True ); 977 aTmp << (sal_uInt8)'B' 978 << (sal_uInt8)'M' 979 << (sal_uInt32)cbBitsSrc 980 << (sal_uInt16)0 981 << (sal_uInt16)0 982 << (sal_uInt32)cbBmiSrc + 14; 983 pWMF->Seek( nStart + offBmiSrc ); 984 pWMF->Read( pBuf + 14, cbBmiSrc ); 985 pWMF->Seek( nStart + offBitsSrc ); 986 pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); 987 aTmp.Seek( 0 ); 988 aBitmap.Read( aTmp, sal_True ); 989 990 // test if it is sensible to crop 991 if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && 992 ( xSrc >= 0 ) && ( ySrc >= 0 ) && 993 ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && 994 ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) 995 { 996 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); 997 aBitmap.Crop( aCropRect ); 998 } 999 aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND ); 1000 } 1001 } 1002 } 1003 break; 1004 1005 case EMR_EXTCREATEFONTINDIRECTW : 1006 { 1007 *pWMF >> nIndex; 1008 if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) 1009 { 1010 LOGFONTW aLogFont; 1011 *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic 1012 >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision 1013 >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily; 1014 1015 sal_Unicode lfFaceName[ LF_FACESIZE ]; 1016 1017 for ( int i = 0; i < LF_FACESIZE; i++ ) 1018 { 1019 sal_uInt16 nChar; 1020 *pWMF >> nChar; 1021 lfFaceName[ i ] = nChar; 1022 } 1023 aLogFont.alfFaceName = UniString( lfFaceName ); 1024 pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) ); 1025 } 1026 } 1027 break; 1028 1029 case EMR_EXTTEXTOUTA : 1030 bFlag = sal_True; 1031 case EMR_EXTTEXTOUTW : 1032 { 1033 sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale; 1034 sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx; 1035 sal_Int32* pDX = NULL; 1036 1037 nCurPos = pWMF->Tell() - 8; 1038 1039 *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale 1040 >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions; 1041 1042 pWMF->SeekRel( 0x10 ); 1043 *pWMF >> offDx; 1044 1045 sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT; 1046 if ( nOptions & ETO_RTLREADING ) 1047 nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; 1048 pOut->SetTextLayoutMode( nTextLayoutMode ); 1049 DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" ); 1050 1051 Point aPos( ptlReferenceX, ptlReferenceY ); 1052 if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) ) 1053 { 1054 if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) ) 1055 { 1056 pWMF->Seek( nCurPos + offDx ); 1057 if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) ) 1058 { 1059 pDX = new sal_Int32[ nLen ]; 1060 sal_uInt32 i; 1061 for ( i = 0; i < nLen; i++ ) 1062 *pWMF >> pDX[ i ]; 1063 } 1064 } 1065 pWMF->Seek( nCurPos + nOffString ); 1066 String aText; 1067 if ( bFlag ) 1068 { 1069 if ( nLen <= ( nEndPos - pWMF->Tell() ) ) 1070 { 1071 sal_Char* pBuf = new sal_Char[ nLen ]; 1072 pWMF->Read( pBuf, nLen ); 1073 aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() ); 1074 delete[] pBuf; 1075 1076 if ( aText.Len() != nLen ) 1077 { 1078 sal_uInt16 i, j, k; 1079 sal_Int32* pOldDx = pDX; 1080 pDX = new sal_Int32[ aText.Len() ]; 1081 for ( i = 0, j = 0; i < aText.Len(); i++ ) 1082 { 1083 ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() ); 1084 pDX[ i ] = 0; 1085 for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ ) 1086 pDX[ i ] += pOldDx[ j++ ]; 1087 } 1088 delete[] pOldDx; 1089 } 1090 } 1091 } 1092 else 1093 { 1094 if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) ) 1095 { 1096 sal_Unicode* pBuf = new sal_Unicode[ nLen ]; 1097 pWMF->Read( pBuf, nLen << 1 ); 1098 #ifdef OSL_BIGENDIAN 1099 sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen ); 1100 while ( pTmp-- != (sal_Char*)pBuf ) 1101 { 1102 nTmp = *pTmp--; 1103 pTmp[ 1 ] = *pTmp; 1104 *pTmp = nTmp; 1105 } 1106 #endif 1107 aText = String( pBuf, (xub_StrLen)nLen ); 1108 delete[] pBuf; 1109 } 1110 } 1111 pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode ); 1112 } 1113 delete[] pDX; 1114 } 1115 break; 1116 1117 case EMR_POLYBEZIERTO16 : 1118 bFlag = sal_True; 1119 case EMR_POLYBEZIER16 : 1120 { 1121 pWMF->SeekRel( 16 ); 1122 *pWMF >> nPoints; 1123 sal_uInt16 i = 0; 1124 if ( bFlag ) 1125 { 1126 i++; 1127 nPoints++; 1128 } 1129 Polygon aPoly( (sal_uInt16)nPoints ); 1130 for( ; i < (sal_uInt16)nPoints; i++ ) 1131 { 1132 *pWMF >> nX16 >> nY16; 1133 aPoly[ i ] = Point( nX16, nY16 ); 1134 } 1135 pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag ); 1136 } 1137 break; 1138 1139 case EMR_POLYGON16 : 1140 { 1141 pWMF->SeekRel( 16 ); 1142 *pWMF >> nPoints; 1143 Polygon aPoly( (sal_uInt16)nPoints ); 1144 for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) 1145 { 1146 *pWMF >> nX16 >> nY16; 1147 aPoly[ k ] = Point( nX16, nY16 ); 1148 } 1149 pOut->DrawPolygon( aPoly, bRecordPath ); 1150 } 1151 break; 1152 1153 case EMR_POLYLINETO16 : 1154 bFlag = sal_True; 1155 case EMR_POLYLINE16 : 1156 { 1157 pWMF->SeekRel( 16 ); 1158 *pWMF >> nPoints; 1159 sal_uInt16 i = 0; 1160 if ( bFlag ) 1161 { 1162 i++; 1163 nPoints++; 1164 } 1165 1166 Polygon aPoly( (sal_uInt16)nPoints ); 1167 for( ; i < (sal_uInt16)nPoints; i++ ) 1168 { 1169 *pWMF >> nX16 >> nY16; 1170 aPoly[ i ] = Point( nX16, nY16 ); 1171 } 1172 pOut->DrawPolyLine( aPoly, bFlag, bRecordPath ); 1173 } 1174 break; 1175 1176 case EMR_POLYPOLYLINE16 : 1177 { 1178 sal_uInt16* pnPoints; 1179 1180 sal_Int32 i, nPoly, nGesPoints; 1181 pWMF->SeekRel( 0x10 ); 1182 // Anzahl der Polygone: 1183 *pWMF >> nPoly >> nGesPoints; 1184 1185 // taking the amount of points of each polygon, retrieving the total number of points 1186 if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) 1187 { 1188 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) 1189 { 1190 pnPoints = new sal_uInt16[ nPoly ]; 1191 for ( i = 0; i < nPoly; i++ ) 1192 { 1193 *pWMF >> nPoints; 1194 pnPoints[ i ] = (sal_uInt16)nPoints; 1195 } 1196 // Polygonpunkte holen: 1197 for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) 1198 { 1199 Polygon aPolygon( pnPoints[ i ] ); 1200 for ( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) 1201 { 1202 *pWMF >> nX16 >> nY16; 1203 aPolygon[ k ] = Point( nX16, nY16 ); 1204 } 1205 pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath ); 1206 } 1207 delete[] pnPoints; 1208 } 1209 } 1210 } 1211 break; 1212 1213 case EMR_POLYPOLYGON16 : 1214 { 1215 sal_uInt32 nPoly(0); 1216 sal_uInt32 nGesPoints(0); 1217 pWMF->SeekRel( 0x10 ); 1218 // Anzahl der Polygone: 1219 *pWMF >> nPoly >> nGesPoints; 1220 sal_uInt32 nReadPoints(0); 1221 1222 if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() ) 1223 { 1224 if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) ) 1225 { 1226 sal_uInt32 i(0); 1227 sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; 1228 1229 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 1230 { 1231 *pWMF >> nPoints; 1232 pnPoints[ i ] = (sal_uInt16)nPoints; 1233 } 1234 1235 if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof() ) 1236 { 1237 PolyPolygon aPolyPoly(nPoly, nPoly); 1238 1239 for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ ) 1240 { 1241 const sal_uInt16 nPointCount(pnPoints[i]); 1242 Point* pPtAry = new Point[nPointCount]; 1243 1244 for(sal_uInt16 b(0); b < nPointCount && !pWMF->IsEof(); b++) 1245 { 1246 *pWMF >> nX16 >> nY16; 1247 pPtAry[b] = Point( nX16, nY16 ); 1248 nReadPoints++; 1249 } 1250 1251 aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); 1252 delete[] pPtAry; 1253 } 1254 1255 // create PolyPolygon actions 1256 pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); 1257 } 1258 1259 delete[] pnPoints; 1260 } 1261 } 1262 1263 OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON16 is unequal imported number (!)"); 1264 } 1265 break; 1266 1267 case EMR_FILLRGN : 1268 { 1269 sal_uInt32 nLen; 1270 PolyPolygon aPolyPoly; 1271 pWMF->SeekRel( 0x10 ); 1272 *pWMF >> nLen >> nIndex; 1273 1274 if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) ) 1275 { 1276 pOut->Push(); 1277 pOut->SelectObject( nIndex ); 1278 pOut->DrawPolyPolygon( aPolyPoly, sal_False ); 1279 pOut->Pop(); 1280 } 1281 } 1282 break; 1283 case EMR_CREATEDIBPATTERNBRUSHPT : 1284 sal_uInt32 nTmp32; 1285 sal_uInt32 nOffset; 1286 *pWMF >> nIndex; 1287 Bitmap aBmp; 1288 BitmapReadAccess* pBmp; 1289 sal_uInt32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1; 1290 1291 *pWMF >> nTmp32; 1292 *pWMF >> nOffset; 1293 for ( sal_uInt32 i = 0; i < (nOffset - 20)/4; i ++ ) 1294 { 1295 *pWMF >> nTmp32; 1296 } 1297 1298 aBmp.Read( *pWMF, sal_False ); 1299 pBmp = aBmp.AcquireReadAccess(); 1300 if ( pBmp ) 1301 { 1302 for ( sal_Int32 y = 0; y < pBmp->Height(); y++ ) 1303 { 1304 for ( sal_Int32 x = 0; x < pBmp->Width(); x++ ) 1305 { 1306 const BitmapColor aColor( pBmp->GetColor( y, x ) ); 1307 1308 nRed += aColor.GetRed(); 1309 nGreen += aColor.GetGreen(); 1310 nBlue += aColor.GetBlue(); 1311 } 1312 } 1313 nCount = pBmp->Height() * pBmp->Width(); 1314 if ( !nCount ) 1315 nCount++; 1316 aBmp.ReleaseAccess( pBmp ); 1317 } 1318 Color aColor( (sal_Char)( nRed / nCount ), (sal_Char)( nGreen / nCount ), (sal_Char)( nBlue / nCount ) ); 1319 pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aColor, sal_False ) ); 1320 1321 break; 1322 1323 #ifdef WIN_MTF_ASSERT 1324 default : WinMtfAssertHandler( "Unknown Meta Action" ); break; 1325 case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break; 1326 case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break; 1327 case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break; 1328 case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break; 1329 case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break; 1330 case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break; 1331 case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break; 1332 case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break; 1333 case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break; 1334 case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break; 1335 case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break; 1336 case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break; 1337 case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break; 1338 case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break; 1339 case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break; 1340 case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break; 1341 case EMR_CREATEDIBPATTERNBRUSHPT : WinMtfAssertHandler( "CreateDibPatternBrushPt" ); break; 1342 case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break; 1343 case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break; 1344 case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break; 1345 case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break; 1346 case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break; 1347 case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break; 1348 case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break; 1349 case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break; 1350 case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break; 1351 case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break; 1352 case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break; 1353 case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break; 1354 case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break; 1355 case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break; 1356 case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break; 1357 case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break; 1358 case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break; 1359 case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break; 1360 case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break; 1361 case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break; 1362 case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break; 1363 1364 case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break; 1365 case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break; 1366 case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break; 1367 case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break; 1368 case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break; 1369 case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break; 1370 case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break; 1371 case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break; 1372 case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break; 1373 case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break; 1374 case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break; 1375 case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break; 1376 1377 case EMR_GDICOMMENT : 1378 case EMR_HEADER : // has already been read at ReadHeader() 1379 break; 1380 #endif 1381 } 1382 pWMF->Seek( nNextPos ); 1383 } 1384 if( aBmpSaveList.Count() ) 1385 pOut->ResolveBitmapActions( aBmpSaveList ); 1386 1387 if ( bStatus ) 1388 pWMF->Seek(nEndPos); 1389 1390 return bStatus; 1391 }; 1392 1393 //----------------------------------------------------------------------------------- 1394 1395 sal_Bool EnhWMFReader::ReadHeader() 1396 { 1397 sal_uInt32 nsal_uInt32, nHeaderSize, nPalEntries; 1398 sal_Int32 nLeft, nTop, nRight, nBottom; 1399 1400 // METAFILEHEADER SPARE ICH MIR HIER 1401 // Einlesen des METAHEADER 1402 *pWMF >> nsal_uInt32 >> nHeaderSize; 1403 if ( nsal_uInt32 != 1 ) // Typ 1404 return sal_False; 1405 1406 // bound size 1407 Rectangle rclBounds; // rectangle in logical units 1/100th mm 1408 *pWMF >> nLeft >> nTop >> nRight >> nBottom; 1409 rclBounds.Left() = nLeft; 1410 rclBounds.Top() = nTop; 1411 rclBounds.Right() = nRight; 1412 rclBounds.Bottom() = nBottom; 1413 1414 // picture frame size 1415 Rectangle rclFrame; // rectangle in device units 1416 *pWMF >> nLeft >> nTop >> nRight >> nBottom; 1417 rclFrame.Left() = nLeft; 1418 rclFrame.Top() = nTop; 1419 rclFrame.Right() = nRight; 1420 rclFrame.Bottom() = nBottom; 1421 1422 *pWMF >> nsal_uInt32; // signature 1423 1424 if ( nsal_uInt32 != 0x464d4520 ) 1425 return sal_False; 1426 1427 *pWMF >> nsal_uInt32; // nVersion 1428 *pWMF >> nEndPos; // size of metafile 1429 nEndPos += nStartPos; 1430 1431 sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid 1432 pWMF->Seek( STREAM_SEEK_TO_END ); 1433 if ( pWMF->Tell() < nEndPos ) 1434 nEndPos = pWMF->Tell(); 1435 pWMF->Seek( nStrmPos ); 1436 1437 *pWMF >> nRecordCount; 1438 1439 if ( !nRecordCount ) 1440 return sal_False; 1441 1442 pWMF->SeekRel( 0xc ); 1443 1444 sal_Int32 nPixX, nPixY, nMillX, nMillY; 1445 *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY; 1446 1447 pOut->SetrclFrame( rclFrame ); 1448 pOut->SetrclBounds( rclBounds ); 1449 pOut->SetRefPix( Size( nPixX, nPixY ) ); 1450 pOut->SetRefMill( Size( nMillX, nMillY ) ); 1451 1452 pWMF->Seek( nStartPos + nHeaderSize ); 1453 return sal_True; 1454 } 1455 1456 //----------------------------------------------------------------------------------- 1457 1458 Rectangle EnhWMFReader::ReadRectangle( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) 1459 { 1460 Point aTL ( Point( x1, y1 ) ); 1461 Point aBR( Point( --x2, --y2 ) ); 1462 return Rectangle( aTL, aBR ); 1463 } 1464 1465 EnhWMFReader::~EnhWMFReader() 1466 { 1467 1468 }; 1469