// Revision: 08 1.7.2.5 source/ui/baseapp/ifontprv.hpp, font, ioc.v400, 001006 
/* NOSHIP */
#ifndef _IFONTPRV_
#define _IFONTPRV_
/*******************************************************************************
* FILE NAME: ifontprv.hpp                                                      *
*                                                                              *
* DESCRIPTION:                                                                 *
*   This file contains the declaration(s) of the class(es):                    *
*     IFontPrivateData                                                         *
*                                                                              *
* COPYRIGHT:                                                                   *
*   IBM Open Class Library                                                     *
*   Licensed Material - Property of IBM                                        *
*   (C) Copyright IBM Corp. 1992, 1997  All Rights Reserved                    *
*                                                                              *
*******************************************************************************/

#include <ibase.hpp>
#include <istring.hpp>
#include <imrefcnt.hpp>
#include <icntptr.hpp>
#include <ipoint.hpp>

extern "C"
  {
#ifdef IC_WIN
  #include <windows.h>
#endif // IC_WIN
#ifdef IC_MOTIF
  #include <Xm/Xm.h>
#endif //IC_MOTIF
  }

#ifdef IC_MOTIF
  #include <ixlfdstr.hpp>
  #include <i2dghand.hpp>
#endif //IC_MOTIF

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma enum(4)
#pragma pack(push,4)

// moved from icconstg.h, these are only used within graph2d:

#define IC_VECTOR_FONT_ONLY_FUNCTION          67
#define IC_FONT_ACCESS_ERROR                 103


#ifdef IC_PMWIN
#ifdef IC_WIN
/*--------------------------------------------------------------------*/
/* Need a wrapper around font handles, allowing us to ref count those */
/* that we allocated so that we can delete them when we are done      */
/*--------------------------------------------------------------------*/
class IFontHandle {
public:
/*---------------------------------- Value -----------------------------------*/
// Use HFONT below, since we are including windows.h already.
typedef HFONT Value;
/*------------------------------- Constructors -------------------------------*/
 #ifdef IC_WIN_STRICT
  #ifdef IC_WIN_STRICT_HANDLES
  IFontHandle ( Value hFont = 0,
                bool allocated = false )
    : fValue( hFont )
    , fAllocatedByIFont( allocated )
    , refs( 1 )
  { }
  #else
  IFontHandle ( void* hFont = 0,
                bool  allocated = false )
    : fValue( (Value) hFont )
    , fAllocatedByIFont( allocated )
    , refs( 1 )
  { }
  #endif
 #else
  IFontHandle ( Value hFont = 0,
                bool  allocated = false )
    : fValue( hFont )
    , fAllocatedByIFont( allocated )
    , refs( 1 )
  { }
 #endif

 ~IFontHandle ( );

unsigned long
  refCount() const { return refs; }

IFontHandle
  &addRef() { refs++; return *this; }

void
  removeRef();

operator HFONT ( )
  { return fValue; }

private:
/*-------------------------------- Private -----------------------------------*/
Value
  fValue;
unsigned long
  refs;
bool
  fAllocatedByIFont;
}; // class IFontHandle


/*--------------------------------------------------------------------*/
/* Structure declarations for caching font enumeration callback info  */
/*--------------------------------------------------------------------*/
typedef struct _FONTINFO {   /* fi */
  char   szFaceName[LF_FACESIZE];  /* face name                       */
  int    iPointSize;               /* point size of font (if fBitmap) */
  struct _FONTINFO *pfiNext;       /* next FONTINFO in the list       */
} FONTINFO, *PFONTINFO;

typedef struct _FACEINFO {   /* faci */
  char   szFaceName[LF_FACESIZE];  /* face name                       */
  struct _FACEINFO *pfaciNext;     /* next FACEINFO in the list       */
} FACEINFO, *PFACEINFO;

