

#ifndef _bitmap_h_ /* Wed Mar 23 12:51:01 1994 */
#define _bitmap_h_





/*
 *
 *          Copyright (C) 1995, M. A. Sridhar
 *  
 *
 *     This software is Copyright M. A. Sridhar, 1995. You are free
 *     to copy, modify or distribute this software  as you see fit,
 *     and to use  it  for  any  purpose, provided   this copyright
 *     notice and the following   disclaimer are included  with all
 *     copies.
 *
 *                        DISCLAIMER
 *
 *     The author makes no warranties, either expressed or implied,
 *     with respect  to  this  software, its  quality, performance,
 *     merchantability, or fitness for any particular purpose. This
 *     software is distributed  AS IS.  The  user of this  software
 *     assumes all risks  as to its quality  and performance. In no
 *     event shall the author be liable for any direct, indirect or
 *     consequential damages, even if the  author has been  advised
 *     as to the possibility of such damages.
 *
 */



#include "base/intseq.h"
#include "base/bytstrng.h"

#include "ui/rectangl.h"

#if defined (__MS_WINDOWS__)
    typedef ulong UI_BitmapHandle;
    typedef ulong UI_PaletteHandle;
    typedef ulong UI_DIBHandle;
#elif defined(__MS_WIN32__)
    typedef HANDLE UI_PaletteHandle;
    typedef HANDLE UI_BitmapHandle;
    typedef HANDLE UI_DIBHandle;
#elif defined (__OS2__)
    typedef ulong UI_PaletteHandle;
    typedef ulong UI_BitmapHandle;
#elif defined (__X_MOTIF__) || defined(__X_YACL__)
    typedef struct _XImage* UI_BitmapHandle;
#endif



class YACL_UI UI_DrawingSurface;
class YACL_UI UI_DisplaySurface;
class YACL_UI UI_BitmapData;



// A Bitmap is a rectangular array of pixels. Although the Bitmap class is
// derived from GraphicObject, a Bitmap instance should not be thought of as
// being in an abstract co-ordinate space, because Bitmaps must usually be
// associated with particular drawing surfaces. So the Bitmap must be
// thought of as an array of pixels for a particular drawing surface.
//
// The Bitmap instance remembers only its pixels, and is not associated with
// any particular position on a drawing surface. Consequently, the
// translation operator+= makes no sense for a Bitmap, so it does nothing.


class YACL_UI UI_BitmapRep;

class YACL_UI UI_Bitmap: public UI_GraphicObject {
    
public:
    
    UI_Bitmap ();
    // Default constructor: does nothing.

    UI_Bitmap (const UI_Bitmap&);
    // Copy constructor.
    
    virtual ~UI_Bitmap ();
    // Destructor: tells the platform to destroy the platform representation
    // of this Bitmap.

    UI_BitmapHandle Handle() const;
    // Return the platform-specific handle of this Bitmap.
    
    long BitsPerPixel () const;
    // Return the number of color bits per pixel.
    
    long Height () const;
    // Return the height of the Bitmap in pixels.
    
    long Width  () const;
    // Return the width of this Bitmap in pixels.
    
    inline UI_Rectangle Shape () const;
    // Return the shape of the bitmap as a rectangle. The origin of the
    // returned rectangle will be (0,0).
    
    inline UI_Rectangle BoundingRectangle() const;
    // Override the inherited pure-virtual method. This is implemented as a
    // synonym for the {\tt Shape} method.
    
    inline bool OnBoundary (const UI_Point& p) const;
    // Tell whether {\tt p} is on the boundary of this Bitmap.
    
    inline bool Includes (const UI_Point& p) const;
    // Tell whether {\tt p} is inside or on the boundary of this Bitmap.
    
    // UI_Color& operator[] (short i, short j);
    
    virtual bool DrawOn (UI_DrawingSurface& sfc,
                         const UI_Point& p = UI_Point (0, 0)) const;
    // Draw this Bitmap on surface {\tt sfc} with its top left corner  at {\tt
    // p}. The point {\tt p} is reckoned with respect to the top left corner
    // of {\tt sfc}.
    
    void CopyFrom (UI_DrawingSurface& s, const UI_Rectangle& r);
    // Copy the region delimited by the rectangle {\tt r} of the surface
    // {\tt s} into this Bitmap.
    
    virtual bool BuildFrom (const UI_BitmapData& data,
                            UI_DrawingSurface* sfc = NULL);
    // Build this Bitmap from the passive representation in {\tt data},
    // assuming that the data is specific to the kind of DrawingSurface that
    // {\tt sfc} represents. If {\tt sfc} is NULL, assume that the data is
    // for the display screen.
    
    virtual bool BuildFrom (const char* name,
                            UI_DrawingSurface* sfc = NULL);
    // Build this Bitmap from the file {\tt name} assuming that the data is
    // specific to the kind of DrawingSurface that {\tt sfc} represents. If
    // {\tt sfc} is NULL, assume that the bitmap will be used on the display
    // screen. Currently only MS-Windows .BMP  and .ICO file formats are
    // supported by this method, although the method works on all platforms.

    void operator+= (const UI_Vector&) {};
    // This operator, though inherited from GraphicObject, does not make
    // sense for a Bitmap, so its implementation is a no-op.
    
#if defined(__OS2__) || defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_PaletteHandle PaletteHandle () const;
    // [Specific to OS/2, Windows and Win32, for YACL internal use only]
    // Return the palette handle for this Bitmap's color palette.
    
#endif
    

    void operator= (const CL_Object& o)
        {if (o.IsA (*this)) operator= ((const UI_Bitmap&) o);} ;

