4
* This header file contains the definition of the HtmlComputedValues
5
* structure, which stores a set of CSS2 properties output by the
6
* styler. This information is used by the layout engine in
7
* htmllayout.c to create the runtime model of the document.
9
* -----------------------------------------------------------------------
13
#ifndef __HTMLPROP_H__
14
#define __HTMLPROP_H__
17
* We need <limits.h> to get the INT_MIN symbol (the most negative number that
18
* can be stored in a C "int".
22
typedef struct HtmlFourSides HtmlFourSides;
23
typedef struct HtmlComputedValues HtmlComputedValues;
24
typedef struct HtmlComputedValuesCreator HtmlComputedValuesCreator;
25
typedef struct HtmlColor HtmlColor;
26
typedef struct HtmlCounterList HtmlCounterList;
28
typedef struct HtmlFont HtmlFont;
29
typedef struct HtmlFontKey HtmlFontKey;
30
typedef struct HtmlFontCache HtmlFontCache;
33
* This structure is used to group four padding, margin or border-width
34
* values together. When we get around to it, it will be used for the
35
* position properties too ('top', 'right', 'bottom' and 'left').
37
struct HtmlFourSides {
45
* The HtmlFont structure is used to store a font in use by the current
46
* document. The following properties are used to determine the Tk
54
* HtmlFont structures are stored in the HtmlTree.aFonts hash table. The hash
55
* table uses a custom key type (struct HtmlFontKey) implemented in htmlhash.c.
57
#define HTML_IFONTSIZE_SCALE 1000
59
/* If iFontSize is positive, then it is in thousandths of points.
60
* If negative, in thousandths of pixels. */
61
int iFontSize; /* Font size in thousandths of points */
63
const char *zFontFamily; /* Name of font family (i.e. "Serif") */
64
unsigned char isItalic; /* True if the font is italic */
65
unsigned char isBold; /* True if the font is bold */
68
int nRef; /* Number of pointers to this structure */
69
HtmlFontKey *pKey; /* Pointer to corresponding HtmlFontKey structure */
70
char *zFont; /* Name of font */
71
Tk_Font tkfont; /* The Tk font */
73
int em_pixels; /* Pixels per 'em' unit */
74
int ex_pixels; /* Pixels per 'ex' unit */
75
int space_pixels; /* Pixels per space (' ') in this font */
76
Tk_FontMetrics metrics;
78
HtmlFont *pNext; /* Next entry in the Html.FontCache LRU list */
82
* In Tk, allocating new fonts is very expensive. So we try hard to
83
* avoid doing it more than is required.
85
#define HTML_MAX_ZEROREF_FONTS 50
86
struct HtmlFontCache {
94
* An HtmlColor structure is used to store each color in use by the current
95
* document. HtmlColor structures are stored in the HtmlTree.aColors hash
96
* table. The hash table uses string keys (the name of the color).
99
int nRef; /* Number of pointers to this structure */
100
char *zColor; /* Name of color */
101
XColor *xcolor; /* The XColor* */
105
* An HtmlCounterList is used to store the computed value of the
106
* 'counter-increment' and 'counter-reset' properties.
108
struct HtmlCounterList {
117
* An instance of this structure stores a set of property values as assigned by
118
* the styler process. The values are as far as I can tell "computed" values,
119
* but in some cases I'm really only guessing.
121
* All values are stored as one of the following broad "types":
124
* ------------------------------------------
125
* eXXX Enumerated type values
126
* iXXX Pixel type values
127
* cXXX Color type values
128
* fXXX Font type values
129
* ------------------------------------------
131
* Enumerated type values
133
* Many properties can be stored as a single variable, for example the
134
* 'display' property is stored in the HtmlComputedValues.eDisplay
135
* variable. Members of the HtmlComputedValues structure with names that
136
* match the pattern "eXXX" contain a CSS constant value (one of the
137
* CSS_CONST_XXX #define symbols). These are defined in the header file
138
* cssprop.h, which is generated during compilation by the script in
141
* Note: Since we use 'unsigned char' to store the eXXX variables:
143
* assert(CSS_CONST_MIN_CONSTANT >= 0);
144
* assert(CSS_CONST_MAX_CONSTANT < 256);
152
* Most variables that match the pattern 'iXXX' contain pixel values - a
153
* length or size expressed in pixels. The only exceptions at the moment
154
* are HtmlFontKey.iFontSize and iZIndex.
158
* Some values, for example the 'width' property, may be either
159
* calculated to an exact number of pixels by the styler or left as a
160
* percentage value. In the first case, the 'int iXXX;' variable for
161
* the property contains the number of pixels. Otherwise, it contains
162
* the percentage value multiplied by 100. If the value is a
163
* percentage, then the PROP_MASK_XXX bit is set in the
164
* HtmlComputedValues.mask mask. For example, given the width of the
165
* parent block in pixels, the following code determines the width in
166
* pixels contained by the HtmlComputedValues structure:
168
* int iParentPixelWidth = <some assignment>;
169
* HtmlComputedValues Values = <some assignment>;
172
* if (Values.mask & PROP_MASK_WIDTH) {
173
* iPixelWidth = (Values.iWidth * iParentPixelWidth / 10000);
175
* iPixelWidth = Values.iWidth;
178
* The 'auto', 'none' and 'normal' values:
180
* If a pixel type value is set to 'auto', 'none' or 'normal', the
181
* integer variable is set to the constant PIXELVAL_AUTO,
182
* PIXELVAL_NONE or PIXELVAL_NORMAL respectively. These are both very
183
* large negative numbers, unlikely to be confused with real pixel
188
* The 'vertical-align' property, stored in iVerticalAlign is different
189
* from the other iXXX values. The styler output for vertical align is
190
* either a number of pixels or one of the constants 'baseline', 'sub'
191
* 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom'. The
192
* 'vertical-align' property can be assigned a percentage value, but
193
* the styler can resolve it. (This matches the CSS 2.1 description of
194
* the computed value - section 10.8.1).
196
* If 'vertical-align' is a constant value, it is stored in
197
* eVerticalAlign (as a CSS_CONST_XXX value). Otherwise, if it is a
198
* pixel value it is stored in iVerticalAlign and eVerticalAlign is set
202
* Todo: Note that inheritance is not done correctly for this property
203
* if it is set to <number>.
206
* Properties not represented:
208
* The following properties should be supported by this structure, as
209
* Tkhtml aims to one day support them. They are not currently supported
210
* because (a) layout engine support is a long way off, and (b) it would
211
* be tricky in some way to do so:
213
* 'clip' 'cursor' 'counter-increment'
214
* 'counter-reset' 'quotes'
216
struct HtmlComputedValues {
217
HtmlImage2 *imZoomedBackgroundImage; /* MUST BE FIRST (see htmlhash.c) */
218
int nRef; /* MUST BE FIRST (see htmlhash.c) */
222
unsigned char eDisplay; /* 'display' */
223
unsigned char eFloat; /* 'float' */
224
unsigned char eClear; /* 'clear' */
226
/* ePosition stores the enumerated 'position' property. The position
227
* structure stores the computed values of the 'top', 'bottom', 'left'
228
* and 'right' properties. */
229
unsigned char ePosition; /* 'position' */
230
HtmlFourSides position; /* (pixels, %, AUTO) */
232
HtmlColor *cBackgroundColor; /* 'background-color' */
234
unsigned char eTextDecoration; /* 'text-decoration' */
236
/* See above. iVerticalAlign is used only if (eVerticalAlign==0) */
237
unsigned char eVerticalAlign; /* 'vertical-align' */
238
int iVerticalAlign; /* 'vertical-align' (pixels) */
240
int iWidth; /* 'width' (pixels, %, AUTO) */
241
int iMinWidth; /* 'min-width' (pixels, %) */
242
int iMaxWidth; /* 'max-height' (pixels, %, NONE) */
243
int iHeight; /* 'height' (pixels, % AUTO) */
244
int iMinHeight; /* 'min-height' (pixels, %) */
245
int iMaxHeight; /* 'max-height' (pixels, %, NONE) */
246
HtmlFourSides padding; /* 'padding' (pixels, %) */
247
HtmlFourSides margin; /* 'margin' (pixels, %, AUTO) */
249
HtmlFourSides border; /* 'border-width' (pixels) */
250
unsigned char eBorderTopStyle; /* 'border-top-style' */
251
unsigned char eBorderRightStyle; /* 'border-right-style' */
252
unsigned char eBorderBottomStyle; /* 'border-bottom-style' */
253
unsigned char eBorderLeftStyle; /* 'border-left-style' */
254
HtmlColor *cBorderTopColor; /* 'border-top-color' */
255
HtmlColor *cBorderRightColor; /* 'border-right-color' */
256
HtmlColor *cBorderBottomColor; /* 'border-bottom-color' */
257
HtmlColor *cBorderLeftColor; /* 'border-left-color' */
259
unsigned char eOutlineStyle; /* 'outline-style' */
260
int iOutlineWidth; /* 'outline-width' (pixels) */
261
HtmlColor *cOutlineColor; /* 'outline-color' */
263
HtmlImage2 *imBackgroundImage; /* 'background-image' */
264
unsigned char eBackgroundRepeat; /* 'background-repeat' */
265
unsigned char eBackgroundAttachment; /* 'background-attachment' */
266
int iBackgroundPositionX;
267
int iBackgroundPositionY;
269
unsigned char eOverflow; /* 'overflow' */
271
int iZIndex; /* 'z-index' (integer, AUTO) */
273
/* The Tkhtml specific properties */
274
HtmlImage2 *imReplacementImage; /* '-tkhtml-replacement-image' */
276
int iOrderedListStart; /* '-tkhtml-ordered-list-start' */
277
int iOrderedListValue; /* '-tkhtml-ordered-list-value' */
279
/* Properties not yet in use - TODO! */
280
unsigned char eUnicodeBidi; /* 'unicode-bidi' */
281
unsigned char eTableLayout; /* 'table-layout' */
283
HtmlCounterList *clCounterReset;
284
HtmlCounterList *clCounterIncrement;
286
/* 'font-size', 'font-family', 'font-style', 'font-weight' */
289
/* INHERITED PROPERTIES START HERE */
290
unsigned char eListStyleType; /* 'list-style-type' */
291
unsigned char eListStylePosition; /* 'list-style-position' */
292
unsigned char eWhitespace; /* 'white-space' */
293
unsigned char eTextAlign; /* 'text-align' */
294
unsigned char eVisibility; /* 'visibility' */
295
HtmlColor *cColor; /* 'color' */
296
HtmlImage2 *imListStyleImage; /* 'list-style-image' */
297
int iTextIndent; /* 'text-indext' (pixels, %) */
298
int iBorderSpacing; /* 'border-spacing' (pixels) */
299
int iLineHeight; /* 'line-height' (pixels, %, NORMAL) */
300
unsigned char eFontVariant; /* 'font-variant' */
302
unsigned char eCursor; /* 'cursor' */
304
/* Properties not yet in use - TODO! */
305
int iWordSpacing; /* 'word-spacing' (pixels, NORMAL) */
306
int iLetterSpacing; /* 'letter-spacing' (pixels, NORMAL) */
307
unsigned char eTextTransform; /* 'text-transform' */
308
unsigned char eDirection; /* 'direction' */
309
unsigned char eBorderCollapse; /* 'border-collapse' */
310
unsigned char eCaptionSide; /* 'caption-side' */
311
unsigned char eEmptyCells; /* 'empty-cells' */
315
* If pzContent is not NULL, then the pointer it points to may be set
316
* to point at allocated memory in which to store the computed value
317
* of the 'content' property.
319
struct HtmlComputedValuesCreator {
320
HtmlComputedValues values;
324
HtmlNode *pNode; /* Node to associate LOG with */
325
HtmlNode *pParent; /* Node to inherit from */
326
unsigned int em_mask;
327
unsigned int ex_mask;
328
int eVerticalAlignPercent; /* True if 'vertical-align' is a % */
329
CssProperty *pDeleteList;
331
CssProperty *pContent;
338
* According to the spec, the following CSS2 properties can also be set to
341
* Unsupported properties:
342
* 'background-position'
343
* 'bottom', 'top', 'left', 'right'
346
* These can be set to percentages, but the styler can resolve them:
347
* 'font-size', 'line-height', 'vertical-align'
349
* The HtmlComputedValues.mask mask also contains the
350
* CONSTANT_MASK_VERTICALALIGN bit. If this bit is set, then
351
* HtmlComputedValues.iVerticalAlign should be interpreted as a constant value
352
* (like an HtmlComputedValues.eXXX variable).
354
#define PROP_MASK_WIDTH 0x00000001
355
#define PROP_MASK_MIN_WIDTH 0x00000002
356
#define PROP_MASK_MAX_WIDTH 0x00000004
357
#define PROP_MASK_HEIGHT 0x00000008
358
#define PROP_MASK_MIN_HEIGHT 0x00000010
359
#define PROP_MASK_MAX_HEIGHT 0x00000020
360
#define PROP_MASK_MARGIN_TOP 0x00000040
361
#define PROP_MASK_MARGIN_RIGHT 0x00000080
362
#define PROP_MASK_MARGIN_BOTTOM 0x00000100
363
#define PROP_MASK_MARGIN_LEFT 0x00000200
364
#define PROP_MASK_PADDING_TOP 0x00000400
365
#define PROP_MASK_PADDING_RIGHT 0x00000800
366
#define PROP_MASK_PADDING_BOTTOM 0x00001000
367
#define PROP_MASK_PADDING_LEFT 0x00002000
368
#define PROP_MASK_VERTICAL_ALIGN 0x00004000
369
#define PROP_MASK_BORDER_TOP_WIDTH 0x00008000
370
#define PROP_MASK_BORDER_RIGHT_WIDTH 0x00010000
371
#define PROP_MASK_BORDER_BOTTOM_WIDTH 0x00020000
372
#define PROP_MASK_BORDER_LEFT_WIDTH 0x00040000
373
#define PROP_MASK_LINE_HEIGHT 0x00080000
374
#define PROP_MASK_BACKGROUND_POSITION_X 0x00100000
375
#define PROP_MASK_BACKGROUND_POSITION_Y 0x00200000
376
#define PROP_MASK_BORDER_SPACING 0x00400000
377
#define PROP_MASK_OUTLINE_WIDTH 0x00800000
378
#define PROP_MASK_TOP 0x01000000
379
#define PROP_MASK_BOTTOM 0x02000000
380
#define PROP_MASK_RIGHT 0x04000000
381
#define PROP_MASK_LEFT 0x08000000
382
#define PROP_MASK_TEXT_INDENT 0x10000000
383
#define PROP_MASK_WORD_SPACING 0x20000000
384
#define PROP_MASK_LETTER_SPACING 0x40000000
387
* Pixel values in the HtmlComputedValues struct may also take the following
388
* special values. These are all very large negative numbers, unlikely to be
389
* confused with real pixel counts. INT_MIN comes from <limits.h>, which is
390
* supplied by Tcl if the operating system doesn't have it.
392
#define PIXELVAL_AUTO (2 + (int)INT_MIN)
393
#define PIXELVAL_NONE (3 + (int)INT_MIN)
394
#define PIXELVAL_NORMAL (4 + (int)INT_MIN)
395
#define MAX_PIXELVAL (5 + (int)INT_MIN)
398
* API Notes for managing HtmlComputedValues structures:
400
* The following three functions are used by the styler phase to create and
401
* populate an HtmlComputedValues structure (a set of property values for a
404
* HtmlComputedValuesInit() (exactly one call)
405
* HtmlComputedValuesSet() (zero or more calls)
406
* HtmlComputedValuesFinish() (exactly one call)
408
* To use this API, the caller allocates (either on the heap or the stack,
409
* doesn't matter) an HtmlComputedValuesCreator struct. The contents are
410
* initialised by HtmlComputedValuesInit().
412
* HtmlComputedValuesCreator sValues;
413
* HtmlComputedValuesInit(pTree, pNode, &sValues);
415
* This initialises the HtmlComputedValuesCreator structure to contain the
416
* default (called "initial" in the CSS spec) value for each property. The
417
* default property values can be overwritten using the
418
* HtmlComputedValuesSet() function (see comments above implementation
421
* Finally, HtmlComputedValuesFinish() is called to obtain the populated
422
* HtmlComputedValues structure. This function returns a pointer to an
423
* HtmlComputedValues structure, which should be associated with the node
424
* in question before it is passed to the layout engine:
426
* p = HtmlComputedValuesFinish(&sValues);
428
* pNode->pPropertyValues = p;
430
* Once an HtmlComputedValues pointer returned by Finish() is no longer
431
* required (when the node is being restyled or deleted), it should be
434
* HtmlComputedValuesRelease(pNode->pPropertyValues);
436
void HtmlComputedValuesInit(
437
HtmlTree*, HtmlNode*, HtmlNode*, HtmlComputedValuesCreator*);
438
int HtmlComputedValuesSet(HtmlComputedValuesCreator *, int, CssProperty*);
439
HtmlComputedValues *HtmlComputedValuesFinish(HtmlComputedValuesCreator *);
441
void HtmlComputedValuesFreeProperty(HtmlComputedValuesCreator*, CssProperty *);
443
void HtmlComputedValuesRelease(HtmlTree *, HtmlComputedValues*);
444
void HtmlComputedValuesReference(HtmlComputedValues *);
447
* The following two functions are used to initialise and destroy the following
448
* tables used by code in htmlprop.c. They are called as part of the
449
* initialisation and destruction of the widget.
454
* HtmlTree.aFontSizeTable
456
void HtmlComputedValuesSetupTables(HtmlTree *);
457
void HtmlComputedValuesCleanupTables(HtmlTree *);
459
void HtmlComputedValuesFreePrototype(HtmlTree *);
462
* Empty the font cache (i.e. because font config options have changed).
464
void HtmlFontCacheClear(HtmlTree *, int);
467
* This function formats the HtmlComputedValues structure as a Tcl list and
468
* sets the result of the interpreter to that list. Used to allow inspection of
469
* a nodes computed values from a Tcl script.
471
int HtmlNodeProperties(Tcl_Interp *, HtmlComputedValues *);
472
int HtmlNodeGetProperty(Tcl_Interp *, Tcl_Obj *, HtmlComputedValues *);
475
* Determine if changing the computed properties of a node from one
476
* argument structure to the other requires a re-layout. Return 1 if it
477
* does, or 0 otherwise.
479
int HtmlComputedValuesCompare(HtmlComputedValues *, HtmlComputedValues *);
482
#define HTML_COMPUTED_MARGIN_TOP margin.iTop
483
#define HTML_COMPUTED_MARGIN_RIGHT margin.iRight
484
#define HTML_COMPUTED_MARGIN_BOTTOM margin.iBottom
485
#define HTML_COMPUTED_MARGIN_LEFT margin.iLeft
487
#define HTML_COMPUTED_PADDING_TOP padding.iTop
488
#define HTML_COMPUTED_PADDING_RIGHT padding.iRight
489
#define HTML_COMPUTED_PADDING_BOTTOM padding.iBottom
490
#define HTML_COMPUTED_PADDING_LEFT padding.iLeft
492
#define HTML_COMPUTED_PADDING_TOP padding.iTop
493
#define HTML_COMPUTED_PADDING_RIGHT padding.iRight
494
#define HTML_COMPUTED_PADDING_BOTTOM padding.iBottom
495
#define HTML_COMPUTED_PADDING_LEFT padding.iLeft
497
#define HTML_COMPUTED_TOP position.iTop
498
#define HTML_COMPUTED_RIGHT position.iRight
499
#define HTML_COMPUTED_BOTTOM position.iBottom
500
#define HTML_COMPUTED_LEFT position.iLeft
502
#define HTML_COMPUTED_HEIGHT iHeight
503
#define HTML_COMPUTED_WIDTH iWidth
504
#define HTML_COMPUTED_MIN_HEIGHT iMinHeight
505
#define HTML_COMPUTED_MIN_WIDTH iMinWidth
506
#define HTML_COMPUTED_MAX_HEIGHT iMaxHeight
507
#define HTML_COMPUTED_MAX_WIDTH iMaxWidth
508
#define HTML_COMPUTED_TEXT_INDENT iTextIndent
510
/* The PIXELVAL macro takes three arguments:
512
* pV - Pointer to HtmlComputedValues structure.
514
* prop - Property identifier (i.e. MARGIN_LEFT). The
515
* HTML_COMPUTED_XXX macros define the set of acceptable
518
* percent_of - The pixel value used to calculate percentage values against.
522
* * If percent_of is less than 0 (i.e. PIXELVAL_AUTO) and the property
523
* specified by prop computed to a percentage, a copy of percent_of is
526
* * If pV==NULL, 0 is returned.
528
#define PIXELVAL(pV, prop, percent_of) ( \
530
((pV)->mask & PROP_MASK_ ## prop) ? ( \
531
((percent_of) <= 0) ? (percent_of) : \
532
(((pV)-> HTML_COMPUTED_ ## prop * (percent_of)) / 10000) \
533
) : ((pV)-> HTML_COMPUTED_ ## prop) \