RICHEDIT: port the RTF parser to the richedit 2.0 control

Mike McCormack mike at codeweavers.com
Mon Mar 7 05:40:59 CST 2005


This is a port of the only useful piece of the Richedit 1.0 (aka 
riched32) control to the richedit 2.0 control.  After Richedit 2.0 works 
a little better we can reimplement the old richedit by forwarding it to 
Krzysztof's new richedit 2.0 implementation.

I'm keeping the tab formatting, as that is how the original RTF Tools 
(http://www.snake.net/software/RTF/) were written.

Mike


ChangeLog:
* port the RTF parser to the richedit 2.0 control
-------------- next part --------------
? dlls/riched20/reader.c
? dlls/riched20/rtf.h
Index: dlls/riched20/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/riched20/Makefile.in,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.in
--- dlls/riched20/Makefile.in	5 Mar 2005 11:19:14 -0000	1.1
+++ dlls/riched20/Makefile.in	7 Mar 2005 05:43:59 -0000
@@ -12,6 +12,7 @@ C_SRCS = \
 	list.c \
 	paint.c \
 	para.c \
+	reader.c \
 	richole.c \
 	row.c \
 	run.c \
Index: dlls/riched20/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.1
diff -u -p -r1.1 editor.c
--- dlls/riched20/editor.c	5 Mar 2005 11:19:14 -0000	1.1
+++ dlls/riched20/editor.c	7 Mar 2005 05:44:00 -0000
@@ -208,6 +208,8 @@
 #include <winreg.h>
 #define NO_SHLWAPI_STREAM 
 #include <shlwapi.h>
+
+#include "rtf.h"
  
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
@@ -304,6 +306,31 @@ ME_TextBuffer *ME_MakeText() {
   return buf;
 }
 
+static LRESULT ME_StreamIn(HWND hwnd, DWORD format, EDITSTREAM *stream)
+{
+  RTF_Info parser;
+
+  TRACE("%p %p\n", stream, hwnd);
+
+  /* setup the RTF parser */
+  memset(&parser, 0, sizeof parser);
+  RTFSetEditStream(&parser, stream);
+  parser.rtfFormat = format&(SF_TEXT|SF_RTF);
+  parser.hwndEdit = hwnd;
+  WriterInit(&parser);
+  RTFInit(&parser);
+  BeginFile(&parser);
+
+  /* do the parsing */
+  RTFRead(&parser);
+  RTFFlushOutputBuffer(&parser);
+
+  /* put the cursor at the top */
+  SendMessageA(hwnd, EM_SETSEL, 0, 0);
+
+  return 0;
+}
+
 ME_TextEditor *ME_MakeEditor(HWND hWnd) {
   ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor);
   HDC hDC;
@@ -414,7 +441,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   UNSUPPORTED_MSG(EM_SETUNDOLIMIT)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROC)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
-  UNSUPPORTED_MSG(EM_STREAMIN)
   UNSUPPORTED_MSG(EM_STREAMOUT)
   UNSUPPORTED_MSG(WM_SETFONT)
   UNSUPPORTED_MSG(WM_PASTE)
@@ -422,7 +448,10 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   UNSUPPORTED_MSG(WM_STYLECHANGED)
 /*  UNSUPPORTED_MSG(WM_UNICHAR) FIXME missing in Wine headers */
     
+/* Messages specific to Richedit controls */
   
