diff options
Diffstat (limited to 'vcl/os2/source/gdi/salgdi.cxx')
-rw-r--r-- | vcl/os2/source/gdi/salgdi.cxx | 852 |
1 files changed, 852 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..f501f8da303e --- /dev/null +++ b/vcl/os2/source/gdi/salgdi.cxx @@ -0,0 +1,852 @@ +/************************************************************************* + * + * $RCSfile: salgdi.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <string.h> +#include <tools/svpm.h> + +#define _SV_SALGDI_CXX + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <salgdi.hxx> +#endif +#ifndef _SV_SALVD_HXX +#include <salvd.hxx> +#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() +{ +} + +// ======================================================================= + +void ImplSalInitGraphics( SalGraphicsData* pData ) +{ + GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL ); +} + +// ----------------------------------------------------------------------- + +void ImplSalDeInitGraphics( SalGraphicsData* pData ) +{ +} + +// ======================================================================= + +SalGraphics::SalGraphics() +{ + maGraphicsData.mhPS = 0; + maGraphicsData.mhDC = 0; + maGraphicsData.mbLine = FALSE; + maGraphicsData.mbFill = FALSE; + maGraphicsData.mbXORMode = FALSE; + maGraphicsData.mbFontIsOutline = FALSE; + maGraphicsData.mbFontIsFixed = FALSE; + maGraphicsData.mnFontMetricCount = 0; + maGraphicsData.mpFontMetrics = NULL; + maGraphicsData.mpClipRectlAry = NULL; +} + +// ----------------------------------------------------------------------- + +SalGraphics::~SalGraphics() +{ + if ( maGraphicsData.mpFontMetrics ) + delete maGraphicsData.mpFontMetrics; +} + +// ----------------------------------------------------------------------- + +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 SalGraphics::GetResolution( long& rDPIX, long& rDPIY ) +{ + long nResolution; + + // convert resolution from pels per meter to pels per inch + DevQueryCaps( maGraphicsData.mhDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nResolution ); + rDPIX = (nResolution * 100) / 3937; + + // convert resolution from pels per meter to pels per inch + DevQueryCaps( maGraphicsData.mhDC, CAPS_VERTICAL_RESOLUTION, 1, &nResolution ); + rDPIY = (nResolution * 100) / 3937; + + if ( rDPIY < 96 ) + { + rDPIX = (rDPIX*96) / rDPIY; + rDPIY = 96; + } +} + +// ----------------------------------------------------------------------- + +void SalGraphics::GetScreenFontResolution( long& rDPIX, long& rDPIY ) +{ + DevQueryCaps( maGraphicsData.mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &rDPIX ); + DevQueryCaps( maGraphicsData.mhDC, CAPS_VERTICAL_FONT_RES, 1, &rDPIY ); +} + +// ----------------------------------------------------------------------- + +USHORT SalGraphics::GetBitCount() +{ + LONG nBitCount; + DevQueryCaps( maGraphicsData.mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount ); + return (USHORT)nBitCount; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::ResetClipRegion() +{ +#ifdef SAL_PRINTER_CLIPPATH + if ( maGraphicsData.mbPrinter ) + GpiSetClipPath( maGraphicsData.mhPS, 0, SCP_RESET ); + else +#endif + { + HRGN hOldRegion; + + GpiSetClipRegion( maGraphicsData.mhPS, NULL, &hOldRegion ); + if ( hOldRegion ) + GpiDestroyRegion( maGraphicsData.mhPS, hOldRegion ); + } +} + +// ----------------------------------------------------------------------- + +void SalGraphics::BeginSetClipRegion( ULONG nCount ) +{ + maGraphicsData.mpClipRectlAry = new RECTL[ nCount ]; + maGraphicsData.mnClipElementCount = 0; +} + +// ----------------------------------------------------------------------- + +BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +{ + RECTL* pClipRect = &maGraphicsData.mpClipRectlAry[ maGraphicsData.mnClipElementCount ]; + pClipRect->xLeft = nX; + pClipRect->yTop = maGraphicsData.mnHeight - nY; + pClipRect->xRight = nX + nWidth; + pClipRect->yBottom = maGraphicsData.mnHeight - (nY + nHeight); + maGraphicsData.mnClipElementCount++; + + return TRUE; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::EndSetClipRegion() +{ +#ifdef SAL_PRINTER_CLIPPATH + if ( maGraphicsData.mbPrinter ) + { + GpiSetClipPath( maGraphicsData.mhPS, 0, SCP_RESET ); + GpiBeginPath( maGraphicsData.mhPS, 1L ); + + for( int i = 0; i < maGraphicsData.mnClipElementCount; i++ ) + { + POINTL aPt; + RECTL* pClipRect = &maGraphicsData.mpClipRectlAry[ i ]; + + aPt.x = pClipRect->xLeft; + aPt.y = pClipRect->yTop-1; + GpiMove( maGraphicsData.mhPS, &aPt ); + + aPt.x = pClipRect->xRight-1; + aPt.y = pClipRect->yBottom; + + GpiBox( maGraphicsData.mhPS, DRO_OUTLINE, &aPt, 0, 0 ); + } + + GpiEndPath( maGraphicsData.mhPS ); + GpiSetClipPath( maGraphicsData.mhPS, 1L, SCP_ALTERNATE | SCP_AND ); + } + else +#endif + { + HRGN hClipRegion = GpiCreateRegion( maGraphicsData.mhPS, + maGraphicsData.mnClipElementCount, + maGraphicsData.mpClipRectlAry ); + HRGN hOldRegion; + + GpiSetClipRegion( maGraphicsData.mhPS, hClipRegion, &hOldRegion ); + if( hOldRegion ) + GpiDestroyRegion( maGraphicsData.mhPS, hOldRegion ); + } + + delete [] maGraphicsData.mpClipRectlAry; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetLineColor() +{ + // don't draw line! + maGraphicsData.mbLine = FALSE; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetLineColor( SalColor nSalColor ) +{ + LINEBUNDLE lb; + + // set color + lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), + SALCOLOR_GREEN( nSalColor ), + SALCOLOR_BLUE( nSalColor ) ); + + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_LINE, + LBB_COLOR, + 0, + &lb ); + + // draw line! + maGraphicsData.mbLine = TRUE; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetFillColor() +{ + // don't fill area! + maGraphicsData.mbFill = FALSE; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetFillColor( SalColor nSalColor ) +{ + AREABUNDLE ab; + + // set color + ab.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), + SALCOLOR_GREEN( nSalColor ), + SALCOLOR_BLUE( nSalColor ) ); + + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_AREA, + ABB_COLOR, + 0, + &ab ); + + // fill area! + maGraphicsData.mbFill = TRUE; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetXORMode( BOOL bSet ) +{ + maGraphicsData.mbXORMode = bSet; + LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT; + + // set mix mode for lines + LINEBUNDLE lb; + lb.usMixMode = nMixMode; + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_LINE, + LBB_MIX_MODE, + 0, + &lb ); + + // set mix mode for areas + AREABUNDLE ab; + ab.usMixMode = nMixMode; + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_AREA, + ABB_MIX_MODE, + 0, + &ab ); + + // set mix mode for text + CHARBUNDLE cb; + cb.usMixMode = nMixMode; + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_CHAR, + CBB_MIX_MODE, + 0, + &cb ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetROPLineColor( SalROPColor nROPColor ) +{ + SetLineColor( ImplGetROPSalColor( nROPColor ) ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::SetROPFillColor( SalROPColor nROPColor ) +{ + SetFillColor( ImplGetROPSalColor( nROPColor ) ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawPixel( long nX, long nY ) +{ + POINTL aPt; + + aPt.x = nX; + aPt.y = TY( nY ); + + // set color + GpiSetPel( maGraphicsData.mhPS, &aPt ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor ) +{ + // save old color + LINEBUNDLE oldLb; + GpiQueryAttrs( maGraphicsData.mhPS, + PRIM_LINE, + LBB_COLOR, + &oldLb ); + + // set new color + LINEBUNDLE lb; + lb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ), + SALCOLOR_GREEN( nSalColor ), + SALCOLOR_BLUE( nSalColor ) ); + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_LINE, + LBB_COLOR, + 0, + &lb ); + + // set color of pixel + POINTL aPt; + aPt.x = nX; + aPt.y = TY( nY ); + GpiSetPel( maGraphicsData.mhPS, &aPt ); + + // restore old color + GpiSetAttrs( maGraphicsData.mhPS, + PRIM_LINE, + LBB_COLOR, + 0, + &oldLb ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + // OS2 zeichnet den Endpunkt mit + POINTL aPt; + aPt.x = nX1; + aPt.y = TY( nY1 ); + GpiMove( maGraphicsData.mhPS, &aPt ); + aPt.x = nX2; + aPt.y = TY( nY2 ); + GpiLine( maGraphicsData.mhPS, &aPt ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight ) +{ + POINTL aPt; + long lControl; + + if ( maGraphicsData.mbFill ) + { + if ( maGraphicsData.mbLine ) + lControl = DRO_OUTLINEFILL; + else + lControl = DRO_FILL; + } + else + { + if ( maGraphicsData.mbLine ) + lControl = DRO_OUTLINE; + else + return; + } + + aPt.x = nX; + aPt.y = TY( nY ); + GpiMove( maGraphicsData.mhPS, &aPt ); + aPt.x = nX + nWidth - 1; + aPt.y = TY( nY + nHeight - 1 ); + GpiBox( maGraphicsData.mhPS, lControl, &aPt, 0, 0 ); +} + +// ----------------------------------------------------------------------- + +void SalGraphics::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 = maGraphicsData.mnHeight - 1; + + while( nTempPoints-- ) + { + (*pTempOS2PtAry).x = (*pTempPtAry).mnX; + (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY; + pTempOS2PtAry++; + pTempPtAry++; + } + + GpiMove( maGraphicsData.mhPS, pOS2PtAry ); + GpiPolyLine( maGraphicsData.mhPS, nPoints, pOS2PtAry ); + delete [] pOS2PtAry; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry ) +{ + 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 = maGraphicsData.mnHeight - 1; + + while( nTempPoints-- ) + { + (*pTempOS2PtAry).x = (*pTempPtAry).mnX; + (*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY; + pTempOS2PtAry++; + pTempPtAry++; + } + + // Innenleben zeichnen + if ( maGraphicsData.mbFill ) + { +#ifdef SAL_PRINTER_POLYPATH + if ( maGraphicsData.mbPrinter ) + { + GpiBeginPath( maGraphicsData.mhPS, 1 ); + GpiMove( maGraphicsData.mhPS, aPolygon.aPointl ); + GpiPolyLine( maGraphicsData.mhPS, aPolygon.ulPoints, aPolygon.aPointl ); + GpiEndPath( maGraphicsData.mhPS ); + GpiFillPath( maGraphicsData.mhPS, 1, 0 ); + + if ( maGraphicsData.mbLine ) + { + GpiMove( maGraphicsData.mhPS, aPolygon.aPointl ); + GpiPolyLine( maGraphicsData.mhPS, aPolygon.ulPoints, aPolygon.aPointl ); + } + } + else +#endif + { + ULONG nOptions = POLYGON_ALTERNATE; + + if ( maGraphicsData.mbLine ) + nOptions |= POLYGON_BOUNDARY; + else + nOptions |= POLYGON_NOBOUNDARY; + + GpiMove( maGraphicsData.mhPS, aPolygon.aPointl ); + GpiPolygons( maGraphicsData.mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL ); + } + } + else + { + if ( maGraphicsData.mbLine ) + { + GpiMove( maGraphicsData.mhPS, aPolygon.aPointl ); + GpiPolyLine( maGraphicsData.mhPS, nPoints, aPolygon.aPointl ); + } + } + + delete [] aPolygon.aPointl; +} + +// ----------------------------------------------------------------------- + +void SalGraphics::DrawPolyPolygon( ULONG nPoly, const ULONG* pPoints, + PCONSTSALPOINT* pPtAry ) +{ + ULONG i; + long nHeight = maGraphicsData.mnHeight - 1; + POLYGON* aPolygonAry = new 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 ( maGraphicsData.mbFill ) + { +#ifdef SAL_PRINTER_POLYPATH + if ( maGraphicsData.mbPrinter ) + { + GpiBeginPath( maGraphicsData.mhPS, 1 ); + for ( i = 0; i < nPoly; i++ ) + { + GpiMove( maGraphicsData.mhPS, aPolygonAry[i].aPointl ); + GpiPolyLine( maGraphicsData.mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl ); + } + GpiEndPath( maGraphicsData.mhPS ); + GpiFillPath( maGraphicsData.mhPS, 1, 0 ); + } + else +#endif + { + ULONG nOptions = POLYGON_ALTERNATE; + + if ( maGraphicsData.mbLine ) + nOptions |= POLYGON_BOUNDARY; + else + nOptions |= POLYGON_NOBOUNDARY; + + GpiMove( maGraphicsData.mhPS, aPolygonAry[ 0 ].aPointl ); + GpiPolygons( maGraphicsData.mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL ); + } + } + else + { + if ( maGraphicsData.mbLine ) + { + for( i = 0; i < nPoly; i++ ) + { + GpiMove( maGraphicsData.mhPS, aPolygonAry[ i ].aPointl ); + GpiPolyLine( maGraphicsData.mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl ); + } + } + } + + // cleanup + for( i = 0; i < nPoly; i++ ) + delete [] aPolygonAry[ i ].aPointl; + delete [] aPolygonAry; +} + +// ======================================================================= + +// MAXIMUM BUFSIZE EQ 0xFFFF +#define POSTSCRIPT_BUFSIZE 0x1024 +// 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 ) + { + for ( ULONG 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; + ULONG nBytesRead; + + if ( nSize < 256 ) // we assume that the file is greater than 256 bytes + return FALSE; + + if ( nSize < POSTSCRIPT_BOUNDINGSEARCH ) + nBytesRead = nSize; + else + nBytesRead = POSTSCRIPT_BOUNDINGSEARCH; + + BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 ); + if ( pDest ) + { + int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked + nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0; + pDest += 14; + for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ ) + { + int nDivision = 1; + BOOL bDivision = FALSE; + BOOL bNegative = FALSE; + BOOL bValid = TRUE; + + while ( ( --nSecurityCount ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++; + BYTE nByte = *pDest; + while ( nSecurityCount && ( 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' ) ) + nSecurityCount = 1; // error parsing the bounding box values + else if ( bValid ) + { + if ( bDivision ) + nDivision*=10; + nNumb[i] *= 10; + nNumb[i] += nByte - '0'; + } + break; + } + nSecurityCount--; + nByte = *(++pDest); + } + if ( bNegative ) + nNumb[i] = -nNumb[i]; + if ( bDivision && ( nDivision != 1 ) ) + nNumb[i] /= nDivision; + } + if ( nSecurityCount) + bRetValue = TRUE; + } + return bRetValue; +} + +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)++ = ' '; +} + +inline void ImplWriteString( BYTE** pBuf, const char* sString ) +{ + strcpy( (char*)*pBuf, sString ); + *pBuf += strlen( sString ); +} + +BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ) +{ + if ( !maGraphicsData.mbPrinter ) + return FALSE; + + BOOL bRet = FALSE; + LONG nLong = 0; + if ( !(DevQueryCaps( maGraphicsData.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 = " "; + for( long i = 0; i < 4; i++ ) + pOS2DXAry[i] = i; + GpiCharStringPosAt( maGraphicsData.mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] ); + + double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] ); + double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) ); + + 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, maGraphicsData.mnHeight - nY - ( dM22 * nBoundingBox[3] ) ); + ImplWriteString( &pTemp, "] concat /showpage {} def\n" ); + + if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, pTemp - pBuf, + (PBYTE)pBuf, 0, NULL ) == DEV_OK ) + { + UINT32 nToDo = nSize; + UINT32 nDoNow; + bRet = TRUE; + while( nToDo && bRet ) + { + nDoNow = 0x4000; + if ( nToDo < nDoNow ) + nDoNow = nToDo; + + if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, nDoNow, (PBYTE)pPtr + nSize - nToDo, + 0, NULL ) == -1 ) + bRet = FALSE; + nToDo -= nDoNow; + } + + if ( bRet ) + { + strcpy ( (char*)pBuf, "\nrestore\n" ); + if ( DevEscape( maGraphicsData.mhDC, DEVESC_RAWDATA, 9, (PBYTE)pBuf, + 0, NULL ) == DEV_OK ) bRet = TRUE; + } + } + } + delete pBuf; + return bRet; +} + |