Commit c8eb32ee authored by Paul Asmuth's avatar Paul Asmuth
Browse files

go back to rasterizing paths using libcairo for now

parent 876aad2e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ add_library(signaltk STATIC
    src/signaltk_cli.cc
    src/signaltk_cmd.cc)

set(SIGNALTK_LDFLAGS signaltk ${CAIRO_LIBRARIES} ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_ICU_LIBRARIES} ${PNG_LIBRARIES} agg)
set(SIGNALTK_LDFLAGS signaltk ${CAIRO_LIBRARIES} ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_ICU_LIBRARIES} ${PNG_LIBRARIES})

file(GLOB test_files "test/**/test_*.cc")
foreach(test_path ${test_files})
+6 −8
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 */
#include <iostream>
#include "brush.h"
#include "layer.h"

namespace signaltk {

@@ -17,7 +18,7 @@ void strokePath(
    const PathData* point_data,
    size_t point_count,
    const StrokeStyle& style) {
  layer->rasterizer.rasterizePath(point_data, point_count);
  layer->rasterizer.strokePath(point_data, point_count, style);
}

void strokeLine(
@@ -28,15 +29,12 @@ void strokeLine(
    double y2,
    const StrokeStyle& style) {
  Path p;
  p.moveTo(10, 10);
  p.lineTo(10, 100);
  p.lineTo(100, 100);
  p.lineTo(100, 10);
  p.closePath();
  p.moveTo(x1, y1);
  p.lineTo(x2, y2);
  p.lineTo(x2, y2);
  p.lineTo(x2, y2);
  strokePath(layer, p.data(), p.size(), style);
}

/* rasterize path using Maxim Shemanarev's libagg */

} // namespace signaltk
+1 −1
Original line number Diff line number Diff line
@@ -12,10 +12,10 @@
#include <stdlib.h>
#include <stdint.h>
#include "colour.h"
#include "layer.h"
#include "path.h"

namespace signaltk {
class Layer;

enum class StrokeLineJoin { MITER, ROUND, BEVEL };
enum class StrokeLineCap { BUTT, SQUARE, ROUND};
+102 −39
Original line number Diff line number Diff line
@@ -9,11 +9,6 @@
 */
#include <signaltk/core/rasterize.h>
#include <signaltk/core/image.h>
#include <agg2/agg_basics.h>
#include <agg2/agg_rasterizer_scanline_aa.h>
#include <agg2/agg_path_storage.h>
#include <agg2/agg_scanline_u.h>
#include <agg2/agg_conv_curve.h>

namespace signaltk {

@@ -26,14 +21,75 @@ Rasterizer::Rasterizer(
  if (!FT_Init_FreeType(&ft)) {
    ft_ready = true;
  }

  cr_surface = cairo_image_surface_create(
      CAIRO_FORMAT_A8,
      pixmap->getWidth(),
      pixmap->getHeight());

  cr_ctx = cairo_create(cr_surface);
}

Rasterizer::~Rasterizer() {
  if (ft_ready) {
    FT_Done_FreeType(ft);
  }

  cairo_destroy(cr_ctx);
  cairo_surface_destroy(cr_surface);
}

/* rasterize using libcairo */
/* FIXME: this is stupid.... */
Status Rasterizer::strokePath(
    const PathData* path_data,
    size_t point_count,
    const StrokeStyle& 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_set_line_width(cr_ctx, style.line_width);
  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;
    }
  }

  cairo_stroke(cr_ctx);

