[PATCH] proper i18n of printing for gnumeric




 Hi, 

 Here is a patch against gnumeric-0.58 that will make printing i18n-friendly.
 It makes printing ideologically correct (rather than supporting ONLY
iso-8859-1 locales) - it will allow printing under any locale with any
encoding: printing should work on utf8 locales (not tested) and 8bit
non-latin1 locales too (tested with russian - ru_RU.KOI8-R under RedHat 6.2).
Of course correct fonts with required glyphs should be registered with
gnome-print and gnome-print should support their encoding (so gnumeric still
won't print under CJK locales - but only because gnome-print doesn't support
them).

 The only additional function required by this patch is mbstowcs. It's
required by SVID 3, so there shouldn't be problems with it. All changes are
ifdefed.

 Without this patch, gnumeric will be able to print only under latin1 locales
with iso-8859-1 encoding.

 It would be nice if this patch was included with gnumeric that is shipped
with gnome-1.4. What do you think?

 Best regards,
  -Vlad
diff -ru gnumeric-0.58~/src/print-cell.c gnumeric-0.58/src/print-cell.c
--- gnumeric-0.58~/src/print-cell.c	Sat Nov 11 18:03:18 2000
+++ gnumeric-0.58/src/print-cell.c	Fri Mar  9 14:51:10 2001
@@ -5,6 +5,7 @@
  *    Miguel de Icaza 1999 (miguel@kernel.org)
  *
  * g_unichar_to_utf8: Copyright Red Hat, Inc
+ * i18n of printing: Copyright 2001 by Vlad Harchev <hvv@hippo.ru>
  */
 #include <config.h>
 #include <gnome.h>
@@ -24,6 +25,18 @@
 #include "print-cell.h"
 #include "rendered-value.h"
 
+/*
+  Define this to enable i18n-wise printing and string measuring - it requires
+  mbstowcs to be available. Most probably printing work fine for ANY locale
+  (though gnome-print doesn't support CJK yet - but when it will be ready, no
+  changes will be needed in the code used when _PROPER_I18N is defined.
+  
+  If this macro is undefined, printing will work only for iso-8859-1, so please
+  try hard to avoid undefining it.
+      - Vlad Harchev <hvv@hippo.ru>
+*/
+#define _PROPER_I18N
+
 static void
 print_vline (GnomePrintContext *context,
 	     double x, double y1, double y2)
@@ -144,6 +157,93 @@
 	return ret;
 }
 
+int
+print_show (GnomePrintContext *pc, char const *text)
+{
+#ifdef _PROPER_I18N
+	wchar_t* wcs,wcbuf[4096];
+	char* utf8,utf8buf[4096];
+	
+	int conv_status;
+	int n = strlen(text);
+	int retval;
+
+	g_return_val_if_fail (pc && text, -1);	
+	
+	if ( n > (sizeof(wcbuf)/sizeof(wcbuf[0])))
+		wcs = g_new(wchar_t,n);
+	else
+		wcs = wcbuf;
+
+	conv_status = mbstowcs(wcs, text, n);
+
+	if (conv_status == (size_t)(-1)){
+		if (wcs != wcbuf)
+			g_free (wcs);
+		return 0;
+	};
+	if (conv_status * 6 > sizeof(utf8buf))
+		utf8 = g_new(gchar, conv_status * 6);
+	else
+		utf8 = utf8buf;
+	{
+		int i;
+		char* p = utf8;
+		for(i = 0; i < conv_status; ++i)
+			p += g_unichar_to_utf8 ( (gint) wcs[i], p);
+		if (wcs != wcbuf)
+			g_free(wcs);			
+		retval = gnome_print_show_sized (pc, utf8, p - utf8);			
+	}	
+
+	if (utf8 != utf8buf)
+		g_free(utf8);
+	return retval;		
+#else
+	return print_show_iso8859_1 (pc, text);
+#endif
+};
+
+double
+get_width_string_n (GnomeFont *font,char const* text,guint n)
+{
+#ifdef _PROPER_I18N
+	wchar_t* wcs,wcbuf[4000];
+	int conv_status,i;
+	double total = 0;	
+	
+	if ( n > (sizeof(wcbuf)/sizeof(wcbuf[0])))
+		wcs = g_new(wchar_t,n);
+	else
+		wcs = wcbuf;
+
+	conv_status = mbstowcs(wcs, text, n);
+
+	if (conv_status == (size_t)(-1)){
+		if (wcs != wcbuf)
+			g_free (wcs);
+		return 0;
+	};
+	for (i = 0; i < conv_status; ++i)
+		total += gnome_font_get_glyph_width(font, 
+				gnome_font_lookup_default(font, wcs[i]));
+
+	if (wcs != wcbuf)
+		g_free(wcs);
+	return total;
+#else
+	return gnome_font_get_width_string_n (font, text, n);
+#endif
+};
+
+
+double
+get_width_string (GnomeFont *font,char const* text)
+{
+	return get_width_string_n (font, text, strlen(text));
+};
+
+
 /***********************************************************/
 
 /*
@@ -160,7 +260,7 @@
 	gnome_print_moveto (context, x, text_base);
 	/* FIXME:
 	 * Switch this back to gnome_print_show once we use UTF-8 internally */
