summaryrefslogtreecommitdiffstats
path: root/tkhtml1/src/html.h
blob: b43da4733c17d06a83a16537f9299c031b354e8b (plain)
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
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
/*
** Structures and typedefs used by the HTML widget
** $Revision$
**
** Copyright (C) 1997-2000 D. Richard Hipp
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Library General Public
** License as published by the Free Software Foundation; either
** version 2 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Library General Public License for more details.
** 
** You should have received a copy of the GNU Library General Public
** License along with this library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA  02111-1307, USA.
**
** Author contact information:
**   drh@acm.org
**   http://www.hwaci.com/drh/
*/

/*
** Debug must be turned on for testing to work.
*/
#define DEBUG 1

/*
** Sanity checking macros.
*/
#ifdef DEBUG
#define HtmlAssert(X) \
  if(!(X)){ \
    fprintf(stderr,"Assertion failed on line %d of %s\n",__LINE__,__FILE__); \
  }
#define HtmlCantHappen \
  fprintf(stderr,"Can't happen on line %d of %s\n",__LINE__,__FILE__);
#else
#define HtmlAssert(X)
#define HtmlCantHappen
#endif

/*
** The TRACE macro is used to print internal information about the
** HTML layout engine during testing and debugging.  The amount of
** information printed is governed by a global variable named
** HtmlTraceMask.  If bits in the first argument to the TRACE macro
** match any bits in HtmlTraceMask variable, then the trace message
** is printed.
**
** All of this is completely disabled, of course, if the DEBUG macro
** is not defined.
*/
#ifdef DEBUG
# define TRACE_INDENT  printf("%*s",HtmlDepth-3,"")
# define TRACE(Flag, Args) \
    if( (Flag)&HtmlTraceMask ){ \
       TRACE_INDENT; printf Args; fflush(stdout); \
    }
# define TRACE_PUSH(Flag)  if( (Flag)&HtmlTraceMask ){ HtmlDepth+=3; }
# define TRACE_POP(Flag)   if( (Flag)&HtmlTraceMask ){ HtmlDepth-=3; }
#else
# define TRACE_INDENT
# define TRACE(Flag, Args)
# define TRACE_PUSH(Flag)
# define TRACE_POP(Flag)
#endif

/*
** Bitmasks for the HtmlTraceMask global variable
*/
#define HtmlTrace_Table1       0x00000001
#define HtmlTrace_Table2       0x00000002
#define HtmlTrace_Table3       0x00000004
#define HtmlTrace_Table4       0x00000008
#define HtmlTrace_Table5       0x00000010
#define HtmlTrace_Table6       0x00000020
#define HtmlTrace_GetLine      0x00000100
#define HtmlTrace_GetLine2     0x00000200
#define HtmlTrace_FixLine      0x00000400
#define HtmlTrace_BreakMarkup  0x00001000
#define HtmlTrace_Style        0x00002000
#define HtmlTrace_Input1       0x00004000


/*
** Macros to allocate and free memory.
*/
#define HtmlAlloc(A)      ((void*)Tcl_Alloc(A))
#define HtmlFree(A)       Tcl_Free((char*)(A))
#define HtmlRealloc(A,B)  ((void*)Tcl_Realloc((A),(B)))

/*
** Various data types.  This code is designed to run on a modern
** cached architecture where the CPU runs a lot faster than the
** memory bus.  Hence we try to pack as much data into as small a space
** as possible so that it is more likely to fit in cache.  The
** extra CPU instruction or two needed to unpack the data is not
** normally an issue since we expect the speed of the memory bus 
** to be the limiting factor.
*/
typedef unsigned char  Html_u8;      /* 8-bit unsigned integer */
typedef short          Html_16;      /* 16-bit signed integer */
typedef unsigned short Html_u16;     /* 16-bit unsigned integer */
typedef int            Html_32;      /* 32-bit signed integer */

/*
** An instance of the following structure is used to record style
** information on each Html element.
*/
struct HtmlStyle {
  unsigned int font    : 6;      /* Font to use for display */
  unsigned int color   : 4;      /* Foreground color */
  signed int subscript : 4;      /* Positive for <sup>, negative for <sub> */
  unsigned int align   : 2;      /* Horizontal alignment */
  unsigned int bgcolor : 4;      /* Background color */
  unsigned int flags   : 12;     /* the STY_ flags below */
}

/*
** We allow 8 different font families:  Normal, Bold, Italic and 
** Bold-Italic in either variable or constant width.
** Within each family there can be up to 7 font sizes from 1
** (the smallest) up to 7 (the largest).  Hence, the widget can use
** a maximum of 56 fonts.  The ".font" field of the style is an integer
** between 0 and 55 which indicates which font to use.
*/
#define N_FONT_FAMILY     8
#define N_FONT_SIZE       7
#define N_FONT            (N_FONT_FAMILY*N_FONT_SIZE)
#define NormalFont(X)     (X)
#define BoldFont(X)       ((X)+N_FONT_SIZE)
#define ItalicFont(X)     ((X)+2*N_FONT_SIZE)
#define CWFont(X)         ((X)+4*N_FONT_SIZE)
#define FontSize(X)       ((X)%N_FONT_SIZE)
#define FontFamily(X)     (((X)/N_FONT_SIZE)*N_FONT_SIZE)
#define FONT_Any           -1
#define FONT_Default      3
#define FontSwitch(Size, Bold, Italic, Cw) \
                          ((Size)+(Bold+(Italic)*2+(Cw)*4)*N_FONT_SIZE)

