Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
0
static bool copy_handler(const char *text, size_t length, struct box *box,
		void *handle, const char *whitespace_text,
		size_t whitespace_length)
{
	bool space = false;
	//XXX: handle box->style to StyledEdit / RTF ?
	/* add any whitespace which precedes the text from this box */
	if (whitespace_text) {
		if (!gui_add_to_clipboard(whitespace_text,
				whitespace_length, false)) {
			return false;
		}
	}

	// add a text_run for StyledEdit-like text formating
	if (box && box->style) {
		text_run *run = new text_run;
		BFont font;
		plot_font_style_t style;
		font_plot_style_from_css(box->style, &style);
		nsbeos_style_to_font(font, &style);
		run->offset = current_selection.Length();
		run->font = font;
		css_color csscolor;
		if (css_computed_color(box->style, &csscolor) == CSS_COLOR_COLOR) {
			run->color = nsbeos_rgb_colour(nscss_color_to_ns(csscolor));
		}
		current_selection_textruns.AddItem(run);
		space = box->space != 0;
	}

	/* add the text from this box */
	if (!gui_add_to_clipboard(text, length, space))
		return false;

	return true;
}
Exemplo n.º 3
0
/**
 * Draw an inline's borders.
 *
 * \param box BOX_INLINE which created the border
 * \param b coordinates of border edge rectangle
 * \param clip cliping area for redrawing border.
 * \param scale scale for redraw
 * \param first true if this is the first rectangle associated with the inline
 * \param last true if this is the last rectangle associated with the inline
 * \param ctx current redraw context
 * \return true if successful, false otherwise
 */
