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

gfont problem with PS fonts on big-endian platforms (patch included)




WML users,

[I submitted details of this issue using the web-form on the gfont web-
 page...]

On big-endian architectures, gfont fails when trying to use PostScript
fonts.  It always reports that the ".gdf[.gz]" files are invalid if the
y were built on a big-endian machine.  Here's what happens:

   $ gfont -F Courier -o /tmp/courier.gif courier  
   Running `.../lib/exec/gfont_mkgdf Courier'
   [Create PK file via GSFtoPK/Ghostscript]
   gsftopk -q pcrr8r 72
   [Convert PK to GdF]
   .../lib/exec/gfont_pktopx pcrr8r.72pk pcrr8r.72px
   .../lib/exec/gfont_pxtogdf pcrr8r.72px pcrr8r.gdf pcrr8r.gdi
   [Compress GdF]
   gzip -9 <pcrr8r.gdf >.../lib/gdf/Courier.gdf.gz
   Still cannot load font 'Courier'
   $

What I found to be the problem was that "gfont_pxtogdf" wrote long words
(such as the number of characters in the font) as a host/native-ordered
integers into the resulting ".gdf" files.  However, the code that reads
the ".gdf" files uses a function called "gdIntern_convert_long" to swab
these values on big-endian systems.  (This caused the number of characters
in the font to be mis- interpreted as 65536 rather than 256 which led to
the errant behavior.)

If you want to use gfont with PostScript fonts on a big-endian machine
(such as Solaris SPARC): apply the accompanying patch, then be sure to run
autoconf immediately afterwards since I did not patch "configure", just
"configure.in".  Next remove "config.cache" and rerun "configure" and
"make install".

Beware: Since the accompanying patch causes gfont to store integers in
big-endian rather than native host-order (which is little-endian on Intel),
it will invalidate your current ".gdf" files.  If you prefer to maintain
compatibility with current ".gdf" files rather than rebuilding them,
perhaps you should wait to see what the WML/gfont maintainer makes of this.
(I did not find any docs which explicitly state the ".gdf" file format
so I didn't know whether storing them in host-order was an oversight or if
it was intended that they always be little-endian or what.)

Dave

P.S. The good news is that, for the most part, WML & gfont work well on
Solaris SPARC.  I'm gathering that the rest of the user-base is on Intel
hence they didn't bump into this issue.

-- 
plonka@doit.wisc.edu  http://net.doit.wisc.edu/~plonka  ARS:N9HZF  Madison, WI
*** configure.in_djp2	Tue Jun 29 13:23:34 1999
--- configure.in	Mon Jul 19 10:43:58 1999
***************
*** 27,32 ****
--- 27,33 ----
  AC_CONFIGURE_PART(CHECK: C Compiler and Perl Interpreter)
  AC_PROG_CC
  AC_PROG_CPP
+ AC_C_BIGENDIAN
  AC_MSG_CHECKING([for Perl language])
  TMPFILE=/tmp/ac.$$
  rm -f $TMPFILE
*** gfont_pxtogdf.c_djp	Fri Sep  5 13:51:38 1997
--- gfont_pxtogdf.c	Mon Jul 19 11:35:23 1999
***************
*** 239,244 ****
--- 239,250 ----
  
  void Put32(FILE *fp, int i)
  {
+ #ifndef WORDS_BIGENDIAN /* { */
+     i = (((i & 0xff000000L) >> 24) | 
+          ((i & 0x00ff0000L) >>  8) |
+          ((i & 0x0000ff00L) <<  8) |
+          ((i & 0x000000ffL) << 24));
+ #endif /* } */
      fwrite(&i, sizeof(int), 1, fp);
      return;
  }
*** gfont_gd.c_djp	Fri Sep  5 13:32:51 1997
--- gfont_gd.c	Mon Jul 19 10:54:14 1999
***************
*** 2674,2713 ****
  /*****************/
  
  /*
!  *  Byte Conversion -- Hilfsroutinen fuer das alte
!  *  Problem High-Endian vs. Little-Endian !!
   */
- unsigned short gdIntern_convert_short(unsigned short z)
- {
-     char *teststring;
-     short t;
- 
-     t = 0x4142;
- 
-     teststring = (char *)&t;
- 
-     if(teststring[0] == 'B' && teststring[1] == 'A')
-         return(z);
-     else
-         return(((z & 0xff00U) >> 8) | ((z & 0x00ffU) << 8));
- }
  unsigned long gdIntern_convert_long(unsigned long z)
  {
!     char *teststring;
!     unsigned long t;
! 
!     t = 0x41424344;
! 
!     teststring = (char *)&t;
! 
!     if(teststring[0] == 'D' && teststring[1] == 'C' &&
!        teststring[2] == 'B' && teststring[3] == 'A')
!         return(z);
!     else
!         return(((z & 0xff000000L) >> 24) | 
!                ((z & 0x00ff0000L) >>  8) |
!                ((z & 0x0000ff00L) <<  8) |
!                ((z & 0x000000ffL) << 24));
  }
  
  gdFontPtr gdFontCreateFromGdf(FILE *in)
--- 2674,2691 ----
  /*****************/
  
  /*
!  *  Byte Conversion
   */
  unsigned long gdIntern_convert_long(unsigned long z)
  {
! #ifdef WORDS_BIGENDIAN /* { */
!     return(z);
! #else /* }{ */
!     return(((z & 0xff000000L) >> 24) | 
!            ((z & 0x00ff0000L) >>  8) |
!            ((z & 0x0000ff00L) <<  8) |
!            ((z & 0x000000ffL) << 24));
! #endif /* } */
  }
  
  gdFontPtr gdFontCreateFromGdf(FILE *in)