/*
 * Copyright © 2020  Ebrahim Byagowi
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

#ifndef HB_DRAW_HH
#define HB_DRAW_HH

#include "hb.hh"

#ifdef HB_EXPERIMENTAL_API
struct hb_draw_funcs_t
{
  hb_object_header_t header;

  hb_draw_move_to_func_t move_to;
  hb_draw_line_to_func_t line_to;
  hb_draw_quadratic_to_func_t quadratic_to;
  bool is_quadratic_to_set;
  hb_draw_cubic_to_func_t cubic_to;
  hb_draw_close_path_func_t close_path;
};

struct draw_helper_t
{
  draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_)
  {
    funcs = funcs_;
    user_data = user_data_;
    path_open = false;
    path_start_x = current_x = path_start_y = current_y = 0;
  }
  ~draw_helper_t () { end_path (); }

  void move_to (hb_position_t x, hb_position_t y)
  {
    if (path_open) end_path ();
    current_x = path_start_x = x;
    current_y = path_start_y = y;
  }

  void line_to (hb_position_t x, hb_position_t y)
  {
    if (equal_to_current (x, y)) return;
    if (!path_open) start_path ();
    funcs->line_to (x, y, user_data);
    current_x = x;
    current_y = y;
  }

  void
  quadratic_to (hb_position_t control_x, hb_position_t control_y,
		hb_position_t to_x, hb_position_t to_y)
  {
    if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y))
      return;
    if (!path_open) start_path ();
    if (funcs->is_quadratic_to_set)
      funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
    else
      funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f),
		       roundf ((current_y + 2.f * control_y) / 3.f),
		       roundf ((to_x + 2.f * control_x) / 3.f),
		       roundf ((to_y + 2.f * control_y) / 3.f),
		       to_x, to_y, user_data);
    current_x = to_x;
    current_y = to_y;
  }

  void
  cubic_to (hb_position_t control1_x, hb_position_t control1_y,
	    hb_position_t control2_x, hb_position_t control2_y,
	    hb_position_t to_x, hb_position_t to_y)
  {
    if (equal_to_current (control1_x, control1_y) &&
        equal_to_current (control2_x, control2_y) &&
	equal_to_current (to_x, to_y))
      return;
    if (!path_open) start_path ();
    funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data);
    current_x = to_x;
    current_y = to_y;
  }

  void end_path ()
  {
    if (path_open)
    {
      if ((path_start_x != current_x) || (path_start_y != current_y))
	funcs->line_to (path_start_x, path_start_y, user_data);
      funcs->close_path (user_data);
    }
    path_open = false;
    path_start_x = current_x = path_start_y = current_y = 0;
  }

  protected:
  bool equal_to_current (hb_position_t x, hb_position_t y)
  { return current_x == x && current_y == y; }

  void start_path ()
  {
    if (path_open) end_path ();
    path_open = true;
    funcs->move_to (path_start_x, path_start_y, user_data);
  }

  hb_position_t path_start_x;
  hb_position_t path_start_y;

  hb_position_t current_x;
  hb_position_t current_y;

  bool path_open;
  const hb_draw_funcs_t *funcs;
  void *user_data;
};
#endif

#endif /* HB_DRAW_HH */
