コード例 #1
0
ファイル: computed.c プロジェクト: JamesLinus/nui3
/**
 * Compute an absolute border side width
 *
 * \param style      Style to process
 * \param ex_size    Ex size, in ems
 * \param get        Function to read length
 * \param set        Function to write length
 * \return CSS_OK on success
 */
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))
{
	css_fixed length;
	css_unit unit;
	uint8_t type;

	type = get(style, &length, &unit);
	if (type == CSS_BORDER_WIDTH_THIN) {
		length = INTTOFIX(1);
		unit = CSS_UNIT_PX;
	} else if (type == CSS_BORDER_WIDTH_MEDIUM) {
		length = INTTOFIX(2);
		unit = CSS_UNIT_PX;
	} else if (type == CSS_BORDER_WIDTH_THICK) {
		length = INTTOFIX(4);
		unit = CSS_UNIT_PX;
	}

	if (unit == CSS_UNIT_EX) {
		length = FMUL(length, ex_size->value);
		unit = ex_size->unit;
	}

	return set(style, CSS_BORDER_WIDTH_WIDTH, length, unit);
}
コード例 #2
0
ファイル: font.c プロジェクト: EyMenZ/NetSurf-OS3
/* exported function documented in render/font_internal.h */
void font_plot_style_from_css(const css_computed_style *css,
		plot_font_style_t *fstyle)
{
	lwc_string **families;
	css_fixed length = 0;
	css_unit unit = CSS_UNIT_PX;
	css_color col;

	fstyle->family = plot_font_generic_family(
			css_computed_font_family(css, &families));

	css_computed_font_size(css, &length, &unit);
	fstyle->size = FIXTOINT(FMUL(nscss_len2pt(length, unit),
				      INTTOFIX(FONT_SIZE_SCALE)));

	/* Clamp font size to configured minimum */
	if (fstyle->size < (nsoption_int(font_min_size) * FONT_SIZE_SCALE) / 10)
		fstyle->size = (nsoption_int(font_min_size) * FONT_SIZE_SCALE) / 10;

	fstyle->weight = plot_font_weight(css_computed_font_weight(css));
	fstyle->flags = plot_font_flags(css_computed_font_style(css),
			css_computed_font_variant(css));

	css_computed_color(css, &col);
	fstyle->foreground = nscss_color_to_ns(col);
	fstyle->background = 0;
}
コード例 #3
0
ファイル: utils.c プロジェクト: ChokshiUtsav/kolibriosSVN
/**
 * Convert an absolute CSS length to points.
 *
 * \param  length  Length to convert
 * \param  unit    Corresponding unit
 * \return	   length in points
 */
css_fixed nscss_len2pt(css_fixed length, css_unit unit)
{
	/* Length must not be relative */
	assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX);

	switch (unit) {
	/* We assume the screen and any other output has the same dpi */
	/* 1in = DPIpx => 1px = (72/DPI)pt */
	case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi);
	/* 1in = 72pt */
	case CSS_UNIT_IN: return FMUL(length, F_72);
	/* 1in = 2.54cm => 1cm = (72/2.54)pt */
	case CSS_UNIT_CM: return FMUL(length, 
				FDIV(F_72, FLTTOFIX(2.54)));
	/* 1in = 25.4mm => 1mm = (72/25.4)pt */
	case CSS_UNIT_MM: return FMUL(length, 
				      FDIV(F_72, FLTTOFIX(25.4)));
	case CSS_UNIT_PT: return length;
	/* 1pc = 12pt */
	case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
	default: break;
	}

	return 0;
}
コード例 #4
0
ファイル: dump.c プロジェクト: Achal-Aggarwal/netsurf
/**
 * Dump a numeric value to the stream in a textual form.
 *
 * \param stream  Stream to write to
 * \param val     Value to write
 */
void dump_css_number(FILE *stream, css_fixed val)
{
	if (INTTOFIX(FIXTOINT(val)) == val)
		fprintf(stream, "%d", FIXTOINT(val));
	else
		dump_css_fixed(stream, val);
}
コード例 #5
0
ファイル: font.c プロジェクト: seanregan/browser
void ami_font_setdevicedpi(int id)
{
	DisplayInfoHandle dih;
	struct DisplayInfo dinfo;
	ULONG ydpi = option_amiga_ydpi;
	ULONG xdpi = option_amiga_ydpi;

	nscss_screen_dpi = INTTOFIX(option_amiga_ydpi);

	if(id && (option_monitor_aspect_x != 0) && (option_monitor_aspect_y != 0))
	{
		if(dih = FindDisplayInfo(id))
		{
			if(GetDisplayInfoData(dih, &dinfo, sizeof(struct DisplayInfo),
				DTAG_DISP, 0))
			{
				int xres = dinfo.Resolution.x;
				int yres = dinfo.Resolution.y;

				if((option_monitor_aspect_x != 4) || (option_monitor_aspect_y != 3))
				{
					/* AmigaOS sees 4:3 modes as square in the DisplayInfo database,
					 * so we correct other modes to "4:3 equiv" here. */
					xres = (xres * option_monitor_aspect_x) / 4;
					yres = (yres * option_monitor_aspect_y) / 3;
				}

				xdpi = (yres * ydpi) / xres;

				LOG(("XDPI = %ld, YDPI = %ld (DisplayInfo resolution %ld x %ld, corrected %ld x %ld)",
					xdpi, ydpi, dinfo.Resolution.x, dinfo.Resolution.y, xres, yres));
			}
		}
	}

	ami_xdpi = xdpi;
	ami_devicedpi = (xdpi << 16) | ydpi;
}
コード例 #6
0
ファイル: orphans.c プロジェクト: CODECOMMUNITY/libcss
css_error css__initial_orphans(css_select_state *state)
{
	return set_orphans(state->computed, CSS_ORPHANS_SET, INTTOFIX(2));
}
コード例 #7
0
ファイル: utils.c プロジェクト: CODECOMMUNITY/libcss
/**
 * Parse a colour specifier
 *
 * \param c       Parsing context
 * \param vector  Vector of tokens to process
 * \param ctx     Pointer to vector iteration context
 * \param value   Pointer to location to receive value
 * \param result  Pointer to location to receive result (AARRGGBB)
 * \return CSS_OK      on success,
 *         CSS_INVALID if the input is invalid
 *
 * Post condition: \a *ctx is updated with the next token to process
 *                 If the input is invalid, then \a *ctx remains unchanged.
 */
