Re: use of pango in main window

Robert Hart <[email protected]>
Newsgroups gmane.comp.audio.zinf.devel
Message-ID <1060714684.13123.93.camel@euclid>
Aha, nobody told me how easy this OO programming stuff was. I have added
a copy constructor to the GTKFont class, that doesn't just copy the
PangoContext and voila.

I have also subtracted one from the font size, because things looked a
bit bigger than before. Does this look right?

Rob

-- 
+-------------------------------------+
| "It's only a trap if you don't take |
| a ladder with you to get out of it" |
| 		-S Ring, Bath Uni     |
|                                     |
| [email protected]                   |
| http://www.nott.ac.uk/~enxrah       |
+-------------------------------------+
pango.diff (text/x-patch, 14.1 KB)
Index: ui/zinf/unix/include/GTKFont.h
===================================================================
RCS file: /cvsroot/zinf/zinf/ui/zinf/unix/include/GTKFont.h,v
retrieving revision 1.3
diff -a -u -r1.3 GTKFont.h
--- ui/zinf/unix/include/GTKFont.h	1 Feb 2003 05:08:03 -0000	1.3
+++ ui/zinf/unix/include/GTKFont.h	12 Aug 2003 18:54:26 -0000
@@ -52,7 +52,9 @@
 
 	GTKFont(FAContext *context, std::string &oName, std::string &oFace, 
 		std::string &oFile, std::string &oDefault);
-      virtual ~GTKFont(void);
+	GTKFont(GTKFont &f);
+
+     virtual ~GTKFont(void);
 
       Error    Load(int iFontHeight, bool bBold, bool bItalic);
       int      GetLength(std::string &oText);
@@ -64,12 +66,10 @@
       FAContext *m_context;
 
     private:
-      FontTypeEnum type;
 
-      GdkFont *gfont;
-#ifdef HAVE_FREETYPE
-      Efont   *ttfont;
-#endif
+      PangoFontDescription* pfont;
+      PangoContext* pango_context;
+      PangoLayout* layout;
      std::string   BuildFontString(bool bBold, bool bItalic, int iFontHeight);
       Error    AddFont(std::string &oFontFile);
 
Index: ui/zinf/unix/src/GTKFont.cpp
===================================================================
RCS file: /cvsroot/zinf/zinf/ui/zinf/unix/src/GTKFont.cpp,v
retrieving revision 1.6
diff -a -u -r1.6 GTKFont.cpp
--- ui/zinf/unix/src/GTKFont.cpp	19 Feb 2003 07:39:23 -0000	1.6
+++ ui/zinf/unix/src/GTKFont.cpp	12 Aug 2003 18:54:26 -0000
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <string>
+//#include <iostream>
 
 using namespace std;
 #include "path_max.h"
@@ -42,236 +43,110 @@
                  string &oFile, string &oDefault) :
                 Font(oName, oFace, oFile, oDefault)
 {
+  //  cerr << "Constructor\n";
     m_context = context;
+    gdk_threads_enter();
+    pango_context = gdk_pango_context_get();
+    gdk_threads_leave();
+    m_oFace = oFace;
+    m_oName = oName;
+    m_oFile = oFile;
+    pfont = NULL;
+    layout = NULL;
+    bold = false;
+    size=0;
+    italic = false;
+    underline = false;
+    first = true;
+}
 
