File:  [WindowsNT SDKs] / mstools / samples / sdktools / imagedit / imagedc.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:24:28 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-nov-1993, ntsdk-jul-1993, HEAD
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993

/****************************************************************************/
/*                                                                          */
/*                         Microsoft Confidential                           */
/*                                                                          */
/*                 Copyright (c) Microsoft Corp.  1987, 1991                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
/****************************** Module Header *******************************
* Module Name: image.c
*
* Routines for manipulating images.
*
* History:
*
****************************************************************************/

#include "imagedit.h"



/************************************************************************
* ImageDCCreate
*
* Allocates the image DC's and bitmaps used to hold the current image
* being edited.  This includes ghdcImage and ghbmImage.  For icons and
* cursors, also allocates the DC and bitmap that holds the AND mask
* that contains information about whether any given pixel is screen
* color, inverted screen color or a true color.  These globals are
* ghdcANDMask and ghbmANDMask.
*
* The image DC will contain the image as it will appear when displayed.
* For icons and cursors, this means that it is the combined XOR and AND
* portions of the image.  When the icon/cursor file is saved, the bits
* will be separated back out, but having them combined in the image
* makes it fast to display the image while editing.  Because of this,
* however, care must be taken when changing the screen color because
* it is not possible to determine from the image DC alone whether a
* pixel is screen color or simply a true color that happens to be the
* same as the current screen color.  The AND mask is very important for
* keeping this straight and must be properly updated when drawing on
* the image DC with any of the drawing tools!
*
* Arguments:
*   INT iType     - Type of image.
*   INT cx        - Width of the image.
*   INT cy        - Height of the image.
*   INT nColors   - Number of colors.
*
* Returns TRUE if successful, or FALSE if an error occurs.
*
* History:
*
************************************************************************/

BOOL ImageDCCreate(
    INT iType,
    INT cx,
    INT cy,
    INT nColors)
{
    HDC hdcParent;

    /*
     * Delete the old image DC's.
     */
    ImageDCDelete();

    hdcParent = GetDC(ghwndMain);

    if (!(ghdcImage = CreateCompatibleDC(hdcParent)))
        goto Error1;

    if (!(ghbmImage = MyCreateBitmap(hdcParent, cx, cy, 16)))
        goto Error2;

    SelectObject(ghdcImage, ghbmImage);

    /*
     * If image is an icon or cursor, also allocate the AND mask
     * DC and bitmap.  Note that this cannot be a DIB (must use
     * CreateBitmap) or the ImageDCSeparate() code will fail.
     */
    if (iType == FT_ICON || iType == FT_CURSOR) {
        if (!(ghdcANDMask = CreateCompatibleDC(hdcParent)))
            goto Error2;

        if (!(ghbmANDMask = CreateBitmap(cx, cy, (BYTE)1, (BYTE)1, NULL)))
            goto Error3;

        SelectObject(ghdcANDMask, ghbmANDMask);
    }

    ReleaseDC(ghwndMain, hdcParent);

    /*
     * Set some globals.
     */
    gcxImage = cx;
    gcyImage = cy;
    gnColors = nColors;

    /*
     * Initialize the bits.
     */
    ImageDCClear();

    return TRUE;

Error3:
    DeleteDC(ghdcANDMask);
    ghdcANDMask = NULL;

Error2:
    DeleteDC(ghdcImage);
    ghdcImage = NULL;

Error1:
    ReleaseDC(ghwndMain, hdcParent);

    return FALSE;
}



/************************************************************************
* ImageDCDelete
*
* Deletes the current image DC.  For icons and cursors, also deletes the
* mask DC.  Finally, it destroys the undo buffers.
*
* History:
*
************************************************************************/

VOID ImageDCDelete(VOID)
{
    if (ghdcImage) {
        DeleteDC(ghdcImage);
        ghdcImage = NULL;
        DeleteObject(ghbmImage);
        ghbmImage = NULL;
    }

    if (ghdcANDMask) {
        DeleteDC(ghdcANDMask);
        ghdcANDMask = NULL;
        DeleteObject(ghbmANDMask);
        ghbmANDMask = NULL;
    }

    /*
     * Destroy the undo buffer.
     */
    ImageFreeUndo();
}



/************************************************************************
* ImageDCClear
*
* Clears the image DC.  Sets it to completely white.  For icons and
* cursors, sets the image mask to be fully opaque also.
*
* History:
*
************************************************************************/

VOID ImageDCClear(VOID)
{
    PatBlt(ghdcImage, 0, 0, gcxImage, gcyImage, WHITENESS);

    /*
     * For icons and cursors, set all the mask bits to zero.
     */
    if (ghdcANDMask)
        PatBlt(ghdcANDMask, 0, 0, gcxImage, gcyImage, BLACKNESS);
}