typedef struct _FONTCOUNT {   /* fcnt */
  PFONTINFO pFontInfo;             /* Pointer to linked list of fonts */
  int       matchCount;            /* Count of fonts matching parms   */
  DWORD     dwType;                /* Type of font to match           */
  long      horzRes;               /* Resolution to match if type     */
  long      vertRes;               /*  of font is a bitmap            */
  BOOL      bPointSizes;
} FONTCOUNT, *PFONTCOUNT;

int CALLBACK EnumAllFonts( LPENUMLOGFONT, LPNEWTEXTMETRIC, int, LPARAM );
int CALLBACK EnumAllFaces( LPENUMLOGFONT, LPNEWTEXTMETRIC, int, LPARAM );
#endif  // IC_WIN

class IFontPrivateData {
/*******************************************************************************
* Objects of IFontData contain the private data for the IFont class.           *
* In addition, IFontData provides reference counting for IFont objects.        *
*******************************************************************************/
friend class IFont;
friend class IWindow;

public:
/*------------------------------- Constructors ---------------------------------
| There are n ways to construct instances of this class:                       |
|   1. default                                                                 |
|   2. Copy constructor.                                                       |
------------------------------------------------------------------------------*/
  IFontPrivateData( );

  IFontPrivateData( const IFontPrivateData& fpd );

unsigned long
  refCount() const { return refs; }

IFontPrivateData
  &addRef() { refs++; return *this; }
void
  removeRef();

private:
/*------------------------------ Data Members ----------------------------------
|  The following data members are used to different font values:               |
|   pfontmetCl - Holds the font metrics for the font.                          |
|   plClCharWidths - Holds the array of character widths for the font.         |
|   pfattrsCl - Holds the font attributes structure.                           |
|   fxClPointSize - Holds the point size for the font.                         |
|   fxClHeight - Holds the character height.                                   |
|   fxClWidth - Holds the character width.                                     |
|   lClFontDir - Holds the direction to draw the font.                         |
|   lClXAngle - Holds the X portion of the font angle.                         |
|   lClYAngle - Holds the Y portion of the font angle.                         |
|   ptlClShear - Holds the font shear.                                         |
|   lClLCId - Holds the ID uses for the logical font.                          |
------------------------------------------------------------------------------*/
int
  flClStyles;

IPoint
  pntClAngle,
  pntClShear;

long
  fxClPointSize,
  lClFontDir;

#ifdef IC_PM
struct _FONTMETRICS
 *pfontmetCl;

struct _FATTRS
 *pfattrsCl;

long
 *plClCharWidths,
  fxClHeight,
  fxClWidth,
  lClLCId;
#endif

#ifdef IC_WIN
IFontHandle
 *fpFontHandle;

HFONT
  prevFont,
  systemFont;

BYTE
  fcharSet;

struct tagLOGFONTA
 *plogfontCl;
struct tagTEXTMETRICA
 *ptextmetricCl;
#endif

unsigned long
  inUseCount,
  refs;

IFontPrivateData
 &operator=( const IFontPrivateData&);
}; // IFontData
#endif //IC_PMWIN

#ifdef IC_MOTIF
class IFontPrivateFontList: public IMRefCounted
{
 private:
  Display*      dpy;
  XmFontList    fontList;
  //
  // The XFontSet identified by XmFONTLIST_DEFAULT_TAG, or null.
  //
  XFontSet      fontSet;
  //
  // Number of fontStruct's in fontSet, or 1 if fontSet is null.
  //
  unsigned long ulNumFontStructs;
  //
  // Array of XFontStruct and array of char*.
  // If XmFONTLIST_DEFAULT_TAG identifies a XFontStruct, there is only one
  // element in each array, &pFontStruct and &fontName.
  // If XmFONTLIST_DEFAULT_TAG identifies an XFontSet, there may be several
  // elements in each array.  The arrays should not be freed.
  //
  XFontStruct** fontStructList; // Contains &pFontStruct when fontSet is null.
  XFontStruct*  pFontStruct; // Only used when fontSet is null.

  char** fontNameList;  // Contains &fontName when fontSet is null.
  char*  fontName;  // Only used when fontSet is null.  Free using XtFree.
  //
  // Dissallow copy and assignment of this class;
  //
  IFontPrivateFontList( const IFontPrivateFontList& );
  IFontPrivateFontList& operator=( const IFontPrivateFontList& );

