summaryrefslogtreecommitdiff
path: root/vcl/os2/source/gdi/salgdi.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/os2/source/gdi/salgdi.cxx')
-rw-r--r--vcl/os2/source/gdi/salgdi.cxx1044
1 files changed, 1044 insertions, 0 deletions
diff --git a/vcl/os2/source/gdi/salgdi.cxx b/vcl/os2/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..dff1557170fb
--- /dev/null
+++ b/vcl/os2/source/gdi/salgdi.cxx
@@ -0,0 +1,1044 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <string.h>
+#include <svpm.h>
+
+#define _SV_SALGDI_CXX
+#include <tools/debug.hxx>
+#include <saldata.hxx>
+#include <salgdi.h>
+#include <tools/debug.hxx>
+#include <salframe.h>
+#include <tools/poly.hxx>
+#ifndef _RTL_STRINGBUF_HXX
+#include <rtl/strbuf.hxx>
+#endif
+
+#ifndef __H_FT2LIB
+#include <wingdi.h>
+#include <ft2lib.h>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+// ClipRegions funktionieren immer noch nicht auf allen getesteten Druckern
+#define SAL_PRINTER_CLIPPATH 1
+// #define SAL_PRINTER_POLYPATH 1
+
+// =======================================================================
+
+void ImplInitSalGDI()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeSalGDI()
+{
+ SalData* pSalData = GetSalData();
+
+ // delete icon cache
+ SalIcon* pIcon = pSalData->mpFirstIcon;
+ while( pIcon )
+ {
+ SalIcon* pTmp = pIcon->pNext;
+ WinDestroyPointer( pIcon->hIcon );
+ delete pIcon;
+ pIcon = pTmp;
+ }
+
+}
+
+// =======================================================================
+
+void ImplSalInitGraphics( Os2SalGraphics* pData )
+{
+ GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalDeInitGraphics( Os2SalGraphics* pData )
+{
+}
+
+// =======================================================================
+
+Os2SalGraphics::Os2SalGraphics()
+{
+ for( int i = 0; i < MAX_FALLBACK; ++i )
+ {
+ mhFonts[ i ] = 0;
+ mpOs2FontData[ i ] = NULL;
+ mpOs2FontEntry[ i ] = NULL;
+ }
+
+ mfFontScale = 1.0;
+
+ mhPS = 0;
+ mhDC = 0;
+ mbLine = FALSE;
+ mbFill = FALSE;
+ mbXORMode = FALSE;
+ mnFontMetricCount = 0;
+ mpFontMetrics = NULL;
+ mpClipRectlAry = NULL;
+
+ mhDefFont = 0;
+ mpFontKernPairs = NULL;
+ mnFontKernPairCount = 0;
+ mbFontKernInit = FALSE;
+
+}
+
+// -----------------------------------------------------------------------
+
+Os2SalGraphics::~Os2SalGraphics()
+{
+ Ft2DeleteSetId( mhPS, LCID_BASE);
+
+ if ( mpFontMetrics )
+ delete mpFontMetrics;
+
+ if ( mpFontKernPairs )
+ delete mpFontKernPairs;
+
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+
+ switch( nROPColor )
+ {
+ case SAL_ROP_0:
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ break;
+
+ case SAL_ROP_1:
+ case SAL_ROP_INVERT:
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ break;
+ }
+
+ return nSalColor;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+ // since OOo asks for DPI, I will query FONT_RES, which seems to be
+ // more correct than _RESOLUTION fields (on my wide screen lcd)
+ // and does not require conversion
+ DevQueryCaps( mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &rDPIX );
+ DevQueryCaps( mhDC, CAPS_VERTICAL_FONT_RES, 1, &rDPIY );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Os2SalGraphics::GetBitCount()
+{
+ LONG nBitCount;
+ DevQueryCaps( mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount );
+ return (USHORT)nBitCount;
+}
+
+// -----------------------------------------------------------------------
+
+long Os2SalGraphics::GetGraphicsWidth() const
+{
+ if( mhWnd )
+ {
+ Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( mhWnd );
+ if( pFrame )
+ {
+ if( pFrame->maGeometry.nWidth )
+ return pFrame->maGeometry.nWidth;
+ else
+ {
+ // TODO: perhaps not needed, maGeometry should always be up-to-date
+ RECTL aRect;
+ WinQueryWindowRect( mhWnd, &aRect );
+ return aRect.xRight;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::ResetClipRegion()
+{
+#ifdef SAL_PRINTER_CLIPPATH
+ if ( mbPrinter )
+ GpiSetClipPath( mhPS, 0, SCP_RESET );
+ else
+#endif
+ {
+ HRGN hOldRegion;
+
+ GpiSetClipRegion( mhPS, NULL, &hOldRegion );
+ if ( hOldRegion )
+ GpiDestroyRegion( mhPS, hOldRegion );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::BeginSetClipRegion( ULONG nCount )
+{
+ mpClipRectlAry = new RECTL[ nCount ];
+ mnClipElementCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Os2SalGraphics::unionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ RECTL* pClipRect = &mpClipRectlAry[ mnClipElementCount ];
+ pClipRect->xLeft = nX;
+ pClipRect->yTop = mnHeight - nY;
+ pClipRect->xRight = nX + nWidth;
+ pClipRect->yBottom = mnHeight - (nY + nHeight);
+ mnClipElementCount++;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+bool Os2SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& )
+{
+ // TODO: implement and advertise OutDevSupport_B2DClip support
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::EndSetClipRegion()
+{
+#ifdef SAL_PRINTER_CLIPPATH
+ if ( mbPrinter )
+ {
+ GpiSetClipPath( mhPS, 0, SCP_RESET );
+ GpiBeginPath( mhPS, 1L );
+
+ for( int i = 0; i < mnClipElementCount; i++ )
+ {
+ POINTL aPt;
+ RECTL* pClipRect = &mpClipRectlAry[ i ];
+
+ aPt.x = pClipRect->xLeft;
+ aPt.y = pClipRect->yTop-1;
+ Ft2Move( mhPS, &aPt );
+
+ aPt.x = pClipRect->xRight-1;
+ aPt.y = pClipRect->yBottom;
+
+ Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 );
+ }
+
+ GpiEndPath( mhPS );
+ GpiSetClipPath( mhPS, 1L, SCP_ALTERNATE | SCP_AND );
+ }
+ else
+#endif
+ {
+ HRGN hClipRegion = GpiCreateRegion( mhPS,
+ mnClipElementCount,
+ mpClipRectlAry );
+ HRGN hOldRegion;
+
+ GpiSetClipRegion( mhPS, hClipRegion, &hOldRegion );
+ if( hOldRegion )
+ GpiDestroyRegion( mhPS, hOldRegion );
+ }
+
+ delete [] mpClipRectlAry;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetLineColor()
+{
+ // don't draw line!
+ mbLine = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ LINEBUNDLE lb;
+
+ // set color
+ lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ Ft2SetAttrs( mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &lb );
+
+ // draw line!
+ mbLine = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetFillColor()
+{
+ // don't fill area!
+ mbFill = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ AREABUNDLE ab;
+
+ // set color
+ ab.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ Ft2SetAttrs( mhPS,
+ PRIM_AREA,
+ ABB_COLOR,
+ 0,
+ &ab );
+
+ // fill area!
+ mbFill = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetXORMode( bool bSet, bool )
+{
+ mbXORMode = bSet;
+ LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT;
+
+ // set mix mode for lines
+ LINEBUNDLE lb;
+ lb.usMixMode = nMixMode;
+ Ft2SetAttrs( mhPS,
+ PRIM_LINE,
+ LBB_MIX_MODE,
+ 0,
+ &lb );
+
+ // set mix mode for areas
+ AREABUNDLE ab;
+ ab.usMixMode = nMixMode;
+ Ft2SetAttrs( mhPS,
+ PRIM_AREA,
+ ABB_MIX_MODE,
+ 0,
+ &ab );
+
+ // set mix mode for text
+ CHARBUNDLE cb;
+ cb.usMixMode = nMixMode;
+ Ft2SetAttrs( mhPS,
+ PRIM_CHAR,
+ CBB_MIX_MODE,
+ 0,
+ &cb );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawPixel( long nX, long nY )
+{
+ POINTL aPt;
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+
+ // set color
+ Ft2SetPel( mhPS, &aPt );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ // save old color
+ LINEBUNDLE oldLb;
+ GpiQueryAttrs( mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ &oldLb );
+
+ // set new color
+ LINEBUNDLE lb;
+ lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ Ft2SetAttrs( mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &lb );
+
+ // set color of pixel
+ POINTL aPt;
+ aPt.x = nX;
+ aPt.y = TY( nY );
+ Ft2SetPel( mhPS, &aPt );
+
+ // restore old color
+ Ft2SetAttrs( mhPS,
+ PRIM_LINE,
+ LBB_COLOR,
+ 0,
+ &oldLb );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ // OS2 zeichnet den Endpunkt mit
+ POINTL aPt;
+ aPt.x = nX1;
+ aPt.y = TY( nY1 );
+ Ft2Move( mhPS, &aPt );
+ aPt.x = nX2;
+ aPt.y = TY( nY2 );
+ GpiLine( mhPS, &aPt );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ POINTL aPt;
+ long lControl;
+
+ if ( mbFill )
+ {
+ if ( mbLine )
+ lControl = DRO_OUTLINEFILL;
+ else
+ lControl = DRO_FILL;
+ }
+ else
+ {
+ if ( mbLine )
+ lControl = DRO_OUTLINE;
+ else
+ return;
+ }
+
+ aPt.x = nX;
+ aPt.y = TY( nY );
+ Ft2Move( mhPS, &aPt );
+ aPt.x = nX + nWidth - 1;
+ aPt.y = TY( nY + nHeight - 1 );
+ Ft2Box( mhPS, lControl, &aPt, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // convert all points to sys orientation
+ POINTL* pOS2PtAry = new POINTL[ nPoints ];
+ POINTL* pTempOS2PtAry = pOS2PtAry;
+ const SalPoint* pTempPtAry = pPtAry;
+ ULONG nTempPoints = nPoints;
+ long nHeight = mnHeight - 1;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+
+ Ft2Move( mhPS, pOS2PtAry );
+ GpiPolyLine( mhPS, nPoints, pOS2PtAry );
+ delete [] pOS2PtAry;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ PM_POLYGON aPolygon;
+
+ // create polygon
+ aPolygon.aPointl = new POINTL[ nPoints ];
+ aPolygon.ulPoints = nPoints;
+
+ // convert all points to sys orientation
+ POINTL* pTempOS2PtAry = aPolygon.aPointl;
+ const SalPoint* pTempPtAry = pPtAry;
+ ULONG nTempPoints = nPoints;
+ long nHeight = mnHeight - 1;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+
+ // Innenleben zeichnen
+ if ( mbFill )
+ {
+#ifdef SAL_PRINTER_POLYPATH
+ if ( mbPrinter )
+ {
+ Ft2BeginPath( mhPS, 1 );
+ Ft2Move( mhPS, aPolygon.aPointl );
+ Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
+ Ft2EndPath( mhPS );
+ Ft2FillPath( mhPS, 1, 0 );
+
+ if ( mbLine )
+ {
+ Ft2Move( mhPS, aPolygon.aPointl );
+ Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
+ }
+ }
+ else
+#endif
+ {
+ ULONG nOptions = POLYGON_ALTERNATE;
+
+ if ( mbLine )
+ nOptions |= POLYGON_BOUNDARY;
+ else
+ nOptions |= POLYGON_NOBOUNDARY;
+
+ Ft2Move( mhPS, aPolygon.aPointl );
+ GpiPolygons( mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL );
+ }
+ }
+ else
+ {
+ if ( mbLine )
+ {
+ Ft2Move( mhPS, aPolygon.aPointl );
+ GpiPolyLine( mhPS, nPoints, aPolygon.aPointl );
+ }
+ }
+
+ delete [] aPolygon.aPointl;
+}
+
+// -----------------------------------------------------------------------
+
+void Os2SalGraphics::drawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ ULONG i;
+ long nHeight = mnHeight - 1;
+ PM_POLYGON* aPolygonAry = new PM_POLYGON[ nPoly ];
+
+ for( i = 0; i < nPoly; i++ )
+ {
+ const SalPoint * pTempPtAry = (const SalPoint*)pPtAry[ i ];
+
+ // create polygon
+ ULONG nTempPoints = pPoints[ i ];
+ POINTL * pTempOS2PtAry = new POINTL[ nTempPoints ];
+
+ // convert all points to sys orientation
+ aPolygonAry[ i ].ulPoints = nTempPoints;
+ aPolygonAry[ i ].aPointl = pTempOS2PtAry;
+
+ while( nTempPoints-- )
+ {
+ (*pTempOS2PtAry).x = (*pTempPtAry).mnX;
+ (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
+ pTempOS2PtAry++;
+ pTempPtAry++;
+ }
+ }
+
+ // Innenleben zeichnen
+ if ( mbFill )
+ {
+#ifdef SAL_PRINTER_POLYPATH
+ if ( mbPrinter )
+ {
+ Ft2BeginPath( mhPS, 1 );
+ for ( i = 0; i < nPoly; i++ )
+ {
+ Ft2Move( mhPS, aPolygonAry[i].aPointl );
+ Ft2PolyLine( mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl );
+ }
+ Ft2EndPath( mhPS );
+ Ft2FillPath( mhPS, 1, 0 );
+ }
+ else
+#endif
+ {
+ ULONG nOptions = POLYGON_ALTERNATE;
+
+ if ( mbLine )
+ nOptions |= POLYGON_BOUNDARY;
+ else
+ nOptions |= POLYGON_NOBOUNDARY;
+
+ Ft2Move( mhPS, aPolygonAry[ 0 ].aPointl );
+ GpiPolygons( mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL );
+ }
+ }
+ else
+ {
+ if ( mbLine )
+ {
+ for( i = 0; i < nPoly; i++ )
+ {
+ Ft2Move( mhPS, aPolygonAry[ i ].aPointl );
+ GpiPolyLine( mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl );
+ }
+ }
+ }
+
+ // cleanup
+ for( i = 0; i < nPoly; i++ )
+ delete [] aPolygonAry[ i ].aPointl;
+ delete [] aPolygonAry;
+}
+
+// -----------------------------------------------------------------------
+
+bool Os2SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
+{
+ // TODO: implement and advertise OutDevSupport_B2DDraw support
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+bool Os2SalGraphics::drawPolyLine(
+ const basegfx::B2DPolygon& /*rPolygon*/,
+ double /*fTransparency*/,
+ const basegfx::B2DVector& /*rLineWidths*/,
+ basegfx::B2DLineJoin /*eLineJoin*/)
+{
+ // TODO: implement
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Os2SalGraphics::drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Os2SalGraphics::drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool Os2SalGraphics::drawPolyPolygonBezier( ULONG nPoly, const ULONG* pPoints,
+ const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
+{
+ return sal_False;
+}
+
+// =======================================================================
+
+// MAXIMUM BUFSIZE EQ 0xFFFF
+#define POSTSCRIPT_BUFSIZE 0x4000
+// we only try to get the BoundingBox in the first 4096 bytes
+#define POSTSCRIPT_BOUNDINGSEARCH 0x1000
+
+static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ ULONG i;
+ for ( i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+
+static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+ BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nSize, 14 );
+ if ( pDest )
+ {
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ pDest += 14;
+
+ int nSizeLeft = nSize - ( pDest - pSource );
+ if ( nSizeLeft > 100 )
+ nSizeLeft = 100; // only 100 bytes following the bounding box will be checked
+
+ int i;
+ for ( i = 0; ( i < 4 ) && nSizeLeft; i++ )
+ {
+ int nDivision = 1;
+ BOOL bDivision = FALSE;
+ BOOL bNegative = FALSE;
+ BOOL bValid = TRUE;
+
+ while ( ( --nSizeLeft ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
+ BYTE nByte = *pDest;
+ while ( nSizeLeft && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
+ {
+ switch ( nByte )
+ {
+ case '.' :
+ if ( bDivision )
+ bValid = FALSE;
+ else
+ bDivision = TRUE;
+ break;
+ case '-' :
+ bNegative = TRUE;
+ break;
+ default :
+ if ( ( nByte < '0' ) || ( nByte > '9' ) )
+ nSizeLeft = 1; // error parsing the bounding box values
+ else if ( bValid )
+ {
+ if ( bDivision )
+ nDivision*=10;
+ nNumb[i] *= 10;
+ nNumb[i] += nByte - '0';
+ }
+ break;
+ }
+ nSizeLeft--;
+ nByte = *(++pDest);
+ }
+ if ( bNegative )
+ nNumb[i] = -nNumb[i];
+ if ( bDivision && ( nDivision != 1 ) )
+ nNumb[i] /= nDivision;
+ }
+ if ( i == 4 )
+ bRetValue = TRUE;
+ }
+ return bRetValue;
+}
+
+#if 0
+static void ImplWriteDouble( BYTE** pBuf, double nNumber )
+{
+// *pBuf += sprintf( (char*)*pBuf, "%f", nNumber );
+
+ if ( nNumber < 0 )
+ {
+ *(*pBuf)++ = (BYTE)'-';
+ nNumber = -nNumber;
+ }
+ ULONG nTemp = (ULONG)nNumber;
+ const String aNumber1( nTemp );
+ ULONG nLen = aNumber1.Len();
+
+ for ( USHORT n = 0; n < nLen; n++ )
+ *(*pBuf)++ = aNumber1[ n ];
+
+ nTemp = (ULONG)( ( nNumber - nTemp ) * 100000 );
+ if ( nTemp )
+ {
+ *(*pBuf)++ = (BYTE)'.';
+ const String aNumber2( nTemp );
+
+ ULONG nLen = aNumber2.Len();
+ if ( nLen < 8 )
+ {
+ for ( n = 0; n < ( 5 - nLen ); n++ )
+ {
+ *(*pBuf)++ = (BYTE)'0';
+ }
+ }
+ for ( USHORT n = 0; n < nLen; n++ )
+ {
+ *(*pBuf)++ = aNumber2[ n ];
+ }
+ }
+ *(*pBuf)++ = ' ';
+}
+#endif
+
+inline void ImplWriteString( BYTE** pBuf, const char* sString )
+{
+ strcpy( (char*)*pBuf, sString );
+ *pBuf += strlen( sString );
+}
+
+BOOL Os2SalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+ if ( !mbPrinter )
+ return FALSE;
+
+ BOOL bRet = FALSE;
+ LONG nLong = 0;
+ if ( !(DevQueryCaps( mhDC, CAPS_TECHNOLOGY, 1, &nLong ) &&
+ (CAPS_TECH_POSTSCRIPT == nLong)) )
+ return FALSE;
+
+ BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
+ double nBoundingBox[4];
+
+ if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
+ {
+ LONG pOS2DXAry[4]; // hack -> print always 2 white space
+ POINTL aPt;
+ aPt.x = 0;
+ aPt.y = 0;
+ PCH pStr = (PCH) " ";
+ for( long i = 0; i < 4; i++ )
+ pOS2DXAry[i] = i;
+ Ft2CharStringPosAt( mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] );
+
+ OStringBuffer aBuf( POSTSCRIPT_BUFSIZE );
+
+ // reserve place for a USHORT
+ aBuf.append( "aa" );
+
+ // #107797# Write out EPS encapsulation header
+ // ----------------------------------------------------------------------------------
+
+ // directly taken from the PLRM 3.0, p. 726. Note:
+ // this will definitely cause problems when
+ // recursively creating and embedding PostScript files
+ // in OOo, since we use statically-named variables
+ // here (namely, b4_Inc_state_salWin, dict_count_salWin and
+ // op_count_salWin). Currently, I have no idea on how to
+ // work around that, except from scanning and
+ // interpreting the EPS for unused identifiers.
+
+ // append the real text
+ aBuf.append( "\n\n/b4_Inc_state_salWin save def\n"
+ "/dict_count_salWin countdictstack def\n"
+ "/op_count_salWin count 1 sub def\n"
+ "userdict begin\n"
+ "/showpage {} def\n"
+ "0 setgray 0 setlinecap\n"
+ "1 setlinewidth 0 setlinejoin\n"
+ "10 setmiterlimit [] 0 setdash newpath\n"
+ "/languagelevel where\n"
+ "{\n"
+ " pop languagelevel\n"
+ " 1 ne\n"
+ " {\n"
+ " false setstrokeadjust false setoverprint\n"
+ " } if\n"
+ "} if\n\n" );
+
+#if 0
+ // #i10737# Apply clipping manually
+ // ----------------------------------------------------------------------------------
+
+ // Windows seems to ignore any clipping at the HDC,
+ // when followed by a POSTSCRIPT_PASSTHROUGH
+
+ // Check whether we've got a clipping, consisting of
+ // exactly one rect (other cases should be, but aren't
+ // handled currently)
+
+ // TODO: Handle more than one rectangle here (take
+ // care, the buffer can handle only POSTSCRIPT_BUFSIZE
+ // characters!)
+ if ( mhRegion != 0 &&
+ mpStdClipRgnData != NULL &&
+ mpClipRgnData == mpStdClipRgnData &&
+ mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(mpClipRgnData->rdh.rcBound);
+
+ aBuf.append( "\nnewpath\n" );
+ aBuf.append( pRect->left );
+ aBuf.append( " " );
+ aBuf.append( pRect->top );
+ aBuf.append( " moveto\n" );
+ aBuf.append( pRect->right );
+ aBuf.append( " " );
+ aBuf.append( pRect->top );
+ aBuf.append( " lineto\n" );
+ aBuf.append( pRect->right );
+ aBuf.append( " " );
+ aBuf.append( pRect->bottom );
+ aBuf.append( " lineto\n" );
+ aBuf.append( pRect->left );
+ aBuf.append( " " );
+ aBuf.append( pRect->bottom );
+ aBuf.append( " lineto\n"
+ "closepath\n"
+ "clip\n"
+ "newpath\n" );
+ }
+#endif
+
+ // #107797# Write out buffer
+ // ----------------------------------------------------------------------------------
+ *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
+ //Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
+ DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
+ (PBYTE)aBuf.getStr(), 0, NULL );
+
+ double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
+ double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) );
+
+ // reserve a USHORT again
+ aBuf.setLength( 2 );
+ aBuf.append( "\n\n[" );
+ aBuf.append( dM11 );
+ aBuf.append( " 0 0 " );
+ aBuf.append( dM22 );
+ aBuf.append( ' ' );
+ aBuf.append( nX - ( dM11 * nBoundingBox[0] ) );
+ aBuf.append( ' ' );
+ aBuf.append( nY - ( dM22 * nBoundingBox[3] ) );
+ aBuf.append( "] concat\n"
+ "%%BeginDocument:\n" );
+ *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
+ DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
+ (PBYTE)aBuf.getStr(), 0, NULL );
+#if 0
+ BYTE* pTemp = pBuf;
+ ImplWriteString( &pTemp, "save\n[ " );
+ ImplWriteDouble( &pTemp, dM11 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, dM22 );
+ ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
+ ImplWriteDouble( &pTemp, mnHeight - nY - ( dM22 * nBoundingBox[3] ) );
+ ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
+
+ if ( DevEscape( mhDC, DEVESC_RAWDATA, pTemp - pBuf,
+ (PBYTE)pBuf, 0, NULL ) == DEV_OK )
+#endif //
+ {
+ UINT32 nToDo = nSize;
+ UINT32 nDoNow;
+ bRet = TRUE;
+ while( nToDo && bRet )
+ {
+ nDoNow = 0x4000;
+ if ( nToDo < nDoNow )
+ nDoNow = nToDo;
+
+ if ( DevEscape( mhDC, DEVESC_RAWDATA, nDoNow, (PBYTE)pPtr + nSize - nToDo,
+ 0, NULL ) == -1 )
+ bRet = FALSE;
+ nToDo -= nDoNow;
+ }
+
+ if ( bRet )
+ {
+ strcpy ( (char*)pBuf, "\nrestore\n" );
+ if ( DevEscape( mhDC, DEVESC_RAWDATA, 9, (PBYTE)pBuf,
+ 0, NULL ) == DEV_OK ) bRet = TRUE;
+ }
+
+ // #107797# Write out EPS encapsulation footer
+ // ----------------------------------------------------------------------------------
+ // reserve a USHORT again
+ aBuf.setLength( 2 );
+ aBuf.append( "%%EndDocument\n"
+ "count op_count_salWin sub {pop} repeat\n"
+ "countdictstack dict_count_salWin sub {end} repeat\n"
+ "b4_Inc_state_salWin restore\n\n" );
+ *((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
+ DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
+ (PBYTE)aBuf.getStr(), 0, NULL );
+ bRet = TRUE;
+
+ }
+ }
+ delete [] pBuf;
+ return bRet;
+}
+
+/*
+ * IsNativeControlSupported()
+ *
+ * Returns TRUE if the platform supports native
+ * drawing of the control defined by nPart
+ */
+BOOL Os2SalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
+{
+ return( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+SystemGraphicsData Os2SalGraphics::GetGraphicsData() const
+{
+ SystemGraphicsData aRes;
+ aRes.nSize = sizeof(aRes);
+#if 0
+ aRes.hDC = mhDC;
+#endif
+ return aRes;
+}
+
+// -----------------------------------------------------------------------