.fill_type = PLOT_OP_TYPE_SOLID, .fill_colour = WIDGET_BASEC, }; plot_style_t *plot_style_fill_wbasec = &plot_style_fill_wbasec_static; /** plot style for dark filled widget base colour . */ static plot_style_t plot_style_fill_darkwbasec_static = { .fill_type = PLOT_OP_TYPE_SOLID, .fill_colour = double_darken_colour(WIDGET_BASEC), }; plot_style_t *plot_style_fill_darkwbasec = &plot_style_fill_darkwbasec_static; /** plot style for light filled widget base colour. */ static plot_style_t plot_style_fill_lightwbasec_static = { .fill_type = PLOT_OP_TYPE_SOLID, .fill_colour = double_lighten_colour(WIDGET_BASEC), }; plot_style_t *plot_style_fill_lightwbasec = &plot_style_fill_lightwbasec_static; /** plot style for widget background. */ static plot_style_t plot_style_fill_wblobc_static = { .fill_type = PLOT_OP_TYPE_SOLID, .fill_colour = WIDGET_BLOBC, }; plot_style_t *plot_style_fill_wblobc = &plot_style_fill_wblobc_static; /** plot style for checkbox cross. */ static plot_style_t plot_style_stroke_wblobc_static = { .stroke_type = PLOT_OP_TYPE_SOLID, .stroke_colour = WIDGET_BLOBC,
/** * Draw one border. * * \param side index of border side (TOP, RIGHT, BOTTOM, LEFT) * \param p array of precomputed border vertices * \param c colour for border * \param style border line style * \param thickness border thickness * \param rectangular whether border is rectangular * \param clip cliping area for redrawing border. * \param ctx current redraw context * \return NSERROR_OK if successful otherwise appropriate error code */ static nserror html_redraw_border_plot(const int side, const int *p, colour c, enum css_border_style_e style, int thickness, bool rectangular, const struct rect *clip, const struct redraw_context *ctx) { int z[8]; /* Vertices of border part */ unsigned int light = side; plot_style_t *plot_style_bdr_in; plot_style_t *plot_style_bdr_out; nserror res = NSERROR_OK; struct rect rect; if (c == NS_TRANSPARENT) { return res; } plot_style_bdr.stroke_type = PLOT_OP_TYPE_DASH; plot_style_bdr.stroke_colour = c; plot_style_bdr.stroke_width = (thickness << PLOT_STYLE_RADIX); plot_style_fillbdr.fill_colour = c; plot_style_fillbdr_dark.fill_colour = darken_colour(c); plot_style_fillbdr_light.fill_colour = lighten_colour(c); plot_style_fillbdr_ddark.fill_colour = double_darken_colour(c); plot_style_fillbdr_dlight.fill_colour = double_lighten_colour(c); switch (style) { case CSS_BORDER_STYLE_DOTTED: plot_style_bdr.stroke_type = PLOT_OP_TYPE_DOT; /* fall through */ case CSS_BORDER_STYLE_DASHED: rect.x0 = (p[0] + p[2]) / 2; rect.y0 = (p[1] + p[3]) / 2; rect.x1 = (p[4] + p[6]) / 2; rect.y1 = (p[5] + p[7]) / 2; res = ctx->plot->line(ctx, &plot_style_bdr, &rect); break; case CSS_BORDER_STYLE_SOLID: /* fall through to default */ default: if (rectangular || thickness == 1) { if (side == TOP || side == RIGHT) { rect.x0 = p[2]; rect.y0 = p[3]; if ((side == TOP) && (p[4] - p[6] != 0)) { rect.x1 = p[4]; } else { rect.x1 = p[6]; } rect.y1 = p[7]; } else { rect.x0 = p[6]; rect.y0 = p[7]; rect.x1 = p[2]; if ((side == LEFT) && (p[1] - p[3] != 0)) { rect.y1 = p[1]; } else { rect.y1 = p[3]; } } res = plot_clipped_rectangle(ctx, &plot_style_fillbdr, clip, &rect); } else { res = ctx->plot->polygon(ctx, &plot_style_fillbdr, p, 4); } break; case CSS_BORDER_STYLE_DOUBLE: z[0] = p[0]; z[1] = p[1]; z[2] = (p[0] * 2 + p[2]) / 3; z[3] = (p[1] * 2 + p[3]) / 3; z[4] = (p[6] * 2 + p[4]) / 3; z[5] = (p[7] * 2 + p[5]) / 3; z[6] = p[6]; z[7] = p[7]; res = ctx->plot->polygon(ctx, &plot_style_fillbdr, z, 4); if (res == NSERROR_OK) { z[0] = p[2]; z[1] = p[3]; z[2] = (p[2] * 2 + p[0]) / 3; z[3] = (p[3] * 2 + p[1]) / 3; z[4] = (p[4] * 2 + p[6]) / 3; z[5] = (p[5] * 2 + p[7]) / 3; z[6] = p[4]; z[7] = p[5]; res = ctx->plot->polygon(ctx, &plot_style_fillbdr, z, 4); } break; case CSS_BORDER_STYLE_GROOVE: light = 3 - light; /* fall through */ case CSS_BORDER_STYLE_RIDGE: /* choose correct colours for each part of the border line */ if (light <= 1) { plot_style_bdr_in = &plot_style_fillbdr_dark; plot_style_bdr_out = &plot_style_fillbdr_light; } else { plot_style_bdr_in = &plot_style_fillbdr_light; plot_style_bdr_out = &plot_style_fillbdr_dark; } /* Render border */ if ((rectangular || thickness == 2) && thickness != 1) { /* Border made up from two parts and can be * plotted with rectangles */ /* First part */ if (side == TOP || side == RIGHT) { rect.x0 = (p[0] + p[2]) / 2; rect.y0 = (p[1] + p[3]) / 2; rect.x1 = p[6]; rect.y1 = p[7]; } else { rect.x0 = p[6]; rect.y0 = p[7]; rect.x1 = (p[0] + p[2]) / 2; rect.y1 = (p[1] + p[3]) / 2; } res = plot_clipped_rectangle(ctx, plot_style_bdr_in, clip, &rect); if (res != NSERROR_OK) { return res; } /* Second part */ if (side == TOP || side == RIGHT) { rect.x0 = p[2]; rect.y0 = p[3]; rect.x1 = (p[6] + p[4]) / 2; rect.y1 = (p[7] + p[5]) / 2; } else { rect.x0 = (p[6] + p[4]) / 2; rect.y0 = (p[7] + p[5]) / 2; rect.x1 = p[2]; rect.y1 = p[3]; } res = plot_clipped_rectangle(ctx, plot_style_bdr_out, clip, &rect); } else if (thickness == 1) { /* Border made up from one part which can be * plotted as a rectangle */ if (side == TOP || side == RIGHT) { rect.x0 = p[2]; rect.y0 = p[3]; rect.x1 = p[6]; rect.y1 = p[7]; rect.x1 = ((side == TOP) && (p[4] - p[6] != 0)) ? rect.x1 + p[4] - p[6] : rect.x1; res = plot_clipped_rectangle(ctx, plot_style_bdr_in, clip, &rect); } else { rect.x0 = p[6]; rect.y0 = p[7]; rect.x1 = p[2]; rect.y1 = p[3]; rect.y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ? rect.y1 + p[1] - p[3] : rect.y1; res = plot_clipped_rectangle(ctx, plot_style_bdr_out, clip, &rect); } } else { /* Border made up from two parts and can't be * plotted with rectangles */ z[0] = p[0]; z[1] = p[1]; z[2] = (p[0] + p[2]) / 2; z[3] = (p[1] + p[3]) / 2; z[4] = (p[6] + p[4]) / 2; z[5] = (p[7] + p[5]) / 2; z[6] = p[6]; z[7] = p[7]; res = ctx->plot->polygon(ctx, plot_style_bdr_in, z, 4); if (res == NSERROR_OK) { z[0] = p[2]; z[1] = p[3]; z[6] = p[4]; z[7] = p[5]; res = ctx->plot->polygon(ctx, plot_style_bdr_out, z, 4); } } break; case CSS_BORDER_STYLE_INSET: light = (light + 2) % 4; /* fall through */ case CSS_BORDER_STYLE_OUTSET: /* choose correct colours for each part of the border line */ switch (light) { case 0: plot_style_bdr_in = &plot_style_fillbdr_light; plot_style_bdr_out = &plot_style_fillbdr_dlight; break; case 1: plot_style_bdr_in = &plot_style_fillbdr_ddark; plot_style_bdr_out = &plot_style_fillbdr_dark; break; case 2: plot_style_bdr_in = &plot_style_fillbdr_dark; plot_style_bdr_out = &plot_style_fillbdr_ddark; break; case 3: plot_style_bdr_in = &plot_style_fillbdr_dlight; plot_style_bdr_out = &plot_style_fillbdr_light; break; default: plot_style_bdr_in = &plot_style_fillbdr; plot_style_bdr_out = &plot_style_fillbdr; break; } /* Render border */ if ((rectangular || thickness == 2) && thickness != 1) { /* Border made up from two parts and can be * plotted with rectangles */ /* First part */ if (side == TOP || side == RIGHT) { rect.x0 = (p[0] + p[2]) / 2; rect.y0 = (p[1] + p[3]) / 2; rect.x1 = p[6]; rect.y1 = p[7]; } else { rect.x0 = p[6]; rect.y0 = p[7]; rect.x1 = (p[0] + p[2]) / 2; rect.y1 = (p[1] + p[3]) / 2; } res = plot_clipped_rectangle(ctx, plot_style_bdr_in, clip, &rect); if (res != NSERROR_OK) { return res; } /* Second part */ if (side == TOP || side == RIGHT) { rect.x0 = p[2]; rect.y0 = p[3]; rect.x1 = (p[6] + p[4]) / 2; rect.y1 = (p[7] + p[5]) / 2; } else { rect.x0 = (p[6] + p[4]) / 2; rect.y0 = (p[7] + p[5]) / 2; rect.x1 = p[2]; rect.y1 = p[3]; } res = plot_clipped_rectangle(ctx, plot_style_bdr_out, clip, &rect); } else if (thickness == 1) { /* Border made up from one part which can be * plotted as a rectangle */ if (side == TOP || side == RIGHT) { rect.x0 = p[2]; rect.y0 = p[3]; rect.x1 = p[6]; rect.y1 = p[7]; rect.x1 = ((side == TOP) && (p[4] - p[6] != 0)) ? rect.x1 + p[4] - p[6] : rect.x1; res = plot_clipped_rectangle(ctx, plot_style_bdr_in, clip, &rect); } else { rect.x0 = p[6]; rect.y0 = p[7]; rect.x1 = p[2]; rect.y1 = p[3]; rect.y1 = ((side == LEFT) && (p[1] - p[3] != 0)) ? rect.y1 + p[1] - p[3] : rect.y1; res = plot_clipped_rectangle(ctx, plot_style_bdr_out, clip, &rect); } } else { /* Border made up from two parts and can't be * plotted with rectangles */ z[0] = p[0]; z[1] = p[1]; z[2] = (p[0] + p[2]) / 2; z[3] = (p[1] + p[3]) / 2; z[4] = (p[6] + p[4]) / 2; z[5] = (p[7] + p[5]) / 2; z[6] = p[6]; z[7] = p[7]; res = ctx->plot->polygon(ctx, plot_style_bdr_in, z, 4); if (res != NSERROR_OK) { return res; } z[0] = p[2]; z[1] = p[3]; z[6] = p[4]; z[7] = p[5]; res = ctx->plot->polygon(ctx, plot_style_bdr_out, z, 4); } break; } return res; }