/*
** Macros for manipulating the fontValid bitmap of an HtmlWidget structure.
*/
#define FontIsValid(H,I)     (((H)->fontValid[(I)>>3] & (1<<((I)&3)))!=0)
#define FontSetValid(H,I)    ((H)->fontValid[(I)>>3] |= (1<<((I)&3)))
#define FontClearValid(H,I)  ((H)->fontValid[(I)>>3] &= ~(1<<((I)&3)))

/*
** Information about available colors.
**
** The widget will use at most N_COLOR colors.  4 of these colors
** are predefined.  The rest are user selectable by options to
** various markups. (Ex:  <font color=red>)
**
** All colors are stored in the apColor[] array of the main widget
** structure.  The ".color" field of the HtmlStyle is an integer
** between 0 and N_COLOR-1 which indicates which of these colors 
** to use.
*/
#define N_COLOR             16      /* Total number of colors */
#define COLOR_Normal         0      /* Index for normal color (black) */
#define COLOR_Unvisited      1      /* Index for unvisited hyperlinks */
#define COLOR_Visited        2      /* Color for visited hyperlinks */
#define COLOR_Selection      3      /* Background color for the selection */
#define COLOR_Background     4      /* Default background color */
#define N_PREDEFINED_COLOR   5      /* Number of predefined colors */

/*
** The "align" field of the style determines how text is justified
** horizontally.  ALIGN_None means that the alignment is not specified.
** (It should probably default to ALIGN_Left in this case.)
*/
#define ALIGN_Left   1
#define ALIGN_Right  2
#define ALIGN_Center 3
#define ALIGN_None   0

/*
** Possible value of the "flags" field of HtmlStyle are shown below.
**
**  STY_Preformatted       If set, the current text occurred within
**                         <pre>..</pre>
**
**  STY_StrikeThru         Draw a solid line thru the middle of this text.
**
**  STY_Underline          This text should drawn with an underline.
**
**  STY_NoBreak            This text occurs within <nobr>..</nobr>
**
**  STY_Anchor             This text occurs within <a href=X>..</a>.
**
**  STY_DT                 This text occurs within <dt>..</dt>.                 
**
**  STY_Invisible          This text should not appear in the main HTML
**                         window.  (For example, it might be within 
**                         <title>..</title> or <marquee>..</marquee>.)
*/
#define STY_Preformatted    0x001
#define STY_StrikeThru      0x002
#define STY_Underline       0x004
#define STY_NoBreak         0x008
#define STY_Anchor          0x010
#define STY_DT              0x020
#define STY_Invisible       0x040
#define STY_FontMask        (STY_StrikeThru|STY_Underline)

/*
** The first thing done with input HTML text is to parse it into
** HtmlElements.  All sizing and layout is done using these elements,
** so this is a very important structure.
**
** Elements are designed so that the common ones (Text and Space)
** require as little storage as possible, in order to increase
** the chance of memory cache hits.  (Turns out I didn't do a
** very good job of this.  This widget is a pig for memory.  But
** the speed is good, so I'm not going to change it right now...)
**
** Some elements require more memory than Text and Space (ex: <IMG>).
** An HtmlElement is therefore represented as a union of many other 
** structures all of different sizes.  That way we can have a pointer 
** to a generic element without having to worry about how big that 
** element is.  The ".base.type" field (which is found in all elements) 
** will tell us what type of element we are dealing with.
**
** NOTE:  This trick will only work on compilers that align all elements
** of a union to the lowest memory address in that union.  This is true
** for every C compiler I've ever seen, but isn't guarenteed for ANSI-C.
*/
union HtmlElement {
  HtmlElement *pNext;
  HtmlBaseElement base;
  HtmlTextElement text;
  HtmlSpaceElement space;
  HtmlMarkupElement markup;
  HtmlCell cell;
  HtmlTable table;
  HtmlRef ref;
  HtmlLi li;
  HtmlListStart list;
  HtmlImageMarkup image;
  HtmlInput input;
  HtmlForm form;
  HtmlHr hr;
  HtmlAnchor anchor;
  HtmlScript script;
  HtmlBlock block;
};

/*
** Every element contains at least this much information:
*/
struct HtmlBaseElement {
  HtmlElement *pNext;         /* Next input token in a list of them all */
  HtmlElement *pPrev;         /* Previous token in a list of them all */
  HtmlStyle style;            /* The rendering style for this token */
  Html_u8 type;               /* The token type. */
  Html_u8 flags;              /* The HTML_ flags below */
  Html_16 count;              /* Various uses, depending on "type" */
};

/*
** Bitmasks for the "flags" field of the HtmlBaseElement
*/
#define HTML_Visible   0x01     /* This element produces "ink" */
#define HTML_NewLine   0x02     /* type==Html_Space and ends with newline */
#define HTML_Selected  0x04     /* Some or all of this Html_Block is selected */
                                /* Used by Html_Block elements only. */

