Benoît Minisini f65184802d [CONFIGURATION]
* NEW: Update copyright and license string in all source files.


git-svn-id: svn://localhost/gambas/trunk@2241 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-08-17 10:41:51 +00:00

628 lines
13 KiB
C++

/***************************************************************************
gfont.cpp
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
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 2, 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 <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->setBold(false);
font->setItalic(false);
font->setUnderline(false);
font->setStrikeOut(false);
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);
}
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::reset()
{
strike = false;
uline = false;
_bold_set = false;
_italic_set = false;
_name_set = false;
_size_set = false;
_strikeout_set = false;
_underline_set = false;
}
void gFont::realize()
{
ct = NULL;
reset();
_nfont++;
}
gFont::gFont(GtkWidget *wid) : gShare()
{
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() : gShare()
{
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) : gShare()
{
//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) : gShare()
{
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);
}
void gFont::copyTo(gFont *dst)
{
dst->reset();
if (_name_set) dst->setName(name());
if (_size_set) dst->setSize(size());
if (_bold_set) dst->setBold(bold());
if (_italic_set) dst->setItalic(italic());
if (_underline_set) dst->setUnderline(underline());
if (_strikeout_set) dst->setStrikeOut(strikeOut());
}
void gFont::mergeFrom(gFont *src)
{
if (!_name_set && src->_name_set) setName(src->name());
if (!_size_set && src->_size_set) setSize(src->size());
if (!_bold_set && src->_bold_set) setBold(src->bold());
if (!_italic_set && src->_italic_set) setItalic(src->italic());
if (!_underline_set && src->_underline_set) setUnderline(src->underline());
if (!_strikeout_set && src->_strikeout_set) setStrikeOut(src->strikeOut());
}
gFont *gFont::copy()
{
gFont *f = new gFont();
copyTo(f);
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);
_bold_set = true;
}
bool gFont::italic()
{
PangoFontDescription *desc=pango_context_get_font_description(ct);
return pango_font_description_get_style(desc) !=PANGO_STYLE_NORMAL;
}
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);
_italic_set = true;
}
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);
_name_set = true;
}
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));
_size_set = true;
}
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()
{
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;
}
const char *gFont::toFullString()
{
GString *desc = g_string_new("");
char *ret;
if (_name_set)
g_string_append_printf(desc, "name=%s ", name());
if (_size_set)
g_string_append_printf(desc, "size=%g ", (double)((int)(size() * 10 + 0.5)) / 10);
if (_bold_set)
g_string_append_printf(desc, "bold=%d ", bold());
if (_italic_set)
g_string_append_printf(desc, "italic=%d ", italic());
if (_underline_set)
g_string_append_printf(desc, "underline=%d ", underline());
if (_strikeout_set)
g_string_append_printf(desc, "strikeout=%d ", 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 || !*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<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;
}
int gFont::resolution()
{
return 0;
}
bool gFont::strikeOut()
{
return strike;
}
bool gFont::underline()
{
return uline;
}
void gFont::setResolution(int vl)
{
}
void gFont::setStrikeOut(bool vl)
{
//stub("setStrikeOut(): partially working");
strike=vl;
_strikeout_set = true;
//updateWidget();
}
void gFont::setUnderline(bool vl)
{
//stub("setUnderline(): partially working");
uline=vl;
_underline_set = true;
//updateWidget();
}
bool gFont::isAllSet()
{
return
_bold_set
&& _italic_set
&& _name_set
&& _size_set
&& _strikeout_set
&& _underline_set;
}