1 /************************************************************************/
2 /*									*/
3 /*  Buffer administration routines.					*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docBufConfig.h"
8 
9 #   include	<stdlib.h>
10 
11 #   include	<utilTree.h>
12 
13 #   include	<appDebugon.h>
14 
15 #   include	"docBuf.h"
16 #   include	"docNotes.h"
17 #   include	"docShape.h"
18 #   include	"docTreeNode.h"
19 #   include	<docTreeType.h>
20 #   include	<textAttributeAdmin.h>
21 #   include	<docBorderPropertyAdmin.h>
22 #   include	<docItemShadingAdmin.h>
23 #   include	<docParaRulerAdmin.h>
24 #   include	"docNodeTree.h"
25 #   include	<utilMatchFont.h>
26 #   include	<docDocumentNote.h>
27 #   include	<docPropertiesAdmin.h>
28 
29 /************************************************************************/
30 
docDeleteFieldFromDocument(BufferDocument * bd,DocumentField * df)31 void docDeleteFieldFromDocument(	BufferDocument *	bd,
32 					DocumentField *		df )
33     {
34     if  ( docFieldHasNote( df->dfKind ) && df->dfNoteIndex >= 0 )
35 	{
36 	docCleanNote( bd, bd->bdNotesList.nlNotes+ df->dfNoteIndex );
37 	docInitNote( bd->bdNotesList.nlNotes+ df->dfNoteIndex );
38 	}
39 
40     docDeleteFieldFromList( &(bd->bdFieldList), df );
41 
42     return;
43     }
44 
45 /************************************************************************/
46 /*									*/
47 /*  Clean and free a whole document.					*/
48 /*									*/
49 /************************************************************************/
50 
docFreeDocument(BufferDocument * bd)51 void docFreeDocument( BufferDocument *	bd )
52     {
53     int		i;
54 
55     docCleanDocumentTree( bd, &(bd->bdBody) );
56 
57     for ( i= 0; i < bd->bdNotesList.nlNoteCount; i++ )
58 	{ docCleanNote( bd, &(bd->bdNotesList.nlNotes[i]) );	}
59 
60     docCleanDocumentTree( bd, &(bd->bdEiFtnsep) );
61     docCleanDocumentTree( bd, &(bd->bdEiFtnsepc) );
62     docCleanDocumentTree( bd, &(bd->bdEiFtncn) );
63 
64     docCleanDocumentTree( bd, &(bd->bdEiAftnsep) );
65     docCleanDocumentTree( bd, &(bd->bdEiAftnsepc) );
66     docCleanDocumentTree( bd, &(bd->bdEiAftncn) );
67 
68     docCleanStyleSheet( &(bd->bdStyleSheet) );
69     docCleanFieldList( &(bd->bdFieldList) );
70     docCleanShapeList( &(bd->bdShapeList) );
71     docCleanObjectList( &(bd->bdObjectList) );
72 
73     docCleanDocumentProperties( &(bd->bdProperties) );
74 
75     if  ( bd->bdNotesList.nlNotes )
76 	{ free( bd->bdNotesList.nlNotes );	}
77 
78     if  ( bd->bdSeqFieldIdentifiers )
79 	{
80 	utilTreeFreeTree( bd->bdSeqFieldIdentifiers,
81 					    utilTreeFreeValue, (void *)0 );
82 	}
83 
84     if  ( bd->bdPropertyLists )
85 	{ docFreeDocumentPropertyLists( bd->bdPropertyLists );	}
86 
87     free( bd );
88     }
89 
90 /************************************************************************/
91 
docGetDefaultFont(BufferDocument * bd)92 int docGetDefaultFont(		BufferDocument *	bd )
93     {
94     int				i;
95     const DocumentFontList *	dfl= bd->bdProperties.dpFontList;
96 
97     if  ( bd->bdProperties.dpDefaultFont >= 0			&&
98 	  bd->bdProperties.dpDefaultFont < dfl->dflFontCount	)
99 	{ return bd->bdProperties.dpDefaultFont;	}
100 
101     for ( i= 0; i < dfl->dflFontCount; i++ )
102 	{
103 	if  ( docFontListGetFontByNumber( dfl, i ) )
104 	    {
105 	    bd->bdProperties.dpDefaultFont= i;
106 	    return bd->bdProperties.dpDefaultFont;
107 	    }
108 	}
109 
110     /*LDEB(bd->bdProperties.dpDefaultFont);*/
111     return bd->bdProperties.dpDefaultFont;
112     }
113 
114 /************************************************************************/
115 /*									*/
116 /*  Initialise a BufferDocument.					*/
117 /*									*/
118 /************************************************************************/
119 
docInitDocument(BufferDocument * bd)120 static void docInitDocument(	BufferDocument *	bd )
121     {
122     bd->bdPropertyLists= (DocumentPropertyLists *)0;
123 
124     docInitObjectList( &(bd->bdObjectList) );
125 
126     docInitDocumentProperties( &(bd->bdProperties) );
127 
128     docInitDocumentTree( &(bd->bdBody) );
129 
130     docInitStyleSheet( &(bd->bdStyleSheet) );
131     docInitFieldList( &(bd->bdFieldList) );
132     docInitShapeList( &(bd->bdShapeList) );
133 
134     bd->bdNotesList.nlNotes= (DocumentNote *)0;
135     bd->bdNotesList.nlNoteCount= 0;
136 
137     bd->bdSeqFieldIdentifiers= (void *)0;
138 
139     docInitDocumentTree( &(bd->bdEiFtnsep) );
140     docInitDocumentTree( &(bd->bdEiFtnsepc) );
141     docInitDocumentTree( &(bd->bdEiFtncn) );
142 
143     docInitDocumentTree( &(bd->bdEiAftnsep) );
144     docInitDocumentTree( &(bd->bdEiAftnsepc) );
145     docInitDocumentTree( &(bd->bdEiAftncn) );
146 
147     bd->bdAutoHyphenate= 0;
148 
149     return;
150     }
151 
152 /************************************************************************/
153 
docGetColorByNumber(RGB8Color * rgb8,const BufferDocument * bd,int colorNumber)154 void docGetColorByNumber(	RGB8Color *		rgb8,
155 				const BufferDocument *	bd,
156 				int			colorNumber )
157     {
158     const DocumentProperties *	dp= &(bd->bdProperties);
159     const ColorPalette *	cp= dp->dpColorPalette;
160 
161     rgb8->rgb8Red= 0;
162     rgb8->rgb8Green= 0;
163     rgb8->rgb8Blue= 0;
164     rgb8->rgb8Alpha= 255;
165 
166     if  ( colorNumber != 0 )
167 	{
168 	if  ( colorNumber < 1			||
169 	      colorNumber >= cp->cpColorCount	)
170 	    { LLDEB(colorNumber,cp->cpColorCount);	}
171 	else{ *rgb8= cp->cpColors[colorNumber];		}
172 	}
173 
174     return;
175     }
176 
177 /************************************************************************/
178 /*									*/
179 /*  Insert the body of the document tree in a fresh document.		*/
180 /*									*/
181 /************************************************************************/
182 
docSetupDocumentBody(BufferDocument * bd)183 static int docSetupDocumentBody(	BufferDocument *	bd )
184     {
185     bd->bdBody.dtRoot= docMakeNode();
186     if  ( ! bd->bdBody.dtRoot )
187 	{ XDEB(bd->bdBody.dtRoot); return -1;	}
188 
189     docInitNode( bd->bdBody.dtRoot, (struct BufferItem *)0, bd,
190 						0, DOClevBODY, DOCinBODY );
191 
192     return 0;
193     }
194 
195 /************************************************************************/
196 /*									*/
197 /*  Create a fresh document.						*/
198 /*									*/
199 /************************************************************************/
200 
docNewDocument(const BufferDocument * bdRef)201 BufferDocument * docNewDocument( const BufferDocument *	bdRef )
202     {
203     BufferDocument *	rval= (BufferDocument *)0;
204     BufferDocument *	bd= (BufferDocument *)0;
205 
206     bd= (BufferDocument *)malloc( sizeof(BufferDocument) );
207     if  ( ! bd )
208 	{ XDEB(bd); goto ready;	}
209 
210     docInitDocument( bd );
211 
212     if  ( bdRef )
213 	{ bd->bdPropertyLists= bdRef->bdPropertyLists;	}
214     else{
215 	bd->bdPropertyLists= docMakeDocumentPropertyLists();
216 	if  ( ! bd->bdPropertyLists )
217 	    { XDEB(bd->bdPropertyLists); goto ready;	}
218 	}
219 
220     bd->bdProperties.dpFontList= &(bd->bdPropertyLists->dplFontList);
221     bd->bdProperties.dpListAdmin= &(bd->bdPropertyLists->dplListAdmin);
222     bd->bdProperties.dpColorPalette= &(bd->bdPropertyLists->dplColorPalette);
223 
224     docDefaultFootEndNotesProperties( &(bd->bdProperties.dpNotesProps) );
225 
226     if  ( docSetupDocumentBody( bd ) )
227 	{ LDEB(1); goto ready;	}
228 
229     rval= bd; bd= (BufferDocument *)0; /* steal */
230 
231   ready:
232 
233     if  ( bd )
234 	{
235 	if  ( bdRef )
236 	    { bd->bdPropertyLists= (DocumentPropertyLists *)0;	}
237 
238 	docFreeDocument( bd );
239 	}
240 
241     return rval;
242     }
243 
244 /************************************************************************/
245 /*									*/
246 /*  Make a new document consisting of one paragraph with one empty	*/
247 /*  particule. This is the starting point for editing and for reading	*/
248 /*  plain text documents.						*/
249 /*									*/
250 /************************************************************************/
251 
docNewFile(TextAttribute * taDefault,const char * defaultFontName,int defaultFontSize,const PostScriptFontList * psfl,const DocumentGeometry * dg)252 BufferDocument * docNewFile(	TextAttribute *			taDefault,
253 				const char *			defaultFontName,
254 				int				defaultFontSize,
255 				const PostScriptFontList *	psfl,
256 				const DocumentGeometry *	dg )
257     {
258     NumberedPropertiesList *	taList;
259     BufferDocument *		bd;
260     DocumentProperties *	dp;
261 
262     PropertyMask		taNewMask;
263     TextAttribute		taNew;
264     int				textAttributeNumber;
265 
266     BufferItem *		bi;
267 
268     utilPropMaskClear( &taNewMask );
269 
270     bd= docNewDocument( (BufferDocument *)0 );
271     if  ( ! bd )
272 	{ XDEB(bd); return (BufferDocument *)0;	}
273 
274     dp= &(bd->bdProperties);
275     dp->dpGeometry= *dg;
276     taList= &(bd->bdPropertyLists->dplTextAttributeList);
277 
278     /*  3  */
279     if  ( psfl )
280 	{
281 	if  ( utilAddPsFontsToDocList( dp->dpFontList, psfl ) )
282 	    { LDEB(psfl->psflFamilyCount); goto failed;	}
283 	}
284     else{
285 	if  ( utilAddBase35FontsToDocList( dp->dpFontList ) )
286 	    { LDEB(35); goto failed;	}
287 	}
288 
289     utilInitTextAttribute( &taNew );
290     taNew.taFontNumber= docGetFontByName( dp->dpFontList, defaultFontName );
291     if  ( taNew.taFontNumber < 0 )
292 	{ LDEB(taNew.taFontNumber); goto failed;	}
293     PROPmaskADD( &taNewMask, TApropFONT_NUMBER );
294 
295     if  ( defaultFontSize < 6 || defaultFontSize > 100 )
296 	{ LDEB(defaultFontSize); defaultFontSize= 24;	}
297     taNew.taFontSizeHalfPoints= defaultFontSize;
298     PROPmaskADD( &taNewMask, TApropFONTSIZE );
299 
300     dp->dpDefaultFont= taNew.taFontNumber;
301 
302     textAttributeNumber= utilTextAttributeNumber( taList, &taNew );
303     if  ( textAttributeNumber < 0 )
304 	{ SLDEB(defaultFontName,textAttributeNumber); goto failed;	}
305 
306     bi= docInsertNode( bd, bd->bdBody.dtRoot, -1, DOClevSECT );
307     if  ( ! bi )
308 	{ XDEB(bi); goto failed;	}
309 
310     bi->biSectDocumentGeometry= dp->dpGeometry;
311 
312     bi= docInsertEmptyParagraph( bd, bi, textAttributeNumber );
313     if  ( ! bi )
314 	{ XDEB(bi); goto failed;	}
315 
316     *taDefault= taNew;
317     return bd;
318 
319   failed:
320 
321     docFreeDocument( bd );
322 
323     return (BufferDocument *)0;
324     }
325 
326 /************************************************************************/
327 /*									*/
328 /*  Determine a text attribute number for a particule.			*/
329 /*									*/
330 /************************************************************************/
331 
docTextAttributeNumber(BufferDocument * bd,const TextAttribute * ta)332 int docTextAttributeNumber(	BufferDocument *	bd,
333 				const TextAttribute *	ta )
334     {
335     NumberedPropertiesList *	taList= &(bd->bdPropertyLists->dplTextAttributeList);
336     const DocumentProperties *	dp= &(bd->bdProperties);
337     const DocumentFontList *	dfl= dp->dpFontList;
338 
339     int				textAttributeNumber;
340 
341     TextAttribute		taCopy= *ta;
342 
343     if  ( taCopy.taFontNumber < 0			||
344 	  taCopy.taFontNumber >= dfl->dflFontCount	)
345 	{
346 	if  ( taCopy.taFontNumber >= dfl->dflFontCount )
347 	    { LLDEB(taCopy.taFontNumber,dfl->dflFontCount);	}
348 
349 	taCopy.taFontNumber= docGetDefaultFont( bd );
350 
351 	if  ( taCopy.taFontNumber < 0 )
352 	    { taCopy.taFontNumber= 0;	}
353 
354 	if  ( taCopy.taFontNumber >= dfl->dflFontCount )
355 	    { LLDEB(taCopy.taFontNumber,dfl->dflFontCount);	}
356 	}
357 
358     textAttributeNumber= utilTextAttributeNumber( taList, &taCopy );
359     if  ( textAttributeNumber < 0 )
360 	{ LDEB(textAttributeNumber); return -1;	}
361 
362     return textAttributeNumber;
363     }
364 
docGetTextAttributeByNumber(TextAttribute * ta,const BufferDocument * bd,int n)365 void docGetTextAttributeByNumber(	TextAttribute *			ta,
366 					const BufferDocument *		bd,
367 					int				n )
368     {
369     NumberedPropertiesList *	taList= &(bd->bdPropertyLists->dplTextAttributeList);
370 
371     utilGetTextAttributeByNumber( ta, taList, n );
372     }
373 
374 /************************************************************************/
375 
docItemShadingNumber(BufferDocument * bd,const ItemShading * is)376 int docItemShadingNumber(	BufferDocument *	bd,
377 				const ItemShading *	is )
378     {
379     NumberedPropertiesList *	isList= &(bd->bdPropertyLists->dplItemShadingList);
380 
381     return docItemShadingNumberImpl( isList, is );
382     }
383 
docGetItemShadingByNumber(ItemShading * is,const BufferDocument * bd,int n)384 void docGetItemShadingByNumber(	ItemShading *			is,
385 				const BufferDocument *		bd,
386 				int				n )
387     {
388     NumberedPropertiesList *	isList= &(bd->bdPropertyLists->dplItemShadingList);
389 
390     docGetItemShadingByNumberImpl( is, isList, n );
391     }
392 
docShadingNumberIsShading(const BufferDocument * bd,int n)393 int docShadingNumberIsShading(	const BufferDocument *		bd,
394 				int				n )
395     {
396     NumberedPropertiesList *	isList= &(bd->bdPropertyLists->dplItemShadingList);
397 
398     return docShadingNumberIsShadingImpl( isList, n );
399     }
400 
401 /************************************************************************/
402 
docBorderPropertiesNumber(BufferDocument * bd,const BorderProperties * bp)403 int docBorderPropertiesNumber(	BufferDocument *		bd,
404 				const BorderProperties *	bp )
405     {
406     NumberedPropertiesList *	bpList= &(bd->bdPropertyLists->dplBorderPropertyList);
407 
408     return docBorderPropertiesNumberImpl( bpList, bp );
409     }
410 
docGetBorderPropertiesByNumber(BorderProperties * bp,const BufferDocument * bd,int n)411 void docGetBorderPropertiesByNumber(	BorderProperties *	bp,
412 				const BufferDocument *		bd,
413 				int				n )
414     {
415     NumberedPropertiesList *	bpList= &(bd->bdPropertyLists->dplBorderPropertyList);
416 
417     docGetBorderPropertiesByNumberImpl( bp, bpList, n );
418     }
419 
docBorderNumberIsBorder(const BufferDocument * bd,int n)420 int docBorderNumberIsBorder(	const BufferDocument *		bd,
421 				int				n )
422     {
423     NumberedPropertiesList *	bpList= &(bd->bdPropertyLists->dplBorderPropertyList);
424 
425     return docBorderNumberIsBorderImpl( bpList, n );
426     }
427 
428 /************************************************************************/
429 
docFramePropertiesNumber(BufferDocument * bd,const FrameProperties * fp)430 int docFramePropertiesNumber(	BufferDocument *	bd,
431 				const FrameProperties *	fp )
432     {
433     NumberedPropertiesList *	fpList= &(bd->bdPropertyLists->dplFramePropertyList);
434 
435     return docFramePropertiesNumberImpl( fpList, fp );
436     }
437 
docGetFramePropertiesByNumber(FrameProperties * fp,const BufferDocument * bd,int n)438 void docGetFramePropertiesByNumber( FrameProperties *		fp,
439 				const BufferDocument *		bd,
440 				int				n )
441     {
442     NumberedPropertiesList *	fpList= &(bd->bdPropertyLists->dplFramePropertyList);
443 
444     docGetFramePropertiesByNumberImpl( fp, fpList, n );
445     }
446 
447 /************************************************************************/
448 
docTabStopListNumber(BufferDocument * bd,const TabStopList * tsl)449 int docTabStopListNumber(	BufferDocument *	bd,
450 				const TabStopList *	tsl )
451     {
452     NumberedPropertiesList *	tslList= &(bd->bdPropertyLists->dplTabStopListList);
453 
454     return docTabStopListNumberImpl( tslList, tsl );
455     }
456 
docGetTabStopListByNumber(TabStopList * tsl,const BufferDocument * bd,int n)457 void docGetTabStopListByNumber(	TabStopList *			tsl,
458 				const BufferDocument *		bd,
459 				int				n )
460     {
461     NumberedPropertiesList *	tslList= &(bd->bdPropertyLists->dplTabStopListList);
462 
463     docGetTabStopListByNumberImpl( tsl, tslList, n );
464     }
465 
466 /************************************************************************/
467 
docGetEncodingName(BufferDocument * bd,TextAttribute * ta,int charset)468 const char * docGetEncodingName(
469 				BufferDocument *		bd,
470 				TextAttribute *			ta,
471 				int				charset )
472     {
473     const char *		encodingName= (const char *)0;
474 
475     const DocumentFont *	df;
476 
477     df= docRtfGetCurrentFont( bd, ta );
478     if  ( df )
479 	{ encodingName= utilGetEncodingName( df->dfName, charset );	}
480 
481     return encodingName;
482     }
483 
484 /************************************************************************/
485 /*									*/
486 /*  Determine the plain text attribute for this document.		*/
487 /*									*/
488 /************************************************************************/
489 
docPlainTextAttribute(TextAttribute * ta,BufferDocument * bd)490 void docPlainTextAttribute(		TextAttribute *		ta,
491 					BufferDocument *	bd )
492     {
493     utilInitTextAttribute( ta );
494     if  ( bd )
495 	{ ta->taFontNumber= docGetDefaultFont( bd );	}
496     ta->taFontSizeHalfPoints= 24;
497 
498     return;
499     }
500 
501 /************************************************************************/
502 
docRtfGetCurrentFont(BufferDocument * bd,TextAttribute * ta)503 const DocumentFont * docRtfGetCurrentFont(
504 				BufferDocument *		bd,
505 				TextAttribute *			ta )
506     {
507     DocumentProperties *	dp= &(bd->bdProperties);
508     DocumentFontList *		dfl= dp->dpFontList;
509     const DocumentFont *	df;
510 
511     if  ( ta->taFontNumber < 0 )
512 	{
513 	/*LDEB(ta->taFontNumber);*/
514 	ta->taFontNumber= docGetDefaultFont( bd );
515 	}
516 
517     df= docFontListGetFontByNumber( dfl, ta->taFontNumber );
518     if  ( ! df )
519 	{
520 	if  ( ta->taFontNumber >= 0 )
521 	    { LXDEB(ta->taFontNumber,df);	}
522 	else{
523 	    ta->taFontNumber= docGetDefaultFont( bd );
524 	    df= docFontListGetFontByNumber( dfl, ta->taFontNumber );
525 	    }
526 	}
527 
528     return df;
529     }
530 
531 /************************************************************************/
532 /*									*/
533 /*  Determine the number of the attribute belonging to the scaps	*/
534 /*  font size. Note that this is used for the shifted lower case	*/
535 /*  letters only.							*/
536 /*									*/
537 /************************************************************************/
538 
docScapsAttributeNumber(BufferDocument * bd,const TextAttribute * ta)539 int docScapsAttributeNumber(		BufferDocument *	bd,
540 					const TextAttribute *	ta )
541     {
542     NumberedPropertiesList *	taList= &(bd->bdPropertyLists->dplTextAttributeList);
543     TextAttribute	taScaps= *ta;
544 
545     taScaps.taFontSizeHalfPoints= SCAPS_SIZE( ta->taFontSizeHalfPoints );
546     taScaps.taSmallCaps= 0;
547 
548     return utilTextAttributeNumber( taList, &taScaps );
549     }
550 
551 /************************************************************************/
552 
docDeleteDrawingShape(struct BufferDocument * bd,DrawingShape * ds)553 void docDeleteDrawingShape(	struct BufferDocument *	bd,
554 				DrawingShape *		ds )
555     {
556     int		i;
557 
558     for ( i= 0; i < ds->dsChildCount; i++ )
559 	{
560 	if  ( ds->dsChildren[i] )
561 	    {
562 	    docDeleteDrawingShape( bd, ds->dsChildren[i] );
563 	    ds->dsChildren[i]= (DrawingShape *)0;
564 	    }
565 	}
566 
567     docEraseDocumentTree( bd, &(ds->dsDocumentTree) );
568 
569     /* Done from the paged list: docCleanDrawingShape( bd, ds ); */
570     docDeleteShapeFromList( &(bd->bdShapeList), ds );
571     }
572 
573 /************************************************************************/
574 
docOverridePaperSize(struct BufferDocument * bd,const DocumentGeometry * dgFrom)575 void docOverridePaperSize(	struct BufferDocument *		bd,
576 				const DocumentGeometry *	dgFrom )
577     {
578     DocumentProperties *	dp= &(bd->bdProperties);
579     int			sect;
580 
581     utilOverridePaperSize( &(dp->dpGeometry), dgFrom );
582 
583     for ( sect= 0; sect < bd->bdBody.dtRoot->biChildCount; sect++ )
584 	{
585 	BufferItem *	sectNode= bd->bdBody.dtRoot->biChildren[sect];
586 
587 	utilOverridePaperSize( &(sectNode->biSectDocumentGeometry), dgFrom );
588 	}
589 
590     return;
591     }
592