[GRASS-dev] iconv a required dependency for using Freetype?

Paul Kelly paul-grass at stjohnspoint.co.uk
Sat May 5 17:59:21 EDT 2007


On Sat, 5 May 2007, Glynn Clements wrote:

> You just need a hard-coded conversion to UCS-2 for the case where
> iconv() is unavailable. ISO-8859-1 -> UCS-2 (used by d.text.freetype)
> is trivial; a built-in UTF-8 -> UCS-2 converter wouldn't be a lot of
> work.

Thanks for the hint - that seems to have worked out fine and I've already 
committed the fix.

I've attached a diff of a few more changes I'm considering making, mostly 
relating to path and filename handling for Windows compatibility in 
loading fonts. Here's what I've changed so far:

lib/driver/Font.c, COM_Font_get():
* Cross-platform check for absolute path (new gislib function added)
* Check for pathname matching the GRASS stroke fonts made more robust by
   (a) First converting all directory separator characters to '/'
   (b) Doing a case-insensitive comparison

lib/driver/font2.c, read_fontmap():
* Warning message when unable to open font made clearer by specifying
the exact path it was trying to open and giving the system error message.

font_init():
* Convert directory separator characters to '/' so that the way the 
directory name is stripped off works
* Strip off the ".hmp" extension if it was there. It strikes me as very
weird that I needed to do this, because without that I reall can't see how 
passing the full path to one of the GRASS stroke fronts would have worked. 
The full filename has to be given in the GRASS_FONT variable, otherwise 
the font_exists() check in COM_Font_get() will fail, but the .hmp is never 
stripped off and then it is added again in read_fontmap(), resulting in it 
trying to open a file ending in ".hmp.hmp".

I haven't committed the changes yet as they're not complete. Apart from
being unsure about stripping off the .hmp extension, specifying a
font in GRASS_FONT from the freetypecap file doesn't work. I'm just
testing this from the command line on Windows, i.e. using direct
rendering as drivers don't work, and I can't see where/if the freetypecap 
file is actually being read. Specifying the full path to a Freetype font
works fine, but is the freetypecap file only read when a driver process
is initialised?

-------------- next part --------------
Index: include/gisdefs.h
===================================================================
RCS file: /home/grass/grassrepository/grass6/include/gisdefs.h,v
retrieving revision 1.99
diff -u -r1.99 gisdefs.h
--- include/gisdefs.h	2 May 2007 06:00:33 -0000	1.99
+++ include/gisdefs.h	5 May 2007 21:43:58 -0000
@@ -865,6 +865,7 @@
 /* paths.c */
 int G_mkdir(const char *);
 int G_is_dirsep(char);
+int G_is_absolute_path(const char *);
 char *G_convert_dirseps_to_host(char *);
 char *G_convert_dirseps_from_host(char *);
 struct stat;
 
 /* timestamp.c */
Index: lib/gis/paths.c
===================================================================
RCS file: /home/grass/grassrepository/grass6/lib/gis/paths.c,v
retrieving revision 2.3
diff -u -r2.3 paths.c
--- lib/gis/paths.c	4 Apr 2007 04:07:01 -0000	2.3
+++ lib/gis/paths.c	5 May 2007 21:43:58 -0000
@@ -41,6 +41,27 @@
 }
 
 /**
+ * \brief Checks if a specified path looks like an absolute
+ *        path on the host system
+ *
+ * \param path String containing path to check
+ *
+ * \return 1 if path looks like an absolute path, 0 if not
+ **/
+
+int G_is_absolute_path(const char *path)
+{
+    if ( G_is_dirsep(path[0])
+#ifdef __MINGW32__	
+	|| ((path[1] == ':') && G_is_dirsep(path[2])) 
+#endif
+       )
+        return 1;
+    else
+        return 0;
+}
+   
+/**
  * \brief Converts directory separator characters in a string to the
  *        native host separator character (/ on Unix, \ on Windows)
  *
Index: lib/driver/Font.c
===================================================================
RCS file: /home/grass/grassrepository/grass6/lib/driver/Font.c,v
retrieving revision 1.8
diff -u -r1.8 Font.c
--- lib/driver/Font.c	3 May 2007 04:32:03 -0000	1.8
+++ lib/driver/Font.c	5 May 2007 21:43:58 -0000
@@ -24,17 +24,25 @@
 
 void COM_Font_get(const char *name)
 {
-	if (name[0] == '/')
+	if (G_is_absolute_path(name))
 	{
 		static char prefix[4096];
+		char name_copy[4096];
 
 		if (!font_exists(name))
 			return;
 
 		if (!*prefix)
+		{		
 			sprintf(prefix, "%s/fonts/", G_gisbase());
-
-		if (strncmp(name, prefix, strlen(prefix)) == 0)
+			G_convert_dirseps_from_host(prefix);
+		}	   
+	   	   
+		/* Case-insensitive comparison with all '/' dirsep chars */
+		strncpy(name_copy, name, strlen(prefix));
+		name_copy[strlen(prefix)] = '\0';
+		G_convert_dirseps_from_host(name_copy);	   
+		if (G_strcasecmp(name_copy, prefix) == 0)
 			stroke_set(name);
 		else
 			freetype_set(name);
Index: lib/driver/font2.c
===================================================================
RCS file: /home/grass/grassrepository/grass6/lib/driver/font2.c,v
retrieving revision 1.2
diff -u -r1.2 font2.c
--- lib/driver/font2.c	5 Mar 2007 06:20:00 -0000	1.2
+++ lib/driver/font2.c	5 May 2007 21:43:58 -0000
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -152,7 +153,8 @@
 	fp = fopen(buf, "r");
 	if (!fp)
 	{
-		G_warning("unable to open font map '%s'", name);
+		G_warning("unable to open font map '%s': %s", buf,
+			  strerror(errno));
 		return;
 	}
 
@@ -185,13 +187,23 @@
 
 int font_init(const char *name)
 {
-	if (strchr(name, '/'))
-		name = strrchr(name, '/') + 1;
+	char name_copy[4096];
+	char *name_ptr;
 
-	if (strcmp(name, current_font) == 0)
+	strcpy(name_copy, name);
+	G_convert_dirseps_from_host(name_copy);	   
+   
+	if (strchr(name_copy, GRASS_DIRSEP))
+		name_ptr = strrchr(name_copy, GRASS_DIRSEP) + 1;
+	else
+		name_ptr = name_copy;     
+
+        G_basename(name_ptr, "hmp");
+
+	if (strcmp(name_ptr, current_font) == 0)
 		return 0;
 
-	strcpy(current_font, name);
+	strcpy(current_font, name_ptr);
 	font_loaded = 0;
 
 	return 0;


More information about the grass-dev mailing list