2968 lines · 74.8 KB · C
RawDownload
/* * This file is part of LibCSS * Licensed under the MIT License, *                http://www.opensource.org/licenses/mit-license.php * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> */ #include <string.h> #include "select/computed.h"#include "select/dispatch.h"#include "select/propget.h"#include "select/propset.h"#include "utils/utils.h" static css_error compute_absolute_color(css_computed_style *style,		uint8_t (*get)(const css_computed_style *style,				css_color *color),		css_error (*set)(css_computed_style *style,				uint8_t type, css_color color));static css_error compute_border_colors(css_computed_style *style); static css_error compute_absolute_border_width(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_border_side_width(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len, css_unit *unit),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len, css_unit unit));static css_error compute_absolute_sides(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_clip(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_line_height(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_margins(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_padding(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_vertical_align(css_computed_style *style,		const css_hint_length *ex_size);static css_error compute_absolute_length(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len, css_unit *unit),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len, css_unit unit));static css_error compute_absolute_length_auto(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len, css_unit *unit),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len, css_unit unit));static css_error compute_absolute_length_none(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len, css_unit *unit),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len, css_unit unit));static css_error compute_absolute_length_normal(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len, css_unit *unit),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len, css_unit unit));static css_error compute_absolute_length_pair(css_computed_style *style,		const css_hint_length *ex_size,		uint8_t (*get)(const css_computed_style *style, 				css_fixed *len1, css_unit *unit1,				css_fixed *len2, css_unit *unit2),		css_error (*set)(css_computed_style *style, uint8_t type,				css_fixed len1, css_unit unit1,				css_fixed len2, css_unit unit2));  /** * Create a computed style * * \param alloc   Memory (de)allocation function * \param pw      Pointer to client-specific data * \param result  Pointer to location to receive result * \return CSS_OK on success, *         CSS_NOMEM on memory exhaustion, *         CSS_BADPARM on bad parameters. */css_error css_computed_style_create(css_allocator_fn alloc, void *pw,		css_computed_style **result){	css_computed_style *s; 	if (alloc == NULL || result == NULL)		return CSS_BADPARM; 	s = alloc(NULL, sizeof(css_computed_style), pw);	if (s == NULL)		return CSS_NOMEM; 	memset(s, 0, sizeof(css_computed_style)); 	s->alloc = alloc;	s->pw = pw; 	*result = s; 	return CSS_OK;} /** * Destroy a computed style * * \param style  Style to destroy * \return CSS_OK on success, appropriate error otherwise */css_error css_computed_style_destroy(css_computed_style *style){	if (style == NULL)		return CSS_BADPARM; 	if (style->uncommon != NULL) {		if (style->uncommon->counter_increment != NULL) {			css_computed_counter *c; 			for (c = style->uncommon->counter_increment; 					c->name != NULL; c++) {				lwc_string_unref(c->name);			} 			style->alloc(style->uncommon->counter_increment, 0,					style->pw);		} 		if (style->uncommon->counter_reset != NULL) {			css_computed_counter *c; 			for (c = style->uncommon->counter_reset; 					c->name != NULL; c++) {				lwc_string_unref(c->name);			} 			style->alloc(style->uncommon->counter_reset, 0,					style->pw);		}			if (style->uncommon->cursor != NULL) {			lwc_string **s; 			for (s = style->uncommon->cursor; *s != NULL; s++) {				lwc_string_unref(*s);			} 			style->alloc(style->uncommon->cursor, 0, style->pw);		} 		if (style->uncommon->content != NULL) {			css_computed_content_item *c; 			for (c = style->uncommon->content; 					c->type != CSS_COMPUTED_CONTENT_NONE;					c++) {				switch (c->type) {				case CSS_COMPUTED_CONTENT_STRING:					lwc_string_unref(c->data.string);					break;				case CSS_COMPUTED_CONTENT_URI:					lwc_string_unref(c->data.uri);					break;				case CSS_COMPUTED_CONTENT_ATTR:					lwc_string_unref(c->data.attr);					break;				case CSS_COMPUTED_CONTENT_COUNTER:					lwc_string_unref(c->data.counter.name);					break;				case CSS_COMPUTED_CONTENT_COUNTERS:					lwc_string_unref(c->data.counters.name);					lwc_string_unref(c->data.counters.sep);					break;				default:					break;				}			} 			style->alloc(style->uncommon->content, 0, style->pw);		} 		style->alloc(style->uncommon, 0, style->pw);	} 	if (style->page != NULL) {		style->alloc(style->page, 0, style->pw);	} 	if (style->aural != NULL) {		style->alloc(style->aural, 0, style->pw);	} 	if (style->font_family != NULL) {		lwc_string **s; 		for (s = style->font_family; *s != NULL; s++) {			lwc_string_unref(*s);		} 		style->alloc(style->font_family, 0, style->pw);	} 	if (style->quotes != NULL) {		lwc_string **s; 		for (s = style->quotes; *s != NULL; s++) {			lwc_string_unref(*s);		} 		style->alloc(style->quotes, 0, style->pw);	} 	if (style->list_style_image != NULL)		lwc_string_unref(style->list_style_image); 	if (style->background_image != NULL)		lwc_string_unref(style->background_image); 	style->alloc(style, 0, style->pw); 	return CSS_OK;} /** * Populate a blank computed style with Initial values * * \param style    Computed style to populate * \param handler  Dispatch table of handler functions * \param pw       Client-specific private data for handler functions * \return CSS_OK on success. */css_error css_computed_style_initialise(css_computed_style *style,		css_select_handler *handler, void *pw){	css_select_state state;	uint32_t i;	css_error error; 	if (style == NULL)		return CSS_BADPARM; 	state.node = NULL;	state.media = CSS_MEDIA_ALL;	state.results = NULL;	state.computed = style;	state.handler = handler;	state.pw = pw; 	for (i = 0; i < CSS_N_PROPERTIES; i++) {		/* No need to initialise anything other than the normal		 * properties -- the others are handled by the accessors */		if (prop_dispatch[i].inherited == false &&				prop_dispatch[i].group == GROUP_NORMAL) {			error = prop_dispatch[i].initial(&state);			if (error != CSS_OK)				return error;		}	} 	return CSS_OK;} /** * Compose two computed styles * * \param parent             Parent style * \param child              Child style * \param compute_font_size  Function to compute an absolute font size * \param pw                 Client data for compute_font_size * \param result             Pointer to style to compose into * \return CSS_OK on success, appropriate error otherwise. * * \pre \a parent is a fully composed style (thus has no inherited properties) * * \note \a child and \a result may point at the same object */css_error css_computed_style_compose(const css_computed_style *parent,		const css_computed_style *child,		css_error (*compute_font_size)(void *pw,			const css_hint *parent, css_hint *size),		void *pw,		css_computed_style *result){	css_error error = CSS_OK;	size_t i; 	/* Iterate through the properties */	for (i = 0; i < CSS_N_PROPERTIES; i++) {		/* Skip any in extension blocks if the block does not exist */			if (prop_dispatch[i].group == GROUP_UNCOMMON &&				parent->uncommon == NULL && 				child->uncommon == NULL)			continue; 		if (prop_dispatch[i].group == GROUP_PAGE &&				parent->page == NULL && child->page == NULL)			continue; 		if (prop_dispatch[i].group == GROUP_AURAL &&				parent->aural == NULL && child->aural == NULL)			continue; 		/* Compose the property */		error = prop_dispatch[i].compose(parent, child, result);		if (error != CSS_OK)			break;	} 	/* Finally, compute absolute values for everything */	return css__compute_absolute_values(parent, result, compute_font_size, pw);} /****************************************************************************** * Property accessors                                                         * ******************************************************************************/  #define CSS_LETTER_SPACING_INDEX 0#define CSS_LETTER_SPACING_SHIFT 2#define CSS_LETTER_SPACING_MASK  0xfcuint8_t css_computed_letter_spacing(		const css_computed_style *style, 		css_fixed *length, css_unit *unit){	if (style->uncommon != NULL) {		uint8_t bits = style->uncommon->bits[CSS_LETTER_SPACING_INDEX];		bits &= CSS_LETTER_SPACING_MASK;		bits >>= CSS_LETTER_SPACING_SHIFT; 		/* 6bits: uuuutt : unit | type */ 		if ((bits & 3) == CSS_LETTER_SPACING_SET) {			*length = style->uncommon->letter_spacing;			*unit = (css_unit) (bits >> 2);		} 		return (bits & 3);	} 	return CSS_LETTER_SPACING_NORMAL;}#undef CSS_LETTER_SPACING_MASK#undef CSS_LETTER_SPACING_SHIFT#undef CSS_LETTER_SPACING_INDEX #define CSS_OUTLINE_COLOR_INDEX 0#define CSS_OUTLINE_COLOR_SHIFT 0#define CSS_OUTLINE_COLOR_MASK  0x3uint8_t css_computed_outline_color(		const css_computed_style *style, css_color *color){	if (style->uncommon != NULL) {		uint8_t bits = style->uncommon->bits[CSS_OUTLINE_COLOR_INDEX];		bits &= CSS_OUTLINE_COLOR_MASK;		bits >>= CSS_OUTLINE_COLOR_SHIFT; 		/* 2bits: tt : type */ 		if ((bits & 3) == CSS_OUTLINE_COLOR_COLOR) {			*color = style->uncommon->outline_color;		} 		return (bits & 3);	} 	return CSS_OUTLINE_COLOR_INVERT;}#undef CSS_OUTLINE_COLOR_MASK#undef CSS_OUTLINE_COLOR_SHIFT#undef CSS_OUTLINE_COLOR_INDEX #define CSS_OUTLINE_WIDTH_INDEX 1#define CSS_OUTLINE_WIDTH_SHIFT 1#define CSS_OUTLINE_WIDTH_MASK  0xfeuint8_t css_computed_outline_width(		const css_computed_style *style, 		css_fixed *length, css_unit *unit){	if (style->uncommon != NULL) {		uint8_t bits = style->uncommon->bits[CSS_OUTLINE_WIDTH_INDEX];		bits &= CSS_OUTLINE_WIDTH_MASK;		bits >>= CSS_OUTLINE_WIDTH_SHIFT; 		/* 7bits: uuuuttt : unit | type */ 		if ((bits & 7) == CSS_OUTLINE_WIDTH_WIDTH) {			*length = style->uncommon->outline_width;			*unit = (css_unit) (bits >> 3);		} 		return (bits & 7);	} 	*length = INTTOFIX(2);	*unit = CSS_UNIT_PX; 	return CSS_OUTLINE_WIDTH_WIDTH;}#undef CSS_OUTLINE_WIDTH_MASK#undef CSS_OUTLINE_WIDTH_SHIFT#undef CSS_OUTLINE_WIDTH_INDEX #define CSS_BORDER_SPACING_INDEX 1#define CSS_BORDER_SPACING_SHIFT 0#define CSS_BORDER_SPACING_MASK  0x1#define CSS_BORDER_SPACING_INDEX1 2#define CSS_BORDER_SPACING_SHIFT1 0#define CSS_BORDER_SPACING_MASK1 0xffuint8_t css_computed_border_spacing(		const css_computed_style *style, 		css_fixed *hlength, css_unit *hunit,		css_fixed *vlength, css_unit *vunit){	if (style->uncommon != NULL) {		uint8_t bits = style->uncommon->bits[CSS_BORDER_SPACING_INDEX];		bits &= CSS_BORDER_SPACING_MASK;		bits >>= CSS_BORDER_SPACING_SHIFT; 		/* 1 bit: type */		if (bits == CSS_BORDER_SPACING_SET) {			uint8_t bits1 = 				style->uncommon->bits[CSS_BORDER_SPACING_INDEX1];			bits1 &= CSS_BORDER_SPACING_MASK1;			bits1 >>= CSS_BORDER_SPACING_SHIFT1; 			/* 8bits: hhhhvvvv : hunit | vunit */ 			*hlength = style->uncommon->border_spacing[0];			*hunit = (css_unit) (bits1 >> 4); 			*vlength = style->uncommon->border_spacing[1];			*vunit = (css_unit) (bits1 & 0xf);		} 		return bits;	} else {		*hlength = *vlength = 0;		*hunit = *vunit = CSS_UNIT_PX;	} 	return CSS_BORDER_SPACING_SET;}#undef CSS_BORDER_SPACING_MASK1#undef CSS_BORDER_SPACING_SHIFT1#undef CSS_BORDER_SPACING_INDEX1#undef CSS_BORDER_SPACING_MASK#undef CSS_BORDER_SPACING_SHIFT#undef CSS_BORDER_SPACING_INDEX #define CSS_WORD_SPACING_INDEX 3#define CSS_WORD_SPACING_SHIFT 2#define CSS_WORD_SPACING_MASK  0xfcuint8_t css_computed_word_spacing(		const css_computed_style *style, 		css_fixed *length, css_unit *unit){	if (style->uncommon != NULL) {		uint8_t bits = style->uncommon->bits[CSS_WORD_SPACING_INDEX];		bits &= CSS_WORD_SPACING_MASK;		bits >>= CSS_WORD_SPACING_SHIFT; 		/* 6bits: uuuutt : unit | type */ 		if ((bits & 3) == CSS_WORD_SPACING_SET) {			*length = style->uncommon->word_spacing;			*unit = (css_unit) (bits >> 2);		} 		return (bits & 3);	} 	return CSS_WORD_SPACING_NORMAL;}#undef CSS_WORD_SPACING_MASK#undef CSS_WORD_SPACING_SHIFT#undef CSS_WORD_SPACING_INDEX #define CSS_COUNTER_INCREMENT_INDEX 3#define CSS_COUNTER_INCREMENT_SHIFT 1#define CSS_COUNTER_INCREMENT_MASK  0x2uint8_t css_computed_counter_increment(		const css_computed_style *style, 		const css_computed_counter **counters){	if (style->uncommon != NULL) {		uint8_t bits = 			style->uncommon->bits[CSS_COUNTER_INCREMENT_INDEX];		bits &= CSS_COUNTER_INCREMENT_MASK;		bits >>= CSS_COUNTER_INCREMENT_SHIFT; 		/* 1bit: type */		*counters = style->uncommon->counter_increment; 		return bits;	} 

Lines 1–500 of 2968.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t