xref: /AOO41X/main/vcl/win/source/gdi/salgdi.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <stdio.h>
32*cdf0e10cSrcweir #include <string.h>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <tools/svwin.h>
37*cdf0e10cSrcweir #include <tools/debug.hxx>
38*cdf0e10cSrcweir #include <tools/poly.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
41*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <win/wincomp.hxx>
44*cdf0e10cSrcweir #include <win/saldata.hxx>
45*cdf0e10cSrcweir #include <win/salgdi.h>
46*cdf0e10cSrcweir #include <win/salframe.h>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <region.h>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir using namespace rtl;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir // =======================================================================
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir // comment out to prevent use of beziers on GDI functions
55*cdf0e10cSrcweir #define USE_GDI_BEZIERS
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir // =======================================================================
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #define DITHER_PAL_DELTA				51
60*cdf0e10cSrcweir #define DITHER_PAL_STEPS				6
61*cdf0e10cSrcweir #define DITHER_PAL_COUNT				(DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS)
62*cdf0e10cSrcweir #define DITHER_MAX_SYSCOLOR 			16
63*cdf0e10cSrcweir #define DITHER_EXTRA_COLORS 			1
64*cdf0e10cSrcweir #define DMAP( _def_nVal, _def_nThres )	((pDitherDiff[_def_nVal]>(_def_nThres))?pDitherHigh[_def_nVal]:pDitherLow[_def_nVal])
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir // =======================================================================
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir struct SysColorEntry
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir 	DWORD			nRGB;
71*cdf0e10cSrcweir 	SysColorEntry*	pNext;
72*cdf0e10cSrcweir };
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir // =======================================================================
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir static SysColorEntry* pFirstSysColor = NULL;
77*cdf0e10cSrcweir static SysColorEntry* pActSysColor = NULL;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir // -----------------------------------------------------------------------------
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir // Blue7
82*cdf0e10cSrcweir static PALETTEENTRY aImplExtraColor1 =
83*cdf0e10cSrcweir {
84*cdf0e10cSrcweir 	0, 184, 255, 0
85*cdf0e10cSrcweir };
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir // -----------------------------------------------------------------------------
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] =
90*cdf0e10cSrcweir {
91*cdf0e10cSrcweir {	 0,    0,	 0, 0 },
92*cdf0e10cSrcweir {	 0,    0, 0x80, 0 },
93*cdf0e10cSrcweir {	 0, 0x80,	 0, 0 },
94*cdf0e10cSrcweir {	 0, 0x80, 0x80, 0 },
95*cdf0e10cSrcweir { 0x80,    0,	 0, 0 },
96*cdf0e10cSrcweir { 0x80,    0, 0x80, 0 },
97*cdf0e10cSrcweir { 0x80, 0x80,	 0, 0 },
98*cdf0e10cSrcweir { 0x80, 0x80, 0x80, 0 },
99*cdf0e10cSrcweir { 0xC0, 0xC0, 0xC0, 0 },
100*cdf0e10cSrcweir {	 0,    0, 0xFF, 0 },
101*cdf0e10cSrcweir {	 0, 0xFF,	 0, 0 },
102*cdf0e10cSrcweir {	 0, 0xFF, 0xFF, 0 },
103*cdf0e10cSrcweir { 0xFF,    0,	 0, 0 },
104*cdf0e10cSrcweir { 0xFF,    0, 0xFF, 0 },
105*cdf0e10cSrcweir { 0xFF, 0xFF,	 0, 0 },
106*cdf0e10cSrcweir { 0xFF, 0xFF, 0xFF, 0 }
107*cdf0e10cSrcweir };
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir // -----------------------------------------------------------------------------
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir static BYTE aOrdDither8Bit[8][8] =
112*cdf0e10cSrcweir {
113*cdf0e10cSrcweir 	 0, 38,  9, 48,  2, 40, 12, 50,
114*cdf0e10cSrcweir 	25, 12, 35, 22, 28, 15, 37, 24,
115*cdf0e10cSrcweir 	 6, 44,  3, 41,  8, 47,  5, 44,
116*cdf0e10cSrcweir 	32, 19, 28, 16, 34, 21, 31, 18,
117*cdf0e10cSrcweir 	 1, 40, 11, 49,  0, 39, 10, 48,
118*cdf0e10cSrcweir 	27, 14, 36, 24, 26, 13, 36, 23,
119*cdf0e10cSrcweir 	 8, 46,  4, 43,  7, 45,  4, 42,
120*cdf0e10cSrcweir 	33, 20, 30, 17, 32, 20, 29, 16
121*cdf0e10cSrcweir };
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir // -----------------------------------------------------------------------------
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir static BYTE aOrdDither16Bit[8][8] =
126*cdf0e10cSrcweir {
127*cdf0e10cSrcweir 	0, 6, 1, 7, 0, 6, 1, 7,
128*cdf0e10cSrcweir 	4, 2, 5, 3, 4, 2, 5, 3,
129*cdf0e10cSrcweir 	1, 7, 0, 6, 1, 7, 0, 6,
130*cdf0e10cSrcweir 	5, 3, 4, 2, 5, 3, 4, 2,
131*cdf0e10cSrcweir 	0, 6, 1, 7, 0, 6, 1, 7,
132*cdf0e10cSrcweir 	4, 2, 5, 3, 4, 2, 5, 3,
133*cdf0e10cSrcweir 	1, 7, 0, 6, 1, 7, 0, 6,
134*cdf0e10cSrcweir 	5, 3, 4, 2, 5, 3, 4, 2
135*cdf0e10cSrcweir };
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir // =======================================================================
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir // Pens muessen wir mit 1 Pixel-Breite erzeugen, da ansonsten die S3-Karte
140*cdf0e10cSrcweir // viele Paintprobleme hat, wenn Polygone/PolyLines gezeichnet werden und
141*cdf0e10cSrcweir // eine komplexe ClipRegion gesetzt ist
142*cdf0e10cSrcweir #define GSL_PEN_WIDTH					1
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir // =======================================================================
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir #define SAL_POLYPOLYCOUNT_STACKBUF			8
147*cdf0e10cSrcweir #define SAL_POLYPOLYPOINTS_STACKBUF 		64
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir // =======================================================================
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir void ImplInitSalGDI()
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	SalData* pSalData = GetSalData();
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 	// init stock brushes
156*cdf0e10cSrcweir 	pSalData->maStockPenColorAry[0] 	= PALETTERGB( 0, 0, 0 );
157*cdf0e10cSrcweir 	pSalData->maStockPenColorAry[1] 	= PALETTERGB( 0xFF, 0xFF, 0xFF );
158*cdf0e10cSrcweir 	pSalData->maStockPenColorAry[2] 	= PALETTERGB( 0xC0, 0xC0, 0xC0 );
159*cdf0e10cSrcweir 	pSalData->maStockPenColorAry[3] 	= PALETTERGB( 0x80, 0x80, 0x80 );
160*cdf0e10cSrcweir 	pSalData->mhStockPenAry[0]			= CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[0] );
161*cdf0e10cSrcweir 	pSalData->mhStockPenAry[1]			= CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[1] );
162*cdf0e10cSrcweir 	pSalData->mhStockPenAry[2]			= CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[2] );
163*cdf0e10cSrcweir 	pSalData->mhStockPenAry[3]			= CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[3] );
164*cdf0e10cSrcweir 	pSalData->mnStockPenCount = 4;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 	pSalData->maStockBrushColorAry[0]	= PALETTERGB( 0, 0, 0 );
167*cdf0e10cSrcweir 	pSalData->maStockBrushColorAry[1]	= PALETTERGB( 0xFF, 0xFF, 0xFF );
168*cdf0e10cSrcweir 	pSalData->maStockBrushColorAry[2]	= PALETTERGB( 0xC0, 0xC0, 0xC0 );
169*cdf0e10cSrcweir 	pSalData->maStockBrushColorAry[3]	= PALETTERGB( 0x80, 0x80, 0x80 );
170*cdf0e10cSrcweir 	pSalData->mhStockBrushAry[0]		= CreateSolidBrush( pSalData->maStockBrushColorAry[0] );
171*cdf0e10cSrcweir 	pSalData->mhStockBrushAry[1]		= CreateSolidBrush( pSalData->maStockBrushColorAry[1] );
172*cdf0e10cSrcweir 	pSalData->mhStockBrushAry[2]		= CreateSolidBrush( pSalData->maStockBrushColorAry[2] );
173*cdf0e10cSrcweir 	pSalData->mhStockBrushAry[3]		= CreateSolidBrush( pSalData->maStockBrushColorAry[3] );
174*cdf0e10cSrcweir 	pSalData->mnStockBrushCount = 4;
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir 	// initialize cache of device contexts
177*cdf0e10cSrcweir 	pSalData->mpHDCCache = new HDCCache[ CACHESIZE_HDC ];
178*cdf0e10cSrcweir 	memset( pSalData->mpHDCCache, 0, CACHESIZE_HDC * sizeof( HDCCache ) );
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     // initialize temporary font list
181*cdf0e10cSrcweir     pSalData->mpTempFontItem = NULL;
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir 	// support palettes for 256 color displays
184*cdf0e10cSrcweir 	HDC hDC = GetDC( 0 );
185*cdf0e10cSrcweir 	int nBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
186*cdf0e10cSrcweir 	int nPlanes = GetDeviceCaps( hDC, PLANES );
187*cdf0e10cSrcweir 	int nRasterCaps = GetDeviceCaps( hDC, RASTERCAPS );
188*cdf0e10cSrcweir 	int nBitCount = nBitsPixel * nPlanes;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 	if ( (nBitCount > 8) && (nBitCount < 24) )
191*cdf0e10cSrcweir 	{
192*cdf0e10cSrcweir 		// test, if we have to dither
193*cdf0e10cSrcweir 		HDC 		hMemDC = ::CreateCompatibleDC( hDC );
194*cdf0e10cSrcweir 		HBITMAP 	hMemBmp = ::CreateCompatibleBitmap( hDC, 8, 8 );
195*cdf0e10cSrcweir 		HBITMAP 	hBmpOld = (HBITMAP) ::SelectObject( hMemDC, hMemBmp );
196*cdf0e10cSrcweir 		HBRUSH		hMemBrush = ::CreateSolidBrush( PALETTERGB( 175, 171, 169 ) );
197*cdf0e10cSrcweir 		HBRUSH		hBrushOld = (HBRUSH) ::SelectObject( hMemDC, hMemBrush );
198*cdf0e10cSrcweir 		sal_Bool		bDither16 = TRUE;
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 		::PatBlt( hMemDC, 0, 0, 8, 8, PATCOPY );
201*cdf0e10cSrcweir 		const COLORREF aCol( ::GetPixel( hMemDC, 0, 0 ) );
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir 		for( int nY = 0; ( nY < 8 ) && bDither16; nY++ )
204*cdf0e10cSrcweir 			for( int nX = 0; ( nX < 8 ) && bDither16; nX++ )
205*cdf0e10cSrcweir 				if( ::GetPixel( hMemDC, nX, nY ) != aCol )
206*cdf0e10cSrcweir 					bDither16 = FALSE;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 		::SelectObject( hMemDC, hBrushOld ), ::DeleteObject( hMemBrush );
209*cdf0e10cSrcweir 		::SelectObject( hMemDC, hBmpOld ), ::DeleteObject( hMemBmp );
210*cdf0e10cSrcweir 		::DeleteDC( hMemDC );
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir 		if( bDither16 )
213*cdf0e10cSrcweir 		{
214*cdf0e10cSrcweir 			// create DIBPattern for 16Bit dithering
215*cdf0e10cSrcweir 			long n;
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 			pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, sizeof( BITMAPINFOHEADER ) + 192 );
218*cdf0e10cSrcweir 			pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
219*cdf0e10cSrcweir 			pSalData->mpDitherDiff = new long[ 256 ];
220*cdf0e10cSrcweir 			pSalData->mpDitherLow = new BYTE[ 256 ];
221*cdf0e10cSrcweir 			pSalData->mpDitherHigh = new BYTE[ 256 ];
222*cdf0e10cSrcweir 			pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER );
223*cdf0e10cSrcweir 			memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 			BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 			pBIH->biSize = sizeof( BITMAPINFOHEADER );
228*cdf0e10cSrcweir 			pBIH->biWidth = 8;
229*cdf0e10cSrcweir 			pBIH->biHeight = 8;
230*cdf0e10cSrcweir 			pBIH->biPlanes = 1;
231*cdf0e10cSrcweir 			pBIH->biBitCount = 24;
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
234*cdf0e10cSrcweir 				pSalData->mpDitherDiff[ n ] = n - ( n & 248L );
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
237*cdf0e10cSrcweir 				pSalData->mpDitherLow[ n ] = (BYTE) ( n & 248 );
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
240*cdf0e10cSrcweir 				pSalData->mpDitherHigh[ n ] = (BYTE) Min( pSalData->mpDitherLow[ n ] + 8L, 255L );
241*cdf0e10cSrcweir 		}
242*cdf0e10cSrcweir 	}
243*cdf0e10cSrcweir 	else if ( (nRasterCaps & RC_PALETTE) && (nBitCount == 8) )
244*cdf0e10cSrcweir 	{
245*cdf0e10cSrcweir 		BYTE			nRed, nGreen, nBlue;
246*cdf0e10cSrcweir 		BYTE			nR, nG, nB;
247*cdf0e10cSrcweir 		PALETTEENTRY*	pPalEntry;
248*cdf0e10cSrcweir 		LOGPALETTE* 	pLogPal;
249*cdf0e10cSrcweir 		const sal_uInt16	nDitherPalCount = DITHER_PAL_COUNT;
250*cdf0e10cSrcweir 		sal_uLong			nTotalCount = DITHER_MAX_SYSCOLOR + nDitherPalCount + DITHER_EXTRA_COLORS;
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 		// create logical palette
253*cdf0e10cSrcweir 		pLogPal = (LOGPALETTE*) new char[ sizeof( LOGPALETTE ) + ( nTotalCount * sizeof( PALETTEENTRY ) ) ];
254*cdf0e10cSrcweir 		pLogPal->palVersion = 0x0300;
255*cdf0e10cSrcweir 		pLogPal->palNumEntries = (sal_uInt16) nTotalCount;
256*cdf0e10cSrcweir 		pPalEntry = pLogPal->palPalEntry;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 		// Standard colors
259*cdf0e10cSrcweir 		memcpy( pPalEntry, aImplSalSysPalEntryAry, DITHER_MAX_SYSCOLOR * sizeof( PALETTEENTRY ) );
260*cdf0e10cSrcweir 		pPalEntry += DITHER_MAX_SYSCOLOR;
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		// own palette (6/6/6)
263*cdf0e10cSrcweir 		for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA )
264*cdf0e10cSrcweir 		{
265*cdf0e10cSrcweir 			for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA )
266*cdf0e10cSrcweir 			{
267*cdf0e10cSrcweir 				for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA )
268*cdf0e10cSrcweir 				{
269*cdf0e10cSrcweir 					pPalEntry->peRed   = nRed;
270*cdf0e10cSrcweir 					pPalEntry->peGreen = nGreen;
271*cdf0e10cSrcweir 					pPalEntry->peBlue  = nBlue;
272*cdf0e10cSrcweir 					pPalEntry->peFlags = 0;
273*cdf0e10cSrcweir 					pPalEntry++;
274*cdf0e10cSrcweir 				}
275*cdf0e10cSrcweir 			}
276*cdf0e10cSrcweir 		}
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 		// insert special 'Blue' as standard drawing color
279*cdf0e10cSrcweir 		*pPalEntry++ = aImplExtraColor1;
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 		// create palette
282*cdf0e10cSrcweir 		pSalData->mhDitherPal = CreatePalette( pLogPal );
283*cdf0e10cSrcweir 		delete[] (char*) pLogPal;
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 		if( pSalData->mhDitherPal )
286*cdf0e10cSrcweir 		{
287*cdf0e10cSrcweir 			// create DIBPattern for 8Bit dithering
288*cdf0e10cSrcweir 			long nSize = sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ) + 64;
289*cdf0e10cSrcweir 			long n;
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 			pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, nSize );
292*cdf0e10cSrcweir 			pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
293*cdf0e10cSrcweir 			pSalData->mpDitherDiff = new long[ 256 ];
294*cdf0e10cSrcweir 			pSalData->mpDitherLow = new BYTE[ 256 ];
295*cdf0e10cSrcweir 			pSalData->mpDitherHigh = new BYTE[ 256 ];
296*cdf0e10cSrcweir 			pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) );
297*cdf0e10cSrcweir 			memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 			BITMAPINFOHEADER*	pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
300*cdf0e10cSrcweir 			short*				pColors = (short*) ( pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) );
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir 			pBIH->biSize = sizeof( BITMAPINFOHEADER );
303*cdf0e10cSrcweir 			pBIH->biWidth = 8;
304*cdf0e10cSrcweir 			pBIH->biHeight = 8;
305*cdf0e10cSrcweir 			pBIH->biPlanes = 1;
306*cdf0e10cSrcweir 			pBIH->biBitCount = 8;
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir 			for( n = 0; n < nDitherPalCount; n++ )
309*cdf0e10cSrcweir 				pColors[ n ] = (short)( n + DITHER_MAX_SYSCOLOR );
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
312*cdf0e10cSrcweir 				pSalData->mpDitherDiff[ n ] = n % 51L;
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
315*cdf0e10cSrcweir 				pSalData->mpDitherLow[ n ] = (BYTE) ( n / 51L );
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 			for( n = 0; n < 256L; n++ )
318*cdf0e10cSrcweir 				pSalData->mpDitherHigh[ n ] = (BYTE)Min( pSalData->mpDitherLow[ n ] + 1, 5 );
319*cdf0e10cSrcweir 		}
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir 		// get system color entries
322*cdf0e10cSrcweir 		ImplUpdateSysColorEntries();
323*cdf0e10cSrcweir 	}
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir 	ReleaseDC( 0, hDC );
326*cdf0e10cSrcweir }
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir // -----------------------------------------------------------------------
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir void ImplFreeSalGDI()
331*cdf0e10cSrcweir {
332*cdf0e10cSrcweir 	SalData*	pSalData = GetSalData();
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir 	// destroy stock objects
335*cdf0e10cSrcweir 	int	i;
336*cdf0e10cSrcweir 	for ( i = 0; i < pSalData->mnStockPenCount; i++ )
337*cdf0e10cSrcweir 		DeletePen( pSalData->mhStockPenAry[i] );
338*cdf0e10cSrcweir 	for ( i = 0; i < pSalData->mnStockBrushCount; i++ )
339*cdf0e10cSrcweir 		DeleteBrush( pSalData->mhStockBrushAry[i] );
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 	// 50% Brush loeschen
342*cdf0e10cSrcweir 	if ( pSalData->mh50Brush )
343*cdf0e10cSrcweir 	{
344*cdf0e10cSrcweir 		DeleteBrush( pSalData->mh50Brush );
345*cdf0e10cSrcweir 		pSalData->mh50Brush = 0;
346*cdf0e10cSrcweir 	}
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 	// 50% Bitmap loeschen
349*cdf0e10cSrcweir 	if ( pSalData->mh50Bmp )
350*cdf0e10cSrcweir 	{
351*cdf0e10cSrcweir 		DeleteBitmap( pSalData->mh50Bmp );
352*cdf0e10cSrcweir 		pSalData->mh50Bmp = 0;
353*cdf0e10cSrcweir 	}
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir 	ImplClearHDCCache( pSalData );
356*cdf0e10cSrcweir 	delete[] pSalData->mpHDCCache;
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir 	// Ditherpalette loeschen, wenn vorhanden
359*cdf0e10cSrcweir 	if ( pSalData->mhDitherPal )
360*cdf0e10cSrcweir 	{
361*cdf0e10cSrcweir 		DeleteObject( pSalData->mhDitherPal );
362*cdf0e10cSrcweir 		pSalData->mhDitherPal = 0;
363*cdf0e10cSrcweir 	}
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 	// delete buffers for dithering DIB patterns, if neccessary
366*cdf0e10cSrcweir 	if ( pSalData->mhDitherDIB )
367*cdf0e10cSrcweir 	{
368*cdf0e10cSrcweir 		GlobalUnlock( pSalData->mhDitherDIB );
369*cdf0e10cSrcweir 		GlobalFree( pSalData->mhDitherDIB );
370*cdf0e10cSrcweir 		pSalData->mhDitherDIB = 0;
371*cdf0e10cSrcweir 		delete[] pSalData->mpDitherDiff;
372*cdf0e10cSrcweir 		delete[] pSalData->mpDitherLow;
373*cdf0e10cSrcweir 		delete[] pSalData->mpDitherHigh;
374*cdf0e10cSrcweir 	}
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 	// delete SysColorList
377*cdf0e10cSrcweir 	SysColorEntry* pEntry = pFirstSysColor;
378*cdf0e10cSrcweir 	while( pEntry )
379*cdf0e10cSrcweir 	{
380*cdf0e10cSrcweir 		SysColorEntry* pTmp = pEntry->pNext;
381*cdf0e10cSrcweir 		delete pEntry;
382*cdf0e10cSrcweir 		pEntry = pTmp;
383*cdf0e10cSrcweir 	}
384*cdf0e10cSrcweir 	pFirstSysColor = NULL;
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir     // delete icon cache
387*cdf0e10cSrcweir     SalIcon* pIcon = pSalData->mpFirstIcon;
388*cdf0e10cSrcweir     pSalData->mpFirstIcon = NULL;
389*cdf0e10cSrcweir     while( pIcon )
390*cdf0e10cSrcweir     {
391*cdf0e10cSrcweir         SalIcon* pTmp = pIcon->pNext;
392*cdf0e10cSrcweir         DestroyIcon( pIcon->hIcon );
393*cdf0e10cSrcweir         DestroyIcon( pIcon->hSmallIcon );
394*cdf0e10cSrcweir         delete pIcon;
395*cdf0e10cSrcweir         pIcon = pTmp;
396*cdf0e10cSrcweir     }
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir     // delete temporary font list
399*cdf0e10cSrcweir     ImplReleaseTempFonts( *pSalData );
400*cdf0e10cSrcweir }
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir // -----------------------------------------------------------------------
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir 	// dither color?
407*cdf0e10cSrcweir 	if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) )
408*cdf0e10cSrcweir 		return TRUE;
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 	PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry;
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir 	// standard palette color?
413*cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ )
414*cdf0e10cSrcweir 	{
415*cdf0e10cSrcweir 		if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue )
416*cdf0e10cSrcweir 			return TRUE;
417*cdf0e10cSrcweir 	}
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	// extra color?
420*cdf0e10cSrcweir 	if ( aImplExtraColor1.peRed == nRed &&
421*cdf0e10cSrcweir 		 aImplExtraColor1.peGreen == nGreen &&
422*cdf0e10cSrcweir 		 aImplExtraColor1.peBlue == nBlue )
423*cdf0e10cSrcweir 	{
424*cdf0e10cSrcweir 		return TRUE;
425*cdf0e10cSrcweir 	}
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir 	return FALSE;
428*cdf0e10cSrcweir }
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir // =======================================================================
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir int ImplIsSysColorEntry( SalColor nSalColor )
433*cdf0e10cSrcweir {
434*cdf0e10cSrcweir 	SysColorEntry*	pEntry = pFirstSysColor;
435*cdf0e10cSrcweir 	const DWORD 	nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
436*cdf0e10cSrcweir 										   SALCOLOR_GREEN( nSalColor ),
437*cdf0e10cSrcweir 										   SALCOLOR_BLUE( nSalColor ) );
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir 	while ( pEntry )
440*cdf0e10cSrcweir 	{
441*cdf0e10cSrcweir 		if ( pEntry->nRGB == nTestRGB )
442*cdf0e10cSrcweir 			return TRUE;
443*cdf0e10cSrcweir 		pEntry = pEntry->pNext;
444*cdf0e10cSrcweir 	}
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 	return FALSE;
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir // =======================================================================
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir static void ImplInsertSysColorEntry( int nSysIndex )
452*cdf0e10cSrcweir {
453*cdf0e10cSrcweir 	const DWORD nRGB = GetSysColor( nSysIndex );
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir 	if ( !ImplIsPaletteEntry( GetRValue( nRGB ), GetGValue( nRGB ), GetBValue( nRGB ) ) )
456*cdf0e10cSrcweir 	{
457*cdf0e10cSrcweir 		if ( !pFirstSysColor )
458*cdf0e10cSrcweir 		{
459*cdf0e10cSrcweir 			pActSysColor = pFirstSysColor = new SysColorEntry;
460*cdf0e10cSrcweir 			pFirstSysColor->nRGB = nRGB;
461*cdf0e10cSrcweir 			pFirstSysColor->pNext = NULL;
462*cdf0e10cSrcweir 		}
463*cdf0e10cSrcweir 		else
464*cdf0e10cSrcweir 		{
465*cdf0e10cSrcweir 			pActSysColor = pActSysColor->pNext = new SysColorEntry;
466*cdf0e10cSrcweir 			pActSysColor->nRGB = nRGB;
467*cdf0e10cSrcweir 			pActSysColor->pNext = NULL;
468*cdf0e10cSrcweir 		}
469*cdf0e10cSrcweir 	}
470*cdf0e10cSrcweir }
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir // =======================================================================
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir void ImplUpdateSysColorEntries()
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	// delete old SysColorList
477*cdf0e10cSrcweir 	SysColorEntry* pEntry = pFirstSysColor;
478*cdf0e10cSrcweir 	while( pEntry )
479*cdf0e10cSrcweir 	{
480*cdf0e10cSrcweir 		SysColorEntry* pTmp = pEntry->pNext;
481*cdf0e10cSrcweir 		delete pEntry;
482*cdf0e10cSrcweir 		pEntry = pTmp;
483*cdf0e10cSrcweir 	}
484*cdf0e10cSrcweir 	pActSysColor = pFirstSysColor = NULL;
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir 	// create new sys color list
487*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_ACTIVEBORDER );
488*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_INACTIVEBORDER );
489*cdf0e10cSrcweir 	if( aSalShlData.mnVersion >= 410 )
490*cdf0e10cSrcweir 	{
491*cdf0e10cSrcweir 		ImplInsertSysColorEntry( COLOR_GRADIENTACTIVECAPTION );
492*cdf0e10cSrcweir 		ImplInsertSysColorEntry( COLOR_GRADIENTINACTIVECAPTION );
493*cdf0e10cSrcweir 	}
494*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_3DFACE );
495*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_3DHILIGHT );
496*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_3DLIGHT );
497*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_3DSHADOW );
498*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_3DDKSHADOW );
499*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_INFOBK );
500*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_INFOTEXT );
501*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_BTNTEXT );
502*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_WINDOW );
503*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_WINDOWTEXT );
504*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_HIGHLIGHT );
505*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_HIGHLIGHTTEXT );
506*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_MENU );
507*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_MENUTEXT );
508*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_ACTIVECAPTION );
509*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_CAPTIONTEXT );
510*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_INACTIVECAPTION );
511*cdf0e10cSrcweir 	ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
512*cdf0e10cSrcweir }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir // -----------------------------------------------------------------------
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
517*cdf0e10cSrcweir {
518*cdf0e10cSrcweir 	SalColor nSalColor;
519*cdf0e10cSrcweir 	if ( nROPColor == SAL_ROP_0 )
520*cdf0e10cSrcweir 		nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
521*cdf0e10cSrcweir 	else
522*cdf0e10cSrcweir 		nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
523*cdf0e10cSrcweir 	return nSalColor;
524*cdf0e10cSrcweir }
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir // =======================================================================
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir void ImplSalInitGraphics( WinSalGraphics* pData )
529*cdf0e10cSrcweir {
530*cdf0e10cSrcweir 	// Beim Printer berechnen wir die minimale Linienstaerke
531*cdf0e10cSrcweir 	if ( pData->mbPrinter )
532*cdf0e10cSrcweir 	{
533*cdf0e10cSrcweir 		int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX );
534*cdf0e10cSrcweir 		if ( nDPIX <= 300 )
535*cdf0e10cSrcweir 			pData->mnPenWidth = 0;
536*cdf0e10cSrcweir 		else
537*cdf0e10cSrcweir 			pData->mnPenWidth = nDPIX/300;
538*cdf0e10cSrcweir 	}
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir 	::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
541*cdf0e10cSrcweir 	::SetBkMode( pData->mhDC, TRANSPARENT );
542*cdf0e10cSrcweir 	::SetROP2( pData->mhDC, R2_COPYPEN );
543*cdf0e10cSrcweir }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir // -----------------------------------------------------------------------
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir void ImplSalDeInitGraphics( WinSalGraphics* pData )
548*cdf0e10cSrcweir {
549*cdf0e10cSrcweir     // clear clip region
550*cdf0e10cSrcweir 	SelectClipRgn( pData->mhDC, 0 );
551*cdf0e10cSrcweir 	// select default objects
552*cdf0e10cSrcweir 	if ( pData->mhDefPen )
553*cdf0e10cSrcweir 		SelectPen( pData->mhDC, pData->mhDefPen );
554*cdf0e10cSrcweir 	if ( pData->mhDefBrush )
555*cdf0e10cSrcweir 		SelectBrush( pData->mhDC, pData->mhDefBrush );
556*cdf0e10cSrcweir 	if ( pData->mhDefFont )
557*cdf0e10cSrcweir 		SelectFont( pData->mhDC, pData->mhDefFont );
558*cdf0e10cSrcweir }
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir // =======================================================================
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir HDC ImplGetCachedDC( sal_uLong nID, HBITMAP hBmp )
563*cdf0e10cSrcweir {
564*cdf0e10cSrcweir 	SalData*	pSalData = GetSalData();
565*cdf0e10cSrcweir 	HDCCache*	pC = &pSalData->mpHDCCache[ nID ];
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 	if( !pC->mhDC )
568*cdf0e10cSrcweir 	{
569*cdf0e10cSrcweir 		HDC hDC = GetDC( 0 );
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 		// neuen DC mit DefaultBitmap anlegen
572*cdf0e10cSrcweir 		pC->mhDC = CreateCompatibleDC( hDC );
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 		if( pSalData->mhDitherPal )
575*cdf0e10cSrcweir 		{
576*cdf0e10cSrcweir 			pC->mhDefPal = SelectPalette( pC->mhDC, pSalData->mhDitherPal, TRUE );
577*cdf0e10cSrcweir 			RealizePalette( pC->mhDC );
578*cdf0e10cSrcweir 		}
579*cdf0e10cSrcweir 
580*cdf0e10cSrcweir 		pC->mhSelBmp = CreateCompatibleBitmap( hDC, CACHED_HDC_DEFEXT, CACHED_HDC_DEFEXT );
581*cdf0e10cSrcweir 		pC->mhDefBmp = (HBITMAP) SelectObject( pC->mhDC, pC->mhSelBmp );
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir 		ReleaseDC( 0, hDC );
584*cdf0e10cSrcweir 	}
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir 	if ( hBmp )
587*cdf0e10cSrcweir 		SelectObject( pC->mhDC, pC->mhActBmp = hBmp );
588*cdf0e10cSrcweir 	else
589*cdf0e10cSrcweir 		pC->mhActBmp = 0;
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	return pC->mhDC;
592*cdf0e10cSrcweir }
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir // =======================================================================
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir void ImplReleaseCachedDC( sal_uLong nID )
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir 	SalData*	pSalData = GetSalData();
599*cdf0e10cSrcweir 	HDCCache*	pC = &pSalData->mpHDCCache[ nID ];
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 	if ( pC->mhActBmp )
602*cdf0e10cSrcweir 		SelectObject( pC->mhDC, pC->mhSelBmp );
603*cdf0e10cSrcweir }
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir // =======================================================================
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir void ImplClearHDCCache( SalData* pData )
608*cdf0e10cSrcweir {
609*cdf0e10cSrcweir 	for( sal_uLong i = 0; i < CACHESIZE_HDC; i++ )
610*cdf0e10cSrcweir 	{
611*cdf0e10cSrcweir 		HDCCache* pC = &pData->mpHDCCache[ i ];
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir 		if( pC->mhDC )
614*cdf0e10cSrcweir 		{
615*cdf0e10cSrcweir 			SelectObject( pC->mhDC, pC->mhDefBmp );
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir 			if( pC->mhDefPal )
618*cdf0e10cSrcweir 				SelectPalette( pC->mhDC, pC->mhDefPal, TRUE );
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir 			DeleteDC( pC->mhDC );
621*cdf0e10cSrcweir 			DeleteObject( pC->mhSelBmp );
622*cdf0e10cSrcweir 		}
623*cdf0e10cSrcweir 	}
624*cdf0e10cSrcweir }
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir // =======================================================================
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir // #100127# Fill point and flag memory from array of points which
629*cdf0e10cSrcweir // might also contain bezier control points for the PolyDraw() GDI method
630*cdf0e10cSrcweir // Make sure pWinPointAry and pWinFlagAry are big enough
631*cdf0e10cSrcweir void ImplPreparePolyDraw( bool						bCloseFigures,
632*cdf0e10cSrcweir                           sal_uLong 					nPoly,
633*cdf0e10cSrcweir                           const sal_uLong* 				pPoints,
634*cdf0e10cSrcweir                           const SalPoint* const* 	pPtAry,
635*cdf0e10cSrcweir                           const BYTE* const* 		pFlgAry,
636*cdf0e10cSrcweir                           POINT* 					pWinPointAry,
637*cdf0e10cSrcweir                           BYTE* 					pWinFlagAry		)
638*cdf0e10cSrcweir {
639*cdf0e10cSrcweir     sal_uLong nCurrPoly;
640*cdf0e10cSrcweir     for( nCurrPoly=0; nCurrPoly<nPoly; ++nCurrPoly )
641*cdf0e10cSrcweir     {
642*cdf0e10cSrcweir         const POINT* pCurrPoint = reinterpret_cast<const POINT*>( *pPtAry++ );
643*cdf0e10cSrcweir         const BYTE* pCurrFlag = *pFlgAry++;
644*cdf0e10cSrcweir         const sal_uLong nCurrPoints = *pPoints++;
645*cdf0e10cSrcweir         const bool bHaveFlagArray( pCurrFlag );
646*cdf0e10cSrcweir         sal_uLong nCurrPoint;
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir         if( nCurrPoints )
649*cdf0e10cSrcweir         {
650*cdf0e10cSrcweir             // start figure
651*cdf0e10cSrcweir             *pWinPointAry++ = *pCurrPoint++;
652*cdf0e10cSrcweir             *pWinFlagAry++  = PT_MOVETO;
653*cdf0e10cSrcweir             ++pCurrFlag;
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir             for( nCurrPoint=1; nCurrPoint<nCurrPoints; )
656*cdf0e10cSrcweir             {
657*cdf0e10cSrcweir                 // #102067# Check existence of flag array
658*cdf0e10cSrcweir                 if( bHaveFlagArray &&
659*cdf0e10cSrcweir                     ( nCurrPoint + 2 ) < nCurrPoints )
660*cdf0e10cSrcweir                 {
661*cdf0e10cSrcweir                     BYTE P4( pCurrFlag[ 2 ] );
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir                     if( ( POLY_CONTROL == pCurrFlag[ 0 ] ) &&
664*cdf0e10cSrcweir                         ( POLY_CONTROL == pCurrFlag[ 1 ] ) &&
665*cdf0e10cSrcweir                         ( POLY_NORMAL == P4 || POLY_SMOOTH == P4 || POLY_SYMMTR == P4 ) )
666*cdf0e10cSrcweir                     {
667*cdf0e10cSrcweir                         // control point one
668*cdf0e10cSrcweir                         *pWinPointAry++ = *pCurrPoint++;
669*cdf0e10cSrcweir                         *pWinFlagAry++  = PT_BEZIERTO;
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir                         // control point two
672*cdf0e10cSrcweir                         *pWinPointAry++ = *pCurrPoint++;
673*cdf0e10cSrcweir                         *pWinFlagAry++  = PT_BEZIERTO;
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir                         // end point
676*cdf0e10cSrcweir                         *pWinPointAry++ = *pCurrPoint++;
677*cdf0e10cSrcweir                         *pWinFlagAry++  = PT_BEZIERTO;
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir                         nCurrPoint += 3;
680*cdf0e10cSrcweir                         pCurrFlag += 3;
681*cdf0e10cSrcweir                         continue;
682*cdf0e10cSrcweir                     }
683*cdf0e10cSrcweir                 }
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir                 // regular line point
686*cdf0e10cSrcweir                 *pWinPointAry++ = *pCurrPoint++;
687*cdf0e10cSrcweir                 *pWinFlagAry++  = PT_LINETO;
688*cdf0e10cSrcweir                 ++pCurrFlag;
689*cdf0e10cSrcweir                 ++nCurrPoint;
690*cdf0e10cSrcweir             }
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir             // end figure?
693*cdf0e10cSrcweir             if( bCloseFigures )
694*cdf0e10cSrcweir                 pWinFlagAry[-1] |= PT_CLOSEFIGURE;
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir     }
697*cdf0e10cSrcweir }
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir // =======================================================================
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir // #100127# draw an array of points which might also contain bezier control points
702*cdf0e10cSrcweir void ImplRenderPath( HDC hdc, sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
703*cdf0e10cSrcweir {
704*cdf0e10cSrcweir     if( nPoints )
705*cdf0e10cSrcweir     {
706*cdf0e10cSrcweir         sal_uInt16 i;
707*cdf0e10cSrcweir         // TODO: profile whether the following options are faster:
708*cdf0e10cSrcweir         // a) look ahead and draw consecutive bezier or line segments by PolyBezierTo/PolyLineTo resp.
709*cdf0e10cSrcweir         // b) convert our flag array to window's and use PolyDraw
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir         MoveToEx( hdc, pPtAry->mnX, pPtAry->mnY, NULL );
712*cdf0e10cSrcweir         ++pPtAry; ++pFlgAry;
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir         for( i=1; i<nPoints; ++i, ++pPtAry, ++pFlgAry )
715*cdf0e10cSrcweir         {
716*cdf0e10cSrcweir             if( *pFlgAry != POLY_CONTROL )
717*cdf0e10cSrcweir             {
718*cdf0e10cSrcweir                 LineTo( hdc, pPtAry->mnX, pPtAry->mnY );
719*cdf0e10cSrcweir             }
720*cdf0e10cSrcweir             else if( nPoints - i > 2 )
721*cdf0e10cSrcweir             {
722*cdf0e10cSrcweir                 PolyBezierTo( hdc, reinterpret_cast<const POINT*>(pPtAry), 3 );
723*cdf0e10cSrcweir                 i += 2; pPtAry += 2; pFlgAry += 2;
724*cdf0e10cSrcweir             }
725*cdf0e10cSrcweir         }
726*cdf0e10cSrcweir     }
727*cdf0e10cSrcweir }
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir // =======================================================================
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir WinSalGraphics::WinSalGraphics()
732*cdf0e10cSrcweir {
733*cdf0e10cSrcweir     for( int i = 0; i < MAX_FALLBACK; ++i )
734*cdf0e10cSrcweir     {
735*cdf0e10cSrcweir         mhFonts[ i ] = 0;
736*cdf0e10cSrcweir         mpWinFontData[ i ]  = NULL;
737*cdf0e10cSrcweir         mpWinFontEntry[ i ] = NULL;
738*cdf0e10cSrcweir     }
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir     mfFontScale = 1.0;
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 	mhDC 				= 0;
743*cdf0e10cSrcweir 	mhPen				= 0;
744*cdf0e10cSrcweir 	mhBrush				= 0;
745*cdf0e10cSrcweir 	mhRegion 			= 0;
746*cdf0e10cSrcweir 	mhDefPen 			= 0;
747*cdf0e10cSrcweir 	mhDefBrush			= 0;
748*cdf0e10cSrcweir 	mhDefFont			= 0;
749*cdf0e10cSrcweir 	mhDefPal 			= 0;
750*cdf0e10cSrcweir 	mpStdClipRgnData 	= NULL;
751*cdf0e10cSrcweir 	mpLogFont			= NULL;
752*cdf0e10cSrcweir 	mpFontCharSets		= NULL;
753*cdf0e10cSrcweir 	mpFontAttrCache		= NULL;
754*cdf0e10cSrcweir 	mnFontCharSetCount	= 0;
755*cdf0e10cSrcweir 	mpFontKernPairs		= NULL;
756*cdf0e10cSrcweir 	mnFontKernPairCount	= 0;
757*cdf0e10cSrcweir 	mbFontKernInit		= FALSE;
758*cdf0e10cSrcweir 	mbXORMode			= FALSE;
759*cdf0e10cSrcweir 	mnPenWidth			= GSL_PEN_WIDTH;
760*cdf0e10cSrcweir }
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir // -----------------------------------------------------------------------
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir WinSalGraphics::~WinSalGraphics()
765*cdf0e10cSrcweir {
766*cdf0e10cSrcweir 	// free obsolete GDI objekts
767*cdf0e10cSrcweir         ReleaseFonts();
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir 	if ( mhPen )
770*cdf0e10cSrcweir 	{
771*cdf0e10cSrcweir 		if ( !mbStockPen )
772*cdf0e10cSrcweir 			DeletePen( mhPen );
773*cdf0e10cSrcweir 	}
774*cdf0e10cSrcweir 	if ( mhBrush )
775*cdf0e10cSrcweir 	{
776*cdf0e10cSrcweir 		if ( !mbStockBrush )
777*cdf0e10cSrcweir 			DeleteBrush( mhBrush );
778*cdf0e10cSrcweir 	}
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir 	if ( mhRegion )
781*cdf0e10cSrcweir 	{
782*cdf0e10cSrcweir 		DeleteRegion( mhRegion );
783*cdf0e10cSrcweir 		mhRegion = 0;
784*cdf0e10cSrcweir 	}
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir 	// Cache-Daten zerstoeren
787*cdf0e10cSrcweir 	if ( mpStdClipRgnData )
788*cdf0e10cSrcweir 		delete [] mpStdClipRgnData;
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	if ( mpLogFont )
791*cdf0e10cSrcweir 		delete mpLogFont;
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir 	if ( mpFontCharSets )
794*cdf0e10cSrcweir 		delete mpFontCharSets;
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir 	if ( mpFontKernPairs )
797*cdf0e10cSrcweir 		delete mpFontKernPairs;
798*cdf0e10cSrcweir }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir // -----------------------------------------------------------------------
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir void WinSalGraphics::GetResolution( long& rDPIX, long& rDPIY )
803*cdf0e10cSrcweir {
804*cdf0e10cSrcweir 	rDPIX = GetDeviceCaps( mhDC, LOGPIXELSX );
805*cdf0e10cSrcweir 	rDPIY = GetDeviceCaps( mhDC, LOGPIXELSY );
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir     // #111139# this fixes the symptom of div by zero on startup
808*cdf0e10cSrcweir     // however, printing will fail most likely as communication with
809*cdf0e10cSrcweir     // the printer seems not to work in this case
810*cdf0e10cSrcweir     if( !rDPIX || !rDPIY )
811*cdf0e10cSrcweir         rDPIX = rDPIY = 600;
812*cdf0e10cSrcweir }
813*cdf0e10cSrcweir 
814*cdf0e10cSrcweir // -----------------------------------------------------------------------
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir sal_uInt16 WinSalGraphics::GetBitCount()
817*cdf0e10cSrcweir {
818*cdf0e10cSrcweir 	return (sal_uInt16)GetDeviceCaps( mhDC, BITSPIXEL );
819*cdf0e10cSrcweir }
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir // -----------------------------------------------------------------------
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir long WinSalGraphics::GetGraphicsWidth() const
824*cdf0e10cSrcweir {
825*cdf0e10cSrcweir     if( mhWnd && IsWindow( mhWnd ) )
826*cdf0e10cSrcweir     {
827*cdf0e10cSrcweir         WinSalFrame* pFrame = GetWindowPtr( mhWnd );
828*cdf0e10cSrcweir         if( pFrame )
829*cdf0e10cSrcweir         {
830*cdf0e10cSrcweir             if( pFrame->maGeometry.nWidth )
831*cdf0e10cSrcweir                 return pFrame->maGeometry.nWidth;
832*cdf0e10cSrcweir             else
833*cdf0e10cSrcweir             {
834*cdf0e10cSrcweir                 // TODO: perhaps not needed, maGeometry should always be up-to-date
835*cdf0e10cSrcweir                 RECT aRect;
836*cdf0e10cSrcweir                 GetClientRect( mhWnd, &aRect );
837*cdf0e10cSrcweir                 return aRect.right;
838*cdf0e10cSrcweir             }
839*cdf0e10cSrcweir         }
840*cdf0e10cSrcweir     }
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir     return 0;
843*cdf0e10cSrcweir }
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir // -----------------------------------------------------------------------
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir void WinSalGraphics::ResetClipRegion()
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir 	if ( mhRegion )
850*cdf0e10cSrcweir 	{
851*cdf0e10cSrcweir 		DeleteRegion( mhRegion );
852*cdf0e10cSrcweir 		mhRegion = 0;
853*cdf0e10cSrcweir 	}
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir 	SelectClipRgn( mhDC, 0 );
856*cdf0e10cSrcweir }
857*cdf0e10cSrcweir 
858*cdf0e10cSrcweir // -----------------------------------------------------------------------
859*cdf0e10cSrcweir 
860*cdf0e10cSrcweir bool WinSalGraphics::setClipRegion( const Region& i_rClip )
861*cdf0e10cSrcweir {
862*cdf0e10cSrcweir 	if ( mhRegion )
863*cdf0e10cSrcweir 	{
864*cdf0e10cSrcweir 		DeleteRegion( mhRegion );
865*cdf0e10cSrcweir 		mhRegion = 0;
866*cdf0e10cSrcweir 	}
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir 	if( i_rClip.HasPolyPolygon() )
869*cdf0e10cSrcweir 	{
870*cdf0e10cSrcweir 	    // TODO: ConvertToB2DPolyPolygon actually is kind of const, just it does not advertise it in the header
871*cdf0e10cSrcweir 	    basegfx::B2DPolyPolygon aPolyPolygon( const_cast<Region&>(i_rClip).ConvertToB2DPolyPolygon() );
872*cdf0e10cSrcweir         const sal_uInt32 nCount(aPolyPolygon.count());
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir         if( nCount )
875*cdf0e10cSrcweir         {
876*cdf0e10cSrcweir             std::vector< POINT > aPolyPoints;
877*cdf0e10cSrcweir             aPolyPoints.reserve( 1024 );
878*cdf0e10cSrcweir             std::vector< INT > aPolyCounts( nCount, 0 );
879*cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nCount; a++)
880*cdf0e10cSrcweir             {
881*cdf0e10cSrcweir                 basegfx::B2DPolygon aPoly( aPolyPolygon.getB2DPolygon(a) );
882*cdf0e10cSrcweir                 aPoly = basegfx::tools::adaptiveSubdivideByDistance( aPoly, 1 );
883*cdf0e10cSrcweir                 const sal_uInt32 nPoints = aPoly.count();
884*cdf0e10cSrcweir                 aPolyCounts[a] = nPoints;
885*cdf0e10cSrcweir                 for( sal_uInt32 b = 0; b < nPoints; b++ )
886*cdf0e10cSrcweir                 {
887*cdf0e10cSrcweir                     basegfx::B2DPoint aPt( aPoly.getB2DPoint( b ) );
888*cdf0e10cSrcweir                     POINT aPOINT;
889*cdf0e10cSrcweir                     aPOINT.x = (LONG)aPt.getX();
890*cdf0e10cSrcweir                     aPOINT.y = (LONG)aPt.getY();
891*cdf0e10cSrcweir                     aPolyPoints.push_back( aPOINT );
892*cdf0e10cSrcweir                 }
893*cdf0e10cSrcweir             }
894*cdf0e10cSrcweir             mhRegion = CreatePolyPolygonRgn( &aPolyPoints[0], &aPolyCounts[0], nCount, ALTERNATE );
895*cdf0e10cSrcweir         }
896*cdf0e10cSrcweir 	}
897*cdf0e10cSrcweir 	else
898*cdf0e10cSrcweir 	{
899*cdf0e10cSrcweir 	    ULONG nRectCount = i_rClip.GetRectCount();
900*cdf0e10cSrcweir 
901*cdf0e10cSrcweir 	    ULONG nRectBufSize = sizeof(RECT)*nRectCount;
902*cdf0e10cSrcweir         if ( nRectCount < SAL_CLIPRECT_COUNT )
903*cdf0e10cSrcweir         {
904*cdf0e10cSrcweir             if ( !mpStdClipRgnData )
905*cdf0e10cSrcweir                 mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
906*cdf0e10cSrcweir             mpClipRgnData = mpStdClipRgnData;
907*cdf0e10cSrcweir         }
908*cdf0e10cSrcweir         else
909*cdf0e10cSrcweir             mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
910*cdf0e10cSrcweir         mpClipRgnData->rdh.dwSize	= sizeof( RGNDATAHEADER );
911*cdf0e10cSrcweir         mpClipRgnData->rdh.iType 	= RDH_RECTANGLES;
912*cdf0e10cSrcweir         mpClipRgnData->rdh.nCount	= nRectCount;
913*cdf0e10cSrcweir         mpClipRgnData->rdh.nRgnSize	= nRectBufSize;
914*cdf0e10cSrcweir         RECT*		pBoundRect = &(mpClipRgnData->rdh.rcBound);
915*cdf0e10cSrcweir         SetRectEmpty( pBoundRect );
916*cdf0e10cSrcweir         RECT* pNextClipRect         = (RECT*)(&(mpClipRgnData->Buffer));
917*cdf0e10cSrcweir         bool bFirstClipRect         = true;
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir         ImplRegionInfo aInfo;
920*cdf0e10cSrcweir         long nX, nY, nW, nH;
921*cdf0e10cSrcweir         bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
922*cdf0e10cSrcweir         while( bRegionRect )
923*cdf0e10cSrcweir         {
924*cdf0e10cSrcweir             if ( nW && nH )
925*cdf0e10cSrcweir             {
926*cdf0e10cSrcweir                 long		nRight = nX + nW;
927*cdf0e10cSrcweir                 long		nBottom = nY + nH;
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir                 if ( bFirstClipRect )
930*cdf0e10cSrcweir                 {
931*cdf0e10cSrcweir                     pBoundRect->left	= nX;
932*cdf0e10cSrcweir                     pBoundRect->top 	= nY;
933*cdf0e10cSrcweir                     pBoundRect->right	= nRight;
934*cdf0e10cSrcweir                     pBoundRect->bottom	= nBottom;
935*cdf0e10cSrcweir                     bFirstClipRect = false;
936*cdf0e10cSrcweir                 }
937*cdf0e10cSrcweir                 else
938*cdf0e10cSrcweir                 {
939*cdf0e10cSrcweir                     if ( nX < pBoundRect->left )
940*cdf0e10cSrcweir                         pBoundRect->left = (int)nX;
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir                     if ( nY < pBoundRect->top )
943*cdf0e10cSrcweir                         pBoundRect->top = (int)nY;
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir                     if ( nRight > pBoundRect->right )
946*cdf0e10cSrcweir                         pBoundRect->right = (int)nRight;
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir                     if ( nBottom > pBoundRect->bottom )
949*cdf0e10cSrcweir                         pBoundRect->bottom = (int)nBottom;
950*cdf0e10cSrcweir                 }
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir                 pNextClipRect->left 	= (int)nX;
953*cdf0e10cSrcweir                 pNextClipRect->top		= (int)nY;
954*cdf0e10cSrcweir                 pNextClipRect->right	= (int)nRight;
955*cdf0e10cSrcweir                 pNextClipRect->bottom	= (int)nBottom;
956*cdf0e10cSrcweir                 pNextClipRect++;
957*cdf0e10cSrcweir             }
958*cdf0e10cSrcweir             else
959*cdf0e10cSrcweir             {
960*cdf0e10cSrcweir                 mpClipRgnData->rdh.nCount--;
961*cdf0e10cSrcweir                 mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
962*cdf0e10cSrcweir             }
963*cdf0e10cSrcweir             bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
964*cdf0e10cSrcweir         }
965*cdf0e10cSrcweir         // create clip region from ClipRgnData
966*cdf0e10cSrcweir         if ( mpClipRgnData->rdh.nCount == 1 )
967*cdf0e10cSrcweir         {
968*cdf0e10cSrcweir             RECT* pRect = &(mpClipRgnData->rdh.rcBound);
969*cdf0e10cSrcweir             mhRegion = CreateRectRgn( pRect->left, pRect->top,
970*cdf0e10cSrcweir                                                      pRect->right, pRect->bottom );
971*cdf0e10cSrcweir         }
972*cdf0e10cSrcweir         else if( mpClipRgnData->rdh.nCount > 1 )
973*cdf0e10cSrcweir         {
974*cdf0e10cSrcweir             ULONG nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
975*cdf0e10cSrcweir             mhRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData );
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir             // if ExtCreateRegion(...) is not supported
978*cdf0e10cSrcweir             if( !mhRegion )
979*cdf0e10cSrcweir             {
980*cdf0e10cSrcweir                 RGNDATAHEADER* pHeader = (RGNDATAHEADER*) mpClipRgnData;
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir                 if( pHeader->nCount )
983*cdf0e10cSrcweir                 {
984*cdf0e10cSrcweir                     RECT* pRect = (RECT*) mpClipRgnData->Buffer;
985*cdf0e10cSrcweir                     mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
986*cdf0e10cSrcweir                     pRect++;
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir                     for( ULONG n = 1; n < pHeader->nCount; n++, pRect++ )
989*cdf0e10cSrcweir                     {
990*cdf0e10cSrcweir                         HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
991*cdf0e10cSrcweir                         CombineRgn( mhRegion, mhRegion, hRgn, RGN_OR );
992*cdf0e10cSrcweir                         DeleteRegion( hRgn );
993*cdf0e10cSrcweir                     }
994*cdf0e10cSrcweir                 }
995*cdf0e10cSrcweir             }
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir             if ( mpClipRgnData != mpStdClipRgnData )
998*cdf0e10cSrcweir                 delete [] mpClipRgnData;
999*cdf0e10cSrcweir         }
1000*cdf0e10cSrcweir 	}
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir 	if( mhRegion )
1003*cdf0e10cSrcweir 	    SelectClipRgn( mhDC, mhRegion );
1004*cdf0e10cSrcweir 	return mhRegion != 0;
1005*cdf0e10cSrcweir }
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir // -----------------------------------------------------------------------
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir void WinSalGraphics::SetLineColor()
1010*cdf0e10cSrcweir {
1011*cdf0e10cSrcweir 	// create and select new pen
1012*cdf0e10cSrcweir 	HPEN hNewPen = GetStockPen( NULL_PEN );
1013*cdf0e10cSrcweir 	HPEN hOldPen = SelectPen( mhDC, hNewPen );
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir 	// destory or save old pen
1016*cdf0e10cSrcweir 	if ( mhPen )
1017*cdf0e10cSrcweir 	{
1018*cdf0e10cSrcweir 		if ( !mbStockPen )
1019*cdf0e10cSrcweir 			DeletePen( mhPen );
1020*cdf0e10cSrcweir 	}
1021*cdf0e10cSrcweir 	else
1022*cdf0e10cSrcweir 		mhDefPen = hOldPen;
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir 	// set new data
1025*cdf0e10cSrcweir 	mhPen		= hNewPen;
1026*cdf0e10cSrcweir 	mbPen		= FALSE;
1027*cdf0e10cSrcweir 	mbStockPen	= TRUE;
1028*cdf0e10cSrcweir }
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir // -----------------------------------------------------------------------
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir void WinSalGraphics::SetLineColor( SalColor nSalColor )
1033*cdf0e10cSrcweir {
1034*cdf0e10cSrcweir     maLineColor = nSalColor;
1035*cdf0e10cSrcweir 	COLORREF	nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
1036*cdf0e10cSrcweir 										SALCOLOR_GREEN( nSalColor ),
1037*cdf0e10cSrcweir 										SALCOLOR_BLUE( nSalColor ) );
1038*cdf0e10cSrcweir 	HPEN		hNewPen = 0;
1039*cdf0e10cSrcweir 	sal_Bool		bStockPen = FALSE;
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir 	// search for stock pen (only screen, because printer have problems,
1042*cdf0e10cSrcweir 	// when we use stock objects)
1043*cdf0e10cSrcweir 	if ( !mbPrinter )
1044*cdf0e10cSrcweir 	{
1045*cdf0e10cSrcweir 		SalData* pSalData = GetSalData();
1046*cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++ )
1047*cdf0e10cSrcweir 		{
1048*cdf0e10cSrcweir 			if ( nPenColor == pSalData->maStockPenColorAry[i] )
1049*cdf0e10cSrcweir 			{
1050*cdf0e10cSrcweir 				hNewPen = pSalData->mhStockPenAry[i];
1051*cdf0e10cSrcweir 				bStockPen = TRUE;
1052*cdf0e10cSrcweir 				break;
1053*cdf0e10cSrcweir 			}
1054*cdf0e10cSrcweir 		}
1055*cdf0e10cSrcweir 	}
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir 	// create new pen
1058*cdf0e10cSrcweir 	if ( !hNewPen )
1059*cdf0e10cSrcweir 	{
1060*cdf0e10cSrcweir 		if ( !mbPrinter )
1061*cdf0e10cSrcweir 		{
1062*cdf0e10cSrcweir 			if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
1063*cdf0e10cSrcweir 				nPenColor = PALRGB_TO_RGB( nPenColor );
1064*cdf0e10cSrcweir 		}
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir 		hNewPen = CreatePen( PS_SOLID, mnPenWidth, nPenColor );
1067*cdf0e10cSrcweir 		bStockPen = FALSE;
1068*cdf0e10cSrcweir 	}
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir 	// select new pen
1071*cdf0e10cSrcweir 	HPEN hOldPen = SelectPen( mhDC, hNewPen );
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir 	// destory or save old pen
1074*cdf0e10cSrcweir 	if ( mhPen )
1075*cdf0e10cSrcweir 	{
1076*cdf0e10cSrcweir 		if ( !mbStockPen )
1077*cdf0e10cSrcweir 			DeletePen( mhPen );
1078*cdf0e10cSrcweir 	}
1079*cdf0e10cSrcweir 	else
1080*cdf0e10cSrcweir 		mhDefPen = hOldPen;
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir 	// set new data
1083*cdf0e10cSrcweir 	mnPenColor	= nPenColor;
1084*cdf0e10cSrcweir 	mhPen		= hNewPen;
1085*cdf0e10cSrcweir 	mbPen		= TRUE;
1086*cdf0e10cSrcweir 	mbStockPen	= bStockPen;
1087*cdf0e10cSrcweir }
1088*cdf0e10cSrcweir 
1089*cdf0e10cSrcweir // -----------------------------------------------------------------------
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir void WinSalGraphics::SetFillColor()
1092*cdf0e10cSrcweir {
1093*cdf0e10cSrcweir 	// create and select new brush
1094*cdf0e10cSrcweir 	HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
1095*cdf0e10cSrcweir 	HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush );
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir 	// destory or save old brush
1098*cdf0e10cSrcweir 	if ( mhBrush )
1099*cdf0e10cSrcweir 	{
1100*cdf0e10cSrcweir 		if ( !mbStockBrush )
1101*cdf0e10cSrcweir 			DeleteBrush( mhBrush );
1102*cdf0e10cSrcweir 	}
1103*cdf0e10cSrcweir 	else
1104*cdf0e10cSrcweir 		mhDefBrush = hOldBrush;
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir 	// set new data
1107*cdf0e10cSrcweir 	mhBrush		= hNewBrush;
1108*cdf0e10cSrcweir 	mbBrush		= FALSE;
1109*cdf0e10cSrcweir 	mbStockBrush = TRUE;
1110*cdf0e10cSrcweir }
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir // -----------------------------------------------------------------------
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir void WinSalGraphics::SetFillColor( SalColor nSalColor )
1115*cdf0e10cSrcweir {
1116*cdf0e10cSrcweir     maFillColor = nSalColor;
1117*cdf0e10cSrcweir 	SalData*	pSalData	= GetSalData();
1118*cdf0e10cSrcweir 	BYTE		nRed		= SALCOLOR_RED( nSalColor );
1119*cdf0e10cSrcweir 	BYTE		nGreen		= SALCOLOR_GREEN( nSalColor );
1120*cdf0e10cSrcweir 	BYTE		nBlue		= SALCOLOR_BLUE( nSalColor );
1121*cdf0e10cSrcweir 	COLORREF	nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
1122*cdf0e10cSrcweir 	HBRUSH		hNewBrush	= 0;
1123*cdf0e10cSrcweir 	sal_Bool		bStockBrush = FALSE;
1124*cdf0e10cSrcweir 
1125*cdf0e10cSrcweir 	// search for stock brush (only screen, because printer have problems,
1126*cdf0e10cSrcweir 	// when we use stock objects)
1127*cdf0e10cSrcweir 	if ( !mbPrinter )
1128*cdf0e10cSrcweir 	{
1129*cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < pSalData->mnStockBrushCount; i++ )
1130*cdf0e10cSrcweir 		{
1131*cdf0e10cSrcweir 			if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
1132*cdf0e10cSrcweir 			{
1133*cdf0e10cSrcweir 				hNewBrush = pSalData->mhStockBrushAry[i];
1134*cdf0e10cSrcweir 				bStockBrush = TRUE;
1135*cdf0e10cSrcweir 				break;
1136*cdf0e10cSrcweir 			}
1137*cdf0e10cSrcweir 		}
1138*cdf0e10cSrcweir 	}
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir 	// create new brush
1141*cdf0e10cSrcweir 	if ( !hNewBrush )
1142*cdf0e10cSrcweir 	{
1143*cdf0e10cSrcweir 		if ( mbPrinter || !pSalData->mhDitherDIB )
1144*cdf0e10cSrcweir 			hNewBrush = CreateSolidBrush( nBrushColor );
1145*cdf0e10cSrcweir 		else
1146*cdf0e10cSrcweir 		{
1147*cdf0e10cSrcweir 			if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
1148*cdf0e10cSrcweir 			{
1149*cdf0e10cSrcweir 				BYTE* pTmp = pSalData->mpDitherDIBData;
1150*cdf0e10cSrcweir 				long* pDitherDiff = pSalData->mpDitherDiff;
1151*cdf0e10cSrcweir 				BYTE* pDitherLow = pSalData->mpDitherLow;
1152*cdf0e10cSrcweir 				BYTE* pDitherHigh = pSalData->mpDitherHigh;
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir 				for( long nY = 0L; nY < 8L; nY++ )
1155*cdf0e10cSrcweir 				{
1156*cdf0e10cSrcweir 					for( long nX = 0L; nX < 8L; nX++ )
1157*cdf0e10cSrcweir 					{
1158*cdf0e10cSrcweir 						const long nThres = aOrdDither16Bit[ nY ][ nX ];
1159*cdf0e10cSrcweir 						*pTmp++ = DMAP( nBlue, nThres );
1160*cdf0e10cSrcweir 						*pTmp++ = DMAP( nGreen, nThres );
1161*cdf0e10cSrcweir 						*pTmp++ = DMAP( nRed, nThres );
1162*cdf0e10cSrcweir 					}
1163*cdf0e10cSrcweir 				}
1164*cdf0e10cSrcweir 
1165*cdf0e10cSrcweir 				hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
1166*cdf0e10cSrcweir 			}
1167*cdf0e10cSrcweir 			else if ( ImplIsSysColorEntry( nSalColor ) )
1168*cdf0e10cSrcweir 			{
1169*cdf0e10cSrcweir 				nBrushColor = PALRGB_TO_RGB( nBrushColor );
1170*cdf0e10cSrcweir 				hNewBrush = CreateSolidBrush( nBrushColor );
1171*cdf0e10cSrcweir 			}
1172*cdf0e10cSrcweir 			else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
1173*cdf0e10cSrcweir 				hNewBrush = CreateSolidBrush( nBrushColor );
1174*cdf0e10cSrcweir 			else
1175*cdf0e10cSrcweir 			{
1176*cdf0e10cSrcweir 				BYTE* pTmp = pSalData->mpDitherDIBData;
1177*cdf0e10cSrcweir 				long* pDitherDiff = pSalData->mpDitherDiff;
1178*cdf0e10cSrcweir 				BYTE* pDitherLow = pSalData->mpDitherLow;
1179*cdf0e10cSrcweir 				BYTE* pDitherHigh = pSalData->mpDitherHigh;
1180*cdf0e10cSrcweir 
1181*cdf0e10cSrcweir 				for ( long nY = 0L; nY < 8L; nY++ )
1182*cdf0e10cSrcweir 				{
1183*cdf0e10cSrcweir 					for ( long nX = 0L; nX < 8L; nX++ )
1184*cdf0e10cSrcweir 					{
1185*cdf0e10cSrcweir 						const long nThres = aOrdDither8Bit[ nY ][ nX ];
1186*cdf0e10cSrcweir 						*pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
1187*cdf0e10cSrcweir 						pTmp++;
1188*cdf0e10cSrcweir 					}
1189*cdf0e10cSrcweir 				}
1190*cdf0e10cSrcweir 
1191*cdf0e10cSrcweir 				hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
1192*cdf0e10cSrcweir 			}
1193*cdf0e10cSrcweir 		}
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir 		bStockBrush = FALSE;
1196*cdf0e10cSrcweir 	}
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir 	// select new brush
1199*cdf0e10cSrcweir 	HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush );
1200*cdf0e10cSrcweir 
1201*cdf0e10cSrcweir 	// destory or save old brush
1202*cdf0e10cSrcweir 	if ( mhBrush )
1203*cdf0e10cSrcweir 	{
1204*cdf0e10cSrcweir 		if ( !mbStockBrush )
1205*cdf0e10cSrcweir 			DeleteBrush( mhBrush );
1206*cdf0e10cSrcweir 	}
1207*cdf0e10cSrcweir 	else
1208*cdf0e10cSrcweir 		mhDefBrush = hOldBrush;
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir 	// set new data
1211*cdf0e10cSrcweir 	mnBrushColor = nBrushColor;
1212*cdf0e10cSrcweir 	mhBrush		= hNewBrush;
1213*cdf0e10cSrcweir 	mbBrush		= TRUE;
1214*cdf0e10cSrcweir 	mbStockBrush = bStockBrush;
1215*cdf0e10cSrcweir }
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir // -----------------------------------------------------------------------
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir void WinSalGraphics::SetXORMode( bool bSet, bool )
1220*cdf0e10cSrcweir {
1221*cdf0e10cSrcweir 	mbXORMode = bSet;
1222*cdf0e10cSrcweir 	::SetROP2( mhDC, bSet ? R2_XORPEN : R2_COPYPEN );
1223*cdf0e10cSrcweir }
1224*cdf0e10cSrcweir 
1225*cdf0e10cSrcweir // -----------------------------------------------------------------------
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir void WinSalGraphics::SetROPLineColor( SalROPColor nROPColor )
1228*cdf0e10cSrcweir {
1229*cdf0e10cSrcweir 	SetLineColor( ImplGetROPSalColor( nROPColor ) );
1230*cdf0e10cSrcweir }
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir // -----------------------------------------------------------------------
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir void WinSalGraphics::SetROPFillColor( SalROPColor nROPColor )
1235*cdf0e10cSrcweir {
1236*cdf0e10cSrcweir 	SetFillColor( ImplGetROPSalColor( nROPColor ) );
1237*cdf0e10cSrcweir }
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir // -----------------------------------------------------------------------
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir void WinSalGraphics::drawPixel( long nX, long nY )
1242*cdf0e10cSrcweir {
1243*cdf0e10cSrcweir 	if ( mbXORMode )
1244*cdf0e10cSrcweir 	{
1245*cdf0e10cSrcweir 		HBRUSH	hBrush = CreateSolidBrush( mnPenColor );
1246*cdf0e10cSrcweir 		HBRUSH	hOldBrush = SelectBrush( mhDC, hBrush );
1247*cdf0e10cSrcweir 		PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
1248*cdf0e10cSrcweir 		SelectBrush( mhDC, hOldBrush );
1249*cdf0e10cSrcweir 		DeleteBrush( hBrush );
1250*cdf0e10cSrcweir 	}
1251*cdf0e10cSrcweir 	else
1252*cdf0e10cSrcweir 		SetPixel( mhDC, (int)nX, (int)nY, mnPenColor );
1253*cdf0e10cSrcweir }
1254*cdf0e10cSrcweir 
1255*cdf0e10cSrcweir // -----------------------------------------------------------------------
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir void WinSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
1258*cdf0e10cSrcweir {
1259*cdf0e10cSrcweir 	COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
1260*cdf0e10cSrcweir 								SALCOLOR_GREEN( nSalColor ),
1261*cdf0e10cSrcweir 								SALCOLOR_BLUE( nSalColor ) );
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir 	if ( !mbPrinter &&
1264*cdf0e10cSrcweir 		 GetSalData()->mhDitherPal &&
1265*cdf0e10cSrcweir 		 ImplIsSysColorEntry( nSalColor ) )
1266*cdf0e10cSrcweir 		nCol = PALRGB_TO_RGB( nCol );
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir 	if ( mbXORMode )
1269*cdf0e10cSrcweir 	{
1270*cdf0e10cSrcweir 		HBRUSH	hBrush = CreateSolidBrush( nCol );
1271*cdf0e10cSrcweir 		HBRUSH	hOldBrush = SelectBrush( mhDC, hBrush );
1272*cdf0e10cSrcweir 		PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
1273*cdf0e10cSrcweir 		SelectBrush( mhDC, hOldBrush );
1274*cdf0e10cSrcweir 		DeleteBrush( hBrush );
1275*cdf0e10cSrcweir 	}
1276*cdf0e10cSrcweir 	else
1277*cdf0e10cSrcweir 		::SetPixel( mhDC, (int)nX, (int)nY, nCol );
1278*cdf0e10cSrcweir }
1279*cdf0e10cSrcweir 
1280*cdf0e10cSrcweir // -----------------------------------------------------------------------
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
1283*cdf0e10cSrcweir {
1284*cdf0e10cSrcweir 	MoveToEx( mhDC, (int)nX1, (int)nY1, NULL );
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir 	// we must paint the endpoint
1287*cdf0e10cSrcweir 	int bPaintEnd = TRUE;
1288*cdf0e10cSrcweir 	if ( nX1 == nX2 )
1289*cdf0e10cSrcweir 	{
1290*cdf0e10cSrcweir 		bPaintEnd = FALSE;
1291*cdf0e10cSrcweir 		if ( nY1 <= nY2 )
1292*cdf0e10cSrcweir 			nY2++;
1293*cdf0e10cSrcweir 		else
1294*cdf0e10cSrcweir 			nY2--;
1295*cdf0e10cSrcweir 	}
1296*cdf0e10cSrcweir 	if ( nY1 == nY2 )
1297*cdf0e10cSrcweir 	{
1298*cdf0e10cSrcweir 		bPaintEnd = FALSE;
1299*cdf0e10cSrcweir 		if ( nX1 <= nX2 )
1300*cdf0e10cSrcweir 			nX2++;
1301*cdf0e10cSrcweir 		else
1302*cdf0e10cSrcweir 			nX2--;
1303*cdf0e10cSrcweir 	}
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir 	LineTo( mhDC, (int)nX2, (int)nY2 );
1306*cdf0e10cSrcweir 
1307*cdf0e10cSrcweir 	if ( bPaintEnd && !mbPrinter )
1308*cdf0e10cSrcweir 	{
1309*cdf0e10cSrcweir 		if ( mbXORMode )
1310*cdf0e10cSrcweir 		{
1311*cdf0e10cSrcweir 			HBRUSH	hBrush = CreateSolidBrush( mnPenColor );
1312*cdf0e10cSrcweir 			HBRUSH	hOldBrush = SelectBrush( mhDC, hBrush );
1313*cdf0e10cSrcweir 			PatBlt( mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
1314*cdf0e10cSrcweir 			SelectBrush( mhDC, hOldBrush );
1315*cdf0e10cSrcweir 			DeleteBrush( hBrush );
1316*cdf0e10cSrcweir 		}
1317*cdf0e10cSrcweir 		else
1318*cdf0e10cSrcweir 			SetPixel( mhDC, (int)nX2, (int)nY2, mnPenColor );
1319*cdf0e10cSrcweir 	}
1320*cdf0e10cSrcweir }
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir // -----------------------------------------------------------------------
1323*cdf0e10cSrcweir 
1324*cdf0e10cSrcweir void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
1325*cdf0e10cSrcweir {
1326*cdf0e10cSrcweir 	if ( !mbPen )
1327*cdf0e10cSrcweir 	{
1328*cdf0e10cSrcweir 		if ( !mbPrinter )
1329*cdf0e10cSrcweir 		{
1330*cdf0e10cSrcweir 			PatBlt( mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight,
1331*cdf0e10cSrcweir 					mbXORMode ? PATINVERT : PATCOPY );
1332*cdf0e10cSrcweir 		}
1333*cdf0e10cSrcweir 		else
1334*cdf0e10cSrcweir 		{
1335*cdf0e10cSrcweir 			RECT aWinRect;
1336*cdf0e10cSrcweir 			aWinRect.left	= nX;
1337*cdf0e10cSrcweir 			aWinRect.top	= nY;
1338*cdf0e10cSrcweir 			aWinRect.right	= nX+nWidth;
1339*cdf0e10cSrcweir 			aWinRect.bottom = nY+nHeight;
1340*cdf0e10cSrcweir 			::FillRect( mhDC, &aWinRect, mhBrush );
1341*cdf0e10cSrcweir 		}
1342*cdf0e10cSrcweir 	}
1343*cdf0e10cSrcweir 	else
1344*cdf0e10cSrcweir 		WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
1345*cdf0e10cSrcweir }
1346*cdf0e10cSrcweir 
1347*cdf0e10cSrcweir // -----------------------------------------------------------------------
1348*cdf0e10cSrcweir 
1349*cdf0e10cSrcweir void WinSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry )
1350*cdf0e10cSrcweir {
1351*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1352*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1353*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolyLine(): POINT != SalPoint" );
1354*cdf0e10cSrcweir 
1355*cdf0e10cSrcweir 	POINT* pWinPtAry = (POINT*)pPtAry;
1356*cdf0e10cSrcweir 	// Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
1357*cdf0e10cSrcweir 	// von Punkten
1358*cdf0e10cSrcweir 	if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
1359*cdf0e10cSrcweir 		Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS );
1360*cdf0e10cSrcweir }
1361*cdf0e10cSrcweir 
1362*cdf0e10cSrcweir // -----------------------------------------------------------------------
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir void WinSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
1365*cdf0e10cSrcweir {
1366*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1367*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1368*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolygon(): POINT != SalPoint" );
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir 	POINT* pWinPtAry = (POINT*)pPtAry;
1371*cdf0e10cSrcweir 	// Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
1372*cdf0e10cSrcweir 	// von Punkten
1373*cdf0e10cSrcweir 	if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
1374*cdf0e10cSrcweir 		WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS );
1375*cdf0e10cSrcweir }
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir // -----------------------------------------------------------------------
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints,
1380*cdf0e10cSrcweir 								   PCONSTSALPOINT* pPtAry )
1381*cdf0e10cSrcweir {
1382*cdf0e10cSrcweir 	UINT	aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
1383*cdf0e10cSrcweir 	UINT*	pWinPointAry;
1384*cdf0e10cSrcweir 	UINT	nPolyPolyPoints = 0;
1385*cdf0e10cSrcweir 	UINT	nPoints;
1386*cdf0e10cSrcweir 	UINT	i;
1387*cdf0e10cSrcweir 
1388*cdf0e10cSrcweir 	if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
1389*cdf0e10cSrcweir 		pWinPointAry = aWinPointAry;
1390*cdf0e10cSrcweir 	else
1391*cdf0e10cSrcweir 		pWinPointAry = new UINT[nPoly];
1392*cdf0e10cSrcweir 
1393*cdf0e10cSrcweir 	for ( i = 0; i < (UINT)nPoly; i++ )
1394*cdf0e10cSrcweir 	{
1395*cdf0e10cSrcweir 		nPoints = (UINT)pPoints[i]+1;
1396*cdf0e10cSrcweir 		pWinPointAry[i] = nPoints;
1397*cdf0e10cSrcweir 		nPolyPolyPoints += nPoints;
1398*cdf0e10cSrcweir 	}
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir 	POINT  aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
1401*cdf0e10cSrcweir 	POINT* pWinPointAryAry;
1402*cdf0e10cSrcweir 	if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
1403*cdf0e10cSrcweir 		pWinPointAryAry = aWinPointAryAry;
1404*cdf0e10cSrcweir 	else
1405*cdf0e10cSrcweir 		pWinPointAryAry = new POINT[nPolyPolyPoints];
1406*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1407*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1408*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
1409*cdf0e10cSrcweir 	const SalPoint* pPolyAry;
1410*cdf0e10cSrcweir 	UINT			n = 0;
1411*cdf0e10cSrcweir 	for ( i = 0; i < (UINT)nPoly; i++ )
1412*cdf0e10cSrcweir 	{
1413*cdf0e10cSrcweir 		nPoints = pWinPointAry[i];
1414*cdf0e10cSrcweir 		pPolyAry = pPtAry[i];
1415*cdf0e10cSrcweir 		memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
1416*cdf0e10cSrcweir 		pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
1417*cdf0e10cSrcweir 		n += nPoints;
1418*cdf0e10cSrcweir 	}
1419*cdf0e10cSrcweir 
1420*cdf0e10cSrcweir 	if ( !WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
1421*cdf0e10cSrcweir 		 (nPolyPolyPoints > MAX_64KSALPOINTS) )
1422*cdf0e10cSrcweir 	{
1423*cdf0e10cSrcweir 		nPolyPolyPoints  = 0;
1424*cdf0e10cSrcweir 		nPoly = 0;
1425*cdf0e10cSrcweir 		do
1426*cdf0e10cSrcweir 		{
1427*cdf0e10cSrcweir 			nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
1428*cdf0e10cSrcweir 			nPoly++;
1429*cdf0e10cSrcweir 		}
1430*cdf0e10cSrcweir 		while ( nPolyPolyPoints < MAX_64KSALPOINTS );
1431*cdf0e10cSrcweir 		nPoly--;
1432*cdf0e10cSrcweir 		if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
1433*cdf0e10cSrcweir 			pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
1434*cdf0e10cSrcweir 		if ( nPoly == 1 )
1435*cdf0e10cSrcweir 			WIN_Polygon( mhDC, pWinPointAryAry, *pWinPointAry );
1436*cdf0e10cSrcweir 		else
1437*cdf0e10cSrcweir 			WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly );
1438*cdf0e10cSrcweir 	}
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir 	if ( pWinPointAry != aWinPointAry )
1441*cdf0e10cSrcweir 		delete [] pWinPointAry;
1442*cdf0e10cSrcweir 	if ( pWinPointAryAry != aWinPointAryAry )
1443*cdf0e10cSrcweir 		delete [] pWinPointAryAry;
1444*cdf0e10cSrcweir }
1445*cdf0e10cSrcweir 
1446*cdf0e10cSrcweir // -----------------------------------------------------------------------
1447*cdf0e10cSrcweir 
1448*cdf0e10cSrcweir #define SAL_POLY_STACKBUF		32
1449*cdf0e10cSrcweir 
1450*cdf0e10cSrcweir // -----------------------------------------------------------------------
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir sal_Bool WinSalGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
1453*cdf0e10cSrcweir {
1454*cdf0e10cSrcweir #ifdef USE_GDI_BEZIERS
1455*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1456*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1457*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolyLineBezier(): POINT != SalPoint" );
1458*cdf0e10cSrcweir 
1459*cdf0e10cSrcweir     ImplRenderPath( mhDC, nPoints, pPtAry, pFlgAry );
1460*cdf0e10cSrcweir 
1461*cdf0e10cSrcweir     return sal_True;
1462*cdf0e10cSrcweir #else
1463*cdf0e10cSrcweir     return sal_False;
1464*cdf0e10cSrcweir #endif
1465*cdf0e10cSrcweir }
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir // -----------------------------------------------------------------------
1468*cdf0e10cSrcweir 
1469*cdf0e10cSrcweir sal_Bool WinSalGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
1470*cdf0e10cSrcweir {
1471*cdf0e10cSrcweir #ifdef USE_GDI_BEZIERS
1472*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1473*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1474*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolygonBezier(): POINT != SalPoint" );
1475*cdf0e10cSrcweir 
1476*cdf0e10cSrcweir     POINT	aStackAry1[SAL_POLY_STACKBUF];
1477*cdf0e10cSrcweir     BYTE	aStackAry2[SAL_POLY_STACKBUF];
1478*cdf0e10cSrcweir     POINT* 	pWinPointAry;
1479*cdf0e10cSrcweir     BYTE* 	pWinFlagAry;
1480*cdf0e10cSrcweir     if( nPoints > SAL_POLY_STACKBUF )
1481*cdf0e10cSrcweir     {
1482*cdf0e10cSrcweir         pWinPointAry = new POINT[ nPoints ];
1483*cdf0e10cSrcweir         pWinFlagAry = new BYTE[ nPoints ];
1484*cdf0e10cSrcweir     }
1485*cdf0e10cSrcweir     else
1486*cdf0e10cSrcweir     {
1487*cdf0e10cSrcweir         pWinPointAry = aStackAry1;
1488*cdf0e10cSrcweir         pWinFlagAry = aStackAry2;
1489*cdf0e10cSrcweir     }
1490*cdf0e10cSrcweir 
1491*cdf0e10cSrcweir     ImplPreparePolyDraw(true, 1, &nPoints, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry);
1492*cdf0e10cSrcweir 
1493*cdf0e10cSrcweir     sal_Bool bRet( sal_False );
1494*cdf0e10cSrcweir 
1495*cdf0e10cSrcweir     if( BeginPath( mhDC ) )
1496*cdf0e10cSrcweir     {
1497*cdf0e10cSrcweir         PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nPoints);
1498*cdf0e10cSrcweir 
1499*cdf0e10cSrcweir         if( EndPath( mhDC ) )
1500*cdf0e10cSrcweir         {
1501*cdf0e10cSrcweir             if( StrokeAndFillPath( mhDC ) )
1502*cdf0e10cSrcweir                 bRet = sal_True;
1503*cdf0e10cSrcweir         }
1504*cdf0e10cSrcweir     }
1505*cdf0e10cSrcweir 
1506*cdf0e10cSrcweir     if( pWinPointAry != aStackAry1 )
1507*cdf0e10cSrcweir     {
1508*cdf0e10cSrcweir         delete [] pWinPointAry;
1509*cdf0e10cSrcweir         delete [] pWinFlagAry;
1510*cdf0e10cSrcweir     }
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir     return bRet;
1513*cdf0e10cSrcweir #else
1514*cdf0e10cSrcweir     return sal_False;
1515*cdf0e10cSrcweir #endif
1516*cdf0e10cSrcweir }
1517*cdf0e10cSrcweir 
1518*cdf0e10cSrcweir // -----------------------------------------------------------------------
1519*cdf0e10cSrcweir 
1520*cdf0e10cSrcweir sal_Bool WinSalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints,
1521*cdf0e10cSrcweir                                              const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
1522*cdf0e10cSrcweir {
1523*cdf0e10cSrcweir #ifdef USE_GDI_BEZIERS
1524*cdf0e10cSrcweir 	// Unter NT koennen wir das Array direkt weiterreichen
1525*cdf0e10cSrcweir 	DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
1526*cdf0e10cSrcweir 				"WinSalGraphics::DrawPolyPolygonBezier(): POINT != SalPoint" );
1527*cdf0e10cSrcweir 
1528*cdf0e10cSrcweir     sal_uLong nCurrPoly, nTotalPoints;
1529*cdf0e10cSrcweir     const sal_uLong* pCurrPoints = pPoints;
1530*cdf0e10cSrcweir     for( nCurrPoly=0, nTotalPoints=0; nCurrPoly<nPoly; ++nCurrPoly )
1531*cdf0e10cSrcweir         nTotalPoints += *pCurrPoints++;
1532*cdf0e10cSrcweir 
1533*cdf0e10cSrcweir     POINT	aStackAry1[SAL_POLY_STACKBUF];
1534*cdf0e10cSrcweir     BYTE	aStackAry2[SAL_POLY_STACKBUF];
1535*cdf0e10cSrcweir     POINT* 	pWinPointAry;
1536*cdf0e10cSrcweir     BYTE* 	pWinFlagAry;
1537*cdf0e10cSrcweir     if( nTotalPoints > SAL_POLY_STACKBUF )
1538*cdf0e10cSrcweir     {
1539*cdf0e10cSrcweir         pWinPointAry = new POINT[ nTotalPoints ];
1540*cdf0e10cSrcweir         pWinFlagAry = new BYTE[ nTotalPoints ];
1541*cdf0e10cSrcweir     }
1542*cdf0e10cSrcweir     else
1543*cdf0e10cSrcweir     {
1544*cdf0e10cSrcweir         pWinPointAry = aStackAry1;
1545*cdf0e10cSrcweir         pWinFlagAry = aStackAry2;
1546*cdf0e10cSrcweir     }
1547*cdf0e10cSrcweir 
1548*cdf0e10cSrcweir     ImplPreparePolyDraw(true, nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry);
1549*cdf0e10cSrcweir 
1550*cdf0e10cSrcweir     sal_Bool bRet( sal_False );
1551*cdf0e10cSrcweir 
1552*cdf0e10cSrcweir     if( BeginPath( mhDC ) )
1553*cdf0e10cSrcweir     {
1554*cdf0e10cSrcweir         PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nTotalPoints);
1555*cdf0e10cSrcweir 
1556*cdf0e10cSrcweir         if( EndPath( mhDC ) )
1557*cdf0e10cSrcweir         {
1558*cdf0e10cSrcweir             if( StrokeAndFillPath( mhDC ) )
1559*cdf0e10cSrcweir                 bRet = sal_True;
1560*cdf0e10cSrcweir         }
1561*cdf0e10cSrcweir     }
1562*cdf0e10cSrcweir 
1563*cdf0e10cSrcweir     if( pWinPointAry != aStackAry1 )
1564*cdf0e10cSrcweir     {
1565*cdf0e10cSrcweir         delete [] pWinPointAry;
1566*cdf0e10cSrcweir         delete [] pWinFlagAry;
1567*cdf0e10cSrcweir     }
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir     return bRet;
1570*cdf0e10cSrcweir #else
1571*cdf0e10cSrcweir     return sal_False;
1572*cdf0e10cSrcweir #endif
1573*cdf0e10cSrcweir }
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir // -----------------------------------------------------------------------
1576*cdf0e10cSrcweir 
1577*cdf0e10cSrcweir #define POSTSCRIPT_BUFSIZE 0x4000			// MAXIMUM BUFSIZE EQ 0xFFFF
1578*cdf0e10cSrcweir #define POSTSCRIPT_BOUNDINGSEARCH 0x1000	// we only try to get the BoundingBox
1579*cdf0e10cSrcweir 											// in the first 4096 bytes
1580*cdf0e10cSrcweir 
1581*cdf0e10cSrcweir static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, sal_uLong nComp, sal_uLong nSize )
1582*cdf0e10cSrcweir {
1583*cdf0e10cSrcweir 	while ( nComp-- >= nSize )
1584*cdf0e10cSrcweir 	{
1585*cdf0e10cSrcweir 		sal_uLong i;
1586*cdf0e10cSrcweir 		for ( i = 0; i < nSize; i++ )
1587*cdf0e10cSrcweir 		{
1588*cdf0e10cSrcweir 			if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
1589*cdf0e10cSrcweir 				break;
1590*cdf0e10cSrcweir 		}
1591*cdf0e10cSrcweir 		if ( i == nSize )
1592*cdf0e10cSrcweir 			return pSource;
1593*cdf0e10cSrcweir 		pSource++;
1594*cdf0e10cSrcweir 	}
1595*cdf0e10cSrcweir 	return NULL;
1596*cdf0e10cSrcweir }
1597*cdf0e10cSrcweir 
1598*cdf0e10cSrcweir static sal_Bool ImplGetBoundingBox( double* nNumb, BYTE* pSource, sal_uLong nSize )
1599*cdf0e10cSrcweir {
1600*cdf0e10cSrcweir 	sal_Bool	bRetValue = FALSE;
1601*cdf0e10cSrcweir 	BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nSize, 14 );
1602*cdf0e10cSrcweir 	if ( pDest )
1603*cdf0e10cSrcweir 	{
1604*cdf0e10cSrcweir 		nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
1605*cdf0e10cSrcweir 		pDest += 14;
1606*cdf0e10cSrcweir 
1607*cdf0e10cSrcweir 		int nSizeLeft = nSize - ( pDest - pSource );
1608*cdf0e10cSrcweir 		if ( nSizeLeft > 100 )
1609*cdf0e10cSrcweir 			nSizeLeft = 100;	// only 100 bytes following the bounding box will be checked
1610*cdf0e10cSrcweir 
1611*cdf0e10cSrcweir 		int i;
1612*cdf0e10cSrcweir 		for ( i = 0; ( i < 4 ) && nSizeLeft; i++ )
1613*cdf0e10cSrcweir 		{
1614*cdf0e10cSrcweir 			int 	nDivision = 1;
1615*cdf0e10cSrcweir 			sal_Bool	bDivision = FALSE;
1616*cdf0e10cSrcweir 			sal_Bool	bNegative = FALSE;
1617*cdf0e10cSrcweir 			sal_Bool	bValid = TRUE;
1618*cdf0e10cSrcweir 
1619*cdf0e10cSrcweir 			while ( ( --nSizeLeft ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
1620*cdf0e10cSrcweir 			BYTE nByte = *pDest;
1621*cdf0e10cSrcweir 			while ( nSizeLeft && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
1622*cdf0e10cSrcweir 			{
1623*cdf0e10cSrcweir 				switch ( nByte )
1624*cdf0e10cSrcweir 				{
1625*cdf0e10cSrcweir 					case '.' :
1626*cdf0e10cSrcweir 						if ( bDivision )
1627*cdf0e10cSrcweir 							bValid = FALSE;
1628*cdf0e10cSrcweir 						else
1629*cdf0e10cSrcweir 							bDivision = TRUE;
1630*cdf0e10cSrcweir 						break;
1631*cdf0e10cSrcweir 					case '-' :
1632*cdf0e10cSrcweir 						bNegative = TRUE;
1633*cdf0e10cSrcweir 						break;
1634*cdf0e10cSrcweir 					default :
1635*cdf0e10cSrcweir 						if ( ( nByte < '0' ) || ( nByte > '9' ) )
1636*cdf0e10cSrcweir 							nSizeLeft = 1; 	// error parsing the bounding box values
1637*cdf0e10cSrcweir 						else if ( bValid )
1638*cdf0e10cSrcweir 						{
1639*cdf0e10cSrcweir 							if ( bDivision )
1640*cdf0e10cSrcweir 								nDivision*=10;
1641*cdf0e10cSrcweir 							nNumb[i] *= 10;
1642*cdf0e10cSrcweir 							nNumb[i] += nByte - '0';
1643*cdf0e10cSrcweir 						}
1644*cdf0e10cSrcweir 						break;
1645*cdf0e10cSrcweir 				}
1646*cdf0e10cSrcweir 				nSizeLeft--;
1647*cdf0e10cSrcweir 				nByte = *(++pDest);
1648*cdf0e10cSrcweir 			}
1649*cdf0e10cSrcweir 			if ( bNegative )
1650*cdf0e10cSrcweir 				nNumb[i] = -nNumb[i];
1651*cdf0e10cSrcweir 			if ( bDivision && ( nDivision != 1 ) )
1652*cdf0e10cSrcweir 				nNumb[i] /= nDivision;
1653*cdf0e10cSrcweir 		}
1654*cdf0e10cSrcweir 		if ( i == 4 )
1655*cdf0e10cSrcweir 			bRetValue = TRUE;
1656*cdf0e10cSrcweir 	}
1657*cdf0e10cSrcweir 	return bRetValue;
1658*cdf0e10cSrcweir }
1659*cdf0e10cSrcweir 
1660*cdf0e10cSrcweir sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
1661*cdf0e10cSrcweir {
1662*cdf0e10cSrcweir 	sal_Bool bRetValue = FALSE;
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir 	if ( mbPrinter )
1665*cdf0e10cSrcweir 	{
1666*cdf0e10cSrcweir 		int nEscape = POSTSCRIPT_PASSTHROUGH;
1667*cdf0e10cSrcweir 
1668*cdf0e10cSrcweir 		if ( Escape( mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) )
1669*cdf0e10cSrcweir 		{
1670*cdf0e10cSrcweir 			double	nBoundingBox[4];
1671*cdf0e10cSrcweir 
1672*cdf0e10cSrcweir 			if ( ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
1673*cdf0e10cSrcweir 			{
1674*cdf0e10cSrcweir                 OStringBuffer aBuf( POSTSCRIPT_BUFSIZE );
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir                 // reserve place for a sal_uInt16
1677*cdf0e10cSrcweir                 aBuf.append( "aa" );
1678*cdf0e10cSrcweir 
1679*cdf0e10cSrcweir                 // #107797# Write out EPS encapsulation header
1680*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir                 // directly taken from the PLRM 3.0, p. 726. Note:
1683*cdf0e10cSrcweir                 // this will definitely cause problems when
1684*cdf0e10cSrcweir                 // recursively creating and embedding PostScript files
1685*cdf0e10cSrcweir                 // in OOo, since we use statically-named variables
1686*cdf0e10cSrcweir                 // here (namely, b4_Inc_state_salWin, dict_count_salWin and
1687*cdf0e10cSrcweir                 // op_count_salWin). Currently, I have no idea on how to
1688*cdf0e10cSrcweir                 // work around that, except from scanning and
1689*cdf0e10cSrcweir                 // interpreting the EPS for unused identifiers.
1690*cdf0e10cSrcweir 
1691*cdf0e10cSrcweir                 // append the real text
1692*cdf0e10cSrcweir                 aBuf.append( "\n\n/b4_Inc_state_salWin save def\n"
1693*cdf0e10cSrcweir                              "/dict_count_salWin countdictstack def\n"
1694*cdf0e10cSrcweir                              "/op_count_salWin count 1 sub def\n"
1695*cdf0e10cSrcweir                              "userdict begin\n"
1696*cdf0e10cSrcweir                              "/showpage {} def\n"
1697*cdf0e10cSrcweir                              "0 setgray 0 setlinecap\n"
1698*cdf0e10cSrcweir                              "1 setlinewidth 0 setlinejoin\n"
1699*cdf0e10cSrcweir                              "10 setmiterlimit [] 0 setdash newpath\n"
1700*cdf0e10cSrcweir                              "/languagelevel where\n"
1701*cdf0e10cSrcweir                              "{\n"
1702*cdf0e10cSrcweir                              "  pop languagelevel\n"
1703*cdf0e10cSrcweir                              "  1 ne\n"
1704*cdf0e10cSrcweir                              "  {\n"
1705*cdf0e10cSrcweir                              "    false setstrokeadjust false setoverprint\n"
1706*cdf0e10cSrcweir                              "  } if\n"
1707*cdf0e10cSrcweir                              "} if\n\n" );
1708*cdf0e10cSrcweir 
1709*cdf0e10cSrcweir 
1710*cdf0e10cSrcweir                 // #i10737# Apply clipping manually
1711*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1712*cdf0e10cSrcweir 
1713*cdf0e10cSrcweir                 // Windows seems to ignore any clipping at the HDC,
1714*cdf0e10cSrcweir                 // when followed by a POSTSCRIPT_PASSTHROUGH
1715*cdf0e10cSrcweir 
1716*cdf0e10cSrcweir                 // Check whether we've got a clipping, consisting of
1717*cdf0e10cSrcweir                 // exactly one rect (other cases should be, but aren't
1718*cdf0e10cSrcweir                 // handled currently)
1719*cdf0e10cSrcweir 
1720*cdf0e10cSrcweir                 // TODO: Handle more than one rectangle here (take
1721*cdf0e10cSrcweir                 // care, the buffer can handle only POSTSCRIPT_BUFSIZE
1722*cdf0e10cSrcweir                 // characters!)
1723*cdf0e10cSrcweir                 if ( mhRegion != 0 &&
1724*cdf0e10cSrcweir                      mpStdClipRgnData != NULL &&
1725*cdf0e10cSrcweir                      mpClipRgnData == mpStdClipRgnData &&
1726*cdf0e10cSrcweir                      mpClipRgnData->rdh.nCount == 1 )
1727*cdf0e10cSrcweir                 {
1728*cdf0e10cSrcweir                     RECT* pRect = &(mpClipRgnData->rdh.rcBound);
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir                     aBuf.append( "\nnewpath\n" );
1731*cdf0e10cSrcweir                     aBuf.append( pRect->left );
1732*cdf0e10cSrcweir                     aBuf.append( " " );
1733*cdf0e10cSrcweir                     aBuf.append( pRect->top );
1734*cdf0e10cSrcweir                     aBuf.append( " moveto\n" );
1735*cdf0e10cSrcweir                     aBuf.append( pRect->right );
1736*cdf0e10cSrcweir                     aBuf.append( " " );
1737*cdf0e10cSrcweir                     aBuf.append( pRect->top );
1738*cdf0e10cSrcweir                     aBuf.append( " lineto\n" );
1739*cdf0e10cSrcweir                     aBuf.append( pRect->right );
1740*cdf0e10cSrcweir                     aBuf.append( " " );
1741*cdf0e10cSrcweir                     aBuf.append( pRect->bottom );
1742*cdf0e10cSrcweir                     aBuf.append( " lineto\n" );
1743*cdf0e10cSrcweir                     aBuf.append( pRect->left );
1744*cdf0e10cSrcweir                     aBuf.append( " " );
1745*cdf0e10cSrcweir                     aBuf.append( pRect->bottom );
1746*cdf0e10cSrcweir                     aBuf.append( " lineto\n"
1747*cdf0e10cSrcweir                                  "closepath\n"
1748*cdf0e10cSrcweir                                  "clip\n"
1749*cdf0e10cSrcweir                                  "newpath\n" );
1750*cdf0e10cSrcweir                 }
1751*cdf0e10cSrcweir 
1752*cdf0e10cSrcweir                 // #107797# Write out buffer
1753*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1754*cdf0e10cSrcweir 				*((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 );
1755*cdf0e10cSrcweir 				Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
1756*cdf0e10cSrcweir 
1757*cdf0e10cSrcweir 
1758*cdf0e10cSrcweir                 // #107797# Write out EPS transformation code
1759*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1760*cdf0e10cSrcweir 				double	dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
1761*cdf0e10cSrcweir 				double	dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] );
1762*cdf0e10cSrcweir                 // reserve a sal_uInt16 again
1763*cdf0e10cSrcweir                 aBuf.setLength( 2 );
1764*cdf0e10cSrcweir                 aBuf.append( "\n\n[" );
1765*cdf0e10cSrcweir                 aBuf.append( dM11 );
1766*cdf0e10cSrcweir                 aBuf.append( " 0 0 " );
1767*cdf0e10cSrcweir                 aBuf.append( dM22 );
1768*cdf0e10cSrcweir                 aBuf.append( ' ' );
1769*cdf0e10cSrcweir                 aBuf.append( nX - ( dM11 * nBoundingBox[0] ) );
1770*cdf0e10cSrcweir                 aBuf.append( ' ' );
1771*cdf0e10cSrcweir                 aBuf.append( nY - ( dM22 * nBoundingBox[3] ) );
1772*cdf0e10cSrcweir                 aBuf.append( "] concat\n"
1773*cdf0e10cSrcweir                              "%%BeginDocument:\n" );
1774*cdf0e10cSrcweir 				*((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 );
1775*cdf0e10cSrcweir 				Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
1776*cdf0e10cSrcweir 
1777*cdf0e10cSrcweir 
1778*cdf0e10cSrcweir                 // #107797# Write out actual EPS content
1779*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1780*cdf0e10cSrcweir 				sal_uLong	nToDo = nSize;
1781*cdf0e10cSrcweir 				sal_uLong	nDoNow;
1782*cdf0e10cSrcweir 				while ( nToDo )
1783*cdf0e10cSrcweir 				{
1784*cdf0e10cSrcweir 					nDoNow = nToDo;
1785*cdf0e10cSrcweir 					if ( nToDo > POSTSCRIPT_BUFSIZE - 2 )
1786*cdf0e10cSrcweir 						nDoNow = POSTSCRIPT_BUFSIZE - 2;
1787*cdf0e10cSrcweir                     // the following is based on the string buffer allocation
1788*cdf0e10cSrcweir                     // of size POSTSCRIPT_BUFSIZE at construction time of aBuf
1789*cdf0e10cSrcweir 					*((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)nDoNow;
1790*cdf0e10cSrcweir 					memcpy( (void*)(aBuf.getStr() + 2), (BYTE*)pPtr + nSize - nToDo, nDoNow );
1791*cdf0e10cSrcweir 					sal_uLong nResult = Escape ( mhDC, nEscape, nDoNow + 2, (LPTSTR)aBuf.getStr(), 0 );
1792*cdf0e10cSrcweir 					if (!nResult )
1793*cdf0e10cSrcweir 						break;
1794*cdf0e10cSrcweir 					nToDo -= nResult;
1795*cdf0e10cSrcweir 				}
1796*cdf0e10cSrcweir 
1797*cdf0e10cSrcweir 
1798*cdf0e10cSrcweir                 // #107797# Write out EPS encapsulation footer
1799*cdf0e10cSrcweir                 // ----------------------------------------------------------------------------------
1800*cdf0e10cSrcweir                 // reserve a sal_uInt16 again
1801*cdf0e10cSrcweir                 aBuf.setLength( 2 );
1802*cdf0e10cSrcweir                 aBuf.append( "%%EndDocument\n"
1803*cdf0e10cSrcweir                              "count op_count_salWin sub {pop} repeat\n"
1804*cdf0e10cSrcweir                              "countdictstack dict_count_salWin sub {end} repeat\n"
1805*cdf0e10cSrcweir                              "b4_Inc_state_salWin restore\n\n" );
1806*cdf0e10cSrcweir 				*((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 );
1807*cdf0e10cSrcweir 				Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
1808*cdf0e10cSrcweir 				bRetValue = TRUE;
1809*cdf0e10cSrcweir 			}
1810*cdf0e10cSrcweir 		}
1811*cdf0e10cSrcweir 	}
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir 	return bRetValue;
1814*cdf0e10cSrcweir }
1815*cdf0e10cSrcweir 
1816*cdf0e10cSrcweir // -----------------------------------------------------------------------
1817*cdf0e10cSrcweir 
1818*cdf0e10cSrcweir SystemGraphicsData WinSalGraphics::GetGraphicsData() const
1819*cdf0e10cSrcweir {
1820*cdf0e10cSrcweir     SystemGraphicsData aRes;
1821*cdf0e10cSrcweir     aRes.nSize = sizeof(aRes);
1822*cdf0e10cSrcweir     aRes.hDC = mhDC;
1823*cdf0e10cSrcweir     return aRes;
1824*cdf0e10cSrcweir }
1825*cdf0e10cSrcweir 
1826*cdf0e10cSrcweir // -----------------------------------------------------------------------
1827