  auto cr_bitmap = cairo_image_surface_get_data(cr_surface);
  auto width = pixmap->getWidth();
  auto height = pixmap->getHeight();
  for (uint32_t y = 0; y < height; ++y) {
    for (uint32_t x = 0; x < width; ++x) {
      auto v = 1.0 - (cr_bitmap[y * width + x] / 255.0);

      if (v == 1.0f) {
        continue;
      }

      // FIXME alpha blend instead
      pixmap->setPixel(x, y, Colour::fromRGBA(v, v, v, 1));
    }
  }
}

/* rasterize path using Maxim Shemanarev's libagg */
/*
Status Rasterizer::rasterizePath(
    const PathData* point_data,
    size_t point_count) {
@@ -43,7 +99,7 @@ Status Rasterizer::rasterizePath(

  agg::rasterizer_scanline_aa<> rasterizer;
  rasterizer.reset();
  //rasterizer.filling_rule(agg::fill_even_odd);
  rasterizer.filling_rule(agg::fill_even_odd);
  //rasterizer.gamma(agg::gamma_power(m_gamma.value() * 2.0));

  agg::path_storage agg_path;
@@ -52,26 +108,28 @@ Status Rasterizer::rasterizePath(

    switch (d.command) {
      case PathCommand::MOVE_TO:
        agg_path.move_to(d.coefficients[0], d.coefficients[1]);
        printf("...move %f, %f\n", d.coefficients[0], d.coefficients[1]);
        rasterizer.move_to(d.coefficients[0], d.coefficients[1]);
        break;
      case PathCommand::LINE_TO:
        agg_path.line_to(d.coefficients[0], d.coefficients[1]);
        printf("...lien %f, %f\n", d.coefficients[0], d.coefficients[1]);
        rasterizer.line_to(d.coefficients[0], d.coefficients[1]);
        break;
      case PathCommand::QUADRATIC_CURVE_TO:
        agg_path.curve3(
            d.coefficients[0],
            d.coefficients[1],
            d.coefficients[2],
            d.coefficients[3]);
        //agg_path.curve3(
        //    d.coefficients[0],
        //    d.coefficients[1],
        //    d.coefficients[2],
        //    d.coefficients[3]);
        break;
      case PathCommand::CUBIC_CURVE_TO:
        agg_path.curve4(
            d.coefficients[0],
            d.coefficients[1],
            d.coefficients[2],
            d.coefficients[3],
            d.coefficients[4],
            d.coefficients[5]);
        //agg_path.curve4(
        //    d.coefficients[0],
        //    d.coefficients[1],
        //    d.coefficients[2],
        //    d.coefficients[3],
        //    d.coefficients[4],
        //    d.coefficients[5]);
        break;
      case PathCommand::CLOSE:
        agg_path.close_polygon();
@@ -79,32 +137,37 @@ Status Rasterizer::rasterizePath(
    }
  }

  agg::conv_curve<agg::path_storage> agg_path_polyline(agg_path);
  rasterizer.add_path(agg_path_polyline);
  printf("... %u, %u\n", rasterizer.min_x(), rasterizer.max_x());

  agg::scanline_u8 scanline;
  scanline.reset(rasterizer.min_x(), rasterizer.max_x());
  while (rasterizer.sweep_scanline(scanline)) {
    for (size_t j = 0; j < scanline.num_spans(); ++j) {
      auto span = scanline.begin() + j;
  //agg::conv_curve<agg::path_storage> agg_path_polyline(agg_path);
  //rasterizer.add_path(agg_path_polyline);

      for (size_t i = 0; i < std::abs(span->len); ++i) {
        double v = span->covers[i] / 255.0f;
        uint32_t ox = span->x + i;
        uint32_t oy = scanline.y();
  //agg::scanline_u8 scanline;
  //scanline.reset(rasterizer.min_x(), 200);
  //while (rasterizer.sweep_scanline(scanline)) {
  //  for (size_t j = 0; j < scanline.num_spans(); ++j) {
  //    //auto span = scanline.begin() + j;

        if (ox >= pixmap->getWidth() || oy >= pixmap->getHeight()) {
          continue;
        }
  //    //for (size_t i = 0; i < std::abs(span->len); ++i) {
  //    //  double v = span->covers[i] / 255.0f;
  //    //  uint32_t ox = span->x + i;
  //    //  uint32_t oy = scanline.y();

        // FIXME alpha blend instead
        pixmap->setPixel(ox, oy, Colour::fromRGBA(v, v, v, 1));
      }
    }
  }
  //    //  if (ox >= pixmap->getWidth() || oy >= pixmap->getHeight()) {
  //    //    continue;
  //    //  }

  //    //  printf("setpixel %u %u\n", ox, oy);

  //    //  // FIXME alpha blend instead
  //    //  pixmap->setPixel(ox, oy, Colour::fromRGBA(v, v, v, 1));
  //    //}
  //  }
  //}

  return OK;
}
*/

Status Rasterizer::drawTextGlyphs(
    const FontInfo& font_info,
+6 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <harfbuzz/hb-icu.h>

#include <signaltk/core/text.h>
#include <signaltk/core/brush.h>

namespace signaltk {
class Image;
@@ -37,9 +38,10 @@ public:
  Rasterizer(const Rasterizer&) = delete;
  Rasterizer& operator=(const Rasterizer&) = delete;

  Status rasterizePath(
  Status strokePath(
      const PathData* point_data,
      size_t point_count);
      size_t point_count,
      const StrokeStyle& style);

  Status drawTextGlyphs(
      const FontInfo& font_info,
@@ -50,6 +52,8 @@ public:
  Image* pixmap;
  FT_Library ft;
  bool ft_ready;
  cairo_surface_t* cr_surface;
  cairo_t* cr_ctx;
};