Coverage Report

Created: 2024-08-17 06:40

/src/harfbuzz/src/hb-draw.hh
Line
Count
Source (jump to first uncovered line)
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
31
/*
32
 * hb_draw_funcs_t
33
 */
34
35
#define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \
36
0
  HB_DRAW_FUNC_IMPLEMENT (move_to) \
37
0
  HB_DRAW_FUNC_IMPLEMENT (line_to) \
38
0
  HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
39
0
  HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
40
0
  HB_DRAW_FUNC_IMPLEMENT (close_path) \
41
  /* ^--- Add new callbacks here */
42
43
struct hb_draw_funcs_t
44
{
45
  hb_object_header_t header;
46
47
  struct {
48
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name;
49
    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
50
#undef HB_DRAW_FUNC_IMPLEMENT
51
  } func;
52
53
  struct {
54
#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
55
    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
56
#undef HB_DRAW_FUNC_IMPLEMENT
57
  } *user_data;
58
59
  struct {
60
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
61
    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
62
#undef HB_DRAW_FUNC_IMPLEMENT
63
  } *destroy;
64
65
  void emit_move_to (void *draw_data, hb_draw_state_t &st,
66
         float to_x, float to_y)
67
21.7k
  { func.move_to (this, draw_data, &st,
68
21.7k
      to_x, to_y,
69
21.7k
      !user_data ? nullptr : user_data->move_to); }
70
  void emit_line_to (void *draw_data, hb_draw_state_t &st,
71
         float to_x, float to_y)
72
109k
  { func.line_to (this, draw_data, &st,
73
109k
      to_x, to_y,
74
109k
      !user_data ? nullptr : user_data->line_to); }
75
  void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
76
        float control_x, float control_y,
77
        float to_x, float to_y)
78
90.9k
  { func.quadratic_to (this, draw_data, &st,
79
90.9k
           control_x, control_y,
80
90.9k
           to_x, to_y,
81
90.9k
           !user_data ? nullptr : user_data->quadratic_to); }
82
  void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
83
          float control1_x, float control1_y,
84
          float control2_x, float control2_y,
85
          float to_x, float to_y)
86
99.1k
  { func.cubic_to (this, draw_data, &st,
87
99.1k
       control1_x, control1_y,
88
99.1k
       control2_x, control2_y,
89
99.1k
       to_x, to_y,
90
99.1k
       !user_data ? nullptr : user_data->cubic_to); }
91
  void emit_close_path (void *draw_data, hb_draw_state_t &st)
92
21.7k
  { func.close_path (this, draw_data, &st,
93
21.7k
         !user_data ? nullptr : user_data->close_path); }
94
95
96
  void move_to (void *draw_data, hb_draw_state_t &st,
97
    float to_x, float to_y)
98
23.0k
  {
99
23.0k
    if (st.path_open) close_path (draw_data, st);
100
23.0k
    st.current_x = to_x;
101
23.0k
    st.current_y = to_y;
102
23.0k
  }
103
104
  void line_to (void *draw_data, hb_draw_state_t &st,
105
    float to_x, float to_y)
106
105k
  {
107
105k
    if (!st.path_open) start_path (draw_data, st);
108
105k
    emit_line_to (draw_data, st, to_x, to_y);
109
105k
    st.current_x = to_x;
110
105k
    st.current_y = to_y;
111
105k
  }
112
113
  void
114
  quadratic_to (void *draw_data, hb_draw_state_t &st,
115
    float control_x, float control_y,
116
    float to_x, float to_y)
117
90.9k
  {
118
90.9k
    if (!st.path_open) start_path (draw_data, st);
119
90.9k
    emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
120
90.9k
    st.current_x = to_x;
121
90.9k
    st.current_y = to_y;
122
90.9k
  }
123
124
  void
125
  cubic_to (void *draw_data, hb_draw_state_t &st,
126
      float control1_x, float control1_y,
127
      float control2_x, float control2_y,
128
      float to_x, float to_y)
129
8.50k
  {
130
8.50k
    if (!st.path_open) start_path (draw_data, st);
131
8.50k
    emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
132
8.50k
    st.current_x = to_x;
133
8.50k
    st.current_y = to_y;
134
8.50k
  }
135
136
  void
137
  close_path (void *draw_data, hb_draw_state_t &st)
138
56.4k
  {
139
56.4k
    if (st.path_open)
140
21.7k
    {
141
21.7k
      if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
142
3.81k
  emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
143
21.7k
      emit_close_path (draw_data, st);
144
21.7k
    }
145
56.4k
    st.path_open = false;
146
56.4k
    st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
147
56.4k
  }
148
149
  protected:
150
151
  void start_path (void *draw_data, hb_draw_state_t &st)
152
21.7k
  {
153
21.7k
    assert (!st.path_open);
154
0
    emit_move_to (draw_data, st, st.current_x, st.current_y);
155
21.7k
    st.path_open = true;
156
21.7k
    st.path_start_x = st.current_x;
157
21.7k
    st.path_start_y = st.current_y;
158
21.7k
  }
159
};
160
DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
161
162
struct hb_draw_session_t
163
{
164
  hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f)
165
    : slant {slant_}, not_slanted {slant == 0.f},
166
      funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
167
35.3k
  {}
168
169
35.3k
  ~hb_draw_session_t () { close_path (); }
170
171
  void move_to (float to_x, float to_y)
172
23.0k
  {
173
23.0k
    if (likely (not_slanted))
174
23.0k
      funcs->move_to (draw_data, st,
175
23.0k
          to_x, to_y);
176
0
    else
177
0
      funcs->move_to (draw_data, st,
178
0
          to_x + to_y * slant, to_y);
179
23.0k
  }
180
  void line_to (float to_x, float to_y)
181
105k
  {
182
105k
    if (likely (not_slanted))
183
105k
      funcs->line_to (draw_data, st,
184
105k
          to_x, to_y);
185
0
    else
186
0
      funcs->line_to (draw_data, st,
187
0
          to_x + to_y * slant, to_y);
188
105k
  }
189
  void
190
  quadratic_to (float control_x, float control_y,
191
    float to_x, float to_y)
192
90.9k
  {
193
90.9k
    if (likely (not_slanted))
194
90.9k
      funcs->quadratic_to (draw_data, st,
195
90.9k
         control_x, control_y,
196
90.9k
         to_x, to_y);
197
0
    else
198
0
      funcs->quadratic_to (draw_data, st,
199
0
         control_x + control_y * slant, control_y,
200
0
         to_x + to_y * slant, to_y);
201
90.9k
  }
202
  void
203
  cubic_to (float control1_x, float control1_y,
204
      float control2_x, float control2_y,
205
      float to_x, float to_y)
206
8.50k
  {
207
8.50k
    if (likely (not_slanted))
208
8.50k
      funcs->cubic_to (draw_data, st,
209
8.50k
           control1_x, control1_y,
210
8.50k
           control2_x, control2_y,
211
8.50k
           to_x, to_y);
212
0
    else
213
0
      funcs->cubic_to (draw_data, st,
214
0
           control1_x + control1_y * slant, control1_y,
215
0
           control2_x + control2_y * slant, control2_y,
216
0
           to_x + to_y * slant, to_y);
217
8.50k
  }
218
  void close_path ()
219
53.2k
  {
220
53.2k
    funcs->close_path (draw_data, st);
221
53.2k
  }
222
223
  protected:
224
  float slant;
225
  bool not_slanted;
226
  hb_draw_funcs_t *funcs;
227
  void *draw_data;
228
  hb_draw_state_t st;
229
};
230
231
#endif /* HB_DRAW_HH */