1 /* 2 * Copyright © 2020 Ebrahim Byagowi 3 * 4 * This is part of HarfBuzz, a text shaping library. 5 * 6 * Permission is hereby granted, without written agreement and without 7 * license or royalty fees, to use, copy, modify, and distribute this 8 * software and its documentation for any purpose, provided that the 9 * above copyright notice and the following two paragraphs appear in 10 * all copies of this software. 11 * 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * DAMAGE. 17 * 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 */ 24 25 #ifndef HB_DRAW_HH 26 #define HB_DRAW_HH 27 28 #include "hb.hh" 29 30 #ifdef HB_EXPERIMENTAL_API 31 struct hb_draw_funcs_t 32 { 33 hb_object_header_t header; 34 35 hb_draw_move_to_func_t move_to; 36 hb_draw_line_to_func_t line_to; 37 hb_draw_quadratic_to_func_t quadratic_to; 38 bool is_quadratic_to_set; 39 hb_draw_cubic_to_func_t cubic_to; 40 hb_draw_close_path_func_t close_path; 41 }; 42 43 struct draw_helper_t 44 { draw_helper_tdraw_helper_t45 draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_) 46 { 47 funcs = funcs_; 48 user_data = user_data_; 49 path_open = false; 50 path_start_x = current_x = path_start_y = current_y = 0; 51 } ~draw_helper_tdraw_helper_t52 ~draw_helper_t () { end_path (); } 53 move_todraw_helper_t54 void move_to (hb_position_t x, hb_position_t y) 55 { 56 if (path_open) end_path (); 57 current_x = path_start_x = x; 58 current_y = path_start_y = y; 59 } 60 line_todraw_helper_t61 void line_to (hb_position_t x, hb_position_t y) 62 { 63 if (equal_to_current (x, y)) return; 64 if (!path_open) start_path (); 65 funcs->line_to (x, y, user_data); 66 current_x = x; 67 current_y = y; 68 } 69 70 void quadratic_todraw_helper_t71 quadratic_to (hb_position_t control_x, hb_position_t control_y, 72 hb_position_t to_x, hb_position_t to_y) 73 { 74 if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y)) 75 return; 76 if (!path_open) start_path (); 77 if (funcs->is_quadratic_to_set) 78 funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data); 79 else 80 funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f), 81 roundf ((current_y + 2.f * control_y) / 3.f), 82 roundf ((to_x + 2.f * control_x) / 3.f), 83 roundf ((to_y + 2.f * control_y) / 3.f), 84 to_x, to_y, user_data); 85 current_x = to_x; 86 current_y = to_y; 87 } 88 89 void cubic_todraw_helper_t90 cubic_to (hb_position_t control1_x, hb_position_t control1_y, 91 hb_position_t control2_x, hb_position_t control2_y, 92 hb_position_t to_x, hb_position_t to_y) 93 { 94 if (equal_to_current (control1_x, control1_y) && 95 equal_to_current (control2_x, control2_y) && 96 equal_to_current (to_x, to_y)) 97 return; 98 if (!path_open) start_path (); 99 funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data); 100 current_x = to_x; 101 current_y = to_y; 102 } 103 end_pathdraw_helper_t104 void end_path () 105 { 106 if (path_open) 107 { 108 if ((path_start_x != current_x) || (path_start_y != current_y)) 109 funcs->line_to (path_start_x, path_start_y, user_data); 110 funcs->close_path (user_data); 111 } 112 path_open = false; 113 path_start_x = current_x = path_start_y = current_y = 0; 114 } 115 116 protected: equal_to_currentdraw_helper_t117 bool equal_to_current (hb_position_t x, hb_position_t y) 118 { return current_x == x && current_y == y; } 119 start_pathdraw_helper_t120 void start_path () 121 { 122 if (path_open) end_path (); 123 path_open = true; 124 funcs->move_to (path_start_x, path_start_y, user_data); 125 } 126 127 hb_position_t path_start_x; 128 hb_position_t path_start_y; 129 130 hb_position_t current_x; 131 hb_position_t current_y; 132 133 bool path_open; 134 const hb_draw_funcs_t *funcs; 135 void *user_data; 136 }; 137 #endif 138 139 #endif /* HB_DRAW_HH */ 140