Added platform independent wxImage class Changed wxBitmap and wxImageList accordingly Correctted header text git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@905 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
913 lines
23 KiB
C++
913 lines
23 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: font.cpp
|
|
// Purpose:
|
|
// Author: Robert Roebling
|
|
// Id: $id$
|
|
// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __GNUG__
|
|
#pragma implementation "font.h"
|
|
#endif
|
|
|
|
#include "wx/font.h"
|
|
#include "wx/utils.h"
|
|
#include <strings.h>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// local data
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern wxFontNameDirectory *wxTheFontNameDirectory;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxFont
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class wxFontRefData: public wxObjectRefData
|
|
{
|
|
public:
|
|
|
|
wxFontRefData(void);
|
|
~wxFontRefData(void);
|
|
|
|
wxList m_scaled_xfonts;
|
|
int m_pointSize;
|
|
int m_family, m_style, m_weight;
|
|
bool m_underlined;
|
|
int m_fontId;
|
|
char* m_faceName;
|
|
|
|
bool m_byXFontName;
|
|
GdkFont *m_font;
|
|
|
|
friend wxFont;
|
|
};
|
|
|
|
wxFontRefData::wxFontRefData(void) : m_scaled_xfonts(wxKEY_INTEGER)
|
|
{
|
|
m_byXFontName = FALSE;
|
|
m_pointSize = 12;
|
|
m_family = wxSWISS;
|
|
m_style = wxNORMAL;
|
|
m_weight = wxNORMAL;
|
|
m_underlined = FALSE;
|
|
m_fontId = 0;
|
|
m_faceName = (char *) NULL;
|
|
m_font = (GdkFont *) NULL;
|
|
}
|
|
|
|
wxFontRefData::~wxFontRefData(void)
|
|
{
|
|
wxNode *node = m_scaled_xfonts.First();
|
|
while (node)
|
|
{
|
|
GdkFont *font = (GdkFont*)node->Data();
|
|
wxNode *next = node->Next();
|
|
gdk_font_unref( font );
|
|
node = next;
|
|
}
|
|
if (m_faceName)
|
|
{
|
|
delete m_faceName;
|
|
m_faceName = (char *) NULL;
|
|
}
|
|
if (m_font) gdk_font_unref( m_font );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define M_FONTDATA ((wxFontRefData *)m_refData)
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
|
|
|
|
wxFont::wxFont(void)
|
|
{
|
|
if (wxTheFontList) wxTheFontList->Append( this );
|
|
}
|
|
|
|
wxFont::wxFont( char *xFontName )
|
|
{
|
|
if (!xFontName) return;
|
|
|
|
m_refData = new wxFontRefData();
|
|
|
|
M_FONTDATA->m_byXFontName = TRUE;
|
|
M_FONTDATA->m_font = gdk_font_load( xFontName );
|
|
}
|
|
|
|
wxFont::wxFont(int PointSize, int FontIdOrFamily, int Style, int Weight,
|
|
bool Underlined, const char* Face)
|
|
{
|
|
m_refData = new wxFontRefData();
|
|
|
|
if ((M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL) )
|
|
{
|
|
M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, FontIdOrFamily );
|
|
M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
|
|
}
|
|
else
|
|
{
|
|
M_FONTDATA->m_fontId = FontIdOrFamily;
|
|
M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
|
|
}
|
|
if (Style == wxDEFAULT) Style = wxSWISS;
|
|
M_FONTDATA->m_style = Style;
|
|
if (Weight == wxDEFAULT) Weight = wxNORMAL;
|
|
M_FONTDATA->m_weight = Weight;
|
|
if (PointSize == wxDEFAULT) PointSize = 10;
|
|
M_FONTDATA->m_pointSize = PointSize;
|
|
M_FONTDATA->m_underlined = Underlined;
|
|
|
|
if (wxTheFontList) wxTheFontList->Append( this );
|
|
}
|
|
|
|
wxFont::wxFont(int PointSize, const char *Face, int Family, int Style,
|
|
int Weight, bool Underlined)
|
|
{
|
|
m_refData = new wxFontRefData();
|
|
|
|
M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, Family );
|
|
M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL;
|
|
M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( M_FONTDATA->m_fontId );
|
|
M_FONTDATA->m_style = Style;
|
|
M_FONTDATA->m_weight = Weight;
|
|
M_FONTDATA->m_pointSize = PointSize;
|
|
M_FONTDATA->m_underlined = Underlined;
|
|
|
|
if (wxTheFontList) wxTheFontList->Append( this );
|
|
}
|
|
|
|
wxFont::wxFont( const wxFont& font )
|
|
{
|
|
Ref( font );
|
|
|
|
if (wxTheFontList) wxTheFontList->Append( this );
|
|
}
|
|
|
|
wxFont::wxFont( const wxFont* font )
|
|
{
|
|
UnRef();
|
|
if (font) Ref( *font );
|
|
|
|
if (wxTheFontList) wxTheFontList->Append( this );
|
|
}
|
|
|
|
wxFont::~wxFont(void)
|
|
{
|
|
if (wxTheFontList) wxTheFontList->DeleteObject( this );
|
|
}
|
|
|
|
wxFont& wxFont::operator = ( const wxFont& font )
|
|
{
|
|
if (*this == font) return (*this);
|
|
Ref( font );
|
|
return *this;
|
|
}
|
|
|
|
bool wxFont::operator == ( const wxFont& font )
|
|
{
|
|
return m_refData == font.m_refData;
|
|
}
|
|
|
|
bool wxFont::operator != ( const wxFont& font )
|
|
{
|
|
return m_refData != font.m_refData;
|
|
}
|
|
|
|
bool wxFont::Ok() const
|
|
{
|
|
return (m_refData != NULL);
|
|
}
|
|
|
|
int wxFont::GetPointSize(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return 0;
|
|
}
|
|
|
|
return M_FONTDATA->m_pointSize;
|
|
}
|
|
|
|
wxString wxFont::GetFaceString(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return "";
|
|
}
|
|
|
|
wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
|
|
return s;
|
|
}
|
|
|
|
wxString wxFont::GetFaceName(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return "";
|
|
}
|
|
|
|
wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
|
|
return s;
|
|
}
|
|
|
|
int wxFont::GetFamily(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return 0;
|
|
}
|
|
|
|
return M_FONTDATA->m_family;
|
|
}
|
|
|
|
wxString wxFont::GetFamilyString(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return "wxDEFAULT";
|
|
}
|
|
|
|
switch (M_FONTDATA->m_family)
|
|
{
|
|
case wxDECORATIVE: return wxString("wxDECORATIVE");
|
|
case wxROMAN: return wxString("wxROMAN");
|
|
case wxSCRIPT: return wxString("wxSCRIPT");
|
|
case wxSWISS: return wxString("wxSWISS");
|
|
case wxMODERN: return wxString("wxMODERN");
|
|
case wxTELETYPE: return wxString("wxTELETYPE");
|
|
default: return "wxDEFAULT";
|
|
}
|
|
|
|
return "wxDEFAULT";
|
|
}
|
|
|
|
int wxFont::GetFontId(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return 0;
|
|
}
|
|
|
|
return M_FONTDATA->m_fontId; // stub
|
|
}
|
|
|
|
int wxFont::GetStyle(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return 0;
|
|
}
|
|
|
|
return M_FONTDATA->m_style;
|
|
}
|
|
|
|
wxString wxFont::GetStyleString(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return "wxDEFAULT";
|
|
}
|
|
|
|
switch (M_FONTDATA->m_style)
|
|
{
|
|
case wxNORMAL: return wxString("wxNORMAL");
|
|
case wxSLANT: return wxString("wxSLANT");
|
|
case wxITALIC: return wxString("wxITALIC");
|
|
default: return wxString("wxDEFAULT");
|
|
}
|
|
|
|
return wxString("wxDEFAULT");
|
|
}
|
|
|
|
int wxFont::GetWeight(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return 0;
|
|
}
|
|
|
|
return M_FONTDATA->m_weight;
|
|
}
|
|
|
|
wxString wxFont::GetWeightString(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return "wxDEFAULT";
|
|
}
|
|
|
|
switch (M_FONTDATA->m_weight)
|
|
{
|
|
case wxNORMAL: return wxString("wxNORMAL");
|
|
case wxBOLD: return wxString("wxBOLD");
|
|
case wxLIGHT: return wxString("wxLIGHT");
|
|
default: return wxString("wxDEFAULT");
|
|
}
|
|
|
|
return wxString("wxDEFAULT");
|
|
}
|
|
|
|
bool wxFont::GetUnderlined(void) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return FALSE;
|
|
}
|
|
|
|
return M_FONTDATA->m_underlined;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// get internal representation of font
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// local help function
|
|
static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
|
|
int style, int weight,
|
|
bool underlined);
|
|
|
|
GdkFont *wxFont::GetInternalFont(float scale) const
|
|
{
|
|
if (!Ok())
|
|
{
|
|
wxFAIL_MSG( "invalid font" );
|
|
return (GdkFont*) NULL;
|
|
}
|
|
|
|
if (M_FONTDATA->m_byXFontName) return M_FONTDATA->m_font;
|
|
|
|
long int_scale = long(scale * 100.0 + 0.5); // key for fontlist
|
|
int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
|
|
GdkFont *font = (GdkFont *) NULL;
|
|
|
|
wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
|
|
if (node)
|
|
{
|
|
font = (GdkFont*)node->Data();
|
|
}
|
|
else
|
|
{
|
|
font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_fontId, M_FONTDATA->m_style,
|
|
M_FONTDATA->m_weight, M_FONTDATA->m_underlined );
|
|
M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
|
|
}
|
|
if (!font)
|
|
printf("could not load any font");
|
|
// wxError("could not load any font", "wxFont");
|
|
return font;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// local utilities to find a X font
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static GdkFont *wxLoadQueryFont(int point_size, int fontid, int style,
|
|
int weight, bool WXUNUSED(underlined))
|
|
{
|
|
char buffer[512];
|
|
char *name = wxTheFontNameDirectory->GetScreenName( fontid, weight, style );
|
|
|
|
if (!name)
|
|
name = "-*-*-*-*-*-*-*-%d-*-*-*-*-*-*";
|
|
sprintf(buffer, name, point_size);
|
|
|
|
return gdk_font_load( buffer );
|
|
}
|
|
|
|
static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
|
|
int style, int weight,
|
|
bool underlined)
|
|
{
|
|
GdkFont *font;
|
|
|
|
font = wxLoadQueryFont( point_size, fontid, style, weight, underlined );
|
|
|
|
if (!font) {
|
|
// search up and down by stepsize 10
|
|
int max_size = point_size + 20 * (1 + (point_size/180));
|
|
int min_size = point_size - 20 * (1 + (point_size/180));
|
|
int i;
|
|
|
|
// Search for smaller size (approx.)
|
|
for (i=point_size-10; !font && i >= 10 && i >= min_size; i -= 10)
|
|
font = wxLoadQueryFont(i, fontid, style, weight, underlined);
|
|
// Search for larger size (approx.)
|
|
for (i=point_size+10; !font && i <= max_size; i += 10)
|
|
font = wxLoadQueryFont(i, fontid, style, weight, underlined);
|
|
// Try default family
|
|
if (!font && fontid != wxDEFAULT)
|
|
font = wxLoadQueryFont(point_size, wxDEFAULT, style,
|
|
weight, underlined);
|
|
// Bogus font
|
|
if (!font)
|
|
font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
|
|
underlined);
|
|
}
|
|
return font;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// face names and index functions
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static char *font_defaults[] = {
|
|
"FamilyDefault", "Default",
|
|
"FamilyRoman", "Roman",
|
|
"FamilyDecorative", "Decorative",
|
|
"FamilyModern", "Modern",
|
|
"FamilyTeletype", "Teletype",
|
|
"FamilySwiss", "Swiss",
|
|
"FamilyScript", "Script",
|
|
|
|
"AfmMedium", "",
|
|
"AfmBold", "Bo",
|
|
"AfmLight", "",
|
|
"AfmStraight", "",
|
|
"AfmItalic", "${AfmSlant}",
|
|
"AfmSlant", "O",
|
|
"AfmRoman", "Ro",
|
|
"AfmTimes", "Times",
|
|
"AfmHelvetica", "Helv",
|
|
"AfmCourier", "Cour",
|
|
|
|
"Afm___", "${AfmTimes,$[weight],$[style]}",
|
|
|
|
"AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
|
|
"AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
|
|
"AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
|
|
"AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
|
|
"AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
|
|
|
|
"AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
|
|
"AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
|
|
|
|
"AfmTeletype__", "${AfmModern,$[weight],$[style]}",
|
|
|
|
"PostScriptMediumStraight", "",
|
|
"PostScriptMediumItalic", "-Oblique",
|
|
"PostScriptMediumSlant", "-Oblique",
|
|
"PostScriptLightStraight", "",
|
|
"PostScriptLightItalic", "-Oblique",
|
|
"PostScriptLightSlant", "-Oblique",
|
|
"PostScriptBoldStraight", "-Bold",
|
|
"PostScriptBoldItalic", "-BoldOblique",
|
|
"PostScriptBoldSlant", "-BoldOblique",
|
|
|
|
#if WX_NORMALIZED_PS_FONTS
|
|
"PostScript___", "${PostScriptTimes,$[weight],$[style]}",
|
|
#else
|
|
"PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
|
|
"PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
|
|
#endif
|
|
|
|
"PostScriptTimesMedium", "",
|
|
"PostScriptTimesLight", "",
|
|
"PostScriptTimesBold", "Bold",
|
|
|
|
"PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
|
|
"PostScriptTimesMediumStraight", "Times-Roman",
|
|
"PostScriptTimesLightStraight", "Times-Roman",
|
|
"PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
|
|
"PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
|
|
|
|
"PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
|
|
"PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
|
|
|
|
"PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
|
|
|
|
#if !WX_NORMALIZED_PS_FONTS
|
|
"PostScriptScript__", "Zapf-Chancery-MediumItalic",
|
|
#endif
|
|
|
|
"ScreenMedium", "medium",
|
|
"ScreenBold", "bold",
|
|
"ScreenLight", "light",
|
|
"ScreenStraight", "r",
|
|
"ScreenItalic", "i",
|
|
"ScreenSlant", "o",
|
|
|
|
"ScreenDefaultBase", "misc-fixed",
|
|
"ScreenRomanBase", "*-times",
|
|
"ScreenDecorativeBase", "*-helvetica",
|
|
"ScreenModernBase", "*-courier",
|
|
"ScreenTeletypeBase", "*-lucidatypewriter",
|
|
"ScreenSwissBase", "*-lucida",
|
|
"ScreenScriptBase", "*-zapfchancery",
|
|
|
|
"ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
|
|
"-normal-*-*-%d-*-*-*-*-*-*",
|
|
|
|
"Screen___",
|
|
"-${ScreenDefaultBase}${ScreenStdSuffix}",
|
|
"ScreenRoman__",
|
|
"-${ScreenRomanBase}${ScreenStdSuffix}",
|
|
"ScreenDecorative__",
|
|
"-${ScreenDecorativeBase}${ScreenStdSuffix}",
|
|
"ScreenModern__",
|
|
"-${ScreenModernBase}${ScreenStdSuffix}",
|
|
"ScreenTeletype__",
|
|
"-${ScreenTeletypeBase}${ScreenStdSuffix}",
|
|
"ScreenSwiss__",
|
|
"-${ScreenSwissBase}${ScreenStdSuffix}",
|
|
"ScreenScript__",
|
|
"-${ScreenScriptBase}${ScreenStdSuffix}",
|
|
(char *) NULL
|
|
};
|
|
|
|
enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD, wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
|
|
enum {wxSTYLE_NORMAL, wxSTYLE_ITALIC, wxSTYLE_SLANT, wxNUM_STYLES};
|
|
|
|
static int WCoordinate(int w)
|
|
{
|
|
switch (w) {
|
|
case wxBOLD: return wxWEIGHT_BOLD;
|
|
case wxLIGHT: return wxWEIGHT_LIGHT;
|
|
case wxNORMAL:
|
|
default: return wxWEIGHT_NORMAL;
|
|
}
|
|
};
|
|
|
|
static int SCoordinate(int s)
|
|
{
|
|
switch (s) {
|
|
case wxITALIC: return wxSTYLE_ITALIC;
|
|
case wxSLANT: return wxSTYLE_SLANT;
|
|
case wxNORMAL:
|
|
default: return wxSTYLE_NORMAL;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxSuffixMap
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class wxSuffixMap {
|
|
public:
|
|
~wxSuffixMap(void);
|
|
|
|
inline char *GetName(int weight, int style)
|
|
{
|
|
return ( map [WCoordinate(weight)] [SCoordinate(style)] );
|
|
}
|
|
|
|
char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
|
|
void Initialize(const char *, const char *);
|
|
};
|
|
|
|
//#if !USE_RESOURCES
|
|
#define wxGetResource(a, b, c) 0
|
|
//#endif
|
|
|
|
static void SearchResource(const char *prefix, const char **names, int count, char **v)
|
|
{
|
|
int k, i, j;
|
|
char resource[1024], **defaults, *internal;
|
|
|
|
k = 1 << count;
|
|
|
|
*v = (char *) NULL;
|
|
internal = (char *) NULL;
|
|
|
|
for (i = 0; i < k; i++) {
|
|
strcpy(resource, prefix);
|
|
for (j = 0; j < count; j++) {
|
|
if (!(i & (1 << j)))
|
|
strcat(resource, names[j]);
|
|
else
|
|
strcat(resource, "_");
|
|
}
|
|
if (wxGetResource(wxAPP_CLASS, (char *)resource, v))
|
|
return;
|
|
if (!internal) {
|
|
defaults = font_defaults;
|
|
while (*defaults) {
|
|
if (!strcmp(*defaults, resource)) {
|
|
internal = defaults[1];
|
|
break;
|
|
}
|
|
defaults += 2;
|
|
}
|
|
}
|
|
}
|
|
if (internal)
|
|
*v = copystring(internal);
|
|
}
|
|
|
|
wxSuffixMap::~wxSuffixMap(void)
|
|
{
|
|
int k, j;
|
|
|
|
for (k = 0; k < wxNUM_WEIGHTS; ++k)
|
|
for (j = 0; j < wxNUM_STYLES; ++j)
|
|
if (map[k][j]) {
|
|
delete[] map[k][j];
|
|
map[k][j] = (char *) NULL;
|
|
}
|
|
}
|
|
|
|
void wxSuffixMap::Initialize(const char *resname, const char *devresname)
|
|
{
|
|
const char *weight, *style;
|
|
char *v;
|
|
int i, j, k;
|
|
const char *names[3];
|
|
|
|
for (k = 0; k < wxNUM_WEIGHTS; k++) {
|
|
switch (k) {
|
|
case wxWEIGHT_NORMAL: weight = "Medium"; break;
|
|
case wxWEIGHT_LIGHT: weight = "Light"; break;
|
|
case wxWEIGHT_BOLD:
|
|
default: weight = "Bold";
|
|
}
|
|
for (j = 0; j < wxNUM_STYLES; j++) {
|
|
switch (j) {
|
|
case wxSTYLE_NORMAL: style = "Straight"; break;
|
|
case wxSTYLE_ITALIC: style = "Italic"; break;
|
|
case wxSTYLE_SLANT:
|
|
default: style = "Slant";
|
|
}
|
|
names[0] = resname;
|
|
names[1] = weight;
|
|
names[2] = style;
|
|
|
|
SearchResource(devresname, names, 3, &v);
|
|
|
|
/* Expand macros in the found string: */
|
|
found:
|
|
int len, closer = 0, startpos = 0;
|
|
|
|
len = (v ? strlen(v) : 0);
|
|
for (i = 0; i < len; i++) {
|
|
if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{'))) {
|
|
startpos = i;
|
|
closer = (v[i+1] == '[') ? ']' : '}';
|
|
++i;
|
|
} else if (v[i] == closer) {
|
|
int newstrlen;
|
|
const char *r = (char *) NULL; bool delete_r = FALSE;
|
|
char *name;
|
|
|
|
name = v + startpos + 2;
|
|
v[i] = 0;
|
|
|
|
if (closer == '}') {
|
|
int i, count, len;
|
|
char **names;
|
|
|
|
for (i = 0, count = 1; name[i]; i++)
|
|
if (name[i] == ',')
|
|
count++;
|
|
|
|
len = i;
|
|
|
|
names = new char*[count];
|
|
names[0] = name;
|
|
for (i = 0, count = 1; i < len; i++)
|
|
if (name[i] == ',') {
|
|
names[count++] = name + i + 1;
|
|
name[i] = 0;
|
|
}
|
|
|
|
SearchResource("", (const char **)names, count, (char **)&r);
|
|
delete_r = (r != 0);
|
|
delete[] names;
|
|
|
|
if (!r) {
|
|
for (i = 0; i < len; i++)
|
|
if (!name[i])
|
|
name[i] = ',';
|
|
r = "";
|
|
printf("Bad resource name \"%s\" in font lookup\n", name);
|
|
}
|
|
} else if (!strcmp(name, "weight")) {
|
|
r = weight;
|
|
} else if (!strcmp(name, "style")) {
|
|
r = style;
|
|
} else if (!strcmp(name, "family")) {
|
|
r = resname;
|
|
} else {
|
|
r = "";
|
|
printf("Bad font macro name \"%s\"\n", name);
|
|
}
|
|
|
|
// add r to v
|
|
newstrlen = strlen(r);
|
|
char *naya = new char[startpos + newstrlen + len - i];
|
|
memcpy(naya, v, startpos);
|
|
memcpy(naya + startpos, r, newstrlen);
|
|
memcpy(naya + startpos + newstrlen, v + i + 1, len - i);
|
|
if (delete_r)
|
|
delete[] (char*)r;
|
|
delete[] v;
|
|
v = naya;
|
|
|
|
goto found;
|
|
}
|
|
}
|
|
/* We have a final value: */
|
|
map[k][j] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxFontNameItem
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class wxFontNameItem : public wxObject {
|
|
DECLARE_DYNAMIC_CLASS(wxFontNameItem)
|
|
public:
|
|
wxFontNameItem(const char *name, int id, int family);
|
|
~wxFontNameItem();
|
|
|
|
inline char* GetScreenName(int w, int s) {return screen.GetName(w, s);}
|
|
inline char* GetPostScriptName(int w, int s) {return printing.GetName(w, s);}
|
|
inline char* GetAFMName(int w, int s) {return afm.GetName(w, s);}
|
|
inline char* GetName(void) {return name;}
|
|
inline int GetFamily(void) {return family;}
|
|
inline int GetId(void) {return id;}
|
|
inline bool IsRoman(void) {return isroman;}
|
|
#if WXDEBUG
|
|
void Dump(ostream& str);
|
|
#endif
|
|
|
|
int id;
|
|
int family;
|
|
char *name;
|
|
wxSuffixMap screen, printing, afm;
|
|
bool isroman;
|
|
};
|
|
|
|
IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
|
|
|
|
wxFontNameItem::wxFontNameItem(const char *Name, int Id, int Family)
|
|
{
|
|
name = copystring(Name);
|
|
id = Id;
|
|
family = Family;
|
|
|
|
screen. Initialize(name, "Screen");
|
|
printing.Initialize(name, "PostScript");
|
|
afm. Initialize(name, "Afm");
|
|
}
|
|
|
|
wxFontNameItem::~wxFontNameItem(void)
|
|
{
|
|
if (name)
|
|
delete[] name;
|
|
name = (char *) NULL;
|
|
}
|
|
|
|
#if WXDEBUG
|
|
void wxFontNameItem::Dump(ostream& str)
|
|
{
|
|
str << "wxFontNameItem(" << name << ")";
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxFontDirectory
|
|
//-----------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
|
|
|
|
wxFontNameDirectory::wxFontNameDirectory(void)
|
|
{
|
|
table = new wxHashTable(wxKEY_INTEGER, 20);
|
|
nextFontId = -1;
|
|
}
|
|
|
|
wxFontNameDirectory::~wxFontNameDirectory()
|
|
{
|
|
// Cleanup wxFontNameItems allocated
|
|
table->BeginFind();
|
|
wxNode *node = table->Next();
|
|
while (node) {
|
|
wxFontNameItem *item = (wxFontNameItem*)node->Data();
|
|
delete item;
|
|
node = table->Next();
|
|
}
|
|
delete table;
|
|
}
|
|
|
|
int wxFontNameDirectory::GetNewFontId(void)
|
|
{
|
|
return (nextFontId--);
|
|
}
|
|
|
|
void wxFontNameDirectory::Initialize()
|
|
{
|
|
Initialize(wxDEFAULT, wxDEFAULT, "Default");
|
|
Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
|
|
Initialize(wxROMAN, wxROMAN, "Roman");
|
|
Initialize(wxMODERN, wxMODERN, "Modern");
|
|
Initialize(wxTELETYPE, wxTELETYPE, "Teletype");
|
|
Initialize(wxSWISS, wxSWISS, "Swiss");
|
|
Initialize(wxSCRIPT, wxSCRIPT, "Script");
|
|
}
|
|
|
|
void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
|
|
{
|
|
char *fam, resource[256];
|
|
|
|
sprintf(resource, "Family%s", resname);
|
|
SearchResource((const char *)resource, (const char **) NULL, 0, (char **)&fam);
|
|
if (fam) {
|
|
if (!strcmp(fam, "Default")) family = wxDEFAULT;
|
|
else if (!strcmp(fam, "Roman")) family = wxROMAN;
|
|
else if (!strcmp(fam, "Decorative")) family = wxDECORATIVE;
|
|
else if (!strcmp(fam, "Modern")) family = wxMODERN;
|
|
else if (!strcmp(fam, "Teletype")) family = wxTELETYPE;
|
|
else if (!strcmp(fam, "Swiss")) family = wxSWISS;
|
|
else if (!strcmp(fam, "Script")) family = wxSCRIPT;
|
|
delete[] fam; // free resource
|
|
}
|
|
table->Put(fontid, new wxFontNameItem(resname, fontid, family));
|
|
}
|
|
|
|
int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
|
|
{
|
|
int id;
|
|
|
|
// font exists -> return id
|
|
if ( (id = GetFontId(name)) ) return id;
|
|
// create new font
|
|
Initialize(id=GetNewFontId(), family, name);
|
|
return id;
|
|
}
|
|
|
|
char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
|
|
{
|
|
wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
|
|
if (item)
|
|
return item->GetScreenName(weight, style);
|
|
// font does not exist
|
|
return (char *) NULL;
|
|
}
|
|
|
|
char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
|
|
{
|
|
wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
|
|
if (item)
|
|
return item->GetPostScriptName(weight, style);
|
|
// font does not exist
|
|
return (char *) NULL;
|
|
}
|
|
|
|
char *wxFontNameDirectory::GetAFMName(int fontid, int weight, int style)
|
|
{
|
|
wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
|
|
if (item)
|
|
return item->GetAFMName(weight, style);
|
|
// font does not exist
|
|
return (char *) NULL;
|
|
}
|
|
|
|
char *wxFontNameDirectory::GetFontName(int fontid)
|
|
{
|
|
wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
|
|
if (item)
|
|
return item->GetName();
|
|
// font does not exist
|
|
return (char *) NULL;
|
|
}
|
|
|
|
int wxFontNameDirectory::GetFontId(const char *name)
|
|
{
|
|
wxNode *node;
|
|
|
|
table->BeginFind();
|
|
|
|
while ( (node = table->Next()) ) {
|
|
wxFontNameItem *item = (wxFontNameItem*)node->Data();
|
|
if (!strcmp(name, item->name))
|
|
return item->id;
|
|
}
|
|
// font does not exist
|
|
return 0;
|
|
}
|
|
|
|
int wxFontNameDirectory::GetFamily(int fontid)
|
|
{
|
|
wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid);
|
|
|
|
if (item)
|
|
return item->family;
|
|
// font does not exist
|
|
return wxDEFAULT;
|
|
}
|