fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

fl_set_fonts_win32.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: fl_set_fonts_win32.cxx 7913 2010-11-29 18:18:27Z greg.ercolano $"
00003 //
00004 // WIN32 font utilities for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this7 library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 // This function fills in the FLTK font table with all the fonts that
00029 // are found on the X server.  It tries to place the fonts into families
00030 // and to sort them so the first 4 in a family are normal, bold, italic,
00031 // and bold italic.
00032 #include <FL/fl_utf8.h>
00033 #ifdef __CYGWIN__
00034 # include <wchar.h>
00035 #endif
00036 
00037 // Bug: older versions calculated the value for *ap as a side effect of
00038 // making the name, and then forgot about it. To avoid having to change
00039 // the header files I decided to store this value in the last character
00040 // of the font name array.
00041 #define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
00042 
00043 // turn a stored font name into a pretty name:
00044 const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
00045   Fl_Fontdesc *f = fl_fonts + fnum;
00046   if (!f->fontname[0]) {
00047     const char* p = f->name;
00048     if (!p || !*p) {if (ap) *ap = 0; return "";}
00049     int type;
00050     switch (*p) {
00051     case 'B': type = FL_BOLD; break;
00052     case 'I': type = FL_ITALIC; break;
00053     case 'P': type = FL_BOLD | FL_ITALIC; break;
00054     default:  type = 0; break;
00055     }
00056     strlcpy(f->fontname, p+1, ENDOFBUFFER);
00057     if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
00058     if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
00059     f->fontname[ENDOFBUFFER] = (char)type;
00060   }
00061   if (ap) *ap = f->fontname[ENDOFBUFFER];
00062   return f->fontname;
00063 }
00064 
00065 static int fl_free_font = FL_FREE_FONT;
00066 
00067 static int CALLBACK
00068 enumcbw(CONST LOGFONTW    *lpelf,
00069         CONST TEXTMETRICW * /*lpntm*/,
00070        DWORD            /*FontType*/,
00071        LPARAM           p) {
00072   if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1;
00073   char *n = NULL;
00074   int l = wcslen(lpelf->lfFaceName);
00075   unsigned dstlen = fl_utf8fromwc(n, 0, (xchar*)lpelf->lfFaceName, l) + 1; // measure the string
00076   n = (char*) malloc(dstlen);
00077 //n[fl_unicode2utf((xchar*)lpelf->lfFaceName, l, n)] = 0;
00078   dstlen = fl_utf8fromwc(n, dstlen, (xchar*)lpelf->lfFaceName, l); // convert the string
00079   n[dstlen] = 0;
00080   for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
00081           if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) {free(n);return 1;}
00082   char buffer[LF_FACESIZE + 1];
00083   strcpy(buffer+1, n);
00084   buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
00085   if (lpelf->lfWeight <= 400)
00086     buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
00087   buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
00088   if (lpelf->lfWeight <= 400)
00089     buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
00090   free(n);
00091   return 1;
00092 } /* enumcbw */
00093 
00094 Fl_Font Fl::set_fonts(const char* xstarname) {
00095   if (fl_free_font == FL_FREE_FONT) {// if not already been called
00096     if (!fl_gc) fl_GetDC(0);
00097 
00098       EnumFontFamiliesW(fl_gc, NULL, (FONTENUMPROCW)enumcbw, xstarname != 0);
00099 
00100   }
00101   return (Fl_Font)fl_free_font;
00102 }
00103 
00104 
00105 static int nbSize;
00106 static int cyPerInch;
00107 static int sizes[128];
00108 static int CALLBACK
00109 
00110 EnumSizeCbW(CONST LOGFONTW    * /*lpelf*/,
00111            CONST TEXTMETRICW *lpntm,
00112            DWORD            fontType,
00113            LPARAM           /*p*/) {
00114   if ((fontType & RASTER_FONTTYPE) == 0) {
00115     sizes[0] = 0;
00116     nbSize = 1;
00117 
00118     // Scalable font
00119     return 0;
00120   }
00121 
00122   int add = lpntm->tmHeight - lpntm->tmInternalLeading;
00123   add = MulDiv(add, 72, cyPerInch);
00124 
00125   int start = 0;
00126   while ((start < nbSize) && (sizes[start] < add)) {
00127     start++;
00128   }
00129 
00130   if ((start < nbSize) && (sizes[start] == add)) {
00131     return 1;
00132   }
00133 
00134   for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1];
00135 
00136   sizes[start] = add;
00137   nbSize++;
00138 
00139   // Stop enum if buffer overflow
00140   return nbSize < 128;
00141 }
00142 
00143 
00144 int
00145 Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
00146   nbSize = 0;
00147   Fl_Fontdesc *s = fl_fonts+fnum;
00148   if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
00149 
00150   if (!fl_gc) fl_GetDC(0);
00151   cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY);
00152   if (cyPerInch < 1) cyPerInch = 1;
00153 
00154 //  int l = fl_utf_nb_char((unsigned char*)s->name+1, strlen(s->name+1));
00155 //  unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short));
00156 //  fl_utf2unicode((unsigned char*)s->name+1, l, (xchar*)b);
00157         const char *nm = (const char*)s->name+1;
00158         int len = strlen(s->name+1);
00159     int l = fl_utf8toUtf16(nm, len, NULL, 0); // Pass NULL to query length required
00160     unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short));
00161     l = fl_utf8toUtf16(nm, len, b, (l+1)); // Now do the conversion
00162     b[l] = 0;
00163     EnumFontFamiliesW(fl_gc, (WCHAR*)b, (FONTENUMPROCW)EnumSizeCbW, 0);
00164         free(b);
00165 
00166   sizep = sizes;
00167   return nbSize;
00168 }
00169 
00170 
00171 //
00172 // End of "$Id: fl_set_fonts_win32.cxx 7913 2010-11-29 18:18:27Z greg.ercolano $".
00173 //