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
* extent2.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 "halloc.h"
47
#include "sockio.h"
48
#include "extent.h"
49
#include "group.h"
50
#include "titlebar.h"
51
#include "cfuns.h"
52
53
using namespace OpenAxiom;
54
55
static void center_nodes(TextNode * begin_node , TextNode * end_node);
56
static int input_string_width(TextNode * node);
57
static int punctuation_width(TextNode * node);
58
static int text_height1(TextNode * node , int Ender);
59
static int verbatim_width(TextNode * node);
60
static int width_of_dash(TextNode * node);
61
static int word_width(TextNode * node);
62
static int x_value(TextNode * node);
63
64
static int cur_height = 0;
65
static int max_x_value = 0;
66
67
/*
68
* start_newline updates the current header node, and also allocates if needed
69
* memory for the next Line Header. It also assigns the first TextNode on the
70
* line to the structure, because this is the last time I will be able to do
71
* this
72
*/
73
74
void
75
start_newline(int distance, TextNode * node)
76
{
77
if (gLineNode != NULL) {
78
if (gTopOfGroupStack->center)
79
center_nodes(gLineNode, node);
80
gLineNode = node;
81
}
82
text_y += distance;
83
past_line_height = distance;
84
present_line_height = line_height;
85
gInLine = 0;
86
}
87
88
/*
89
* center_nodes goes through and centers all the text between the two
90
* given nodes.
91
*/
92
93
static void
94
center_nodes(TextNode * begin_node, TextNode * end_node)
95
{
96
int begin_x, end_x, wmid_x, offset, mid_x;
97
TextNode *node;
98
99
end_x = text_x;
100
begin_x = x_value(begin_node);
101
mid_x = (int) (end_x + begin_x) / 2;
102
wmid_x = (int) (right_margin + indent) / 2;
103
104
if (mid_x > wmid_x)
105
offset = 0;
106
else
107
offset = wmid_x - mid_x;
108
109
for (node = begin_node; node != end_node; node = node->next)
110
if (node->x > 0)
111
node->x += offset;
112
}
113
114
static int
115
punctuation_width(TextNode * node)
116
{
117
int twidth, width = strlen(node->data.text);
118
119
twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, width);
120
121
/* check to see if there was some space in front */
122
123
if (gInLine && (node->space & FRONTSPACE))
124
twidth += inter_word_space;
125
126
# if 0
127
if (node->space & BACKSPACE) {
128
switch (node->data.text[0]) {
129
case '.':
130
case '?':
131
case '!':
132
twidth += term_punct_space;
133
break;
134
}
135
}
136
#endif
137
138
return twidth;
139
}
140
141
static int
142
input_string_width(TextNode * node)
143
{
144
InputItem *item;
145
int t_width;
146
147
/** search the symbol table for the proper entry **/
148
149
item = node->link->reference.string;
150
151
/** Once I have gotten this far, I should just be able to calculate
152
the width using the normal font **/
153
154
t_width = (item->size + 1) * gInputFont->max_bounds.width + 10;
155
return t_width;
156
157
}
158
159
static int
160
word_width(TextNode * node)
161
{
162
int twidth, len = strlen(node->data.text);
163
164
twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len);
165
if (node->space & FRONTSPACE)
166
twidth += inter_word_space;
167
168
return twidth;
169
}
170
171
static int
172
verbatim_width(TextNode * node)
173
{
174
int twidth, len = strlen(node->data.text);
175
176
twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len);
177
if (node->space)
178
twidth += inter_word_space;
179
180
return twidth;
181
}
182
183
static int
184
width_of_dash(TextNode * node)
185
{
186
int num_dashes, twidth;
187
188
num_dashes = strlen(node->data.text);
189
if (num_dashes > 1)
190
twidth = node->width = num_dashes * dash_width;
191
else
192
twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font,
193
node->data.text, 1);
194
if (node->space)
195
twidth += inter_word_space;
196
return twidth;
197
}
198
199
/*
200
* return the gWindow->width in pixels of the given text node, when
201
* displayed
202
*/
203
204
int
205
text_width(TextNode * node, int Ender)
206
{
207
int twidth = 0, num_words;
208
209
for (num_words = 0; node != NULL; num_words++, node = node->next) {
210
if (Ender == openaxiom_Endtokens_token) {
211
if (node->type == openaxiom_Endtokens_token)
212
return twidth;
213
}
214
else if (node->type == Ender)
215
return twidth;
216
217
switch (node->type) {
218
case openaxiom_Macro_token:
219
case openaxiom_Pound_token:
220
if (node->space && gInLine)
221
twidth += inter_word_space;
222
break;
223
case openaxiom_Punctuation_token:
224
twidth += punctuation_width(node);
225
break;
226
case openaxiom_Dash_token:
227
if (gInLine && node->space)
228
twidth += inter_word_space;
229
twidth += width_of_dash(node);
230
break;
231
case openaxiom_Verbatim_token:
232
case openaxiom_Spadsrctxt_token:
233
twidth += verbatim_width(node);
234
break;
235
case openaxiom_Lsquarebrace_token:
236
case openaxiom_Rsquarebrace_token:
237
case openaxiom_Word_token:
238
twidth += word_width(node);
239
break;
240
case openaxiom_Box_token:
241
twidth += 2 * box_space;
242
break;
243
case openaxiom_Link_token:
244
case openaxiom_Downlink_token:
245
case openaxiom_Memolink_token:
246
case openaxiom_Windowlink_token:
247
case openaxiom_LispMemoLink_token:
248
case openaxiom_Lispwindowlink_token:
249
case openaxiom_Lisplink_token:
250
case openaxiom_Unixlink_token:
251
case openaxiom_Spadcall_token:
252
case openaxiom_Spadcallquit_token:
253
case openaxiom_Qspadcall_token:
254
case openaxiom_Qspadcallquit_token:
255
case openaxiom_LispDownLink_token:
256
case openaxiom_Lispcommand_token:
257
case openaxiom_Lispcommandquit_token:
258
case openaxiom_Spadlink_token:
259
case openaxiom_Spaddownlink_token:
260
case openaxiom_Spadmemolink_token:
261
case openaxiom_Unixcommand_token:
262
case openaxiom_Upbutton_token:
263
case openaxiom_Returnbutton_token:
264
case openaxiom_Description_token:
265
push_active_group();
266
break;
267
case openaxiom_Endbutton_token:
268
case openaxiom_Endspadcommand_token:
269
case openaxiom_Enddescription_token:
270
pop_group_stack();
271
break;
272
case openaxiom_Endlink_token:
273
pop_group_stack();
274
break;
275
case openaxiom_Inputstring_token:
276
twidth += input_string_width(node);
277
break;
278
case openaxiom_SimpleBox_token:
279
case openaxiom_Radiobox_token:
280
twidth += node->width + ((node->space) ? inter_word_space : 0);
281
break;
282
case openaxiom_Spadcommand_token:
283
case openaxiom_Spadgraph_token:
284
push_spad_group();
285
break;
286
case openaxiom_VSpace_token:
287
break;
288
case openaxiom_HSpace_token:
289
twidth +=
290
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
291
break;
292
case openaxiom_Space_token:
293
twidth += (gTopOfGroupStack->cur_font->max_bounds.width) *
294
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
295
break;
296
case openaxiom_Tab_token:
297
twidth = (gTopOfGroupStack->cur_font->max_bounds.width) *
298
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
299
break;
300
case openaxiom_Table_token:
301
twidth = gWindow->width - left_margin - right_margin_space;
302
break;
303
case openaxiom_Tableitem_token:
304
case openaxiom_Group_token:
305
twidth += (node->space) ? inter_word_space : 0;
306
push_group_stack();
307
break;
308
case openaxiom_BoldFace_token:
309
if (node->space)
310
twidth += inter_word_space;
311
bf_top_group();
312
break;
313
case openaxiom_Emphasize_token:
314
if (node->space)
315
twidth += inter_word_space;
316
if (gTopOfGroupStack->cur_font == gRmFont)
317
em_top_group();
318
else
319
rm_top_group();
320
break;
321
case openaxiom_It_token:
322
if (node->space)
323
twidth += inter_word_space;
324
em_top_group();
325
break;
326
case openaxiom_Rm_token:
327
case openaxiom_Sl_token:
328
case openaxiom_Tt_token:
329
if (node->space)
330
twidth += inter_word_space;
331
rm_top_group();
332
break;
333
case openaxiom_Endgroup_token:
334
pop_group_stack();
335
break;
336
case openaxiom_Controlbitmap_token:
337
case openaxiom_Inputbitmap_token:
338
if (node->width == -1)
339
insert_bitmap_file(node);
340
twidth += node->width;
341
break;
342
case openaxiom_Inputpixmap_token:
343
if (node->width == -1)
344
insert_pixmap_file(node);
345
twidth += node->width;
346
break;
347
case openaxiom_Mbox_token:
348
case openaxiom_Indent_token:
349
case openaxiom_Endmacro_token:
350
case openaxiom_Free_token:
351
case openaxiom_Bound_token:
352
case openaxiom_Beep_token:
353
case openaxiom_Item_token:
354
case openaxiom_Titem_token:
355
case openaxiom_Beginitems_token:
356
case openaxiom_Noop_token:
357
case openaxiom_Endinputbox_token:
358
case openaxiom_Fi_token:
359
case openaxiom_Ifcond_token:
360
case openaxiom_Endif_token:
361
case openaxiom_Begintitems_token:
362
case openaxiom_Enditems_token:
363
case openaxiom_Endtitems_token:
364
case openaxiom_Endtableitem_token:
365
case openaxiom_Endtable_token:
366
case openaxiom_Endparameter_token:
367
case openaxiom_Endbox_token:
368
case openaxiom_Endheader_token:
369
case openaxiom_Endfooter_token:
370
case openaxiom_Endscrolling_token:
371
case openaxiom_Endverbatim_token:
372
case openaxiom_Endspadsrc_token:
373
break;
374
case openaxiom_Newline_token:
375
/* WOw, I guess I should ertunr a really big number */
376
twidth += gWindow->width;
377
break;
378
default:
379
380
/*
381
* fprintf(stderr, "Unknown nodetype %d in text_width\n",
382
* node->type);
383
*/
384
break;
385
}
386
}
387
return twidth;
388
}
389
390
/*
391
* total_width traces through the nodes, until it finds a blank space. It is
392
* used by compute_word_extent, and compute_punctuation extent to determine
393
* How far we go before we actually see white space.
394
*/
395
396
int
397
total_width(TextNode * node, int Ender)
398
{
399
int twidth = 0;
400
401
for (; (node != NULL); node = node->next) {
402
if (Ender == openaxiom_Endtokens_token) {
403
if (node->type >= openaxiom_Endtokens_token)
404
return twidth;
405
}
406
else if (node->type == Ender)
407
return twidth;
408
409
/*
410
* The first thing we check for is to see if there was space in front
411
* of the current node, if so we are done
412
*/
413
414
if (node->space)
415
return twidth;
416
417
/*** Else depending on the node type ***/
418
419
switch (node->type) {
420
case openaxiom_Noop_token:
421
case openaxiom_Endinputbox_token:
422
case openaxiom_Pound_token:
423
case openaxiom_Ifcond_token:
424
case openaxiom_Fi_token:
425
case openaxiom_Endif_token:
426
break;
427
case openaxiom_Rsquarebrace_token:
428
case openaxiom_Punctuation_token:
429
case openaxiom_Word_token:
430
case openaxiom_Dash_token:
431
twidth += XTextWidth(gTopOfGroupStack->cur_font, node->data.text,
432
strlen(node->data.text));
433
break;
434
case openaxiom_Box_token:
435
case openaxiom_Link_token:
436
case openaxiom_Downlink_token:
437
case openaxiom_Memolink_token:
438
case openaxiom_Windowlink_token:
439
case openaxiom_LispMemoLink_token:
440
case openaxiom_Lispwindowlink_token:
441
case openaxiom_Lisplink_token:
442
case openaxiom_Unixlink_token:
443
case openaxiom_Spadcall_token:
444
case openaxiom_Spadcallquit_token:
445
case openaxiom_Qspadcall_token:
446
case openaxiom_Qspadcallquit_token:
447
case openaxiom_LispDownLink_token:
448
case openaxiom_Lispcommand_token:
449
case openaxiom_Lispcommandquit_token:
450
case openaxiom_Spadlink_token:
451
case openaxiom_Spaddownlink_token:
452
case openaxiom_Spadmemolink_token:
453
case openaxiom_Unixcommand_token:
454
case openaxiom_Inputstring_token:
455
case openaxiom_SimpleBox_token:
456
case openaxiom_Radiobox_token:
457
case openaxiom_Upbutton_token:
458
case openaxiom_Returnbutton_token:
459
case openaxiom_Spadcommand_token:
460
case openaxiom_Spadgraph_token:
461
case openaxiom_VSpace_token:
462
case openaxiom_HSpace_token:
463
case openaxiom_Space_token:
464
case openaxiom_Table_token:
465
case openaxiom_Group_token:
466
case openaxiom_Controlbitmap_token:
467
case openaxiom_Inputbitmap_token:
468
case openaxiom_Inputpixmap_token:
469
case openaxiom_Free_token:
470
case openaxiom_Beep_token:
471
case openaxiom_Bound_token:
472
case openaxiom_Lsquarebrace_token:
473
case openaxiom_BoldFace_token:
474
case openaxiom_Emphasize_token:
475
case openaxiom_It_token:
476
case openaxiom_Rm_token:
477
case openaxiom_Sl_token:
478
case openaxiom_Tt_token:
479
case openaxiom_Newline_token:
480
case openaxiom_Verbatim_token:
481
case openaxiom_Spadsrctxt_token:
482
return twidth;
483
default:
484
break;
485
}
486
}
487
return twidth;
488
}
489
490
/*
491
* init_extents initialize some text size variables
492
*/
493
494
void
495
init_extents()
496
{
497
present_line_height = line_height;
498
gInLine = 0;
499
gInItem = 0;
500
gInAxiomCommand = 0;
501
item_indent = 0;
502
gInDesc = 0;
503
indent = left_margin;
504
text_x = indent;
505
gTopOfGroupStack->cur_font = gRmFont;
506
gTopOfGroupStack->cur_color = gRmColor;
507
right_margin = gWindow->width - right_margin_space;
508
clear_item_stack();
509
}
510
511
/*
512
* init_title_extents initialize some title text size variables
513
*/
514
515
void
516
init_title_extents(HyperDocPage * page)
517
{
518
present_line_height = line_height;
519
gInLine = 0;
520
gInAxiomCommand = 0;
521
item_indent = 0;
522
gInDesc = 0;
523
indent = left_margin + page->title->x;
524
text_x = indent;
525
gTopOfGroupStack->cur_font = gRmFont;
526
gTopOfGroupStack->cur_color = gRmColor;
527
right_margin = gWindow->width - right_margin_space - gWindow->border_width -
528
2 * twwidth;
529
clear_item_stack();
530
}
531
532
/*
533
* init_text initialize some text size variables
534
*/
535
536
void
537
init_text()
538
{
539
normal_text_height = gRmFont->ascent + gRmFont->descent;
540
line_height = gRmFont->ascent + gRmFont->descent + inter_line_space;
541
word_off_height = line_height - normal_text_height;
542
space_width = gRmFont->max_bounds.width;
543
}
544
545
/*
546
* text_height returns the height of a piece of formatted text in pixels
547
*/
548
549
int
550
text_height(TextNode * node, int Ender)
551
{
552
cur_height = 0;
553
return text_height1(node, Ender);
554
}
555
556
/*
557
* text_height1 is the recursive part of text_height
558
*/
559
560
static int
561
text_height1(TextNode * node, int Ender)
562
{
563
for (; node != NULL; node = node->next) {
564
if (Ender == openaxiom_Endtokens_token) {
565
if (node->type > -openaxiom_Endtokens_token)
566
return cur_height;
567
}
568
else if (node->type == Ender)
569
return cur_height;
570
switch (node->type) {
571
case openaxiom_Center_token:
572
case openaxiom_Downlink_token:
573
case openaxiom_Link_token:
574
case openaxiom_Spadcommand_token:
575
case openaxiom_Spadgraph_token:
576
case openaxiom_Upbutton_token:
577
case openaxiom_Returnbutton_token:
578
case openaxiom_Windowlink_token:
579
case openaxiom_Memolink_token:
580
case openaxiom_Lispwindowlink_token:
581
case openaxiom_Lisplink_token:
582
case openaxiom_Unixlink_token:
583
case openaxiom_Spadcall_token:
584
case openaxiom_Spadcallquit_token:
585
case openaxiom_Qspadcall_token:
586
case openaxiom_Qspadcallquit_token:
587
case openaxiom_LispDownLink_token:
588
case openaxiom_LispMemoLink_token:
589
case openaxiom_Lispcommand_token:
590
case openaxiom_Lispcommandquit_token:
591
case openaxiom_Spadlink_token:
592
case openaxiom_Spaddownlink_token:
593
case openaxiom_Spadmemolink_token:
594
case openaxiom_Unixcommand_token:
595
case openaxiom_SimpleBox_token:
596
case openaxiom_Radiobox_token:
597
case openaxiom_Group_token:
598
case openaxiom_Box_token:
599
case openaxiom_Controlbitmap_token:
600
case openaxiom_Inputbitmap_token:
601
case openaxiom_Inputpixmap_token:
602
case openaxiom_Horizontalline_token:
603
case openaxiom_Punctuation_token:
604
case openaxiom_Lsquarebrace_token:
605
case openaxiom_Rsquarebrace_token:
606
case openaxiom_Word_token:
607
case openaxiom_Verbatim_token:
608
case openaxiom_Math_token:
609
case openaxiom_Spadsrctxt_token:
610
case openaxiom_Dash_token:
611
case openaxiom_Inputstring_token:
612
cur_height = max(node->y, cur_height);
613
break;
614
case openaxiom_Mbox_token:
615
case openaxiom_Macro_token:
616
case openaxiom_Pound_token:
617
case openaxiom_Emphasize_token:
618
case openaxiom_BoldFace_token:
619
case openaxiom_It_token:
620
case openaxiom_Rm_token:
621
case openaxiom_Sl_token:
622
case openaxiom_Tt_token:
623
case openaxiom_Endparameter_token:
624
case openaxiom_Description_token:
625
case openaxiom_Enddescription_token:
626
case openaxiom_Noop_token:
627
case openaxiom_Fi_token:
628
case openaxiom_Ifcond_token:
629
case openaxiom_Endif_token:
630
case openaxiom_Endinputbox_token:
631
case openaxiom_Tab_token:
632
case openaxiom_Newline_token:
633
case openaxiom_Space_token:
634
case openaxiom_VSpace_token:
635
case openaxiom_HSpace_token:
636
case openaxiom_Beginitems_token:
637
case openaxiom_Begintitems_token:
638
case openaxiom_Endtitems_token:
639
case openaxiom_Titem_token:
640
case openaxiom_Enditems_token:
641
case openaxiom_Endtable_token:
642
case openaxiom_Endtableitem_token:
643
case openaxiom_Item_token:
644
case openaxiom_Par_token:
645
case openaxiom_Beep_token:
646
case openaxiom_Free_token:
647
case openaxiom_Bound_token:
648
case openaxiom_Endgroup_token:
649
case openaxiom_Endcenter_token:
650
case openaxiom_Endbutton_token:
651
case openaxiom_Endmacro_token:
652
case openaxiom_Tableitem_token:
653
case openaxiom_Endlink_token:
654
case openaxiom_Endspadcommand_token:
655
case openaxiom_Indent_token:
656
case openaxiom_Indentrel_token:
657
case openaxiom_Endbox_token:
658
case openaxiom_Endmbox_token:
659
case openaxiom_Table_token:
660
case openaxiom_Endverbatim_token:
661
case openaxiom_Endmath_token:
662
case openaxiom_Spadsrc_token:
663
case openaxiom_Endspadsrc_token:
664
break;
665
case openaxiom_Beginscroll_token:
666
case openaxiom_Endscroll_token:
667
break;
668
case openaxiom_Endscrolling_token:
669
return cur_height;
670
default:
671
672
/*
673
* fprintf(stderr, "Text_height1: Unknown Node Type %d\n",
674
* node->type);
675
*/
676
break;
677
}
678
}
679
return cur_height;
680
}
681
682
/*
683
* max_x returns the height of a piece of formatted text in pixels
684
*/
685
686
int
687
max_x(TextNode * node, int Ender)
688
{
689
max_x_value = 0;
690
for (; node != NULL; node = node->next) {
691
if (Ender == openaxiom_Endtokens_token) {
692
if (node->type >= openaxiom_Endtokens_token)
693
return max_x_value;
694
}
695
else if (node->type == Ender)
696
return max_x_value;
697
switch (node->type) {
698
case openaxiom_Lsquarebrace_token:
699
case openaxiom_Rsquarebrace_token:
700
case openaxiom_Word_token:
701
max_x_value = max(max_x_value, node->x + word_width(node));
702
break;
703
case openaxiom_Verbatim_token:
704
case openaxiom_Spadsrctxt_token:
705
max_x_value = max(max_x_value, node->x + verbatim_width(node));
706
break;
707
case openaxiom_Punctuation_token:
708
max_x_value = max(max_x_value, node->x + punctuation_width(node));
709
break;
710
case openaxiom_Dash_token:
711
max_x_value = max(max_x_value, node->x + width_of_dash(node));
712
break;
713
case openaxiom_HSpace_token:
714
max_x_value = max(max_x_value, node->x +
715
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1));
716
break;
717
case openaxiom_Space_token:
718
max_x_value = max(max_x_value, node->x +
719
(gTopOfGroupStack->cur_font->max_bounds.width) *
720
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1));
721
break;
722
case openaxiom_Group_token:
723
push_group_stack();
724
break;
725
case openaxiom_BoldFace_token:
726
bf_top_group();
727
break;
728
case openaxiom_Emphasize_token:
729
if (gTopOfGroupStack->cur_font == gRmFont)
730
em_top_group();
731
else
732
rm_top_group();
733
break;
734
case openaxiom_It_token:
735
em_top_group();
736
break;
737
case openaxiom_Rm_token:
738
case openaxiom_Sl_token:
739
case openaxiom_Tt_token:
740
rm_top_group();
741
break;
742
case openaxiom_Endgroup_token:
743
pop_group_stack();
744
break;
745
case openaxiom_Controlbitmap_token:
746
case openaxiom_Inputbitmap_token:
747
if (node->width == -1)
748
insert_bitmap_file(node);
749
max_x_value = max(max_x_value, node->x + node->width);
750
break;
751
case openaxiom_Inputpixmap_token:
752
if (node->width == -1)
753
insert_pixmap_file(node);
754
max_x_value = max(max_x_value, node->y + node->width);
755
break;
756
default:
757
break;
758
}
759
}
760
return cur_height;
761
}
762
763
static int
764
x_value(TextNode * node)
765
{
766
for (; node != NULL; node = node->next) {
767
switch (node->type) {
768
case openaxiom_Controlbitmap_token:
769
case openaxiom_Inputbitmap_token:
770
case openaxiom_Inputpixmap_token:
771
case openaxiom_Lsquarebrace_token:
772
case openaxiom_Rsquarebrace_token:
773
case openaxiom_Word_token:
774
case openaxiom_Verbatim_token:
775
case openaxiom_Spadsrctxt_token:
776
case openaxiom_Dash_token:
777
case openaxiom_Punctuation_token:
778
case openaxiom_VSpace_token:
779
case openaxiom_HSpace_token:
780
case openaxiom_Horizontalline_token:
781
case openaxiom_Box_token:
782
case openaxiom_Downlink_token:
783
case openaxiom_Link_token:
784
case openaxiom_Lispwindowlink_token:
785
case openaxiom_Lisplink_token:
786
case openaxiom_Unixlink_token:
787
case openaxiom_Spadcall_token:
788
case openaxiom_Spadcallquit_token:
789
case openaxiom_Qspadcall_token:
790
case openaxiom_Qspadcallquit_token:
791
case openaxiom_LispDownLink_token:
792
case openaxiom_LispMemoLink_token:
793
case openaxiom_Lispcommand_token:
794
case openaxiom_Lispcommandquit_token:
795
case openaxiom_Spadlink_token:
796
case openaxiom_Spaddownlink_token:
797
case openaxiom_Spadmemolink_token:
798
case openaxiom_Spadcommand_token:
799
case openaxiom_Spadgraph_token:
800
case openaxiom_Unixcommand_token:
801
case openaxiom_Space_token:
802
case openaxiom_SimpleBox_token:
803
case openaxiom_Radiobox_token:
804
return node->x;
805
default:
806
#ifdef DEBUG
807
fprintf(stderr, "X_value did not know x value of type %d\n", node->type);
808
#endif
809
return x_value(node->next);
810
}
811
}
812
return 0;
813
}
814
815
/*
816
* trailing_space computes the length of the trailing spaces of a node
817
*/
818
819
int
820
trailing_space(TextNode * node)
821
{
822
int space = 0;
823
824
for (; node->type < openaxiom_Endtokens_token; node = node->next);
825
if (node->type == openaxiom_Space_token)
826
space += inter_word_space *
827
(node->data.node != NULL ? atoi(node->data.node->data.text) : 1);
828
return space;
829
}
830
831
/*
832
* insert_bitmap_file reads a bitmap file into memory
833
*/
834
835
void
836
insert_bitmap_file(TextNode * node)
837
{
838
char *filename = node->data.text;
839
int bm_width, bm_height;
840
XImage *im;
841
ImageStruct *image;
842
843
if (*filename == ' ')
844
filename++;
845
if (node->image.pm == 0) {
846
if (
847
((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL)
848
|| (oa_getenv("HTCACHE"))) {
849
850
/*
851
* read the bitmap if not already in memory or if the environment
852
* variable HTCACHE is set (NAG addition).
853
*/
854
855
im = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename,
856
&bm_width, &bm_height);
857
858
/** now add the image to the gImageHashTable **/
859
image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct");
860
image->image.xi = im;
861
image->width = image->image.xi->width;
862
image->height = image->image.xi->height;
863
image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1,"Image Filename");
864
/* strcpy(image->filename, filename); */
865
sprintf(image->filename, "%s", filename);
866
hash_insert(&gImageHashTable, (char *)image, image->filename);
867
}
868
node->width = image->width;
869
node->height = image->height;
870
node->image.xi = image->image.xi;
871
}
872
}
873
874
/*
875
* insert_pixmap_file reads a pixmap file into memory
876
*/
877
878
void
879
insert_pixmap_file(TextNode * node)
880
{
881
char *filename = node->data.text;
882
int bm_width, bm_height, ret_val;
883
XImage *xi;
884
ImageStruct *image;
885
886
if (*filename == ' ')
887
filename++;
888
if (node->image.xi == 0) {
889
if ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) {
890
ret_val = read_pixmap_file(gXDisplay, gXScreenNumber, filename, &xi,
891
&bm_width, &bm_height);
892
switch (ret_val) {
893
case(-1):
894
gSwitch_to_mono = 1;
895
return;
896
case BitmapFileInvalid:
897
fprintf(stderr, "File %s contains invalid bitmap data\n", filename);
898
return;
899
case BitmapOpenFailed:
900
fprintf(stderr, "couldn't open bitmap file %s\n", filename);
901
return;
902
case BitmapNoMemory:
903
fprintf(stderr, "not enough memory to store bitmap\n");
904
return;
905
}
906
image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct");
907
image->width = bm_width;
908
image->height = bm_height;
909
image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1,
910
"insert_pixmap--filename");
911
/* strcpy(image->filename, filename); */
912
sprintf(image->filename, "%s", filename);
913
image->image.xi = xi;
914
hash_insert(&gImageHashTable, (char *)image, image->filename);
915
}
916
node->width = image->width;
917
node->height = plh(image->height + inter_line_space);
918
node->image.xi = image->image.xi;
919
}
920
}
921
922
/*
923
* plh calculates the closet value of line_height > height
924
*/
925
926
int
927
plh(int height)
928
{
929
int rheight = height;
930
931
if (gExtentRegion == Scrolling) {
932
for (rheight = line_height; rheight < height; rheight += line_height)
933
;
934
}
935
return rheight;
936
}
937
938