home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / imagedit / imagedc.c < prev    next >
Text File  |  1996-06-12  |  11KB  |  337 lines

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