|
|
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.