Subject: PFB files for printers that don't understand them
From: Mike Meyer (mwm@mired.org)
Date: Sat Jun 10 2000 - 13:16:53 CDT
This patch returns PFB files as PFA files so that printing them to
postscript printers that don't understand PFB works properly. It's the
second version, it patches only xap_Unixfont.(cpp|h) and expects to be
applied in the abi/src/af/xap/unix directory.
This version of the patch solves the performance problems. The
solution was to have xap_UnixFont keep track of the ut_ByteBuf
position instead of just deleting characters, thus eliminating the
data shuffling. It's obvious in retrospect.
 
        Thanx,
        <mike
--- xap_UnixFont.cpp-old	Fri Jun  9 12:46:50 2000
+++ xap_UnixFont.cpp	Sat Jun 10 13:04:47 2000
@@ -87,7 +87,7 @@
 
         m_metricsData = NULL;
         
-	m_PFAFile = NULL;
+	m_PFFile = NULL;
         
         m_fontKey = NULL;
 }
@@ -103,7 +103,7 @@
         
         m_metricsData = NULL;
 
-	m_PFAFile = NULL;
+	m_PFFile = NULL;
 
         m_fontKey = NULL;
 
@@ -120,7 +120,7 @@
         FREEP(m_fontfile);
         FREEP(m_metricfile);
 
-	DELETEP(m_PFAFile);
+	DELETEP(m_PFFile);
         
         FREEP(m_fontKey);
 
@@ -304,10 +304,11 @@
 UT_Bool XAP_UnixFont::openPFA(void)
 {
         ASSERT_MEMBERS;
+	int peeked;
         
-	m_PFAFile = fopen(m_fontfile, "r");
+	m_PFFile = fopen(m_fontfile, "r");
 
-	if (!m_PFAFile)
+	if (!m_PFFile)
         {
                 char message[1024];
                 g_snprintf(message, 1024,
@@ -316,14 +317,19 @@
                 return UT_FALSE;
         }
 
+	/* Check to see if it's a binary or ascii PF file */
+	peeked = fgetc(m_PFFile);
+	ungetc(peeked, m_PFFile);
+	m_PFB = peeked == PFB_MARKER;
+	m_bufpos = 0;
         return UT_TRUE;
 }
 
 UT_Bool XAP_UnixFont::closePFA(void)
 {
-	if (m_PFAFile)
+	if (m_PFFile)
         {
-		fclose(m_PFAFile);
+		fclose(m_PFFile);
                 return UT_TRUE;
         }
         return UT_FALSE;
@@ -331,8 +337,95 @@
 
 char XAP_UnixFont::getPFAChar(void)
 {
-	UT_ASSERT(m_PFAFile);
-	return fgetc(m_PFAFile);
+	UT_ASSERT(m_PFFile);
+	return m_PFB ? _getPFBChar() : fgetc(m_PFFile);
+}
+
+char XAP_UnixFont::_getPFBChar(void)
+{
+	char message[1024];
+	UT_Byte inbuf[BUFSIZ], hexbuf[2 * BUFSIZ], *inp, *hexp;
+	int  type, in, got, length;
+	static char *hex = "0123456789abcdef";
+
+	if (m_buffer.getLength() > m_bufpos )
+	{
+		return m_buffer.getPointer(m_bufpos++)[0];
+	}
+
+	// Read a new block into the buffer.
+	m_buffer.truncate(0);
+	in = fgetc(m_PFFile);
+	type = fgetc(m_PFFile);
+
+	if (in != PFB_MARKER
+	    || (type != PFB_ASCII && type != PFB_BINARY && type != PFB_DONE))
+	{
+		g_snprintf(message, 1024,
+				   "AbiWord encountered errors parsing the font data file\n"
+				   "[%s].\n"
+				   "These errors were not fatal, but printing may be incorrect.",
+				   m_fontfile);
+		messageBoxOK(message);
+		return EOF;
+	}
+
+	if (type == PFB_DONE)
+	{
+		/*
+		 * If there's data after this, the file is corrupt and we want
+		 * to ignore it.
+		 */
+		ungetc(PFB_DONE, m_PFFile);
+		return EOF;
+	}
+
+	length = fgetc(m_PFFile) & 0xFF;
+	length |= (fgetc(m_PFFile) & 0XFF) << 8;
+	length |= (fgetc(m_PFFile) & 0XFF) << 16;
+	length |= (fgetc(m_PFFile) & 0XFF) << 24;
+	if (feof(m_PFFile))
+	{
+		g_snprintf(message, 1024,
+				   "AbiWord encountered errors parsing the font data file\n"
+				   "[%s].\n"
+				   "These errors were not fatal, but printing may be incorrect.",
+				   m_fontfile);
+		messageBoxOK(message);
+		return EOF;
+	}
+
+	while (length > 0)
+	{
+		in = (length > BUFSIZ ? BUFSIZ : length);
+		got = fread(inbuf, 1, in, m_PFFile);
+		if (in != got)
+		{
+		g_snprintf(message, 1024,
+				   "AbiWord encountered errors parsing the font data file\n"
+				   "[%s].\n"
+				   "These errors were not fatal, but printing may be incorrect.",
+				   m_fontfile);
+			messageBoxOK(message);
+			length = got;
+		}
+		if (type == PFB_ASCII)
+			m_buffer.append(inbuf, got);
+		else // type == PFB_BINARY
+		{
+			hexp = hexbuf;
+			for (inp = inbuf; inp - inbuf < got; inp += 1)
+			{
+				  *hexp++ = hex[(*inp >> 4) & 0xf];
+				  *hexp++ = hex[*inp & 0xf];
+			}
+			m_buffer.append(hexbuf, 2 * got);
+		}
+		length -= got ;
+	}
+
+	m_bufpos = 1;
+	return m_buffer.getPointer(0)[0];
 }
 
 const char * XAP_UnixFont::getFontKey(void)
--- xap_UnixFont.h-old	Fri Jun  9 12:46:51 2000
+++ xap_UnixFont.h	Sat Jun 10 12:47:45 2000
@@ -26,6 +26,7 @@
 
 #include "ut_types.h"
 #include "ut_vector.h"
+#include "ut_bytebuf.h"
 
 #include "gr_Graphics.h"
 
@@ -97,8 +98,19 @@
         char * 					m_fontfile;
         char *					m_metricfile;
 
-	FILE *	 				m_PFAFile;
+	// The font file proper
+	FILE *	 				m_PFFile;
+	UT_Bool					m_PFB;
+	UT_ByteBuf				m_buffer;
+	UT_uint32				m_bufpos;
+	char					_getPFBChar(void);
 };
+
+/* Values found in PFB files */
+#define	PFB_MARKER	0x80
+#define PFB_ASCII	1
+#define PFB_BINARY	2
+#define PFB_DONE	3
 
 /*****************************************************************/
 
This archive was generated by hypermail 2b25 : Sat Jun 10 2000 - 13:17:47 CDT