|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: brush.c
3: *
4: * Contains the brush realization and dithering code.
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: \**************************************************************************/
8: #include "driver.h"
9:
10: #define OBR_REALIZED 1
11: #define OBR_4BPP 2
12:
13: // aulDefBitMapping is used to translate packed pel into Planar
14:
15: extern ULONG aulDefBitMapping[8];
16: extern ULONG gRealizedBrushHeight[HS_DDI_MAX*2];
17: extern BYTE gaajRealizedPat[HS_DDI_MAX][32];
18:
19: // Asm routines
20:
21: ULONG CountColors(VOID *, ULONG, WORD *, DWORD);
22: BOOL bQuickPattern(BYTE *, ULONG);
23: BOOL bShrinkPattern(BYTE *, ULONG);
24:
25: VOID vMono16Wide(DWORD *, DWORD *, DWORD);
26: VOID vMono8Wide(DWORD *, DWORD *, DWORD);
27: VOID vMono4Wide(DWORD *, DWORD *, DWORD);
28: VOID vMono2Wide(DWORD *, DWORD *, DWORD);
29: VOID vBrush2ColorToMono(BYTE *, BYTE *, DWORD, DWORD, BYTE);
30: VOID vConvert4BppToPlanar(BYTE *, BYTE *, DWORD, DWORD *);
31: VOID vConvert8BppToPlanar(BYTE *, BYTE *, DWORD, DWORD *);
32: VOID vCopyOrgBrush(BYTE *pDest, BYTE *pSrc, LONG lScan, XLATEOBJ *pxlo);
33: VOID vCreatePlaneMasks(BYTE *, BYTE *);
34: SURFOBJ *DrvConvertBrush(SURFOBJ *psoPattern, HBITMAP *phbmTmp, XLATEOBJ *pxlo,
35: ULONG cx, ULONG cy);
36:
37: typedef VOID (*PFNV)();
38:
39: /******************************Public*Routine******************************\
40: * DrvRealizeBrush
41: *
42: *
43: \**************************************************************************/
44:
45: BOOL DrvRealizeBrush(
46: BRUSHOBJ *pbo,
47: SURFOBJ *psoTarget,
48: SURFOBJ *psoPattern,
49: SURFOBJ *psoMask,
50: XLATEOBJ *pxlo,
51: ULONG iHatch)
52: {
53: ULONG cx; // Height of pattern surface
54: ULONG cy; // Width of pattern surface
55: LONG cbScan; // Width in bytes of one scan
56: PVOID pvBits; // Source bits
57: ULONG *pulXlate; // Color translation
58: HBITMAP hbmTmp; // Temp bmp handle for brush conversion
59: BRUSHINST *pbri; // pointer to where realization goes
60: BYTE jBkColor, jFgColor; // local copies of mono attributes
61: PFNV pfnConvert; // function pointer to mono conversion
62: BYTE jColors[2]; // place holder for special color->mono
63: // conversion.
64: BOOL bConversion = FALSE; // True if we converted to 4bpp
65:
66: cx = psoPattern->sizlBitmap.cx;
67: cy = psoPattern->sizlBitmap.cy;
68:
69: if ((cy != 8) || (cx > 16))
70: {
71: return(FALSE);
72: }
73:
74: pbri = BRUSHOBJ_pvAllocRbrush(pbo,sizeof(BRUSHINST));
75: if (pbri == (BRUSHINST *)NULL)
76: return(FALSE);
77:
78: pbri->RealWidth = (BYTE)cx;
79:
80: switch (psoPattern->iBitmapFormat)
81: {
82: case BMF_1BPP:
83: case BMF_4BPP:
84: case BMF_8BPP:
85: break;
86:
87: default:
88: if ((cx != 8) && (cx != 16))
89: return(FALSE);
90:
91: // Convert to 4bpp
92:
93: psoPattern = DrvConvertBrush(psoPattern, &hbmTmp, pxlo, cx, cy);
94: if (psoPattern == (SURFOBJ *)NULL)
95: return(FALSE);
96:
97: bConversion = TRUE;
98: break;
99: }
100:
101: //
102: // Setup the pointer to the bits, and the scan-to-scan advance direction.
103: //
104: cbScan = psoPattern->lDelta;
105: pvBits = psoPattern->pvScan0;
106:
107: //
108: // If this is a hatch brush, we already have it in realized form.
109: //
110: if ((iHatch < HS_DDI_MAX) && (psoPattern->iBitmapFormat == BMF_1BPP))
111: {
112: pbri->usStyle = BRI_MONO_PATTERN;
113: pbri->fjAccel = 0;
114: pbri->Width = 16;
115: pbri->Height = gRealizedBrushHeight[iHatch*2];
116: pbri->YShiftValue = (BYTE)gRealizedBrushHeight[(iHatch*2)+1];
117: pbri->pPattern = (BYTE *)&(gaajRealizedPat[iHatch]);
118: pbri->jBkColor = (BYTE)pxlo->pulXlate[0];
119: pbri->jFgColor = (BYTE)pxlo->pulXlate[1];
120: pbri->jOldBrushRealized = 0;
121:
122: return(TRUE);
123: }
124:
125: if (psoPattern->iBitmapFormat == BMF_1BPP)
126: {
127: switch (cx) {
128: case 16:
129: if ((bShrinkPattern)((BYTE *)pvBits, cbScan))
130: {
131: cx = 8;
132: pbri->RealWidth = (BYTE)cx;
133: } else {
134: pfnConvert = vMono16Wide;
135: break;
136: }
137: case 8:
138: pfnConvert = vMono8Wide;
139: break;
140:
141: case 2:
142: pfnConvert = vMono2Wide;
143: break;
144:
145: case 4:
146: pfnConvert = vMono4Wide;
147: break;
148:
149: default:
150: return(FALSE);
151: }
152:
153: pbri->usStyle = BRI_MONO_PATTERN;
154: pbri->fjAccel = 0;
155: pbri->jBkColor = (BYTE)pxlo->pulXlate[0];
156: pbri->jFgColor = (BYTE)pxlo->pulXlate[1];
157: pbri->Width = 16;
158: pbri->pPattern = (BYTE *)&(pbri->ajPattern[0]);
159: pbri->jOldBrushRealized = 0;
160:
161: (*pfnConvert)(pbri->pPattern, pvBits, cbScan);
162:
163: if (bQuickPattern(pbri->pPattern, 8))
164: {
165: pbri->Height = 2;
166: pbri->YShiftValue = 1;
167: }
168: else
169: {
170: pbri->Height = 8;
171: pbri->YShiftValue = 3;
172: }
173:
174: return(TRUE);
175: }
176:
177: if ((cx != 8) && (cx != 16))
178: return(FALSE);
179:
180: if (pxlo->flXlate & XO_TABLE)
181: pulXlate = pxlo->pulXlate;
182: else
183: pulXlate = (PULONG)NULL;
184:
185: if ((psoPattern->iBitmapFormat == BMF_4BPP) &&
186: (CountColors(pvBits, cx, (WORD *)&jColors, cbScan) == 2)) {
187:
188: if ((cx == 16) && (bShrinkPattern)((BYTE *)pvBits, cbScan))
189: {
190: cx = 8;
191: pbri->RealWidth = (BYTE)cx;
192: }
193:
194: pbri->usStyle = BRI_MONO_PATTERN;
195: pbri->Height = 8;
196: pbri->YShiftValue = 3;
197: pbri->Width = 16;
198: pbri->fjAccel = 1;
199: pbri->pPattern = (BYTE *)&(pbri->ajPattern[0]);
200: pbri->jOldBrushRealized = OBR_4BPP;
201:
202: if (pulXlate != (PULONG)NULL) {
203:
204: jBkColor = (BYTE)pulXlate[jColors[0]];
205: jFgColor = (BYTE)pulXlate[jColors[1]];
206: } else {
207:
208: jBkColor = jColors[0];
209: jFgColor = jColors[1];
210: }
211:
212: if (jBkColor > jFgColor) {
213: pbri->jBkColor = jBkColor;
214: pbri->jFgColor = jFgColor;
215: } else {
216: pbri->jBkColor = jFgColor;
217: pbri->jFgColor = jBkColor;
218: }
219:
220:
221: vBrush2ColorToMono(pbri->pPattern, (BYTE *)pvBits, cbScan,
222: cx, pbri->jBkColor);
223:
224: if (bQuickPattern(pbri->pPattern, 8))
225: {
226: pbri->Height = 2;
227: pbri->YShiftValue = 1;
228: }
229:
230: vCopyOrgBrush(&(pbri->ajC0[0]),pvBits, cbScan, pxlo);
231:
232: if (bConversion) {
233: EngUnlockSurface(psoPattern);
234: EngDeleteSurface((HSURF)hbmTmp);
235: }
236:
237: return(TRUE);
238: }
239: else if (cx != 8)
240: return(FALSE);
241:
242: pbri->pPattern = (BYTE *)&(pbri->ajC0[0]);
243:
244: // At this point we know we have an 8x8 color pattern in either a
245: // 4bpp or 8bpp format.
246:
247: if (psoPattern->iBitmapFormat == BMF_4BPP)
248: vConvert4BppToPlanar(pbri->pPattern, (BYTE *)pvBits, cbScan, pulXlate);
249:
250: else // 8bpp
251: vConvert8BppToPlanar(pbri->pPattern, (BYTE *)pvBits, cbScan, pulXlate);
252: #ifdef FAST_PLANE
253: vCreatePlaneMasks(&(pbri->ajPlaneMasks),pbri->pPattern);
254: #endif
255: // Set proper accelerators in the brush for the output code.
256:
257: pbri->usStyle = BRI_COLOR_PATTERN; // Brush style is arbitrary pattern
258: pbri->fjAccel = 0; // Accelerator flags - no special casing
259: pbri->Height = 8;
260: pbri->YShiftValue = 3;
261: pbri->Width = 8;
262: pbri->fjAccel = 1;
263: pbri->jOldBrushRealized = OBR_REALIZED|OBR_4BPP;
264:
265: if (bConversion) {
266: EngUnlockSurface(psoPattern);
267: EngDeleteSurface((HSURF)hbmTmp);
268: }
269:
270: return(TRUE);
271: }
272:
273: /****************************************************************************\
274: * DrvvConvertBrush()
275: *
276: * Converts a brush to a 4bpp bmp
277: *
278: \****************************************************************************/
279:
280: SURFOBJ *DrvConvertBrush(
281: SURFOBJ *psoPattern,
282: HBITMAP *phbmTmp,
283: XLATEOBJ *pxlo,
284: ULONG cx,
285: ULONG cy)
286: {
287: SURFOBJ *psoTmp;
288: RECTL rclTmp;
289: SIZEL sizlTmp;
290: POINTL ptl;
291:
292: ptl.x = 0;
293: ptl.y = 0;
294: rclTmp.top = 0;
295: rclTmp.left = 0;
296: rclTmp.right = cx;
297: sizlTmp.cx = cx;
298: rclTmp.bottom = cy;
299: sizlTmp.cy = cy;
300:
301: // Create bitmap in our compatible format.
302:
303: *phbmTmp = EngCreateBitmap(sizlTmp, cx / 2, BMF_4BPP, 0, NULL);
304:
305: if ((*phbmTmp) && ((psoTmp = EngLockSurface((HSURF)*phbmTmp)) != NULL))
306: {
307: if (EngCopyBits(psoTmp, psoPattern, NULL, pxlo, &rclTmp, &ptl))
308: return(psoTmp);
309:
310: EngUnlockSurface(psoTmp);
311: EngDeleteSurface((HSURF)*phbmTmp);
312: }
313:
314: return((SURFOBJ *)NULL);
315: }
316:
317:
318: /****************************************************************************\
319: * vCopyOrgBrush
320: *
321: * When we realize a mono or 2 color brush, we copy the original 4bpp brush
322: * to the ajC0 area of the realized brush. If we are called to do a
323: * rop that we don't directly support, vConvertBrush will be called to
324: * convert the orginal 4bpp brush to a planar brush that the blt compiler can
325: * use. Since this is a rare event, we do this on request instead of at
326: * realization time.
327: *
328: \****************************************************************************/
329:
330: VOID vCopyOrgBrush(
331: BYTE *pDest,
332: BYTE *pSrc,
333: LONG lScan,
334: XLATEOBJ *pxlo)
335: {
336: ULONG *pulXlate, *pulDest;
337: BYTE jByte, jColor;
338: int i;
339:
340: if (pxlo->flXlate & XO_TABLE) {
341: pulXlate = pxlo->pulXlate;
342:
343: for (i=0;i<32;i++) {
344:
345: jColor = *pSrc; // Get Next byte
346: jByte = jColor;
347:
348: jByte = pulXlate[jByte & 0xf];
349: jByte = pulXlate[(jColor >> 4) & 0xf] << 4;
350: *pDest = jByte;
351:
352: pSrc += lScan;
353: pDest++;
354: }
355: } else {
356: pulDest = (ULONG *)pDest;
357:
358: for (i=0;i<8;i++) {
359: *pulDest = *(ULONG *)pSrc;
360:
361: pSrc += lScan;
362: pulDest++;
363: }
364:
365: }
366: }
367:
368:
369: /****************************************************************************\
370: * vConvertBrush()
371: *
372: * This called when we are going to do a rop3 with a non-solid brush. We have
373: * to convert our brush back to the old blt compiler format in order for this
374: * blt to work properly.
375: *
376: \****************************************************************************/
377:
378: BOOL bConvertBrush(
379: BRUSHINST *pbri)
380: {
381: BYTE jPattern[32];
382: if (pbri->jOldBrushRealized & OBR_REALIZED)
383: return(TRUE);
384:
385: //
386: // The blt compiler only handles 8x8
387: //
388: if (pbri->RealWidth != 8)
389: return(FALSE);
390:
391: if (pbri->jOldBrushRealized & OBR_4BPP) {
392: memcpy(&(jPattern[0]), &(pbri->ajC0[0]), 32);
393: vConvert4BppToPlanar(&(pbri->ajC0[0]), &(jPattern[0]), 4, NULL);
394: pbri->jOldBrushRealized |= OBR_REALIZED;
395:
396: return(TRUE);
397: }
398:
399: return(FALSE);
400: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.