bool ro_save_draw_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) { pencil_code code; const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1, draw_LINE_TO, x1 * 2, -y0 * 2 - 1, draw_LINE_TO, x1 * 2, -y1 * 2 - 1, draw_LINE_TO, x0 * 2, -y1 * 2 - 1, draw_CLOSE_LINE, draw_END_PATH }; if (style->fill_type != PLOT_OP_TYPE_NONE) { code = pencil_path(ro_save_draw_diagram, path, sizeof path / sizeof path[0], style->fill_colour << 8, pencil_TRANSPARENT, 0, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); } if (style->stroke_type != PLOT_OP_TYPE_NONE) { code = pencil_path(ro_save_draw_diagram, path, sizeof path / sizeof path[0], pencil_TRANSPARENT, style->stroke_colour << 8, style->stroke_width, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); } return true; }
bool ro_save_draw_polygon(const int *p, unsigned int n, const plot_style_t *style) { pencil_code code; int path[n * 3 + 1]; unsigned int i; for (i = 0; i != n; i++) { path[i * 3 + 0] = draw_LINE_TO; path[i * 3 + 1] = p[i * 2 + 0] * 2; path[i * 3 + 2] = -p[i * 2 + 1] * 2; } path[0] = draw_MOVE_TO; path[n * 3] = draw_END_PATH; code = pencil_path(ro_save_draw_diagram, path, n * 3 + 1, style->fill_colour << 8, pencil_TRANSPARENT, 0, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); return true; }
bool ro_save_draw_line(int x0, int y0, int x1, int y1, const plot_style_t *style) { pencil_code code; const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1, draw_LINE_TO, x1 * 2, -y1 * 2 - 1, draw_END_PATH }; code = pencil_path(ro_save_draw_diagram, path, sizeof path / sizeof path[0], pencil_TRANSPARENT, style->stroke_colour << 8, style->stroke_width, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); return true; }
bool ro_save_draw_path(const float *p, unsigned int n, colour fill, float width, colour c, const float transform[6]) { if (n == 0) return true; if (p[0] != PLOTTER_PATH_MOVE) { LOG(("path doesn't start with a move")); return false; } int *path = malloc(sizeof *path * (n + 10)); if (!path) { LOG(("out of memory")); return false; } unsigned int i; bool empty_path = true; for (i = 0; i < n; ) { if (p[i] == PLOTTER_PATH_MOVE) { path[i] = draw_MOVE_TO; path[i + 1] = (transform[0] * p[i + 1] + transform[2] * -p[i + 2] + transform[4]) * 2; path[i + 2] = (transform[1] * p[i + 1] + transform[3] * -p[i + 2] + -transform[5]) * 2; i += 3; } else if (p[i] == PLOTTER_PATH_CLOSE) { path[i] = draw_CLOSE_LINE; i++; } else if (p[i] == PLOTTER_PATH_LINE) { path[i] = draw_LINE_TO; path[i + 1] = (transform[0] * p[i + 1] + transform[2] * -p[i + 2] + transform[4]) * 2; path[i + 2] = (transform[1] * p[i + 1] + transform[3] * -p[i + 2] + -transform[5]) * 2; i += 3; empty_path = false; } else if (p[i] == PLOTTER_PATH_BEZIER) { path[i] = draw_BEZIER_TO; path[i + 1] = (transform[0] * p[i + 1] + transform[2] * -p[i + 2] + transform[4]) * 2; path[i + 2] = (transform[1] * p[i + 1] + transform[3] * -p[i + 2] + -transform[5]) * 2; path[i + 3] = (transform[0] * p[i + 3] + transform[2] * -p[i + 4] + transform[4]) * 2; path[i + 4] = (transform[1] * p[i + 3] + transform[3] * -p[i + 4] + -transform[5]) * 2; path[i + 5] = (transform[0] * p[i + 5] + transform[2] * -p[i + 6] + transform[4]) * 2; path[i + 6] = (transform[1] * p[i + 5] + transform[3] * -p[i + 6] + -transform[5]) * 2; i += 7; empty_path = false; } else { LOG(("bad path command %f", p[i])); free(path); return false; } } path[i] = draw_END_PATH; if (empty_path) { free(path); return true; } pencil_code code = pencil_path(ro_save_draw_diagram, path, i + 1, fill == NS_TRANSPARENT ? pencil_TRANSPARENT : fill << 8, c == NS_TRANSPARENT ? pencil_TRANSPARENT : c << 8, width, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); free(path); if (code != pencil_OK) return ro_save_draw_error(code); return true; }
bool save_as_draw(hlcache_handle *h, const char *path) { pencil_code code; char *drawfile_buffer; struct rect clip; struct content_redraw_data data; size_t drawfile_size; os_error *error; struct redraw_context ctx = { .interactive = false, .background_images = true, .plot = &ro_save_draw_plotters }; ro_save_draw_diagram = pencil_create(); if (!ro_save_draw_diagram) { warn_user("NoMemory", 0); return false; } ro_save_draw_width = content_get_width(h); ro_save_draw_height = content_get_height(h); clip.x0 = clip.y0 = INT_MIN; clip.x1 = clip.y1 = INT_MAX; data.x = 0; data.y = -ro_save_draw_height; data.width = ro_save_draw_width; data.height = ro_save_draw_height; data.background_colour = 0xFFFFFF; data.scale = 1; data.repeat_x = false; data.repeat_y = false; if (!content_redraw(h, &data, &clip, &ctx)) { pencil_free(ro_save_draw_diagram); return false; } /*pencil_dump(ro_save_draw_diagram);*/ code = pencil_save_drawfile(ro_save_draw_diagram, "NetSurf", &drawfile_buffer, &drawfile_size); if (code != pencil_OK) { warn_user("SaveError", 0); pencil_free(ro_save_draw_diagram); return false; } assert(drawfile_buffer); error = xosfile_save_stamped(path, osfile_TYPE_DRAW, (byte *) drawfile_buffer, (byte *) drawfile_buffer + drawfile_size); if (error) { LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess); warn_user("SaveError", error->errmess); pencil_free(ro_save_draw_diagram); return false; } pencil_free(ro_save_draw_diagram); return true; } bool ro_save_draw_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) { pencil_code code; const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1, draw_LINE_TO, x1 * 2, -y0 * 2 - 1, draw_LINE_TO, x1 * 2, -y1 * 2 - 1, draw_LINE_TO, x0 * 2, -y1 * 2 - 1, draw_CLOSE_LINE, draw_END_PATH }; if (style->fill_type != PLOT_OP_TYPE_NONE) { code = pencil_path(ro_save_draw_diagram, path, sizeof path / sizeof path[0], style->fill_colour << 8, pencil_TRANSPARENT, 0, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); } if (style->stroke_type != PLOT_OP_TYPE_NONE) { code = pencil_path(ro_save_draw_diagram, path, sizeof path / sizeof path[0], pencil_TRANSPARENT, style->stroke_colour << 8, style->stroke_width, pencil_JOIN_MITRED, pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, pencil_SOLID); if (code != pencil_OK) return ro_save_draw_error(code); } return true; }