+  case EM_STREAMIN:
+   return ME_StreamIn(hWnd, wParam, (EDITSTREAM*)lParam);
   case WM_GETDLGCODE:
   {
     UINT code = DLGC_WANTCHARS|DLGC_WANTARROWS;
--- /dev/null	2005-02-25 01:31:53.000000000 +0900
+++ dlls/riched20/reader.c	2005-03-07 14:40:40.000000000 +0900
@@ -0,0 +1,3778 @@
+/*
+ * WINE RTF file reader
+ *
+ * Portions Copyright 2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Derived from RTF Tools by Paul DuBois (dubois at primate.wisc.edu)
+ * Homepage: http://www.snake.net/software/RTF/
+ * Original license follows:
+ */
+
+/*
+ * reader.c - RTF file reader.  Release 1.10.
+ *
+ * ....
+ *
+ * Author: Paul DuBois	dubois at primate.wisc.edu
+ *
+ * This software may be redistributed without restriction and used for
+ * any purpose whatsoever.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "rtf.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+
+extern HANDLE me_heap;
+
+static int      _RTFGetChar(RTF_Info *);
+static void	_RTFGetToken (RTF_Info *);
+static void	_RTFGetToken2 (RTF_Info *);
+static int	GetChar (RTF_Info *);
+static void	ReadFontTbl (RTF_Info *);
+static void	ReadColorTbl (RTF_Info *);
+static void	ReadStyleSheet (RTF_Info *);
+static void	ReadInfoGroup (RTF_Info *);
+static void	ReadPictGroup (RTF_Info *);
+static void	ReadObjGroup (RTF_Info *);
+static void	LookupInit (void);
+static void	Lookup (RTF_Info *, char *);
+static int	Hash (char*);
+
+static void	CharSetInit (RTF_Info *);
+static void	ReadCharSetMaps (RTF_Info *);
+
+
+/*
+ RTF ANSI character set (\ansi) general map
+ These are taken from the ISO-Latin-1 (ISO-8859-1) encodings, with
+ a few additions
+
+ Field 1 is the standard character name which the character value in
+ field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+ use the value in field 2.)
+
+ The character value may be given either as a single character (which will be
+ converted to the ASCII value of the character), or in numeric format, either
+ in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+ characters.*/
+
+int ansi_gen[] =
+{
+  rtfSC_formula 	 ,0x06,
+  rtfSC_nobrkhyphen	 ,0x1e,
+  rtfSC_opthyphen	 ,0x1f,
+  rtfSC_space		 ,' ',
+  rtfSC_exclam  	 ,'!',
+  rtfSC_quotedbl	 ,'"',
+  rtfSC_numbersign	 ,'#',
+  rtfSC_dollar  	 ,'$',
+  rtfSC_percent 	 ,'%',
+  rtfSC_ampersand	 ,'&',
+  rtfSC_quoteright	 ,'\\',
+  rtfSC_parenleft	 ,'(',
+  rtfSC_parenright	 ,')',
+  rtfSC_asterisk	 ,'*',
+  rtfSC_plus		 ,'+',
+  rtfSC_comma		 ,',',
+  rtfSC_hyphen  	 ,'-',
+  rtfSC_period  	 ,'.',
+  rtfSC_slash		 ,'/',
+  rtfSC_zero		 ,'0',
+  rtfSC_one		 ,'1',
+  rtfSC_two		 ,'2',
+  rtfSC_three		 ,'3',
+  rtfSC_four		 ,'4',
+  rtfSC_five		 ,'5',
+  rtfSC_six		 ,'6',
+  rtfSC_seven		 ,'7',
+  rtfSC_eight		 ,'8',
+  rtfSC_nine		 ,'9',
+  rtfSC_colon		 ,':',
+  rtfSC_semicolon	 ,';',
+  rtfSC_less		 ,'<',
+  rtfSC_equal		 ,'=',
+  rtfSC_greater 	 ,'>',
+  rtfSC_question	 ,'?',
+  rtfSC_at		 ,'@',
+  rtfSC_A		 ,'A',
+  rtfSC_B		 ,'B',
+  rtfSC_C		 ,'C',
+  rtfSC_D		 ,'D',
+  rtfSC_E		 ,'E',
+  rtfSC_F		 ,'F',
+  rtfSC_G		 ,'G',
+  rtfSC_H		 ,'H',
+  rtfSC_I		 ,'I',
+  rtfSC_J		 ,'J',
+  rtfSC_K		 ,'K',
+  rtfSC_L		 ,'L',
+  rtfSC_M		 ,'M',
+  rtfSC_N		 ,'N',
+  rtfSC_O		 ,'O',
+  rtfSC_P		 ,'P',
+  rtfSC_Q		 ,'Q',
+  rtfSC_R		 ,'R',
+  rtfSC_S		 ,'S',
+  rtfSC_T		 ,'T',
+  rtfSC_U		 ,'U',
+  rtfSC_V		 ,'V',
+  rtfSC_W		 ,'W',
+  rtfSC_X		 ,'X',
+  rtfSC_Y		 ,'Y',
+  rtfSC_Z		 ,'Z',
+  rtfSC_bracketleft	 ,'[',
+  rtfSC_backslash	 ,'\\',
+  rtfSC_bracketright	 ,']',
+  rtfSC_asciicircum	 ,'^',
+  rtfSC_underscore	 ,'_',
+  rtfSC_quoteleft	 ,'`',
+  rtfSC_a		 ,'a',
+  rtfSC_b		 ,'b',
+  rtfSC_c		 ,'c',
+  rtfSC_d		 ,'d',
+  rtfSC_e		 ,'e',
+  rtfSC_f		 ,'f',
+  rtfSC_g		 ,'g',
+  rtfSC_h		 ,'h',
+  rtfSC_i		 ,'i',
+  rtfSC_j		 ,'j',
+  rtfSC_k		 ,'k',
+  rtfSC_l		 ,'l',
+  rtfSC_m		 ,'m',
+  rtfSC_n		 ,'n',
+  rtfSC_o		 ,'o',
+  rtfSC_p		 ,'p',
+  rtfSC_q		 ,'q',
+  rtfSC_r		 ,'r',
+  rtfSC_s		 ,'s',
+  rtfSC_t		 ,'t',
+  rtfSC_u		 ,'u',
+  rtfSC_v		 ,'v',
+  rtfSC_w		 ,'w',
+  rtfSC_x		 ,'x',
+  rtfSC_y		 ,'y',
+  rtfSC_z		 ,'z',
+  rtfSC_braceleft	 ,'{',
+  rtfSC_bar		 ,'|',
+  rtfSC_braceright	 ,'}',
+  rtfSC_asciitilde	 ,'~',
+  rtfSC_nobrkspace	 ,0xa0,
+  rtfSC_exclamdown	 ,0xa1,
+  rtfSC_cent		 ,0xa2,
+  rtfSC_sterling	 ,0xa3,
+  rtfSC_currency	 ,0xa4,
+  rtfSC_yen		 ,0xa5,
+  rtfSC_brokenbar	 ,0xa6,
+  rtfSC_section 	 ,0xa7,
+  rtfSC_dieresis	 ,0xa8,
+  rtfSC_copyright	 ,0xa9,
+  rtfSC_ordfeminine	 ,0xaa,
+  rtfSC_guillemotleft	 ,0xab,
+  rtfSC_logicalnot	 ,0xac,
+  rtfSC_opthyphen	 ,0xad,
+  rtfSC_registered	 ,0xae,
+  rtfSC_macron  	 ,0xaf,
+  rtfSC_degree  	 ,0xb0,
+  rtfSC_plusminus	 ,0xb1,
+  rtfSC_twosuperior	 ,0xb2,
+  rtfSC_threesuperior	 ,0xb3,
+  rtfSC_acute		 ,0xb4,
+  rtfSC_mu		 ,0xb5,
+  rtfSC_paragraph	 ,0xb6,
+  rtfSC_periodcentered   ,0xb7,
+  rtfSC_cedilla 	 ,0xb8,
+  rtfSC_onesuperior	 ,0xb9,
+  rtfSC_ordmasculine	 ,0xba,
+  rtfSC_guillemotright   ,0xbb,
+  rtfSC_onequarter	 ,0xbc,
+  rtfSC_onehalf 	 ,0xbd,
+  rtfSC_threequarters	 ,0xbe,
+  rtfSC_questiondown	 ,0xbf,
+  rtfSC_Agrave  	 ,0xc0,
+  rtfSC_Aacute  	 ,0xc1,
+  rtfSC_Acircumflex	 ,0xc2,
+  rtfSC_Atilde  	 ,0xc3,
+  rtfSC_Adieresis	 ,0xc4,
+  rtfSC_Aring		 ,0xc5,
+  rtfSC_AE		 ,0xc6,
+  rtfSC_Ccedilla	 ,0xc7,
+  rtfSC_Egrave  	 ,0xc8,
+  rtfSC_Eacute  	 ,0xc9,
+  rtfSC_Ecircumflex	 ,0xca,
+  rtfSC_Edieresis	 ,0xcb,
+  rtfSC_Igrave  	 ,0xcc,
+  rtfSC_Iacute  	 ,0xcd,
+  rtfSC_Icircumflex	 ,0xce,
+  rtfSC_Idieresis	 ,0xcf,
+  rtfSC_Eth		 ,0xd0,
+  rtfSC_Ntilde  	 ,0xd1,
+  rtfSC_Ograve  	 ,0xd2,
+  rtfSC_Oacute  	 ,0xd3,
+  rtfSC_Ocircumflex	 ,0xd4,
+  rtfSC_Otilde  	 ,0xd5,
+  rtfSC_Odieresis	 ,0xd6,
+  rtfSC_multiply	 ,0xd7,
+  rtfSC_Oslash  	 ,0xd8,
+  rtfSC_Ugrave  	 ,0xd9,
+  rtfSC_Uacute  	 ,0xda,
+  rtfSC_Ucircumflex	 ,0xdb,
+  rtfSC_Udieresis	 ,0xdc,
+  rtfSC_Yacute  	 ,0xdd,
+  rtfSC_Thorn		 ,0xde,
+  rtfSC_germandbls	 ,0xdf,
+  rtfSC_agrave  	 ,0xe0,
+  rtfSC_aacute  	 ,0xe1,
+  rtfSC_acircumflex	 ,0xe2,
+  rtfSC_atilde  	 ,0xe3,
+  rtfSC_adieresis	 ,0xe4,
+  rtfSC_aring		 ,0xe5,
+  rtfSC_ae		 ,0xe6,
+  rtfSC_ccedilla	 ,0xe7,
+  rtfSC_egrave  	 ,0xe8,
+  rtfSC_eacute  	 ,0xe9,
+  rtfSC_ecircumflex	 ,0xea,
+  rtfSC_edieresis	 ,0xeb,
+  rtfSC_igrave  	 ,0xec,
+  rtfSC_iacute  	 ,0xed,
+  rtfSC_icircumflex	 ,0xee,
+  rtfSC_idieresis	 ,0xef,
+  rtfSC_eth		 ,0xf0,
+  rtfSC_ntilde  	 ,0xf1,
+  rtfSC_ograve  	 ,0xf2,
+  rtfSC_oacute  	 ,0xf3,
+  rtfSC_ocircumflex	 ,0xf4,
+  rtfSC_otilde  	 ,0xf5,
+  rtfSC_odieresis	 ,0xf6,
+  rtfSC_divide  	 ,0xf7,
+  rtfSC_oslash  	 ,0xf8,
+  rtfSC_ugrave  	 ,0xf9,
+  rtfSC_uacute  	 ,0xfa,
+  rtfSC_ucircumflex	 ,0xfb,
+  rtfSC_udieresis	 ,0xfc,
+  rtfSC_yacute  	 ,0xfd,
+  rtfSC_thorn		 ,0xfe,
+  rtfSC_ydieresis	 ,0xff
+};
+
+/*
+ * RTF ANSI character set (\ansi) Symbol font map
+ *
+ * Field 1 is the standard character name which the character value in
+ * field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+ * use the value in field 2.)
+ *
+ * The character value may be given either as a single character (which will be
+ * converted to the ASCII value of the character), or in numeric format, either
+ * in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+ * characters.
+ *
+ */
+
+int ansi_sym[] =
+{
+  rtfSC_formula        ,0x06,
+  rtfSC_nobrkhyphen    ,0x1e,
+  rtfSC_opthyphen      ,0x1f,
+  rtfSC_space	       ,' ',
+  rtfSC_exclam         ,'!',
+  rtfSC_universal      ,'"',
+  rtfSC_mathnumbersign ,'#',
+  rtfSC_existential    ,'$',
+  rtfSC_percent        ,'%',
+  rtfSC_ampersand      ,'&',
+  rtfSC_suchthat       ,'\\',
+  rtfSC_parenleft      ,'(',
+  rtfSC_parenright     ,')',
+  rtfSC_mathasterisk   ,'*',
+  rtfSC_mathplus       ,'+',
+  rtfSC_comma	       ,',',
+  rtfSC_mathminus      ,'-',
+  rtfSC_period         ,'.',
+  rtfSC_slash	       ,'/',
+  rtfSC_zero	       ,'0',
+  rtfSC_one	       ,'1',
+  rtfSC_two	       ,'2',
+  rtfSC_three	       ,'3',
+  rtfSC_four	       ,'4',
+  rtfSC_five	       ,'5',
+  rtfSC_six	       ,'6',
+  rtfSC_seven	       ,'7',
+  rtfSC_eight	       ,'8',
+  rtfSC_nine	       ,'9',
+  rtfSC_colon	       ,':',
+  rtfSC_semicolon      ,';',
+  rtfSC_less	       ,'<',
+  rtfSC_mathequal      ,'=',
+  rtfSC_greater        ,'>',
+  rtfSC_question       ,'?',
+  rtfSC_congruent      ,'@',
+  rtfSC_Alpha	       ,'A',
+  rtfSC_Beta	       ,'B',
+  rtfSC_Chi	       ,'C',
+  rtfSC_Delta	       ,'D',
+  rtfSC_Epsilon        ,'E',
+  rtfSC_Phi	       ,'F',
+  rtfSC_Gamma	       ,'G',
+  rtfSC_Eta	       ,'H',
+  rtfSC_Iota	       ,'I',
+  rtfSC_Kappa	       ,'K',
+  rtfSC_Lambda         ,'L',
+  rtfSC_Mu	       ,'M',
+  rtfSC_Nu	       ,'N',
+  rtfSC_Omicron        ,'O',
+  rtfSC_Pi	       ,'P',
+  rtfSC_Theta	       ,'Q',
+  rtfSC_Rho	       ,'R',
+  rtfSC_Sigma	       ,'S',
+  rtfSC_Tau	       ,'T',
+  rtfSC_Upsilon        ,'U',
+  rtfSC_varsigma       ,'V',
+  rtfSC_Omega	       ,'W',
+  rtfSC_Xi	       ,'X',
+  rtfSC_Psi	       ,'Y',
+  rtfSC_Zeta	       ,'Z',
+  rtfSC_bracketleft    ,'[',
+  rtfSC_backslash      ,'\\',
+  rtfSC_bracketright   ,']',
+  rtfSC_asciicircum    ,'^',
+  rtfSC_underscore     ,'_',
+  rtfSC_quoteleft      ,'`',
+  rtfSC_alpha	       ,'a',
+  rtfSC_beta	       ,'b',
+  rtfSC_chi	       ,'c',
+  rtfSC_delta	       ,'d',
+  rtfSC_epsilon        ,'e',
+  rtfSC_phi	       ,'f',
+  rtfSC_gamma	       ,'g',
+  rtfSC_eta	       ,'h',
+  rtfSC_iota	       ,'i',
+  rtfSC_kappa	       ,'k',
+  rtfSC_lambda         ,'l',
+  rtfSC_mu	       ,'m',
+  rtfSC_nu	       ,'n',
+  rtfSC_omicron        ,'o',
+  rtfSC_pi	       ,'p',
+  rtfSC_theta	       ,'q',
+  rtfSC_rho	       ,'r',
+  rtfSC_sigma	       ,'s',
+  rtfSC_tau	       ,'t',
+  rtfSC_upsilon        ,'u',
+  rtfSC_omega	       ,'w',
+  rtfSC_xi	       ,'x',
+  rtfSC_psi	       ,'y',
+  rtfSC_zeta	       ,'z',
+  rtfSC_braceleft      ,'{',
+  rtfSC_bar	       ,'|',
+  rtfSC_braceright     ,'}',
+  rtfSC_mathtilde      ,'~'
+};
+
+/*
+ *  Output sequence map for rtf2text
+ *
+ *  Field 1 is the standard character name.  Field 2 is the output sequence
+ *  to produce for that character.
+ *
+ *  The output sequence is simply a string of characters.  If it contains
+ *  whitespace, it may be quoted.  If it contains quotes, it may be quoted
+ *  with a different quote character.
+ *
+ *  characters in ASCII range (32-127
+ */
+
+const char *text_map[] = {
+  "space"	      ," ",
+  "exclam"	      ,"!",
+  "quotedbl"	      ,"\"",
+  "numbersign"        ,"#",
+  "dollar"	      ,"$",
+  "percent"	      ,"%",
+  "ampersand"	      ,"&",
+  "quoteright"        ,"'",
+  "parenleft"	      ,"(",
+  "parenright"        ,")",
+  "asterisk"	      ,"*",
+  "plus"	      ,"+",
+  "comma"	      ,",",
+  "hyphen"	      ,"-",
+  "period"	      ,".",
+  "slash"	      ,"/",
+  "zero"	      ,"0",
+  "one" 	      ,"1",
+  "two" 	      ,"2",
+  "three"	      ,"3",
+  "four"	      ,"4",
+  "five"	      ,"5",
+  "six" 	      ,"6",
+  "seven"	      ,"7",
+  "eight"	      ,"8",
+  "nine"	      ,"9",
+  "colon"	      ,":",
+  "semicolon"	      ,";",
+  "less"	      ,"<",
+  "equal"	      ,"=",
+  "greater"	      ,">",
+  "question"	      ,"?",
+  "at"  	      ,"@",
+  "A"		      ,"A",
+  "B"		      ,"B",
+  "C"		      ,"C",
+  "D"		      ,"D",
+  "E"		      ,"E",
+  "F"		      ,"F",
+  "G"		      ,"G",
+  "H"		      ,"H",
+  "I"		      ,"I",
+  "J"		      ,"J",
+  "K"		      ,"K",
+  "L"		      ,"L",
+  "M"		      ,"M",
+  "N"		      ,"N",
+  "O"		      ,"O",
+  "P"		      ,"P",
+  "Q"		      ,"Q",
+  "R"		      ,"R",
+  "S"		      ,"S",
+  "T"		      ,"T",
+  "U"		      ,"U",
+  "V"		      ,"V",
+  "W"		      ,"W",
+  "X"		      ,"X",
+  "Y"		      ,"Y",
+  "Z"		      ,"Z",
+  "bracketleft"       ,"[",
+  "backslash"	      ,"\\",
+  "bracketright"      ,"]",
+  "asciicircum"       ,"^",
+  "underscore"        ,"_",
+  "quoteleft"	      ,"`",
+  "a"		      ,"a",
+  "b"		      ,"b",
+  "c"		      ,"c",
+  "d"		      ,"d",
+  "e"		      ,"e",
+  "f"		      ,"f",
+  "g"		      ,"g",
+  "h"		      ,"h",
+  "i"		      ,"i",
+  "j"		      ,"j",
+  "k"		      ,"k",
+  "l"		      ,"l",
+  "m"		      ,"m",
+  "n"		      ,"n",
+  "o"		      ,"o",
+  "p"		      ,"p",
+  "q"		      ,"q",
+  "r"		      ,"r",
+  "s"		      ,"s",
+  "t"		      ,"t",
+  "u"		      ,"u",
+  "v"		      ,"v",
+  "w"		      ,"w",
+  "x"		      ,"x",
+  "y"		      ,"y",
+  "z"		      ,"z",
+  "braceleft"	      ,"{",
+  "bar" 	      ,"|",
+  "braceright"        ,"}",
+  "asciitilde"        ,"~",
+  "AE"  	      ,"AE",
+  "OE"  	      ,"OE",
+  "acute"	      ,"'",
+  "ae"  	      ,"ae",
+  "angleleft"	      ,"<",
+  "angleright"        ,">",
+  "arrowboth"	      ,"<->",
+  "arrowdblboth"      ,"<=>",
+  "arrowdblleft"      ,"<=",
+  "arrowdblright"     ,"=>",
+  "arrowleft"	      ,"<-",
+  "arrowright"        ,"->",
+  "bullet"	      ,"o",
+  "cent"	      ,"cent",
+  "circumflex"        ,"^",
+  "copyright"	      ,"(c)",
+  "copyrightsans"     ,"(c)",
+  "degree"	      ,"deg.",
+  "divide"	      ,"/",
+  "dotlessi"	      ,"i",
+  "ellipsis"	      ,"...",
+  "emdash"	      ,"--",
+  "endash"	      ,"-",
+  "fi"  	      ,"fi",
+  "fl"  	      ,"fl",
+  "fraction"	      ,"/",
+  "germandbls"        ,"ss",
+  "grave"	      ,"`",
+  "greaterequal"      ,">=",
+  "guillemotleft"     ,"<<",
+  "guillemotright"    ,">>",
+  "guilsinglleft"     ,"<",
+  "guilsinglright"    ,">",
+  "lessequal"	      ,"<=",
+  "logicalnot"        ,"~",
+  "mathasterisk"      ,"*",
+  "mathequal"	      ,"=",
+  "mathminus"	      ,"-",
+  "mathnumbersign"    ,"#",
+  "mathplus"	      ,"+",
+  "mathtilde"	      ,"~",
+  "minus"	      ,"-",
+  "mu"  	      ,"u",
+  "multiply"	      ,"x",
+  "nobrkhyphen"       ,"-",
+  "nobrkspace"        ," ",
+  "notequal"	      ,"!=",
+  "oe"  	      ,"oe",
+  "onehalf"	      ,"1/2",
+  "onequarter"        ,"1/4",
+  "periodcentered"    ,".",
+  "plusminus"	      ,"+/-",
+  "quotedblbase"      ,",,",
+  "quotedblleft"      ,"\"",
+  "quotedblright"     ,"\"",
+  "quotesinglbase"    ,",",
+  "registered"        ,"reg.",
+  "registersans"      ,"reg.",
+  "threequarters"     ,"3/4",
+  "tilde"	      ,"~",
+  "trademark"	      ,"(TM)",
+  "trademarksans"     ,"(TM)"
+};
+
+/*
+ * This array is used to map standard character names onto their numeric codes.
+ * The position of the name within the array is the code.
+ * stdcharnames.h is generated in the ../h directory.
+ */
+
+const char *stdCharName[] =
+{
+	"nothing",
+	"space",
+	"exclam",
+	"quotedbl",
+	"numbersign",
+	"dollar",
+	"percent",
+	"ampersand",
+	"quoteright",
+	"parenleft",
+	"parenright",
+	"asterisk",
+	"plus",
+	"comma",
+	"hyphen",
+	"period",
+	"slash",
+	"zero",
+	"one",
+	"two",
+	"three",
+	"four",
+	"five",
+	"six",
+	"seven",
+	"eight",
+	"nine",
+	"colon",
+	"semicolon",
+	"less",
+	"equal",
+	"greater",
+	"question",
+	"at",
+	"A",
+	"B",
+	"C",
+	"D",
+	"E",
+	"F",
+	"G",
+	"H",
+	"I",
+	"J",
+	"K",
+	"L",
+	"M",
+	"N",
+	"O",
+	"P",
+	"Q",
+	"R",
+	"S",
+	"T",
+	"U",
+	"V",
+	"W",
+	"X",
+	"Y",
+	"Z",
+	"bracketleft",
+	"backslash",
+	"bracketright",
+	"asciicircum",
+	"underscore",
+	"quoteleft",
+	"a",
+	"b",
+	"c",
+	"d",
+	"e",
+	"f",
+	"g",
+	"h",
+	"i",
+	"j",
+	"k",
+	"l",
+	"m",
+	"n",
+	"o",
+	"p",
+	"q",
+	"r",
+	"s",
+	"t",
+	"u",
+	"v",
+	"w",
+	"x",
+	"y",
+	"z",
+	"braceleft",
+	"bar",
+	"braceright",
+	"asciitilde",
+	"exclamdown",
+	"cent",
+	"sterling",
+	"fraction",
+	"yen",
+	"florin",
+	"section",
+	"currency",
+	"quotedblleft",
+	"guillemotleft",
+	"guilsinglleft",
+	"guilsinglright",
+	"fi",
+	"fl",
+	"endash",
+	"dagger",
+	"daggerdbl",
+	"periodcentered",
+	"paragraph",
+	"bullet",
+	"quotesinglbase",
+	"quotedblbase",
+	"quotedblright",
+	"guillemotright",
+	"ellipsis",
+	"perthousand",
+	"questiondown",
+	"grave",
+	"acute",
+	"circumflex",
+	"tilde",
+	"macron",
+	"breve",
+	"dotaccent",
+	"dieresis",
+	"ring",
+	"cedilla",
+	"hungarumlaut",
+	"ogonek",
+	"caron",
+	"emdash",
+	"AE",
+	"ordfeminine",
+	"Lslash",
+	"Oslash",
+	"OE",
+	"ordmasculine",
+	"ae",
+	"dotlessi",
+	"lslash",
+	"oslash",
+	"oe",
+	"germandbls",
+	"Aacute",
+	"Acircumflex",
+	"Adieresis",
+	"Agrave",
+	"Aring",
+	"Atilde",
+	"Ccedilla",
+	"Eacute",
+	"Ecircumflex",
+	"Edieresis",
+	"Egrave",
+	"Eth",
+	"Iacute",
+	"Icircumflex",
+	"Idieresis",
+	"Igrave",
+	"Ntilde",
+	"Oacute",
+	"Ocircumflex",
+	"Odieresis",
+	"Ograve",
+	"Otilde",
+	"Scaron",
+	"Thorn",
+	"Uacute",
+	"Ucircumflex",
+	"Udieresis",
+	"Ugrave",
+	"Yacute",
+	"Ydieresis",
+	"aacute",
+	"acircumflex",
+	"adieresis",
+	"agrave",
+	"aring",
+	"atilde",
+	"brokenbar",
+	"ccedilla",
+	"copyright",
+	"degree",
+	"divide",
+	"eacute",
+	"ecircumflex",
+	"edieresis",
+	"egrave",
+	"eth",
+	"iacute",
+	"icircumflex",
+	"idieresis",
+	"igrave",
+	"logicalnot",
+	"minus",
+	"multiply",
+	"ntilde",
+	"oacute",
+	"ocircumflex",
+	"odieresis",
+	"ograve",
+	"onehalf",
+	"onequarter",
+	"onesuperior",
+	"otilde",
+	"plusminus",
+	"registered",
+	"thorn",
+	"threequarters",
+	"threesuperior",
+	"trademark",
+	"twosuperior",
+	"uacute",
+	"ucircumflex",
+	"udieresis",
+	"ugrave",
+	"yacute",
+	"ydieresis",
+	"Alpha",
+	"Beta",
+	"Chi",
+	"Delta",
+	"Epsilon",
+	"Phi",
+	"Gamma",
+	"Eta",
+	"Iota",
+	"Kappa",
+	"Lambda",
+	"Mu",
+	"Nu",
+	"Omicron",
+	"Pi",
+	"Theta",
+	"Rho",
+	"Sigma",
+	"Tau",
+	"Upsilon",
+	"varUpsilon",
+	"Omega",
+	"Xi",
+	"Psi",
+	"Zeta",
+	"alpha",
+	"beta",
+	"chi",
+	"delta",
+	"epsilon",
+	"phi",
+	"varphi",
+	"gamma",
+	"eta",
+	"iota",
+	"kappa",
+	"lambda",
+	"mu",
+	"nu",
+	"omicron",
+	"pi",
+	"varpi",
+	"theta",
+	"vartheta",
+	"rho",
+	"sigma",
+	"varsigma",
+	"tau",
+	"upsilon",
+	"omega",
+	"xi",
+	"psi",
+	"zeta",
+	"nobrkspace",
+	"nobrkhyphen",
+	"lessequal",
+	"greaterequal",
+	"infinity",
+	"integral",
+	"notequal",
+	"radical",
+	"radicalex",
+	"approxequal",
+	"apple",
+	"partialdiff",
+	"opthyphen",
+	"formula",
+	"lozenge",
+	"universal",
+	"existential",
+	"suchthat",
+	"congruent",
+	"therefore",
+	"perpendicular",
+	"minute",
+	"club",
+	"diamond",
+	"heart",
+	"spade",
+	"arrowboth",
+	"arrowleft",
+	"arrowup",
+	"arrowright",
+	"arrowdown",
+	"second",
+	"proportional",
+	"equivalence",
+	"arrowvertex",
+	"arrowhorizex",
+	"carriagereturn",
+	"aleph",
+	"Ifraktur",
+	"Rfraktur",
+	"weierstrass",
+	"circlemultiply",
+	"circleplus",
+	"emptyset",
+	"intersection",
+	"union",
+	"propersuperset",
+	"reflexsuperset",
+	"notsubset",
+	"propersubset",
+	"reflexsubset",
+	"element",
+	"notelement",
+	"angle",
+	"gradient",
+	"product",
+	"logicaland",
+	"logicalor",
+	"arrowdblboth",
+	"arrowdblleft",
+	"arrowdblup",
+	"arrowdblright",
+	"arrowdbldown",
+	"angleleft",
+	"registersans",
+	"copyrightsans",
+	"trademarksans",
+	"angleright",
+	"mathplus",
+	"mathminus",
+	"mathasterisk",
+	"mathnumbersign",
+	"dotmath",
+	"mathequal",
+	"mathtilde",
+        (char *) NULL
+};
+
+int _RTFGetChar(RTF_Info *info)
+{
+	int ch;
+
+	TRACE("\n");
+
+	if (info->dwInputSize <= info->dwInputUsed)
+	{
+		long count = 0;
+		info->editstream.pfnCallback(info->editstream.dwCookie, 
+			info->InputBuffer, sizeof(info->InputBuffer), &count);
+		if(count == 0)
+			return EOF;
+		info->dwInputSize = count;
+		info->dwInputUsed = 0;
+	}
+	ch = info->InputBuffer[info->dwInputUsed++];
+	if (!ch)
+		 return EOF;
+	return ch;
+}
+
+void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es)
+{
+	TRACE("\n");
+
+	info->editstream.dwCookie = es->dwCookie;
+	info->editstream.dwError  = es->dwError;
+	info->editstream.pfnCallback = es->pfnCallback;
+}
+
+/*
+ * Initialize the reader.  This may be called multiple times,
+ * to read multiple files.  The only thing not reset is the input
+ * stream; that must be done with RTFSetStream().
+ */
+
+void RTFInit(RTF_Info *info)
+{
+	int	i;
+	RTFColor	*cp;
+	RTFFont		*fp;
+	RTFStyle	*sp;
+	RTFStyleElt	*eltList, *ep;
+
+	TRACE("\n");
+
+	if (info->rtfTextBuf == (char *) NULL)	/* initialize the text buffers */
+	{
+		info->rtfTextBuf = RTFAlloc (rtfBufSiz);
+		info->pushedTextBuf = RTFAlloc (rtfBufSiz);
+		if (info->rtfTextBuf == (char *) NULL
+			|| info->pushedTextBuf == (char *) NULL)
+			RTFPanic (info,"Cannot allocate text buffers.");
+		info->rtfTextBuf[0] = info->pushedTextBuf[0] = '\0';
+	}
+
+	RTFFree (info->inputName);
+	RTFFree (info->outputName);
+	info->inputName = info->outputName = (char *) NULL;
+
+	/* initialize lookup table */
+	LookupInit ();
+
+	for (i = 0; i < rtfMaxClass; i++)
+		RTFSetClassCallback (info, i, (RTFFuncPtr) NULL);
+	for (i = 0; i < rtfMaxDestination; i++)
+		RTFSetDestinationCallback (info, i, (RTFFuncPtr) NULL);
+
+	/* install built-in destination readers */
+	RTFSetDestinationCallback (info, rtfFontTbl, ReadFontTbl);
+	RTFSetDestinationCallback (info, rtfColorTbl, ReadColorTbl);
+	RTFSetDestinationCallback (info, rtfStyleSheet, ReadStyleSheet);
+	RTFSetDestinationCallback (info, rtfInfo, ReadInfoGroup);
+	RTFSetDestinationCallback (info, rtfPict, ReadPictGroup);
+	RTFSetDestinationCallback (info, rtfObject, ReadObjGroup);
+
+
+	RTFSetReadHook (info, (RTFFuncPtr) NULL);
+
+	/* dump old lists if necessary */
+
+	while (info->fontList != (RTFFont *) NULL)
+	{
+		fp = info->fontList->rtfNextFont;
+		RTFFree (info->fontList->rtfFName);
+		RTFFree ((char *) info->fontList);
+		info->fontList = fp;
+	}
+	while (info->colorList != (RTFColor *) NULL)
+	{
+		cp = info->colorList->rtfNextColor;
+		RTFFree ((char *) info->colorList);
+		info->colorList = cp;
+	}
+	while (info->styleList != (RTFStyle *) NULL)
+	{
+		sp = info->styleList->rtfNextStyle;
+		eltList = info->styleList->rtfSSEList;
+		while (eltList != (RTFStyleElt *) NULL)
+		{
+			ep = eltList->rtfNextSE;
+			RTFFree (eltList->rtfSEText);
+			RTFFree ((char *) eltList);
+			eltList = ep;
+		}
+		RTFFree (info->styleList->rtfSName);
+		RTFFree ((char *) info->styleList);
+		info->styleList = sp;
+	}
+
+	info->rtfClass = -1;
+	info->pushedClass = -1;
+	info->pushedChar = EOF;
+
+	info->rtfLineNum = 0;
+	info->rtfLinePos = 0;
+	info->prevChar = EOF;
+	info->bumpLine = 0;
+
+	CharSetInit (info);
+	info->csTop = 0;
+}
+
+/*
+ * Set or get the input or output file name.  These are never guaranteed
+ * to be accurate, only insofar as the calling program makes them so.
+ */
+
+void RTFSetInputName(RTF_Info *info, char *name)
+{
+	TRACE("\n");
+
+	if ((info->inputName = RTFStrSave (name)) == (char *) NULL)
+		RTFPanic (info,"RTFSetInputName: out of memory");
+}
+
+
+char *RTFGetInputName(RTF_Info *info)
+{
+	return (info->inputName);
+}
+
+
+void RTFSetOutputName(RTF_Info *info, char *name)
+{
+	TRACE("\n");
+
+	if ((info->outputName = RTFStrSave (name)) == (char *) NULL)
+		RTFPanic (info, "RTFSetOutputName: out of memory");
+}
+
+
+char *RTFGetOutputName(RTF_Info *info)
+{
+	return (info->outputName);
+}
+
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Callback table manipulation routines
+ */
+
+
+/*
+ * Install or return a writer callback for a token class
+ */
+
+void RTFSetClassCallback(RTF_Info *info, int class, RTFFuncPtr callback)
+{
+	if (class >= 0 && class < rtfMaxClass)
+		info->ccb[class] = callback;
+}
+
+
+RTFFuncPtr RTFGetClassCallback(RTF_Info *info, int class)
+{
+	if (class >= 0 && class < rtfMaxClass)
+		return (info->ccb[class]);
+	return ((RTFFuncPtr) NULL);
+}
+
+
+/*
+ * Install or return a writer callback for a destination type
+ */
+
+void RTFSetDestinationCallback(RTF_Info *info, int dest, RTFFuncPtr callback)
+{
+	if (dest >= 0 && dest < rtfMaxDestination)
+		info->dcb[dest] = callback;
+}
+
+
+RTFFuncPtr RTFGetDestinationCallback(RTF_Info *info, int dest)
+{
+	if (dest >= 0 && dest < rtfMaxDestination)
+		return (info->dcb[dest]);
+	return ((RTFFuncPtr) NULL);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Token reading routines
+ */
+
+
+/*
+ * Read the input stream, invoking the writer's callbacks
+ * where appropriate.
+ */
+
+void RTFRead(RTF_Info *info)
+{
+	while (RTFGetToken (info) != rtfEOF)
+		RTFRouteToken (info);
+}
+
+
+/*
+ * Route a token.  If it's a destination for which a reader is
+ * installed, process the destination internally, otherwise
+ * pass the token to the writer's class callback.
+ */
+
+void RTFRouteToken(RTF_Info *info)
+{
+	RTFFuncPtr	p;
+
+	TRACE("\n");
+
+	if (info->rtfClass < 0 || info->rtfClass >= rtfMaxClass)	/* watchdog */
+	{
+		RTFPanic (info,"Unknown class %d: %s (reader malfunction)",
+							info->rtfClass, info->rtfTextBuf);
+	}
+	if (RTFCheckCM (info, rtfControl, rtfDestination))
+	{
+		/* invoke destination-specific callback if there is one */
+		if ((p = RTFGetDestinationCallback (info, info->rtfMinor))
+							!= (RTFFuncPtr) NULL)
+		{
+			(*p) (info);
+			return;
+		}
+	}
+	/* invoke class callback if there is one */
+	if ((p = RTFGetClassCallback (info, info->rtfClass)) != (RTFFuncPtr) NULL)
+		(*p) (info);
+}
+
+
+/*
+ * Skip to the end of the current group.  When this returns,
+ * writers that maintain a state stack may want to call their
+ * state unstacker; global vars will still be set to the group's
+ * closing brace.
+ */
+
+void RTFSkipGroup(RTF_Info *info)
+{
+	int	level = 1;
+
+	TRACE("\n");
+
+	while (RTFGetToken (info) != rtfEOF)
+	{
+		if (info->rtfClass == rtfGroup)
+		{
+			if (info->rtfMajor == rtfBeginGroup)
+				++level;
+			else if (info->rtfMajor == rtfEndGroup)
+			{
+				if (--level < 1)
+					break;	/* end of initial group */
+			}
+		}
+	}
+}
+
+
+/*
+ * Read one token.  Call the read hook if there is one.  The
+ * token class is the return value.  Returns rtfEOF when there
+ * are no more tokens.
+ */
+
+int RTFGetToken(RTF_Info *info)
+{
+	RTFFuncPtr	p;
+
+	TRACE("\n");
+
+	for (;;)
+	{
+		_RTFGetToken (info);
+		if ((p = RTFGetReadHook (info)) != (RTFFuncPtr) NULL)
+			(*p) (info);	/* give read hook a look at token */
+
+		/* Silently discard newlines, carriage returns, nulls.  */
+		if (!(info->rtfClass == rtfText && info->rtfFormat != SF_TEXT
+			&& (info->rtfMajor == '\r' || info->rtfMajor == '\n' || info->rtfMajor == '\0')))
+			break;
+	}
+	return (info->rtfClass);
+}
+
+
+/*
+ * Install or return a token reader hook.
+ */
+
+void RTFSetReadHook(RTF_Info *info, RTFFuncPtr f)
+{
+	info->readHook = f;
+}
+
+
+RTFFuncPtr RTFGetReadHook(RTF_Info *info)
+{
+	return (info->readHook);
+}
+
+
+void RTFUngetToken(RTF_Info *info)
+{
+	TRACE("\n");
+
+	if (info->pushedClass >= 0)	/* there's already an ungotten token */
+		RTFPanic (info,"cannot unget two tokens");
+	if (info->rtfClass < 0)
+		RTFPanic (info,"no token to unget");
+	info->pushedClass = info->rtfClass;
+	info->pushedMajor = info->rtfMajor;
+	info->pushedMinor = info->rtfMinor;
+	info->pushedParam = info->rtfParam;
+	(void) strcpy (info->pushedTextBuf, info->rtfTextBuf);
+}
+
+
+int RTFPeekToken(RTF_Info *info)
+{
+	_RTFGetToken (info);
+	RTFUngetToken (info);
+	return (info->rtfClass);
+}
+
+
+static void _RTFGetToken(RTF_Info *info)
+{
+	RTFFont	*fp;
+
+	TRACE("\n");
+
+        if (info->rtfFormat == SF_TEXT) {
+            info->rtfMajor = GetChar (info);
+            info->rtfMinor = rtfSC_nothing;
+            info->rtfParam = rtfNoParam;
+            info->rtfTextBuf[info->rtfTextLen = 0] = '\0';
+            if (info->rtfMajor == EOF)
+                info->rtfClass = rtfEOF;
+            else
+	        info->rtfClass = rtfText;
+	    return;
+	}
+
+	/* first check for pushed token from RTFUngetToken() */
+
+	if (info->pushedClass >= 0)
+	{
+		info->rtfClass = info->pushedClass;
+		info->rtfMajor = info->pushedMajor;
+		info->rtfMinor = info->pushedMinor;
+		info->rtfParam = info->pushedParam;
+		(void) strcpy (info->rtfTextBuf, info->pushedTextBuf);
+		info->rtfTextLen = strlen (info->rtfTextBuf);
+		info->pushedClass = -1;
+		return;
+	}
+
+	/*
+	 * Beyond this point, no token is ever seen twice, which is
+	 * important, e.g., for making sure no "}" pops the font stack twice.
+	 */
+
+	_RTFGetToken2 (info);
+	if (info->rtfClass == rtfText)	/* map RTF char to standard code */
+		info->rtfMinor = RTFMapChar (info, info->rtfMajor);
+
+	/*
+	 * If auto-charset stuff is activated, see if anything needs doing,
+	 * like reading the charset maps or switching between them.
+	 */
+
+	if (info->autoCharSetFlags == 0)
+		return;
+
+	if ((info->autoCharSetFlags & rtfReadCharSet)
+		&& RTFCheckCM (info, rtfControl, rtfCharSet))
+	{
+		ReadCharSetMaps (info);
+	}
+	else if ((info->autoCharSetFlags & rtfSwitchCharSet)
+		&& RTFCheckCMM (info, rtfControl, rtfCharAttr, rtfFontNum))
+	{
+		if ((fp = RTFGetFont (info, info->rtfParam)) != (RTFFont *) NULL)
+		{
+			if (strncmp (fp->rtfFName, "Symbol", 6) == 0)
+				info->curCharSet = rtfCSSymbol;
+			else
+				info->curCharSet = rtfCSGeneral;
+			RTFSetCharSet (info, info->curCharSet);
+		}
+	}
+	else if ((info->autoCharSetFlags & rtfSwitchCharSet) && info->rtfClass == rtfGroup)
+	{
+		switch (info->rtfMajor)
+		{
+		case rtfBeginGroup:
+			if (info->csTop >= maxCSStack)
+				RTFPanic (info, "_RTFGetToken: stack overflow");
+			info->csStack[info->csTop++] = info->curCharSet;
+			break;
+		case rtfEndGroup:
+			/*
+			 * If stack top is 1 at this point, we are ending the
+			 * group started by the initial {, which ends the
+			 * RTF stream
+			 */
+			if (info->csTop <= 0)
+				RTFPanic (info,"_RTFGetToken: stack underflow");
+			else if (info->csTop == 1)
+				info->rtfClass = rtfEOF;
+			else
+			{
+				info->curCharSet = info->csStack[--info->csTop];
+				RTFSetCharSet (info, info->curCharSet);
+			}
+			break;
+		}
+	}
+}
+
+
+/* this shouldn't be called anywhere but from _RTFGetToken() */
+
+static void _RTFGetToken2(RTF_Info *info)
+{
+	int	sign;
+	int	c;
+
+	TRACE("\n");
+
+	/* initialize token vars */
+
+	info->rtfClass = rtfUnknown;
+	info->rtfParam = rtfNoParam;
+	info->rtfTextBuf[info->rtfTextLen = 0] = '\0';
+
+	/* get first character, which may be a pushback from previous token */
+
+	if (info->pushedChar != EOF)
+	{
+		c = info->pushedChar;
+		info->rtfTextBuf[info->rtfTextLen++] = c;
+		info->rtfTextBuf[info->rtfTextLen] = '\0';
+		info->pushedChar = EOF;
+	}
+	else if ((c = GetChar (info)) == EOF)
+	{
+		info->rtfClass = rtfEOF;
+		return;
+	}
+
+	if (c == '{')
+	{
+		info->rtfClass = rtfGroup;
+		info->rtfMajor = rtfBeginGroup;
+		return;
+	}
+	if (c == '}')
+	{
+		info->rtfClass = rtfGroup;
+		info->rtfMajor = rtfEndGroup;
+		return;
+	}
+	if (c != '\\')
+	{
+		/*
+		 * Two possibilities here:
+		 * 1) ASCII 9, effectively like \tab control symbol
+		 * 2) literal text char
+		 */
+		if (c == '\t')			/* ASCII 9 */
+		{
+			info->rtfClass = rtfControl;
+			info->rtfMajor = rtfSpecialChar;
+			info->rtfMinor = rtfTab;
+		}
+		else
+		{
+			info->rtfClass = rtfText;
+			info->rtfMajor = c;
+		}
+		return;
+	}
+	if ((c = GetChar (info)) == EOF)
+	{
+		/* early eof, whoops (class is rtfUnknown) */
+		return;
+	}
+	if (!isalpha (c))
+	{
+		/*
+		 * Three possibilities here:
+		 * 1) hex encoded text char, e.g., \'d5, \'d3
+		 * 2) special escaped text char, e.g., \{, \}
+		 * 3) control symbol, e.g., \_, \-, \|, \<10>
+		 */
+		if (c == '\'')				/* hex char */
+		{
+		int	c2;
+
+			if ((c = GetChar (info)) != EOF && (c2 = GetChar (info)) != EOF)
+			{
+				/* should do isxdigit check! */
+				info->rtfClass = rtfText;
+				info->rtfMajor = RTFCharToHex (c) * 16
+						+ RTFCharToHex (c2);
+				return;
+			}
+			/* early eof, whoops (class is rtfUnknown) */
+			return;
+		}
+
+		/* escaped char */
+		/*if (index (":{}\\", c) != (char *) NULL)*/ /* escaped char */
+		if (c == ':' || c == '{' || c == '}' || c == '\\')
+		{
+			info->rtfClass = rtfText;
+			info->rtfMajor = c;
+			return;
+		}
+
+		/* control symbol */
+		Lookup (info, info->rtfTextBuf);	/* sets class, major, minor */
+		return;
+	}
+	/* control word */
+	while (isalpha (c))
+	{
+		if ((c = GetChar (info)) == EOF)
+			break;
+	}
+
+	/*
+	 * At this point, the control word is all collected, so the
+	 * major/minor numbers are determined before the parameter
+	 * (if any) is scanned.  There will be one too many characters
+	 * in the buffer, though, so fix up before and restore after
+	 * looking up.
+	 */
+
+	if (c != EOF)
+		info->rtfTextBuf[info->rtfTextLen-1] = '\0';
+	Lookup (info, info->rtfTextBuf);	/* sets class, major, minor */
+	if (c != EOF)
+		info->rtfTextBuf[info->rtfTextLen-1] = c;
+
+	/*
+	 * Should be looking at first digit of parameter if there
+	 * is one, unless it's negative.  In that case, next char
+	 * is '-', so need to gobble next char, and remember sign.
+	 */
+
+	sign = 1;
+	if (c == '-')
+	{
+		sign = -1;
+		c = GetChar (info);
+	}
+	if (c != EOF && isdigit (c))
+	{
+		info->rtfParam = 0;
+		while (isdigit (c))	/* gobble parameter */
+		{
+			info->rtfParam = info->rtfParam * 10 + c - '0';
+			if ((c = GetChar (info)) == EOF)
+				break;
+		}
+		info->rtfParam *= sign;
+	}
+	/*
+	 * If control symbol delimiter was a blank, gobble it.
+	 * Otherwise the character is first char of next token, so
+	 * push it back for next call.  In either case, delete the
+	 * delimiter from the token buffer.
+	 */
+	if (c != EOF)
+	{
+		if (c != ' ')
+			info->pushedChar = c;
+		info->rtfTextBuf[--info->rtfTextLen] = '\0';
+	}
+}
+
+
+/*
+ * Read the next character from the input.  This handles setting the
+ * current line and position-within-line variables.  Those variable are
+ * set correctly whether lines end with CR, LF, or CRLF (the last being
+ * the tricky case).
+ *
+ * bumpLine indicates whether the line number should be incremented on
+ * the *next* input character.
+ */
+
+
+static int GetChar(RTF_Info *info)
+{
+	int	c;
+	int	oldBumpLine;
+
+	TRACE("\n");
+
+	if ((c = _RTFGetChar(info)) != EOF)
+	{
+		info->rtfTextBuf[info->rtfTextLen++] = c;
+		info->rtfTextBuf[info->rtfTextLen] = '\0';
+	}
+	if (info->prevChar == EOF)
+		info->bumpLine = 1;
+	oldBumpLine = info->bumpLine;	/* non-zero if prev char was line ending */
+	info->bumpLine = 0;
+	if (c == '\r')
+		info->bumpLine = 1;
+	else if (c == '\n')
+	{
+		info->bumpLine = 1;
+		if (info->prevChar == '\r')		/* oops, previous \r wasn't */
+			oldBumpLine = 0;	/* really a line ending */
+	}
+	++info->rtfLinePos;
+	if (oldBumpLine)	/* were we supposed to increment the */
+	{			/* line count on this char? */
+		++info->rtfLineNum;
+		info->rtfLinePos = 1;
+	}
+	info->prevChar = c;
+	return (c);
+}
+
+
+/*
+ * Synthesize a token by setting the global variables to the
+ * values supplied.  Typically this is followed with a call
+ * to RTFRouteToken().
+ *
+ * If a param value other than rtfNoParam is passed, it becomes
+ * part of the token text.
+ */
+
+void RTFSetToken(RTF_Info *info, int class, int major, int minor, int param, const char *text)
+{
+	TRACE("\n");
+
+	info->rtfClass = class;
+	info->rtfMajor = major;
+	info->rtfMinor = minor;
+	info->rtfParam = param;
+	if (param == rtfNoParam)
+		(void) strcpy (info->rtfTextBuf, text);
+	else
+		sprintf (info->rtfTextBuf, "%s%d", text, param);
+	info->rtfTextLen = strlen (info->rtfTextBuf);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Routines to handle mapping of RTF character sets
+ * onto standard characters.
+ *
+ * RTFStdCharCode(name)	given char name, produce numeric code
+ * RTFStdCharName(code)	given char code, return name
+ * RTFMapChar(c)	map input (RTF) char code to std code
+ * RTFSetCharSet(id)	select given charset map
+ * RTFGetCharSet()	get current charset map
+ *
+ * See ../h/README for more information about charset names and codes.
+ */
+
+
+/*
+ * Initialize charset stuff.
+ */
+
+static void CharSetInit(RTF_Info *info)
+{
+	TRACE("\n");
+
+	info->autoCharSetFlags = (rtfReadCharSet | rtfSwitchCharSet);
+	RTFFree (info->genCharSetFile);
+	info->genCharSetFile = (char *) NULL;
+	info->haveGenCharSet = 0;
+	RTFFree (info->symCharSetFile);
+	info->symCharSetFile = (char *) NULL;
+	info->haveSymCharSet = 0;
+	info->curCharSet = rtfCSGeneral;
+	info->curCharCode = info->genCharCode;
+}
+
+
+/*
+ * Specify the name of a file to be read when auto-charset-file reading is
+ * done.
+ */
+
+void RTFSetCharSetMap (RTF_Info *info, char *name, int csId)
+{
+	TRACE("\n");
+
+	if ((name = RTFStrSave (name)) == (char *) NULL)	/* make copy */
+		RTFPanic (info,"RTFSetCharSetMap: out of memory");
+	switch (csId)
+	{
+	case rtfCSGeneral:
+		RTFFree (info->genCharSetFile);	/* free any previous value */
+		info->genCharSetFile = name;
+		break;
+	case rtfCSSymbol:
+		RTFFree (info->symCharSetFile);	/* free any previous value */
+		info->symCharSetFile = name;
+		break;
+	}
+}
+
+
+/*
+ * Do auto-charset-file reading.
+ * will always use the ansi charset no mater what the value
+ * of the rtfTextBuf is.
+ *
+ * TODO: add support for other charset in the future.
+ *
+ */
+
+static void ReadCharSetMaps(RTF_Info *info)
+{
+	char	buf[rtfBufSiz];
+
+	TRACE("\n");
+
+	if (info->genCharSetFile != (char *) NULL)
+		(void) strcpy (buf, info->genCharSetFile);
+	else
+		sprintf (buf, "%s-gen", &info->rtfTextBuf[1]);
+	if (RTFReadCharSetMap (info, rtfCSGeneral) == 0)
+		RTFPanic (info,"ReadCharSetMaps: Cannot read charset map %s", buf);
+	if (info->symCharSetFile != (char *) NULL)
+            (void) strcpy (buf, info->symCharSetFile);
+	else
+		sprintf (buf, "%s-sym", &info->rtfTextBuf[1]);
+	if (RTFReadCharSetMap (info, rtfCSSymbol) == 0)
+		RTFPanic (info,"ReadCharSetMaps: Cannot read charset map %s", buf);
+}
+
+
+
+/*
+ * Convert a CharSetMap (character_name, character) into
+ * this form : array[character_ident] = character;
+ */
+
+int RTFReadCharSetMap(RTF_Info *info, int csId)
+{
+        int	*stdCodeArray;
+        unsigned int i;
+
+	TRACE("\n");
+
+	switch (csId)
+	{
+	default:
+		return (0);	/* illegal charset id */
+	case rtfCSGeneral:
+
+		info->haveGenCharSet = 1;
+		stdCodeArray = info->genCharCode;
+		for (i = 0; i < charSetSize; i++)
+		{
+		    stdCodeArray[i] = rtfSC_nothing;
+		}
+
+		for ( i = 0 ; i< sizeof(ansi_gen)/(sizeof(int));i+=2)
+		{
+		    stdCodeArray[ ansi_gen[i+1] ] = ansi_gen[i];
+		}
+		break;
+
+	case rtfCSSymbol:
+
+		info->haveSymCharSet = 1;
+		stdCodeArray = info->symCharCode;
+		for (i = 0; i < charSetSize; i++)
+		{
+		    stdCodeArray[i] = rtfSC_nothing;
+		}
+
+		for ( i = 0 ; i< sizeof(ansi_sym)/(sizeof(int));i+=2)
+		{
+		    stdCodeArray[ ansi_sym[i+1] ] = ansi_sym[i];
+		}
+		break;
+	}
+
+	return (1);
+}
+
+
+/*
+ * Given a standard character name (a string), find its code (a number).
+ * Return -1 if name is unknown.
+ */
+
+int RTFStdCharCode(RTF_Info *info, const char *name)
+{
+	int	i;
+
+	TRACE("\n");
+
+	for (i = 0; i < rtfSC_MaxChar; i++)
+	{
+		if (strcmp (name, stdCharName[i]) == 0)
+			return (i);
+	}
+	return (-1);
+}
+
+
+/*
+ * Given a standard character code (a number), find its name (a string).
+ * Return NULL if code is unknown.
+ */
+
+const char *RTFStdCharName(RTF_Info *info, int code)
+{
+	if (code < 0 || code >= rtfSC_MaxChar)
+		return ((char *) NULL);
+	return (stdCharName[code]);
+}
+
+
+/*
+ * Given an RTF input character code, find standard character code.
+ * The translator should read the appropriate charset maps when it finds a
+ * charset control.  However, the file might not contain one.  In this
+ * case, no map will be available.  When the first attempt is made to
+ * map a character under these circumstances, RTFMapChar() assumes ANSI
+ * and reads the map as necessary.
+ */
+
+int RTFMapChar(RTF_Info *info, int c)
+{
+	TRACE("\n");
+
+	switch (info->curCharSet)
+	{
+	case rtfCSGeneral:
+		if (!info->haveGenCharSet)
+		{
+			if (RTFReadCharSetMap (info, rtfCSGeneral) == 0)
+				RTFPanic (info,"RTFMapChar: cannot read ansi-gen");
+		}
+		break;
+	case rtfCSSymbol:
+		if (!info->haveSymCharSet)
+		{
+			if (RTFReadCharSetMap (info, rtfCSSymbol) == 0)
+				RTFPanic (info,"RTFMapChar: cannot read ansi-sym");
+		}
+		break;
+	}
+	if (c < 0 || c >= charSetSize)
+		return (rtfSC_nothing);
+	return (info->curCharCode[c]);
+}
+
+
+/*
+ * Set the current character set.  If csId is illegal, uses general charset.
+ */
+
+void RTFSetCharSet(RTF_Info *info, int csId)
+{
+	TRACE("\n");
+
+	switch (csId)
+	{
+	default:		/* use general if csId unknown */
+	case rtfCSGeneral:
+		info->curCharCode = info->genCharCode;
+		info->curCharSet = csId;
+		break;
+	case rtfCSSymbol:
+		info->curCharCode = info->symCharCode;
+		info->curCharSet = csId;
+		break;
+	}
+}
+
+
+int RTFGetCharSet(RTF_Info *info)
+{
+	return (info->curCharSet);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Special destination readers.  They gobble the destination so the
+ * writer doesn't have to deal with them.  That's wrong for any
+ * translator that wants to process any of these itself.  In that
+ * case, these readers should be overridden by installing a different
+ * destination callback.
+ *
+ * NOTE: The last token read by each of these reader will be the
+ * destination's terminating '}', which will then be the current token.
+ * That '}' token is passed to RTFRouteToken() - the writer has already
+ * seen the '{' that began the destination group, and may have pushed a
+ * state; it also needs to know at the end of the group that a state
+ * should be popped.
+ *
+ * It's important that rtf.h and the control token lookup table list
+ * as many symbols as possible, because these destination readers
+ * unfortunately make strict assumptions about the input they expect,
+ * and a token of class rtfUnknown will throw them off easily.
+ */
+
+
+/*
+ * Read { \fonttbl ... } destination.  Old font tables don't have
+ * braces around each table entry; try to adjust for that.
+ */
+
+static void ReadFontTbl(RTF_Info *info)
+{
+	RTFFont		*fp = NULL;
+	char		buf[rtfBufSiz], *bp;
+	int		old = -1;
+	const char	*fn = "ReadFontTbl";
+
+	TRACE("\n");
+
+	for (;;)
+	{
+		(void) RTFGetToken (info);
+		if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
+			break;
+		if (old < 0)		/* first entry - determine tbl type */
+		{
+			if (RTFCheckCMM (info, rtfControl, rtfCharAttr, rtfFontNum))
+				old = 1;	/* no brace */
+			else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))
+				old = 0;	/* brace */
+			else			/* can't tell! */
+				RTFPanic (info, "%s: Cannot determine format", fn);
+		}
+		if (old == 0)		/* need to find "{" here */
+		{
+			if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
+				RTFPanic (info, "%s: missing \"{\"", fn);
+			(void) RTFGetToken (info);	/* yes, skip to next token */
+		}
+		if ((fp = New (RTFFont)) == (RTFFont *) NULL)
+			RTFPanic (info, "%s: cannot allocate font entry", fn);
+
+		fp->rtfNextFont = info->fontList;
+		info->fontList = fp;
+
+		fp->rtfFName = (char *) NULL;
+		fp->rtfFAltName = (char *) NULL;
+		fp->rtfFNum = -1;
+		fp->rtfFFamily = 0;
+		fp->rtfFCharSet = 0;
+		fp->rtfFPitch = 0;
+		fp->rtfFType = 0;
+		fp->rtfFCodePage = 0;
+
+		while (info->rtfClass != rtfEOF
+		       && !RTFCheckCM (info, rtfText, ';')
+		       && !RTFCheckCM (info, rtfGroup, rtfEndGroup))
+		{
+			if (info->rtfClass == rtfControl)
+			{
+				switch (info->rtfMajor)
+				{
+				default:
+					/* ignore token but announce it */
+					RTFMsg (info,"%s: unknown token \"%s\"\n",
+							fn, info->rtfTextBuf);
+                                        break;
+				case rtfFontFamily:
+					fp->rtfFFamily = info->rtfMinor;
+					break;
+				case rtfCharAttr:
+					switch (info->rtfMinor)
+					{
+					default:
+						break;	/* ignore unknown? */
+					case rtfFontNum:
+						fp->rtfFNum = info->rtfParam;
+						break;
+					}
+					break;
+				case rtfFontAttr:
+					switch (info->rtfMinor)
+					{
+					default:
+						break;	/* ignore unknown? */
+					case rtfFontCharSet:
+						fp->rtfFCharSet = info->rtfParam;
+						break;
+					case rtfFontPitch:
+						fp->rtfFPitch = info->rtfParam;
+						break;
+					case rtfFontCodePage:
+						fp->rtfFCodePage = info->rtfParam;
+						break;
+					case rtfFTypeNil:
+					case rtfFTypeTrueType:
+						fp->rtfFType = info->rtfParam;
+						break;
+					}
+					break;
+				}
+			}
+			else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))	/* dest */
+			{
+				RTFSkipGroup (info);	/* ignore for now */
+			}
+			else if (info->rtfClass == rtfText)	/* font name */
+			{
+				bp = buf;
+                                while (info->rtfClass == rtfText
+                                        && !RTFCheckCM (info, rtfText, ';'))
+				{
+					*bp++ = info->rtfMajor;
+					(void) RTFGetToken (info);
+				}
+
+				/* FIX: in some cases the <fontinfo> isn't finished with a semi-column */
+				if(RTFCheckCM (info, rtfGroup, rtfEndGroup))
+				{
+				  RTFUngetToken (info);
+				}
+				*bp = '\0';
+				fp->rtfFName = RTFStrSave (buf);
+				if (fp->rtfFName == (char *) NULL)
+					RTFPanic (info, "%s: cannot allocate font name", fn);
+				/* already have next token; don't read one */
+				/* at bottom of loop */
+				continue;
+			}
+			else
+			{
+				/* ignore token but announce it */
+				RTFMsg (info, "%s: unknown token \"%s\"\n",
+							fn,info->rtfTextBuf);
+			}
+			(void) RTFGetToken (info);
+		}
+		if (old == 0)	/* need to see "}" here */
+		{
+			(void) RTFGetToken (info);
+			if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
+				RTFPanic (info, "%s: missing \"}\"", fn);
+		}
+	}
+	if (fp->rtfFNum == -1)
+		RTFPanic (info,"%s: missing font number", fn);
+/*
+ * Could check other pieces of structure here, too, I suppose.
+ */
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+/*
+ * The color table entries have color values of -1 if
+ * the default color should be used for the entry (only
+ * a semi-colon is given in the definition, no color values).
+ * There will be a problem if a partial entry (1 or 2 but
+ * not 3 color values) is given.  The possibility is ignored
+ * here.
+ */
+
+static void ReadColorTbl(RTF_Info *info)
+{
+	RTFColor	*cp;
+	int		cnum = 0;
+	const char	*fn = "ReadColorTbl";
+
+	TRACE("\n");
+
+	for (;;)
+	{
+		(void) RTFGetToken (info);
+		if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
+			break;
+		if ((cp = New (RTFColor)) == (RTFColor *) NULL)
+			RTFPanic (info,"%s: cannot allocate color entry", fn);
+		cp->rtfCNum = cnum++;
+		cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;
+		cp->rtfNextColor = info->colorList;
+		info->colorList = cp;
+		while (RTFCheckCM (info, rtfControl, rtfColorName))
+		{
+			switch (info->rtfMinor)
+			{
+			case rtfRed:	cp->rtfCRed = info->rtfParam; break;
+			case rtfGreen:	cp->rtfCGreen = info->rtfParam; break;
+			case rtfBlue:	cp->rtfCBlue = info->rtfParam; break;
+			}
+			RTFGetToken (info);
+		}
+		if (!RTFCheckCM (info, rtfText, (int) ';'))
+			RTFPanic (info,"%s: malformed entry", fn);
+	}
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+/*
+ * The "Normal" style definition doesn't contain any style number,
+ * all others do.  Normal style is given style rtfNormalStyleNum.
+ */
+
+static void ReadStyleSheet(RTF_Info *info)
+{
+	RTFStyle	*sp;
+	RTFStyleElt	*sep, *sepLast;
+	char		buf[rtfBufSiz], *bp;
+	const char	*fn = "ReadStyleSheet";
+
+	TRACE("\n");
+
+	for (;;)
+	{
+		(void) RTFGetToken (info);
+		if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
+			break;
+		if ((sp = New (RTFStyle)) == (RTFStyle *) NULL)
+			RTFPanic (info,"%s: cannot allocate stylesheet entry", fn);
+		sp->rtfSName = (char *) NULL;
+		sp->rtfSNum = -1;
+		sp->rtfSType = rtfParStyle;
+		sp->rtfSAdditive = 0;
+		sp->rtfSBasedOn = rtfNoStyleNum;
+		sp->rtfSNextPar = -1;
+		sp->rtfSSEList = sepLast = (RTFStyleElt *) NULL;
+		sp->rtfNextStyle = info->styleList;
+		sp->rtfExpanding = 0;
+		info->styleList = sp;
+		if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
+			RTFPanic (info,"%s: missing \"{\"", fn);
+		for (;;)
+		{
+			(void) RTFGetToken (info);
+			if (info->rtfClass == rtfEOF
+				|| RTFCheckCM (info, rtfText, ';'))
+				break;
+			if (info->rtfClass == rtfControl)
+			{
+				if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest))
+					continue;	/* ignore "\*" */
+				if (RTFCheckMM (info, rtfParAttr, rtfStyleNum))
+				{
+					sp->rtfSNum = info->rtfParam;
+					sp->rtfSType = rtfParStyle;
+					continue;
+				}
+				if (RTFCheckMM (info, rtfCharAttr, rtfCharStyleNum))
+				{
+					sp->rtfSNum = info->rtfParam;
+					sp->rtfSType = rtfCharStyle;
+					continue;
+				}
+				if (RTFCheckMM (info, rtfSectAttr, rtfSectStyleNum))
+				{
+					sp->rtfSNum = info->rtfParam;
+					sp->rtfSType = rtfSectStyle;
+					continue;
+				}
+				if (RTFCheckMM (info, rtfStyleAttr, rtfBasedOn))
+				{
+					sp->rtfSBasedOn = info->rtfParam;
+					continue;
+				}
+				if (RTFCheckMM (info, rtfStyleAttr, rtfAdditive))
+				{
+					sp->rtfSAdditive = 1;
+					continue;
+				}
+				if (RTFCheckMM (info, rtfStyleAttr, rtfNext))
+				{
+					sp->rtfSNextPar = info->rtfParam;
+					continue;
+				}
+				if ((sep = New (RTFStyleElt)) == (RTFStyleElt *) NULL)
+					RTFPanic (info,"%s: cannot allocate style element", fn);
+				sep->rtfSEClass = info->rtfClass;
+				sep->rtfSEMajor = info->rtfMajor;
+				sep->rtfSEMinor = info->rtfMinor;
+				sep->rtfSEParam = info->rtfParam;
+				if ((sep->rtfSEText = RTFStrSave (info->rtfTextBuf))
+								== (char *) NULL)
+					RTFPanic (info,"%s: cannot allocate style element text", fn);
+				if (sepLast == (RTFStyleElt *) NULL)
+					sp->rtfSSEList = sep;	/* first element */
+				else				/* add to end */
+					sepLast->rtfNextSE = sep;
+				sep->rtfNextSE = (RTFStyleElt *) NULL;
+				sepLast = sep;
+			}
+			else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))
+			{
+				/*
+				 * This passes over "{\*\keycode ... }, among
+				 * other things. A temporary (perhaps) hack.
+				 */
+				RTFSkipGroup (info);
+				continue;
+			}
+			else if (info->rtfClass == rtfText)	/* style name */
+			{
+				bp = buf;
+				while (info->rtfClass == rtfText)
+				{
+					if (info->rtfMajor == ';')
+					{
+						/* put back for "for" loop */
+						(void) RTFUngetToken (info);
+						break;
+					}
+					*bp++ = info->rtfMajor;
+					(void) RTFGetToken (info);
+				}
+				*bp = '\0';
+				if ((sp->rtfSName = RTFStrSave (buf)) == (char *) NULL)
+					RTFPanic (info, "%s: cannot allocate style name", fn);
+			}
+			else		/* unrecognized */
+			{
+				/* ignore token but announce it */
+				RTFMsg (info, "%s: unknown token \"%s\"\n",
+							fn, info->rtfTextBuf);
+			}
+		}
+		(void) RTFGetToken (info);
+		if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
+			RTFPanic (info, "%s: missing \"}\"", fn);
+
+		/*
+		 * Check over the style structure.  A name is a must.
+		 * If no style number was specified, check whether it's the
+		 * Normal style (in which case it's given style number
+		 * rtfNormalStyleNum).  Note that some "normal" style names
+		 * just begin with "Normal" and can have other stuff following,
+		 * e.g., "Normal,Times 10 point".  Ugh.
+		 *
+		 * Some German RTF writers use "Standard" instead of "Normal".
+		 */
+		if (sp->rtfSName == (char *) NULL)
+			RTFPanic (info,"%s: missing style name", fn);
+		if (sp->rtfSNum < 0)
+		{
+			if (strncmp (buf, "Normal", 6) != 0
+				&& strncmp (buf, "Standard", 8) != 0)
+				RTFPanic (info,"%s: missing style number", fn);
+			sp->rtfSNum = rtfNormalStyleNum;
+		}
+		if (sp->rtfSNextPar == -1)	/* if \snext not given, */
+			sp->rtfSNextPar = sp->rtfSNum;	/* next is itself */
+	}
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+static void ReadInfoGroup(RTF_Info *info)
+{
+	RTFSkipGroup (info);
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+static void ReadPictGroup(RTF_Info *info)
+{
+	RTFSkipGroup (info);
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+static void ReadObjGroup(RTF_Info *info)
+{
+	RTFSkipGroup (info);
+	RTFRouteToken (info);	/* feed "}" back to router */
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Routines to return pieces of stylesheet, or font or color tables.
+ * References to style 0 are mapped onto the Normal style.
+ */
+
+
+RTFStyle *RTFGetStyle(RTF_Info *info, int num)
+{
+	RTFStyle	*s;
+
+	if (num == -1)
+		return (info->styleList);
+	for (s = info->styleList; s != (RTFStyle *) NULL; s = s->rtfNextStyle)
+	{
+		if (s->rtfSNum == num)
+			break;
+	}
+	return (s);		/* NULL if not found */
+}
+
+
+RTFFont *RTFGetFont(RTF_Info *info, int num)
+{
+	RTFFont	*f;
+
+	if (num == -1)
+		return (info->fontList);
+	for (f = info->fontList; f != (RTFFont *) NULL; f = f->rtfNextFont)
+	{
+		if (f->rtfFNum == num)
+			break;
+	}
+	return (f);		/* NULL if not found */
+}
+
+
+RTFColor *RTFGetColor(RTF_Info *info, int num)
+{
+	RTFColor	*c;
+
+	if (num == -1)
+		return (info->colorList);
+	for (c = info->colorList; c != (RTFColor *) NULL; c = c->rtfNextColor)
+	{
+		if (c->rtfCNum == num)
+			break;
+	}
+	return (c);		/* NULL if not found */
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/*
+ * Expand style n, if there is such a style.
+ */
+
+void RTFExpandStyle(RTF_Info *info, int n)
+{
+	RTFStyle	*s;
+	RTFStyleElt	*se;
+
+	TRACE("\n");
+
+	if (n == -1 || (s = RTFGetStyle (info, n)) == (RTFStyle *) NULL)
+		return;
+	if (s->rtfExpanding != 0)
+		RTFPanic (info,"Style expansion loop, style %d", n);
+	s->rtfExpanding = 1;	/* set expansion flag for loop detection */
+	/*
+	 * Expand "based-on" style (unless it's the same as the current
+	 * style -- Normal style usually gives itself as its own based-on
+	 * style).  Based-on style expansion is done by synthesizing
+	 * the token that the writer needs to see in order to trigger
+	 * another style expansion, and feeding to token back through
+	 * the router so the writer sees it.
+	 */
+	if (n != s->rtfSBasedOn)
+	{
+		RTFSetToken (info, rtfControl, rtfParAttr, rtfStyleNum,
+							s->rtfSBasedOn, "\\s");
+		RTFRouteToken (info);
+	}
+	/*
+	 * Now route the tokens unique to this style.  RTFSetToken()
+	 * isn't used because it would add the param value to the end
+	 * of the token text, which already has it in.
+	 */
+	for (se = s->rtfSSEList; se != (RTFStyleElt *) NULL; se = se->rtfNextSE)
+	{
+		info->rtfClass = se->rtfSEClass;
+		info->rtfMajor = se->rtfSEMajor;
+		info->rtfMinor = se->rtfSEMinor;
+		info->rtfParam = se->rtfSEParam;
+		(void) strcpy (info->rtfTextBuf, se->rtfSEText);
+		info->rtfTextLen = strlen (info->rtfTextBuf);
+		RTFRouteToken (info);
+	}
+	s->rtfExpanding = 0;	/* done - clear expansion flag */
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Control symbol lookup routines
+ */
+
+
+typedef struct RTFKey	RTFKey;
+
+struct RTFKey
+{
+	int        rtfKMajor;	/* major number */
+	int        rtfKMinor;	/* minor number */
+	const char *rtfKStr;	/* symbol name */
+	int        rtfKHash;	/* symbol name hash value */
+};
+
+/*
+ * A minor number of -1 means the token has no minor number
+ * (all valid minor numbers are >= 0).
+ */
+
+static RTFKey	rtfKey[] =
+{
+	/*
+	 * Special characters
+	 */
+
+	{ rtfSpecialChar,	rtfIIntVersion,		"vern",		0 },
+	{ rtfSpecialChar,	rtfICreateTime,		"creatim",	0 },
+	{ rtfSpecialChar,	rtfIRevisionTime,	"revtim",	0 },
+	{ rtfSpecialChar,	rtfIPrintTime,		"printim",	0 },
+	{ rtfSpecialChar,	rtfIBackupTime,		"buptim",	0 },
+	{ rtfSpecialChar,	rtfIEditTime,		"edmins",	0 },
+	{ rtfSpecialChar,	rtfIYear,		"yr",		0 },
+	{ rtfSpecialChar,	rtfIMonth,		"mo",		0 },
+	{ rtfSpecialChar,	rtfIDay,		"dy",		0 },
+	{ rtfSpecialChar,	rtfIHour,		"hr",		0 },
+	{ rtfSpecialChar,	rtfIMinute,		"min",		0 },
+	{ rtfSpecialChar,	rtfISecond,		"sec",		0 },
+	{ rtfSpecialChar,	rtfINPages,		"nofpages",	0 },
+	{ rtfSpecialChar,	rtfINWords,		"nofwords",	0 },
+	{ rtfSpecialChar,	rtfINChars,		"nofchars",	0 },
+	{ rtfSpecialChar,	rtfIIntID,		"id",		0 },
+
+	{ rtfSpecialChar,	rtfCurHeadDate,		"chdate",	0 },
+	{ rtfSpecialChar,	rtfCurHeadDateLong,	"chdpl",	0 },
+	{ rtfSpecialChar,	rtfCurHeadDateAbbrev,	"chdpa",	0 },
+	{ rtfSpecialChar,	rtfCurHeadTime,		"chtime",	0 },
+	{ rtfSpecialChar,	rtfCurHeadPage,		"chpgn",	0 },
+	{ rtfSpecialChar,	rtfSectNum,		"sectnum",	0 },
+	{ rtfSpecialChar,	rtfCurFNote,		"chftn",	0 },
+	{ rtfSpecialChar,	rtfCurAnnotRef,		"chatn",	0 },
+	{ rtfSpecialChar,	rtfFNoteSep,		"chftnsep",	0 },
+	{ rtfSpecialChar,	rtfFNoteCont,		"chftnsepc",	0 },
+	{ rtfSpecialChar,	rtfCell,		"cell",		0 },
+	{ rtfSpecialChar,	rtfRow,			"row",		0 },
+	{ rtfSpecialChar,	rtfPar,			"par",		0 },
+	/* newline and carriage return are synonyms for */
+	/* \par when they are preceded by a \ character */
+	{ rtfSpecialChar,	rtfPar,			"\n",		0 },
+	{ rtfSpecialChar,	rtfPar,			"\r",		0 },
+	{ rtfSpecialChar,	rtfSect,		"sect",		0 },
+	{ rtfSpecialChar,	rtfPage,		"page",		0 },
+	{ rtfSpecialChar,	rtfColumn,		"column",	0 },
+	{ rtfSpecialChar,	rtfLine,		"line",		0 },
+	{ rtfSpecialChar,	rtfSoftPage,		"softpage",	0 },
+	{ rtfSpecialChar,	rtfSoftColumn,		"softcol",	0 },
+	{ rtfSpecialChar,	rtfSoftLine,		"softline",	0 },
+	{ rtfSpecialChar,	rtfSoftLineHt,		"softlheight",	0 },
+	{ rtfSpecialChar,	rtfTab,			"tab",		0 },
+	{ rtfSpecialChar,	rtfEmDash,		"emdash",	0 },
+	{ rtfSpecialChar,	rtfEnDash,		"endash",	0 },
+	{ rtfSpecialChar,	rtfEmSpace,		"emspace",	0 },
+	{ rtfSpecialChar,	rtfEnSpace,		"enspace",	0 },
+	{ rtfSpecialChar,	rtfBullet,		"bullet",	0 },
+	{ rtfSpecialChar,	rtfLQuote,		"lquote",	0 },
+	{ rtfSpecialChar,	rtfRQuote,		"rquote",	0 },
+	{ rtfSpecialChar,	rtfLDblQuote,		"ldblquote",	0 },
+	{ rtfSpecialChar,	rtfRDblQuote,		"rdblquote",	0 },
+	{ rtfSpecialChar,	rtfFormula,		"|",		0 },
+	{ rtfSpecialChar,	rtfNoBrkSpace,		"~",		0 },
+	{ rtfSpecialChar,	rtfNoReqHyphen,		"-",		0 },
+	{ rtfSpecialChar,	rtfNoBrkHyphen,		"_",		0 },
+	{ rtfSpecialChar,	rtfOptDest,		"*",		0 },
+	{ rtfSpecialChar,	rtfLTRMark,		"ltrmark",	0 },
+	{ rtfSpecialChar,	rtfRTLMark,		"rtlmark",	0 },
+	{ rtfSpecialChar,	rtfNoWidthJoiner,	"zwj",		0 },
+	{ rtfSpecialChar,	rtfNoWidthNonJoiner,	"zwnj",		0 },
+	/* is this valid? */
+	{ rtfSpecialChar,	rtfCurHeadPict,		"chpict",	0 },
+
+	/*
+	 * Character formatting attributes
+	 */
+
+	{ rtfCharAttr,	rtfPlain,		"plain",	0 },
+	{ rtfCharAttr,	rtfBold,		"b",		0 },
+	{ rtfCharAttr,	rtfAllCaps,		"caps",		0 },
+	{ rtfCharAttr,	rtfDeleted,		"deleted",	0 },
+	{ rtfCharAttr,	rtfSubScript,		"dn",		0 },
+	{ rtfCharAttr,	rtfSubScrShrink,	"sub",		0 },
+	{ rtfCharAttr,	rtfNoSuperSub,		"nosupersub",	0 },
+	{ rtfCharAttr,	rtfExpand,		"expnd",	0 },
+	{ rtfCharAttr,	rtfExpandTwips,		"expndtw",	0 },
+	{ rtfCharAttr,	rtfKerning,		"kerning",	0 },
+	{ rtfCharAttr,	rtfFontNum,		"f",		0 },
+	{ rtfCharAttr,	rtfFontSize,		"fs",		0 },
+	{ rtfCharAttr,	rtfItalic,		"i",		0 },
+	{ rtfCharAttr,	rtfOutline,		"outl",		0 },
+	{ rtfCharAttr,	rtfRevised,		"revised",	0 },
+	{ rtfCharAttr,	rtfRevAuthor,		"revauth",	0 },
+	{ rtfCharAttr,	rtfRevDTTM,		"revdttm",	0 },
+	{ rtfCharAttr,	rtfSmallCaps,		"scaps",	0 },
+	{ rtfCharAttr,	rtfShadow,		"shad",		0 },
+	{ rtfCharAttr,	rtfStrikeThru,		"strike",	0 },
+	{ rtfCharAttr,	rtfUnderline,		"ul",		0 },
+	{ rtfCharAttr,	rtfDotUnderline,	"uld",		0 },
+	{ rtfCharAttr,	rtfDbUnderline,		"uldb",		0 },
+	{ rtfCharAttr,	rtfNoUnderline,		"ulnone",	0 },
+	{ rtfCharAttr,	rtfWordUnderline,	"ulw",		0 },
+	{ rtfCharAttr,	rtfSuperScript,		"up",		0 },
+	{ rtfCharAttr,	rtfSuperScrShrink,	"super",	0 },
+	{ rtfCharAttr,	rtfInvisible,		"v",		0 },
+	{ rtfCharAttr,	rtfForeColor,		"cf",		0 },
+	{ rtfCharAttr,	rtfBackColor,		"cb",		0 },
+	{ rtfCharAttr,	rtfRTLChar,		"rtlch",	0 },
+	{ rtfCharAttr,	rtfLTRChar,		"ltrch",	0 },
+	{ rtfCharAttr,	rtfCharStyleNum,	"cs",		0 },
+	{ rtfCharAttr,	rtfCharCharSet,		"cchs",		0 },
+	{ rtfCharAttr,	rtfLanguage,		"lang",		0 },
+	/* this has disappeared from spec 1.2 */
+	{ rtfCharAttr,	rtfGray,		"gray",		0 },
+
+	/*
+	 * Paragraph formatting attributes
+	 */
+
+	{ rtfParAttr,	rtfParDef,		"pard",		0 },
+	{ rtfParAttr,	rtfStyleNum,		"s",		0 },
+	{ rtfParAttr,	rtfHyphenate,		"hyphpar",	0 },
+	{ rtfParAttr,	rtfInTable,		"intbl",	0 },
+	{ rtfParAttr,	rtfKeep,		"keep",		0 },
+	{ rtfParAttr,	rtfNoWidowControl,	"nowidctlpar",	0 },
+	{ rtfParAttr,	rtfKeepNext,		"keepn",	0 },
+	{ rtfParAttr,	rtfOutlineLevel,	"level",	0 },
+	{ rtfParAttr,	rtfNoLineNum,		"noline",	0 },
+	{ rtfParAttr,	rtfPBBefore,		"pagebb",	0 },
+	{ rtfParAttr,	rtfSideBySide,		"sbys",		0 },
+	{ rtfParAttr,	rtfQuadLeft,		"ql",		0 },
+	{ rtfParAttr,	rtfQuadRight,		"qr",		0 },
+	{ rtfParAttr,	rtfQuadJust,		"qj",		0 },
+	{ rtfParAttr,	rtfQuadCenter,		"qc",		0 },
+	{ rtfParAttr,	rtfFirstIndent,		"fi",		0 },
+	{ rtfParAttr,	rtfLeftIndent,		"li",		0 },
+	{ rtfParAttr,	rtfRightIndent,		"ri",		0 },
+	{ rtfParAttr,	rtfSpaceBefore,		"sb",		0 },
+	{ rtfParAttr,	rtfSpaceAfter,		"sa",		0 },
+	{ rtfParAttr,	rtfSpaceBetween,	"sl",		0 },
+	{ rtfParAttr,	rtfSpaceMultiply,	"slmult",	0 },
+
+	{ rtfParAttr,	rtfSubDocument,		"subdocument",	0 },
+
+	{ rtfParAttr,	rtfRTLPar,		"rtlpar",	0 },
+	{ rtfParAttr,	rtfLTRPar,		"ltrpar",	0 },
+
+	{ rtfParAttr,	rtfTabPos,		"tx",		0 },
+	/*
+	 * FrameMaker writes \tql (to mean left-justified tab, apparently)
+	 * although it's not in the spec.  It's also redundant, since lj
+	 * tabs are the default.
+	 */
+	{ rtfParAttr,	rtfTabLeft,		"tql",		0 },
+	{ rtfParAttr,	rtfTabRight,		"tqr",		0 },
+	{ rtfParAttr,	rtfTabCenter,		"tqc",		0 },
+	{ rtfParAttr,	rtfTabDecimal,		"tqdec",	0 },
+	{ rtfParAttr,	rtfTabBar,		"tb",		0 },
+	{ rtfParAttr,	rtfLeaderDot,		"tldot",	0 },
+	{ rtfParAttr,	rtfLeaderHyphen,	"tlhyph",	0 },
+	{ rtfParAttr,	rtfLeaderUnder,		"tlul",		0 },
+	{ rtfParAttr,	rtfLeaderThick,		"tlth",		0 },
+	{ rtfParAttr,	rtfLeaderEqual,		"tleq",		0 },
+
+	{ rtfParAttr,	rtfParLevel,		"pnlvl",	0 },
+	{ rtfParAttr,	rtfParBullet,		"pnlvlblt",	0 },
+	{ rtfParAttr,	rtfParSimple,		"pnlvlbody",	0 },
+	{ rtfParAttr,	rtfParNumCont,		"pnlvlcont",	0 },
+	{ rtfParAttr,	rtfParNumOnce,		"pnnumonce",	0 },
+	{ rtfParAttr,	rtfParNumAcross,	"pnacross",	0 },
+	{ rtfParAttr,	rtfParHangIndent,	"pnhang",	0 },
+	{ rtfParAttr,	rtfParNumRestart,	"pnrestart",	0 },
+	{ rtfParAttr,	rtfParNumCardinal,	"pncard",	0 },
+	{ rtfParAttr,	rtfParNumDecimal,	"pndec",	0 },
+	{ rtfParAttr,	rtfParNumULetter,	"pnucltr",	0 },
+	{ rtfParAttr,	rtfParNumURoman,	"pnucrm",	0 },
+	{ rtfParAttr,	rtfParNumLLetter,	"pnlcltr",	0 },
+	{ rtfParAttr,	rtfParNumLRoman,	"pnlcrm",	0 },
+	{ rtfParAttr,	rtfParNumOrdinal,	"pnord",	0 },
+	{ rtfParAttr,	rtfParNumOrdinalText,	"pnordt",	0 },
+	{ rtfParAttr,	rtfParNumBold,		"pnb",		0 },
+	{ rtfParAttr,	rtfParNumItalic,	"pni",		0 },
+	{ rtfParAttr,	rtfParNumAllCaps,	"pncaps",	0 },
+	{ rtfParAttr,	rtfParNumSmallCaps,	"pnscaps",	0 },
+	{ rtfParAttr,	rtfParNumUnder,		"pnul",		0 },
+	{ rtfParAttr,	rtfParNumDotUnder,	"pnuld",	0 },
+	{ rtfParAttr,	rtfParNumDbUnder,	"pnuldb",	0 },
+	{ rtfParAttr,	rtfParNumNoUnder,	"pnulnone",	0 },
+	{ rtfParAttr,	rtfParNumWordUnder,	"pnulw",	0 },
+	{ rtfParAttr,	rtfParNumStrikethru,	"pnstrike",	0 },
+	{ rtfParAttr,	rtfParNumForeColor,	"pncf",		0 },
+	{ rtfParAttr,	rtfParNumFont,		"pnf",		0 },
+	{ rtfParAttr,	rtfParNumFontSize,	"pnfs",		0 },
+	{ rtfParAttr,	rtfParNumIndent,	"pnindent",	0 },
+	{ rtfParAttr,	rtfParNumSpacing,	"pnsp",		0 },
+	{ rtfParAttr,	rtfParNumInclPrev,	"pnprev",	0 },
+	{ rtfParAttr,	rtfParNumCenter,	"pnqc",		0 },
+	{ rtfParAttr,	rtfParNumLeft,		"pnql",		0 },
+	{ rtfParAttr,	rtfParNumRight,		"pnqr",		0 },
+	{ rtfParAttr,	rtfParNumStartAt,	"pnstart",	0 },
+
+	{ rtfParAttr,	rtfBorderTop,		"brdrt",	0 },
+	{ rtfParAttr,	rtfBorderBottom,	"brdrb",	0 },
+	{ rtfParAttr,	rtfBorderLeft,		"brdrl",	0 },
+	{ rtfParAttr,	rtfBorderRight,		"brdrr",	0 },
+	{ rtfParAttr,	rtfBorderBetween,	"brdrbtw",	0 },
+	{ rtfParAttr,	rtfBorderBar,		"brdrbar",	0 },
+	{ rtfParAttr,	rtfBorderBox,		"box",		0 },
+	{ rtfParAttr,	rtfBorderSingle,	"brdrs",	0 },
+	{ rtfParAttr,	rtfBorderThick,		"brdrth",	0 },
+	{ rtfParAttr,	rtfBorderShadow,	"brdrsh",	0 },
+	{ rtfParAttr,	rtfBorderDouble,	"brdrdb",	0 },
+	{ rtfParAttr,	rtfBorderDot,		"brdrdot",	0 },
+	{ rtfParAttr,	rtfBorderDot,		"brdrdash",	0 },
+	{ rtfParAttr,	rtfBorderHair,		"brdrhair",	0 },
+	{ rtfParAttr,	rtfBorderWidth,		"brdrw",	0 },
+	{ rtfParAttr,	rtfBorderColor,		"brdrcf",	0 },
+	{ rtfParAttr,	rtfBorderSpace,		"brsp",		0 },
+
+	{ rtfParAttr,	rtfShading,		"shading",	0 },
+	{ rtfParAttr,	rtfBgPatH,		"bghoriz",	0 },
+	{ rtfParAttr,	rtfBgPatV,		"bgvert",	0 },
+	{ rtfParAttr,	rtfFwdDiagBgPat,	"bgfdiag",	0 },
+	{ rtfParAttr,	rtfBwdDiagBgPat,	"bgbdiag",	0 },
+	{ rtfParAttr,	rtfHatchBgPat,		"bgcross",	0 },
+	{ rtfParAttr,	rtfDiagHatchBgPat,	"bgdcross",	0 },
+	{ rtfParAttr,	rtfDarkBgPatH,		"bgdkhoriz",	0 },
+	{ rtfParAttr,	rtfDarkBgPatV,		"bgdkvert",	0 },
+	{ rtfParAttr,	rtfFwdDarkBgPat,	"bgdkfdiag",	0 },
+	{ rtfParAttr,	rtfBwdDarkBgPat,	"bgdkbdiag",	0 },
+	{ rtfParAttr,	rtfDarkHatchBgPat,	"bgdkcross",	0 },
+	{ rtfParAttr,	rtfDarkDiagHatchBgPat,	"bgdkdcross",	0 },
+	{ rtfParAttr,	rtfBgPatLineColor,	"cfpat",	0 },
+	{ rtfParAttr,	rtfBgPatColor,		"cbpat",	0 },
+
+	/*
+	 * Section formatting attributes
+	 */
+
+	{ rtfSectAttr,	rtfSectDef,		"sectd",	0 },
+	{ rtfSectAttr,	rtfENoteHere,		"endnhere",	0 },
+	{ rtfSectAttr,	rtfPrtBinFirst,		"binfsxn",	0 },
+	{ rtfSectAttr,	rtfPrtBin,		"binsxn",	0 },
+	{ rtfSectAttr,	rtfSectStyleNum,	"ds",		0 },
+
+	{ rtfSectAttr,	rtfNoBreak,		"sbknone",	0 },
+	{ rtfSectAttr,	rtfColBreak,		"sbkcol",	0 },
+	{ rtfSectAttr,	rtfPageBreak,		"sbkpage",	0 },
+	{ rtfSectAttr,	rtfEvenBreak,		"sbkeven",	0 },
+	{ rtfSectAttr,	rtfOddBreak,		"sbkodd",	0 },
+
+	{ rtfSectAttr,	rtfColumns,		"cols",		0 },
+	{ rtfSectAttr,	rtfColumnSpace,		"colsx",	0 },
+	{ rtfSectAttr,	rtfColumnNumber,	"colno",	0 },
+	{ rtfSectAttr,	rtfColumnSpRight,	"colsr",	0 },
+	{ rtfSectAttr,	rtfColumnWidth,		"colw",		0 },
+	{ rtfSectAttr,	rtfColumnLine,		"linebetcol",	0 },
+
+	{ rtfSectAttr,	rtfLineModulus,		"linemod",	0 },
+	{ rtfSectAttr,	rtfLineDist,		"linex",	0 },
+	{ rtfSectAttr,	rtfLineStarts,		"linestarts",	0 },
+	{ rtfSectAttr,	rtfLineRestart,		"linerestart",	0 },
+	{ rtfSectAttr,	rtfLineRestartPg,	"lineppage",	0 },
+	{ rtfSectAttr,	rtfLineCont,		"linecont",	0 },
+
+	{ rtfSectAttr,	rtfSectPageWid,		"pgwsxn",	0 },
+	{ rtfSectAttr,	rtfSectPageHt,		"pghsxn",	0 },
+	{ rtfSectAttr,	rtfSectMarginLeft,	"marglsxn",	0 },
+	{ rtfSectAttr,	rtfSectMarginRight,	"margrsxn",	0 },
+	{ rtfSectAttr,	rtfSectMarginTop,	"margtsxn",	0 },
+	{ rtfSectAttr,	rtfSectMarginBottom,	"margbsxn",	0 },
+	{ rtfSectAttr,	rtfSectMarginGutter,	"guttersxn",	0 },
+	{ rtfSectAttr,	rtfSectLandscape,	"lndscpsxn",	0 },
+	{ rtfSectAttr,	rtfTitleSpecial,	"titlepg",	0 },
+	{ rtfSectAttr,	rtfHeaderY,		"headery",	0 },
+	{ rtfSectAttr,	rtfFooterY,		"footery",	0 },
+
+	{ rtfSectAttr,	rtfPageStarts,		"pgnstarts",	0 },
+	{ rtfSectAttr,	rtfPageCont,		"pgncont",	0 },
+	{ rtfSectAttr,	rtfPageRestart,		"pgnrestart",	0 },
+	{ rtfSectAttr,	rtfPageNumRight,	"pgnx",		0 },
+	{ rtfSectAttr,	rtfPageNumTop,		"pgny",		0 },
+	{ rtfSectAttr,	rtfPageDecimal,		"pgndec",	0 },
+	{ rtfSectAttr,	rtfPageURoman,		"pgnucrm",	0 },
+	{ rtfSectAttr,	rtfPageLRoman,		"pgnlcrm",	0 },
+	{ rtfSectAttr,	rtfPageULetter,		"pgnucltr",	0 },
+	{ rtfSectAttr,	rtfPageLLetter,		"pgnlcltr",	0 },
+	{ rtfSectAttr,	rtfPageNumHyphSep,	"pgnhnsh",	0 },
+	{ rtfSectAttr,	rtfPageNumSpaceSep,	"pgnhnsp",	0 },
+	{ rtfSectAttr,	rtfPageNumColonSep,	"pgnhnsc",	0 },
+	{ rtfSectAttr,	rtfPageNumEmdashSep,	"pgnhnsm",	0 },
+	{ rtfSectAttr,	rtfPageNumEndashSep,	"pgnhnsn",	0 },
+
+	{ rtfSectAttr,	rtfTopVAlign,		"vertalt",	0 },
+	/* misspelled as "vertal" in specification 1.0 */
+	{ rtfSectAttr,	rtfBottomVAlign,	"vertalb",	0 },
+	{ rtfSectAttr,	rtfCenterVAlign,	"vertalc",	0 },
+	{ rtfSectAttr,	rtfJustVAlign,		"vertalj",	0 },
+
+	{ rtfSectAttr,	rtfRTLSect,		"rtlsect",	0 },
+	{ rtfSectAttr,	rtfLTRSect,		"ltrsect",	0 },
+
+	/* I've seen these in an old spec, but not in real files... */
+	/*rtfSectAttr,	rtfNoBreak,		"nobreak",	0,*/
+	/*rtfSectAttr,	rtfColBreak,		"colbreak",	0,*/
+	/*rtfSectAttr,	rtfPageBreak,		"pagebreak",	0,*/
+	/*rtfSectAttr,	rtfEvenBreak,		"evenbreak",	0,*/
+	/*rtfSectAttr,	rtfOddBreak,		"oddbreak",	0,*/
+
+	/*
+	 * Document formatting attributes
+	 */
+
+	{ rtfDocAttr,	rtfDefTab,		"deftab",	0 },
+	{ rtfDocAttr,	rtfHyphHotZone,		"hyphhotz",	0 },
+	{ rtfDocAttr,	rtfHyphConsecLines,	"hyphconsec",	0 },
+	{ rtfDocAttr,	rtfHyphCaps,		"hyphcaps",	0 },
+	{ rtfDocAttr,	rtfHyphAuto,		"hyphauto",	0 },
+	{ rtfDocAttr,	rtfLineStart,		"linestart",	0 },
+	{ rtfDocAttr,	rtfFracWidth,		"fracwidth",	0 },
+	/* \makeback was given in old version of spec, it's now */
+	/* listed as \makebackup */
+	{ rtfDocAttr,	rtfMakeBackup,		"makeback",	0 },
+	{ rtfDocAttr,	rtfMakeBackup,		"makebackup",	0 },
+	{ rtfDocAttr,	rtfRTFDefault,		"defformat",	0 },
+	{ rtfDocAttr,	rtfPSOverlay,		"psover",	0 },
+	{ rtfDocAttr,	rtfDocTemplate,		"doctemp",	0 },
+	{ rtfDocAttr,	rtfDefLanguage,		"deflang",	0 },
+
+	{ rtfDocAttr,	rtfFENoteType,		"fet",		0 },
+	{ rtfDocAttr,	rtfFNoteEndSect,	"endnotes",	0 },
+	{ rtfDocAttr,	rtfFNoteEndDoc,		"enddoc",	0 },
+	{ rtfDocAttr,	rtfFNoteText,		"ftntj",	0 },
+	{ rtfDocAttr,	rtfFNoteBottom,		"ftnbj",	0 },
+	{ rtfDocAttr,	rtfENoteEndSect,	"aendnotes",	0 },
+	{ rtfDocAttr,	rtfENoteEndDoc,		"aenddoc",	0 },
+	{ rtfDocAttr,	rtfENoteText,		"aftntj",	0 },
+	{ rtfDocAttr,	rtfENoteBottom,		"aftnbj",	0 },
+	{ rtfDocAttr,	rtfFNoteStart,		"ftnstart",	0 },
+	{ rtfDocAttr,	rtfENoteStart,		"aftnstart",	0 },
+	{ rtfDocAttr,	rtfFNoteRestartPage,	"ftnrstpg",	0 },
+	{ rtfDocAttr,	rtfFNoteRestart,	"ftnrestart",	0 },
+	{ rtfDocAttr,	rtfFNoteRestartCont,	"ftnrstcont",	0 },
+	{ rtfDocAttr,	rtfENoteRestart,	"aftnrestart",	0 },
+	{ rtfDocAttr,	rtfENoteRestartCont,	"aftnrstcont",	0 },
+	{ rtfDocAttr,	rtfFNoteNumArabic,	"ftnnar",	0 },
+	{ rtfDocAttr,	rtfFNoteNumLLetter,	"ftnnalc",	0 },
+	{ rtfDocAttr,	rtfFNoteNumULetter,	"ftnnauc",	0 },
+	{ rtfDocAttr,	rtfFNoteNumLRoman,	"ftnnrlc",	0 },
+	{ rtfDocAttr,	rtfFNoteNumURoman,	"ftnnruc",	0 },
+	{ rtfDocAttr,	rtfFNoteNumChicago,	"ftnnchi",	0 },
+	{ rtfDocAttr,	rtfENoteNumArabic,	"aftnnar",	0 },
+	{ rtfDocAttr,	rtfENoteNumLLetter,	"aftnnalc",	0 },
+	{ rtfDocAttr,	rtfENoteNumULetter,	"aftnnauc",	0 },
+	{ rtfDocAttr,	rtfENoteNumLRoman,	"aftnnrlc",	0 },
+	{ rtfDocAttr,	rtfENoteNumURoman,	"aftnnruc",	0 },
+	{ rtfDocAttr,	rtfENoteNumChicago,	"aftnnchi",	0 },
+
+	{ rtfDocAttr,	rtfPaperWidth,		"paperw",	0 },
+	{ rtfDocAttr,	rtfPaperHeight,		"paperh",	0 },
+	{ rtfDocAttr,	rtfPaperSize,		"psz",		0 },
+	{ rtfDocAttr,	rtfLeftMargin,		"margl",	0 },
+	{ rtfDocAttr,	rtfRightMargin,		"margr",	0 },
+	{ rtfDocAttr,	rtfTopMargin,		"margt",	0 },
+	{ rtfDocAttr,	rtfBottomMargin,	"margb",	0 },
+	{ rtfDocAttr,	rtfFacingPage,		"facingp",	0 },
+	{ rtfDocAttr,	rtfGutterWid,		"gutter",	0 },
+	{ rtfDocAttr,	rtfMirrorMargin,	"margmirror",	0 },
+	{ rtfDocAttr,	rtfLandscape,		"landscape",	0 },
+	{ rtfDocAttr,	rtfPageStart,		"pgnstart",	0 },
+	{ rtfDocAttr,	rtfWidowCtrl,		"widowctrl",	0 },
+
+	{ rtfDocAttr,	rtfLinkStyles,		"linkstyles",	0 },
+
+	{ rtfDocAttr,	rtfNoAutoTabIndent,	"notabind",	0 },
+	{ rtfDocAttr,	rtfWrapSpaces,		"wraptrsp",	0 },
+	{ rtfDocAttr,	rtfPrintColorsBlack,	"prcolbl",	0 },
+	{ rtfDocAttr,	rtfNoExtraSpaceRL,	"noextrasprl",	0 },
+	{ rtfDocAttr,	rtfNoColumnBalance,	"nocolbal",	0 },
+	{ rtfDocAttr,	rtfCvtMailMergeQuote,	"cvmme",	0 },
+	{ rtfDocAttr,	rtfSuppressTopSpace,	"sprstsp",	0 },
+	{ rtfDocAttr,	rtfSuppressPreParSpace,	"sprsspbf",	0 },
+	{ rtfDocAttr,	rtfCombineTblBorders,	"otblrul",	0 },
+	{ rtfDocAttr,	rtfTranspMetafiles,	"transmf",	0 },
+	{ rtfDocAttr,	rtfSwapBorders,		"swpbdr",	0 },
+	{ rtfDocAttr,	rtfShowHardBreaks,	"brkfrm",	0 },
+
+	{ rtfDocAttr,	rtfFormProtected,	"formprot",	0 },
+	{ rtfDocAttr,	rtfAllProtected,	"allprot",	0 },
+	{ rtfDocAttr,	rtfFormShading,		"formshade",	0 },
+	{ rtfDocAttr,	rtfFormDisplay,		"formdisp",	0 },
+	{ rtfDocAttr,	rtfPrintData,		"printdata",	0 },
+
+	{ rtfDocAttr,	rtfRevProtected,	"revprot",	0 },
+	{ rtfDocAttr,	rtfRevisions,		"revisions",	0 },
+	{ rtfDocAttr,	rtfRevDisplay,		"revprop",	0 },
+	{ rtfDocAttr,	rtfRevBar,		"revbar",	0 },
+
+	{ rtfDocAttr,	rtfAnnotProtected,	"annotprot",	0 },
+
+	{ rtfDocAttr,	rtfRTLDoc,		"rtldoc",	0 },
+	{ rtfDocAttr,	rtfLTRDoc,		"ltrdoc",	0 },
+
+	/*
+	 * Style attributes
+	 */
+
+	{ rtfStyleAttr,	rtfAdditive,		"additive",	0 },
+	{ rtfStyleAttr,	rtfBasedOn,		"sbasedon",	0 },
+	{ rtfStyleAttr,	rtfNext,		"snext",	0 },
+
+	/*
+	 * Picture attributes
+	 */
+
+	{ rtfPictAttr,	rtfMacQD,		"macpict",	0 },
+	{ rtfPictAttr,	rtfPMMetafile,		"pmmetafile",	0 },
+	{ rtfPictAttr,	rtfWinMetafile,		"wmetafile",	0 },
+	{ rtfPictAttr,	rtfDevIndBitmap,	"dibitmap",	0 },
+	{ rtfPictAttr,	rtfWinBitmap,		"wbitmap",	0 },
+	{ rtfPictAttr,	rtfPixelBits,		"wbmbitspixel",	0 },
+	{ rtfPictAttr,	rtfBitmapPlanes,	"wbmplanes",	0 },
+	{ rtfPictAttr,	rtfBitmapWid,		"wbmwidthbytes", 0 },
+
+	{ rtfPictAttr,	rtfPicWid,		"picw",		0 },
+	{ rtfPictAttr,	rtfPicHt,		"pich",		0 },
+	{ rtfPictAttr,	rtfPicGoalWid,		"picwgoal",	0 },
+	{ rtfPictAttr,	rtfPicGoalHt,		"pichgoal",	0 },
+	/* these two aren't in the spec, but some writers emit them */
+	{ rtfPictAttr,	rtfPicGoalWid,		"picwGoal",	0 },
+	{ rtfPictAttr,	rtfPicGoalHt,		"pichGoal",	0 },
+	{ rtfPictAttr,	rtfPicScaleX,		"picscalex",	0 },
+	{ rtfPictAttr,	rtfPicScaleY,		"picscaley",	0 },
+	{ rtfPictAttr,	rtfPicScaled,		"picscaled",	0 },
+	{ rtfPictAttr,	rtfPicCropTop,		"piccropt",	0 },
+	{ rtfPictAttr,	rtfPicCropBottom,	"piccropb",	0 },
+	{ rtfPictAttr,	rtfPicCropLeft,		"piccropl",	0 },
+	{ rtfPictAttr,	rtfPicCropRight,	"piccropr",	0 },
+
+	{ rtfPictAttr,	rtfPicMFHasBitmap,	"picbmp",	0 },
+	{ rtfPictAttr,	rtfPicMFBitsPerPixel,	"picbpp",	0 },
+
+	{ rtfPictAttr,	rtfPicBinary,		"bin",		0 },
+
+	/*
+	 * NeXT graphic attributes
+	 */
+
+	{ rtfNeXTGrAttr,	rtfNeXTGWidth,		"width",	0 },
+	{ rtfNeXTGrAttr,	rtfNeXTGHeight,		"height",	0 },
+
+	/*
+	 * Destinations
+	 */
+
+	{ rtfDestination,	rtfFontTbl,		"fonttbl",	0 },
+	{ rtfDestination,	rtfFontAltName,		"falt",		0 },
+	{ rtfDestination,	rtfEmbeddedFont,	"fonteb",	0 },
+	{ rtfDestination,	rtfFontFile,		"fontfile",	0 },
+	{ rtfDestination,	rtfFileTbl,		"filetbl",	0 },
+	{ rtfDestination,	rtfFileInfo,		"file",		0 },
+	{ rtfDestination,	rtfColorTbl,		"colortbl",	0 },
+	{ rtfDestination,	rtfStyleSheet,		"stylesheet",	0 },
+	{ rtfDestination,	rtfKeyCode,		"keycode",	0 },
+	{ rtfDestination,	rtfRevisionTbl,		"revtbl",	0 },
+	{ rtfDestination,	rtfInfo,		"info",		0 },
+	{ rtfDestination,	rtfITitle,		"title",	0 },
+	{ rtfDestination,	rtfISubject,		"subject",	0 },
+	{ rtfDestination,	rtfIAuthor,		"author",	0 },
+	{ rtfDestination,	rtfIOperator,		"operator",	0 },
+	{ rtfDestination,	rtfIKeywords,		"keywords",	0 },
+	{ rtfDestination,	rtfIComment,		"comment",	0 },
+	{ rtfDestination,	rtfIVersion,		"version",	0 },
+	{ rtfDestination,	rtfIDoccomm,		"doccomm",	0 },
+	/* \verscomm may not exist -- was seen in earlier spec version */
+	{ rtfDestination,	rtfIVerscomm,		"verscomm",	0 },
+	{ rtfDestination,	rtfNextFile,		"nextfile",	0 },
+	{ rtfDestination,	rtfTemplate,		"template",	0 },
+	{ rtfDestination,	rtfFNSep,		"ftnsep",	0 },
+	{ rtfDestination,	rtfFNContSep,		"ftnsepc",	0 },
+	{ rtfDestination,	rtfFNContNotice,	"ftncn",	0 },
+	{ rtfDestination,	rtfENSep,		"aftnsep",	0 },
+	{ rtfDestination,	rtfENContSep,		"aftnsepc",	0 },
+	{ rtfDestination,	rtfENContNotice,	"aftncn",	0 },
+	{ rtfDestination,	rtfPageNumLevel,	"pgnhn",	0 },
+	{ rtfDestination,	rtfParNumLevelStyle,	"pnseclvl",	0 },
+	{ rtfDestination,	rtfHeader,		"header",	0 },
+	{ rtfDestination,	rtfFooter,		"footer",	0 },
+	{ rtfDestination,	rtfHeaderLeft,		"headerl",	0 },
+	{ rtfDestination,	rtfHeaderRight,		"headerr",	0 },
+	{ rtfDestination,	rtfHeaderFirst,		"headerf",	0 },
+	{ rtfDestination,	rtfFooterLeft,		"footerl",	0 },
+	{ rtfDestination,	rtfFooterRight,		"footerr",	0 },
+	{ rtfDestination,	rtfFooterFirst,		"footerf",	0 },
+	{ rtfDestination,	rtfParNumText,		"pntext",	0 },
+	{ rtfDestination,	rtfParNumbering,	"pn",		0 },
+	{ rtfDestination,	rtfParNumTextAfter,	"pntexta",	0 },
+	{ rtfDestination,	rtfParNumTextBefore,	"pntextb",	0 },
+	{ rtfDestination,	rtfBookmarkStart,	"bkmkstart",	0 },
+	{ rtfDestination,	rtfBookmarkEnd,		"bkmkend",	0 },
+	{ rtfDestination,	rtfPict,		"pict",		0 },
+	{ rtfDestination,	rtfObject,		"object",	0 },
+	{ rtfDestination,	rtfObjClass,		"objclass",	0 },
+	{ rtfDestination,	rtfObjName,		"objname",	0 },
+	{ rtfObjAttr,	rtfObjTime,		"objtime",	0 },
+	{ rtfDestination,	rtfObjData,		"objdata",	0 },
+	{ rtfDestination,	rtfObjAlias,		"objalias",	0 },
+	{ rtfDestination,	rtfObjSection,		"objsect",	0 },
+	/* objitem and objtopic aren't documented in the spec! */
+	{ rtfDestination,	rtfObjItem,		"objitem",	0 },
+	{ rtfDestination,	rtfObjTopic,		"objtopic",	0 },
+	{ rtfDestination,	rtfObjResult,		"result",	0 },
+	{ rtfDestination,	rtfDrawObject,		"do",		0 },
+	{ rtfDestination,	rtfFootnote,		"footnote",	0 },
+	{ rtfDestination,	rtfAnnotRefStart,	"atrfstart",	0 },
+	{ rtfDestination,	rtfAnnotRefEnd,		"atrfend",	0 },
+	{ rtfDestination,	rtfAnnotID,		"atnid",	0 },
+	{ rtfDestination,	rtfAnnotAuthor,		"atnauthor",	0 },
+	{ rtfDestination,	rtfAnnotation,		"annotation",	0 },
+	{ rtfDestination,	rtfAnnotRef,		"atnref",	0 },
+	{ rtfDestination,	rtfAnnotTime,		"atntime",	0 },
+	{ rtfDestination,	rtfAnnotIcon,		"atnicn",	0 },
+	{ rtfDestination,	rtfField,		"field",	0 },
+	{ rtfDestination,	rtfFieldInst,		"fldinst",	0 },
+	{ rtfDestination,	rtfFieldResult,		"fldrslt",	0 },
+	{ rtfDestination,	rtfDataField,		"datafield",	0 },
+	{ rtfDestination,	rtfIndex,		"xe",		0 },
+	{ rtfDestination,	rtfIndexText,		"txe",		0 },
+	{ rtfDestination,	rtfIndexRange,		"rxe",		0 },
+	{ rtfDestination,	rtfTOC,			"tc",		0 },
+	{ rtfDestination,	rtfNeXTGraphic,		"NeXTGraphic",	0 },
+
+	/*
+	 * Font families
+	 */
+
+	{ rtfFontFamily,	rtfFFNil,		"fnil",		0 },
+	{ rtfFontFamily,	rtfFFRoman,		"froman",	0 },
+	{ rtfFontFamily,	rtfFFSwiss,		"fswiss",	0 },
+	{ rtfFontFamily,	rtfFFModern,		"fmodern",	0 },
+	{ rtfFontFamily,	rtfFFScript,		"fscript",	0 },
+	{ rtfFontFamily,	rtfFFDecor,		"fdecor",	0 },
+	{ rtfFontFamily,	rtfFFTech,		"ftech",	0 },
+	{ rtfFontFamily,	rtfFFBidirectional,	"fbidi",	0 },
+
+	/*
+	 * Font attributes
+	 */
+
+	{ rtfFontAttr,	rtfFontCharSet,		"fcharset",	0 },
+	{ rtfFontAttr,	rtfFontPitch,		"fprq",		0 },
+	{ rtfFontAttr,	rtfFontCodePage,	"cpg",		0 },
+	{ rtfFontAttr,	rtfFTypeNil,		"ftnil",	0 },
+	{ rtfFontAttr,	rtfFTypeTrueType,	"fttruetype",	0 },
+
+	/*
+	 * File table attributes
+	 */
+
+	{ rtfFileAttr,	rtfFileNum,		"fid",		0 },
+	{ rtfFileAttr,	rtfFileRelPath,		"frelative",	0 },
+	{ rtfFileAttr,	rtfFileOSNum,		"fosnum",	0 },
+
+	/*
+	 * File sources
+	 */
+
+	{ rtfFileSource,	rtfSrcMacintosh,	"fvalidmac",	0 },
+	{ rtfFileSource,	rtfSrcDOS,		"fvaliddos",	0 },
+	{ rtfFileSource,	rtfSrcNTFS,		"fvalidntfs",	0 },
+	{ rtfFileSource,	rtfSrcHPFS,		"fvalidhpfs",	0 },
+	{ rtfFileSource,	rtfSrcNetwork,		"fnetwork",	0 },
+
+	/*
+	 * Color names
+	 */
+
+	{ rtfColorName,	rtfRed,			"red",		0 },
+	{ rtfColorName,	rtfGreen,		"green",	0 },
+	{ rtfColorName,	rtfBlue,		"blue",		0 },
+
+	/*
+	 * Charset names
+	 */
+
+	{ rtfCharSet,	rtfMacCharSet,		"mac",		0 },
+	{ rtfCharSet,	rtfAnsiCharSet,		"ansi",		0 },
+	{ rtfCharSet,	rtfPcCharSet,		"pc",		0 },
+	{ rtfCharSet,	rtfPcaCharSet,		"pca",		0 },
+
+	/*
+	 * Table attributes
+	 */
+
+	{ rtfTblAttr,	rtfRowDef,		"trowd",	0 },
+	{ rtfTblAttr,	rtfRowGapH,		"trgaph",	0 },
+	{ rtfTblAttr,	rtfCellPos,		"cellx",	0 },
+	{ rtfTblAttr,	rtfMergeRngFirst,	"clmgf",	0 },
+	{ rtfTblAttr,	rtfMergePrevious,	"clmrg",	0 },
+
+	{ rtfTblAttr,	rtfRowLeft,		"trql",		0 },
+	{ rtfTblAttr,	rtfRowRight,		"trqr",		0 },
+	{ rtfTblAttr,	rtfRowCenter,		"trqc",		0 },
+	{ rtfTblAttr,	rtfRowLeftEdge,		"trleft",	0 },
+	{ rtfTblAttr,	rtfRowHt,		"trrh",		0 },
+	{ rtfTblAttr,	rtfRowHeader,		"trhdr",	0 },
+	{ rtfTblAttr,	rtfRowKeep,		"trkeep",	0 },
+
+	{ rtfTblAttr,	rtfRTLRow,		"rtlrow",	0 },
+	{ rtfTblAttr,	rtfLTRRow,		"ltrrow",	0 },
+
+	{ rtfTblAttr,	rtfRowBordTop,		"trbrdrt",	0 },
+	{ rtfTblAttr,	rtfRowBordLeft,		"trbrdrl",	0 },
+	{ rtfTblAttr,	rtfRowBordBottom,	"trbrdrb",	0 },
+	{ rtfTblAttr,	rtfRowBordRight,	"trbrdrr",	0 },
+	{ rtfTblAttr,	rtfRowBordHoriz,	"trbrdrh",	0 },
+	{ rtfTblAttr,	rtfRowBordVert,		"trbrdrv",	0 },
+
+	{ rtfTblAttr,	rtfCellBordBottom,	"clbrdrb",	0 },
+	{ rtfTblAttr,	rtfCellBordTop,		"clbrdrt",	0 },
+	{ rtfTblAttr,	rtfCellBordLeft,	"clbrdrl",	0 },
+	{ rtfTblAttr,	rtfCellBordRight,	"clbrdrr",	0 },
+
+	{ rtfTblAttr,	rtfCellShading,		"clshdng",	0 },
+	{ rtfTblAttr,	rtfCellBgPatH,		"clbghoriz",	0 },
+	{ rtfTblAttr,	rtfCellBgPatV,		"clbgvert",	0 },
+	{ rtfTblAttr,	rtfCellFwdDiagBgPat,	"clbgfdiag",	0 },
+	{ rtfTblAttr,	rtfCellBwdDiagBgPat,	"clbgbdiag",	0 },
+	{ rtfTblAttr,	rtfCellHatchBgPat,	"clbgcross",	0 },
+	{ rtfTblAttr,	rtfCellDiagHatchBgPat,	"clbgdcross",	0 },
+	/*
+	 * The spec lists "clbgdkhor", but the corresponding non-cell
+	 * control is "bgdkhoriz".  At any rate Macintosh Word seems
+	 * to accept both "clbgdkhor" and "clbgdkhoriz".
+	 */
+	{ rtfTblAttr,	rtfCellDarkBgPatH,	"clbgdkhoriz",	0 },
+	{ rtfTblAttr,	rtfCellDarkBgPatH,	"clbgdkhor",	0 },
+	{ rtfTblAttr,	rtfCellDarkBgPatV,	"clbgdkvert",	0 },
+	{ rtfTblAttr,	rtfCellFwdDarkBgPat,	"clbgdkfdiag",	0 },
+	{ rtfTblAttr,	rtfCellBwdDarkBgPat,	"clbgdkbdiag",	0 },
+	{ rtfTblAttr,	rtfCellDarkHatchBgPat,	"clbgdkcross",	0 },
+	{ rtfTblAttr,	rtfCellDarkDiagHatchBgPat, "clbgdkdcross",	0 },
+	{ rtfTblAttr,	rtfCellBgPatLineColor, "clcfpat",	0 },
+	{ rtfTblAttr,	rtfCellBgPatColor,	"clcbpat",	0 },
+
+	/*
+	 * Field attributes
+	 */
+
+	{ rtfFieldAttr,	rtfFieldDirty,		"flddirty",	0 },
+	{ rtfFieldAttr,	rtfFieldEdited,		"fldedit",	0 },
+	{ rtfFieldAttr,	rtfFieldLocked,		"fldlock",	0 },
+	{ rtfFieldAttr,	rtfFieldPrivate,	"fldpriv",	0 },
+	{ rtfFieldAttr,	rtfFieldAlt,		"fldalt",	0 },
+
+	/*
+	 * Positioning attributes
+	 */
+
+	{ rtfPosAttr,	rtfAbsWid,		"absw",		0 },
+	{ rtfPosAttr,	rtfAbsHt,		"absh",		0 },
+
+	{ rtfPosAttr,	rtfRPosMargH,		"phmrg",	0 },
+	{ rtfPosAttr,	rtfRPosPageH,		"phpg",		0 },
+	{ rtfPosAttr,	rtfRPosColH,		"phcol",	0 },
+	{ rtfPosAttr,	rtfPosX,		"posx",		0 },
+	{ rtfPosAttr,	rtfPosNegX,		"posnegx",	0 },
+	{ rtfPosAttr,	rtfPosXCenter,		"posxc",	0 },
+	{ rtfPosAttr,	rtfPosXInside,		"posxi",	0 },
+	{ rtfPosAttr,	rtfPosXOutSide,		"posxo",	0 },
+	{ rtfPosAttr,	rtfPosXRight,		"posxr",	0 },
+	{ rtfPosAttr,	rtfPosXLeft,		"posxl",	0 },
+
+	{ rtfPosAttr,	rtfRPosMargV,		"pvmrg",	0 },
+	{ rtfPosAttr,	rtfRPosPageV,		"pvpg",		0 },
+	{ rtfPosAttr,	rtfRPosParaV,		"pvpara",	0 },
+	{ rtfPosAttr,	rtfPosY,		"posy",		0 },
+	{ rtfPosAttr,	rtfPosNegY,		"posnegy",	0 },
+	{ rtfPosAttr,	rtfPosYInline,		"posyil",	0 },
+	{ rtfPosAttr,	rtfPosYTop,		"posyt",	0 },
+	{ rtfPosAttr,	rtfPosYCenter,		"posyc",	0 },
+	{ rtfPosAttr,	rtfPosYBottom,		"posyb",	0 },
+
+	{ rtfPosAttr,	rtfNoWrap,		"nowrap",	0 },
+	{ rtfPosAttr,	rtfDistFromTextAll,	"dxfrtext",	0 },
+	{ rtfPosAttr,	rtfDistFromTextX,	"dfrmtxtx",	0 },
+	{ rtfPosAttr,	rtfDistFromTextY,	"dfrmtxty",	0 },
+	/* \dyfrtext no longer exists in spec 1.2, apparently */
+	/* replaced by \dfrmtextx and \dfrmtexty. */
+	{ rtfPosAttr,	rtfTextDistY,		"dyfrtext",	0 },
+
+	{ rtfPosAttr,	rtfDropCapLines,	"dropcapli",	0 },
+	{ rtfPosAttr,	rtfDropCapType,		"dropcapt",	0 },
+
+	/*
+	 * Object controls
+	 */
+
+	{ rtfObjAttr,	rtfObjEmb,		"objemb",	0 },
+	{ rtfObjAttr,	rtfObjLink,		"objlink",	0 },
+	{ rtfObjAttr,	rtfObjAutoLink,		"objautlink",	0 },
+	{ rtfObjAttr,	rtfObjSubscriber,	"objsub",	0 },
+	{ rtfObjAttr,	rtfObjPublisher,	"objpub",	0 },
+	{ rtfObjAttr,	rtfObjICEmb,		"objicemb",	0 },
+
+	{ rtfObjAttr,	rtfObjLinkSelf,		"linkself",	0 },
+	{ rtfObjAttr,	rtfObjLock,		"objupdate",	0 },
+	{ rtfObjAttr,	rtfObjUpdate,		"objlock",	0 },
+
+	{ rtfObjAttr,	rtfObjHt,		"objh",		0 },
+	{ rtfObjAttr,	rtfObjWid,		"objw",		0 },
+	{ rtfObjAttr,	rtfObjSetSize,		"objsetsize",	0 },
+	{ rtfObjAttr,	rtfObjAlign,		"objalign",	0 },
+	{ rtfObjAttr,	rtfObjTransposeY,	"objtransy",	0 },
+	{ rtfObjAttr,	rtfObjCropTop,		"objcropt",	0 },
+	{ rtfObjAttr,	rtfObjCropBottom,	"objcropb",	0 },
+	{ rtfObjAttr,	rtfObjCropLeft,		"objcropl",	0 },
+	{ rtfObjAttr,	rtfObjCropRight,	"objcropr",	0 },
+	{ rtfObjAttr,	rtfObjScaleX,		"objscalex",	0 },
+	{ rtfObjAttr,	rtfObjScaleY,		"objscaley",	0 },
+
+	{ rtfObjAttr,	rtfObjResRTF,		"rsltrtf",	0 },
+	{ rtfObjAttr,	rtfObjResPict,		"rsltpict",	0 },
+	{ rtfObjAttr,	rtfObjResBitmap,	"rsltbmp",	0 },
+	{ rtfObjAttr,	rtfObjResText,		"rslttxt",	0 },
+	{ rtfObjAttr,	rtfObjResMerge,		"rsltmerge",	0 },
+
+	{ rtfObjAttr,	rtfObjBookmarkPubObj,	"bkmkpub",	0 },
+	{ rtfObjAttr,	rtfObjPubAutoUpdate,	"pubauto",	0 },
+
+	/*
+	 * Associated character formatting attributes
+	 */
+
+	{ rtfACharAttr,	rtfACBold,		"ab",		0 },
+	{ rtfACharAttr,	rtfACAllCaps,		"caps",		0 },
+	{ rtfACharAttr,	rtfACForeColor,		"acf",		0 },
+	{ rtfACharAttr,	rtfACSubScript,		"adn",		0 },
+	{ rtfACharAttr,	rtfACExpand,		"aexpnd",	0 },
+	{ rtfACharAttr,	rtfACFontNum,		"af",		0 },
+	{ rtfACharAttr,	rtfACFontSize,		"afs",		0 },
+	{ rtfACharAttr,	rtfACItalic,		"ai",		0 },
+	{ rtfACharAttr,	rtfACLanguage,		"alang",	0 },
+	{ rtfACharAttr,	rtfACOutline,		"aoutl",	0 },
+	{ rtfACharAttr,	rtfACSmallCaps,		"ascaps",	0 },
+	{ rtfACharAttr,	rtfACShadow,		"ashad",	0 },
+	{ rtfACharAttr,	rtfACStrikeThru,	"astrike",	0 },
+	{ rtfACharAttr,	rtfACUnderline,		"aul",		0 },
+	{ rtfACharAttr,	rtfACDotUnderline,	"auld",		0 },
+	{ rtfACharAttr,	rtfACDbUnderline,	"auldb",	0 },
+	{ rtfACharAttr,	rtfACNoUnderline,	"aulnone",	0 },
+	{ rtfACharAttr,	rtfACWordUnderline,	"aulw",		0 },
+	{ rtfACharAttr,	rtfACSuperScript,	"aup",		0 },
+
+	/*
+	 * Footnote attributes
+	 */
+
+	{ rtfFNoteAttr,	rtfFNAlt,		"ftnalt",	0 },
+
+	/*
+	 * Key code attributes
+	 */
+
+	{ rtfKeyCodeAttr,	rtfAltKey,		"alt",		0 },
+	{ rtfKeyCodeAttr,	rtfShiftKey,		"shift",	0 },
+	{ rtfKeyCodeAttr,	rtfControlKey,		"ctrl",		0 },
+	{ rtfKeyCodeAttr,	rtfFunctionKey,		"fn",		0 },
+
+	/*
+	 * Bookmark attributes
+	 */
+
+	{ rtfBookmarkAttr, rtfBookmarkFirstCol,	"bkmkcolf",	0 },
+	{ rtfBookmarkAttr, rtfBookmarkLastCol,	"bkmkcoll",	0 },
+
+	/*
+	 * Index entry attributes
+	 */
+
+	{ rtfIndexAttr,	rtfIndexNumber,		"xef",		0 },
+	{ rtfIndexAttr,	rtfIndexBold,		"bxe",		0 },
+	{ rtfIndexAttr,	rtfIndexItalic,		"ixe",		0 },
+
+	/*
+	 * Table of contents attributes
+	 */
+
+	{ rtfTOCAttr,	rtfTOCType,		"tcf",		0 },
+	{ rtfTOCAttr,	rtfTOCLevel,		"tcl",		0 },
+
+	/*
+	 * Drawing object attributes
+	 */
+
+	{ rtfDrawAttr,	rtfDrawLock,		"dolock",	0 },
+	{ rtfDrawAttr,	rtfDrawPageRelX,	"doxpage",	0 },
+	{ rtfDrawAttr,	rtfDrawColumnRelX,	"dobxcolumn",	0 },
+	{ rtfDrawAttr,	rtfDrawMarginRelX,	"dobxmargin",	0 },
+	{ rtfDrawAttr,	rtfDrawPageRelY,	"dobypage",	0 },
+	{ rtfDrawAttr,	rtfDrawColumnRelY,	"dobycolumn",	0 },
+	{ rtfDrawAttr,	rtfDrawMarginRelY,	"dobymargin",	0 },
+	{ rtfDrawAttr,	rtfDrawHeight,		"dobhgt",	0 },
+
+	{ rtfDrawAttr,	rtfDrawBeginGroup,	"dpgroup",	0 },
+	{ rtfDrawAttr,	rtfDrawGroupCount,	"dpcount",	0 },
+	{ rtfDrawAttr,	rtfDrawEndGroup,	"dpendgroup",	0 },
+	{ rtfDrawAttr,	rtfDrawArc,		"dparc",	0 },
+	{ rtfDrawAttr,	rtfDrawCallout,		"dpcallout",	0 },
+	{ rtfDrawAttr,	rtfDrawEllipse,		"dpellipse",	0 },
+	{ rtfDrawAttr,	rtfDrawLine,		"dpline",	0 },
+	{ rtfDrawAttr,	rtfDrawPolygon,		"dppolygon",	0 },
+	{ rtfDrawAttr,	rtfDrawPolyLine,	"dppolyline",	0 },
+	{ rtfDrawAttr,	rtfDrawRect,		"dprect",	0 },
+	{ rtfDrawAttr,	rtfDrawTextBox,		"dptxbx",	0 },
+
+	{ rtfDrawAttr,	rtfDrawOffsetX,		"dpx",		0 },
+	{ rtfDrawAttr,	rtfDrawSizeX,		"dpxsize",	0 },
+	{ rtfDrawAttr,	rtfDrawOffsetY,		"dpy",		0 },
+	{ rtfDrawAttr,	rtfDrawSizeY,		"dpysize",	0 },
+
+	{ rtfDrawAttr,	rtfCOAngle,		"dpcoa",	0 },
+	{ rtfDrawAttr,	rtfCOAccentBar,		"dpcoaccent",	0 },
+	{ rtfDrawAttr,	rtfCOBestFit,		"dpcobestfit",	0 },
+	{ rtfDrawAttr,	rtfCOBorder,		"dpcoborder",	0 },
+	{ rtfDrawAttr,	rtfCOAttachAbsDist,	"dpcodabs",	0 },
+	{ rtfDrawAttr,	rtfCOAttachBottom,	"dpcodbottom",	0 },
+	{ rtfDrawAttr,	rtfCOAttachCenter,	"dpcodcenter",	0 },
+	{ rtfDrawAttr,	rtfCOAttachTop,		"dpcodtop",	0 },
+	{ rtfDrawAttr,	rtfCOLength,		"dpcolength",	0 },
+	{ rtfDrawAttr,	rtfCONegXQuadrant,	"dpcominusx",	0 },
+	{ rtfDrawAttr,	rtfCONegYQuadrant,	"dpcominusy",	0 },
+	{ rtfDrawAttr,	rtfCOOffset,		"dpcooffset",	0 },
+	{ rtfDrawAttr,	rtfCOAttachSmart,	"dpcosmarta",	0 },
+	{ rtfDrawAttr,	rtfCODoubleLine,	"dpcotdouble",	0 },
+	{ rtfDrawAttr,	rtfCORightAngle,	"dpcotright",	0 },
+	{ rtfDrawAttr,	rtfCOSingleLine,	"dpcotsingle",	0 },
+	{ rtfDrawAttr,	rtfCOTripleLine,	"dpcottriple",	0 },
+
+	{ rtfDrawAttr,	rtfDrawTextBoxMargin,	"dptxbxmar",	0 },
+	{ rtfDrawAttr,	rtfDrawTextBoxText,	"dptxbxtext",	0 },
+	{ rtfDrawAttr,	rtfDrawRoundRect,	"dproundr",	0 },
+
+	{ rtfDrawAttr,	rtfDrawPointX,		"dpptx",	0 },
+	{ rtfDrawAttr,	rtfDrawPointY,		"dppty",	0 },
+	{ rtfDrawAttr,	rtfDrawPolyCount,	"dppolycount",	0 },
+
+	{ rtfDrawAttr,	rtfDrawArcFlipX,	"dparcflipx",	0 },
+	{ rtfDrawAttr,	rtfDrawArcFlipY,	"dparcflipy",	0 },
+
+	{ rtfDrawAttr,	rtfDrawLineBlue,	"dplinecob",	0 },
+	{ rtfDrawAttr,	rtfDrawLineGreen,	"dplinecog",	0 },
+	{ rtfDrawAttr,	rtfDrawLineRed,		"dplinecor",	0 },
+	{ rtfDrawAttr,	rtfDrawLinePalette,	"dplinepal",	0 },
+	{ rtfDrawAttr,	rtfDrawLineDashDot,	"dplinedado",	0 },
+	{ rtfDrawAttr,	rtfDrawLineDashDotDot,	"dplinedadodo",	0 },
+	{ rtfDrawAttr,	rtfDrawLineDash,	"dplinedash",	0 },
+	{ rtfDrawAttr,	rtfDrawLineDot,		"dplinedot",	0 },
+	{ rtfDrawAttr,	rtfDrawLineGray,	"dplinegray",	0 },
+	{ rtfDrawAttr,	rtfDrawLineHollow,	"dplinehollow",	0 },
+	{ rtfDrawAttr,	rtfDrawLineSolid,	"dplinesolid",	0 },
+	{ rtfDrawAttr,	rtfDrawLineWidth,	"dplinew",	0 },
+
+	{ rtfDrawAttr,	rtfDrawHollowEndArrow,	"dpaendhol",	0 },
+	{ rtfDrawAttr,	rtfDrawEndArrowLength,	"dpaendl",	0 },
+	{ rtfDrawAttr,	rtfDrawSolidEndArrow,	"dpaendsol",	0 },
+	{ rtfDrawAttr,	rtfDrawEndArrowWidth,	"dpaendw",	0 },
+	{ rtfDrawAttr,	rtfDrawHollowStartArrow,"dpastarthol",	0 },
+	{ rtfDrawAttr,	rtfDrawStartArrowLength,"dpastartl",	0 },
+	{ rtfDrawAttr,	rtfDrawSolidStartArrow,	"dpastartsol",	0 },
+	{ rtfDrawAttr,	rtfDrawStartArrowWidth,	"dpastartw",	0 },
+
+	{ rtfDrawAttr,	rtfDrawBgFillBlue,	"dpfillbgcb",	0 },
+	{ rtfDrawAttr,	rtfDrawBgFillGreen,	"dpfillbgcg",	0 },
+	{ rtfDrawAttr,	rtfDrawBgFillRed,	"dpfillbgcr",	0 },
+	{ rtfDrawAttr,	rtfDrawBgFillPalette,	"dpfillbgpal",	0 },
+	{ rtfDrawAttr,	rtfDrawBgFillGray,	"dpfillbggray",	0 },
+	{ rtfDrawAttr,	rtfDrawFgFillBlue,	"dpfillfgcb",	0 },
+	{ rtfDrawAttr,	rtfDrawFgFillGreen,	"dpfillfgcg",	0 },
+	{ rtfDrawAttr,	rtfDrawFgFillRed,	"dpfillfgcr",	0 },
+	{ rtfDrawAttr,	rtfDrawFgFillPalette,	"dpfillfgpal",	0 },
+	{ rtfDrawAttr,	rtfDrawFgFillGray,	"dpfillfggray",	0 },
+	{ rtfDrawAttr,	rtfDrawFillPatIndex,	"dpfillpat",	0 },
+
+	{ rtfDrawAttr,	rtfDrawShadow,		"dpshadow",	0 },
+	{ rtfDrawAttr,	rtfDrawShadowXOffset,	"dpshadx",	0 },
+	{ rtfDrawAttr,	rtfDrawShadowYOffset,	"dpshady",	0 },
+
+	{ rtfVersion,	-1,			"rtf",		0 },
+	{ rtfDefFont,	-1,			"deff",		0 },
+
+	{ 0,		-1,			(char *) NULL,	0 }
+};
+
+
+/*
+ * Initialize lookup table hash values.  Only need to do this once.
+ */
+
+static void LookupInit(void)
+{
+	static int	inited = 0;
+	RTFKey	*rp;
+
+	if (inited == 0)
+	{
+		for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++)
+			rp->rtfKHash = Hash ((char*)rp->rtfKStr);
+		++inited;
+	}
+}
+
+
+/*
+ * Determine major and minor number of control token.  If it's
+ * not found, the class turns into rtfUnknown.
+ */
+
+static void Lookup(RTF_Info *info, char *s)
+{
+	RTFKey	*rp;
+	int	hash;
+
+	TRACE("\n");
+	++s;			/* skip over the leading \ character */
+	hash = Hash (s);
+	for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++)
+	{
+		if (hash == rp->rtfKHash && strcmp (s, rp->rtfKStr) == 0)
+		{
+			info->rtfClass = rtfControl;
+			info->rtfMajor = rp->rtfKMajor;
+			info->rtfMinor = rp->rtfKMinor;
+			return;
+		}
+	}
+	info->rtfClass = rtfUnknown;
+}
+
+
+/*
+ * Compute hash value of symbol
+ */
+
+static int Hash(char *s)
+{
+	char	c;
+	int	val = 0;
+
+	while ((c = *s++) != '\0')
+		val += (int) c;
+	return (val);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Memory allocation routines
+ */
+
+
+/*
+ * Return pointer to block of size bytes, or NULL if there's
+ * not enough memory available.
+ *
+ * This is called through RTFAlloc(), a define which coerces the
+ * argument to int.  This avoids the persistent problem of allocation
+ * failing under THINK C when a long is passed.
+ */
+
+char *_RTFAlloc(int size)
+{
+	return HeapAlloc(me_heap, 0, size);
+}
+
+
+/*
+ * Saves a string on the heap and returns a pointer to it.
+ */
+
+
+char *RTFStrSave(char *s)
+{
+	char	*p;
+
+	if ((p = RTFAlloc ((int) (strlen (s) + 1))) == (char *) NULL)
+		return ((char *) NULL);
+	return (strcpy (p, s));
+}
+
+
+void RTFFree(char *p)
+{
+        HeapFree(me_heap, 0, p);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/*
+ * Token comparison routines
+ */
+
+int RTFCheckCM(RTF_Info *info, int class, int major)
+{
+	return (info->rtfClass == class && info->rtfMajor == major);
+}
+
+
+int RTFCheckCMM(RTF_Info *info, int class, int major, int minor)
+{
+	return (info->rtfClass == class && info->rtfMajor == major && info->rtfMinor == minor);
+}
+
+
+int RTFCheckMM(RTF_Info *info, int major, int minor)
+{
+	return (info->rtfMajor == major && info->rtfMinor == minor);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+int RTFCharToHex(char c)
+{
+	if (isupper (c))
+		c = tolower (c);
+	if (isdigit (c))
+		return (c - '0');	/* '0'..'9' */
+	return (c - 'a' + 10);		/* 'a'..'f' */
+}
+
+
+int RTFHexToChar(int i)
+{
+	if (i < 10)
+		return (i + '0');
+	return (i - 10 + 'a');
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * RTFReadOutputMap() -- Read output translation map
+ */
+
+/*
+ * Read in an array describing the relation between the standard character set
+ * and an RTF translator's corresponding output sequences.  Each line consists
+ * of a standard character name and the output sequence for that character.
+ *
+ * outMap is an array of strings into which the sequences should be placed.
+ * It should be declared like this in the calling program:
+ *
+ *	char *outMap[rtfSC_MaxChar];
+ *
+ * reinit should be non-zero if outMap should be initialized
+ * zero otherwise.
+ *
+ */
+
+int RTFReadOutputMap(RTF_Info *info, char *outMap[], int reinit)
+{
+	unsigned int  i;
+	int  stdCode;
+
+	if (reinit)
+	{
+		for (i = 0; i < rtfSC_MaxChar; i++)
+		{
+			outMap[i] = (char *) NULL;
+		}
+	}
+
+	for (i=0 ;i< sizeof(text_map)/sizeof(char*); i+=2)
+	{
+		const char *name = text_map[i];
+		const char *seq  = text_map[i+1];
+		stdCode = RTFStdCharCode( info, name );
+		outMap[stdCode] = (char*)seq;
+	}
+
+	return (1);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Open a library file.
+ */
+
+
+void RTFSetOpenLibFileProc(RTF_Info *info, FILE	*(*proc)())
+{
+	info->libFileOpen = proc;
+}
+
+
+FILE *RTFOpenLibFile (RTF_Info *info, char *file, char *mode)
+{
+	if (info->libFileOpen == NULL)
+		return ((FILE *) NULL);
+	return ((*info->libFileOpen) (file, mode));
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Print message.  Default is to send message to stderr
+ * but this may be overridden with RTFSetMsgProc().
+ *
+ * Message should include linefeeds as necessary.  If the default
+ * function is overridden, the overriding function may want to
+ * map linefeeds to another line ending character or sequence if
+ * the host system doesn't use linefeeds.
+ */
+
+
+void RTFMsg (RTF_Info *info, const char *fmt, ...)
+{
+	char	buf[rtfBufSiz];
+
+	va_list args;
+	va_start (args,fmt);
+	vsprintf (buf, fmt, args);
+	va_end (args);
+	MESSAGE( "%s", buf);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/*
+ * Process termination.  Print error message and exit.  Also prints
+ * current token, and current input line number and position within
+ * line if any input has been read from the current file.  (No input
+ * has been read if prevChar is EOF).
+ */
+
+static void DefaultPanicProc(RTF_Info *info, char *s)
+{
+	MESSAGE( "%s", s);
+	/*exit (1);*/
+}
+
+
+
+void RTFPanic(RTF_Info *info, const char *fmt, ...)
+{
+	char	buf[rtfBufSiz];
+
+	va_list args;
+	va_start (args,fmt);
+	vsprintf (buf, fmt, args);
+	va_end (args);
+	(void) strcat (buf, "\n");
+	if (info->prevChar != EOF && info->rtfTextBuf != (char *) NULL)
+	{
+		sprintf (buf + strlen (buf),
+			"Last token read was \"%s\" near line %ld, position %d.\n",
+			info->rtfTextBuf, info->rtfLineNum, info->rtfLinePos);
+	}
+	DefaultPanicProc(info, buf);
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * originally from RTF tools' text-writer.c
+ *
+ * text-writer -- RTF-to-text translation writer code.
+ *
+ * Read RTF input, write text of document (text extraction).
+ */
+
+static void	TextClass (RTF_Info *info);
+static void	ControlClass (RTF_Info *info);
+static void	Destination (RTF_Info *info);
+static void	SpecialChar (RTF_Info *info);
+static void	PutStdChar (RTF_Info *info, int stdCode);
+static void	PutLitChar (RTF_Info *info, int c);
+static void	PutLitStr (RTF_Info *info, char	*s);
+
+/*
+ * Initialize the writer.
+ */
+
+void
+WriterInit (RTF_Info *info )
+{
+	RTFReadOutputMap (info, info->outMap,1);
+}
+
+
+int
+BeginFile (RTF_Info *info )
+{
+	/* install class callbacks */
+
+	RTFSetClassCallback (info, rtfText, TextClass);
+	RTFSetClassCallback (info, rtfControl, ControlClass);
+
+	return (1);
+}
+
+
+/*
+ * Write out a character.  rtfMajor contains the input character, rtfMinor
+ * contains the corresponding standard character code.
+ *
+ * If the input character isn't in the charset map, try to print some
+ * representation of it.
+ */
+
+static void
+TextClass (RTF_Info *info)
+{
+	char	buf[rtfBufSiz];
+
+	TRACE("\n");
+
+	if (info->rtfFormat == SF_TEXT)
+	        PutLitChar (info, info->rtfMajor);
+	else if (info->rtfMinor != rtfSC_nothing)
+		PutStdChar (info, info->rtfMinor);
+	else
+	{
+		if (info->rtfMajor < 128)	/* in ASCII range */
+			sprintf (buf, "[[%c]]", info->rtfMajor);
+		else
+			sprintf (buf, "[[\\'%02x]]", info->rtfMajor);
+		PutLitStr (info, buf);
+	}
+}
+
+
+static void
+ControlClass (RTF_Info *info)
+{
+	TRACE("\n");
+
+	switch (info->rtfMajor)
+	{
+	case rtfDestination:
+		Destination (info);
+		break;
+	case rtfSpecialChar:
+		SpecialChar (info);
+		break;
+	}
+}
+
+
+/*
+ * This function notices destinations that should be ignored
+ * and skips to their ends.  This keeps, for instance, picture
+ * data from being considered as plain text.
+ */
+
+static void
+Destination (RTF_Info *info)
+{
+	TRACE("\n");
+
+	switch (info->rtfMinor)
+	{
+	case rtfPict:
+	case rtfFNContSep:
+	case rtfFNContNotice:
+	case rtfInfo:
+	case rtfIndexRange:
+	case rtfITitle:
+	case rtfISubject:
+	case rtfIAuthor:
+	case rtfIOperator:
+	case rtfIKeywords:
+	case rtfIComment:
+	case rtfIVersion:
+	case rtfIDoccomm:
+		RTFSkipGroup (info);
+		break;
+	}
+}
+
+
+/*
+ * The reason these use the rtfSC_xxx thingies instead of just writing
+ * out ' ', '-', '"', etc., is so that the mapping for these characters
+ * can be controlled by the text-map file.
+ */
+
+void SpecialChar (RTF_Info *info)
+{
+
+	TRACE("\n");
+
+	switch (info->rtfMinor)
+	{
+	case rtfPage:
+	case rtfSect:
+	case rtfRow:
+	case rtfLine:
+	case rtfPar:
+		PutLitChar (info, '\n');
+		break;
+	case rtfCell:
+		PutStdChar (info, rtfSC_space);	/* make sure cells are separated */
+		break;
+	case rtfNoBrkSpace:
+		PutStdChar (info, rtfSC_nobrkspace);
+		break;
+	case rtfTab:
+		PutLitChar (info, '\t');
+		break;
+	case rtfNoBrkHyphen:
+		PutStdChar (info, rtfSC_nobrkhyphen);
+		break;
+	case rtfBullet:
+		PutStdChar (info, rtfSC_bullet);
+		break;
+	case rtfEmDash:
+		PutStdChar (info, rtfSC_emdash);
+		break;
+	case rtfEnDash:
+		PutStdChar (info, rtfSC_endash);
+		break;
+	case rtfLQuote:
+		PutStdChar (info, rtfSC_quoteleft);
+		break;
+	case rtfRQuote:
+		PutStdChar (info, rtfSC_quoteright);
+		break;
+	case rtfLDblQuote:
+		PutStdChar (info, rtfSC_quotedblleft);
+		break;
+	case rtfRDblQuote:
+		PutStdChar (info, rtfSC_quotedblright);
+		break;
+	}
+}
+
+
+/*
+ * Eventually this should keep track of the destination of the
+ * current state and only write text when in the initial state.
+ *
+ * If the output sequence is unspecified in the output map, write
+ * the character's standard name instead.  This makes map deficiencies
+ * obvious and provides incentive to fix it. :-)
+ */
+
+void PutStdChar (RTF_Info *info, int stdCode)
+{
+
+	char	*oStr = (char *) NULL;
+	char	buf[rtfBufSiz];
+
+/*	if (stdCode == rtfSC_nothing)
+		RTFPanic ("Unknown character code, logic error\n");
+*/
+	TRACE("\n");
+
+	oStr = info->outMap[stdCode];
+	if (oStr == (char *) NULL)	/* no output sequence in map */
+	{
+		sprintf (buf, "[[%s]]", RTFStdCharName (info, stdCode));
+		oStr = buf;
+	}
+	PutLitStr (info, oStr);
+}
+
+void PutLitChar (RTF_Info *info, int c)
+{
+	if( info->dwOutputCount >= ( sizeof info->OutputBuffer - 1 ) )
+		RTFFlushOutputBuffer( info );
+	info->OutputBuffer[info->dwOutputCount++] = c;
+}
+
+void RTFFlushOutputBuffer( RTF_Info *info )
+{
+	info->OutputBuffer[info->dwOutputCount] = 0;
+	SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) info->OutputBuffer );
+	info->dwOutputCount = 0;
+}
+
+static void PutLitStr (RTF_Info *info, char *str )
+{
+	int len = strlen( str );
+
+	if( ( len + info->dwOutputCount + 1 ) > sizeof info->OutputBuffer )
+		RTFFlushOutputBuffer( info );
+	if( ( len + 1 ) >= sizeof info->OutputBuffer )
+	{
+		SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str );
+		return;
+	}
+	strcpy( &info->OutputBuffer[info->dwOutputCount], str );
+	info->dwOutputCount += len;
+}
--- /dev/null	2005-02-25 01:31:53.000000000 +0900
+++ dlls/riched20/rtf.h	2005-03-07 14:01:23.000000000 +0900
@@ -0,0 +1,1570 @@
+#ifndef _RTF
+#define _RTF
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "richedit.h"
+
+
+/* The following defines are automatically generated.  Do not edit. */
+
+
+/* These must be sequential beginning from zero */
+
+#define rtfSC_nothing	0
+#define rtfSC_space	1
+#define rtfSC_exclam	2
+#define rtfSC_quotedbl	3
+#define rtfSC_numbersign	4
+#define rtfSC_dollar	5
+#define rtfSC_percent	6
+#define rtfSC_ampersand	7
+#define rtfSC_quoteright	8
+#define rtfSC_parenleft	9
+#define rtfSC_parenright	10
+#define rtfSC_asterisk	11
+#define rtfSC_plus	12
+#define rtfSC_comma	13
+#define rtfSC_hyphen	14
+#define rtfSC_period	15
+#define rtfSC_slash	16
+#define rtfSC_zero	17
+#define rtfSC_one	18
+#define rtfSC_two	19
+#define rtfSC_three	20
+#define rtfSC_four	21
+#define rtfSC_five	22
+#define rtfSC_six	23
+#define rtfSC_seven	24
+#define rtfSC_eight	25
+#define rtfSC_nine	26
+#define rtfSC_colon	27
+#define rtfSC_semicolon	28
+#define rtfSC_less	29
+#define rtfSC_equal	30
+#define rtfSC_greater	31
+#define rtfSC_question	32
+#define rtfSC_at	33
+#define rtfSC_A	34
+#define rtfSC_B	35
+#define rtfSC_C	36
+#define rtfSC_D	37
+#define rtfSC_E	38
+#define rtfSC_F	39
+#define rtfSC_G	40
+#define rtfSC_H	41
+#define rtfSC_I	42
+#define rtfSC_J	43
+#define rtfSC_K	44
+#define rtfSC_L	45
+#define rtfSC_M	46
+#define rtfSC_N	47
+#define rtfSC_O	48
+#define rtfSC_P	49
+#define rtfSC_Q	50
+#define rtfSC_R	51
+#define rtfSC_S	52
+#define rtfSC_T	53
+#define rtfSC_U	54
+#define rtfSC_V	55
+#define rtfSC_W	56
+#define rtfSC_X	57
+#define rtfSC_Y	58
+#define rtfSC_Z	59
+#define rtfSC_bracketleft	60
+#define rtfSC_backslash	61
+#define rtfSC_bracketright	62
+#define rtfSC_asciicircum	63
+#define rtfSC_underscore	64
+#define rtfSC_quoteleft	65
+#define rtfSC_a	66
+#define rtfSC_b	67
+#define rtfSC_c	68
+#define rtfSC_d	69
+#define rtfSC_e	70
+#define rtfSC_f	71
+#define rtfSC_g	72
+#define rtfSC_h	73
+#define rtfSC_i	74
+#define rtfSC_j	75
+#define rtfSC_k	76
+#define rtfSC_l	77
+#define rtfSC_m	78
+#define rtfSC_n	79
+#define rtfSC_o	80
+#define rtfSC_p	81
+#define rtfSC_q	82
+#define rtfSC_r	83
+#define rtfSC_s	84
+#define rtfSC_t	85
+#define rtfSC_u	86
+#define rtfSC_v	87
+#define rtfSC_w	88
+#define rtfSC_x	89
+#define rtfSC_y	90
+#define rtfSC_z	91
+#define rtfSC_braceleft	92
+#define rtfSC_bar	93
+#define rtfSC_braceright	94
+#define rtfSC_asciitilde	95
+#define rtfSC_exclamdown	96
+#define rtfSC_cent	97
+#define rtfSC_sterling	98
+#define rtfSC_fraction	99
+#define rtfSC_yen	100
+#define rtfSC_florin	101
+#define rtfSC_section	102
+#define rtfSC_currency	103
+#define rtfSC_quotedblleft	104
+#define rtfSC_guillemotleft	105
+#define rtfSC_guilsinglleft	106
+#define rtfSC_guilsinglright	107
+#define rtfSC_fi	108
+#define rtfSC_fl	109
+#define rtfSC_endash	110
+#define rtfSC_dagger	111
+#define rtfSC_daggerdbl	112
+#define rtfSC_periodcentered	113
+#define rtfSC_paragraph	114
+#define rtfSC_bullet	115
+#define rtfSC_quotesinglbase	116
+#define rtfSC_quotedblbase	117
+#define rtfSC_quotedblright	118
+#define rtfSC_guillemotright	119
+#define rtfSC_ellipsis	120
+#define rtfSC_perthousand	121
+#define rtfSC_questiondown	122
+#define rtfSC_grave	123
+#define rtfSC_acute	124
+#define rtfSC_circumflex	125
+#define rtfSC_tilde	126
+#define rtfSC_macron	127
+#define rtfSC_breve	128
+#define rtfSC_dotaccent	129
+#define rtfSC_dieresis	130
+#define rtfSC_ring	131
+#define rtfSC_cedilla	132
+#define rtfSC_hungarumlaut	133
+#define rtfSC_ogonek	134
+#define rtfSC_caron	135
+#define rtfSC_emdash	136
+#define rtfSC_AE	137
+#define rtfSC_ordfeminine	138
+#define rtfSC_Lslash	139
+#define rtfSC_Oslash	140
+#define rtfSC_OE	141
+#define rtfSC_ordmasculine	142
+#define rtfSC_ae	143
+#define rtfSC_dotlessi	144
+#define rtfSC_lslash	145
+#define rtfSC_oslash	146
+#define rtfSC_oe	147
+#define rtfSC_germandbls	148
+#define rtfSC_Aacute	149
+#define rtfSC_Acircumflex	150
+#define rtfSC_Adieresis	151
+#define rtfSC_Agrave	152
+#define rtfSC_Aring	153
+#define rtfSC_Atilde	154
+#define rtfSC_Ccedilla	155
+#define rtfSC_Eacute	156
+#define rtfSC_Ecircumflex	157
+#define rtfSC_Edieresis	158
+#define rtfSC_Egrave	159
+#define rtfSC_Eth	160
+#define rtfSC_Iacute	161
+#define rtfSC_Icircumflex	162
+#define rtfSC_Idieresis	163
+#define rtfSC_Igrave	164
+#define rtfSC_Ntilde	165
+#define rtfSC_Oacute	166
+#define rtfSC_Ocircumflex	167
+#define rtfSC_Odieresis	168
+#define rtfSC_Ograve	169
+#define rtfSC_Otilde	170
+#define rtfSC_Scaron	171
+#define rtfSC_Thorn	172
+#define rtfSC_Uacute	173
+#define rtfSC_Ucircumflex	174
+#define rtfSC_Udieresis	175
+#define rtfSC_Ugrave	176
+#define rtfSC_Yacute	177
+#define rtfSC_Ydieresis	178
+#define rtfSC_aacute	179
+#define rtfSC_acircumflex	180
+#define rtfSC_adieresis	181
+#define rtfSC_agrave	182
+#define rtfSC_aring	183
+#define rtfSC_atilde	184
+#define rtfSC_brokenbar	185
+#define rtfSC_ccedilla	186
+#define rtfSC_copyright	187
+#define rtfSC_degree	188
+#define rtfSC_divide	189
+#define rtfSC_eacute	190
+#define rtfSC_ecircumflex	191
+#define rtfSC_edieresis	192
+#define rtfSC_egrave	193
+#define rtfSC_eth	194
+#define rtfSC_iacute	195
+#define rtfSC_icircumflex	196
+#define rtfSC_idieresis	197
+#define rtfSC_igrave	198
+#define rtfSC_logicalnot	199
+#define rtfSC_minus	200
+#define rtfSC_multiply	201
+#define rtfSC_ntilde	202
+#define rtfSC_oacute	203
+#define rtfSC_ocircumflex	204
+#define rtfSC_odieresis	205
+#define rtfSC_ograve	206
+#define rtfSC_onehalf	207
+#define rtfSC_onequarter	208
+#define rtfSC_onesuperior	209
+#define rtfSC_otilde	210
+#define rtfSC_plusminus	211
+#define rtfSC_registered	212
+#define rtfSC_thorn	213
+#define rtfSC_threequarters	214
+#define rtfSC_threesuperior	215
+#define rtfSC_trademark	216
+#define rtfSC_twosuperior	217
+#define rtfSC_uacute	218
+#define rtfSC_ucircumflex	219
+#define rtfSC_udieresis	220
+#define rtfSC_ugrave	221
+#define rtfSC_yacute	222
+#define rtfSC_ydieresis	223
+#define rtfSC_Alpha	224
+#define rtfSC_Beta	225
+#define rtfSC_Chi	226
+#define rtfSC_Delta	227
+#define rtfSC_Epsilon	228
+#define rtfSC_Phi	229
+#define rtfSC_Gamma	230
+#define rtfSC_Eta	231
+#define rtfSC_Iota	232
+#define rtfSC_Kappa	233
+#define rtfSC_Lambda	234
+#define rtfSC_Mu	235
+#define rtfSC_Nu	236
+#define rtfSC_Omicron	237
+#define rtfSC_Pi	238
+#define rtfSC_Theta	239
+#define rtfSC_Rho	240
+#define rtfSC_Sigma	241
+#define rtfSC_Tau	242
+#define rtfSC_Upsilon	243
+#define rtfSC_varUpsilon	244
+#define rtfSC_Omega	245
+#define rtfSC_Xi	246
+#define rtfSC_Psi	247
+#define rtfSC_Zeta	248
+#define rtfSC_alpha	249
+#define rtfSC_beta	250
+#define rtfSC_chi	251
+#define rtfSC_delta	252
+#define rtfSC_epsilon	253
+#define rtfSC_phi	254
+#define rtfSC_varphi	255
+#define rtfSC_gamma	256
+#define rtfSC_eta	257
+#define rtfSC_iota	258
+#define rtfSC_kappa	259
+#define rtfSC_lambda	260
+#define rtfSC_mu	261
+#define rtfSC_nu	262
+#define rtfSC_omicron	263
+#define rtfSC_pi	264
+#define rtfSC_varpi	265
+#define rtfSC_theta	266
+#define rtfSC_vartheta	267
+#define rtfSC_rho	268
+#define rtfSC_sigma	269
+#define rtfSC_varsigma	270
+#define rtfSC_tau	271
+#define rtfSC_upsilon	272
+#define rtfSC_omega	273
+#define rtfSC_xi	274
+#define rtfSC_psi	275
+#define rtfSC_zeta	276
+#define rtfSC_nobrkspace	277
+#define rtfSC_nobrkhyphen	278
+#define rtfSC_lessequal	279
+#define rtfSC_greaterequal	280
+#define rtfSC_infinity	281
+#define rtfSC_integral	282
+#define rtfSC_notequal	283
+#define rtfSC_radical	284
+#define rtfSC_radicalex	285
+#define rtfSC_approxequal	286
+#define rtfSC_apple	287
+#define rtfSC_partialdiff	288
+#define rtfSC_opthyphen	289
+#define rtfSC_formula	290
+#define rtfSC_lozenge	291
+#define rtfSC_universal	292
+#define rtfSC_existential	293
+#define rtfSC_suchthat	294
+#define rtfSC_congruent	295
+#define rtfSC_therefore	296
+#define rtfSC_perpendicular	297
+#define rtfSC_minute	298
+#define rtfSC_club	299
+#define rtfSC_diamond	300
+#define rtfSC_heart	301
+#define rtfSC_spade	302
+#define rtfSC_arrowboth	303
+#define rtfSC_arrowleft	304
+#define rtfSC_arrowup	305
+#define rtfSC_arrowright	306
+#define rtfSC_arrowdown	307
+#define rtfSC_second	308
+#define rtfSC_proportional	309
+#define rtfSC_equivalence	310
+#define rtfSC_arrowvertex	311
+#define rtfSC_arrowhorizex	312
+#define rtfSC_carriagereturn	313
+#define rtfSC_aleph	314
+#define rtfSC_Ifraktur	315
+#define rtfSC_Rfraktur	316
+#define rtfSC_weierstrass	317
+#define rtfSC_circlemultiply	318
+#define rtfSC_circleplus	319
+#define rtfSC_emptyset	320
+#define rtfSC_intersection	321
+#define rtfSC_union	322
+#define rtfSC_propersuperset	323
+#define rtfSC_reflexsuperset	324
+#define rtfSC_notsubset	325
+#define rtfSC_propersubset	326
+#define rtfSC_reflexsubset	327
+#define rtfSC_element	328
+#define rtfSC_notelement	329
+#define rtfSC_angle	330
+#define rtfSC_gradient	331
+#define rtfSC_product	332
+#define rtfSC_logicaland	333
+#define rtfSC_logicalor	334
+#define rtfSC_arrowdblboth	335
+#define rtfSC_arrowdblleft	336
+#define rtfSC_arrowdblup	337
+#define rtfSC_arrowdblright	338
+#define rtfSC_arrowdbldown	339
+#define rtfSC_angleleft	340
+#define rtfSC_registersans	341
+#define rtfSC_copyrightsans	342
+#define rtfSC_trademarksans	343
+#define rtfSC_angleright	344
+#define rtfSC_mathplus	345
+#define rtfSC_mathminus	346
+#define rtfSC_mathasterisk	347
+#define rtfSC_mathnumbersign	348
+#define rtfSC_dotmath	349
+#define rtfSC_mathequal	350
+#define rtfSC_mathtilde	351
+
+#define rtfSC_MaxChar	352
+/*
+ * rtf.h - RTF document processing stuff.  Release 1.10.
+ */
+
+
+/*
+ * Twentieths of a point (twips) per inch (Many RTF measurements
+ * are in twips per inch (tpi) units).  Assumes 72 points/inch.
+ */
+
+# define	rtfTpi		1440
+
+/*
+ * RTF buffer size (avoids BUFSIZ, which differs across systems)
+ */
+
+# define	rtfBufSiz	1024
+
+/*
+ * Tokens are associated with up to three classification numbers:
+ *
+ * Class number: Broadest (least detailed) breakdown.  For programs
+ * 	that only care about gross token distinctions.
+ * Major/minor numbers: Within their class, tokens have a major
+ * 	number, and may also have a minor number to further
+ * 	distinquish tokens with the same major number.
+ *
+ *	*** Class, major and minor token numbers are all >= 0 ***
+ *
+ * Tokens that can't be classified are put in the "unknown" class.
+ * For such, the major and minor numbers are meaningless, although
+ * rtfTextBuf may be of interest then.
+ *
+ * Text tokens are a single character, and the major number indicates
+ * the character value (note: can be non-ascii, i.e., greater than 127).
+ * There is no minor number.
+ *
+ * Control symbols may have a parameter value, which will be found in
+ * rtfParam.  If no parameter was given, rtfParam = rtfNoParam.
+ *
+ * RTFGetToken() return value is the class number, but it sets all the
+ * global token vars.
+ *
+ * rtfEOF is a fake token used by the reader; the writer never sees
+ * it (except in the token reader hook, if it installs one).
+ */
+
+
+# ifdef THINK_C
+# define	rtfNoParam	(-32768)	/* 16-bit max. neg. value */
+# endif
+# ifndef rtfNoParam
+# define	rtfNoParam	(-1000000)
+# endif
+
+
+
+
+/*
+ * For some reason, the no-style number is 222
+ */
+
+# define	rtfNoStyleNum		222
+# define	rtfNormalStyleNum	0
+
+
+/*
+ * Token classes (must be zero-based and sequential)
+ */
+
+# define	rtfUnknown	0
+# define	rtfGroup	1
+# define	rtfText		2
+# define	rtfControl	3
+# define	rtfEOF		4
+# define	rtfMaxClass	5	/* highest class + 1 */
+
+/*
+ * Group class major numbers
+ */
+
+# define	rtfBeginGroup	0
+# define	rtfEndGroup	1
+
+/*
+ * Control class major and minor numbers.
+ */
+
+# define	rtfVersion	0
+
+# define	rtfDefFont	1
+
+# define	rtfCharSet	2
+# define		rtfAnsiCharSet		0
+# define		rtfMacCharSet		1
+# define		rtfPcCharSet		2
+# define		rtfPcaCharSet		3
+
+
+/* destination minor numbers should be zero-based and sequential */
+
+# define	rtfDestination	3
+# define		rtfFontTbl		0
+# define		rtfFontAltName		1	/* new in 1.10 */
+# define		rtfEmbeddedFont		2	/* new in 1.10 */
+# define		rtfFontFile		3	/* new in 1.10 */
+# define		rtfFileTbl		4	/* new in 1.10 */
+# define		rtfFileInfo		5	/* new in 1.10 */
+# define		rtfColorTbl		6
+# define		rtfStyleSheet		7
+# define		rtfKeyCode		8
+# define		rtfRevisionTbl		9	/* new in 1.10 */
+# define		rtfInfo			10
+# define		rtfITitle		11
+# define		rtfISubject		12
+# define		rtfIAuthor		13
+# define		rtfIOperator		14
+# define		rtfIKeywords		15
+# define		rtfIComment		16
+# define		rtfIVersion		17
+# define		rtfIDoccomm		18
+# define		rtfIVerscomm		19
+# define		rtfNextFile		20	/* reclassified in 1.10 */
+# define		rtfTemplate		21	/* reclassified in 1.10 */
+# define		rtfFNSep		22
+# define		rtfFNContSep		23
+# define		rtfFNContNotice		24
+# define		rtfENSep		25	/* new in 1.10 */
+# define		rtfENContSep		26	/* new in 1.10 */
+# define		rtfENContNotice		27	/* new in 1.10 */
+# define		rtfPageNumLevel		28	/* new in 1.10 */
+# define		rtfParNumLevelStyle	29	/* new in 1.10 */
+# define		rtfHeader		30
+# define		rtfFooter		31
+# define		rtfHeaderLeft		32
+# define		rtfHeaderRight		33
+# define		rtfHeaderFirst		34
+# define		rtfFooterLeft		35
+# define		rtfFooterRight		36
+# define		rtfFooterFirst		37
+# define		rtfParNumText		38	/* new in 1.10 */
+# define		rtfParNumbering		39	/* new in 1.10 */
+# define		rtfParNumTextAfter	40	/* new in 1.10 */
+# define		rtfParNumTextBefore	41	/* new in 1.10 */
+# define		rtfBookmarkStart	42
+# define		rtfBookmarkEnd		43
+# define		rtfPict			44
+# define		rtfObject		45
+# define		rtfObjClass		46
+# define		rtfObjName		47
+# define		rtfObjTime		48	/* new in 1.10 */
+# define		rtfObjData		49
+# define		rtfObjAlias		50
+# define		rtfObjSection		51
+# define		rtfObjResult		52
+# define		rtfObjItem		53	/* new in 1.10 */
+# define		rtfObjTopic		54	/* new in 1.10 */
+# define		rtfDrawObject		55	/* new in 1.10 */
+# define		rtfFootnote		56
+# define		rtfAnnotRefStart	57	/* new in 1.10 */
+# define		rtfAnnotRefEnd		58	/* new in 1.10 */
+# define		rtfAnnotID		59	/* reclassified in 1.10 */
+# define		rtfAnnotAuthor		60	/* new in 1.10 */
+# define		rtfAnnotation		61	/* reclassified in 1.10 */
+# define		rtfAnnotRef		62	/* new in 1.10 */
+# define		rtfAnnotTime		63	/* new in 1.10 */
+# define		rtfAnnotIcon		64	/* new in 1.10 */
+# define		rtfField		65
+# define		rtfFieldInst		66
+# define		rtfFieldResult		67
+# define		rtfDataField		68	/* new in 1.10 */
+# define		rtfIndex		69
+# define		rtfIndexText		70
+# define		rtfIndexRange		71
+# define		rtfTOC			72
+# define		rtfNeXTGraphic		73
+# define		rtfMaxDestination	74	/* highest dest + 1 */
+
+# define	rtfFontFamily	4
+# define		rtfFFNil		0
+# define		rtfFFRoman		1
+# define		rtfFFSwiss		2
+# define		rtfFFModern		3
+# define		rtfFFScript		4
+# define		rtfFFDecor		5
+# define		rtfFFTech		6
+# define		rtfFFBidirectional	7	/* new in 1.10 */
+
+# define	rtfColorName	5
+# define		rtfRed			0
+# define		rtfGreen		1
+# define		rtfBlue			2
+
+# define	rtfSpecialChar	6
+	/* special chars seen in \info destination */
+# define		rtfIIntVersion		0
+# define		rtfICreateTime		1
+# define		rtfIRevisionTime	2
+# define		rtfIPrintTime		3
+# define		rtfIBackupTime		4
+# define		rtfIEditTime		5
+# define		rtfIYear		6
+# define		rtfIMonth		7
+# define		rtfIDay			8
+# define		rtfIHour		9
+# define		rtfIMinute		10
+# define		rtfISecond		11	/* new in 1.10 */
+# define		rtfINPages		12
+# define		rtfINWords		13
+# define		rtfINChars		14
+# define		rtfIIntID		15
+	/* other special chars */
+# define		rtfCurHeadDate		16
+# define		rtfCurHeadDateLong	17
+# define		rtfCurHeadDateAbbrev	18
+# define		rtfCurHeadTime		19
+# define		rtfCurHeadPage		20
+# define		rtfSectNum		21	/* new in 1.10 */
+# define		rtfCurFNote		22
+# define		rtfCurAnnotRef		23
+# define		rtfFNoteSep		24
+# define		rtfFNoteCont		25
+# define		rtfCell			26
+# define		rtfRow			27
+# define		rtfPar			28
+# define		rtfSect			29
+# define		rtfPage			30
+# define		rtfColumn		31
+# define		rtfLine			32
+# define		rtfSoftPage		33	/* new in 1.10 */
+# define		rtfSoftColumn		34	/* new in 1.10 */
+# define		rtfSoftLine		35	/* new in 1.10 */
+# define		rtfSoftLineHt		36	/* new in 1.10 */
+# define		rtfTab			37
+# define		rtfEmDash		38
+# define		rtfEnDash		39
+# define		rtfEmSpace		40	/* new in 1.10 */
+# define		rtfEnSpace		41	/* new in 1.10 */
+# define		rtfBullet		42
+# define		rtfLQuote		43
+# define		rtfRQuote		44
+# define		rtfLDblQuote		45
+# define		rtfRDblQuote		46
+# define		rtfFormula		47
+# define		rtfNoBrkSpace		49
+# define		rtfNoReqHyphen		50
+# define		rtfNoBrkHyphen		51
+# define		rtfOptDest		52
+# define		rtfLTRMark		53	/* new in 1.10 */
+# define		rtfRTLMark		54	/* new in 1.10 */
+# define		rtfNoWidthJoiner	55	/* new in 1.10 */
+# define		rtfNoWidthNonJoiner	56	/* new in 1.10 */
+# define		rtfCurHeadPict		57	/* valid? */
+/*# define		rtfCurAnnot		58*/	/* apparently not used */
+
+# define	rtfStyleAttr	7
+# define		rtfAdditive		0	/* new in 1.10 */
+# define		rtfBasedOn		1
+# define		rtfNext			2
+
+# define	rtfDocAttr	8
+# define		rtfDefTab		0
+# define		rtfHyphHotZone		1
+# define		rtfHyphConsecLines	2	/* new in 1.10 */
+# define		rtfHyphCaps		3	/* new in 1.10 */
+# define		rtfHyphAuto		4	/* new in 1.10 */
+# define		rtfLineStart		5
+# define		rtfFracWidth		6
+# define		rtfMakeBackup		7
+# define		rtfRTFDefault		8
+# define		rtfPSOverlay		9
+# define		rtfDocTemplate		10	/* new in 1.10 */
+# define		rtfDefLanguage		11
+# define		rtfFENoteType		12	/* new in 1.10 */
+# define		rtfFNoteEndSect		13
+# define		rtfFNoteEndDoc		14
+# define		rtfFNoteText		15
+# define		rtfFNoteBottom		16
+# define		rtfENoteEndSect		17	/* new in 1.10 */
+# define		rtfENoteEndDoc		18	/* new in 1.10 */
+# define		rtfENoteText		19	/* new in 1.10 */
+# define		rtfENoteBottom		20	/* new in 1.10 */
+# define		rtfFNoteStart		21
+# define		rtfENoteStart		22	/* new in 1.10 */
+# define		rtfFNoteRestartPage	23	/* new in 1.10 */
+# define		rtfFNoteRestart		24
+# define		rtfFNoteRestartCont	25	/* new in 1.10 */
+# define		rtfENoteRestart		26	/* new in 1.10 */
+# define		rtfENoteRestartCont	27	/* new in 1.10 */
+# define		rtfFNoteNumArabic	28	/* new in 1.10 */
+# define		rtfFNoteNumLLetter	29	/* new in 1.10 */
+# define		rtfFNoteNumULetter	30	/* new in 1.10 */
+# define		rtfFNoteNumLRoman	31	/* new in 1.10 */
+# define		rtfFNoteNumURoman	32	/* new in 1.10 */
+# define		rtfFNoteNumChicago	33	/* new in 1.10 */
+# define		rtfENoteNumArabic	34	/* new in 1.10 */
+# define		rtfENoteNumLLetter	35	/* new in 1.10 */
+# define		rtfENoteNumULetter	36	/* new in 1.10 */
+# define		rtfENoteNumLRoman	37	/* new in 1.10 */
+# define		rtfENoteNumURoman	38	/* new in 1.10 */
+# define		rtfENoteNumChicago	39	/* new in 1.10 */
+# define		rtfPaperWidth		40
+# define		rtfPaperHeight		41
+# define		rtfPaperSize		42	/* new in 1.10 */
+# define		rtfLeftMargin		43
+# define		rtfRightMargin		44
+# define		rtfTopMargin		45
+# define		rtfBottomMargin		46
+# define		rtfFacingPage		47
+# define		rtfGutterWid		48
+# define		rtfMirrorMargin		49
+# define		rtfLandscape		50
+# define		rtfPageStart		51
+# define		rtfWidowCtrl		52
+# define		rtfLinkStyles		53	/* new in 1.10 */
+# define		rtfNoAutoTabIndent	54	/* new in 1.10 */
+# define		rtfWrapSpaces		55	/* new in 1.10 */
+# define		rtfPrintColorsBlack	56	/* new in 1.10 */
+# define		rtfNoExtraSpaceRL	57	/* new in 1.10 */
+# define		rtfNoColumnBalance	58	/* new in 1.10 */
+# define		rtfCvtMailMergeQuote	59	/* new in 1.10 */
+# define		rtfSuppressTopSpace	60	/* new in 1.10 */
+# define		rtfSuppressPreParSpace	61	/* new in 1.10 */
+# define		rtfCombineTblBorders	62	/* new in 1.10 */
+# define		rtfTranspMetafiles	63	/* new in 1.10 */
+# define		rtfSwapBorders		64	/* new in 1.10 */
+# define		rtfShowHardBreaks	65	/* new in 1.10 */
+# define		rtfFormProtected	66	/* new in 1.10 */
+# define		rtfAllProtected		67	/* new in 1.10 */
+# define		rtfFormShading		68	/* new in 1.10 */
+# define		rtfFormDisplay		69	/* new in 1.10 */
+# define		rtfPrintData		70	/* new in 1.10 */
+# define		rtfRevProtected		71	/* new in 1.10 */
+# define		rtfRevisions		72
+# define		rtfRevDisplay		73
+# define		rtfRevBar		74
+# define		rtfAnnotProtected	75	/* new in 1.10 */
+# define		rtfRTLDoc		76	/* new in 1.10 */
+# define		rtfLTRDoc		77	/* new in 1.10 */
+
+# define	rtfSectAttr	9
+# define		rtfSectDef		0
+# define		rtfENoteHere		1
+# define		rtfPrtBinFirst		2
+# define		rtfPrtBin		3
+# define		rtfSectStyleNum		4	/* new in 1.10 */
+# define		rtfNoBreak		5
+# define		rtfColBreak		6
+# define		rtfPageBreak		7
+# define		rtfEvenBreak		8
+# define		rtfOddBreak		9
+# define		rtfColumns		10
+# define		rtfColumnSpace		11
+# define		rtfColumnNumber		12	/* new in 1.10 */
+# define		rtfColumnSpRight	13	/* new in 1.10 */
+# define		rtfColumnWidth		14	/* new in 1.10 */
+# define		rtfColumnLine		15
+# define		rtfLineModulus		16
+# define		rtfLineDist		17
+# define		rtfLineStarts		18
+# define		rtfLineRestart		19
+# define		rtfLineRestartPg	20
+# define		rtfLineCont		21
+# define		rtfSectPageWid		22
+# define		rtfSectPageHt		23
+# define		rtfSectMarginLeft	24
+# define		rtfSectMarginRight	25
+# define		rtfSectMarginTop	26
+# define		rtfSectMarginBottom	27
+# define		rtfSectMarginGutter	28
+# define		rtfSectLandscape	29
+# define		rtfTitleSpecial		30
+# define		rtfHeaderY		31
+# define		rtfFooterY		32
+# define		rtfPageStarts		33
+# define		rtfPageCont		34
+# define		rtfPageRestart		35
+# define		rtfPageNumRight		36	/* renamed in 1.10 */
+# define		rtfPageNumTop		37
+# define		rtfPageDecimal		38
+# define		rtfPageURoman		39
+# define		rtfPageLRoman		40
+# define		rtfPageULetter		41
+# define		rtfPageLLetter		42
+# define		rtfPageNumHyphSep	43	/* new in 1.10 */
+# define		rtfPageNumSpaceSep	44	/* new in 1.10 */
+# define		rtfPageNumColonSep	45	/* new in 1.10 */
+# define		rtfPageNumEmdashSep	46	/* new in 1.10 */
+# define		rtfPageNumEndashSep	47	/* new in 1.10 */
+# define		rtfTopVAlign		48
+# define		rtfBottomVAlign		49
+# define		rtfCenterVAlign		50
+# define		rtfJustVAlign		51
+# define		rtfRTLSect		52	/* new in 1.10 */
+# define		rtfLTRSect		53	/* new in 1.10 */
+
+# define	rtfTblAttr	10
+# define		rtfRowDef		0
+# define		rtfRowGapH		1
+# define		rtfCellPos		2
+# define		rtfMergeRngFirst	3
+# define		rtfMergePrevious	4
+# define		rtfRowLeft		5
+# define		rtfRowRight		6
+# define		rtfRowCenter		7
+# define		rtfRowLeftEdge		8
+# define		rtfRowHt		9
+# define		rtfRowHeader		10	/* new in 1.10 */
+# define		rtfRowKeep		11	/* new in 1.10 */
+# define		rtfRTLRow		12	/* new in 1.10 */
+# define		rtfLTRRow		13	/* new in 1.10 */
+# define		rtfRowBordTop		14	/* new in 1.10 */
+# define		rtfRowBordLeft		15	/* new in 1.10 */
+# define		rtfRowBordBottom	16	/* new in 1.10 */
+# define		rtfRowBordRight		17	/* new in 1.10 */
+# define		rtfRowBordHoriz		18	/* new in 1.10 */
+# define		rtfRowBordVert		19	/* new in 1.10 */
+# define		rtfCellBordBottom	20
+# define		rtfCellBordTop		21
+# define		rtfCellBordLeft		22
+# define		rtfCellBordRight	23
+# define		rtfCellShading		24
+# define		rtfCellBgPatH		25
+# define		rtfCellBgPatV		26
+# define		rtfCellFwdDiagBgPat	27
+# define		rtfCellBwdDiagBgPat	28
+# define		rtfCellHatchBgPat	29
+# define		rtfCellDiagHatchBgPat	30
+# define		rtfCellDarkBgPatH	31
+# define		rtfCellDarkBgPatV	32
+# define		rtfCellFwdDarkBgPat	33
+# define		rtfCellBwdDarkBgPat	34
+# define		rtfCellDarkHatchBgPat	35
+# define		rtfCellDarkDiagHatchBgPat 36
+# define		rtfCellBgPatLineColor	37
+# define		rtfCellBgPatColor	38
+
+# define	rtfParAttr	11
+# define		rtfParDef		0
+# define		rtfStyleNum		1
+# define		rtfHyphenate		2	/* new in 1.10 */
+# define		rtfInTable		3
+# define		rtfKeep			4
+# define		rtfNoWidowControl	5	/* new in 1.10 */
+# define		rtfKeepNext		6
+# define		rtfOutlineLevel		7	/* new in 1.10 */
+# define		rtfNoLineNum		8
+# define		rtfPBBefore		9
+# define		rtfSideBySide		10
+# define		rtfQuadLeft		11
+# define		rtfQuadRight		12
+# define		rtfQuadJust		13
+# define		rtfQuadCenter		14
+# define		rtfFirstIndent		15
+# define		rtfLeftIndent		16
+# define		rtfRightIndent		17
+# define		rtfSpaceBefore		18
+# define		rtfSpaceAfter		19
+# define		rtfSpaceBetween		20
+# define		rtfSpaceMultiply	21	/* new in 1.10 */
+# define		rtfSubDocument		22	/* new in 1.10 */
+# define		rtfRTLPar		23	/* new in 1.10 */
+# define		rtfLTRPar		24	/* new in 1.10 */
+# define		rtfTabPos		25
+# define		rtfTabLeft		26	/* new in 1.10 */
+# define		rtfTabRight		27
+# define		rtfTabCenter		28
+# define		rtfTabDecimal		29
+# define		rtfTabBar		30
+# define		rtfLeaderDot		31
+# define		rtfLeaderHyphen		32
+# define		rtfLeaderUnder		33
+# define		rtfLeaderThick		34
+# define		rtfLeaderEqual		35
+# define		rtfParLevel		36	/* new in 1.10 */
+# define		rtfParBullet		37	/* new in 1.10 */
+# define		rtfParSimple		38	/* new in 1.10 */
+# define		rtfParNumCont		39	/* new in 1.10 */
+# define		rtfParNumOnce		40	/* new in 1.10 */
+# define		rtfParNumAcross		41	/* new in 1.10 */
+# define		rtfParHangIndent	42	/* new in 1.10 */
+# define		rtfParNumRestart	43	/* new in 1.10 */
+# define		rtfParNumCardinal	44	/* new in 1.10 */
+# define		rtfParNumDecimal	45	/* new in 1.10 */
+# define		rtfParNumULetter	46	/* new in 1.10 */
+# define		rtfParNumURoman		47	/* new in 1.10 */
+# define		rtfParNumLLetter	48	/* new in 1.10 */
+# define		rtfParNumLRoman		49	/* new in 1.10 */
+# define		rtfParNumOrdinal	50	/* new in 1.10 */
+# define		rtfParNumOrdinalText	51	/* new in 1.10 */
+# define		rtfParNumBold		52	/* new in 1.10 */
+# define		rtfParNumItalic		53	/* new in 1.10 */
+# define		rtfParNumAllCaps	54	/* new in 1.10 */
+# define		rtfParNumSmallCaps	55	/* new in 1.10 */
+# define		rtfParNumUnder		56	/* new in 1.10 */
+# define		rtfParNumDotUnder	57	/* new in 1.10 */
+# define		rtfParNumDbUnder	58	/* new in 1.10 */
+# define		rtfParNumNoUnder	59	/* new in 1.10 */
+# define		rtfParNumWordUnder	60	/* new in 1.10 */
+# define		rtfParNumStrikethru	61	/* new in 1.10 */
+# define		rtfParNumForeColor	62	/* new in 1.10 */
+# define		rtfParNumFont		63	/* new in 1.10 */
+# define		rtfParNumFontSize	64	/* new in 1.10 */
+# define		rtfParNumIndent		65	/* new in 1.10 */
+# define		rtfParNumSpacing	66	/* new in 1.10 */
+# define		rtfParNumInclPrev	67	/* new in 1.10 */
+# define		rtfParNumCenter		68	/* new in 1.10 */
+# define		rtfParNumLeft		69	/* new in 1.10 */
+# define		rtfParNumRight		70	/* new in 1.10 */
+# define		rtfParNumStartAt	71	/* new in 1.10 */
+# define		rtfBorderTop		72
+# define		rtfBorderBottom		73
+# define		rtfBorderLeft		74
+# define		rtfBorderRight		75
+# define		rtfBorderBetween	76
+# define		rtfBorderBar		77
+# define		rtfBorderBox		78
+# define		rtfBorderSingle		79
+# define		rtfBorderThick		80
+# define		rtfBorderShadow		81
+# define		rtfBorderDouble		82
+# define		rtfBorderDot		83
+# define		rtfBorderDash		84	/* new in 1.10 */
+# define		rtfBorderHair		85
+# define		rtfBorderWidth		86
+# define		rtfBorderColor		87
+# define		rtfBorderSpace		88
+# define		rtfShading		89
+# define		rtfBgPatH		90
+# define		rtfBgPatV		91
+# define		rtfFwdDiagBgPat		92
+# define		rtfBwdDiagBgPat		93
+# define		rtfHatchBgPat		94
+# define		rtfDiagHatchBgPat	95
+# define		rtfDarkBgPatH		96
+# define		rtfDarkBgPatV		97
+# define		rtfFwdDarkBgPat		98
+# define		rtfBwdDarkBgPat		99
+# define		rtfDarkHatchBgPat	100
+# define		rtfDarkDiagHatchBgPat	101
+# define		rtfBgPatLineColor	102
+# define		rtfBgPatColor		103
+
+# define	rtfCharAttr	12
+# define		rtfPlain		0
+# define		rtfBold			1
+# define		rtfAllCaps		2
+# define		rtfDeleted		3
+# define		rtfSubScript		4
+# define		rtfSubScrShrink		5	/* new in 1.10 */
+# define		rtfNoSuperSub		6	/* new in 1.10 */
+# define		rtfExpand		7
+# define		rtfExpandTwips		8	/* new in 1.10 */
+# define		rtfKerning		9	/* new in 1.10 */
+# define		rtfFontNum		10
+# define		rtfFontSize		11
+# define		rtfItalic		12
+# define		rtfOutline		13
+# define		rtfRevised		14
+# define		rtfRevAuthor		15	/* new in 1.10 */
+# define		rtfRevDTTM		16	/* new in 1.10 */
+# define		rtfSmallCaps		17
+# define		rtfShadow		18
+# define		rtfStrikeThru		19
+# define		rtfUnderline		20
+# define		rtfDotUnderline		21	/* renamed in 1.10 */
+# define		rtfDbUnderline		22
+# define		rtfNoUnderline		23
+# define		rtfWordUnderline	24	/* renamed in 1.10 */
+# define		rtfSuperScript		25
+# define		rtfSuperScrShrink	26	/* new in 1.10 */
+# define		rtfInvisible		27
+# define		rtfForeColor		28
+# define		rtfBackColor		29
+# define		rtfRTLChar		30	/* new in 1.10 */
+# define		rtfLTRChar		31	/* new in 1.10 */
+# define		rtfCharStyleNum		32	/* new in 1.10 */
+# define		rtfCharCharSet		33	/* new in 1.10 */
+# define		rtfLanguage		34
+# define		rtfGray			35
+
+# define	rtfPictAttr	13
+# define		rtfMacQD		0
+# define		rtfPMMetafile		1
+# define		rtfWinMetafile		2
+# define		rtfDevIndBitmap		3
+# define		rtfWinBitmap		4
+# define		rtfPixelBits		5
+# define		rtfBitmapPlanes		6
+# define		rtfBitmapWid		7
+# define		rtfPicWid		8
+# define		rtfPicHt		9
+# define		rtfPicGoalWid		10
+# define		rtfPicGoalHt		11
+# define		rtfPicScaleX		12
+# define		rtfPicScaleY		13
+# define		rtfPicScaled		14
+# define		rtfPicCropTop		15
+# define		rtfPicCropBottom	16
+# define		rtfPicCropLeft		17
+# define		rtfPicCropRight		18
+# define		rtfPicMFHasBitmap	19	/* new in 1.10 */
+# define		rtfPicMFBitsPerPixel	20	/* new in 1.10 */
+# define		rtfPicBinary		21
+
+# define	rtfBookmarkAttr	14
+# define		rtfBookmarkFirstCol	0
+# define		rtfBookmarkLastCol	1
+
+# define	rtfNeXTGrAttr	15
+# define		rtfNeXTGWidth		0
+# define		rtfNeXTGHeight		1
+
+# define	rtfFieldAttr	16
+# define		rtfFieldDirty		0
+# define		rtfFieldEdited		1
+# define		rtfFieldLocked		2
+# define		rtfFieldPrivate		3
+# define		rtfFieldAlt		4	/* new in 1.10 */
+
+# define	rtfTOCAttr	17
+# define		rtfTOCType		0
+# define		rtfTOCLevel		1
+
+# define	rtfPosAttr	18
+# define		rtfAbsWid		0
+# define		rtfAbsHt		1
+# define		rtfRPosMargH		2
+# define		rtfRPosPageH		3
+# define		rtfRPosColH		4
+# define		rtfPosX			5
+# define		rtfPosNegX		6	/* new in 1.10 */
+# define		rtfPosXCenter		7
+# define		rtfPosXInside		8
+# define		rtfPosXOutSide		9
+# define		rtfPosXRight		10
+# define		rtfPosXLeft		11
+# define		rtfRPosMargV		12
+# define		rtfRPosPageV		13
+# define		rtfRPosParaV		14
+# define		rtfPosY			15
+# define		rtfPosNegY		16	/* new in 1.10 */
+# define		rtfPosYInline		17
+# define		rtfPosYTop		18
+# define		rtfPosYCenter		19
+# define		rtfPosYBottom		20
+# define		rtfNoWrap		21
+# define		rtfDistFromTextAll	22	/* renamed in 1.10 */
+# define		rtfDistFromTextX	23	/* new in 1.10 */
+# define		rtfDistFromTextY	24	/* new in 1.10 */
+# define		rtfTextDistY		25
+# define		rtfDropCapLines		26	/* new in 1.10 */
+# define		rtfDropCapType		27	/* new in 1.10 */
+
+# define	rtfObjAttr	19
+# define		rtfObjEmb		0
+# define		rtfObjLink		1
+# define		rtfObjAutoLink		2
+# define		rtfObjSubscriber	3
+# define		rtfObjPublisher		4	/* new in 1.10 */
+# define		rtfObjICEmb		5
+# define		rtfObjLinkSelf		6
+# define		rtfObjLock		7
+# define		rtfObjUpdate		8	/* new in 1.10 */
+# define		rtfObjHt		9
+# define		rtfObjWid		10
+# define		rtfObjSetSize		11
+# define		rtfObjAlign		12	/* new in 1.10 */
+# define		rtfObjTransposeY	13
+# define		rtfObjCropTop		14
+# define		rtfObjCropBottom	15
+# define		rtfObjCropLeft		16
+# define		rtfObjCropRight		17
+# define		rtfObjScaleX		18
+# define		rtfObjScaleY		19
+# define		rtfObjResRTF		20
+# define		rtfObjResPict		21
+# define		rtfObjResBitmap		22
+# define		rtfObjResText		23
+# define		rtfObjResMerge		24
+# define		rtfObjBookmarkPubObj	25
+# define		rtfObjPubAutoUpdate	26
+
+# define	rtfFNoteAttr	20			/* new in 1.10 */
+# define		rtfFNAlt		0	/* new in 1.10 */
+
+# define	rtfKeyCodeAttr	21			/* new in 1.10 */
+# define		rtfAltKey		0	/* new in 1.10 */
+# define		rtfShiftKey		1	/* new in 1.10 */
+# define		rtfControlKey		2	/* new in 1.10 */
+# define		rtfFunctionKey		3	/* new in 1.10 */
+
+# define	rtfACharAttr	22			/* new in 1.10 */
+# define		rtfACBold		0	/* new in 1.10 */
+# define		rtfACAllCaps		1	/* new in 1.10 */
+# define		rtfACForeColor		2	/* new in 1.10 */
+# define		rtfACSubScript		3	/* new in 1.10 */
+# define		rtfACExpand		4	/* new in 1.10 */
+# define		rtfACFontNum		5	/* new in 1.10 */
+# define		rtfACFontSize		6	/* new in 1.10 */
+# define		rtfACItalic		7	/* new in 1.10 */
+# define		rtfACLanguage		8	/* new in 1.10 */
+# define		rtfACOutline		9	/* new in 1.10 */
+# define		rtfACSmallCaps		10	/* new in 1.10 */
+# define		rtfACShadow		11	/* new in 1.10 */
+# define		rtfACStrikeThru		12	/* new in 1.10 */
+# define		rtfACUnderline		13	/* new in 1.10 */
+# define		rtfACDotUnderline	14	/* new in 1.10 */
+# define		rtfACDbUnderline	15	/* new in 1.10 */
+# define		rtfACNoUnderline	16	/* new in 1.10 */
+# define		rtfACWordUnderline	17	/* new in 1.10 */
+# define		rtfACSuperScript	18	/* new in 1.10 */
+
+# define	rtfFontAttr	23			/* new in 1.10 */
+# define		rtfFontCharSet		0	/* new in 1.10 */
+# define		rtfFontPitch		1	/* new in 1.10 */
+# define		rtfFontCodePage		2	/* new in 1.10 */
+# define		rtfFTypeNil		3	/* new in 1.10 */
+# define		rtfFTypeTrueType	4	/* new in 1.10 */
+
+# define	rtfFileAttr	24			/* new in 1.10 */
+# define		rtfFileNum		0	/* new in 1.10 */
+# define		rtfFileRelPath		1	/* new in 1.10 */
+# define		rtfFileOSNum		2	/* new in 1.10 */
+
+# define	rtfFileSource	25			/* new in 1.10 */
+# define		rtfSrcMacintosh		0	/* new in 1.10 */
+# define		rtfSrcDOS		1	/* new in 1.10 */
+# define		rtfSrcNTFS		2	/* new in 1.10 */
+# define		rtfSrcHPFS		3	/* new in 1.10 */
+# define		rtfSrcNetwork		4	/* new in 1.10 */
+
+/*
+ * Drawing attributes
+ */
+
+# define	rtfDrawAttr	26			/* new in 1.10 */
+# define		rtfDrawLock		0	/* new in 1.10 */
+# define		rtfDrawPageRelX		1	/* new in 1.10 */
+# define		rtfDrawColumnRelX	2	/* new in 1.10 */
+# define		rtfDrawMarginRelX	3	/* new in 1.10 */
+# define		rtfDrawPageRelY		4	/* new in 1.10 */
+# define		rtfDrawColumnRelY	5	/* new in 1.10 */
+# define		rtfDrawMarginRelY	6	/* new in 1.10 */
+# define		rtfDrawHeight		7	/* new in 1.10 */
+
+# define		rtfDrawBeginGroup	8	/* new in 1.10 */
+# define		rtfDrawGroupCount	9	/* new in 1.10 */
+# define		rtfDrawEndGroup		10	/* new in 1.10 */
+# define		rtfDrawArc		11	/* new in 1.10 */
+# define		rtfDrawCallout		12	/* new in 1.10 */
+# define		rtfDrawEllipse		13	/* new in 1.10 */
+# define		rtfDrawLine		14	/* new in 1.10 */
+# define		rtfDrawPolygon		15	/* new in 1.10 */
+# define		rtfDrawPolyLine		16	/* new in 1.10 */
+# define		rtfDrawRect		17	/* new in 1.10 */
+# define		rtfDrawTextBox		18	/* new in 1.10 */
+
+# define		rtfDrawOffsetX		19	/* new in 1.10 */
+# define		rtfDrawSizeX		20	/* new in 1.10 */
+# define		rtfDrawOffsetY		21	/* new in 1.10 */
+# define		rtfDrawSizeY		22	/* new in 1.10 */
+
+# define		rtfCOAngle		23	/* new in 1.10 */
+# define		rtfCOAccentBar		24	/* new in 1.10 */
+# define		rtfCOBestFit		25	/* new in 1.10 */
+# define		rtfCOBorder		26	/* new in 1.10 */
+# define		rtfCOAttachAbsDist	27	/* new in 1.10 */
+# define		rtfCOAttachBottom	28	/* new in 1.10 */
+# define		rtfCOAttachCenter	29	/* new in 1.10 */
+# define		rtfCOAttachTop		30	/* new in 1.10 */
+# define		rtfCOLength		31	/* new in 1.10 */
+# define		rtfCONegXQuadrant	32	/* new in 1.10 */
+# define		rtfCONegYQuadrant	33	/* new in 1.10 */
+# define		rtfCOOffset		34	/* new in 1.10 */
+# define		rtfCOAttachSmart	35	/* new in 1.10 */
+# define		rtfCODoubleLine		36	/* new in 1.10 */
+# define		rtfCORightAngle		37	/* new in 1.10 */
+# define		rtfCOSingleLine		38	/* new in 1.10 */
+# define		rtfCOTripleLine		39	/* new in 1.10 */
+
+# define		rtfDrawTextBoxMargin	40	/* new in 1.10 */
+# define		rtfDrawTextBoxText	41	/* new in 1.10 */
+# define		rtfDrawRoundRect	42	/* new in 1.10 */
+
+# define		rtfDrawPointX		43	/* new in 1.10 */
+# define		rtfDrawPointY		44	/* new in 1.10 */
+# define		rtfDrawPolyCount	45	/* new in 1.10 */
+
+# define		rtfDrawArcFlipX		46	/* new in 1.10 */
+# define		rtfDrawArcFlipY		47	/* new in 1.10 */
+
+# define		rtfDrawLineBlue		48	/* new in 1.10 */
+# define		rtfDrawLineGreen	49	/* new in 1.10 */
+# define		rtfDrawLineRed		50	/* new in 1.10 */
+# define		rtfDrawLinePalette	51	/* new in 1.10 */
+# define		rtfDrawLineDashDot	52	/* new in 1.10 */
+# define		rtfDrawLineDashDotDot	53	/* new in 1.10 */
+# define		rtfDrawLineDash		54	/* new in 1.10 */
+# define		rtfDrawLineDot		55	/* new in 1.10 */
+# define		rtfDrawLineGray		56	/* new in 1.10 */
+# define		rtfDrawLineHollow	57	/* new in 1.10 */
+# define		rtfDrawLineSolid	58	/* new in 1.10 */
+# define		rtfDrawLineWidth	59	/* new in 1.10 */
+
+# define		rtfDrawHollowEndArrow	60	/* new in 1.10 */
+# define		rtfDrawEndArrowLength	61	/* new in 1.10 */
+# define		rtfDrawSolidEndArrow	62	/* new in 1.10 */
+# define		rtfDrawEndArrowWidth	63	/* new in 1.10 */
+# define		rtfDrawHollowStartArrow	64	/* new in 1.10 */
+# define		rtfDrawStartArrowLength	65	/* new in 1.10 */
+# define		rtfDrawSolidStartArrow	66	/* new in 1.10 */
+# define		rtfDrawStartArrowWidth	67	/* new in 1.10 */
+
+# define		rtfDrawBgFillBlue	68	/* new in 1.10 */
+# define		rtfDrawBgFillGreen	69	/* new in 1.10 */
+# define		rtfDrawBgFillRed	70	/* new in 1.10 */
+# define		rtfDrawBgFillPalette	71	/* new in 1.10 */
+# define		rtfDrawBgFillGray	72	/* new in 1.10 */
+# define		rtfDrawFgFillBlue	73	/* new in 1.10 */
+# define		rtfDrawFgFillGreen	74	/* new in 1.10 */
+# define		rtfDrawFgFillRed	75	/* new in 1.10 */
+# define		rtfDrawFgFillPalette	76	/* new in 1.10 */
+# define		rtfDrawFgFillGray	77	/* new in 1.10 */
+# define		rtfDrawFillPatIndex	78	/* new in 1.10 */
+
+# define		rtfDrawShadow		79	/* new in 1.10 */
+# define		rtfDrawShadowXOffset	80	/* new in 1.10 */
+# define		rtfDrawShadowYOffset	81	/* new in 1.10 */
+
+/*
+ * index entry attributes
+ */
+
+# define	rtfIndexAttr	27			/* new in 1.10 */
+# define		rtfIndexNumber		0	/* new in 1.10 */
+# define		rtfIndexBold		1	/* reclassified in 1.10 */
+# define		rtfIndexItalic		2	/* reclassified in 1.10 */
+
+
+/*
+ * \wmetafile argument values
+ */
+
+# define	rtfWmMmText		1
+# define	rtfWmMmLometric		2
+# define	rtfWmMmHimetric		3
+# define	rtfWmMmLoenglish	4
+# define	rtfWmMmHienglish	5
+# define	rtfWmMmTwips		6
+# define	rtfWmMmIsotropic	7
+# define	rtfWmMmAnisotropic	8
+
+/*
+ * \pmmetafile argument values
+ */
+
+# define	rtfPmPuArbitrary	4
+# define	rtfPmPuPels		8
+# define	rtfPmPuLometric		12
+# define	rtfPmPuHimetric		16
+# define	rtfPmPuLoenglish	20
+# define	rtfPmPuHienglish	24
+# define	rtfPmPuTwips		28
+
+/*
+ * \lang argument values
+ */
+
+# define	rtfLangNoLang			0x0400
+# define	rtfLangAlbanian			0x041c
+# define	rtfLangArabic			0x0401
+# define	rtfLangBahasa			0x0421
+# define	rtfLangBelgianDutch		0x0813
+# define	rtfLangBelgianFrench		0x080c
+# define	rtfLangBrazilianPortuguese	0x0416
+# define	rtfLangBulgarian		0x0402
+# define	rtfLangCatalan			0x0403
+# define	rtfLangLatinCroatoSerbian	0x041a
+# define	rtfLangCzech			0x0405
+# define	rtfLangDanish			0x0406
+# define	rtfLangDutch			0x0413
+# define	rtfLangAustralianEnglish	0x0c09
+# define	rtfLangUKEnglish		0x0809
+# define	rtfLangUSEnglish		0x0409
+# define	rtfLangFinnish			0x040b
+# define	rtfLangFrench			0x040c
+# define	rtfLangCanadianFrench		0x0c0c
+# define	rtfLangGerman			0x0407
+# define	rtfLangGreek			0x0408
+# define	rtfLangHebrew			0x040d
+# define	rtfLangHungarian		0x040e
+# define	rtfLangIcelandic		0x040f
+# define	rtfLangItalian			0x0410
+# define	rtfLangJapanese			0x0411
+# define	rtfLangKorean			0x0412
+# define	rtfLangBokmalNorwegian		0x0414
+# define	rtfLangNynorskNorwegian		0x0814
+# define	rtfLangPolish			0x0415
+# define	rtfLangPortuguese		0x0816
+# define	rtfLangRhaetoRomanic		0x0417
+# define	rtfLangRomanian			0x0418
+# define	rtfLangRussian			0x0419
+# define	rtfLangCyrillicSerboCroatian	0x081a
+# define	rtfLangSimplifiedChinese	0x0804
+# define	rtfLangSlovak			0x041b
+# define	rtfLangCastilianSpanish		0x040a
+# define	rtfLangMexicanSpanish		0x080a
+# define	rtfLangSwedish			0x041d
+# define	rtfLangSwissFrench		0x100c
+# define	rtfLangSwissGerman		0x0807
+# define	rtfLangSwissItalian		0x0810
+# define	rtfLangThai			0x041e
+# define	rtfLangTraditionalChinese	0x0404
+# define	rtfLangTurkish			0x041f
+# define	rtfLangUrdu			0x0420
+
+/*
+ * CharSet indices
+ */
+
+# define	rtfCSGeneral	0	/* general (default) charset */
+# define	rtfCSSymbol	1	/* symbol charset */
+
+/*
+ * Flags for auto-charset-processing.  Both are on by default.
+ */
+
+# define	rtfReadCharSet		0x01	/* auto-read charset files */
+# define	rtfSwitchCharSet	0x02	/* auto-switch charset maps */
+
+/*
+ * Style types
+ */
+
+# define	rtfParStyle	0	/* the default */
+# define	rtfCharStyle	1
+# define	rtfSectStyle	2
+
+/*
+ * RTF font, color and style structures.  Used for font table,
+ * color table, and stylesheet processing.
+ */
+
+typedef struct RTFFont		RTFFont;
+typedef struct RTFColor		RTFColor;
+typedef struct RTFStyle		RTFStyle;
+typedef struct RTFStyleElt	RTFStyleElt;
+
+
+struct RTFFont
+{
+	char	*rtfFName;		/* font name */
+	char	*rtfFAltName;		/* font alternate name */
+	int	rtfFNum;		/* font number */
+	int	rtfFFamily;		/* font family */
+	int	rtfFCharSet;		/* font charset */
+	int	rtfFPitch;		/* font pitch */
+	int	rtfFType;		/* font type */
+	int	rtfFCodePage;		/* font code page */
+	RTFFont	*rtfNextFont;		/* next font in list */
+};
+
+
+/*
+ * Color values are -1 if the default color for the the color
+ * number should be used.  The default color is writer-dependent.
+ */
+
+struct RTFColor
+{
+	int		rtfCNum;	/* color number */
+	int		rtfCRed;	/* red value */
+	int		rtfCGreen;	/* green value */
+	int		rtfCBlue;	/* blue value */
+	RTFColor	*rtfNextColor;	/* next color in list */
+};
+
+
+struct RTFStyle
+{
+	char		*rtfSName;	/* style name */
+	int		rtfSType;	/* style type */
+	int		rtfSAdditive;	/* whether or not style is additive */
+	int		rtfSNum;	/* style number */
+	int		rtfSBasedOn;	/* style this one's based on */
+	int		rtfSNextPar;	/* style next paragraph style */
+	RTFStyleElt	*rtfSSEList;	/* list of style words */
+	int		rtfExpanding;	/* non-zero = being expanded */
+	RTFStyle	*rtfNextStyle;	/* next style in style list */
+};
+
+
+struct RTFStyleElt
+{
+	int		rtfSEClass;	/* token class */
+	int		rtfSEMajor;	/* token major number */
+	int		rtfSEMinor;	/* token minor number */
+	int		rtfSEParam;	/* control symbol parameter */
+	char		*rtfSEText;	/* text of symbol */
+	RTFStyleElt	*rtfNextSE;	/* next element in style */
+};
+
+
+/*
+ * Return pointer to new element of type t, or NULL
+ * if no memory available.
+ */
+
+# define        New(t)  ((t *) RTFAlloc ((int) sizeof (t)))
+
+/* maximum number of character values representable in a byte */
+
+# define        charSetSize             256
+
+/* charset stack size */
+
+# define        maxCSStack              10
+
+
+struct _RTF_Info;
+typedef struct _RTF_Info RTF_Info;
+
+typedef	void (*RTFFuncPtr) (RTF_Info *);		/* generic function pointer */
+
+struct _RTF_Info {
+    /*
+     * Public variables (listed in rtf.h)
+     */
+
+    /*
+     * Information pertaining to last token read by RTFToken.  The
+     * text is exactly as it occurs in the input file, e.g., "\{"
+     * will be found in rtfTextBuf as "\{", even though it means "{".
+     * These variables are also set when styles are reprocessed.
+     */
+
+    int	rtfClass;
+    int	rtfMajor;
+    int	rtfMinor;
+    int	rtfParam;
+    int rtfFormat;
+    char *rtfTextBuf;
+    int	rtfTextLen;
+
+    long rtfLineNum;
+    int	rtfLinePos;
+
+
+    /*
+     * Private stuff
+     */
+
+    int	pushedChar;	/* pushback char if read too far */
+
+    int	pushedClass;	/* pushed token info for RTFUngetToken() */
+    int	pushedMajor;
+    int	pushedMinor;
+    int	pushedParam;
+    char *pushedTextBuf;
+
+    int	prevChar;
+    int	bumpLine;
+
+    RTFFont	*fontList;	/* these lists MUST be */
+    RTFColor	*colorList;	/* initialized to NULL */
+    RTFStyle	*styleList;
+
+    char *inputName;
+    char *outputName;
+
+    EDITSTREAM editstream;
+    char InputBuffer[0x1000];
+    DWORD dwInputSize;
+    DWORD dwInputUsed;
+
+    /* edit window to output to */
+    HWND hwndEdit;
+
+    /*
+     * These arrays are used to map RTF input character values onto the standard
+     * character names represented by the values.  Input character values are
+     * used as indices into the arrays to produce standard character codes.
+     */
+
+
+    char *genCharSetFile ;
+    int	genCharCode[charSetSize];	/* general */
+    int	haveGenCharSet;
+
+    char *symCharSetFile;
+    int	symCharCode[charSetSize];	/* symbol */
+    int	haveSymCharSet;
+
+    int	curCharSet;
+    int	*curCharCode;
+
+    /*
+     * By default, the reader is configured to handle charset mapping invisibly,
+     * including reading the charset files and switching charset maps as necessary
+     * for Symbol font.
+     */
+
+    int	autoCharSetFlags;
+
+    /*
+     * Stack for keeping track of charset map on group begin/end.  This is
+     * necessary because group termination reverts the font to the previous
+     * value, which may implicitly change it.
+     */
+
+    int	csStack[maxCSStack];
+    int	csTop;
+
+    RTFFuncPtr       ccb[rtfMaxClass];               /* class callbacks */
+
+    RTFFuncPtr       dcb[rtfMaxDestination]; /* destination callbacks */
+
+    RTFFuncPtr       readHook;
+
+    RTFFuncPtr       panicProc;
+
+    FILE     *(*libFileOpen) ();
+
+    char     *outMap[rtfSC_MaxChar];
+
+    DWORD    dwOutputCount;
+    char     OutputBuffer[0x1000];
+};
+
+
+/*
+ * Public RTF reader routines
+ */
+
+void		RTFInit (RTF_Info *);
+void		RTFSetInputName (RTF_Info *, char *);
+char		*RTFGetInputName (RTF_Info *);
+void		RTFSetOutputName (RTF_Info *, char *);
+char		*RTFGetOutputName (RTF_Info *);
+void		RTFSetClassCallback (RTF_Info *, int, RTFFuncPtr);
+RTFFuncPtr	RTFGetClassCallback (RTF_Info *, int);
+void		RTFSetDestinationCallback (RTF_Info *, int, RTFFuncPtr);
+RTFFuncPtr	RTFGetDestinationCallback (RTF_Info *, int);
+void		RTFRead (RTF_Info *);
+int		RTFGetToken (RTF_Info *);	/* writer should rarely need this */
+void		RTFUngetToken (RTF_Info *);
+int		RTFPeekToken (RTF_Info *);
+void		RTFSetToken (RTF_Info *, int, int, int, int, const char *);
+void		RTFSetReadHook (RTF_Info *, RTFFuncPtr);
+RTFFuncPtr	RTFGetReadHook (RTF_Info *);
+void		RTFRouteToken (RTF_Info *);
+void		RTFSkipGroup (RTF_Info *);
+void		RTFExpandStyle (RTF_Info *, int);
+int		RTFCheckCM (RTF_Info *, int, int);
+int		RTFCheckCMM (RTF_Info *, int, int, int);
+int		RTFCheckMM (RTF_Info *, int, int);
+RTFFont		*RTFGetFont (RTF_Info *, int);
+RTFColor	*RTFGetColor (RTF_Info *, int);
+RTFStyle	*RTFGetStyle (RTF_Info *, int);
+# define	RTFAlloc(size)	_RTFAlloc ((int) size)
+char		*_RTFAlloc (int);
+char		*RTFStrSave (char *);
+void		RTFFree (char *);
+int		RTFCharToHex ( char);
+int		RTFHexToChar ( int );
+void		RTFSetMsgProc ( RTFFuncPtr );
+void		RTFSetPanicProc ( RTF_Info *, RTFFuncPtr);
+
+/*
+ * The following messing around is used to allow RTFMsg() and RTFPanic()
+ * to be variable-argument functions that are declared publicly but
+ * without generating prototype-mismatch errors on systems that have
+ * stdarg.h.
+ */
+
+void	RTFMsg (RTF_Info *, const char *fmt, ...);
+void	RTFPanic (RTF_Info *, const char *fmt, ...);
+
+int 	    	RTFReadOutputMap ( RTF_Info *, char *[], int);
+int		RTFReadCharSetMap ( RTF_Info *, int);
+void		RTFSetCharSetMap ( RTF_Info *, char *, int);
+int		RTFStdCharCode ( RTF_Info *, const char *);
+const char	*RTFStdCharName ( RTF_Info *, int);
+int		RTFMapChar ( RTF_Info *, int);
+int		RTFGetCharSet( RTF_Info * );
+void		RTFSetCharSet( RTF_Info *, int);
+
+void	RTFSetOpenLibFileProc ( RTF_Info *, FILE *(*)());
+FILE	*RTFOpenLibFile ( RTF_Info *, char *, char *);
+
+void	RTFFlushOutputBuffer( RTF_Info *info );
+void	RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
+
+void	WriterInit (RTF_Info *);
+int	BeginFile (RTF_Info *);
+
+#endif


More information about the wine-patches mailing list