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