Commit 17644a88 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

graphics: implement fillPath, arcTo

parent fbdf7e78
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -33,6 +33,36 @@

namespace plotfx {

void fillPath(
    Layer* layer,
    const Path& path,
    const FillStyle& style) {
  fillPath(
      layer,
      Rectangle(0, 0, layer->width, layer->height),
      path.data(),
      path.size(),
      style);
}

void fillPath(
    Layer* layer,
    const Rectangle& clip,
    const Path& path,
    const FillStyle& style) {
  fillPath(layer, clip, path.data(), path.size(), style);
}

void fillPath(
    Layer* layer,
    const Rectangle& clip,
    const PathData* point_data,
    size_t point_count,
    const FillStyle& style) {
  layer->rasterizer.fillPath(clip, point_data, point_count, style);
}


void strokePath(
    Layer* layer,
    const Path& path,
+25 −0
Original line number Diff line number Diff line
@@ -55,6 +55,31 @@ struct StrokeStyle {
  Colour colour;
};

struct FillStyle {
  FillStyle() :
    colour(Colour::fromRGB(0, 0, 0)) {}

  Colour colour;
};

void fillPath(
    Layer* layer,
    const Path& path,
    const FillStyle& style);

void fillPath(
    Layer* layer,
    const Rectangle& clip,
    const Path& path,
    const FillStyle& style);

void fillPath(
    Layer* layer,
    const Rectangle& clip,
    const PathData* path_data,
    size_t path_data_count,
    const FillStyle& style);

void strokePath(
    Layer* layer,
    const Path& path,
+43 −1
Original line number Diff line number Diff line
@@ -60,7 +60,46 @@ Rasterizer::~Rasterizer() {
  cairo_surface_destroy(cr_surface);
}

/* rasterize using libcairo */
Status Rasterizer::fillPath(
    const Rectangle& clip,
    const PathData* path_data,
    size_t point_count,
    const FillStyle& style) {
  if (point_count < 2) {
    return ERROR_INVALID_ARGUMENT;
  }

  cairo_set_source_rgba(
     cr_ctx,
     style.colour.red(),
     style.colour.green(),
     style.colour.blue(),
     style.colour.alpha());

  cairo_rectangle(cr_ctx, clip.x, clip.y, clip.w, clip.h);
  cairo_clip(cr_ctx);
  cairo_new_path(cr_ctx);

  for (size_t i = 0; i < point_count; ++i) {
    const auto& cmd = path_data[i];
    switch (cmd.command) {
      case PathCommand::MOVE_TO:
        cairo_move_to(cr_ctx, cmd[0], cmd[1]);
        break;
      case PathCommand::LINE_TO:
        cairo_line_to(cr_ctx, cmd[0], cmd[1]);
        break;
      case PathCommand::ARC_TO:
        cairo_arc(cr_ctx, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
        break;
    }
  }

  cairo_fill(cr_ctx);

  return OK;
}

Status Rasterizer::strokePath(
    const Rectangle& clip,
    const PathData* path_data,
@@ -92,6 +131,9 @@ Status Rasterizer::strokePath(
      case PathCommand::LINE_TO:
        cairo_line_to(cr_ctx, cmd[0], cmd[1]);
        break;
      case PathCommand::ARC_TO:
        cairo_arc(cr_ctx, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
        break;
    }
  }

+6 −0
Original line number Diff line number Diff line
@@ -59,6 +59,12 @@ public:
  Rasterizer(const Rasterizer&) = delete;
  Rasterizer& operator=(const Rasterizer&) = delete;

  Status fillPath(
      const Rectangle& clip,
      const PathData* point_data,
      size_t point_count,
      const FillStyle& style);

  Status strokePath(
      const Rectangle& clip,
      const PathData* point_data,