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