 protected:
  static XmFontList createFontList( XtPointer fontOrFontSet,
                                    XmFontType type,
                                    const char* tag );
  static unsigned long getProp(Atom, XFontStruct* pFontStruct);
  char* getFontName( XFontStruct* aFontStructPtr ); // Free using XtFree.

  IFontPrivateFontList& initialize( XmFontList aFontList, Display* aDpy );
  IFontPrivateFontList& initialize( XmFontList aFontList,
                                    XFontStruct* aFontStructPtr,
                                    Display* aDpy );
 public:
  typedef ICountedPointerTo< IFontPrivateFontList > Handle;

  IFontPrivateFontList();
  IFontPrivateFontList( XmFontList aFontList, Display* aDpy );
  IFontPrivateFontList( XFontSet aFontSet, Display* aDpy );
  virtual ~IFontPrivateFontList();

  Display* display() const
    { return dpy; }
  XmFontList   xmFontList() const
    { return fontList; }
  XFontSet     xFontSet() const
    { return fontSet; } // May return null.
  unsigned long numFontStructs() const
    { return ulNumFontStructs; }
  XFontStruct* xFontStruct( unsigned long index=0 ) const
    { return fontStructList[index]; }
  char* xFontName( unsigned long index=0 ) const
    { return fontNameList[index]; } // May return null.
};

class IFontPrivateFontStruct: public IFontPrivateFontList
{
 public:
  IFontPrivateFontStruct( XFontStruct* aFontStructPtr, Display* aDpy );
  virtual ~IFontPrivateFontStruct();
};

class IFontPrivateFontSet: public IFontPrivateFontList
{
 public:
  IFontPrivateFontSet( XFontSet aFontSet, Display* aDpy );
  virtual ~IFontPrivateFontSet();
};

