home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
font.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-09
|
31KB
|
1,142 lines
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. 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.
*
*/
#if defined(__GNUC__)
#pragma implementation
#endif
#include "base/objset.h"
#include "base/intset.h"
#include "base/strgseq.h"
#include "ui/font.h"
#include "ui/applic.h"
#include "ui/cntroler.h"
#include "ui/visualob.h"
#include "ui/dsplsurf.h"
CL_Sequence<UI_FontInfo> UI_Font::_allFonts;
#if defined(__MS_WINDOWS__)
long UI_Font::_ppi = 0;
#elif defined(__OS2__)
#include <string.h>
static CL_IntegerSet _LocalIdSet (0, 0); // The local id's currently in use.
// Local id zero is always in use.
#endif
static const DEFAULT_POINT_SIZE = 11;
#if defined (__MS_WINDOWS__)
#include <windows.h>
typedef TEXTMETRIC NativeFontStruct;
#elif defined (__OS2__)
typedef FONTMETRICS NativeFontStruct;
#elif defined (__X_MOTIF__)
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
typedef XFontStruct NativeFontStruct;
#endif
class UI_FontEntry: public UI_FontDesc {
public:
UI_FontEntry (short pt = 0, const char* tf = "",
UI_NativeFontRep nm = (UI_NativeFontRep) NULL,
ulong style = 0, bool sf = FALSE
);
~UI_FontEntry ();
bool Italic() {return _style & UIFont_Italic;};
bool Underline() {return _style & UIFont_Underline;};
bool BoldFace() {return _style & UIFont_BoldFace;};
bool StrikeOut() {return _style & UIFont_StrikeOut;};
bool IsFixed ();
bool IsScalable () const;
short Ascent() const;
short Descent() const;
UI_ResourceHandle Handle() const { return _handle; };
#if defined(__X_MOTIF__)
NativeFontStruct* FontInfo () { return _font; };
#else
NativeFontStruct* FontInfo () { return &_font; };
#endif
void RemoveReference() { _refcnt --; };
void AddReference() { _refcnt ++; };
short RefCount () const { return _refcnt; };
short Height () const;
short Width () const;
void Handle (UI_ResourceHandle h) { _handle = h; };
void FetchFontData (UI_ResourceHandle hdc);
const char* ClassName () const {return "UI_FontEntry";}
private:
UI_NativeFontRep _nativeName;
UI_ResourceHandle _handle;
bool _stockfont;
#if defined(__X_MOTIF__)
NativeFontStruct* _font;
#else
NativeFontStruct _font;
#endif
short _refcnt;
friend UI_Font;
};
class FontEntrySet: public CL_ObjectSet {
public:
~FontEntrySet () {DestroyContents();};
};
static FontEntrySet _FontEntries;
UI_Font::UI_Font
#if defined(__MS_WINDOWS__) || defined(__OS2__)
(UI_VisualObject*) // We don't use the parameter under Windows or OS/2
#else
(UI_VisualObject* v)
#endif
: UI_DisplayResource (NULL)
{
_Init ();
}
void UI_Font::_Init
#if defined(__MS_WINDOWS__) || defined(__OS2__)
(UI_VisualObject*) // We don't use the parameter under Windows or OS/2
#else
(UI_VisualObject* v)
#endif
{
_entry = NULL;
#if defined (__MS_WINDOWS__)
_nativeName = SYSTEM_FONT;
_stockFont = TRUE;
_Setup (_nativeName);
#elif defined(__OS2__)
_ptSize = 10;
_typeFace = "System";
_style = 0;
_Setup ();
#elif defined (__X_MOTIF__)
XrmDatabase xrdb;
XrmValue fontvalue;
UI_VObjCollection* parent = 0;
CL_String resource, resourceStack [20], resourceClass;
char *restype [20];
short i = 0;
xrdb = XrmGetDatabase (_TheApplication->Controller().AppDisplay());
if (!xrdb) {
CL_Error::Warning ("UI_Font::UI_Font: Can't get resource database!");
return;
}
if (!v)
_nativeName = "fixed";
else {
parent = v->Parent();
resourceStack [i++] = v->InstanceName();
while (parent) {
resourceStack [i++] = parent->InstanceName();
parent = parent->Parent();
}
resource = _TheApplication->AppClass () + ".";
while (i > 0) {
resource += resourceStack [--i];
resource += ".";
}
resourceClass += "*Font";
resource += "font";
if (!XrmGetResource (xrdb, (char *)resource.AsPtr(),
(char *) resourceClass.AsPtr(),
restype, &fontvalue))
_nativeName = "fixed";
else
_nativeName = (char *)fontvalue.addr;
}
_Setup (_nativeName);
#endif
}
UI_Font::UI_Font (const CL_String& typeface, short pts, ulong style)
: UI_DisplayResource (NULL)
{
_entry = NULL;
_typeFace = typeface;
_ptSize = pts;
_style = style;
_stockFont = FALSE;
_Setup ();
}
UI_Font::UI_Font (UI_DrawingSurface* sfc)
: UI_DisplayResource (sfc)
{
_Init ();
}
UI_Font::UI_Font (const UI_Font& f): UI_DisplayResource (f._clientCtxt)
{
_entry = NULL;
_typeFace = f._typeFace;
_ptSize = f._ptSize;
_style = f._style;
_handle = 0;
_stockFont = f._stockFont;
_nativeName = f._nativeName;
_Setup ();
}
UI_Font::~UI_Font()
{
UI_FontEntry* rfe = (UI_FontEntry *) _entry;
if (rfe) {
rfe->RemoveReference();
if (rfe->RefCount() == 0) {
_FontEntries.Remove (rfe);
delete rfe;
}
}
}
void UI_Font::UseClient (UI_DrawingSurface* client)
{
_clientCtxt = client;
if (_clientCtxt)
_Setup ();
}
bool UI_Font::IsFixed () const
{
return _entry ? ((UI_FontEntry*) _entry)->IsFixed() : TRUE;
}
long UI_Font::Height () const
{
return _entry ? ((UI_FontEntry*) _entry)->Height() : 0;
}
long UI_Font::Width () const
{
return _entry ? ((UI_FontEntry*) _entry)->Width() : 0;
}
#if defined(__MS_WINDOWS__)
static UI_ResourceHandle _GetFontHandle (const UI_FontDesc& font,
HDC dev_ctxt)
{
LOGFONT lf;
CL_String face = font.TypeFace();
if (face.Size() <= 0)
return GetStockObject (SYSTEM_FONT);
long pixels_per_inch;
short ptSize = font.PointSize ();
ulong style = font.Style ();
pixels_per_inch = GetDeviceCaps (dev_ctxt, LOGPIXELSY);
lf.lfHeight = (pixels_per_inch * ptSize)/72;
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = style & UIFont_BoldFace ? FW_BOLD:FW_NORMAL;
lf.lfItalic = style & UIFont_Italic ? TRUE : FALSE;
lf.lfUnderline = style & UIFont_Underline ? TRUE : FALSE;
lf.lfStrikeOut = style & UIFont_StrikeOut ? TRUE : FALSE;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH |FF_DONTCARE;
for (short i = 0; i < face.Length() && i < LF_FACESIZE-1;i++)
lf.lfFaceName[i] = face[i];
lf.lfFaceName[i] = '\0';
return (UI_ResourceHandle) CreateFontIndirect (&lf);
}
#elif defined(__OS2__)
static UI_ResourceHandle _GetFontHandle (const UI_FontDesc& font,
HPS dev_ctxt)
{
ulong style = font.Style ();
FATTRS fatr;
fatr.usRecordLength = sizeof fatr;
fatr.lMatch = 0; // Do not force match
fatr.idRegistry = 0; // Use default registry
fatr.usCodePage = 850; // Code page 850
fatr.lMaxBaselineExt = 0;
fatr.lAveCharWidth = 0;
fatr.fsType = 0;
fatr.fsFontUse = 0;
fatr.fsSelection =
(style & UIFont_Underline ? FATTR_SEL_UNDERSCORE : 0) |
(style & UIFont_Italic ? FATTR_SEL_ITALIC : 0) |
(style & UIFont_StrikeOut ? FATTR_SEL_STRIKEOUT : 0) |
(style & UIFont_BoldFace ? FATTR_SEL_BOLD : 0);
CL_String faceName = font.TypeFace();
if (style & UIFont_BoldFace)
faceName += " Bold";
if (style & UIFont_Italic)
faceName += " Italic";
strcpy (fatr.szFacename, faceName.AsPtr());
UI_ResourceHandle h = _LocalIdSet.SmallestNonMember();
if (h > 254)
CL_Error::Warning ("Font: GetFontHandle: Too many fonts requested.");
if (GpiCreateLogFont (dev_ctxt, NULL, h, &fatr) == GPI_ERROR)
return 0;
_LocalIdSet.Add (h);
return h;
}
#endif
long UI_Font::Width (const char* string) const
{
if (_clientCtxt)
return _clientCtxt->TextWidth (string);
#if defined(__X_MOTIF__)
return TextWidth (string);
#elif defined(__OS2__)
HPS hps = WinGetPS (HWND_DESKTOP);
POINTL textBox[TXTBOX_COUNT];
GpiQueryTextBox (hps, strlen (string), (char*) string,
TXTBOX_COUNT, textBox);
WinReleasePS (hps);
return textBox[TXTBOX_CONCAT].x;
#elif defined(__MS_WINDOWS__)
HDC dev_ctxt = CreateDC ("DISPLAY", NULL, NULL, NULL);
if (dev_ctxt <= 0)
return 0;
UI_FontDesc desc (_typeFace, _ptSize, _style);
HFONT hFont = _GetFontHandle (desc, dev_ctxt);
CL_String s (string);
HFONT old = SelectObject (dev_ctxt, hFont);
long width = GetTextExtent (_handle, s.AsPtr(), s.Size());
SelectObject (dev_ctxt, old);
DeleteObject (hFont);
return width;
#endif
}
short UI_Font::PointSize() const
{
return _entry ? ((UI_FontEntry*) _entry)->PointSize() : _ptSize;
}
CL_String UI_Font::TypeFace() const
{
if (_entry)
return ((UI_FontEntry*) _entry)->TypeFace();
return _typeFace;
}
bool UI_Font::Italic() const
{
return _entry ? ((UI_FontEntry*) _entry)->Italic()
: (_style & UIFont_Italic);
}
bool UI_Font::Underline() const
{
return _entry ? ((UI_FontEntry*) _entry)->Underline()
: (_style & UIFont_Underline);
}
bool UI_Font::BoldFace() const
{
return _entry ? ((UI_FontEntry*) _entry)->BoldFace()
: (_style & UIFont_BoldFace);
}
bool UI_Font::StrikeOut() const
{
return _entry ? ((UI_FontEntry*) _entry)->StrikeOut()
: (_style & UIFont_StrikeOut);
}
short UI_Font::Ascent () const
{
return _entry ? ((UI_FontEntry*) _entry)->Ascent() : 0;
}
short UI_Font::Descent () const
{
return _entry ? ((UI_FontEntry*) _entry)->Descent() : 0;
}
bool UI_Font::IsScalable () const
{
return _entry ? ((UI_FontEntry*) _entry)->IsScalable() : FALSE;
}
void UI_Font::PointSize (short sz)
{
if (_ptSize == sz || !PrepareToChange())
return;
_ptSize = sz;
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
void UI_Font::TypeFace (const char* str)
{
if (_typeFace == str || !PrepareToChange())
return;
_typeFace = CL_String (str).InLowerCase ();
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
void UI_Font::Italic (bool val)
{
if ((_style & UIFont_Italic ? TRUE : FALSE) == val || !PrepareToChange())
return;
if (val)
_style |= UIFont_Italic;
else
_style &= ~UIFont_Italic;
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
void UI_Font::Underline(bool val)
{
if ((_style & UIFont_Underline ? TRUE : FALSE) == val ||
!PrepareToChange())
return;
if (val)
_style |= UIFont_Underline;
else
_style &= ~UIFont_Underline;
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
void UI_Font::BoldFace(bool val)
{
if ((_style & UIFont_BoldFace ? TRUE : FALSE) == val ||
!PrepareToChange())
return;
if (val)
_style |= UIFont_BoldFace;
else
_style &= ~UIFont_BoldFace;
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
void UI_Font::StrikeOut(bool val)
{
if ((_style & UIFont_StrikeOut ? TRUE : FALSE) == val ||
!PrepareToChange())
return;
if (val)
_style |= UIFont_StrikeOut;
else
_style &= ~UIFont_StrikeOut;
_handle = 0;
_stockFont = FALSE;
_Setup ();
Notify();
}
#if defined(__OS2__)
static void _SetupPointSize (HPS hps, short pointSize)
{
// This function is based on the code on Page 362 of Petzold's book.
LONG xRes, yRes ;
SIZEF sizef ;
HDC hdc = GpiQueryDevice (hps) ;
DevQueryCaps (hdc, CAPS_HORIZONTAL_FONT_RES, 1, &xRes) ;
DevQueryCaps (hdc, CAPS_VERTICAL_FONT_RES, 1, &yRes) ;
// POINTL aptl[2] ;
// pointSize *= 10; // Because the following code uses decipoints
// aptl[0].x = 0 ;
// aptl[0].y = 0 ;
// static const int DPM = 28346; // # decipoints per meter
// // (Petzold, p. 367)
// static const int DPM2 = DPM/2;
// aptl[1].x = (16 * xRes * pointSize + DPM2) / DPM;
// aptl[1].y = (16 * yRes * pointSize + DPM2) / DPM;
// GpiConvert (hps, CVTC_DEVICE, CVTC_PAGE, 2L, aptl) ;
// sizef.cx = (aptl[1].x - aptl[0].x) << 12 ;
// sizef.cy = (aptl[1].y - aptl[0].y) << 12 ;
sizef.cx = MAKEFIXED (xRes * pointSize / 72, 0);
sizef.cy = MAKEFIXED (yRes * pointSize / 72, 0);
GpiSetCharBox (hps, &sizef) ;
}
void UI_Font::_Setup()
{
// Under OS/2, we don't use the FontEntries set, because fonts are tied
// to presentation spaces under OS/2, unlike under Windows.
if (!_clientCtxt)
return;
UI_FontDesc desc (_typeFace, _ptSize, _style);
HPS dev_ctxt = _clientCtxt->Handle();
GpiSetCharSet (dev_ctxt, LCID_DEFAULT);
if (_handle)
GpiDeleteSetId (dev_ctxt, _handle);
UI_FontEntry* fe = new UI_FontEntry
((short) _ptSize, _typeFace, _nativeName,
_style, _stockFont);
if (!fe)
return; // No memory
_handle = _GetFontHandle (desc, dev_ctxt);
if (!GpiSetCharSet (dev_ctxt, _handle))
UI_Application::PMError();
_SetupPointSize (dev_ctxt, _ptSize);
fe->Handle (_handle);
fe->FetchFontData (dev_ctxt);
_height = fe->Height();
_width = fe->Width();
if (_entry)
delete (UI_FontEntry*) _entry;
_entry = fe;
GpiSetCharSet (dev_ctxt, _handle);
}
#elif defined(__MS_WINDOWS__)
void UI_Font::_Setup()
{
UI_FontEntry *fe = new UI_FontEntry
((short) _ptSize, _typeFace, _nativeName,
_style, _stockFont);
UI_FontEntry* entry = (UI_FontEntry*) _FontEntries.Find (fe);
bool tmpDsplSfc = FALSE;
UI_ResourceHandle dev_ctxt = 0;
if (!entry) {
if (_clientCtxt)
dev_ctxt = _clientCtxt->Handle();
else {
dev_ctxt = CreateDC ("DISPLAY", NULL, NULL, NULL);
if (dev_ctxt <= 0)
return;
tmpDsplSfc = TRUE;
}
UI_FontDesc desc (_typeFace, _ptSize, _style);
_handle = _GetFontHandle (desc, dev_ctxt);
fe->Handle (_handle);
fe->FetchFontData (dev_ctxt);
_height = fe->Height();
_width = fe->Width();
if (tmpDsplSfc)
DeleteObject (dev_ctxt);
UI_FontEntry* alloc = (UI_FontEntry*) _FontEntries.Find (fe);
if (alloc) {
delete fe;
entry = alloc;
}
else {
entry = fe;
_FontEntries.Add (entry);
}
}
UI_FontEntry* e = (UI_FontEntry*) _entry;
if (!e || e != entry) {
entry->AddReference ();
_entry = entry;
_handle = entry->Handle();
if (e) {
e->RemoveReference ();
if (e->RefCount() == 0) {
_FontEntries.Remove (e);
delete e;
}
}
}
else
_handle = entry->Handle();
if (!tmpDsplSfc && dev_ctxt)
SelectObject (dev_ctxt, _handle);
}
#elif defined (__X_MOTIF__)
void UI_Font::_Setup()
{
UI_FontEntry *fe = new UI_FontEntry
((short) _ptSize, _typeFace, _nativeName,
_style, _stockFont);
if (_entry && *(UI_FontEntry*) _entry == *fe)
return;
UI_FontEntry* entry = (UI_FontEntry*) _FontEntries.Find (fe);
Display* dpy = _TheApplication->Controller().AppDisplay();
int count = 0;
char **fontNames;
CL_String name;
if (!entry) {
bool itals = FALSE;
CL_String ptString;
if (_nativeName.Size() == 0 || _nativeName.CharIndex ('-') >= 0) {
itals = _style & UIFont_Italic;
ptString = _ptSize > 0 ? CL_String (_ptSize)
: CL_String("*");
name.AssignWithFormat ("-*-%s-%s-%c-*--%s-*-*-*-*-*-*-*",
_typeFace.AsPtr(),
_style & UIFont_BoldFace ? "bold": "medium",
(itals ? 'i' : 'r'), ptString.AsPtr());
}
else
name = _nativeName;
fontNames = XListFonts (dpy, (char *) name.AsPtr(), 1, &count);
if (itals && !fontNames) {
name.AssignWithFormat ("-*-%s-%s-%c-*--%s-*-*-*-*-*-*-*",
_typeFace.AsPtr(),
_style & UIFont_BoldFace ? "bold": "medium",
'o' , ptString.AsPtr());
fontNames = XListFonts (dpy, (char *) name.AsPtr(), 1, &count);
}
if (fontNames == NULL) {
CL_Error::Warning ("UI_Font::_Setup(): Font %s not matched",
name.AsPtr());
_handle = 0;
return;
}
_nativeName = name;
_handle = (UI_ResourceHandle) XLoadFont (dpy, fontNames [0]);
fe->Handle (_handle);
fe->FetchFontData (_handle);
entry = fe;
_FontEntries.Add (entry);
XFreeFontNames (fontNames);
}
UI_FontEntry* e = (UI_FontEntry*) _entry;
if (!e || e != entry) {
entry->AddReference ();
_entry = entry;
_handle = entry->Handle();
if (e) {
e->RemoveReference ();
if (e->RefCount() == 0) {
_FontEntries.Remove (e);
delete e;
}
}
}
}
#endif
#if defined(__MS_WINDOWS__) || defined(__X_MOTIF__)
void UI_Font::_Setup (UI_NativeFontRep nativerep)
{
#if defined(__MS_WINDOWS__)
LOGFONT lf;
_handle = GetStockObject (nativerep);
GetObject (_handle, sizeof (LOGFONT), (LPSTR) &lf);
_ptSize = DEFAULT_POINT_SIZE;
_style = 0;
if (lf.lfWeight == FW_BOLD)
_style |= UIFont_BoldFace;
if (lf.lfItalic)
_style |= UIFont_Italic;
if (lf.lfStrikeOut)
_style |= UIFont_StrikeOut;
if (lf.lfUnderline)
_style |= UIFont_Underline;
#elif defined (__X_MOTIF__)
int count = 0;
if (nativerep.CharIndex ('-') < 0) {
// No '-' in the font name: maybe something like 9x15
_ptSize = 0;
_style = 0;
_typeFace = nativerep;
_nativeName = nativerep;
}
else {
long ptsize = nativerep.Field (6, "-").AsLong ();
CL_String tf = nativerep.Field (2, "-");
bool italic = nativerep.Field (4, "-") [0] == 'o';
bool ul = FALSE;
bool boldface = nativerep.Field (3, "-") == (const char *)"bold";
bool so = FALSE;
_ptSize = ptsize;
_typeFace = tf;
_style |= (italic ? UIFont_Italic : 0) |
(ul ? UIFont_Underline : 0) |
(boldface ? UIFont_BoldFace : 0) |
(so ? UIFont_StrikeOut : 0);
}
_nativeName = nativerep;
#endif
_Setup();
}
#endif // defined(__MS_WINDOWS__) || defined(__X_MOTIF__)
void UI_Font::operator= (const UI_FontDesc& o)
{
if (!PrepareToChange())
return;
_typeFace = o.TypeFace();
_ptSize = o.PointSize();
_style = o.Style();
_stockFont = FALSE;
#if defined(__X_MOTIF__)
_nativeName = "";
#elif defined(__MS_WINDOWS__)
_nativeName = 0;
#elif defined(__OS2__)
_nativeName = 0;
#endif
_Setup ();
Notify();
}
void UI_Font::operator= (const CL_Object& o)
{
if (CL_String (o.ClassName()) != "UI_FontDesc") // Must use RTTI
return;
*this = (const UI_FontDesc&) o;
}
#if defined(__X_MOTIF__)
long UI_Font::TextWidth (const CL_String& s) const
{
UI_FontEntry* entry = (UI_FontEntry*) _entry;
if (!_entry)
return 0;
return XTextWidth (entry->_font, s.AsPtr(), s.Size());
}
#endif
void* UI_Font::NativeFontStruct () const
{
UI_FontEntry* entry = (UI_FontEntry*) _entry;
if (!entry)
return 0;
#if defined(__X_MOTIF__)
return entry->_font;
#else
return &(entry->_font);
#endif
}
#if defined(__X_MOTIF__)
void UI_Font::operator= (const char* name)
{
_Setup (name);
}
#endif
// ---------------------- Font enumeration method ------------------------
#if defined(__X_MOTIF__)
const CL_Sequence<UI_FontInfo>& UI_Font::AvailableFonts ()
{
Display *dpy = XtDisplay (_TheApplication->Controller().ShellWidget());
int count;
char* fontSpec = "-*-*-*-*-*--*-*-*-*-*-*-*-*";
char** fontNames = XListFonts (dpy, "*", 10000, &count);
if (!fontNames || count <= 0)
return _allFonts;
for (long i = 0; i < count; i++) {
long style = 0;
CL_String field[12];
CL_String name = fontNames[i];
short n = name.Split (field, 11, "-");
if (n <= 2)
continue;
unsigned long val;
short points;
if (field[3] == "o" || field[3] == "i")
style |= UIFont_Italic;
if (field[2] == "bold")
style |= UIFont_BoldFace;
points = field[6].AsLong() / 10;
UI_FontInfo f (field[1], points, style);
if (points == 0) {
f._ptSize = 0;
f._scalable = TRUE;
}
f._fixedWidth = field[10] == "m";
_allFonts.Add (f);
}
XFreeFontNames (fontNames);
_allFonts.Sort();
return _allFonts;
}
#elif defined(__MS_WINDOWS__)
int CALLBACK GetFontNames (LOGFONT FAR* lpnlf, TEXTMETRIC FAR*, int,
LPSTR lParam)
{
CL_StringSequence& names = *(CL_StringSequence*) lParam;
names.Add (lpnlf->lfFaceName);
return 1;
}
int CALLBACK GetFonts (LOGFONT FAR* lpnlf, TEXTMETRIC FAR* tm, int type,
LPSTR)
{
UI_Font::_AddFont (lpnlf, tm, type);
return 1;
}
void UI_Font::_AddFont (void* p, void* q, int type)
{
LOGFONT* lpnlf = (LOGFONT*) p;
TEXTMETRIC FAR* tm = (TEXTMETRIC FAR*) q;
ulong style =
(lpnlf->lfWeight == FW_BOLD ? UIFont_BoldFace : 0) |
(lpnlf->lfItalic ? UIFont_Italic : 0) |
(lpnlf->lfUnderline ? UIFont_Underline : 0) |
(lpnlf->lfStrikeOut ? UIFont_StrikeOut : 0);
short ptSize = (72*(long) tm->tmHeight) / maxl (1, _ppi);
UI_FontInfo info (lpnlf->lfFaceName, ptSize, style,
type == TRUETYPE_FONTTYPE);
_allFonts.Add (info);
}
const CL_Sequence<UI_FontInfo>& UI_Font::AvailableFonts ()
{
HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
if (dc == 0)
return _allFonts; // Failed
_ppi = GetDeviceCaps (dc, LOGPIXELSY);
CL_StringSequence fontNames;
EnumFontFamilies (dc, NULL, (FONTENUMPROC) GetFontNames,
(LPSTR) &fontNames);
long n = fontNames.Size();
for (long i = 0; i < n; i++)
EnumFontFamilies (dc, fontNames[i].AsPtr(),
(FONTENUMPROC) GetFonts, (LPSTR) &_allFonts);
_allFonts.Sort();
DeleteDC (dc);
return _allFonts;
}
#elif defined (__OS2__)
const CL_Sequence<UI_FontInfo>& UI_Font::AvailableFonts ()
{
HPS hps = WinGetPS (HWND_DESKTOP);
if (hps == 0)
return _allFonts; // Failed
LONG nFonts = 0;
nFonts = GpiQueryFonts (hps, QF_PUBLIC, NULL, &nFonts, 0, NULL);
PFONTMETRICS pfm = new FONTMETRICS [nFonts];
if (!pfm)
return _allFonts; // No memory
GpiQueryFonts (hps, QF_PUBLIC, NULL, &nFonts, sizeof (FONTMETRICS), pfm);
for (long i = 0; i < nFonts; i++) {
ulong style =
(pfm[i].fsSelection & FM_SEL_BOLD ? UIFont_BoldFace : 0) |
(pfm[i].fsSelection & FM_SEL_ITALIC ? UIFont_Italic : 0) |
(pfm[i].fsSelection & FM_SEL_STRIKEOUT ? UIFont_StrikeOut : 0) |
(pfm[i].fsSelection & FM_SEL_UNDERSCORE? UIFont_Underline : 0);
short ptSize = pfm[i].sNominalPointSize / 10;
UI_FontInfo info (pfm[i].szFacename, ptSize, style,
pfm[i].fsDefn & FM_DEFN_OUTLINE ? TRUE : FALSE);
_allFonts.Add (info);
}
delete [] pfm;
WinReleasePS (hps);
_allFonts.Sort();
return _allFonts;
}
#endif
///////////////////////////////////////////////////////////////////////////
// FontEntry:
///////////////////////////////////////////////////////////////////////////
UI_FontEntry::UI_FontEntry (short pt, const char* tf,
UI_NativeFontRep nm, ulong style,
bool sf
)
: UI_FontDesc (tf, pt, style)
{
_nativeName = nm;
_stockfont = sf;
_refcnt = 0;
_handle = 0;
}
UI_FontEntry::~UI_FontEntry()
{
#if defined(__MS_WINDOWS__)
if (_handle && _typeFace.InLowerCase() != "system") {
DeleteObject((HANDLE) _handle);
}
#elif defined(__OS2__)
if (_handle)
_LocalIdSet.Remove (_handle);
#elif defined(__X_MOTIF__)
if (_handle) {
Display *dpy = XtDisplay
(_TheApplication->Controller().ShellWidget());
XFreeFont (dpy, _font);
}
#endif
}
void UI_FontEntry::FetchFontData (UI_ResourceHandle dev_ctxt)
{
#if defined (__MS_WINDOWS__)
if (!dev_ctxt)
return;
TEXTMETRIC tm;
HANDLE old_font = SelectObject (dev_ctxt, _handle);
long pixels_per_inch = GetDeviceCaps (dev_ctxt, LOGPIXELSY);
if (!pixels_per_inch)
return;
GetTextMetrics (dev_ctxt, &tm);
char faceName [LF_FACESIZE];
GetTextFace (dev_ctxt, LF_FACESIZE-1,faceName);
SelectObject (dev_ctxt, old_font);
_ptSize = (72*(long) tm.tmHeight) / ((long) pixels_per_inch);
_font = tm;
_typeFace = faceName;
_style =
(_font.tmWeight == FW_BOLD ? UIFont_BoldFace : 0) |
(_font.tmItalic ? UIFont_Italic : 0) |
(_font.tmStruckOut ? UIFont_StrikeOut : 0) |
(_font.tmUnderlined ? UIFont_Underline : 0);
#elif defined(__OS2__)
if (!dev_ctxt)
return;
FONTMETRICS fm;
GpiQueryFontMetrics (dev_ctxt, sizeof (FONTMETRICS), &fm);
long yRes;
HDC hdc = GpiQueryDevice (dev_ctxt) ;
DevQueryCaps (hdc, CAPS_VERTICAL_FONT_RES, 1, &yRes) ;
_ptSize = fm.lEmHeight * 72 / maxl (1, yRes);
_font = fm;
_typeFace = fm.szFacename;
_style =
(fm.fsSelection & FATTR_SEL_UNDERSCORE ? UIFont_Underline : 0) |
(fm.fsSelection & FATTR_SEL_ITALIC ? UIFont_Italic : 0) |
(fm.fsSelection & FATTR_SEL_STRIKEOUT ? UIFont_StrikeOut : 0) |
(fm.fsSelection & FATTR_SEL_BOLD ? UIFont_BoldFace : 0);
#elif defined (__X_MOTIF__)
Display *dpy = XtDisplay (_TheApplication->Controller().ShellWidget());
_font = XQueryFont (dpy, _handle);
#endif
}
bool UI_FontEntry::IsFixed ()
{
#if defined (__MS_WINDOWS__)
return (_font.tmPitchAndFamily & 0x0f) == FIXED_PITCH;
// Check the four low-order bits
#elif defined(__OS2__)
return _font.fsType & FM_TYPE_FIXED ? TRUE : FALSE;
#elif defined (__X_MOTIF__)
return _typeFace == "fixed" || _nativeName.Field (10, "-") == "m";
#endif
}
short UI_FontEntry::Height () const
{
#if defined (__MS_WINDOWS__)
return _font.tmHeight;
#elif defined (__OS2__)
return _font.lMaxAscender + _font.lMaxDescender;
#elif defined (__X_MOTIF__)
return _font ? (_font->max_bounds.ascent + _font->max_bounds.descent)
: 0;
#endif
}
short UI_FontEntry::Width () const
{
#if defined (__MS_WINDOWS__)
return _font.tmAveCharWidth;
#elif defined (__OS2__)
return _font.lAveCharWidth;
#elif defined (__X_MOTIF__)
return _font->max_bounds.rbearing - _font->min_bounds.lbearing;
#endif
}
short UI_FontEntry::Ascent () const
{
#if defined (__MS_WINDOWS__)
return _font.tmAscent;
#elif defined(__OS2__)
return _font.lMaxAscender;
#elif defined (__X_MOTIF__)
return _font->ascent;
#endif
}
short UI_FontEntry::Descent () const
{
#if defined (__MS_WINDOWS__)
return _font.tmDescent;
#elif defined(__OS2__)
return _font.lMaxDescender;
#elif defined (__X_MOTIF__)
return _font->descent;
#endif
}
bool UI_FontEntry::IsScalable () const
{
#if defined (__MS_WINDOWS__)
return (_font.tmPitchAndFamily & TMPF_VECTOR) ? TRUE : FALSE;
#elif defined (__OS2__)
return _font.fsDefn & FM_DEFN_OUTLINE ? TRUE : FALSE;
#elif defined (__X_MOTIF__)
return _nativeName.Field (6, "-") == 0;
#endif
}