Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2010, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
/******************************************************************************
37
*
38
* extent1.h: HyperDoc extent computation routines
39
*
40
* Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993.
41
*
42
****************************************************************************/
43
44
#include "openaxiom-c-macros.h"
45
#include "debug.h"
46
#include "sockio.h"
47
#include "extent.h"
48
#include "hyper.h"
49
#include "group.h"
50
#include "titlebar.h"
51
#include "scrollbar.h"
52
53
static void compute_begin_items_extent(TextNode * node);
54
static void compute_bf_extent(TextNode * node);
55
static void compute_box_extent(TextNode * node);
56
static void compute_button_extent(TextNode * node);
57
static void compute_center_extent(TextNode * node);
58
static void compute_dash_extent(TextNode * node);
59
static void compute_em_extent(TextNode * node);
60
static void compute_ifcond_extent(TextNode * node);
61
static void compute_image_extent(TextNode * node);
62
static void compute_input_extent(TextNode * node);
63
static void compute_ir_extent(TextNode * node);
64
static void compute_it_extent(TextNode * node);
65
static void compute_item_extent(TextNode * node);
66
static void compute_mbox_extent(TextNode * node);
67
static void compute_mitem_extent(TextNode * node);
68
static void compute_paste_extent(TextNode * node);
69
static void compute_pastebutton_extent(TextNode * node);
70
static void compute_punctuation_extent(TextNode * node);
71
static void compute_rm_extent(TextNode * node);
72
static void compute_spadcommand_extent(TextNode * node);
73
static void compute_spadsrc_extent(TextNode * node);
74
static void compute_spadsrctxt_extent(TextNode * node);
75
static void compute_table_extent(TextNode * * node);
76
static void compute_verbatim_extent(TextNode * node);
77
static void compute_word_extent(TextNode * node);
78
static void end_spadcommand_extent(TextNode * node);
79
static void end_spadsrc_extent(TextNode * node);
80
static void endbutton_extent(TextNode * node);
81
static void endif_extent(TextNode * node);
82
static void endpastebutton_extent(TextNode * node);
83
84
/*
85
* Now we declare all the values which are shared among the extent routines
86
* and the showing routines
87
*/
88
89
int noop_count;
90
91
TextNode *link_node = NULL;
92
TextNode *paste_node = NULL;
93
TextNode *spad_node = NULL;
94
TextNode *if_node = NULL;
95
96
97
short int gExtentRegion;
98
99
100
short int gInDesc;
101
short int gInLine; /* true iff there have been words printed */
102
short int gInItem; /* true iff we are in a \item */
103
short int gInAxiomCommand; /* true iff we are in a \spadcommand */
104
short int gInTable;
105
106
/* Variables for the formatting state */
107
108
int right_margin_space;
109
int right_margin;
110
int indent;
111
int item_indent;
112
int text_x;
113
int text_y;
114
int y_off;
115
int scroll_bot;
116
int need_scroll_up_button;
117
int need_scroll_down_button;
118
int item_space;
119
int present_line_height;
120
int past_line_height;
121
int line_height; /* space between lines */
122
int normal_text_height; /* space between lines */
123
int space_width; /* the maximum width of a character */
124
int word_off_height; /* the diff between text height and */
125
126
TextNode *gLineNode;
127
128
/*
129
* Computes the extent of the input string or box
130
*/
131
132
static void
133
compute_input_extent(TextNode * node)
134
{
135
InputItem *item;
136
int t_width;
137
int num_lines;
138
139
/* search the symbol table for the proper entry */
140
141
item = node->link->reference.string;
142
num_lines = item->num_lines;
143
144
/*
145
* Once we have gotten this far, we should just be able to calculate the
146
* width using the normal font
147
*/
148
149
t_width = (item->size + 1) * gInputFont->max_bounds.width + 10;
150
151
if (gInLine)
152
text_x += inter_word_space;
153
154
if (text_x + t_width > right_margin) {
155
start_newline(present_line_height, node);
156
text_x = indent;
157
}
158
node->x = text_x;
159
160
/* now figure out the height of the current window */
161
162
node->height = line_height * (num_lines);
163
node->y = text_y - line_height + node->height - 1;
164
if (node->height > present_line_height)
165
present_line_height = plh(node->height);
166
node->width = t_width;
167
gInLine = 1;
168
text_x += t_width;
169
}
170
171
static void
172
compute_punctuation_extent(TextNode * node)
173
{
174
int twidth;
175
int nextwidth;
176
int incwidth;
177
178
node->height = normal_text_height;
179
node->width = strlen(node->data.text);
180
incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text,
181
node->width);
182
183
/* always check to see if there was some space in front of us */
184
185
if (gInLine && (node->space & FRONTSPACE))
186
twidth += inter_word_space;
187
188
/*
189
* now calcualte the width of the next one if it needs to be considered
190
*/
191
192
if (!(node->space & BACKSPACE))
193
nextwidth = total_width(node->next, openaxiom_Endtokens_token);
194
else
195
nextwidth = 0;
196
197
if ((!(node->space & BACKSPACE)) &&
198
(text_x + twidth + nextwidth > right_margin) && gInLine) {
199
start_newline(present_line_height, node);
200
if (gInAxiomCommand) {
201
text_x = indent + spadcom_indent;
202
}
203
else
204
text_x = indent;
205
}
206
207
if (node->space & FRONTSPACE)
208
text_x += inter_word_space;
209
210
node->x = text_x;
211
212
/*
213
* Now try to see if we should leave space after myself. Always leave
214
* space when there is space
215
*/
216
217
if (node->space & BACKSPACE) {
218
switch (node->data.text[0]) {
219
case '.':
220
case '?':
221
case '!':
222
text_x += term_punct_space;
223
break;
224
}
225
}
226
227
text_x += incwidth;
228
node->y = text_y - word_off_height;
229
gInLine = 1;
230
}
231
232
static void
233
compute_word_extent(TextNode * node)
234
{
235
int twidth;
236
int nextwidth;
237
int incwidth;
238
239
node->height = normal_text_height;
240
node->width = strlen(node->data.text);
241
incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text,
242
node->width);
243
244
/*
245
* Now if we should drop some space in front of me, then add it to twidth
246
*/
247
248
if (gInLine && node->space)
249
twidth += inter_word_space;
250
251
/*
252
* Now what we should do is find all the things after us that have no
253
* space in front and add there width on.
254
*/
255
256
nextwidth = total_width(node->next, openaxiom_Endtokens_token);
257
258
259
/*
260
* Should we start a new line?
261
*/
262
263
if (text_x + twidth + nextwidth > right_margin && gInLine) {
264
start_newline(present_line_height, node);
265
if (gInAxiomCommand) {
266
text_x = indent + spadcom_indent;
267
}
268
else
269
text_x = indent;
270
}
271
272
/*
273
* Now see if we am on the beginning of a line, and if not add some space
274
* if we need to
275
*/
276
277
if (gInLine && node->space)
278
text_x += inter_word_space;
279
280
node->x = text_x;
281
node->y = text_y - word_off_height;
282
text_x += incwidth;
283
gInLine = 1;
284
}
285
286
static void
287
compute_verbatim_extent(TextNode *node)
288
{
289
node->height = normal_text_height;
290
node->width = strlen(node->data.text);
291
292
node->x = text_x;
293
node->y = text_y - word_off_height;
294
gInLine = 1;
295
return;
296
}
297
298
static void
299
compute_spadsrctxt_extent(TextNode *node)
300
{
301
node->height = normal_text_height;
302
node->width = strlen(node->data.text);
303
304
if (gInLine) {
305
start_newline(present_line_height, node);
306
text_x = indent;
307
}
308
node->x = text_x;
309
node->y = text_y - word_off_height;
310
gInLine = 1;
311
return;
312
}
313
314
static void
315
compute_dash_extent(TextNode *node)
316
{
317
int num_dashes;
318
int twidth;
319
int nextwidth;
320
321
node->height = normal_text_height;
322
323
num_dashes = strlen(node->data.text);
324
325
if (num_dashes > 1)
326
twidth = node->width = num_dashes * dash_width;
327
else
328
twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font,
329
node->data.text, 1);
330
331
if (gInLine && node->space)
332
twidth += inter_word_space;
333
334
/*
335
* Now what we should do is find all the things after us that have no
336
* space in front and add there width on.
337
*/
338
339
nextwidth = total_width(node->next, openaxiom_Endtokens_token);
340
341
/*
342
* Should we start a new line?
343
*/
344
345
if (text_x + twidth + nextwidth > right_margin) {
346
start_newline(present_line_height, node);
347
if (gInAxiomCommand) {
348
text_x = indent + spadcom_indent;
349
}
350
else
351
text_x = indent;
352
}
353
354
/*
355
* Now see if we am on the beginning of a line, and if not add some space
356
* if we need to
357
*/
358
359
if (gInLine && node->space)
360
text_x += inter_word_space;
361
362
node->x = text_x;
363
if (num_dashes > 1)
364
node->y = text_y - dash_y;
365
else
366
node->y = text_y - word_off_height;
367
text_x += node->width;
368
gInLine = 1;
369
return;
370
}
371
372
void
373
compute_text_extent(TextNode *node)
374
{
375
for (; node != NULL; node = node->next) {
376
switch (node->type) {
377
case openaxiom_Endpastebutton_token:
378
endpastebutton_extent(node);
379
break;
380
case openaxiom_Paste_token:
381
compute_paste_extent(node);
382
break;
383
case openaxiom_Endpaste_token:
384
if (gInLine) {
385
start_newline(present_line_height, node);
386
text_x = indent;
387
}
388
break;
389
case openaxiom_Pastebutton_token:
390
compute_pastebutton_extent(node);
391
break;
392
case openaxiom_Ifcond_token:
393
compute_ifcond_extent(node);
394
break;
395
case openaxiom_Fi_token:
396
break;
397
case openaxiom_Endif_token:
398
if (if_node == NULL) {
399
return;
400
}
401
else
402
endif_extent(node);
403
break;
404
case openaxiom_Endcenter_token:
405
start_newline(present_line_height, node->next);
406
pop_group_stack();
407
text_x = indent;
408
break;
409
case openaxiom_Pound_token:
410
case openaxiom_Macro_token:
411
/* check to see if we had space in front of me, if so add it */
412
413
if (node->space && gInLine)
414
text_x += inter_word_space;
415
break;
416
case openaxiom_Punctuation_token:
417
compute_punctuation_extent(node);
418
break;
419
case openaxiom_Endmath_token:
420
break;
421
case openaxiom_Endverbatim_token:
422
if (gInLine) {
423
start_newline(present_line_height, node);
424
text_x = indent;
425
}
426
break;
427
case openaxiom_Spadsrctxt_token:
428
compute_spadsrctxt_extent(node);
429
break;
430
case openaxiom_Math_token:
431
compute_word_extent(node);
432
break;
433
case openaxiom_Verbatim_token:
434
compute_verbatim_extent(node);
435
break;
436
case openaxiom_WindowId_token:
437
case openaxiom_Word_token:
438
case openaxiom_Lsquarebrace_token:
439
case openaxiom_Rsquarebrace_token:
440
compute_word_extent(node);
441
break;
442
case openaxiom_Dash_token:
443
compute_dash_extent(node);
444
break;
445
case openaxiom_HSpace_token:
446
node->height = line_height;
447
node->x = text_x;
448
node->y = text_y;
449
if (gInLine) {
450
text_x +=
451
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
452
}
453
break;
454
case openaxiom_VSpace_token:
455
node->height = line_height;
456
node->x = text_x;
457
node->y = text_y + present_line_height;;
458
text_y +=
459
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1) +
460
present_line_height;
461
past_line_height = (node->data.node != NULL ?
462
atoi(node->data.node->data.text) : 1)
463
+ present_line_height;
464
465
present_line_height = line_height;
466
break;
467
case openaxiom_Space_token:
468
node->height = line_height;
469
node->x = text_x;
470
node->y = text_y;
471
text_x += (gTopOfGroupStack->cur_font->max_bounds.width) *
472
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
473
break;
474
case openaxiom_Tab_token:
475
node->height = line_height;
476
text_x = indent + (gTopOfGroupStack->cur_font->max_bounds.width) *
477
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
478
gInLine = 0;
479
break;
480
case openaxiom_Par_token:
481
node->height = line_height;
482
if (gInItem)
483
text_x = indent;
484
else
485
text_x = indent + paragraph_space;
486
if (gInLine) {
487
start_newline(present_line_height, node);
488
}
489
break;
490
case openaxiom_Newline_token:
491
if (gInLine) {
492
start_newline(present_line_height, node);
493
text_x = indent;
494
}
495
break;
496
case openaxiom_Horizontalline_token:
497
if (gInLine) {
498
start_newline(present_line_height, node);
499
text_x = indent;
500
}
501
node->height = line_height;
502
gInLine = 0;
503
node->y = text_y - line_height / 2;
504
node->x = text_x;
505
start_newline(present_line_height, node);
506
break;
507
case openaxiom_Center_token:
508
compute_center_extent(node);
509
break;
510
case openaxiom_Box_token:
511
compute_box_extent(node);
512
break;
513
case openaxiom_Mbox_token:
514
compute_mbox_extent(node);
515
break;
516
case openaxiom_Beginitems_token:
517
case openaxiom_Begintitems_token:
518
compute_begin_items_extent(node);
519
break;
520
case openaxiom_Enditems_token:
521
case openaxiom_Endtitems_token:
522
pop_item_stack();
523
if (gInLine) {
524
start_newline(present_line_height, node);
525
}
526
text_x = indent;
527
break;
528
case openaxiom_Titem_token:
529
if (gInLine) {
530
start_newline(present_line_height, node);
531
}
532
text_x = indent - item_space;
533
break;
534
case openaxiom_Item_token:
535
compute_item_extent(node);
536
break;
537
case openaxiom_Mitem_token:
538
compute_mitem_extent(node);
539
break;
540
case openaxiom_Upbutton_token:
541
case openaxiom_Returnbutton_token:
542
case openaxiom_Memolink_token:
543
case openaxiom_Downlink_token:
544
case openaxiom_Link_token:
545
case openaxiom_Windowlink_token:
546
compute_button_extent(node);
547
break;
548
case openaxiom_Unixlink_token:
549
case openaxiom_Lisplink_token:
550
case openaxiom_Lispwindowlink_token:
551
case openaxiom_Spadcall_token:
552
case openaxiom_Spadcallquit_token:
553
case openaxiom_Qspadcall_token:
554
case openaxiom_Qspadcallquit_token:
555
case openaxiom_LispDownLink_token:
556
case openaxiom_LispMemoLink_token:
557
case openaxiom_Lispcommand_token:
558
case openaxiom_Lispcommandquit_token:
559
case openaxiom_Spadlink_token:
560
case openaxiom_Spaddownlink_token:
561
case openaxiom_Spadmemolink_token:
562
case openaxiom_Unixcommand_token:
563
compute_button_extent(node);
564
break;
565
case openaxiom_Endbutton_token:
566
endbutton_extent(node);
567
break;
568
case openaxiom_Endlink_token:
569
if (link_node == NULL)
570
return;
571
else
572
endbutton_extent(node);
573
break;
574
case openaxiom_Spadsrc_token:
575
compute_spadsrc_extent(node);
576
break;
577
case openaxiom_Spadcommand_token:
578
case openaxiom_Spadgraph_token:
579
compute_spadcommand_extent(node);
580
break;
581
case openaxiom_Endspadsrc_token:
582
end_spadsrc_extent(node);
583
break;
584
case openaxiom_Endspadcommand_token:
585
end_spadcommand_extent(node);
586
break;
587
case openaxiom_Indent_token:
588
indent = left_margin +
589
atoi(node->data.node->data.text) *
590
(gTopOfGroupStack->cur_font->max_bounds.width);
591
if (!gInLine)
592
text_x = indent;
593
break;
594
case openaxiom_Indentrel_token:
595
indent += atoi(node->data.node->data.text) *
596
(gTopOfGroupStack->cur_font->max_bounds.width);
597
if (!gInLine)
598
text_x = indent;
599
break;
600
case openaxiom_Group_token:
601
push_group_stack();
602
node->y = text_y;
603
if (gInLine && node->space)
604
text_x += inter_word_space;
605
break;
606
case openaxiom_Endgroup_token:
607
pop_group_stack();
608
break;
609
case openaxiom_Tableitem_token:
610
push_group_stack();
611
node->y = text_y;
612
if (gInLine && node->space)
613
text_x += inter_word_space;
614
break;
615
case openaxiom_Endtableitem_token:
616
pop_group_stack();
617
return;
618
case openaxiom_Controlbitmap_token:
619
case openaxiom_Inputbitmap_token:
620
if (node->width == -1)
621
insert_bitmap_file(node);
622
compute_image_extent(node);
623
break;
624
case openaxiom_Inputpixmap_token:
625
if (node->width == -1)
626
insert_pixmap_file(node);
627
compute_image_extent(node);
628
break;
629
case openaxiom_Table_token:
630
compute_table_extent(&node);
631
break;
632
case openaxiom_BoldFace_token:
633
compute_bf_extent(node);
634
break;
635
case openaxiom_Emphasize_token:
636
compute_em_extent(node);
637
break;
638
case openaxiom_It_token:
639
compute_it_extent(node);
640
break;
641
case openaxiom_Rm_token:
642
case openaxiom_Sl_token:
643
case openaxiom_Tt_token:
644
compute_rm_extent(node);
645
break;
646
case openaxiom_Inputstring_token:
647
compute_input_extent(node);
648
break;
649
case openaxiom_SimpleBox_token:
650
case openaxiom_Radiobox_token:
651
compute_ir_extent(node);
652
break;
653
case openaxiom_Endbox_token:
654
text_x += box_width;
655
break;
656
case openaxiom_Endmacro_token:
657
case openaxiom_Endparameter_token:
658
break;
659
case openaxiom_Description_token:
660
bf_top_group();
661
break;
662
case openaxiom_Enddescription_token:
663
pop_group_stack();
664
if (gInDesc)
665
return;
666
break;
667
case openaxiom_Endscrolling_token:
668
669
/*
670
* What we should do here is if we am in the middle of a line, we
671
* should end it here an now.
672
*/
673
674
if (gInLine)
675
start_newline(present_line_height, node);
676
break;
677
case openaxiom_Noop_token:
678
noop_count++;
679
break;
680
case openaxiom_Endinputbox_token:
681
case openaxiom_Endheader_token:
682
case openaxiom_Endtitle_token:
683
case openaxiom_Endfooter_token:
684
case openaxiom_Rbrace_token:
685
case openaxiom_Free_token:
686
case openaxiom_Bound_token:
687
case openaxiom_Beep_token:
688
case 0:
689
break;
690
default:
691
fprintf(stderr, "Compute_text_extent: Unknown node type %d\n",
692
node->type);
693
break;
694
}
695
}
696
}
697
698
static void
699
compute_begin_items_extent(TextNode * node)
700
{
701
int store_x, store_y, lh;
702
703
/*
704
* This routine pushes the current item_stack, and then tries to set the
705
* item_indent, and the indent level. It checks for an optional argument
706
* to begin{items} and if found uses its width.
707
*/
708
if (gInLine) {
709
start_newline(present_line_height, node);
710
}
711
store_x = text_x, store_y = text_y, lh = present_line_height;
712
text_x = indent;
713
push_item_stack();
714
gInItem++;
715
item_indent = indent;
716
if (node->data.node != NULL) {
717
/* we have a desc */
718
gInDesc = 1;
719
compute_text_extent(node->data.node);
720
gInDesc = 0;
721
item_space = text_width(node->data.node, openaxiom_Enddescription_token);
722
text_x = store_x;
723
text_y = store_y;
724
present_line_height = lh;
725
indent = item_indent + item_space;
726
}
727
else
728
indent = item_indent + 30;
729
gInLine = 0;
730
}
731
732
static void
733
compute_item_extent(TextNode * node)
734
{
735
if (gInLine)
736
start_newline(present_line_height, node);
737
text_x = item_indent;
738
}
739
740
static void
741
compute_mitem_extent(TextNode *node)
742
{
743
if (gInLine) {
744
start_newline(present_line_height, node);
745
}
746
text_x = item_indent;
747
}
748
749
static void
750
endif_extent(TextNode *node)
751
{
752
/*
753
* This node has the responsibilty for updating text_x and text_y so that
754
* they are the maxaimum width of teh else and then statements
755
*/
756
757
text_x = if_node->x;
758
text_y = if_node->y;
759
if_node = NULL;
760
}
761
762
static void
763
compute_ifcond_extent(TextNode *node)
764
{
765
TextNode *condnode = node->data.ifnode->cond;
766
TextNode *tln = gLineNode;
767
int store_x = text_x, store_y = text_y, lh = present_line_height;
768
int then_x, then_y;
769
770
/*
771
* This routine checks the value of the condition and swaps in the else
772
* or the then depending
773
*/
774
775
/*
776
* we have to compute the maximum width and height of the rest of the
777
* text and stuff
778
*/
779
push_group_stack();
780
if (gInLine && node->space)
781
text_x += inter_word_space;
782
compute_text_extent(node->data.ifnode->thennode);
783
then_x = text_x;
784
then_y = text_y;
785
text_x = store_x;
786
text_y = store_y;
787
present_line_height = lh;
788
gLineNode = tln;
789
if (gInLine && node->space)
790
text_x += inter_word_space;
791
compute_text_extent(node->data.ifnode->elsenode);
792
/* Now choose the best one that is biggest and put it into ifnode */
793
if (then_y > text_y) {
794
node->y = then_y;
795
node->x = then_x;
796
}
797
else if (text_y > then_y) {
798
node->y = text_y;
799
node->x = text_x;
800
}
801
else if (text_x > then_x) {
802
node->y = text_y;
803
node->x = text_x;
804
}
805
else {
806
node->y = then_y;
807
node->x = then_x;
808
}
809
/* restore everything */
810
text_x = store_x;
811
text_y = store_y;
812
present_line_height = lh;
813
gLineNode = tln;
814
node->width = 0;
815
816
if_node = node;
817
if (gInLine && node->space)
818
text_x += inter_word_space;
819
if (check_condition(condnode)) {
820
node->next = node->data.ifnode->thennode;
821
}
822
else {
823
node->next = node->data.ifnode->elsenode;
824
}
825
pop_group_stack();
826
}
827
828
static void
829
compute_center_extent(TextNode * node)
830
{
831
if (gInLine)
832
start_newline(present_line_height, node);
833
834
center_top_group();
835
836
if (gLineNode)
837
text_x = indent;
838
else {
839
fprintf(stderr, "(HyperDoc) Internal error: unexpected state in compute_center_extent.\n");
840
exit(-1);
841
}
842
}
843
844
static void
845
compute_bf_extent(TextNode *node)
846
{
847
if (gInLine && node->space)
848
text_x += inter_word_space;
849
node->x = text_x;
850
node->y = text_y;
851
bf_top_group();
852
}
853
854
static void
855
compute_em_extent(TextNode *node)
856
{
857
if (gInLine && node->space)
858
text_x += inter_word_space;
859
node->x = text_x;
860
node->y = text_y;
861
if (gTopOfGroupStack->cur_font == gEmFont)
862
rm_top_group();
863
else
864
em_top_group();
865
}
866
867
static void
868
compute_it_extent(TextNode *node)
869
{
870
if (gInLine && node->space)
871
text_x += inter_word_space;
872
node->x = text_x;
873
node->y = text_y;
874
}
875
876
static void
877
compute_rm_extent(TextNode *node)
878
{
879
if (gInLine && node->space)
880
text_x += inter_word_space;
881
node->x = text_x;
882
node->y = text_y;
883
rm_top_group();
884
}
885
886
static void
887
compute_button_extent(TextNode *node)
888
{
889
int twidth;
890
/*int store_x = text_x;*/
891
/*int store_y = text_y;*/
892
/*int lh = present_line_height;*/
893
894
push_active_group();
895
896
/* First see if we should leave a little space in front of myself * */
897
if (gInLine && node->space)
898
text_x += inter_word_space;
899
900
twidth = text_width(node->next, openaxiom_Endbutton_token);
901
if (gInLine && node->space)
902
text_x += inter_word_space;
903
if (text_x + twidth > right_margin && gInLine) {
904
start_newline(present_line_height, node);
905
text_x = indent;
906
}
907
node->x = text_x;
908
node->y = text_y;
909
link_node = node;
910
}
911
912
static void
913
endbutton_extent(TextNode *node)
914
{
915
int temp;
916
int height;
917
int twidth;
918
int y;
919
int maxx;
920
921
maxx = max_x(link_node, openaxiom_Endbutton_token);
922
link_node->width = twidth = text_width(link_node->next,
923
openaxiom_Endbutton_token);
924
height = link_node->y;
925
temp = text_height(link_node->next, openaxiom_Endbutton_token);
926
link_node->height = temp - link_node->y + line_height;
927
928
if (gInLine)
929
y = text_y;
930
else
931
y = text_y - past_line_height;
932
if (y > height) {
933
link_node->y = temp; /* height + link_node->height -
934
* normal_text_height; */
935
link_node->width = maxx - indent;
936
if (gInLine) {
937
start_newline(present_line_height, node);
938
text_x = indent;
939
}
940
}
941
else {
942
link_node->width = twidth;
943
link_node->y = text_y + link_node->height - line_height;
944
}
945
pop_group_stack();
946
link_node = NULL;
947
}
948
949
static void
950
compute_pastebutton_extent(TextNode *node)
951
{
952
int twidth;
953
954
push_active_group();
955
956
/*
957
First see if we should leave a little space in front of myself * */
958
959
if (gInLine && node->space)
960
text_x += inter_word_space;
961
962
twidth = text_width(node->next, openaxiom_Endpastebutton_token);
963
if (gInLine && node->space)
964
text_x += inter_word_space;
965
if (text_x + twidth > right_margin && gInLine) {
966
start_newline(present_line_height, node);
967
text_x = indent;
968
}
969
node->x = text_x;
970
node->y = text_y;
971
paste_node = node;
972
return;
973
}
974
975
static void
976
endpastebutton_extent(TextNode *node)
977
{
978
int temp;
979
int height;
980
int twidth;
981
982
paste_node->width = twidth = text_width(paste_node->next, openaxiom_Endpastebutton_token);
983
height = paste_node->y;
984
temp = text_height(paste_node->next, openaxiom_Endpastebutton_token);
985
paste_node->height = temp - paste_node->y + line_height;
986
if (text_y > height) {
987
paste_node->y = temp;
988
paste_node->width = right_margin - indent;
989
if (gInLine) {
990
start_newline(present_line_height, node);
991
text_x = indent;
992
}
993
}
994
else {
995
paste_node->width = twidth;
996
paste_node->y = text_y + paste_node->height - line_height;
997
}
998
pop_group_stack();
999
paste_node = NULL;
1000
gInLine = 1;
1001
}
1002
1003
static void
1004
compute_paste_extent(TextNode *node)
1005
{
1006
if (gInLine) {
1007
start_newline(present_line_height, node);
1008
text_x = indent;
1009
}
1010
node->x = text_x;
1011
node->y = text_y;
1012
node->height = line_height;
1013
}
1014
1015
/* Compute the text extent of a spadcommand node */
1016
1017
static void
1018
compute_spadcommand_extent(TextNode *node)
1019
{
1020
/*
1021
* From now on if there is an example which will take over a line, then
1022
* it will start and end with a newline
1023
*/
1024
1025
/*int height;*/
1026
int t_width;
1027
/*int store_x = text_x;*/
1028
/*int store_y = text_y;*/
1029
/*int lh = present_line_height;*/
1030
1031
gInAxiomCommand = 1;
1032
1033
push_spad_group();
1034
1035
/* Check to see if we should space in front of myself */
1036
if (gInLine && node->space)
1037
text_x += inter_word_space;
1038
t_width = text_width(node->next, openaxiom_Endspadcommand_token);
1039
if (gInLine && ((text_x + t_width) > right_margin)) {
1040
start_newline(present_line_height, node);
1041
text_x = indent;
1042
}
1043
node->x = text_x;
1044
node->y = text_y;
1045
spad_node = node;
1046
1047
}
1048
1049
static void
1050
compute_spadsrc_extent(TextNode *node)
1051
{
1052
/*
1053
* From now on if there is an example which will take over a line, then
1054
* it will start and end with a newline
1055
*/
1056
1057
/*int store_x = text_x;*/
1058
/*int store_y = text_y;*/
1059
/*int lh = present_line_height;*/
1060
1061
gInAxiomCommand = 1;
1062
1063
push_spad_group();
1064
1065
if (gInLine) {
1066
start_newline(present_line_height, node);
1067
text_x = indent;
1068
}
1069
node->x = text_x;
1070
node->y = text_y;
1071
spad_node = node;
1072
1073
}
1074
1075
static void
1076
end_spadcommand_extent(TextNode *node)
1077
{
1078
int temp;
1079
int height;
1080
int twidth;
1081
int maxx;
1082
/*int y = (gInLine) ? (text_y) : (text_y - past_line_height);*/
1083
1084
maxx = max_x(spad_node, openaxiom_Endspadcommand_token);
1085
twidth = spad_node->width = text_width(spad_node->next,
1086
openaxiom_Endspadcommand_token);
1087
height = spad_node->y;
1088
temp = text_height(spad_node->next, openaxiom_Endspadcommand_token);
1089
1090
spad_node->height = temp - height + line_height;
1091
if (text_y > height && gInLine) {
1092
spad_node->y = temp;
1093
spad_node->width = maxx - indent;
1094
start_newline(present_line_height, node);
1095
text_x = indent;
1096
}
1097
else {
1098
spad_node->width = twidth;
1099
spad_node->y = text_y - line_height + spad_node->height;
1100
}
1101
pop_group_stack();
1102
gInAxiomCommand = 0;
1103
spad_node = NULL;
1104
}
1105
1106
static void
1107
end_spadsrc_extent(TextNode *node)
1108
{
1109
int temp;
1110
int height;
1111
int twidth;
1112
int maxx;
1113
int y = (gInLine) ? (text_y) : (text_y - past_line_height);
1114
1115
maxx = max_x(spad_node, openaxiom_Endspadsrc_token);
1116
1117
twidth = spad_node->width = text_width(spad_node->next,
1118
openaxiom_Endspadsrc_token);
1119
height = spad_node->y;
1120
temp = text_height(spad_node->next, openaxiom_Endspadsrc_token);
1121
spad_node->height = temp - height + line_height;
1122
if (y > height && gInLine) {
1123
spad_node->y = temp;
1124
spad_node->width = maxx - indent;
1125
start_newline(present_line_height, node);
1126
text_x = indent;
1127
}
1128
else {
1129
spad_node->width = twidth;
1130
spad_node->y = text_y - line_height + spad_node->height;
1131
}
1132
pop_group_stack();
1133
gInAxiomCommand = 0;
1134
spad_node = NULL;
1135
}
1136
1137
static void
1138
compute_mbox_extent(TextNode *node)
1139
{
1140
node->width = text_width(node->next, openaxiom_Endmbox_token);
1141
if (node->space)
1142
text_x += inter_word_space;
1143
if (text_x + node->width > right_margin) {
1144
start_newline(present_line_height, node);
1145
text_x = indent;
1146
}
1147
node->x = text_x;
1148
node->y = text_y;
1149
}
1150
1151
static void
1152
compute_box_extent(TextNode *node)
1153
{
1154
int t_width;
1155
1156
/*
1157
* First thing we do is see if we need to skip some space in front of the
1158
* word
1159
*/
1160
1161
if (gInLine && node->space)
1162
text_x += inter_word_space;
1163
1164
/* Calculate the actual width of the box */
1165
1166
t_width = text_width(node->next, openaxiom_Endbox_token) + 2 * box_width;
1167
1168
if (text_x + t_width > right_margin) {
1169
start_newline(present_line_height, node);
1170
text_x = indent;
1171
}
1172
node->x = text_x;
1173
text_x = text_x + box_width;
1174
node->y = text_y - 2;
1175
node->width = t_width;
1176
node->height = line_height - 2;
1177
gInLine = 1;
1178
}
1179
1180
static void
1181
compute_ir_extent(TextNode *node)
1182
{
1183
int t_width;
1184
1185
/*
1186
* First thing we do is see if we need to skip some space in front of the
1187
* word
1188
*/
1189
1190
if (gInLine && node->space)
1191
text_x += inter_word_space;
1192
1193
/* Calculate the actual width of the box */
1194
1195
t_width = node->width;
1196
1197
if (text_x + t_width > right_margin) {
1198
start_newline(present_line_height, node);
1199
text_x = indent;
1200
}
1201
node->x = text_x;
1202
if (node->height > line_height) {
1203
node->height = present_line_height = plh(node->height + inter_line_space);
1204
node->y = text_y + node->height - normal_text_height;
1205
}
1206
else {
1207
node->y = text_y - line_height + node->height;
1208
}
1209
gInLine = 1;
1210
text_x += node->width;
1211
}
1212
1213
/* read a bitmap file into memory */
1214
1215
static void
1216
compute_image_extent(TextNode *node)
1217
{
1218
if (text_x + node->width > right_margin) {
1219
start_newline(present_line_height, node);
1220
text_x = indent;
1221
}
1222
node->x = text_x;
1223
if (node->height > line_height) {
1224
present_line_height = plh(node->height + inter_line_space);
1225
node->y = text_y + node->height - line_height;
1226
}
1227
else {
1228
node->y = text_y - line_height + node->height;
1229
}
1230
text_x += node->width;
1231
gInLine = 1;
1232
}
1233
1234
/*
1235
* compute the coordinates of the entries in a table
1236
*/
1237
1238
static void
1239
compute_table_extent(TextNode **node)
1240
{
1241
int num_cols, num_lines;
1242
int max_width = 0, node_width, col_width;
1243
int x, y, num_entries = 0,/* n=0, */ screen_width, table_top;
1244
TextNode *front = *node;
1245
TextNode *tn;
1246
1247
gInTable = 1;
1248
front->x = text_x;
1249
front->y = text_y;
1250
for (tn = front->next; tn->type != openaxiom_Endtable_token;
1251
num_entries++, tn = tn->next) {
1252
/* Now we need to scan the table group by group */
1253
node_width = text_width(tn->next, openaxiom_Endtableitem_token);
1254
if (node_width > max_width)
1255
max_width = node_width;
1256
/* Get to the beginning og the next group */
1257
for (; tn->type != openaxiom_Endtableitem_token; tn = tn->next);
1258
}
1259
col_width = max_width + min_inter_column_space;
1260
screen_width = gWindow->width - right_margin_space - indent;
1261
num_cols = screen_width / col_width;
1262
if (num_cols == 0)
1263
num_cols = 1;
1264
num_lines = num_entries / num_cols;
1265
if (num_entries % num_cols != 0)
1266
++num_lines;
1267
if (gInLine) {
1268
start_newline(present_line_height, *node);
1269
}
1270
table_top = text_y;
1271
num_cols = num_entries / num_lines;
1272
if (num_entries % num_lines != 0)
1273
++num_cols;
1274
col_width = screen_width / num_cols;
1275
for (tn = front->next, x = 0; x < num_cols; x++)
1276
for (y = 0; y < num_lines && tn->type != openaxiom_Endtable_token; y++) {
1277
if (num_cols == 1 && y > 0)
1278
text_y += line_height;
1279
else
1280
text_y = table_top + y * line_height;
1281
text_x = indent + x * col_width;
1282
gInLine = 0;
1283
compute_text_extent(tn->next);
1284
for (; tn->type != openaxiom_Endtableitem_token; tn = tn->next);
1285
tn = tn->next;
1286
}
1287
front->height = num_lines * line_height;
1288
front->width = screen_width;
1289
text_x = indent;
1290
if (num_cols == 1)
1291
text_y += line_height;
1292
else
1293
text_y = table_top + front->height;
1294
*node = tn;
1295
gInLine = 0;
1296
}
1297
1298
void
1299
compute_title_extent(HyperDocPage *page)
1300
{
1301
right_margin_space = non_scroll_right_margin_space;
1302
page->title->height = twheight + gWindow->border_width;
1303
page->title->x = gWindow->border_width + 2 * twwidth + (int) gWindow->border_width / 2;
1304
gLineNode = page->title->next;
1305
init_title_extents(page);
1306
text_y = top_margin + line_height;
1307
compute_text_extent(page->title->next);
1308
page->title->height = max(text_height(page->title->next,
1309
openaxiom_Endtitle_token),
1310
twheight);
1311
}
1312
1313
void
1314
compute_header_extent(HyperDocPage *page)
1315
{
1316
1317
/*
1318
* Hopefully we will soon be able to actually compute the needed height
1319
* for the header here
1320
*/
1321
1322
int ty; /* UNUSED */
1323
1324
gExtentRegion = Header;
1325
right_margin_space = non_scroll_right_margin_space;
1326
init_extents();
1327
ty = text_y = 3 * top_margin + line_height + max(page->title->height, twheight);
1328
gLineNode = page->header->next;
1329
compute_text_extent(page->header->next);
1330
page->header->height = text_height(page->header->next,
1331
openaxiom_Endheader_token);
1332
if (page->header->height) {
1333
page->header->height += 1 / 2 * line_height;
1334
page->top_scroll_margin = (gInLine) ? text_y : text_y - past_line_height;
1335
if (!(page->page_flags & NOLINES))
1336
page->top_scroll_margin += (int) line_height / 2;
1337
page->top_scroll_margin += gWindow->border_width + 2 * top_margin;
1338
}
1339
else {
1340
page->top_scroll_margin = page->title->height + gWindow->border_width +
1341
2 * scroll_top_margin;
1342
}
1343
}
1344
1345
void
1346
compute_footer_extent(HyperDocPage * page)
1347
{
1348
if (page->footer) {
1349
gExtentRegion = Footer;
1350
right_margin_space = non_scroll_right_margin_space;
1351
init_extents();
1352
present_line_height = line_height;
1353
text_y = line_height;
1354
gLineNode = page->footer->next;
1355
compute_text_extent(page->footer->next);
1356
page->footer->height = text_height(page->footer->next,
1357
openaxiom_Endfooter_token);
1358
if (page->footer->height) {
1359
if ((!page->page_flags & NOLINES))
1360
page->footer->height += (int) line_height / 2;
1361
page->bot_scroll_margin = gWindow->height -
1362
page->footer->height - bottom_margin
1363
- gWindow->border_width + top_margin;
1364
}
1365
else
1366
page->bot_scroll_margin = gWindow->height;
1367
}
1368
}
1369
1370
void
1371
compute_scrolling_extent(HyperDocPage *page)
1372
{
1373
/* Check to see if there is a scrolling region */
1374
1375
if (!page->scrolling) {
1376
return;
1377
}
1378
noop_count = 0;
1379
1380
/* If there is then compute all the proper locations */
1381
gExtentRegion = Scrolling;
1382
right_margin_space = non_scroll_right_margin_space + gScrollbarWidth;
1383
init_extents();
1384
text_y = line_height;
1385
gLineNode = page->scrolling->next;
1386
compute_text_extent(page->scrolling->next);
1387
1388
/*
1389
* the following is an attempt to fix the bug where one cannot scroll
1390
* down to a bitmap that is opened at the bottom of a page.
1391
*/
1392
1393
/*
1394
* TTT trial if(!gInLine)
1395
*/
1396
if (0) {
1397
text_y = text_y - past_line_height;
1398
}
1399
else if (present_line_height > line_height)
1400
text_y = text_y + present_line_height - line_height;
1401
page->scrolling->height = text_y;
1402
1403
}
1404
1405