| 1 | /* | 
|---|
| 2 | * - Need to document error code meanings. | 
|---|
| 3 | * - Need to do something with \* on destinations. | 
|---|
| 4 | * - Make the parameter a long? | 
|---|
| 5 | * | 
|---|
| 6 | * reader.c - RTF file reader.  Release 1.10. | 
|---|
| 7 | * | 
|---|
| 8 | * ASCII 10 (\n) and 13 (\r) are ignored and silently discarded. | 
|---|
| 9 | * Nulls are also discarded. | 
|---|
| 10 | * (although the read hook will still get a look at them.) | 
|---|
| 11 | * | 
|---|
| 12 | * "\:" is not a ":", it's a control symbol.  But some versions of | 
|---|
| 13 | * Word seem to write "\:" for ":".  This reader treats "\:" as a | 
|---|
| 14 | * plain text ":" | 
|---|
| 15 | * | 
|---|
| 16 | * 19 Mar 93 | 
|---|
| 17 | * - Add hack to skip "{\*\keycode ... }" group in stylesheet. | 
|---|
| 18 | * This is probably the wrong thing to do, but it's simple. | 
|---|
| 19 | * 13 Jul 93 | 
|---|
| 20 | * - Add THINK C awareness to malloc() declaration.  Necessary so | 
|---|
| 21 | * compiler knows the malloc argument is 4 bytes.  Ugh. | 
|---|
| 22 | * 07 Sep 93 | 
|---|
| 23 | * - Text characters are mapped onto standard codes, which are placed | 
|---|
| 24 | * in rtfMinor. | 
|---|
| 25 | * - Eliminated use of index() function. | 
|---|
| 26 | * 05 Mar 94 | 
|---|
| 27 | * - Added zillions of new symbols (those defined in RTF spec 1.2). | 
|---|
| 28 | * 14 Mar 94 | 
|---|
| 29 | * - Public functions RTFMsg() and RTFPanic() now take variable arguments. | 
|---|
| 30 | * This means RTFPanic() now is used in place of what was formerly the | 
|---|
| 31 | * internal function Error(). | 
|---|
| 32 | * - 8-bit characters are now legal, so they're not converted to \'xx | 
|---|
| 33 | * hex char representation now. | 
|---|
| 34 | * 01 Apr 94 | 
|---|
| 35 | * - Added public variables rtfLineNum and rtfLinePos. | 
|---|
| 36 | * - #include string.h or strings.h, avoiding strncmp() problem where | 
|---|
| 37 | * last argument is treated as zero when prototype isn't available. | 
|---|
| 38 | * 04 Apr 94 | 
|---|
| 39 | * - Treat style numbers 222 and 0 properly as "no style" and "normal". | 
|---|
| 40 | * | 
|---|
| 41 | * Author: Paul DuBois  dubois@primate.wisc.edu | 
|---|
| 42 | * | 
|---|
| 43 | * This software may be redistributed without restriction and used for | 
|---|
| 44 | * any purpose whatsoever. | 
|---|
| 45 | */ | 
|---|
| 46 |  | 
|---|
| 47 | # ifndef STRING_H | 
|---|
| 48 | # define STRING_H <string.h> | 
|---|
| 49 | # endif | 
|---|
| 50 |  | 
|---|
| 51 | # include       <stdio.h> | 
|---|
| 52 | # include       <ctype.h> | 
|---|
| 53 | # include       STRING_H | 
|---|
| 54 | # ifdef STDARG | 
|---|
| 55 | # include       <stdarg.h> | 
|---|
| 56 | # else | 
|---|
| 57 | # ifdef VARARGS | 
|---|
| 58 | # include       <varargs.h> | 
|---|
| 59 | # endif /* VARARGS */ | 
|---|
| 60 | # endif /* STDARG */ | 
|---|
| 61 |  | 
|---|
| 62 | # define        rtfInternal | 
|---|
| 63 | # include       "rtf.h" | 
|---|
| 64 | # undef         rtfInternal | 
|---|
| 65 |  | 
|---|
| 66 | /* | 
|---|
| 67 | *  include hard coded charsets | 
|---|
| 68 | */ | 
|---|
| 69 |  | 
|---|
| 70 | #include "ansi_gen.h" | 
|---|
| 71 | #include "ansi_sym.h" | 
|---|
| 72 | #include "text_map.h" | 
|---|
| 73 |  | 
|---|
| 74 | #include <stdlib.h> | 
|---|
| 75 |  | 
|---|
| 76 | #include "charlist.h" | 
|---|
| 77 | #include "windef.h" | 
|---|
| 78 | #include "winbase.h" | 
|---|
| 79 | #include "wine/debug.h" | 
|---|
| 80 |  | 
|---|
| 81 | WINE_DEFAULT_DEBUG_CHANNEL(richedit); | 
|---|
| 82 |  | 
|---|
| 83 | #ifdef __WIN32OS2__ /* no useful trace in this file! */ | 
|---|
| 84 | #define TRACE(a) do {} while (0) | 
|---|
| 85 | #endif | 
|---|
| 86 |  | 
|---|
| 87 | extern HANDLE RICHED32_hHeap; | 
|---|
| 88 |  | 
|---|
| 89 | /* | 
|---|
| 90 | * Return pointer to new element of type t, or NULL | 
|---|
| 91 | * if no memory available. | 
|---|
| 92 | */ | 
|---|
| 93 |  | 
|---|
| 94 | # define        New(t)  ((t *) RTFAlloc ((int) sizeof (t))) | 
|---|
| 95 |  | 
|---|
| 96 | /* maximum number of character values representable in a byte */ | 
|---|
| 97 |  | 
|---|
| 98 | # define        charSetSize             256 | 
|---|
| 99 |  | 
|---|
| 100 | /* charset stack size */ | 
|---|
| 101 |  | 
|---|
| 102 | # define        maxCSStack              10 | 
|---|
| 103 |  | 
|---|
| 104 | static int      _RTFGetChar(); | 
|---|
| 105 | static void     _RTFGetToken (); | 
|---|
| 106 | static void     _RTFGetToken2 (); | 
|---|
| 107 | static int      GetChar (); | 
|---|
| 108 | static void     ReadFontTbl (); | 
|---|
| 109 | static void     ReadColorTbl (); | 
|---|
| 110 | static void     ReadStyleSheet (); | 
|---|
| 111 | static void     ReadInfoGroup (); | 
|---|
| 112 | static void     ReadPictGroup (); | 
|---|
| 113 | static void     ReadObjGroup (); | 
|---|
| 114 | static void     LookupInit (); | 
|---|
| 115 | static void     Lookup (); | 
|---|
| 116 | static int      Hash (); | 
|---|
| 117 |  | 
|---|
| 118 | static void     CharSetInit (); | 
|---|
| 119 | static void     ReadCharSetMaps (); | 
|---|
| 120 |  | 
|---|
| 121 |  | 
|---|
| 122 | /* | 
|---|
| 123 | * Public variables (listed in rtf.h) | 
|---|
| 124 | */ | 
|---|
| 125 |  | 
|---|
| 126 | int     rtfClass; | 
|---|
| 127 | int     rtfMajor; | 
|---|
| 128 | int     rtfMinor; | 
|---|
| 129 | int     rtfParam; | 
|---|
| 130 | int     rtfFormat; | 
|---|
| 131 | char    *rtfTextBuf = (char *) NULL; | 
|---|
| 132 | int     rtfTextLen; | 
|---|
| 133 |  | 
|---|
| 134 | long    rtfLineNum; | 
|---|
| 135 | int     rtfLinePos; | 
|---|
| 136 |  | 
|---|
| 137 |  | 
|---|
| 138 | /* | 
|---|
| 139 | * Private stuff | 
|---|
| 140 | */ | 
|---|
| 141 |  | 
|---|
| 142 | static int      pushedChar;     /* pushback char if read too far */ | 
|---|
| 143 |  | 
|---|
| 144 | static int      pushedClass;    /* pushed token info for RTFUngetToken() */ | 
|---|
| 145 | static int      pushedMajor; | 
|---|
| 146 | static int      pushedMinor; | 
|---|
| 147 | static int      pushedParam; | 
|---|
| 148 | static char     *pushedTextBuf = (char *) NULL; | 
|---|
| 149 |  | 
|---|
| 150 | static int      prevChar; | 
|---|
| 151 | static int      bumpLine; | 
|---|
| 152 |  | 
|---|
| 153 | static RTFFont  *fontList = (RTFFont *) NULL;   /* these lists MUST be */ | 
|---|
| 154 | static RTFColor *colorList = (RTFColor *) NULL; /* initialized to NULL */ | 
|---|
| 155 | static RTFStyle *styleList = (RTFStyle *) NULL; | 
|---|
| 156 |  | 
|---|
| 157 | static char     *inputName = (char *) NULL; | 
|---|
| 158 | static char     *outputName = (char *) NULL; | 
|---|
| 159 |  | 
|---|
| 160 | static EDITSTREAM editstream; | 
|---|
| 161 | static CHARLIST inputCharList = {0, NULL, NULL}; | 
|---|
| 162 |  | 
|---|
| 163 | /* | 
|---|
| 164 | * This array is used to map standard character names onto their numeric codes. | 
|---|
| 165 | * The position of the name within the array is the code. | 
|---|
| 166 | * stdcharnames.h is generated in the ../h directory. | 
|---|
| 167 | */ | 
|---|
| 168 |  | 
|---|
| 169 | #include "stdcharnames.h" | 
|---|
| 170 |  | 
|---|
| 171 | /* | 
|---|
| 172 | * These arrays are used to map RTF input character values onto the standard | 
|---|
| 173 | * character names represented by the values.  Input character values are | 
|---|
| 174 | * used as indices into the arrays to produce standard character codes. | 
|---|
| 175 | */ | 
|---|
| 176 |  | 
|---|
| 177 |  | 
|---|
| 178 | static char     *genCharSetFile = (char *) NULL; | 
|---|
| 179 | static int      genCharCode[charSetSize];       /* general */ | 
|---|
| 180 | static int      haveGenCharSet = 0; | 
|---|
| 181 |  | 
|---|
| 182 | static char     *symCharSetFile = (char *) NULL; | 
|---|
| 183 | static int      symCharCode[charSetSize];       /* symbol */ | 
|---|
| 184 | static int      haveSymCharSet = 0; | 
|---|
| 185 |  | 
|---|
| 186 | static int      curCharSet = rtfCSGeneral; | 
|---|
| 187 | static int      *curCharCode = genCharCode; | 
|---|
| 188 |  | 
|---|
| 189 | /* | 
|---|
| 190 | * By default, the reader is configured to handle charset mapping invisibly, | 
|---|
| 191 | * including reading the charset files and switching charset maps as necessary | 
|---|
| 192 | * for Symbol font. | 
|---|
| 193 | */ | 
|---|
| 194 |  | 
|---|
| 195 | static int      autoCharSetFlags; | 
|---|
| 196 |  | 
|---|
| 197 | /* | 
|---|
| 198 | * Stack for keeping track of charset map on group begin/end.  This is | 
|---|
| 199 | * necessary because group termination reverts the font to the previous | 
|---|
| 200 | * value, which may implicitly change it. | 
|---|
| 201 | */ | 
|---|
| 202 |  | 
|---|
| 203 | static int      csStack[maxCSStack]; | 
|---|
| 204 | static int      csTop = 0; | 
|---|
| 205 |  | 
|---|
| 206 | /* | 
|---|
| 207 | * Get a char from the charlist. The charlist is used to store characters | 
|---|
| 208 | * from the editstream. | 
|---|
| 209 | * | 
|---|
| 210 | */ | 
|---|
| 211 |  | 
|---|
| 212 | int _RTFGetChar(void) | 
|---|
| 213 | { | 
|---|
| 214 | char myChar; | 
|---|
| 215 |  | 
|---|
| 216 | TRACE("\n"); | 
|---|
| 217 |  | 
|---|
| 218 | if(CHARLIST_GetNbItems(&inputCharList) == 0) | 
|---|
| 219 | { | 
|---|
| 220 | char buff[10]; | 
|---|
| 221 | long pcb; | 
|---|
| 222 | editstream.pfnCallback(editstream.dwCookie, buff, 1, &pcb); | 
|---|
| 223 | if(pcb == 0) | 
|---|
| 224 | return EOF; | 
|---|
| 225 | else | 
|---|
| 226 | CHARLIST_Enqueue(&inputCharList, buff[0]); | 
|---|
| 227 | } | 
|---|
| 228 | myChar = CHARLIST_Dequeue(&inputCharList); | 
|---|
| 229 | return (int) myChar; | 
|---|
| 230 | } | 
|---|
| 231 |  | 
|---|
| 232 | void RTFSetEditStream(EDITSTREAM *es) | 
|---|
| 233 | { | 
|---|
| 234 | TRACE("\n"); | 
|---|
| 235 |  | 
|---|
| 236 | editstream.dwCookie = es->dwCookie; | 
|---|
| 237 | editstream.dwError  = es->dwError; | 
|---|
| 238 | editstream.pfnCallback = es->pfnCallback; | 
|---|
| 239 | } | 
|---|
| 240 |  | 
|---|
| 241 | /* | 
|---|
| 242 | * Initialize the reader.  This may be called multiple times, | 
|---|
| 243 | * to read multiple files.  The only thing not reset is the input | 
|---|
| 244 | * stream; that must be done with RTFSetStream(). | 
|---|
| 245 | */ | 
|---|
| 246 |  | 
|---|
| 247 | void RTFInit(void) | 
|---|
| 248 | { | 
|---|
| 249 | int     i; | 
|---|
| 250 | RTFColor        *cp; | 
|---|
| 251 | RTFFont         *fp; | 
|---|
| 252 | RTFStyle        *sp; | 
|---|
| 253 | RTFStyleElt     *eltList, *ep; | 
|---|
| 254 |  | 
|---|
| 255 | TRACE("\n"); | 
|---|
| 256 |  | 
|---|
| 257 | if (rtfTextBuf == (char *) NULL)        /* initialize the text buffers */ | 
|---|
| 258 | { | 
|---|
| 259 | rtfTextBuf = RTFAlloc (rtfBufSiz); | 
|---|
| 260 | pushedTextBuf = RTFAlloc (rtfBufSiz); | 
|---|
| 261 | if (rtfTextBuf == (char *) NULL | 
|---|
| 262 | || pushedTextBuf == (char *) NULL) | 
|---|
| 263 | RTFPanic ("Cannot allocate text buffers."); | 
|---|
| 264 | rtfTextBuf[0] = pushedTextBuf[0] = '\0'; | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 | RTFFree (inputName); | 
|---|
| 268 | RTFFree (outputName); | 
|---|
| 269 | inputName = outputName = (char *) NULL; | 
|---|
| 270 |  | 
|---|
| 271 | /* initialize lookup table */ | 
|---|
| 272 | LookupInit (); | 
|---|
| 273 |  | 
|---|
| 274 | for (i = 0; i < rtfMaxClass; i++) | 
|---|
| 275 | RTFSetClassCallback (i, (RTFFuncPtr) NULL); | 
|---|
| 276 | for (i = 0; i < rtfMaxDestination; i++) | 
|---|
| 277 | RTFSetDestinationCallback (i, (RTFFuncPtr) NULL); | 
|---|
| 278 |  | 
|---|
| 279 | /* install built-in destination readers */ | 
|---|
| 280 | RTFSetDestinationCallback (rtfFontTbl, ReadFontTbl); | 
|---|
| 281 | RTFSetDestinationCallback (rtfColorTbl, ReadColorTbl); | 
|---|
| 282 | RTFSetDestinationCallback (rtfStyleSheet, ReadStyleSheet); | 
|---|
| 283 | RTFSetDestinationCallback (rtfInfo, ReadInfoGroup); | 
|---|
| 284 | RTFSetDestinationCallback (rtfPict, ReadPictGroup); | 
|---|
| 285 | RTFSetDestinationCallback (rtfObject, ReadObjGroup); | 
|---|
| 286 |  | 
|---|
| 287 |  | 
|---|
| 288 | RTFSetReadHook ((RTFFuncPtr) NULL); | 
|---|
| 289 |  | 
|---|
| 290 | /* dump old lists if necessary */ | 
|---|
| 291 |  | 
|---|
| 292 | while (fontList != (RTFFont *) NULL) | 
|---|
| 293 | { | 
|---|
| 294 | fp = fontList->rtfNextFont; | 
|---|
| 295 | RTFFree (fontList->rtfFName); | 
|---|
| 296 | RTFFree ((char *) fontList); | 
|---|
| 297 | fontList = fp; | 
|---|
| 298 | } | 
|---|
| 299 | while (colorList != (RTFColor *) NULL) | 
|---|
| 300 | { | 
|---|
| 301 | cp = colorList->rtfNextColor; | 
|---|
| 302 | RTFFree ((char *) colorList); | 
|---|
| 303 | colorList = cp; | 
|---|
| 304 | } | 
|---|
| 305 | while (styleList != (RTFStyle *) NULL) | 
|---|
| 306 | { | 
|---|
| 307 | sp = styleList->rtfNextStyle; | 
|---|
| 308 | eltList = styleList->rtfSSEList; | 
|---|
| 309 | while (eltList != (RTFStyleElt *) NULL) | 
|---|
| 310 | { | 
|---|
| 311 | ep = eltList->rtfNextSE; | 
|---|
| 312 | RTFFree (eltList->rtfSEText); | 
|---|
| 313 | RTFFree ((char *) eltList); | 
|---|
| 314 | eltList = ep; | 
|---|
| 315 | } | 
|---|
| 316 | RTFFree (styleList->rtfSName); | 
|---|
| 317 | RTFFree ((char *) styleList); | 
|---|
| 318 | styleList = sp; | 
|---|
| 319 | } | 
|---|
| 320 |  | 
|---|
| 321 | rtfClass = -1; | 
|---|
| 322 | pushedClass = -1; | 
|---|
| 323 | pushedChar = EOF; | 
|---|
| 324 |  | 
|---|
| 325 | rtfLineNum = 0; | 
|---|
| 326 | rtfLinePos = 0; | 
|---|
| 327 | prevChar = EOF; | 
|---|
| 328 | bumpLine = 0; | 
|---|
| 329 |  | 
|---|
| 330 | CharSetInit (); | 
|---|
| 331 | csTop = 0; | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 | /* | 
|---|
| 335 | * Set or get the input or output file name.  These are never guaranteed | 
|---|
| 336 | * to be accurate, only insofar as the calling program makes them so. | 
|---|
| 337 | */ | 
|---|
| 338 |  | 
|---|
| 339 | void RTFSetInputName(char *name) | 
|---|
| 340 | { | 
|---|
| 341 | TRACE("\n"); | 
|---|
| 342 |  | 
|---|
| 343 | if ((inputName = RTFStrSave (name)) == (char *) NULL) | 
|---|
| 344 | RTFPanic ("RTFSetInputName: out of memory"); | 
|---|
| 345 | } | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | char *RTFGetInputName(void) | 
|---|
| 349 | { | 
|---|
| 350 | return (inputName); | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 |  | 
|---|
| 354 | void RTFSetOutputName(char *name) | 
|---|
| 355 | { | 
|---|
| 356 | TRACE("\n"); | 
|---|
| 357 |  | 
|---|
| 358 | if ((outputName = RTFStrSave (name)) == (char *) NULL) | 
|---|
| 359 | RTFPanic ("RTFSetOutputName: out of memory"); | 
|---|
| 360 | } | 
|---|
| 361 |  | 
|---|
| 362 |  | 
|---|
| 363 | char *RTFGetOutputName(void) | 
|---|
| 364 | { | 
|---|
| 365 | return (outputName); | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 |  | 
|---|
| 369 |  | 
|---|
| 370 | /* ---------------------------------------------------------------------- */ | 
|---|
| 371 |  | 
|---|
| 372 | /* | 
|---|
| 373 | * Callback table manipulation routines | 
|---|
| 374 | */ | 
|---|
| 375 |  | 
|---|
| 376 |  | 
|---|
| 377 | /* | 
|---|
| 378 | * Install or return a writer callback for a token class | 
|---|
| 379 | */ | 
|---|
| 380 |  | 
|---|
| 381 |  | 
|---|
| 382 | static RTFFuncPtr       ccb[rtfMaxClass];               /* class callbacks */ | 
|---|
| 383 |  | 
|---|
| 384 |  | 
|---|
| 385 | void RTFSetClassCallback(int class, RTFFuncPtr callback) | 
|---|
| 386 | { | 
|---|
| 387 | if (class >= 0 && class < rtfMaxClass) | 
|---|
| 388 | ccb[class] = callback; | 
|---|
| 389 | } | 
|---|
| 390 |  | 
|---|
| 391 |  | 
|---|
| 392 | RTFFuncPtr RTFGetClassCallback(int class) | 
|---|
| 393 | { | 
|---|
| 394 | if (class >= 0 && class < rtfMaxClass) | 
|---|
| 395 | return (ccb[class]); | 
|---|
| 396 | return ((RTFFuncPtr) NULL); | 
|---|
| 397 | } | 
|---|
| 398 |  | 
|---|
| 399 |  | 
|---|
| 400 | /* | 
|---|
| 401 | * Install or return a writer callback for a destination type | 
|---|
| 402 | */ | 
|---|
| 403 |  | 
|---|
| 404 | static RTFFuncPtr       dcb[rtfMaxDestination]; /* destination callbacks */ | 
|---|
| 405 |  | 
|---|
| 406 |  | 
|---|
| 407 | void RTFSetDestinationCallback(int dest, RTFFuncPtr callback) | 
|---|
| 408 | { | 
|---|
| 409 | if (dest >= 0 && dest < rtfMaxDestination) | 
|---|
| 410 | dcb[dest] = callback; | 
|---|
| 411 | } | 
|---|
| 412 |  | 
|---|
| 413 |  | 
|---|
| 414 | RTFFuncPtr RTFGetDestinationCallback(int dest) | 
|---|
| 415 | { | 
|---|
| 416 | if (dest >= 0 && dest < rtfMaxDestination) | 
|---|
| 417 | return (dcb[dest]); | 
|---|
| 418 | return ((RTFFuncPtr) NULL); | 
|---|
| 419 | } | 
|---|
| 420 |  | 
|---|
| 421 |  | 
|---|
| 422 | /* ---------------------------------------------------------------------- */ | 
|---|
| 423 |  | 
|---|
| 424 | /* | 
|---|
| 425 | * Token reading routines | 
|---|
| 426 | */ | 
|---|
| 427 |  | 
|---|
| 428 |  | 
|---|
| 429 | /* | 
|---|
| 430 | * Read the input stream, invoking the writer's callbacks | 
|---|
| 431 | * where appropriate. | 
|---|
| 432 | */ | 
|---|
| 433 |  | 
|---|
| 434 | void RTFRead(void) | 
|---|
| 435 | { | 
|---|
| 436 | while (RTFGetToken () != rtfEOF) | 
|---|
| 437 | RTFRouteToken (); | 
|---|
| 438 | } | 
|---|
| 439 |  | 
|---|
| 440 |  | 
|---|
| 441 | /* | 
|---|
| 442 | * Route a token.  If it's a destination for which a reader is | 
|---|
| 443 | * installed, process the destination internally, otherwise | 
|---|
| 444 | * pass the token to the writer's class callback. | 
|---|
| 445 | */ | 
|---|
| 446 |  | 
|---|
| 447 | void RTFRouteToken(void) | 
|---|
| 448 | { | 
|---|
| 449 | RTFFuncPtr      p; | 
|---|
| 450 |  | 
|---|
| 451 | TRACE("\n"); | 
|---|
| 452 |  | 
|---|
| 453 | if (rtfClass < 0 || rtfClass >= rtfMaxClass)    /* watchdog */ | 
|---|
| 454 | { | 
|---|
| 455 | RTFPanic ("Unknown class %d: %s (reader malfunction)", | 
|---|
| 456 | rtfClass, rtfTextBuf); | 
|---|
| 457 | } | 
|---|
| 458 | if (RTFCheckCM (rtfControl, rtfDestination)) | 
|---|
| 459 | { | 
|---|
| 460 | /* invoke destination-specific callback if there is one */ | 
|---|
| 461 | if ((p = RTFGetDestinationCallback (rtfMinor)) | 
|---|
| 462 | != (RTFFuncPtr) NULL) | 
|---|
| 463 | { | 
|---|
| 464 | (*p) (); | 
|---|
| 465 | return; | 
|---|
| 466 | } | 
|---|
| 467 | } | 
|---|
| 468 | /* invoke class callback if there is one */ | 
|---|
| 469 | if ((p = RTFGetClassCallback (rtfClass)) != (RTFFuncPtr) NULL) | 
|---|
| 470 | (*p) (); | 
|---|
| 471 | } | 
|---|
| 472 |  | 
|---|
| 473 |  | 
|---|
| 474 | /* | 
|---|
| 475 | * Skip to the end of the current group.  When this returns, | 
|---|
| 476 | * writers that maintain a state stack may want to call their | 
|---|
| 477 | * state unstacker; global vars will still be set to the group's | 
|---|
| 478 | * closing brace. | 
|---|
| 479 | */ | 
|---|
| 480 |  | 
|---|
| 481 | void RTFSkipGroup(void) | 
|---|
| 482 | { | 
|---|
| 483 | int     level = 1; | 
|---|
| 484 | TRACE("\n"); | 
|---|
| 485 |  | 
|---|
| 486 | while (RTFGetToken () != rtfEOF) | 
|---|
| 487 | { | 
|---|
| 488 | if (rtfClass == rtfGroup) | 
|---|
| 489 | { | 
|---|
| 490 | if (rtfMajor == rtfBeginGroup) | 
|---|
| 491 | ++level; | 
|---|
| 492 | else if (rtfMajor == rtfEndGroup) | 
|---|
| 493 | { | 
|---|
| 494 | if (--level < 1) | 
|---|
| 495 | break;  /* end of initial group */ | 
|---|
| 496 | } | 
|---|
| 497 | } | 
|---|
| 498 | } | 
|---|
| 499 | } | 
|---|
| 500 |  | 
|---|
| 501 |  | 
|---|
| 502 | /* | 
|---|
| 503 | * Read one token.  Call the read hook if there is one.  The | 
|---|
| 504 | * token class is the return value.  Returns rtfEOF when there | 
|---|
| 505 | * are no more tokens. | 
|---|
| 506 | */ | 
|---|
| 507 |  | 
|---|
| 508 | int RTFGetToken(void) | 
|---|
| 509 | { | 
|---|
| 510 | RTFFuncPtr      p; | 
|---|
| 511 | TRACE("\n"); | 
|---|
| 512 |  | 
|---|
| 513 | for (;;) | 
|---|
| 514 | { | 
|---|
| 515 | _RTFGetToken (); | 
|---|
| 516 | if ((p = RTFGetReadHook ()) != (RTFFuncPtr) NULL) | 
|---|
| 517 | (*p) ();        /* give read hook a look at token */ | 
|---|
| 518 |  | 
|---|
| 519 | /* Silently discard newlines, carriage returns, nulls.  */ | 
|---|
| 520 | if (!(rtfClass == rtfText && rtfFormat != SF_TEXT | 
|---|
| 521 | && (rtfMajor == '\r' || rtfMajor == '\n' || rtfMajor == '\0'))) | 
|---|
| 522 | break; | 
|---|
| 523 | } | 
|---|
| 524 | return (rtfClass); | 
|---|
| 525 | } | 
|---|
| 526 |  | 
|---|
| 527 |  | 
|---|
| 528 | /* | 
|---|
| 529 | * Install or return a token reader hook. | 
|---|
| 530 | */ | 
|---|
| 531 |  | 
|---|
| 532 | static RTFFuncPtr       readHook; | 
|---|
| 533 |  | 
|---|
| 534 |  | 
|---|
| 535 | void RTFSetReadHook(RTFFuncPtr f) | 
|---|
| 536 | { | 
|---|
| 537 | readHook = f; | 
|---|
| 538 | } | 
|---|
| 539 |  | 
|---|
| 540 |  | 
|---|
| 541 | RTFFuncPtr RTFGetReadHook(void) | 
|---|
| 542 | { | 
|---|
| 543 | return (readHook); | 
|---|
| 544 | } | 
|---|
| 545 |  | 
|---|
| 546 |  | 
|---|
| 547 | void RTFUngetToken(void) | 
|---|
| 548 | { | 
|---|
| 549 | TRACE("\n"); | 
|---|
| 550 |  | 
|---|
| 551 | if (pushedClass >= 0)   /* there's already an ungotten token */ | 
|---|
| 552 | RTFPanic ("cannot unget two tokens"); | 
|---|
| 553 | if (rtfClass < 0) | 
|---|
| 554 | RTFPanic ("no token to unget"); | 
|---|
| 555 | pushedClass = rtfClass; | 
|---|
| 556 | pushedMajor = rtfMajor; | 
|---|
| 557 | pushedMinor = rtfMinor; | 
|---|
| 558 | pushedParam = rtfParam; | 
|---|
| 559 | (void) strcpy (pushedTextBuf, rtfTextBuf); | 
|---|
| 560 | } | 
|---|
| 561 |  | 
|---|
| 562 |  | 
|---|
| 563 | int RTFPeekToken(void) | 
|---|
| 564 | { | 
|---|
| 565 | _RTFGetToken (); | 
|---|
| 566 | RTFUngetToken (); | 
|---|
| 567 | return (rtfClass); | 
|---|
| 568 | } | 
|---|
| 569 |  | 
|---|
| 570 |  | 
|---|
| 571 | static void _RTFGetToken(void) | 
|---|
| 572 | { | 
|---|
| 573 | RTFFont *fp; | 
|---|
| 574 |  | 
|---|
| 575 | TRACE("\n"); | 
|---|
| 576 |  | 
|---|
| 577 | if (rtfFormat == SF_TEXT) { | 
|---|
| 578 | rtfMajor = GetChar (); | 
|---|
| 579 | rtfMinor = rtfSC_nothing; | 
|---|
| 580 | rtfParam = rtfNoParam; | 
|---|
| 581 | rtfTextBuf[rtfTextLen = 0] = '\0'; | 
|---|
| 582 | if (rtfMajor == EOF) | 
|---|
| 583 | rtfClass = rtfEOF; | 
|---|
| 584 | else | 
|---|
| 585 | rtfClass = rtfText; | 
|---|
| 586 | return; | 
|---|
| 587 | } | 
|---|
| 588 |  | 
|---|
| 589 | /* first check for pushed token from RTFUngetToken() */ | 
|---|
| 590 |  | 
|---|
| 591 | if (pushedClass >= 0) | 
|---|
| 592 | { | 
|---|
| 593 | rtfClass = pushedClass; | 
|---|
| 594 | rtfMajor = pushedMajor; | 
|---|
| 595 | rtfMinor = pushedMinor; | 
|---|
| 596 | rtfParam = pushedParam; | 
|---|
| 597 | (void) strcpy (rtfTextBuf, pushedTextBuf); | 
|---|
| 598 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 599 | pushedClass = -1; | 
|---|
| 600 | return; | 
|---|
| 601 | } | 
|---|
| 602 |  | 
|---|
| 603 | /* | 
|---|
| 604 | * Beyond this point, no token is ever seen twice, which is | 
|---|
| 605 | * important, e.g., for making sure no "}" pops the font stack twice. | 
|---|
| 606 | */ | 
|---|
| 607 |  | 
|---|
| 608 | _RTFGetToken2 (); | 
|---|
| 609 | if (rtfClass == rtfText)        /* map RTF char to standard code */ | 
|---|
| 610 | rtfMinor = RTFMapChar (rtfMajor); | 
|---|
| 611 |  | 
|---|
| 612 | /* | 
|---|
| 613 | * If auto-charset stuff is activated, see if anything needs doing, | 
|---|
| 614 | * like reading the charset maps or switching between them. | 
|---|
| 615 | */ | 
|---|
| 616 |  | 
|---|
| 617 | if (autoCharSetFlags == 0) | 
|---|
| 618 | return; | 
|---|
| 619 |  | 
|---|
| 620 | if ((autoCharSetFlags & rtfReadCharSet) | 
|---|
| 621 | && RTFCheckCM (rtfControl, rtfCharSet)) | 
|---|
| 622 | { | 
|---|
| 623 | ReadCharSetMaps (); | 
|---|
| 624 | } | 
|---|
| 625 | else if ((autoCharSetFlags & rtfSwitchCharSet) | 
|---|
| 626 | && RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) | 
|---|
| 627 | { | 
|---|
| 628 | if ((fp = RTFGetFont (rtfParam)) != (RTFFont *) NULL) | 
|---|
| 629 | { | 
|---|
| 630 | if (strncmp (fp->rtfFName, "Symbol", 6) == 0) | 
|---|
| 631 | curCharSet = rtfCSSymbol; | 
|---|
| 632 | else | 
|---|
| 633 | curCharSet = rtfCSGeneral; | 
|---|
| 634 | RTFSetCharSet (curCharSet); | 
|---|
| 635 | } | 
|---|
| 636 | } | 
|---|
| 637 | else if ((autoCharSetFlags & rtfSwitchCharSet) && rtfClass == rtfGroup) | 
|---|
| 638 | { | 
|---|
| 639 | switch (rtfMajor) | 
|---|
| 640 | { | 
|---|
| 641 | case rtfBeginGroup: | 
|---|
| 642 | if (csTop >= maxCSStack) | 
|---|
| 643 | RTFPanic ("_RTFGetToken: stack overflow"); | 
|---|
| 644 | csStack[csTop++] = curCharSet; | 
|---|
| 645 | break; | 
|---|
| 646 | case rtfEndGroup: | 
|---|
| 647 | if (csTop <= 0) | 
|---|
| 648 | RTFPanic ("_RTFGetToken: stack underflow"); | 
|---|
| 649 | curCharSet = csStack[--csTop]; | 
|---|
| 650 | RTFSetCharSet (curCharSet); | 
|---|
| 651 | break; | 
|---|
| 652 | } | 
|---|
| 653 | } | 
|---|
| 654 | } | 
|---|
| 655 |  | 
|---|
| 656 |  | 
|---|
| 657 | /* this shouldn't be called anywhere but from _RTFGetToken() */ | 
|---|
| 658 |  | 
|---|
| 659 | static void _RTFGetToken2(void) | 
|---|
| 660 | { | 
|---|
| 661 | int     sign; | 
|---|
| 662 | int     c; | 
|---|
| 663 |  | 
|---|
| 664 | TRACE("\n"); | 
|---|
| 665 |  | 
|---|
| 666 | /* initialize token vars */ | 
|---|
| 667 |  | 
|---|
| 668 | rtfClass = rtfUnknown; | 
|---|
| 669 | rtfParam = rtfNoParam; | 
|---|
| 670 | rtfTextBuf[rtfTextLen = 0] = '\0'; | 
|---|
| 671 |  | 
|---|
| 672 | /* get first character, which may be a pushback from previous token */ | 
|---|
| 673 |  | 
|---|
| 674 | if (pushedChar != EOF) | 
|---|
| 675 | { | 
|---|
| 676 | c = pushedChar; | 
|---|
| 677 | rtfTextBuf[rtfTextLen++] = c; | 
|---|
| 678 | rtfTextBuf[rtfTextLen] = '\0'; | 
|---|
| 679 | pushedChar = EOF; | 
|---|
| 680 | } | 
|---|
| 681 | else if ((c = GetChar ()) == EOF) | 
|---|
| 682 | { | 
|---|
| 683 | rtfClass = rtfEOF; | 
|---|
| 684 | return; | 
|---|
| 685 | } | 
|---|
| 686 |  | 
|---|
| 687 | if (c == '{') | 
|---|
| 688 | { | 
|---|
| 689 | rtfClass = rtfGroup; | 
|---|
| 690 | rtfMajor = rtfBeginGroup; | 
|---|
| 691 | return; | 
|---|
| 692 | } | 
|---|
| 693 | if (c == '}') | 
|---|
| 694 | { | 
|---|
| 695 | rtfClass = rtfGroup; | 
|---|
| 696 | rtfMajor = rtfEndGroup; | 
|---|
| 697 | return; | 
|---|
| 698 | } | 
|---|
| 699 | if (c != '\\') | 
|---|
| 700 | { | 
|---|
| 701 | /* | 
|---|
| 702 | * Two possibilities here: | 
|---|
| 703 | * 1) ASCII 9, effectively like \tab control symbol | 
|---|
| 704 | * 2) literal text char | 
|---|
| 705 | */ | 
|---|
| 706 | if (c == '\t')                  /* ASCII 9 */ | 
|---|
| 707 | { | 
|---|
| 708 | rtfClass = rtfControl; | 
|---|
| 709 | rtfMajor = rtfSpecialChar; | 
|---|
| 710 | rtfMinor = rtfTab; | 
|---|
| 711 | } | 
|---|
| 712 | else | 
|---|
| 713 | { | 
|---|
| 714 | rtfClass = rtfText; | 
|---|
| 715 | rtfMajor = c; | 
|---|
| 716 | } | 
|---|
| 717 | return; | 
|---|
| 718 | } | 
|---|
| 719 | if ((c = GetChar ()) == EOF) | 
|---|
| 720 | { | 
|---|
| 721 | /* early eof, whoops (class is rtfUnknown) */ | 
|---|
| 722 | return; | 
|---|
| 723 | } | 
|---|
| 724 | if (!isalpha (c)) | 
|---|
| 725 | { | 
|---|
| 726 | /* | 
|---|
| 727 | * Three possibilities here: | 
|---|
| 728 | * 1) hex encoded text char, e.g., \'d5, \'d3 | 
|---|
| 729 | * 2) special escaped text char, e.g., \{, \} | 
|---|
| 730 | * 3) control symbol, e.g., \_, \-, \|, \<10> | 
|---|
| 731 | */ | 
|---|
| 732 | if (c == '\'')                          /* hex char */ | 
|---|
| 733 | { | 
|---|
| 734 | int     c2; | 
|---|
| 735 |  | 
|---|
| 736 | if ((c = GetChar ()) != EOF && (c2 = GetChar ()) != EOF) | 
|---|
| 737 | { | 
|---|
| 738 | /* should do isxdigit check! */ | 
|---|
| 739 | rtfClass = rtfText; | 
|---|
| 740 | rtfMajor = RTFCharToHex (c) * 16 | 
|---|
| 741 | + RTFCharToHex (c2); | 
|---|
| 742 | return; | 
|---|
| 743 | } | 
|---|
| 744 | /* early eof, whoops (class is rtfUnknown) */ | 
|---|
| 745 | return; | 
|---|
| 746 | } | 
|---|
| 747 |  | 
|---|
| 748 | /* escaped char */ | 
|---|
| 749 | /*if (index (":{}\\", c) != (char *) NULL)*/ /* escaped char */ | 
|---|
| 750 | if (c == ':' || c == '{' || c == '}' || c == '\\') | 
|---|
| 751 | { | 
|---|
| 752 | rtfClass = rtfText; | 
|---|
| 753 | rtfMajor = c; | 
|---|
| 754 | return; | 
|---|
| 755 | } | 
|---|
| 756 |  | 
|---|
| 757 | /* control symbol */ | 
|---|
| 758 | Lookup (rtfTextBuf);    /* sets class, major, minor */ | 
|---|
| 759 | return; | 
|---|
| 760 | } | 
|---|
| 761 | /* control word */ | 
|---|
| 762 | while (isalpha (c)) | 
|---|
| 763 | { | 
|---|
| 764 | if ((c = GetChar ()) == EOF) | 
|---|
| 765 | break; | 
|---|
| 766 | } | 
|---|
| 767 |  | 
|---|
| 768 | /* | 
|---|
| 769 | * At this point, the control word is all collected, so the | 
|---|
| 770 | * major/minor numbers are determined before the parameter | 
|---|
| 771 | * (if any) is scanned.  There will be one too many characters | 
|---|
| 772 | * in the buffer, though, so fix up before and restore after | 
|---|
| 773 | * looking up. | 
|---|
| 774 | */ | 
|---|
| 775 |  | 
|---|
| 776 | if (c != EOF) | 
|---|
| 777 | rtfTextBuf[rtfTextLen-1] = '\0'; | 
|---|
| 778 | Lookup (rtfTextBuf);    /* sets class, major, minor */ | 
|---|
| 779 | if (c != EOF) | 
|---|
| 780 | rtfTextBuf[rtfTextLen-1] = c; | 
|---|
| 781 |  | 
|---|
| 782 | /* | 
|---|
| 783 | * Should be looking at first digit of parameter if there | 
|---|
| 784 | * is one, unless it's negative.  In that case, next char | 
|---|
| 785 | * is '-', so need to gobble next char, and remember sign. | 
|---|
| 786 | */ | 
|---|
| 787 |  | 
|---|
| 788 | sign = 1; | 
|---|
| 789 | if (c == '-') | 
|---|
| 790 | { | 
|---|
| 791 | sign = -1; | 
|---|
| 792 | c = GetChar (); | 
|---|
| 793 | } | 
|---|
| 794 | if (c != EOF && isdigit (c)) | 
|---|
| 795 | { | 
|---|
| 796 | rtfParam = 0; | 
|---|
| 797 | while (isdigit (c))     /* gobble parameter */ | 
|---|
| 798 | { | 
|---|
| 799 | rtfParam = rtfParam * 10 + c - '0'; | 
|---|
| 800 | if ((c = GetChar ()) == EOF) | 
|---|
| 801 | break; | 
|---|
| 802 | } | 
|---|
| 803 | rtfParam *= sign; | 
|---|
| 804 | } | 
|---|
| 805 | /* | 
|---|
| 806 | * If control symbol delimiter was a blank, gobble it. | 
|---|
| 807 | * Otherwise the character is first char of next token, so | 
|---|
| 808 | * push it back for next call.  In either case, delete the | 
|---|
| 809 | * delimiter from the token buffer. | 
|---|
| 810 | */ | 
|---|
| 811 | if (c != EOF) | 
|---|
| 812 | { | 
|---|
| 813 | if (c != ' ') | 
|---|
| 814 | pushedChar = c; | 
|---|
| 815 | rtfTextBuf[--rtfTextLen] = '\0'; | 
|---|
| 816 | } | 
|---|
| 817 | } | 
|---|
| 818 |  | 
|---|
| 819 |  | 
|---|
| 820 | /* | 
|---|
| 821 | * Read the next character from the input.  This handles setting the | 
|---|
| 822 | * current line and position-within-line variables.  Those variable are | 
|---|
| 823 | * set correctly whether lines end with CR, LF, or CRLF (the last being | 
|---|
| 824 | * the tricky case). | 
|---|
| 825 | * | 
|---|
| 826 | * bumpLine indicates whether the line number should be incremented on | 
|---|
| 827 | * the *next* input character. | 
|---|
| 828 | */ | 
|---|
| 829 |  | 
|---|
| 830 |  | 
|---|
| 831 | static int GetChar(void) | 
|---|
| 832 | { | 
|---|
| 833 | int     c; | 
|---|
| 834 | int     oldBumpLine; | 
|---|
| 835 |  | 
|---|
| 836 | TRACE("\n"); | 
|---|
| 837 |  | 
|---|
| 838 | if ((c = _RTFGetChar()) != EOF) | 
|---|
| 839 | { | 
|---|
| 840 | rtfTextBuf[rtfTextLen++] = c; | 
|---|
| 841 | rtfTextBuf[rtfTextLen] = '\0'; | 
|---|
| 842 | } | 
|---|
| 843 | if (prevChar == EOF) | 
|---|
| 844 | bumpLine = 1; | 
|---|
| 845 | oldBumpLine = bumpLine; /* non-zero if prev char was line ending */ | 
|---|
| 846 | bumpLine = 0; | 
|---|
| 847 | if (c == '\r') | 
|---|
| 848 | bumpLine = 1; | 
|---|
| 849 | else if (c == '\n') | 
|---|
| 850 | { | 
|---|
| 851 | bumpLine = 1; | 
|---|
| 852 | if (prevChar == '\r')           /* oops, previous \r wasn't */ | 
|---|
| 853 | oldBumpLine = 0;        /* really a line ending */ | 
|---|
| 854 | } | 
|---|
| 855 | ++rtfLinePos; | 
|---|
| 856 | if (oldBumpLine)        /* were we supposed to increment the */ | 
|---|
| 857 | {                       /* line count on this char? */ | 
|---|
| 858 | ++rtfLineNum; | 
|---|
| 859 | rtfLinePos = 1; | 
|---|
| 860 | } | 
|---|
| 861 | prevChar = c; | 
|---|
| 862 | return (c); | 
|---|
| 863 | } | 
|---|
| 864 |  | 
|---|
| 865 |  | 
|---|
| 866 | /* | 
|---|
| 867 | * Synthesize a token by setting the global variables to the | 
|---|
| 868 | * values supplied.  Typically this is followed with a call | 
|---|
| 869 | * to RTFRouteToken(). | 
|---|
| 870 | * | 
|---|
| 871 | * If a param value other than rtfNoParam is passed, it becomes | 
|---|
| 872 | * part of the token text. | 
|---|
| 873 | */ | 
|---|
| 874 |  | 
|---|
| 875 | void RTFSetToken(int class, int major, int minor, int param, char *text) | 
|---|
| 876 | { | 
|---|
| 877 | TRACE("\n"); | 
|---|
| 878 |  | 
|---|
| 879 | rtfClass = class; | 
|---|
| 880 | rtfMajor = major; | 
|---|
| 881 | rtfMinor = minor; | 
|---|
| 882 | rtfParam = param; | 
|---|
| 883 | if (param == rtfNoParam) | 
|---|
| 884 | (void) strcpy (rtfTextBuf, text); | 
|---|
| 885 | else | 
|---|
| 886 | sprintf (rtfTextBuf, "%s%d", text, param); | 
|---|
| 887 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 888 | } | 
|---|
| 889 |  | 
|---|
| 890 |  | 
|---|
| 891 | /* ---------------------------------------------------------------------- */ | 
|---|
| 892 |  | 
|---|
| 893 | /* | 
|---|
| 894 | * Routines to handle mapping of RTF character sets | 
|---|
| 895 | * onto standard characters. | 
|---|
| 896 | * | 
|---|
| 897 | * RTFStdCharCode(name) given char name, produce numeric code | 
|---|
| 898 | * RTFStdCharName(code) given char code, return name | 
|---|
| 899 | * RTFMapChar(c)        map input (RTF) char code to std code | 
|---|
| 900 | * RTFSetCharSet(id)    select given charset map | 
|---|
| 901 | * RTFGetCharSet()      get current charset map | 
|---|
| 902 | * | 
|---|
| 903 | * See ../h/README for more information about charset names and codes. | 
|---|
| 904 | */ | 
|---|
| 905 |  | 
|---|
| 906 |  | 
|---|
| 907 | /* | 
|---|
| 908 | * Initialize charset stuff. | 
|---|
| 909 | */ | 
|---|
| 910 |  | 
|---|
| 911 | static void CharSetInit(void) | 
|---|
| 912 | { | 
|---|
| 913 | TRACE("\n"); | 
|---|
| 914 |  | 
|---|
| 915 | autoCharSetFlags = (rtfReadCharSet | rtfSwitchCharSet); | 
|---|
| 916 | RTFFree (genCharSetFile); | 
|---|
| 917 | genCharSetFile = (char *) NULL; | 
|---|
| 918 | haveGenCharSet = 0; | 
|---|
| 919 | RTFFree (symCharSetFile); | 
|---|
| 920 | symCharSetFile = (char *) NULL; | 
|---|
| 921 | haveSymCharSet = 0; | 
|---|
| 922 | curCharSet = rtfCSGeneral; | 
|---|
| 923 | curCharCode = genCharCode; | 
|---|
| 924 | } | 
|---|
| 925 |  | 
|---|
| 926 |  | 
|---|
| 927 | /* | 
|---|
| 928 | * Specify the name of a file to be read when auto-charset-file reading is | 
|---|
| 929 | * done. | 
|---|
| 930 | */ | 
|---|
| 931 |  | 
|---|
| 932 | void RTFSetCharSetMap (char *name, int csId) | 
|---|
| 933 | { | 
|---|
| 934 | TRACE("\n"); | 
|---|
| 935 |  | 
|---|
| 936 | if ((name = RTFStrSave (name)) == (char *) NULL)        /* make copy */ | 
|---|
| 937 | RTFPanic ("RTFSetCharSetMap: out of memory"); | 
|---|
| 938 | switch (csId) | 
|---|
| 939 | { | 
|---|
| 940 | case rtfCSGeneral: | 
|---|
| 941 | RTFFree (genCharSetFile);       /* free any previous value */ | 
|---|
| 942 | genCharSetFile = name; | 
|---|
| 943 | break; | 
|---|
| 944 | case rtfCSSymbol: | 
|---|
| 945 | RTFFree (symCharSetFile);       /* free any previous value */ | 
|---|
| 946 | symCharSetFile = name; | 
|---|
| 947 | break; | 
|---|
| 948 | } | 
|---|
| 949 | } | 
|---|
| 950 |  | 
|---|
| 951 |  | 
|---|
| 952 | /* | 
|---|
| 953 | * Do auto-charset-file reading. | 
|---|
| 954 | * will always use the ansi charset no mater what the value | 
|---|
| 955 | * of the rtfTextBuf is. | 
|---|
| 956 | * | 
|---|
| 957 | * TODO: add support for other charset in the future. | 
|---|
| 958 | * | 
|---|
| 959 | */ | 
|---|
| 960 |  | 
|---|
| 961 | static void ReadCharSetMaps(void) | 
|---|
| 962 | { | 
|---|
| 963 | char    buf[rtfBufSiz]; | 
|---|
| 964 |  | 
|---|
| 965 | TRACE("\n"); | 
|---|
| 966 |  | 
|---|
| 967 | if (genCharSetFile != (char *) NULL) | 
|---|
| 968 | (void) strcpy (buf, genCharSetFile); | 
|---|
| 969 | else | 
|---|
| 970 | sprintf (buf, "%s-gen", &rtfTextBuf[1]); | 
|---|
| 971 | if (RTFReadCharSetMap (rtfCSGeneral) == 0) | 
|---|
| 972 | RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf); | 
|---|
| 973 | if (symCharSetFile != (char *) NULL) | 
|---|
| 974 | (void) strcpy (buf, symCharSetFile); | 
|---|
| 975 | else | 
|---|
| 976 | sprintf (buf, "%s-sym", &rtfTextBuf[1]); | 
|---|
| 977 | if (RTFReadCharSetMap (rtfCSSymbol) == 0) | 
|---|
| 978 | RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf); | 
|---|
| 979 | } | 
|---|
| 980 |  | 
|---|
| 981 |  | 
|---|
| 982 |  | 
|---|
| 983 | /* | 
|---|
| 984 | * Convert a CaracterSetMap (caracter_name, caracter) into | 
|---|
| 985 | * this form : array[caracter_ident] = caracter; | 
|---|
| 986 | */ | 
|---|
| 987 |  | 
|---|
| 988 | int RTFReadCharSetMap(int csId) | 
|---|
| 989 | { | 
|---|
| 990 | int     *stdCodeArray; | 
|---|
| 991 | int i; | 
|---|
| 992 |  | 
|---|
| 993 | TRACE("\n"); | 
|---|
| 994 |  | 
|---|
| 995 | switch (csId) | 
|---|
| 996 | { | 
|---|
| 997 | default: | 
|---|
| 998 | return (0);     /* illegal charset id */ | 
|---|
| 999 | case rtfCSGeneral: | 
|---|
| 1000 |  | 
|---|
| 1001 | haveGenCharSet = 1; | 
|---|
| 1002 | stdCodeArray = genCharCode; | 
|---|
| 1003 | for (i = 0; i < charSetSize; i++) | 
|---|
| 1004 | { | 
|---|
| 1005 | stdCodeArray[i] = rtfSC_nothing; | 
|---|
| 1006 | } | 
|---|
| 1007 |  | 
|---|
| 1008 | for ( i = 0 ; i< sizeof(ansi_gen)/(sizeof(int));i+=2) | 
|---|
| 1009 | { | 
|---|
| 1010 | stdCodeArray[ ansi_gen[i+1] ] = ansi_gen[i]; | 
|---|
| 1011 | } | 
|---|
| 1012 | break; | 
|---|
| 1013 |  | 
|---|
| 1014 | case rtfCSSymbol: | 
|---|
| 1015 |  | 
|---|
| 1016 | haveSymCharSet = 1; | 
|---|
| 1017 | stdCodeArray = symCharCode; | 
|---|
| 1018 | for (i = 0; i < charSetSize; i++) | 
|---|
| 1019 | { | 
|---|
| 1020 | stdCodeArray[i] = rtfSC_nothing; | 
|---|
| 1021 | } | 
|---|
| 1022 |  | 
|---|
| 1023 | for ( i = 0 ; i< sizeof(ansi_sym)/(sizeof(int));i+=2) | 
|---|
| 1024 | { | 
|---|
| 1025 | stdCodeArray[ ansi_sym[i+1] ] = ansi_sym[i]; | 
|---|
| 1026 | } | 
|---|
| 1027 | break; | 
|---|
| 1028 | } | 
|---|
| 1029 |  | 
|---|
| 1030 | return (1); | 
|---|
| 1031 | } | 
|---|
| 1032 |  | 
|---|
| 1033 |  | 
|---|
| 1034 | /* | 
|---|
| 1035 | * Given a standard character name (a string), find its code (a number). | 
|---|
| 1036 | * Return -1 if name is unknown. | 
|---|
| 1037 | */ | 
|---|
| 1038 |  | 
|---|
| 1039 | int RTFStdCharCode(char *name) | 
|---|
| 1040 | { | 
|---|
| 1041 | int     i; | 
|---|
| 1042 |  | 
|---|
| 1043 | TRACE("\n"); | 
|---|
| 1044 |  | 
|---|
| 1045 | for (i = 0; i < rtfSC_MaxChar; i++) | 
|---|
| 1046 | { | 
|---|
| 1047 | if (strcmp (name, stdCharName[i]) == 0) | 
|---|
| 1048 | return (i); | 
|---|
| 1049 | } | 
|---|
| 1050 | return (-1); | 
|---|
| 1051 | } | 
|---|
| 1052 |  | 
|---|
| 1053 |  | 
|---|
| 1054 | /* | 
|---|
| 1055 | * Given a standard character code (a number), find its name (a string). | 
|---|
| 1056 | * Return NULL if code is unknown. | 
|---|
| 1057 | */ | 
|---|
| 1058 |  | 
|---|
| 1059 | char *RTFStdCharName(int code) | 
|---|
| 1060 | { | 
|---|
| 1061 | if (code < 0 || code >= rtfSC_MaxChar) | 
|---|
| 1062 | return ((char *) NULL); | 
|---|
| 1063 | return (stdCharName[code]); | 
|---|
| 1064 | } | 
|---|
| 1065 |  | 
|---|
| 1066 |  | 
|---|
| 1067 | /* | 
|---|
| 1068 | * Given an RTF input character code, find standard character code. | 
|---|
| 1069 | * The translator should read the appropriate charset maps when it finds a | 
|---|
| 1070 | * charset control.  However, the file might not contain one.  In this | 
|---|
| 1071 | * case, no map will be available.  When the first attempt is made to | 
|---|
| 1072 | * map a character under these circumstances, RTFMapChar() assumes ANSI | 
|---|
| 1073 | * and reads the map as necessary. | 
|---|
| 1074 | */ | 
|---|
| 1075 |  | 
|---|
| 1076 | int RTFMapChar(int c) | 
|---|
| 1077 | { | 
|---|
| 1078 | TRACE("\n"); | 
|---|
| 1079 |  | 
|---|
| 1080 | switch (curCharSet) | 
|---|
| 1081 | { | 
|---|
| 1082 | case rtfCSGeneral: | 
|---|
| 1083 | if (!haveGenCharSet) | 
|---|
| 1084 | { | 
|---|
| 1085 | if (RTFReadCharSetMap (rtfCSGeneral) == 0) | 
|---|
| 1086 | RTFPanic ("RTFMapChar: cannot read ansi-gen"); | 
|---|
| 1087 | } | 
|---|
| 1088 | break; | 
|---|
| 1089 | case rtfCSSymbol: | 
|---|
| 1090 | if (!haveSymCharSet) | 
|---|
| 1091 | { | 
|---|
| 1092 | if (RTFReadCharSetMap (rtfCSSymbol) == 0) | 
|---|
| 1093 | RTFPanic ("RTFMapChar: cannot read ansi-sym"); | 
|---|
| 1094 | } | 
|---|
| 1095 | break; | 
|---|
| 1096 | } | 
|---|
| 1097 | if (c < 0 || c >= charSetSize) | 
|---|
| 1098 | return (rtfSC_nothing); | 
|---|
| 1099 | return (curCharCode[c]); | 
|---|
| 1100 | } | 
|---|
| 1101 |  | 
|---|
| 1102 |  | 
|---|
| 1103 | /* | 
|---|
| 1104 | * Set the current character set.  If csId is illegal, uses general charset. | 
|---|
| 1105 | */ | 
|---|
| 1106 |  | 
|---|
| 1107 | void RTFSetCharSet(int csId) | 
|---|
| 1108 | { | 
|---|
| 1109 | TRACE("\n"); | 
|---|
| 1110 |  | 
|---|
| 1111 | switch (csId) | 
|---|
| 1112 | { | 
|---|
| 1113 | default:                /* use general if csId unknown */ | 
|---|
| 1114 | case rtfCSGeneral: | 
|---|
| 1115 | curCharCode = genCharCode; | 
|---|
| 1116 | curCharSet = csId; | 
|---|
| 1117 | break; | 
|---|
| 1118 | case rtfCSSymbol: | 
|---|
| 1119 | curCharCode = symCharCode; | 
|---|
| 1120 | curCharSet = csId; | 
|---|
| 1121 | break; | 
|---|
| 1122 | } | 
|---|
| 1123 | } | 
|---|
| 1124 |  | 
|---|
| 1125 |  | 
|---|
| 1126 | int RTFGetCharSet(void) | 
|---|
| 1127 | { | 
|---|
| 1128 | return (curCharSet); | 
|---|
| 1129 | } | 
|---|
| 1130 |  | 
|---|
| 1131 |  | 
|---|
| 1132 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1133 |  | 
|---|
| 1134 | /* | 
|---|
| 1135 | * Special destination readers.  They gobble the destination so the | 
|---|
| 1136 | * writer doesn't have to deal with them.  That's wrong for any | 
|---|
| 1137 | * translator that wants to process any of these itself.  In that | 
|---|
| 1138 | * case, these readers should be overridden by installing a different | 
|---|
| 1139 | * destination callback. | 
|---|
| 1140 | * | 
|---|
| 1141 | * NOTE: The last token read by each of these reader will be the | 
|---|
| 1142 | * destination's terminating '}', which will then be the current token. | 
|---|
| 1143 | * That '}' token is passed to RTFRouteToken() - the writer has already | 
|---|
| 1144 | * seen the '{' that began the destination group, and may have pushed a | 
|---|
| 1145 | * state; it also needs to know at the end of the group that a state | 
|---|
| 1146 | * should be popped. | 
|---|
| 1147 | * | 
|---|
| 1148 | * It's important that rtf.h and the control token lookup table list | 
|---|
| 1149 | * as many symbols as possible, because these destination readers | 
|---|
| 1150 | * unfortunately make strict assumptions about the input they expect, | 
|---|
| 1151 | * and a token of class rtfUnknown will throw them off easily. | 
|---|
| 1152 | */ | 
|---|
| 1153 |  | 
|---|
| 1154 |  | 
|---|
| 1155 | /* | 
|---|
| 1156 | * Read { \fonttbl ... } destination.  Old font tables don't have | 
|---|
| 1157 | * braces around each table entry; try to adjust for that. | 
|---|
| 1158 | */ | 
|---|
| 1159 |  | 
|---|
| 1160 | static void ReadFontTbl(void) | 
|---|
| 1161 | { | 
|---|
| 1162 | RTFFont *fp = NULL; | 
|---|
| 1163 | char    buf[rtfBufSiz], *bp; | 
|---|
| 1164 | int     old = -1; | 
|---|
| 1165 | char    *fn = "ReadFontTbl"; | 
|---|
| 1166 |  | 
|---|
| 1167 | TRACE("\n"); | 
|---|
| 1168 |  | 
|---|
| 1169 | for (;;) | 
|---|
| 1170 | { | 
|---|
| 1171 | (void) RTFGetToken (); | 
|---|
| 1172 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1173 | break; | 
|---|
| 1174 | if (old < 0)            /* first entry - determine tbl type */ | 
|---|
| 1175 | { | 
|---|
| 1176 | if (RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) | 
|---|
| 1177 | old = 1;        /* no brace */ | 
|---|
| 1178 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1179 | old = 0;        /* brace */ | 
|---|
| 1180 | else                    /* can't tell! */ | 
|---|
| 1181 | RTFPanic ("%s: Cannot determine format", fn); | 
|---|
| 1182 | } | 
|---|
| 1183 | if (old == 0)           /* need to find "{" here */ | 
|---|
| 1184 | { | 
|---|
| 1185 | if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1186 | RTFPanic ("%s: missing \"{\"", fn); | 
|---|
| 1187 | (void) RTFGetToken ();  /* yes, skip to next token */ | 
|---|
| 1188 | } | 
|---|
| 1189 | if ((fp = New (RTFFont)) == (RTFFont *) NULL) | 
|---|
| 1190 | RTFPanic ("%s: cannot allocate font entry", fn); | 
|---|
| 1191 |  | 
|---|
| 1192 | fp->rtfNextFont = fontList; | 
|---|
| 1193 | fontList = fp; | 
|---|
| 1194 |  | 
|---|
| 1195 | fp->rtfFName = (char *) NULL; | 
|---|
| 1196 | fp->rtfFAltName = (char *) NULL; | 
|---|
| 1197 | fp->rtfFNum = -1; | 
|---|
| 1198 | fp->rtfFFamily = 0; | 
|---|
| 1199 | fp->rtfFCharSet = 0; | 
|---|
| 1200 | fp->rtfFPitch = 0; | 
|---|
| 1201 | fp->rtfFType = 0; | 
|---|
| 1202 | fp->rtfFCodePage = 0; | 
|---|
| 1203 |  | 
|---|
| 1204 | while (rtfClass != rtfEOF | 
|---|
| 1205 | && !RTFCheckCM (rtfText, ';') | 
|---|
| 1206 | && !RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1207 | { | 
|---|
| 1208 | if (rtfClass == rtfControl) | 
|---|
| 1209 | { | 
|---|
| 1210 | switch (rtfMajor) | 
|---|
| 1211 | { | 
|---|
| 1212 | default: | 
|---|
| 1213 | /* ignore token but announce it */ | 
|---|
| 1214 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1215 | fn, rtfTextBuf); | 
|---|
| 1216 | case rtfFontFamily: | 
|---|
| 1217 | fp->rtfFFamily = rtfMinor; | 
|---|
| 1218 | break; | 
|---|
| 1219 | case rtfCharAttr: | 
|---|
| 1220 | switch (rtfMinor) | 
|---|
| 1221 | { | 
|---|
| 1222 | default: | 
|---|
| 1223 | break;  /* ignore unknown? */ | 
|---|
| 1224 | case rtfFontNum: | 
|---|
| 1225 | fp->rtfFNum = rtfParam; | 
|---|
| 1226 | break; | 
|---|
| 1227 | } | 
|---|
| 1228 | break; | 
|---|
| 1229 | case rtfFontAttr: | 
|---|
| 1230 | switch (rtfMinor) | 
|---|
| 1231 | { | 
|---|
| 1232 | default: | 
|---|
| 1233 | break;  /* ignore unknown? */ | 
|---|
| 1234 | case rtfFontCharSet: | 
|---|
| 1235 | fp->rtfFCharSet = rtfParam; | 
|---|
| 1236 | break; | 
|---|
| 1237 | case rtfFontPitch: | 
|---|
| 1238 | fp->rtfFPitch = rtfParam; | 
|---|
| 1239 | break; | 
|---|
| 1240 | case rtfFontCodePage: | 
|---|
| 1241 | fp->rtfFCodePage = rtfParam; | 
|---|
| 1242 | break; | 
|---|
| 1243 | case rtfFTypeNil: | 
|---|
| 1244 | case rtfFTypeTrueType: | 
|---|
| 1245 | fp->rtfFType = rtfParam; | 
|---|
| 1246 | break; | 
|---|
| 1247 | } | 
|---|
| 1248 | break; | 
|---|
| 1249 | } | 
|---|
| 1250 | } | 
|---|
| 1251 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup))  /* dest */ | 
|---|
| 1252 | { | 
|---|
| 1253 | RTFSkipGroup ();        /* ignore for now */ | 
|---|
| 1254 | } | 
|---|
| 1255 | else if (rtfClass == rtfText)   /* font name */ | 
|---|
| 1256 | { | 
|---|
| 1257 | bp = buf; | 
|---|
| 1258 | while (rtfClass != rtfEOF | 
|---|
| 1259 | && !RTFCheckCM (rtfText, ';') | 
|---|
| 1260 | && !RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1261 | { | 
|---|
| 1262 | *bp++ = rtfMajor; | 
|---|
| 1263 | (void) RTFGetToken (); | 
|---|
| 1264 | } | 
|---|
| 1265 |  | 
|---|
| 1266 | /* FIX: in some cases the <fontinfo> isn't finished with a semi-column */ | 
|---|
| 1267 | if(RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1268 | { | 
|---|
| 1269 | RTFUngetToken (); | 
|---|
| 1270 | } | 
|---|
| 1271 | *bp = '\0'; | 
|---|
| 1272 | fp->rtfFName = RTFStrSave (buf); | 
|---|
| 1273 | if (fp->rtfFName == (char *) NULL) | 
|---|
| 1274 | RTFPanic ("%s: cannot allocate font name", fn); | 
|---|
| 1275 | /* already have next token; don't read one */ | 
|---|
| 1276 | /* at bottom of loop */ | 
|---|
| 1277 | continue; | 
|---|
| 1278 | } | 
|---|
| 1279 | else | 
|---|
| 1280 | { | 
|---|
| 1281 | /* ignore token but announce it */ | 
|---|
| 1282 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1283 | fn, rtfTextBuf); | 
|---|
| 1284 | } | 
|---|
| 1285 | (void) RTFGetToken (); | 
|---|
| 1286 | } | 
|---|
| 1287 | if (old == 0)   /* need to see "}" here */ | 
|---|
| 1288 | { | 
|---|
| 1289 | (void) RTFGetToken (); | 
|---|
| 1290 | if (!RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1291 | RTFPanic ("%s: missing \"}\"", fn); | 
|---|
| 1292 | } | 
|---|
| 1293 | } | 
|---|
| 1294 | if (fp->rtfFNum == -1) | 
|---|
| 1295 | RTFPanic ("%s: missing font number", fn); | 
|---|
| 1296 | /* | 
|---|
| 1297 | * Could check other pieces of structure here, too, I suppose. | 
|---|
| 1298 | */ | 
|---|
| 1299 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1300 | } | 
|---|
| 1301 |  | 
|---|
| 1302 |  | 
|---|
| 1303 | /* | 
|---|
| 1304 | * The color table entries have color values of -1 if | 
|---|
| 1305 | * the default color should be used for the entry (only | 
|---|
| 1306 | * a semi-colon is given in the definition, no color values). | 
|---|
| 1307 | * There will be a problem if a partial entry (1 or 2 but | 
|---|
| 1308 | * not 3 color values) is given.  The possibility is ignored | 
|---|
| 1309 | * here. | 
|---|
| 1310 | */ | 
|---|
| 1311 |  | 
|---|
| 1312 | static void ReadColorTbl(void) | 
|---|
| 1313 | { | 
|---|
| 1314 | RTFColor        *cp; | 
|---|
| 1315 | int             cnum = 0; | 
|---|
| 1316 | char            *fn = "ReadColorTbl"; | 
|---|
| 1317 |  | 
|---|
| 1318 | TRACE("\n"); | 
|---|
| 1319 |  | 
|---|
| 1320 | for (;;) | 
|---|
| 1321 | { | 
|---|
| 1322 | (void) RTFGetToken (); | 
|---|
| 1323 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1324 | break; | 
|---|
| 1325 | if ((cp = New (RTFColor)) == (RTFColor *) NULL) | 
|---|
| 1326 | RTFPanic ("%s: cannot allocate color entry", fn); | 
|---|
| 1327 | cp->rtfCNum = cnum++; | 
|---|
| 1328 | cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1; | 
|---|
| 1329 | cp->rtfNextColor = colorList; | 
|---|
| 1330 | colorList = cp; | 
|---|
| 1331 | while (RTFCheckCM (rtfControl, rtfColorName)) | 
|---|
| 1332 | { | 
|---|
| 1333 | switch (rtfMinor) | 
|---|
| 1334 | { | 
|---|
| 1335 | case rtfRed:    cp->rtfCRed = rtfParam; break; | 
|---|
| 1336 | case rtfGreen:  cp->rtfCGreen = rtfParam; break; | 
|---|
| 1337 | case rtfBlue:   cp->rtfCBlue = rtfParam; break; | 
|---|
| 1338 | } | 
|---|
| 1339 | RTFGetToken (); | 
|---|
| 1340 | } | 
|---|
| 1341 | if (!RTFCheckCM (rtfText, (int) ';')) | 
|---|
| 1342 | RTFPanic ("%s: malformed entry", fn); | 
|---|
| 1343 | } | 
|---|
| 1344 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1345 | } | 
|---|
| 1346 |  | 
|---|
| 1347 |  | 
|---|
| 1348 | /* | 
|---|
| 1349 | * The "Normal" style definition doesn't contain any style number, | 
|---|
| 1350 | * all others do.  Normal style is given style rtfNormalStyleNum. | 
|---|
| 1351 | */ | 
|---|
| 1352 |  | 
|---|
| 1353 | static void ReadStyleSheet(void) | 
|---|
| 1354 | { | 
|---|
| 1355 | RTFStyle        *sp; | 
|---|
| 1356 | RTFStyleElt     *sep, *sepLast; | 
|---|
| 1357 | char            buf[rtfBufSiz], *bp; | 
|---|
| 1358 | char            *fn = "ReadStyleSheet"; | 
|---|
| 1359 |  | 
|---|
| 1360 | TRACE("\n"); | 
|---|
| 1361 |  | 
|---|
| 1362 | for (;;) | 
|---|
| 1363 | { | 
|---|
| 1364 | (void) RTFGetToken (); | 
|---|
| 1365 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1366 | break; | 
|---|
| 1367 | if ((sp = New (RTFStyle)) == (RTFStyle *) NULL) | 
|---|
| 1368 | RTFPanic ("%s: cannot allocate stylesheet entry", fn); | 
|---|
| 1369 | sp->rtfSName = (char *) NULL; | 
|---|
| 1370 | sp->rtfSNum = -1; | 
|---|
| 1371 | sp->rtfSType = rtfParStyle; | 
|---|
| 1372 | sp->rtfSAdditive = 0; | 
|---|
| 1373 | sp->rtfSBasedOn = rtfNoStyleNum; | 
|---|
| 1374 | sp->rtfSNextPar = -1; | 
|---|
| 1375 | sp->rtfSSEList = sepLast = (RTFStyleElt *) NULL; | 
|---|
| 1376 | sp->rtfNextStyle = styleList; | 
|---|
| 1377 | sp->rtfExpanding = 0; | 
|---|
| 1378 | styleList = sp; | 
|---|
| 1379 | if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1380 | RTFPanic ("%s: missing \"{\"", fn); | 
|---|
| 1381 | for (;;) | 
|---|
| 1382 | { | 
|---|
| 1383 | (void) RTFGetToken (); | 
|---|
| 1384 | if (rtfClass == rtfEOF | 
|---|
| 1385 | || RTFCheckCM (rtfText, ';')) | 
|---|
| 1386 | break; | 
|---|
| 1387 | if (rtfClass == rtfControl) | 
|---|
| 1388 | { | 
|---|
| 1389 | if (RTFCheckMM (rtfSpecialChar, rtfOptDest)) | 
|---|
| 1390 | continue;       /* ignore "\*" */ | 
|---|
| 1391 | if (RTFCheckMM (rtfParAttr, rtfStyleNum)) | 
|---|
| 1392 | { | 
|---|
| 1393 | sp->rtfSNum = rtfParam; | 
|---|
| 1394 | sp->rtfSType = rtfParStyle; | 
|---|
| 1395 | continue; | 
|---|
| 1396 | } | 
|---|
| 1397 | if (RTFCheckMM (rtfCharAttr, rtfCharStyleNum)) | 
|---|
| 1398 | { | 
|---|
| 1399 | sp->rtfSNum = rtfParam; | 
|---|
| 1400 | sp->rtfSType = rtfCharStyle; | 
|---|
| 1401 | continue; | 
|---|
| 1402 | } | 
|---|
| 1403 | if (RTFCheckMM (rtfSectAttr, rtfSectStyleNum)) | 
|---|
| 1404 | { | 
|---|
| 1405 | sp->rtfSNum = rtfParam; | 
|---|
| 1406 | sp->rtfSType = rtfSectStyle; | 
|---|
| 1407 | continue; | 
|---|
| 1408 | } | 
|---|
| 1409 | if (RTFCheckMM (rtfStyleAttr, rtfBasedOn)) | 
|---|
| 1410 | { | 
|---|
| 1411 | sp->rtfSBasedOn = rtfParam; | 
|---|
| 1412 | continue; | 
|---|
| 1413 | } | 
|---|
| 1414 | if (RTFCheckMM (rtfStyleAttr, rtfAdditive)) | 
|---|
| 1415 | { | 
|---|
| 1416 | sp->rtfSAdditive = 1; | 
|---|
| 1417 | continue; | 
|---|
| 1418 | } | 
|---|
| 1419 | if (RTFCheckMM (rtfStyleAttr, rtfNext)) | 
|---|
| 1420 | { | 
|---|
| 1421 | sp->rtfSNextPar = rtfParam; | 
|---|
| 1422 | continue; | 
|---|
| 1423 | } | 
|---|
| 1424 | if ((sep = New (RTFStyleElt)) == (RTFStyleElt *) NULL) | 
|---|
| 1425 | RTFPanic ("%s: cannot allocate style element", fn); | 
|---|
| 1426 | sep->rtfSEClass = rtfClass; | 
|---|
| 1427 | sep->rtfSEMajor = rtfMajor; | 
|---|
| 1428 | sep->rtfSEMinor = rtfMinor; | 
|---|
| 1429 | sep->rtfSEParam = rtfParam; | 
|---|
| 1430 | if ((sep->rtfSEText = RTFStrSave (rtfTextBuf)) | 
|---|
| 1431 | == (char *) NULL) | 
|---|
| 1432 | RTFPanic ("%s: cannot allocate style element text", fn); | 
|---|
| 1433 | if (sepLast == (RTFStyleElt *) NULL) | 
|---|
| 1434 | sp->rtfSSEList = sep;   /* first element */ | 
|---|
| 1435 | else                            /* add to end */ | 
|---|
| 1436 | sepLast->rtfNextSE = sep; | 
|---|
| 1437 | sep->rtfNextSE = (RTFStyleElt *) NULL; | 
|---|
| 1438 | sepLast = sep; | 
|---|
| 1439 | } | 
|---|
| 1440 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1441 | { | 
|---|
| 1442 | /* | 
|---|
| 1443 | * This passes over "{\*\keycode ... }, among | 
|---|
| 1444 | * other things. A temporary (perhaps) hack. | 
|---|
| 1445 | */ | 
|---|
| 1446 | RTFSkipGroup (); | 
|---|
| 1447 | continue; | 
|---|
| 1448 | } | 
|---|
| 1449 | else if (rtfClass == rtfText)   /* style name */ | 
|---|
| 1450 | { | 
|---|
| 1451 | bp = buf; | 
|---|
| 1452 | while (rtfClass == rtfText) | 
|---|
| 1453 | { | 
|---|
| 1454 | if (rtfMajor == ';') | 
|---|
| 1455 | { | 
|---|
| 1456 | /* put back for "for" loop */ | 
|---|
| 1457 | (void) RTFUngetToken (); | 
|---|
| 1458 | break; | 
|---|
| 1459 | } | 
|---|
| 1460 | *bp++ = rtfMajor; | 
|---|
| 1461 | (void) RTFGetToken (); | 
|---|
| 1462 | } | 
|---|
| 1463 | *bp = '\0'; | 
|---|
| 1464 | if ((sp->rtfSName = RTFStrSave (buf)) == (char *) NULL) | 
|---|
| 1465 | RTFPanic ("%s: cannot allocate style name", fn); | 
|---|
| 1466 | } | 
|---|
| 1467 | else            /* unrecognized */ | 
|---|
| 1468 | { | 
|---|
| 1469 | /* ignore token but announce it */ | 
|---|
| 1470 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1471 | fn, rtfTextBuf); | 
|---|
| 1472 | } | 
|---|
| 1473 | } | 
|---|
| 1474 | (void) RTFGetToken (); | 
|---|
| 1475 | if (!RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1476 | RTFPanic ("%s: missing \"}\"", fn); | 
|---|
| 1477 |  | 
|---|
| 1478 | /* | 
|---|
| 1479 | * Check over the style structure.  A name is a must. | 
|---|
| 1480 | * If no style number was specified, check whether it's the | 
|---|
| 1481 | * Normal style (in which case it's given style number | 
|---|
| 1482 | * rtfNormalStyleNum).  Note that some "normal" style names | 
|---|
| 1483 | * just begin with "Normal" and can have other stuff following, | 
|---|
| 1484 | * e.g., "Normal,Times 10 point".  Ugh. | 
|---|
| 1485 | * | 
|---|
| 1486 | * Some German RTF writers use "Standard" instead of "Normal". | 
|---|
| 1487 | */ | 
|---|
| 1488 | if (sp->rtfSName == (char *) NULL) | 
|---|
| 1489 | RTFPanic ("%s: missing style name", fn); | 
|---|
| 1490 | if (sp->rtfSNum < 0) | 
|---|
| 1491 | { | 
|---|
| 1492 | if (strncmp (buf, "Normal", 6) != 0 | 
|---|
| 1493 | && strncmp (buf, "Standard", 8) != 0) | 
|---|
| 1494 | RTFPanic ("%s: missing style number", fn); | 
|---|
| 1495 | sp->rtfSNum = rtfNormalStyleNum; | 
|---|
| 1496 | } | 
|---|
| 1497 | if (sp->rtfSNextPar == -1)      /* if \snext not given, */ | 
|---|
| 1498 | sp->rtfSNextPar = sp->rtfSNum;  /* next is itself */ | 
|---|
| 1499 | } | 
|---|
| 1500 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1501 | } | 
|---|
| 1502 |  | 
|---|
| 1503 |  | 
|---|
| 1504 | static void ReadInfoGroup(void) | 
|---|
| 1505 | { | 
|---|
| 1506 | RTFSkipGroup (); | 
|---|
| 1507 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1508 | } | 
|---|
| 1509 |  | 
|---|
| 1510 |  | 
|---|
| 1511 | static void ReadPictGroup(void) | 
|---|
| 1512 | { | 
|---|
| 1513 | RTFSkipGroup (); | 
|---|
| 1514 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1515 | } | 
|---|
| 1516 |  | 
|---|
| 1517 |  | 
|---|
| 1518 | static void ReadObjGroup(void) | 
|---|
| 1519 | { | 
|---|
| 1520 | RTFSkipGroup (); | 
|---|
| 1521 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1522 | } | 
|---|
| 1523 |  | 
|---|
| 1524 |  | 
|---|
| 1525 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1526 |  | 
|---|
| 1527 | /* | 
|---|
| 1528 | * Routines to return pieces of stylesheet, or font or color tables. | 
|---|
| 1529 | * References to style 0 are mapped onto the Normal style. | 
|---|
| 1530 | */ | 
|---|
| 1531 |  | 
|---|
| 1532 |  | 
|---|
| 1533 | RTFStyle *RTFGetStyle(int num) | 
|---|
| 1534 | { | 
|---|
| 1535 | RTFStyle        *s; | 
|---|
| 1536 |  | 
|---|
| 1537 | if (num == -1) | 
|---|
| 1538 | return (styleList); | 
|---|
| 1539 | for (s = styleList; s != (RTFStyle *) NULL; s = s->rtfNextStyle) | 
|---|
| 1540 | { | 
|---|
| 1541 | if (s->rtfSNum == num) | 
|---|
| 1542 | break; | 
|---|
| 1543 | } | 
|---|
| 1544 | return (s);             /* NULL if not found */ | 
|---|
| 1545 | } | 
|---|
| 1546 |  | 
|---|
| 1547 |  | 
|---|
| 1548 | RTFFont *RTFGetFont(int num) | 
|---|
| 1549 | { | 
|---|
| 1550 | RTFFont *f; | 
|---|
| 1551 |  | 
|---|
| 1552 | if (num == -1) | 
|---|
| 1553 | return (fontList); | 
|---|
| 1554 | for (f = fontList; f != (RTFFont *) NULL; f = f->rtfNextFont) | 
|---|
| 1555 | { | 
|---|
| 1556 | if (f->rtfFNum == num) | 
|---|
| 1557 | break; | 
|---|
| 1558 | } | 
|---|
| 1559 | return (f);             /* NULL if not found */ | 
|---|
| 1560 | } | 
|---|
| 1561 |  | 
|---|
| 1562 |  | 
|---|
| 1563 | RTFColor *RTFGetColor(int num) | 
|---|
| 1564 | { | 
|---|
| 1565 | RTFColor        *c; | 
|---|
| 1566 |  | 
|---|
| 1567 | if (num == -1) | 
|---|
| 1568 | return (colorList); | 
|---|
| 1569 | for (c = colorList; c != (RTFColor *) NULL; c = c->rtfNextColor) | 
|---|
| 1570 | { | 
|---|
| 1571 | if (c->rtfCNum == num) | 
|---|
| 1572 | break; | 
|---|
| 1573 | } | 
|---|
| 1574 | return (c);             /* NULL if not found */ | 
|---|
| 1575 | } | 
|---|
| 1576 |  | 
|---|
| 1577 |  | 
|---|
| 1578 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1579 |  | 
|---|
| 1580 |  | 
|---|
| 1581 | /* | 
|---|
| 1582 | * Expand style n, if there is such a style. | 
|---|
| 1583 | */ | 
|---|
| 1584 |  | 
|---|
| 1585 | void RTFExpandStyle(int n) | 
|---|
| 1586 | { | 
|---|
| 1587 | RTFStyle        *s; | 
|---|
| 1588 | RTFStyleElt     *se; | 
|---|
| 1589 |  | 
|---|
| 1590 | TRACE("\n"); | 
|---|
| 1591 |  | 
|---|
| 1592 | if (n == -1 || (s = RTFGetStyle (n)) == (RTFStyle *) NULL) | 
|---|
| 1593 | return; | 
|---|
| 1594 | if (s->rtfExpanding != 0) | 
|---|
| 1595 | RTFPanic ("Style expansion loop, style %d", n); | 
|---|
| 1596 | s->rtfExpanding = 1;    /* set expansion flag for loop detection */ | 
|---|
| 1597 | /* | 
|---|
| 1598 | * Expand "based-on" style (unless it's the same as the current | 
|---|
| 1599 | * style -- Normal style usually gives itself as its own based-on | 
|---|
| 1600 | * style).  Based-on style expansion is done by synthesizing | 
|---|
| 1601 | * the token that the writer needs to see in order to trigger | 
|---|
| 1602 | * another style expansion, and feeding to token back through | 
|---|
| 1603 | * the router so the writer sees it. | 
|---|
| 1604 | */ | 
|---|
| 1605 | if (n != s->rtfSBasedOn) | 
|---|
| 1606 | { | 
|---|
| 1607 | RTFSetToken (rtfControl, rtfParAttr, rtfStyleNum, | 
|---|
| 1608 | s->rtfSBasedOn, "\\s"); | 
|---|
| 1609 | RTFRouteToken (); | 
|---|
| 1610 | } | 
|---|
| 1611 | /* | 
|---|
| 1612 | * Now route the tokens unique to this style.  RTFSetToken() | 
|---|
| 1613 | * isn't used because it would add the param value to the end | 
|---|
| 1614 | * of the token text, which already has it in. | 
|---|
| 1615 | */ | 
|---|
| 1616 | for (se = s->rtfSSEList; se != (RTFStyleElt *) NULL; se = se->rtfNextSE) | 
|---|
| 1617 | { | 
|---|
| 1618 | rtfClass = se->rtfSEClass; | 
|---|
| 1619 | rtfMajor = se->rtfSEMajor; | 
|---|
| 1620 | rtfMinor = se->rtfSEMinor; | 
|---|
| 1621 | rtfParam = se->rtfSEParam; | 
|---|
| 1622 | (void) strcpy (rtfTextBuf, se->rtfSEText); | 
|---|
| 1623 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 1624 | RTFRouteToken (); | 
|---|
| 1625 | } | 
|---|
| 1626 | s->rtfExpanding = 0;    /* done - clear expansion flag */ | 
|---|
| 1627 | } | 
|---|
| 1628 |  | 
|---|
| 1629 |  | 
|---|
| 1630 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1631 |  | 
|---|
| 1632 | /* | 
|---|
| 1633 | * Control symbol lookup routines | 
|---|
| 1634 | */ | 
|---|
| 1635 |  | 
|---|
| 1636 |  | 
|---|
| 1637 | typedef struct RTFKey   RTFKey; | 
|---|
| 1638 |  | 
|---|
| 1639 | struct RTFKey | 
|---|
| 1640 | { | 
|---|
| 1641 | int     rtfKMajor;      /* major number */ | 
|---|
| 1642 | int     rtfKMinor;      /* minor number */ | 
|---|
| 1643 | char    *rtfKStr;       /* symbol name */ | 
|---|
| 1644 | int     rtfKHash;       /* symbol name hash value */ | 
|---|
| 1645 | }; | 
|---|
| 1646 |  | 
|---|
| 1647 | /* | 
|---|
| 1648 | * A minor number of -1 means the token has no minor number | 
|---|
| 1649 | * (all valid minor numbers are >= 0). | 
|---|
| 1650 | */ | 
|---|
| 1651 |  | 
|---|
| 1652 | static RTFKey   rtfKey[] = | 
|---|
| 1653 | { | 
|---|
| 1654 | /* | 
|---|
| 1655 | * Special characters | 
|---|
| 1656 | */ | 
|---|
| 1657 |  | 
|---|
| 1658 | { rtfSpecialChar,       rtfIIntVersion,         "vern",         0 }, | 
|---|
| 1659 | { rtfSpecialChar,       rtfICreateTime,         "creatim",      0 }, | 
|---|
| 1660 | { rtfSpecialChar,       rtfIRevisionTime,       "revtim",       0 }, | 
|---|
| 1661 | { rtfSpecialChar,       rtfIPrintTime,          "printim",      0 }, | 
|---|
| 1662 | { rtfSpecialChar,       rtfIBackupTime,         "buptim",       0 }, | 
|---|
| 1663 | { rtfSpecialChar,       rtfIEditTime,           "edmins",       0 }, | 
|---|
| 1664 | { rtfSpecialChar,       rtfIYear,               "yr",           0 }, | 
|---|
| 1665 | { rtfSpecialChar,       rtfIMonth,              "mo",           0 }, | 
|---|
| 1666 | { rtfSpecialChar,       rtfIDay,                "dy",           0 }, | 
|---|
| 1667 | { rtfSpecialChar,       rtfIHour,               "hr",           0 }, | 
|---|
| 1668 | { rtfSpecialChar,       rtfIMinute,             "min",          0 }, | 
|---|
| 1669 | { rtfSpecialChar,       rtfISecond,             "sec",          0 }, | 
|---|
| 1670 | { rtfSpecialChar,       rtfINPages,             "nofpages",     0 }, | 
|---|
| 1671 | { rtfSpecialChar,       rtfINWords,             "nofwords",     0 }, | 
|---|
| 1672 | { rtfSpecialChar,       rtfINChars,             "nofchars",     0 }, | 
|---|
| 1673 | { rtfSpecialChar,       rtfIIntID,              "id",           0 }, | 
|---|
| 1674 |  | 
|---|
| 1675 | { rtfSpecialChar,       rtfCurHeadDate,         "chdate",       0 }, | 
|---|
| 1676 | { rtfSpecialChar,       rtfCurHeadDateLong,     "chdpl",        0 }, | 
|---|
| 1677 | { rtfSpecialChar,       rtfCurHeadDateAbbrev,   "chdpa",        0 }, | 
|---|
| 1678 | { rtfSpecialChar,       rtfCurHeadTime,         "chtime",       0 }, | 
|---|
| 1679 | { rtfSpecialChar,       rtfCurHeadPage,         "chpgn",        0 }, | 
|---|
| 1680 | { rtfSpecialChar,       rtfSectNum,             "sectnum",      0 }, | 
|---|
| 1681 | { rtfSpecialChar,       rtfCurFNote,            "chftn",        0 }, | 
|---|
| 1682 | { rtfSpecialChar,       rtfCurAnnotRef,         "chatn",        0 }, | 
|---|
| 1683 | { rtfSpecialChar,       rtfFNoteSep,            "chftnsep",     0 }, | 
|---|
| 1684 | { rtfSpecialChar,       rtfFNoteCont,           "chftnsepc",    0 }, | 
|---|
| 1685 | { rtfSpecialChar,       rtfCell,                "cell",         0 }, | 
|---|
| 1686 | { rtfSpecialChar,       rtfRow,                 "row",          0 }, | 
|---|
| 1687 | { rtfSpecialChar,       rtfPar,                 "par",          0 }, | 
|---|
| 1688 | /* newline and carriage return are synonyms for */ | 
|---|
| 1689 | /* \par when they are preceded by a \ character */ | 
|---|
| 1690 | { rtfSpecialChar,       rtfPar,                 "\n",           0 }, | 
|---|
| 1691 | { rtfSpecialChar,       rtfPar,                 "\r",           0 }, | 
|---|
| 1692 | { rtfSpecialChar,       rtfSect,                "sect",         0 }, | 
|---|
| 1693 | { rtfSpecialChar,       rtfPage,                "page",         0 }, | 
|---|
| 1694 | { rtfSpecialChar,       rtfColumn,              "column",       0 }, | 
|---|
| 1695 | { rtfSpecialChar,       rtfLine,                "line",         0 }, | 
|---|
| 1696 | { rtfSpecialChar,       rtfSoftPage,            "softpage",     0 }, | 
|---|
| 1697 | { rtfSpecialChar,       rtfSoftColumn,          "softcol",      0 }, | 
|---|
| 1698 | { rtfSpecialChar,       rtfSoftLine,            "softline",     0 }, | 
|---|
| 1699 | { rtfSpecialChar,       rtfSoftLineHt,          "softlheight",  0 }, | 
|---|
| 1700 | { rtfSpecialChar,       rtfTab,                 "tab",          0 }, | 
|---|
| 1701 | { rtfSpecialChar,       rtfEmDash,              "emdash",       0 }, | 
|---|
| 1702 | { rtfSpecialChar,       rtfEnDash,              "endash",       0 }, | 
|---|
| 1703 | { rtfSpecialChar,       rtfEmSpace,             "emspace",      0 }, | 
|---|
| 1704 | { rtfSpecialChar,       rtfEnSpace,             "enspace",      0 }, | 
|---|
| 1705 | { rtfSpecialChar,       rtfBullet,              "bullet",       0 }, | 
|---|
| 1706 | { rtfSpecialChar,       rtfLQuote,              "lquote",       0 }, | 
|---|
| 1707 | { rtfSpecialChar,       rtfRQuote,              "rquote",       0 }, | 
|---|
| 1708 | { rtfSpecialChar,       rtfLDblQuote,           "ldblquote",    0 }, | 
|---|
| 1709 | { rtfSpecialChar,       rtfRDblQuote,           "rdblquote",    0 }, | 
|---|
| 1710 | { rtfSpecialChar,       rtfFormula,             "|",            0 }, | 
|---|
| 1711 | { rtfSpecialChar,       rtfNoBrkSpace,          "~",            0 }, | 
|---|
| 1712 | { rtfSpecialChar,       rtfNoReqHyphen,         "-",            0 }, | 
|---|
| 1713 | { rtfSpecialChar,       rtfNoBrkHyphen,         "_",            0 }, | 
|---|
| 1714 | { rtfSpecialChar,       rtfOptDest,             "*",            0 }, | 
|---|
| 1715 | { rtfSpecialChar,       rtfLTRMark,             "ltrmark",      0 }, | 
|---|
| 1716 | { rtfSpecialChar,       rtfRTLMark,             "rtlmark",      0 }, | 
|---|
| 1717 | { rtfSpecialChar,       rtfNoWidthJoiner,       "zwj",          0 }, | 
|---|
| 1718 | { rtfSpecialChar,       rtfNoWidthNonJoiner,    "zwnj",         0 }, | 
|---|
| 1719 | /* is this valid? */ | 
|---|
| 1720 | { rtfSpecialChar,       rtfCurHeadPict,         "chpict",       0 }, | 
|---|
| 1721 |  | 
|---|
| 1722 | /* | 
|---|
| 1723 | * Character formatting attributes | 
|---|
| 1724 | */ | 
|---|
| 1725 |  | 
|---|
| 1726 | { rtfCharAttr,  rtfPlain,               "plain",        0 }, | 
|---|
| 1727 | { rtfCharAttr,  rtfBold,                "b",            0 }, | 
|---|
| 1728 | { rtfCharAttr,  rtfAllCaps,             "caps",         0 }, | 
|---|
| 1729 | { rtfCharAttr,  rtfDeleted,             "deleted",      0 }, | 
|---|
| 1730 | { rtfCharAttr,  rtfSubScript,           "dn",           0 }, | 
|---|
| 1731 | { rtfCharAttr,  rtfSubScrShrink,        "sub",          0 }, | 
|---|
| 1732 | { rtfCharAttr,  rtfNoSuperSub,          "nosupersub",   0 }, | 
|---|
| 1733 | { rtfCharAttr,  rtfExpand,              "expnd",        0 }, | 
|---|
| 1734 | { rtfCharAttr,  rtfExpandTwips,         "expndtw",      0 }, | 
|---|
| 1735 | { rtfCharAttr,  rtfKerning,             "kerning",      0 }, | 
|---|
| 1736 | { rtfCharAttr,  rtfFontNum,             "f",            0 }, | 
|---|
| 1737 | { rtfCharAttr,  rtfFontSize,            "fs",           0 }, | 
|---|
| 1738 | { rtfCharAttr,  rtfItalic,              "i",            0 }, | 
|---|
| 1739 | { rtfCharAttr,  rtfOutline,             "outl",         0 }, | 
|---|
| 1740 | { rtfCharAttr,  rtfRevised,             "revised",      0 }, | 
|---|
| 1741 | { rtfCharAttr,  rtfRevAuthor,           "revauth",      0 }, | 
|---|
| 1742 | { rtfCharAttr,  rtfRevDTTM,             "revdttm",      0 }, | 
|---|
| 1743 | { rtfCharAttr,  rtfSmallCaps,           "scaps",        0 }, | 
|---|
| 1744 | { rtfCharAttr,  rtfShadow,              "shad",         0 }, | 
|---|
| 1745 | { rtfCharAttr,  rtfStrikeThru,          "strike",       0 }, | 
|---|
| 1746 | { rtfCharAttr,  rtfUnderline,           "ul",           0 }, | 
|---|
| 1747 | { rtfCharAttr,  rtfDotUnderline,        "uld",          0 }, | 
|---|
| 1748 | { rtfCharAttr,  rtfDbUnderline,         "uldb",         0 }, | 
|---|
| 1749 | { rtfCharAttr,  rtfNoUnderline,         "ulnone",       0 }, | 
|---|
| 1750 | { rtfCharAttr,  rtfWordUnderline,       "ulw",          0 }, | 
|---|
| 1751 | { rtfCharAttr,  rtfSuperScript,         "up",           0 }, | 
|---|
| 1752 | { rtfCharAttr,  rtfSuperScrShrink,      "super",        0 }, | 
|---|
| 1753 | { rtfCharAttr,  rtfInvisible,           "v",            0 }, | 
|---|
| 1754 | { rtfCharAttr,  rtfForeColor,           "cf",           0 }, | 
|---|
| 1755 | { rtfCharAttr,  rtfBackColor,           "cb",           0 }, | 
|---|
| 1756 | { rtfCharAttr,  rtfRTLChar,             "rtlch",        0 }, | 
|---|
| 1757 | { rtfCharAttr,  rtfLTRChar,             "ltrch",        0 }, | 
|---|
| 1758 | { rtfCharAttr,  rtfCharStyleNum,        "cs",           0 }, | 
|---|
| 1759 | { rtfCharAttr,  rtfCharCharSet,         "cchs",         0 }, | 
|---|
| 1760 | { rtfCharAttr,  rtfLanguage,            "lang",         0 }, | 
|---|
| 1761 | /* this has disappeared from spec 1.2 */ | 
|---|
| 1762 | { rtfCharAttr,  rtfGray,                "gray",         0 }, | 
|---|
| 1763 |  | 
|---|
| 1764 | /* | 
|---|
| 1765 | * Paragraph formatting attributes | 
|---|
| 1766 | */ | 
|---|
| 1767 |  | 
|---|
| 1768 | { rtfParAttr,   rtfParDef,              "pard",         0 }, | 
|---|
| 1769 | { rtfParAttr,   rtfStyleNum,            "s",            0 }, | 
|---|
| 1770 | { rtfParAttr,   rtfHyphenate,           "hyphpar",      0 }, | 
|---|
| 1771 | { rtfParAttr,   rtfInTable,             "intbl",        0 }, | 
|---|
| 1772 | { rtfParAttr,   rtfKeep,                "keep",         0 }, | 
|---|
| 1773 | { rtfParAttr,   rtfNoWidowControl,      "nowidctlpar",  0 }, | 
|---|
| 1774 | { rtfParAttr,   rtfKeepNext,            "keepn",        0 }, | 
|---|
| 1775 | { rtfParAttr,   rtfOutlineLevel,        "level",        0 }, | 
|---|
| 1776 | { rtfParAttr,   rtfNoLineNum,           "noline",       0 }, | 
|---|
| 1777 | { rtfParAttr,   rtfPBBefore,            "pagebb",       0 }, | 
|---|
| 1778 | { rtfParAttr,   rtfSideBySide,          "sbys",         0 }, | 
|---|
| 1779 | { rtfParAttr,   rtfQuadLeft,            "ql",           0 }, | 
|---|
| 1780 | { rtfParAttr,   rtfQuadRight,           "qr",           0 }, | 
|---|
| 1781 | { rtfParAttr,   rtfQuadJust,            "qj",           0 }, | 
|---|
| 1782 | { rtfParAttr,   rtfQuadCenter,          "qc",           0 }, | 
|---|
| 1783 | { rtfParAttr,   rtfFirstIndent,         "fi",           0 }, | 
|---|
| 1784 | { rtfParAttr,   rtfLeftIndent,          "li",           0 }, | 
|---|
| 1785 | { rtfParAttr,   rtfRightIndent,         "ri",           0 }, | 
|---|
| 1786 | { rtfParAttr,   rtfSpaceBefore,         "sb",           0 }, | 
|---|
| 1787 | { rtfParAttr,   rtfSpaceAfter,          "sa",           0 }, | 
|---|
| 1788 | { rtfParAttr,   rtfSpaceBetween,        "sl",           0 }, | 
|---|
| 1789 | { rtfParAttr,   rtfSpaceMultiply,       "slmult",       0 }, | 
|---|
| 1790 |  | 
|---|
| 1791 | { rtfParAttr,   rtfSubDocument,         "subdocument",  0 }, | 
|---|
| 1792 |  | 
|---|
| 1793 | { rtfParAttr,   rtfRTLPar,              "rtlpar",       0 }, | 
|---|
| 1794 | { rtfParAttr,   rtfLTRPar,              "ltrpar",       0 }, | 
|---|
| 1795 |  | 
|---|
| 1796 | { rtfParAttr,   rtfTabPos,              "tx",           0 }, | 
|---|
| 1797 | /* | 
|---|
| 1798 | * FrameMaker writes \tql (to mean left-justified tab, apparently) | 
|---|
| 1799 | * although it's not in the spec.  It's also redundant, since lj | 
|---|
| 1800 | * tabs are the default. | 
|---|
| 1801 | */ | 
|---|
| 1802 | { rtfParAttr,   rtfTabLeft,             "tql",          0 }, | 
|---|
| 1803 | { rtfParAttr,   rtfTabRight,            "tqr",          0 }, | 
|---|
| 1804 | { rtfParAttr,   rtfTabCenter,           "tqc",          0 }, | 
|---|
| 1805 | { rtfParAttr,   rtfTabDecimal,          "tqdec",        0 }, | 
|---|
| 1806 | { rtfParAttr,   rtfTabBar,              "tb",           0 }, | 
|---|
| 1807 | { rtfParAttr,   rtfLeaderDot,           "tldot",        0 }, | 
|---|
| 1808 | { rtfParAttr,   rtfLeaderHyphen,        "tlhyph",       0 }, | 
|---|
| 1809 | { rtfParAttr,   rtfLeaderUnder,         "tlul",         0 }, | 
|---|
| 1810 | { rtfParAttr,   rtfLeaderThick,         "tlth",         0 }, | 
|---|
| 1811 | { rtfParAttr,   rtfLeaderEqual,         "tleq",         0 }, | 
|---|
| 1812 |  | 
|---|
| 1813 | { rtfParAttr,   rtfParLevel,            "pnlvl",        0 }, | 
|---|
| 1814 | { rtfParAttr,   rtfParBullet,           "pnlvlblt",     0 }, | 
|---|
| 1815 | { rtfParAttr,   rtfParSimple,           "pnlvlbody",    0 }, | 
|---|
| 1816 | { rtfParAttr,   rtfParNumCont,          "pnlvlcont",    0 }, | 
|---|
| 1817 | { rtfParAttr,   rtfParNumOnce,          "pnnumonce",    0 }, | 
|---|
| 1818 | { rtfParAttr,   rtfParNumAcross,        "pnacross",     0 }, | 
|---|
| 1819 | { rtfParAttr,   rtfParHangIndent,       "pnhang",       0 }, | 
|---|
| 1820 | { rtfParAttr,   rtfParNumRestart,       "pnrestart",    0 }, | 
|---|
| 1821 | { rtfParAttr,   rtfParNumCardinal,      "pncard",       0 }, | 
|---|
| 1822 | { rtfParAttr,   rtfParNumDecimal,       "pndec",        0 }, | 
|---|
| 1823 | { rtfParAttr,   rtfParNumULetter,       "pnucltr",      0 }, | 
|---|
| 1824 | { rtfParAttr,   rtfParNumURoman,        "pnucrm",       0 }, | 
|---|
| 1825 | { rtfParAttr,   rtfParNumLLetter,       "pnlcltr",      0 }, | 
|---|
| 1826 | { rtfParAttr,   rtfParNumLRoman,        "pnlcrm",       0 }, | 
|---|
| 1827 | { rtfParAttr,   rtfParNumOrdinal,       "pnord",        0 }, | 
|---|
| 1828 | { rtfParAttr,   rtfParNumOrdinalText,   "pnordt",       0 }, | 
|---|
| 1829 | { rtfParAttr,   rtfParNumBold,          "pnb",          0 }, | 
|---|
| 1830 | { rtfParAttr,   rtfParNumItalic,        "pni",          0 }, | 
|---|
| 1831 | { rtfParAttr,   rtfParNumAllCaps,       "pncaps",       0 }, | 
|---|
| 1832 | { rtfParAttr,   rtfParNumSmallCaps,     "pnscaps",      0 }, | 
|---|
| 1833 | { rtfParAttr,   rtfParNumUnder,         "pnul",         0 }, | 
|---|
| 1834 | { rtfParAttr,   rtfParNumDotUnder,      "pnuld",        0 }, | 
|---|
| 1835 | { rtfParAttr,   rtfParNumDbUnder,       "pnuldb",       0 }, | 
|---|
| 1836 | { rtfParAttr,   rtfParNumNoUnder,       "pnulnone",     0 }, | 
|---|
| 1837 | { rtfParAttr,   rtfParNumWordUnder,     "pnulw",        0 }, | 
|---|
| 1838 | { rtfParAttr,   rtfParNumStrikethru,    "pnstrike",     0 }, | 
|---|
| 1839 | { rtfParAttr,   rtfParNumForeColor,     "pncf",         0 }, | 
|---|
| 1840 | { rtfParAttr,   rtfParNumFont,          "pnf",          0 }, | 
|---|
| 1841 | { rtfParAttr,   rtfParNumFontSize,      "pnfs",         0 }, | 
|---|
| 1842 | { rtfParAttr,   rtfParNumIndent,        "pnindent",     0 }, | 
|---|
| 1843 | { rtfParAttr,   rtfParNumSpacing,       "pnsp",         0 }, | 
|---|
| 1844 | { rtfParAttr,   rtfParNumInclPrev,      "pnprev",       0 }, | 
|---|
| 1845 | { rtfParAttr,   rtfParNumCenter,        "pnqc",         0 }, | 
|---|
| 1846 | { rtfParAttr,   rtfParNumLeft,          "pnql",         0 }, | 
|---|
| 1847 | { rtfParAttr,   rtfParNumRight,         "pnqr",         0 }, | 
|---|
| 1848 | { rtfParAttr,   rtfParNumStartAt,       "pnstart",      0 }, | 
|---|
| 1849 |  | 
|---|
| 1850 | { rtfParAttr,   rtfBorderTop,           "brdrt",        0 }, | 
|---|
| 1851 | { rtfParAttr,   rtfBorderBottom,        "brdrb",        0 }, | 
|---|
| 1852 | { rtfParAttr,   rtfBorderLeft,          "brdrl",        0 }, | 
|---|
| 1853 | { rtfParAttr,   rtfBorderRight,         "brdrr",        0 }, | 
|---|
| 1854 | { rtfParAttr,   rtfBorderBetween,       "brdrbtw",      0 }, | 
|---|
| 1855 | { rtfParAttr,   rtfBorderBar,           "brdrbar",      0 }, | 
|---|
| 1856 | { rtfParAttr,   rtfBorderBox,           "box",          0 }, | 
|---|
| 1857 | { rtfParAttr,   rtfBorderSingle,        "brdrs",        0 }, | 
|---|
| 1858 | { rtfParAttr,   rtfBorderThick,         "brdrth",       0 }, | 
|---|
| 1859 | { rtfParAttr,   rtfBorderShadow,        "brdrsh",       0 }, | 
|---|
| 1860 | { rtfParAttr,   rtfBorderDouble,        "brdrdb",       0 }, | 
|---|
| 1861 | { rtfParAttr,   rtfBorderDot,           "brdrdot",      0 }, | 
|---|
| 1862 | { rtfParAttr,   rtfBorderDot,           "brdrdash",     0 }, | 
|---|
| 1863 | { rtfParAttr,   rtfBorderHair,          "brdrhair",     0 }, | 
|---|
| 1864 | { rtfParAttr,   rtfBorderWidth,         "brdrw",        0 }, | 
|---|
| 1865 | { rtfParAttr,   rtfBorderColor,         "brdrcf",       0 }, | 
|---|
| 1866 | { rtfParAttr,   rtfBorderSpace,         "brsp",         0 }, | 
|---|
| 1867 |  | 
|---|
| 1868 | { rtfParAttr,   rtfShading,             "shading",      0 }, | 
|---|
| 1869 | { rtfParAttr,   rtfBgPatH,              "bghoriz",      0 }, | 
|---|
| 1870 | { rtfParAttr,   rtfBgPatV,              "bgvert",       0 }, | 
|---|
| 1871 | { rtfParAttr,   rtfFwdDiagBgPat,        "bgfdiag",      0 }, | 
|---|
| 1872 | { rtfParAttr,   rtfBwdDiagBgPat,        "bgbdiag",      0 }, | 
|---|
| 1873 | { rtfParAttr,   rtfHatchBgPat,          "bgcross",      0 }, | 
|---|
| 1874 | { rtfParAttr,   rtfDiagHatchBgPat,      "bgdcross",     0 }, | 
|---|
| 1875 | { rtfParAttr,   rtfDarkBgPatH,          "bgdkhoriz",    0 }, | 
|---|
| 1876 | { rtfParAttr,   rtfDarkBgPatV,          "bgdkvert",     0 }, | 
|---|
| 1877 | { rtfParAttr,   rtfFwdDarkBgPat,        "bgdkfdiag",    0 }, | 
|---|
| 1878 | { rtfParAttr,   rtfBwdDarkBgPat,        "bgdkbdiag",    0 }, | 
|---|
| 1879 | { rtfParAttr,   rtfDarkHatchBgPat,      "bgdkcross",    0 }, | 
|---|
| 1880 | { rtfParAttr,   rtfDarkDiagHatchBgPat,  "bgdkdcross",   0 }, | 
|---|
| 1881 | { rtfParAttr,   rtfBgPatLineColor,      "cfpat",        0 }, | 
|---|
| 1882 | { rtfParAttr,   rtfBgPatColor,          "cbpat",        0 }, | 
|---|
| 1883 |  | 
|---|
| 1884 | /* | 
|---|
| 1885 | * Section formatting attributes | 
|---|
| 1886 | */ | 
|---|
| 1887 |  | 
|---|
| 1888 | { rtfSectAttr,  rtfSectDef,             "sectd",        0 }, | 
|---|
| 1889 | { rtfSectAttr,  rtfENoteHere,           "endnhere",     0 }, | 
|---|
| 1890 | { rtfSectAttr,  rtfPrtBinFirst,         "binfsxn",      0 }, | 
|---|
| 1891 | { rtfSectAttr,  rtfPrtBin,              "binsxn",       0 }, | 
|---|
| 1892 | { rtfSectAttr,  rtfSectStyleNum,        "ds",           0 }, | 
|---|
| 1893 |  | 
|---|
| 1894 | { rtfSectAttr,  rtfNoBreak,             "sbknone",      0 }, | 
|---|
| 1895 | { rtfSectAttr,  rtfColBreak,            "sbkcol",       0 }, | 
|---|
| 1896 | { rtfSectAttr,  rtfPageBreak,           "sbkpage",      0 }, | 
|---|
| 1897 | { rtfSectAttr,  rtfEvenBreak,           "sbkeven",      0 }, | 
|---|
| 1898 | { rtfSectAttr,  rtfOddBreak,            "sbkodd",       0 }, | 
|---|
| 1899 |  | 
|---|
| 1900 | { rtfSectAttr,  rtfColumns,             "cols",         0 }, | 
|---|
| 1901 | { rtfSectAttr,  rtfColumnSpace,         "colsx",        0 }, | 
|---|
| 1902 | { rtfSectAttr,  rtfColumnNumber,        "colno",        0 }, | 
|---|
| 1903 | { rtfSectAttr,  rtfColumnSpRight,       "colsr",        0 }, | 
|---|
| 1904 | { rtfSectAttr,  rtfColumnWidth,         "colw",         0 }, | 
|---|
| 1905 | { rtfSectAttr,  rtfColumnLine,          "linebetcol",   0 }, | 
|---|
| 1906 |  | 
|---|
| 1907 | { rtfSectAttr,  rtfLineModulus,         "linemod",      0 }, | 
|---|
| 1908 | { rtfSectAttr,  rtfLineDist,            "linex",        0 }, | 
|---|
| 1909 | { rtfSectAttr,  rtfLineStarts,          "linestarts",   0 }, | 
|---|
| 1910 | { rtfSectAttr,  rtfLineRestart,         "linerestart",  0 }, | 
|---|
| 1911 | { rtfSectAttr,  rtfLineRestartPg,       "lineppage",    0 }, | 
|---|
| 1912 | { rtfSectAttr,  rtfLineCont,            "linecont",     0 }, | 
|---|
| 1913 |  | 
|---|
| 1914 | { rtfSectAttr,  rtfSectPageWid,         "pgwsxn",       0 }, | 
|---|
| 1915 | { rtfSectAttr,  rtfSectPageHt,          "pghsxn",       0 }, | 
|---|
| 1916 | { rtfSectAttr,  rtfSectMarginLeft,      "marglsxn",     0 }, | 
|---|
| 1917 | { rtfSectAttr,  rtfSectMarginRight,     "margrsxn",     0 }, | 
|---|
| 1918 | { rtfSectAttr,  rtfSectMarginTop,       "margtsxn",     0 }, | 
|---|
| 1919 | { rtfSectAttr,  rtfSectMarginBottom,    "margbsxn",     0 }, | 
|---|
| 1920 | { rtfSectAttr,  rtfSectMarginGutter,    "guttersxn",    0 }, | 
|---|
| 1921 | { rtfSectAttr,  rtfSectLandscape,       "lndscpsxn",    0 }, | 
|---|
| 1922 | { rtfSectAttr,  rtfTitleSpecial,        "titlepg",      0 }, | 
|---|
| 1923 | { rtfSectAttr,  rtfHeaderY,             "headery",      0 }, | 
|---|
| 1924 | { rtfSectAttr,  rtfFooterY,             "footery",      0 }, | 
|---|
| 1925 |  | 
|---|
| 1926 | { rtfSectAttr,  rtfPageStarts,          "pgnstarts",    0 }, | 
|---|
| 1927 | { rtfSectAttr,  rtfPageCont,            "pgncont",      0 }, | 
|---|
| 1928 | { rtfSectAttr,  rtfPageRestart,         "pgnrestart",   0 }, | 
|---|
| 1929 | { rtfSectAttr,  rtfPageNumRight,        "pgnx",         0 }, | 
|---|
| 1930 | { rtfSectAttr,  rtfPageNumTop,          "pgny",         0 }, | 
|---|
| 1931 | { rtfSectAttr,  rtfPageDecimal,         "pgndec",       0 }, | 
|---|
| 1932 | { rtfSectAttr,  rtfPageURoman,          "pgnucrm",      0 }, | 
|---|
| 1933 | { rtfSectAttr,  rtfPageLRoman,          "pgnlcrm",      0 }, | 
|---|
| 1934 | { rtfSectAttr,  rtfPageULetter,         "pgnucltr",     0 }, | 
|---|
| 1935 | { rtfSectAttr,  rtfPageLLetter,         "pgnlcltr",     0 }, | 
|---|
| 1936 | { rtfSectAttr,  rtfPageNumHyphSep,      "pgnhnsh",      0 }, | 
|---|
| 1937 | { rtfSectAttr,  rtfPageNumSpaceSep,     "pgnhnsp",      0 }, | 
|---|
| 1938 | { rtfSectAttr,  rtfPageNumColonSep,     "pgnhnsc",      0 }, | 
|---|
| 1939 | { rtfSectAttr,  rtfPageNumEmdashSep,    "pgnhnsm",      0 }, | 
|---|
| 1940 | { rtfSectAttr,  rtfPageNumEndashSep,    "pgnhnsn",      0 }, | 
|---|
| 1941 |  | 
|---|
| 1942 | { rtfSectAttr,  rtfTopVAlign,           "vertalt",      0 }, | 
|---|
| 1943 | /* misspelled as "vertal" in specification 1.0 */ | 
|---|
| 1944 | { rtfSectAttr,  rtfBottomVAlign,        "vertalb",      0 }, | 
|---|
| 1945 | { rtfSectAttr,  rtfCenterVAlign,        "vertalc",      0 }, | 
|---|
| 1946 | { rtfSectAttr,  rtfJustVAlign,          "vertalj",      0 }, | 
|---|
| 1947 |  | 
|---|
| 1948 | { rtfSectAttr,  rtfRTLSect,             "rtlsect",      0 }, | 
|---|
| 1949 | { rtfSectAttr,  rtfLTRSect,             "ltrsect",      0 }, | 
|---|
| 1950 |  | 
|---|
| 1951 | /* I've seen these in an old spec, but not in real files... */ | 
|---|
| 1952 | /*rtfSectAttr,  rtfNoBreak,             "nobreak",      0,*/ | 
|---|
| 1953 | /*rtfSectAttr,  rtfColBreak,            "colbreak",     0,*/ | 
|---|
| 1954 | /*rtfSectAttr,  rtfPageBreak,           "pagebreak",    0,*/ | 
|---|
| 1955 | /*rtfSectAttr,  rtfEvenBreak,           "evenbreak",    0,*/ | 
|---|
| 1956 | /*rtfSectAttr,  rtfOddBreak,            "oddbreak",     0,*/ | 
|---|
| 1957 |  | 
|---|
| 1958 | /* | 
|---|
| 1959 | * Document formatting attributes | 
|---|
| 1960 | */ | 
|---|
| 1961 |  | 
|---|
| 1962 | { rtfDocAttr,   rtfDefTab,              "deftab",       0 }, | 
|---|
| 1963 | { rtfDocAttr,   rtfHyphHotZone,         "hyphhotz",     0 }, | 
|---|
| 1964 | { rtfDocAttr,   rtfHyphConsecLines,     "hyphconsec",   0 }, | 
|---|
| 1965 | { rtfDocAttr,   rtfHyphCaps,            "hyphcaps",     0 }, | 
|---|
| 1966 | { rtfDocAttr,   rtfHyphAuto,            "hyphauto",     0 }, | 
|---|
| 1967 | { rtfDocAttr,   rtfLineStart,           "linestart",    0 }, | 
|---|
| 1968 | { rtfDocAttr,   rtfFracWidth,           "fracwidth",    0 }, | 
|---|
| 1969 | /* \makeback was given in old version of spec, it's now */ | 
|---|
| 1970 | /* listed as \makebackup */ | 
|---|
| 1971 | { rtfDocAttr,   rtfMakeBackup,          "makeback",     0 }, | 
|---|
| 1972 | { rtfDocAttr,   rtfMakeBackup,          "makebackup",   0 }, | 
|---|
| 1973 | { rtfDocAttr,   rtfRTFDefault,          "defformat",    0 }, | 
|---|
| 1974 | { rtfDocAttr,   rtfPSOverlay,           "psover",       0 }, | 
|---|
| 1975 | { rtfDocAttr,   rtfDocTemplate,         "doctemp",      0 }, | 
|---|
| 1976 | { rtfDocAttr,   rtfDefLanguage,         "deflang",      0 }, | 
|---|
| 1977 |  | 
|---|
| 1978 | { rtfDocAttr,   rtfFENoteType,          "fet",          0 }, | 
|---|
| 1979 | { rtfDocAttr,   rtfFNoteEndSect,        "endnotes",     0 }, | 
|---|
| 1980 | { rtfDocAttr,   rtfFNoteEndDoc,         "enddoc",       0 }, | 
|---|
| 1981 | { rtfDocAttr,   rtfFNoteText,           "ftntj",        0 }, | 
|---|
| 1982 | { rtfDocAttr,   rtfFNoteBottom,         "ftnbj",        0 }, | 
|---|
| 1983 | { rtfDocAttr,   rtfENoteEndSect,        "aendnotes",    0 }, | 
|---|
| 1984 | { rtfDocAttr,   rtfENoteEndDoc,         "aenddoc",      0 }, | 
|---|
| 1985 | { rtfDocAttr,   rtfENoteText,           "aftntj",       0 }, | 
|---|
| 1986 | { rtfDocAttr,   rtfENoteBottom,         "aftnbj",       0 }, | 
|---|
| 1987 | { rtfDocAttr,   rtfFNoteStart,          "ftnstart",     0 }, | 
|---|
| 1988 | { rtfDocAttr,   rtfENoteStart,          "aftnstart",    0 }, | 
|---|
| 1989 | { rtfDocAttr,   rtfFNoteRestartPage,    "ftnrstpg",     0 }, | 
|---|
| 1990 | { rtfDocAttr,   rtfFNoteRestart,        "ftnrestart",   0 }, | 
|---|
| 1991 | { rtfDocAttr,   rtfFNoteRestartCont,    "ftnrstcont",   0 }, | 
|---|
| 1992 | { rtfDocAttr,   rtfENoteRestart,        "aftnrestart",  0 }, | 
|---|
| 1993 | { rtfDocAttr,   rtfENoteRestartCont,    "aftnrstcont",  0 }, | 
|---|
| 1994 | { rtfDocAttr,   rtfFNoteNumArabic,      "ftnnar",       0 }, | 
|---|
| 1995 | { rtfDocAttr,   rtfFNoteNumLLetter,     "ftnnalc",      0 }, | 
|---|
| 1996 | { rtfDocAttr,   rtfFNoteNumULetter,     "ftnnauc",      0 }, | 
|---|
| 1997 | { rtfDocAttr,   rtfFNoteNumLRoman,      "ftnnrlc",      0 }, | 
|---|
| 1998 | { rtfDocAttr,   rtfFNoteNumURoman,      "ftnnruc",      0 }, | 
|---|
| 1999 | { rtfDocAttr,   rtfFNoteNumChicago,     "ftnnchi",      0 }, | 
|---|
| 2000 | { rtfDocAttr,   rtfENoteNumArabic,      "aftnnar",      0 }, | 
|---|
| 2001 | { rtfDocAttr,   rtfENoteNumLLetter,     "aftnnalc",     0 }, | 
|---|
| 2002 | { rtfDocAttr,   rtfENoteNumULetter,     "aftnnauc",     0 }, | 
|---|
| 2003 | { rtfDocAttr,   rtfENoteNumLRoman,      "aftnnrlc",     0 }, | 
|---|
| 2004 | { rtfDocAttr,   rtfENoteNumURoman,      "aftnnruc",     0 }, | 
|---|
| 2005 | { rtfDocAttr,   rtfENoteNumChicago,     "aftnnchi",     0 }, | 
|---|
| 2006 |  | 
|---|
| 2007 | { rtfDocAttr,   rtfPaperWidth,          "paperw",       0 }, | 
|---|
| 2008 | { rtfDocAttr,   rtfPaperHeight,         "paperh",       0 }, | 
|---|
| 2009 | { rtfDocAttr,   rtfPaperSize,           "psz",          0 }, | 
|---|
| 2010 | { rtfDocAttr,   rtfLeftMargin,          "margl",        0 }, | 
|---|
| 2011 | { rtfDocAttr,   rtfRightMargin,         "margr",        0 }, | 
|---|
| 2012 | { rtfDocAttr,   rtfTopMargin,           "margt",        0 }, | 
|---|
| 2013 | { rtfDocAttr,   rtfBottomMargin,        "margb",        0 }, | 
|---|
| 2014 | { rtfDocAttr,   rtfFacingPage,          "facingp",      0 }, | 
|---|
| 2015 | { rtfDocAttr,   rtfGutterWid,           "gutter",       0 }, | 
|---|
| 2016 | { rtfDocAttr,   rtfMirrorMargin,        "margmirror",   0 }, | 
|---|
| 2017 | { rtfDocAttr,   rtfLandscape,           "landscape",    0 }, | 
|---|
| 2018 | { rtfDocAttr,   rtfPageStart,           "pgnstart",     0 }, | 
|---|
| 2019 | { rtfDocAttr,   rtfWidowCtrl,           "widowctrl",    0 }, | 
|---|
| 2020 |  | 
|---|
| 2021 | { rtfDocAttr,   rtfLinkStyles,          "linkstyles",   0 }, | 
|---|
| 2022 |  | 
|---|
| 2023 | { rtfDocAttr,   rtfNoAutoTabIndent,     "notabind",     0 }, | 
|---|
| 2024 | { rtfDocAttr,   rtfWrapSpaces,          "wraptrsp",     0 }, | 
|---|
| 2025 | { rtfDocAttr,   rtfPrintColorsBlack,    "prcolbl",      0 }, | 
|---|
| 2026 | { rtfDocAttr,   rtfNoExtraSpaceRL,      "noextrasprl",  0 }, | 
|---|
| 2027 | { rtfDocAttr,   rtfNoColumnBalance,     "nocolbal",     0 }, | 
|---|
| 2028 | { rtfDocAttr,   rtfCvtMailMergeQuote,   "cvmme",        0 }, | 
|---|
| 2029 | { rtfDocAttr,   rtfSuppressTopSpace,    "sprstsp",      0 }, | 
|---|
| 2030 | { rtfDocAttr,   rtfSuppressPreParSpace, "sprsspbf",     0 }, | 
|---|
| 2031 | { rtfDocAttr,   rtfCombineTblBorders,   "otblrul",      0 }, | 
|---|
| 2032 | { rtfDocAttr,   rtfTranspMetafiles,     "transmf",      0 }, | 
|---|
| 2033 | { rtfDocAttr,   rtfSwapBorders,         "swpbdr",       0 }, | 
|---|
| 2034 | { rtfDocAttr,   rtfShowHardBreaks,      "brkfrm",       0 }, | 
|---|
| 2035 |  | 
|---|
| 2036 | { rtfDocAttr,   rtfFormProtected,       "formprot",     0 }, | 
|---|
| 2037 | { rtfDocAttr,   rtfAllProtected,        "allprot",      0 }, | 
|---|
| 2038 | { rtfDocAttr,   rtfFormShading,         "formshade",    0 }, | 
|---|
| 2039 | { rtfDocAttr,   rtfFormDisplay,         "formdisp",     0 }, | 
|---|
| 2040 | { rtfDocAttr,   rtfPrintData,           "printdata",    0 }, | 
|---|
| 2041 |  | 
|---|
| 2042 | { rtfDocAttr,   rtfRevProtected,        "revprot",      0 }, | 
|---|
| 2043 | { rtfDocAttr,   rtfRevisions,           "revisions",    0 }, | 
|---|
| 2044 | { rtfDocAttr,   rtfRevDisplay,          "revprop",      0 }, | 
|---|
| 2045 | { rtfDocAttr,   rtfRevBar,              "revbar",       0 }, | 
|---|
| 2046 |  | 
|---|
| 2047 | { rtfDocAttr,   rtfAnnotProtected,      "annotprot",    0 }, | 
|---|
| 2048 |  | 
|---|
| 2049 | { rtfDocAttr,   rtfRTLDoc,              "rtldoc",       0 }, | 
|---|
| 2050 | { rtfDocAttr,   rtfLTRDoc,              "ltrdoc",       0 }, | 
|---|
| 2051 |  | 
|---|
| 2052 | /* | 
|---|
| 2053 | * Style attributes | 
|---|
| 2054 | */ | 
|---|
| 2055 |  | 
|---|
| 2056 | { rtfStyleAttr, rtfAdditive,            "additive",     0 }, | 
|---|
| 2057 | { rtfStyleAttr, rtfBasedOn,             "sbasedon",     0 }, | 
|---|
| 2058 | { rtfStyleAttr, rtfNext,                "snext",        0 }, | 
|---|
| 2059 |  | 
|---|
| 2060 | /* | 
|---|
| 2061 | * Picture attributes | 
|---|
| 2062 | */ | 
|---|
| 2063 |  | 
|---|
| 2064 | { rtfPictAttr,  rtfMacQD,               "macpict",      0 }, | 
|---|
| 2065 | { rtfPictAttr,  rtfPMMetafile,          "pmmetafile",   0 }, | 
|---|
| 2066 | { rtfPictAttr,  rtfWinMetafile,         "wmetafile",    0 }, | 
|---|
| 2067 | { rtfPictAttr,  rtfDevIndBitmap,        "dibitmap",     0 }, | 
|---|
| 2068 | { rtfPictAttr,  rtfWinBitmap,           "wbitmap",      0 }, | 
|---|
| 2069 | { rtfPictAttr,  rtfPixelBits,           "wbmbitspixel", 0 }, | 
|---|
| 2070 | { rtfPictAttr,  rtfBitmapPlanes,        "wbmplanes",    0 }, | 
|---|
| 2071 | { rtfPictAttr,  rtfBitmapWid,           "wbmwidthbytes", 0 }, | 
|---|
| 2072 |  | 
|---|
| 2073 | { rtfPictAttr,  rtfPicWid,              "picw",         0 }, | 
|---|
| 2074 | { rtfPictAttr,  rtfPicHt,               "pich",         0 }, | 
|---|
| 2075 | { rtfPictAttr,  rtfPicGoalWid,          "picwgoal",     0 }, | 
|---|
| 2076 | { rtfPictAttr,  rtfPicGoalHt,           "pichgoal",     0 }, | 
|---|
| 2077 | /* these two aren't in the spec, but some writers emit them */ | 
|---|
| 2078 | { rtfPictAttr,  rtfPicGoalWid,          "picwGoal",     0 }, | 
|---|
| 2079 | { rtfPictAttr,  rtfPicGoalHt,           "pichGoal",     0 }, | 
|---|
| 2080 | { rtfPictAttr,  rtfPicScaleX,           "picscalex",    0 }, | 
|---|
| 2081 | { rtfPictAttr,  rtfPicScaleY,           "picscaley",    0 }, | 
|---|
| 2082 | { rtfPictAttr,  rtfPicScaled,           "picscaled",    0 }, | 
|---|
| 2083 | { rtfPictAttr,  rtfPicCropTop,          "piccropt",     0 }, | 
|---|
| 2084 | { rtfPictAttr,  rtfPicCropBottom,       "piccropb",     0 }, | 
|---|
| 2085 | { rtfPictAttr,  rtfPicCropLeft,         "piccropl",     0 }, | 
|---|
| 2086 | { rtfPictAttr,  rtfPicCropRight,        "piccropr",     0 }, | 
|---|
| 2087 |  | 
|---|
| 2088 | { rtfPictAttr,  rtfPicMFHasBitmap,      "picbmp",       0 }, | 
|---|
| 2089 | { rtfPictAttr,  rtfPicMFBitsPerPixel,   "picbpp",       0 }, | 
|---|
| 2090 |  | 
|---|
| 2091 | { rtfPictAttr,  rtfPicBinary,           "bin",          0 }, | 
|---|
| 2092 |  | 
|---|
| 2093 | /* | 
|---|
| 2094 | * NeXT graphic attributes | 
|---|
| 2095 | */ | 
|---|
| 2096 |  | 
|---|
| 2097 | { rtfNeXTGrAttr,        rtfNeXTGWidth,          "width",        0 }, | 
|---|
| 2098 | { rtfNeXTGrAttr,        rtfNeXTGHeight,         "height",       0 }, | 
|---|
| 2099 |  | 
|---|
| 2100 | /* | 
|---|
| 2101 | * Destinations | 
|---|
| 2102 | */ | 
|---|
| 2103 |  | 
|---|
| 2104 | { rtfDestination,       rtfFontTbl,             "fonttbl",      0 }, | 
|---|
| 2105 | { rtfDestination,       rtfFontAltName,         "falt",         0 }, | 
|---|
| 2106 | { rtfDestination,       rtfEmbeddedFont,        "fonteb",       0 }, | 
|---|
| 2107 | { rtfDestination,       rtfFontFile,            "fontfile",     0 }, | 
|---|
| 2108 | { rtfDestination,       rtfFileTbl,             "filetbl",      0 }, | 
|---|
| 2109 | { rtfDestination,       rtfFileInfo,            "file",         0 }, | 
|---|
| 2110 | { rtfDestination,       rtfColorTbl,            "colortbl",     0 }, | 
|---|
| 2111 | { rtfDestination,       rtfStyleSheet,          "stylesheet",   0 }, | 
|---|
| 2112 | { rtfDestination,       rtfKeyCode,             "keycode",      0 }, | 
|---|
| 2113 | { rtfDestination,       rtfRevisionTbl,         "revtbl",       0 }, | 
|---|
| 2114 | { rtfDestination,       rtfInfo,                "info",         0 }, | 
|---|
| 2115 | { rtfDestination,       rtfITitle,              "title",        0 }, | 
|---|
| 2116 | { rtfDestination,       rtfISubject,            "subject",      0 }, | 
|---|
| 2117 | { rtfDestination,       rtfIAuthor,             "author",       0 }, | 
|---|
| 2118 | { rtfDestination,       rtfIOperator,           "operator",     0 }, | 
|---|
| 2119 | { rtfDestination,       rtfIKeywords,           "keywords",     0 }, | 
|---|
| 2120 | { rtfDestination,       rtfIComment,            "comment",      0 }, | 
|---|
| 2121 | { rtfDestination,       rtfIVersion,            "version",      0 }, | 
|---|
| 2122 | { rtfDestination,       rtfIDoccomm,            "doccomm",      0 }, | 
|---|
| 2123 | /* \verscomm may not exist -- was seen in earlier spec version */ | 
|---|
| 2124 | { rtfDestination,       rtfIVerscomm,           "verscomm",     0 }, | 
|---|
| 2125 | { rtfDestination,       rtfNextFile,            "nextfile",     0 }, | 
|---|
| 2126 | { rtfDestination,       rtfTemplate,            "template",     0 }, | 
|---|
| 2127 | { rtfDestination,       rtfFNSep,               "ftnsep",       0 }, | 
|---|
| 2128 | { rtfDestination,       rtfFNContSep,           "ftnsepc",      0 }, | 
|---|
| 2129 | { rtfDestination,       rtfFNContNotice,        "ftncn",        0 }, | 
|---|
| 2130 | { rtfDestination,       rtfENSep,               "aftnsep",      0 }, | 
|---|
| 2131 | { rtfDestination,       rtfENContSep,           "aftnsepc",     0 }, | 
|---|
| 2132 | { rtfDestination,       rtfENContNotice,        "aftncn",       0 }, | 
|---|
| 2133 | { rtfDestination,       rtfPageNumLevel,        "pgnhn",        0 }, | 
|---|
| 2134 | { rtfDestination,       rtfParNumLevelStyle,    "pnseclvl",     0 }, | 
|---|
| 2135 | { rtfDestination,       rtfHeader,              "header",       0 }, | 
|---|
| 2136 | { rtfDestination,       rtfFooter,              "footer",       0 }, | 
|---|
| 2137 | { rtfDestination,       rtfHeaderLeft,          "headerl",      0 }, | 
|---|
| 2138 | { rtfDestination,       rtfHeaderRight,         "headerr",      0 }, | 
|---|
| 2139 | { rtfDestination,       rtfHeaderFirst,         "headerf",      0 }, | 
|---|
| 2140 | { rtfDestination,       rtfFooterLeft,          "footerl",      0 }, | 
|---|
| 2141 | { rtfDestination,       rtfFooterRight,         "footerr",      0 }, | 
|---|
| 2142 | { rtfDestination,       rtfFooterFirst,         "footerf",      0 }, | 
|---|
| 2143 | { rtfDestination,       rtfParNumText,          "pntext",       0 }, | 
|---|
| 2144 | { rtfDestination,       rtfParNumbering,        "pn",           0 }, | 
|---|
| 2145 | { rtfDestination,       rtfParNumTextAfter,     "pntexta",      0 }, | 
|---|
| 2146 | { rtfDestination,       rtfParNumTextBefore,    "pntextb",      0 }, | 
|---|
| 2147 | { rtfDestination,       rtfBookmarkStart,       "bkmkstart",    0 }, | 
|---|
| 2148 | { rtfDestination,       rtfBookmarkEnd,         "bkmkend",      0 }, | 
|---|
| 2149 | { rtfDestination,       rtfPict,                "pict",         0 }, | 
|---|
| 2150 | { rtfDestination,       rtfObject,              "object",       0 }, | 
|---|
| 2151 | { rtfDestination,       rtfObjClass,            "objclass",     0 }, | 
|---|
| 2152 | { rtfDestination,       rtfObjName,             "objname",      0 }, | 
|---|
| 2153 | { rtfObjAttr,   rtfObjTime,             "objtime",      0 }, | 
|---|
| 2154 | { rtfDestination,       rtfObjData,             "objdata",      0 }, | 
|---|
| 2155 | { rtfDestination,       rtfObjAlias,            "objalias",     0 }, | 
|---|
| 2156 | { rtfDestination,       rtfObjSection,          "objsect",      0 }, | 
|---|
| 2157 | /* objitem and objtopic aren't documented in the spec! */ | 
|---|
| 2158 | { rtfDestination,       rtfObjItem,             "objitem",      0 }, | 
|---|
| 2159 | { rtfDestination,       rtfObjTopic,            "objtopic",     0 }, | 
|---|
| 2160 | { rtfDestination,       rtfObjResult,           "result",       0 }, | 
|---|
| 2161 | { rtfDestination,       rtfDrawObject,          "do",           0 }, | 
|---|
| 2162 | { rtfDestination,       rtfFootnote,            "footnote",     0 }, | 
|---|
| 2163 | { rtfDestination,       rtfAnnotRefStart,       "atrfstart",    0 }, | 
|---|
| 2164 | { rtfDestination,       rtfAnnotRefEnd,         "atrfend",      0 }, | 
|---|
| 2165 | { rtfDestination,       rtfAnnotID,             "atnid",        0 }, | 
|---|
| 2166 | { rtfDestination,       rtfAnnotAuthor,         "atnauthor",    0 }, | 
|---|
| 2167 | { rtfDestination,       rtfAnnotation,          "annotation",   0 }, | 
|---|
| 2168 | { rtfDestination,       rtfAnnotRef,            "atnref",       0 }, | 
|---|
| 2169 | { rtfDestination,       rtfAnnotTime,           "atntime",      0 }, | 
|---|
| 2170 | { rtfDestination,       rtfAnnotIcon,           "atnicn",       0 }, | 
|---|
| 2171 | { rtfDestination,       rtfField,               "field",        0 }, | 
|---|
| 2172 | { rtfDestination,       rtfFieldInst,           "fldinst",      0 }, | 
|---|
| 2173 | { rtfDestination,       rtfFieldResult,         "fldrslt",      0 }, | 
|---|
| 2174 | { rtfDestination,       rtfDataField,           "datafield",    0 }, | 
|---|
| 2175 | { rtfDestination,       rtfIndex,               "xe",           0 }, | 
|---|
| 2176 | { rtfDestination,       rtfIndexText,           "txe",          0 }, | 
|---|
| 2177 | { rtfDestination,       rtfIndexRange,          "rxe",          0 }, | 
|---|
| 2178 | { rtfDestination,       rtfTOC,                 "tc",           0 }, | 
|---|
| 2179 | { rtfDestination,       rtfNeXTGraphic,         "NeXTGraphic",  0 }, | 
|---|
| 2180 |  | 
|---|
| 2181 | /* | 
|---|
| 2182 | * Font families | 
|---|
| 2183 | */ | 
|---|
| 2184 |  | 
|---|
| 2185 | { rtfFontFamily,        rtfFFNil,               "fnil",         0 }, | 
|---|
| 2186 | { rtfFontFamily,        rtfFFRoman,             "froman",       0 }, | 
|---|
| 2187 | { rtfFontFamily,        rtfFFSwiss,             "fswiss",       0 }, | 
|---|
| 2188 | { rtfFontFamily,        rtfFFModern,            "fmodern",      0 }, | 
|---|
| 2189 | { rtfFontFamily,        rtfFFScript,            "fscript",      0 }, | 
|---|
| 2190 | { rtfFontFamily,        rtfFFDecor,             "fdecor",       0 }, | 
|---|
| 2191 | { rtfFontFamily,        rtfFFTech,              "ftech",        0 }, | 
|---|
| 2192 | { rtfFontFamily,        rtfFFBidirectional,     "fbidi",        0 }, | 
|---|
| 2193 |  | 
|---|
| 2194 | /* | 
|---|
| 2195 | * Font attributes | 
|---|
| 2196 | */ | 
|---|
| 2197 |  | 
|---|
| 2198 | { rtfFontAttr,  rtfFontCharSet,         "fcharset",     0 }, | 
|---|
| 2199 | { rtfFontAttr,  rtfFontPitch,           "fprq",         0 }, | 
|---|
| 2200 | { rtfFontAttr,  rtfFontCodePage,        "cpg",          0 }, | 
|---|
| 2201 | { rtfFontAttr,  rtfFTypeNil,            "ftnil",        0 }, | 
|---|
| 2202 | { rtfFontAttr,  rtfFTypeTrueType,       "fttruetype",   0 }, | 
|---|
| 2203 |  | 
|---|
| 2204 | /* | 
|---|
| 2205 | * File table attributes | 
|---|
| 2206 | */ | 
|---|
| 2207 |  | 
|---|
| 2208 | { rtfFileAttr,  rtfFileNum,             "fid",          0 }, | 
|---|
| 2209 | { rtfFileAttr,  rtfFileRelPath,         "frelative",    0 }, | 
|---|
| 2210 | { rtfFileAttr,  rtfFileOSNum,           "fosnum",       0 }, | 
|---|
| 2211 |  | 
|---|
| 2212 | /* | 
|---|
| 2213 | * File sources | 
|---|
| 2214 | */ | 
|---|
| 2215 |  | 
|---|
| 2216 | { rtfFileSource,        rtfSrcMacintosh,        "fvalidmac",    0 }, | 
|---|
| 2217 | { rtfFileSource,        rtfSrcDOS,              "fvaliddos",    0 }, | 
|---|
| 2218 | { rtfFileSource,        rtfSrcNTFS,             "fvalidntfs",   0 }, | 
|---|
| 2219 | { rtfFileSource,        rtfSrcHPFS,             "fvalidhpfs",   0 }, | 
|---|
| 2220 | { rtfFileSource,        rtfSrcNetwork,          "fnetwork",     0 }, | 
|---|
| 2221 |  | 
|---|
| 2222 | /* | 
|---|
| 2223 | * Color names | 
|---|
| 2224 | */ | 
|---|
| 2225 |  | 
|---|
| 2226 | { rtfColorName, rtfRed,                 "red",          0 }, | 
|---|
| 2227 | { rtfColorName, rtfGreen,               "green",        0 }, | 
|---|
| 2228 | { rtfColorName, rtfBlue,                "blue",         0 }, | 
|---|
| 2229 |  | 
|---|
| 2230 | /* | 
|---|
| 2231 | * Charset names | 
|---|
| 2232 | */ | 
|---|
| 2233 |  | 
|---|
| 2234 | { rtfCharSet,   rtfMacCharSet,          "mac",          0 }, | 
|---|
| 2235 | { rtfCharSet,   rtfAnsiCharSet,         "ansi",         0 }, | 
|---|
| 2236 | { rtfCharSet,   rtfPcCharSet,           "pc",           0 }, | 
|---|
| 2237 | { rtfCharSet,   rtfPcaCharSet,          "pca",          0 }, | 
|---|
| 2238 |  | 
|---|
| 2239 | /* | 
|---|
| 2240 | * Table attributes | 
|---|
| 2241 | */ | 
|---|
| 2242 |  | 
|---|
| 2243 | { rtfTblAttr,   rtfRowDef,              "trowd",        0 }, | 
|---|
| 2244 | { rtfTblAttr,   rtfRowGapH,             "trgaph",       0 }, | 
|---|
| 2245 | { rtfTblAttr,   rtfCellPos,             "cellx",        0 }, | 
|---|
| 2246 | { rtfTblAttr,   rtfMergeRngFirst,       "clmgf",        0 }, | 
|---|
| 2247 | { rtfTblAttr,   rtfMergePrevious,       "clmrg",        0 }, | 
|---|
| 2248 |  | 
|---|
| 2249 | { rtfTblAttr,   rtfRowLeft,             "trql",         0 }, | 
|---|
| 2250 | { rtfTblAttr,   rtfRowRight,            "trqr",         0 }, | 
|---|
| 2251 | { rtfTblAttr,   rtfRowCenter,           "trqc",         0 }, | 
|---|
| 2252 | { rtfTblAttr,   rtfRowLeftEdge,         "trleft",       0 }, | 
|---|
| 2253 | { rtfTblAttr,   rtfRowHt,               "trrh",         0 }, | 
|---|
| 2254 | { rtfTblAttr,   rtfRowHeader,           "trhdr",        0 }, | 
|---|
| 2255 | { rtfTblAttr,   rtfRowKeep,             "trkeep",       0 }, | 
|---|
| 2256 |  | 
|---|
| 2257 | { rtfTblAttr,   rtfRTLRow,              "rtlrow",       0 }, | 
|---|
| 2258 | { rtfTblAttr,   rtfLTRRow,              "ltrrow",       0 }, | 
|---|
| 2259 |  | 
|---|
| 2260 | { rtfTblAttr,   rtfRowBordTop,          "trbrdrt",      0 }, | 
|---|
| 2261 | { rtfTblAttr,   rtfRowBordLeft,         "trbrdrl",      0 }, | 
|---|
| 2262 | { rtfTblAttr,   rtfRowBordBottom,       "trbrdrb",      0 }, | 
|---|
| 2263 | { rtfTblAttr,   rtfRowBordRight,        "trbrdrr",      0 }, | 
|---|
| 2264 | { rtfTblAttr,   rtfRowBordHoriz,        "trbrdrh",      0 }, | 
|---|
| 2265 | { rtfTblAttr,   rtfRowBordVert,         "trbrdrv",      0 }, | 
|---|
| 2266 |  | 
|---|
| 2267 | { rtfTblAttr,   rtfCellBordBottom,      "clbrdrb",      0 }, | 
|---|
| 2268 | { rtfTblAttr,   rtfCellBordTop,         "clbrdrt",      0 }, | 
|---|
| 2269 | { rtfTblAttr,   rtfCellBordLeft,        "clbrdrl",      0 }, | 
|---|
| 2270 | { rtfTblAttr,   rtfCellBordRight,       "clbrdrr",      0 }, | 
|---|
| 2271 |  | 
|---|
| 2272 | { rtfTblAttr,   rtfCellShading,         "clshdng",      0 }, | 
|---|
| 2273 | { rtfTblAttr,   rtfCellBgPatH,          "clbghoriz",    0 }, | 
|---|
| 2274 | { rtfTblAttr,   rtfCellBgPatV,          "clbgvert",     0 }, | 
|---|
| 2275 | { rtfTblAttr,   rtfCellFwdDiagBgPat,    "clbgfdiag",    0 }, | 
|---|
| 2276 | { rtfTblAttr,   rtfCellBwdDiagBgPat,    "clbgbdiag",    0 }, | 
|---|
| 2277 | { rtfTblAttr,   rtfCellHatchBgPat,      "clbgcross",    0 }, | 
|---|
| 2278 | { rtfTblAttr,   rtfCellDiagHatchBgPat,  "clbgdcross",   0 }, | 
|---|
| 2279 | /* | 
|---|
| 2280 | * The spec lists "clbgdkhor", but the corresponding non-cell | 
|---|
| 2281 | * control is "bgdkhoriz".  At any rate Macintosh Word seems | 
|---|
| 2282 | * to accept both "clbgdkhor" and "clbgdkhoriz". | 
|---|
| 2283 | */ | 
|---|
| 2284 | { rtfTblAttr,   rtfCellDarkBgPatH,      "clbgdkhoriz",  0 }, | 
|---|
| 2285 | { rtfTblAttr,   rtfCellDarkBgPatH,      "clbgdkhor",    0 }, | 
|---|
| 2286 | { rtfTblAttr,   rtfCellDarkBgPatV,      "clbgdkvert",   0 }, | 
|---|
| 2287 | { rtfTblAttr,   rtfCellFwdDarkBgPat,    "clbgdkfdiag",  0 }, | 
|---|
| 2288 | { rtfTblAttr,   rtfCellBwdDarkBgPat,    "clbgdkbdiag",  0 }, | 
|---|
| 2289 | { rtfTblAttr,   rtfCellDarkHatchBgPat,  "clbgdkcross",  0 }, | 
|---|
| 2290 | { rtfTblAttr,   rtfCellDarkDiagHatchBgPat, "clbgdkdcross",      0 }, | 
|---|
| 2291 | { rtfTblAttr,   rtfCellBgPatLineColor, "clcfpat",       0 }, | 
|---|
| 2292 | { rtfTblAttr,   rtfCellBgPatColor,      "clcbpat",      0 }, | 
|---|
| 2293 |  | 
|---|
| 2294 | /* | 
|---|
| 2295 | * Field attributes | 
|---|
| 2296 | */ | 
|---|
| 2297 |  | 
|---|
| 2298 | { rtfFieldAttr, rtfFieldDirty,          "flddirty",     0 }, | 
|---|
| 2299 | { rtfFieldAttr, rtfFieldEdited,         "fldedit",      0 }, | 
|---|
| 2300 | { rtfFieldAttr, rtfFieldLocked,         "fldlock",      0 }, | 
|---|
| 2301 | { rtfFieldAttr, rtfFieldPrivate,        "fldpriv",      0 }, | 
|---|
| 2302 | { rtfFieldAttr, rtfFieldAlt,            "fldalt",       0 }, | 
|---|
| 2303 |  | 
|---|
| 2304 | /* | 
|---|
| 2305 | * Positioning attributes | 
|---|
| 2306 | */ | 
|---|
| 2307 |  | 
|---|
| 2308 | { rtfPosAttr,   rtfAbsWid,              "absw",         0 }, | 
|---|
| 2309 | { rtfPosAttr,   rtfAbsHt,               "absh",         0 }, | 
|---|
| 2310 |  | 
|---|
| 2311 | { rtfPosAttr,   rtfRPosMargH,           "phmrg",        0 }, | 
|---|
| 2312 | { rtfPosAttr,   rtfRPosPageH,           "phpg",         0 }, | 
|---|
| 2313 | { rtfPosAttr,   rtfRPosColH,            "phcol",        0 }, | 
|---|
| 2314 | { rtfPosAttr,   rtfPosX,                "posx",         0 }, | 
|---|
| 2315 | { rtfPosAttr,   rtfPosNegX,             "posnegx",      0 }, | 
|---|
| 2316 | { rtfPosAttr,   rtfPosXCenter,          "posxc",        0 }, | 
|---|
| 2317 | { rtfPosAttr,   rtfPosXInside,          "posxi",        0 }, | 
|---|
| 2318 | { rtfPosAttr,   rtfPosXOutSide,         "posxo",        0 }, | 
|---|
| 2319 | { rtfPosAttr,   rtfPosXRight,           "posxr",        0 }, | 
|---|
| 2320 | { rtfPosAttr,   rtfPosXLeft,            "posxl",        0 }, | 
|---|
| 2321 |  | 
|---|
| 2322 | { rtfPosAttr,   rtfRPosMargV,           "pvmrg",        0 }, | 
|---|
| 2323 | { rtfPosAttr,   rtfRPosPageV,           "pvpg",         0 }, | 
|---|
| 2324 | { rtfPosAttr,   rtfRPosParaV,           "pvpara",       0 }, | 
|---|
| 2325 | { rtfPosAttr,   rtfPosY,                "posy",         0 }, | 
|---|
| 2326 | { rtfPosAttr,   rtfPosNegY,             "posnegy",      0 }, | 
|---|
| 2327 | { rtfPosAttr,   rtfPosYInline,          "posyil",       0 }, | 
|---|
| 2328 | { rtfPosAttr,   rtfPosYTop,             "posyt",        0 }, | 
|---|
| 2329 | { rtfPosAttr,   rtfPosYCenter,          "posyc",        0 }, | 
|---|
| 2330 | { rtfPosAttr,   rtfPosYBottom,          "posyb",        0 }, | 
|---|
| 2331 |  | 
|---|
| 2332 | { rtfPosAttr,   rtfNoWrap,              "nowrap",       0 }, | 
|---|
| 2333 | { rtfPosAttr,   rtfDistFromTextAll,     "dxfrtext",     0 }, | 
|---|
| 2334 | { rtfPosAttr,   rtfDistFromTextX,       "dfrmtxtx",     0 }, | 
|---|
| 2335 | { rtfPosAttr,   rtfDistFromTextY,       "dfrmtxty",     0 }, | 
|---|
| 2336 | /* \dyfrtext no longer exists in spec 1.2, apparently */ | 
|---|
| 2337 | /* replaced by \dfrmtextx and \dfrmtexty. */ | 
|---|
| 2338 | { rtfPosAttr,   rtfTextDistY,           "dyfrtext",     0 }, | 
|---|
| 2339 |  | 
|---|
| 2340 | { rtfPosAttr,   rtfDropCapLines,        "dropcapli",    0 }, | 
|---|
| 2341 | { rtfPosAttr,   rtfDropCapType,         "dropcapt",     0 }, | 
|---|
| 2342 |  | 
|---|
| 2343 | /* | 
|---|
| 2344 | * Object controls | 
|---|
| 2345 | */ | 
|---|
| 2346 |  | 
|---|
| 2347 | { rtfObjAttr,   rtfObjEmb,              "objemb",       0 }, | 
|---|
| 2348 | { rtfObjAttr,   rtfObjLink,             "objlink",      0 }, | 
|---|
| 2349 | { rtfObjAttr,   rtfObjAutoLink,         "objautlink",   0 }, | 
|---|
| 2350 | { rtfObjAttr,   rtfObjSubscriber,       "objsub",       0 }, | 
|---|
| 2351 | { rtfObjAttr,   rtfObjPublisher,        "objpub",       0 }, | 
|---|
| 2352 | { rtfObjAttr,   rtfObjICEmb,            "objicemb",     0 }, | 
|---|
| 2353 |  | 
|---|
| 2354 | { rtfObjAttr,   rtfObjLinkSelf,         "linkself",     0 }, | 
|---|
| 2355 | { rtfObjAttr,   rtfObjLock,             "objupdate",    0 }, | 
|---|
| 2356 | { rtfObjAttr,   rtfObjUpdate,           "objlock",      0 }, | 
|---|
| 2357 |  | 
|---|
| 2358 | { rtfObjAttr,   rtfObjHt,               "objh",         0 }, | 
|---|
| 2359 | { rtfObjAttr,   rtfObjWid,              "objw",         0 }, | 
|---|
| 2360 | { rtfObjAttr,   rtfObjSetSize,          "objsetsize",   0 }, | 
|---|
| 2361 | { rtfObjAttr,   rtfObjAlign,            "objalign",     0 }, | 
|---|
| 2362 | { rtfObjAttr,   rtfObjTransposeY,       "objtransy",    0 }, | 
|---|
| 2363 | { rtfObjAttr,   rtfObjCropTop,          "objcropt",     0 }, | 
|---|
| 2364 | { rtfObjAttr,   rtfObjCropBottom,       "objcropb",     0 }, | 
|---|
| 2365 | { rtfObjAttr,   rtfObjCropLeft,         "objcropl",     0 }, | 
|---|
| 2366 | { rtfObjAttr,   rtfObjCropRight,        "objcropr",     0 }, | 
|---|
| 2367 | { rtfObjAttr,   rtfObjScaleX,           "objscalex",    0 }, | 
|---|
| 2368 | { rtfObjAttr,   rtfObjScaleY,           "objscaley",    0 }, | 
|---|
| 2369 |  | 
|---|
| 2370 | { rtfObjAttr,   rtfObjResRTF,           "rsltrtf",      0 }, | 
|---|
| 2371 | { rtfObjAttr,   rtfObjResPict,          "rsltpict",     0 }, | 
|---|
| 2372 | { rtfObjAttr,   rtfObjResBitmap,        "rsltbmp",      0 }, | 
|---|
| 2373 | { rtfObjAttr,   rtfObjResText,          "rslttxt",      0 }, | 
|---|
| 2374 | { rtfObjAttr,   rtfObjResMerge,         "rsltmerge",    0 }, | 
|---|
| 2375 |  | 
|---|
| 2376 | { rtfObjAttr,   rtfObjBookmarkPubObj,   "bkmkpub",      0 }, | 
|---|
| 2377 | { rtfObjAttr,   rtfObjPubAutoUpdate,    "pubauto",      0 }, | 
|---|
| 2378 |  | 
|---|
| 2379 | /* | 
|---|
| 2380 | * Associated character formatting attributes | 
|---|
| 2381 | */ | 
|---|
| 2382 |  | 
|---|
| 2383 | { rtfACharAttr, rtfACBold,              "ab",           0 }, | 
|---|
| 2384 | { rtfACharAttr, rtfACAllCaps,           "caps",         0 }, | 
|---|
| 2385 | { rtfACharAttr, rtfACForeColor,         "acf",          0 }, | 
|---|
| 2386 | { rtfACharAttr, rtfACSubScript,         "adn",          0 }, | 
|---|
| 2387 | { rtfACharAttr, rtfACExpand,            "aexpnd",       0 }, | 
|---|
| 2388 | { rtfACharAttr, rtfACFontNum,           "af",           0 }, | 
|---|
| 2389 | { rtfACharAttr, rtfACFontSize,          "afs",          0 }, | 
|---|
| 2390 | { rtfACharAttr, rtfACItalic,            "ai",           0 }, | 
|---|
| 2391 | { rtfACharAttr, rtfACLanguage,          "alang",        0 }, | 
|---|
| 2392 | { rtfACharAttr, rtfACOutline,           "aoutl",        0 }, | 
|---|
| 2393 | { rtfACharAttr, rtfACSmallCaps,         "ascaps",       0 }, | 
|---|
| 2394 | { rtfACharAttr, rtfACShadow,            "ashad",        0 }, | 
|---|
| 2395 | { rtfACharAttr, rtfACStrikeThru,        "astrike",      0 }, | 
|---|
| 2396 | { rtfACharAttr, rtfACUnderline,         "aul",          0 }, | 
|---|
| 2397 | { rtfACharAttr, rtfACDotUnderline,      "auld",         0 }, | 
|---|
| 2398 | { rtfACharAttr, rtfACDbUnderline,       "auldb",        0 }, | 
|---|
| 2399 | { rtfACharAttr, rtfACNoUnderline,       "aulnone",      0 }, | 
|---|
| 2400 | { rtfACharAttr, rtfACWordUnderline,     "aulw",         0 }, | 
|---|
| 2401 | { rtfACharAttr, rtfACSuperScript,       "aup",          0 }, | 
|---|
| 2402 |  | 
|---|
| 2403 | /* | 
|---|
| 2404 | * Footnote attributes | 
|---|
| 2405 | */ | 
|---|
| 2406 |  | 
|---|
| 2407 | { rtfFNoteAttr, rtfFNAlt,               "ftnalt",       0 }, | 
|---|
| 2408 |  | 
|---|
| 2409 | /* | 
|---|
| 2410 | * Key code attributes | 
|---|
| 2411 | */ | 
|---|
| 2412 |  | 
|---|
| 2413 | { rtfKeyCodeAttr,       rtfAltKey,              "alt",          0 }, | 
|---|
| 2414 | { rtfKeyCodeAttr,       rtfShiftKey,            "shift",        0 }, | 
|---|
| 2415 | { rtfKeyCodeAttr,       rtfControlKey,          "ctrl",         0 }, | 
|---|
| 2416 | { rtfKeyCodeAttr,       rtfFunctionKey,         "fn",           0 }, | 
|---|
| 2417 |  | 
|---|
| 2418 | /* | 
|---|
| 2419 | * Bookmark attributes | 
|---|
| 2420 | */ | 
|---|
| 2421 |  | 
|---|
| 2422 | { rtfBookmarkAttr, rtfBookmarkFirstCol, "bkmkcolf",     0 }, | 
|---|
| 2423 | { rtfBookmarkAttr, rtfBookmarkLastCol,  "bkmkcoll",     0 }, | 
|---|
| 2424 |  | 
|---|
| 2425 | /* | 
|---|
| 2426 | * Index entry attributes | 
|---|
| 2427 | */ | 
|---|
| 2428 |  | 
|---|
| 2429 | { rtfIndexAttr, rtfIndexNumber,         "xef",          0 }, | 
|---|
| 2430 | { rtfIndexAttr, rtfIndexBold,           "bxe",          0 }, | 
|---|
| 2431 | { rtfIndexAttr, rtfIndexItalic,         "ixe",          0 }, | 
|---|
| 2432 |  | 
|---|
| 2433 | /* | 
|---|
| 2434 | * Table of contents attributes | 
|---|
| 2435 | */ | 
|---|
| 2436 |  | 
|---|
| 2437 | { rtfTOCAttr,   rtfTOCType,             "tcf",          0 }, | 
|---|
| 2438 | { rtfTOCAttr,   rtfTOCLevel,            "tcl",          0 }, | 
|---|
| 2439 |  | 
|---|
| 2440 | /* | 
|---|
| 2441 | * Drawing object attributes | 
|---|
| 2442 | */ | 
|---|
| 2443 |  | 
|---|
| 2444 | { rtfDrawAttr,  rtfDrawLock,            "dolock",       0 }, | 
|---|
| 2445 | { rtfDrawAttr,  rtfDrawPageRelX,        "doxpage",      0 }, | 
|---|
| 2446 | { rtfDrawAttr,  rtfDrawColumnRelX,      "dobxcolumn",   0 }, | 
|---|
| 2447 | { rtfDrawAttr,  rtfDrawMarginRelX,      "dobxmargin",   0 }, | 
|---|
| 2448 | { rtfDrawAttr,  rtfDrawPageRelY,        "dobypage",     0 }, | 
|---|
| 2449 | { rtfDrawAttr,  rtfDrawColumnRelY,      "dobycolumn",   0 }, | 
|---|
| 2450 | { rtfDrawAttr,  rtfDrawMarginRelY,      "dobymargin",   0 }, | 
|---|
| 2451 | { rtfDrawAttr,  rtfDrawHeight,          "dobhgt",       0 }, | 
|---|
| 2452 |  | 
|---|
| 2453 | { rtfDrawAttr,  rtfDrawBeginGroup,      "dpgroup",      0 }, | 
|---|
| 2454 | { rtfDrawAttr,  rtfDrawGroupCount,      "dpcount",      0 }, | 
|---|
| 2455 | { rtfDrawAttr,  rtfDrawEndGroup,        "dpendgroup",   0 }, | 
|---|
| 2456 | { rtfDrawAttr,  rtfDrawArc,             "dparc",        0 }, | 
|---|
| 2457 | { rtfDrawAttr,  rtfDrawCallout,         "dpcallout",    0 }, | 
|---|
| 2458 | { rtfDrawAttr,  rtfDrawEllipse,         "dpellipse",    0 }, | 
|---|
| 2459 | { rtfDrawAttr,  rtfDrawLine,            "dpline",       0 }, | 
|---|
| 2460 | { rtfDrawAttr,  rtfDrawPolygon,         "dppolygon",    0 }, | 
|---|
| 2461 | { rtfDrawAttr,  rtfDrawPolyLine,        "dppolyline",   0 }, | 
|---|
| 2462 | { rtfDrawAttr,  rtfDrawRect,            "dprect",       0 }, | 
|---|
| 2463 | { rtfDrawAttr,  rtfDrawTextBox,         "dptxbx",       0 }, | 
|---|
| 2464 |  | 
|---|
| 2465 | { rtfDrawAttr,  rtfDrawOffsetX,         "dpx",          0 }, | 
|---|
| 2466 | { rtfDrawAttr,  rtfDrawSizeX,           "dpxsize",      0 }, | 
|---|
| 2467 | { rtfDrawAttr,  rtfDrawOffsetY,         "dpy",          0 }, | 
|---|
| 2468 | { rtfDrawAttr,  rtfDrawSizeY,           "dpysize",      0 }, | 
|---|
| 2469 |  | 
|---|
| 2470 | { rtfDrawAttr,  rtfCOAngle,             "dpcoa",        0 }, | 
|---|
| 2471 | { rtfDrawAttr,  rtfCOAccentBar,         "dpcoaccent",   0 }, | 
|---|
| 2472 | { rtfDrawAttr,  rtfCOBestFit,           "dpcobestfit",  0 }, | 
|---|
| 2473 | { rtfDrawAttr,  rtfCOBorder,            "dpcoborder",   0 }, | 
|---|
| 2474 | { rtfDrawAttr,  rtfCOAttachAbsDist,     "dpcodabs",     0 }, | 
|---|
| 2475 | { rtfDrawAttr,  rtfCOAttachBottom,      "dpcodbottom",  0 }, | 
|---|
| 2476 | { rtfDrawAttr,  rtfCOAttachCenter,      "dpcodcenter",  0 }, | 
|---|
| 2477 | { rtfDrawAttr,  rtfCOAttachTop,         "dpcodtop",     0 }, | 
|---|
| 2478 | { rtfDrawAttr,  rtfCOLength,            "dpcolength",   0 }, | 
|---|
| 2479 | { rtfDrawAttr,  rtfCONegXQuadrant,      "dpcominusx",   0 }, | 
|---|
| 2480 | { rtfDrawAttr,  rtfCONegYQuadrant,      "dpcominusy",   0 }, | 
|---|
| 2481 | { rtfDrawAttr,  rtfCOOffset,            "dpcooffset",   0 }, | 
|---|
| 2482 | { rtfDrawAttr,  rtfCOAttachSmart,       "dpcosmarta",   0 }, | 
|---|
| 2483 | { rtfDrawAttr,  rtfCODoubleLine,        "dpcotdouble",  0 }, | 
|---|
| 2484 | { rtfDrawAttr,  rtfCORightAngle,        "dpcotright",   0 }, | 
|---|
| 2485 | { rtfDrawAttr,  rtfCOSingleLine,        "dpcotsingle",  0 }, | 
|---|
| 2486 | { rtfDrawAttr,  rtfCOTripleLine,        "dpcottriple",  0 }, | 
|---|
| 2487 |  | 
|---|
| 2488 | { rtfDrawAttr,  rtfDrawTextBoxMargin,   "dptxbxmar",    0 }, | 
|---|
| 2489 | { rtfDrawAttr,  rtfDrawTextBoxText,     "dptxbxtext",   0 }, | 
|---|
| 2490 | { rtfDrawAttr,  rtfDrawRoundRect,       "dproundr",     0 }, | 
|---|
| 2491 |  | 
|---|
| 2492 | { rtfDrawAttr,  rtfDrawPointX,          "dpptx",        0 }, | 
|---|
| 2493 | { rtfDrawAttr,  rtfDrawPointY,          "dppty",        0 }, | 
|---|
| 2494 | { rtfDrawAttr,  rtfDrawPolyCount,       "dppolycount",  0 }, | 
|---|
| 2495 |  | 
|---|
| 2496 | { rtfDrawAttr,  rtfDrawArcFlipX,        "dparcflipx",   0 }, | 
|---|
| 2497 | { rtfDrawAttr,  rtfDrawArcFlipY,        "dparcflipy",   0 }, | 
|---|
| 2498 |  | 
|---|
| 2499 | { rtfDrawAttr,  rtfDrawLineBlue,        "dplinecob",    0 }, | 
|---|
| 2500 | { rtfDrawAttr,  rtfDrawLineGreen,       "dplinecog",    0 }, | 
|---|
| 2501 | { rtfDrawAttr,  rtfDrawLineRed,         "dplinecor",    0 }, | 
|---|
| 2502 | { rtfDrawAttr,  rtfDrawLinePalette,     "dplinepal",    0 }, | 
|---|
| 2503 | { rtfDrawAttr,  rtfDrawLineDashDot,     "dplinedado",   0 }, | 
|---|
| 2504 | { rtfDrawAttr,  rtfDrawLineDashDotDot,  "dplinedadodo", 0 }, | 
|---|
| 2505 | { rtfDrawAttr,  rtfDrawLineDash,        "dplinedash",   0 }, | 
|---|
| 2506 | { rtfDrawAttr,  rtfDrawLineDot,         "dplinedot",    0 }, | 
|---|
| 2507 | { rtfDrawAttr,  rtfDrawLineGray,        "dplinegray",   0 }, | 
|---|
| 2508 | { rtfDrawAttr,  rtfDrawLineHollow,      "dplinehollow", 0 }, | 
|---|
| 2509 | { rtfDrawAttr,  rtfDrawLineSolid,       "dplinesolid",  0 }, | 
|---|
| 2510 | { rtfDrawAttr,  rtfDrawLineWidth,       "dplinew",      0 }, | 
|---|
| 2511 |  | 
|---|
| 2512 | { rtfDrawAttr,  rtfDrawHollowEndArrow,  "dpaendhol",    0 }, | 
|---|
| 2513 | { rtfDrawAttr,  rtfDrawEndArrowLength,  "dpaendl",      0 }, | 
|---|
| 2514 | { rtfDrawAttr,  rtfDrawSolidEndArrow,   "dpaendsol",    0 }, | 
|---|
| 2515 | { rtfDrawAttr,  rtfDrawEndArrowWidth,   "dpaendw",      0 }, | 
|---|
| 2516 | { rtfDrawAttr,  rtfDrawHollowStartArrow,"dpastarthol",  0 }, | 
|---|
| 2517 | { rtfDrawAttr,  rtfDrawStartArrowLength,"dpastartl",    0 }, | 
|---|
| 2518 | { rtfDrawAttr,  rtfDrawSolidStartArrow, "dpastartsol",  0 }, | 
|---|
| 2519 | { rtfDrawAttr,  rtfDrawStartArrowWidth, "dpastartw",    0 }, | 
|---|
| 2520 |  | 
|---|
| 2521 | { rtfDrawAttr,  rtfDrawBgFillBlue,      "dpfillbgcb",   0 }, | 
|---|
| 2522 | { rtfDrawAttr,  rtfDrawBgFillGreen,     "dpfillbgcg",   0 }, | 
|---|
| 2523 | { rtfDrawAttr,  rtfDrawBgFillRed,       "dpfillbgcr",   0 }, | 
|---|
| 2524 | { rtfDrawAttr,  rtfDrawBgFillPalette,   "dpfillbgpal",  0 }, | 
|---|
| 2525 | { rtfDrawAttr,  rtfDrawBgFillGray,      "dpfillbggray", 0 }, | 
|---|
| 2526 | { rtfDrawAttr,  rtfDrawFgFillBlue,      "dpfillfgcb",   0 }, | 
|---|
| 2527 | { rtfDrawAttr,  rtfDrawFgFillGreen,     "dpfillfgcg",   0 }, | 
|---|
| 2528 | { rtfDrawAttr,  rtfDrawFgFillRed,       "dpfillfgcr",   0 }, | 
|---|
| 2529 | { rtfDrawAttr,  rtfDrawFgFillPalette,   "dpfillfgpal",  0 }, | 
|---|
| 2530 | { rtfDrawAttr,  rtfDrawFgFillGray,      "dpfillfggray", 0 }, | 
|---|
| 2531 | { rtfDrawAttr,  rtfDrawFillPatIndex,    "dpfillpat",    0 }, | 
|---|
| 2532 |  | 
|---|
| 2533 | { rtfDrawAttr,  rtfDrawShadow,          "dpshadow",     0 }, | 
|---|
| 2534 | { rtfDrawAttr,  rtfDrawShadowXOffset,   "dpshadx",      0 }, | 
|---|
| 2535 | { rtfDrawAttr,  rtfDrawShadowYOffset,   "dpshady",      0 }, | 
|---|
| 2536 |  | 
|---|
| 2537 | { rtfVersion,   -1,                     "rtf",          0 }, | 
|---|
| 2538 | { rtfDefFont,   -1,                     "deff",         0 }, | 
|---|
| 2539 |  | 
|---|
| 2540 | { 0,            -1,                     (char *) NULL,  0 } | 
|---|
| 2541 | }; | 
|---|
| 2542 |  | 
|---|
| 2543 |  | 
|---|
| 2544 | /* | 
|---|
| 2545 | * Initialize lookup table hash values.  Only need to do this once. | 
|---|
| 2546 | */ | 
|---|
| 2547 |  | 
|---|
| 2548 | static void LookupInit(void) | 
|---|
| 2549 | { | 
|---|
| 2550 | static int      inited = 0; | 
|---|
| 2551 | RTFKey  *rp; | 
|---|
| 2552 |  | 
|---|
| 2553 | if (inited == 0) | 
|---|
| 2554 | { | 
|---|
| 2555 | for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++) | 
|---|
| 2556 | rp->rtfKHash = Hash (rp->rtfKStr); | 
|---|
| 2557 | ++inited; | 
|---|
| 2558 | } | 
|---|
| 2559 | } | 
|---|
| 2560 |  | 
|---|
| 2561 |  | 
|---|
| 2562 | /* | 
|---|
| 2563 | * Determine major and minor number of control token.  If it's | 
|---|
| 2564 | * not found, the class turns into rtfUnknown. | 
|---|
| 2565 | */ | 
|---|
| 2566 |  | 
|---|
| 2567 | static void Lookup(char *s) | 
|---|
| 2568 | { | 
|---|
| 2569 | RTFKey  *rp; | 
|---|
| 2570 | int     hash; | 
|---|
| 2571 |  | 
|---|
| 2572 | TRACE("\n"); | 
|---|
| 2573 | ++s;                    /* skip over the leading \ character */ | 
|---|
| 2574 | hash = Hash (s); | 
|---|
| 2575 | for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++) | 
|---|
| 2576 | { | 
|---|
| 2577 | if (hash == rp->rtfKHash && strcmp (s, rp->rtfKStr) == 0) | 
|---|
| 2578 | { | 
|---|
| 2579 | rtfClass = rtfControl; | 
|---|
| 2580 | rtfMajor = rp->rtfKMajor; | 
|---|
| 2581 | rtfMinor = rp->rtfKMinor; | 
|---|
| 2582 | return; | 
|---|
| 2583 | } | 
|---|
| 2584 | } | 
|---|
| 2585 | rtfClass = rtfUnknown; | 
|---|
| 2586 | } | 
|---|
| 2587 |  | 
|---|
| 2588 |  | 
|---|
| 2589 | /* | 
|---|
| 2590 | * Compute hash value of symbol | 
|---|
| 2591 | */ | 
|---|
| 2592 |  | 
|---|
| 2593 | static int Hash(char *s) | 
|---|
| 2594 | { | 
|---|
| 2595 | char    c; | 
|---|
| 2596 | int     val = 0; | 
|---|
| 2597 |  | 
|---|
| 2598 | while ((c = *s++) != '\0') | 
|---|
| 2599 | val += (int) c; | 
|---|
| 2600 | return (val); | 
|---|
| 2601 | } | 
|---|
| 2602 |  | 
|---|
| 2603 |  | 
|---|
| 2604 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2605 |  | 
|---|
| 2606 | /* | 
|---|
| 2607 | * Memory allocation routines | 
|---|
| 2608 | */ | 
|---|
| 2609 |  | 
|---|
| 2610 |  | 
|---|
| 2611 | /* | 
|---|
| 2612 | * Return pointer to block of size bytes, or NULL if there's | 
|---|
| 2613 | * not enough memory available. | 
|---|
| 2614 | * | 
|---|
| 2615 | * This is called through RTFAlloc(), a define which coerces the | 
|---|
| 2616 | * argument to int.  This avoids the persistent problem of allocation | 
|---|
| 2617 | * failing under THINK C when a long is passed. | 
|---|
| 2618 | */ | 
|---|
| 2619 |  | 
|---|
| 2620 | char *_RTFAlloc(int size) | 
|---|
| 2621 | { | 
|---|
| 2622 | return HeapAlloc(RICHED32_hHeap, 0, size); | 
|---|
| 2623 | } | 
|---|
| 2624 |  | 
|---|
| 2625 |  | 
|---|
| 2626 | /* | 
|---|
| 2627 | * Saves a string on the heap and returns a pointer to it. | 
|---|
| 2628 | */ | 
|---|
| 2629 |  | 
|---|
| 2630 |  | 
|---|
| 2631 | char *RTFStrSave(char *s) | 
|---|
| 2632 | { | 
|---|
| 2633 | char    *p; | 
|---|
| 2634 |  | 
|---|
| 2635 | if ((p = RTFAlloc ((int) (strlen (s) + 1))) == (char *) NULL) | 
|---|
| 2636 | return ((char *) NULL); | 
|---|
| 2637 | return (strcpy (p, s)); | 
|---|
| 2638 | } | 
|---|
| 2639 |  | 
|---|
| 2640 |  | 
|---|
| 2641 | void RTFFree(char *p) | 
|---|
| 2642 | { | 
|---|
| 2643 | if (p != (char *) NULL) | 
|---|
| 2644 | HeapFree(RICHED32_hHeap, 0, p); | 
|---|
| 2645 | } | 
|---|
| 2646 |  | 
|---|
| 2647 |  | 
|---|
| 2648 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2649 |  | 
|---|
| 2650 |  | 
|---|
| 2651 | /* | 
|---|
| 2652 | * Token comparison routines | 
|---|
| 2653 | */ | 
|---|
| 2654 |  | 
|---|
| 2655 | int RTFCheckCM(int class, int major) | 
|---|
| 2656 | { | 
|---|
| 2657 | return (rtfClass == class && rtfMajor == major); | 
|---|
| 2658 | } | 
|---|
| 2659 |  | 
|---|
| 2660 |  | 
|---|
| 2661 | int RTFCheckCMM(int class, int major, int minor) | 
|---|
| 2662 | { | 
|---|
| 2663 | return (rtfClass == class && rtfMajor == major && rtfMinor == minor); | 
|---|
| 2664 | } | 
|---|
| 2665 |  | 
|---|
| 2666 |  | 
|---|
| 2667 | int RTFCheckMM(int major, int minor) | 
|---|
| 2668 | { | 
|---|
| 2669 | return (rtfMajor == major && rtfMinor == minor); | 
|---|
| 2670 | } | 
|---|
| 2671 |  | 
|---|
| 2672 |  | 
|---|
| 2673 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2674 |  | 
|---|
| 2675 |  | 
|---|
| 2676 | int RTFCharToHex(char c) | 
|---|
| 2677 | { | 
|---|
| 2678 | if (isupper (c)) | 
|---|
| 2679 | c = tolower (c); | 
|---|
| 2680 | if (isdigit (c)) | 
|---|
| 2681 | return (c - '0');       /* '0'..'9' */ | 
|---|
| 2682 | return (c - 'a' + 10);          /* 'a'..'f' */ | 
|---|
| 2683 | } | 
|---|
| 2684 |  | 
|---|
| 2685 |  | 
|---|
| 2686 | int RTFHexToChar(int i) | 
|---|
| 2687 | { | 
|---|
| 2688 | if (i < 10) | 
|---|
| 2689 | return (i + '0'); | 
|---|
| 2690 | return (i - 10 + 'a'); | 
|---|
| 2691 | } | 
|---|
| 2692 |  | 
|---|
| 2693 |  | 
|---|
| 2694 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2695 |  | 
|---|
| 2696 | /* | 
|---|
| 2697 | * RTFReadOutputMap() -- Read output translation map | 
|---|
| 2698 | */ | 
|---|
| 2699 |  | 
|---|
| 2700 | /* | 
|---|
| 2701 | * Read in an array describing the relation between the standard character set | 
|---|
| 2702 | * and an RTF translator's corresponding output sequences.  Each line consists | 
|---|
| 2703 | * of a standard character name and the output sequence for that character. | 
|---|
| 2704 | * | 
|---|
| 2705 | * outMap is an array of strings into which the sequences should be placed. | 
|---|
| 2706 | * It should be declared like this in the calling program: | 
|---|
| 2707 | * | 
|---|
| 2708 | *      char *outMap[rtfSC_MaxChar]; | 
|---|
| 2709 | * | 
|---|
| 2710 | * reinit should be non-zero if outMap should be initialized | 
|---|
| 2711 | * zero otherwise. | 
|---|
| 2712 | * | 
|---|
| 2713 | */ | 
|---|
| 2714 |  | 
|---|
| 2715 | int RTFReadOutputMap(char *outMap[], int reinit) | 
|---|
| 2716 | { | 
|---|
| 2717 | int  i; | 
|---|
| 2718 | int  stdCode; | 
|---|
| 2719 | char *name, *seq; | 
|---|
| 2720 |  | 
|---|
| 2721 | if (reinit) | 
|---|
| 2722 | { | 
|---|
| 2723 | for (i = 0; i < rtfSC_MaxChar; i++) | 
|---|
| 2724 | { | 
|---|
| 2725 | outMap[i] = (char *) NULL; | 
|---|
| 2726 | } | 
|---|
| 2727 | } | 
|---|
| 2728 |  | 
|---|
| 2729 | for (i=0 ;i< sizeof(text_map)/sizeof(char*); i+=2) | 
|---|
| 2730 | { | 
|---|
| 2731 | name = text_map[i]; | 
|---|
| 2732 | seq  = text_map[i+1]; | 
|---|
| 2733 | stdCode = RTFStdCharCode( name ); | 
|---|
| 2734 | outMap[stdCode] = seq; | 
|---|
| 2735 | } | 
|---|
| 2736 |  | 
|---|
| 2737 | return (1); | 
|---|
| 2738 | } | 
|---|
| 2739 |  | 
|---|
| 2740 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2741 |  | 
|---|
| 2742 | /* | 
|---|
| 2743 | * Open a library file. | 
|---|
| 2744 | */ | 
|---|
| 2745 |  | 
|---|
| 2746 |  | 
|---|
| 2747 | static FILE     *(*libFileOpen) () = NULL; | 
|---|
| 2748 |  | 
|---|
| 2749 |  | 
|---|
| 2750 |  | 
|---|
| 2751 | void RTFSetOpenLibFileProc(FILE *(*proc)()) | 
|---|
| 2752 | { | 
|---|
| 2753 | libFileOpen = proc; | 
|---|
| 2754 | } | 
|---|
| 2755 |  | 
|---|
| 2756 |  | 
|---|
| 2757 | FILE *RTFOpenLibFile (char *file, char *mode) | 
|---|
| 2758 | { | 
|---|
| 2759 | if (libFileOpen == NULL) | 
|---|
| 2760 | return ((FILE *) NULL); | 
|---|
| 2761 | return ((*libFileOpen) (file, mode)); | 
|---|
| 2762 | } | 
|---|
| 2763 |  | 
|---|
| 2764 |  | 
|---|
| 2765 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2766 |  | 
|---|
| 2767 | /* | 
|---|
| 2768 | * Print message.  Default is to send message to stderr | 
|---|
| 2769 | * but this may be overridden with RTFSetMsgProc(). | 
|---|
| 2770 | * | 
|---|
| 2771 | * Message should include linefeeds as necessary.  If the default | 
|---|
| 2772 | * function is overridden, the overriding function may want to | 
|---|
| 2773 | * map linefeeds to another line ending character or sequence if | 
|---|
| 2774 | * the host system doesn't use linefeeds. | 
|---|
| 2775 | */ | 
|---|
| 2776 |  | 
|---|
| 2777 |  | 
|---|
| 2778 | static void DefaultMsgProc(char *s) | 
|---|
| 2779 | { | 
|---|
| 2780 | MESSAGE( "%s", s); | 
|---|
| 2781 | } | 
|---|
| 2782 |  | 
|---|
| 2783 |  | 
|---|
| 2784 | static RTFFuncPtr       msgProc = DefaultMsgProc; | 
|---|
| 2785 |  | 
|---|
| 2786 |  | 
|---|
| 2787 | void RTFSetMsgProc(RTFFuncPtr proc) | 
|---|
| 2788 | { | 
|---|
| 2789 | msgProc = proc; | 
|---|
| 2790 | } | 
|---|
| 2791 |  | 
|---|
| 2792 |  | 
|---|
| 2793 | # ifdef STDARG | 
|---|
| 2794 |  | 
|---|
| 2795 | /* | 
|---|
| 2796 | * This version is for systems with stdarg | 
|---|
| 2797 | */ | 
|---|
| 2798 |  | 
|---|
| 2799 | void RTFMsg (char *fmt, ...) | 
|---|
| 2800 | { | 
|---|
| 2801 | char    buf[rtfBufSiz]; | 
|---|
| 2802 |  | 
|---|
| 2803 | va_list args; | 
|---|
| 2804 | va_start (args,fmt); | 
|---|
| 2805 | vsprintf (buf, fmt, args); | 
|---|
| 2806 | va_end (args); | 
|---|
| 2807 | (*msgProc) (buf); | 
|---|
| 2808 | } | 
|---|
| 2809 |  | 
|---|
| 2810 | # else /* !STDARG */ | 
|---|
| 2811 |  | 
|---|
| 2812 | # ifdef VARARGS | 
|---|
| 2813 |  | 
|---|
| 2814 |  | 
|---|
| 2815 | /* | 
|---|
| 2816 | * This version is for systems that have varargs. | 
|---|
| 2817 | */ | 
|---|
| 2818 |  | 
|---|
| 2819 | void RTFMsg (va_dcl va_alist) | 
|---|
| 2820 | { | 
|---|
| 2821 | va_list args; | 
|---|
| 2822 | char    *fmt; | 
|---|
| 2823 | char    buf[rtfBufSiz]; | 
|---|
| 2824 |  | 
|---|
| 2825 | va_start (args); | 
|---|
| 2826 | fmt = va_arg (args, char *); | 
|---|
| 2827 | vsprintf (buf, fmt, args); | 
|---|
| 2828 | va_end (args); | 
|---|
| 2829 | (*msgProc) (buf); | 
|---|
| 2830 | } | 
|---|
| 2831 |  | 
|---|
| 2832 | # else  /* !VARARGS */ | 
|---|
| 2833 |  | 
|---|
| 2834 | /* | 
|---|
| 2835 | * This version is for systems that don't have varargs. | 
|---|
| 2836 | */ | 
|---|
| 2837 |  | 
|---|
| 2838 | void RTFMsg (char *fmt, char *a1, char *a2, char *a3, char *a4, char *a5, char *a6, char *a7, char *a8, char *a9) | 
|---|
| 2839 | { | 
|---|
| 2840 | char    buf[rtfBufSiz]; | 
|---|
| 2841 |  | 
|---|
| 2842 | sprintf (buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); | 
|---|
| 2843 | (*msgProc) (buf); | 
|---|
| 2844 | } | 
|---|
| 2845 |  | 
|---|
| 2846 | # endif /* !VARARGS */ | 
|---|
| 2847 | # endif /* !STDARG */ | 
|---|
| 2848 |  | 
|---|
| 2849 |  | 
|---|
| 2850 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2851 |  | 
|---|
| 2852 |  | 
|---|
| 2853 | /* | 
|---|
| 2854 | * Process termination.  Print error message and exit.  Also prints | 
|---|
| 2855 | * current token, and current input line number and position within | 
|---|
| 2856 | * line if any input has been read from the current file.  (No input | 
|---|
| 2857 | * has been read if prevChar is EOF). | 
|---|
| 2858 | */ | 
|---|
| 2859 |  | 
|---|
| 2860 | static void DefaultPanicProc(char *s) | 
|---|
| 2861 | { | 
|---|
| 2862 | MESSAGE( "%s", s); | 
|---|
| 2863 | /*exit (1);*/ | 
|---|
| 2864 | } | 
|---|
| 2865 |  | 
|---|
| 2866 |  | 
|---|
| 2867 | static RTFFuncPtr       panicProc = DefaultPanicProc; | 
|---|
| 2868 |  | 
|---|
| 2869 |  | 
|---|
| 2870 | void RTFSetPanicProc(RTFFuncPtr proc) | 
|---|
| 2871 | { | 
|---|
| 2872 | panicProc = proc; | 
|---|
| 2873 | } | 
|---|
| 2874 |  | 
|---|
| 2875 |  | 
|---|
| 2876 | # ifdef STDARG | 
|---|
| 2877 |  | 
|---|
| 2878 | /* | 
|---|
| 2879 | * This version is for systems with stdarg | 
|---|
| 2880 | */ | 
|---|
| 2881 |  | 
|---|
| 2882 | void RTFPanic(char *fmt, ...) | 
|---|
| 2883 | { | 
|---|
| 2884 | char    buf[rtfBufSiz]; | 
|---|
| 2885 |  | 
|---|
| 2886 | va_list args; | 
|---|
| 2887 | va_start (args,fmt); | 
|---|
| 2888 | vsprintf (buf, fmt, args); | 
|---|
| 2889 | va_end (args); | 
|---|
| 2890 | (void) strcat (buf, "\n"); | 
|---|
| 2891 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2892 | { | 
|---|
| 2893 | sprintf (buf + strlen (buf), | 
|---|
| 2894 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 2895 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 2896 | } | 
|---|
| 2897 | (*panicProc) (buf); | 
|---|
| 2898 | } | 
|---|
| 2899 |  | 
|---|
| 2900 | # else /* !STDARG */ | 
|---|
| 2901 |  | 
|---|
| 2902 | # ifdef VARARGS | 
|---|
| 2903 |  | 
|---|
| 2904 |  | 
|---|
| 2905 | /* | 
|---|
| 2906 | * This version is for systems that have varargs. | 
|---|
| 2907 | */ | 
|---|
| 2908 |  | 
|---|
| 2909 | void RTFPanic(va_dcl va_alist) | 
|---|
| 2910 | { | 
|---|
| 2911 | va_list args; | 
|---|
| 2912 | char    *fmt; | 
|---|
| 2913 | char    buf[rtfBufSiz]; | 
|---|
| 2914 |  | 
|---|
| 2915 | va_start (args); | 
|---|
| 2916 | fmt = va_arg (args, char *); | 
|---|
| 2917 | vsprintf (buf, fmt, args); | 
|---|
| 2918 | va_end (args); | 
|---|
| 2919 | (void) strcat (buf, "\n"); | 
|---|
| 2920 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2921 | { | 
|---|
| 2922 | sprintf (buf + strlen (buf), | 
|---|
| 2923 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 2924 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 2925 | } | 
|---|
| 2926 | (*panicProc) (buf); | 
|---|
| 2927 | } | 
|---|
| 2928 |  | 
|---|
| 2929 | # else  /* !VARARGS */ | 
|---|
| 2930 |  | 
|---|
| 2931 | /* | 
|---|
| 2932 | * This version is for systems that don't have varargs. | 
|---|
| 2933 | */ | 
|---|
| 2934 |  | 
|---|
| 2935 | void RTFPanic (char *fmt, char *a1, char *a2, char *a3, char *a4, char *a5, char *a6, char *a7, char *a8, char *a9) | 
|---|
| 2936 | { | 
|---|
| 2937 | char    buf[rtfBufSiz]; | 
|---|
| 2938 |  | 
|---|
| 2939 | sprintf (buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); | 
|---|
| 2940 | (void) strcat (buf, "\n"); | 
|---|
| 2941 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2942 | { | 
|---|
| 2943 | sprintf (buf + strlen (buf), | 
|---|
| 2944 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 2945 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 2946 | } | 
|---|
| 2947 | (*panicProc) (buf); | 
|---|
| 2948 | } | 
|---|
| 2949 |  | 
|---|
| 2950 | # endif /* !VARARGS */ | 
|---|
| 2951 | # endif /* !STDARG */ | 
|---|