css_error css__parse_colour_specifier(css_language *c,
		const parserutils_vector *vector, int *ctx,
		uint16_t *value, uint32_t *result)
{
	int orig_ctx = *ctx;
	const css_token *token;
	bool match;
	css_error error;

	consumeWhitespace(vector, ctx);

	/* IDENT(<colour name>) | 
	 * HASH(rgb | rrggbb) |
	 * FUNCTION(rgb) [ [ NUMBER | PERCENTAGE ] ',' ] {3} ')'
	 * FUNCTION(rgba) [ [ NUMBER | PERCENTAGE ] ',' ] {4} ')'
	 * FUNCTION(hsl) ANGLE ',' PERCENTAGE ',' PERCENTAGE  ')'
	 * FUNCTION(hsla) ANGLE ',' PERCENTAGE ',' PERCENTAGE ',' NUMBER ')'
	 *
	 * For quirks, NUMBER | DIMENSION | IDENT, too
	 * I.E. "123456" -> NUMBER, "1234f0" -> DIMENSION, "f00000" -> IDENT
	 */
	token = parserutils_vector_iterate(vector, ctx);
	if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
			token->type != CSS_TOKEN_HASH &&
			token->type != CSS_TOKEN_FUNCTION)) {
		if (c->sheet->quirks_allowed == false ||
				token == NULL ||
				(token->type != CSS_TOKEN_NUMBER &&
				token->type != CSS_TOKEN_DIMENSION))
			goto invalid;
	}

	if (token->type == CSS_TOKEN_IDENT) {
		if ((lwc_string_caseless_isequal(
				token->idata, c->strings[TRANSPARENT],
				&match) == lwc_error_ok && match)) {
			*value = COLOR_TRANSPARENT;
			*result = 0; /* black transparent */
			return CSS_OK;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[CURRENTCOLOR],
				&match) == lwc_error_ok && match)) {
			*value = COLOR_CURRENT_COLOR;
			*result = 0;
			return CSS_OK;
		}

		error = css__parse_named_colour(c, token->idata, result);
		if (error != CSS_OK && c->sheet->quirks_allowed) {
			error = css__parse_hash_colour(token->idata, result);
			if (error == CSS_OK)
				c->sheet->quirks_used = true;
		}

		if (error != CSS_OK)
			goto invalid;
	} else if (token->type == CSS_TOKEN_HASH) {
		error = css__parse_hash_colour(token->idata, result);
		if (error != CSS_OK)
			goto invalid;
	} else if (c->sheet->quirks_allowed &&
			token->type == CSS_TOKEN_NUMBER) {
		error = css__parse_hash_colour(token->idata, result);
		if (error == CSS_OK)
			c->sheet->quirks_used = true;
		else
			goto invalid;
	} else if (c->sheet->quirks_allowed &&
			token->type == CSS_TOKEN_DIMENSION) {
		error = css__parse_hash_colour(token->idata, result);
		if (error == CSS_OK)
			c->sheet->quirks_used = true;
		else
			goto invalid;
	} else if (token->type == CSS_TOKEN_FUNCTION) {
		uint8_t r = 0, g = 0, b = 0, a = 0xff;
		int colour_channels = 0;

		if ((lwc_string_caseless_isequal(
				token->idata, c->strings[RGB],
				&match) == lwc_error_ok && match)) {
			colour_channels = 3;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[RGBA],
				&match) == lwc_error_ok && match)) {
			colour_channels = 4;
		} if ((lwc_string_caseless_isequal(
				token->idata, c->strings[HSL],
				&match) == lwc_error_ok && match)) {
			colour_channels = 5;
		} else if ((lwc_string_caseless_isequal(
				token->idata, c->strings[HSLA],
				&match) == lwc_error_ok && match)) {
			colour_channels = 6;
		}

		if (colour_channels == 3 || colour_channels == 4) {
			int i;
			css_token_type valid = CSS_TOKEN_NUMBER;
			uint8_t *components[4] = { &r, &g, &b, &a };

			for (i = 0; i < colour_channels; i++) {
				uint8_t *component;
				css_fixed num;
				size_t consumed = 0;
				int32_t intval;
				bool int_only;

				component = components[i];

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_peek(vector, *ctx);
				if (token == NULL || (token->type !=
						CSS_TOKEN_NUMBER &&
						token->type !=
						CSS_TOKEN_PERCENTAGE))
					goto invalid;

				if (i == 0)
					valid = token->type;
				else if (i < 3 && token->type != valid)
					goto invalid;

				/* The alpha channel may be a float */
				if (i < 3)
					int_only = (valid == CSS_TOKEN_NUMBER);
				else
					int_only = false;

				num = css__number_from_lwc_string(token->idata,
						int_only, &consumed);
				if (consumed != lwc_string_length(token->idata))
					goto invalid;

				if (valid == CSS_TOKEN_NUMBER) {
					if (i == 3) {
						/* alpha channel */
						intval = FIXTOINT(
							FMUL(num, F_255));
					} else {
						/* colour channels */
						intval = FIXTOINT(num);
					}
				} else {
					intval = FIXTOINT(
						FDIV(FMUL(num, F_255), F_100));
				}

				if (intval > 255)
					*component = 255;
				else if (intval < 0)
					*component = 0;
				else
					*component = intval;

				parserutils_vector_iterate(vector, ctx);

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_peek(vector, *ctx);
				if (token == NULL)
					goto invalid;

				if (i != (colour_channels - 1) &&
						tokenIsChar(token, ',')) {
					parserutils_vector_iterate(vector, ctx);
				} else if (i == (colour_channels - 1) &&
						tokenIsChar(token, ')')) {
					parserutils_vector_iterate(vector, ctx);
				} else {
					goto invalid;
				}
			}
		} else if (colour_channels == 5 || colour_channels == 6) {
			/* hue - saturation - lightness */
			size_t consumed = 0;
			css_fixed hue, sat, lit;
			int32_t alpha = 255;

			/* hue is a number without a unit representing an 
			 * angle (0-360) degrees  
			 */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_NUMBER))
				goto invalid;

			hue = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise hue to the range [0, 360) */
			while (hue < 0)
				hue += F_360;
			while (hue >= F_360)
				hue -= F_360;

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if (!tokenIsChar(token, ','))
				goto invalid;


			/* saturation */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_PERCENTAGE))
				goto invalid;

			sat = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise saturation to the range [0, 100] */
			if (sat < INTTOFIX(0))
				sat = INTTOFIX(0);
			else if (sat > INTTOFIX(100))
				sat = INTTOFIX(100);

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if (!tokenIsChar(token, ','))
				goto invalid;


			/* lightness */
			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);
			if ((token == NULL) || (token->type != CSS_TOKEN_PERCENTAGE))
				goto invalid;

			lit = css__number_from_lwc_string(token->idata, false, &consumed);
			if (consumed != lwc_string_length(token->idata))
				goto invalid; /* failed to consume the whole string as a number */

			/* Normalise lightness to the range [0, 100] */
			if (lit < INTTOFIX(0))
				lit = INTTOFIX(0);
			else if (lit > INTTOFIX(100))
				lit = INTTOFIX(100);

			consumeWhitespace(vector, ctx);

			token = parserutils_vector_iterate(vector, ctx);

			if (colour_channels == 6) {
				/* alpha */

				if (!tokenIsChar(token, ','))
					goto invalid;
			
				consumeWhitespace(vector, ctx);

				token = parserutils_vector_iterate(vector, ctx);
				if ((token == NULL) || (token->type != CSS_TOKEN_NUMBER))
					goto invalid;

				alpha = css__number_from_lwc_string(token->idata, false, &consumed);
				if (consumed != lwc_string_length(token->idata))
					goto invalid; /* failed to consume the whole string as a number */
				
				alpha = FIXTOINT(FMUL(alpha, F_255));

				consumeWhitespace(vector, ctx);

				token = parserutils_vector_iterate(vector, ctx);

			}

			if (!tokenIsChar(token, ')'))
				goto invalid;

			/* have a valid HSV entry, convert to RGB */
			HSL_to_RGB(hue, sat, lit, &r, &g, &b);

			/* apply alpha */
			if (alpha > 255)
				a = 255;
			else if (alpha < 0)
				a = 0;
			else
				a = alpha;

		} else {
			goto invalid;
		}

		*result = (a << 24) | (r << 16) | (g << 8) | b;
	}

	*value = COLOR_SET;

	return CSS_OK;