-    type = kFontTypeUnknown;
- 
-#ifdef HAVE_FREETYPE
-    if (oFile.length() > 0) {
-        AddFont(oFile);
-        type = kFontTypeTTF;
-        gfont = NULL;
-        ttfont = NULL;
-        bold = false;
-        italic = false;
-        underline = false;
-        first = true;
-        return;
-    }
-#endif
-
-    string finalName;    
-    vector<string> Names;
-    vector<string>::iterator i;
-
-    char *dup = strdup(m_oFace.c_str());
-    char *token = strtok(dup, ",");
-    while (token) {
-         Names.push_back(string(token));
-         token = strtok(NULL, ",");
-    }
-
-    bool gdkfound = false;
-    bool ttffound = false;
-
-#ifdef HAVE_FREETYPE
-    string dir;
-    string ttfbase, ttfpath;
-    WIN32_FIND_DATA find;
-    HANDLE handle;
- 
-    m_context->prefs->GetPrefString(kInstallDirPref, &dir);
-    ttfbase = dir + "/" + BRANDING_SHARE_PATH + "/fonts";
-    ttfpath = ttfbase + "/*.ttf";
- 
-    struct stat st;
-    if (-1 == stat(ttfbase.c_str(), &st))
-        mkdir(ttfbase.c_str(), 0755);
-
-    handle = FindFirstFile((char *)ttfpath.c_str(), &find);
-    if (handle != INVALID_HANDLE_VALUE) {
-        do { 
-            i = Names.begin(); 
-            for (; i != Names.end(); i++) {
-                if (!strncasecmp(find.cFileName, (*i).c_str(), (*i).length())) {
-                    finalName = ttfbase + string("/") + string(find.cFileName);
-                    ttffound = true;
-                    break;
-                }
-            }
-            if (ttffound == true)
-                break;
-        } while (FindNextFile(handle, &find));
-        FindClose(handle);
-    }
-
-    char *fadir = ZinfDir(NULL);
-    ttfbase = string(fadir) + string("/fonts");
-    delete [] fadir;
-
-    if (-1 == stat(ttfbase.c_str(), &st))
-        mkdir(ttfbase.c_str(), 0755);
-
-    ttfpath = ttfbase + string("/*.ttf");
-    handle = FindFirstFile((char *)ttfpath.c_str(), &find);
-    if (handle != INVALID_HANDLE_VALUE) {
-        do {
-            i = Names.begin();
-            for (; i != Names.end(); i++) {
-                if (!strncasecmp(find.cFileName, (*i).c_str(), (*i).length())) {
-                    finalName = ttfbase + string("/") + string(find.cFileName);
-                    ttffound = true;
-                    break;
-                }
-            }
-            if (ttffound == true)
-                break;
-        } while (FindNextFile(handle, &find));
-        FindClose(handle);
-    }
-
-    ttfbase = "./fonts";
-    ttfpath = ttfbase + string("/*.ttf");
-    handle = FindFirstFile((char *)ttfpath.c_str(), &find);
-    if (handle != INVALID_HANDLE_VALUE) {
-        do {
-            i = Names.begin();
-            for (; i != Names.end(); i++) {
-                if (!strncasecmp(find.cFileName, (*i).c_str(), (*i).length())) {
-                    finalName = ttfbase + string("/") + string(find.cFileName);
-                    ttffound = true;
-                    break;
-                }
-            }
-            if (ttffound == true)
-                break;
-        } while (FindNextFile(handle, &find));
-        FindClose(handle);
-    }
-#endif
-
-    if (!ttffound) {
-        gdk_threads_enter();
-        i = Names.begin();
-        for (; i != Names.end(); i++) {
-            if (gdkfound = ListFonts((char *)(*i).c_str())) {
-                finalName = *i;
-                break;
-            }
-        }
-        gdk_threads_leave();
-    }
-
-    if (gdkfound) {
-        m_oFace = finalName; 
-        type = kFontTypeGdk;
-    }
-#ifdef HAVE_FREETYPE
-    else if (ttffound) { 
-        m_oFace = finalName;
-        type = kFontTypeTTF;
-    }
-#endif
-    else {
-        m_oFace = m_oDefault;
-        type = kFontTypeGdk;
-    }
-    free(dup);
-
-    gfont = NULL;
-#ifdef HAVE_FREETYPE
-    ttfont = NULL;
-#endif
+GTKFont::GTKFont(GTKFont &f) : Font(f)
+{
+  //  cerr << "Copy Constructor\n";
+    m_context = f.m_context;
+    gdk_threads_enter();
+    pango_context = gdk_pango_context_get();
+    gdk_threads_leave();
+    m_oFace = f.m_oFace;
+    m_oName = f.m_oName;
+    m_oFile = f.m_oFile;
+    m_oDefault = f.m_oDefault;
+    pfont = NULL;
+    layout = NULL;
     bold = false;
+    size=0;
     italic = false;
     underline = false;
     first = true;
 }
 
