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