/*
** Each text element holds additional information as show here.  Notice
** that extra space is allocated so that zText[] will be large enough
** to hold the complete text of the element.  X and y coordinates are
** relative to the virtual canvas.  The y coordinate refers to the
** baseline.
*/
struct HtmlTextElement {
  HtmlBaseElement base;       /* All the base information */
  Html_32 y;                  /* y coordinate where text should be rendered */
  Html_16 x;                  /* x coordinate where text should be rendered */
  Html_16 w;                  /* width of this token in pixels */
  Html_u8 ascent;             /* height above the baseline */
  Html_u8 descent;            /* depth below the baseline */
  Html_u8 spaceWidth;         /* Width of one space in the current font */
  char zText[1];              /* Text for this element.  Null terminated */
};

/*
** Each space element is represented like this:
*/
struct HtmlSpaceElement {
  HtmlBaseElement base;       /* All the base information */
  Html_16 w;                  /* Width of a single space in current font */
  Html_u8 ascent;             /* height above the baseline */
  Html_u8 descent;            /* depth below the baseline */
};

/*
** Most markup uses this structure.  Some markup extends this structure
** with additional information, but most use it as a base, at the very
** least. 
**
** If the markup doesn't have arguments (the "count" field of
** HtmlBaseElement is 0) then the extra "argv" field of this structure
** is not allocated and should not be used.
*/
struct HtmlMarkupElement {
  HtmlBaseElement base;
  char **argv;
};

/* Each <td> or <th> markup is represented by an instance of the 
** following structure.
**
** Drawing for a cell is a sunken 3D border with the border width given
** by the borderWidth field in the associated <table> structure.
*/
struct HtmlCell {
  HtmlMarkupElement markup;
  Html_16 rowspan;          /* Number of rows spanned by this cell */
  Html_16 colspan;          /* Number of columns spanned by this cell */
  Html_16 x;                /* X coordinate of left edge of border */
  Html_16 w;                /* Width of the border */
  Html_32 y;                /* Y coordinate of top of border indentation */
  Html_32 h;                /* Height of the border */
  HtmlElement *pTable;      /* Pointer back to the <table> */
  HtmlElement *pEnd;        /* Element that ends this cell */
};

/*
** The maximum number of columns allowed in a table.  Any columns beyond
** this number are ignored.
*/
#define HTML_MAX_COLUMNS 40

/*
** This structure is used for each <table> element.
**
** In the minW[] and maxW[] arrays, the [0] element is the overall
** minimum and maximum width, including cell padding, spacing and 
** the "hspace".  All other elements are the minimum and maximum 
** width for the contents of individual cells without any spacing or
** padding.
*/
struct HtmlTable {
  HtmlMarkupElement markup;
  Html_u8 borderWidth;           /* Width of the border */
  Html_u8 nCol;                  /* Number of columns */
  Html_u16 nRow;                 /* Number of rows */
  Html_32 y;                     /* top edge of table border */
  Html_32 h;                     /* height of the table border */
  Html_16 x;                     /* left edge of table border */
  Html_16 w;                     /* width of the table border */
  int minW[HTML_MAX_COLUMNS+1];  /* minimum width of each column */
  int maxW[HTML_MAX_COLUMNS+1];  /* maximum width of each column */
};

/* This structure is used for </table>, </td>, <tr>, </tr> 
** and </th> elements.  It points back to the <table> element 
** that began the table.  It is also used by </a> to point back
** to the original <a>.  I'll probably think of other uses before
** all is said and done...
*/
struct HtmlRef {
  HtmlMarkupElement markup;
  HtmlElement *pOther;         /* Pointer to some other Html element */
};

/*
** An instance of the following structure is used to represent
** each <LI> markup.
*/
struct HtmlLi {
  HtmlMarkupElement markup;
  Html_u8 type;     /* What type of list is this? */
  Html_u8 ascent;   /* height above the baseline */
  Html_u8 descent;  /* depth below the baseline */
  Html_16 cnt;      /* Value for this element (if inside <OL>) */
  Html_16 x;        /* X coordinate of the bullet */
  Html_32 y;        /* Y coordinate of the bullet */
};

/*
** The .type field of an HtmlLi or HtmlListStart structure can take on 
** any of the following values to indicate what type of bullet to draw.
** The value in HtmlLi will take precedence over the value in HtmlListStart
** if the two values differ.
*/
#define LI_TYPE_Undefined 0     /* If in HtmlLi, use the HtmlListStart value */
#define LI_TYPE_Bullet1   1     /* A solid circle */
#define LI_TYPE_Bullet2   2     /* A hollow circle */
#define LI_TYPE_Bullet3   3     /* A hollow square */
#define LI_TYPE_Enum_1    4     /* Arabic numbers */
#define LI_TYPE_Enum_A    5     /* A, B, C, ... */
#define LI_TYPE_Enum_a    6     /* a, b, c, ... */
#define LI_TYPE_Enum_I    7     /* Capitalized roman numerals */
#define LI_TYPE_Enum_i    8     /* Lower-case roman numerals */

