* use qe_mallocz for all structures * prevent spurious uses of malloc/free/realloc * pass pointers to pointers to all deletion functions * use consistent patterns for list deletions * add more dependencies in Makefiles
680 lines
22 KiB
C
680 lines
22 KiB
C
/*
|
|
* CSS core for qemacs.
|
|
*
|
|
* Copyright (c) 2000-2002 Fabrice Bellard.
|
|
* Copyright (c) 2007-2014 Charlie Gordon.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser 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
|
|
*/
|
|
|
|
#ifndef CSS_H
|
|
#define CSS_H
|
|
|
|
struct CSSBox;
|
|
|
|
typedef struct CSSBox CSSBox;
|
|
|
|
/* display property */
|
|
enum CSSDisplay {
|
|
CSS_DISPLAY_INLINE,
|
|
CSS_DISPLAY_BLOCK,
|
|
CSS_DISPLAY_TABLE,
|
|
CSS_DISPLAY_TABLE_ROW,
|
|
CSS_DISPLAY_TABLE_ROW_GROUP,
|
|
CSS_DISPLAY_TABLE_HEADER_GROUP,
|
|
CSS_DISPLAY_TABLE_FOOTER_GROUP,
|
|
CSS_DISPLAY_TABLE_COLUMN,
|
|
CSS_DISPLAY_TABLE_COLUMN_GROUP,
|
|
CSS_DISPLAY_TABLE_CELL,
|
|
CSS_DISPLAY_TABLE_CAPTION,
|
|
CSS_DISPLAY_LIST_ITEM,
|
|
CSS_DISPLAY_MARKER,
|
|
CSS_DISPLAY_INLINE_BLOCK, /* qemacs extension (CSS3 ?) */
|
|
CSS_DISPLAY_INLINE_TABLE,
|
|
CSS_DISPLAY_NONE,
|
|
};
|
|
|
|
enum CSSProperties {
|
|
CSS_display,
|
|
CSS_color,
|
|
CSS_background_color,
|
|
CSS_white_space,
|
|
#define CSS_WHITE_SPACE_NORMAL 0
|
|
#define CSS_WHITE_SPACE_PRE 1
|
|
#define CSS_WHITE_SPACE_NOWRAP 2
|
|
#define CSS_WHITE_SPACE_PREWRAP 3 /* qemacs extension for editing
|
|
(XXX: use CSS3)*/
|
|
CSS_direction,
|
|
#define CSS_DIRECTION_LTR 0
|
|
#define CSS_DIRECTION_RTL 1
|
|
CSS_float,
|
|
#define CSS_FLOAT_NONE 0
|
|
#define CSS_FLOAT_LEFT 1
|
|
#define CSS_FLOAT_RIGHT 2
|
|
CSS_font_family,
|
|
CSS_font_style,
|
|
#define CSS_FONT_STYLE_NORMAL 0
|
|
#define CSS_FONT_STYLE_ITALIC 1
|
|
CSS_font_weight,
|
|
#define CSS_FONT_WEIGHT_NORMAL 0
|
|
#define CSS_FONT_WEIGHT_BOLD 1
|
|
#define CSS_FONT_WEIGHT_BOLDER 2
|
|
#define CSS_FONT_WEIGHT_LIGHTER 3
|
|
CSS_font_size,
|
|
CSS_text_decoration,
|
|
#define CSS_TEXT_DECORATION_NONE 0
|
|
#define CSS_TEXT_DECORATION_UNDERLINE 1
|
|
#define CSS_TEXT_DECORATION_LINE_THROUGH 2
|
|
CSS_text_align,
|
|
#define CSS_TEXT_ALIGN_LEFT 0
|
|
#define CSS_TEXT_ALIGN_RIGHT 1
|
|
#define CSS_TEXT_ALIGN_CENTER 2
|
|
CSS_width,
|
|
CSS_height,
|
|
CSS_unicode_bidi,
|
|
#define CSS_UNICODE_BIDI_NORMAL 0
|
|
#define CSS_UNICODE_BIDI_EMBED 1
|
|
#define CSS_UNICODE_BIDI_OVERRIDE 2
|
|
CSS_border_width,
|
|
CSS_border_left_width,
|
|
CSS_border_top_width,
|
|
CSS_border_right_width,
|
|
CSS_border_bottom_width,
|
|
|
|
CSS_border_color,
|
|
CSS_border_left_color,
|
|
CSS_border_top_color,
|
|
CSS_border_right_color,
|
|
CSS_border_bottom_color,
|
|
|
|
CSS_border_style,
|
|
CSS_border_left_style,
|
|
CSS_border_top_style,
|
|
CSS_border_right_style,
|
|
CSS_border_bottom_style,
|
|
#define CSS_BORDER_STYLE_NONE 0
|
|
#define CSS_BORDER_STYLE_HIDDEN 1
|
|
#define CSS_BORDER_STYLE_DOTTED 2
|
|
#define CSS_BORDER_STYLE_DASHED 3
|
|
#define CSS_BORDER_STYLE_SOLID 4
|
|
#define CSS_BORDER_STYLE_DOUBLE 5
|
|
#define CSS_BORDER_STYLE_GROOVE 6
|
|
#define CSS_BORDER_STYLE_RIDGE 7
|
|
#define CSS_BORDER_STYLE_INSET 8
|
|
#define CSS_BORDER_STYLE_OUTSET 9
|
|
|
|
CSS_border,
|
|
CSS_border_left,
|
|
CSS_border_top,
|
|
CSS_border_right,
|
|
CSS_border_bottom,
|
|
|
|
CSS_padding,
|
|
CSS_padding_left,
|
|
CSS_padding_top,
|
|
CSS_padding_right,
|
|
CSS_padding_bottom,
|
|
|
|
CSS_margin,
|
|
CSS_margin_left,
|
|
CSS_margin_top,
|
|
CSS_margin_right,
|
|
CSS_margin_bottom,
|
|
CSS_clear,
|
|
#define CSS_CLEAR_NONE 0
|
|
#define CSS_CLEAR_LEFT 1
|
|
#define CSS_CLEAR_RIGHT 2
|
|
#define CSS_CLEAR_BOTH 3
|
|
CSS_overflow,
|
|
#define CSS_OVERFLOW_VISIBLE 0
|
|
#define CSS_OVERFLOW_HIDDEN 1
|
|
CSS_visibility,
|
|
#define CSS_VISIBILITY_VISIBLE 0
|
|
#define CSS_VISIBILITY_HIDDEN 1
|
|
CSS_table_layout,
|
|
#define CSS_TABLE_LAYOUT_AUTO 0
|
|
#define CSS_TABLE_LAYOUT_FIXED 1
|
|
CSS_vertical_align,
|
|
#define CSS_VERTICAL_ALIGN_BASELINE 0
|
|
#define CSS_VERTICAL_ALIGN_SUB 1
|
|
#define CSS_VERTICAL_ALIGN_SUPER 2
|
|
#define CSS_VERTICAL_ALIGN_TOP 3
|
|
#define CSS_VERTICAL_ALIGN_TEXT_TOP 4
|
|
#define CSS_VERTICAL_ALIGN_MIDDLE 5
|
|
#define CSS_VERTICAL_ALIGN_BOTTOM 6
|
|
#define CSS_VERTICAL_ALIGN_TEXT_BOTTOM 7
|
|
CSS_border_collapse,
|
|
#define CSS_BORDER_COLLAPSE_COLLAPSE 0
|
|
#define CSS_BORDER_COLLAPSE_SEPARATE 1
|
|
CSS_border_spacing,
|
|
CSS_border_spacing_horizontal,
|
|
CSS_border_spacing_vertical,
|
|
CSS_line_height,
|
|
CSS_position,
|
|
#define CSS_POSITION_STATIC 0
|
|
#define CSS_POSITION_RELATIVE 1
|
|
#define CSS_POSITION_ABSOLUTE 2
|
|
#define CSS_POSITION_FIXED 3
|
|
CSS_content,
|
|
CSS_caption_side,
|
|
#define CSS_CAPTION_SIDE_TOP 0
|
|
#define CSS_CAPTION_SIDE_BOTTOM 1
|
|
#define CSS_CAPTION_SIDE_LEFT 2
|
|
#define CSS_CAPTION_SIDE_RIGHT 3
|
|
CSS_marker_offset,
|
|
CSS_list_style_type,
|
|
#define CSS_LIST_STYLE_TYPE_DISC 0
|
|
#define CSS_LIST_STYLE_TYPE_CIRCLE 1
|
|
#define CSS_LIST_STYLE_TYPE_SQUARE 2
|
|
#define CSS_LIST_STYLE_TYPE_DECIMAL 3
|
|
#define CSS_LIST_STYLE_TYPE_LOWER_ALPHA 4
|
|
#define CSS_LIST_STYLE_TYPE_UPPER_ALPHA 5
|
|
#define CSS_LIST_STYLE_TYPE_LOWER_ROMAN 6
|
|
#define CSS_LIST_STYLE_TYPE_UPPER_ROMAN 7
|
|
#define CSS_LIST_STYLE_TYPE_NONE 8
|
|
CSS_column_span, /* qemacs extension */
|
|
CSS_row_span, /* qemacs extension */
|
|
CSS_content_alt, /* qemacs extension */
|
|
CSS_list_style_position,
|
|
#define CSS_LIST_STYLE_POSITION_OUTSIDE 0
|
|
#define CSS_LIST_STYLE_POSITION_INSIDE 1
|
|
CSS_counter_reset,
|
|
CSS_counter_increment,
|
|
CSS_bidi_mode, /* qemacs extension */
|
|
#define CSS_BIDI_MODE_NORMAL 0
|
|
#define CSS_BIDI_MODE_TEST 1
|
|
CSS_left,
|
|
CSS_top,
|
|
CSS_right,
|
|
CSS_bottom,
|
|
NB_PROPERTIES,
|
|
};
|
|
|
|
#define CSS_AUTO ((int)0x80000000)
|
|
#define CSS_INHERIT ((int)0x80000001)
|
|
|
|
typedef unsigned int CSSColor;
|
|
|
|
typedef struct CSSPropertyDef {
|
|
const char *name;
|
|
unsigned short struct_offset; /* in CSSState */
|
|
unsigned char storage;
|
|
#define CSS_STORAGE_INT 0
|
|
#define CSS_STORAGE_PTR 1
|
|
unsigned int type;
|
|
#define CSS_TYPE_AUTO 0x80000000
|
|
#define CSS_TYPE_NOINHERIT 0x40000000
|
|
/* the four next properties will be set according to the CSS rules for
|
|
margin, borders and padding */
|
|
#define CSS_TYPE_FOUR 0x20000000
|
|
#define CSS_TYPE_TWO 0x10000000 /* the same with two args */
|
|
#define CSS_TYPE_SPECIAL 0x08000000 /* XXX: special storage needed */
|
|
#define CSS_TYPE_INHERITED 0x04000000 /* property is inherited */
|
|
#define CSS_TYPE_ARGS 0x02000000 /* no limit on number of args */
|
|
/* types can be ored */
|
|
#define CSS_TYPE_LENGTH 0x00000001
|
|
#define CSS_TYPE_COLOR 0x00000002
|
|
#define CSS_TYPE_ENUM 0x00000004
|
|
#define CSS_TYPE_BORDER_STYLE 0x00000008
|
|
#define CSS_TYPE_FONT_FAMILY 0x00000010
|
|
#define CSS_TYPE_BORDER_ENUM 0x00000020
|
|
#define CSS_TYPE_STRING 0x00000040
|
|
#define CSS_TYPE_INTEGER 0x00000080
|
|
#define CSS_TYPE_ATTR 0x00000100 /* attr(x) */
|
|
#define CSS_TYPE_COUNTER 0x00000200 /* counter(x[,type]) */
|
|
#define CSS_TYPE_LIST_STYLE 0x00000400
|
|
#define CSS_TYPE_IDENT 0x00000800
|
|
|
|
} CSSPropertyDef;
|
|
|
|
typedef union CSSPropertyStorage {
|
|
int val; /* CSS_STORAGE_INT */
|
|
struct CSSProperty *ptr; /* CSS_STORAGE_PTR */
|
|
} CSSPropertyStorage;
|
|
|
|
#define CSSPropertyStoragePtr(s, off) ((CSSPropertyStorage*)((char*)(s) + (off)))
|
|
|
|
extern const CSSPropertyDef css_properties[NB_PROPERTIES];
|
|
|
|
/* CSS parsing */
|
|
|
|
/* length are normalized to this value, except pixel units */
|
|
#define CSS_LENGTH_FRAC_BITS 8
|
|
#define CSS_LENGTH_FRAC_BASE (1 << CSS_LENGTH_FRAC_BITS)
|
|
|
|
/* number of pixels for one px */
|
|
#define CSS_SCREEN_PX_SIZE 1
|
|
/* resolution */
|
|
#define CSS_SCREEN_DPI 72
|
|
|
|
#define CSS_TTY_PX_SIZE (1.0/8.0)
|
|
#define CSS_TTY_DPI 9
|
|
|
|
/* currently, we define ex as a scaling of the font size */
|
|
#define CSS_EX_SCALE ((int)(0.8 * CSS_LENGTH_FRAC_BASE))
|
|
|
|
#define CSS_UNIT_NONE 0
|
|
#define CSS_UNIT_PIXEL 1
|
|
#define CSS_UNIT_PERCENT 2
|
|
#define CSS_UNIT_EX 3
|
|
#define CSS_UNIT_EM 4
|
|
#define CSS_UNIT_IN 6
|
|
|
|
/* the following units are never used except in parsing */
|
|
#define CSS_UNIT_MM 5
|
|
#define CSS_UNIT_CM 7
|
|
#define CSS_UNIT_PT 8
|
|
#define CSS_UNIT_PC 9
|
|
|
|
/* additional values */
|
|
#define CSS_VALUE_STRING 11
|
|
#define CSS_VALUE_COUNTER 12
|
|
#define CSS_VALUE_ATTR 13
|
|
#define CSS_VALUE_COLOR 14
|
|
#define CSS_VALUE_IDENT 15
|
|
#define CSS_VALUE_INTEGER 16
|
|
|
|
/* CSS identifier handling */
|
|
typedef enum CSSIdent {
|
|
CSS_ID_NIL = 0,
|
|
CSS_ID_ALL = 1, /* '*' ident */
|
|
#define CSSID(id) CSS_ID_ ## id,
|
|
#define CSSIDSTR(id, str) CSS_ID_ ## id,
|
|
#include "cssid.h"
|
|
#undef CSSID
|
|
#undef CSSIDSTR
|
|
} CSSIdent;
|
|
|
|
typedef struct CSSIdentEntry {
|
|
CSSIdent id;
|
|
struct CSSIdentEntry *hash_next;
|
|
char str[1];
|
|
} CSSIdentEntry;
|
|
|
|
const char *css_ident_str(CSSIdent id);
|
|
CSSIdent css_new_ident(const char *str);
|
|
|
|
static inline unsigned int css_hash_ident(CSSIdent id, unsigned int hash_size)
|
|
{
|
|
return (unsigned int)id % hash_size;
|
|
}
|
|
|
|
/* property handling */
|
|
|
|
typedef struct CSSPropertyValue {
|
|
int type; /* see CSS_UNIT_xxx or CSS_VALUE_xxx */
|
|
union {
|
|
int val;
|
|
char *str;
|
|
CSSIdent attr_id;
|
|
struct {
|
|
CSSIdent counter_id;
|
|
int type;
|
|
} counter;
|
|
} u;
|
|
} CSSPropertyValue;
|
|
|
|
typedef struct CSSProperty {
|
|
unsigned short property;
|
|
unsigned short nb_values;
|
|
struct CSSProperty *next; /* may change: use array ? */
|
|
CSSPropertyValue value; /* in fact an array, but need
|
|
to change all the types */
|
|
} CSSProperty;
|
|
|
|
/* tag attribute handling */
|
|
|
|
typedef struct CSSAttribute {
|
|
CSSIdent attr;
|
|
struct CSSAttribute *next;
|
|
char value[1];
|
|
} CSSAttribute;
|
|
|
|
/* css box definition (most important data structure) */
|
|
|
|
struct CSSBox {
|
|
CSSIdent tag; /* tag name of the box, may be CSS_ID_NIL
|
|
for anonymous box */
|
|
CSSAttribute *attrs; /* attributes (may be NULL) */
|
|
CSSProperty *properties; /* explicit properties */
|
|
struct CSSState *props; /* computed properties for this box */
|
|
struct CSSBox *next; /* next box at same level */
|
|
/* bounding box of the draw primitives of the box and all its
|
|
childs */
|
|
CSSRect bbox;
|
|
/* layout info */
|
|
int x, y; /* absolute content position. XXX: currently also
|
|
relative to parent in the layout */
|
|
int width, height; /* content width & height */
|
|
/* inline specific layout. Not useful in fact XXX: use an union,
|
|
or merge with padding_xx */
|
|
unsigned short padding_top;
|
|
unsigned short padding_bottom;
|
|
unsigned short ascent; /* cannot use font ascent in case of
|
|
fallback XXX: find a way to suppress this field */
|
|
unsigned char embedding_level; /* from layout: bidir embedding level */
|
|
unsigned char content_type;
|
|
#define CSS_CONTENT_TYPE_CHILDS 0
|
|
#define CSS_CONTENT_TYPE_BUFFER 1
|
|
#define CSS_CONTENT_TYPE_STRING 2
|
|
#define CSS_CONTENT_TYPE_IMAGE 3
|
|
/* true if the content ends with eol. (used in
|
|
CSS_CONTENT_TYPE_BUFFER to display the cursor */
|
|
unsigned char content_eol:1;
|
|
unsigned char absolute_pos:1; /* true if absolute position (only
|
|
meaningful during layout */
|
|
unsigned char split:1; /* true if this box is a splitted box
|
|
(no need to free its content) */
|
|
/* true if there was a space in the previous box (useful in inline
|
|
formatting context) */
|
|
unsigned char last_space;
|
|
/* next inline box in an inline formatting context. Only used
|
|
during bidi pass, so we could put this field in another field
|
|
to save space */
|
|
struct CSSBox *next_inline;
|
|
/* parent box */
|
|
struct CSSBox *parent;
|
|
/* holds a pointer to the relevant data depending on content_type:
|
|
* - CSS_CONTENT_TYPE_BUFFER: points the the edit buffer
|
|
* - CSS_CONTENT_TYPE_STRING: points the an allocated string
|
|
* - CSS_CONTENT_TYPE_IMAGE: should point to alternate content
|
|
*/
|
|
void *content_data;
|
|
union {
|
|
struct {
|
|
struct CSSBox *last; /* used only when building the tree */
|
|
struct CSSBox *first; /* first box under this box, if any */
|
|
} child;
|
|
struct {
|
|
int start; /* start of text in buffer or string */
|
|
int end; /* end of text in buffer or string */
|
|
} buffer;
|
|
struct {
|
|
char *content_alt; /* alternate content */
|
|
} image;
|
|
} u;
|
|
};
|
|
|
|
/* horrible, but simple: we store EOL content (\A) as this value. Need
|
|
to find a better unicode value and to store it in UTF8 */
|
|
#define CSS_CONTENT_EOL 0x01
|
|
|
|
typedef struct CSSState {
|
|
int display;
|
|
CSSColor color;
|
|
CSSColor bgcolor;
|
|
CSSColor border_colors[4];
|
|
CSSRect padding;
|
|
CSSRect border;
|
|
CSSRect margin;
|
|
int border_styles[4];
|
|
int white_space;
|
|
int direction;
|
|
int block_float;
|
|
int font_family;
|
|
int font_style;
|
|
int text_decoration;
|
|
int font_weight;
|
|
int font_size;
|
|
int text_align;
|
|
int width;
|
|
int height;
|
|
int unicode_bidi;
|
|
int clear;
|
|
int overflow;
|
|
int visibility; /* XXX: initial value should be inherit */
|
|
int table_layout;
|
|
int vertical_align;
|
|
int border_collapse;
|
|
int border_spacing_horizontal;
|
|
int border_spacing_vertical;
|
|
int line_height;
|
|
int position;
|
|
int caption_side;
|
|
int marker_offset;
|
|
int list_style_type;
|
|
int column_span;
|
|
int row_span;
|
|
int list_style_position;
|
|
int bidi_mode;
|
|
int left;
|
|
int top;
|
|
int right;
|
|
int bottom;
|
|
/* after hash_next, no hashing or bulk comparisons are done */
|
|
struct CSSState *hash_next;
|
|
/* set of complex properties which are handled once after the
|
|
cascade is done */
|
|
struct CSSProperty *content;
|
|
struct CSSProperty *content_alt;
|
|
struct CSSProperty *counter_reset;
|
|
struct CSSProperty *counter_increment;
|
|
} CSSState;
|
|
|
|
/* style sheet handling */
|
|
|
|
typedef struct CSSStyleSheetAttributeEntry {
|
|
struct CSSStyleSheetAttributeEntry *next;
|
|
CSSIdent attr; /* attribute */
|
|
unsigned char op;
|
|
#define CSS_ATTR_OP_SET 0
|
|
#define CSS_ATTR_OP_EQUAL 1
|
|
#define CSS_ATTR_OP_IN_LIST 2
|
|
#define CSS_ATTR_OP_IN_HLIST 3
|
|
char value[1];
|
|
} CSSStyleSheetAttributeEntry;
|
|
|
|
/* simple selector */
|
|
typedef struct CSSSimpleSelector {
|
|
/* relation between next and current simple selector */
|
|
unsigned char tree_op;
|
|
#define CSS_TREE_OP_NONE 0 /* no next simple selector */
|
|
#define CSS_TREE_OP_DESCENDANT 1
|
|
#define CSS_TREE_OP_CHILD 2
|
|
#define CSS_TREE_OP_PRECEEDED 3
|
|
unsigned short pclasses; /* pseudo classes & elements */
|
|
#define CSS_PCLASS_FIRST_CHILD 0x0001
|
|
#define CSS_PCLASS_LINK 0x0002
|
|
#define CSS_PCLASS_VISITED 0x0004
|
|
#define CSS_PCLASS_ACTIVE 0x0008
|
|
#define CSS_PCLASS_HOVER 0x0010
|
|
#define CSS_PCLASS_FOCUS 0x0020
|
|
/* pseudo elements */
|
|
#define CSS_PCLASS_FIRST_LINE 0x0040
|
|
#define CSS_PCLASS_FIRST_LETTER 0x0080
|
|
#define CSS_PCLASS_BEFORE 0x0100
|
|
#define CSS_PCLASS_AFTER 0x0200
|
|
|
|
CSSIdent tag; /* selection tag, CSS_ID_ALL means all */
|
|
CSSIdent tag_id; /* id */
|
|
CSSStyleSheetAttributeEntry *attrs; /* attribute list */
|
|
struct CSSSimpleSelector *next; /* next selector operation */
|
|
} CSSSimpleSelector;
|
|
|
|
typedef struct CSSStyleSheetEntry {
|
|
CSSSimpleSelector sel; /* main selector */
|
|
int media; /* CSS2 media mask */
|
|
CSSProperty *props; /* associated properties */
|
|
struct CSSStyleSheetEntry *hash_next; /* hash table for next matching tag */
|
|
struct CSSStyleSheetEntry *next; /* next entry in style sheet */
|
|
} CSSStyleSheetEntry;
|
|
|
|
#define CSS_TAG_HASH_SIZE 521
|
|
|
|
typedef struct CSSStyleSheet {
|
|
CSSStyleSheetEntry *first_entry, **plast_entry;
|
|
CSSStyleSheetEntry *tag_hash[CSS_TAG_HASH_SIZE];
|
|
} CSSStyleSheet;
|
|
|
|
typedef struct {
|
|
const char *ptr;
|
|
int line_num;
|
|
const char *filename;
|
|
int ignore_case; /* true if case must be ignored (convert to lower case) */
|
|
} CSSParseState;
|
|
|
|
CSSStyleSheet *css_new_style_sheet(void);
|
|
void css_parse_style_sheet_str(CSSStyleSheet *s, const char *buffer, int flags);
|
|
void css_parse_style_sheet(CSSStyleSheet *s, CSSParseState *b);
|
|
void css_free_style_sheet(CSSStyleSheet **sp);
|
|
void css_dump_style_sheet(CSSStyleSheet *s);
|
|
void css_merge_style_sheet(CSSStyleSheet *s, CSSStyleSheet *a);
|
|
|
|
CSSProperty *css_parse_properties(CSSParseState *b, const char *props_str);
|
|
void css_add_prop_values(CSSProperty ***last_prop,
|
|
int property_index,
|
|
int nb_values, CSSPropertyValue *val_ptr);
|
|
void css_add_prop(CSSProperty ***last_prop,
|
|
int property_index, CSSPropertyValue *val_ptr);
|
|
void css_add_prop_unit(CSSProperty ***last_prop,
|
|
int property_index, int type, int val);
|
|
void css_add_prop_int(CSSProperty ***last_prop,
|
|
int property_index, int val);
|
|
CSSStyleSheetEntry *add_style_entry(CSSStyleSheet *s,
|
|
CSSSimpleSelector *ss,
|
|
int media);
|
|
void add_attribute(CSSStyleSheetAttributeEntry ***last_attr,
|
|
CSSIdent attr, int op, const char *value);
|
|
int get_font_size(int i);
|
|
|
|
/* CSS creating, layout and display */
|
|
|
|
struct CSSContext;
|
|
|
|
#define PROPS_HASH_SIZE 521
|
|
#define PROPS_SIZE offsetof(CSSState, hash_next)
|
|
|
|
typedef struct CSSCounterValue {
|
|
CSSIdent counter_id;
|
|
int value;
|
|
struct CSSCounterValue *prev;
|
|
} CSSCounterValue;
|
|
|
|
typedef struct CSSContext {
|
|
CSSStyleSheet *style_sheet;
|
|
QEditScreen *screen;
|
|
/* various default settings */
|
|
/* XXX: use style sheet ? */
|
|
int selection_bgcolor;
|
|
int selection_fgcolor;
|
|
int default_bgcolor;
|
|
|
|
/* edit buffer */
|
|
EditBuffer *b;
|
|
/* selection handling */
|
|
int selection_start, selection_end;
|
|
/* private content */
|
|
int media; /* initialized when creating CSSContext */
|
|
int px_size; /* px unit size, in displayed pixels (CSS_LENGTH_FRAC_BASE) */
|
|
int dots_per_inch; /* convert from inch to displayed pixels */
|
|
int bg_drawn; /* temporary for css_display */
|
|
CSSRect bg_rect; /* temporary for css_display */
|
|
CSSAbortFunc *abort_func;
|
|
void *abort_opaque;
|
|
int nb_props; /* statistics */
|
|
|
|
/* only used during css_compute() */
|
|
CSSCounterValue *counter_stack_ptr;
|
|
CSSCounterValue *counter_stack_base;
|
|
|
|
/* css attributes for the boxes are shared here */
|
|
CSSState *hash_props[PROPS_HASH_SIZE];
|
|
} CSSContext;
|
|
|
|
/* document managing */
|
|
|
|
void css_init(void);
|
|
|
|
CSSContext *css_new_document(QEditScreen *screen,
|
|
EditBuffer *b);
|
|
void css_delete_document(CSSContext **sp);
|
|
|
|
int css_compute(CSSContext *s, CSSBox *box);
|
|
int css_layout(CSSContext *s, CSSBox *box, int width,
|
|
CSSAbortFunc *abort_func, void *abort_opaque);
|
|
void css_display(CSSContext *s, CSSBox *box,
|
|
CSSRect *clip_box, int dx, int dy);
|
|
|
|
/* cursor/edition handling */
|
|
int box_get_text(CSSContext *s,
|
|
unsigned int *line_buf, int max_size,
|
|
int *offsets, CSSBox *box);
|
|
int css_get_cursor_pos(CSSContext *s, CSSBox *box,
|
|
CSSBox **box_ptr, int *x0_ptr, int *y0_ptr,
|
|
CSSRect *cursor_ptr, int *dir_ptr,
|
|
int offset);
|
|
int css_get_offset_pos(CSSContext *s, CSSBox *box, int xc, int dir);
|
|
|
|
typedef int (*CSSIterateFunc)(void *opaque, CSSBox *box, int x0, int y0);
|
|
int css_box_iterate(CSSContext *s, CSSBox *box, void *opaque,
|
|
CSSIterateFunc iterate_func);
|
|
|
|
|
|
/* box tree handling */
|
|
CSSBox *css_new_box(CSSIdent tag, CSSAttribute *attrs);
|
|
CSSBox *css_add_box(CSSBox *parent_box, CSSBox *box);
|
|
void css_delete_box(CSSBox **boxp);
|
|
void css_set_text_buffer(CSSBox *box, EditBuffer *b,
|
|
int offset1, int offset2, int eol);
|
|
void css_set_text_string(CSSBox *box, const char *string);
|
|
void css_make_child_box(CSSBox *box);
|
|
void css_set_child_box(CSSBox *parent_box, CSSBox *box);
|
|
|
|
/* box tree display (debug) */
|
|
void css_dump_box(CSSBox *box, int level);
|
|
void css_dump(CSSBox *box);
|
|
|
|
/* XML parser */
|
|
struct XMLState;
|
|
typedef struct XMLState XMLState;
|
|
|
|
#define XML_HTML 0x0001 /* enable html tag interpretation which cannot
|
|
be specified in a stylesheet */
|
|
#define XML_IGNORE_CASE 0x0002 /* ignore case for both xml/css tag parsing */
|
|
#define XML_DOCBOOK 0x0004 /* programlisting is handled as PRE */
|
|
#define XML_HTML_SYNTAX 0x0008 /* modify xml parser to accept HTML syntax */
|
|
|
|
XMLState *xml_begin(CSSStyleSheet *style_sheet, int flags,
|
|
CSSAbortFunc *abort_func, void *abort_opaque,
|
|
const char *filename, QECharset *charset);
|
|
int xml_parse(XMLState *s, char *buf, int buf_len);
|
|
CSSBox *xml_end(XMLState **sp);
|
|
|
|
CSSBox *xml_parse_buffer(EditBuffer *b, int offset_start, int offset_end,
|
|
CSSStyleSheet *style_sheet, int flags,
|
|
CSSAbortFunc *abort_func, void *abort_opaque);
|
|
int find_entity(const char *str);
|
|
const char *find_entity_str(int code);
|
|
|
|
#endif
|
|
|
|
/* The following functions must be provided by the user */
|
|
|
|
/* error reporting during parsing */
|
|
void html_error(int line_num, const char *fmt, va_list ap);
|
|
|
|
void css_error(const char *filename, int line_num, const char *msg);
|
|
|
|
/* file handling (for external scripts/css) */
|
|
struct CSSFile;
|
|
typedef struct CSSFile CSSFile;
|
|
|
|
CSSFile *css_open(CSSContext *s, const char *filename);
|
|
int css_filesize(CSSFile *f);
|
|
int css_read(CSSFile *f, char *buf, int size);
|
|
void css_close(CSSFile *f);
|
|
|
|
extern char const docbook_style[];
|
|
extern char const html_style[];
|