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();
}