| /* |
| * 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 */ |