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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include "wv.h"
28 #include "bintree.h"
29 
30 /*
31  * To apply a UPX.chpx to a UPE.chp, apply the UPX.chpx.grpprl to
32  * UPE.chp. Note that a UPE.chp for a paragraph style should always have
33  * UPE.chp.istd == istdNormalChar.
34  */
35 void
wvAddCHPXFromBucket(CHP * achp,UPXF * upxf,STSH * stsh)36 wvAddCHPXFromBucket (CHP * achp, UPXF * upxf, STSH * stsh)
37 {
38     U8 *pointer;
39     U16 i = 0;
40     U16 sprm;
41 
42 #ifdef SPRMTEST
43     fprintf (stderr, "\n");
44     while (i < upxf->cbUPX)
45       {
46 	  fprintf (stderr, "%x (%d) ", *(upxf->upx.chpx.grpprl + i),
47 		   *(upxf->upx.chpx.grpprl + i));
48 	  i++;
49       }
50     fprintf (stderr, "\n");
51     i = 0;
52 #endif
53     while (i + 2 < upxf->cbUPX) /* is this check sufficient ?? */
54       {
55 	  sprm = bread_16ubit (upxf->upx.chpx.grpprl + i, &i);
56 #ifdef SPRMTEST
57 	  wvError (("sprm is %x, i is %d\n", sprm, i));
58 #endif
59 	  pointer = upxf->upx.chpx.grpprl + i;
60 	  wvApplySprmFromBucket (WORD8, sprm, NULL, achp, NULL, stsh, pointer,
61 				 &i, NULL);
62       }
63 }
64 
65 void
wvApplyCHPXFromBucket(CHP * achp,CHPX * chpx,STSH * stsh)66 wvApplyCHPXFromBucket (CHP * achp, CHPX * chpx, STSH * stsh)
67 {
68     U8 *pointer;
69     U16 i = 0;
70     U16 sprm;
71 #ifdef SPRMTEST
72     fprintf (stderr, "\n");
73     while (i < chpx->cbGrpprl)
74       {
75 	  fprintf (stderr, "%x (%d) ", *(chpx->grpprl + i),
76 		   *(chpx->grpprl + i));
77 	  i++;
78       }
79     fprintf (stderr, "\n");
80     i = 0;
81 #endif
82     while (i < chpx->cbGrpprl)
83       {
84 	  sprm = bread_16ubit (chpx->grpprl + i, &i);
85 	  wvTrace (("the sprm is %d\n", sprm));
86 	  pointer = chpx->grpprl + i;
87 	  wvApplySprmFromBucket (WORD8, sprm, NULL, achp, NULL, stsh, pointer,
88 				 &i, NULL);
89       }
90     achp->istd = chpx->istd;
91 }
92 
93 void
wvAddCHPXFromBucket6(CHP * achp,UPXF * upxf,STSH * stsh)94 wvAddCHPXFromBucket6 (CHP * achp, UPXF * upxf, STSH * stsh)
95 {
96     U8 *pointer;
97     U16 i = 0;
98     U8 sprm8;
99     U16 sprm;
100     wvTrace (("cbUPX word 6 is %d\n", upxf->cbUPX));
101 
102 #ifdef SPRMTEST
103     fprintf (stderr, "\n");
104     while (i < upxf->cbUPX)
105       {
106 	  fprintf (stderr, "%x (%d) ", *(upxf->upx.chpx.grpprl + i),
107 		   *(upxf->upx.chpx.grpprl + i));
108 	  i++;
109       }
110     fprintf (stderr, "\n");
111     i = 0;
112 #endif
113     while (i < upxf->cbUPX)
114       {
115 	  sprm8 = bread_8ubit (upxf->upx.chpx.grpprl + i, &i);
116 #ifdef SPRMTEST
117 	  wvError (("chp word 6 sprm is %x (%d)\n", sprm8, sprm8));
118 #endif
119 	  sprm = (U16) wvGetrgsprmWord6 (sprm8);
120 #ifdef SPRMTEST
121 	  wvError (("chp word 6 sprm is converted to %x\n", sprm));
122 #endif
123 
124 	  pointer = upxf->upx.chpx.grpprl + i;
125 	  wvApplySprmFromBucket (WORD6, sprm, NULL, achp, NULL, stsh, pointer,
126 				 &i, NULL);
127       }
128 }
129 
130 
131 void
wvInitCHPFromIstd(CHP * achp,U16 istdBase,STSH * stsh)132 wvInitCHPFromIstd (CHP * achp, U16 istdBase, STSH * stsh)
133 {
134     wvTrace (("initing from %d\n", istdBase));
135     if (istdBase == istdNil) {
136  	wvInitCHP (achp);
137 
138 	/* Set the Nil style's fonts from the defaults. */
139 	achp->ftcAscii = stsh->Stshi.rgftcStandardChpStsh[0];
140 	achp->ftcFE = stsh->Stshi.rgftcStandardChpStsh[1];
141 	achp->ftcOther = stsh->Stshi.rgftcStandardChpStsh[2];
142     }
143     else
144       {
145 	  if (istdBase >= stsh->Stshi.cstd)
146 	    {
147 		wvError (
148 			 ("ISTD out of bounds, requested %d of %d\n",
149 			  istdBase, stsh->Stshi.cstd));
150 		wvInitCHP (achp);	/*it can't hurt to try and start with a blank istd */
151 		return;
152 	    }
153 	  else
154 	    {
155 		if (stsh->std[istdBase].cupx == 0)	/*empty slot in the array, i don't think this should happen */
156 		  {
157 		      wvTrace (("Empty style slot used (chp)\n"));
158 		      wvInitCHP (achp);
159 		  }
160 		else
161 		  {
162 		      wvTrace (("type is %d\n", stsh->std[istdBase].sgc));
163 		      switch (stsh->std[istdBase].sgc)
164 			{
165 			case sgcPara:
166 			    wvCopyCHP (achp,
167 				       &(stsh->std[istdBase].grupe[1].achp));
168 			    break;
169 			case sgcChp:
170 			    wvInitCHP (achp);
171 			    wvApplyCHPXFromBucket (achp,
172 						   &(stsh->std[istdBase].
173 						     grupe[0].chpx), stsh);
174 				strncpy(achp->stylename,stsh->std[istdBase].xstzName, sizeof(achp->stylename));
175 			    break;
176 			}
177 		  }
178 	    }
179       }
180 
181 }
182 
183 
184 
185 /*
186 The standard CHP is all zeros except:
187 
188 hps               20 half-points
189 fcPic             -1
190 istd              10 (the standard character style)
191 lidDefault, lidFE 0x0400 (no proofing)
192 wCharScale        100
193 fUsePgsuSettings  -1
194 */
195 
196 void
wvInitCHP(CHP * item)197 wvInitCHP (CHP * item)
198 {
199     int i;
200 
201     item->fBold = 0;
202     item->fItalic = 0;
203     item->fRMarkDel = 0;
204     item->fOutline = 0;
205     item->fFldVanish = 0;
206     item->fSmallCaps = 0;
207     item->fCaps = 0;
208     item->fVanish = 0;
209     item->fRMark = 0;
210     item->fSpec = 0;
211     item->fStrike = 0;
212     item->fObj = 0;
213     item->fShadow = 0;
214     item->fLowerCase = 0;
215     item->fData = 0;
216     item->fOle2 = 0;
217     item->fEmboss = 0;
218     item->fImprint = 0;
219     item->fDStrike = 0;
220     item->fUsePgsuSettings = -1;     /*-1 ? */
221     item->reserved1 = 0;
222     item->reserved2 = 0;
223     item->reserved11 = 0;
224     item->ftc = 0;
225     item->ftcAscii = 0;
226     item->ftcFE = 0;
227     item->ftcOther = 0;
228     item->hps = 20;
229     item->dxaSpace = 0;
230     item->iss = 0;
231     item->kul = 0;
232     item->fSpecSymbol = 0;
233     item->ico = 0;
234     item->reserved3 = 0;
235     item->fSysVanish = 0;
236     item->hpsPos = 0;
237     item->super_sub = 0;
238     item->lid = 0;
239     item->lidDefault = 0x0400;
240     item->lidFE = 0x0400;
241     item->idct = 0;
242     item->idctHint = 0;
243     item->wCharScale = 100;
244     item->fcPic_fcObj_lTagObj = -1;
245     item->ibstRMark = 0;
246     item->ibstRMarkDel = 0;
247 
248     wvInitDTTM (&item->dttmRMark);
249     wvInitDTTM (&item->dttmRMarkDel);
250 
251     item->reserved4 = 0;
252     item->istd = istdNormalChar;
253     item->ftcSym = 0;
254     item->xchSym = 0;
255     item->idslRMReason = 0;
256     item->idslReasonDel = 0;
257     item->ysr = 0;
258     item->chYsr = 0;
259     item->cpg = 0;
260     item->hpsKern = 0;
261     item->icoHighlight = 0;
262     item->fHighlight = 0;
263     item->kcd = 0;
264     item->fNavHighlight = 0;
265     item->fChsDiff = 0;
266     item->fMacChs = 0;
267     item->fFtcAsciSym = 0;
268     item->reserved5 = 0;
269     item->fPropRMark = 0;
270     item->ibstPropRMark = 0;
271 
272     wvInitDTTM (&item->dttmPropRMark);
273 
274     item->sfxtText = 0;
275     item->reserved6 = 0;
276     item->reserved7 = 0;
277     item->reserved8 = 0;
278     item->reserved9 = 0;
279 
280     wvInitDTTM (&item->reserved10);
281 
282     item->fDispFldRMark = 0;
283     item->ibstDispFldRMark = 0;
284 
285     wvInitDTTM (&item->dttmDispFldRMark);
286 
287     for (i = 0; i < 16; i++)
288 	item->xstDispFldRMark[i] = 0;
289 
290     wvInitSHD (&item->shd);
291 
292     wvInitBRC (&item->brc);
293 
294     /* bidi */
295     item->fBidi = 0;
296     item->fBoldBidi = 0;
297     item->fItalicBidi = 0;
298     item->ftcBidi = 0;
299     item->hpsBidi = 0;
300     item->icoBidi = 0;
301     item->lidBidi = 0;
302 
303 	item->stylename[0] = 0;
304 }
305 
306 void
wvCopyCHP(CHP * dest,CHP * src)307 wvCopyCHP (CHP * dest, CHP * src)
308 {
309     int i;
310 
311     dest->fBold = src->fBold;
312     dest->fItalic = src->fItalic;
313     dest->fRMarkDel = src->fRMarkDel;
314     dest->fOutline = src->fOutline;
315     dest->fFldVanish = src->fFldVanish;
316     dest->fSmallCaps = src->fSmallCaps;
317     dest->fCaps = src->fCaps;
318     dest->fVanish = src->fVanish;
319     dest->fRMark = src->fRMark;
320     dest->fSpec = src->fSpec;
321     dest->fStrike = src->fStrike;
322     dest->fObj = src->fObj;
323     dest->fShadow = src->fShadow;
324     dest->fLowerCase = src->fLowerCase;
325     dest->fData = src->fData;
326     dest->fOle2 = src->fOle2;
327     dest->fEmboss = src->fEmboss;
328     dest->fImprint = src->fImprint;
329     dest->fDStrike = src->fDStrike;
330     dest->fUsePgsuSettings = src->fUsePgsuSettings;
331     dest->reserved1 = src->reserved1;
332     dest->reserved2 = src->reserved2;
333     dest->reserved11 = src->reserved11;
334     dest->ftc = src->ftc;
335     dest->ftcAscii = src->ftcAscii;
336     dest->ftcFE = src->ftcFE;
337     dest->ftcOther = src->ftcOther;
338     dest->hps = src->hps;
339     dest->dxaSpace = src->dxaSpace;
340     dest->iss = src->iss;
341     dest->kul = src->kul;
342     dest->fSpecSymbol = src->fSpecSymbol;
343     dest->ico = src->ico;
344     dest->reserved3 = src->reserved3;
345     dest->fSysVanish = src->fSysVanish;
346     dest->hpsPos = src->hpsPos;
347     dest->super_sub = src->super_sub;
348     dest->lid = src->lid;
349     dest->lidDefault = src->lidDefault;
350     dest->lidFE = src->lidFE;
351     dest->idct = src->idct;
352     dest->idctHint = src->idctHint;
353     dest->wCharScale = src->wCharScale;
354     dest->fcPic_fcObj_lTagObj = src->fcPic_fcObj_lTagObj;
355     dest->ibstRMark = src->ibstRMark;
356     dest->ibstRMarkDel = src->ibstRMarkDel;
357 
358     wvCopyDTTM (&dest->dttmRMark, &src->dttmRMark);
359     wvCopyDTTM (&dest->dttmRMarkDel, &src->dttmRMarkDel);
360 
361     dest->reserved4 = src->reserved4;
362     dest->istd = src->istd;
363     dest->ftcSym = src->ftcSym;
364     dest->xchSym = src->xchSym;
365     dest->idslRMReason = src->idslRMReason;
366     dest->idslReasonDel = src->idslReasonDel;
367     dest->ysr = src->ysr;
368     dest->chYsr = src->chYsr;
369     dest->cpg = src->cpg;
370     dest->hpsKern = src->hpsKern;
371     dest->icoHighlight = src->icoHighlight;
372     dest->fHighlight = src->fHighlight;
373     dest->kcd = src->kcd;
374     dest->fNavHighlight = src->fNavHighlight;
375     dest->fChsDiff = src->fChsDiff;
376     dest->fMacChs = src->fMacChs;
377     dest->fFtcAsciSym = src->fFtcAsciSym;
378     dest->reserved5 = src->reserved5;
379     dest->fPropRMark = src->fPropRMark;
380     dest->ibstPropRMark = src->ibstPropRMark;
381 
382     wvCopyDTTM (&dest->dttmPropRMark, &src->dttmPropRMark);
383 
384     dest->sfxtText = src->sfxtText;
385     dest->reserved6 = src->reserved6;
386     dest->reserved7 = src->reserved7;
387     dest->reserved8 = src->reserved8;
388     dest->reserved9 = src->reserved9;
389 
390     wvCopyDTTM (&dest->reserved10, &src->reserved10);
391 
392     dest->fDispFldRMark = src->fDispFldRMark;
393     dest->ibstDispFldRMark = src->ibstDispFldRMark;
394 
395     wvCopyDTTM (&dest->dttmDispFldRMark, &src->dttmDispFldRMark);
396 
397     for (i = 0; i < 16; i++)
398 	dest->xstDispFldRMark[i] = src->xstDispFldRMark[i];
399 
400     wvCopySHD (&dest->shd, &src->shd);
401 
402     wvCopyBRC (&dest->brc, &src->brc);
403 
404     /* bidi */
405     dest->fBidi = src->fBidi;
406     dest->fBoldBidi = src->fBoldBidi;
407     dest->fItalicBidi = src->fItalicBidi;
408     dest->ftcBidi = src->ftcBidi;
409     dest->hpsBidi = src->hpsBidi;
410     dest->icoBidi = src->icoBidi;
411     dest->lidBidi = src->lidBidi;
412 
413 	strcpy(dest->stylename,src->stylename);
414 }
415 
416 /*
417  * The chpx for the null style has an istd of zero, a cbGrpprl of zero
418  * (and an empty grpprl) this only exists in the UPD/UPE
419  */
420 void
wvInitCHPX(CHPX * item)421 wvInitCHPX (CHPX * item)
422 {
423     item->istd = 0;
424     item->cbGrpprl = 0;
425     item->grpprl = NULL;
426 }
427 
428 /*
429  * For a character style, the UPE.chpx can be constructed by starting with
430  * the first UPE from the based-on style (std.istdBase).
431 */
432 void
wvInitCHPXFromIstd(CHPX * chpx,U16 istdBase,STSH * stsh)433 wvInitCHPXFromIstd (CHPX * chpx, U16 istdBase, STSH * stsh)
434 {
435     if (istdBase == istdNil)
436 	wvInitCHPX (chpx);
437     else
438       {
439 	  if (istdBase >= stsh->Stshi.cstd)
440 	    {
441 		wvError (
442 			 ("ISTD out of bounds, requested %d of %d\n",
443 			  istdBase, stsh->Stshi.cstd));
444 		wvInitCHPX (chpx);	/*it can't hurt to try and start with a blank istd */
445 		return;
446 	    }
447 	  else
448 	      wvCopyCHPX (chpx, &(stsh->std[istdBase].grupe[0].chpx));
449       }
450 }
451 
452 void
wvCopyCHPX(CHPX * dest,CHPX * src)453 wvCopyCHPX (CHPX * dest, CHPX * src)
454 {
455     int i;
456     dest->istd = src->istd;
457     dest->cbGrpprl = src->cbGrpprl;
458     if (dest->cbGrpprl)
459 	dest->grpprl = (U8 *) wvMalloc (dest->cbGrpprl);
460     else
461 	dest->grpprl = NULL;
462     if (dest->grpprl == NULL || src->grpprl == NULL)
463 	return;
464     for (i = 0; i < dest->cbGrpprl; i++)
465 	dest->grpprl[i] = src->grpprl[i];
466 }
467 
468 void
wvReleaseCHPX(CHPX * item)469 wvReleaseCHPX (CHPX * item)
470 {
471     wvFree (item->grpprl);
472 }
473 
474 int
wvCompLT(void * a,void * b)475 wvCompLT (void *a, void *b)
476 {
477     U8 *a2, *b2;
478     U16 sprm1, sprm2;
479     a2 = (U8 *) a;
480     b2 = (U8 *) b;
481     sprm1 = sread_16ubit (a2);
482     sprm2 = sread_16ubit (b2);
483     return (sprm1 < sprm2);
484 }
485 
486 int
wvCompEQ(void * a,void * b)487 wvCompEQ (void *a, void *b)
488 {
489     U8 *a2, *b2;
490     U16 sprm1, sprm2;
491     a2 = (U8 *) a;
492     b2 = (U8 *) b;
493     sprm1 = sread_16ubit (a2);
494     sprm2 = sread_16ubit (b2);
495     return (sprm1 == sprm2);
496 }
497 
498 
499 /*
500 Apply the first UPX (UPX.chpx) in std.grupx to the UPE.
501 
502 To apply a UPX.chpx to a UPE.chpx, take the grpprl in UPE.chpx.grpprl (which
503 has a length of UPE.chpx.cbGrpprl) and merge the grpprl in UPX.chpx.grpprl
504 into it.
505 
506 Merging grpprls is a tricky business, but for character styles it is easy
507 because no prls in character style grpprls should interact with each other.
508 Each prl from the source (the UPX.chpx.grpprl) should be inserted into the
509 destination (the UPE.chpx.grpprl) so that the sprm of each prl is in increasing
510 order, and any prls that have the same sprm are replaced by the prl in the
511 source.
512 
513 UPE.chpx.cbGrpprl is then set to the length of resulting grpprl, and
514 UPE.chpx.istd is set to the style's istd.
515 */
516 void
wvMergeCHPXFromBucket(CHPX * dest,UPXF * src)517 wvMergeCHPXFromBucket (CHPX * dest, UPXF * src)
518 {
519     BintreeInfo tree;
520     Node *testn, *testp;
521     U16 i = 0, j;
522     U16 sprm;
523     U8 len = 0;
524     U8 temp;
525     Node *test = NULL;
526 
527     U8 *pointer, *dpointer;
528     U8 *grpprl = NULL;
529 
530     /*
531        use a binary tree ala the wmf stuff and first insert every dest sprm into it,
532        then insert every src sprm into it, take the full count and take them out of
533        the tree and create the list from them
534      */
535     InitBintree (&tree, wvCompLT, wvCompEQ);
536     pointer = dest->grpprl;
537 
538     while (i < dest->cbGrpprl)
539       {
540 	  wvTrace (("gotcha the sprm is %x\n", *((U16 *) pointer)));
541 	  test = InsertNode (&tree, (void *) pointer);
542 	  sprm = dread_16ubit (NULL, &pointer);
543 	  wvTrace (("the sprm is %x\n", sprm));
544 	  temp = wvEatSprm (sprm, pointer, &i);
545 	  pointer += temp;
546 	  i += 2;
547 	  if (test)
548 	      len += temp + 2;
549       }
550 
551     i = 0;
552     pointer = src->upx.chpx.grpprl;
553     i = 0;
554     while (i < src->cbUPX)
555       {
556 	  /*wvTrace(("gotcha 2 the sprm is %x\n",*((U16 *)pointer))); */
557 	  test = InsertNode (&tree, (void *) pointer);
558     if(!pointer)
559       break;
560 	  sprm = dread_16ubit (NULL, &pointer);
561 	  i += 2;
562 	  wvTrace (("the sprm is %x\n", sprm));
563 	  temp = wvEatSprm (sprm, pointer, &i);
564 	  wvTrace (("len of op is %d\n", temp));
565 	  pointer += temp;
566 	  wvTrace (("p dis is %d\n", pointer - src->upx.chpx.grpprl));
567 	  if (test)
568 	      len += temp + 2;
569       }
570 
571     if (len != 0)
572 	grpprl = (U8 *) wvMalloc (len);
573     else
574 	return;
575 
576 
577     dpointer = grpprl;
578 
579     testn = NextNode (&tree, NULL);
580     while (testn != NULL)
581       {
582 	  pointer = (U8 *) testn->Data;
583 	  sprm = sread_16ubit (pointer);
584 	  wvTrace (("methinks the sprm is %x\n", sprm));
585 	  pointer += 2;
586 
587 	  i = 0;
588 	  wvEatSprm (sprm, pointer, &i);
589 	  wvTrace (("i is now %d\n", i));
590 
591 	  pointer = (U8 *) testn->Data;
592 	  for (j = 0; j < i + 2; j++)
593 	      *dpointer++ = *pointer++;
594 
595 	  testp = NextNode (&tree, testn);
596 	  wvDeleteNode (&tree, testn);
597 	  testn = testp;
598       }
599     wvFree (dest->grpprl);
600     dest->grpprl = grpprl;
601     dest->cbGrpprl = len;
602 
603     /*test */
604     i = 0;
605     pointer = dest->grpprl;
606     while (i < dest->cbGrpprl)
607       {
608 	  sprm = dread_16ubit (NULL, &pointer);
609 	  wvTrace (("final test the sprm is %x\n", sprm));
610 	  temp = wvEatSprm (sprm, pointer, &i);
611 	  pointer += temp;
612 	  i += 2;
613 	  if (test)
614 	      len += temp + 2;
615       }
616 }
617 
618 
619 void
wvUpdateCHPXBucket(UPXF * src)620 wvUpdateCHPXBucket (UPXF * src)
621 {
622     U16 i = 0, j;
623     U16 sprm;
624     U8 sprm8;
625     U16 len = 0;
626     int temp;
627 
628     U8 *pointer, *dpointer;
629     U8 *grpprl = NULL;
630 
631     i = 0;
632     if (src->cbUPX == 0)
633 	return;
634     pointer = src->upx.chpx.grpprl;
635     wvTrace (("Msrc->cbUPX len is %d\n", src->cbUPX));
636     for (i = 0; i < src->cbUPX; i++)
637 	wvTrace (("%x\n", src->upx.chpx.grpprl[i]));
638     wvTrace (("Mend\n"));
639     i = 0;
640     len = 0;
641     while (i < src->cbUPX)
642       {
643 	  sprm8 = dread_8ubit (NULL, &pointer);
644 	  wvTrace (("Mpre the sprm is %x\n", sprm8));
645 	  sprm = (U16) wvGetrgsprmWord6 (sprm8);
646 	  wvTrace (("Mpost the sprm is %x\n", sprm));
647 	  i++;
648 	  len += 2;
649 	  temp = wvEatSprm (sprm, pointer, &i);
650 	  wvTrace (("Mlen of op is %d\n", temp));
651 	  pointer += temp;
652 	  wvTrace (("Mp dis is %d\n", pointer - src->upx.chpx.grpprl));
653 	  len += temp;
654       }
655     wvTrace (("Mlen ends up as %d\n", len));
656 
657     if (len == 0)
658 	return;
659 
660     grpprl = (U8 *) wvMalloc (len);
661 
662     dpointer = grpprl;
663 
664     i = 0;
665     pointer = src->upx.chpx.grpprl;
666     while (i < src->cbUPX)
667       {
668 	  sprm8 = dread_8ubit (NULL, &pointer);
669 	  sprm = (U16) wvGetrgsprmWord6 (sprm8);
670 	  i++;
671 	  *dpointer++ = (sprm & 0x00FF);
672 	  *dpointer++ = (sprm & 0xff00) >> 8;
673 	  temp = wvEatSprm (sprm, pointer, &i);
674 	  for (j = 0; j < temp; j++)
675 	      *dpointer++ = *pointer++;
676 	  wvTrace (("Mlen of op is %d\n", temp));
677       }
678     wvFree (src->upx.chpx.grpprl);
679     src->upx.chpx.grpprl = grpprl;
680     src->cbUPX = len;
681     for (i = 0; i < src->cbUPX; i++)
682 	wvTrace (("%x\n", src->upx.chpx.grpprl[i]));
683 }
684 
685 /*
686  * taken from wvAssembleSimplePAP in pap.c and modified
687  * to handle CHP's
688  * -JB
689  */
690 
691 int
wvAssembleSimpleCHP(wvVersion ver,CHP * achp,const PAP * apap,U32 fc,CHPX_FKP * fkp,STSH * stsh)692 wvAssembleSimpleCHP (wvVersion ver, CHP * achp, const PAP * apap, U32 fc, CHPX_FKP * fkp,
693 		     STSH * stsh)
694 {
695     CHPX *chpx;
696     int index;
697     UPXF upxf;
698     int ret = 0;
699     U16 tistd;
700 
701 
702     /* initialize CHP to para's stylesheet character properties this
703        * should have resolved all the other stylesheet dependencies
704        * for us, when the stsh's were initialized. */
705 
706 	wvInitCHPFromIstd (achp, apap->istd, stsh);
707 	/* having done this, we want to set the achp->istd to nil, since
708     any char istd value stored in the para style is not applicable
709     (its a para style */
710 	achp->istd = istdNil;
711 	tistd = istdNil;
712 
713  apply_chpx:
714 	/* get CHPX */
715 	if(fkp)
716 	{
717 		/* the PAPX version of the function only looks at rgfc's, which are
718 		 * the same for CHPX and PAPX FKPs, so we'll reuse the function */
719 		index = wvGetIndexFCInFKP_PAPX ((PAPX_FKP *) fkp, fc);
720 
721 		wvTrace (("index is %d, using %d\n", index, index - 1));
722 
723 		chpx = &(fkp->grpchpx[index - 1]);
724 
725 		/* apply CHPX from FKP */
726 		if ((chpx) && (chpx->cbGrpprl > 0))
727 		{
728 			ret = 1;
729 			/* for (i = 0; i < chpx->cbGrpprl; i++) */
730 			upxf.cbUPX = chpx->cbGrpprl;
731 			upxf.upx.chpx.grpprl = chpx->grpprl;
732 			if (ver == WORD8)
733 				wvAddCHPXFromBucket (achp, &upxf, stsh);
734 			else
735 				wvAddCHPXFromBucket6 (achp, &upxf, stsh);
736 		}
737 
738 		if(achp->istd < stsh->Stshi.cstd) {
739 		  if (0 != stsh->std[achp->istd].xstzName) {
740 		    strncpy(achp->stylename,stsh->std[achp->istd].xstzName, sizeof(achp->stylename));
741 		  }
742 		  else {
743 		    wvError (("trying to copy null string\n"));
744 		  }
745 		}
746 
747 		if(achp->istd != tistd)
748 		{
749 			/* the chpx contained instruction to apply character
750 			   style: we have to start all over again, since we init
751 			   the chp from the wrong (paragraph) style */
752 			tistd = achp->istd;
753 			wvInitCHPFromIstd (achp, achp->istd, stsh);
754 			goto apply_chpx;
755 		}
756 	}
757 
758     return (ret);
759 }
760 
761 
762 void
wvGetCHPX(wvVersion ver,CHPX * item,U8 * page,U16 * pos)763 wvGetCHPX (wvVersion ver, CHPX * item, U8 * page, U16 * pos)
764 {
765     U8 i;
766     item->cbGrpprl = bread_8ubit (&(page[*pos]), pos);
767     if (item->cbGrpprl > 0)
768       {
769 	  item->grpprl = (U8 *) wvMalloc (item->cbGrpprl);
770 	  memcpy (item->grpprl, &(page[*pos]), item->cbGrpprl);
771       }
772     else
773 	item->grpprl = NULL;
774 
775     item->istd = 0;		/* I have no idea what to set this to... --
776 						   nothing; the istd is contained in the grpprl*/
777 
778     for (i = 0; i < item->cbGrpprl; i++)
779 	wvTrace (("chpx byte is %x\n", item->grpprl[i]));
780 }
781