| /* | 
 |  *	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 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; | 
 | } |