bool
html_redraw_inline_borders(struct box *box,
			   struct rect b,
			   const struct rect *clip,
			   float scale,
			   bool first,
			   bool last,
			   const struct redraw_context *ctx)
{
	int top = box->border[TOP].width;
	int right = box->border[RIGHT].width;
	int bottom = box->border[BOTTOM].width;
	int left = box->border[LEFT].width;
	colour col;
	int p[8]; /* Box border vertices */
	int z[8]; /* Border vertices */
	bool square_end_1;
	bool square_end_2;
	nserror res;

	if (scale != 1.0) {
		top *= scale;
		right *= scale;
		bottom *= scale;
		left *= scale;
	}

	/* Calculate border vertices
	 *
	 *    A----------------------+
	 *    | \                  / |
	 *    |   B--------------+   |
	 *    |   |              |   |
	 *    |   +--------------C   |
	 *    | /                  \ |
	 *    +----------------------D
	 */
	p[0] = b.x0;				p[1] = b.y0;		/* A */
	p[2] = first ? b.x0 + left : b.x0;	p[3] = b.y0 + top;	/* B */
	p[4] = last ? b.x1 - right : b.x1;	p[5] = b.y1 - bottom;	/* C */
	p[6] = b.x1;				p[7] = b.y1;		/* D */

	assert(box->style);

	/* Left */
	square_end_1 = (top == 0);
	square_end_2 = (bottom == 0);
	if (left != 0 &&
	    first &&
	    nscss_color_is_transparent(box->border[LEFT].c) == false) {
		col = nscss_color_to_ns(box->border[LEFT].c);

		z[0] = p[0];	z[1] = p[7];
		z[2] = p[2];	z[3] = p[5];
		z[4] = p[2];	z[5] = p[3];
		z[6] = p[0];	z[7] = p[1];

		if (nscss_color_is_transparent(box->border[TOP].c) == false &&
		    box->border[TOP].style != CSS_BORDER_STYLE_DOUBLE) {
			/* make border overhang top corner fully,
			 * if top border is opaque
			 */
			z[5] -= top;
			square_end_1 = true;
		}

		if (nscss_color_is_transparent(box->border[BOTTOM].c) == false &&
		    box->border[BOTTOM].style != CSS_BORDER_STYLE_DOUBLE) {
			/* make border overhang bottom corner fully,
			 * if bottom border is opaque
			 */
			z[3] += bottom;
			square_end_2 = true;
		}

		res = html_redraw_border_plot(LEFT,
					      z,
					      col,
					      box->border[LEFT].style,
					      left,
					      square_end_1 && square_end_2,
					      clip,
					      ctx);
		if (res != NSERROR_OK) {
			return false;
		}
	}

	/* Right */
	square_end_1 = (top == 0);
	square_end_2 = (bottom == 0);
	if (right != 0 &&
	    last &&
	    nscss_color_is_transparent(box->border[RIGHT].c) == false) {
		col = nscss_color_to_ns(box->border[RIGHT].c);

		z[0] = p[6];	z[1] = p[1];
		z[2] = p[4];	z[3] = p[3];
		z[4] = p[4];	z[5] = p[5];
		z[6] = p[6];	z[7] = p[7];

		if (nscss_color_is_transparent(box->border[TOP].c) == false &&
		    box->border[TOP].style != CSS_BORDER_STYLE_DOUBLE) {
			/* make border overhang top corner fully,
			 * if top border is opaque
			 */
			z[3] -= top;
			square_end_1 = true;
		}

		if (nscss_color_is_transparent(box->border[BOTTOM].c) == false &&
		    box->border[BOTTOM].style != CSS_BORDER_STYLE_DOUBLE) {
			/* make border overhang bottom corner fully,
			 * if bottom border is opaque
			 */
			z[5] += bottom;
			square_end_2 = true;
		}

		res = html_redraw_border_plot(RIGHT,
					      z,
					      col,
					      box->border[RIGHT].style,
					      right,
					      square_end_1 && square_end_2,
					      clip,
					      ctx);
		if (res != NSERROR_OK) {
			return false;
		}
	}

	/* Top */
	square_end_1 = (left == 0);
	square_end_2 = (right == 0);
	if (top != 0 &&
	    nscss_color_is_transparent(box->border[TOP].c) == false) {
		col = nscss_color_to_ns(box->border[TOP].c);

		z[0] = p[2];	z[1] = p[3];
		z[2] = p[0];	z[3] = p[1];
		z[4] = p[6];	z[5] = p[1];
		z[6] = p[4];	z[7] = p[3];

		if (first &&
		    box->border[TOP].style == CSS_BORDER_STYLE_SOLID &&
		    box->border[TOP].c == box->border[LEFT].c) {
			/* don't bother overlapping left corner if
			 * it's the same colour anyway
			 */
			z[2] += left;
			square_end_1 = true;
		}

		if (last &&
		    box->border[TOP].style == CSS_BORDER_STYLE_SOLID &&
		    box->border[TOP].c == box->border[RIGHT].c) {
			/* don't bother overlapping right corner if
			 * it's the same colour anyway
			 */
			z[4] -= right;
			square_end_2 = true;
		}

		res = html_redraw_border_plot(TOP,
					      z,
					      col,
					      box->border[TOP].style,
					      top,
					      square_end_1 && square_end_2,
					      clip,
					      ctx);
		if (res != NSERROR_OK) {
			return false;
		}
	}

	/* Bottom */
	square_end_1 = (left == 0);
	square_end_2 = (right == 0);
	if (bottom != 0 &&
	    nscss_color_is_transparent(box->border[BOTTOM].c) == false) {
		col = nscss_color_to_ns(box->border[BOTTOM].c);

		z[0] = p[4];	z[1] = p[5];
		z[2] = p[6];	z[3] = p[7];
		z[4] = p[0];	z[5] = p[7];
		z[6] = p[2];	z[7] = p[5];

		if (first &&
		    box->border[BOTTOM].style == CSS_BORDER_STYLE_SOLID &&
		    box->border[BOTTOM].c == box->border[LEFT].c) {
			/* don't bother overlapping left corner if
			 * it's the same colour anyway
			 */
			z[4] += left;
			square_end_1 = true;
		}

		if (last &&
		    box->border[BOTTOM].style == CSS_BORDER_STYLE_SOLID &&
		    box->border[BOTTOM].c == box->border[RIGHT].c) {
			/* don't bother overlapping right corner if
			 * it's the same colour anyway
			 */
			z[2] -= right;
			square_end_2 = true;
		}

		res = html_redraw_border_plot(BOTTOM,
					      z,
					      col,
					      box->border[BOTTOM].style,
					      bottom,
					      square_end_1 && square_end_2,
					      clip,
					      ctx);
		if (res != NSERROR_OK) {
			return false;
		}
	}

	return true;
}
Exemplo n.º 4
0
/**
 * Draw borders for a box.
 *
 * \param box box to draw
 * \param x_parent coordinate of left padding edge of parent of box
 * \param y_parent coordinate of top padding edge of parent of box
 * \param p_width width of padding box
 * \param p_height height of padding box
 * \param clip cliping area for redrawing border.
 * \param scale scale for redraw
 * \param ctx current redraw context
 * \return true if successful, false otherwise
 */
