|
|
1.1 root 1: /****************************************************************************/
2: /* */
3: /* Microsoft Confidential */
4: /* */
5: /* Copyright (c) Microsoft Corp. 1987, 1991 */
6: /* All Rights Reserved */
7: /* */
8: /****************************************************************************/
9: /****************************** Module Header *******************************
10: * Module Name: image.c
11: *
12: * Routines for manipulating images.
13: *
14: * History:
15: *
16: ****************************************************************************/
17:
18: #include "imagedit.h"
19:
20:
21:
22: /************************************************************************
23: * ImageDCCreate
24: *
25: * Allocates the image DC's and bitmaps used to hold the current image
26: * being edited. This includes ghdcImage and ghbmImage. For icons and
27: * cursors, also allocates the DC and bitmap that holds the AND mask
28: * that contains information about whether any given pixel is screen
29: * color, inverted screen color or a true color. These globals are
30: * ghdcANDMask and ghbmANDMask.
31: *
32: * The image DC will contain the image as it will appear when displayed.
33: * For icons and cursors, this means that it is the combined XOR and AND
34: * portions of the image. When the icon/cursor file is saved, the bits
35: * will be separated back out, but having them combined in the image
36: * makes it fast to display the image while editing. Because of this,
37: * however, care must be taken when changing the screen color because
38: * it is not possible to determine from the image DC alone whether a
39: * pixel is screen color or simply a true color that happens to be the
40: * same as the current screen color. The AND mask is very important for
41: * keeping this straight and must be properly updated when drawing on
42: * the image DC with any of the drawing tools!
43: *
44: * Arguments:
45: * INT iType - Type of image.
46: * INT cx - Width of the image.
47: * INT cy - Height of the image.
48: * INT nColors - Number of colors.
49: *
50: * Returns TRUE if successful, or FALSE if an error occurs.
51: *
52: * History:
53: *
54: ************************************************************************/
55:
56: BOOL ImageDCCreate(
57: INT iType,
58: INT cx,
59: INT cy,
60: INT nColors)
61: {
62: HDC hdcParent;
63:
64: /*
65: * Delete the old image DC's.
66: */
67: ImageDCDelete();
68:
69: hdcParent = GetDC(ghwndMain);
70:
71: if (!(ghdcImage = CreateCompatibleDC(hdcParent)))
72: goto Error1;
73:
74: if (!(ghbmImage = MyCreateBitmap(hdcParent, cx, cy, 16)))
75: goto Error2;
76:
77: SelectObject(ghdcImage, ghbmImage);
78:
79: /*
80: * If image is an icon or cursor, also allocate the AND mask
81: * DC and bitmap. Note that this cannot be a DIB (must use
82: * CreateBitmap) or the ImageDCSeparate() code will fail.
83: */
84: if (iType == FT_ICON || iType == FT_CURSOR) {
85: if (!(ghdcANDMask = CreateCompatibleDC(hdcParent)))
86: goto Error2;
87:
88: if (!(ghbmANDMask = CreateBitmap(cx, cy, (BYTE)1, (BYTE)1, NULL)))
89: goto Error3;
90:
91: SelectObject(ghdcANDMask, ghbmANDMask);
92: }
93:
94: ReleaseDC(ghwndMain, hdcParent);
95:
96: /*
97: * Set some globals.
98: */
99: gcxImage = cx;
100: gcyImage = cy;
101: gnColors = nColors;
102:
103: /*
104: * Initialize the bits.
105: */
106: ImageDCClear();
107:
108: return TRUE;
109:
110: Error3:
111: DeleteDC(ghdcANDMask);
112: ghdcANDMask = NULL;
113:
114: Error2:
115: DeleteDC(ghdcImage);
116: ghdcImage = NULL;
117:
118: Error1:
119: ReleaseDC(ghwndMain, hdcParent);
120:
121: return FALSE;
122: }
123:
124:
125:
126: /************************************************************************
127: * ImageDCDelete
128: *
129: * Deletes the current image DC. For icons and cursors, also deletes the
130: * mask DC. Finally, it destroys the undo buffers.
131: *
132: * History:
133: *
134: ************************************************************************/
135:
136: VOID ImageDCDelete(VOID)
137: {
138: if (ghdcImage) {
139: DeleteDC(ghdcImage);
140: ghdcImage = NULL;
141: DeleteObject(ghbmImage);
142: ghbmImage = NULL;
143: }
144:
145: if (ghdcANDMask) {
146: DeleteDC(ghdcANDMask);
147: ghdcANDMask = NULL;
148: DeleteObject(ghbmANDMask);
149: ghbmANDMask = NULL;
150: }
151:
152: /*
153: * Destroy the undo buffer.
154: */
155: ImageFreeUndo();
156: }
157:
158:
159:
160: /************************************************************************
161: * ImageDCClear
162: *
163: * Clears the image DC. Sets it to completely white. For icons and
164: * cursors, sets the image mask to be fully opaque also.
165: *
166: * History:
167: *
168: ************************************************************************/
169:
170: VOID ImageDCClear(VOID)
171: {
172: PatBlt(ghdcImage, 0, 0, gcxImage, gcyImage, WHITENESS);
173:
174: /*
175: * For icons and cursors, set all the mask bits to zero.
176: */
177: if (ghdcANDMask)
178: PatBlt(ghdcANDMask, 0, 0, gcxImage, gcyImage, BLACKNESS);
179: }
180:
181:
182:
183: /************************************************************************
184: * ImageDCSeparate
185: *
186: * This function separates out the XOR mask in hdcImage so that it does
187: * not have any pixels that are screen/inverse color. This must be done
188: * prior to saving the image (or changing the screen color) because
189: * normally the hdcImage contains the image as it will be displayed,
190: * which is really a combined view of the XOR and AND masks. The function
191: * ImageDCCombine can be used after this function to combine the masks
192: * back together.
193: *
194: * History:
195: *
196: ************************************************************************/
197:
198: VOID ImageDCSeparate(
199: HDC hdcImage,
200: INT cx,
201: INT cy,
202: HDC hdcANDMask,
203: DWORD rgbScreen)
204: {
205: HBITMAP hbmTemp;
206: HDC hdcTemp;
207: HBITMAP hbmOld;
208:
209: /*
210: * Create a temporary bitmap and DC for the mask bits and
211: * select bitmap into the DC.
212: */
213: hdcTemp = CreateCompatibleDC(hdcImage);
214: hbmTemp = CreateCompatibleBitmap(hdcImage, cx, cy);
215: hbmOld = SelectObject(hdcTemp, hbmTemp);
216:
217: /*
218: * Background color of temporary DC is set to the specified
219: * screen (transparent) color. The bits from mask DC (mono) are
220: * transferred to temp. DC (color). Thus the 1s in the mask (corresp.
221: * to "screen" and "inverse" portions) become "screen" colored pixels
222: * in temporary DC.
223: */
224: SetBkColor(hdcTemp, rgbScreen);
225: BitBlt(hdcTemp, 0, 0, cx, cy, hdcANDMask, 0, 0, SRCCOPY);
226:
227: /*
228: * The bits in the temporary DC are XORed against the bits in the image
229: * DC to recover the true XOR mask in hdcImage. The AND mask is already
230: * in hdcANDMask.
231: */
232: BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCINVERT);
233:
234: SelectObject(hdcTemp, hbmOld);
235: DeleteDC(hdcTemp);
236: DeleteObject(hbmTemp);
237: }
238:
239:
240:
241: /************************************************************************
242: * ImageDCCombine
243: *
244: * This function takes the raw XOR mask in hdcImage and combines
245: * it with the AND mask in hdcANDMask to put into hdcImage the
246: * current image as it will be displayed. This needs to be done after
247: * it is separated (just prior to saving the file and also when changing
248: * the screen color) and when the image is first opened.
249: *
250: * The current screen color in ghbrScreen is used when combining the
251: * image in this routine.
252: *
253: * History:
254: *
255: ************************************************************************/
256:
257: VOID ImageDCCombine(
258: HDC hdcImage,
259: INT cx,
260: INT cy,
261: HDC hdcANDMask)
262: {
263: HBITMAP hbmTemp;
264: HDC hdcTemp;
265: HBITMAP hbmOld;
266: HBRUSH hbrOld;
267:
268: /*
269: * Make a copy of the image DC with the XOR mask in it.
270: */
271: hdcTemp = CreateCompatibleDC(hdcImage);
272: hbmTemp = CreateCompatibleBitmap(hdcImage, cx, cy);
273: hbmOld = SelectObject(hdcTemp, hbmTemp);
274: BitBlt(hdcTemp, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);
275:
276: /*
277: * Clear the image DC to the current screen color.
278: */
279: hbrOld = SelectObject(hdcImage, ghbrScreen);
280: PatBlt(hdcImage, 0, 0, cx, cy , PATCOPY);
281: SelectObject(hdcImage, hbrOld);
282:
283: /*
284: * Reconstruct the image by superimposing the XOR and AND masks.
285: */
286: BitBlt(hdcImage, 0, 0, cx, cy, hdcANDMask, 0, 0, SRCAND);
287: BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCINVERT);
288:
289: SelectObject(hdcTemp, hbmOld);
290: DeleteDC(hdcTemp);
291: DeleteObject(hbmTemp);
292: }
293:
294:
295:
296: /************************************************************************
297: * ImageDCMonoBlt
298: *
299: * This function blts an image onto a monochrome bitmap, then back
300: * again. This converts it to a monochrome image.
301: *
302: * History:
303: *
304: ************************************************************************/
305:
306: VOID ImageDCMonoBlt(
307: HDC hdcImage,
308: INT cx,
309: INT cy)
310: {
311: HBITMAP hbmTemp;
312: HDC hdcTemp;
313: HBITMAP hbmOld;
314:
315: /*
316: * Create a temporary monochrome bitmap and dc.
317: */
318: hdcTemp = CreateCompatibleDC(hdcImage);
319: hbmTemp = MyCreateBitmap(hdcImage, cx, cy, 2);
320: hbmOld = SelectObject(hdcTemp, hbmTemp);
321:
322: /*
323: * Blt the image to the mono bitmap, then back again.
324: */
325: BitBlt(hdcTemp, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);
326: BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCCOPY);
327:
328: /*
329: * Cleanup.
330: */
331: SelectObject(hdcTemp, hbmOld);
332: DeleteObject(hbmTemp);
333: DeleteDC(hdcTemp);
334: }
335:
336:
337:
338:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.