wine/dlls/wineps/brush.c
Huw Davies a45df5d991 Rework clipping so that the PS clip path is only set just before any
graphics output event. Doing it this way means we don't ever need to
call initclip which is a Good Thing.
2003-05-19 19:06:47 +00:00

258 lines
6.1 KiB
C

/*
* PostScript brush handling
*
* Copyright 1998 Huw D M Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "psdrv.h"
#include "wine/debug.h"
#include "winbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
/***********************************************************************
* SelectBrush (WINEPS.@)
*/
HBRUSH PSDRV_SelectBrush( PSDRV_PDEVICE *physDev, HBRUSH hbrush )
{
LOGBRUSH logbrush;
if (!GetObjectA( hbrush, sizeof(logbrush), &logbrush )) return 0;
TRACE("hbrush = %p\n", hbrush);
switch(logbrush.lbStyle) {
case BS_SOLID:
PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
break;
case BS_NULL:
break;
case BS_HATCHED:
PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
break;
case BS_PATTERN:
case BS_DIBPATTERN:
break;
default:
FIXME("Unrecognized brush style %d\n", logbrush.lbStyle);
break;
}
physDev->brush.set = FALSE;
return hbrush;
}
/**********************************************************************
*
* PSDRV_SetBrush
*
*/
static BOOL PSDRV_SetBrush(PSDRV_PDEVICE *physDev)
{
LOGBRUSH logbrush;
BOOL ret = TRUE;
if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
{
ERR("Can't get BRUSHOBJ\n");
return FALSE;
}
switch (logbrush.lbStyle) {
case BS_SOLID:
case BS_HATCHED:
PSDRV_WriteSetColor(physDev, &physDev->brush.color);
break;
case BS_NULL:
break;
default:
ret = FALSE;
break;
}
physDev->brush.set = TRUE;
return TRUE;
}
/**********************************************************************
*
* PSDRV_Fill
*
*/
static BOOL PSDRV_Fill(PSDRV_PDEVICE *physDev, BOOL EO)
{
if(!EO)
return PSDRV_WriteFill(physDev);
else
return PSDRV_WriteEOFill(physDev);
}
/**********************************************************************
*
* PSDRV_Clip
*
*/
static BOOL PSDRV_Clip(PSDRV_PDEVICE *physDev, BOOL EO)
{
if(!EO)
return PSDRV_WriteClip(physDev);
else
return PSDRV_WriteEOClip(physDev);
}
/**********************************************************************
*
* PSDRV_Brush
*
*/
BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO)
{
LOGBRUSH logbrush;
BOOL ret = TRUE;
if(physDev->pathdepth)
return FALSE;
if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
{
ERR("Can't get BRUSHOBJ\n");
return FALSE;
}
switch (logbrush.lbStyle) {
case BS_SOLID:
PSDRV_WriteGSave(physDev);
PSDRV_SetBrush(physDev);
PSDRV_Fill(physDev, EO);
PSDRV_WriteGRestore(physDev);
break;
case BS_HATCHED:
PSDRV_WriteGSave(physDev);
PSDRV_SetBrush(physDev);
switch(logbrush.lbHatch) {
case HS_VERTICAL:
case HS_CROSS:
PSDRV_WriteGSave(physDev);
PSDRV_Clip(physDev, EO);
PSDRV_WriteHatch(physDev);
PSDRV_WriteStroke(physDev);
PSDRV_WriteGRestore(physDev);
if(logbrush.lbHatch == HS_VERTICAL)
break;
/* else fallthrough for HS_CROSS */
case HS_HORIZONTAL:
PSDRV_WriteGSave(physDev);
PSDRV_Clip(physDev, EO);
PSDRV_WriteRotate(physDev, 90.0);
PSDRV_WriteHatch(physDev);
PSDRV_WriteStroke(physDev);
PSDRV_WriteGRestore(physDev);
break;
case HS_FDIAGONAL:
case HS_DIAGCROSS:
PSDRV_WriteGSave(physDev);
PSDRV_Clip(physDev, EO);
PSDRV_WriteRotate(physDev, -45.0);
PSDRV_WriteHatch(physDev);
PSDRV_WriteStroke(physDev);
PSDRV_WriteGRestore(physDev);
if(logbrush.lbHatch == HS_FDIAGONAL)
break;
/* else fallthrough for HS_DIAGCROSS */
case HS_BDIAGONAL:
PSDRV_WriteGSave(physDev);
PSDRV_Clip(physDev, EO);
PSDRV_WriteRotate(physDev, 45.0);
PSDRV_WriteHatch(physDev);
PSDRV_WriteStroke(physDev);
PSDRV_WriteGRestore(physDev);
break;
default:
ERR("Unknown hatch style\n");
ret = FALSE;
break;
}
PSDRV_WriteGRestore(physDev);
break;
case BS_NULL:
break;
case BS_PATTERN:
{
BITMAP bm;
BYTE *bits;
GetObjectA( (HBITMAP)logbrush.lbHatch, sizeof(BITMAP), &bm);
TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
bm.bmBitsPixel);
bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
GetBitmapBits( (HBITMAP)logbrush.lbHatch, bm.bmWidthBytes * bm.bmHeight, bits);
if(physDev->pi->ppd->LanguageLevel > 1) {
PSDRV_WriteGSave(physDev);
PSDRV_WritePatternDict(physDev, &bm, bits);
PSDRV_Fill(physDev, EO);
PSDRV_WriteGRestore(physDev);
} else {
FIXME("Trying to set a pattern brush on a level 1 printer\n");
ret = FALSE;
}
HeapFree(PSDRV_Heap, 0, bits);
}
break;
case BS_DIBPATTERN:
{
BITMAPINFO *bmi = GlobalLock16(logbrush.lbHatch);
UINT usage = logbrush.lbColor;
TRACE("size %ldx%ldx%d\n", bmi->bmiHeader.biWidth,
bmi->bmiHeader.biHeight, bmi->bmiHeader.biBitCount);
if(physDev->pi->ppd->LanguageLevel > 1) {
PSDRV_WriteGSave(physDev);
ret = PSDRV_WriteDIBPatternDict(physDev, bmi, usage);
PSDRV_Fill(physDev, EO);
PSDRV_WriteGRestore(physDev);
} else {
FIXME("Trying to set a pattern brush on a level 1 printer\n");
ret = FALSE;
}
GlobalUnlock16(logbrush.lbHatch);
}
break;
default:
ret = FALSE;
break;
}
return ret;
}