bool
html_redraw_borders(struct box *box,
		    int x_parent,
		    int y_parent,
		    int p_width,
		    int p_height,
		    const struct rect *clip,
		    float scale,
		    const struct redraw_context *ctx)
{
	unsigned int sides[] = { LEFT, RIGHT, TOP, BOTTOM };
	int top = box->border[TOP].width;
	int right = box->border[RIGHT].width;
	int bottom = box->border[BOTTOM].width;
	int left = box->border[LEFT].width;
	int x, y;
	unsigned int i, side;
	int p[8]; /* Box border vertices */
	int z[8]; /* Border vertices */
	bool square_end_1 = false;
	bool square_end_2 = false;
	nserror res;

	x = x_parent + box->x;
	y = y_parent + box->y;

	if (scale != 1.0) {
		top *= scale;
		right *= scale;
		bottom *= scale;
		left *= scale;
		x *= scale;
		y *= scale;
	}

	assert(box->style);

	/* Calculate border vertices
	 *
	 *    A----------------------+
	 *    | \                  / |
	 *    |   B--------------+   |
	 *    |   |              |   |
	 *    |   +--------------C   |
	 *    | /                  \ |
	 *    +----------------------D
	 */
	p[0] = x - left;		p[1] = y - top;			/* A */
	p[2] = x;			p[3] = y;			/* B */
	p[4] = x + p_width;		p[5] = y + p_height;		/* C */
	p[6] = x + p_width + right;	p[7] = y + p_height + bottom;	/* D */

	for (i = 0; i != 4; i++) {
		colour col = 0;
		side = sides[i]; /* plot order */

		if (box->border[side].width == 0 ||
		    nscss_color_is_transparent(box->border[side].c)) {
			continue;
		}

		switch (side) {
		case LEFT:
			square_end_1 = (top == 0);
			square_end_2 = (bottom == 0);

			z[0] = p[0];	z[1] = p[7];
			z[2] = p[2];	z[3] = p[5];
			z[4] = p[2];	z[5] = p[3];
			z[6] = p[0];	z[7] = p[1];

			if (nscss_color_is_transparent(box->border[TOP].c) == false &&
			    box->border[TOP].style != CSS_BORDER_STYLE_DOUBLE) {
				/* make border overhang top corner fully,
				 * if top border is opaque
				 */
				z[5] -= top;
				square_end_1 = true;
			}
			if (nscss_color_is_transparent(box->border[BOTTOM].c) == false &&
			    box->border[BOTTOM].style != CSS_BORDER_STYLE_DOUBLE) {
				/* make border overhang bottom corner fully,
				 * if bottom border is opaque
				 */
				z[3] += bottom;
				square_end_2 = true;
			}

			col = nscss_color_to_ns(box->border[side].c);

			res = html_redraw_border_plot(side,
						      z,
						      col,
						      box->border[side].style,
						      box->border[side].width * scale,
						      square_end_1 && square_end_2,
						      clip,
						      ctx);
			if (res != NSERROR_OK) {
				return false;
			}
			break;

		case RIGHT:
			square_end_1 = (top == 0);
			square_end_2 = (bottom == 0);

			z[0] = p[6];	z[1] = p[1];
			z[2] = p[4];	z[3] = p[3];
			z[4] = p[4];	z[5] = p[5];
			z[6] = p[6];	z[7] = p[7];

			if (nscss_color_is_transparent(box->border[TOP].c) == false &&
			    box->border[TOP].style != CSS_BORDER_STYLE_DOUBLE) {
				/* make border overhang top corner fully,
				 * if top border is opaque
				 */
				z[3] -= top;
				square_end_1 = true;
			}
			if (nscss_color_is_transparent(box->border[BOTTOM].c) == false &&
			    box->border[BOTTOM].style != CSS_BORDER_STYLE_DOUBLE) {
				/* make border overhang bottom corner fully,
				 * if bottom border is opaque
				 */
				z[5] += bottom;
				square_end_2 = true;
			}

			col = nscss_color_to_ns(box->border[side].c);

			res = html_redraw_border_plot(side,
						      z,
						      col,
						      box->border[side].style,
						      box->border[side].width * scale,
						      square_end_1 && square_end_2,
						      clip,
						      ctx);
			if (res != NSERROR_OK) {
				return false;
			}
			break;

		case TOP:
			if (clip->y0 > p[3]) {
				/* clip rectangle is below border; nothing to
				 * plot
				 */
				continue;
			}

			square_end_1 = (left == 0);
			square_end_2 = (right == 0);

			z[0] = p[2];	z[1] = p[3];
			z[2] = p[0];	z[3] = p[1];
			z[4] = p[6];	z[5] = p[1];
			z[6] = p[4];	z[7] = p[3];

			if (box->border[TOP].style == CSS_BORDER_STYLE_SOLID &&
			    box->border[TOP].c == box->border[LEFT].c) {
				/* don't bother overlapping left corner if
				 * it's the same colour anyway
				 */
				z[2] += left;
				square_end_1 = true;
			}
			if (box->border[TOP].style == CSS_BORDER_STYLE_SOLID &&
			    box->border[TOP].c == box->border[RIGHT].c) {
				/* don't bother overlapping right corner if
				 * it's the same colour anyway
				 */
				z[4] -= right;
				square_end_2 = true;
			}

			col = nscss_color_to_ns(box->border[side].c);

			res = html_redraw_border_plot(side,
						      z,
						      col,
						      box->border[side].style,
						      box->border[side].width * scale,
						      square_end_1 && square_end_2,
						      clip,
						      ctx);
			if (res != NSERROR_OK) {
				return false;
			}
			break;

		case BOTTOM:
			if (clip->y1 < p[5]) {
				/* clip rectangle is above border; nothing to
				 * plot
				 */
				continue;
			}

			square_end_1 = (left == 0);
			square_end_2 = (right == 0);

			z[0] = p[4];	z[1] = p[5];
			z[2] = p[6];	z[3] = p[7];
			z[4] = p[0];	z[5] = p[7];
			z[6] = p[2];	z[7] = p[5];

			if (box->border[BOTTOM].style == CSS_BORDER_STYLE_SOLID &&
			    box->border[BOTTOM].c == box->border[LEFT].c) {
				/* don't bother overlapping left corner if
				 * it's the same colour anyway
				 */
				z[4] += left;
				square_end_1 = true;
			}
			if (box->border[BOTTOM].style == CSS_BORDER_STYLE_SOLID &&
			    box->border[BOTTOM].c == box->border[RIGHT].c) {
				/* don't bother overlapping right corner if
				 * it's the same colour anyway
				 */
				z[2] -= right;
				square_end_2 = true;
			}

			col = nscss_color_to_ns(box->border[side].c);

			res = html_redraw_border_plot(side,
						      z,
						      col,
						      box->border[side].style,
						      box->border[side].width * scale,
						      square_end_1 && square_end_2,
						      clip,
						      ctx);
			if (res != NSERROR_OK) {
				return false;
			}
			break;

		default:
			assert(side == TOP || side == BOTTOM ||
			       side == LEFT || side == RIGHT);
			break;
		}
	}

	return true;
}