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