X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dfc5454127ac2195e10deebb216d82c674e757df..4d194d6368477b8bd1d15d261aff7a8c63ed5064:/src/motif/font.cpp diff --git a/src/motif/font.cpp b/src/motif/font.cpp index feeb310e0b..4b46312660 100644 --- a/src/motif/font.cpp +++ b/src/motif/font.cpp @@ -6,7 +6,7 @@ // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -19,13 +19,33 @@ #include "wx/gdicmn.h" #include "wx/utils.h" -#include +#include #if !USE_SHARED_LIBRARIES IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) #endif -wxFontRefData::wxFontRefData(): m_fontsByScale(wxKEY_INTEGER) +wxXFont::wxXFont() +{ + m_fontStruct = (WXFontStructPtr) 0; + m_fontList = (WXFontList) 0; + m_display = (WXDisplay*) 0; + m_scale = 100; +} + +wxXFont::~wxXFont() +{ + XmFontList fontList = (XmFontList) m_fontList; + + XmFontListFree (fontList); + + // TODO: why does freeing the font produce a segv??? + // Note that XFreeFont wasn't called in wxWin 1.68 either. + // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct; + // XFreeFont((Display*) m_display, fontStruct); +} + +wxFontRefData::wxFontRefData() { m_style = 0; m_pointSize = 0; @@ -36,7 +56,7 @@ wxFontRefData::wxFontRefData(): m_fontsByScale(wxKEY_INTEGER) m_faceName = ""; } -wxFontRefData::wxFontRefData(const wxFontRefData& data): m_fontsByScale(wxKEY_INTEGER) +wxFontRefData::wxFontRefData(const wxFontRefData& data) { m_style = data.m_style; m_pointSize = data.m_pointSize; @@ -52,14 +72,14 @@ wxFontRefData::wxFontRefData(const wxFontRefData& data): m_fontsByScale(wxKEY_IN wxFontRefData::~wxFontRefData() { - wxNode* node = m_fontsByScale.First(); + wxNode* node = m_fonts.First(); while (node) { - XFontStruct* fontStruct = (XFontStruct*) node->Data(); - XFreeFont((Display*) wxGetDisplay, fontStruct); + wxXFont* f = (wxXFont*) node->Data(); + delete f; node = node->Next(); } - m_fontsByScale.Clear(); + m_fonts.Clear(); } wxFont::wxFont() @@ -107,17 +127,17 @@ bool wxFont::RealizeResource() void wxFont::Unshare() { - // Don't change shared data - if (!m_refData) + // Don't change shared data + if (!m_refData) { - m_refData = new wxFontRefData(); - } + m_refData = new wxFontRefData(); + } else { - wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData); - UnRef(); - m_refData = ref; - } + wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData); + UnRef(); + m_refData = ref; + } } void wxFont::SetPointSize(int pointSize) @@ -176,32 +196,32 @@ void wxFont::SetUnderlined(bool underlined) wxString wxFont::GetFamilyString() const { - wxString fam(""); - switch (GetFamily()) - { + wxString fam(""); + switch (GetFamily()) + { case wxDECORATIVE: - fam = "wxDECORATIVE"; - break; + fam = "wxDECORATIVE"; + break; case wxROMAN: - fam = "wxROMAN"; - break; + fam = "wxROMAN"; + break; case wxSCRIPT: - fam = "wxSCRIPT"; - break; + fam = "wxSCRIPT"; + break; case wxSWISS: - fam = "wxSWISS"; - break; + fam = "wxSWISS"; + break; case wxMODERN: - fam = "wxMODERN"; - break; + fam = "wxMODERN"; + break; case wxTELETYPE: - fam = "wxTELETYPE"; - break; + fam = "wxTELETYPE"; + break; default: - fam = "wxDEFAULT"; - break; - } - return fam; + fam = "wxDEFAULT"; + break; + } + return fam; } /* New font system */ @@ -209,7 +229,7 @@ wxString wxFont::GetFaceName() const { wxString str(""); if (M_FONTDATA) - str = M_FONTDATA->m_faceName ; + str = M_FONTDATA->m_faceName ; return str; } @@ -218,15 +238,15 @@ wxString wxFont::GetStyleString() const wxString styl(""); switch (GetStyle()) { - case wxITALIC: - styl = "wxITALIC"; - break; - case wxSLANT: - styl = "wxSLANT"; - break; - default: - styl = "wxNORMAL"; - break; + case wxITALIC: + styl = "wxITALIC"; + break; + case wxSLANT: + styl = "wxSLANT"; + break; + default: + styl = "wxNORMAL"; + break; } return styl; } @@ -236,15 +256,15 @@ wxString wxFont::GetWeightString() const wxString w(""); switch (GetWeight()) { - case wxBOLD: - w = "wxBOLD"; - break; - case wxLIGHT: - w = "wxLIGHT"; - break; - default: - w = "wxNORMAL"; - break; + case wxBOLD: + w = "wxBOLD"; + break; + case wxLIGHT: + w = "wxLIGHT"; + break; + default: + w = "wxNORMAL"; + break; } return w; } @@ -252,96 +272,105 @@ wxString wxFont::GetWeightString() const // Find an existing, or create a new, XFontStruct // based on this wxFont and the given scale. Append the // font to list in the private data for future reference. -WXFontStructPtr wxFont::FindOrCreateFontStruct(double scale) +wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const { - if (!Ok()) - return NULL; - - long intScale = long(scale * 100.0 + 0.5); // key for fontlist - int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100; - - wxNode* node = M_FONTDATA->m_fontsByScale.Find(intScale); - if (node) - { - return (WXFontStructPtr) node->Data(); - } - - WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family, - M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); - - if (!font) - { - // search up and down by stepsize 10 - int max_size = pointSize + 20 * (1 + (pointSize/180)); - int min_size = pointSize - 20 * (1 + (pointSize/180)); - int i; - - // Search for smaller size (approx.) - for (i=pointSize-10; !font && i >= 10 && i >= min_size; i -= 10) - font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); - // Search for larger size (approx.) - for (i=pointSize+10; !font && i <= max_size; i += 10) - font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); - // Try default family - if (!font && M_FONTDATA->m_family != wxDEFAULT) - font = LoadQueryFont(pointSize, wxDEFAULT, M_FONTDATA->m_style, - M_FONTDATA->m_weight, M_FONTDATA->m_underlined); - // Bogus font - if (!font) - font = LoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, - M_FONTDATA->m_underlined); - } - if (font) - { - M_FONTDATA->m_fontsByScale.Append(intScale, (wxObject*) font); - return (WXFontStructPtr) font; - } - return font; + if (!Ok()) + return (wxXFont*) NULL; + + long intScale = long(scale * 100.0 + 0.5); // key for wxXFont + int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100; + + wxNode* node = M_FONTDATA->m_fonts.First(); + while (node) + { + wxXFont* f = (wxXFont*) node->Data(); + if ((!display || (f->m_display == display)) && (f->m_scale == intScale)) + return f; + node = node->Next(); + } + + WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family, + M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + + if (!font) + { + // search up and down by stepsize 10 + int max_size = pointSize + 20 * (1 + (pointSize/180)); + int min_size = pointSize - 20 * (1 + (pointSize/180)); + int i; + + // Search for smaller size (approx.) + for (i=pointSize-10; !font && i >= 10 && i >= min_size; i -= 10) + font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Search for larger size (approx.) + for (i=pointSize+10; !font && i <= max_size; i += 10) + font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Try default family + if (!font && M_FONTDATA->m_family != wxDEFAULT) + font = LoadQueryFont(pointSize, wxDEFAULT, M_FONTDATA->m_style, + M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Bogus font + if (!font) + font = LoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + M_FONTDATA->m_underlined); + wxASSERT_MSG( (font != (XFontStruct*) NULL), "Could not allocate even a default font -- something is wrong." ); + } + if (font) + { + wxXFont* f = new wxXFont; + f->m_fontStruct = font; + f->m_display = ( display ? display : wxGetDisplay() ); + f->m_scale = intScale; + f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET); + M_FONTDATA->m_fonts.Append(f); + return f; + } + return (wxXFont*) NULL; } WXFontStructPtr wxFont::LoadQueryFont(int pointSize, int family, int style, - int weight, bool underlined) + int weight, bool underlined) const { char *xfamily; char *xstyle; char *xweight; switch (family) { - case wxDECORATIVE: xfamily = "lucida"; - break; - case wxROMAN: xfamily = "times"; - break; - case wxMODERN: xfamily = "courier"; - break; - case wxSWISS: xfamily = "lucida"; - break; - case wxDEFAULT: - default: xfamily = "*"; + case wxDECORATIVE: xfamily = "lucida"; + break; + case wxROMAN: xfamily = "times"; + break; + case wxMODERN: xfamily = "courier"; + break; + case wxSWISS: xfamily = "lucida"; + break; + case wxDEFAULT: + default: xfamily = "*"; } switch (style) { - case wxITALIC: xstyle = "i"; - break; - case wxSLANT: xstyle = "o"; - break; - case wxNORMAL: xstyle = "r"; - break; - default: xstyle = "*"; - break; + case wxITALIC: xstyle = "i"; + break; + case wxSLANT: xstyle = "o"; + break; + case wxNORMAL: xstyle = "r"; + break; + default: xstyle = "*"; + break; } switch (weight) { - case wxBOLD: xweight = "bold"; - break; - case wxLIGHT: - case wxNORMAL: xweight = "medium"; - break; - default: xweight = "*"; - break; + case wxBOLD: xweight = "bold"; + break; + case wxLIGHT: + case wxNORMAL: xweight = "medium"; + break; + default: xweight = "*"; + break; } sprintf(wxBuffer, "-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-*-*", - xfamily, xweight, xstyle, pointSize); + xfamily, xweight, xstyle, pointSize); Display *dpy = (Display*) wxGetDisplay(); XFontStruct* font = XLoadQueryFont(dpy, wxBuffer);