/*
** An instance of this structure is used for <UL> or <OL>
** markup.
*/
struct HtmlListStart {
  HtmlMarkupElement markup;
  Html_u8 type;            /* One of the LI_TYPE_ defines above */
  Html_u8 compact;         /* True if the COMPACT flag is present */
  Html_u16 cnt;            /* Next value for <OL> */
  Html_u16 width;          /* How much space to allow for indentation */
  HtmlElement *pPrev;      /* Next higher level list, or NULL */
};

/*
** Information about each image on the HTML widget is held in an
** instance of the following structure.  A pointer to this structure
** is the clientData for the image change callback.  All image structures
** are held on a list attached to the main widget structure.
**
** This structure is NOT an element.  The <IMG> element is represented
** by an HtmlImageMarkup structure below.  There is one HtmlImageMarkup
** for each <IMG> in the source HTML.  There is one of these structures
** for each unique image loaded.  (If two <IMG> specify the same image,
** there are still two HtmlImageMarkup structures but only one
** HtmlImage structure that is shared between them.)
*/
struct HtmlImage {
  HtmlWidget *htmlPtr;     /* The owner of this image */
  Tk_Image image;          /* The Tk image token */
  Html_32 w;               /* Requested width of this image (0 if none) */
  Html_32 h;               /* Requested height of this image (0 if none) */
  char *zUrl;              /* The URL for this image. */
  char *zWidth, *zHeight;  /* Width and height in the <img> markup. */
  HtmlImage *pNext;        /* Next image on the list */
  HtmlElement *pList;      /* List of all <IMG> markups that use this 
                           ** same image */
};

/* Each <img> markup is represented by an instance of the 
** following structure.
**
** If pImage==0, then we use the alternative text in zAlt.
*/
struct HtmlImageMarkup {
  HtmlMarkupElement markup;
  Html_u8 align;          /* Alignment.  See IMAGE_ALIGN_ defines below */
  Html_u8 textAscent;     /* Ascent of text font in force at the <IMG> */
  Html_u8 textDescent;    /* Descent of text font in force at the <IMG> */
  Html_u8 redrawNeeded;   /* Need to redraw this image because the image
                          ** content changed. */
  Html_16 h;              /* Actual height of the image */
  Html_16 w;              /* Actual width of the image */
  Html_16 ascent;         /* How far image extends above "y" */
  Html_16 descent;        /* How far image extends below "y" */
  Html_16 x;              /* X coordinate of left edge of the image */
  Html_32 y;              /* Y coordinate of image baseline */
  char *zAlt;             /* Alternative text */
  HtmlImage *pImage;      /* Corresponding HtmlImage structure */
  HtmlElement *pNext;     /* Next markup using the same HtmlImage structure */
};

/*
** Allowed alignments for images.  These represent the allowed arguments
** to the "align=" field of the <IMG> markup.
*/
#define IMAGE_ALIGN_Bottom        0
#define IMAGE_ALIGN_Middle        1
#define IMAGE_ALIGN_Top           2
#define IMAGE_ALIGN_TextTop       3
#define IMAGE_ALIGN_AbsMiddle     4
#define IMAGE_ALIGN_AbsBottom     5
#define IMAGE_ALIGN_Left          6
#define IMAGE_ALIGN_Right         7

/*
** All kinds of form markup, including <INPUT>, <TEXTAREA> and <SELECT>
** are represented by instances of the following structure.
**
** (later...)  We also use this for the <APPLET> markup.  That way,
** the window we create for an <APPLET> responds to the HtmlMapControls()
** and HtmlUnmapControls() function calls.  For an <APPLET>, the
** pForm field is NULL.  (Later still...) <EMBED> works just like
** <APPLET> so it uses this structure too.
*/
struct HtmlInput {
  HtmlMarkupElement markup;
  HtmlElement *pForm;      /* The <FORM> to which this belongs */
  HtmlElement *pNext;      /* Next element in a list of all input elements */
  Tk_Window tkwin;         /* The window that implements this control */
  HtmlWidget *htmlPtr;     /* The whole widget.  Needed by geometry callbacks */
  HtmlElement *pEnd;       /* End tag for <TEXTAREA>, etc. */
  Html_32  y;              /* Baseline for this input element */
  Html_u16 x;              /* Left edge */
  Html_u16 w, h;           /* Width and height of this control */
  Html_u8 padLeft;         /* Extra padding on left side of the control */
  Html_u8 align;           /* One of the IMAGE_ALIGN_xxx  types */
  Html_u8 textAscent;      /* Ascent for the current font */
  Html_u8 textDescent;     /* descent for the current font */
  Html_u8 type;            /* What type of input is this? */
  Html_u8 sized;           /* True if this input has been sized already */
  Html_u16 cnt;            /* Used to derive widget name. 0 if no widget */
};

/*
** An input control can be one of the following types.  See the
** comment about <APPLET> on the HtmlInput structure insight into
** INPUT_TYPE_Applet.
*/
#define INPUT_TYPE_Unknown      0
#define INPUT_TYPE_Checkbox     1
#define INPUT_TYPE_File         2
#define INPUT_TYPE_Hidden       3
#define INPUT_TYPE_Image        4
#define INPUT_TYPE_Password     5
#define INPUT_TYPE_Radio        6
#define INPUT_TYPE_Reset        7
#define INPUT_TYPE_Select       8
#define INPUT_TYPE_Submit       9
#define INPUT_TYPE_Text        10
#define INPUT_TYPE_TextArea    11
#define INPUT_TYPE_Applet      12

