brush.c 6.11 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4 5
/*
 *	PostScript brush handling
 *
 * Copyright 1998  Huw D M Davies
 *
6 7 8 9 10 11 12 13 14 15 16 17
 * 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
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20 21
 */

#include "psdrv.h"
22
#include "wine/debug.h"
23
#include "winbase.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
24

25
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
26

Alexandre Julliard's avatar
Alexandre Julliard committed
27
/***********************************************************************
28
 *           SelectBrush   (WINEPS.@)
Alexandre Julliard's avatar
Alexandre Julliard committed
29
 */
30
HBRUSH CDECL PSDRV_SelectBrush( PSDRV_PDEVICE *physDev, HBRUSH hbrush )
Alexandre Julliard's avatar
Alexandre Julliard committed
31
{
32
    LOGBRUSH logbrush;
Alexandre Julliard's avatar
Alexandre Julliard committed
33

34 35
    if (!GetObjectA( hbrush, sizeof(logbrush), &logbrush )) return 0;

36
    TRACE("hbrush = %p\n", hbrush);
Alexandre Julliard's avatar
Alexandre Julliard committed
37

38
    switch(logbrush.lbStyle) {
Alexandre Julliard's avatar
Alexandre Julliard committed
39 40

    case BS_SOLID:
41
        PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
Alexandre Julliard's avatar
Alexandre Julliard committed
42 43 44 45 46 47
	break;

    case BS_NULL:
        break;

    case BS_HATCHED:
48
        PSDRV_CreateColor(physDev, &physDev->brush.color, logbrush.lbColor);
49 50
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
51
    case BS_PATTERN:
52
    case BS_DIBPATTERN:
Alexandre Julliard's avatar
Alexandre Julliard committed
53 54 55
	break;

    default:
56
        FIXME("Unrecognized brush style %d\n", logbrush.lbStyle);
Alexandre Julliard's avatar
Alexandre Julliard committed
57 58 59 60
	break;
    }

    physDev->brush.set = FALSE;
61
    return hbrush;
Alexandre Julliard's avatar
Alexandre Julliard committed
62 63 64 65 66 67 68 69
}


/**********************************************************************
 *
 *	PSDRV_SetBrush
 *
 */