invalid:
	*ctx = orig_ctx;
	return CSS_INVALID;
}
コード例 #8
0
ファイル: utils.c プロジェクト: CODECOMMUNITY/libcss
/**
 * Convert Hue Saturation Lightness value to RGB.
 *
 * \param hue Hue in degrees 0..360
 * \param sat Saturation value in percent 0..100
 * \param lit Lightness value in percent 0..100
 * \param r red component
 * \param g green component
 * \param b blue component
 */
static void HSL_to_RGB(css_fixed hue, css_fixed sat, css_fixed lit, uint8_t *r, uint8_t *g, uint8_t *b)
{
	css_fixed min_rgb, max_rgb, chroma;
	css_fixed relative_hue, scaled_hue, mid1, mid2;
	int sextant;

#define ORGB(R, G, B) \
	*r = FIXTOINT(FDIV(FMUL((R), F_255), F_100)); \
	*g = FIXTOINT(FDIV(FMUL((G), F_255), F_100)); \
	*b = FIXTOINT(FDIV(FMUL((B), F_255), F_100))

	/* If saturation is zero there is no hue and r = g = b = lit */
	if (sat == INTTOFIX(0)) {
		ORGB(lit, lit, lit);
		return;
	}

	/* Compute max(r,g,b) */
	if (lit <= INTTOFIX(50)) {
		max_rgb = FDIV(FMUL(lit, FADD(sat, F_100)), F_100);
	} else {
		max_rgb = FDIV(FSUB(FMUL(FADD(lit, sat), F_100), FMUL(lit, sat)), F_100);
	}

	/* Compute min(r,g,b) */
	min_rgb = FSUB(FMUL(lit, INTTOFIX(2)), max_rgb);

	/* We know that the value of at least one of the components is 
	 * max(r,g,b) and that the value of at least one of the other
	 * components is min(r,g,b).
	 *
	 * We can determine which components have these values by
	 * considering which the sextant of the hexcone the hue lies
	 * in:
	 *
	 * Sextant:	max(r,g,b):	min(r,g,b):
	 *
	 * 0		r		b
	 * 1		g		b
	 * 2		g		r
	 * 3		b		r
	 * 4		b		g
	 * 5		r		g
	 *
	 * Thus, we need only compute the value of the third component
	 */

	/* Chroma is the difference between min and max */
	chroma = FSUB(max_rgb, min_rgb);

	/* Compute which sextant the hue lies in (truncates result) */
	hue = FDIV(FMUL(hue, INTTOFIX(6)), F_360);
	sextant = FIXTOINT(hue);

	/* Compute offset of hue from start of sextant */
	relative_hue = FSUB(hue, INTTOFIX(sextant));

	/* Scale offset by chroma */
        scaled_hue = FMUL(relative_hue, chroma);

	/* Compute potential values of the third colour component */
        mid1 = FADD(min_rgb, scaled_hue);
        mid2 = FSUB(max_rgb, scaled_hue);

	/* Populate result */
        switch (sextant) {
	case 0: ORGB(max_rgb,   mid1,      min_rgb); break;
	case 1: ORGB(mid2,      max_rgb,   min_rgb); break;
	case 2: ORGB(min_rgb,   max_rgb,   mid1); break;
	case 3: ORGB(min_rgb,   mid2,      max_rgb); break;
	case 4: ORGB(mid1,      min_rgb,   max_rgb); break;
	case 5: ORGB(max_rgb,   min_rgb,   mid2); break;
        }

#undef ORGB
}
コード例 #9
0
ファイル: utils.c プロジェクト: ChokshiUtsav/kolibriosSVN
/**
 * Convert a CSS length to pixels.
 *
 * \param  length  Length to convert
 * \param  unit    Corresponding unit
 * \param  style   Computed style applying to length. May be NULL if unit is 
 *                 neither em nor ex
 * \return	   length in pixels
 */