    UI_Bitmap& operator= (const UI_Bitmap& b);
    
    const char* ClassName () const {return "UI_Bitmap";};
    
protected:
    
    UI_BitmapRep*   _rep;
    ulong           _width;
    ulong           _height;
    ulong           _bitsPerPixel;


#if defined(__OS2__) || defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_PaletteHandle _paletteHandle;
#endif
    
    bool _CreateBitmapFromData (const UI_BitmapData& bi,
                                UI_DrawingSurface* sfc);

    void _CleanUp();
    

#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_DIBHandle DIBHandle () const;
    // [MS-Windows-specific, for YACL internal use only]
    
#endif
};





// The BitmapData class is an encapsulation of  a passive representation of
// a Bitmap. It can be used to construct a Bitmap via the latter's {\tt
// BuildFrom} method.

class YACL_UI UI_BitmapData {

public:
    struct ColorInfo {
        uchar red, green, blue;
    };


    enum ColorBitsEnum {Color_1Bit  = 1,  Color_4Bits = 4,
                        Color_8Bits = 8 /* , Color_24Bits = 24 */};

    UI_BitmapData (short w, short h, ColorBitsEnum cBits, short nColors,
                   ColorInfo colors[], ulong pixel[]);
    // Construct a BitmapData object {\tt w} pixels wide and {\tt h} pixels
    // high. {\tt cBits} is the number of color bits per pixel. {\tt
    // ColorInfo} is the color table of colors used by the bitmap, and {\tt
    // nColors} is  the number of entries in the color table. {\tt pixel}
    // contains the individual pixel values; its cells contain indices into
    // the color table {\tt colors}. {\tt pixel} must contain {\tt w * h}
    // cells. Its contents must be specified in row-major order beginning at
    // the top left-hand corner of the bitmap.
    //
    // 24-bit color bitmaps are not yet supported.

    UI_BitmapData();
    // Default constructor: build an empty BitmapData object.

    virtual ~UI_BitmapData ();
    // Destructor.

    UI_BitmapData (const UI_BitmapData& o);
    // Copy constructor.

    UI_BitmapData& operator= (const UI_BitmapData& o);

    short Height () const {return _height;};
    // Return the height in pixels of the represented Bitmap.

    short Width () const  {return _width;};
    // Return the width in pixels of the represented Bitmap.

    short ColorBitsCount () const {return _nColorBits;};
    // Return the number of bits per color.

    short ColorCount () const {return _numColors;};
    // Return the number of distinct colors used.

    const CL_IntegerSequence& Pixels () const {return _pixels;};
    // Return the  pixel array in row major order.

    ColorInfo  Color (short i) const { return _colors [i]; };
    // Return the $i$-th color.
    
    ColorInfo* Colors () const { return _colors; };
    // Return a pointer to the array of distinct colors.

    bool ReadFrom (const char* fileName);
    
    const CL_ByteString& PaletteData() const {return _paletteData;};
    // Return the palette data of this BitmapData object.
    
    
    

    
protected:
    short              _width;
    short              _height;
    short              _nColorBits;
    short              _numColors;
    ColorInfo*         _colors;
    CL_IntegerSequence _pixels;
    CL_ByteString _paletteData;
    
    void _Init (short w, short h, ColorBitsEnum cBits, short nColors,
                ColorInfo colors[], ulong pixel[]);

    bool ReadData (const CL_Stream&, long w, long h, short nColorBits,
                   long offset, bool compress);
    
};





class YACL_UI UI_BitmapRep {

    // This is a private class containing the representation of a
    // bitmap. It uses reference counting to ensure that a single instance
    // is shared by multiple copies of the same bitmap.
    
public:
    UI_BitmapRep ();

    void Ref ()    { _refCount++;};
    
    void Unref ()  { _refCount--;};

protected:
    long _refCount;
    UI_BitmapHandle _handle;
#if defined(__OS2__) || defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_PaletteHandle _paletteHandle;
#endif
    
#if defined (__MS_WINDOWS__) || defined(__MS_WIN32__)
    HANDLE _hDIB;
#endif
    friend UI_Bitmap;
};



inline UI_Rectangle UI_Bitmap::BoundingRectangle() const
{
    return Shape();
}


inline bool UI_Bitmap::OnBoundary (const UI_Point& p) const
{
    return Shape().OnBoundary(p);
}


inline bool UI_Bitmap::Includes (const UI_Point& p) const
{
    return Shape().Includes (p);
}


inline UI_BitmapHandle UI_Bitmap::Handle () const
{
    return _rep->_handle;
}

inline long UI_Bitmap::BitsPerPixel () const
{
    return _bitsPerPixel;
}

inline long UI_Bitmap::Height () const
{
    return _height;
}

inline long UI_Bitmap::Width  () const
{
    return _width;
}


inline UI_Rectangle UI_Bitmap::Shape () const
{
    return UI_Rectangle (0, 0, _width, _height);
}


#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__) || defined(__OS2__)
inline UI_BitmapHandle UI_Bitmap::PaletteHandle () const
{
    return _rep->_paletteHandle;
}
#endif


#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
inline UI_BitmapHandle UI_Bitmap::DIBHandle () const
{
    return _rep->_hDIB;
}
#endif



inline UI_BitmapRep::UI_BitmapRep ()
    : _refCount (0), _handle (0)
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__) || defined(__OS2__)
      , _paletteHandle (0)
#endif
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
      , _hDIB (0)
#endif
{
}

#endif /* _bitmap_h_ */
