summaryrefslogtreecommitdiff
path: root/vcl/win/source/gdi/salgdi.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/source/gdi/salgdi.cxx')
-rw-r--r--vcl/win/source/gdi/salgdi.cxx945
1 files changed, 51 insertions, 894 deletions
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index be4a6c8e8fe9..28469eb1a017 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -32,6 +32,9 @@
#include <win/salframe.h>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include "salgdiimpl.hxx"
+#include "gdiimpl.hxx"
+
// comment out to prevent use of beziers on GDI functions
#define USE_GDI_BEZIERS
@@ -106,9 +109,6 @@ static BYTE aOrdDither16Bit[8][8] =
// complex is set
#define GSL_PEN_WIDTH 1
-#define SAL_POLYPOLYCOUNT_STACKBUF 8
-#define SAL_POLYPOLYPOINTS_STACKBUF 64
-
void ImplInitSalGDI()
{
SalData* pSalData = GetSalData();
@@ -365,6 +365,23 @@ void ImplFreeSalGDI()
pSalData->mbResourcesAlreadyFreed = true;
}
+int ImplIsSysColorEntry( SalColor nSalColor )
+{
+ SysColorEntry* pEntry = pFirstSysColor;
+ const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ while ( pEntry )
+ {
+ if ( pEntry->nRGB == nTestRGB )
+ return TRUE;
+ pEntry = pEntry->pNext;
+ }
+
+ return FALSE;
+}
+
static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
{
// dither color?
@@ -391,23 +408,6 @@ static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
return FALSE;
}
-int ImplIsSysColorEntry( SalColor nSalColor )
-{
- SysColorEntry* pEntry = pFirstSysColor;
- const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
-
- while ( pEntry )
- {
- if ( pEntry->nRGB == nTestRGB )
- return TRUE;
- pEntry = pEntry->pNext;
- }
-
- return FALSE;
-}
-
static void ImplInsertSysColorEntry( int nSysIndex )
{
const DWORD nRGB = GetSysColor( nSysIndex );
@@ -466,16 +466,6 @@ void ImplUpdateSysColorEntries()
ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
}
-static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
-{
- SalColor nSalColor;
- if ( nROPColor == SAL_ROP_0 )
- nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
- else
- nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
- return nSalColor;
-}
-
void ImplSalInitGraphics( WinSalGraphics* pData )
{
// calculate the minimal line width for the printer
@@ -566,106 +556,8 @@ void ImplClearHDCCache( SalData* pData )
}
}
-// #100127# Fill point and flag memory from array of points which
-// might also contain bezier control points for the PolyDraw() GDI method
-// Make sure pWinPointAry and pWinFlagAry are big enough
-void ImplPreparePolyDraw( bool bCloseFigures,
- sal_uLong nPoly,
- const sal_uInt32* pPoints,
- const SalPoint* const* pPtAry,
- const BYTE* const* pFlgAry,
- POINT* pWinPointAry,
- BYTE* pWinFlagAry )
-{
- sal_uLong nCurrPoly;
- for( nCurrPoly=0; nCurrPoly<nPoly; ++nCurrPoly )
- {
- const POINT* pCurrPoint = reinterpret_cast<const POINT*>( *pPtAry++ );
- const BYTE* pCurrFlag = *pFlgAry++;
- const sal_uInt32 nCurrPoints = *pPoints++;
- const bool bHaveFlagArray( pCurrFlag );
- sal_uLong nCurrPoint;
-
- if( nCurrPoints )
- {
- // start figure
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_MOVETO;
- ++pCurrFlag;
-
- for( nCurrPoint=1; nCurrPoint<nCurrPoints; )
- {
- // #102067# Check existence of flag array
- if( bHaveFlagArray &&
- ( nCurrPoint + 2 ) < nCurrPoints )
- {
- BYTE P4( pCurrFlag[ 2 ] );
-
- if( ( POLY_CONTROL == pCurrFlag[ 0 ] ) &&
- ( POLY_CONTROL == pCurrFlag[ 1 ] ) &&
- ( POLY_NORMAL == P4 || POLY_SMOOTH == P4 || POLY_SYMMTR == P4 ) )
- {
- // control point one
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- // control point two
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- // end point
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- nCurrPoint += 3;
- pCurrFlag += 3;
- continue;
- }
- }
-
- // regular line point
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_LINETO;
- ++pCurrFlag;
- ++nCurrPoint;
- }
-
- // end figure?
- if( bCloseFigures )
- pWinFlagAry[-1] |= PT_CLOSEFIGURE;
- }
- }
-}
-
-// #100127# draw an array of points which might also contain bezier control points
-void ImplRenderPath( HDC hdc, sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
-{
- if( nPoints )
- {
- sal_uInt16 i;
- // TODO: profile whether the following options are faster:
- // a) look ahead and draw consecutive bezier or line segments by PolyBezierTo/PolyLineTo resp.
- // b) convert our flag array to window's and use PolyDraw
-
- MoveToEx( hdc, pPtAry->mnX, pPtAry->mnY, NULL );
- ++pPtAry; ++pFlgAry;
-
- for( i=1; i<nPoints; ++i, ++pPtAry, ++pFlgAry )
- {
- if( *pFlgAry != POLY_CONTROL )
- {
- LineTo( hdc, pPtAry->mnX, pPtAry->mnY );
- }
- else if( nPoints - i > 2 )
- {
- PolyBezierTo( hdc, reinterpret_cast<const POINT*>(pPtAry), 3 );
- i += 2; pPtAry += 2; pFlgAry += 2;
- }
- }
- }
-}
-
-WinSalGraphics::WinSalGraphics()
+WinSalGraphics::WinSalGraphics():
+ mpImpl(new WinSalGraphicsImpl(*this))
{
for( int i = 0; i < MAX_FALLBACK; ++i )
{
@@ -678,8 +570,6 @@ WinSalGraphics::WinSalGraphics()
mfCurrentFontScale = 1.0;
mhLocalDC = 0;
- mhPen = 0;
- mhBrush = 0;
mhRegion = 0;
mhDefPen = 0;
mhDefBrush = 0;
@@ -693,7 +583,6 @@ WinSalGraphics::WinSalGraphics()
mpFontKernPairs = NULL;
mnFontKernPairCount = 0;
mbFontKernInit = FALSE;
- mbXORMode = FALSE;
mnPenWidth = GSL_PEN_WIDTH;
}
@@ -702,17 +591,6 @@ WinSalGraphics::~WinSalGraphics()
// free obsolete GDI objects
ReleaseFonts();
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
-
if ( mhRegion )
{
DeleteRegion( mhRegion );
@@ -730,6 +608,11 @@ WinSalGraphics::~WinSalGraphics()
delete mpFontKernPairs;
}
+HWND WinSalGraphics::gethWnd()
+{
+ return mhWnd;
+}
+
void WinSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
{
rDPIX = GetDeviceCaps( getHDC(), LOGPIXELSX );
@@ -744,839 +627,111 @@ void WinSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
sal_uInt16 WinSalGraphics::GetBitCount() const
{
- return (sal_uInt16)GetDeviceCaps( getHDC(), BITSPIXEL );
+ return mpImpl->GetBitCount();
}
long WinSalGraphics::GetGraphicsWidth() const
{
- if( mhWnd && IsWindow( mhWnd ) )
- {
- WinSalFrame* pFrame = GetWindowPtr( mhWnd );
- if( pFrame )
- {
- if( pFrame->maGeometry.nWidth )
- return pFrame->maGeometry.nWidth;
- else
- {
- // TODO: perhaps not needed, maGeometry should always be up-to-date
- RECT aRect;
- GetClientRect( mhWnd, &aRect );
- return aRect.right;
- }
- }
- }
-
- return 0;
+ return mpImpl->GetGraphicsWidth();
}
void WinSalGraphics::ResetClipRegion()
{
- if ( mhRegion )
- {
- DeleteRegion( mhRegion );
- mhRegion = 0;
- }
-
- SelectClipRgn( getHDC(), 0 );
+ mpImpl->ResetClipRegion();
}
bool WinSalGraphics::setClipRegion( const vcl::Region& i_rClip )
{
- if ( mhRegion )
- {
- DeleteRegion( mhRegion );
- mhRegion = 0;
- }
-
- bool bUsePolygon(i_rClip.HasPolyPolygonOrB2DPolyPolygon());
- static bool bTryToAvoidPolygon(true);
-
- // #i122149# try to avoid usage of tools::PolyPolygon ClipRegions when tools::PolyPolygon is no curve
- // and only contains horizontal/vertical edges. In that case, use the fallback
- // in GetRegionRectangles which will use vcl::Region::GetAsRegionBand() which will do
- // the correct polygon-to-RegionBand transformation.
- // Background is that when using the same Rectangle as rectangle or as Polygon
- // clip region will lead to different results; the polygon-based one will be
- // one pixel less to the right and down (see GDI docu for CreatePolygonRgn). This
- // again is because of the polygon-nature and it's classic handling when filling.
- // This also means that all cases which use a 'true' polygon-based incarnation of
- // a vcl::Region should know what they do - it may lead to repaint errors.
- if(bUsePolygon && bTryToAvoidPolygon)
- {
- const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
-
- if(!aPolyPolygon.areControlPointsUsed())
- {
- if(basegfx::tools::containsOnlyHorizontalAndVerticalEdges(aPolyPolygon))
- {
- bUsePolygon = false;
- }
- }
- }
-
- if(bUsePolygon)
- {
- // #i122149# check the comment above to know that this may lead to potential repaint
- // problems. It may be solved (if needed) by scaling the polygon by one in X
- // and Y. Currently the workaround to only use it if really unavoidable will
- // solve most cases. When someone is really using polygon-based Regions he
- // should know what he is doing.
- // Added code to do that scaling to check if it works, testing it.
- const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
- const sal_uInt32 nCount(aPolyPolygon.count());
-
- if( nCount )
- {
- std::vector< POINT > aPolyPoints;
- aPolyPoints.reserve( 1024 );
- std::vector< INT > aPolyCounts( nCount, 0 );
- basegfx::B2DHomMatrix aExpand;
- static bool bExpandByOneInXandY(true);
-
- if(bExpandByOneInXandY)
- {
- const basegfx::B2DRange aRangeS(aPolyPolygon.getB2DRange());
- const basegfx::B2DRange aRangeT(aRangeS.getMinimum(), aRangeS.getMaximum() + basegfx::B2DTuple(1.0, 1.0));
- aExpand = basegfx::B2DHomMatrix(basegfx::tools::createSourceRangeTargetRangeTransform(aRangeS, aRangeT));
- }
-
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- const basegfx::B2DPolygon aPoly(
- basegfx::tools::adaptiveSubdivideByDistance(
- aPolyPolygon.getB2DPolygon(a),
- 1));
- const sal_uInt32 nPoints(aPoly.count());
- aPolyCounts[a] = nPoints;
-
- for( sal_uInt32 b = 0; b < nPoints; b++ )
- {
- basegfx::B2DPoint aPt(aPoly.getB2DPoint(b));
-
- if(bExpandByOneInXandY)
- {
- aPt = aExpand * aPt;
- }
-
- POINT aPOINT;
- // #i122149# do correct rounding
- aPOINT.x = basegfx::fround(aPt.getX());
- aPOINT.y = basegfx::fround(aPt.getY());
- aPolyPoints.push_back( aPOINT );
- }
- }
-
- mhRegion = CreatePolyPolygonRgn( &aPolyPoints[0], &aPolyCounts[0], nCount, ALTERNATE );
- }
- }
- else
- {
- RectangleVector aRectangles;
- i_rClip.GetRegionRectangles(aRectangles);
-
- sal_uLong nRectBufSize = sizeof(RECT)*aRectangles.size();
- if ( aRectangles.size() < SAL_CLIPRECT_COUNT )
- {
- if ( !mpStdClipRgnData )
- mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
- mpClipRgnData = mpStdClipRgnData;
- }
- else
- mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
- mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
- mpClipRgnData->rdh.iType = RDH_RECTANGLES;
- mpClipRgnData->rdh.nCount = aRectangles.size();
- mpClipRgnData->rdh.nRgnSize = nRectBufSize;
- RECT* pBoundRect = &(mpClipRgnData->rdh.rcBound);
- SetRectEmpty( pBoundRect );
- RECT* pNextClipRect = (RECT*)(&(mpClipRgnData->Buffer));
- bool bFirstClipRect = true;
-
- for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
- {
- const long nW(aRectIter->GetWidth());
- const long nH(aRectIter->GetHeight());
-
- if(nW && nH)
- {
- const long nRight(aRectIter->Left() + nW);
- const long nBottom(aRectIter->Top() + nH);
-
- if(bFirstClipRect)
- {
- pBoundRect->left = aRectIter->Left();
- pBoundRect->top = aRectIter->Top();
- pBoundRect->right = nRight;
- pBoundRect->bottom = nBottom;
- bFirstClipRect = false;
- }
- else
- {
- if(aRectIter->Left() < pBoundRect->left)
- {
- pBoundRect->left = (int)aRectIter->Left();
- }
-
- if(aRectIter->Top() < pBoundRect->top)
- {
- pBoundRect->top = (int)aRectIter->Top();
- }
-
- if(nRight > pBoundRect->right)
- {
- pBoundRect->right = (int)nRight;
- }
-
- if(nBottom > pBoundRect->bottom)
- {
- pBoundRect->bottom = (int)nBottom;
- }
- }
-
- pNextClipRect->left = (int)aRectIter->Left();
- pNextClipRect->top = (int)aRectIter->Top();
- pNextClipRect->right = (int)nRight;
- pNextClipRect->bottom = (int)nBottom;
- pNextClipRect++;
- }
- else
- {
- mpClipRgnData->rdh.nCount--;
- mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
- }
- }
-
- // create clip region from ClipRgnData
- if(0 == mpClipRgnData->rdh.nCount)
- {
- // #i123585# region is empty; this may happen when e.g. a tools::PolyPolygon is given
- // that contains no polygons or only empty ones (no width/height). This is
- // perfectly fine and we are done, except setting it (see end of method)
- }
- else if(1 == mpClipRgnData->rdh.nCount)
- {
- RECT* pRect = &(mpClipRgnData->rdh.rcBound);
- mhRegion = CreateRectRgn( pRect->left, pRect->top,
- pRect->right, pRect->bottom );
- }
- else if(mpClipRgnData->rdh.nCount > 1)
- {
- sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
- mhRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData );
-
- // if ExtCreateRegion(...) is not supported
- if( !mhRegion )
- {
- RGNDATAHEADER* pHeader = (RGNDATAHEADER*) mpClipRgnData;
-
- if( pHeader->nCount )
- {
- RECT* pRect = (RECT*) mpClipRgnData->Buffer;
- mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
- pRect++;
-
- for( sal_uLong n = 1; n < pHeader->nCount; n++, pRect++ )
- {
- HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
- CombineRgn( mhRegion, mhRegion, hRgn, RGN_OR );
- DeleteRegion( hRgn );
- }
- }
- }
-
- if ( mpClipRgnData != mpStdClipRgnData )
- delete [] mpClipRgnData;
- }
- }
-
- if( mhRegion )
- {
- SelectClipRgn( getHDC(), mhRegion );
-
- // debug code if you weant to check range of the newly applied ClipRegion
- //RECT aBound;
- //const int aRegionType = GetRgnBox(mhRegion, &aBound);
-
- //bool bBla = true;
- }
- else
- {
- // #i123585# See above, this is a valid case, execute it
- SelectClipRgn( getHDC(), 0 );
- }
-
- // #i123585# retval no longer dependent of mhRegion, see TaskId comments above
- return true;
+ return mpImpl->setClipRegion( i_rClip );
}
void WinSalGraphics::SetLineColor()
{
- // create and select new pen
- HPEN hNewPen = GetStockPen( NULL_PEN );
- HPEN hOldPen = SelectPen( getHDC(), hNewPen );
-
- // destroy or save old pen
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- else
- mhDefPen = hOldPen;
-
- // set new data
- mhPen = hNewPen;
- mbPen = FALSE;
- mbStockPen = TRUE;
+ mpImpl->SetLineColor();
}
void WinSalGraphics::SetLineColor( SalColor nSalColor )
{
- maLineColor = nSalColor;
- COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
- HPEN hNewPen = 0;
- bool bStockPen = FALSE;
-
- // search for stock pen (only screen, because printer have problems,
- // when we use stock objects)
- if ( !mbPrinter )
- {
- SalData* pSalData = GetSalData();
- for ( sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++ )
- {
- if ( nPenColor == pSalData->maStockPenColorAry[i] )
- {
- hNewPen = pSalData->mhStockPenAry[i];
- bStockPen = TRUE;
- break;
- }
- }
- }
-
- // create new pen
- if ( !hNewPen )
- {
- if ( !mbPrinter )
- {
- if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
- nPenColor = PALRGB_TO_RGB( nPenColor );
- }
-
- hNewPen = CreatePen( PS_SOLID, mnPenWidth, nPenColor );
- bStockPen = FALSE;
- }
-
- // select new pen
- HPEN hOldPen = SelectPen( getHDC(), hNewPen );
-
- // destroy or save old pen
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- else
- mhDefPen = hOldPen;
-
- // set new data
- mnPenColor = nPenColor;
- mhPen = hNewPen;
- mbPen = TRUE;
- mbStockPen = bStockPen;
+ mpImpl->SetLineColor( nSalColor );
}
void WinSalGraphics::SetFillColor()
{
- // create and select new brush
- HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush );
-
- // destroy or save old brush
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
- else
- mhDefBrush = hOldBrush;
-
- // set new data
- mhBrush = hNewBrush;
- mbBrush = FALSE;
- mbStockBrush = TRUE;
+ mpImpl->SetFillColor();
}
void WinSalGraphics::SetFillColor( SalColor nSalColor )
{
- maFillColor = nSalColor;
- SalData* pSalData = GetSalData();
- BYTE nRed = SALCOLOR_RED( nSalColor );
- BYTE nGreen = SALCOLOR_GREEN( nSalColor );
- BYTE nBlue = SALCOLOR_BLUE( nSalColor );
- COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
- HBRUSH hNewBrush = 0;
- bool bStockBrush = FALSE;
-
- // search for stock brush (only screen, because printer have problems,
- // when we use stock objects)
- if ( !mbPrinter )
- {
- for ( sal_uInt16 i = 0; i < pSalData->mnStockBrushCount; i++ )
- {
- if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
- {
- hNewBrush = pSalData->mhStockBrushAry[i];
- bStockBrush = TRUE;
- break;
- }
- }
- }
-
- // create new brush
- if ( !hNewBrush )
- {
- if ( mbPrinter || !pSalData->mhDitherDIB )
- hNewBrush = CreateSolidBrush( nBrushColor );
- else
- {
- if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
- {
- BYTE* pTmp = pSalData->mpDitherDIBData;
- long* pDitherDiff = pSalData->mpDitherDiff;
- BYTE* pDitherLow = pSalData->mpDitherLow;
- BYTE* pDitherHigh = pSalData->mpDitherHigh;
-
- for( long nY = 0L; nY < 8L; nY++ )
- {
- for( long nX = 0L; nX < 8L; nX++ )
- {
- const long nThres = aOrdDither16Bit[ nY ][ nX ];
- *pTmp++ = DMAP( nBlue, nThres );
- *pTmp++ = DMAP( nGreen, nThres );
- *pTmp++ = DMAP( nRed, nThres );
- }
- }
-
- hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
- }
- else if ( ImplIsSysColorEntry( nSalColor ) )
- {
- nBrushColor = PALRGB_TO_RGB( nBrushColor );
- hNewBrush = CreateSolidBrush( nBrushColor );
- }
- else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
- hNewBrush = CreateSolidBrush( nBrushColor );
- else
- {
- BYTE* pTmp = pSalData->mpDitherDIBData;
- long* pDitherDiff = pSalData->mpDitherDiff;
- BYTE* pDitherLow = pSalData->mpDitherLow;
- BYTE* pDitherHigh = pSalData->mpDitherHigh;
-
- for ( long nY = 0L; nY < 8L; nY++ )
- {
- for ( long nX = 0L; nX < 8L; nX++ )
- {
- const long nThres = aOrdDither8Bit[ nY ][ nX ];
- *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
- pTmp++;
- }
- }
-
- hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
- }
- }
-
- bStockBrush = FALSE;
- }
-
- // select new brush
- HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush );
-
- // destroy or save old brush
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
- else
- mhDefBrush = hOldBrush;
-
- // set new data
- mnBrushColor = nBrushColor;
- mhBrush = hNewBrush;
- mbBrush = TRUE;
- mbStockBrush = bStockBrush;
+ mpImpl->SetFillColor( nSalColor );
}
-void WinSalGraphics::SetXORMode( bool bSet, bool )
+void WinSalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
{
- mbXORMode = bSet;
- ::SetROP2( getHDC(), bSet ? R2_XORPEN : R2_COPYPEN );
+ mpImpl->SetXORMode( bSet, bInvertOnly );
}
void WinSalGraphics::SetROPLineColor( SalROPColor nROPColor )
{
- SetLineColor( ImplGetROPSalColor( nROPColor ) );
+ mpImpl->SetROPLineColor( nROPColor );
}
void WinSalGraphics::SetROPFillColor( SalROPColor nROPColor )
{
- SetFillColor( ImplGetROPSalColor( nROPColor ) );
+ mpImpl->SetROPFillColor( nROPColor );
}
void WinSalGraphics::drawPixel( long nX, long nY )
{
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)nX, (int)nY, mnPenColor );
+ mpImpl->drawPixel( nX, nY );
}
void WinSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
{
- COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
-
- if ( !mbPrinter &&
- GetSalData()->mhDitherPal &&
- ImplIsSysColorEntry( nSalColor ) )
- nCol = PALRGB_TO_RGB( nCol );
-
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( nCol );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- ::SetPixel( getHDC(), (int)nX, (int)nY, nCol );
+ mpImpl->drawPixel( nX, nY, nSalColor );
}
void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
- MoveToEx( getHDC(), (int)nX1, (int)nY1, NULL );
-
- // we must paint the endpoint
- int bPaintEnd = TRUE;
- if ( nX1 == nX2 )
- {
- bPaintEnd = FALSE;
- if ( nY1 <= nY2 )
- nY2++;
- else
- nY2--;
- }
- if ( nY1 == nY2 )
- {
- bPaintEnd = FALSE;
- if ( nX1 <= nX2 )
- nX2++;
- else
- nX2--;
- }
-
- LineTo( getHDC(), (int)nX2, (int)nY2 );
-
- if ( bPaintEnd && !mbPrinter )
- {
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)nX2, (int)nY2, mnPenColor );
- }
+ mpImpl->drawLine( nX1, nY1, nX2, nY2 );
}
void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
{
- if ( !mbPen )
- {
- if ( !mbPrinter )
- {
- PatBlt( getHDC(), (int)nX, (int)nY, (int)nWidth, (int)nHeight,
- mbXORMode ? PATINVERT : PATCOPY );
- }
- else
- {
- RECT aWinRect;
- aWinRect.left = nX;
- aWinRect.top = nY;
- aWinRect.right = nX+nWidth;
- aWinRect.bottom = nY+nHeight;
- ::FillRect( getHDC(), &aWinRect, mhBrush );
- }
- }
- else
- WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+ mpImpl->drawRect( nX, nY, nWidth, nHeight );
}
void WinSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" );
-
- POINT* pWinPtAry = (POINT*)pPtAry;
-
- // we assume there are at least 2 points (Polyline requres at least 2 point, see MSDN)
- // we must paint the endpoint for last line
- BOOL bPaintEnd = TRUE;
- if ( pWinPtAry[nPoints-2].x == pWinPtAry[nPoints-1].x )
- {
- bPaintEnd = FALSE;
- if ( pWinPtAry[nPoints-2].y <= pWinPtAry[nPoints-1].y )
- pWinPtAry[nPoints-1].y++;
- else
- pWinPtAry[nPoints-1].y--;
- }
- if ( pWinPtAry[nPoints-2].y == pWinPtAry[nPoints-1].y )
- {
- bPaintEnd = FALSE;
- if ( pWinPtAry[nPoints-2].x <= pWinPtAry[nPoints-1].x )
- pWinPtAry[nPoints-1].x++;
- else
- pWinPtAry[nPoints-1].x--;
- }
-
- // for Windows 95 and its maximum number of points
- if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
-
- if ( bPaintEnd && !mbPrinter )
- {
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), mnPenColor );
- }
+ mpImpl->drawPolyLine( nPoints, pPtAry );
}
void WinSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolygon(): POINT != SalPoint" );
-
- POINT* pWinPtAry = (POINT*)pPtAry;
- // for Windows 95 and its maximum number of points
- if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+ mpImpl->drawPolygon( nPoints, pPtAry );
}
void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints,
PCONSTSALPOINT* pPtAry )
{
- UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
- UINT* pWinPointAry;
- UINT nPolyPolyPoints = 0;
- UINT nPoints;
- UINT i;
-
- if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
- pWinPointAry = aWinPointAry;
- else
- pWinPointAry = new UINT[nPoly];
-
- for ( i = 0; i < (UINT)nPoly; i++ )
- {
- nPoints = (UINT)pPoints[i]+1;
- pWinPointAry[i] = nPoints;
- nPolyPolyPoints += nPoints;
- }
-
- POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
- POINT* pWinPointAryAry;
- if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
- pWinPointAryAry = aWinPointAryAry;
- else
- pWinPointAryAry = new POINT[nPolyPolyPoints];
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
- const SalPoint* pPolyAry;
- UINT n = 0;
- for ( i = 0; i < (UINT)nPoly; i++ )
- {
- nPoints = pWinPointAry[i];
- pPolyAry = pPtAry[i];
- memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
- pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
- n += nPoints;
- }
-
- if ( !WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
- (nPolyPolyPoints > MAX_64KSALPOINTS) )
- {
- nPolyPolyPoints = 0;
- nPoly = 0;
- do
- {
- nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
- nPoly++;
- }
- while ( nPolyPolyPoints < MAX_64KSALPOINTS );
- nPoly--;
- if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
- pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
- if ( nPoly == 1 )
- WIN_Polygon( getHDC(), pWinPointAryAry, *pWinPointAry );
- else
- WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, nPoly );
- }
-
- if ( pWinPointAry != aWinPointAry )
- delete [] pWinPointAry;
- if ( pWinPointAryAry != aWinPointAryAry )
- delete [] pWinPointAryAry;
+ mpImpl->drawPolyPolygon( nPoly, pPoints, pPtAry );
}
-#define SAL_POLY_STACKBUF 32
-
bool WinSalGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyLineBezier(): POINT != SalPoint" );
-
- ImplRenderPath( getHDC(), nPoints, pPtAry, pFlgAry );
-
- return true;
-#else
- return false;
-#endif
+ return mpImpl->drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
}
bool WinSalGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolygonBezier(): POINT != SalPoint" );
-
- POINT aStackAry1[SAL_POLY_STACKBUF];
- BYTE aStackAry2[SAL_POLY_STACKBUF];
- POINT* pWinPointAry;
- BYTE* pWinFlagAry;
- if( nPoints > SAL_POLY_STACKBUF )
- {
- pWinPointAry = new POINT[ nPoints ];
- pWinFlagAry = new BYTE[ nPoints ];
- }
- else
- {
- pWinPointAry = aStackAry1;
- pWinFlagAry = aStackAry2;
- }
-
- sal_uInt32 nPoints_i32(nPoints);
- ImplPreparePolyDraw(true, 1, &nPoints_i32, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry);
-
- bool bRet( false );
-
- if( BeginPath( getHDC() ) )
- {
- PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nPoints);
-
- if( EndPath( getHDC() ) )
- {
- if( StrokeAndFillPath( getHDC() ) )
- bRet = true;
- }
- }
-
- if( pWinPointAry != aStackAry1 )
- {
- delete [] pWinPointAry;
- delete [] pWinFlagAry;
- }
-
- return bRet;
-#else
- return false;
-#endif
+ return mpImpl->drawPolygonBezier( nPoints, pPtAry, pFlgAry );
}
bool WinSalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints,
const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyPolygonBezier(): POINT != SalPoint" );
-
- sal_uLong nCurrPoly, nTotalPoints;
- const sal_uInt32* pCurrPoints = pPoints;
- for( nCurrPoly=0, nTotalPoints=0; nCurrPoly<nPoly; ++nCurrPoly )
- nTotalPoints += *pCurrPoints++;
-
- POINT aStackAry1[SAL_POLY_STACKBUF];
- BYTE aStackAry2[SAL_POLY_STACKBUF];
- POINT* pWinPointAry;
- BYTE* pWinFlagAry;
- if( nTotalPoints > SAL_POLY_STACKBUF )
- {
- pWinPointAry = new POINT[ nTotalPoints ];
- pWinFlagAry = new BYTE[ nTotalPoints ];
- }
- else
- {
- pWinPointAry = aStackAry1;
- pWinFlagAry = aStackAry2;
- }
-
- ImplPreparePolyDraw(true, nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry);
-
- bool bRet( false );
-
- if( BeginPath( getHDC() ) )
- {
- PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nTotalPoints);
-
- if( EndPath( getHDC() ) )
- {
- if( StrokeAndFillPath( getHDC() ) )
- bRet = true;
- }
- }
-
- if( pWinPointAry != aStackAry1 )
- {
- delete [] pWinPointAry;
- delete [] pWinFlagAry;
- }
-
- return bRet;
-#else
- return false;
-#endif
+ return mpImpl->drawPolyPolygonBezier( nPoly, pPoints, pPtAry, pFlgAry );
}
-#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
-
static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, sal_uLong nComp, sal_uLong nSize )
{
while ( nComp-- >= nSize )
@@ -1656,6 +811,8 @@ static bool ImplGetBoundingBox( double* nNumb, BYTE* pSource, sal_uLong nSize )
return bRetValue;
}
+#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
+
bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
{
bool bRetValue = false;