Commit 66855ea3 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

add explicit unit conversion, fix typo in ReturnCode

parent 373b033b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2,8 +2,8 @@ width: 1200px;
height: 480px;

points {
  xs: 60, 200, 14;
  ys: 60px, 200px, 14em;
  xs: 60, 50%, 200;
  ys: 60px, 50%, 14em;
  sizes: 4pt, 20pt;
}

+30 −26
Original line number Diff line number Diff line
@@ -51,9 +51,34 @@ static const double kDefaultPointSizeMaxPT = 24;
static const double kDefaultLabelPaddingEM = 0.4;

ReturnCode draw(
    const PlotPointsConfig& config,
    PlotPointsConfig config,
    const Rectangle& clip,
    Layer* layer) {
  /* convert units */
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_relative, clip.x, clip.x + clip.w, _1)
      },
      &*config.x.begin(),
      &*config.x.end());

  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_relative, clip.y, clip.y + clip.h, _1)
      },
      &*config.y.begin(),
      &*config.y.end());

  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1)
      },
      &*config.sizes.begin(),
      &*config.sizes.end());

  /* draw points */
  for (size_t i = 0; i < config.x.size(); ++i) {
    auto sx = clip.x + config.x[i];
    auto sy = clip.y + config.y[i];
@@ -76,6 +101,7 @@ ReturnCode draw(
    fillPath(layer, clip, path, style);
  }

  /* draw labels */
  for (size_t i = 0; i < config.labels.size(); ++i) {
    const auto& label_text = config.labels[i];

@@ -123,22 +149,12 @@ ReturnCode configure(
  DomainConfig color_domain;
  ColorScheme color_palette;

  //SeriesRef sizes;
  //DomainConfig size_domain;
  std::optional<Measure> size;

  SeriesRef data_x;
  SeriesRef data_y;

  std::vector<Measure> pos_x;
  std::vector<Measure> pos_y;

  ParseToFn<Measure> parse_measure =
      bind(&configure_measure, _1, _2);

  static const ParserDefinitions pdefs = {
    {"xs", configure_vec(parse_measure, &pos_x)},
    {"ys", configure_vec(parse_measure, &pos_y)},
    {"xs", configure_vec(parse_measure, &config->x)},
    {"ys", configure_vec(parse_measure, &config->y)},
    {"sizes", configure_vec(parse_measure, &config->sizes)},
    //{"color", configure_color_opt(&color)},
    //{"colors", configure_series_fn(data, &colors)},
@@ -150,11 +166,7 @@ ReturnCode configure(
  }

  /* check dataset */
  //if (!data_x || !data_y) {
  //  return ReturnCode::error("EARG", "the following properties are required: x, y");
  //}

  if (pos_x.size() != pos_y.size()) {
  if (config->x.size() != config->y.size()) {
    return ReturnCode::error(
        "EARG",
        "the length of the 'x' and 'y' properties must be equal");
@@ -201,14 +213,6 @@ ReturnCode configure(
  //    series_to_colors(colors, color_domain, color_palette),
  //    groups_to_colors(data_x->size(), groups, color_palette));

  for (const auto& v : pos_x) {
    config->x.emplace_back(v);
  }

  for (const auto& v : pos_y) {
    config->y.emplace_back(v);
  }

  config->label_font = doc.font_sans;
  config->label_font_size = doc.font_size;
  if (data_labels) {
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ struct PlotPointsConfig {
};

ReturnCode draw(
    const PlotPointsConfig& config,
    PlotPointsConfig config,
    const Rectangle& clip,
    Layer* layer);

+63 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "measure.h"
#include <assert.h>
#include <iostream>

namespace plotfx {
@@ -68,6 +69,10 @@ Measure from_user(double v) {
  return Measure(Unit::USER, v);
}

Measure from_rel(double v) {
  return Measure(Unit::REL, v);
}

ReturnCode parse_measure(
    const std::string& s,
    Measure* measure) {
@@ -100,7 +105,22 @@ ReturnCode parse_measure(
    return OK;
  }

  return ERROR;
  if (unit == "%") {
    *measure = from_rel(value / 100.0);
    return OK;
  }

  if (unit == "rel") {
    *measure = from_rel(value);
    return OK;
  }

  return {
    ERROR,
    StringUtil::format(
        "invalid unit: '$0', expected one of 'px', 'pt', 'em', 'rem', 'rel' or '%'",
        unit)
  };
}

Measure measure_or(const Measure& primary, const Measure& fallback) {
@@ -111,5 +131,47 @@ Measure measure_or(const Measure& primary, const Measure& fallback) {
  }
}

void convert_units(
    const std::vector<UnitConverter>& converters,
    Measure* begin,
    Measure* end) {
  assert(begin <= end);

  for (auto cur = begin; cur != end; ++cur) {
    for (const auto& c : converters) {
      c(cur);
    }
  }
}

void convert_unit_typographic(
    double dpi,
    double font_size,
    Measure* measure) {
  switch (measure->unit) {
    case Unit::PT:
      measure->value = (measure->value / 72.0) * dpi;
      measure->unit = Unit::UNIT;
      break;
    case Unit::REM:
      measure->value = (measure->value / 72.0) * dpi * font_size;
      measure->unit = Unit::UNIT;
      break;
  }
}

void convert_unit_relative(
    double range_begin,
    double range_end,
    Measure* measure) {
  switch (measure->unit) {
    case Unit::REL:
      measure->unit = Unit::UNIT;
      measure->value =
          range_begin + std::clamp(measure->value, 0.0, 1.0) * (range_end - range_begin);
      break;
  }
}

} // namespace plotfx
+18 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <utils/return_code.h>

namespace plotfx {
struct Rectangle;

enum class Unit {
  UNIT,  // Screen units
@@ -58,6 +59,7 @@ Measure from_pt(double v, double dpi);
Measure from_pt(double v);
Measure from_em(double v, double font_size);
Measure from_em(double v);
Measure from_rel(double v);
Measure from_user(double v);

ReturnCode parse_measure(
@@ -66,6 +68,22 @@ ReturnCode parse_measure(

Measure measure_or(const Measure& primary, const Measure& fallback);

using UnitConverter = std::function<void (Measure*)>;

void convert_units(
    const std::vector<UnitConverter>& converters,
    Measure* begin,
    Measure* end);

void convert_unit_typographic(
    double dpi,
    double font_size_pt,
    Measure* measure);

void convert_unit_relative(
    double range_begin,
    double range_end,
    Measure* measure);

} // namespace plotfx
Loading