Go to most recent revision | Compare with Previous | Blame | View Log
/////////////////////////////////////////////////////////////////////////////// Name: src/unix/fontenum.cpp// Purpose: wxFontEnumerator class for X11/GDK// Author: Vadim Zeitlin// Modified by:// Created: 01.10.99// RCS-ID: $Id: fontenum.cpp 6722 2005-08-22 21:02:29Z davids $// Copyright: (c) Vadim Zeitlin// Licence: wxWindows licence/////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)#pragma implementation "fontenum.h"#endif// for compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#include "wx/dynarray.h"#include "wx/string.h"#include "wx/regex.h"#include "wx/utils.h"#include "wx/app.h"#include "wx/fontmap.h"#include "wx/fontenum.h"#include "wx/fontutil.h"#include "wx/encinfo.h"// ----------------------------------------------------------------------------// Pango// ----------------------------------------------------------------------------#if wxUSE_PANGO#include "pango/pango.h"#ifdef __WXGTK20__#include "gtk/gtk.h"extern GtkWidget *wxGetRootWindow();#endifstatic intcmp_families (const void *a, const void *b){const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);return g_utf8_collate (a_name, b_name);}// I admit I don't yet understand encodings with Pangobool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,bool fixedWidthOnly){#ifndef HAVE_PANGO_FONT_FAMILY_IS_MONOSPACEif ( fixedWidthOnly ){OnFacename( wxT("monospace") );}else#endif{PangoFontFamily **families = NULL;gint n_families = 0;pango_context_list_families (#ifdef __WXGTK20__gtk_widget_get_pango_context( wxGetRootWindow() ),#elsewxTheApp->GetPangoContext(),#endif&families, &n_families );qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);for (int i=0; i<n_families; i++){#ifdef HAVE_PANGO_FONT_FAMILY_IS_MONOSPACEif (!fixedWidthOnly ||pango_font_family_is_monospace(families[i]))#endif{const gchar *name = pango_font_family_get_name(families[i]);OnFacename(wxString(name, wxConvUTF8));}}g_free(families);}return TRUE;}bool wxFontEnumerator::EnumerateEncodings(const wxString& family){return FALSE;}#else// Pango#ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++// The resulting warnings are switched off here#pragma message disable nosimpint#endif#include <X11/Xlib.h>#ifdef __VMS__#pragma message enable nosimpint#endif// ----------------------------------------------------------------------------// private functions// ----------------------------------------------------------------------------// create the list of all fonts with the given spacing and encodingstatic char **CreateFontList(wxChar spacing, wxFontEncoding encoding,int *nFonts);// extract all font families from the given font list and call our// OnFacename() for each of themstatic bool ProcessFamiliesFromFontList(wxFontEnumerator *This,char **fonts,int nFonts);// ----------------------------------------------------------------------------// private types// ----------------------------------------------------------------------------// ============================================================================// implementation// ============================================================================// ----------------------------------------------------------------------------// helpers// ----------------------------------------------------------------------------#if !wxUSE_NANOXstatic char **CreateFontList(wxChar spacing,wxFontEncoding encoding,int *nFonts){wxNativeEncodingInfo info;wxGetNativeFontEncoding(encoding, &info);#if wxUSE_FONTMAPif ( !wxTestFontEncoding(info) ){// ask font mapper for a replacement(void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);}#endif // wxUSE_FONTMAPwxString pattern;pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),spacing,info.xregistry.c_str(),info.xencoding.c_str());// get the list of all fontsreturn XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);}static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,char **fonts,int nFonts){#if wxUSE_REGEXwxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);#endif // wxUSE_REGEX// extract the list of (unique) font familieswxSortedArrayString families;for ( int n = 0; n < nFonts; n++ ){char *font = fonts[n];#if wxUSE_REGEXif ( !re.Matches(font) )#else // !wxUSE_REGEXif ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )#endif // wxUSE_REGEX/!wxUSE_REGEX{// it's not a full font name (probably an alias)continue;}char *dash = strchr(font + 1, '-');char *family = dash + 1;dash = strchr(family, '-');*dash = '\0'; // !NULL because Matches() above succeededwxString fam(family);if ( families.Index(fam) == wxNOT_FOUND ){if ( !This->OnFacename(fam) ){// stop enumeratingreturn FALSE;}families.Add(fam);}//else: already seen}return TRUE;}#endif// wxUSE_NANOX// ----------------------------------------------------------------------------// wxFontEnumerator// ----------------------------------------------------------------------------bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,bool fixedWidthOnly){#if wxUSE_NANOXreturn FALSE;#elseint nFonts;char **fonts;if ( fixedWidthOnly ){bool cont = TRUE;fonts = CreateFontList(wxT('m'), encoding, &nFonts);if ( fonts ){cont = ProcessFamiliesFromFontList(this, fonts, nFonts);XFreeFontNames(fonts);}if ( !cont ){return TRUE;}fonts = CreateFontList(wxT('c'), encoding, &nFonts);if ( !fonts ){return TRUE;}}else{fonts = CreateFontList(wxT('*'), encoding, &nFonts);if ( !fonts ){// it's ok if there are no fonts in given encoding - but it's not// ok if there are no fonts at allwxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,wxT("No fonts at all on this system?"));return FALSE;}}(void)ProcessFamiliesFromFontList(this, fonts, nFonts);XFreeFontNames(fonts);return TRUE;#endif// wxUSE_NANOX}bool wxFontEnumerator::EnumerateEncodings(const wxString& family){#if wxUSE_NANOXreturn FALSE;#elsewxString pattern;pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),family.IsEmpty() ? wxT("*") : family.c_str());// get the list of all fontsint nFonts;char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),32767, &nFonts);if ( !fonts ){// unknown family?return FALSE;}// extract the list of (unique) encodingswxSortedArrayString encodings;for ( int n = 0; n < nFonts; n++ ){char *font = fonts[n];if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) ){// it's not a full font name (probably an alias)continue;}// extract the familychar *dash = strchr(font + 1, '-');char *familyFont = dash + 1;dash = strchr(familyFont, '-');*dash = '\0'; // !NULL because Matches() above succeededif ( !family.IsEmpty() && (family != familyFont) ){// family doesn't matchcontinue;}// now extract the registry/encodingchar *p = dash + 1; // just after the dash after familydash = strrchr(p, '-');wxString registry(dash + 1);*dash = '\0';dash = strrchr(p, '-');wxString encoding(dash + 1);encoding << wxT('-') << registry;if ( encodings.Index(encoding) == wxNOT_FOUND ){if ( !OnFontEncoding(familyFont, encoding) ){break;}encodings.Add(encoding);}//else: already had this one}XFreeFontNames(fonts);return TRUE;#endif// wxUSE_NANOX}#endif// __WXGTK20__