Coverage Report

Created: 2025-07-01 07:03

/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
440k
  { func.move_to (this, draw_data, &st,
68
440k
      to_x, to_y,
69
440k
      !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
11.9M
  { func.line_to (this, draw_data, &st,
73
11.9M
      to_x, to_y,
74
11.9M
      !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
1.92M
  { func.quadratic_to (this, draw_data, &st,
79
1.92M
           control_x, control_y,
80
1.92M
           to_x, to_y,
81
1.92M
           !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
2.66M
  { func.cubic_to (this, draw_data, &st,
87
2.66M
       control1_x, control1_y,
88
2.66M
       control2_x, control2_y,
89
2.66M
       to_x, to_y,
90
2.66M
       !user_data ? nullptr : user_data->cubic_to); }
91
  void emit_close_path (void *draw_data, hb_draw_state_t &st)
92
440k
  { func.close_path (this, draw_data, &st,
93
440k
         !user_data ? nullptr : user_data->close_path); }
94
95
96
  void
97
  HB_ALWAYS_INLINE
98
  move_to (void *draw_data, hb_draw_state_t &st,
99
     float to_x, float to_y)
100
452k
  {
101
452k
    if (unlikely (st.path_open)) close_path (draw_data, st);
102
103
452k
    st.current_x = to_x;
104
452k
    st.current_y = to_y;
105
452k
  }
106
107
  void
108
  HB_ALWAYS_INLINE
109
  line_to (void *draw_data, hb_draw_state_t &st,
110
     float to_x, float to_y)
111
11.9M
  {
112
11.9M
    if (unlikely (!st.path_open)) start_path (draw_data, st);
113
114
11.9M
    emit_line_to (draw_data, st, to_x, to_y);
115
116
11.9M
    st.current_x = to_x;
117
11.9M
    st.current_y = to_y;
118
11.9M
  }
119
120
  void
121
  HB_ALWAYS_INLINE
122
  quadratic_to (void *draw_data, hb_draw_state_t &st,
123
    float control_x, float control_y,
124
    float to_x, float to_y)
125
1.92M
  {
126
1.92M
    if (unlikely (!st.path_open)) start_path (draw_data, st);
127
128
1.92M
    emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
129
130
1.92M
    st.current_x = to_x;
131
1.92M
    st.current_y = to_y;
132
1.92M
  }
133
134
  void
135
  HB_ALWAYS_INLINE
136
  cubic_to (void *draw_data, hb_draw_state_t &st,
137
      float control1_x, float control1_y,
138
      float control2_x, float control2_y,
139
      float to_x, float to_y)
140
2.54M
  {
141
2.54M
    if (unlikely (!st.path_open)) start_path (draw_data, st);
142
143
2.54M
    emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
144
145
2.54M
    st.current_x = to_x;
146
2.54M
    st.current_y = to_y;
147
2.54M
  }
148
149
  void
150
  HB_ALWAYS_INLINE
151
  close_path (void *draw_data, hb_draw_state_t &st)
152
6.14M
  {
153
6.14M
    if (likely (st.path_open))
154
440k
    {
155
440k
      if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
156
64.9k
  emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
157
440k
      emit_close_path (draw_data, st);
158
440k
    }
159
6.14M
    st.path_open = false;
160
6.14M
    st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
161
6.14M
  }
162
163
  protected:
164
165
  void start_path (void *draw_data, hb_draw_state_t &st)
166
440k
  {
167
440k
    assert (!st.path_open);
168
440k
    emit_move_to (draw_data, st, st.current_x, st.current_y);
169
440k
    st.path_open = true;
170
440k
    st.path_start_x = st.current_x;
171
440k
    st.path_start_y = st.current_y;
172
440k
  }
173
};
174
DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
175
176
struct hb_draw_session_t
177
{
178
  hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_)
179
5.71M
    : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
180
5.71M
  {}
181
182
5.71M
  ~hb_draw_session_t () { close_path (); }
183
184
  HB_ALWAYS_INLINE
185
  void move_to (float to_x, float to_y)
186
363k
  {
187
363k
    funcs->move_to (draw_data, st,
188
363k
        to_x, to_y);
189
363k
  }
190
  HB_ALWAYS_INLINE
191
  void line_to (float to_x, float to_y)
192
11.7M
  {
193
11.7M
    funcs->line_to (draw_data, st,
194
11.7M
        to_x, to_y);
195
11.7M
  }
196
  void
197
  HB_ALWAYS_INLINE
198
  quadratic_to (float control_x, float control_y,
199
    float to_x, float to_y)
200
1.60M
  {
201
1.60M
    funcs->quadratic_to (draw_data, st,
202
1.60M
       control_x, control_y,
203
1.60M
       to_x, to_y);
204
1.60M
  }
205
  void
206
  HB_ALWAYS_INLINE
207
  cubic_to (float control1_x, float control1_y,
208
      float control2_x, float control2_y,
209
      float to_x, float to_y)
210
2.49M
  {
211
2.49M
    funcs->cubic_to (draw_data, st,
212
2.49M
         control1_x, control1_y,
213
2.49M
         control2_x, control2_y,
214
2.49M
         to_x, to_y);
215
2.49M
  }
216
  HB_ALWAYS_INLINE
217
  void close_path ()
218
6.00M
  {
219
6.00M
    funcs->close_path (draw_data, st);
220
6.00M
  }
221
222
  public:
223
  hb_draw_funcs_t *funcs;
224
  void *draw_data;
225
  hb_draw_state_t st;
226
};
227
228
229
HB_INTERNAL hb_draw_funcs_t *
230
hb_draw_extents_get_funcs ();
231
232
233
#endif /* HB_DRAW_HH */