/*
** There can be multiple <FORM> entries on a single HTML page.
** Each one must be given a unique number for identification purposes,
** and so we can generate unique state variable names for radiobuttons,
** checkbuttons, and entry boxes.
*/
struct HtmlForm {
  HtmlMarkupElement markup;
  Html_u16 id;             /* Unique number assigned to this form */
};

/*
** Information used by a <HR> markup
*/
struct HtmlHr {
  HtmlMarkupElement markup;
  Html_32  y;              /* Baseline for this input element */
  Html_u16 x;              /* Left edge */
  Html_u16 w, h;           /* Width and height of this control */
  Html_u8 is3D;            /* Is it drawn 3D? */
};

/*
** Information used by a <A> markup
*/
struct HtmlAnchor {
  HtmlMarkupElement markup;
  Html_32  y;              /* Top edge for this element */
};

/*
** Information about the <SCRIPT> markup.  The parser treats <SCRIPT>
** specially.  All text between <SCRIPT> and </SCRIPT> is captured and
** is pointed to by the zScript field of this structure.
**
** Note that zScript is not null-terminated.   Instead, zScript just
** points to a spot in the zText field of the HtmlWidget structure.
** The nScript field determines how long the script is.
*/
struct HtmlScript {
  HtmlMarkupElement markup;
  char *zScript;           /* Complete text of this script */
  int nScript;             /* Number of characters of text */
}

/*
** A block is a single unit of display information.  This can be
** one or more text elements, or the border of table, or an
** image, etc.
**
** Blocks are used to improve display speed and to improve the
** speed of linear searchs through the token list.  A single
** block will typically contain enough information to display
** a dozen or more Text and Space elements all with a single
** call to Tk_DrawChars().  The blocks are linked together on
** their own list, so we can search them much faster then elements
** (since there are fewer of them.)
**
** Of course, you can construct pathological HTML that has as
** many Blocks as it has normal tokens.  But you haven't lost
** anything.  Using blocks just speeds things up in the common
** case.
**
** Much of the information needed for display is held in the
** original HtmlElement structures.  "base.pNext" points to the first
** structure in the list which can be used to find the "style"
** "x" and "y".
**
** If n==0, then "base.pNext" might point to a special HtmlElement that
** defines some other kind of drawing, like <LI> or <IMG> or <INPUT>.
*/
struct HtmlBlock {
  HtmlBaseElement base;      /* Superclass.  Must be first */
  char *z;                   /* Space to hold text when n>0 */
  int top, bottom;           /* Extremes of y coordinates */
  Html_u16 left, right;      /* Left and right boundry of this object */
  Html_u16 n;                /* Number of characters in z[] */
  HtmlBlock *pPrev, *pNext;  /* Linked list of all Blocks */
};

/*
** Linux doesn't have a stricmp() function.
*/
#ifndef HAVE_STRICMP
# define stricmp strcasecmp
# define strnicmp strncasecmp
#endif

/*
** A stack of these structures is used to keep track of nested font and
** style changes.  This allows us to easily revert to the previous style
** when we encounter and end-tag like </em> or </h3>.
**
** This stack is used to keep track of the current style while walking
** the list of elements.  After all elements have been assigned a style,
** the information in this stack is no longer used.
*/
struct HtmlStyleStack {
  HtmlStyleStack *pNext;   /* Next style on the stack */
  int type;                /* A markup that ends this style. Ex: Html_EndEM */
  HtmlStyle style;         /* The currently active style. */
}

/*
** A stack of the following structures is used to remember the
** left and right margins within a layout context.
*/
struct HtmlMargin {
  int indent;          /* Size of the current margin */
  int bottom;          /* Y value at which this margin expires */
  int tag;             /* Markup that will cancel this margin */
  HtmlMargin *pNext;   /* Previous margin */
};

/*
** How much space (in pixels) used for a single level of indentation due
** to a <UL> or <DL> or <BLOCKQUOTE>, etc.
*/
#define HTML_INDENT 36

/*
** A layout context holds all state information used by the layout
** engine.
*/
struct HtmlLayoutContext {
  HtmlWidget *htmlPtr;          /* The html widget undergoing layout */
  HtmlElement *pStart;          /* Start of elements to layout */
  HtmlElement *pEnd;            /* Stop when reaching this element */
  int headRoom;                 /* Extra space wanted above this line */
  int top;                      /* Absolute top of drawing area */
  int bottom;                   /* Bottom of previous line */
  int left, right;              /* Left and right extremes of drawing area */
  int pageWidth;                /* Width of the layout field, including
                                ** the margins */
  int maxX, maxY;               /* Maximum X and Y values of paint */
  HtmlMargin *leftMargin;       /* Stack of left margins */
  HtmlMargin *rightMargin;      /* Stack of right margins */
};