/*------------------------------------------------------------------------------
| IFontPrivateData                                                             |
| Maintains private instance data                                              |
------------------------------------------------------------------------------*/
class IFontPrivateData {
public:
typedef ICountedPointerTo< IFontPrivateFontList > Handle;

/*------------------------- Constructors/Destructor ----------------------------
|  You can create an IFontPrivateData object from                              |
|    - nothing.  You need to use checkForMatch or loadXLFD to complete         |
|      specification of the object,                                            |
|    - an XmFontList                                                           |
|    - font specifications                                                     |
|    - an IPresSpaceHandle                                                     |
|    - another IFontPrivateData object                                         |
------------------------------------------------------------------------------*/
  IFontPrivateData();
  IFontPrivateData(XmFontList    xmfontList);
  IFontPrivateData(const char*   pszFaceName,
                   unsigned long ulPointSize,
                   Boolean       useFixedFont,
                   Boolean       useVectorFont,
                   const IPresSpaceHandle& hpsInit);
  IFontPrivateData(const IPresSpaceHandle& presSpace);
  IFontPrivateData(const IFontPrivateData& orig);
  ~IFontPrivateData();

IFontPrivateData
  &operator=      (const IFontPrivateData& orig);

/*---------------------------- Loading/searching -------------------------------
|  These functions are for loading or searching for a font                     |
|    checkForMatch - Searches for and loads a font matching the                |
|                    currently specified attributes (size, style, etc)         |
|    loadXLFD      - loads a font from an X Logical Font Description string    |
------------------------------------------------------------------------------*/
IFontPrivateData&  checkForMatch(const IPresSpaceHandle& hps
                                 = IPresSpaceHandle() );
IFontPrivateData&  checkForMatchSimple(const IPresSpaceHandle& hps
                                 = IPresSpaceHandle() );
IFontPrivateData&  loadXLFD( char * xlfd );
IFontPrivateData&  loadXLFD(IXLFDString baseXLFDstr);

/*-------------------------------- Attributes ----------------------------------
|  These function access or set font attributes.                               |
|     X / Motif objects -  you can access the display, the XFontStruct,        |
|                          and the XmFontList for the font object.  Note       |
|                          that you should NOT free any of these objects.      |
|     getProp           - gets a particular property of the font from the      |
|                         X server                                             |
|     pointSize         - get point size                                       |
|     setPointSize      - set point size                                       |
|     faceName          - get face name of the font                            |
|     setFaceName       - set face name of the font                            |
|     avgCharWidth      - return average character width in pixels             |
|     beginUsingFont    - Sets the presentation space to use the font.         |
|     endUsingFont      - Restores the presentation space to the default font. |
------------------------------------------------------------------------------*/
Display           *display() const
   { return dpy; }

XmFontList   xmFontList() const
   {
    // d5185
    // IFont uses xmFontList() to give the font list to one or more widgets.
    // Increase the reference count to keep this font list for use by the
    // widget.  If we don't do this, the font list we get back from the
    // widget may have a dangling pointers to an XFontSet which was freed when
    // *this was destructed.
    hFontList->addRef();  // Keep the font list, since it is given to a window.
    return hFontList->xmFontList();
   }
XFontSet     xFontSet() const
   { return hFontList->xFontSet(); } // May return null.
 unsigned long numFontStructs() const
   { return hFontList->numFontStructs(); }
// XFontStruct* xFontStruct( unsigned long index=0 ) const
//    { return hFontList->xFontStruct(index); }
char* xFontName( unsigned long index=0 ) const
   { return hFontList->xFontName(index); }  // May return null.

unsigned long      getProp(Atom);

unsigned long      pointSize() const
   { return xpointSize / 10;}
IFontPrivateData&  setPointSize(unsigned long size)
   { xpointSize = size * 10; return *this;}
const IString&     faceName() const
   { return facename;}
IFontPrivateData&  setFaceName( const char* name )
   { facename = name;   return *this;}
IFontPrivateData&  beginUsingFont (const IPresSpaceHandle& hps) ;
IFontPrivateData&  endUsingFont (const IPresSpaceHandle& hps) ;
unsigned long      avgCharWidth() const
   {return avgWidth/10;}
ISize              maxCharSize() const
   {return maxSize;}
IPair              maxAscentDescent() const
   {return maxAscDesc;}
int                xHeight() const
   {return xaXHeight;}
int                capHeight() const
   {return xaCapHeight;}

ISize              inkSize( const char* text ) const;
ISize              logicalSize( const char* text ) const;

/*------------------------------- Font Styles ----------------------------------
| These functions allow setting and accessing the font style attributes        |
| for the current font object.                                                 |
------------------------------------------------------------------------------*/
Boolean            isBold() const
   {return !!(flags & bold); }
Boolean            isItalic() const
   {return !!(flags & italic); }
Boolean            isFixed() const
   {return !!(flags & fixed); }
Boolean            isVector() const
   {return !!(flags & vector); }
IFontPrivateData
  &setBold  ( Boolean bTurnOn=true ),
  &setItalic( Boolean bTurnOn=true ),
  &setFixed ( Boolean bTurnOn=true ),
  &setVector( Boolean bTurnOn=true );

private:
// FontFlags is the values for the flags member
enum FontFlags { bold=1, italic=2, fixed=4, vector=8 };
void               initialize();
void               getFontInfo();
void buildXLFD( IXLFDString& strXLFD,bool useFontSet);

// member data
  // Copy and assignment allows IFontPrivateData objects to share the
  // same IFontPrivateFontList objects.
  // Use IFontPrivateFontList::Handle to do the reference counting.
  IFontPrivateFontList::Handle hFontList;
  GContext      prevFont;
  IString       facename;
  unsigned long xpointSize;
  unsigned long avgWidth;
  unsigned long flags;
  unsigned long resX,
                resY,
                resXexact,
                resYexact;
  Display*      dpy;
  ISize         maxSize;
  IPair         maxAscDesc;
  int           xaXHeight;
  int           xaCapHeight;
  IXLFDString   XLFDstr;
};

#endif //IC_MOTIF

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _IFONTPRV_