css_fixed nscss_len2px(css_fixed length, css_unit unit, 
		const css_computed_style *style)
{
	/* We assume the screen and ay other output has the same dpi */
	css_fixed px_per_unit;

	assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX));

	switch (unit) {
	case CSS_UNIT_EM:
	case CSS_UNIT_EX:
	{
		css_fixed font_size = 0;
		css_unit font_unit = CSS_UNIT_PT;

		css_computed_font_size(style, &font_size, &font_unit);

		/* Convert to points */
		font_size = nscss_len2pt(font_size, font_unit);

		/* Clamp to configured minimum */
		if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) {
		  font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10);
		}

		/* Convert to pixels (manually, to maximise precision) 
		 * 1in = 72pt => 1pt = (DPI/72)px */
		px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);

		/* Scale ex units: we use a fixed ratio of 1ex = 0.6em */
		if (unit == CSS_UNIT_EX)
			px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
	}
		break;
	case CSS_UNIT_PX: 
		px_per_unit = F_1;
		break;
	/* 1in = DPIpx */
	case CSS_UNIT_IN: 
		px_per_unit = nscss_screen_dpi;
		break;
	/* 1in = 2.54cm => 1cm = (DPI/2.54)px */
	case CSS_UNIT_CM: 
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54));
		break;
	/* 1in = 25.4mm => 1mm = (DPI/25.4)px */
	case CSS_UNIT_MM: 
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4));
		break;
	/* 1in = 72pt => 1pt = (DPI/72)px */
	case CSS_UNIT_PT: 
		px_per_unit = FDIV(nscss_screen_dpi, F_72);
		break;
	/* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */
	case CSS_UNIT_PC: 
		px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6));
		break;
	default:
		px_per_unit = 0;
		break;
	}

	/* Ensure we round px_per_unit to the nearest whole number of pixels:
	 * the use of FIXTOINT() below will truncate. */
	px_per_unit += F_0_5;

	/* Calculate total number of pixels */
	return FMUL(length, TRUNCATEFIX(px_per_unit));
}
コード例 #10
0
ファイル: print.c プロジェクト: EyMenZ/NetSurf-OS3
/**
 * Generates one of the predefined print settings sets.
 *
 * \param configuration the requested configuration
 * \param filename the filename or NULL
 * \param font_func font handling functions
 * \return print_settings in case if successful, NULL if unknown
 *                        configuration or lack of memory.
 */