/*
** With 28 different fonts and 16 colors, we could in principle have
** as many as 448 different GCs.  But in practice, a single page of
** HTML will typically have much less than this.  So we won't try to
** keep all GCs on hand.  Instead, We'll keep around the most recently
** used GCs and allocate new ones as necessary.
**
** The following structure is used to build a cache of GCs in the
** main widget structure.
*/
#define N_CACHE_GC 16
struct GcCache {
  GC gc;                /* The graphics context */
  Html_u8 font;         /* Font used for this context */
  Html_u8 color;        /* Color used for this context */
  Html_u8 index;        /* Index used for LRU replacement */
};

/*
** An HtmlIndex is a reference to a particular character within a
** particular Text or Space token.  
*/
struct HtmlIndex {
  HtmlElement *p;      /* The token containing the character */
  int i;               /* Index of the character */
};

/*
** A single instance of the following structure (together with various
** other structures to which this structure points) contains complete 
** state information for a single HTML widget.  The clientData for
** the widget command is a pointer to this structure.
**
** The HTML widget is really a mega-widget.  It consists of two nested
** windows.  The outer window (tkwin) contains the focus highlight border,
** the 3D border and the padding between the border and the text.  All
** text that results from the HTML is drawn into the clipping window
** (clipwin).  The clipping window is a child of the main
** window and has the name "x".  We have to use a clipping window so
** that subwindows required by <FORM> will be clipped properly and won't
** overlap with the borders.
**
** Two primary coordinate systems are used in this widget.
**
**   Window coordinates      In this system, (0,0) is the upper left-hand
**                           corner of the clipping window.  This coordinates
**                           apply only to objects which is visible on screen.
**
**   Virtual canvas          The virtual canvas is an imaginary canvas holding
**                           the entire document.  Typically, part of the
**                           virtual canvas will show thru the clipping 
**                           window to become visible.  The mapping from
**                           window to virtual canvas coordinates is
**                           governed by the "xOffset" and "yOffset" fields
**                           of the widget structure.
**
** 
*/
struct HtmlWidget {
  Tk_Window tkwin;              /* The main window for this widget */
  Tk_Window clipwin;            /* The clipping window in which all text is
                                ** rendered. */
  char *zClipwin;               /* Name of the clipping window. */
  Display *display;             /* The X11 Server that contains tkwin */
  Tcl_Interp *interp;           /* The interpreter in which the widget lives */
  char *zCmdName;               /* Name of the command */
  HtmlElement *pFirst;          /* First HTML token on a list of them all */
  HtmlElement *pLast;           /* Last HTML token on the list */
  int nToken;                   /* Number of HTML tokens on the list.
                                 * Html_Block tokens don't count. */
  HtmlElement *lastSized;       /* Last HTML element that has been sized */
  HtmlElement *nextPlaced;      /* Next HTML element that needs to be 
                                 * positioned on canvas. */
  HtmlBlock *firstBlock;        /* List of all HtmlBlock tokens */
  HtmlBlock *lastBlock;         /* Last HtmlBlock in the list */
  HtmlElement *firstInput;      /* First <INPUT> element */
  HtmlElement *lastInput;       /* Last <INPUT> element */
  int nInput;                   /* The number of <INPUT> elements */
  int nForm;                    /* The number of <FORM> elements */
  int varId;                    /* Used to construct a unique name for a
                                ** global array used by <INPUT> elements */

  /*
   * Information about the selected region of text
   */
  HtmlIndex selBegin;           /* Start of the selection */
  HtmlIndex selEnd;             /* End of the selection */
  HtmlBlock *pSelStartBlock;    /* Block in which selection starts */
  Html_16 selStartIndex;        /* Index in pSelStartBlock of first selected
                                 * character */
  Html_16 selEndIndex;          /* Index of last selecte char in pSelEndBlock */
  HtmlBlock *pSelEndBlock;      /* Block in which selection ends */

  /*
   * Information about the insertion cursor 
   */
  int insOnTime;                /* How long the cursor states one (millisec) */
  int insOffTime;               /* How long it is off (milliseconds) */
  int insStatus;                /* Is it visible? */
  Tcl_TimerToken insTimer;      /* Timer used to flash the insertion cursor */
  HtmlIndex ins;                /* The insertion cursor position */
  HtmlBlock *pInsBlock;         /* The HtmlBlock containing the cursor */
  int insIndex;                 /* Index in pInsBlock of the cursor */

  /*
   * The following fields hold state information used by
   * the tokenizer.
   */
  char *zText;                  /* Complete text of the unparsed HTML */
  int nText;                    /* Number of characters in zText */
  int nAlloc;                   /* Space allocated for zText */
  int nComplete;                /* How much of zText has actually been
                                 * converted into tokens */
  int iCol;                     /* The column in which zText[nComplete]
                                 * occurs.  Used to resolve tabs in input */
  int iPlaintext;               /* If not zero, this is the token type that
                                 * caused us to go into plaintext mode.  One
                                 * of Html_PLAINTEXT, Html_LISTING or
                                 * Html_XMP */
  HtmlScript *pScript;            /* <SCRIPT> currently being parsed */
  char *zHandler[Html_TypeCount]; /* If not NULL, this is a TCL routine that
                                 * is used to process tokens of the given 
                                 * type */
  /*
   * These fields hold state information used by the HtmlAddStyle routine.
   * We have to store this state information here since HtmlAddStyle
   * operates incrementally.  This information must be carried from
   * one incremental execution to the next.
   */
  HtmlStyleStack *styleStack;   /* The style stack */
  int paraAlignment;            /* Justification associated with <p> */
  int rowAlignment;             /* Justification associated with <tr> */
  int anchorFlags;              /* Style flags associated with <A>...</A> */
  int inDt;                     /* Style flags associated with <DT>...</DT> */
  int inTr;                     /* True if within <tr>..</tr> */
  int inTd;                     /* True if within <td>..</td> or <th>..</th> */
  HtmlElement *anchorStart;     /* Most recent <a href=...> */
  HtmlElement *formStart;       /* Most recent <form> */
  HtmlElement *formElemStart;   /* Most recent <textarea> or <select> */
  HtmlElement *innerList;       /* The inner most <OL> or <UL> */