/************************************************************************
* ImageDCSeparate
*
* This function separates out the XOR mask in hdcImage so that it does
* not have any pixels that are screen/inverse color.  This must be done
* prior to saving the image (or changing the screen color) because
* normally the hdcImage contains the image as it will be displayed,
* which is really a combined view of the XOR and AND masks.  The function
* ImageDCCombine can be used after this function to combine the masks
* back together.
*
* History:
*
************************************************************************/

VOID ImageDCSeparate(
    HDC hdcImage,
    INT cx,
    INT cy,
    HDC hdcANDMask,
    DWORD rgbScreen)
{
    HBITMAP hbmTemp;
    HDC hdcTemp;
    HBITMAP hbmOld;

    /*
     * Create a temporary bitmap and DC for the mask bits and
     * select bitmap into the DC.
     */
    hdcTemp = CreateCompatibleDC(hdcImage);
    hbmTemp = CreateCompatibleBitmap(hdcImage, cx, cy);
    hbmOld = SelectObject(hdcTemp, hbmTemp);

    /*
     * Background color of temporary DC is set to the specified
     * screen (transparent) color. The bits from mask DC (mono) are
     * transferred to temp. DC (color). Thus the 1s in the mask (corresp.
     * to "screen" and "inverse" portions) become "screen" colored pixels
     * in temporary DC.
     */
    SetBkColor(hdcTemp, rgbScreen);
    BitBlt(hdcTemp, 0, 0, cx, cy, hdcANDMask, 0, 0, SRCCOPY);

    /*
     * The bits in the temporary DC are XORed against the bits in the image
     * DC to recover the true XOR mask in hdcImage.  The AND mask is already
     * in hdcANDMask.
     */
    BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCINVERT);

    SelectObject(hdcTemp, hbmOld);
    DeleteDC(hdcTemp);
    DeleteObject(hbmTemp);
}



/************************************************************************
* ImageDCCombine
*
* This function takes the raw XOR mask in hdcImage and combines
* it with the AND mask in hdcANDMask to put into hdcImage the
* current image as it will be displayed.  This needs to be done after
* it is separated (just prior to saving the file and also when changing
* the screen color) and when the image is first opened.
*
* The current screen color in ghbrScreen is used when combining the
* image in this routine.
*
* History:
*
************************************************************************/

VOID ImageDCCombine(
    HDC hdcImage,
    INT cx,
    INT cy,
    HDC hdcANDMask)
{
    HBITMAP hbmTemp;
    HDC hdcTemp;
    HBITMAP hbmOld;
    HBRUSH hbrOld;

    /*
     * Make a copy of the image DC with the XOR mask in it.
     */
    hdcTemp = CreateCompatibleDC(hdcImage);
    hbmTemp = CreateCompatibleBitmap(hdcImage, cx, cy);
    hbmOld = SelectObject(hdcTemp, hbmTemp);
    BitBlt(hdcTemp, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);

    /*
     * Clear the image DC to the current screen color.
     */
    hbrOld = SelectObject(hdcImage, ghbrScreen);
    PatBlt(hdcImage, 0, 0, cx, cy , PATCOPY);
    SelectObject(hdcImage, hbrOld);

    /*
     * Reconstruct the image by superimposing the XOR and AND masks.
     */
    BitBlt(hdcImage, 0, 0, cx, cy, hdcANDMask, 0, 0, SRCAND);
    BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCINVERT);

    SelectObject(hdcTemp, hbmOld);
    DeleteDC(hdcTemp);
    DeleteObject(hbmTemp);
}



/************************************************************************
* ImageDCMonoBlt
*
* This function blts an image onto a monochrome bitmap, then back
* again.  This converts it to a monochrome image.
*
* History:
*
************************************************************************/

VOID ImageDCMonoBlt(
    HDC hdcImage,
    INT cx,
    INT cy)
{
    HBITMAP hbmTemp;
    HDC hdcTemp;
    HBITMAP hbmOld;

    /*
     * Create a temporary monochrome bitmap and dc.
     */
    hdcTemp = CreateCompatibleDC(hdcImage);
    hbmTemp = MyCreateBitmap(hdcImage, cx, cy, 2);
    hbmOld = SelectObject(hdcTemp, hbmTemp);

    /*
     * Blt the image to the mono bitmap, then back again.
     */
    BitBlt(hdcTemp, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);
    BitBlt(hdcImage, 0, 0, cx, cy, hdcTemp, 0, 0, SRCCOPY);

    /*
     * Cleanup.
     */
    SelectObject(hdcTemp, hbmOld);
    DeleteObject(hbmTemp);
    DeleteDC(hdcTemp);
}





unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.