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