struct print_settings *print_make_settings(print_configuration configuration,
		const char *filename, const struct font_functions *font_func)
{
	struct print_settings *settings;
	css_fixed length = 0;
	css_unit unit = CSS_UNIT_MM;
	
	switch (configuration){
		case PRINT_DEFAULT:	
			settings = (struct print_settings*) 
					malloc(sizeof(struct print_settings));
			if (settings == NULL)
				return NULL;
			
			settings->page_width  = DEFAULT_PAGE_WIDTH;
			settings->page_height = DEFAULT_PAGE_HEIGHT;
			settings->copies = DEFAULT_COPIES;

			settings->scale = DEFAULT_EXPORT_SCALE;
			
			length = INTTOFIX(DEFAULT_MARGIN_LEFT_MM);
			settings->margins[MARGINLEFT] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(DEFAULT_MARGIN_RIGHT_MM);
			settings->margins[MARGINRIGHT] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(DEFAULT_MARGIN_TOP_MM);
			settings->margins[MARGINTOP] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(DEFAULT_MARGIN_BOTTOM_MM);
			settings->margins[MARGINBOTTOM] = 
					nscss_len2px(length, unit, NULL);
			break;
		/* use settings from the Export options tab */
		case PRINT_OPTIONS:
			settings = (struct print_settings*) 
					malloc(sizeof(struct print_settings));
			if (settings == NULL)
				return NULL;
			
			settings->page_width  = DEFAULT_PAGE_WIDTH;
			settings->page_height = DEFAULT_PAGE_HEIGHT;
			settings->copies = DEFAULT_COPIES;
			
			settings->scale = (float)nsoption_int(export_scale) / 100;
			
			length = INTTOFIX(nsoption_int(margin_left));
			settings->margins[MARGINLEFT] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(nsoption_int(margin_right));
			settings->margins[MARGINRIGHT] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(nsoption_int(margin_top));
			settings->margins[MARGINTOP] = 
					nscss_len2px(length, unit, NULL);
			length = INTTOFIX(nsoption_int(margin_bottom));
			settings->margins[MARGINBOTTOM] = 
					nscss_len2px(length, unit, NULL);
			break;
		default:
			return NULL;
	}

	/* Set font functions */
	settings->font_func = font_func;

	/* Output filename, or NULL if printing */
	if (filename != NULL) {
		settings->output = strdup(filename);
		if (settings->output == NULL) {
			free(settings);
			return NULL;
		}
	} else 
		settings->output = NULL;

	return settings;	
}
コード例 #11
0
ファイル: computed.c プロジェクト: JamesLinus/nui3
/**
 * Compute the absolute values of a style
 *
 * \param parent             Parent style, or NULL for tree root
 * \param style              Computed style to process
 * \param compute_font_size  Callback to calculate an absolute font-size
 * \param pw                 Private word for callback
 * \return CSS_OK on success.
 */
