|  | /* | 
|  | *	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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
|  | */ | 
|  |  | 
|  | #include "psdrv.h" | 
|  | #include "wine/debug.h" | 
|  | #include "winbase.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(psdrv); | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           SelectBrush   (WINEPS.@) | 
|  | */ | 
|  | HBRUSH CDECL 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 %dx%dx%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; | 
|  | } |