[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gEDA: Unicode support
El mié, 26-01-2005 a las 23:28 -0500, Ales Hvezda escribió:
> Hi Carlos,
>
> [snip]
> >Mmmmm.... I was thinking in a user using gtk+1.2 or gtk+2.0, but not
> >both with the same schematic. Certainly a gschem compiled with gtk+1.2
> >will not be able to properly display a schematic containing Unicode
> >texts....=20
> >If there were a function which could check if a string is unicode or
> >not, then one possible solution can be warn the user if he is using
> >gschem/gtk+1.2 and such string is found, or use iconv to translate the
> >string.
> >I'm not sure if it is worth trying to do it now gschem is dropping
> >support with gtk+1.2 .
>
> Yeah, there is such a function in gtk (or glib, I can't remember)
> which validates the string as utf-8. However, yeah, I don't want to
> invest any time in doing this (unless it is virtually free).
Are you sure? since there is no UTF8 support in gtk1.2, I believed
there's no UTF8 checking function in gtk1.2 ...
> [snip]
> >So the task can be divided into two steps:
> > - Put the hash table into libgeda, and have the font map hardcoded,
> >like it is now.
> > - Load the hash table from a file.
> >
>
> Yeah, that's what I had in mind.
I have a problem with the first task. It's almost done, using a
hashtable mapping between characters and font definition files, so the
second should be easy to do.
The problem is the following: with the attached patch, I think UTF8
support is mostly implemented, but the '\n' character is not properly
handled (multiline texts are converted into single line texts).
The problem shows up in the o_text_create_string function, in
libgeda/noweb/o_text_basic.nw .
The code handling the '\n' character is inside the
"if (o_font_set->font_prim_objs->next) {" .
The problem is that the code inside that 'if' clause is executed for any
character BUT the newline.
I don't know where that struct is filled (in particular the "next"
field), so I'm getting lost.
I would be grateful to anyone who could check the attached patch and
take a look at what's going on...
[snip]
> Yeah, in order to fully support all of unicode, we would have to
> drop the vector font and switch to pango/freetype. Not impossible, but
> would require a significant rewrite of the entire text engine and probably
> a good chunk of the rendering engine as well. I would like to save this
> task for the next generation program.
Ok. but... "next generation program"?? :-O . I haven't read anything
about it before!! What are you planning for it? :-)
> >it can use unicode, but I can't see support for asian, cyrillic, (they
> >will have to build a font for just using gschem) or right to left
> >writings without using gtk for it.
> > - how much effort could be to have gschem using GTK text rendering?.
>
> Quite a bit and I'm not 100% convinced that I would be able to
> squeeze the necessary performance out of the existing rendering engine
> without completely rewriting it. Something I've been tempted to do, but
> haven't because there are bigger fish to fry.
>
> I think for now, as the next stepping stone, we should get libgeda
> to read/write unicode characters and create the above mentioned lookup
> table to handle the conversion from unicode character to custom vector
> font. I don't see this as a viable long term approach but rather as a short
> term fix which will get us past the current broken behavior.
No problem.
>
> > - advantages or disadvantages? could it be worth or not?
>
>
> My biggest question with regard to this would be: Would people
> be really that interested in adding and manipulating i18n text in the
> schematic? Granted gschem supports that to some degree now and I've never
> been happy with it, but do people really want to create i18n schematics?
> Are there any other schematic capture systems out there where are fully
> i18n (I'm talking about unicode here and all the nice feature that come
> with it)?
Well, I like to use text in my mother tongue, so I had to make the
missing characters and added it to libgeda. I suppose other people
prefer to use their own language, which is no problem if most of the
characters you use are already done, but I don't think an asian newbie
will do it for chinese, japanese, or whatever.
That's a big market that geda is missing right now.
I've seen schematics in asian languages, so I guess there are special
versions of commercial programs for those languages.
Anyway, such a big change can be done in the future.
Regards,
Carlos
Index: gschem/noweb/gschem.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/gschem.nw,v
retrieving revision 1.28
diff -a -u -r1.28 gschem.nw
--- gschem/noweb/gschem.nw 16 Jan 2005 17:13:38 -0000 1.28
+++ gschem/noweb/gschem.nw 29 Jan 2005 16:12:12 -0000
@@ -242,7 +242,7 @@
set_window_current_key(w_current);
/* o_text_init(); goes away */
- o_text_init();
+ o_text_init(w_current);
x_repaint_background(w_current);
Index: libgeda/include/defines.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/include/defines.h,v
retrieving revision 1.41
diff -a -u -r1.41 defines.h
--- libgeda/include/defines.h 23 Jan 2005 04:12:42 -0000 1.41
+++ libgeda/include/defines.h 29 Jan 2005 16:12:15 -0000
@@ -367,4 +367,14 @@
#define OTHER_PATH_SEPARATER_STRING "\\"
#endif
+/* Since we use Unicode, which isn't supported in GTK 1.2, define
+ the equivalent of the used functions here.
+ GTK 1.2 always deal with chars, instead of multibyte characters
+ as Unicode. */
+#ifdef HAS_GTK12
+typedef unsigned char gunichar;
+#define g_utf8_get_char_validated(string, len) (*((char *)string))
+#define g_utf8_find_next_char(string, len) ((char*)string+1)
+#endif
+
#endif
Index: libgeda/include/prototype.h
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/include/prototype.h,v
retrieving revision 1.82
diff -a -u -r1.82 prototype.h
--- libgeda/include/prototype.h 23 Jan 2005 01:43:32 -0000 1.82
+++ libgeda/include/prototype.h 29 Jan 2005 16:12:19 -0000
@@ -357,9 +357,9 @@
void get_text_bounds(TOPLEVEL *w_current, OBJECT *o_current, int *left, int *top, int *right, int *bottom);
void world_get_text_bounds(TOPLEVEL *w_current, OBJECT *o_current, int *left, int *top, int *right, int *bottom);
OBJECT *o_text_add_head(void);
-void o_text_init(void);
+void o_text_init(TOPLEVEL *w_current);
void o_text_print_set(void);
-OBJECT *o_text_load_font(TOPLEVEL *w_current, unsigned char needed_char);
+OBJECT *o_text_load_font(TOPLEVEL *w_current, gunichar needed_char);
int o_text_num_lines(char *string);
int o_text_height(char *string, int size);
int o_text_width(TOPLEVEL *w_current, char *string, int size);
Index: libgeda/noweb/o_text_basic.nw
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/libgeda/noweb/o_text_basic.nw,v
retrieving revision 1.16
diff -a -u -r1.16 o_text_basic.nw
--- libgeda/noweb/o_text_basic.nw 12 Jan 2004 02:05:58 -0000 1.16
+++ libgeda/noweb/o_text_basic.nw 29 Jan 2005 16:12:32 -0000
@@ -114,13 +114,18 @@
#define BACKING 2
/* font storage and friends are staying global so that all can access */
-#define NUM_CHARS 256
@ %def WINONLY BACKING NUM_CHARS
<<o_text_basic.c : global variable>>=
-OBJECT font_set[NUM_CHARS];
+/* Stores a list with font data */
+GSList *font_set;
+/* Hashtable storing font_character (string) as a key, and pointer to data */
+GHashTable *font_loaded;
+
+/* Hashtable storing mapping between character and font definition file */
+GHashTable *font_char_to_file;
/* Size of a tab in characters */
int tab_in_chars = 8;
@@ -194,14 +199,191 @@
<<o_text_basic.c : o_text_init()>>=
void
-o_text_init(void)
+o_text_init(TOPLEVEL *w_current)
{
int i;
+ gchar *aux_str;
- for (i = 0 ; i < NUM_CHARS; i++) {
- font_set[i].font_prim_objs = NULL;
- font_set[i].font_text_size = 100;
- }
+ font_set = NULL;
+ font_loaded = g_hash_table_new_full (g_str_hash, g_str_equal, free, free);
+ font_char_to_file = g_hash_table_new_full (g_str_hash, g_str_equal, free, free);
+
+ /* Fill font to file hash table with already known characters */
+ aux_str = g_strdup_printf ("%s%c", w_current->font_directory,
+ PATH_SEPARATER_CHAR);
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(" ") ,
+ g_strdup_printf("%sspace.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("\n"),
+ g_strdup_printf("%snewline.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("!"),
+ g_strdup_printf("%sexcl.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(","),
+ g_strdup_printf("%scomma.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("("),
+ g_strdup_printf("%slparen.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(")"),
+ g_strdup_printf("%srparen.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("-"),
+ g_strdup_printf("%sminus.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("+"),
+ g_strdup_printf("%splus.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("#"),
+ g_strdup_printf("%spound.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("?"),
+ g_strdup_printf("%squest.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("\""),
+ g_strdup_printf("%squote.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(":"),
+ g_strdup_printf("%scolon.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("@"),
+ g_strdup_printf("%sat.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("="),
+ g_strdup_printf("%sequal.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(">"),
+ g_strdup_printf("%smore.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("<"),
+ g_strdup_printf("%sless.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("/"),
+ g_strdup_printf("%sslash.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("$"),
+ g_strdup_printf("%sdollar.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf(";"),
+ g_strdup_printf("%ssemi.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("&"),
+ g_strdup_printf("%samper.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("\\"),
+ g_strdup_printf("%sbackslash.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("{"),
+ g_strdup_printf("%slbrace.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("}"),
+ g_strdup_printf("%srbrace.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("'"),
+ g_strdup_printf("%sapost.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("`"),
+ g_strdup_printf("%sbacktick.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("^"),
+ g_strdup_printf("%scaret.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("%%"),
+ g_strdup_printf("%spercent.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("["),
+ g_strdup_printf("%slbrack.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("]"),
+ g_strdup_printf("%srbrack.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("*"),
+ g_strdup_printf("%sastericks.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("."),
+ g_strdup_printf("%speriod.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("_"),
+ g_strdup_printf("%sunder.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("~"),
+ g_strdup_printf("%stilde.sym", aux_str));
+ g_hash_table_insert (font_char_to_file, g_strdup_printf("|"),
+ g_strdup_printf("%svbar.sym", aux_str));
+ /* A-umlaut finnish/swedish/german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 196),
+ g_strdup_printf("%sA-diaeresis.sym", aux_str));
+ /* A-ring finnish/swedish/danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 197),
+ g_strdup_printf("%sA-ring.sym", aux_str));
+ /* AE-diphtong danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 198),
+ g_strdup_printf("%sAE-lig.sym", aux_str));
+ /* O-umlaut finnish/swedish/german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 214),
+ g_strdup_printf("%sO-diaeresis.sym", aux_str));
+ /* O-slash danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 216),
+ g_strdup_printf("%sO-slash.sym", aux_str));
+ /* U-umlaut german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 220),
+ g_strdup_printf("%sU-diaeresis.sym", aux_str));
+ /* a-umlaut finnish/swedish/german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 228),
+ g_strdup_printf("%sa_-diaeresis.sym", aux_str));
+ /* a-ring finnish/swedish/danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 229),
+ g_strdup_printf("%sa_-ring.sym", aux_str));
+ /* ae-diphtong danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 230),
+ g_strdup_printf("%sae_-lig.sym", aux_str));
+ /* o-umlaut finnish/swedish/german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 246),
+ g_strdup_printf("%so_-diaeresis.sym", aux_str));
+ /* o-slash danish/norwegian */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 248),
+ g_strdup_printf("%so_-slash.sym", aux_str));
+ /* u-umlaut german */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 252),
+ g_strdup_printf("%su_-diaeresis.sym", aux_str));
+ /* a-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 225),
+ g_strdup_printf("%sa_-acute-accent.sym", aux_str));
+ /* e-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 233),
+ g_strdup_printf("%se_-acute-accent.sym", aux_str));
+ /* i-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 237),
+ g_strdup_printf("%si_-acute-accent.sym", aux_str));
+ /* o-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 243),
+ g_strdup_printf("%so_-acute-accent.sym", aux_str));
+ /* u-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 250),
+ g_strdup_printf("%su_-acute-accent.sym", aux_str));
+ /* A-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 193),
+ g_strdup_printf("%sA-acute-accent.sym", aux_str));
+ /* E-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 201),
+ g_strdup_printf("%sE-acute-accent.sym", aux_str));
+ /* I-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 205),
+ g_strdup_printf("%sI-acute-accent.sym", aux_str));
+ /* O-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 211),
+ g_strdup_printf("%sO-acute-accent.sym", aux_str));
+ /* U-acute_accent spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 218),
+ g_strdup_printf("%sU-acute-accent.sym", aux_str));
+ /* n-tilde spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 241),
+ g_strdup_printf("%sn_-tilde.sym", aux_str));
+ /* N-tilde spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 209),
+ g_strdup_printf("%sN-tilde.sym", aux_str));
+ /* open exclamation spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 161),
+ g_strdup_printf("%sexcl-open.sym", aux_str));
+ /* open question spanish */
+ g_hash_table_insert (font_char_to_file,
+ g_strdup_printf("%c", 191),
+ g_strdup_printf("%squest-open.sym", aux_str));
+ free(aux_str);
}
@@ -217,15 +399,19 @@
void
o_text_print_set(void)
{
- OBJECT *o_current;
- int i;
+ OBJECT *o_current, *o_font_set;
+ char i;
+ gchar *aux_str;
for (i = 'A' ; i < 'Z'+1; i++) {
- if (font_set[i].font_prim_objs != NULL) {
+ aux_str = g_strdup_printf("%c", i);
+ o_font_set = g_hash_table_lookup (font_loaded, aux_str);
+ free(aux_str);
+ if (o_font_set != NULL) {
printf("%c: LOADED\n", i);
/* for (o_current=font_set[i].font_prim_objs; o_current;
o_current=o_current->next) */
- for (o_current=return_tail(font_set[i].font_prim_objs); o_current;
+ for (o_current=return_tail(o_font_set->font_prim_objs); o_current;
o_current=o_current->prev)
{
printf(" %s\n", o_current->name);
@@ -247,314 +433,16 @@
<<o_text_basic.c : o_text_load_font()>>=
OBJECT *
-o_text_load_font(TOPLEVEL *w_current, unsigned char needed_char)
+o_text_load_font(TOPLEVEL *w_current, gunichar needed_char)
{
- char *temp_string = NULL;
- OBJECT *temp_parent;
+ gchar *temp_string = NULL;
+ OBJECT *temp_parent, *o_font_set;
int not_found = FALSE;
+ gchar *aux_str;
+ gchar *aux_str2;
- switch(needed_char) {
-
- case(' '):
- temp_string = g_strdup_printf("%s%cspace.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('\n'):
- temp_string = g_strdup_printf("%s%cnewline.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
-
- case('!'):
- temp_string = g_strdup_printf("%s%cexcl.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case(','):
- temp_string = g_strdup_printf("%s%ccomma.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('('):
- temp_string = g_strdup_printf("%s%clparen.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case(')'):
- temp_string = g_strdup_printf("%s%crparen.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('-'):
- temp_string = g_strdup_printf("%s%cminus.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('+'):
- temp_string = g_strdup_printf("%s%cplus.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('#'):
- temp_string = g_strdup_printf("%s%cpound.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('?'):
- temp_string = g_strdup_printf("%s%cquest.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('"'):
- temp_string = g_strdup_printf("%s%cquote.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case(':'):
- temp_string = g_strdup_printf("%s%ccolon.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('@'):
- temp_string = g_strdup_printf("%s%cat.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('='):
- temp_string = g_strdup_printf("%s%cequal.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('>'):
- temp_string = g_strdup_printf("%s%cmore.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('<'):
- temp_string = g_strdup_printf("%s%cless.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('/'):
- temp_string = g_strdup_printf("%s%cslash.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('$'):
- temp_string = g_strdup_printf("%s%cdollar.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case(';'):
- temp_string = g_strdup_printf("%s%csemi.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('&'):
- temp_string = g_strdup_printf("%s%camper.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('\\'):
- temp_string = g_strdup_printf("%s%cbackslash.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('{'):
- temp_string = g_strdup_printf("%s%clbrace.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('}'):
- temp_string = g_strdup_printf("%s%crbrace.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('\''):
- temp_string = g_strdup_printf("%s%capost.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('`'):
- temp_string = g_strdup_printf("%s%cbacktick.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('^'):
- temp_string = g_strdup_printf("%s%ccaret.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('%'):
- temp_string = g_strdup_printf("%s%cpercent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('['):
- temp_string = g_strdup_printf("%s%clbrack.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case(']'):
- temp_string = g_strdup_printf("%s%crbrack.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('*'):
- temp_string = g_strdup_printf("%s%castericks.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('.'):
- temp_string = g_strdup_printf("%s%cperiod.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('_'):
- temp_string = g_strdup_printf("%s%cunder.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('~'):
- temp_string = g_strdup_printf("%s%ctilde.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case('|'):
- temp_string = g_strdup_printf("%s%cvbar.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (196): /* A-umlaut finnish/swedish/german */
- temp_string = g_strdup_printf("%s%cA-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (197): /* A-ring finnish/swedish/danish/norwegian */
- temp_string = g_strdup_printf("%s%cA-ring.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (198): /* AE-diphtong danish/norwegian */
- temp_string = g_strdup_printf("%s%cAE-lig.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (214): /* O-umlaut finnish/swedish/german */
- temp_string = g_strdup_printf("%s%cO-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (216): /* O-slash danish/norwegian */
- temp_string = g_strdup_printf("%s%cO-slash.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (220): /* U-umlaut german */
- temp_string = g_strdup_printf("%s%cU-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (228): /* a-umlaut finnish/swedish/german */
- temp_string = g_strdup_printf("%s%ca_-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (229): /* a-ring finnish/swedish/danish/norwegian */
- temp_string = g_strdup_printf("%s%ca_-ring.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (230): /* ae-diphtong danish/norwegian */
- temp_string = g_strdup_printf("%s%cae_-lig.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (246): /* o-umlaut finnish/swedish/german */
- temp_string = g_strdup_printf("%s%co_-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (248): /* o-slash danish/norwegian */
- temp_string = g_strdup_printf("%s%co_-slash.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (252): /* u-umlaut german */
- temp_string = g_strdup_printf("%s%cu_-diaeresis.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (225): /* a-acute_accent spanish */
- temp_string = g_strdup_printf("%s%ca_-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (233): /* e-acute_accent spanish */
- temp_string = g_strdup_printf("%s%ce_-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (237): /* i-acute_accent spanish */
- temp_string = g_strdup_printf("%s%ci_-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (243): /* o-acute_accent spanish */
- temp_string = g_strdup_printf("%s%co_-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (250): /* u-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cu_-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (193): /* A-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cA-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (201): /* E-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cE-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (205): /* I-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cI-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (211): /* O-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cO-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (218): /* U-acute_accent spanish */
- temp_string = g_strdup_printf("%s%cU-acute-accent.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (241): /* n-tilde spanish */
- temp_string = g_strdup_printf("%s%cn_-tilde.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (209): /* N-tilde spanish */
- temp_string = g_strdup_printf("%s%cN-tilde.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (161): /* open exclamation spanish */
- temp_string = g_strdup_printf("%s%cexcl-open.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- case (191): /* open question spanish */
- temp_string = g_strdup_printf("%s%cquest-open.sym",
- w_current->font_directory, PATH_SEPARATER_CHAR);
- break;
-
- default:
+ aux_str = g_strdup_printf("%c", needed_char);
+ if ((aux_str2 = g_hash_table_lookup(font_char_to_file, aux_str)) == NULL) {
/* this is needed since WinNT file systems are
* case insensitive, and cannot tell the difference
* between A.sym and a.sym. So we create a_.sym -
@@ -569,9 +457,12 @@
w_current->font_directory, PATH_SEPARATER_CHAR,
needed_char);
}
- break;
-
}
+ else {
+ temp_string = g_strdup_printf("%s", aux_str2);
+ }
+ aux_str2 = NULL;
+ free(aux_str);
if ( access(temp_string, R_OK) != 0 ) {
s_log_message("Could not find character %c definition\n",needed_char, temp_string);
@@ -584,31 +475,65 @@
not_found = TRUE;
}
- /* printf("loading: %s\n", temp_string);*/
+ /* Make new object for the font set list */
+ o_font_set = (OBJECT *) malloc(sizeof(OBJECT));
+
+ if (o_font_set == NULL) {
+ fprintf(stderr, "Could not perform malloc; something is broken or increase your process limits\n");
+ exit(-1);
+ }
+
+ o_font_set->font_prim_objs = NULL;
+ o_font_set->font_text_size = 100;
+
+ /* Add it to the list and hash table. Some functions will need it */
+ aux_str = g_strdup_printf("%c", needed_char);
+ g_hash_table_insert(font_loaded, aux_str, o_font_set);
+ if (g_hash_table_lookup(font_loaded, aux_str) == NULL) {
+ fprintf(stderr, "Can't find the node that was just inserted!!!\n");
+ exit(-1);
+ }
+ /* aux_str will only be freed when removing the entry in the hash table */
+
+ font_set = g_slist_append (font_set, o_font_set);
+
+ o_font_set->name = NULL;
+ o_font_set->font_prim_objs = o_text_add_head();
- font_set[(unsigned char) needed_char].font_prim_objs = o_text_add_head();
+ /* Modify name of the text so we can free the hashtable entry later */
+ if (o_font_set->name != NULL) {
+ free(o_font_set->name);
+ }
+ o_font_set->name = aux_str;
temp_parent = w_current->page_current->object_parent;
/* set the addition of attributes to the head node */
- w_current->page_current->object_parent = font_set[(unsigned char) needed_char].font_prim_objs;
+ w_current->page_current->object_parent = o_font_set->font_prim_objs;
- font_set[(unsigned char) needed_char].font_prim_objs =
- o_read(w_current, font_set[(unsigned char) needed_char].font_prim_objs,
- temp_string);
+ o_font_set->font_prim_objs = o_read(w_current, o_font_set->font_prim_objs,
+ temp_string);
w_current->page_current->object_parent = temp_parent;
- font_set[(unsigned char) needed_char].font_prim_objs =
- return_head(font_set[(unsigned char) needed_char].font_prim_objs);
+ o_font_set->font_prim_objs = return_head(o_font_set->font_prim_objs);
if (not_found == TRUE) {
/* set the font text size (width) to the question mark's size */
/* yes, the question mark character was loaded instead of the real char */
/* 63 == question mark character */
- font_set[(unsigned char) needed_char].font_text_size =
- font_set[63].font_text_size;
+
+ OBJECT *aux_obj;
+
+ aux_str = g_strdup_printf("?");
+ aux_obj = g_hash_table_lookup (font_loaded, aux_str);
+ if (aux_obj == NULL) {
+ o_text_load_font(w_current, (gunichar) '?');
+ aux_obj = g_hash_table_lookup (font_loaded, aux_str);
+ }
+ free (aux_str);
+
+ o_font_set->font_text_size = aux_obj->font_text_size;
}
-
- return(font_set[(unsigned char) needed_char].font_prim_objs);
+ return(o_font_set->font_prim_objs);
}
@@ -624,7 +549,9 @@
int
o_text_num_lines(char *string)
{
- int i, line_count = 0;
+ int line_count = 0;
+ gchar *aux;
+ gunichar current_char;
if (string == NULL) {
return 0;
@@ -633,9 +560,12 @@
/* if it's not null, then we have at least one line */
line_count++;
/* Count how many \n are in the string */
- for (i = 0; i <= strlen(string); i++) {
- if (string[i] == '\n')
+ aux = string;
+ while (aux && ((gunichar) (*aux) != 0) ) {
+ current_char = g_utf8_get_char_validated(aux, -1);
+ if (current_char == '\n')
line_count++;
+ aux = g_utf8_find_next_char(aux, NULL);
}
return (line_count);
@@ -689,38 +619,58 @@
int len;
int width=0, max_width=0;
int size_of_tab_in_coord;
-
+ gchar *aux;
+ gunichar current_char;
+ OBJECT *o_font_set;
+ gchar *aux_str;
+
+ aux_str = g_strdup_printf("%c", TAB_CHAR_MODEL[0]);
+ o_font_set = g_hash_table_lookup (font_loaded, aux_str);
+
/* Make sure TAB_CHAR_MODEL is loaded before trying to use its text */
/* size */
- if (font_set[(unsigned char) TAB_CHAR_MODEL[0]].font_prim_objs == NULL) {
- o_text_load_font(w_current, (unsigned char) TAB_CHAR_MODEL[0]);
+ if (o_font_set == NULL) {
+ o_text_load_font(w_current, (gunichar) TAB_CHAR_MODEL[0]);
+ o_font_set = (OBJECT *) g_hash_table_lookup (font_loaded, aux_str);
}
+ free (aux_str);
+
/* Get the maximum tab width's in coordinates */
size_of_tab_in_coord = tab_in_chars * size *
- font_set[(unsigned char) TAB_CHAR_MODEL[0]].font_text_size ;
-
+ o_font_set->font_text_size ;
+
if (string == NULL) {
return 0;
}
- len = strlen(string);
- for (i = 0 ; i < len ; i++ ) {
- if (string[i] == '\n') {
+
+ aux = string;
+ while (aux && ((gunichar) (*aux) != 0) ) {
+ current_char = g_utf8_get_char_validated(aux, -1);
+ aux = g_utf8_find_next_char(aux, NULL);
+
+ if (current_char == '\n') {
width = 0;
continue;
}
- if (string[i] == '\t') {
+ if (current_char == '\t') {
width += (size_of_tab_in_coord - (width % size_of_tab_in_coord));
continue;
}
-
- if (font_set[(unsigned char) string[i]].font_prim_objs == NULL) {
- o_text_load_font(w_current, (unsigned char) string[i]);
- }
- width = width + size*font_set[(unsigned char) string[i]].font_text_size;
+ /* Find current_char */
+ aux_str = g_strdup_printf("%c", current_char);
+ o_font_set = g_hash_table_lookup (font_loaded, aux_str);
+ if (o_font_set == NULL) {
+ o_text_load_font(w_current, (gunichar) current_char);
+ o_font_set = g_hash_table_lookup (font_loaded, aux_str);
+ }
+ free (aux_str);
+
+ width = width + size*o_font_set->font_text_size;
if (width > max_width)
max_width = width;
+
}
/* the size is a fudge factor */
@@ -728,6 +678,7 @@
/* Yes, the -size*10 fudge factor should be removed. */
/* return(max_width - size*10); */
return(max_width);
+
}
@@ -748,8 +699,6 @@
OBJECT *temp_tail=NULL;
OBJECT *temp_list;
OBJECT *start_of_char;
- int i;
- int len;
int x_offset;
int y_offset;
int text_width;
@@ -757,6 +706,10 @@
int char_height;
int line_start_x, line_start_y;
int sign=1;
+ gchar *aux;
+ gunichar current_char;
+ gchar *aux_str;
+ OBJECT *o_font_set;
temp_list = object_list;
@@ -766,7 +719,6 @@
return(NULL);
}
- len = strlen(string);
/* now read in the chars */
temp_tail = w_current->page_current->object_tail;
@@ -928,37 +880,52 @@
line_start_x = x_offset;
line_start_y = y_offset;
- for (i = 0 ; i < len ; i++ ) {
-
- if (font_set[(unsigned char) string[i]].font_prim_objs == NULL) {
- o_text_load_font(w_current, (unsigned char) string[i]);
+ aux = string;
+ while (aux && ((gunichar) (*aux) != 0) ) {
+
+ current_char = g_utf8_get_char_validated(aux, -1);
+ aux = g_utf8_find_next_char(aux, NULL);
+
+ aux_str = g_strdup_printf("%c", current_char);
+ o_font_set = g_hash_table_lookup(font_loaded, aux_str);
+ if (o_font_set == NULL) {
+ o_text_load_font(w_current, (gunichar) current_char);
+ o_font_set = g_hash_table_lookup(font_loaded, aux_str);
}
+ free(aux_str);
start_of_char = temp_list;
- if (font_set[(unsigned char) string[i]].font_prim_objs->next) {
+ if (o_font_set->font_prim_objs->next) {
int rel_char_coord;
int size_of_tab_in_coord;
+ OBJECT *o_font_set_aux;
/* Make sure TAB_CHAR_MODEL is loaded before trying to use its text */
/* size */
- if (font_set[(unsigned char) TAB_CHAR_MODEL[0]].font_prim_objs == NULL) {
- o_text_load_font(w_current, (unsigned char) TAB_CHAR_MODEL[0]);
+ aux_str = g_strdup_printf("%c", TAB_CHAR_MODEL[0]);
+ o_font_set_aux = g_hash_table_lookup(font_loaded, aux_str);
+ if (o_font_set_aux == NULL) {
+ o_text_load_font(w_current, (gunichar) TAB_CHAR_MODEL[0]);
+ o_font_set_aux = g_hash_table_lookup(font_loaded, aux_str);
}
+ free (aux_str);
+
/* Get the maximum tab width's in coordinates */
size_of_tab_in_coord = tab_in_chars *
o_text_width(w_current, TAB_CHAR_MODEL, size/2);
- if (string[i] != '\n' && string[i] != '\t') {
+ if (current_char != '\n' && current_char != '\t') {
/* only add the character if it is not a newline or tab character */
temp_list = o_list_copy_all(w_current,
- font_set[(unsigned char) string[i]].font_prim_objs->next,
+ o_font_set->font_prim_objs->next,
temp_list, NORMAL_FLAG);
- start_of_char = start_of_char->next;
+ if (start_of_char != NULL)
+ start_of_char = start_of_char->next;
}
/* if the character is a newline or tab, this code will "continue" */
- switch (string[i]) {
+ switch (current_char) {
case '\n':
switch (angle) {
case 0:
@@ -1048,24 +1015,25 @@
switch(angle) {
case(0):
x_offset = (x_offset) +
- size/2*font_set[(unsigned char) string[i]].font_text_size;
+ size/2*o_font_set->font_text_size;
break;
case(90):
y_offset = (y_offset) +
- size/2*font_set[(unsigned char) string[i]].font_text_size;
+ size/2*o_font_set->font_text_size;
break;
case(180):
x_offset = (x_offset) -
- size/2*font_set[(unsigned char) string[i]].font_text_size;
+ size/2*o_font_set->font_text_size;
break;
case(270):
y_offset = (y_offset) -
- size/2*font_set[(unsigned char) string[i]].font_text_size;
+ size/2*o_font_set->font_text_size;
break;
}
+
}
/* don't set the head */
@@ -1078,7 +1046,6 @@
return(object_list);
}
-
@ %def o_text_create_string
@@ -1398,6 +1365,8 @@
unsigned int temp;
int special=0;
char *string;
+ gchar *aux_str;
+ OBJECT *o_font_set;
string = g_strdup(remove_nl(buf));
@@ -1416,10 +1385,22 @@
character = 10;
}
- temp = (unsigned char) character;
- if ( temp >= 0 && temp <= 255) {
- font_set[(unsigned char) character].font_text_size = width;
+ /* With Unicode support, there's no need that the character is 0-255. */
+ /* temp = (unsigned char) character; */
+ /* if ( temp >= 0 && temp <= 255) { */
+
+ aux_str = g_strdup_printf("%c", character);
+ o_font_set = g_hash_table_lookup (font_loaded, aux_str);
+ free (aux_str);
+
+ if (o_font_set != NULL) {
+ o_font_set->font_text_size = width;
+ }
+ else {
+ fprintf(stderr, "o_text_set_info_font: character %c not found!!!\n", character);
}
+
+ /* } */
free(string);
}
@@ -1656,13 +1637,28 @@
o_text_freeallfonts(TOPLEVEL *w_current)
{
int i;
+ OBJECT *aux;
- for (i = 0 ; i < NUM_CHARS; i++) {
- if (font_set[i].font_prim_objs != NULL) {
- s_delete_list_fromstart(w_current, font_set[i].font_prim_objs);
- font_set[i].font_prim_objs = NULL;
+ aux = (OBJECT *) font_set;
+ while ((aux = (OBJECT *) g_slist_nth_data(font_set,0)) != NULL) {
+ if (aux->font_prim_objs != NULL) {
+ s_delete_list_fromstart(w_current, aux->font_prim_objs);
+ aux->font_prim_objs = NULL;
}
+ /* Remove the entry from the hash table */
+ /* (OBJECT *)->name = key of font_loaded, so it will be freed later */
+
+ /* Remove from the list the node with data pointed by aux */
+ font_set = g_slist_remove(font_set, aux);
+
}
+ g_slist_free (font_set);
+
+ /* Destroy the font to file hashtable */
+ g_hash_table_destroy(font_loaded);
+
+ /* Destroy the font to file hashtable */
+ g_hash_table_destroy(font_char_to_file);
}
@@ -2272,6 +2268,8 @@
}
o_current=o_current->next;
}
+ /* String?? Which string? */
+ /* free(string); */
}