-	print_show_iso8859_1 (context, text);
+	print_show (context, text);
 
 	/* FIXME how to handle small fonts ?
 	 * the text_base should be at least 2 pixels above the bottom */
@@ -204,7 +304,7 @@
 
 	for (line_begin = p = text; *p; p++){
 		double const len_current =
-			gnome_font_get_width_string_n (font, p, 1);
+			get_width_string_n (font, p, 1);
 
 		/* Wrap if there is an embeded newline, or we have overflowed */
 		if (*p == '\n' || used + len_current > width){
@@ -443,7 +543,7 @@
 	if (mstyle_get_font_strike (mstyle))
 		line_offset[num_lines++] = font_ascent/-2;
 
-	cell_width_pts = gnome_font_get_width_string (print_font, text);
+	cell_width_pts = get_width_string (print_font, text);
 
 	/* if a number overflows, do special drawing */
 	if (width < cell_width_pts && cell_is_number (cell) &&
@@ -565,17 +665,17 @@
 			case HALIGN_JUSTIFY:
 				x_offset = ci->margin_a;
 				if (num_lines > 0)
-					len = gnome_font_get_width_string (print_font, str);
+					len = get_width_string (print_font, str);
 				break;
 
 			case HALIGN_RIGHT:
-				len = gnome_font_get_width_string (print_font, str);
+				len = get_width_string (print_font, str);
 				x_offset = ci->size_pts - ci->margin_b - len;
 				break;
 
 			case HALIGN_CENTER:
 			case HALIGN_CENTER_ACROSS_SELECTION:
-				len = gnome_font_get_width_string (print_font, str);
+				len = get_width_string (print_font, str);
 				x_offset = (ci->size_pts - len) / 2;
 			}
 
diff -ru gnumeric-0.58~/src/print-cell.h gnumeric-0.58/src/print-cell.h
--- gnumeric-0.58~/src/print-cell.h	Tue Sep 12 01:29:23 2000
+++ gnumeric-0.58/src/print-cell.h	Fri Mar  9 14:41:04 2001
@@ -17,7 +17,11 @@
 
 /* This function got introduced when gnome-print switched to UTF-8, and will
  * disappear again once Gnumeric makes the switch */
-int print_show_iso8859_1 (GnomePrintContext *pc, char const *text);
+int print_show (GnomePrintContext *pc, char const *text);
+
+/* Use these instead of gnome_font_get_width_string[_n] ! */
+double get_width_string_n (GnomeFont *font,char const* text,guint n);
+double get_width_string (GnomeFont *font,char const* text);
 
 void print_make_rectangle_path (GnomePrintContext *pc,
 				double left, double bottom,
diff -ru gnumeric-0.58~/src/print.c gnumeric-0.58/src/print.c
--- gnumeric-0.58~/src/print.c	Fri Nov  3 07:39:55 2000
+++ gnumeric-0.58/src/print.c	Fri Mar  9 14:41:44 2001
@@ -274,7 +274,7 @@
 		return;
 	}
 	
-	len = gnome_font_get_width_string (pj->decoration_font, text);
+	len = get_width_string (pj->decoration_font, text);
 	
 	pm = &pj->pi->margins;
 	switch (side){
@@ -294,9 +294,8 @@
 		x = 0;
 	}	
 	gnome_print_moveto (pj->print_context, x, y);
-	/* FIXME:
-	 * Switch this back to gnome_print_show once we use UTF-8 internally */
-	print_show_iso8859_1 (pj->print_context, text);
+
+	print_show (pj->print_context, text);
 	g_free (text);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]