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