+
 Error GTKFont::AddFont(string &oFontFile)
 {
-    string oFontDest;
-    char fcopy[_MAX_PATH], *filename, *ext;
-    struct stat st;
-    string tempfile;
-
-    char *fadir = ZinfDir(NULL);
-    oFontDest = string(fadir) + string ("/fonts");
-    delete [] fadir;
-
-    if (-1 == stat(oFontDest.c_str(), &st))
-        mkdir(oFontDest.c_str(), 0755);
-
-    strcpy(fcopy, oFontFile.c_str());
-    filename = strrchr(fcopy, '/');
-    if (filename) 
-        filename = filename + 1;
-    ext = strrchr(filename, '.');
-    if (ext) {
-        *ext = '\0';
-        ext++;
-    }
-
-    tempfile = oFontFile;
-    if (-1 == stat(tempfile.c_str(), &st)) 
-        tempfile = FindFile(tempfile);
+  //  cerr << "AddFont(" << oFontFile << ")" <<endl;
+//     string oFontDest;
+//     char fcopy[_MAX_PATH], *filename, *ext;
+//     struct stat st;
+//     string tempfile;
+
+//     char *fadir = ZinfDir(NULL);
+//     oFontDest = string(fadir) + string ("/fonts");
+//     delete [] fadir;
+
+//     if (-1 == stat(oFontDest.c_str(), &st))
+//         mkdir(oFontDest.c_str(), 0755);
+
+//     strcpy(fcopy, oFontFile.c_str());
+//     filename = strrchr(fcopy, '/');
+//     if (filename) 
+//         filename = filename + 1;
+//     ext = strrchr(filename, '.');
+//     if (ext) {
+//         *ext = '\0';
+//         ext++;
+//     }
+
+//     tempfile = oFontFile;
+//     if (-1 == stat(tempfile.c_str(), &st)) 
+//         tempfile = FindFile(tempfile);
          
-    oFontDest += string("/") + string(filename);
-    if (ext)
-        oFontDest += string(".") + string(ext);
+//     oFontDest += string("/") + string(filename);
+//     if (ext)
+//         oFontDest += string(".") + string(ext);
 
-    CopyFile(tempfile.c_str(), oFontDest.c_str(), true);
+//     CopyFile(tempfile.c_str(), oFontDest.c_str(), true);
 
-    m_oFace = oFontDest;
+//     m_oFace = oFontDest;
 
     return kError_NoErr;
 }
     
 Error GTKFont::Load(int iFontHeight, bool bBold, bool bItalic)
 {
-    gdk_threads_enter();
-    if (type == kFontTypeGdk) {
-        if (bold != bBold || italic != bItalic || size != iFontHeight || 
-            !gfont) {
-            bold = bBold;
-            italic = bItalic;
-            size = iFontHeight;
-            if (gfont)
-                gdk_font_unref(gfont);
-            string fontname = BuildFontString(bold, italic, size);
-            gfont = gdk_font_load(fontname.c_str());
-            if (!gfont) {
-                fontname = BuildFontString(bold, italic, size - 1);
-                gfont = gdk_font_load(fontname.c_str());
-                if (!gfont) {
-                    gfont = gdk_font_load("variable");  
-                    if (!gfont) {
-                        gfont = gdk_font_load("fixed");
-                        if (!gfont) {
-                            gdk_threads_leave();
-                            //cout << "oops, couldn't load _any_ fonts...\n";
-                            return kError_YouScrewedUp;
-                        }
-                    }
-                }
-            } 
-        }
-    }
-#ifdef HAVE_FREETYPE
-    else {
-        if (!ttfont || iFontHeight != size) {
-            size = iFontHeight;
-            if (ttfont)
-                Efont_free(ttfont);
-            ttfont = Efont_load((char *)m_oFace.c_str(), iFontHeight - 3);
-            if (!ttfont) {
-                gdk_threads_leave();
-                //cout << "ERROR loading ttf " << m_oFace << "\n";
-                return kError_YouScrewedUp;
-            }
-        }
-    }
-#endif
+  gdk_threads_enter();
+  if (pfont==NULL)
+        layout = pango_layout_new(pango_context);
+  if (bold != bBold || italic != bItalic || size != iFontHeight) {
+      bold = bBold;
+      italic = bItalic;
+      size = iFontHeight;
+      if (pfont)
+	pango_font_description_free(pfont);
+      string fontname = BuildFontString(bold, italic, size-1);
+      pfont = pango_font_description_from_string(fontname.c_str());
+      if (!pfont) {
+	pfont = pango_font_description_from_string("sans");  
+	if (!pfont) {
+	  gdk_threads_leave();
+	  //cout << "oops, couldn't load _any_ fonts...\n";
+	  return kError_YouScrewedUp;
+	}
+      }
+    pango_context_load_font(pango_context, pfont);
+    pango_layout_set_font_description (layout, pfont);
+    pango_layout_context_changed(layout);
+   }
+
     gdk_threads_leave();
     return kError_NoErr;
 }