  /*
   * These fields are used to hold the state of the layout engine.
   * Because the layout is incremental, this state must be held for
   * the life of the widget.
   */
  HtmlLayoutContext layoutContext;

  /*
   * Information used when displaying the widget:
   */
  Tk_3DBorder border;		/* Background color */
  int borderWidth;		/* Width of the border. */
  int relief;			/* 3-D effect: TK_RELIEF_RAISED, etc. */
  int highlightWidth;		/* Width in pixels of highlight to draw
				 * around widget when it has the focus.
				 * <= 0 means don't draw a highlight. */
  XColor *highlightBgColorPtr;  /* Color for drawing traversal highlight
				 * area when highlight is off. */
  XColor *highlightColorPtr;	/* Color for drawing traversal highlight. */
  int inset;			/* Total width of highlight and 3-D border */
  Tk_Font aFont[N_FONT];	/* Information about all screen fonts */
  char fontValid[(N_FONT+7)/8]; /* If bit N%8 of work N/8 of this field is 0
                                 * if aFont[N] needs to be reallocated before
                                 * being used. */
  XColor *apColor[N_COLOR];     /* Information about all colors */
  int colorUsed;                /* bit N is 1 if color N is in use.  Only
                                ** applies to colors that aren't predefined */
  int iDark[N_COLOR];           /* Dark 3D shadow of color K is iDark[K] */
  int iLight[N_COLOR];          /* Light 3D shadow of color K is iLight[K] */
  XColor *fgColor;              /* Color of normal text. apColor[0] */
  XColor *newLinkColor;         /* Color of unvisitied links. apColor[1] */
  XColor *oldLinkColor;         /* Color of visitied links. apColor[2] */
  XColor *selectionColor;       /* Background color for selections */
  GcCache aGcCache[N_CACHE_GC]; /* A cache of GCs for general use */
  int lastGC;                   /* Index of recently used GC */
  HtmlImage *imageList;         /* A list of all images */
  int width, height;		/* User-requested size of the usable drawing
                                 * area, in pixels.   Borders and padding
                                 * make the actual window a little larger */
  int realWidth, realHeight;    /* The actual physical size of tkwin as
                                 * reported in the most recent ConfigureNotify
                                 * event. */
  int padx, pady;               /* Separation between the edge of the window
                                 * and rendered HTML.  */
  int underlineLinks;           /* TRUE if we should underline hyperlinks */

  /* Information about the selection
  */
  int exportSelection;          /* True if the selection is automatically
                                 * exported to the clipboard */

  /* Callback commands.  The HTML parser will invoke callbacks from time
  ** to time to find out information it needs to complete formatting of
  ** the document.  The following fields define the callback commands.
  */
  char *zIsVisited;             /* Command to tell if a hyperlink has already
                                ** been visited */
  char *zGetImage;              /* Command to get an image from a URL */
  char *zFrameCommand;          /* Command for handling <frameset> markup */
  char *zAppletCommand;         /* Command to process applets */
  char *zResolverCommand;       /* Command to resolve URIs */
  char *zFormCommand;           /* When user presses Submit */
  char *zHyperlinkCommand;      /* Invoked when a hyperlink is clicked */
  char *zFontCommand;           /* Invoked to find font names */
  char *zScriptCommand;         /* Invoked for each <SCRIPT> markup */

   /*
    * Miscellaneous information:
    */
  int tableRelief;              /* 3d effects on <TABLE> */
  int ruleRelief;               /* 3d effects on <HR> */
  char *zBase;                  /* The base URI */
  char *zBaseHref;              /* zBase as modified by <BASE HREF=..> markup */
  Tk_Cursor cursor;		/* Current cursor for window, or None. */
  char *takeFocus;		/* Value of -takefocus option;  not used in
				 * the C code, but used by keyboard traversal
				 * scripts.  Malloc'ed, but may be NULL. */
  char *yScrollCmd;		/* Command prefix for communicating with
				 * vertical scrollbar.  NULL means no command
				 * to issue.  Malloc'ed. */
  char *xScrollCmd;		/* Command prefix for communicating with
				 * horizontal scrollbar.  NULL means no command
				 * to issue.  Malloc'ed. */
  int xOffset, yOffset;         /* Current scroll position.  These form the
                                 * coordinate in the virtual canvas that
                                 * corresponds to (0,0) on the physical screen
                                 * in window tkwin */
  int maxX, maxY;               /* Maximum extent of any "paint" that appears
                                 * on the virtual canvas.  Used to compute 
                                 * scrollbar positions. */
  int dirtyLeft, dirtyTop;      /* Top left corner of region to redraw.  These
                                 * are physical screen coordinates relative to
                                 * clipwin, not tkwin. */
  int dirtyRight, dirtyBottom;  /* Bottom right corner of region to redraw */
  int locked;                   /* Number of locks on this structure. Don't
                                ** delete until it reaches zero. */
  int flags;			/* Various flags;  see below for
				 * definitions. */
}

