merge the formfield patch from ooo-build
[ooovba.git] / vcl / os2 / source / gdi / salgdi.cxx
blob688b234bdc682d4d1e6b4c6637b8c65ac914f598
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salgdi.cxx,v $
10 * $Revision: 1.8.6.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <string.h>
32 #include <svpm.h>
34 #define _SV_SALGDI_CXX
35 #include <tools/debug.hxx>
36 #include <saldata.hxx>
37 #include <salgdi.h>
38 #include <tools/debug.hxx>
39 #include <salframe.h>
40 #include <tools/poly.hxx>
41 #ifndef _RTL_STRINGBUF_HXX
42 #include <rtl/strbuf.hxx>
43 #endif
45 #ifndef __H_FT2LIB
46 #include <wingdi.h>
47 #include <ft2lib.h>
48 #endif
50 // -----------
51 // - Defines -
52 // -----------
54 // ClipRegions funktionieren immer noch nicht auf allen getesteten Druckern
55 #define SAL_PRINTER_CLIPPATH 1
56 // #define SAL_PRINTER_POLYPATH 1
58 // =======================================================================
60 void ImplInitSalGDI()
64 // -----------------------------------------------------------------------
66 void ImplFreeSalGDI()
68 SalData* pSalData = GetSalData();
70 // delete icon cache
71 SalIcon* pIcon = pSalData->mpFirstIcon;
72 while( pIcon )
74 SalIcon* pTmp = pIcon->pNext;
75 WinDestroyPointer( pIcon->hIcon );
76 delete pIcon;
77 pIcon = pTmp;
82 // =======================================================================
84 void ImplSalInitGraphics( Os2SalGraphics* pData )
86 GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL );
89 // -----------------------------------------------------------------------
91 void ImplSalDeInitGraphics( Os2SalGraphics* pData )
95 // =======================================================================
97 Os2SalGraphics::Os2SalGraphics()
99 for( int i = 0; i < MAX_FALLBACK; ++i )
101 mhFonts[ i ] = 0;
102 mpOs2FontData[ i ] = NULL;
103 mpOs2FontEntry[ i ] = NULL;
106 mfFontScale = 1.0;
108 mhPS = 0;
109 mhDC = 0;
110 mbLine = FALSE;
111 mbFill = FALSE;
112 mbXORMode = FALSE;
113 mnFontMetricCount = 0;
114 mpFontMetrics = NULL;
115 mpClipRectlAry = NULL;
117 mhDefFont = 0;
118 mpFontKernPairs = NULL;
119 mnFontKernPairCount = 0;
120 mbFontKernInit = FALSE;
124 // -----------------------------------------------------------------------
126 Os2SalGraphics::~Os2SalGraphics()
128 Ft2DeleteSetId( mhPS, LCID_BASE);
130 if ( mpFontMetrics )
131 delete mpFontMetrics;
133 if ( mpFontKernPairs )
134 delete mpFontKernPairs;
138 // -----------------------------------------------------------------------
140 static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
142 SalColor nSalColor;
144 switch( nROPColor )
146 case SAL_ROP_0:
147 nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
148 break;
150 case SAL_ROP_1:
151 case SAL_ROP_INVERT:
152 nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
153 break;
156 return nSalColor;
159 // -----------------------------------------------------------------------
161 void Os2SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
163 // since OOo asks for DPI, I will query FONT_RES, which seems to be
164 // more correct than _RESOLUTION fields (on my wide screen lcd)
165 // and does not require conversion
166 DevQueryCaps( mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &rDPIX );
167 DevQueryCaps( mhDC, CAPS_VERTICAL_FONT_RES, 1, &rDPIY );
170 // -----------------------------------------------------------------------
172 USHORT Os2SalGraphics::GetBitCount()
174 LONG nBitCount;
175 DevQueryCaps( mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount );
176 return (USHORT)nBitCount;
179 // -----------------------------------------------------------------------
181 long Os2SalGraphics::GetGraphicsWidth() const
183 if( mhWnd )
185 Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( mhWnd );
186 if( pFrame )
188 if( pFrame->maGeometry.nWidth )
189 return pFrame->maGeometry.nWidth;
190 else
192 // TODO: perhaps not needed, maGeometry should always be up-to-date
193 RECTL aRect;
194 WinQueryWindowRect( mhWnd, &aRect );
195 return aRect.xRight;
200 return 0;
203 // -----------------------------------------------------------------------
205 void Os2SalGraphics::ResetClipRegion()
207 #ifdef SAL_PRINTER_CLIPPATH
208 if ( mbPrinter )
209 GpiSetClipPath( mhPS, 0, SCP_RESET );
210 else
211 #endif
213 HRGN hOldRegion;
215 GpiSetClipRegion( mhPS, NULL, &hOldRegion );
216 if ( hOldRegion )
217 GpiDestroyRegion( mhPS, hOldRegion );
221 // -----------------------------------------------------------------------
223 void Os2SalGraphics::BeginSetClipRegion( ULONG nCount )
225 mpClipRectlAry = new RECTL[ nCount ];
226 mnClipElementCount = 0;
229 // -----------------------------------------------------------------------
231 BOOL Os2SalGraphics::unionClipRegion( long nX, long nY, long nWidth, long nHeight )
233 RECTL* pClipRect = &mpClipRectlAry[ mnClipElementCount ];
234 pClipRect->xLeft = nX;
235 pClipRect->yTop = mnHeight - nY;
236 pClipRect->xRight = nX + nWidth;
237 pClipRect->yBottom = mnHeight - (nY + nHeight);
238 mnClipElementCount++;
240 return TRUE;
243 // -----------------------------------------------------------------------
245 bool Os2SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& )
247 // TODO: implement and advertise OutDevSupport_B2DClip support
248 return false;
251 // -----------------------------------------------------------------------
253 void Os2SalGraphics::EndSetClipRegion()
255 #ifdef SAL_PRINTER_CLIPPATH
256 if ( mbPrinter )
258 GpiSetClipPath( mhPS, 0, SCP_RESET );
259 GpiBeginPath( mhPS, 1L );
261 for( int i = 0; i < mnClipElementCount; i++ )
263 POINTL aPt;
264 RECTL* pClipRect = &mpClipRectlAry[ i ];
266 aPt.x = pClipRect->xLeft;
267 aPt.y = pClipRect->yTop-1;
268 Ft2Move( mhPS, &aPt );
270 aPt.x = pClipRect->xRight-1;
271 aPt.y = pClipRect->yBottom;
273 Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 );
276 GpiEndPath( mhPS );
277 GpiSetClipPath( mhPS, 1L, SCP_ALTERNATE | SCP_AND );
279 else
280 #endif
282 HRGN hClipRegion = GpiCreateRegion( mhPS,
283 mnClipElementCount,
284 mpClipRectlAry );
285 HRGN hOldRegion;
287 GpiSetClipRegion( mhPS, hClipRegion, &hOldRegion );
288 if( hOldRegion )
289 GpiDestroyRegion( mhPS, hOldRegion );
292 delete [] mpClipRectlAry;
295 // -----------------------------------------------------------------------
297 void Os2SalGraphics::SetLineColor()
299 // don't draw line!
300 mbLine = FALSE;
303 // -----------------------------------------------------------------------
305 void Os2SalGraphics::SetLineColor( SalColor nSalColor )
307 LINEBUNDLE lb;
309 // set color
310 lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
311 SALCOLOR_GREEN( nSalColor ),
312 SALCOLOR_BLUE( nSalColor ) );
314 Ft2SetAttrs( mhPS,
315 PRIM_LINE,
316 LBB_COLOR,
318 &lb );
320 // draw line!
321 mbLine = TRUE;
324 // -----------------------------------------------------------------------
326 void Os2SalGraphics::SetFillColor()
328 // don't fill area!
329 mbFill = FALSE;
332 // -----------------------------------------------------------------------
334 void Os2SalGraphics::SetFillColor( SalColor nSalColor )
336 AREABUNDLE ab;
338 // set color
339 ab.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
340 SALCOLOR_GREEN( nSalColor ),
341 SALCOLOR_BLUE( nSalColor ) );
343 Ft2SetAttrs( mhPS,
344 PRIM_AREA,
345 ABB_COLOR,
347 &ab );
349 // fill area!
350 mbFill = TRUE;
353 // -----------------------------------------------------------------------
355 void Os2SalGraphics::SetXORMode( bool bSet, bool )
357 mbXORMode = bSet;
358 LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT;
360 // set mix mode for lines
361 LINEBUNDLE lb;
362 lb.usMixMode = nMixMode;
363 Ft2SetAttrs( mhPS,
364 PRIM_LINE,
365 LBB_MIX_MODE,
367 &lb );
369 // set mix mode for areas
370 AREABUNDLE ab;
371 ab.usMixMode = nMixMode;
372 Ft2SetAttrs( mhPS,
373 PRIM_AREA,
374 ABB_MIX_MODE,
376 &ab );
378 // set mix mode for text
379 CHARBUNDLE cb;
380 cb.usMixMode = nMixMode;
381 Ft2SetAttrs( mhPS,
382 PRIM_CHAR,
383 CBB_MIX_MODE,
385 &cb );
388 // -----------------------------------------------------------------------
390 void Os2SalGraphics::SetROPLineColor( SalROPColor nROPColor )
392 SetLineColor( ImplGetROPSalColor( nROPColor ) );
395 // -----------------------------------------------------------------------
397 void Os2SalGraphics::SetROPFillColor( SalROPColor nROPColor )
399 SetFillColor( ImplGetROPSalColor( nROPColor ) );
402 // -----------------------------------------------------------------------
404 void Os2SalGraphics::drawPixel( long nX, long nY )
406 POINTL aPt;
408 aPt.x = nX;
409 aPt.y = TY( nY );
411 // set color
412 Ft2SetPel( mhPS, &aPt );
415 // -----------------------------------------------------------------------
417 void Os2SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
419 // save old color
420 LINEBUNDLE oldLb;
421 GpiQueryAttrs( mhPS,
422 PRIM_LINE,
423 LBB_COLOR,
424 &oldLb );
426 // set new color
427 LINEBUNDLE lb;
428 lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
429 SALCOLOR_GREEN( nSalColor ),
430 SALCOLOR_BLUE( nSalColor ) );
431 Ft2SetAttrs( mhPS,
432 PRIM_LINE,
433 LBB_COLOR,
435 &lb );
437 // set color of pixel
438 POINTL aPt;
439 aPt.x = nX;
440 aPt.y = TY( nY );
441 Ft2SetPel( mhPS, &aPt );
443 // restore old color
444 Ft2SetAttrs( mhPS,
445 PRIM_LINE,
446 LBB_COLOR,
448 &oldLb );
451 // -----------------------------------------------------------------------
453 void Os2SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
455 // OS2 zeichnet den Endpunkt mit
456 POINTL aPt;
457 aPt.x = nX1;
458 aPt.y = TY( nY1 );
459 Ft2Move( mhPS, &aPt );
460 aPt.x = nX2;
461 aPt.y = TY( nY2 );
462 GpiLine( mhPS, &aPt );
465 // -----------------------------------------------------------------------
467 void Os2SalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
469 POINTL aPt;
470 long lControl;
472 if ( mbFill )
474 if ( mbLine )
475 lControl = DRO_OUTLINEFILL;
476 else
477 lControl = DRO_FILL;
479 else
481 if ( mbLine )
482 lControl = DRO_OUTLINE;
483 else
484 return;
487 aPt.x = nX;
488 aPt.y = TY( nY );
489 Ft2Move( mhPS, &aPt );
490 aPt.x = nX + nWidth - 1;
491 aPt.y = TY( nY + nHeight - 1 );
492 Ft2Box( mhPS, lControl, &aPt, 0, 0 );
495 // -----------------------------------------------------------------------
497 void Os2SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
499 // convert all points to sys orientation
500 POINTL* pOS2PtAry = new POINTL[ nPoints ];
501 POINTL* pTempOS2PtAry = pOS2PtAry;
502 const SalPoint* pTempPtAry = pPtAry;
503 ULONG nTempPoints = nPoints;
504 long nHeight = mnHeight - 1;
506 while( nTempPoints-- )
508 (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
509 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
510 pTempOS2PtAry++;
511 pTempPtAry++;
514 Ft2Move( mhPS, pOS2PtAry );
515 GpiPolyLine( mhPS, nPoints, pOS2PtAry );
516 delete [] pOS2PtAry;
519 // -----------------------------------------------------------------------
521 void Os2SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry )
523 PM_POLYGON aPolygon;
525 // create polygon
526 aPolygon.aPointl = new POINTL[ nPoints ];
527 aPolygon.ulPoints = nPoints;
529 // convert all points to sys orientation
530 POINTL* pTempOS2PtAry = aPolygon.aPointl;
531 const SalPoint* pTempPtAry = pPtAry;
532 ULONG nTempPoints = nPoints;
533 long nHeight = mnHeight - 1;
535 while( nTempPoints-- )
537 (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
538 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
539 pTempOS2PtAry++;
540 pTempPtAry++;
543 // Innenleben zeichnen
544 if ( mbFill )
546 #ifdef SAL_PRINTER_POLYPATH
547 if ( mbPrinter )
549 Ft2BeginPath( mhPS, 1 );
550 Ft2Move( mhPS, aPolygon.aPointl );
551 Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
552 Ft2EndPath( mhPS );
553 Ft2FillPath( mhPS, 1, 0 );
555 if ( mbLine )
557 Ft2Move( mhPS, aPolygon.aPointl );
558 Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
561 else
562 #endif
564 ULONG nOptions = POLYGON_ALTERNATE;
566 if ( mbLine )
567 nOptions |= POLYGON_BOUNDARY;
568 else
569 nOptions |= POLYGON_NOBOUNDARY;
571 Ft2Move( mhPS, aPolygon.aPointl );
572 GpiPolygons( mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL );
575 else
577 if ( mbLine )
579 Ft2Move( mhPS, aPolygon.aPointl );
580 GpiPolyLine( mhPS, nPoints, aPolygon.aPointl );
584 delete [] aPolygon.aPointl;
587 // -----------------------------------------------------------------------
589 void Os2SalGraphics::drawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
590 PCONSTSALPOINT* pPtAry )
592 ULONG i;
593 long nHeight = mnHeight - 1;
594 PM_POLYGON* aPolygonAry = new PM_POLYGON[ nPoly ];
596 for( i = 0; i < nPoly; i++ )
598 const SalPoint * pTempPtAry = (const SalPoint*)pPtAry[ i ];
600 // create polygon
601 ULONG nTempPoints = pPoints[ i ];
602 POINTL * pTempOS2PtAry = new POINTL[ nTempPoints ];
604 // convert all points to sys orientation
605 aPolygonAry[ i ].ulPoints = nTempPoints;
606 aPolygonAry[ i ].aPointl = pTempOS2PtAry;
608 while( nTempPoints-- )
610 (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
611 (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
612 pTempOS2PtAry++;
613 pTempPtAry++;
617 // Innenleben zeichnen
618 if ( mbFill )
620 #ifdef SAL_PRINTER_POLYPATH
621 if ( mbPrinter )
623 Ft2BeginPath( mhPS, 1 );
624 for ( i = 0; i < nPoly; i++ )
626 Ft2Move( mhPS, aPolygonAry[i].aPointl );
627 Ft2PolyLine( mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl );
629 Ft2EndPath( mhPS );
630 Ft2FillPath( mhPS, 1, 0 );
632 else
633 #endif
635 ULONG nOptions = POLYGON_ALTERNATE;
637 if ( mbLine )
638 nOptions |= POLYGON_BOUNDARY;
639 else
640 nOptions |= POLYGON_NOBOUNDARY;
642 Ft2Move( mhPS, aPolygonAry[ 0 ].aPointl );
643 GpiPolygons( mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL );
646 else
648 if ( mbLine )
650 for( i = 0; i < nPoly; i++ )
652 Ft2Move( mhPS, aPolygonAry[ i ].aPointl );
653 GpiPolyLine( mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl );
658 // cleanup
659 for( i = 0; i < nPoly; i++ )
660 delete [] aPolygonAry[ i ].aPointl;
661 delete [] aPolygonAry;
664 // -----------------------------------------------------------------------
666 bool Os2SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
668 // TODO: implement and advertise OutDevSupport_B2DDraw support
669 return false;
672 // -----------------------------------------------------------------------
674 bool Os2SalGraphics::drawPolyLine(
675 const basegfx::B2DPolygon& /*rPolygon*/,
676 const basegfx::B2DVector& /*rLineWidths*/,
677 basegfx::B2DLineJoin /*eLineJoin*/)
679 // TODO: implement
680 return false;
683 // -----------------------------------------------------------------------
685 sal_Bool Os2SalGraphics::drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
687 return sal_False;
690 // -----------------------------------------------------------------------
692 sal_Bool Os2SalGraphics::drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
694 return sal_False;
697 // -----------------------------------------------------------------------
699 sal_Bool Os2SalGraphics::drawPolyPolygonBezier( ULONG nPoly, const ULONG* pPoints,
700 const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
702 return sal_False;
705 // =======================================================================
707 // MAXIMUM BUFSIZE EQ 0xFFFF
708 #define POSTSCRIPT_BUFSIZE 0x4000
709 // we only try to get the BoundingBox in the first 4096 bytes
710 #define POSTSCRIPT_BOUNDINGSEARCH 0x1000
712 static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
714 while ( nComp-- >= nSize )
716 ULONG i;
717 for ( i = 0; i < nSize; i++ )
719 if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
720 break;
722 if ( i == nSize )
723 return pSource;
724 pSource++;
726 return NULL;
730 static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
732 BOOL bRetValue = FALSE;
733 BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nSize, 14 );
734 if ( pDest )
736 nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
737 pDest += 14;
739 int nSizeLeft = nSize - ( pDest - pSource );
740 if ( nSizeLeft > 100 )
741 nSizeLeft = 100; // only 100 bytes following the bounding box will be checked
743 int i;
744 for ( i = 0; ( i < 4 ) && nSizeLeft; i++ )
746 int nDivision = 1;
747 BOOL bDivision = FALSE;
748 BOOL bNegative = FALSE;
749 BOOL bValid = TRUE;
751 while ( ( --nSizeLeft ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
752 BYTE nByte = *pDest;
753 while ( nSizeLeft && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
755 switch ( nByte )
757 case '.' :
758 if ( bDivision )
759 bValid = FALSE;
760 else
761 bDivision = TRUE;
762 break;
763 case '-' :
764 bNegative = TRUE;
765 break;
766 default :
767 if ( ( nByte < '0' ) || ( nByte > '9' ) )
768 nSizeLeft = 1; // error parsing the bounding box values
769 else if ( bValid )
771 if ( bDivision )
772 nDivision*=10;
773 nNumb[i] *= 10;
774 nNumb[i] += nByte - '0';
776 break;
778 nSizeLeft--;
779 nByte = *(++pDest);
781 if ( bNegative )
782 nNumb[i] = -nNumb[i];
783 if ( bDivision && ( nDivision != 1 ) )
784 nNumb[i] /= nDivision;
786 if ( i == 4 )
787 bRetValue = TRUE;
789 return bRetValue;
792 #if 0
793 static void ImplWriteDouble( BYTE** pBuf, double nNumber )
795 // *pBuf += sprintf( (char*)*pBuf, "%f", nNumber );
797 if ( nNumber < 0 )
799 *(*pBuf)++ = (BYTE)'-';
800 nNumber = -nNumber;
802 ULONG nTemp = (ULONG)nNumber;
803 const String aNumber1( nTemp );
804 ULONG nLen = aNumber1.Len();
806 for ( USHORT n = 0; n < nLen; n++ )
807 *(*pBuf)++ = aNumber1[ n ];
809 nTemp = (ULONG)( ( nNumber - nTemp ) * 100000 );
810 if ( nTemp )
812 *(*pBuf)++ = (BYTE)'.';
813 const String aNumber2( nTemp );
815 ULONG nLen = aNumber2.Len();
816 if ( nLen < 8 )
818 for ( n = 0; n < ( 5 - nLen ); n++ )
820 *(*pBuf)++ = (BYTE)'0';
823 for ( USHORT n = 0; n < nLen; n++ )
825 *(*pBuf)++ = aNumber2[ n ];
828 *(*pBuf)++ = ' ';
830 #endif
832 inline void ImplWriteString( BYTE** pBuf, const char* sString )
834 strcpy( (char*)*pBuf, sString );
835 *pBuf += strlen( sString );
838 BOOL Os2SalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
840 if ( !mbPrinter )
841 return FALSE;
843 BOOL bRet = FALSE;
844 LONG nLong = 0;
845 if ( !(DevQueryCaps( mhDC, CAPS_TECHNOLOGY, 1, &nLong ) &&
846 (CAPS_TECH_POSTSCRIPT == nLong)) )
847 return FALSE;
849 BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
850 double nBoundingBox[4];
852 if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
854 LONG pOS2DXAry[4]; // hack -> print always 2 white space
855 POINTL aPt;
856 aPt.x = 0;
857 aPt.y = 0;
858 PCH pStr = (PCH) " ";
859 for( long i = 0; i < 4; i++ )
860 pOS2DXAry[i] = i;
861 Ft2CharStringPosAt( mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] );
863 OStringBuffer aBuf( POSTSCRIPT_BUFSIZE );
865 // reserve place for a USHORT
866 aBuf.append( "aa" );
868 // #107797# Write out EPS encapsulation header
869 // ----------------------------------------------------------------------------------
871 // directly taken from the PLRM 3.0, p. 726. Note:
872 // this will definitely cause problems when
873 // recursively creating and embedding PostScript files
874 // in OOo, since we use statically-named variables
875 // here (namely, b4_Inc_state_salWin, dict_count_salWin and
876 // op_count_salWin). Currently, I have no idea on how to
877 // work around that, except from scanning and
878 // interpreting the EPS for unused identifiers.
880 // append the real text
881 aBuf.append( "\n\n/b4_Inc_state_salWin save def\n"
882 "/dict_count_salWin countdictstack def\n"
883 "/op_count_salWin count 1 sub def\n"
884 "userdict begin\n"
885 "/showpage {} def\n"
886 "0 setgray 0 setlinecap\n"
887 "1 setlinewidth 0 setlinejoin\n"
888 "10 setmiterlimit [] 0 setdash newpath\n"
889 "/languagelevel where\n"
890 "{\n"
891 " pop languagelevel\n"
892 " 1 ne\n"
893 " {\n"
894 " false setstrokeadjust false setoverprint\n"
895 " } if\n"
896 "} if\n\n" );
898 #if 0
899 // #i10737# Apply clipping manually
900 // ----------------------------------------------------------------------------------
902 // Windows seems to ignore any clipping at the HDC,
903 // when followed by a POSTSCRIPT_PASSTHROUGH
905 // Check whether we've got a clipping, consisting of
906 // exactly one rect (other cases should be, but aren't
907 // handled currently)
909 // TODO: Handle more than one rectangle here (take
910 // care, the buffer can handle only POSTSCRIPT_BUFSIZE
911 // characters!)
912 if ( mhRegion != 0 &&
913 mpStdClipRgnData != NULL &&
914 mpClipRgnData == mpStdClipRgnData &&
915 mpClipRgnData->rdh.nCount == 1 )
917 RECT* pRect = &(mpClipRgnData->rdh.rcBound);
919 aBuf.append( "\nnewpath\n" );
920 aBuf.append( pRect->left );
921 aBuf.append( " " );
922 aBuf.append( pRect->top );
923 aBuf.append( " moveto\n" );
924 aBuf.append( pRect->right );
925 aBuf.append( " " );
926 aBuf.append( pRect->top );
927 aBuf.append( " lineto\n" );
928 aBuf.append( pRect->right );
929 aBuf.append( " " );
930 aBuf.append( pRect->bottom );
931 aBuf.append( " lineto\n" );
932 aBuf.append( pRect->left );
933 aBuf.append( " " );
934 aBuf.append( pRect->bottom );
935 aBuf.append( " lineto\n"
936 "closepath\n"
937 "clip\n"
938 "newpath\n" );
940 #endif
942 // #107797# Write out buffer
943 // ----------------------------------------------------------------------------------
944 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
945 //Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
946 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
947 (PBYTE)aBuf.getStr(), 0, NULL );
949 double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
950 double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) );
952 // reserve a USHORT again
953 aBuf.setLength( 2 );
954 aBuf.append( "\n\n[" );
955 aBuf.append( dM11 );
956 aBuf.append( " 0 0 " );
957 aBuf.append( dM22 );
958 aBuf.append( ' ' );
959 aBuf.append( nX - ( dM11 * nBoundingBox[0] ) );
960 aBuf.append( ' ' );
961 aBuf.append( nY - ( dM22 * nBoundingBox[3] ) );
962 aBuf.append( "] concat\n"
963 "%%BeginDocument:\n" );
964 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
965 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
966 (PBYTE)aBuf.getStr(), 0, NULL );
967 #if 0
968 BYTE* pTemp = pBuf;
969 ImplWriteString( &pTemp, "save\n[ " );
970 ImplWriteDouble( &pTemp, dM11 );
971 ImplWriteDouble( &pTemp, 0 );
972 ImplWriteDouble( &pTemp, 0 );
973 ImplWriteDouble( &pTemp, dM22 );
974 ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
975 ImplWriteDouble( &pTemp, mnHeight - nY - ( dM22 * nBoundingBox[3] ) );
976 ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
978 if ( DevEscape( mhDC, DEVESC_RAWDATA, pTemp - pBuf,
979 (PBYTE)pBuf, 0, NULL ) == DEV_OK )
980 #endif //
982 UINT32 nToDo = nSize;
983 UINT32 nDoNow;
984 bRet = TRUE;
985 while( nToDo && bRet )
987 nDoNow = 0x4000;
988 if ( nToDo < nDoNow )
989 nDoNow = nToDo;
991 if ( DevEscape( mhDC, DEVESC_RAWDATA, nDoNow, (PBYTE)pPtr + nSize - nToDo,
992 0, NULL ) == -1 )
993 bRet = FALSE;
994 nToDo -= nDoNow;
997 if ( bRet )
999 strcpy ( (char*)pBuf, "\nrestore\n" );
1000 if ( DevEscape( mhDC, DEVESC_RAWDATA, 9, (PBYTE)pBuf,
1001 0, NULL ) == DEV_OK ) bRet = TRUE;
1004 // #107797# Write out EPS encapsulation footer
1005 // ----------------------------------------------------------------------------------
1006 // reserve a USHORT again
1007 aBuf.setLength( 2 );
1008 aBuf.append( "%%EndDocument\n"
1009 "count op_count_salWin sub {pop} repeat\n"
1010 "countdictstack dict_count_salWin sub {end} repeat\n"
1011 "b4_Inc_state_salWin restore\n\n" );
1012 *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
1013 DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
1014 (PBYTE)aBuf.getStr(), 0, NULL );
1015 bRet = TRUE;
1019 delete pBuf;
1020 return bRet;
1024 * IsNativeControlSupported()
1026 * Returns TRUE if the platform supports native
1027 * drawing of the control defined by nPart
1029 BOOL Os2SalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
1031 return( FALSE );
1034 // -----------------------------------------------------------------------
1036 SystemGraphicsData Os2SalGraphics::GetGraphicsData() const
1038 SystemGraphicsData aRes;
1039 aRes.nSize = sizeof(aRes);
1040 #if 0
1041 aRes.hDC = mhDC;
1042 #endif
1043 return aRes;
1046 // -----------------------------------------------------------------------