@@ -279,35 +154,20 @@
 int GTKFont::GetLength(string &oText)
 {
     int retvalue = 0;
-
     gdk_threads_enter();
-    if (type == kFontTypeGdk) 
-        retvalue = gdk_string_measure(gfont, oText.c_str());
-#ifdef HAVE_FREETYPE
-    else if (type == kFontTypeTTF) {
-        Efont_extents(ttfont, (char *)oText.c_str(), NULL, NULL, &retvalue, 
-                      NULL, NULL, NULL, NULL);
-    }
-#endif
+    pango_layout_set_text(layout, oText.c_str(), -1);
+    pango_layout_get_pixel_size (layout, &retvalue, NULL);
     gdk_threads_leave();
     return retvalue;
+
 }
 
 int GTKFont::GetHeight(string &oText)
 {
     int retvalue = 0;
-
     gdk_threads_enter();
-    if (type == kFontTypeGdk)
-       retvalue = gdk_string_height(gfont, oText.c_str());
-#ifdef HAVE_FREETYPE
-    else if (type == kFontTypeTTF) {
-       int ascent = 0, descent = 0;
-       Efont_extents(ttfont, (char *)oText.c_str(), &ascent, &descent, NULL, 
-                     NULL, NULL, NULL, NULL);
-       retvalue = ascent + descent;
-    }
-#endif
+    pango_layout_set_text(layout, oText.c_str(), -1);
+    pango_layout_get_pixel_size (layout, NULL, &retvalue);
     gdk_threads_leave();
     return retvalue;
 }
@@ -331,26 +191,13 @@
 
     gdk_gc_set_clip_rectangle(gc, &clipRect);
 
-    if (type == kFontTypeGdk) {
-       gdk_draw_string(bitmap->GetBitmap(), gfont, gc, oClipRect.x1 + iOffset, 
-                       oClipRect.y1 + oClipRect.Height() - 3, oText.c_str());
+    pango_layout_set_text(layout,oText.c_str(),-1);
+    gdk_draw_layout(bitmap->GetBitmap(), gc, 
+		    oClipRect.x1 + iOffset, 
+		    oClipRect.y1 - 3,
+		    layout);
 
-    // TODO: Underline...
-    }
-#ifdef HAVE_FREETYPE
-    else if (type == kFontTypeTTF) {
-       int ycoord;
-       ycoord = oClipRect.y1 + oClipRect.Height();
-       if (ttfont->ascent < oClipRect.Height()) 
-           ycoord -= ttfont->descent;
-       else 
-           ycoord -= ttfont->descent / 2;
-       ycoord++;
 
-       EFont_draw_string(bitmap->GetBitmap(), gc, oClipRect.x1 + iOffset, 
-                         ycoord, (char *)oText.c_str(), ttfont);
-    }
-#endif
     gdk_flush();
     gdk_gc_unref(gc);
     gdk_threads_leave();
@@ -360,36 +207,34 @@
 
 string GTKFont::BuildFontString(bool bBold, bool bItalic, int iFontHeight)
 {
-   // This isn't the greatest method, as it will probably return stuff we
-   // don't have....
-   string retstring = "-*-" + m_oFace;
+   string retstring = m_oFace;
    if (bBold)
-       retstring += string("-bold-");
-   else
-       retstring += string("-medium-");
+       retstring += string(" bold");
+
    if (bItalic)
-       retstring += string("i-normal-*-");
-   else 
-       retstring += string("r-normal-*-");
+       retstring += string(" italic");
+
    char tempstr[16];
-   sprintf(tempstr, "%d", iFontHeight);
-   retstring += string(tempstr) + string("-*-*-*-*-*-*-*");
+   sprintf(tempstr, " %d", iFontHeight);
+   retstring += string(tempstr);
    return retstring;
 }
 
 GTKFont::~GTKFont(void)
 {
-    gdk_threads_enter();
-    if (type == kFontTypeGdk) {
-        if (gfont)
-            gdk_font_unref(gfont);
-    }
-#ifdef HAVE_FREETYPE
-    else {
-        if (ttfont) {
-            Efont_free(ttfont);
-         }
-    }
-#endif
-    gdk_threads_leave();
+  //  cerr << "Destructor\n";
+  gdk_threads_enter();
+  if (pfont)
+    {
+
+      pango_font_description_free(pfont);
+      pfont=NULL;
+    }
+    //what else do we need to free here? layout, context?
+    //shot in the dark. is this right?
+  if (G_IS_OBJECT(layout))
+    g_object_unref(layout);
+  if (G_IS_OBJECT(pango_context))
+    g_object_unref(pango_context);
+  gdk_threads_leave();
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.