853 lines
24 KiB
C++
853 lines
24 KiB
C++
/*************************************************************************
|
|
*
|
|
* $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;
|
|
}
|
|
|