hypertext.anubis
31.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
The Anubis Project.
A Widget System (4th version).
Creating new widgets.
Copyright (c) Alain Proute' 2005.
Authors: Alain Prouté
Olivier Duvernois
read widget.anubis
read tools.anubis
read tools/basis.anubis
read image.anubis
This file defines the 'hypertext' widget. This widget displays a text from a 'String',
interpreting a few 'control characters'. The text may contain widgets inserted in it
(hence the name 'hypertext'). You can choose the size of the font and the color of
characters. The text is supposed to be fixed, hence no variable is given for creating
an hypertext widget. Some special visual effects may be achieved:
public type WidgetTextEffect:
// no effect
normal (RGB color), // color of text
// shadow effect (of course, the shadow is under the text)
shadow (RGB main_color, // color of text
RGB shadow_color, // color for shadow of text
Int32 dx, Int32 dy), // position of shadow relative to text
// engraving effect
engraved (RGB color), // the text seems to be engraved into the background,
// if 'color' is the color of the background
// relief effect
relief (RGB color). // color is the color of the background
The text is displayed on several lines if necessary. You must give the maximal width of
the text. If the text is wider than this width, new lines are created. You must also
provide the size (in pixels) of the margin all around the text. You can also control
the minimal number of pixels between consecutive lines (vertical spacing). If a
background color is provided, the text is presented over a uniform background of this
color. Otherwise, no background is displayed, and the parent widget is visible between
the characters.
Consider the maximal width you provide as an indication and not a definitive
argument. Actually, this width could be automatically enlarge if the width of a widget
or the size of word (a word is here a string whitout any spaces) is greater than your
width parameter.
The content of the hypertext is a mix of strings and widgets. Strings are under the
rules defined for then function 'split_string_into_lines()' in
widgets4/tools.anubis. Each widget goes with a integer to indicate the number of pixels
the bottom of the inserted widget is placed relative to the base line of the text.
The content of hypertext is a series of strings, links and widgets. Strings and links
are under the rules exposed for the function 'split_string_into_lines()' in
widgets3/tools.anubis. The hypertext link will have the same behaviour than the string
: it will be cut at the end of the line to continue on the next; as describe above,
links and strings cannot enlarge the hypertext. But if you definitevely want a no-cut
link, construct it through the widget 'button' : widgets can enlarge the hypertext if
necesary. Widgets are called in two hypertexts : posw (for 'positioning widget') and
floatingw (for 'floating widget'). The posw goes with a integer to indicate the number
of pixels the bottom of the inserted widget is placed relative to the base line of the
text. With the floatingw, the other hypertext of the same line will occupied all the
height of the floatingw. For example, a string will be written over as many lines it's
possible. The floatingw needs a position relative to the line (left or right).
The visual aspect of posw and floatingw, follows by a string will be something like :
+---- Window -----------------------------------------+
| |
| |
| +- posw --------+ |
| | | |
| | | Eleonor of Aquitaine (1124,1204) |
| | | |
| | | |
| +---------------+ |
| |
| +- floatingw ---+ is probably the most well-known |
| | | queen of the Middle-Ages. No doubt|
| | | certain exceptionnal aspects of |
| | | her life explain this notoriety : |
| +---------------+ two mariages to the Kings of |
| France and England; ... |
| |
+-----------------------------------------------------+
public type PosWidget:
left_pw (Int32 v_pos, // vertical_position,
Int32 spacer, // spacer between the widget and the text against it
Widget wid),
right_pw (Int32 v_pos, //vertical_position,
Int32 spacer, // spacer between the widget and the text against it
Widget wid).
public type FloatingWidget:
left_fw (Int32 spacer, // spacer between the widget and the text against it
Widget wid),
right_fw (Int32 spacer, // spacer between the widget and the text against it
Widget wid).
public type LinkWidget:
link(String txt,
WidgetEventToolBox -> One action). // action performed by the link
public type HyperTextCode:
code (String).
public type HyperTextList:
list (List(String) items,
Word8 item_mark).
public type HyperTextContent:
empty,
htc_string (HyperTextContent,String),
htc_link (HyperTextContent,LinkWidget),
htc_pos (HyperTextContent,PosWidget),
htc_floating (HyperTextContent,FloatingWidget),
htc_code (HyperTextContent,HyperTextCode),
htc_list (HyperTextContent,HyperTextList),
htc_content (HyperTextContent,HyperTextContent).
public define HyperTextContent HyperTextContent c - String s = htc_string(c,s).
public define HyperTextContent HyperTextContent c - LinkWidget s = htc_link(c,s).
public define HyperTextContent HyperTextContent c - PosWidget s = htc_pos(c,s).
public define HyperTextContent HyperTextContent c - FloatingWidget s = htc_floating(c,s).
public define HyperTextContent HyperTextContent c - HyperTextCode s = htc_code(c,s).
public define HyperTextContent HyperTextContent c - HyperTextList s = htc_list(c,s).
public define HyperTextContent HyperTextContent c - HyperTextContent s = htc_content(c,s).
For making your hypertext, you may write something like : :
"This " - "photograph " - pos(-12,create_image("flowers.jpg")) - " was taken in Paris.".
Note 1 : caracter '&' is reserved. To have a '&' in your text, type '\&'.
Note 2 : spaces begening or ending a text and repeated spaces are remove. To have
surely a space, type '\ '.
You may also want to center or justify the text either on the left, on the right, or
both. The 'justify' attribute is of type:
public type WidgetTextJustify:
center, // | centered text |
left, // | left justified text |
right, // | right justified text |
both. // | text justified on both sides |
Now, here is the hypertext creation function. We also provide some convenience
functions, but you should create convenience functions of your own if you use many
hypertext widgets in your project.
public define Widget
hypertext
(
SystemFont font, //
WidgetTextEffect effect, // (see above)
Maybe(RGB) background, // non mandatory background
Int32 width, // maximal width of text
Int32 margin, // margin for 4 sides
Int32 vertical_spacing, // number of pixels between lines
Int32 indent, // number of pixels before beginning of paragraphs
WidgetTextJustify justify, // how to justify the text
HyperTextContent content,
Maybe(RGB) link_color // failure if there is no links in hypertext
).
Note : if (WidgetTextJustify)center is choosen, the indentation will be not applied.
Convenience functions:
----------------------
(1) Creating a simple text with no effect and no widget inserted. 'margin' is set to
10, 'glue' to 1, 'vertical_spacing' to 3, and 'justify' to left.
public define Widget
create_text
(
SystemFont font,
RGB color,
Int32 width,
String text
) =
create_hypertext(font,
normal(color),
failure,
width,
10,
1,
3,
left,
text+empty,
failure).
(2) Creating a header.
public define Widget
create_header
(
SystemFont font,
WidgetTextEffect effect, // (see above)
Int32 width,
String text // the text itself
) = create_hypertext(font,
effect,
failure,
width,
10,
3,
0,
center,
text+empty,
failure).
--- That's all for the public part ! --------------------------------------------------
$$$$ -> something to do !
*** [1] Tools
*************
*** [1.1] Reconstructing HyperTextContent
Pour la mise en place de l'hypertext, il est nécessaire à plusieurs endroits de
découper les chaînes de caractères (représentés par le String de l'alternative
'HypertTextContent - String') en mots et d'en calculer la longueur en pixel. Pour
éviter ce calcul redondant, ces strings, d'abord transformés en List(String) par la
fonction split_string_into_lines (-> liste de paragraphes) seront concervés sous forme
de List(List(Word_Width)) (1 liste par paragraphe), liste déterminée au moment du
calcul de la largeur du widget HyperTextContent, i.e. au premier endroit où ce calcul
intervient.
Le type HyperTextContent sera donc transformé en HT_Content, où
l'alternative'HypertTextContent - String' devient 'HT_Content - List(Word_Width)', les
autres alternatives restant de construction identique.
On pourrait imaginer un mécanisme identique pour LinkWiget, qui contient un String. On
repoussera pour ce cas une telle façon de procéder dans l'immédiat, considérant que le
texte d'un lien est généralement court (même si 'court' est une notion éminament
subjective !).
public type Word_Width:
word_width (String word,
Int32 width).
type HT_Content:
empty,
htc_ww (HT_Content,List(List(Word_Width))),
htc_link (HT_Content,LinkWidget),
htc_pos (HT_Content,PosWidget),
htc_floating (HT_Content,FloatingWidget),
htc_code (HT_Content,HyperTextCode),
htc_list (HT_Content,HyperTextList),
htc_content (HT_Content,HT_Content).
define HT_Content HT_Content c - List(List(Word_Width)) s = htc_ww(c,s).
define HT_Content HT_Content c - LinkWidget s = htc_link(c,s).
define HT_Content HT_Content c - PosWidget s = htc_pos(c,s).
define HT_Content HT_Content c - FloatingWidget s = htc_floating(c,s).
define HT_Content HT_Content c - HyperTextCode s = htc_code(c,s).
define HT_Content HT_Content c - HyperTextList s = htc_list(c,s).
define HT_Content HT_Content c - HT_Content s = htc_content(c,s).
*** [1.2] Tools with Word_Width
********************************
define Int32
width_sum
(
List(Word_Width) lww
) =
if lww is
{
[] then (Int32)0,
[h . t] then width(h)+width_sum(t)
}.
*** [1.3] Extracting words from a string
****************************************
define List(Word_Width)
extract_words
(
String text,
Int32 n,
String word,
Int32 width,
List(Word_Width) so_far,
String -> Int32 text_width
) =
if nth(n,text) is
{
failure then reverse([word_width(word,width) . so_far]),
success(c) then
if c = ' '
then extract_words(text,n+1,"",0,[word_width(word,width) . so_far],text_width)
else with s = implode([c]),
extract_words(text,n+1,word+s,width+text_width(s),so_far,text_width)
}.
define List(Word_Width)
extract_words
(
String text,
String -> Int32 text_width
) =
extract_words(text,0,"",0,[],text_width).
define List(List(Word_Width))
extract_words
(
List(String) lines,
String -> Int32 text_width
) =
reverse(map((String s) |-> extract_words(s,text_width),lines)).
define List(String)
extract_words
(
String text,
Int32 n,
String word,
List(String) so_far
) =
if nth(n,text) is
{
failure then [word . so_far],
success(c) then
if c = ' '
then extract_words(text,n+1,"",[word . so_far])
else extract_words(text,n+1,word+implode([c]),so_far)
}.
define List(String)
extract_words
(
String text
) =
extract_words(text,0,"",[]).
*** [1.4] Current margin
define (Int32,List(Int32))
current_margin
(
Int32 margin,
List(Int32) margin_stack
) =
if margin_stack is
{
[] then (margin,[]),
[h . t] then (h,t)
}.
*** [1.5] Computing one line of text
The purpose is to compute the all text which could be printed on one line.
The function returns :
. the text to be printed
. the List(Word_With) of words to be printed (used when 'both' justify is choosen),
. the width of this texts
. the unused part of the original List(Word_Width) (which be printed on next line(s)).
define (String,List(Word_Width),Int32,List(Word_Width))
text_line_to_print
(
List(Word_Width) lww,
Int32 space_width,
String so_far,
List(Word_Width) used_lww,
Int32 all_width,
Int32 -> Bool is_too_large
) =
if lww is
{
[] then (so_far,reverse(used_lww),all_width,[]),
[h . t] then
with new_width = all_width+width(h)+space_width,
if is_too_large(new_width)
then (so_far,reverse(used_lww),all_width,[h]+t)
else text_line_to_print(t,space_width,so_far+" "+word(h),[h . used_lww],new_width,is_too_large)
}.
*** [2] Computing the hypertext content width & height
*** [2.1] Width
When width is computed, HyperTextContent is transformed into HT_Content.
A maximal width is given; but this with must be considered only as an indication : it's
necessary to compute in from the hypertext content.
The definive width will be the maximum of :
. the given width,
. width of includes widgets
. width of each words
define Int32
text_max_width
(
List(List(Word_Width)) llww,
Int32 max_width
) =
if llww is
{
[] then max_width,
[h . t] then text_max_width(t,greatest(map(width,h),max_width))
}.
define (Int32,HT_Content)
ht_width
(
String -> Int32 text_width,
Int32 max_width,
HyperTextContent content,
HT_Content new_content,
) =
if content is
{
empty then (max_width,new_content),
htc_string(htc,s) then with llww = extract_words(reverse(split_string_into_lines(s)),text_width),
ht_width(text_width,
text_max_width(llww,max_width),
htc,new_content - llww),
htc_link(htc,lw) then ht_width(text_width,
greatest(map((String a) |-> text_width(a),extract_words(txt(lw))),
max_width),
htc,new_content - lw),
htc_pos(htc,pw) then if size(wid(pw)) is (w,h) then
ht_width(text_width,max(max_width,w),htc,new_content - pw),
htc_floating(htc,fw) then if size(wid(fw)) is (w,h) then
ht_width(text_width,max(max_width,w),htc,new_content - fw),
htc_code(htc,c) then ht_width(text_width,max_width,htc,new_content - c), // $$$$
htc_list(htc,l) then ht_width(text_width,max_width,htc,new_content - l), // $$$$
htc_content(htc1,htc2) then
if ht_width(text_width,max_width,htc1,new_content) is (w1,new_ht1) then
if ht_width(text_width,max_width,htc2,new_content) is (w2,new_ht2) then
(max(w1,w2),new_ht1 - new_ht2)
}.
*** [2.2] Height
*** [2.2.1] Height of a List(List(Word_Width)
define (Int32,List(Int32))
compute_height_lww
(
List(Word_Width) lww,
Int32 margin,
List(Int32) margin_stack,
Int32 content_width,
Int32 space_width,
Int32 indent,
Int32 total_font_height,
Int32 y
) =
if current_margin(margin,margin_stack) is (marg,m_stack) then
if text_line_to_print(lww,space_width,"",[],0,(Int32 i) |-> i > content_width - indent) is
(txt,used_lww,text_width,unused_lww) then
if unused_lww is []
then (y+total_font_height,m_stack)
else compute_height_lww(unused_lww,margin,m_stack,content_width,space_width,0,
total_font_height,y+total_font_height).
define (Int32,List(Int32))
compute_height_llww
(
List(List(Word_Width)) llww,
Int32 margin,
List(Int32) margin_stack,
Int32 content_width,
Int32 space_width,
Int32 indent,
Int32 total_font_height,
Int32 y
) =
if llww is
{
[] then (y,margin_stack),
[h . t] then
if compute_height_lww(h,margin,margin_stack,content_width,space_width,
indent,total_font_height,y) is
(new_y,new_m_stack) then
compute_height_llww(t,margin,new_m_stack,content_width,space_width,indent,total_font_height,new_y)
}.
*** [2.2.2] Height and floting/pos widget
Avec un FloatingWidget, de taille (w_fw,h_fw), il sera possible d'écrire, sur la largeu
define Int32
compute_height
(
HT_Content content,
String -> Int32 text_width,
Int32 margin,
Int32 content_width,
Int32 indent,
Int32 total_font_height,
List(Int32) margin_stack,
Int32 y
) =
if content is
{
empty then y,
htc_ww(htc,llww) then
if compute_height_llww(llww,margin,margin_stack,content_width,text_width(" "),
indent,total_font_height,y) is
(new_y,new_m_stack) then
compute_height(htc,text_width,margin,content_width,indent,total_font_height,
new_m_stack,new_y),
htc_link(htc,lw) then
compute_height(htc,text_width,margin,content_width,indent,total_font_height,margin_stack,y),
htc_pos(htc,pw) then
if size(wid(pw)) is (w_pw,h_pw) then
compute_height(htc,text_width,margin,content_width,indent,total_font_height,margin_stack,y),
htc_floating(htc,fw) then
compute_height(htc,text_width,margin,content_width,indent,total_font_height,margin_stack,y),
htc_code(htc,c) then // $$$$
compute_height(htc,text_width,margin,content_width,indent,total_font_height,margin_stack,y),
htc_list(htc,l) then // $$$$
compute_height(htc,text_width,margin,content_width,indent,total_font_height,margin_stack,y),
htc_content(htc1,htc2) then
compute_height(htc2,text_width,margin,content_width,indent,total_font_height,margin_stack,
compute_height(htc1,text_width,margin,content_width,indent,total_font_height,margin_stack,y))
}.
*** [3] Drawing hypertext
*** [3.1] Format WidgetTextEffect
define (String,Int32,Int32) -> One
draw_text_with_effect
(
WidgetDrawToolBox dtb,
WidgetTextEffect effect,
SystemFont font
) =
(String text, Int32 x, Int32 y) |->
if effect is
{
normal(color) then
forget(draw(dtb)(text,font,color,x,y)),
shadow(mc,sc,sx,sy) then
forget(draw(dtb)(text,font,sc,x+sx,y+sy));
forget(draw(dtb)(text,font,mc,x,y)),
engraved(color) then
forget(draw(dtb)(text,font,lighten(color),x+2,y+2));
forget(draw(dtb)(text,font,darken(color),x,y));
forget(draw(dtb)(text,font,color,x+1,y+1)),
relief(color) then
forget(draw(dtb)(text,font,darken(color),x+2,y+2));
forget(draw(dtb)(text,font,lighten(color),x,y));
forget(draw(dtb)(text,font,color,x+1,y+1))
}.
*** [3.2] Format WidgetTextJustify
**********************************
Where text will begin to be printed ? Knowing margin, max width and text width, we can
compute the x_position of the text.
define (Int32,Int32) -> Int32
x_position
(
WidgetTextJustify justify,
Int32 margin,
Int32 max_width,
) =
(Int32 text_width,Int32 indent) |->
if justify is
{
center then margin+(max_width-text_width)/2, // no indent when center
left then margin+indent,
right then margin+max_width-text_width,
both then margin+indent
}.
If (WidgetTextJustify)both is choosen, spaces between words will be computed as
following :
.1. compute locations where at least one space must exist (example : 4 locations if
there is 5 words to print).
.2. compute how many space must be added
.3. compute minimum spaces between words (equally distribution)
.4. put the others spaces between words from the middle of the line to left and right sides
define String
justify_text
(
List(Word_Width) lww,
String at_least,
Int32 -> String more_space,
Int32 ct
) =
if lww is
{
[] then "",
[h . t] then
if t is []
then word(h)
else word(h)+at_least+more_space(ct)+justify_text(t,at_least,more_space,ct+1)
}.
define String
justify_text
(
List(Word_Width) lww,
String -> Int32 string_width,
Int32 content_width,
Int32 space_width
) =
with locations_nb = length(lww)-1,
spaces_to_add = (Int32)((content_width-width_sum(lww))/space_width),
justify_text
(lww,
constant_string(max(1,spaces_to_add/locations_nb),' '), // at least, between two words
with q = (spaces_to_add (mod locations_nb)), // spaces to distribute not-equally
(Int32 ct) |->
if q = 0 then ""
else with l = (locations_nb/2)-(q/2),
r = (locations_nb/2)+(q/2)+(q (mod 2)),
if l<ct & ct=<r then " " else "",
0).
define String
transform_text
(
WidgetTextJustify justify,
String txt,
List(Word_Width) lww,
String -> Int32 string_width,
Int32 content_width,
Int32 space_width
) =
if justify is
{
center then txt,
left then txt,
right then txt,
both then justify_text(lww,string_width,content_width,space_width)
}.
'draw_string' returns the y position for the next object to print and the state of
margin_stack.
define (Int32,List(Int32))
draw_string
(
(String,Int32,Int32) -> One draw_text_with_effect,
(Int32,Int32) -> Int32 x_position,
WidgetTextJustify justify,
String -> Int32 string_width,
List(Word_Width) lww,
Int32 margin,
List(Int32) margin_stack,
Int32 content_width,
Int32 space_width,
Int32 indent,
Int32 total_font_height,
Int32 y
) =
if current_margin(margin,margin_stack) is (marg,m_stack) then
if text_line_to_print(lww,space_width,"",[],0,(Int32 i) |-> i > content_width-indent) is
(txt,used_lww,text_width,unused_lww) then
draw_text_with_effect
(if unused_lww is []
then txt
else transform_text(justify,txt,used_lww,string_width,content_width-indent,space_width),
x_position(text_width,indent),y);
if unused_lww is []
then (y+total_font_height,m_stack)
else draw_string(draw_text_with_effect,x_position,justify,string_width,unused_lww,margin,m_stack,
content_width,space_width,0,total_font_height,y+total_font_height).
define (Int32,List(Int32))
draw_string
(
(String,Int32,Int32) -> One draw_text_with_effect,
(Int32,Int32) -> Int32 x_position,
WidgetTextJustify justify,
String -> Int32 string_width,
List(List(Word_Width)) llww,
Int32 margin,
List(Int32) margin_stack,
Int32 content_width,
Int32 space_width,
Int32 indent,
Int32 total_font_height,
Int32 y
) =
if llww is
{
[] then (y,margin_stack),
[h . t] then
if draw_string(draw_text_with_effect,x_position,justify,string_width,h,margin,margin_stack,
content_width,space_width,indent,total_font_height,y) is
(new_y,new_margin_stack) then
draw_string
(draw_text_with_effect,x_position,justify,string_width,t,margin,new_margin_stack,
content_width,space_width,indent,total_font_height,new_y)
}.
define (Int32,List(Int32))
draw_string
(
WidgetDrawToolBox dtb,
WidgetTextEffect effect,
WidgetTextJustify justify,
SystemFont font,
List(List(Word_Width)) llww,
String -> Int32 string_width,
Int32 margin,
List(Int32) margin_stack,
Int32 content_width,
Int32 space_width,
Int32 indent,
Int32 total_font_height,
Int32 y,
) =
draw_string(draw_text_with_effect(dtb,effect,font),
x_position(justify,margin,content_width),
justify,string_width,
llww,margin,margin_stack,content_width,space_width,indent,total_font_height,y).
define One
draw_hypertext
(
WidgetDrawToolBox dtb,
WidgetTextEffect effect,
WidgetTextJustify justify,
SystemFont font,
HT_Content content,
String -> Int32 string_width,
Int32 margin,
Int32 content_width,
Int32 indent,
Int32 total_font_height,
List(Int32) margin_stack,
Int32 y
) =
if content is
{
empty then unique,
htc_ww(htc,llww) then
if draw_string(dtb,effect,justify,font,llww,string_width,margin,margin_stack,content_width,
string_width(" "),indent,total_font_height,y) is
(new_y,new_margin_stack) then
draw_hypertext(dtb,effect,justify,font,htc,string_width,margin,content_width,
indent,total_font_height,new_margin_stack,new_y),
htc_link(htc,lw) then unique,
htc_pos(htc,pw) then unique,
htc_floating(htc,fw) then unique,
htc_code(htc,c) then unique,
htc_list(htc,l) then unique,
htc_content(htc1,htc2) then unique
}.
*** [] Creating hypertext
public define Widget
hypertext
(
SystemFont font, //
WidgetTextEffect effect, // (see above)
Maybe(RGB) background, // non mandatory background
Int32 max_width, // maximal width of text
Int32 margin, // margin for 4 sides
Int32 vertical_spacing, // number of pixels between lines
Int32 indent, // number of pixels before beginning of paragraphs
WidgetTextJustify justify, // how to justify the text
HyperTextContent content,
Maybe(RGB) link_color // failure if there is no links in hypertext
) =
with string_width = (String s) |-> printed_text_width(font,s),
if ht_width(string_width,max_width,content,empty) is (ht_width,new_content) then
with widget_width = ht_width+2*margin,
info = get_font_info(font),
font_height = word8_to_int32(height(info)),
font_depth = word8_to_int32(depth(info)),
total_font_height = font_height+font_depth,
widget_height = compute_height(new_content,string_width,margin,ht_width,indent,
total_font_height,[],margin)+margin,
create_widget
(
(One u) |-> (widget_width,widget_height),
(WidgetDrawToolBox dtb) |->
draw_hypertext(dtb,effect,justify,font,new_content,string_width,margin,ht_width,indent,
total_font_height,[],margin+font_height),
(WidgetEventToolBox etb, WidgetEvent e) |-> ignored,
(One u) |-> []
).