css_error compute_absolute_values(const css_computed_style *parent,
		css_computed_style *style,
		css_error (*compute_font_size)(void *pw, 
			const css_hint *parent, css_hint *size),
		void *pw)
{
	css_hint psize, size, ex_size;
	css_error error;

	/* Ensure font-size is absolute */
	if (parent != NULL) {
		psize.status = get_font_size(parent, 
				&psize.data.length.value, 
				&psize.data.length.unit);
	}

	size.status = get_font_size(style, 
			&size.data.length.value, 
			&size.data.length.unit);

	error = compute_font_size(pw, parent != NULL ? &psize : NULL, &size);
	if (error != CSS_OK)
		return error;

	error = set_font_size(style, size.status,
			size.data.length.value, 
			size.data.length.unit);
	if (error != CSS_OK)
		return error;

	/* Compute the size of an ex unit */
	ex_size.status = CSS_FONT_SIZE_DIMENSION;
	ex_size.data.length.value = INTTOFIX(1);
	ex_size.data.length.unit = CSS_UNIT_EX;
	error = compute_font_size(pw, &size, &ex_size);
	if (error != CSS_OK)
		return error;

	/* Convert ex size into ems */
	if (size.data.length.value != 0)
		ex_size.data.length.value = FDIV(ex_size.data.length.value, 
					size.data.length.value);
	else
		ex_size.data.length.value = 0;
	ex_size.data.length.unit = CSS_UNIT_EM;

	/* Fix up background-position */
	error = compute_absolute_length_pair(style, &ex_size.data.length, 
			get_background_position,
			set_background_position);
	if (error != CSS_OK)
		return error;

	/* Fix up border-{top,right,bottom,left}-color */
	error = compute_border_colors(style);
	if (error != CSS_OK)
		return error;

	/* Fix up border-{top,right,bottom,left}-width */
	error = compute_absolute_border_width(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up sides */
	error = compute_absolute_sides(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up height */
	error = compute_absolute_length_auto(style, &ex_size.data.length, 
			get_height, set_height);
	if (error != CSS_OK)
		return error;

	/* Fix up line-height (must be before vertical-align) */
	error = compute_absolute_line_height(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up margins */
	error = compute_absolute_margins(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up max-height */
	error = compute_absolute_length_none(style, &ex_size.data.length, 
			get_max_height, set_max_height);
	if (error != CSS_OK)
		return error;

	/* Fix up max-width */
	error = compute_absolute_length_none(style, &ex_size.data.length, 
			get_max_width, set_max_width);
	if (error != CSS_OK)
		return error;

	/* Fix up min-height */
	error = compute_absolute_length(style, &ex_size.data.length, 
			get_min_height, set_min_height);
	if (error != CSS_OK)
		return error;

	/* Fix up min-width */
	error = compute_absolute_length(style, &ex_size.data.length, 
			get_min_width, set_min_width);
	if (error != CSS_OK)
		return error;

	/* Fix up padding */
	error = compute_absolute_padding(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up text-indent */
	error = compute_absolute_length(style, &ex_size.data.length, 
			get_text_indent, set_text_indent);
	if (error != CSS_OK)
		return error;

	/* Fix up vertical-align */
	error = compute_absolute_vertical_align(style, &ex_size.data.length);
	if (error != CSS_OK)
		return error;

	/* Fix up width */
	error = compute_absolute_length_auto(style, &ex_size.data.length, 
			get_width, set_width);
	if (error != CSS_OK)
		return error;

	/* Uncommon properties */
	if (style->uncommon != NULL) {
		/* Fix up border-spacing */
		error = compute_absolute_length_pair(style,
				&ex_size.data.length,
				get_border_spacing,
				set_border_spacing);
		if (error != CSS_OK)
			return error;

		/* Fix up clip */
		error = compute_absolute_clip(style, &ex_size.data.length);
		if (error != CSS_OK)
			return error;

		/* Fix up letter-spacing */
		error = compute_absolute_length_normal(style,
				&ex_size.data.length,
				get_letter_spacing, 
				set_letter_spacing);
		if (error != CSS_OK)
			return error;

		/* Fix up outline-width */
		error = compute_absolute_border_side_width(style, 
				&ex_size.data.length, 
				get_outline_width, 
				set_outline_width);
		if (error != CSS_OK)
			return error;

		/* Fix up word spacing */
		error = compute_absolute_length_normal(style,
				&ex_size.data.length,
				get_word_spacing, 
				set_word_spacing);
		if (error != CSS_OK)
			return error;
	}

	return CSS_OK;
}
コード例 #12
0
ファイル: opacity.c プロジェクト: CODECOMMUNITY/libcss
css_error css__initial_opacity(css_select_state *state)
{
	return set_opacity(state->computed, CSS_OPACITY_SET, INTTOFIX(1));
}
コード例 #13
0
ファイル: select.c プロジェクト: kyllikki/netsurf
/**
 * Font size computation callback for libcss
 *
 * \param pw      Computation context
 * \param parent  Parent font size (absolute)
 * \param size    Font size to compute
 * \return CSS_OK on success
 *
 * \post \a size will be an absolute font size
 */
css_error nscss_compute_font_size(void *pw, const css_hint *parent,
		css_hint *size)
{
	/**
	 * Table of font-size keyword scale factors
	 *
	 * These are multiplied by the configured default font size
	 * to produce an absolute size for the relevant keyword
	 */
	static const css_fixed factors[] = {
		FLTTOFIX(0.5625), /* xx-small */
		FLTTOFIX(0.6250), /* x-small */
		FLTTOFIX(0.8125), /* small */
		FLTTOFIX(1.0000), /* medium */
		FLTTOFIX(1.1250), /* large */
		FLTTOFIX(1.5000), /* x-large */
		FLTTOFIX(2.0000)  /* xx-large */
	};
	css_hint_length parent_size;

	/* Grab parent size, defaulting to medium if none */
	if (parent == NULL) {
		parent_size.value = FDIV(FMUL(factors[CSS_FONT_SIZE_MEDIUM - 1],
				INTTOFIX(nsoption_int(font_size))),
				INTTOFIX(10));
		parent_size.unit = CSS_UNIT_PT;
	} else {
		assert(parent->status == CSS_FONT_SIZE_DIMENSION);
		assert(parent->data.length.unit != CSS_UNIT_EM);
		assert(parent->data.length.unit != CSS_UNIT_EX);
		assert(parent->data.length.unit != CSS_UNIT_PCT);

		parent_size = parent->data.length;
	}

	assert(size->status != CSS_FONT_SIZE_INHERIT);

	if (size->status < CSS_FONT_SIZE_LARGER) {
		/* Keyword -- simple */
		size->data.length.value = FDIV(FMUL(factors[size->status - 1],
				INTTOFIX(nsoption_int(font_size))), F_10);
		size->data.length.unit = CSS_UNIT_PT;
	} else if (size->status == CSS_FONT_SIZE_LARGER) {
		/** \todo Step within table, if appropriate */
		size->data.length.value =
				FMUL(parent_size.value, FLTTOFIX(1.2));
		size->data.length.unit = parent_size.unit;
	} else if (size->status == CSS_FONT_SIZE_SMALLER) {
		/** \todo Step within table, if appropriate */
		size->data.length.value =
				FDIV(parent_size.value, FLTTOFIX(1.2));
		size->data.length.unit = parent_size.unit;
	} else if (size->data.length.unit == CSS_UNIT_EM ||
			size->data.length.unit == CSS_UNIT_EX ||
			size->data.length.unit == CSS_UNIT_CAP ||
			size->data.length.unit == CSS_UNIT_CH ||
			size->data.length.unit == CSS_UNIT_IC) {
		size->data.length.value =
			FMUL(size->data.length.value, parent_size.value);

		switch (size->data.length.unit) {
		case CSS_UNIT_EX:
			/* 1ex = 0.6em in NetSurf */
			size->data.length.value = FMUL(size->data.length.value,
					FLTTOFIX(0.6));
			break;
		case CSS_UNIT_CAP:
			/* Height of captals.  1cap = 0.9em in NetSurf. */
			size->data.length.value = FMUL(size->data.length.value,
					FLTTOFIX(0.9));
			break;
		case CSS_UNIT_CH:
			/* Width of '0'.  1ch = 0.4em in NetSurf. */
			size->data.length.value = FMUL(size->data.length.value,
					FLTTOFIX(0.4));
			break;
		case CSS_UNIT_IC:
			/* Width of U+6C43.  1ic = 1.1em in NetSurf. */
			size->data.length.value = FMUL(size->data.length.value,
					FLTTOFIX(1.1));
			break;
		default:
			/* No scaling required for EM. */
			break;
		}

		size->data.length.unit = parent_size.unit;
	} else if (size->data.length.unit == CSS_UNIT_PCT) {
		size->data.length.value = FDIV(FMUL(size->data.length.value,
				parent_size.value), INTTOFIX(100));
		size->data.length.unit = parent_size.unit;
	} else if (size->data.length.unit == CSS_UNIT_REM) {
		nscss_select_ctx *ctx = pw;
		if (parent == NULL) {
			size->data.length.value = parent_size.value;
			size->data.length.unit = parent_size.unit;
		} else {
			css_computed_font_size(ctx->root_style,
					&parent_size.value,
					&size->data.length.unit);
			size->data.length.value = FMUL(
					size->data.length.value,
					parent_size.value);
		}
	} else if (size->data.length.unit == CSS_UNIT_RLH) {
		/** TODO: Convert root element line-height to absolute value. */
		size->data.length.value = FMUL(size->data.length.value, FDIV(
				INTTOFIX(nsoption_int(font_size)),
				INTTOFIX(10)));
		size->data.length.unit = CSS_UNIT_PT;
	}

	size->status = CSS_FONT_SIZE_DIMENSION;

	return CSS_OK;
}
コード例 #14
0
ファイル: html_object.c プロジェクト: EyMenZ/NetSurf-OS3
static nserror
html_object_callback(hlcache_handle *object,
		     const hlcache_event *event,
		     void *pw)
{
	struct content_html_object *o = pw;
	html_content *c = (html_content *) o->parent;
	int x, y;
	struct box *box;

	assert(c->base.status != CONTENT_STATUS_ERROR);

	box = o->box;
	if (box == NULL && event->type != CONTENT_MSG_ERROR) {
		return NSERROR_OK;
	}

	switch (event->type) {
	case CONTENT_MSG_LOADING:
		if (c->base.status != CONTENT_STATUS_LOADING && c->bw != NULL)
			content_open(object,
					c->bw, &c->base,
					box->object_params);
		break;

	case CONTENT_MSG_READY:
		if (content_can_reformat(object)) {
			/* TODO: avoid knowledge of box internals here */
			content_reformat(object, false,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->width : 0,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->height : 0);

			/* Adjust parent content for new object size */
			html_object_done(box, object, o->background);
			if (c->base.status == CONTENT_STATUS_READY ||
					c->base.status == CONTENT_STATUS_DONE)
				content__reformat(&c->base, false,
						c->base.available_width,
						c->base.height);
		}
		break;

	case CONTENT_MSG_DONE:
		c->base.active--;
		LOG("%d fetches active", c->base.active);

		html_object_done(box, object, o->background);

		if (c->base.status != CONTENT_STATUS_LOADING &&
				box->flags & REPLACE_DIM) {
			union content_msg_data data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			data.redraw.x = x + box->padding[LEFT];
			data.redraw.y = y + box->padding[TOP];
			data.redraw.width = box->width;
			data.redraw.height = box->height;
			data.redraw.full_redraw = true;

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_ERROR:
		hlcache_handle_release(object);

		o->content = NULL;

		if (box != NULL) {
			c->base.active--;
			LOG("%d fetches active", c->base.active);

			content_add_error(&c->base, "?", 0);
			html_object_failed(box, c, o->background);
		}
		break;

	case CONTENT_MSG_REDRAW:
		if (c->base.status != CONTENT_STATUS_LOADING) {
			union content_msg_data data = event->data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			if (object == box->background) {
				/* Redraw request is for background */
				css_fixed hpos = 0, vpos = 0;
				css_unit hunit = CSS_UNIT_PX;
				css_unit vunit = CSS_UNIT_PX;
				int width = box->padding[LEFT] + box->width +
						box->padding[RIGHT];
				int height = box->padding[TOP] + box->height +
						box->padding[BOTTOM];
				int t, h, l, w;

				/* Need to know background-position */
				css_computed_background_position(box->style,
						&hpos, &hunit, &vpos, &vunit);

				w = content_get_width(box->background);
				if (hunit == CSS_UNIT_PCT) {
					l = (width - w) * hpos / INTTOFIX(100);
				} else {
					l = FIXTOINT(nscss_len2px(hpos, hunit,
							box->style));
				}

				h = content_get_height(box->background);
				if (vunit == CSS_UNIT_PCT) {
					t = (height - h) * vpos / INTTOFIX(100);
				} else {
					t = FIXTOINT(nscss_len2px(vpos, vunit,
							box->style));
				}

				/* Redraw area depends on background-repeat */
				switch (css_computed_background_repeat(
						box->style)) {
				case CSS_BACKGROUND_REPEAT_REPEAT:
					data.redraw.x = 0;
					data.redraw.y = 0;
					data.redraw.width = box->width;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_X:
					data.redraw.x = 0;
					data.redraw.y += t;
					data.redraw.width = box->width;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_Y:
					data.redraw.x += l;
					data.redraw.y = 0;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_NO_REPEAT:
					data.redraw.x += l;
					data.redraw.y += t;
					break;

				default:
					break;
				}

				data.redraw.object_width = box->width;
				data.redraw.object_height = box->height;

				/* Add offset to box */
				data.redraw.x += x;
				data.redraw.y += y;
				data.redraw.object_x += x;
				data.redraw.object_y += y;

				content_broadcast(&c->base,
						CONTENT_MSG_REDRAW, data);
				break;

			} else {
				/* Non-background case */
				if (hlcache_handle_get_content(object) ==
						event->data.redraw.object) {

					int w = content_get_width(object);
					int h = content_get_height(object);

					if (w != 0) {
						data.redraw.x =
							data.redraw.x *
							box->width / w;
						data.redraw.width =
							data.redraw.width *
							box->width / w;
					}

					if (h != 0) {
						data.redraw.y =
							data.redraw.y *
							box->height / h;
						data.redraw.height =
							data.redraw.height *
							box->height / h;
					}

					data.redraw.object_width = box->width;
					data.redraw.object_height = box->height;
				}

				data.redraw.x += x + box->padding[LEFT];
				data.redraw.y += y + box->padding[TOP];
				data.redraw.object_x += x + box->padding[LEFT];
				data.redraw.object_y += y + box->padding[TOP];
			}

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_REFRESH:
		if (content_get_type(object) == CONTENT_HTML) {
			/* only for HTML objects */
			guit->misc->schedule(event->data.delay * 1000,
					html_object_refresh, o);
		}

		break;

	case CONTENT_MSG_LINK:
		/* Don't care about favicons that aren't on top level content */
		break;

	case CONTENT_MSG_GETCTX:
		*(event->data.jscontext) = NULL;
		break;

	case CONTENT_MSG_SCROLL:
		if (box->scroll_x != NULL)
			scrollbar_set(box->scroll_x, event->data.scroll.x0,
					false);
		if (box->scroll_y != NULL)
			scrollbar_set(box->scroll_y, event->data.scroll.y0,
					false);
		break;

	case CONTENT_MSG_DRAGSAVE:
	{
		union content_msg_data msg_data;
		if (event->data.dragsave.content == NULL)
			msg_data.dragsave.content = object;
		else
			msg_data.dragsave.content =
					event->data.dragsave.content;

		content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, msg_data);
	}
		break;

	case CONTENT_MSG_SAVELINK:
	case CONTENT_MSG_POINTER:
	case CONTENT_MSG_SELECTMENU:
	case CONTENT_MSG_GADGETCLICK:
		/* These messages are for browser window layer.
		 * we're not interested, so pass them on. */
		content_broadcast(&c->base, event->type, event->data);
		break;

	case CONTENT_MSG_CARET:
	{
		union html_focus_owner focus_owner;
		focus_owner.content = box;

		switch (event->data.caret.type) {
		case CONTENT_CARET_REMOVE:
		case CONTENT_CARET_HIDE:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					true, 0, 0, 0, NULL);
			break;
		case CONTENT_CARET_SET_POS:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					false, event->data.caret.pos.x,
					event->data.caret.pos.y,
					event->data.caret.pos.height,
					event->data.caret.pos.clip);
			break;
		}
	}
		break;

	case CONTENT_MSG_DRAG:
	{
		html_drag_type drag_type = HTML_DRAG_NONE;
		union html_drag_owner drag_owner;
		drag_owner.content = box;

		switch (event->data.drag.type) {
		case CONTENT_DRAG_NONE:
			drag_type = HTML_DRAG_NONE;
			drag_owner.no_owner = true;
			break;
		case CONTENT_DRAG_SCROLL:
			drag_type = HTML_DRAG_CONTENT_SCROLL;
			break;
		case CONTENT_DRAG_SELECTION:
			drag_type = HTML_DRAG_CONTENT_SELECTION;
			break;
		}
		html_set_drag_type(c, drag_type, drag_owner,
				event->data.drag.rect);
	}
		break;

	case CONTENT_MSG_SELECTION:
	{
		html_selection_type sel_type;
		union html_selection_owner sel_owner;

		if (event->data.selection.selection) {
			sel_type = HTML_SELECTION_CONTENT;
			sel_owner.content = box;
		} else {
			sel_type = HTML_SELECTION_NONE;
			sel_owner.none = true;
		}
		html_set_selection(c, sel_type, sel_owner,
				event->data.selection.read_only);
	}
		break;

	default:
		break;
	}

	if (c->base.status == CONTENT_STATUS_READY && c->base.active == 0 &&
			(event->type == CONTENT_MSG_LOADING ||
			event->type == CONTENT_MSG_DONE ||
			event->type == CONTENT_MSG_ERROR)) {
		/* all objects have arrived */
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
		content_set_done(&c->base);
	}

	/* If  1) the configuration option to reflow pages while objects are
	 *        fetched is set
	 *     2) an object is newly fetched & converted,
	 *     3) the box's dimensions need to change due to being replaced
	 *     4) the object's parent HTML is ready for reformat,
	 *     5) the time since the previous reformat is more than the
	 *        configured minimum time between reformats
	 * then reformat the page to display newly fetched objects */
	else if (nsoption_bool(incremental_reflow) &&
			event->type == CONTENT_MSG_DONE &&
			box != NULL && !(box->flags & REPLACE_DIM) &&
			(c->base.status == CONTENT_STATUS_READY ||
			 c->base.status == CONTENT_STATUS_DONE) &&
			(wallclock() > c->base.reformat_time)) {
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
	}

	return NSERROR_OK;
}