1 /* wvWare
2  * Copyright (C) Caolan McNamara, Dom Lachowicz, and others
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 
20 #include <string.h>
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28 #include "wv.h"
29 
30 /*
31 void wvToggle(int ret,CHP *in,STSH *stsh,U8 toggle,type)
32 
33 When the parameter of the sprm is set to 0 or 1, then
34 the CHP property is set to the parameter value.
35 
36 */
37 
38 /*
39 When the parameter of the sprm is 128, then the CHP property is set to the
40 value that is stored for the property in the style sheet. CHP When the
41 parameter of the sprm is 129, the CHP property is set to the negation of the
42 value that is stored for the property in the style sheet CHP.
43 sprmCFBold through sprmCFVanish are stored only in grpprls linked to piece table
44 entries.
45 
46 
47 */
48 
49 /*
50 an argument might be made that instead of in being returned or negated that
51 it should be the looked up in the original chp through the istd that should
52 be used, in which case this should be a macro that does the right thing.
53 but im uncertain as to which is the correct one to do, ideas on a postcard
54 to... etc etc
55 
56 This argument which i left as a comment to the original function has been
57 bourne out in practice, so i converted this to a macro and did a lookup
58 on the original unmodified chp in the stylesheet to check against
59 
60 Interestingly enough, even though the spec says that these are only used
61 in piece table grpprls this is untrue, examples/doc-that-needs-utf8.doc
62 has them in the stylesheet definition portion, which is a serious problem
63 as the style that must be checked is not generated before this modifier
64 comes along, a real nuisance.
65 */
66 
67 #define wvTOGGLE(ret,in,stsh,toggle,type) \
68 	{ \
69 	CHP ctemp; \
70 	if ((toggle == 0) || (toggle == 1))  \
71 		ret = toggle; \
72 	else \
73 		{ \
74 		\
75 		wvInitCHPFromIstd(&ctemp,in->istd,stsh); \
76 	\
77 		if (toggle == 128) \
78 			ret = ctemp.type; \
79 		else if (toggle == 129) \
80 			ret = !ctemp.type; \
81 		else \
82 			wvWarning("Strangle sprm toggle value, ignoring\n"); \
83 		} \
84 	}
85 
86 
87 /*
88  spra value operand size
89  0          1 byte (operand affects 1 bit)
90  1          1 byte
91  2          2 bytes
92  3          4 bytes
93  4          2 bytes
94  5          2 bytes
95  6          variable length -- following byte is size of operand
96  7          3 bytes
97 */
98 int
wvSprmLen(int spra)99 wvSprmLen (int spra)
100 {
101     switch (spra)
102       {
103       case 0:
104       case 1:
105 	  return (1);
106       case 2:
107       case 4:
108       case 5:
109 	  return (2);
110       case 7:
111 	  return (3);
112       case 3:
113 	  return (4);
114       case 6:
115 	  return (-1);
116 	  /*variable length -- following byte is size of operand */
117       default:
118 	  wvError (("Incorrect spra value %d\n", spra));
119       }
120     return (-2);
121 }
122 
123 void
wvInitSprm(Sprm * aSprm)124 wvInitSprm (Sprm * aSprm)
125 {
126     aSprm->ispmd = 0;
127     aSprm->fSpec = 0;
128     aSprm->sgc = 0;
129     aSprm->spra = 0;
130 }
131 
132 void
wvGetSprmFromU16(Sprm * aSprm,U16 sprm)133 wvGetSprmFromU16 (Sprm * aSprm, U16 sprm)
134 {
135 #ifdef PURIFY
136     wvInitSprm (aSprm);
137 #endif
138     aSprm->ispmd = sprm & 0x01ff;
139     aSprm->fSpec = (sprm & 0x0200) >> 9;
140     aSprm->sgc = (sprm & 0x1c00) >> 10;
141     aSprm->spra = (sprm & 0xe000) >> 13;
142 }
143 
144 #undef EXAMINE_SPRM
145 U8
wvEatSprm(U16 sprm,U8 * pointer,U16 * pos)146 wvEatSprm (U16 sprm, U8 * pointer, U16 * pos)
147 {
148     int len;
149     Sprm aSprm;
150 #ifdef EXAMINE_SPRM
151 	U8 temp[256];
152 	U16 p;
153 	U8  *pi;
154 	int i;
155 #endif
156     wvTrace (("Eating sprm %x\n", sprm));
157     wvGetSprmFromU16 (&aSprm, sprm);
158     if (sprm == sprmPChgTabs)
159       {
160 	  wvTrace (("sprmPChgTabs\n"));
161 	  len = wvApplysprmPChgTabs (NULL, pointer, pos);
162 	  len++;
163 	  return (len);
164       }
165     else if ((sprm == sprmTDefTable) || (sprm == sprmTDefTable10))
166       {
167 	  wvTrace (("sprmTDefTable\\sprmTDefTable10\n"));
168 	  len = bread_16ubit (pointer, pos);
169 	  len--;
170       }
171 	else
172       {
173 	  len = wvSprmLen (aSprm.spra);
174 #ifdef EXAMINE_SPRM
175 	  i = 0;
176 	  p = *pos;
177 	  pi = pointer;
178 #endif
179 	  wvTrace (("wvSprmLen len is %d\n", len));
180 	  if (len < 0)
181 	    {
182 		len = bread_8ubit (pointer, pos);
183 		/* bread increased pos, but in order to keep len and pos in
184 		   sync later on, we have to decreased it again */
185 		(*pos)--;
186 #ifdef EXAMINE_SPRM
187 		pi++;
188 		while(i < sizeof(temp) && i < len)
189 		{
190 			temp[i] = bread_8ubit(pi, &p);
191 			pi++;
192 			i++;
193 		}
194 #endif
195 		len++;
196 	    }
197 #ifdef EXAMINE_SPRM
198 	  else
199 	  {
200 		while(i < sizeof(temp) && i < len)
201 		{
202 			temp[i] = bread_8ubit(pi, &p);
203 			pi++;
204 			i++;
205 		}
206 	  }
207 #endif
208       }
209     (*pos) += len;
210     return (len);
211 }
212 #undef EXAMINE_SPRM
213 
214 Sprm
wvApplySprmFromBucket(wvVersion ver,U16 sprm,PAP * apap,CHP * achp,SEP * asep,STSH * stsh,U8 * pointer,U16 * pos,wvStream * data)215 wvApplySprmFromBucket (wvVersion ver, U16 sprm, PAP * apap, CHP * achp,
216 		       SEP * asep, STSH * stsh, U8 * pointer, U16 * pos,
217 		       wvStream * data)
218 {
219     BRC10 tempBRC10;
220     U16 temp16;
221     U8 temp8;
222     PAP temppap;
223     CHP tempchp;
224     SEP tempsep;
225     U8 toggle;
226     Sprm RetSprm;
227 
228     /*bullet proofing */
229     if (apap == NULL)
230       {
231 	  wvInitPAP (&temppap);
232 	  apap = &temppap;
233       }
234     if (achp == NULL)
235       {
236 	  wvInitCHP (&tempchp);
237 	  achp = &tempchp;
238       }
239     if (asep == NULL)
240       {
241 #ifdef PURIFY
242 	  wvInitSEP (&tempsep);
243 #endif
244 	  asep = &tempsep;
245       }
246 #ifdef SPRMTEST
247     wvError (("sprm is %x\n", sprm));
248 #endif
249 
250     switch (sprm)
251       {
252 	  /*Beginning of PAP */
253       case sprmPIstd:
254 	  apap->istd = bread_16ubit (pointer, pos);
255 	  break;
256       case sprmPIstdPermute:
257 	  wvApplysprmPIstdPermute (apap, pointer, pos);
258 	  break;
259       case sprmPIncLvl:
260 	  wvApplysprmPIncLvl (apap, pointer, pos);
261 	  break;
262       case sprmPJc:
263 	  apap->jc = bread_8ubit (pointer, pos);
264 	  wvTrace (("jc is now %d\n", apap->jc));
265 	  break;
266       case sprmPFSideBySide:
267 	  apap->fSideBySide = bread_8ubit (pointer, pos);
268 	  break;
269       case sprmPFKeep:
270 	  apap->fKeep = bread_8ubit (pointer, pos);
271 	  break;
272       case sprmPFKeepFollow:
273 	  apap->fKeepFollow = bread_8ubit (pointer, pos);
274 	  break;
275       case sprmPFPageBreakBefore:
276 	  apap->fPageBreakBefore = bread_8ubit (pointer, pos);
277 	  break;
278       case sprmPBrcl:
279 	  apap->brcl = bread_8ubit (pointer, pos);
280 	  break;
281       case sprmPBrcp:
282 	  apap->brcp = bread_8ubit (pointer, pos);
283 	  break;
284       case sprmPIlvl:
285 	  apap->ilvl = bread_8ubit (pointer, pos);
286 	  break;
287       case sprmPIlfo:
288 	  apap->ilfo = (S16) bread_16ubit (pointer, pos);
289 	  wvTrace (("ilfo is %d\n", apap->ilfo));
290 	  break;
291       case sprmPFNoLineNumb:
292 	  apap->fNoLnn = bread_8ubit (pointer, pos);
293 	  break;
294       case sprmPChgTabsPapx:
295 	  wvApplysprmPChgTabsPapx (apap, pointer, pos);
296 	  break;
297       case sprmPDxaRight:
298 	  apap->dxaRight = (S16) bread_16ubit (pointer, pos);
299 	  break;
300       case sprmPDxaLeft:
301 	  apap->dxaLeft = (S16) bread_16ubit (pointer, pos);
302 	  break;
303       case sprmPNest:
304 	  /*
305 	     sprmPNest (opcode 0x4610) causes its operand, a two-byte dxa value to be
306 	     added to pap.dxaLeft. If the result of the addition is less than 0, 0 is
307 	     stored into pap.dxaLeft.
308 	   */
309 	  temp16 = (S16) bread_16ubit (pointer, pos);
310 	  apap->dxaLeft += temp16;
311 	  if (apap->dxaLeft < 0)
312 	      apap->dxaLeft = 0;
313 	  break;
314       case sprmPDxaLeft1:
315 	  apap->dxaLeft1 = (S16) bread_16ubit (pointer, pos);
316 	  break;
317       case sprmPDyaLine:
318 	  wvGetLSPDFromBucket (&apap->lspd, pointer);
319 	  (*pos) += 4;
320 	  break;
321       case sprmPDyaBefore:
322 	  apap->dyaBefore = bread_16ubit (pointer, pos);
323 	  break;
324       case sprmPDyaAfter:
325 	  apap->dyaAfter = bread_16ubit (pointer, pos);
326 	  break;
327       case sprmPChgTabs:
328 	  wvApplysprmPChgTabs (apap, pointer, pos);
329 	  break;
330       case sprmPFInTable:
331 	  apap->fInTable = bread_8ubit (pointer, pos);
332 	  break;
333       case sprmPFTtp:
334 	  apap->fTtp = bread_8ubit (pointer, pos);
335 	  break;
336       case sprmPDxaAbs:
337 	  apap->dxaAbs = (S16) bread_16ubit (pointer, pos);
338 	  break;
339       case sprmPDyaAbs:
340 	  apap->dyaAbs = (S16) bread_16ubit (pointer, pos);
341 	  break;
342       case sprmPDxaWidth:
343 	  apap->dxaWidth = (S16) bread_16ubit (pointer, pos);
344 	  break;
345       case sprmPPc:
346 	  wvApplysprmPPc (apap, pointer, pos);
347 	  break;
348       case sprmPBrcTop10:
349 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
350 	  (*pos) += 2;
351 	  wvConvertBRC10ToBRC (&apap->brcTop, &tempBRC10);
352 	  break;
353       case sprmPBrcLeft10:
354 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
355 	  (*pos) += 2;
356 	  wvConvertBRC10ToBRC (&apap->brcLeft, &tempBRC10);
357 	  break;
358       case sprmPBrcBottom10:
359 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
360 	  (*pos) += 2;
361 	  wvConvertBRC10ToBRC (&apap->brcBottom, &tempBRC10);
362 	  break;
363       case sprmPBrcRight10:
364 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
365 	  (*pos) += 2;
366 	  wvConvertBRC10ToBRC (&apap->brcRight, &tempBRC10);
367 	  break;
368       case sprmPBrcBetween10:
369 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
370 	  (*pos) += 2;
371 	  wvConvertBRC10ToBRC (&apap->brcBetween, &tempBRC10);
372 	  break;
373       case sprmPBrcBar10:
374 	  wvGetBRC10FromBucket (&tempBRC10, pointer);
375 	  (*pos) += 2;
376 	  wvConvertBRC10ToBRC (&apap->brcBar, &tempBRC10);
377 	  break;
378       case sprmPDxaFromText10:
379 	  apap->dxaFromText = (S16) bread_16ubit (pointer, pos);
380 	  break;
381       case sprmPWr:
382 	  apap->wr = bread_8ubit (pointer, pos);
383 	  break;
384       case sprmPBrcTop:
385 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcTop, pointer);
386 	  break;
387       case sprmPBrcLeft:
388 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcLeft, pointer);
389 	  break;
390       case sprmPBrcBottom:
391 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcBottom, pointer);
392 	  break;
393       case sprmPBrcRight:
394 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcRight, pointer);
395 	  break;
396       case sprmPBrcBetween:
397 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcBetween, pointer);
398 	  break;
399       case sprmPBrcBar:
400 	  (*pos) += wvGetBRCFromBucket (ver, &apap->brcBar, pointer);
401 	  break;
402       case sprmPFNoAutoHyph:
403 	  apap->fNoAutoHyph = bread_8ubit (pointer, pos);
404 	  break;
405       case sprmPWHeightAbs:
406 	  /* ???? apap->wHeightAbs */
407 	  (*pos) += 2;
408 	  break;
409       case sprmPDcs:
410 	  wvGetDCSFromBucket (&apap->dcs, pointer);
411 	  (*pos) += 2;
412 	  break;
413       case sprmPShd:
414 	  wvGetSHDFromBucket (&apap->shd, pointer);
415 	  (*pos) += 2;
416 	  break;
417       case sprmPDyaFromText:
418 	  apap->dyaFromText = (S16) bread_16ubit (pointer, pos);
419 	  break;
420       case sprmPDxaFromText:
421 	  apap->dxaFromText = (S16) bread_16ubit (pointer, pos);
422 	  break;
423       case sprmPFLocked:
424 	  apap->fLocked = bread_8ubit (pointer, pos);
425 	  break;
426       case sprmPFWidowControl:
427 	  apap->fWidowControl = bread_8ubit (pointer, pos);
428 	  break;
429       case sprmPFKinsoku:
430 	  apap->fKinsoku = bread_8ubit (pointer, pos);
431 	  break;
432       case sprmPFWordWrap:
433 	  apap->fWordWrap = bread_8ubit (pointer, pos);
434 	  break;
435       case sprmPFOverflowPunct:
436 	  apap->fOverflowPunct = bread_8ubit (pointer, pos);
437 	  break;
438       case sprmPFTopLinePunct:
439 	  apap->fTopLinePunct = bread_8ubit (pointer, pos);
440 	  break;
441       case sprmPFAutoSpaceDE:
442 	  apap->fAutoSpaceDE = bread_8ubit (pointer, pos);
443 	  break;
444       case sprmPFAutoSpaceDN:
445 	  /* ???? apap->fAutoSpaceDN */
446 	  (*pos)++;
447 	  break;
448       case sprmPWAlignFont:
449 	  apap->wAlignFont = (S16) bread_16ubit (pointer, pos);
450 	  break;
451       case sprmPFrameTextFlow:
452 	  wvApplysprmPFrameTextFlow (apap, pointer, pos);
453 	  break;
454       case sprmPISnapBaseLine:
455 	  /*obsolete: not applicable in Word97 and later versions */
456 	  (*pos)++;
457 	  break;
458       case sprmPNLvlAnm:
459 	  /*obsolete: not applicable in Word97 and later version */
460 	  apap->nLvlAnm = bread_8ubit (pointer, pos);
461 	  wvTrace (("%d\n", apap->nLvlAnm));
462 	  break;
463       case sprmPAnld:
464 	  wvApplysprmPAnld (ver, apap, pointer, pos);
465 	  break;
466       case sprmPPropRMark:
467 	  wvApplysprmPPropRMark (apap, pointer, pos);
468 	  break;
469       case sprmPOutLvl:
470 	  /*has no effect if pap.istd is < 1 or is > 9 */
471 	  temp8 = bread_8ubit (pointer, pos);
472 	  if ((apap->istd >= 1) && (apap->istd <= 9))
473 	      apap->lvl = temp8;
474 	  break;
475       case sprmPFBiDi:
476 	apap->fBidi = bread_8ubit (pointer, pos);
477 	break;
478       case sprmPFNumRMIns:
479 	  apap->fNumRMIns = bread_8ubit (pointer, pos);
480 	  break;
481       case sprmPCrLf:
482 	  /* ???? */
483 	  (*pos)++;
484 	  break;
485       case sprmPNumRM:
486 	  wvApplysprmPNumRM (apap, pointer, pos);
487 	  break;
488       case sprmPHugePapx2:
489       case sprmPHugePapx:
490 	  wvApplysprmPHugePapx (apap, pointer, pos, data, stsh);
491 	  break;
492       case sprmPFUsePgsuSettings:
493 	  apap->fUsePgsuSettings = bread_8ubit (pointer, pos);
494 	  break;
495       case sprmPFAdjustRight:
496 	  apap->fAdjustRight = bread_8ubit (pointer, pos);
497 	  break;
498       case sprmPRsid:
499 	  /*  apap->rsid = */ bread_32ubit (pointer, pos);
500 	  break;
501       case sprmPItap:
502 		 apap->fInTable =bread_32ubit (pointer, pos); /*  Need to introduce apap->fInTableW97? */
503 		/* apap->fTtp++;   this line fixed bug #11433 but caused #12476 */
504 	  break;
505 	  /*End of PAP */
506 
507 
508 	  /*Begin of CHP */
509       case sprmCFRMarkDel:
510 	  achp->fRMarkDel = bread_8ubit (pointer, pos);
511 	  break;
512       case sprmCFRMark:
513 	  achp->fRMark = bread_8ubit (pointer, pos);
514 	  break;
515       case sprmCFFldVanish:
516 	  achp->fFldVanish = bread_8ubit (pointer, pos);
517 	  break;
518       case sprmCPicLocation:
519 	  if (ver != WORD8)
520 	    {
521 		wvTrace (("byte is %x\n", bread_8ubit (pointer, pos)));
522 		pointer++;
523 	    }
524 	  /*
525 	     This sprm moves the 4-byte operand of the sprm into the
526 	     chp.fcPic field. It simultaneously sets chp.fSpec to 1.
527 	   */
528 	  achp->fcPic_fcObj_lTagObj = bread_32ubit (pointer, pos);
529 	  wvTrace (("Len is %x\n", achp->fcPic_fcObj_lTagObj));
530 	  achp->fSpec = 1;
531 	  break;
532       case sprmCIbstRMark:
533 	  achp->ibstRMark = (S16) bread_16ubit (pointer, pos);
534 	  break;
535       case sprmCDttmRMark:
536 	  wvGetDTTMFromBucket (&achp->dttmRMark, pointer);
537 	  (*pos) += 4;
538 	  break;
539       case sprmCFData:
540 	  achp->fData = bread_8ubit (pointer, pos);
541 	  break;
542       case sprmCIdslRMark:
543 	  achp->idslRMReason = (S16) bread_16ubit (pointer, pos);
544 	  break;
545       case sprmCChs:
546 	  wvApplysprmCChs (achp, pointer, pos);
547 	  break;
548       case sprmCSymbol:
549 	  wvApplysprmCSymbol (ver, achp, pointer, pos);
550 	  break;
551       case sprmCFOle2:
552 	  achp->fOle2 = bread_8ubit (pointer, pos);
553 	  break;
554       case sprmCHighlight:
555 	  /* ico (fHighlight is set to 1 iff ico is not 0) */
556 	  achp->icoHighlight = bread_8ubit (pointer, pos);
557 	  if (achp->icoHighlight)
558 	      achp->fHighlight = 1;	/*? */
559 
560 	  /*another possibility is... */
561 	  /* if (achp->ico) achp->fHighlight = 1; */
562 	  /*
563 	     or is it something else, who knows the entire documentation on
564 	     the topic consist of the if and only if (iff) line, or maybe
565 	     iff is a type for if, who knows eh ?
566 	   */
567 	  break;
568       case sprmCObjLocation:
569 	  achp->fcPic_fcObj_lTagObj = (S32) bread_32ubit (pointer, pos);
570 	  break;
571       case sprmCIstd:
572 	  achp->istd = bread_16ubit (pointer, pos);
573 	  break;
574       case sprmCIstdPermute:
575 	  wvApplysprmCIstdPermute (achp, pointer, pos);	/*unfinished */
576 	  break;
577       case sprmCDefault:
578 	  wvApplysprmCDefault (achp, pointer, pos);
579 	  break;
580       case sprmCPlain:
581 	  wvApplysprmCPlain (achp, stsh);
582 	  break;
583       case sprmCFBold:
584 	  toggle = bread_8ubit (pointer, pos);
585 	  wvTrace (("toggle here is %d, istd is %d\n", toggle, achp->istd));
586 	  wvTOGGLE (achp->fBold, achp, stsh, toggle, fBold) break;
587       case sprmCFItalic:
588 	  toggle = bread_8ubit (pointer, pos);
589 	  wvTrace (("Italic is %d, sprm val is %d\n", achp->fItalic, toggle));
590 	  wvTOGGLE (achp->fItalic, achp, stsh, toggle, fItalic)
591 	      wvTrace (("Italic is now %d\n", achp->fItalic));
592 	  break;
593       case sprmCFStrike:
594 	  toggle = bread_8ubit (pointer, pos);
595 	  wvTOGGLE (achp->fStrike, achp, stsh, toggle, fStrike) break;
596       case sprmCFOutline:
597 	  toggle = bread_8ubit (pointer, pos);
598 	  wvTOGGLE (achp->fOutline, achp, stsh, toggle, fOutline) break;
599       case sprmCFShadow:
600 	  toggle = bread_8ubit (pointer, pos);
601 	  wvTOGGLE (achp->fShadow, achp, stsh, toggle, fShadow) break;
602       case sprmCFSmallCaps:
603 	  toggle = bread_8ubit (pointer, pos);
604 	  wvTOGGLE (achp->fSmallCaps, achp, stsh, toggle, fSmallCaps) break;
605       case sprmCFCaps:
606 	  toggle = bread_8ubit (pointer, pos);
607 	  wvTOGGLE (achp->fCaps, achp, stsh, toggle, fCaps) break;
608       case sprmCFVanish:
609 	  wvTrace (("vanish modified\n"));
610 	  toggle = bread_8ubit (pointer, pos);
611 	  wvTOGGLE (achp->fVanish, achp, stsh, toggle, fVanish) break;
612       case sprmCFtcDefault:
613 	  toggle = bread_8ubit (pointer, pos);
614 	  wvTOGGLE (achp->fBold, achp, stsh, toggle, fBold) break;
615       case sprmCKul:
616 	  achp->kul = bread_8ubit (pointer, pos);
617 	  break;
618       case sprmCSizePos:
619 	  wvApplysprmCSizePos (achp, pointer, pos);
620 	  break;
621       case sprmCDxaSpace:
622 	  achp->dxaSpace = (S16) bread_16ubit (pointer, pos);
623 	  break;
624       case sprmCIco:
625 	  achp->ico = bread_8ubit (pointer, pos);
626 	  break;
627       case sprmCHps:
628 	  /*incorrect marked as being a byte in docs ? */
629 	  achp->hps = bread_16ubit (pointer, pos);
630 	  break;
631       case sprmCHpsInc:
632 	  wvApplysprmCHpsInc (achp, pointer, pos);
633 	  break;
634       case sprmCHpsPos:
635 	  /*incorrect marked as being a byte in docs ? */
636 	  achp->hpsPos = bread_16ubit (pointer, pos);
637 	  break;
638       case sprmCHpsPosAdj:
639 	  wvApplysprmCHpsPosAdj (achp, pointer, pos);
640 	  break;
641       case sprmCMajority:
642 	  wvApplysprmCMajority (achp, stsh, pointer, pos);
643 	  break;
644       case sprmCIss:
645 	  achp->iss = bread_8ubit (pointer, pos);
646 	  break;
647       case sprmCHpsNew50:
648 	  bread_8ubit (pointer, pos);
649 	  achp->hps = bread_16ubit (pointer, pos);
650 	  break;
651       case sprmCHpsInc1:
652 	  wvApplysprmCHpsInc1 (achp, pointer, pos);
653 	  break;
654       case sprmCHpsKern:
655 	  /*the spec would you have you believe that this is a U8 */
656 	  achp->hpsKern = bread_16ubit (pointer, pos);
657 	  break;
658       case sprmCMajority50:
659 	  wvApplysprmCMajority50 (achp, stsh, pointer, pos);
660 	  break;
661       case sprmCHpsMul:
662 	  /*percentage to grow hps ?? */
663 	  achp->hps = achp->hps * bread_16ubit (pointer, pos) / 100;
664 	  break;
665       case sprmCYsri:
666 	  /* ???? achp->ysri */
667 	  bread_8ubit (pointer, pos);
668 	  break;
669       case sprmCRgFtc0:
670 	  achp->ftcAscii = bread_16ubit (pointer, pos);
671 	  break;
672       case sprmCRgFtc1:
673 	  achp->ftcFE = bread_16ubit (pointer, pos);
674 	  break;
675       case sprmCRgFtc2:
676 	  achp->ftcOther = bread_16ubit (pointer, pos);
677 	  break;
678       case sprmCFDStrike:
679 	  achp->fDStrike = bread_8ubit (pointer, pos);
680 	  break;
681       case sprmCFImprint:
682 	  achp->fImprint = bread_8ubit (pointer, pos);
683 	  break;
684       case sprmCFSpec:
685 	  achp->fSpec = bread_8ubit (pointer, pos);
686 	  break;
687       case sprmCFObj:
688 	  achp->fObj = bread_8ubit (pointer, pos);
689 	  break;
690       case sprmCPropRMark:
691 	  wvApplysprmCPropRMark (achp, pointer, pos);
692 	  break;
693       case sprmCFEmboss:
694 	  achp->fEmboss = bread_8ubit (pointer, pos);
695 	  break;
696       case sprmCSfxText:
697 	  achp->sfxtText = bread_8ubit (pointer, pos);
698 	  break;
699       case sprmCDispFldRMark:
700 	  wvApplysprmCDispFldRMark (achp, pointer, pos);
701 	  break;
702       case sprmCIbstRMarkDel:
703 	  achp->ibstRMarkDel = (S16) bread_16ubit (pointer, pos);
704 	  break;
705       case sprmCDttmRMarkDel:
706 	  wvGetDTTMFromBucket (&achp->dttmRMarkDel, pointer);
707 	  (*pos) += 4;
708 	  break;
709       case sprmCBrc:
710 	  (*pos) += wvGetBRCFromBucket (ver, &achp->brc, pointer);
711 	  break;
712       case sprmCShd:
713 	  wvGetSHDFromBucket (&achp->shd, pointer);
714 	  (*pos) += 2;
715       case sprmCIdslRMarkDel:
716 	  /* achp->idslRMReasonDel ???? */
717 	  (S16) bread_16ubit (pointer, pos);
718 	  break;
719       case sprmCFUsePgsuSettings:
720 	  achp->fUsePgsuSettings = bread_8ubit (pointer, pos);
721 	  break;
722       case sprmCRgLid0:
723 	  achp->lidDefault = bread_16ubit (pointer, pos);
724 	  break;
725       case sprmCRgLid1:
726 	  achp->lidFE = bread_16ubit (pointer, pos);
727 	  break;
728       case sprmCIdctHint:
729 	  achp->idctHint = bread_8ubit (pointer, pos);
730 	  break;
731       case sprmCFFtcAsciSymb:	/* not fully mentioned in spec */
732 	  achp->fFtcAsciSym = bread_8ubit (pointer, pos);
733 	  break;
734       case sprmCCpg:		/* not fully mentioned in spec */
735 	  achp->cpg = bread_16ubit (pointer, pos);
736 	  break;
737       case sprmCLid:		/*
738 				   only used internally, never stored ( word 97 )
739 				   but exists in earlier versions so...
740 				 */
741 	  achp->lid = bread_16ubit (pointer, pos);
742 	  achp->lidDefault = achp->lid;
743 	  achp->lidFE = achp->lid;
744 	  wvTrace (("lid is %x\n", achp->lidDefault));
745 	  break;
746       case sprmCRsidText:
747 		 bread_32ubit (pointer, pos);
748 	  break;
749 
750 	  /* BiDi */
751 
752       case sprmCFBiDi:		/* is this run BiDi */
753 	  achp->fBidi = bread_8ubit (pointer, pos);
754 	  break;
755 
756       case sprmCFDiacColor: /* ???? */
757 	bread_16ubit (pointer, pos);
758 	break;
759 
760       case sprmCFBoldBi:
761 	achp->fBoldBidi = bread_8ubit (pointer, pos);
762 	break;
763 
764       case sprmCFItalicBi:
765 	achp->fItalicBidi = bread_8ubit (pointer, pos);
766 	break;
767 
768       case sprmCFtcBi:
769 	achp->ftcBidi = bread_16ubit (pointer, pos);
770 	break;
771 
772       case sprmCLidBi:
773 	achp->lidBidi = bread_16ubit (pointer, pos);
774 	break;
775 
776       case sprmCIcoBi:
777 	achp->icoBidi = bread_8ubit (pointer, pos);
778 	break;
779 
780       case sprmCHpsBi:
781 	achp->hpsBidi = bread_16ubit (pointer, pos);
782 	break;
783 	  /* End of CHP */
784 
785 
786 	  /* Begin of SEP */
787       case sprmScnsPgn:
788 	  asep->cnsPgn = bread_8ubit (pointer, pos);
789 	  break;
790       case sprmSiHeadingPgn:
791 	  asep->iHeadingPgn = bread_8ubit (pointer, pos);
792 	  break;
793       case sprmSOlstAnm:
794 	  wvApplysprmSOlstAnm (ver, asep, pointer, pos);
795 	  break;
796       case sprmSDxaColWidth:
797       case sprmSDxaColSpacing:
798 	  /* well then no one has docs for these two , they're 3 long
799 	     but affects (i guess by name) a 89 long array so who
800 	     knows
801 	   */
802 	  bread_8ubit (pointer, pos);
803 	  bread_8ubit (pointer, pos);
804 	  bread_8ubit (pointer, pos);
805 	  break;
806       case sprmSFEvenlySpaced:
807 	  asep->fEvenlySpaced = bread_8ubit (pointer, pos);
808 	  break;
809       case sprmSFProtected:
810 	  asep->fUnlocked = bread_8ubit (pointer, pos);
811 	  break;
812       case sprmSDmBinFirst:
813 	  asep->dmBinFirst = bread_16ubit (pointer, pos);
814 	  break;
815       case sprmSDmBinOther:
816 	  asep->dmBinFirst = bread_16ubit (pointer, pos);
817 	  break;
818       case sprmSBkc:
819 	  asep->bkc = bread_8ubit (pointer, pos);
820 	  break;
821       case sprmSFTitlePage:
822 	  asep->fTitlePage = bread_8ubit (pointer, pos);
823 	  break;
824       case sprmSCcolumns:
825 	  asep->ccolM1 = bread_16ubit (pointer, pos);
826 	  break;
827       case sprmSDxaColumns:
828 	  asep->dxaColumns = (S16) bread_16ubit (pointer, pos);
829 	  break;
830       case sprmSFAutoPgn:
831 	  asep->fAutoPgn = bread_8ubit (pointer, pos);
832 	  break;
833       case sprmSNfcPgn:
834 	  asep->nfcPgn = bread_8ubit (pointer, pos);
835 	  break;
836       case sprmSDyaPgn:
837 	  asep->dyaPgn = (S16) bread_16ubit (pointer, pos);
838 	  break;
839       case sprmSDxaPgn:
840 	  asep->dxaPgn = (S16) bread_16ubit (pointer, pos);
841 	  break;
842       case sprmSFPgnRestart:
843 	  asep->fPgnRestart = bread_8ubit (pointer, pos);
844 	  break;
845       case sprmSFEndnote:
846 	  asep->fEndNote = bread_8ubit (pointer, pos);
847 	  break;
848       case sprmSLnc:
849 	  asep->lnc = bread_8ubit (pointer, pos);
850 	  break;
851       case sprmSGprfIhdt:
852 	  asep->grpfIhdt = bread_8ubit (pointer, pos);
853 	  break;
854       case sprmSNLnnMod:
855 	  asep->nLnnMod = bread_16ubit (pointer, pos);
856 	  break;
857       case sprmSDxaLnn:
858 	  asep->dxaLnn = (S16) bread_16ubit (pointer, pos);
859 	  break;
860       case sprmSDyaHdrTop:
861 	  asep->dyaHdrTop = bread_16ubit (pointer, pos);
862 	  break;
863       case sprmSDyaHdrBottom:
864 	  asep->dyaHdrBottom = bread_16ubit (pointer, pos);
865 	  break;
866       case sprmSLBetween:
867 	  asep->fLBetween = bread_8ubit (pointer, pos);
868 	  break;
869       case sprmSVjc:
870 	  asep->fLBetween = bread_8ubit (pointer, pos);
871 	  break;
872       case sprmSLnnMin:
873 	  asep->lnnMin = (S16) bread_16ubit (pointer, pos);
874 	  break;
875       case sprmSPgnStart:
876 	  asep->pgnStart = bread_16ubit (pointer, pos);
877 	  break;
878       case sprmSBOrientation:
879 	  asep->dmOrientPage = bread_8ubit (pointer, pos);
880 	  break;
881       case sprmSBCustomize:
882 	  /*noone knows what this is */
883 	  bread_8ubit (pointer, pos);
884 	  break;
885       case sprmSXaPage:
886 	  asep->xaPage = bread_16ubit (pointer, pos);
887 	  break;
888       case sprmSYaPage:
889 	  asep->yaPage = bread_16ubit (pointer, pos);
890 	  break;
891       case sprmSDxaLeft:
892 	  asep->dxaLeft = bread_16ubit (pointer, pos);
893 	  break;
894       case sprmSDxaRight:
895 	  asep->dxaRight = bread_16ubit (pointer, pos);
896 	  break;
897       case sprmSDyaTop:
898 	  asep->dyaTop = (S16) bread_16ubit (pointer, pos);
899 	  break;
900       case sprmSDyaBottom:
901 	  asep->dyaBottom = (S16) bread_16ubit (pointer, pos);
902 	  break;
903       case sprmSDzaGutter:
904 	  asep->dzaGutter = bread_16ubit (pointer, pos);
905 	  break;
906       case sprmSDmPaperReq:
907 	  asep->dmPaperReq = bread_16ubit (pointer, pos);
908 	  break;
909       case sprmSPropRMark:
910 	  wvApplysprmSPropRMark (asep, pointer, pos);
911 	  break;
912       case sprmSFBiDi:
913 	  asep->fBidi = bread_8ubit (pointer, pos);
914 	  break;
915       case sprmSFFacingCol: /* ?????? , what the hell are these two */
916       case sprmSFRTLGutter:
917 	  bread_8ubit (pointer, pos);
918 	  break;
919       case sprmSBrcTop:
920 	  (*pos) += wvGetBRCFromBucket (ver, &asep->brcTop, pointer);
921 	  break;
922       case sprmSBrcLeft:
923 	  (*pos) += wvGetBRCFromBucket (ver, &asep->brcLeft, pointer);
924 	  break;
925       case sprmSBrcBottom:
926 	  (*pos) += wvGetBRCFromBucket (ver, &asep->brcBottom, pointer);
927 	  break;
928       case sprmSBrcRight:
929 	  (*pos) += wvGetBRCFromBucket (ver, &asep->brcRight, pointer);
930 	  break;
931       case sprmSPgbProp:
932 	  asep->pgbProp = (S16) bread_16ubit (pointer, pos);
933 	  break;
934       case sprmSDxtCharSpace:
935 	  asep->dxtCharSpace = (S32) bread_32ubit (pointer, pos);
936 	  break;
937       case sprmSDyaLinePitch:
938 	  /* incorrectly documented; is only word size */
939 	  asep->dyaLinePitch = (S32) bread_16ubit (pointer, pos);
940 	  break;
941       case sprmSClm:
942 	  /* who knows */
943 	  bread_16ubit (pointer, pos);
944 	  break;
945       case sprmSTextFlow:
946 	  asep->wTextFlow = (S16) bread_16ubit (pointer, pos);
947 	  break;
948 	  /* End of SEP */
949 
950 	  /* Begin of TAP */
951       case sprmTJc:
952 	  apap->ptap.jc = (S16) bread_16ubit (pointer, pos);
953 	  break;
954       case sprmTFCantSplit:
955 	  apap->ptap.fCantSplit = bread_8ubit (pointer, pos);
956 	  break;
957       case sprmTTableHeader:
958 	  apap->ptap.fTableHeader = bread_8ubit (pointer, pos);
959 	  break;
960       case sprmTDyaRowHeight:	/* check len */
961 	  asep->dyaLinePitch = (S16) bread_16ubit (pointer, pos);
962 	  break;
963       case sprmTDiagLine:	/* ????? */
964 	  wvError (("huh, show me this document\n"));
965 	  break;
966       case sprmTHTMLProps:	/* ???? */
967 	  apap->ptap.lwHTMLProps = (S32) bread_32ubit (pointer, pos);
968 	  break;
969       case sprmTDxaLeft:
970 	  wvApplysprmTDxaLeft (&apap->ptap, pointer, pos);
971 	  break;
972       case sprmTDxaGapHalf:
973 	  wvApplysprmTDxaGapHalf (&apap->ptap, pointer, pos);
974 	  break;
975       case sprmTTableBorders:
976 	  wvApplysprmTTableBorders (ver, &apap->ptap, pointer, pos);
977 	  break;
978       case sprmTDefTable10:
979 	  wvApplysprmTDefTable10 (&apap->ptap, pointer, pos);
980 	  break;
981       case sprmTDefTable:
982 	  wvApplysprmTDefTable (&apap->ptap, pointer, pos);
983 	  break;
984       case sprmTDefTableShd:
985 	  /*
986 	     wvApplysprmTDefTableShd follows the written spec, but
987 	     it isnt't working out for me, maybe its my own fault,
988 	     anyhow Im trying wv2 out temporarily
989 	   */
990 	  wv2ApplysprmTDefTableShd (&apap->ptap, pointer, pos);
991 	  /*
992 	     wvApplysprmTDefTableShd(&apap->ptap,pointer,pos);
993 	   */
994 	  break;
995       case sprmTTlp:
996 	  wvGetTLPFromBucket (&(apap->ptap.tlp), pointer);
997 	  (*pos) += cbTLP;
998 	  break;
999       case sprmTSetBrc:
1000 	  wvApplysprmTSetBrc (ver, &apap->ptap, pointer, pos);
1001 	  break;
1002       case sprmTInsert:
1003 	  wvApplysprmTInsert (&apap->ptap, pointer, pos);
1004 	  break;
1005       case sprmTDelete:
1006 	  wvApplysprmTDelete (&apap->ptap, pointer, pos);
1007 	  break;
1008       case sprmTDxaCol:
1009 	  wvApplysprmTDxaCol (&apap->ptap, pointer, pos);
1010 	  break;
1011       case sprmTMerge:
1012 	  wvApplysprmTMerge (&apap->ptap, pointer, pos);
1013 	  break;
1014       case sprmTSplit:
1015 	  wvApplysprmTSplit (&apap->ptap, pointer, pos);
1016 	  break;
1017       case sprmTSetBrc10:
1018 	  wvApplysprmTSetBrc10 (&apap->ptap, pointer, pos);
1019 	  break;
1020       case sprmTSetShd:
1021 	  wvApplysprmTSetShd (&apap->ptap, pointer, pos);
1022 	  break;
1023       case sprmTSetShdOdd:
1024 	  wvApplysprmTSetShdOdd (&apap->ptap, pointer, pos);
1025 	  break;
1026       case sprmTTextFlow:
1027 	  wvError (("huh, show me this document\n"));
1028 	  wvApplysprmTTextFlow (&apap->ptap, pointer, pos);
1029 	  break;
1030       case sprmTVertMerge:
1031 	  wvApplysprmTVertMerge (&apap->ptap, pointer, pos);
1032 	  break;
1033       case sprmTFBiDi:		/* ????? */
1034 	  bread_16ubit (pointer, pos);
1035 	  break;
1036       case sprmTUNKNOWN1:
1037 	  /* read wv.h and word 6 sprm 204
1038 	     further down in this file to understand this
1039 	   */
1040 	  bread_8ubit (pointer, pos);
1041 	  bread_16ubit (pointer, pos);
1042 	  break;
1043       case sprmTVertAlign:
1044 	  wvApplysprmTVertAlign (&apap->ptap, pointer, pos);
1045 	  break;
1046 
1047 	  /* end of TAP */
1048 
1049 	  /*
1050 	     case sprmPicBrcl
1051 	   */
1052 
1053       case sprmPRuler:		/* ???? */
1054       case sprmCIdCharType:	/* obsolete */
1055       case sprmCKcd:		/* ???? */
1056       case sprmCCharScale:	/* ???? */
1057       case sprmNoop:		/* no operand */
1058 	  break;
1059       default:
1060 	wvTrace(("unknown sprm: %d\n", sprm));
1061 	  wvEatSprm (sprm, pointer, pos);
1062 	  break;
1063       }
1064 
1065     wvGetSprmFromU16 (&RetSprm, sprm);
1066     return (RetSprm);
1067 }
1068 
1069 void
wvApplysprmPIstdPermute(PAP * apap,U8 * pointer,U16 * pos)1070 wvApplysprmPIstdPermute (PAP * apap, U8 * pointer, U16 * pos)
1071 {
1072     U8 cch;
1073     U8 fLongg;
1074     U8 fSpare;
1075     U16 istdFirst;
1076     U16 istdLast;
1077     U16 *rgistd;
1078     U16 i;
1079 
1080     cch = dread_8ubit (NULL, &pointer);
1081     (*pos)++;
1082     fLongg = dread_8ubit (NULL, &pointer);
1083     (*pos)++;
1084     fSpare = dread_8ubit (NULL, &pointer);
1085     (*pos)++;
1086     istdFirst = dread_16ubit (NULL, &pointer);
1087     (*pos) += 2;
1088     istdLast = dread_16ubit (NULL, &pointer);
1089     (*pos) += 2;
1090 
1091     if ( cch > 6)
1092       {
1093 	  rgistd = (U16 *) wvMalloc (sizeof (U16) * ((cch - 6) / 2));
1094 	  if (rgistd == NULL)
1095 	    {
1096 		wvError (
1097 			 ("Could not allocate %d\n",
1098 			  sizeof (U16) * ((cch - 6) / 2)));
1099 		return;
1100 	    }
1101 	  for (i = 0; i < (cch - 6) / 2; i++)
1102 	    {
1103 		rgistd[i] = dread_16ubit (NULL, &pointer);
1104 		(*pos) += 2;
1105 	    }
1106       }
1107     else
1108       return;
1109 
1110     /*
1111        First check if pap.istd is greater than the istdFirst recorded in the sprm
1112        and less than or equal to the istdLast recorded in the sprm If not, the sprm
1113        has no effect. If it is, pap.istd is set to rgistd[pap.istd - istdFirst]
1114      */
1115 
1116     if ((apap->istd > istdFirst) && (apap->istd <= istdLast))
1117       {
1118 	  wvTrace (("%d %d %d\n", apap->istd, istdFirst, istdLast));
1119 	  apap->istd = rgistd[apap->istd - istdFirst];
1120       }
1121     wvFree (rgistd);
1122 }
1123 
1124 void
wvApplysprmPIncLvl(PAP * apap,U8 * pointer,U16 * pos)1125 wvApplysprmPIncLvl (PAP * apap, U8 * pointer, U16 * pos)
1126 {
1127     U8 temp8;
1128     S8 tempS8;
1129     temp8 = bread_8ubit (pointer, pos);
1130     /*
1131        If pap.stc is < 1 or > 9, sprmPIncLvl has no effect. Otherwise, if the value
1132        stored in the byte has its highest order bit off, the value is a positive
1133        difference which should be added to pap.istd and pap.lvl and then pap.stc
1134        should be set to min(pap.istd, 9). If the byte value has its highest order
1135        bit on, the value is a negative difference which should be sign extended to
1136        a word and then subtracted from pap.istd and pap.lvl. Then pap.stc should be
1137        set to max(1, pap.istd).
1138 
1139        Now... hang on a sec coz
1140 
1141        Note that the storage and behavior of styles has changed radically since
1142        Word 2 for Windows, beginning with nFib 63. Some of the differences are:
1143        <chomp>
1144        * The style code is called an istd, rather than an stc.
1145 
1146        So, for the purposes of this filter, we ignore the stc component of the
1147        instructions
1148 
1149      */
1150 
1151     if ((apap->istd < 1) || (apap->istd > 9))
1152 	return;
1153 
1154     if ((temp8 & 0x80) >> 7 == 0)
1155       {
1156 	  apap->istd += temp8;
1157 	  apap->lvl += temp8;
1158 	  /*
1159 	     apap->stc = min(apap->istd, 9);
1160 	   */
1161       }
1162     else
1163       {
1164 	  tempS8 = (S8) temp8;
1165 	  apap->istd += tempS8;
1166 	  apap->lvl += tempS8;
1167 	  /*
1168 	     apap->stc = max(1, apap->istd);
1169 	   */
1170       }
1171 }
1172 
1173 void
wvApplysprmPChgTabsPapx(PAP * apap,U8 * pointer,U16 * pos)1174 wvApplysprmPChgTabsPapx (PAP * apap, U8 * pointer, U16 * pos)
1175 {
1176     S16 temp_rgdxaTab[itbdMax];
1177     TBD temp_rgtbd[itbdMax];
1178     int i, j, k = 0, oldpos;
1179     U8 cch, itbdDelMax;
1180     S16 *rgdxaDel;
1181     U8 itbdAddMax;
1182     S16 *rgdxaAdd;
1183     int add = 0;
1184     TBD *rgtbdAdd;
1185 
1186     oldpos = *pos;
1187     cch = dread_8ubit (NULL, &pointer);
1188     (*pos)++;
1189     itbdDelMax = dread_8ubit (NULL, &pointer);
1190     (*pos)++;
1191     if (itbdDelMax != 0)
1192       {
1193 	  rgdxaDel = (S16 *) wvMalloc (sizeof (U16) * itbdDelMax);
1194 	  for (i = 0; i < itbdDelMax; i++)
1195 	    {
1196 		rgdxaDel[i] = (S16) dread_16ubit (NULL, &pointer);
1197 		(*pos) += 2;
1198 	    }
1199       }
1200     else
1201 	rgdxaDel = NULL;
1202     itbdAddMax = dread_8ubit (NULL, &pointer);
1203     wvTrace (("itbdAddMax is %d\n", itbdAddMax));
1204     (*pos)++;
1205     if (itbdAddMax != 0)
1206       {
1207 	  rgdxaAdd = (S16 *) wvMalloc (sizeof (U16) * itbdAddMax);
1208 	  for (i = 0; i < itbdAddMax; i++)
1209 	    {
1210 		rgdxaAdd[i] = (S16) dread_16ubit (NULL, &pointer);
1211 		wvTrace (("stops are %d\n", rgdxaAdd[i]));
1212 		(*pos) += 2;
1213 	    }
1214 	  rgtbdAdd = (TBD *) wvMalloc (itbdAddMax * sizeof (TBD));
1215 	  for (i = 0; i < itbdAddMax; i++)
1216 	    {
1217 		wvGetTBDFromBucket (&rgtbdAdd[i], pointer);
1218 		(*pos)++;
1219 	    }
1220       }
1221     else
1222       {
1223 	  rgdxaAdd = NULL;
1224 	  rgtbdAdd = NULL;
1225       }
1226 
1227 #ifdef DEBUG
1228     if (*pos - oldpos != cch + 1)
1229 	wvTrace (("Offset Problem in wvApplysprmPChgTabsPapx\n"));
1230 #endif
1231 
1232     /*
1233        When sprmPChgTabsPapx is interpreted, the rgdxaDel of the sprm is applied
1234        first to the pap that is being transformed. This is done by deleting from
1235        the pap the rgdxaTab entry and rgtbd entry of any tab whose rgdxaTab value
1236        is equal to one of the rgdxaDel values in the sprm. It is guaranteed that
1237        the entries in pap.rgdxaTab and the sprm's rgdxaDel and rgdxaAdd are
1238        recorded in ascending dxa order.
1239 
1240        Then the rgdxaAdd and rgtbdAdd entries are merged into the pap's rgdxaTab
1241        and rgtbd arrays so that the resulting pap rgdxaTab is sorted in ascending
1242        order with no duplicates.
1243      */
1244     for (j = 0; j < apap->itbdMac && k < itbdMax; j++)
1245       {
1246 	  add = 1;
1247 	  for (i = 0; i < itbdDelMax; i++)
1248 	    {
1249 		if (rgdxaDel[i] == apap->rgdxaTab[j])
1250 		  {
1251 		      add = 0;
1252 		      break;
1253 		  }
1254 	    }
1255 	  if (add)
1256 	    {
1257 		temp_rgdxaTab[k] = apap->rgdxaTab[j];
1258 		wvCopyTBD (&temp_rgtbd[k++], &apap->rgtbd[j]);
1259 	    }
1260       }
1261     /*temp_rgdxaTab now contains all the tab stops to be retained after the delete */
1262     apap->itbdMac = k;
1263     k = 0;
1264     j = 0;
1265     i = 0;
1266     while ((j < apap->itbdMac) || (i < itbdAddMax))
1267       {
1268 #if 0
1269 	  wvTrace (("i %d j apap->itbdMac %d %d\n", i, j, apap->itbdMac));
1270 	  wvTrace (("temp_rgdxaTab[j] %d\n", temp_rgdxaTab[j]));
1271 	  wvTrace (("rgdxaAdd[i] %d\n", rgdxaAdd[i]));
1272 #endif
1273 	  if ((j < apap->itbdMac)
1274 	      && (i >= itbdAddMax || temp_rgdxaTab[j] < rgdxaAdd[i]))
1275 	    {
1276 		/* if we have one from the retained group that should be added */
1277 		apap->rgdxaTab[k] = temp_rgdxaTab[j];
1278 		wvCopyTBD (&apap->rgtbd[k++], &temp_rgtbd[j++]);
1279 	    }
1280 	  else if ((j < apap->itbdMac) && (temp_rgdxaTab[j] == rgdxaAdd[i]))
1281 	    {
1282 		/* if we have one from the retained group that should be added
1283 		   which is the same as one from the new group */
1284 		apap->rgdxaTab[k] = rgdxaAdd[i];
1285 		wvCopyTBD (&apap->rgtbd[k++], &rgtbdAdd[i++]);
1286 		j++;
1287 	    }
1288 	  else			/*if (i < itbdAddMax) */
1289 	    {
1290 		/* if we have one from the new group to be added */
1291 		apap->rgdxaTab[k] = rgdxaAdd[i];
1292 		wvCopyTBD (&apap->rgtbd[k++], &rgtbdAdd[i++]);
1293 	    }
1294       }
1295     wvTrace (("k is %d\n", k));
1296 
1297     apap->itbdMac = k;
1298 
1299     for (i = 0; i < apap->itbdMac; i++)
1300       {
1301 	  wvTrace (
1302 		   ("tab %d rgdxa %d %x\n", i, apap->rgdxaTab[i],
1303 		    apap->rgdxaTab[i]));
1304       }
1305 
1306     wvFree (rgtbdAdd);
1307     wvFree (rgdxaAdd);
1308     wvFree (rgdxaDel);
1309 }
1310 
1311 int
wvApplysprmPChgTabs(PAP * apap,U8 * pointer,U16 * pos)1312 wvApplysprmPChgTabs (PAP * apap, U8 * pointer, U16 * pos)
1313 {
1314     S16 temp_rgdxaTab[itbdMax];
1315     TBD temp_rgtbd[itbdMax];
1316     U8 cch;
1317     U8 itbdDelMax;
1318     S16 *rgdxaDel;
1319     S16 *rgdxaClose;
1320     U8 itbdAddMax;
1321     S16 *rgdxaAdd;
1322     TBD *rgtbdAdd;
1323     int add = 0;
1324     U8 i, j, k = 0;
1325 
1326     wvTrace (("entering wvApplysprmPChgTabs\n"));
1327     /*
1328        itbdDelMax and itbdAddMax are defined to be equal to 50. This means that the
1329        largest possible instance of sprmPChgTabs is 354. When the length of the
1330        sprm is greater than or equal to 255, the cch field will be set equal to
1331        255. When cch == 255, the actual length of the sprm can be calculated as
1332        follows: length = 2 + itbdDelMax * 4 + itbdAddMax * 3.
1333      */
1334 
1335     cch = dread_8ubit (NULL, &pointer);
1336     wvTrace (("cch is %d\n", cch));
1337     (*pos)++;
1338     itbdDelMax = dread_8ubit (NULL, &pointer);
1339     (*pos)++;
1340 
1341     wvTrace (("itbdDelMax is %d\n", itbdDelMax));
1342     if (itbdDelMax != 0)
1343       {
1344 	  rgdxaDel = (S16 *) wvMalloc (sizeof (S16) * itbdDelMax);
1345 	  rgdxaClose = (S16 *) wvMalloc (sizeof (S16) * itbdDelMax);
1346 	  for (i = 0; i < itbdDelMax; i++)
1347 	    {
1348 		rgdxaDel[i] = (S16) dread_16ubit (NULL, &pointer);
1349 		(*pos) += 2;
1350 	    }
1351 	  for (i = 0; i < itbdDelMax; i++)
1352 	    {
1353 		rgdxaClose[i] = dread_16ubit (NULL, &pointer);
1354 		(*pos) += 2;
1355 	    }
1356       }
1357     else
1358       {
1359 	  rgdxaDel = NULL;
1360 	  rgdxaClose = NULL;
1361       }
1362     itbdAddMax = dread_8ubit (NULL, &pointer);
1363     wvTrace (("itbdAddMax is %d\n", itbdAddMax));
1364     (*pos)++;
1365     if (itbdAddMax != 0)
1366       {
1367 	  rgdxaAdd = (S16 *) wvMalloc (sizeof (S16) * itbdAddMax);
1368 	  rgtbdAdd = (TBD *) wvMalloc (itbdAddMax * sizeof (TBD));
1369 	  for (i = 0; i < itbdAddMax; i++)
1370 	    {
1371 		rgdxaAdd[i] = (S16) dread_16ubit (NULL, &pointer);
1372 		wvTrace (("rgdxaAdd %d is %x\n", i, rgdxaAdd[i]));
1373 		(*pos) += 2;
1374 	    }
1375 	  for (i = 0; i < itbdAddMax; i++)
1376 	    {
1377 		wvGetTBDFromBucket (&rgtbdAdd[i], pointer);
1378 		(*pos)++;
1379 	    }
1380       }
1381     else
1382       {
1383 	  rgdxaAdd = NULL;
1384 	  rgtbdAdd = NULL;
1385       }
1386 
1387     if (cch == 225)
1388 	cch = 2 + itbdDelMax * 4 + itbdAddMax * 3;
1389 
1390     /*
1391        When sprmPChgTabs is interpreted, the rgdxaDel of the sprm is applied first
1392        to the pap that is being transformed. This is done by deleting from the pap
1393        the rgdxaTab entry and rgtbd entry of any tab whose rgdxaTab value is within
1394        the interval [rgdxaDel[i] - rgdxaClose[i], rgdxaDel[i] + rgdxaClose[i]] It
1395        is guaranteed that the entries in pap.rgdxaTab and the sprm's rgdxaDel and
1396        rgdxaAdd are recorded in ascending dxa order.
1397 
1398        Then the rgdxaAdd and rgtbdAdd entries are merged into the pap's rgdxaTab
1399        and rgtbd arrays so that the resulting pap rgdxaTab is sorted in ascending
1400        order with no duplicates.
1401      */
1402     if (apap == NULL)
1403       {
1404 	  wvFree (rgdxaDel);
1405 	  wvFree (rgtbdAdd);
1406 	  wvFree (rgdxaAdd);
1407 	  wvFree (rgdxaClose);
1408 	  return (cch);
1409       }
1410 
1411     wvTrace (("here %d\n", apap->itbdMac));
1412     for (j = 0; j < apap->itbdMac && k < itbdMax; j++)
1413       {
1414 	  add = 1;
1415 	  for (i = 0; i < itbdDelMax; i++)
1416 	    {
1417 		wvTrace (
1418 			 ("examing %x against %x\n", apap->rgdxaTab[j],
1419 			  rgdxaDel[i]));
1420 		if ((apap->rgdxaTab[j] >= rgdxaDel[i] - rgdxaClose[i])
1421 		    && (apap->rgdxaTab[j] <= rgdxaDel[i] + rgdxaClose[i]))
1422 		  {
1423 		      wvTrace (("deleting\n"));
1424 		      add = 0;
1425 		      break;
1426 		  }
1427 	    }
1428 	  if (add)
1429 	    {
1430 		temp_rgdxaTab[k] = apap->rgdxaTab[j];
1431 		wvCopyTBD (&temp_rgtbd[k++], &apap->rgtbd[j]);
1432 	    }
1433       }
1434     apap->itbdMac = k;
1435     wvTrace (("here %d\n", apap->itbdMac));
1436 
1437     k = 0;
1438     j = 0;
1439     i = 0;
1440     while ((j < apap->itbdMac) || (i < itbdAddMax))
1441       {
1442 	  if ((j < apap->itbdMac)
1443 	      && (i >= itbdAddMax || temp_rgdxaTab[j] < rgdxaAdd[i]))
1444 	    {
1445 		wvTrace (("adding from nondeleted tab stops\n"));
1446 		apap->rgdxaTab[k] = temp_rgdxaTab[j];
1447 		wvCopyTBD (&apap->rgtbd[k++], &temp_rgtbd[j++]);
1448 	    }
1449 	  else if ((j < apap->itbdMac) && (temp_rgdxaTab[j] == rgdxaAdd[i]))
1450 	    {
1451 		wvTrace (("adding from new tab stops\n"));
1452 		apap->rgdxaTab[k] = rgdxaAdd[i];
1453 		wvCopyTBD (&apap->rgtbd[k++], &rgtbdAdd[i++]);
1454 		j++;
1455 	    }
1456 	  else			/*if (i < itbdAddMax) */
1457 	    {
1458 		wvTrace (("adding from new tab stops\n"));
1459 		apap->rgdxaTab[k] = rgdxaAdd[i];
1460 		wvCopyTBD (&apap->rgtbd[k++], &rgtbdAdd[i++]);
1461 	    }
1462       }
1463 
1464     apap->itbdMac = k;
1465     wvTrace (("here %d\n", apap->itbdMac));
1466 
1467     for (i = 0; i < apap->itbdMac; i++)
1468       {
1469 	  wvTrace (
1470 		   ("tab %d rgdxa %d %x\n", i, apap->rgdxaTab[i],
1471 		    apap->rgdxaTab[i]));
1472       }
1473 
1474     wvFree (rgdxaDel);
1475     wvFree (rgtbdAdd);
1476     wvFree (rgdxaAdd);
1477     wvFree (rgdxaClose);
1478     wvTrace (("Exiting Successfully\n"));
1479 
1480     return (cch);
1481 }
1482 
1483 void
wvApplysprmPPc(PAP * apap,U8 * pointer,U16 * pos)1484 wvApplysprmPPc (PAP * apap, U8 * pointer, U16 * pos)
1485 {
1486     U8 temp8;
1487     struct _temp {
1488 	U32 reserved:4;
1489 	U32 pcVert:2;
1490 	U32 pcHorz:2;
1491     } temp;
1492 
1493 
1494     temp8 = bread_8ubit (pointer, pos);
1495 #ifdef PURIFY
1496     temp.pcVert = 0;
1497     temp.pcHorz = 0;
1498 #endif
1499     temp.pcVert = (temp8 & 0x0C) >> 4;
1500     temp.pcHorz = (temp8 & 0x03) >> 6;
1501 
1502     /*
1503        sprmPPc is interpreted by moving pcVert to pap.pcVert if pcVert != 3 and by
1504        moving pcHorz to pap.pcHorz if pcHorz != 3.
1505      */
1506 
1507     if (temp.pcVert != 3)
1508 	apap->pcVert = temp.pcVert;
1509     if (temp.pcHorz != 3)
1510 	apap->pcHorz = temp.pcHorz;
1511 }
1512 
1513 void
wvApplysprmPFrameTextFlow(PAP * apap,U8 * pointer,U16 * pos)1514 wvApplysprmPFrameTextFlow (PAP * apap, U8 * pointer, U16 * pos)
1515 {
1516     U16 temp16 = bread_16ubit (pointer, pos);
1517 
1518     apap->fVertical = temp16 & 0x0001;
1519     apap->fBackward = (temp16 & 0x0002) >> 1;
1520     apap->fRotateFont = (temp16 & 0x0004) >> 2;
1521 }
1522 
1523 void
wvApplysprmPAnld(wvVersion ver,PAP * apap,U8 * pointer,U16 * pos)1524 wvApplysprmPAnld (wvVersion ver, PAP * apap, U8 * pointer, U16 * pos)
1525 {
1526     dread_8ubit (NULL, &pointer);
1527     (*pos)++;
1528     wvGetANLD_FromBucket (ver, &apap->anld, pointer);
1529     if (ver == WORD8)
1530 	(*pos) += cbANLD;
1531     else
1532 	(*pos) += cb6ANLD;
1533 }
1534 
1535 void
wvApplysprmPPropRMark(PAP * apap,U8 * pointer,U16 * pos)1536 wvApplysprmPPropRMark (PAP * apap, U8 * pointer, U16 * pos)
1537 {
1538     dread_8ubit (NULL, &pointer);
1539     /*
1540        sprmPPropRMark is interpreted by moving the first parameter
1541        byte to pap.fPropRMark, the next two bytes to pap.ibstPropRMark, and the
1542        remaining four bytes to pap.dttmPropRMark.
1543      */
1544     apap->fPropRMark = dread_8ubit (NULL, &pointer);
1545     (*pos)++;
1546     apap->ibstPropRMark = dread_16ubit (NULL, &pointer);
1547     (*pos) += 2;
1548     wvGetDTTMFromBucket (&apap->dttmPropRMark, pointer);
1549     (*pos) += 4;
1550 }
1551 
1552 void
wvApplysprmPNumRM(PAP * apap,U8 * pointer,U16 * pos)1553 wvApplysprmPNumRM (PAP * apap, U8 * pointer, U16 * pos)
1554 {
1555     dread_8ubit (NULL, &pointer);
1556     (*pos)++;
1557     wvGetNUMRMFromBucket (&apap->numrm, pointer);
1558     (*pos) += cbNUMRM;
1559 }
1560 
1561 void
wvApplysprmPHugePapx(PAP * apap,U8 * pointer,U16 * pos,wvStream * data,STSH * stsh)1562 wvApplysprmPHugePapx (PAP * apap, U8 * pointer, U16 * pos, wvStream * data,
1563 		      STSH * stsh)
1564 {
1565     U32 offset;
1566     U16 len, i, sprm;
1567     U8 *grpprl, *pointer2;
1568     /*
1569        sprmPHugePapx is stored in PAPX FKPs in place of the grpprl of a PAPX which
1570        would otherwise be too big to fit in an FKP (as of this writing, 488 bytes
1571        is the size of the largest PAPX which can fit in an FKP). The parameter fc
1572        gives the location of the grpprl in the data stream. The first word at that
1573        fc counts the number of bytes in the grpprl (not including the byte count
1574        itself). A sprmPHugePapx should therefore only be found in a PAPX FKP and
1575        should be the only sprm in that PAPX's grpprl.
1576      */
1577     offset = dread_32ubit (NULL, &pointer);
1578     (*pos) += 4;
1579     wvTrace (("Offset is %x in data stream\n", offset));
1580     if (!(data))
1581       {
1582 	  wvError (("No data stream!!\n"));
1583 	  return;
1584       }
1585     if (0 > wvStream_goto (data, offset))
1586       {
1587 	  wvError (("Couldn't seek data stream!!\n"));
1588 	  apap->fTtp++;
1589 	  return;
1590       }
1591     len = read_16ubit (data);
1592     if (!len)
1593       {
1594 	  wvWarning ("sprmPHugePapx len is 0, seems unlikely\n");
1595 	  return;
1596       }
1597 
1598     grpprl = (U8 *) wvMalloc (len);
1599 
1600     for (i = 0; i < len; i++)
1601 	grpprl[i] = read_8ubit (data);
1602 
1603     i = 0;
1604     while (i < len - 2)
1605       {
1606 	  sprm = bread_16ubit (grpprl + i, &i);
1607 #ifdef SPRMTEST
1608 	  wvError (("sprm is %x\n", sprm));
1609 #endif
1610 	  pointer2 = grpprl + i;
1611 	  if (i < len)
1612 	      wvApplySprmFromBucket (WORD8, sprm, apap, NULL, NULL, stsh,
1613 				     pointer2, &i, data);
1614       }
1615     wvFree (grpprl);
1616 }
1617 
1618 void
wvApplysprmCChs(CHP * achp,U8 * pointer,U16 * pos)1619 wvApplysprmCChs (CHP * achp, U8 * pointer, U16 * pos)
1620 {
1621     /*
1622        When this sprm is interpreted, the first byte of the operand is moved to
1623        chp.fChsDiff and the remaining word is moved to chp.chse.
1624      */
1625     achp->fChsDiff = dread_8ubit (NULL, &pointer);
1626     (*pos)++;
1627     /*achp->chse ???? */
1628     /* the doc says to set this, but it doesnt exist anywhere else in the docs */
1629     dread_16ubit (NULL, &pointer);
1630     (*pos) += 2;
1631 }
1632 
1633 void
wvApplysprmCSymbol(wvVersion ver,CHP * achp,U8 * pointer,U16 * pos)1634 wvApplysprmCSymbol (wvVersion ver, CHP * achp, U8 * pointer, U16 * pos)
1635 {
1636     if (ver == WORD8)
1637       {
1638 	  /*
1639 	     Word 8
1640 	     This sprm's operand is 4 bytes. The first 2 hold the font code; the last 2
1641 	     hold a character specifier. When this sprm is interpreted, the font code is
1642 	     moved to chp.ftcSym and the character specifier is moved to chp.xchSym and
1643 	     chp.fSpec is set to 1.
1644 	   */
1645 	  achp->ftcSym = dread_16ubit (NULL, &pointer);
1646 	  (*pos) += 2;
1647 	  achp->xchSym = dread_16ubit (NULL, &pointer);
1648 	  (*pos) += 2;
1649 	  wvTrace (("%d %d\n", achp->ftcSym, achp->xchSym));
1650       }
1651     else
1652       {
1653 	  /*
1654 	     Word 6 and 7
1655 	     The length byte recorded at offset 1 in this
1656 	     sprm will always be 3. When this sprm is interpreted the two byte
1657 	     font code recorded at offset 2 is moved to chp.ftcSym, the single
1658 	     byte character specifier recorded at offset 4 is moved to chp.chSym
1659 	     and chp.fSpec is set to 1.
1660 	   */
1661 	  dread_8ubit (NULL, &pointer);
1662 	  (*pos)++;
1663 	  achp->ftcSym = dread_16ubit (NULL, &pointer);
1664 	  (*pos) += 2;
1665 	  achp->xchSym = dread_8ubit (NULL, &pointer);
1666 	  achp->xchSym += 61440;	/* promote this char into a unicode char to
1667 					   be consistent with what word 8 does */
1668 	  (*pos)++;
1669       }
1670     achp->fSpec = 1;
1671 }
1672 
1673 void
wvApplysprmCIstdPermute(CHP * achp,U8 * pointer,U16 * pos)1674 wvApplysprmCIstdPermute (CHP * achp, U8 * pointer, U16 * pos)
1675 {
1676     U8 cch;
1677     U8 fLongg;
1678     U8 fSpare;
1679     U16 istdFirst;
1680     U16 istdLast;
1681     U16 *rgistd;
1682     U16 i;
1683 
1684     cch = dread_8ubit (NULL, &pointer);
1685     (*pos)++;
1686     fLongg = dread_8ubit (NULL, &pointer);
1687     (*pos)++;
1688     fSpare = dread_8ubit (NULL, &pointer);
1689     (*pos)++;
1690     istdFirst = dread_16ubit (NULL, &pointer);
1691     (*pos) += 2;
1692     istdLast = dread_16ubit (NULL, &pointer);
1693     (*pos) += 2;
1694 
1695     if (cch > 6)
1696       {
1697 	  rgistd = (U16 *) wvMalloc (sizeof (U16) * ((cch - 6) / 2));
1698 	  for (i = 0; i < (cch - 6) / 2; i++)
1699 	    {
1700 		rgistd[i] = dread_16ubit (NULL, &pointer);
1701 		(*pos) += 2;
1702 	    }
1703       }
1704     else
1705 	rgistd = NULL;
1706     /*
1707        first check if chp.istd is greater than the
1708        istdFirst recorded in the sprm and less than or equal to the istdLast
1709        recorded in the sprm If not, the sprm has no effect. If it is, chp.istd is
1710        set to rgstd[chp.istd - istdFirst] and any chpx stored in that rgstd entry
1711        is applied to the chp.
1712 
1713        Note that it is possible that an istd may be recorded in the rgistd that
1714        refers to a paragraph style. This will no harmful consequences since the
1715        istd for a paragraph style should never be recorded in chp.istd.
1716      */
1717 
1718     if ((achp->istd > istdFirst) && (achp->istd <= istdLast))
1719       {
1720 	  achp->istd = rgistd[achp->istd - istdFirst];
1721 	  /*
1722 	     if really a chp style
1723 	     wvAddCHPXFromUPEBucket(achp,&(stsh->std[achp->istd].grupe[0].chpx),stsh);
1724 	     else
1725 	     complain;
1726 	   */
1727       }
1728     wvFree (rgistd);
1729 }
1730 
1731 void
wvApplysprmCDefault(CHP * achp,U8 * pointer,U16 * pos)1732 wvApplysprmCDefault (CHP * achp, U8 * pointer, U16 * pos)
1733 {
1734     /*
1735        sprmCDefault (opcode 0x2A32) clears the fBold, fItalic, fOutline, fStrike,
1736        fShadow, fSmallCaps, fCaps, fVanish, kul and ico fields of the chp to 0. It
1737        was first defined for Word 3.01 and had to be backward compatible with Word
1738        3.00 so it is a variable length sprm whose count of bytes is 0. It consists
1739        of the sprmCDefault opcode followed by a byte of 0.
1740      */
1741     dread_8ubit (NULL, &pointer);
1742     (*pos)++;
1743     achp->fBold = 0;
1744     achp->fItalic = 0;
1745     achp->fOutline = 0;
1746     achp->fStrike = 0;
1747     achp->fShadow = 0;
1748     achp->fSmallCaps = 0;
1749     achp->fCaps = 0;
1750     achp->fVanish = 0;
1751     achp->kul = 0;
1752     achp->ico = 0;
1753 }
1754 
1755 void
wvApplysprmCPlain(CHP * achp,STSH * stsh)1756 wvApplysprmCPlain (CHP * achp, STSH * stsh)
1757 {
1758     U8 fSpec;
1759     /*
1760        the style sheet CHP is copied over the original CHP preserving the
1761        fSpec setting from the original CHP.
1762      */
1763     fSpec = achp->fSpec;
1764     wvInitCHPFromIstd (achp, achp->istd, stsh);
1765     achp->fSpec = fSpec;
1766 }
1767 
1768 
1769 U8
wvToggle(U8 in,U8 toggle)1770 wvToggle (U8 in, U8 toggle)
1771 {
1772     /*
1773        When the parameter of the sprm is set to 0 or 1, then
1774        the CHP property is set to the parameter value.
1775      */
1776     if ((toggle == 0) || (toggle == 1))
1777 	return (toggle);
1778     /*
1779        When the parameter of the sprm is 128, then the CHP property is set to the
1780        value that is stored for the property in the style sheet. CHP When the
1781        parameter of the sprm is 129, the CHP property is set to the negation of the
1782        value that is stored for the property in the style sheet CHP.
1783      */
1784 
1785     /*
1786        an argument might be made that instead of in being returned or negated that
1787        it should be the looked up in the original chp through the istd that should
1788        be used, in which case this should be a macro that does the right thing.
1789        but im uncertain as to which is the correct one to do, ideas on a postcard
1790        to... etc etc
1791      */
1792     if (toggle == 128)
1793 	return (in);
1794     else if (toggle == 129)
1795 	return (!in);
1796     wvWarning ("Strangle sprm toggle value, ignoring\n");
1797     return (in);
1798 }
1799 
1800 void
wvApplysprmCSizePos(CHP * achp,U8 * pointer,U16 * pos)1801 wvApplysprmCSizePos (CHP * achp, U8 * pointer, U16 * pos)
1802 {
1803     U8 prevhpsPos;
1804     U16 temp8;
1805     struct _temp {
1806 	U32 hpsSize:8;
1807 	U32 cInc:7;
1808 	U32 fAdjust:1;
1809 	U32 hpsPos:8;
1810     } temp;
1811     temp.hpsSize = dread_8ubit (NULL, &pointer);
1812     (*pos)++;
1813     temp8 = dread_8ubit (NULL, &pointer);
1814     (*pos)++;
1815     temp.cInc = (temp8 & 0x7f) >> 8;
1816     temp.fAdjust = (temp8 & 0x80) >> 7;
1817     temp.hpsPos = dread_8ubit (NULL, &pointer);
1818     (*pos)++;
1819 
1820     /*
1821        if hpsSize != 0 then chp.hps is set to hpsSize.
1822 
1823        If cInc is != 0, the cInc is interpreted as a 7 bit twos complement
1824        number and the procedure described below for interpreting sprmCHpsInc is
1825        followed to increase or decrease the chp.hps by the specified number of
1826        levels.
1827 
1828        If hpsPos is != 128, then chp.hpsPos is set equal to hpsPos.
1829 
1830        If fAdjust is on , hpsPos != 128 and hpsPos != 0 and the previous value of
1831        chp.hpsPos == 0, then chp.hps is reduced by one level following the method
1832        described for sprmCHpsInc.
1833 
1834        If fAdjust is on, hpsPos == 0 and the previous value of chp.hpsPos != 0,
1835        then the chp.hps value is increased by one level using the method described
1836        below for sprmCHpsInc.
1837      */
1838 
1839     if (temp.hpsSize != 0)
1840 	achp->hps = temp.hpsSize;
1841 
1842     if (temp.cInc != 0)
1843       {
1844       }
1845 
1846     prevhpsPos = achp->hpsPos;
1847 
1848     if (temp.hpsPos != 128)
1849 	achp->hpsPos = temp.hpsPos;
1850 #if 0
1851     /*else ? who knows ? */
1852     if ((temp.fAdjust) && (temp.hpsPos != 128) && (temp.hpsPos != 0)
1853 	&& (achp->hpsPos == 0))
1854 	/*reduce level */ ;
1855     if ((temp.fAdjust) && (temp.hpsPos == 0) && (achp->hpsPos != 0))
1856 	/*increase level */ ;
1857 #endif
1858 
1859     /*
1860        This depends on an implementation of sprmCHpsInc, read wvApplysprmCHpsInc for
1861        some comments on the whole matter
1862      */
1863 
1864     wvError (
1865 	     ("This document has an unsupported sprm (sprmCSizePos), please mail "));
1866     wvError (
1867 	     ("Caolan.McNamara@ul.ie with this document, as i haven't been able to "));
1868     wvError (("get any examples of it so as to figure out how to handle it\n"));
1869 
1870 }
1871 
1872 void
wvApplysprmCHpsInc(CHP * achp,U8 * pointer,U16 * pos)1873 wvApplysprmCHpsInc (CHP * achp, U8 * pointer, U16 * pos)
1874 {
1875     U8 param;
1876     /*
1877        sprmCHpsInc(opcode 0x2A44) is a three-byte sprm consisting of the sprm
1878        opcode and a one-byte parameter.
1879 
1880        Word keeps an ordered array of the font sizes that are defined for the fonts
1881        recorded in the system file with each font size transformed into an hps.
1882 
1883        The parameter is a one-byte twos complement number. Word uses this number
1884        to calculate an index in the font size array to determine the new hps for a
1885        run. When Word interprets this sprm and the parameter is positive, it searches
1886        the array of font sizes to find the index of the smallest entry in the font
1887        size table that is greater than the current chp.hps.It then adds the
1888        parameter minus 1 to the index and maxes this with the index of the last array
1889        entry. It uses the result as an index into the font size array and assigns that
1890        entry of the array to chp.hps.
1891 
1892        When the parameter is negative, Word searches the array of font sizes to
1893        find the index of the entry that is less than or equal to the current
1894        chp.hps. It then adds the negative parameter to the index and does a min of
1895        the result with 0. The result of the min function is used as an index into
1896        the font size array and that entry of the array is assigned to chp.hps.
1897        sprmCHpsInc is stored only in grpprls linked to piece table entries.
1898      */
1899 
1900     wvError (
1901 	     ("This document has an unsupported sprm (sprmCHpsInc), please mail"));
1902     wvError (
1903 	     ("Caolan.McNamara@ul.ie with this document, as i haven't been able to "));
1904     wvError (("get any examples of it so as to figure out how to handle it\n"));
1905 
1906     param = dread_8ubit (NULL, &pointer);
1907 
1908     /*
1909        Now for christ sake !!, how on earth would i have an "ordered array of the
1910        font sizes that are defined for the fonts recorded in the system file", that
1911        sounds to me that i would have to have access to the fonts on the actual
1912        machine that word was last run on !, it sounds to me that this sprm might only
1913        be used during the editing of a file, so im going to have to ignore it because
1914        it complete goobledegook to me
1915      */
1916 
1917 }
1918 
1919 void
wvApplysprmCHpsPosAdj(CHP * achp,U8 * pointer,U16 * pos)1920 wvApplysprmCHpsPosAdj (CHP * achp, U8 * pointer, U16 * pos)
1921 {
1922     U8 param;
1923     /*
1924        sprmCHpsPosAdj (opcode 0x2A46) causes the hps of a run to be reduced the
1925        first time text is superscripted or subscripted and causes the hps of a run
1926        to be increased when superscripting/subscripting is removed from a run.
1927 
1928        The one byte parameter of this sprm is the new hpsPos value that is to be
1929        stored in chp.hpsPos.
1930 
1931        If the new hpsPos is not equal 0 (meaning that the text is to be super/
1932        subscripted), Word first examines the current value of chp.hpsPos
1933        to see if it is equal to 0.
1934 
1935        If so, Word uses the algorithm described for sprmCHpsInc to decrease chp.hps
1936        by one level.
1937 
1938        If the new hpsPos == 0 (meaning the text is not super/subscripted),
1939        Word examines the current chp.hpsPos to see if it is not equal to 0. If it is
1940        not (which means text is being restored to normal position), Word uses the
1941        sprmCHpsInc algorithm to increase chp.hps by one level.
1942 
1943        After chp.hps is adjusted, the parameter value is stored in chp.hpsPos.
1944      */
1945 
1946     wvError (
1947 	     ("This document has an partially unsupported sprm (sprmCHpsPosAdj), please mail "));
1948     wvError (
1949 	     ("Caolan.McNamara@ul.ie with this document, as i haven't been able to "));
1950     wvError (("get any examples of it so as to figure out how to handle it\n"));
1951 
1952     param = dread_8ubit (NULL, &pointer);
1953     (*pos)++;
1954 
1955     /*
1956        please see wvApplysprmCHpsInc for why this is unfinished
1957      */
1958 
1959 #if 0
1960     if ((param != 0) && (achp->hpsPos == 0))
1961 	/*decrease chp.hps */ ;
1962     else if ((param == 0) && (achp->hpsPos != 0))
1963 	/*increase chp.hps */ ;
1964 #endif
1965 
1966     achp->hpsPos = param;
1967 
1968 
1969 }
1970 
1971 void
wvApplysprmCMajority(CHP * achp,STSH * stsh,U8 * pointer,U16 * pos)1972 wvApplysprmCMajority (CHP * achp, STSH * stsh, U8 * pointer, U16 * pos)
1973 {
1974     U16 i;
1975     CHP base;
1976     CHP orig;
1977     UPXF upxf;
1978     /*
1979        Bytes 0 and 1 of
1980        sprmCMajority contains the opcode, byte 2 contains the length of the
1981        following list of character sprms. . Word begins interpretation of this sprm
1982        by applying the stored character sprm list to a standard chp. That chp has
1983        chp.istd = istdNormalChar. chp.hps=20, chp.lid=0x0400 and chp.ftc = 4. Word
1984        then compares fBold, fItalic, fStrike, fOutline, fShadow, fSmallCaps, fCaps,
1985        ftc, hps, hpsPos, kul, qpsSpace and ico in the original CHP with the values
1986        recorded for these fields in the generated CHP.. If a field in the original
1987        CHP has the same value as the field stored in the generated CHP, then that
1988        field is reset to the value stored in the style's CHP. If the two copies
1989        differ, then the original CHP value is left unchanged.
1990      */
1991     wvTrace (
1992 	     ("This document has a sprm (sprmCMajority), that ive never seen in practice please mail "));
1993     wvTrace (
1994 	     ("Caolan.McNamara@ul.ie with this document, as i haven't been able to "));
1995     wvTrace (
1996 	     ("get any examples of it so as to figure out if its handled correctly\n"));
1997 
1998     wvInitCHP (&base);
1999     base.ftc = 4;
2000 
2001     /*generate a UPE and run wvAddCHPXFromBucket */
2002 
2003     upxf.cbUPX = dread_8ubit (NULL, &pointer);
2004     (*pos)++;
2005     upxf.upx.chpx.grpprl = (U8 *) wvMalloc (upxf.cbUPX);
2006 
2007     for (i = 0; i < upxf.cbUPX; i++)
2008       {
2009 	  upxf.upx.chpx.grpprl[i] = dread_8ubit (NULL, &pointer);
2010 	  (*pos)++;
2011       }
2012 
2013     wvTrace (("achp istd is %d\n", achp->istd));
2014 
2015     wvAddCHPXFromBucket (&base, &upxf, stsh);
2016 
2017     wvTrace (("achp istd is %d\n", achp->istd));
2018 
2019     wvTrace (("my underline started as %d\n", achp->kul));
2020 
2021     wvInitCHPFromIstd (&orig, achp->istd, stsh);
2022 
2023     /* this might be a little wrong, review after doing dedicated CHP's */
2024     if (achp->fBold == base.fBold)
2025 	achp->fBold = orig.fBold;
2026     if (achp->fItalic == base.fItalic)
2027 	achp->fItalic = orig.fItalic;
2028     if (achp->fStrike == base.fStrike)
2029 	achp->fStrike = orig.fStrike;
2030     if (achp->fOutline == base.fOutline)
2031 	achp->fOutline = orig.fOutline;
2032     if (achp->fShadow == base.fShadow)
2033 	achp->fShadow = orig.fShadow;
2034     if (achp->fSmallCaps == base.fSmallCaps)
2035 	achp->fSmallCaps = orig.fSmallCaps;
2036     if (achp->fCaps == base.fCaps)
2037 	achp->fCaps = orig.fCaps;
2038     if (achp->ftc == base.ftc)
2039 	achp->ftc = orig.ftc;
2040     if (achp->hps == base.hps)
2041 	achp->hps = orig.hps;
2042     if (achp->hpsPos == base.hpsPos)
2043 	achp->hpsPos = orig.hpsPos;
2044     if (achp->kul == base.kul)
2045 	achp->kul = orig.kul;
2046     /* ????
2047        if (achp->qpsSpace == base.qpsSpace)
2048        achp->qpsSpace = orig.qpsSpace;
2049      */
2050     if (achp->ico == base.ico)
2051 	achp->ico = orig.ico;
2052 
2053     /*
2054        these ones are mentioned in a different part of the spec, that
2055        doesnt have as much weight as the above, but i'm going to add them
2056        anyway
2057      */
2058     if (achp->fVanish == base.fVanish)
2059 	achp->fVanish = orig.fVanish;
2060     wvTrace (("%d\n", base.dxaSpace));
2061     wvTrace (("%d\n", achp->dxaSpace));
2062     if (achp->dxaSpace == base.dxaSpace)
2063 	achp->dxaSpace = orig.dxaSpace;
2064     if (achp->lidDefault == base.lidDefault)
2065 	achp->lidDefault = orig.lidDefault;
2066     if (achp->lidFE == base.lidFE)
2067 	achp->lidFE = orig.lidFE;
2068     wvFree (upxf.upx.chpx.grpprl);
2069 
2070 
2071     wvTrace (("my underline ended as %d\n", achp->kul));
2072 }
2073 
2074 void
wvApplysprmCHpsInc1(CHP * achp,U8 * pointer,U16 * pos)2075 wvApplysprmCHpsInc1 (CHP * achp, U8 * pointer, U16 * pos)
2076 {
2077     /*
2078        This sprm is interpreted by adding the two byte increment
2079        stored as the opcode of the sprm to chp.hps. If this result is less than 8,
2080        the chp.hps is set to 8. If the result is greater than 32766, the chp.hps is
2081        set to 32766.
2082      */
2083     dread_8ubit (NULL, &pointer);
2084     (*pos)++;
2085     achp->hps += dread_16ubit (NULL, &pointer);
2086     (*pos) += 2;
2087     if (achp->hps < 8)
2088 	achp->hps = 8;
2089     else if (achp->hps > 32766)
2090 	achp->hps = 32766;
2091 }
2092 
2093 
2094 void
wvApplysprmCMajority50(CHP * achp,STSH * stsh,U8 * pointer,U16 * pos)2095 wvApplysprmCMajority50 (CHP * achp, STSH * stsh, U8 * pointer, U16 * pos)
2096 {
2097     U16 i;
2098     CHP base;
2099     CHP orig;
2100     UPXF upxf;
2101     /*
2102        Bytes 0 and 1 of
2103        sprmCMajority contains the opcode, byte 2 contains the length of the
2104        following list of character sprms. . Word begins interpretation of this sprm
2105        by applying the stored character sprm list to a standard chp. That chp has
2106        chp.istd = istdNormalChar. chp.hps=20, chp.lid=0x0400 and chp.ftc = 4. Word
2107        then compares fBold, fItalic, fStrike, fOutline, fShadow, fSmallCaps, fCaps,
2108        ftc, hps, hpsPos, kul, qpsSpace and ico in the original CHP with the values
2109        recorded for these fields in the generated CHP.. If a field in the original
2110        CHP has the same value as the field stored in the generated CHP, then that
2111        field is reset to the value stored in the style's CHP. If the two copies
2112        differ, then the original CHP value is left unchanged.
2113      */
2114     wvTrace (
2115 	     ("This document has a sprm (sprmCMajority50), that ive never seen in practice please mail "));
2116     wvTrace (
2117 	     ("Caolan.McNamara@ul.ie with this document, as i haven't been able to "));
2118     wvTrace (
2119 	     ("get any examples of it so as to figure out if its handled correctly\n"));
2120 
2121     wvInitCHP (&base);
2122     base.ftc = 4;
2123 
2124     /*generate a UPE and run wvAddCHPXFromBucket */
2125 
2126     upxf.cbUPX = dread_8ubit (NULL, &pointer);
2127     (*pos)++;
2128     upxf.upx.chpx.grpprl = (U8 *) wvMalloc (upxf.cbUPX);
2129 
2130     for (i = 0; i < upxf.cbUPX; i++)
2131       {
2132 	  upxf.upx.chpx.grpprl[i] = dread_8ubit (NULL, &pointer);
2133 	  (*pos)++;
2134       }
2135 
2136     wvAddCHPXFromBucket (&base, &upxf, stsh);
2137 
2138     wvInitCHPFromIstd (&orig, achp->istd, stsh);
2139 
2140     /* this might be a little wrong, review after doing dedicated CHP's */
2141     wvTrace (("istd is %d\n", achp->istd));
2142     if (achp->fBold == base.fBold)
2143 	achp->fBold = orig.fBold;
2144     if (achp->fItalic == base.fItalic)
2145 	achp->fItalic = orig.fItalic;
2146     if (achp->fStrike == base.fStrike)
2147 	achp->fStrike = orig.fStrike;
2148     if (achp->fSmallCaps == base.fSmallCaps)
2149 	achp->fSmallCaps = orig.fSmallCaps;
2150     if (achp->fCaps == base.fCaps)
2151 	achp->fCaps = orig.fCaps;
2152     if (achp->ftc == base.ftc)
2153 	achp->ftc = orig.ftc;
2154     if (achp->hps == base.hps)
2155 	achp->hps = orig.hps;
2156     if (achp->hpsPos == base.hpsPos)
2157 	achp->hpsPos = orig.hpsPos;
2158     if (achp->kul == base.kul)
2159 	achp->kul = orig.kul;
2160     if (achp->ico == base.ico)
2161 	achp->ico = orig.ico;
2162     if (achp->fVanish == base.fVanish)
2163 	achp->fVanish = orig.fVanish;
2164     if (achp->dxaSpace == base.dxaSpace)
2165 	achp->dxaSpace = orig.dxaSpace;
2166 
2167     wvFree (upxf.upx.chpx.grpprl); /* this seemed to be missing... */
2168 }
2169 
2170 void
wvApplysprmCPropRMark(CHP * achp,U8 * pointer,U16 * pos)2171 wvApplysprmCPropRMark (CHP * achp, U8 * pointer, U16 * pos)
2172 {
2173     dread_8ubit (NULL, &pointer);	/*len */
2174     (*pos)++;
2175     achp->fPropRMark = dread_8ubit (NULL, &pointer);
2176     (*pos)++;
2177     achp->ibstPropRMark = (S16) dread_16ubit (NULL, &pointer);
2178     (*pos) += 2;
2179     wvGetDTTMFromBucket (&achp->dttmPropRMark, pointer);
2180     (*pos) += 4;
2181 }
2182 
2183 void
wvApplysprmCDispFldRMark(CHP * achp,U8 * pointer,U16 * pos)2184 wvApplysprmCDispFldRMark (CHP * achp, U8 * pointer, U16 * pos)
2185 {
2186     /*
2187        is interpreted by moving the first
2188        parameter byte to chp.fDispFldRMark, the next two bytes to
2189        chp.ibstDispFldRMark, the next four bytes to chp.dttmDispFldRMark,
2190        and the remaining 32 bytes to chp.xstDispFldRMark.
2191      */
2192 
2193     int i;
2194     dread_8ubit (NULL, &pointer);	/*len */
2195     (*pos)++;
2196     achp->fDispFldRMark = dread_8ubit (NULL, &pointer);
2197     (*pos)++;
2198     achp->ibstDispFldRMark = (S16) dread_16ubit (NULL, &pointer);
2199     (*pos) += 2;
2200     wvGetDTTMFromBucket (&achp->dttmDispFldRMark, pointer);
2201     (*pos) += 4;
2202     pointer += 4;
2203     for (i = 0; i < 16; i++)
2204       {
2205 	  achp->xstDispFldRMark[i] = dread_16ubit (NULL, &pointer);
2206 	  (*pos) += 2;
2207       }
2208 }
2209 
2210 
2211 void
wvApplysprmSOlstAnm(wvVersion ver,SEP * asep,U8 * pointer,U16 * pos)2212 wvApplysprmSOlstAnm (wvVersion ver, SEP * asep, U8 * pointer, U16 * pos)
2213 {
2214     U8 len = dread_8ubit (NULL, &pointer);
2215     wvGetOLSTFromBucket (ver, &asep->olstAnm, pointer);
2216     if (len != cbOLST)
2217 	wvError (("OLST len is different from expected\n"));
2218     (*pos) += len;
2219 }
2220 
2221 void
wvApplysprmSPropRMark(SEP * asep,U8 * pointer,U16 * pos)2222 wvApplysprmSPropRMark (SEP * asep, U8 * pointer, U16 * pos)
2223 {
2224     dread_8ubit (NULL, &pointer);
2225     (*pos)++;
2226     /*
2227        sprmPPropRMark is interpreted by moving the first parameter
2228        byte to pap.fPropRMark, the next two bytes to pap.ibstPropRMark, and the
2229        remaining four bytes to pap.dttmPropRMark.
2230      */
2231     asep->fPropRMark = dread_8ubit (NULL, &pointer);
2232     (*pos)++;
2233     asep->ibstPropRMark = dread_16ubit (NULL, &pointer);
2234     (*pos) += 2;
2235     wvGetDTTMFromBucket (&asep->dttmPropRMark, pointer);
2236     (*pos) += 4;
2237 }
2238 
2239 
2240 /*
2241 sprmTDxaLeft (opcode 0x9601) is called to adjust the x position within a
2242 column which marks the left boundary of text within the first cell of a
2243 table row. This sprm causes a whole table row to be shifted left or right
2244 within its column leaving the horizontal width and vertical height of cells
2245 in the row unchanged. Bytes 0-1 of the sprm contains the opcode, and the new
2246 dxa position, call it dxaNew, is stored as an integer in bytes 2 and 3. Word
2247 interprets this sprm by adding dxaNew - (rgdxaCenter[0] + tap.dxaGapHalf) to
2248 every entry of tap.rgdxaCenter whose index is less than tap.itcMac.
2249 sprmTDxaLeft is stored only in grpprls linked to piece table entries.
2250 */
2251 void
wvApplysprmTDxaLeft(TAP * aTap,U8 * pointer,U16 * pos)2252 wvApplysprmTDxaLeft (TAP * aTap, U8 * pointer, U16 * pos)
2253 {
2254     S16 dxaNew = (S16) dread_16ubit (NULL, &pointer);
2255     int i;
2256     (*pos) += 2;
2257     dxaNew = dxaNew - (aTap->rgdxaCenter[0] + aTap->dxaGapHalf);
2258     for (i = 0; i < aTap->itcMac; i++)
2259 	aTap->rgdxaCenter[i] += dxaNew;
2260 }
2261 
2262 /*
2263 sprmTDxaGapHalf (opcode 0x9602) adjusts the white space that is maintained
2264 between columns by changing tap.dxaGapHalf. Because we want the left
2265 boundary of text within the leftmost cell to be at the same location after
2266 the sprm is applied, Word also adjusts tap.rgdxCenter[0] by the amount that
2267 tap.dxaGapHalf changes. Bytes 0-1 of the sprm contains the opcode, and the
2268 new dxaGapHalf, call it dxaGapHalfNew, is stored in bytes 2 and 3. When the
2269 sprm is interpreted, the change between the old and new dxaGapHalf values,
2270 tap.dxaGapHalf - dxaGapHalfNew, is added to tap.rgdxaCenter[0] and then
2271 dxaGapHalfNew is moved to tap.dxaGapHalf. sprmTDxaGapHalf is stored in PAPXs
2272 and also in grpprls linked to piece table entries.
2273 
2274 */
2275 void
wvApplysprmTDxaGapHalf(TAP * aTap,U8 * pointer,U16 * pos)2276 wvApplysprmTDxaGapHalf (TAP * aTap, U8 * pointer, U16 * pos)
2277 {
2278     S16 dxaGapHalfNew = (S16) dread_16ubit (NULL, &pointer);
2279     (*pos) += 2;
2280     aTap->rgdxaCenter[0] += aTap->dxaGapHalf - dxaGapHalfNew;
2281     aTap->dxaGapHalf = dxaGapHalfNew;
2282 }
2283 
2284 /*
2285 sprmTTableBorders (opcode 0xD605) sets the tap.rgbrcTable. The sprm is
2286 interpreted by moving the 24 bytes of the sprm's operand to tap.rgbrcTable.
2287 */
2288 void
wvApplysprmTTableBorders(wvVersion ver,TAP * aTap,U8 * pointer,U16 * pos)2289 wvApplysprmTTableBorders (wvVersion ver, TAP * aTap, U8 * pointer, U16 * pos)
2290 {
2291     int i, d;
2292     if (ver == WORD8)
2293       {
2294 	  dread_8ubit (NULL, &pointer);
2295 	  (*pos)++;
2296       }
2297     for (i = 0; i < 6; i++)
2298       {
2299 	  d = wvGetBRCFromBucket (ver, &(aTap->rgbrcTable[i]), pointer);
2300 	  pointer += d;
2301 	  (*pos) += d;
2302       }
2303 }
2304 
2305 /*
2306 sprmTDefTable (opcode 0xD608) defines the boundaries of table cells
2307 (tap.rgdxaCenter) and the properties of each cell in a table (tap.rgtc).
2308 Bytes 0 and 1 of the sprm contain its opcode. Bytes 2 and 3 store a two-byte
2309 length of the following parameter. Byte 4 contains the number of cells that
2310 are to be defined by the sprm, call it itcMac. When the sprm is interpreted,
2311 itcMac is moved to tap.itcMac. itcMac cannot be larger than 32. In bytes 5
2312 through 5+2*(itcMac + 1) -1 , is stored an array of integer dxa values
2313 sorted in ascending order which will be moved to tap.rgdxaCenter. In bytes
2314 5+ 2*(itcMac + 1) through byte 5+2*(itcMac + 1) + 10*itcMac - 1 is stored an
2315 array of TC entries corresponding to the stored tap.rgdxaCenter. This array
2316 is moved to tap.rgtc. sprmTDefTable is only stored in PAPXs.
2317 */
2318 void
wvApplysprmTDefTable(TAP * aTap,U8 * pointer,U16 * pos)2319 wvApplysprmTDefTable (TAP * aTap, U8 * pointer, U16 * pos)
2320 {
2321     U16 len;
2322     int i, t, oldpos;
2323     wvVersion type;
2324     len = dread_16ubit (NULL, &pointer);
2325     (*pos) += 2;
2326     wvTrace (("wvApplysprmTDefTable\n"));
2327     aTap->itcMac = dread_8ubit (NULL, &pointer);
2328     (*pos)++;
2329     oldpos = (*pos) - 2;
2330     wvTrace (("oldpos is %x\n", oldpos));
2331     wvTrace (("C: there are %d cells\n", aTap->itcMac));
2332     for (i = 0; i < aTap->itcMac + 1; i++)
2333       {
2334 	  aTap->rgdxaCenter[i] = (S16) dread_16ubit (NULL, &pointer);
2335 	  wvTrace (("C: cell boun is %d\n", aTap->rgdxaCenter[i]));
2336 	  (*pos) += 2;
2337       }
2338 
2339     wvTrace (
2340 	     ("HERE-->pos is now %d, the len was %d, there is %d left\n",
2341 	      *pos, len, len - (*pos - oldpos)));
2342 
2343     if ((len - (*pos - oldpos)) < (cb6TC * aTap->itcMac))
2344       {
2345 	  pointer += len - (*pos - oldpos);
2346 	  (*pos) += len - (*pos - oldpos);
2347 	  return;
2348       }
2349 
2350     if ((len - (*pos - oldpos)) < (cbTC * aTap->itcMac))
2351 	type = WORD6;
2352     else
2353 	type = WORD8;
2354 
2355     wvTrace (("type is %d\n", type));
2356 
2357     wvTrace (("left over is %d\n", len - (*pos - oldpos)));
2358 
2359     for (i = 0; i < aTap->itcMac; i++)
2360       {
2361 	  t = wvGetTCFromBucket (type, &(aTap->rgtc[i]), pointer);
2362 	  wvTrace (("DefTable merge is %d\n", aTap->rgtc[i].fVertMerge));
2363 	  /* for christ sake !!, word 8 stores word 6 sized TC's in this sprm ! */
2364 	  (*pos) += t;
2365 	  pointer += t;
2366 	  wvTrace (("t is %d, under is %x\n", t, *pointer));
2367       }
2368 
2369     wvTrace (("left over is %d\n", len - (*pos - oldpos)));
2370 
2371     while (len - (*pos - oldpos))
2372       {
2373 	  wvTrace (("Eating byte %x\n", dread_8ubit (NULL, &pointer)));
2374 	  (*pos)++;
2375       }
2376     wvTrace (
2377 	     ("oldpos is %x, pos is %x, diff is %d\n", oldpos, *pos,
2378 	      *pos - oldpos - 2));
2379 }
2380 
2381 /*
2382 sprmTDefTable10 (opcode0xD606) is an obsolete version of sprmTDefTable
2383 (opcode 0xD608) that was used in WinWord 1.x. Its contents are identical to
2384 those in sprmTDefTable, except that the TC structures contain the obsolete
2385 structures BRC10s.
2386 */
2387 
2388 void
wvApplysprmTDefTable10(TAP * aTap,U8 * pointer,U16 * pos)2389 wvApplysprmTDefTable10 (TAP * aTap, U8 * pointer, U16 * pos)
2390 {
2391     U16 len;
2392     int i, t;
2393     len = dread_16ubit (NULL, &pointer);
2394     (*pos) += 2;
2395     aTap->itcMac = dread_8ubit (NULL, &pointer);
2396     (*pos)++;
2397     for (i = 0; i < aTap->itcMac + 1; i++)
2398       {
2399 	  aTap->rgdxaCenter[i] = (S16) dread_16ubit (NULL, &pointer);
2400 	  (*pos) += 2;
2401       }
2402     for (i = 0; i < aTap->itcMac; i++)
2403       {
2404 	  t = wvGetTCFromBucket (WORD6, &(aTap->rgtc[i]), pointer);
2405 	  (*pos) += t;
2406 	  pointer += t;
2407       }
2408 }
2409 
2410 void
wv2ApplysprmTDefTableShd(TAP * aTap,U8 * pointer,U16 * pos)2411 wv2ApplysprmTDefTableShd (TAP * aTap, U8 * pointer, U16 * pos)
2412 {
2413     U8 len;
2414     U16 itcMac;
2415     int i;
2416 
2417     len = dread_8ubit (NULL, &pointer);
2418     (*pos)++;
2419     itcMac = len / cbSHD;
2420     wvTrace (
2421 	     ("len in 2sprmTDefTableShd is %d, no of cells is %d\n", len,
2422 	      itcMac));
2423 
2424     for (i = 0; i < itcMac; i++)
2425       {
2426 	  wvGetSHDFromBucket (&(aTap->rgshd[i]), pointer);
2427 	  pointer += cbSHD;
2428 	  (*pos) += cbSHD;
2429       }
2430 }
2431 
2432 
2433 /*
2434 sprmTDefTableShd (opcode 0xD609) is similar to sprmTDefTable, and
2435 compliments it by defining the shading of each cell in a table (tap.rgshd).
2436 Bytes 0 and 1 of the sprm contain its opcode. Bytes 2 and 3 store a two-byte
2437 length of the following parameter. Byte 4 contains the number of cells that
2438 are to be defined by the sprm, call it itcMac. itcMac cannot be larger than
2439 32. In bytes 5 through 5+2*(itcMac + 1) -1 , is stored an array of SHDs.
2440 This array is moved to tap.rgshd. sprmTDefTable is only stored in PAPXs.
2441 */
2442 void
wvApplysprmTDefTableShd(TAP * aTap,U8 * pointer,U16 * pos)2443 wvApplysprmTDefTableShd (TAP * aTap, U8 * pointer, U16 * pos)
2444 {
2445     U16 len;
2446     U16 itcMac;
2447     int i, oldpos;
2448 
2449     len = dread_16ubit (NULL, &pointer);
2450     (*pos) += 2;
2451     if (len >= 0x4000)
2452       {
2453 	  len = len & 0x00ff;
2454 	  wvError (
2455 		   ("bad len in sprmTDefTableShd, munging to %d instead\n",
2456 		    len));
2457       }
2458     wvTrace (("wvApplysprmTDefTableShd, len %d\n", len));
2459     itcMac = dread_8ubit (NULL, &pointer);
2460     (*pos)++;
2461     oldpos = (*pos) - 2;
2462     wvTrace (("oldpos is %x\n", oldpos));
2463     wvTrace (("C: there are %d cells\n", itcMac));
2464     if (itcMac > 32)
2465 	wvError (("Broken word doc, recovering from stupidity\n"));
2466     else
2467       {
2468 	  if ((len - (*pos - oldpos)) < (cbSHD * aTap->itcMac))
2469 	    {
2470 		wvError (("Broken sprmDefTableShd, recovering from problem\n"));
2471 		pointer += len - (*pos - oldpos);
2472 		(*pos) += len - (*pos - oldpos);
2473 		return;
2474 	    }
2475 
2476 	  for (i = 0; i < itcMac; i++)
2477 	    {
2478 		wvGetSHDFromBucket (&(aTap->rgshd[i]), pointer);
2479 		pointer += cbSHD;
2480 		(*pos) += cbSHD;
2481 	    }
2482       }
2483 
2484     while (len - (*pos - oldpos))
2485       {
2486 	  wvTrace (("Eating byte %x\n", dread_8ubit (NULL, &pointer)));
2487 	  (*pos)++;
2488       }
2489     wvTrace (
2490 	     ("oldpos is %x, pos is %x, diff is %d\n", oldpos, *pos,
2491 	      *pos - oldpos - 2));
2492 }
2493 
2494 /*
2495 Word 8
2496 
2497 sprmTSetBrc (opcode 0xD620) allows the border definitions(BRCs) within TCs
2498 to be set to new values. It has the following format:
2499 
2500  b10 b16 field          type  size bitfield comments
2501 
2502  0   0   sprm           short               opcode 0xD620
2503 
2504  2   2   count          byte                number of bytes for operand
2505 
2506  3   3   itcFirst       byte                the index of the first cell
2507                                             that is to have its borders
2508                                             changed.
2509 
2510  4   4   itcLim         byte                index of the cell that follows
2511                                             the last cell to have its
2512                                             borders changed
2513 
2514  5   5                  short :4   F0       reserved
2515 
2516          fChangeRight   short :1   08       =1 when tap.rgtc[].brcRight is
2517                                             to be changed
2518 
2519          fChangeBottom  short :1   04       =1 when tap.rgtc[].brcBottom
2520                                             is to be changed
2521 
2522          fChangeLeft    short :1   02       =1 when tap.rgtc[].brcLeft is
2523                                             to be changed
2524 
2525          fChangeTop     short :1   01       =1 when tap.rgtc[].brcTop is
2526                                             to be changed
2527 
2528  6   6   brc            BRC                 new BRC value to be stored in
2529                                             TCs.
2530 
2531 */
2532 /* Pre Word 8 *
2533 0    0    	sprm byte opcode 193
2534 1    1    	itcFirst  byte
2535 2    2    	itcLim    byte
2536 3    3         int  :4 F0   reserved
2537 			fChangeRight int  :1   08
2538 			fChangeBottom int  :1   04
2539 			fChangeLeft int  :1   02
2540 			fChangeTop int  :1   01
2541 	4    4  brc  BRC
2542 */
2543 void
wvApplysprmTSetBrc(wvVersion ver,TAP * aTap,U8 * pointer,U16 * pos)2544 wvApplysprmTSetBrc (wvVersion ver, TAP * aTap, U8 * pointer, U16 * pos)
2545 {
2546     U8 itcFirst, itcLim, len, temp8;
2547     BRC abrc;
2548     int i;
2549     if (ver == WORD8)
2550       {
2551 	  len = dread_8ubit (NULL, &pointer);
2552 	  (*pos)++;
2553 	  wvTrace (("the len is %d", len));
2554       }
2555     itcFirst = dread_8ubit (NULL, &pointer);
2556     itcLim = dread_8ubit (NULL, &pointer);
2557     temp8 = dread_8ubit (NULL, &pointer);
2558     (*pos) += 3;
2559     (*pos) += wvGetBRCFromBucket (ver, &abrc, pointer);
2560 
2561     for (i = itcFirst; i < itcLim; i++)
2562       {
2563 	  if (temp8 & 0x08)
2564 	      wvCopyBRC (&aTap->rgtc[i].brcRight, &abrc);
2565 	  if (temp8 & 0x04)
2566 	      wvCopyBRC (&aTap->rgtc[i].brcBottom, &abrc);
2567 	  if (temp8 & 0x02)
2568 	      wvCopyBRC (&aTap->rgtc[i].brcLeft, &abrc);
2569 	  if (temp8 & 0x01)
2570 	      wvCopyBRC (&aTap->rgtc[i].brcTop, &abrc);
2571       }
2572 }
2573 
2574 /*
2575 sprmTInsert (opcode 0x7621) inserts new cell definitions in an existing
2576 table's cell structure.
2577 
2578 Bytes 0 and 1 of the sprm contain the opcode.
2579 
2580 Byte 2 is the index within tap.rgdxaCenter and tap.rgtc at which the new dxaCenter
2581 and tc values will be inserted. Call this index itcInsert.
2582 
2583 Byte 3 contains a count of the cell definitions to be added to the tap, call it ctc.
2584 
2585 Bytes 4 and 5 contain the width of the cells that will be added, call it dxaCol.
2586 
2587 If there are already cells defined at the index where cells are to be inserted,
2588 tap.rgdxaCenter entries at or above this index must be moved to the entry
2589 ctc higher and must be adjusted by adding ctc*dxaCol to the value stored.
2590 
2591 The contents of tap.rgtc at or above the index must be moved 10*ctc bytes
2592 higher in tap.rgtc.
2593 
2594 If itcInsert is greater than the original tap.itcMac, itcInsert - tap.ctc columns
2595 beginning with index tap.itcMac must be added of width dxaCol
2596 (loop from itcMac to itcMac+itcInsert-tap.ctc adding dxaCol to the rgdxaCenter
2597 value of the previous entry and storing sum as dxaCenter of new entry),
2598 whose TC entries are cleared to zeros.
2599 
2600 Beginning with index itcInsert, ctc columns of width dxaCol must be added by
2601 constructing new tap.rgdxaCenter and tap.rgtc entries with the newly defined
2602 rgtc entries cleared to zeros.
2603 
2604 Finally, the number of cells that were added to the tap is added to tap.itcMac.
2605 
2606 sprmTInsert is stored only in grpprls linked to piece table entries.
2607 */
2608 
2609 void
wvApplysprmTInsert(TAP * aTap,U8 * pointer,U16 * pos)2610 wvApplysprmTInsert (TAP * aTap, U8 * pointer, U16 * pos)
2611 {
2612     U8 itcInsert = dread_8ubit (NULL, &pointer);
2613     U8 ctc = dread_8ubit (NULL, &pointer);
2614     S16 dxaCol = (S16) dread_16ubit (NULL, &pointer);
2615     int i;
2616     (*pos) += 4;
2617 
2618     if (itcInsert <= aTap->itcMac + 1)
2619       {
2620 	  for (i = aTap->itcMac + 1; i >= itcInsert; i--)
2621 	    {
2622 		aTap->rgdxaCenter[i + ctc] =
2623 		    aTap->rgdxaCenter[i] + ctc * dxaCol;
2624 		aTap->rgtc[i + ctc] = aTap->rgtc[i];
2625 	    }
2626       }
2627 
2628     if (itcInsert > aTap->itcMac)
2629       {
2630 	  for (i = aTap->itcMac; i < aTap->itcMac + itcInsert - ctc; i++)
2631 	    {
2632 		aTap->rgdxaCenter[i] = aTap->rgdxaCenter[i - 1] + dxaCol;
2633 		wvInitTC (&(aTap->rgtc[i]));
2634 	    }
2635       }
2636 
2637     for (i = itcInsert; i < ctc + itcInsert; i++)
2638       {
2639 	  aTap->rgdxaCenter[i] = aTap->rgdxaCenter[i - 1] + dxaCol;
2640 	  wvInitTC (&(aTap->rgtc[i]));
2641       }
2642 
2643     aTap->itcMac += ctc;
2644 }
2645 
2646 
2647 /*
2648 sprmTDelete (opcode 0x5622) deletes cell definitions from an existing
2649 table's cell structure. Bytes 0 and 1of the sprm contain the opcode. Byte 2
2650 contains the index of the first cell to delete, call it itcFirst. Byte 3
2651 contains the index of the cell that follows the last cell to be deleted,
2652 call it itcLim. sprmTDelete causes any rgdxaCenter and rgtc entries whose
2653 index is greater than or equal to itcLim to be moved to the entry that is
2654 itcLim - itcFirst lower, and causes tap.itcMac to be decreased by the number
2655 of cells deleted. sprmTDelete is stored only in grpprls linked to piece
2656 table entries.
2657 */
2658 void
wvApplysprmTDelete(TAP * aTap,U8 * pointer,U16 * pos)2659 wvApplysprmTDelete (TAP * aTap, U8 * pointer, U16 * pos)
2660 {
2661     U8 itcFirst = dread_8ubit (NULL, &pointer);
2662     U8 itcLim = dread_8ubit (NULL, &pointer);
2663     int i;
2664     (*pos) += 2;
2665 
2666     for (i = itcLim; i < aTap->itcMac + 1; i++)
2667       {
2668 	  aTap->rgdxaCenter[i - (itcLim - itcFirst)] = aTap->rgdxaCenter[i];
2669 	  wvCopyTC (&(aTap->rgtc[i - (itcLim - itcFirst)]), &(aTap->rgtc[i]));
2670       }
2671 }
2672 
2673 /*
2674 sprmTDxaCol (opcode 0x7623) changes the width of cells whose index is within
2675 a certain range to be a certain value. Bytes 0 and 1of the sprm contain the
2676 opcode. Byte 2 contains the index of the first cell whose width is to be
2677 changed, call it itcFirst. Byte 3 contains the index of the cell that
2678 follows the last cell whose width is to be changed, call it itcLim. Bytes 4
2679 and 5 contain the new width of the cell, call it dxaCol.
2680 
2681 This sprm causes the itcLim - itcFirst entries of tap.rgdxaCenter to be
2682 adjusted so that tap.rgdxaCenter[i+1] = tap.rgdxaCenter[i] + dxaCol. Any
2683 tap.rgdxaCenter entries that exist beyond itcLim are adjusted to take into
2684 account the amount added to or removed from the previous columns.
2685 */
2686 void
wvApplysprmTDxaCol(TAP * aTap,U8 * pointer,U16 * pos)2687 wvApplysprmTDxaCol (TAP * aTap, U8 * pointer, U16 * pos)
2688 {
2689     U8 itcFirst = dread_8ubit (NULL, &pointer);
2690     U8 itcLim = dread_8ubit (NULL, &pointer);
2691     S16 dxaCol = (S16) dread_16ubit (NULL, &pointer);
2692     S16 diff = 0;
2693     int i;
2694     (*pos) += 4;
2695     for (i = itcFirst; i < itcLim; i++)
2696       {
2697 	  diff += aTap->rgdxaCenter[i + 1] - (aTap->rgdxaCenter[i] + dxaCol);
2698 	  aTap->rgdxaCenter[i + 1] = aTap->rgdxaCenter[i] + dxaCol;
2699       }
2700     for (i = itcLim; i < aTap->itcMac + 1; i++);
2701     aTap->rgdxaCenter[i + 1] += diff;
2702 }
2703 
2704 /*
2705 sprmTMerge (opcode 0x5624) merges the display areas of cells within a
2706 specified range. Bytes 0 and 1 of the sprm contain the opcode. Byte 2
2707 contains the index of the first cell that is to be merged, call it itcFirst.
2708 Byte 3 contains the index of the cell that follows the last cell to be
2709 merged, call it itcLim.
2710 
2711 This sprm causes tap.rgtc[itcFirst].fFirstMerged to
2712 be set to 1. Cells in the range whose index is greater than itcFirst and
2713 less than itcLim have tap.rgtc[].fMerged set to 1. sprmTMerge is stored only
2714 in grpprls linked to piece table entries.
2715 
2716 */
2717 void
wvApplysprmTMerge(TAP * aTap,U8 * pointer,U16 * pos)2718 wvApplysprmTMerge (TAP * aTap, U8 * pointer, U16 * pos)
2719 {
2720     U8 itcFirst = dread_8ubit (NULL, &pointer);
2721     U8 itcLim = dread_8ubit (NULL, &pointer);
2722     int i;
2723     (*pos) += 2;
2724 
2725     aTap->rgtc[itcFirst].fFirstMerged = 1;
2726     for (i = itcFirst + 1; i < itcLim; i++)
2727 	aTap->rgtc[i].fMerged = 1;
2728 }
2729 
2730 /*
2731 sprmTSplit (opcode 0x5625) splits the display areas of merged cells into
2732 their originally assigned display areas. Bytes 0 and 1 of the sprm contain
2733 the opcode. Byte 2 contains the index of the first cell that is to be split,
2734 call it itcFirst. Byte 3 contains the index of the cell that follows the
2735 last cell to be split, call it itcLim.
2736 
2737 This sprm clears
2738 tap.rgtc[].fFirstMerged and tap.rgtc[].fMerged for all rgtc entries >=
2739 itcFirst and < itcLim. sprmTSplit is stored only in grpprls linked to piece
2740 table entries.
2741 */
2742 void
wvApplysprmTSplit(TAP * aTap,U8 * pointer,U16 * pos)2743 wvApplysprmTSplit (TAP * aTap, U8 * pointer, U16 * pos)
2744 {
2745     U8 itcFirst = dread_8ubit (NULL, &pointer);
2746     U8 itcLim = dread_8ubit (NULL, &pointer);
2747     int i;
2748     (*pos) += 2;
2749 
2750     for (i = itcFirst; i < itcLim; i++)
2751       {
2752 	  aTap->rgtc[i].fMerged = 0;
2753 	  aTap->rgtc[itcFirst].fFirstMerged = 0;
2754       }
2755 }
2756 
2757 /*
2758 This is guess based upon SetBrc
2759 */
2760 void
wvApplysprmTSetBrc10(TAP * aTap,U8 * pointer,U16 * pos)2761 wvApplysprmTSetBrc10 (TAP * aTap, U8 * pointer, U16 * pos)
2762 {
2763     U8 itcFirst, itcLim, len, temp8;
2764     BRC10 abrc;
2765     int i;
2766     len = dread_8ubit (NULL, &pointer);
2767     itcFirst = dread_8ubit (NULL, &pointer);
2768     itcLim = dread_8ubit (NULL, &pointer);
2769     temp8 = dread_8ubit (NULL, &pointer);
2770     (*pos) += 3;
2771     (*pos) += wvGetBRC10FromBucket (&abrc, pointer);
2772 
2773     for (i = itcFirst; i < itcLim; i++)
2774       {
2775 	  if (temp8 & 0x08)
2776 	      wvConvertBRC10ToBRC (&aTap->rgtc[i].brcRight, &abrc);
2777 	  if (temp8 & 0x04)
2778 	      wvConvertBRC10ToBRC (&aTap->rgtc[i].brcBottom, &abrc);
2779 	  if (temp8 & 0x02)
2780 	      wvConvertBRC10ToBRC (&aTap->rgtc[i].brcLeft, &abrc);
2781 	  if (temp8 & 0x01)
2782 	      wvConvertBRC10ToBRC (&aTap->rgtc[i].brcTop, &abrc);
2783       }
2784 }
2785 
2786 /*
2787 sprmTSetShd (opcode 0x7627) allows the shading definitions(SHDs) within a
2788 tap to be set to new values. Bytes 0 and 1 of the sprm contain the opcode.
2789 Byte 2 contains the index of the first cell whose shading is to be changed,
2790 call it itcFirst. Byte 3 contains the index of the cell that follows the
2791 last cell whose shading is to be changed, call it itcLim. Bytes 4 and 5
2792 contain the SHD structure, call it shd. This sprm causes the itcLim -
2793 itcFirst entries of tap.rgshd to be set to shd. sprmTSetShd is stored only
2794 in grpprls linked to piece table entries.
2795 */
2796 void
wvApplysprmTSetShd(TAP * aTap,U8 * pointer,U16 * pos)2797 wvApplysprmTSetShd (TAP * aTap, U8 * pointer, U16 * pos)
2798 {
2799     U8 itcFirst = dread_8ubit (NULL, &pointer);
2800     U8 itcLim = dread_8ubit (NULL, &pointer);
2801     int i;
2802     SHD shd;
2803     (*pos) += 2;
2804 
2805     wvGetSHDFromBucket (&shd, pointer);
2806     (*pos) += cbSHD;
2807 
2808     for (i = itcFirst; i < itcLim; i++)
2809 	wvCopySHD (&aTap->rgshd[i], &shd);
2810 }
2811 
2812 /*
2813 sprmTSetShdOdd (opcode 0x7628) is identical to sprmTSetShd, but it only
2814 changes the rgshd for odd indices between itcFirst and. sprmTSetShdOdd is
2815 stored only in grpprls linked to piece table entries.
2816 */
2817 void
wvApplysprmTSetShdOdd(TAP * aTap,U8 * pointer,U16 * pos)2818 wvApplysprmTSetShdOdd (TAP * aTap, U8 * pointer, U16 * pos)
2819 {
2820     U8 itcFirst = dread_8ubit (NULL, &pointer);
2821     U8 itcLim = dread_8ubit (NULL, &pointer);
2822     int i;
2823     SHD shd;
2824     (*pos) += 2;
2825 
2826     wvGetSHDFromBucket (&shd, pointer);
2827     (*pos) += cbSHD;
2828 
2829     for (i = itcFirst; i < itcLim; i++)
2830       {
2831 	  if ((i / 2) != (i + 1) / 2)
2832 	      wvCopySHD (&aTap->rgshd[i], &shd);
2833       }
2834 }
2835 
2836 /* guess */
2837 void
wvApplysprmTTextFlow(TAP * aTap,U8 * pointer,U16 * pos)2838 wvApplysprmTTextFlow (TAP * aTap, U8 * pointer, U16 * pos)
2839 {
2840     U8 val = dread_8ubit (NULL, &pointer);
2841     int i;
2842     (*pos)++;
2843 
2844     for (i = 0; i < aTap->itcMac; i++)
2845       {
2846 	  /* just a complete guess who knows */
2847 	  aTap->rgtc[i].fVertical = val & 0x0001;
2848 	  aTap->rgtc[i].fBackward = (val & 0x0002) >> 1;
2849 	  aTap->rgtc[i].fRotateFont = (val & 0x0004) >> 2;
2850       }
2851 }
2852 
2853 /*
2854 sprmTVertMerge (opcode 0xD62B) changes the vertical cell merge properties
2855 for a cell in the tap.rgtc[]. Bytes 0 and 1 of the sprm contain the opcode.
2856 Byte 2 contains the index of the cell whose vertical cell merge properties
2857 are to be changed. Byte 3 codes the new vertical cell merge properties for
2858 the cell, a 0 clears both fVertMerge and fVertRestart, a 1 sets fVertMerge
2859 and clears fVertRestart, and a 3 sets both flags. sprmTVertMerge is stored
2860 only in grpprls linked to piece table entries.
2861 */
2862 void
wvApplysprmTVertMerge(TAP * aTap,U8 * pointer,U16 * pos)2863 wvApplysprmTVertMerge (TAP * aTap, U8 * pointer, U16 * pos)
2864 {
2865     U8 index, props, count;
2866     wvTrace (("doing Vertical merge\n"));
2867 
2868     count = dread_8ubit (NULL, &pointer);
2869     wvTrace (("count is %d\n", count));	/* check against word 8 please */
2870     index = dread_8ubit (NULL, &pointer);
2871     props = dread_8ubit (NULL, &pointer);
2872     (*pos) += 3;
2873 
2874     switch (props)
2875       {
2876       case 0:
2877 	  aTap->rgtc[index].fVertMerge = 0;
2878 	  aTap->rgtc[index].fVertRestart = 0;
2879 	  break;
2880       case 1:
2881 	  aTap->rgtc[index].fVertMerge = 1;
2882 	  aTap->rgtc[index].fVertRestart = 0;
2883 	  break;
2884       case 3:
2885 	  aTap->rgtc[index].fVertMerge = 1;
2886 	  aTap->rgtc[index].fVertRestart = 1;
2887 	  break;
2888       }
2889 }
2890 
2891 /*
2892 sprmTVertAlign (opcode 0xD62C) changes the vertical alignment property in
2893 the tap.rgtc[]. Bytes 0 and 1 of the sprm contain the opcode. Byte 2
2894 contains the index of the first cell whose shading is to be changed, call it
2895 itcFirst. Byte 3 contains the index of the cell that follows the last cell
2896 whose shading is to be changed, call it itcLim. This sprm causes the
2897 vertAlign properties of the itcLim - itcFirst entries of tap.rgtc[] to be
2898 set to the new vertical alignment property contained in Byte 4.
2899 sprmTVertAlign is stored only in grpprls linked to piece table entries.
2900 */
2901 void
wvApplysprmTVertAlign(TAP * aTap,U8 * pointer,U16 * pos)2902 wvApplysprmTVertAlign (TAP * aTap, U8 * pointer, U16 * pos)
2903 {
2904     U8 itcFirst = dread_8ubit (NULL, &pointer);
2905     U8 itcLim = dread_8ubit (NULL, &pointer);
2906     U8 props = dread_8ubit (NULL, &pointer);
2907     int i;
2908     (*pos) += 3;
2909 
2910     for (i = itcFirst; i < itcLim; i++)
2911 	aTap->rgtc[i].vertAlign = props;
2912 }
2913 
2914 SprmName rgsprmPrm[0x80] =
2915     { sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmPIncLvl, sprmPJc,
2916     sprmPFSideBySide, sprmPFKeep, sprmPFKeepFollow, sprmPFPageBreakBefore,
2917     sprmPBrcl, sprmPBrcp, sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop,
2918     sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2919     sprmNoop, sprmPFInTable, sprmPFTtp, sprmNoop, sprmNoop, sprmNoop, sprmPPc,
2920     sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2921     sprmPWr, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2922     sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2923     sprmPFLocked, sprmPFWidowControl, sprmNoop, sprmPFKinsoku, sprmPFWordWrap,
2924     sprmPFOverflowPunct, sprmPFTopLinePunct, sprmPFAutoSpaceDE,
2925     sprmPFAutoSpaceDN, sprmNoop, sprmNoop, sprmPISnapBaseLine, sprmNoop,
2926     sprmNoop, sprmNoop, sprmCFStrikeRM, sprmCFRMark, sprmCFFldVanish,
2927     sprmNoop,
2928     sprmNoop, sprmNoop, sprmCFData, sprmNoop, sprmNoop, sprmNoop, sprmCFOle2,
2929     sprmNoop, sprmCHighlight, sprmCFEmboss, sprmCSfxText, sprmNoop, sprmNoop,
2930     sprmNoop, sprmCPlain, sprmNoop, sprmCFBold, sprmCFItalic, sprmCFStrike,
2931     sprmCFOutline, sprmCFShadow, sprmCFSmallCaps, sprmCFCaps, sprmCFVanish,
2932     sprmNoop, sprmCKul, sprmNoop, sprmNoop, sprmNoop, sprmCIco, sprmNoop,
2933     sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop, sprmCIss, sprmNoop,
2934     sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2935     sprmNoop, sprmNoop, sprmCFDStrike, sprmCFImprint, sprmCFSpec, sprmCFObj,
2936     sprmPicBrcl, sprmPOutLvl, sprmNoop, sprmNoop, sprmNoop, sprmNoop,
2937     sprmNoop,
2938     sprmPPnbrRMarkNot
2939 };
2940 
2941 SprmName
wvGetrgsprmPrm(U16 in)2942 wvGetrgsprmPrm (U16 in)
2943 {
2944     if (in > 0x80)
2945       {
2946 	  wvError (("Impossible rgsprmPrm value\n"));
2947 	  return (sprmNoop);
2948       }
2949     return (rgsprmPrm[in]);
2950 }
2951 
2952 
2953 SprmName rgsprmWord6[256] = {
2954     sprmNoop /*          0 */ ,
2955     sprmNoop /*                  1 */ ,
2956     sprmPIstd /*         2 */ ,
2957     sprmPIstdPermute /*  3 */ ,
2958     sprmPIncLvl /*       4 */ ,
2959     sprmPJc /*           5 */ ,
2960     sprmPFSideBySide /*  6 */ ,
2961     sprmPFKeep /*        7 */ ,
2962     sprmPFKeepFollow /*  8 */ ,
2963     sprmPFPageBreakBefore /*  9 */ ,	/* added F */
2964     sprmPBrcl /*         10 */ ,
2965     sprmPBrcp /*         11 */ ,
2966     sprmPAnld /*         12 */ ,
2967     sprmPNLvlAnm /*      13 */ ,
2968     sprmPFNoLineNumb /*  14 */ ,
2969     sprmPChgTabsPapx /*  15 */ ,
2970     sprmPDxaRight /*     16 */ ,
2971     sprmPDxaLeft /*      17 */ ,
2972     sprmPNest /*         18 */ ,
2973     sprmPDxaLeft1 /*     19 */ ,
2974     sprmPDyaLine /*      20 */ ,
2975     sprmPDyaBefore /*    21 */ ,
2976     sprmPDyaAfter /*     22 */ ,
2977     sprmPChgTabs /*      23 */ ,
2978     sprmPFInTable /*     24 */ ,
2979     sprmPFTtp /*         25 */ ,	/* added F */
2980     sprmPDxaAbs /*       26 */ ,
2981     sprmPDyaAbs /*       27 */ ,
2982     sprmPDxaWidth /*     28 */ ,
2983     sprmPPc /*           29 */ ,
2984     sprmPBrcTop10 /*     30 */ ,
2985     sprmPBrcLeft10 /*    31 */ ,
2986     sprmPBrcBottom10 /*  32 */ ,
2987     sprmPBrcRight10 /*   33 */ ,
2988     sprmPBrcBetween10 /* 34 */ ,
2989     sprmPBrcBar10 /*     35 */ ,
2990     sprmPDxaFromText10 /*   36 */ ,	/* new name */
2991     sprmPWr /*           37 */ ,
2992     sprmPBrcTop /*       38 */ ,
2993     sprmPBrcLeft /*      39 */ ,
2994     sprmPBrcBottom /*    40 */ ,
2995     sprmPBrcRight /*     41 */ ,
2996     sprmPBrcBetween /*   42 */ ,
2997     sprmPBrcBar /*       43 */ ,
2998     sprmPFNoAutoHyph /*  44 */ ,
2999     sprmPWHeightAbs /*   45 */ ,
3000     sprmPDcs /*          46 */ ,
3001     sprmPShd /*          47 */ ,
3002     sprmPDyaFromText /*  48 */ ,
3003     sprmPDxaFromText /*  49 */ ,
3004     sprmPFLocked /*      50 */ ,
3005     sprmPFWidowControl /*  51 */ ,
3006     sprmNoop /*          52 */ ,
3007     sprmNoop /*          53 */ ,
3008     sprmNoop /*          54 */ ,
3009     sprmNoop /*          55 */ ,
3010     sprmNoop /*          56 */ ,
3011     sprmPUNKNOWN2 /*     57 */ ,
3012     sprmPUNKNOWN3 /*     58 */ ,
3013     sprmPUNKNOWN4 /*     59 */ ,
3014     sprmNoop /*          60 */ ,
3015     sprmNoop /*          61 */ ,
3016     sprmNoop /*          62 */ ,
3017     sprmNoop /*          63 */ ,
3018     sprmNoop /*          64 */ ,
3019     sprmCFStrikeRM /*    65 */ ,
3020     sprmCFRMark /*       66 */ ,
3021     sprmCFFldVanish /*   67 */ ,
3022     sprmCPicLocation /*  68 */ ,
3023     sprmCIbstRMark /*    69 */ ,
3024     sprmCDttmRMark /*    70 */ ,
3025     sprmCFData /*        71 */ ,
3026     sprmCIdslRMark /*     72 */ ,	/* new name */
3027     sprmCChs /*         73 */ ,	/* new name */
3028     sprmCSymbol /*       74 */ ,
3029     sprmCFOle2 /*        75 */ ,
3030     sprmNoop /*          76 */ ,
3031     sprmNoop /*          77 */ ,
3032     sprmNoop /*          78 */ ,
3033     sprmNoop /*          79 */ ,
3034     sprmCIstd /*         80 */ ,
3035     sprmCIstdPermute /*  81 */ ,
3036     sprmCDefault /*      82 */ ,
3037     sprmCPlain /*        83 */ ,
3038     sprmNoop /*          84 */ ,
3039     sprmCFBold /*        85 */ ,
3040     sprmCFItalic /*      86 */ ,
3041     sprmCFStrike /*      87 */ ,
3042     sprmCFOutline /*     88 */ ,
3043     sprmCFShadow /*      89 */ ,
3044     sprmCFSmallCaps /*   90 */ ,
3045     sprmCFCaps /*        91 */ ,
3046     sprmCFVanish /*      92 */ ,
3047     sprmCFtc /*          93 */ ,
3048     sprmCKul /*          94 */ ,
3049     sprmCSizePos /*      95 */ ,
3050     sprmCDxaSpace /*     96 */ ,
3051     sprmCLid /*          97 */ ,
3052     sprmCIco /*          98 */ ,
3053     sprmCHps /*          99 */ ,
3054     sprmCHpsInc /*       100 */ ,
3055     sprmCHpsPos /*       101 */ ,
3056     sprmCHpsPosAdj /*    102 */ ,
3057     sprmCMajority /*     103 */ ,
3058     sprmCIss /*          104 */ ,
3059     sprmCHpsNew50 /*     105 */ ,
3060     sprmCHpsInc1 /*      106 */ ,
3061     sprmCHpsKern /*      107 */ ,
3062     sprmCMajority50 /*   108 */ ,
3063     sprmCHpsMul /*       109 */ ,
3064     sprmCYsri /*             110 */ ,	/* new name */
3065     sprmCUNKNOWN5 /*     111 */ ,
3066     sprmCUNKNOWN6 /*     112 */ ,
3067     sprmCUNKNOWN7 /*     113 */ ,
3068     sprmNoop /*          114 */ ,
3069     sprmNoop /*          115 */ ,
3070     sprmNoop /*          116 */ ,
3071     sprmCFSpec /*        117 */ ,
3072     sprmCFObj /*         118 */ ,
3073     sprmPicBrcl /*       119 */ ,
3074     sprmPicScale /*      120 */ ,
3075     sprmPicBrcTop /*     121 */ ,
3076     sprmPicBrcLeft /*    122 */ ,
3077     sprmPicBrcBottom /*  123 */ ,
3078     sprmPicBrcRight /*   124 */ ,
3079     sprmNoop /*          125 */ ,
3080     sprmNoop /*          126 */ ,
3081     sprmNoop /*          127 */ ,
3082     sprmNoop /*          128 */ ,
3083     sprmNoop /*          129 */ ,
3084     sprmNoop /*          130 */ ,
3085     sprmScnsPgn /*           131 */ ,	/* new name */
3086     sprmSiHeadingPgn /*  132 */ ,
3087     sprmSOlstAnm /*      133 */ ,
3088     sprmNoop /*          134 */ ,
3089     sprmNoop /*          135 */ ,
3090     sprmSDxaColWidth /*  136 */ ,
3091     sprmSDxaColWidth /*  137 */ ,	/* new name */
3092     sprmSFEvenlySpaced /*138 */ ,
3093     sprmSFProtected /*   139 */ ,
3094     sprmSDmBinFirst /*   140 */ ,
3095     sprmSDmBinOther /*   141 */ ,
3096     sprmSBkc /*          142 */ ,
3097     sprmSFTitlePage /*   143 */ ,
3098     sprmSCcolumns /*     144 */ ,
3099     sprmSDxaColumns /*   145 */ ,
3100     sprmSFAutoPgn /*     146 */ ,
3101     sprmSNfcPgn /*       147 */ ,
3102     sprmSDyaPgn /*       148 */ ,
3103     sprmSDxaPgn /*       149 */ ,
3104     sprmSFPgnRestart /*  150 */ ,
3105     sprmSFEndnote /*     151 */ ,
3106     sprmSLnc /*          152 */ ,
3107     sprmSGprfIhdt /*     153 */ ,
3108     sprmSNLnnMod /*      154 */ ,
3109     sprmSDxaLnn /*       155 */ ,
3110     sprmSDyaHdrTop /*    156 */ ,
3111     sprmSDyaHdrBottom /* 157 */ ,
3112     sprmNoop /*          158 */ ,
3113     sprmSVjc /*          159 */ ,
3114     sprmSLnnMin /*       160 */ ,
3115     sprmSPgnStart /*     161 */ ,
3116     sprmSBOrientation /* 162 */ ,
3117     sprmSBCustomize /*   163 */ ,
3118     sprmSXaPage /*       164 */ ,
3119     sprmSYaPage /*       165 */ ,
3120     sprmSDxaLeft /*      166 */ ,
3121     sprmSDxaRight /*     167 */ ,
3122     sprmSDyaTop /*       168 */ ,
3123     sprmSDyaBottom /*    169 */ ,
3124     sprmSDzaGutter /*    170 */ ,
3125     sprmSDmPaperReq /*   171 */ ,
3126     sprmNoop /*          172 */ ,
3127     sprmNoop /*          173 */ ,
3128     sprmNoop /*          174 */ ,
3129     sprmNoop /*          175 */ ,
3130     sprmNoop /*          176 */ ,
3131     sprmNoop /*          177 */ ,
3132     sprmNoop /*          178 */ ,
3133     sprmNoop /*          179 */ ,
3134     sprmNoop /*          180 */ ,
3135     sprmNoop /*          181 */ ,
3136     sprmTJc /*           182 */ ,
3137     sprmTDxaLeft /*      183 */ ,
3138     sprmTDxaGapHalf /*   184 */ ,
3139     sprmTFCantSplit /*   185 */ ,
3140     sprmTTableHeader /*  186 */ ,
3141     sprmTTableBorders /* 187 */ ,
3142     sprmTDefTable10 /*   188 */ ,
3143     sprmTDyaRowHeight /* 189 */ ,
3144     sprmTDefTable /*     190 */ ,
3145     sprmTDefTableShd /*  191 */ ,
3146     sprmTTlp /*          192 */ ,
3147     sprmTSetBrc /*       193 */ ,
3148     sprmTInsert /*       194 */ ,
3149     sprmTDelete /*       195 */ ,
3150     sprmTDxaCol /*       196 */ ,
3151     sprmTMerge /*        197 */ ,
3152     sprmTSplit /*        198 */ ,
3153     sprmTSetBrc10 /*     199 */ ,
3154     sprmTSetShd /*       200 */ ,
3155     sprmNoop /*          201 */ ,
3156     sprmNoop /*          202 */ ,
3157     sprmNoop /*          203 */ ,
3158 
3159     sprmTUNKNOWN1 /*    204 */ ,
3160     /*guess I know that this should be either
3161      * a) 3 bytes long,
3162      * b) complex with a len of 2,
3163      * its certainly a table related sprm, my guess is sprmTVertMerge
3164      * as that fits its profile, but it isn't working in practice.
3165      * */
3166 #if 0
3167     sprmNoop /*          205 */ ,
3168     sprmNoop /*          206 */ ,
3169     sprmNoop /*          207 */ ,
3170     sprmMax			/*           208 */
3171 #endif
3172 };
3173 
3174 SprmName
wvGetrgsprmWord6(U8 in)3175 wvGetrgsprmWord6 (U8 in)
3176 {
3177     return (rgsprmWord6[in]);
3178 }
3179