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