home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / unix / fontenum.cpp < prev    next >
C/C++ Source or Header  |  2002-11-10  |  10KB  |  340 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        src/unix/fontenum.cpp
  3. // Purpose:     wxFontEnumerator class for X11/GDK
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     01.10.99
  7. // RCS-ID:      $Id: fontenum.cpp,v 1.17.2.2 2002/11/09 19:27:01 RR Exp $
  8. // Copyright:   (c) Vadim Zeitlin
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "fontenum.h"
  22. #endif
  23.  
  24. #include "wx/defs.h"
  25. #include "wx/dynarray.h"
  26. #include "wx/string.h"
  27. #include "wx/regex.h"
  28. #include "wx/utils.h"
  29. #include "wx/app.h"
  30. #include "wx/fontmap.h"
  31. #include "wx/fontenum.h"
  32. #include "wx/fontutil.h"
  33.  
  34. // ----------------------------------------------------------------------------
  35. // Pango
  36. // ----------------------------------------------------------------------------
  37.  
  38. #if wxUSE_PANGO
  39.  
  40. #include "pango/pango.h"
  41.  
  42. #ifdef __WXGTK20__
  43. #include "gtk/gtk.h"
  44. extern GtkWidget *wxGetRootWindow();
  45. #endif
  46.  
  47. static int
  48. cmp_families (const void *a, const void *b)
  49. {
  50.   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
  51.   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
  52.   
  53.   return g_utf8_collate (a_name, b_name);
  54. }
  55.  
  56. // I admit I don't yet understand encodings with Pango
  57. bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
  58.                                           bool fixedWidthOnly)
  59. {
  60.     if ( fixedWidthOnly )
  61.     {
  62.         OnFacename( wxT("monospace") );
  63.     }
  64.     else
  65.     {
  66.         PangoFontFamily **families = NULL;
  67.         gint n_families = 0;
  68.         pango_context_list_families ( 
  69. #ifdef __WXGTK20__
  70.             gtk_widget_get_pango_context( wxGetRootWindow() ),
  71. #else
  72.             wxTheApp->GetPangoContext(),
  73. #endif
  74.             &families, &n_families );
  75.         qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
  76.  
  77.         for (int i=0; i<n_families; i++)
  78.         {
  79.             const gchar *name = pango_font_family_get_name( families[i] );
  80.             
  81.             wxString tmp( name, wxConvUTF8 );
  82.             OnFacename( tmp );
  83.         }
  84.     }
  85.     
  86.     return TRUE;
  87. }
  88.  
  89. bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
  90. {
  91.     return FALSE;
  92. }
  93.  
  94.  
  95. #else
  96.   // Pango
  97.  
  98. #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
  99.                // The resulting warnings are switched off here
  100. #pragma message disable nosimpint
  101. #endif
  102. #include <X11/Xlib.h>
  103. #ifdef __VMS__
  104. #pragma message enable nosimpint
  105. #endif
  106.  
  107. // ----------------------------------------------------------------------------
  108. // private functions
  109. // ----------------------------------------------------------------------------
  110.  
  111. // create the list of all fonts with the given spacing and encoding
  112. static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
  113.                              int *nFonts);
  114.  
  115. // extract all font families from the given font list and call our
  116. // OnFacename() for each of them
  117. static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
  118.                                         char **fonts,
  119.                                         int nFonts);
  120.  
  121.  
  122. // ----------------------------------------------------------------------------
  123. // private types
  124. // ----------------------------------------------------------------------------
  125.  
  126. // ============================================================================
  127. // implementation
  128. // ============================================================================
  129.  
  130. // ----------------------------------------------------------------------------
  131. // helpers
  132. // ----------------------------------------------------------------------------
  133.  
  134. #if !wxUSE_NANOX
  135. static char **CreateFontList(wxChar spacing,
  136.                              wxFontEncoding encoding,
  137.                              int *nFonts)
  138. {
  139.     wxNativeEncodingInfo info;
  140.     wxGetNativeFontEncoding(encoding, &info);
  141.  
  142. #if wxUSE_FONTMAP
  143.     if ( !wxTestFontEncoding(info) )
  144.     {
  145.         // ask font mapper for a replacement
  146.         (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
  147.     }
  148. #endif // wxUSE_FONTMAP
  149.  
  150.     wxString pattern;
  151.     pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
  152.                    spacing,
  153.                    info.xregistry.c_str(),
  154.                    info.xencoding.c_str());
  155.  
  156.     // get the list of all fonts
  157.     return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
  158. }
  159.  
  160. static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
  161.                                         char **fonts,
  162.                                         int nFonts)
  163. {
  164. #if wxUSE_REGEX
  165.     wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
  166. #endif // wxUSE_REGEX
  167.  
  168.     // extract the list of (unique) font families
  169.     wxSortedArrayString families;
  170.     for ( int n = 0; n < nFonts; n++ )
  171.     {
  172.         char *font = fonts[n];
  173. #if wxUSE_REGEX
  174.         if ( !re.Matches(font) )
  175. #else // !wxUSE_REGEX
  176.         if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
  177. #endif // wxUSE_REGEX/!wxUSE_REGEX
  178.         {
  179.             // it's not a full font name (probably an alias)
  180.             continue;
  181.         }
  182.  
  183.         char *dash = strchr(font + 1, '-');
  184.         char *family = dash + 1;
  185.         dash = strchr(family, '-');
  186.         *dash = '\0'; // !NULL because Matches() above succeeded
  187.         wxString fam(family);
  188.  
  189.         if ( families.Index(fam) == wxNOT_FOUND )
  190.         {
  191.             if ( !This->OnFacename(fam) )
  192.             {
  193.                 // stop enumerating
  194.                 return FALSE;
  195.             }
  196.  
  197.             families.Add(fam);
  198.         }
  199.         //else: already seen
  200.     }
  201.  
  202.     return TRUE;
  203. }
  204. #endif
  205.   // wxUSE_NANOX
  206.  
  207. // ----------------------------------------------------------------------------
  208. // wxFontEnumerator
  209. // ----------------------------------------------------------------------------
  210.  
  211. bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
  212.                                           bool fixedWidthOnly)
  213. {
  214. #if wxUSE_NANOX
  215.     return FALSE;
  216. #else
  217.     int nFonts;
  218.     char **fonts;
  219.  
  220.     if ( fixedWidthOnly )
  221.     {
  222.         bool cont = TRUE;
  223.         fonts = CreateFontList(wxT('m'), encoding, &nFonts);
  224.         if ( fonts )
  225.         {
  226.             cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
  227.  
  228.             XFreeFontNames(fonts);
  229.         }
  230.  
  231.         if ( !cont )
  232.         {
  233.             return TRUE;
  234.         }
  235.  
  236.         fonts = CreateFontList(wxT('c'), encoding, &nFonts);
  237.         if ( !fonts )
  238.         {
  239.             return TRUE;
  240.         }
  241.     }
  242.     else
  243.     {
  244.         fonts = CreateFontList(wxT('*'), encoding, &nFonts);
  245.  
  246.         if ( !fonts )
  247.         {
  248.             // it's ok if there are no fonts in given encoding - but it's not
  249.             // ok if there are no fonts at all
  250.             wxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,
  251.                          wxT("No fonts at all on this system?"));
  252.  
  253.             return FALSE;
  254.         }
  255.     }
  256.  
  257.     (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
  258.  
  259.     XFreeFontNames(fonts);
  260.     return TRUE;
  261. #endif
  262.     // wxUSE_NANOX
  263. }
  264.  
  265. bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
  266. {
  267. #if wxUSE_NANOX
  268.     return FALSE;
  269. #else
  270.     wxString pattern;
  271.     pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
  272.                    family.IsEmpty() ? wxT("*") : family.c_str());
  273.  
  274.     // get the list of all fonts
  275.     int nFonts;
  276.     char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
  277.                               32767, &nFonts);
  278.  
  279.     if ( !fonts )
  280.     {
  281.         // unknown family?
  282.         return FALSE;
  283.     }
  284.  
  285.     // extract the list of (unique) encodings
  286.     wxSortedArrayString encodings;
  287.     for ( int n = 0; n < nFonts; n++ )
  288.     {
  289.         char *font = fonts[n];
  290.         if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
  291.         {
  292.             // it's not a full font name (probably an alias)
  293.             continue;
  294.         }
  295.  
  296.         // extract the family
  297.         char *dash = strchr(font + 1, '-');
  298.         char *familyFont = dash + 1;
  299.         dash = strchr(familyFont, '-');
  300.         *dash = '\0'; // !NULL because Matches() above succeeded
  301.  
  302.         if ( !family.IsEmpty() && (family != familyFont) )
  303.         {
  304.             // family doesn't match
  305.             continue;
  306.         }
  307.  
  308.         // now extract the registry/encoding
  309.         char *p = dash + 1; // just after the dash after family
  310.         dash = strrchr(p, '-');
  311.  
  312.         wxString registry(dash + 1);
  313.         *dash = '\0';
  314.  
  315.         dash = strrchr(p, '-');
  316.         wxString encoding(dash + 1);
  317.  
  318.         encoding << wxT('-') << registry;
  319.         if ( encodings.Index(encoding) == wxNOT_FOUND )
  320.         {
  321.             if ( !OnFontEncoding(familyFont, encoding) )
  322.             {
  323.                 break;
  324.             }
  325.  
  326.             encodings.Add(encoding);
  327.         }
  328.         //else: already had this one
  329.     }
  330.  
  331.     XFreeFontNames(fonts);
  332.  
  333.     return TRUE;
  334. #endif
  335.     // wxUSE_NANOX
  336. }
  337.  
  338. #endif
  339.    // __WXGTK20__
  340.