70
static BOOL PSDRV_SetBrush(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
71
{
72
    LOGBRUSH logbrush;
73
    BOOL ret = TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
74

75
    if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
76
    {
77
        ERR("Can't get BRUSHOBJ\n");
78 79
	return FALSE;
    }
80 81

    switch (logbrush.lbStyle) {
Alexandre Julliard's avatar
Alexandre Julliard committed
82
    case BS_SOLID:
83
    case BS_HATCHED:
84
        PSDRV_WriteSetColor(physDev, &physDev->brush.color);
Alexandre Julliard's avatar
Alexandre Julliard committed
85 86
	break;

87 88 89
    case BS_NULL:
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
90
    default:
91
        ret = FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
92 93 94 95 96 97
        break;

    }
    physDev->brush.set = TRUE;
    return TRUE;
}
98 99 100 101 102 103 104


/**********************************************************************
 *
 *	PSDRV_Fill
 *
 */
105
static BOOL PSDRV_Fill(PSDRV_PDEVICE *physDev, BOOL EO)
106 107
{
    if(!EO)
108
        return PSDRV_WriteFill(physDev);
109
    else
110
        return PSDRV_WriteEOFill(physDev);
111 112 113 114 115 116 117 118
}


/**********************************************************************
 *
 *	PSDRV_Clip
 *
 */
119
static BOOL PSDRV_Clip(PSDRV_PDEVICE *physDev, BOOL EO)
120 121
{
    if(!EO)
122
        return PSDRV_WriteClip(physDev);
123
    else
124
        return PSDRV_WriteEOClip(physDev);
125 126 127 128 129 130 131
}

/**********************************************************************
 *
 *	PSDRV_Brush
 *
 */
132
BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO)
133
{
134
    LOGBRUSH logbrush;
135
    BOOL ret = TRUE;
136

137 138 139
    if(physDev->pathdepth)
        return FALSE;

140
    if (!GetObjectA( GetCurrentObject(physDev->hdc,OBJ_BRUSH), sizeof(logbrush), &logbrush ))
141
    {
142
        ERR("Can't get BRUSHOBJ\n");
143 144 145
	return FALSE;
    }

146
    switch (logbrush.lbStyle) {
147
    case BS_SOLID:
148
	PSDRV_WriteGSave(physDev);
149
        PSDRV_SetBrush(physDev);
150 151
        PSDRV_Fill(physDev, EO);
	PSDRV_WriteGRestore(physDev);
152 153 154
	break;

    case BS_HATCHED:
155
        PSDRV_WriteGSave(physDev);
156
        PSDRV_SetBrush(physDev);
157

158
	switch(logbrush.lbHatch) {
159 160
	case HS_VERTICAL:
	case HS_CROSS:
161
            PSDRV_WriteGSave(physDev);
162 163 164 165
	    PSDRV_Clip(physDev, EO);
	    PSDRV_WriteHatch(physDev);
	    PSDRV_WriteStroke(physDev);
	    PSDRV_WriteGRestore(physDev);
166
	    if(logbrush.lbHatch == HS_VERTICAL)
167 168 169 170
	        break;
	    /* else fallthrough for HS_CROSS */

	case HS_HORIZONTAL:
171
            PSDRV_WriteGSave(physDev);
172 173 174 175 176
	    PSDRV_Clip(physDev, EO);
	    PSDRV_WriteRotate(physDev, 90.0);
	    PSDRV_WriteHatch(physDev);
	    PSDRV_WriteStroke(physDev);
	    PSDRV_WriteGRestore(physDev);
177 178 179 180
	    break;

	case HS_FDIAGONAL:
	case HS_DIAGCROSS:
181 182 183 184 185 186
	    PSDRV_WriteGSave(physDev);
	    PSDRV_Clip(physDev, EO);
	    PSDRV_WriteRotate(physDev, -45.0);
	    PSDRV_WriteHatch(physDev);
	    PSDRV_WriteStroke(physDev);
	    PSDRV_WriteGRestore(physDev);
187
	    if(logbrush.lbHatch == HS_FDIAGONAL)
188 189
	        break;
	    /* else fallthrough for HS_DIAGCROSS */
190

191
	case HS_BDIAGONAL:
192 193 194 195 196 197
	    PSDRV_WriteGSave(physDev);
	    PSDRV_Clip(physDev, EO);
	    PSDRV_WriteRotate(physDev, 45.0);
	    PSDRV_WriteHatch(physDev);
	    PSDRV_WriteStroke(physDev);
	    PSDRV_WriteGRestore(physDev);
198 199 200
	    break;

	default:
201
	    ERR("Unknown hatch style\n");
202 203
	    ret = FALSE;
            break;
204
	}
205
        PSDRV_WriteGRestore(physDev);
206 207 208 209 210
	break;

    case BS_NULL:
	break;

211 212 213 214
    case BS_PATTERN:
        {
	    BITMAP bm;
	    BYTE *bits;
215
	    GetObjectA( (HBITMAP)logbrush.lbHatch, sizeof(BITMAP), &bm);
216 217 218
	    TRACE("BS_PATTERN %dx%d %d bpp\n", bm.bmWidth, bm.bmHeight,
		  bm.bmBitsPixel);
	    bits = HeapAlloc(PSDRV_Heap, 0, bm.bmWidthBytes * bm.bmHeight);
219
	    GetBitmapBits( (HBITMAP)logbrush.lbHatch, bm.bmWidthBytes * bm.bmHeight, bits);
220

221
	    if(physDev->pi->ppd->LanguageLevel > 1) {
222 223 224 225
	        PSDRV_WriteGSave(physDev);
	        PSDRV_WritePatternDict(physDev, &bm, bits);
		PSDRV_Fill(physDev, EO);
		PSDRV_WriteGRestore(physDev);
226 227
	    } else {
	        FIXME("Trying to set a pattern brush on a level 1 printer\n");
228
		ret = FALSE;
229
	    }
230
	    HeapFree(PSDRV_Heap, 0, bits);
231 232 233
	}
	break;

234 235 236 237
    case BS_DIBPATTERN:
        {
	    BITMAPINFO *bmi = GlobalLock16(logbrush.lbHatch);
	    UINT usage = logbrush.lbColor;
238
	    TRACE("size %dx%dx%d\n", bmi->bmiHeader.biWidth,
239 240 241 242 243 244 245 246 247 248 249 250 251 252
		  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;

253
    default:
254
        ret = FALSE;
255 256
	break;
    }
257
    return ret;
258
}