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 #include <string.h> 25 #include <svpm.h> 26 27 #define _SV_SALGDI_CXX 28 #include <tools/debug.hxx> 29 #include <os2/saldata.hxx> 30 #include <os2/salgdi.h> 31 #include <tools/debug.hxx> 32 #include <os2/salframe.h> 33 #include <tools/poly.hxx> 34 #ifndef _RTL_STRINGBUF_HXX 35 #include <rtl/strbuf.hxx> 36 #endif 37 38 #include <region.h> 39 40 #ifndef __H_FT2LIB 41 #include <os2/wingdi.h> 42 #include <ft2lib.h> 43 #endif 44 45 // ----------- 46 // - Defines - 47 // ----------- 48 49 // ClipRegions funktionieren immer noch nicht auf allen getesteten Druckern 50 #define SAL_PRINTER_CLIPPATH 1 51 // #define SAL_PRINTER_POLYPATH 1 52 53 // ======================================================================= 54 55 void ImplInitSalGDI() 56 { 57 } 58 59 // ----------------------------------------------------------------------- 60 61 void ImplFreeSalGDI() 62 { 63 SalData* pSalData = GetSalData(); 64 65 // delete icon cache 66 SalIcon* pIcon = pSalData->mpFirstIcon; 67 while( pIcon ) 68 { 69 SalIcon* pTmp = pIcon->pNext; 70 WinDestroyPointer( pIcon->hIcon ); 71 delete pIcon; 72 pIcon = pTmp; 73 } 74 75 } 76 77 // ======================================================================= 78 79 void ImplSalInitGraphics( Os2SalGraphics* pData ) 80 { 81 GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL ); 82 } 83 84 // ----------------------------------------------------------------------- 85 86 void ImplSalDeInitGraphics( Os2SalGraphics* pData ) 87 { 88 } 89 90 // ======================================================================= 91 92 Os2SalGraphics::Os2SalGraphics() 93 { 94 for( int i = 0; i < MAX_FALLBACK; ++i ) 95 { 96 mhFonts[ i ] = 0; 97 mpOs2FontData[ i ] = NULL; 98 mpOs2FontEntry[ i ] = NULL; 99 } 100 101 mfFontScale = 1.0; 102 103 mhPS = 0; 104 mhDC = 0; 105 mbLine = FALSE; 106 mbFill = FALSE; 107 mbXORMode = FALSE; 108 mnFontMetricCount = 0; 109 mpFontMetrics = NULL; 110 mpClipRectlAry = NULL; 111 112 mhDefFont = 0; 113 mpFontKernPairs = NULL; 114 mnFontKernPairCount = 0; 115 mbFontKernInit = FALSE; 116 117 } 118 119 // ----------------------------------------------------------------------- 120 121 Os2SalGraphics::~Os2SalGraphics() 122 { 123 Ft2DeleteSetId( mhPS, LCID_BASE); 124 125 if ( mpFontMetrics ) 126 delete mpFontMetrics; 127 128 if ( mpFontKernPairs ) 129 delete mpFontKernPairs; 130 131 } 132 133 // ----------------------------------------------------------------------- 134 135 static SalColor ImplGetROPSalColor( SalROPColor nROPColor ) 136 { 137 SalColor nSalColor; 138 139 switch( nROPColor ) 140 { 141 case SAL_ROP_0: 142 nSalColor = MAKE_SALCOLOR( 0, 0, 0 ); 143 break; 144 145 case SAL_ROP_1: 146 case SAL_ROP_INVERT: 147 nSalColor = MAKE_SALCOLOR( 255, 255, 255 ); 148 break; 149 } 150 151 return nSalColor; 152 } 153 154 // ----------------------------------------------------------------------- 155 156 void Os2SalGraphics::GetResolution( long& rDPIX, long& rDPIY ) 157 { 158 // since OOo asks for DPI, I will query FONT_RES, which seems to be 159 // more correct than _RESOLUTION fields (on my wide screen lcd) 160 // and does not require conversion 161 DevQueryCaps( mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &rDPIX ); 162 DevQueryCaps( mhDC, CAPS_VERTICAL_FONT_RES, 1, &rDPIY ); 163 } 164 165 // ----------------------------------------------------------------------- 166 167 USHORT Os2SalGraphics::GetBitCount() 168 { 169 LONG nBitCount; 170 DevQueryCaps( mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount ); 171 return (USHORT)nBitCount; 172 } 173 174 // ----------------------------------------------------------------------- 175 176 long Os2SalGraphics::GetGraphicsWidth() const 177 { 178 if( mhWnd ) 179 { 180 Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( mhWnd ); 181 if( pFrame ) 182 { 183 if( pFrame->maGeometry.nWidth ) 184 return pFrame->maGeometry.nWidth; 185 else 186 { 187 // TODO: perhaps not needed, maGeometry should always be up-to-date 188 RECTL aRect; 189 WinQueryWindowRect( mhWnd, &aRect ); 190 return aRect.xRight; 191 } 192 } 193 } 194 195 return 0; 196 } 197 198 // ----------------------------------------------------------------------- 199 200 void Os2SalGraphics::ResetClipRegion() 201 { 202 #ifdef SAL_PRINTER_CLIPPATH 203 if ( mbPrinter ) 204 GpiSetClipPath( mhPS, 0, SCP_RESET ); 205 else 206 #endif 207 { 208 HRGN hOldRegion; 209 210 GpiSetClipRegion( mhPS, NULL, &hOldRegion ); 211 if ( hOldRegion ) 212 GpiDestroyRegion( mhPS, hOldRegion ); 213 } 214 } 215 216 // ----------------------------------------------------------------------- 217 218 bool Os2SalGraphics::setClipRegion( const Region& i_rClip ) 219 { 220 ULONG nCount = i_rClip.GetRectCount(); 221 222 mpClipRectlAry = new RECTL[ nCount ]; 223 mnClipElementCount = 0; 224 225 ImplRegionInfo aInfo; 226 long nX, nY, nW, nH; 227 bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH ); 228 while( bRegionRect ) 229 { 230 if ( nW && nH ) 231 { 232 RECTL* pClipRect = &mpClipRectlAry[ mnClipElementCount ]; 233 pClipRect->xLeft = nX; 234 pClipRect->yTop = mnHeight - nY; 235 pClipRect->xRight = nX + nW; 236 pClipRect->yBottom = mnHeight - (nY + nH); 237 mnClipElementCount++; 238 } 239 bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH ); 240 } 241 #ifdef SAL_PRINTER_CLIPPATH 242 if ( mbPrinter ) 243 { 244 GpiSetClipPath( mhPS, 0, SCP_RESET ); 245 GpiBeginPath( mhPS, 1L ); 246 247 for( int i = 0; i < mnClipElementCount; i++ ) 248 { 249 POINTL aPt; 250 RECTL* pClipRect = &mpClipRectlAry[ i ]; 251 252 aPt.x = pClipRect->xLeft; 253 aPt.y = pClipRect->yTop-1; 254 Ft2Move( mhPS, &aPt ); 255 256 aPt.x = pClipRect->xRight-1; 257 aPt.y = pClipRect->yBottom; 258 259 Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 ); 260 } 261 262 GpiEndPath( mhPS ); 263 GpiSetClipPath( mhPS, 1L, SCP_ALTERNATE | SCP_AND ); 264 } 265 else 266 #endif 267 { 268 HRGN hClipRegion = GpiCreateRegion( mhPS, 269 mnClipElementCount, 270 mpClipRectlAry ); 271 HRGN hOldRegion; 272 273 GpiSetClipRegion( mhPS, hClipRegion, &hOldRegion ); 274 if( hOldRegion ) 275 GpiDestroyRegion( mhPS, hOldRegion ); 276 } 277 278 delete [] mpClipRectlAry; 279 280 return true; 281 } 282 283 // ----------------------------------------------------------------------- 284 285 void Os2SalGraphics::SetLineColor() 286 { 287 // don't draw line! 288 mbLine = FALSE; 289 } 290 291 // ----------------------------------------------------------------------- 292 293 void Os2SalGraphics::SetLineColor( SalColor nSalColor ) 294 { 295 LINEBUNDLE lb; 296 297 // set color 298 lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), 299 SALCOLOR_GREEN( nSalColor ), 300 SALCOLOR_BLUE( nSalColor ) ); 301 302 Ft2SetAttrs( mhPS, 303 PRIM_LINE, 304 LBB_COLOR, 305 0, 306 &lb ); 307 308 // draw line! 309 mbLine = TRUE; 310 } 311 312 // ----------------------------------------------------------------------- 313 314 void Os2SalGraphics::SetFillColor() 315 { 316 // don't fill area! 317 mbFill = FALSE; 318 } 319 320 // ----------------------------------------------------------------------- 321 322 void Os2SalGraphics::SetFillColor( SalColor nSalColor ) 323 { 324 AREABUNDLE ab; 325 326 // set color 327 ab.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), 328 SALCOLOR_GREEN( nSalColor ), 329 SALCOLOR_BLUE( nSalColor ) ); 330 331 Ft2SetAttrs( mhPS, 332 PRIM_AREA, 333 ABB_COLOR, 334 0, 335 &ab ); 336 337 // fill area! 338 mbFill = TRUE; 339 } 340 341 // ----------------------------------------------------------------------- 342 343 void Os2SalGraphics::SetXORMode( bool bSet, bool ) 344 { 345 mbXORMode = bSet; 346 LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT; 347 348 // set mix mode for lines 349 LINEBUNDLE lb; 350 lb.usMixMode = nMixMode; 351 Ft2SetAttrs( mhPS, 352 PRIM_LINE, 353 LBB_MIX_MODE, 354 0, 355 &lb ); 356 357 // set mix mode for areas 358 AREABUNDLE ab; 359 ab.usMixMode = nMixMode; 360 Ft2SetAttrs( mhPS, 361 PRIM_AREA, 362 ABB_MIX_MODE, 363 0, 364 &ab ); 365 366 // set mix mode for text 367 CHARBUNDLE cb; 368 cb.usMixMode = nMixMode; 369 Ft2SetAttrs( mhPS, 370 PRIM_CHAR, 371 CBB_MIX_MODE, 372 0, 373 &cb ); 374 } 375 376 // ----------------------------------------------------------------------- 377 378 void Os2SalGraphics::SetROPLineColor( SalROPColor nROPColor ) 379 { 380 SetLineColor( ImplGetROPSalColor( nROPColor ) ); 381 } 382 383 // ----------------------------------------------------------------------- 384 385 void Os2SalGraphics::SetROPFillColor( SalROPColor nROPColor ) 386 { 387 SetFillColor( ImplGetROPSalColor( nROPColor ) ); 388 } 389 390 // ----------------------------------------------------------------------- 391 392 void Os2SalGraphics::drawPixel( long nX, long nY ) 393 { 394 POINTL aPt; 395 396 aPt.x = nX; 397 aPt.y = TY( nY ); 398 399 // set color 400 Ft2SetPel( mhPS, &aPt ); 401 } 402 403 // ----------------------------------------------------------------------- 404 405 void Os2SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) 406 { 407 // save old color 408 LINEBUNDLE oldLb; 409 GpiQueryAttrs( mhPS, 410 PRIM_LINE, 411 LBB_COLOR, 412 &oldLb ); 413 414 // set new color 415 LINEBUNDLE lb; 416 lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), 417 SALCOLOR_GREEN( nSalColor ), 418 SALCOLOR_BLUE( nSalColor ) ); 419 Ft2SetAttrs( mhPS, 420 PRIM_LINE, 421 LBB_COLOR, 422 0, 423 &lb ); 424 425 // set color of pixel 426 POINTL aPt; 427 aPt.x = nX; 428 aPt.y = TY( nY ); 429 Ft2SetPel( mhPS, &aPt ); 430 431 // restore old color 432 Ft2SetAttrs( mhPS, 433 PRIM_LINE, 434 LBB_COLOR, 435 0, 436 &oldLb ); 437 } 438 439 // ----------------------------------------------------------------------- 440 441 void Os2SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) 442 { 443 // OS2 zeichnet den Endpunkt mit 444 POINTL aPt; 445 aPt.x = nX1; 446 aPt.y = TY( nY1 ); 447 Ft2Move( mhPS, &aPt ); 448 aPt.x = nX2; 449 aPt.y = TY( nY2 ); 450 GpiLine( mhPS, &aPt ); 451 } 452 453 // ----------------------------------------------------------------------- 454 455 void Os2SalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) 456 { 457 POINTL aPt; 458 long lControl; 459 460 if ( mbFill ) 461 { 462 if ( mbLine ) 463 lControl = DRO_OUTLINEFILL; 464 else 465 lControl = DRO_FILL; 466 } 467 else 468 { 469 if ( mbLine ) 470 lControl = DRO_OUTLINE; 471 else 472 return; 473 } 474 475 aPt.x = nX; 476 aPt.y = TY( nY ); 477 Ft2Move( mhPS, &aPt ); 478 aPt.x = nX + nWidth - 1; 479 aPt.y = TY( nY + nHeight - 1 ); 480 Ft2Box( mhPS, lControl, &aPt, 0, 0 ); 481 } 482 483 // ----------------------------------------------------------------------- 484 485 void Os2SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ) 486 { 487 // convert all points to sys orientation 488 POINTL* pOS2PtAry = new POINTL[ nPoints ]; 489 POINTL* pTempOS2PtAry = pOS2PtAry; 490 const SalPoint* pTempPtAry = pPtAry; 491 ULONG nTempPoints = nPoints; 492 long nHeight = mnHeight - 1; 493 494 while( nTempPoints-- ) 495 { 496 (*pTempOS2PtAry).x = (*pTempPtAry).mnX; 497 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY; 498 pTempOS2PtAry++; 499 pTempPtAry++; 500 } 501 502 Ft2Move( mhPS, pOS2PtAry ); 503 GpiPolyLine( mhPS, nPoints, pOS2PtAry ); 504 delete [] pOS2PtAry; 505 } 506 507 // ----------------------------------------------------------------------- 508 509 void Os2SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) 510 { 511 PM_POLYGON aPolygon; 512 513 // create polygon 514 aPolygon.aPointl = new POINTL[ nPoints ]; 515 aPolygon.ulPoints = nPoints; 516 517 // convert all points to sys orientation 518 POINTL* pTempOS2PtAry = aPolygon.aPointl; 519 const SalPoint* pTempPtAry = pPtAry; 520 ULONG nTempPoints = nPoints; 521 long nHeight = mnHeight - 1; 522 523 while( nTempPoints-- ) 524 { 525 (*pTempOS2PtAry).x = (*pTempPtAry).mnX; 526 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY; 527 pTempOS2PtAry++; 528 pTempPtAry++; 529 } 530 531 // Innenleben zeichnen 532 if ( mbFill ) 533 { 534 #ifdef SAL_PRINTER_POLYPATH 535 if ( mbPrinter ) 536 { 537 Ft2BeginPath( mhPS, 1 ); 538 Ft2Move( mhPS, aPolygon.aPointl ); 539 Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl ); 540 Ft2EndPath( mhPS ); 541 Ft2FillPath( mhPS, 1, 0 ); 542 543 if ( mbLine ) 544 { 545 Ft2Move( mhPS, aPolygon.aPointl ); 546 Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl ); 547 } 548 } 549 else 550 #endif 551 { 552 ULONG nOptions = POLYGON_ALTERNATE; 553 554 if ( mbLine ) 555 nOptions |= POLYGON_BOUNDARY; 556 else 557 nOptions |= POLYGON_NOBOUNDARY; 558 559 Ft2Move( mhPS, aPolygon.aPointl ); 560 GpiPolygons( mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL ); 561 } 562 } 563 else 564 { 565 if ( mbLine ) 566 { 567 Ft2Move( mhPS, aPolygon.aPointl ); 568 GpiPolyLine( mhPS, nPoints, aPolygon.aPointl ); 569 } 570 } 571 572 delete [] aPolygon.aPointl; 573 } 574 575 // ----------------------------------------------------------------------- 576 577 void Os2SalGraphics::drawPolyPolygon( ULONG nPoly, const ULONG* pPoints, 578 PCONSTSALPOINT* pPtAry ) 579 { 580 ULONG i; 581 long nHeight = mnHeight - 1; 582 PM_POLYGON* aPolygonAry = new PM_POLYGON[ nPoly ]; 583 584 for( i = 0; i < nPoly; i++ ) 585 { 586 const SalPoint * pTempPtAry = (const SalPoint*)pPtAry[ i ]; 587 588 // create polygon 589 ULONG nTempPoints = pPoints[ i ]; 590 POINTL * pTempOS2PtAry = new POINTL[ nTempPoints ]; 591 592 // convert all points to sys orientation 593 aPolygonAry[ i ].ulPoints = nTempPoints; 594 aPolygonAry[ i ].aPointl = pTempOS2PtAry; 595 596 while( nTempPoints-- ) 597 { 598 (*pTempOS2PtAry).x = (*pTempPtAry).mnX; 599 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY; 600 pTempOS2PtAry++; 601 pTempPtAry++; 602 } 603 } 604 605 // Innenleben zeichnen 606 if ( mbFill ) 607 { 608 #ifdef SAL_PRINTER_POLYPATH 609 if ( mbPrinter ) 610 { 611 Ft2BeginPath( mhPS, 1 ); 612 for ( i = 0; i < nPoly; i++ ) 613 { 614 Ft2Move( mhPS, aPolygonAry[i].aPointl ); 615 Ft2PolyLine( mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl ); 616 } 617 Ft2EndPath( mhPS ); 618 Ft2FillPath( mhPS, 1, 0 ); 619 } 620 else 621 #endif 622 { 623 ULONG nOptions = POLYGON_ALTERNATE; 624 625 if ( mbLine ) 626 nOptions |= POLYGON_BOUNDARY; 627 else 628 nOptions |= POLYGON_NOBOUNDARY; 629 630 Ft2Move( mhPS, aPolygonAry[ 0 ].aPointl ); 631 GpiPolygons( mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL ); 632 } 633 } 634 else 635 { 636 if ( mbLine ) 637 { 638 for( i = 0; i < nPoly; i++ ) 639 { 640 Ft2Move( mhPS, aPolygonAry[ i ].aPointl ); 641 GpiPolyLine( mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl ); 642 } 643 } 644 } 645 646 // cleanup 647 for( i = 0; i < nPoly; i++ ) 648 delete [] aPolygonAry[ i ].aPointl; 649 delete [] aPolygonAry; 650 } 651 652 // ----------------------------------------------------------------------- 653 654 bool Os2SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ ) 655 { 656 // TODO: implement and advertise OutDevSupport_B2DDraw support 657 return false; 658 } 659 660 // ----------------------------------------------------------------------- 661 662 bool Os2SalGraphics::drawPolyLine( 663 const basegfx::B2DPolygon& /*rPolygon*/, 664 double /*fTransparency*/, 665 const basegfx::B2DVector& /*rLineWidths*/, 666 basegfx::B2DLineJoin /*eLineJoin*/) 667 { 668 // TODO: implement 669 return false; 670 } 671 672 // ----------------------------------------------------------------------- 673 674 sal_Bool Os2SalGraphics::drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) 675 { 676 return sal_False; 677 } 678 679 // ----------------------------------------------------------------------- 680 681 sal_Bool Os2SalGraphics::drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) 682 { 683 return sal_False; 684 } 685 686 // ----------------------------------------------------------------------- 687 688 sal_Bool Os2SalGraphics::drawPolyPolygonBezier( ULONG nPoly, const ULONG* pPoints, 689 const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry ) 690 { 691 return sal_False; 692 } 693 694 // ======================================================================= 695 696 // MAXIMUM BUFSIZE EQ 0xFFFF 697 #define POSTSCRIPT_BUFSIZE 0x4000 698 // we only try to get the BoundingBox in the first 4096 PM_BYTEs 699 #define POSTSCRIPT_BOUNDINGSEARCH 0x1000 700 701 static PM_BYTE* ImplSearchEntry( PM_BYTE* pSource, PM_BYTE* pDest, ULONG nComp, ULONG nSize ) 702 { 703 while ( nComp-- >= nSize ) 704 { 705 ULONG i; 706 for ( i = 0; i < nSize; i++ ) 707 { 708 if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) ) 709 break; 710 } 711 if ( i == nSize ) 712 return pSource; 713 pSource++; 714 } 715 return NULL; 716 } 717 718 719 static PM_BOOL ImplGetBoundingBox( double* nNumb, PM_BYTE* pSource, ULONG nSize ) 720 { 721 PM_BOOL bRetValue = FALSE; 722 PM_BYTE* pDest = ImplSearchEntry( pSource, (PM_BYTE*)"%%BoundingBox:", nSize, 14 ); 723 if ( pDest ) 724 { 725 nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0; 726 pDest += 14; 727 728 int nSizeLeft = nSize - ( pDest - pSource ); 729 if ( nSizeLeft > 100 ) 730 nSizeLeft = 100; // only 100 PM_BYTEs following the bounding box will be checked 731 732 int i; 733 for ( i = 0; ( i < 4 ) && nSizeLeft; i++ ) 734 { 735 int nDivision = 1; 736 PM_BOOL bDivision = FALSE; 737 PM_BOOL bNegative = FALSE; 738 PM_BOOL bValid = TRUE; 739 740 while ( ( --nSizeLeft ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++; 741 PM_BYTE nPM_BYTE = *pDest; 742 while ( nSizeLeft && ( nPM_BYTE != ' ' ) && ( nPM_BYTE != 0x9 ) && ( nPM_BYTE != 0xd ) && ( nPM_BYTE != 0xa ) ) 743 { 744 switch ( nPM_BYTE ) 745 { 746 case '.' : 747 if ( bDivision ) 748 bValid = FALSE; 749 else 750 bDivision = TRUE; 751 break; 752 case '-' : 753 bNegative = TRUE; 754 break; 755 default : 756 if ( ( nPM_BYTE < '0' ) || ( nPM_BYTE > '9' ) ) 757 nSizeLeft = 1; // error parsing the bounding box values 758 else if ( bValid ) 759 { 760 if ( bDivision ) 761 nDivision*=10; 762 nNumb[i] *= 10; 763 nNumb[i] += nPM_BYTE - '0'; 764 } 765 break; 766 } 767 nSizeLeft--; 768 nPM_BYTE = *(++pDest); 769 } 770 if ( bNegative ) 771 nNumb[i] = -nNumb[i]; 772 if ( bDivision && ( nDivision != 1 ) ) 773 nNumb[i] /= nDivision; 774 } 775 if ( i == 4 ) 776 bRetValue = TRUE; 777 } 778 return bRetValue; 779 } 780 781 #if 0 782 static void ImplWriteDouble( PM_BYTE** pBuf, double nNumber ) 783 { 784 // *pBuf += sprintf( (char*)*pBuf, "%f", nNumber ); 785 786 if ( nNumber < 0 ) 787 { 788 *(*pBuf)++ = (PM_BYTE)'-'; 789 nNumber = -nNumber; 790 } 791 ULONG nTemp = (ULONG)nNumber; 792 const String aNumber1( nTemp ); 793 ULONG nLen = aNumber1.Len(); 794 795 for ( USHORT n = 0; n < nLen; n++ ) 796 *(*pBuf)++ = aNumber1[ n ]; 797 798 nTemp = (ULONG)( ( nNumber - nTemp ) * 100000 ); 799 if ( nTemp ) 800 { 801 *(*pBuf)++ = (PM_BYTE)'.'; 802 const String aNumber2( nTemp ); 803 804 ULONG nLen = aNumber2.Len(); 805 if ( nLen < 8 ) 806 { 807 for ( n = 0; n < ( 5 - nLen ); n++ ) 808 { 809 *(*pBuf)++ = (PM_BYTE)'0'; 810 } 811 } 812 for ( USHORT n = 0; n < nLen; n++ ) 813 { 814 *(*pBuf)++ = aNumber2[ n ]; 815 } 816 } 817 *(*pBuf)++ = ' '; 818 } 819 #endif 820 821 inline void ImplWriteString( PM_BYTE** pBuf, const char* sString ) 822 { 823 strcpy( (char*)*pBuf, sString ); 824 *pBuf += strlen( sString ); 825 } 826 827 sal_Bool Os2SalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ) 828 { 829 if ( !mbPrinter ) 830 return FALSE; 831 832 PM_BOOL bRet = FALSE; 833 LONG nLong = 0; 834 if ( !(DevQueryCaps( mhDC, CAPS_TECHNOLOGY, 1, &nLong ) && 835 (CAPS_TECH_POSTSCRIPT == nLong)) ) 836 return FALSE; 837 838 PM_BYTE* pBuf = new PM_BYTE[ POSTSCRIPT_BUFSIZE ]; 839 double nBoundingBox[4]; 840 841 if ( pBuf && ImplGetBoundingBox( nBoundingBox, (PM_BYTE*)pPtr, nSize ) ) 842 { 843 LONG pOS2DXAry[4]; // hack -> print always 2 white space 844 POINTL aPt; 845 aPt.x = 0; 846 aPt.y = 0; 847 PCH pStr = (PCH) " "; 848 for( long i = 0; i < 4; i++ ) 849 pOS2DXAry[i] = i; 850 Ft2CharStringPosAt( mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] ); 851 852 OStringBuffer aBuf( POSTSCRIPT_BUFSIZE ); 853 854 // reserve place for a USHORT 855 aBuf.append( "aa" ); 856 857 // #107797# Write out EPS encapsulation header 858 // ---------------------------------------------------------------------------------- 859 860 // directly taken from the PLRM 3.0, p. 726. Note: 861 // this will definitely cause problems when 862 // recursively creating and embedding PostScript files 863 // in OOo, since we use statically-named variables 864 // here (namely, b4_Inc_state_salWin, dict_count_salWin and 865 // op_count_salWin). Currently, I have no idea on how to 866 // work around that, except from scanning and 867 // interpreting the EPS for unused identifiers. 868 869 // append the real text 870 aBuf.append( "\n\n/b4_Inc_state_salWin save def\n" 871 "/dict_count_salWin countdictstack def\n" 872 "/op_count_salWin count 1 sub def\n" 873 "userdict begin\n" 874 "/showpage {} def\n" 875 "0 setgray 0 setlinecap\n" 876 "1 setlinewidth 0 setlinejoin\n" 877 "10 setmiterlimit [] 0 setdash newpath\n" 878 "/languagelevel where\n" 879 "{\n" 880 " pop languagelevel\n" 881 " 1 ne\n" 882 " {\n" 883 " false setstrokeadjust false setoverprint\n" 884 " } if\n" 885 "} if\n\n" ); 886 887 #if 0 888 // #i10737# Apply clipping manually 889 // ---------------------------------------------------------------------------------- 890 891 // Windows seems to ignore any clipping at the HDC, 892 // when followed by a POSTSCRIPT_PASSTHROUGH 893 894 // Check whether we've got a clipping, consisting of 895 // exactly one rect (other cases should be, but aren't 896 // handled currently) 897 898 // TODO: Handle more than one rectangle here (take 899 // care, the buffer can handle only POSTSCRIPT_BUFSIZE 900 // characters!) 901 if ( mhRegion != 0 && 902 mpStdClipRgnData != NULL && 903 mpClipRgnData == mpStdClipRgnData && 904 mpClipRgnData->rdh.nCount == 1 ) 905 { 906 RECT* pRect = &(mpClipRgnData->rdh.rcBound); 907 908 aBuf.append( "\nnewpath\n" ); 909 aBuf.append( pRect->left ); 910 aBuf.append( " " ); 911 aBuf.append( pRect->top ); 912 aBuf.append( " moveto\n" ); 913 aBuf.append( pRect->right ); 914 aBuf.append( " " ); 915 aBuf.append( pRect->top ); 916 aBuf.append( " lineto\n" ); 917 aBuf.append( pRect->right ); 918 aBuf.append( " " ); 919 aBuf.append( pRect->bottom ); 920 aBuf.append( " lineto\n" ); 921 aBuf.append( pRect->left ); 922 aBuf.append( " " ); 923 aBuf.append( pRect->bottom ); 924 aBuf.append( " lineto\n" 925 "closepath\n" 926 "clip\n" 927 "newpath\n" ); 928 } 929 #endif 930 931 // #107797# Write out buffer 932 // ---------------------------------------------------------------------------------- 933 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 ); 934 //Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); 935 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(), 936 (PM_BYTE*)aBuf.getStr(), 0, NULL ); 937 938 double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] ); 939 double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) ); 940 941 // reserve a USHORT again 942 aBuf.setLength( 2 ); 943 aBuf.append( "\n\n[" ); 944 aBuf.append( dM11 ); 945 aBuf.append( " 0 0 " ); 946 aBuf.append( dM22 ); 947 aBuf.append( ' ' ); 948 aBuf.append( nX - ( dM11 * nBoundingBox[0] ) ); 949 aBuf.append( ' ' ); 950 aBuf.append( nY - ( dM22 * nBoundingBox[3] ) ); 951 aBuf.append( "] concat\n" 952 "%%BeginDocument:\n" ); 953 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 ); 954 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(), 955 (PM_BYTE*)aBuf.getStr(), 0, NULL ); 956 #if 0 957 PM_BYTE* pTemp = pBuf; 958 ImplWriteString( &pTemp, "save\n[ " ); 959 ImplWriteDouble( &pTemp, dM11 ); 960 ImplWriteDouble( &pTemp, 0 ); 961 ImplWriteDouble( &pTemp, 0 ); 962 ImplWriteDouble( &pTemp, dM22 ); 963 ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) ); 964 ImplWriteDouble( &pTemp, mnHeight - nY - ( dM22 * nBoundingBox[3] ) ); 965 ImplWriteString( &pTemp, "] concat /showpage {} def\n" ); 966 967 if ( DevEscape( mhDC, DEVESC_RAWDATA, pTemp - pBuf, 968 (PM_BYTE*)pBuf, 0, NULL ) == DEV_OK ) 969 #endif // 970 { 971 sal_uInt32 nToDo = nSize; 972 sal_uInt32 nDoNow; 973 bRet = TRUE; 974 while( nToDo && bRet ) 975 { 976 nDoNow = 0x4000; 977 if ( nToDo < nDoNow ) 978 nDoNow = nToDo; 979 980 if ( DevEscape( mhDC, DEVESC_RAWDATA, nDoNow, (PM_BYTE*)pPtr + nSize - nToDo, 981 0, NULL ) == -1 ) 982 bRet = FALSE; 983 nToDo -= nDoNow; 984 } 985 986 if ( bRet ) 987 { 988 strcpy ( (char*)pBuf, "\nrestore\n" ); 989 if ( DevEscape( mhDC, DEVESC_RAWDATA, 9, (PM_BYTE*)pBuf, 990 0, NULL ) == DEV_OK ) bRet = TRUE; 991 } 992 993 // #107797# Write out EPS encapsulation footer 994 // ---------------------------------------------------------------------------------- 995 // reserve a USHORT again 996 aBuf.setLength( 2 ); 997 aBuf.append( "%%EndDocument\n" 998 "count op_count_salWin sub {pop} repeat\n" 999 "countdictstack dict_count_salWin sub {end} repeat\n" 1000 "b4_Inc_state_salWin restore\n\n" ); 1001 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 ); 1002 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(), 1003 (PM_BYTE*)aBuf.getStr(), 0, NULL ); 1004 bRet = TRUE; 1005 1006 } 1007 } 1008 delete [] pBuf; 1009 return bRet; 1010 } 1011 1012 /* 1013 * IsNativeControlSupported() 1014 * 1015 * Returns TRUE if the platform supports native 1016 * drawing of the control defined by nPart 1017 */ 1018 sal_Bool Os2SalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart ) 1019 { 1020 return( FALSE ); 1021 } 1022 1023 // ----------------------------------------------------------------------- 1024 1025 SystemGraphicsData Os2SalGraphics::GetGraphicsData() const 1026 { 1027 SystemGraphicsData aRes; 1028 aRes.nSize = sizeof(aRes); 1029 #if 0 1030 aRes.hDC = mhDC; 1031 #endif 1032 return aRes; 1033 } 1034 1035 // ----------------------------------------------------------------------- 1036