/*
 * Flag bits "flags" field of the Html widget:
 *
 * REDRAW_PENDING         A DoWhenIdle handler has already been queued to 
 *                        call HtmlRedrawCallback() function.
 *
 * GOT_FOCUS              This widget currently has input focus.
 *
 * HSCROLL                Horizontal scrollbar position needs to be
 *                        recomputed.
 *
 * VSCROLL                Vertical scrollbar position needs to be
 *                        recomputed.
 *
 * RELAYOUT               We need to reposition every element on the 
 *                        virtual canvas.  (This happens, for example,
 *                        when the size of the widget changes and we
 *                        need to recompute the line breaks.)
 *
 * RESIZE_ELEMENTS        We need to recompute the size of every element.
 *                        This happens, for example, when the fonts
 *                        change.
 *
 * REDRAW_FOCUS           We need to repaint the focus highlight border.
 *
 * REDRAW_TEXT            Everything in the clipping window needs to be redrawn.
 *
 * REDRAW_BORDER          Everything outside the clipping window needs
 *                        to be redrawn.
 *
 * RESIZE_CLIPWIN         The size and position of the clipping window 
 *                        needs to be adjusted using Tk_MoveResizeWindow().
 *
 * STYLER_RUNNING         There is a call to HtmlAddStyle() in process.
 *                        Used to prevent a recursive call to HtmlAddStyle().
 *
 * INSERT_FLASHING        True if there is a timer callback pending that will
 *                        toggle the state of the insertion cursor.
 *
 * REDRAW_IMAGES          One or more HtmlImageMarkup structures have
 *                        their redrawNeeded flag set.
 */

#define REDRAW_PENDING	     0x000001
#define GOT_FOCUS            0x000002
#define HSCROLL              0x000004
#define VSCROLL              0x000008
#define RELAYOUT             0x000010
#define RESIZE_ELEMENTS      0x000020
#define REDRAW_FOCUS         0x000040
#define REDRAW_TEXT          0x000080
#define REDRAW_BORDER        0x000100
#define EXTEND_LAYOUT        0x000200
#define RESIZE_CLIPWIN       0x000400
#define STYLER_RUNNING       0x000800
#define INSERT_FLASHING      0x001000
#define REDRAW_IMAGES        0x002000

/*
** Macros to set, clear or test bits of the "flags" field.
*/
#define HtmlHasFlag(A,F)      (((A)->flags&(F))==(F))
#define HtmlHasAnyFlag(A,F)   (((A)->flags&(F))!=0)
#define HtmlSetFlag(A,F)      ((A)->flags|=(F))
#define HtmlClearFlag(A,F)    ((A)->flags&=~(F))

/*
** No coordinate is every as big as this number
*/
#define LARGE_NUMBER 100000000

/*
** Default values for configuration options
*/
#define DEF_HTML_BG_COLOR             DEF_FRAME_BG_COLOR
#define DEF_HTML_BG_MONO              DEF_FRAME_BG_MONO
#define DEF_HTML_BORDER_WIDTH         "2"
#define DEF_HTML_CALLBACK             ""
#define DEF_HTML_CURSOR               DEF_FRAME_CURSOR
#define DEF_HTML_EXPORT_SEL           "yes"
#define DEF_HTML_FG                   DEF_BUTTON_FG
#define DEF_HTML_HEIGHT               "400"
#define DEF_HTML_HIGHLIGHT_BG         DEF_BUTTON_HIGHLIGHT_BG
#define DEF_HTML_HIGHLIGHT            DEF_BUTTON_HIGHLIGHT
#define DEF_HTML_HIGHLIGHT_WIDTH      "0"
#define DEF_HTML_INSERT_OFF_TIME      "300"
#define DEF_HTML_INSERT_ON_TIME       "600"
#define DEF_HTML_PADX                 "5"
#define DEF_HTML_PADY                 "5"
#define DEF_HTML_RELIEF               "raised"
#define DEF_HTML_SCROLL_COMMAND       ""
#define DEF_HTML_SELECTION_COLOR      "skyblue"
#define DEF_HTML_TAKE_FOCUS           "0"
#define DEF_HTML_UNVISITED            "blue1"
#define DEF_HTML_VISITED              "blue3"
#define DEF_HTML_WIDTH                "600"

#ifdef NAVIGATOR_TABLES

#define DEF_HTML_TABLE_BORDER             "0"
#define DEF_HTML_TABLE_CELLPADDING        "2"
#define DEF_HTML_TABLE_CELLSPACING        "5"
#define DEF_HTML_TABLE_BORDER_LIGHT_COLOR "gray80"
#define DEF_HTML_TABLE_BORDER_DARK_COLOR  "gray40"

#endif /* NAVIGATOR_TABLES */