/*************************************************************************** gfont.cpp (c) 2004-2006 - Daniel Campos Fernández Gtkmae "GTK+ made easy" classes Realizado para la Junta de Extremadura. Consejería de Educación Ciencia y Tecnología. Proyecto gnuLinEx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************/ #include "widgets.h" #include "font-parser.h" #include "gdesktop.h" #include "gtools.h" #include "gb.form.font.h" #include static void set_font_from_string(gFont *font, const char *str) { gchar **tokens, **p; gchar *elt; int grade; double size; font->setBold(false); font->setItalic(false); font->setUnderline(false); font->setStrikeOut(false); font->setName(gDesktop::font()->name()); font->setSize(gDesktop::font()->size()); if (!str || !*str) return; tokens = g_strsplit(str, ",", 0); p = tokens; for(p = tokens; *p; p++) { elt = *p; if (!strcasecmp(elt, "bold")) font->setBold(true); else if (!strcasecmp(elt, "italic")) font->setItalic(true); else if (!strcasecmp(elt, "underline")) font->setUnderline(true); else if (!strcasecmp(elt, "strikeout")) font->setStrikeOut(true); else if (elt[0] == '+' || elt[0] == '-' || elt[0] == '0') { grade = atoi(elt); if (grade || elt[0] == '0') font->setGrade(grade); } else { size = atof(elt); if (size != 0.0) font->setSize(size); else font->setName(elt); } } g_strfreev(tokens); } /******************************************************************************** gFont *********************************************************************************/ static int FONT_n_families; GList *FONT_families = NULL; static int _nfont = 0; void gFont::init() { PangoFontFamily **_families; PangoContext *ct; char *buf1,*buf2; int bucle; ct=gdk_pango_context_get(); pango_context_list_families(ct, &_families, &FONT_n_families); for (bucle=0;bucledata); iter=iter->next; } } if (FONT_families) g_list_free(FONT_families); //if (_nfont) // fprintf(stderr, "WARNING: %d gFont objects were not freed.\n", _nfont); } int gFont::count() { if (!FONT_families) gFont::init(); return FONT_n_families; } const char *gFont::familyItem(int pos) { if (!FONT_families) gFont::init(); if ( (pos<0) || (pos>=FONT_n_families) ) return NULL; return (const char*)g_list_nth (FONT_families,pos)->data; } #if 0 void gFont::updateWidget() { if (!wid) return; PangoFontDescription *desc=pango_context_get_font_description(ct); gtk_widget_modify_font(wid,desc); if (G_OBJECT_TYPE(wid)==GTK_TYPE_LABEL) { PangoAttrList *pal=pango_attr_list_new(); if (strike) { PangoAttribute *pa=pango_attr_strikethrough_new(true); pa->start_index = 0; pa->end_index = g_utf8_strlen(gtk_label_get_text(GTK_LABEL(wid)), -1); pango_attr_list_insert(pal, pa); } if (uline) { PangoAttribute *pa=pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pa->start_index = 0; pa->end_index = g_utf8_strlen(gtk_label_get_text(GTK_LABEL(wid)), -1); pango_attr_list_insert(pal, pa); } gtk_label_set_attributes(GTK_LABEL(wid), pal); pango_attr_list_unref(pal); } } #endif void gFont::realize() { gShare::gShare(); strike = false; uline = false; _nfont++; } gFont::gFont(GtkWidget *wid) { PangoAttrList *lst; PangoAttrIterator* iter; realize(); ct=gtk_widget_create_pango_context(wid); g_object_ref(ct); if (G_OBJECT_TYPE(wid)==GTK_TYPE_LABEL) { lst=gtk_label_get_attributes(GTK_LABEL(wid)); if (lst) { iter=pango_attr_list_get_iterator(lst); if (pango_attr_iterator_get(iter,PANGO_ATTR_STRIKETHROUGH)) strike=true; if (pango_attr_iterator_get(iter,PANGO_ATTR_UNDERLINE)) uline=true; pango_attr_iterator_destroy(iter); } } } gFont::gFont() { GtkStyle *sty=gtk_widget_get_default_style(); realize(); ct=gdk_pango_context_get(); pango_context_set_font_description(ct,sty->font_desc); } gFont::gFont(PangoFontDescription *fd) { //GtkStyle *sty=gtk_widget_get_default_style(); realize(); ct=gdk_pango_context_get(); pango_context_set_font_description(ct, fd); } gFont::gFont(const char *name) { GtkStyle *sty=gtk_widget_get_default_style(); realize(); ct=gdk_pango_context_get(); pango_context_set_font_description(ct,sty->font_desc); set_font_from_string(this, name); } gFont *gFont::copy() { gFont *f = new gFont(); f->setName(name()); f->setSize(size()); f->setBold(bold()); f->setItalic(italic()); f->setUnderline(underline()); f->setStrikeOut(strikeOut()); return f; } gFont::~gFont() { g_object_unref(ct); _nfont--; } int gFont::ascent() { PangoFontDescription *desc=pango_context_get_font_description(ct); PangoFontMetrics *metric=pango_context_get_metrics(ct,desc,NULL); return gt_pango_to_pixel(pango_font_metrics_get_ascent(metric)); } int gFont::descent() { PangoFontDescription *desc=pango_context_get_font_description(ct); PangoFontMetrics *metric=pango_context_get_metrics(ct,desc,NULL); return gt_pango_to_pixel(pango_font_metrics_get_descent(metric)); } bool gFont::bold() { PangoFontDescription *desc=pango_context_get_font_description(ct); PangoWeight w; w=pango_font_description_get_weight(desc); if (w>PANGO_WEIGHT_NORMAL) return true; return false; } void gFont::setBold(bool vl) { PangoFontDescription *desc=pango_context_get_font_description(ct); if (vl) pango_font_description_set_weight(desc,PANGO_WEIGHT_BOLD); else pango_font_description_set_weight(desc,PANGO_WEIGHT_NORMAL); //updateWidget(); } bool gFont::italic() { PangoFontDescription *desc=pango_context_get_font_description(ct); if (pango_font_description_get_style(desc)==PANGO_STYLE_NORMAL) return false; return true; } void gFont::setItalic(bool vl) { PangoFontDescription *desc=pango_context_get_font_description(ct); if (vl) pango_font_description_set_style(desc,PANGO_STYLE_ITALIC); else pango_font_description_set_style(desc,PANGO_STYLE_NORMAL); //updateWidget(); } char* gFont::name() { PangoFontDescription *desc=pango_context_get_font_description(ct); return (char *)pango_font_description_get_family (desc); } void gFont::setName(char *nm) { PangoFontDescription *desc=pango_context_get_font_description(ct); pango_font_description_set_family (desc,nm); //updateWidget(); } double gFont::size() { double size; PangoFontDescription *desc=pango_context_get_font_description(ct); size=pango_font_description_get_size(desc); return size / (double)PANGO_SCALE; } int gFont::grade() { double desktop = gDesktop::font()->size(); return SIZE_TO_GRADE(size(), desktop); } void gFont::setSize(double sz) { PangoFontDescription *desc=pango_context_get_font_description(ct); pango_font_description_set_size (desc,(int)(sz*PANGO_SCALE)); //updateWidget(); } void gFont::setGrade(int grade) { double desktop = gDesktop::font()->size(); if (grade < -4 || grade > 16) return; setSize(GRADE_TO_SIZE(grade, desktop)); } const char *gFont::toString() { //PangoFontDescription *desc=pango_context_get_font_description(ct); //return pango_font_description_to_string(desc); GString *desc = g_string_new(name()); char *ret; g_string_append_printf(desc, ",%g", (double)((int)(size() * 10 + 0.5)) / 10); if (bold()) g_string_append(desc, ",Bold"); if (italic()) g_string_append(desc, ",Italic"); if (underline()) g_string_append(desc, ",Underline"); if (strikeOut()) g_string_append(desc, ",StrikeOut"); ret = g_string_free(desc, false); gt_free_later(ret); return ret; } int gFont::width(const char *text, int len) { PangoLayout *ly; int w; if (!text) return 0; if (!strlen(text)) return 0; ly=pango_layout_new(ct); pango_layout_set_text(ly,text,len); pango_layout_get_size(ly,&w,NULL); g_object_unref(G_OBJECT(ly)); return gt_pango_to_pixel(w); } int gFont::height(const char *text, int len) { PangoLayout *ly; int h; if (len == 0 || !text || !*text) text = " "; ly=pango_layout_new(ct); pango_layout_set_text(ly,text,len); pango_layout_get_size(ly,NULL,&h); g_object_unref(G_OBJECT(ly)); return gt_pango_to_pixel(h); } int gFont::height() { return height(" ", 1); } bool gFont::scalable() { bool ret=false; PangoFontDescription *desc=pango_context_get_font_description(ct); //PangoFontDescription *tmp; const char* name=pango_font_description_get_family(desc); PangoFontFamily **families; PangoFontFace **faces; int *sizes; int n_families; int n_faces; int n_sizes; //int b2; const char *buf; if (!name) return false; pango_context_list_families(ct,&families,&n_families); if (!families) return false; for (int bucle=0;bucle