2007-12-30 16:41:49 +00:00
|
|
|
/***************************************************************************
|
|
|
|
|
|
|
|
gfont.cpp
|
|
|
|
|
|
|
|
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
|
|
|
|
|
|
|
|
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"
|
2008-12-28 19:01:39 +00:00
|
|
|
#include "gtools.h"
|
2007-12-30 16:41:49 +00:00
|
|
|
#include "gb.form.font.h"
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
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;bucle<FONT_n_families;bucle++)
|
|
|
|
{
|
|
|
|
buf1=(char*)pango_font_family_get_name (_families[bucle]);
|
|
|
|
if (buf1){
|
|
|
|
buf2=(char*)g_malloc(sizeof(char)*(strlen(buf1)+1));
|
|
|
|
strcpy(buf2,buf1);
|
|
|
|
FONT_families=g_list_prepend (FONT_families,buf2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FONT_families) FONT_families=g_list_sort(FONT_families,(GCompareFunc)strcasecmp);
|
|
|
|
|
|
|
|
g_free(_families);
|
|
|
|
g_object_unref(G_OBJECT(ct));
|
|
|
|
}
|
|
|
|
|
|
|
|
void gFont::exit()
|
|
|
|
{
|
|
|
|
GList *iter;
|
|
|
|
|
|
|
|
iter=FONT_families;
|
|
|
|
|
|
|
|
if (iter)
|
|
|
|
{
|
|
|
|
iter=g_list_first(iter);
|
|
|
|
while (iter)
|
|
|
|
{
|
|
|
|
g_free(iter->data);
|
|
|
|
iter=iter->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FONT_families) g_list_free(FONT_families);
|
|
|
|
|
|
|
|
//if (_nfont)
|
|
|
|
// fprintf(stderr, "WARNING: %d gFont objects were not freed.\n", _nfont);
|
|
|
|
}
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
int gFont::count()
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
if (!FONT_families) gFont::init();
|
|
|
|
return FONT_n_families;
|
|
|
|
}
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
const char *gFont::familyItem(int pos)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
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();
|
2008-12-28 19:01:39 +00:00
|
|
|
strike = false;
|
|
|
|
uline = false;
|
2007-12-30 16:41:49 +00:00
|
|
|
_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--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
int gFont::ascent()
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
PangoFontDescription *desc=pango_context_get_font_description(ct);
|
|
|
|
PangoFontMetrics *metric=pango_context_get_metrics(ct,desc,NULL);
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
return gt_pango_to_pixel(pango_font_metrics_get_ascent(metric));
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
int gFont::descent()
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
PangoFontDescription *desc=pango_context_get_font_description(ct);
|
|
|
|
PangoFontMetrics *metric=pango_context_get_metrics(ct,desc,NULL);
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
return gt_pango_to_pixel(pango_font_metrics_get_descent(metric));
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
return gt_pango_to_pixel(w);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int gFont::height(const char *text, int len)
|
|
|
|
{
|
|
|
|
PangoLayout *ly;
|
|
|
|
int h;
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
if (len == 0 || !text || !*text) text = " ";
|
2007-12-30 16:41:49 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
return gt_pango_to_pixel(h);
|
2007-12-30 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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<n_families;bucle++)
|
|
|
|
{
|
|
|
|
buf=pango_font_family_get_name(families[bucle]);
|
|
|
|
if (!strcmp(buf,name))
|
|
|
|
{
|
|
|
|
pango_font_family_list_faces(families[bucle],&faces,&n_faces);
|
|
|
|
if (faces)
|
|
|
|
{
|
|
|
|
pango_font_face_list_sizes(faces[0],&sizes,&n_sizes);
|
|
|
|
if (sizes)
|
|
|
|
g_free(sizes);
|
|
|
|
else
|
|
|
|
ret=true;
|
|
|
|
g_free(faces);
|
|
|
|
g_free(families);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_free(families);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(families);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool gFont::fixed()
|
|
|
|
{
|
|
|
|
bool ret=false;
|
|
|
|
|
|
|
|
PangoFontDescription *desc=pango_context_get_font_description(ct);
|
|
|
|
const char* name=pango_font_description_get_family(desc);
|
|
|
|
PangoFontFamily **families;
|
|
|
|
int n_families;
|
|
|
|
const char *buf;
|
|
|
|
|
|
|
|
if (!name) return false;
|
|
|
|
|
|
|
|
pango_context_list_families(ct,&families,&n_families);
|
|
|
|
|
|
|
|
if (!families) return false;
|
|
|
|
|
|
|
|
for (int bucle=0;bucle<n_families;bucle++)
|
|
|
|
{
|
|
|
|
buf=pango_font_family_get_name(families[bucle]);
|
|
|
|
if (!strcmp(buf,name))
|
|
|
|
{
|
|
|
|
ret=pango_font_family_is_monospace (families[bucle]);
|
|
|
|
g_free(families);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(families);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char** gFont::styles()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
int gFont::resolution()
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool gFont::strikeOut()
|
|
|
|
{
|
|
|
|
return strike;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool gFont::underline()
|
|
|
|
{
|
|
|
|
return uline;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-28 19:01:39 +00:00
|
|
|
void gFont::setResolution(int vl)
|
2007-12-30 16:41:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void gFont::setStrikeOut(bool vl)
|
|
|
|
{
|
|
|
|
//stub("setStrikeOut(): partially working");
|
|
|
|
strike=vl;
|
|
|
|
//updateWidget();
|
|
|
|
}
|
|
|
|
|
|
|
|
void gFont::setUnderline(bool vl)
|
|
|
|
{
|
|
|
|
//stub("setUnderline(): partially working");
|
|
|
|
uline=vl;
|
|
|
|
//updateWidget();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|