Click here to Skip to main content
15,896,343 members
Articles / Containers / Virtual Machine

TOOL

Rate me:
Please Sign up or sign in to vote.
4.98/5 (52 votes)
23 Oct 200676 min read 231.3K   5.4K   147  
TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language interpreter. The purpose of this article is to introduce the TOOL interpreter and language from the perspective of a person who has a desire to include a scripting solution as part of his project.
/*****************************************************************************/
/*                              SOURCE FILE                                  */
/*****************************************************************************/
/*
       $Archive:   $

      $Revision:   $
          $Date:   $
        $Author:   $

    Description:   handles device independant bitmaps both to the screen and 
                   the printer

*/
static char OBJECT_ID[] = "$Revision:   $ : $Date:   $";
/*****************************************************************************/

#include "../../../stdafx.h"
#include "VMDib.h"


static DWORD   dwOffset;
static RECT    rcClip;
static BOOL    bMemoryDIB  = TRUE;  // Load Entire DIB into memory in CF_DIB format
static BOOL    bLegitDraw  = FALSE; // We have a valid bitmap to draw           
static HANDLE  hdibCurrent = NULL;  // Handle to current memory DIB         
static HANDLE  hbiCurrent  = NULL;  // Handle to current bitmap info struct 


/*****************************************************************************/
/*

     FUNCTION NAME:  PrintTheBitMap

       DESCRIPTION:  

             INPUT:  ps - 
            OUTPUT:  none

           RETURNS:  TRUE if worked, FALSE if not 
*/
BOOL WINAPI PrintTheBitMap( PRTTYPE* ps )
{
  BITMAPINFOHEADER bi;
  RECT             Rect;

  if ( InitDIB( ps )==FALSE )
  {
    return( FALSE );
  }   
  DibInfo( hbiCurrent, &bi );

  if ( !IsRectEmpty( &rcClip ) )
  {
    bi.biWidth  = rcClip.right  - rcClip.left;
    bi.biHeight = rcClip.bottom - rcClip.top;
  }
  
  // Fix bounding rectangle for the picture ..
  //
  Rect.top      = ps->rc.top;
  Rect.left     = ps->rc.left;
  Rect.bottom   = ps->rc.bottom-ps->rc.top;
  Rect.right    = ps->rc.right-ps->rc.left;
  ps->rc.right  = Rect.right;
  ps->rc.bottom = Rect.bottom;

  // ... and inform the driver
  //
  ps->pDC->Escape( SET_BOUNDS, sizeof( RECT ), (LPSTR)&Rect, NULL );
  PrintDIB( ps, ps->rc.left, ps->rc.top, ps->rc.right, ps->rc.bottom );
  FreeDib();
  return( TRUE );
}
/* End of function "PrintTheBitMap"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  ScreenPrintTheBitMap

       DESCRIPTION:  

             INPUT:  ps - 
            OUTPUT:  none

           RETURNS:  TRUE if worked, FALSE if not 
*/
BOOL WINAPI ScreenPrintTheBitMap( PRTTYPE* ps )
{
  BITMAPINFOHEADER bi;
  RECT             Rect;

  if ( hbiCurrent == NULL )
  {
    if ( InitDIB( ps ) == FALSE )
    {
      return( FALSE );
    }   
  }

  DibInfo( hbiCurrent, &bi );

  if ( !IsRectEmpty( &rcClip ) )
  {
    bi.biWidth  = rcClip.right  - rcClip.left;
    bi.biHeight = rcClip.bottom - rcClip.top;
  }

  // Fix bounding rectangle for the picture ..
  //
  Rect.top    = ps->rc.top;
  Rect.left   = ps->rc.left;
  Rect.bottom = ps->rc.bottom-ps->rc.top;
  Rect.right  = ps->rc.right-ps->rc.left;

  // ... and inform the driver
  //
  ps->pDC->Escape( SET_BOUNDS, sizeof( RECT ), (LPSTR)&Rect, NULL );

  PrintDIB( ps, ps->rc.left, ps->rc.top, (int)bi.biWidth, (int)bi.biHeight );    
  return( TRUE );
}
/* End of function "ScreenPrintTheBitMap"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  InitDIB

       DESCRIPTION:  

             INPUT:  ps - 
            OUTPUT:  none

           RETURNS:  TRUE if worked, FALSE if not
*/
int WINAPI InitDIB( PRTTYPE* ps )
{
  unsigned           fh;
  BITMAPINFOHEADER   bi;
  OFSTRUCT           of;

  FreeDib();

  // Open the file and get a handle to it's BITMAPINFO
  //
  fh = OpenFile( (LPCSTR)ps->Text, (LPOFSTRUCT)&of, OF_READ );
  if ( fh == -1 ) 
  {
    return( FALSE );
  }
  hbiCurrent = ReadDibBitmapInfo(fh);

  dwOffset = _llseek( fh, 0L, SEEK_CUR );
  _lclose( fh );

  if ( hbiCurrent == NULL ) 
  {
    return( FALSE );
  }
  DibInfo( hbiCurrent,&bi );

  bLegitDraw = TRUE;

  // If the input bitmap is not in RGB FORMAT the banding code will
  // not work!  we need to load the DIB bits into memory.
  // if memory DIB, load it all NOW!  This will avoid calling the
  // banding code.
  //
  if ( bMemoryDIB || bi.biCompression != BI_RGB )
  {
    hdibCurrent = OpenDIB( ps->Text );
  }

  //  If the RLE could not be loaded all at once, exit gracefully NOW,
  //  to avoid calling the banding code
  //
  if ( ( bi.biCompression != BI_RGB ) && !hdibCurrent )
  {
    FreeDib();
    return( FALSE );
  }
  return( TRUE );
}
/* End of function "InitDIB"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  FreeDib

       DESCRIPTION:  

             INPUT:  void - 
            OUTPUT:  none

           RETURNS:  void  
*/
void WINAPI FreeDib( void )
{
  if ( hdibCurrent )
  {
    GlobalFree( hdibCurrent );
  }

  if ( hbiCurrent && hbiCurrent != hdibCurrent )
  {
    GlobalFree( hbiCurrent );
  }

  bLegitDraw  = FALSE;
  hdibCurrent = NULL;
  hbiCurrent  = NULL;
  SetRectEmpty( &rcClip );
}
/* End of function "FreeDib"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  PrintDIB

       DESCRIPTION:  

             INPUT:  ps - 
                     x - 
                     y - 
                     dx - 
                     dy - 
            OUTPUT:  

           RETURNS:  void
*/
void WINAPI PrintDIB( PRTTYPE *ps, int x, int y, int dx, int dy )
{
  BITMAPINFOHEADER bi;
  int dibX;
  int dibY;
  int dibDX;
  int dibDY;

  if ( !bLegitDraw )
  {
    return;
  }

  DibInfo( hbiCurrent, &bi );

  if ( IsRectEmpty( &rcClip ) )
  {
    dibX  = 0;
    dibY  = 0;
    dibDX = (int)bi.biWidth;
    dibDY = (int)bi.biHeight;
  }
  else
  {
    dibX  = rcClip.left;
    dibY  = (int)bi.biHeight - 1 - rcClip.bottom;
    dibDX = rcClip.right  - rcClip.left;
    dibDY = rcClip.bottom - rcClip.top;
  }

  if ( hdibCurrent )
  {
    // Stretch the DIB to printer DC 
    //
    StretchDibBlt( ps->pDC->GetSafeHdc(),
                   x,
                   y,
                   dx,
                   dy,
                   hdibCurrent,
                   dibX,
                   dibY,
                   dibDX,
                   dibDY,
                   SRCCOPY );
  }
}
/* End of function "PrintDIB"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  OpenDIB

       DESCRIPTION:  

             INPUT:  szFile - 
            OUTPUT:  none

           RETURNS:  HANDLE  
*/
HANDLE WINAPI OpenDIB( LPCSTR szFile )
{
  unsigned            fh;
  BITMAPINFOHEADER    bi;
  LPBITMAPINFOHEADER  lpbi;
  DWORD               dwLen = 0;
  DWORD               dwBits;
  HANDLE              hdib;
  HANDLE              h;
  OFSTRUCT            of;

  // Open the file and read the DIB information 
  //
  fh = OpenFile( szFile, &of, OF_READ );
  if ( fh == -1 )
  {
    return( NULL );
  }

  hdib = ReadDibBitmapInfo( fh );
  if ( !hdib )
  {
    return( NULL );
  }
  DibInfo( hdib,&bi );

  // Calculate the memory needed to hold the DIB
  //
  dwBits = bi.biSizeImage;
  dwLen  = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;

  // Try to increase the size of the bitmap info. buffer to hold the DIB
  //
  h = GlobalReAlloc( hdib, dwLen, GHND );
  if ( !h )
  {
    GlobalFree( hdib );
    hdib = NULL;
  }
  else
  {
    hdib = h;
  }

  // Read in the bits
  //
  if ( hdib )
  {
    lpbi = (LPBITMAPINFOHEADER)GlobalLock( hdib );
    lread( fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize( lpbi ), dwBits );
    GlobalUnlock( hdib );
  }
  _lclose( fh );

  return( hdib );
}
/* End of function "OpenDIB"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  DibInfo

       DESCRIPTION:  

             INPUT:  hbi - 
                     lpbi - 
            OUTPUT:  

           RETURNS:  BOOL 
*/
BOOL WINAPI DibInfo( HANDLE hbi, LPBITMAPINFOHEADER lpbi )
{
  if ( hbi )
  {
    *lpbi = *(LPBITMAPINFOHEADER)GlobalLock( hbi );

    // fill in the default fields 
    //
    if ( lpbi->biSize != sizeof( BITMAPCOREHEADER ) )
    {
      if ( lpbi->biSizeImage == 0L )
      {
        lpbi->biSizeImage = WIDTHBYTES( lpbi->biWidth * lpbi->biBitCount ) * lpbi->biHeight;
      }
    
      if ( lpbi->biClrUsed == 0L )
      {
        lpbi->biClrUsed = DibNumColors( lpbi );
      }
    }
    GlobalUnlock( hbi );
    return( TRUE );
  }
  return( FALSE );
}
/* End of function "DibInfo"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  ReadDibBitmapInfo

       DESCRIPTION:  

             INPUT:  fh - 
            OUTPUT:  none

           RETURNS:  HANDLE - 
*/
HANDLE WINAPI ReadDibBitmapInfo( int fh )
{
  DWORD     off;
  HANDLE    hbi = NULL;
  int       size;
  int       i;
  WORD      nNumColors;

  RGBQUAD FAR       *pRgb;
  BITMAPINFOHEADER   bi;
  BITMAPCOREHEADER   bc;
  LPBITMAPINFOHEADER lpbi;
  BITMAPFILEHEADER   bf;
  DWORD              dwWidth = 0;
  DWORD              dwHeight = 0;
  WORD               wPlanes, wBitCount;

  if ( fh == -1 )
  {
    return( NULL );
  }

  // Reset file pointer and read file header
  //
  off = _llseek( fh, 0L, SEEK_CUR );
  if ( sizeof( bf ) != _lread( fh, (LPSTR)&bf, sizeof( bf ) ) )
  {
    return( FALSE );
  }

  // Do we have a RC HEADER? 
  //
  if ( !ISDIB( bf.bfType ) ) 
  {
    bf.bfOffBits = 0L;
    _llseek( fh, off, SEEK_SET );
  }
  if ( sizeof( bi ) != _lread( fh, (LPSTR)&bi, sizeof( bi ) ) )
  {
    return( FALSE );
  }

  nNumColors = DibNumColors( &bi );

  // Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
  // and extract the field information accordingly. If a BITMAPCOREHEADER,
  // transfer it's field information to a BITMAPINFOHEADER-style block
  //
  switch ( size = (int)bi.biSize )
  {
    case sizeof( BITMAPINFOHEADER ):
    {
    }
    break;

    case sizeof( BITMAPCOREHEADER ):
    {
      bc = *(BITMAPCOREHEADER*)&bi;

      dwWidth   = (DWORD)bc.bcWidth;
      dwHeight  = (DWORD)bc.bcHeight;
      wPlanes   = bc.bcPlanes;
      wBitCount = bc.bcBitCount;

      bi.biSize               = sizeof(BITMAPINFOHEADER);
      bi.biWidth              = dwWidth;
      bi.biHeight             = dwHeight;
      bi.biPlanes             = wPlanes;
      bi.biBitCount           = wBitCount;

      bi.biCompression        = BI_RGB;
      bi.biSizeImage          = 0;
      bi.biXPelsPerMeter      = 0;
      bi.biYPelsPerMeter      = 0;
      bi.biClrUsed            = nNumColors;
      bi.biClrImportant       = nNumColors;

      _llseek( fh, (LONG)sizeof( BITMAPCOREHEADER ) - sizeof( BITMAPINFOHEADER ), SEEK_CUR );
    }
    break;

    default:
    {
      // Not a DIB!
      //
      return( NULL );
    }
  }

  //  Fill in some default values if they are zero
  //
  if ( bi.biSizeImage == 0 )
  {
    bi.biSizeImage = WIDTHBYTES( (DWORD)bi.biWidth * bi.biBitCount ) * bi.biHeight;
  }
  if ( bi.biClrUsed == 0 )
  {
    bi.biClrUsed = DibNumColors( &bi );
  }

  // Allocate for the BITMAPINFO structure and the color table.
  //
  hbi = GlobalAlloc(GHND, (LONG)bi.biSize + nNumColors * sizeof( RGBQUAD ) );

  if ( !hbi )
  {
    return( NULL );
  }
  
  lpbi  = (LPBITMAPINFOHEADER)GlobalLock( hbi );
  *lpbi = bi;

  // Get a pointer to the color table
  //
  pRgb = (RGBQUAD FAR*)( (LPSTR)lpbi + bi.biSize );

  if ( nNumColors )
  {
    if ( size == sizeof( BITMAPCOREHEADER ) )
    {
      // Convert a old color table (3 byte RGBTRIPLEs) to a new
      // color table (4 byte RGBQUADs)
      //
      _lread( fh, (LPSTR)pRgb, nNumColors * sizeof( RGBTRIPLE ) );

      for ( i = nNumColors - 1; i >= 0; i-- )
      {
        RGBQUAD rgb;

        rgb.rgbRed      = ( (RGBTRIPLE FAR*)pRgb )[ i ].rgbtRed;
        rgb.rgbBlue     = ( (RGBTRIPLE FAR*)pRgb )[ i ].rgbtBlue;
        rgb.rgbGreen    = ( (RGBTRIPLE FAR*)pRgb )[ i ].rgbtGreen;
        rgb.rgbReserved = (BYTE)0;

        pRgb[ i ] = rgb;
      }
    }
    else
    {
      _lread( fh, (LPSTR)pRgb, nNumColors * sizeof( RGBQUAD ) );
    }
  }

  if ( bf.bfOffBits != 0L )
  {
    _llseek( fh, off + bf.bfOffBits, SEEK_SET );
  }
  GlobalUnlock( hbi );
  return( hbi );
}
/* End of function "ReadDibBitmapInfo"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  PaletteSize

       DESCRIPTION:  

             INPUT:  pv - 
            OUTPUT:  none

           RETURNS:  WORD - 
*/
WORD WINAPI PaletteSize( VOID FAR* pv )
{
  LPBITMAPINFOHEADER lpbi;
  WORD               NumColors;

  lpbi      = (LPBITMAPINFOHEADER)pv;
  NumColors = DibNumColors(lpbi);

  if ( lpbi->biSize == sizeof( BITMAPCOREHEADER ) )
  {
    return( NumColors * sizeof( RGBTRIPLE ) );
  }
  else
  {
    return( NumColors * sizeof( RGBQUAD ) );
  }
}
/* End of function "PaletteSize"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  DibNumColors

       DESCRIPTION:  

             INPUT:  pv - 
            OUTPUT:  none

           RETURNS:  WORD - 
*/
WORD WINAPI DibNumColors( VOID FAR* pv )
{
  int                 bits;
  LPBITMAPINFOHEADER  lpbi;
  LPBITMAPCOREHEADER  lpbc;

  lpbi = ( (LPBITMAPINFOHEADER) pv );
  lpbc = ( (LPBITMAPCOREHEADER) pv );

  // With the BITMAPINFO format headers, the size of the palette
  // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  // is dependent on the bits per pixel ( = 2 raised to the power of
  // bits/pixel).
  //
  if ( lpbi->biSize != sizeof( BITMAPCOREHEADER ) )
  {
    if ( lpbi->biClrUsed != 0 )
    {
      return( (WORD) lpbi->biClrUsed );
    }
    bits = lpbi->biBitCount;
  }
  else
  {
    bits = lpbc->bcBitCount;
  }

  switch ( bits )
  {
    case 1:
    {
      return( 2 ); 
    }
    break;

    case 4:
    {
      return( 16 );
    }
    break;

    case 8:
    {
      return( 256 );
    }
    break;

    default:
    {
      // A 24 bitcount DIB has no color table
      //
      return( 0 );
    }
    break;
  }
}
/* End of function "DibNumColors"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  StretchDibBlt

       DESCRIPTION:  

             INPUT:  hdc - 
                     x - 
                     y - 
                     dx - 
                     dy - 
                     hdib - 
                     x0 - 
                     y0 - 
                     dx0 - 
                     dy0 - 
                     rop - 
            OUTPUT:  

           RETURNS:  BOOL - 
*/
BOOL WINAPI StretchDibBlt( HDC hdc, int x, int y, int dx, int dy, HANDLE hdib, int x0, int y0, int dx0, int dy0, LONG rop )
{
  LPBITMAPINFOHEADER lpbi;
  LPSTR              pBuf;
  BOOL               f;

  lpbi = (LPBITMAPINFOHEADER)GlobalLock( hdib );

  if ( !lpbi )
  {
    return( FALSE );
  }

  pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize( lpbi );

  f = StretchDIBits ( hdc,
                      x, 
                      y,
                      dx, 
                      dy,
                      x0, 
                      y0,
                      dx0, 
                      dy0,
                      pBuf, 
                      (LPBITMAPINFO)lpbi,
                      DIB_RGB_COLORS,
                      rop );

  GlobalUnlock( hdib );
  return( f );
}
/* End of function "StretchDibBlt"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  lread

       DESCRIPTION:  

             INPUT:  fh - 
                     pv - 
                     ul - 
            OUTPUT:  

           RETURNS:  DWORD - 
*/
DWORD PASCAL lread( int fh, VOID far* pv, DWORD ul )
{
  DWORD  ulT = ul;
  BYTE*  hp = (unsigned char*)pv;

  while ( ul > (DWORD)MAXREAD ) 
  {
    if ( _lread( fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD )
    {
      return( 0 );
    }
    ul -= MAXREAD;
    hp += MAXREAD;
  }
  if ( _lread( fh, (LPSTR)hp, (WORD)ul ) != (WORD)ul )
  {
    return( 0 );
  }
  return( ulT );
}
/* End of function "lread"
/*****************************************************************************/


/*****************************************************************************/
/* Check-in history */
/*
 *$Log:  $
*/
/*****************************************************************************/


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions