1 /************************************************************************/
2 /*									*/
3 /*  Layout functionality relating to positioned frames etc.		*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docLayoutConfig.h"
8 
9 #   include	<stddef.h>
10 
11 #   include	<docPageGrid.h>
12 
13 #   include	<appDebugon.h>
14 
15 /************************************************************************/
16 /*									*/
17 /*  Resolve X position of frame						*/
18 /*									*/
19 /************************************************************************/
20 
21 # if 0
22 
23 Word GUI:
24 
25     ALIGNMENT/BOOK LAYOUT:
26     (Left/Centerted/Right) x (Margin/Page/Column/Character)
27 
28     Frame: \phmrg -> Margin
29     Frame: \phpg -> Page
30     Frame: \phcol -> Column
31 
32     Frame: \posx99 -> Absolute
33     Frame: \posxl -> Left
34     Frame: \posxc -> Center
35     Frame: \posxr -> Right
36     Frame: \posxi -> Inside
37     Frame: \posxo -> Outside
38 
39     Table: \tphmrg -> Margin
40     Table: \tphpg -> Page
41     Table: \tphcol -> Column
42 
43     Table: \tposx99 -> Absolute
44     Table: \tposxl -> Left
45     Table: \tposxc -> Center
46     Table: \tposxr -> Right
47     Table: \tposxi -> Inside
48     Table: \tposxo -> Outside
49 
50     Shape: \shpbxmargin -> Margin or \shpbxignore and posrelh=0
51     Shape: \shpbxpage -> Page or \shpbxignore and posrelh=1
52     Shape: \shpbxcolumn -> Column or \shpbxignore and posrelh=2
53     Shape: \shpbxignore and posrelh=3 -> Character
54 
55     Shape: posh absent -> Absolute
56     Shape: posh= 1 -> Left
57     Shape: posh= 2 -> Center
58     Shape: posh= 3 -> Right
59     Shape: posh= 4 -> Inside
60     Shape: posh= 5 -> Outside
61 
62     Drawing Object: \dobxpage -> Page
63     Drawing Object: \dobxcolumn -> Column
64     Drawing Object: \dobxmargin -> Margin
65 
66     Margin:
67     -------
68     Left, Margin:	Left of text box at left margin.
69     Centered, Margin:	Center of text box at center of page.
70     Right, Margin:	Right of text box at right margin.
71 
72     Inside, Margin:	Left of text box at left margin. (=Left *)
73     Outside, Margin:	Right of text box at right margin. (=Right *)
74 			*) On odd pages. On Even pages, Inside and
75 			   outside are swapped. Even if the document
76 			   does not have the facing pages property set.
77 
78     Page:
79     -------
80     Left, Page:		Right of text box at left margin.
81     Centered, Page:	Center of text box at center of page.
82     Right, Page:	Left of text box at right margin.
83 
84     Inside, Margin:	Right of text box at left margin. (=Left *)
85     Outside, Margin:	Left of text box at right margin. (=Right *)
86 			*) On odd pages. On Even pages, Inside and
87 			   outside are swapped. Even if the document
88 			   does not have the facing pages property set.
89 
90     Character:
91     ----------
92     The information below applies if the frame is below or above the
93     regular text. If text wraps around the frame, MS-Word makes some
94     attempts to do something similar, but the result is rather inpredictable.
95     This is not surprising: this is almost impossible to implement.
96     Left, Character:	The left of the frame is at the position where
97 			the frame is anchored.
98     Center, Character:	The center of the frame is at the position where
99 			the frame is anchored.
100     Right, Character:	The right of the frame is at the position where
101 			the frame is anchored.
102 
103     ABS POS: (Margin/Page/Column/Character)
104     The left of the frame is positioned relative to the positions.
105 
106 # endif
107 
docLayoutFrameX(BlockFrame * bfTextFrame,int xRefProp,int xPosProp,int xPosVal,int layoutInCell,const ParagraphFrame * pfRef,const BlockFrame * bfRef,int xChar,int frameWide)108 void docLayoutFrameX(		BlockFrame *			bfTextFrame,
109 				int				xRefProp,
110 				int				xPosProp,
111 				int				xPosVal,
112 				int				layoutInCell,
113 				const ParagraphFrame *		pfRef,
114 				const BlockFrame *		bfRef,
115 				int				xChar,
116 				int				frameWide )
117     {
118     int		xRef= 0;
119     int		xRel= 0;
120     int		xRight= 0;
121 
122     if  ( xPosProp == FXposXI )
123 	{
124 	if  ( bfRef->bfPage % 2 )
125 	    { xPosProp= FXposXR;	}
126 	else{ xPosProp= FXposXL;	}
127 	}
128 
129     if  ( xPosProp == FXposXO )
130 	{
131 	if  ( bfRef->bfPage % 2 )
132 	    { xPosProp= FXposXL;	}
133 	else{ xPosProp= FXposXR;	}
134 	}
135 
136     switch( xRefProp )
137 	{
138 	case FXrefMARGIN:
139 	    xRef= bfRef->bfPageGeometry.dgLeftMarginTwips;
140 	    xRight= bfRef->bfPageGeometry.dgPageWideTwips-
141 				    bfRef->bfPageGeometry.dgRightMarginTwips;
142 
143 	    switch( xPosProp )
144 		{
145 		case FXposXGIVEN:
146 		    xRel= xPosVal;
147 		    /* Copy MS-Word behaviour	*/
148 		    if  ( xRel < -xRef )
149 			{ xRel=  -xRef;	}
150 		    break;
151 		case FXposXL:
152 		    xRel= 0;
153 		    break;
154 		case FXposXC:
155 		    xRef= ( xRef+ xRight )/ 2;
156 		    xRel= -frameWide/ 2;
157 		    break;
158 		case FXposXR:
159 		    xRef= xRight;
160 		    xRel= -frameWide;
161 		    break;
162 		case FXposXI: case FXposXO: default:
163 		    LDEB(xPosProp);
164 		    break;
165 		}
166 	    break;
167 
168 	case FXrefCOLUMN:
169 	    if  ( layoutInCell )
170 		{
171 		xRef= pfRef->pfCellContentRect.drX0;
172 		xRight= pfRef->pfCellContentRect.drX1;
173 		}
174 	    else{
175 		xRef= bfRef->bfContentRect.drX0;
176 		xRight= bfRef->bfContentRect.drX1;
177 		}
178 
179 	    switch( xPosProp )
180 		{
181 		case FXposXGIVEN:
182 		    xRel= xPosVal;
183 		    /* Copy MS-Word behaviour	*/
184 		    if  ( xRel < -xRef )
185 			{ xRel=  -xRef;	}
186 		    break;
187 		case FXposXL:
188 		    xRel= 0;
189 		    break;
190 		case FXposXC:
191 		    xRef= ( xRef+ xRight )/ 2;
192 		    xRel= -frameWide/ 2;
193 		    break;
194 		case FXposXR:
195 		    xRef= xRight;
196 		    xRel= -frameWide;
197 		    break;
198 		case FXposXI: case FXposXO: default:
199 		    LDEB(xPosProp);
200 		    break;
201 		}
202 	    break;
203 
204 	case FXrefPAGE:
205 	    xRef= 0;
206 	    xRight= bfRef->bfPageGeometry.dgPageWideTwips;
207 
208 	    switch( xPosProp )
209 		{
210 		case FXposXGIVEN:
211 		    xRel= xPosVal;
212 		    /* Copy MS-Word behaviour	*/
213 		    if  ( xRel < -xRef )
214 			{ xRel=  -xRef;	}
215 		    break;
216 		case FXposXL:
217 		    xRef= bfRef->bfPageGeometry.dgLeftMarginTwips;
218 		    xRel= -frameWide;
219 		    break;
220 		case FXposXC:
221 		    xRef= ( xRef+ xRight )/ 2;
222 		    xRel= -frameWide/ 2;
223 		    break;
224 		case FXposXR:
225 		    xRef= bfRef->bfPageGeometry.dgPageWideTwips-
226 				    bfRef->bfPageGeometry.dgRightMarginTwips;
227 		    xRel= 0;
228 		    break;
229 		case FXposXI: case FXposXO: default:
230 		    LDEB(xPosProp);
231 		    break;
232 		}
233 	    break;
234 
235 	case FXrefCHARACTER:
236 	    xRef= xChar;
237 	    xRel= 0;
238 
239 	    switch( xPosProp )
240 		{
241 		case FXposXGIVEN:
242 		    xRel= xPosVal;
243 		    /* Copy MS-Word behaviour	*/
244 		    if  ( xRel < -xRef )
245 			{ xRel=  -xRef;	}
246 		    break;
247 		case FXposXL:
248 		    xRel= 0;
249 		    break;
250 		case FXposXC:
251 		    xRel= -frameWide/ 2;
252 		    break;
253 		case FXposXR:
254 		    xRel= -frameWide;
255 		    break;
256 		case FXposXI: case FXposXO: default:
257 		    LDEB(xPosProp);
258 		    break;
259 		}
260 	    break;
261 
262 	default:
263 	    LDEB(xRefProp); return;
264 	}
265 
266     bfTextFrame->bfPageGeometry= bfRef->bfPageGeometry;
267 
268     bfTextFrame->bfContentRect.drX0= xRef+ xRel;
269     bfTextFrame->bfContentRect.drX1= bfTextFrame->bfContentRect.drX0+ frameWide;
270 
271     bfTextFrame->bfFlowRect.drX0= bfTextFrame->bfContentRect.drX0;
272     bfTextFrame->bfFlowRect.drX1= bfTextFrame->bfContentRect.drX1;
273     return;
274     }
275 
276 # if 0
277 
278 Word GUI:
279 
280     ALIGNMENT: (Top/Centerted/Bottom/Inside/Outside) x (Margin/Page/Line)
281 
282     Frame: \pvmrg -> Margin
283     Frame: \pvpg -> Page
284     Frame: \pvpara -> Paragraph
285 
286     Frame: \posy99 -> Absolute
287     Frame: \posyt -> Top
288     Frame: \posyc -> Center
289     Frame: \posyb -> Bottom
290     Frame: \posyin -> Inside
291     Frame: \posyout -> Outside
292 
293     It looks like posyil: "Positions the paragraph vertically to be inline"
294     means the same as pvpara,posyt. But it might be that the tag is simply
295     ignored.
296 
297     Table: \tpvmrg -> Margin
298     Table: \tpvpg -> Page
299     Table: \tpvpara -> Paragraph
300 
301     Table: \tposy99 -> Absolute
302     Table: \tposyt -> Top
303     Table: \tposyc -> Center
304     Table: \tposyb -> Bottom
305     Table: \tposyin -> Inside
306     Table: \tposyout -> Outside
307 
308     Shape: \shpbymargin -> Margin or \shpbyignore and posrelv=0
309     Shape: \shpbypage -> Page or \shpbyignore and posrelv=1
310     Shape: \shpbypara -> Column or \shpbyignore and posrelv=2
311     Shape: \shpbyignore and posrelv=3 -> Line
312 
313     Shape: posv absent -> Absolute
314     Shape: posv= 1 -> Top
315     Shape: posv= 2 -> Center
316     Shape: posv= 3 -> Bottom
317     Shape: posv= 4 -> Inside
318     Shape: posv= 5 -> Outside
319 
320     Drawing Object: \dobypage -> Page
321     Drawing Object: \dobypara -> Paragraph
322     Drawing Object: \dobymargin -> Margin
323 
324     Margin:
325     -------
326     Top, Margin:	Top of text box at top margin.
327     Centerted, Margin:	Vertically centered on the page.
328     Bottom, Margin:	Bottom of text box at bottom margin of the page.
329     Inside, Margin:	Top of text box at top margin. (=Top)
330     Outside, Margin:	Bottom of text box at bottom margin. (=Bottom)
331 
332     Page:
333     -------
334     Top, Page:		Top of text box at top of page.
335     Centerted, Page:	Vertically centered on the page.
336     Bottom, Page:	Bottom of text box at bottom of the page.
337     Inside, Page:	Center of text box at header (top) position.
338     Outside, Page:	Center of text box at footer (bottom) position.
339 
340     Line:
341     -----
342     Top, Line:		Top of text box at top of line.
343     Centerted, Line:	Line at the side of the text box
344 			Looks like the lines in/outside box are aligned,
345 			rather than that the box and the line are precisely
346 			centered.
347     Bottom, Line:	Bottom of text box at top of line.
348     Inside, Line:	Top of text box at top of line.
349     Outside, Line:	Bottom of text box at top of line.
350 
351     Paragraph:
352     ----------
353     NOTE that there is no option to verically align to the paragraph in
354     the MS-Word UI. Experiments were made with a manually modified
355     rtf file.
356 
357     For Old-Fashined "Positioned Objects and Frames", the paragraph is
358     the next paragraph. For 'Drawing Shapes' it is the paragraph that the
359     shape is anchored in.
360 
361     Top, Paragraph:	All vertical alignments to a paragraph place the top
362 			of the text box at the top of the paragraph.
363 			Most probably, MS-Word switches to an absolute
364 			position, relative to the paragraph top.
365     Centerted, Paragraph: All vertical alignments to a paragraph etc.
366     Bottom, Paragraph:	All vertical alignments to a paragraph etc.
367     Inside, Paragraph:	All vertical alignments to a paragraph etc.
368     Outside, Paragraph:	All vertical alignments to a paragraph etc.
369 
370     ABS POS: (Margin/Page/Paragraph/Line)
371     Positions are relative to the top of the objects.
372 
373 # endif
374 
docLayoutFrameY(BlockFrame * bfTextFrame,int yRefProp,int yPosProp,int yPosVal,const LayoutPosition * lpLineTop,const LayoutPosition * lpParaTop,const BlockFrame * bfRef,int frameHighProp,int frameHighVal)375 void docLayoutFrameY(		BlockFrame *			bfTextFrame,
376 				int				yRefProp,
377 				int				yPosProp,
378 				int				yPosVal,
379 				const LayoutPosition *		lpLineTop,
380 				const LayoutPosition *		lpParaTop,
381 				const BlockFrame *		bfRef,
382 				int				frameHighProp,
383 				int				frameHighVal )
384     {
385     /*
386     const DocumentGeometry *	dg= &(bfRef->bfPageGeometry);
387     */
388 
389     int				yRef= 0;
390     int				yRel= 0;
391     int				yBot= 0;
392 
393     switch( yRefProp )
394 	{
395 	case FYrefMARGIN:
396 	    yRef= bfRef->bfContentRect.drY0;
397 	    yBot= bfRef->bfPageGeometry.dgPageHighTwips-
398 				    bfRef->bfPageGeometry.dgBottomMarginTwips;
399 	    switch( yPosProp )
400 		{
401 		case FYposYGIVEN:
402 		    yRel= yPosVal;
403 		    /* Copy MS-Word behaviour	*/
404 		    if  ( yRel < -yRef )
405 			{ yRel=  -yRef;	}
406 		    break;
407 		case FYposYT:
408 		    yRel= 0;
409 		    break;
410 		case FYposYC:
411 		    yRef= ( yRef+ yBot )/ 2;
412 		    yRel= -frameHighVal/ 2;
413 		    break;
414 		case FYposYB:
415 		    yRef= yBot;
416 		    yRel= -frameHighVal;
417 		    break;
418 		case FYposYIN:
419 		    yRel= 0;
420 		    break;
421 		case FYposYOUT:
422 		    yRef= yBot;
423 		    yRel= -frameHighVal;
424 		    break;
425 		default:
426 		    LDEB(yPosProp);
427 		    break;
428 		}
429 	    break;
430 
431 	case FYrefPAGE:
432 	    yRef= 0;
433 	    yBot= bfRef->bfPageGeometry.dgPageHighTwips;
434 
435 	    switch( yPosProp )
436 		{
437 		case FYposYGIVEN:
438 		    yRel= yPosVal;
439 		    /* Copy MS-Word behaviour	*/
440 		    if  ( yRel < -yRef )
441 			{ yRel=  -yRef;	}
442 		    break;
443 		case FYposYT:
444 		    yRel= 0;
445 		    break;
446 		case FYposYC:
447 		    yRef= ( yRef+ yBot )/ 2;
448 		    yRel= -frameHighVal/ 2;
449 		    break;
450 		case FYposYB:
451 		    yRef= yBot;
452 		    yRel= -frameHighVal;
453 		    break;
454 		case FYposYIN:
455 		    yRef= bfRef->bfPageGeometry.dgHeaderPositionTwips;
456 		    yRel= -frameHighVal/ 2;
457 		    break;
458 		case FYposYOUT:
459 		    yRef= bfRef->bfPageGeometry.dgFooterPositionTwips;
460 		    yRel= -frameHighVal/ 2;
461 		    break;
462 		default:
463 		    LDEB(yPosProp);
464 		    break;
465 		}
466 	    break;
467 
468 	case FYrefPARA:
469 	    yRef= lpParaTop->lpPageYTwips;
470 
471 	    switch( yPosProp )
472 		{
473 		case FYposYGIVEN:
474 		    yRel= yPosVal;
475 		    /* Copy MS-Word behaviour	*/
476 		    if  ( yRel < -yRef )
477 			{ yRel=  -yRef;	}
478 		    break;
479 		case FYposYT:
480 		case FYposYC:
481 		case FYposYB:
482 		case FYposYIN:
483 		case FYposYOUT:
484 		    yRel= 0;
485 		    break;
486 		default:
487 		    LDEB(yPosProp);
488 		    break;
489 		}
490 	    break;
491 
492 	case FYrefLINE:
493 	    yRef= lpLineTop->lpPageYTwips;
494 
495 	    switch( yPosProp )
496 		{
497 		case FYposYGIVEN:
498 		    yRel= yPosVal;
499 		    /* Copy MS-Word behaviour	*/
500 		    if  ( yRel < -yRef )
501 			{ yRel=  -yRef;	}
502 		    break;
503 		case FYposYT:
504 		    yRel= 0;
505 		    break;
506 		case FYposYC:
507 		    /* See above: Align baselines! */
508 		    yRel= -frameHighVal/ 2;
509 		    break;
510 		case FYposYB:
511 		    yRel= -frameHighVal;
512 		    break;
513 		case FYposYIN:
514 		    yRel= 0;
515 		    break;
516 		case FYposYOUT:
517 		    yRel= -frameHighVal;
518 		    break;
519 		default:
520 		    LDEB(yPosProp);
521 		    break;
522 		}
523 	    break;
524 
525 	default:
526 	    LDEB(yRefProp);
527 	    break;
528 	}
529 
530     bfTextFrame->bfContentRect.drY0= yRef+ yRel;
531     if  ( frameHighProp < 0 )
532 	{
533 	bfTextFrame->bfContentRect.drY1=
534 			    bfTextFrame->bfContentRect.drY0- frameHighProp;
535 	}
536     else{
537 	/* will see later on */
538 	bfTextFrame->bfContentRect.drY1= bfTextFrame->bfContentRect.drY0+
539 					bfRef->bfPageGeometry.dgPageHighTwips;
540 	}
541 
542     bfTextFrame->bfFlowRect.drY0= bfTextFrame->bfContentRect.drY0;
543     bfTextFrame->bfFlowRect.drY1= bfTextFrame->bfContentRect.drY1;
544 
545     return;
546     }
547 
548 /************************************************************************/
549 /*									*/
550 /*  Translate FrameProperties to a block frame for the text box.	*/
551 /*									*/
552 /*  1)  Should be irrelevant as text frames cannot be recursive. It	*/
553 /*	does no harm to set the correct value however.			*/
554 /*  2)  Should be irrelevant as text frames cannot be attached to a	*/
555 /*	character.							*/
556 /*  3)  Should be irrelevant as text frames cannot be bound to a table	*/
557 /*	column. (Shapes can!)						*/
558 /*									*/
559 /************************************************************************/
560 
docLayoutSetTextFrame(BlockFrame * bfTextFrame,const LayoutPosition * lpRef,const BlockFrame * bfRef,const FrameProperties * fp,int frameHighVal)561 void docLayoutSetTextFrame(	BlockFrame *			bfTextFrame,
562 				const LayoutPosition *		lpRef,
563 				const BlockFrame *		bfRef,
564 				const FrameProperties *		fp,
565 				int				frameHighVal )
566     {
567     /*  2  */
568     const int				xChar= 0;
569     /*  3  */
570     const int				layoutInCell= 0;
571     const ParagraphFrame *		pfRef= (const ParagraphFrame *)0;
572 
573     /*  1  */
574     bfTextFrame->bfPage= bfRef->bfPage;
575     bfTextFrame->bfColumn= bfRef->bfColumn; /* ignored */
576 
577     /*  X  */
578     docLayoutFrameX( bfTextFrame,
579 			fp->fpXReference, fp->fpXPosition, fp->fpXTwips,
580 			layoutInCell, pfRef, bfRef, xChar, fp->fpWideTwips );
581 
582     /*  Y  */
583     docLayoutFrameY( bfTextFrame,
584 			    fp->fpYReference, fp->fpYPosition, fp->fpYTwips,
585 			    lpRef, lpRef, bfRef,
586 			    fp->fpHighTwips, frameHighVal );
587 
588     return;
589     }
590 
591