/* 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; }
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; }
/** * 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; }
/** * 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; }