44cfc7cb65
linecap: Reintegrating finished LineCap feature Patch contributed by Regina Henschel http://svn.apache.org/viewvc?view=revision&revision=1232507 Patches contributed by Sven Jacobi impress212: #i81610# fixed animation export http://svn.apache.org/viewvc?view=revision&revision=1167620 impress212: drawinglayer gbuild environment changes http://svn.apache.org/viewvc?view=revision&revision=1167627 http://svn.apache.org/viewvc?view=revision&revision=1167628 impress212: DffPropSet -> minor code improvements, removing table http://svn.apache.org/viewvc?view=revision&revision=1167634 impress212: #158494# fixed excel import (text rotation) http://svn.apache.org/viewvc?view=revision&revision=1167638 Patches contributed by Armin Le Grand Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement http://svn.apache.org/viewvc?view=revision&revision=1220836 #118728# changed indentifying definitions for Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1229961 #118838# LineGeometry creation for complicated cases optimized to create single Polygons http://svn.apache.org/viewvc?view=revision&revision=1236232 #119176# corrected file type detection for SVG for svg files without xml header http://svn.apache.org/viewvc?view=revision&revision=1309445 #118728# Extended Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1230531 #118529# solve break converters and convert commands for OLEs and images http://svn.apache.org/viewvc?view=revision&revision=1186168 svg: added WaE changes from branch svgreplacement to trunc http://svn.apache.org/viewvc?view=revision&revision=1222974 svg: corrected missing member initialization http://svn.apache.org/viewvc?view=revision&revision=1226134 fix for #118525#: Using primitives for chart sub-geometry visualisation http://svn.apache.org/viewvc?view=revision&revision=1226879 #118898# Adapted ImpGraphic::ImplGetBitmap to correctly convert metafiles to bitmapEx ... http://svn.apache.org/viewvc?view=revision&revision=1293316 fix for #118525#: removed no longer used variable maOriginalMapMode, one more exception eliminated http://svn.apache.org/viewvc?view=revision&revision=1227097 #16758# Added buffering to the VDev usages of the VclProcessor2D derivates... http://svn.apache.org/viewvc?view=revision&revision=1229521 #116758# Secured VDev buffer device to Vcl deinit http://svn.apache.org/viewvc?view=revision&revision=1230574 #116758# added remembering allocated VDevs for VDevBuffer to be able to also delete these when vcl goes down; it should never happen, but You never know http://svn.apache.org/viewvc?view=revision&revision=1230927 #118730# Changed SvgClipPathNode to use MaskPrimitive2D for primitive representation instead of TransparencePrimitive2D http://svn.apache.org/viewvc?view=revision&revision=1231198 #118822# secured 3D geometry creation (slices) by subdividing the 2D source polyPolygon early http://svn.apache.org/viewvc?view=revision&revision=1234749 #118829# enhanced Svg gradient quality, obstacles avoided http://svn.apache.org/viewvc?view=revision&revision=1235361 #118834# Unified usage of TextBreakupHelper as single tooling class for i18n text primitive breakup http://svn.apache.org/viewvc?view=revision&revision=1236110 #118853# added square pixel size limit to conversion of TransparencePrimitive2D to Metafile action http://svn.apache.org/viewvc?view=revision&revision=1237656 #118824# coreccted mirroring and boundrect when the graphicmanager is used for bitmap output http://svn.apache.org/viewvc?view=revision&revision=1240097 #115092# Corrected VclProcessor2D::RenderPolygonStrokePrimitive2D for various optimization scenarios http://svn.apache.org/viewvc?view=revision&revision=1241434 #118783# Corrected errors in ID strings, corrected Svg line/fill export, corrected polygon close state http://svn.apache.org/viewvc?view=revision&revision=1232006 #118796# corrected null-pointer usage in SVG text exporter http://svn.apache.org/viewvc?view=revision&revision=1240262 #118729# Use GraphicStreamUrl and GraphicUrl to allow multi image import with linked graphics, too http://svn.apache.org/viewvc?view=revision&revision=1229962 #118898# corrected error in GDIMetaFile::GetBoundRect in handling MetaFloatTransparentAction http://svn.apache.org/viewvc?view=revision&revision=1293349 #118855# Corrected handling of possibly created empty clipRegions after PolyPolygon clipping http://svn.apache.org/viewvc?view=revision&revision=1237725 #115962# Better (but not yet optimal, see comments in task) handling of MetaFloatTransparentAction in PDF export http://svn.apache.org/viewvc?view=revision&revision=1241078 IP clearance: #118466# This patch removes librsvg, libcroco, libgsf, ... http://svn.apache.org/viewvc?view=revision&revision=1200879 118779# Added svg content streaming in/out to ImpGraphic stream operators http://svn.apache.org/viewvc?view=revision&revision=1231908 linecap: correctons for WaE and mac drawing http://svn.apache.org/viewvc?view=revision&revision=1232793 svg: uses current system Dpi for Svg replacement image creation http://svn.apache.org/viewvc?view=revision&revision=1233948 Patches contributed by Mathias Bauer (and others) gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1394326 Remove duplicate header includes. cws mba34issues01: #i117720#: convert assertion into warning http://svn.apache.org/viewvc?view=revision&revision=1172352 118485 - Styles for OLEs are not saved. Submitted by Armin Le Grand. http://svn.apache.org/viewvc?view=revision&revision=1182166 cws mba34issues01: #i117714#: remove assertion http://svn.apache.org/viewvc?view=revision&revision=1172357 Patch contributed by Jurgen Schmidt add some additional checks to ensure proper reading operations http://svn.apache.org/viewvc?view=revision&revision=1209022 mostly prefer our stream / bounds checking work. Patches contributed by Herbert Duerr #i118816# add clarifying comment regarding Font::*Color*() methods http://svn.apache.org/viewvc?view=revision&revision=1233833 extend macro->string handling for empty strings http://svn.apache.org/viewvc?view=revision&revision=1175801 avoid magic constants for SALCOLOR_NONE http://svn.apache.org/viewvc?view=revision&revision=1177543 initialize slant properly in ImplFontMetricData constructor (author=iorsh) http://svn.apache.org/viewvc?view=revision&revision=1177551 #i118675# make check for extension updates more stable http://svn.apache.org/viewvc?view=revision&revision=1214797 #a118617# remove VBasicEventListener.dll binary There are no known users depending on its CLSID http://svn.apache.org/viewvc?view=revision&revision=1203697 Patches contributed by Ariel Constenla-Haile Fix build breaker on Linux/gcc http://svn.apache.org/viewvc?view=revision&revision=1221104 Fix crash when trying to instantiate css.graphic.GraphicRasterizer_RSVG http://svn.apache.org/viewvc?view=revision&revision=1215559 Patches contributed by Oliver-Rainer Wittmann sw34bf06: #i117962# - method <SwFlyFrm::IsPaint(..)> - consider instances of <SwFlyDrawObj> http://svn.apache.org/viewvc?view=revision&revision=1172120 sw34bf06: #i117783# - Writer's implementation of XPagePrintable - apply print settings to new printing routines http://svn.apache.org/viewvc?view=revision&revision=1172115 gnumake4 work variously from Hans-Joachim Lankenau http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1396782 http://svn.apache.org/viewvc?view=revision&revision=1394707 plus some amount of re-splitting of legacy headers. Patch contributed by Pavel Janik WaE: Remove unused variables. http://svn.apache.org/viewvc?view=revision&revision=1230697 Patches contributed by Takashi Ono mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 Patch contributed by Christian Lippka impress212: #i98044# re enable Text menu for outline and title shapes http://svn.apache.org/viewvc?view=revision&revision=1167639 Patch contributed by Andre Fischer 118674: Made category B code optional and disabled by default. http://svn.apache.org/viewvc?view=revision&revision=1215131 118881: Ignore empty paragraphs after bullets. http://svn.apache.org/viewvc?view=revision&revision=1296205 Patches contributed by Philipp Lohmann ooo340fixes: #i117780# use rtl allocator http://svn.apache.org/viewvc?view=revision&revision=1172087 ooo34gsl02: #i117807# fix an off by one error (index actually inside the pfb section header) http://svn.apache.org/viewvc?view=revision&revision=1167576 various cleanups, related compilation fixes, warning cleanups, re-working of obsolete stl template pieces to use boost instead, changed string classes, re-adapt KDE about data, about dialog, fixing warnings, and other fixes & improvements. Disable svg import / render for about/ branding code-paths for now. Restore full icon theme set. Remove OS/2 conditionals and sources. Remove conflicting gtk/full-screen monitors support. Retain existing svg rasterizer files - temporarily disabled. Standardize stringificaiton and fixup dllpostfix issues. Rename SvgGradientHelper::== to equalTo to avoid overloading issues. Use the flat GdiPlus API for LineCaps calls.
833 lines
30 KiB
C++
833 lines
30 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <svsys.h>
|
|
#include <tools/debug.hxx>
|
|
|
|
#include <win/wincomp.hxx>
|
|
#include <win/salbmp.h>
|
|
#include <win/saldata.hxx>
|
|
#include <win/salids.hrc>
|
|
#include <win/salgdi.h>
|
|
#include <win/salframe.h>
|
|
|
|
#include "vcl/salbtype.hxx"
|
|
#include "vcl/bmpacc.hxx"
|
|
#include "outdata.hxx"
|
|
|
|
bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const
|
|
{
|
|
static bool bAllowForTest(true);
|
|
bool bRet = false;
|
|
|
|
switch( eType )
|
|
{
|
|
case OutDevSupport_TransparentRect:
|
|
bRet = mbVirDev || mbWindow;
|
|
break;
|
|
case OutDevSupport_B2DClip:
|
|
bRet = true;
|
|
break;
|
|
case OutDevSupport_B2DDraw:
|
|
bRet = bAllowForTest;
|
|
default: break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
// =======================================================================
|
|
|
|
void WinSalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
|
|
{
|
|
HDC hSrcDC;
|
|
DWORD nRop;
|
|
|
|
if ( pSrcGraphics )
|
|
hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->mhDC;
|
|
else
|
|
hSrcDC = mhDC;
|
|
|
|
if ( mbXORMode )
|
|
nRop = SRCINVERT;
|
|
else
|
|
nRop = SRCCOPY;
|
|
|
|
if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
|
|
(pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
|
|
{
|
|
BitBlt( mhDC,
|
|
(int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
|
|
(int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
|
|
hSrcDC,
|
|
(int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
|
|
nRop );
|
|
}
|
|
else
|
|
{
|
|
int nOldStretchMode = SetStretchBltMode( mhDC, STRETCH_DELETESCANS );
|
|
StretchBlt( mhDC,
|
|
(int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
|
|
(int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
|
|
hSrcDC,
|
|
(int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
|
|
(int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
|
|
nRop );
|
|
SetStretchBltMode( mhDC, nOldStretchMode );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImplCalcOutSideRgn( const RECT& rSrcRect,
|
|
int nLeft, int nTop, int nRight, int nBottom,
|
|
HRGN& rhInvalidateRgn )
|
|
{
|
|
HRGN hTempRgn;
|
|
|
|
// Bereiche ausserhalb des sichtbaren Bereiches berechnen
|
|
if ( rSrcRect.left < nLeft )
|
|
{
|
|
if ( !rhInvalidateRgn )
|
|
rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
|
|
hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 );
|
|
CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
}
|
|
if ( rSrcRect.top < nTop )
|
|
{
|
|
if ( !rhInvalidateRgn )
|
|
rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
|
|
hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop );
|
|
CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
}
|
|
if ( rSrcRect.right > nRight )
|
|
{
|
|
if ( !rhInvalidateRgn )
|
|
rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
|
|
hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 );
|
|
CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
}
|
|
if ( rSrcRect.bottom > nBottom )
|
|
{
|
|
if ( !rhInvalidateRgn )
|
|
rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
|
|
hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 );
|
|
CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::copyArea( long nDestX, long nDestY,
|
|
long nSrcX, long nSrcY,
|
|
long nSrcWidth, long nSrcHeight,
|
|
sal_uInt16 nFlags )
|
|
{
|
|
bool bRestoreClipRgn = false;
|
|
HRGN hOldClipRgn = 0;
|
|
int nOldClipRgnType = ERROR;
|
|
HRGN hInvalidateRgn = 0;
|
|
|
|
// Muessen die ueberlappenden Bereiche auch invalidiert werden?
|
|
if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow )
|
|
{
|
|
// compute and invalidate those parts that were either off-screen or covered by other windows
|
|
// while performing the above BitBlt
|
|
// those regions then have to be invalidated as they contain useless/wrong data
|
|
RECT aSrcRect;
|
|
RECT aClipRect;
|
|
RECT aTempRect;
|
|
RECT aTempRect2;
|
|
HRGN hTempRgn;
|
|
HWND hWnd;
|
|
|
|
// restrict srcRect to this window (calc intersection)
|
|
aSrcRect.left = (int)nSrcX;
|
|
aSrcRect.top = (int)nSrcY;
|
|
aSrcRect.right = aSrcRect.left+(int)nSrcWidth;
|
|
aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight;
|
|
GetClientRect( mhWnd, &aClipRect );
|
|
if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) )
|
|
{
|
|
// transform srcRect to screen coordinates
|
|
POINT aPt;
|
|
aPt.x = 0;
|
|
aPt.y = 0;
|
|
ClientToScreen( mhWnd, &aPt );
|
|
aSrcRect.left += aPt.x;
|
|
aSrcRect.top += aPt.y;
|
|
aSrcRect.right += aPt.x;
|
|
aSrcRect.bottom += aPt.y;
|
|
hInvalidateRgn = 0;
|
|
|
|
// compute the parts that are off screen (ie invisible)
|
|
RECT theScreen;
|
|
ImplSalGetWorkArea( NULL, &theScreen, NULL ); // find the screen area taking multiple monitors into account
|
|
ImplCalcOutSideRgn( aSrcRect, theScreen.left, theScreen.top, theScreen.right, theScreen.bottom, hInvalidateRgn );
|
|
|
|
// Bereiche die von anderen Fenstern ueberlagert werden berechnen
|
|
HRGN hTempRgn2 = 0;
|
|
HWND hWndTopWindow = mhWnd;
|
|
// Find the TopLevel Window, because only Windows which are in
|
|
// in the foreground of our TopLevel window must be considered
|
|
if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD )
|
|
{
|
|
RECT aTempRect3 = aSrcRect;
|
|
do
|
|
{
|
|
hWndTopWindow = ::GetParent( hWndTopWindow );
|
|
|
|
// Test, if the Parent clips our window
|
|
GetClientRect( hWndTopWindow, &aTempRect );
|
|
POINT aPt2;
|
|
aPt2.x = 0;
|
|
aPt2.y = 0;
|
|
ClientToScreen( hWndTopWindow, &aPt2 );
|
|
aTempRect.left += aPt2.x;
|
|
aTempRect.top += aPt2.y;
|
|
aTempRect.right += aPt2.x;
|
|
aTempRect.bottom += aPt2.y;
|
|
IntersectRect( &aTempRect3, &aTempRect3, &aTempRect );
|
|
}
|
|
while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD );
|
|
|
|
// If one or more Parents clip our window, than we must
|
|
// calculate the outside area
|
|
if ( !EqualRect( &aSrcRect, &aTempRect3 ) )
|
|
{
|
|
ImplCalcOutSideRgn( aSrcRect,
|
|
aTempRect3.left, aTempRect3.top,
|
|
aTempRect3.right, aTempRect3.bottom,
|
|
hInvalidateRgn );
|
|
}
|
|
}
|
|
// retrieve the top-most (z-order) child window
|
|
hWnd = GetWindow( GetDesktopWindow(), GW_CHILD );
|
|
while ( hWnd )
|
|
{
|
|
if ( hWnd == hWndTopWindow )
|
|
break;
|
|
if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) )
|
|
{
|
|
GetWindowRect( hWnd, &aTempRect );
|
|
if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) )
|
|
{
|
|
// hWnd covers part or all of aSrcRect
|
|
if ( !hInvalidateRgn )
|
|
hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect );
|
|
|
|
// get full bounding box of hWnd
|
|
hTempRgn = CreateRectRgnIndirect( &aTempRect );
|
|
|
|
// get region of hWnd (the window may be shaped)
|
|
if ( !hTempRgn2 )
|
|
hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 );
|
|
int nRgnType = GetWindowRgn( hWnd, hTempRgn2 );
|
|
if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
|
|
{
|
|
// convert window region to screen coordinates
|
|
OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top );
|
|
// and intersect with the window's bounding box
|
|
CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND );
|
|
}
|
|
// finally compute that part of aSrcRect which is not covered by any parts of hWnd
|
|
CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
}
|
|
}
|
|
// retrieve the next window in the z-order, i.e. the window below hwnd
|
|
hWnd = GetWindow( hWnd, GW_HWNDNEXT );
|
|
}
|
|
if ( hTempRgn2 )
|
|
DeleteRegion( hTempRgn2 );
|
|
if ( hInvalidateRgn )
|
|
{
|
|
// hInvalidateRgn contains the fully visible parts of the original srcRect
|
|
hTempRgn = CreateRectRgnIndirect( &aSrcRect );
|
|
// substract it from the original rect to get the occluded parts
|
|
int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF );
|
|
DeleteRegion( hTempRgn );
|
|
|
|
if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
|
|
{
|
|
// move the occluded parts to the destination pos
|
|
int nOffX = (int)(nDestX-nSrcX);
|
|
int nOffY = (int)(nDestY-nSrcY);
|
|
OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y );
|
|
|
|
// by excluding hInvalidateRgn from the system's clip region
|
|
// we will prevent bitblt from copying useless data
|
|
// epsecially now shadows from overlapping windows will appear (#i36344)
|
|
hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 );
|
|
nOldClipRgnType = GetClipRgn( mhDC, hOldClipRgn );
|
|
|
|
bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate
|
|
ExtSelectClipRgn( mhDC, hInvalidateRgn, RGN_DIFF );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BitBlt( mhDC,
|
|
(int)nDestX, (int)nDestY,
|
|
(int)nSrcWidth, (int)nSrcHeight,
|
|
mhDC,
|
|
(int)nSrcX, (int)nSrcY,
|
|
SRCCOPY );
|
|
|
|
if( bRestoreClipRgn )
|
|
{
|
|
// restore old clip region
|
|
if( nOldClipRgnType != ERROR )
|
|
SelectClipRgn( mhDC, hOldClipRgn);
|
|
DeleteRegion( hOldClipRgn );
|
|
|
|
// invalidate regions that were not copied
|
|
bool bInvalidate = true;
|
|
|
|
// Combine Invalidate Region with existing ClipRegion
|
|
HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 );
|
|
if ( GetClipRgn( mhDC, hTempRgn ) == 1 )
|
|
{
|
|
int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND );
|
|
if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) )
|
|
bInvalidate = false;
|
|
}
|
|
DeleteRegion( hTempRgn );
|
|
|
|
if ( bInvalidate )
|
|
{
|
|
InvalidateRgn( mhWnd, hInvalidateRgn, TRUE );
|
|
// Hier loesen wir nur ein Update aus, wenn es der
|
|
// MainThread ist, damit es beim Bearbeiten der
|
|
// Paint-Message keinen Deadlock gibt, da der
|
|
// SolarMutex durch diesen Thread schon gelockt ist
|
|
SalData* pSalData = GetSalData();
|
|
DWORD nCurThreadId = GetCurrentThreadId();
|
|
if ( pSalData->mnAppThreadId == nCurThreadId )
|
|
UpdateWindow( mhWnd );
|
|
}
|
|
|
|
DeleteRegion( hInvalidateRgn );
|
|
}
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImplDrawBitmap( HDC hDC,
|
|
const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap,
|
|
sal_Bool bPrinter, int nDrawMode )
|
|
{
|
|
if( hDC )
|
|
{
|
|
HGLOBAL hDrawDIB;
|
|
HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
|
|
WinSalBitmap* pTmpSalBmp = NULL;
|
|
sal_Bool bPrintDDB = ( bPrinter && hDrawDDB );
|
|
|
|
if( bPrintDDB )
|
|
{
|
|
pTmpSalBmp = new WinSalBitmap;
|
|
pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
|
|
hDrawDIB = pTmpSalBmp->ImplGethDIB();
|
|
}
|
|
else
|
|
hDrawDIB = rSalBitmap.ImplGethDIB();
|
|
|
|
if( hDrawDIB )
|
|
{
|
|
PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
|
|
PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
|
|
PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
|
|
rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
|
|
const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
|
|
|
|
StretchDIBits( hDC,
|
|
(int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
|
|
(int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
|
|
(int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY),
|
|
(int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
|
|
pBits, pBI, DIB_RGB_COLORS, nDrawMode );
|
|
|
|
GlobalUnlock( hDrawDIB );
|
|
SetStretchBltMode( hDC, nOldStretchMode );
|
|
}
|
|
else if( hDrawDDB && !bPrintDDB )
|
|
{
|
|
HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB );
|
|
COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF);
|
|
COLORREF nOldTextColor = RGB(0,0,0);
|
|
sal_Bool bMono = ( rSalBitmap.GetBitCount() == 1 );
|
|
|
|
if( bMono )
|
|
{
|
|
COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF );
|
|
COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 );
|
|
//fdo#33455 handle 1 bit depth pngs with palette entries
|
|
//to set fore/back colors
|
|
if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(true))
|
|
{
|
|
const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
|
|
if (rPalette.GetEntryCount() == 2)
|
|
{
|
|
SalColor nCol;
|
|
nCol = ImplColorToSal(rPalette[0]);
|
|
nTextColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
|
|
nCol = ImplColorToSal(rPalette[1]);
|
|
nBkColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
|
|
}
|
|
}
|
|
nOldBkColor = SetBkColor( hDC, nBkColor );
|
|
nOldTextColor = ::SetTextColor( hDC, nTextColor );
|
|
}
|
|
|
|
if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
|
|
(pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
|
|
{
|
|
BitBlt( hDC,
|
|
(int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
|
|
(int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
|
|
hBmpDC,
|
|
(int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
|
|
nDrawMode );
|
|
}
|
|
else
|
|
{
|
|
const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
|
|
|
|
StretchBlt( hDC,
|
|
(int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
|
|
(int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
|
|
hBmpDC,
|
|
(int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
|
|
(int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
|
|
nDrawMode );
|
|
|
|
SetStretchBltMode( hDC, nOldStretchMode );
|
|
}
|
|
|
|
if( bMono )
|
|
{
|
|
SetBkColor( hDC, nOldBkColor );
|
|
::SetTextColor( hDC, nOldTextColor );
|
|
}
|
|
|
|
ImplReleaseCachedDC( CACHED_HDC_DRAW );
|
|
}
|
|
|
|
if( bPrintDDB )
|
|
delete pTmpSalBmp;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
|
|
const SalBitmap& rSalBitmap )
|
|
{
|
|
ImplDrawBitmap( mhDC, pPosAry, static_cast<const WinSalBitmap&>(rSalBitmap),
|
|
mbPrinter,
|
|
mbXORMode ? SRCINVERT : SRCCOPY );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
|
|
const SalBitmap& rSSalBitmap,
|
|
SalColor nTransparentColor )
|
|
{
|
|
DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
|
|
|
|
const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
|
|
|
|
WinSalBitmap* pMask = new WinSalBitmap;
|
|
const Point aPoint;
|
|
const Size aSize( rSalBitmap.GetSize() );
|
|
HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL );
|
|
HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap );
|
|
const BYTE cRed = SALCOLOR_RED( nTransparentColor );
|
|
const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor );
|
|
const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor );
|
|
|
|
if( rSalBitmap.ImplGethDDB() )
|
|
{
|
|
HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() );
|
|
COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
|
|
|
|
BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
|
|
|
|
SetBkColor( hSrcDC, aOldCol );
|
|
ImplReleaseCachedDC( CACHED_HDC_2 );
|
|
}
|
|
else
|
|
{
|
|
WinSalBitmap* pTmpSalBmp = new WinSalBitmap;
|
|
|
|
if( pTmpSalBmp->Create( rSalBitmap, this ) )
|
|
{
|
|
HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() );
|
|
COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
|
|
|
|
BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
|
|
|
|
SetBkColor( hSrcDC, aOldCol );
|
|
ImplReleaseCachedDC( CACHED_HDC_2 );
|
|
}
|
|
|
|
delete pTmpSalBmp;
|
|
}
|
|
|
|
ImplReleaseCachedDC( CACHED_HDC_1 );
|
|
|
|
// hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE )
|
|
if( pMask->Create( hMaskBitmap, FALSE, FALSE ) )
|
|
drawBitmap( pPosAry, rSalBitmap, *pMask );
|
|
|
|
delete pMask;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
|
|
const SalBitmap& rSSalBitmap,
|
|
const SalBitmap& rSTransparentBitmap )
|
|
{
|
|
DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
|
|
|
|
const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
|
|
const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap);
|
|
|
|
SalTwoRect aPosAry = *pPosAry;
|
|
int nDstX = (int)aPosAry.mnDestX;
|
|
int nDstY = (int)aPosAry.mnDestY;
|
|
int nDstWidth = (int)aPosAry.mnDestWidth;
|
|
int nDstHeight = (int)aPosAry.mnDestHeight;
|
|
HDC hDC = mhDC;
|
|
HBITMAP hMemBitmap = 0;
|
|
HBITMAP hMaskBitmap = 0;
|
|
|
|
if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) )
|
|
{
|
|
hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
|
|
hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
|
|
}
|
|
|
|
HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap );
|
|
HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap );
|
|
|
|
aPosAry.mnDestX = aPosAry.mnDestY = 0;
|
|
BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY );
|
|
|
|
// bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
|
|
// die Farben der Maske richtig auf die Palette abzubilden,
|
|
// wenn wir die DIB direkt ausgeben => DDB-Ausgabe
|
|
if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
|
|
{
|
|
WinSalBitmap aTmp;
|
|
|
|
if( aTmp.Create( rTransparentBitmap, this ) )
|
|
ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY );
|
|
}
|
|
else
|
|
ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY );
|
|
|
|
// now MemDC contains background, MaskDC the transparency mask
|
|
|
|
// #105055# Respect XOR mode
|
|
if( mbXORMode )
|
|
{
|
|
ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE );
|
|
// now MaskDC contains the bitmap area with black background
|
|
BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT );
|
|
// now MemDC contains background XORed bitmap area ontop
|
|
}
|
|
else
|
|
{
|
|
BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND );
|
|
// now MemDC contains background with masked-out bitmap area
|
|
ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE );
|
|
// now MaskDC contains the bitmap area with black background
|
|
BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT );
|
|
// now MemDC contains background and bitmap merged together
|
|
}
|
|
// copy to output DC
|
|
BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY );
|
|
|
|
ImplReleaseCachedDC( CACHED_HDC_1 );
|
|
ImplReleaseCachedDC( CACHED_HDC_2 );
|
|
|
|
// hMemBitmap != 0 ==> hMaskBitmap != 0
|
|
if( hMemBitmap )
|
|
{
|
|
DeleteObject( hMemBitmap );
|
|
DeleteObject( hMaskBitmap );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
bool WinSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
|
|
const SalBitmap& rSrcBitmap,
|
|
const SalBitmap& rAlphaBmp )
|
|
{
|
|
(void)rTR; (void)rSrcBitmap; (void)rAlphaBmp;
|
|
|
|
// TODO(P3): implement alpha bmp blits. Catch: Windows only
|
|
// handles 32bpp, premultiplied bitmaps
|
|
return false;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
|
|
long nHeight, sal_uInt8 nTransparency )
|
|
{
|
|
if( mbPen || !mbBrush || mbXORMode )
|
|
return false; // can only perform solid fills without XOR.
|
|
|
|
HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 );
|
|
SetPixel( hMemDC, (int)0, (int)0, mnBrushColor );
|
|
|
|
BLENDFUNCTION aFunc = {
|
|
AC_SRC_OVER,
|
|
0,
|
|
sal::static_int_cast<sal_uInt8>(255 - 255L*nTransparency/100),
|
|
0
|
|
};
|
|
|
|
// hMemDC contains a 1x1 bitmap of the right color - stretch-blit
|
|
// that to dest hdc
|
|
bool bRet = AlphaBlend( mhDC, nX, nY, nWidth, nHeight,
|
|
hMemDC, 0,0,1,1,
|
|
aFunc ) == TRUE;
|
|
|
|
ImplReleaseCachedDC( CACHED_HDC_1 );
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::drawMask( const SalTwoRect* pPosAry,
|
|
const SalBitmap& rSSalBitmap,
|
|
SalColor nMaskColor )
|
|
{
|
|
DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
|
|
|
|
const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
|
|
|
|
SalTwoRect aPosAry = *pPosAry;
|
|
const BYTE cRed = SALCOLOR_RED( nMaskColor );
|
|
const BYTE cGreen = SALCOLOR_GREEN( nMaskColor );
|
|
const BYTE cBlue = SALCOLOR_BLUE( nMaskColor );
|
|
HDC hDC = mhDC;
|
|
HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) );
|
|
HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush );
|
|
|
|
// bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
|
|
// die Farben der Maske richtig auf die Palette abzubilden,
|
|
// wenn wir die DIB direkt ausgeben => DDB-Ausgabe
|
|
if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
|
|
{
|
|
WinSalBitmap aTmp;
|
|
|
|
if( aTmp.Create( rSalBitmap, this ) )
|
|
ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL );
|
|
}
|
|
else
|
|
ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
|
|
|
|
SelectBrush( hDC, hOldBrush );
|
|
DeleteBrush( hMaskBrush );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
|
|
{
|
|
DBG_ASSERT( !mbPrinter, "No ::GetBitmap() from printer possible!" );
|
|
|
|
WinSalBitmap* pSalBitmap = NULL;
|
|
|
|
nDX = labs( nDX );
|
|
nDY = labs( nDY );
|
|
|
|
HDC hDC = mhDC;
|
|
HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
|
|
HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
|
|
sal_Bool bRet;
|
|
|
|
bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE;
|
|
ImplReleaseCachedDC( CACHED_HDC_1 );
|
|
|
|
if( bRet )
|
|
{
|
|
pSalBitmap = new WinSalBitmap;
|
|
|
|
if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
|
|
{
|
|
delete pSalBitmap;
|
|
pSalBitmap = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers)
|
|
DeleteBitmap( hBmpBitmap );
|
|
}
|
|
|
|
return pSalBitmap;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
SalColor WinSalGraphics::getPixel( long nX, long nY )
|
|
{
|
|
COLORREF aWinCol = ::GetPixel( mhDC, (int) nX, (int) nY );
|
|
|
|
if ( CLR_INVALID == aWinCol )
|
|
return MAKE_SALCOLOR( 0, 0, 0 );
|
|
else
|
|
return MAKE_SALCOLOR( GetRValue( aWinCol ),
|
|
GetGValue( aWinCol ),
|
|
GetBValue( aWinCol ) );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
|
|
{
|
|
if ( nFlags & SAL_INVERT_TRACKFRAME )
|
|
{
|
|
HPEN hDotPen = CreatePen( PS_DOT, 0, 0 );
|
|
HPEN hOldPen = SelectPen( mhDC, hDotPen );
|
|
HBRUSH hOldBrush = SelectBrush( mhDC, GetStockBrush( NULL_BRUSH ) );
|
|
int nOldROP = SetROP2( mhDC, R2_NOT );
|
|
|
|
WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
|
|
|
|
SetROP2( mhDC, nOldROP );
|
|
SelectPen( mhDC, hOldPen );
|
|
SelectBrush( mhDC, hOldBrush );
|
|
DeletePen( hDotPen );
|
|
}
|
|
else if ( nFlags & SAL_INVERT_50 )
|
|
{
|
|
SalData* pSalData = GetSalData();
|
|
if ( !pSalData->mh50Brush )
|
|
{
|
|
if ( !pSalData->mh50Bmp )
|
|
pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
|
|
pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
|
|
}
|
|
|
|
COLORREF nOldTextColor = ::SetTextColor( mhDC, 0 );
|
|
HBRUSH hOldBrush = SelectBrush( mhDC, pSalData->mh50Brush );
|
|
PatBlt( mhDC, nX, nY, nWidth, nHeight, PATINVERT );
|
|
::SetTextColor( mhDC, nOldTextColor );
|
|
SelectBrush( mhDC, hOldBrush );
|
|
}
|
|
else
|
|
{
|
|
RECT aRect;
|
|
aRect.left = (int)nX;
|
|
aRect.top = (int)nY;
|
|
aRect.right = (int)nX+nWidth;
|
|
aRect.bottom = (int)nY+nHeight;
|
|
::InvertRect( mhDC, &aRect );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
|
|
{
|
|
HPEN hPen;
|
|
HPEN hOldPen;
|
|
HBRUSH hBrush;
|
|
HBRUSH hOldBrush = 0;
|
|
COLORREF nOldTextColor RGB(0,0,0);
|
|
int nOldROP = SetROP2( mhDC, R2_NOT );
|
|
|
|
if ( nSalFlags & SAL_INVERT_TRACKFRAME )
|
|
hPen = CreatePen( PS_DOT, 0, 0 );
|
|
else
|
|
{
|
|
|
|
if ( nSalFlags & SAL_INVERT_50 )
|
|
{
|
|
SalData* pSalData = GetSalData();
|
|
if ( !pSalData->mh50Brush )
|
|
{
|
|
if ( !pSalData->mh50Bmp )
|
|
pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
|
|
pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
|
|
}
|
|
|
|
hBrush = pSalData->mh50Brush;
|
|
}
|
|
else
|
|
hBrush = GetStockBrush( BLACK_BRUSH );
|
|
|
|
hPen = GetStockPen( NULL_PEN );
|
|
nOldTextColor = ::SetTextColor( mhDC, 0 );
|
|
hOldBrush = SelectBrush( mhDC, hBrush );
|
|
}
|
|
hOldPen = SelectPen( mhDC, hPen );
|
|
|
|
POINT* pWinPtAry;
|
|
// Unter NT koennen wir das Array direkt weiterreichen
|
|
DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
|
|
"WinSalGraphics::DrawPolyLine(): POINT != SalPoint" );
|
|
|
|
pWinPtAry = (POINT*)pPtAry;
|
|
// Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
|
|
// von Punkten
|
|
if ( nSalFlags & SAL_INVERT_TRACKFRAME )
|
|
{
|
|
if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
|
|
Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS );
|
|
}
|
|
else
|
|
{
|
|
if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
|
|
WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS );
|
|
}
|
|
|
|
SetROP2( mhDC, nOldROP );
|
|
SelectPen( mhDC, hOldPen );
|
|
|
|
if ( nSalFlags & SAL_INVERT_TRACKFRAME )
|
|
DeletePen( hPen );
|
|
else
|
|
{
|
|
::SetTextColor( mhDC, nOldTextColor );
|
|
SelectBrush( mhDC, hOldBrush );
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|