Bug Summary

File:jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc
Warning:line 324, column 3
Argument to free() is the address of the global variable '_hb_NullPool', which is not memory allocated by malloc()

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hb-shape-plan.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D GETPAGESIZE -D HAVE_MPROTECT -D HAVE_PTHREAD -D HAVE_SYSCONF -D HAVE_SYS_MMAN_H -D HAVE_UNISTD_H -D HB_NO_PRAGMA_GCC_DIAGNOSTIC -D HAVE_INTEL_ATOMIC_PRIMITIVES -I /usr/include/freetype2 -D LE_STANDALONE -D HEADLESS -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libfontmanager -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libfontmanager -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.desktop -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/awt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/font -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/font -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/pipe -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/loops -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-unused -Wno-type-limits -Wno-missing-field-initializers -Wno-strict-aliasing -Wno-reorder -Wno-delete-non-virtual-dtor -Wno-strict-overflow -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-unused-result -Wno-extra -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc
1/*
2 * Copyright © 2012 Google, Inc.
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 * Google Author(s): Behdad Esfahbod
25 */
26
27#include "hb.hh"
28#include "hb-shape-plan.hh"
29#include "hb-shaper.hh"
30#include "hb-font.hh"
31#include "hb-buffer.hh"
32
33
34/**
35 * SECTION:hb-shape-plan
36 * @title: hb-shape-plan
37 * @short_description: Object representing a shaping plan
38 * @include: hb.h
39 *
40 * Shape plans are an internal mechanism. Each plan contains state
41 * describing how HarfBuzz will shape a particular text segment, based on
42 * the combination of segment properties and the capabilities in the
43 * font face in use.
44 *
45 * Shape plans are not used for shaping directly, but can be queried to
46 * access certain information about how shaping will perform, given a set
47 * of specific input parameters (script, language, direction, features,
48 * etc.).
49 *
50 * Most client programs will not need to deal with shape plans directly.
51 **/
52
53
54/*
55 * hb_shape_plan_key_t
56 */
57
58bool
59hb_shape_plan_key_t::init (bool copy,
60 hb_face_t *face,
61 const hb_segment_properties_t *props,
62 const hb_feature_t *user_features,
63 unsigned int num_user_features,
64 const int *coords,
65 unsigned int num_coords,
66 const char * const *shaper_list)
67{
68 hb_feature_t *features = nullptr;
69 if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
70 goto bail;
71
72 this->props = *props;
73 this->num_user_features = num_user_features;
74 this->user_features = copy ? features : user_features;
75 if (copy && num_user_features)
76 {
77 memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
78 /* Make start/end uniform to easier catch bugs. */
79 for (unsigned int i = 0; i < num_user_features; i++)
80 {
81 if (features[0].start != HB_FEATURE_GLOBAL_START0)
82 features[0].start = 1;
83 if (features[0].end != HB_FEATURE_GLOBAL_END((unsigned int) -1))
84 features[0].end = 2;
85 }
86 }
87 this->shaper_func = nullptr;
88 this->shaper_name = nullptr;
89#ifndef HB_NO_OT_SHAPE
90 this->ot.init (face, coords, num_coords);
91#endif
92
93 /*
94 * Choose shaper.
95 */
96
97#define HB_SHAPER_PLAN(shaper) \
98 HB_STMT_STARTdo { \
99 if (face->data.shaper) \
100 { \
101 this->shaper_func = _hb_##shaper##_shape; \
102 this->shaper_name = #shaper; \
103 return true; \
104 } \
105 } HB_STMT_ENDwhile (0)
106
107 if (unlikely (shaper_list)(__builtin_expect (!!(shaper_list), 0)))
108 {
109 for (; *shaper_list; shaper_list++)
110 if (false)
111 ;
112#define HB_SHAPER_IMPLEMENT(shaper) \
113 else if (0 == strcmp (*shaper_list, #shaper)) \
114 HB_SHAPER_PLAN (shaper);
115#include "hb-shaper-list.hh"
116#undef HB_SHAPER_IMPLEMENT
117 }
118 else
119 {
120 const hb_shaper_entry_t *shapers = _hb_shapers_get ();
121 for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
122 if (false)
123 ;
124#define HB_SHAPER_IMPLEMENT(shaper) \
125 else if (shapers[i].func == _hb_##shaper##_shape) \
126 HB_SHAPER_PLAN (shaper);
127#include "hb-shaper-list.hh"
128#undef HB_SHAPER_IMPLEMENT
129 }
130#undef HB_SHAPER_PLAN
131
132bail:
133 ::free (features);
134 return false;
135}
136
137bool
138hb_shape_plan_key_t::user_features_match (const hb_shape_plan_key_t *other)
139{
140 if (this->num_user_features != other->num_user_features)
141 return false;
142 for (unsigned int i = 0; i < num_user_features; i++)
143 {
144 if (this->user_features[i].tag != other->user_features[i].tag ||
145 this->user_features[i].value != other->user_features[i].value ||
146 (this->user_features[i].start == HB_FEATURE_GLOBAL_START0 &&
147 this->user_features[i].end == HB_FEATURE_GLOBAL_END((unsigned int) -1)) !=
148 (other->user_features[i].start == HB_FEATURE_GLOBAL_START0 &&
149 other->user_features[i].end == HB_FEATURE_GLOBAL_END((unsigned int) -1)))
150 return false;
151 }
152 return true;
153}
154
155bool
156hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
157{
158 return hb_segment_properties_equal (&this->props, &other->props) &&
159 this->user_features_match (other) &&
160#ifndef HB_NO_OT_SHAPE
161 this->ot.equal (&other->ot) &&
162#endif
163 this->shaper_func == other->shaper_func;
164}
165
166
167/*
168 * hb_shape_plan_t
169 */
170
171
172/**
173 * hb_shape_plan_create: (Xconstructor)
174 * @face: #hb_face_t to use
175 * @props: The #hb_segment_properties_t of the segment
176 * @user_features: (array length=num_user_features): The list of user-selected features
177 * @num_user_features: The number of user-selected features
178 * @shaper_list: (array zero-terminated=1): List of shapers to try
179 *
180 * Constructs a shaping plan for a combination of @face, @user_features, @props,
181 * and @shaper_list.
182 *
183 * Return value: (transfer full): The shaping plan
184 *
185 * Since: 0.9.7
186 **/
187hb_shape_plan_t *
188hb_shape_plan_create (hb_face_t *face,
189 const hb_segment_properties_t *props,
190 const hb_feature_t *user_features,
191 unsigned int num_user_features,
192 const char * const *shaper_list)
193{
194 return hb_shape_plan_create2 (face, props,
195 user_features, num_user_features,
196 nullptr, 0,
197 shaper_list);
198}
199
200/**
201 * hb_shape_plan_create2: (Xconstructor)
202 * @face: #hb_face_t to use
203 * @props: The #hb_segment_properties_t of the segment
204 * @user_features: (array length=num_user_features): The list of user-selected features
205 * @num_user_features: The number of user-selected features
206 * @coords: (array length=num_coords): The list of variation-space coordinates
207 * @num_coords: The number of variation-space coordinates
208 * @shaper_list: (array zero-terminated=1): List of shapers to try
209 *
210 * The variable-font version of #hb_shape_plan_create.
211 * Constructs a shaping plan for a combination of @face, @user_features, @props,
212 * and @shaper_list, plus the variation-space coordinates @coords.
213 *
214 * Return value: (transfer full): The shaping plan
215 *
216 * Since: 1.4.0
217 **/
218hb_shape_plan_t *
219hb_shape_plan_create2 (hb_face_t *face,
220 const hb_segment_properties_t *props,
221 const hb_feature_t *user_features,
222 unsigned int num_user_features,
223 const int *coords,
224 unsigned int num_coords,
225 const char * const *shaper_list)
226{
227 DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
228 "face=%p num_features=%d num_coords=%d shaper_list=%p",_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
229 face,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
230 num_user_features,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
231 num_coords,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
232 shaper_list)_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d num_coords=%d shaper_list=%p"
, face, num_user_features, num_coords, shaper_list)
;
233
234 assert (props->direction != HB_DIRECTION_INVALID)(static_cast <bool> (props->direction != HB_DIRECTION_INVALID
) ? void (0) : __assert_fail ("props->direction != HB_DIRECTION_INVALID"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc"
, 234, __extension__ __PRETTY_FUNCTION__))
;
235
236 hb_shape_plan_t *shape_plan;
237
238 if (unlikely (!props)(__builtin_expect (!!(!props), 0)))
239 goto bail;
240 if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
241 goto bail;
242
243 if (unlikely (!face)(__builtin_expect (!!(!face), 0)))
244 face = hb_face_get_empty ();
245 hb_face_make_immutable (face);
246 shape_plan->face_unsafe = face;
247
248 if (unlikely (!shape_plan->key.init (true,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
249 face,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
250 props,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
251 user_features,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
252 num_user_features,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
253 coords,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
254 num_coords,(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
255 shaper_list))(__builtin_expect (!!(!shape_plan->key.init (true, face, props
, user_features, num_user_features, coords, num_coords, shaper_list
)), 0))
)
256 goto bail2;
257#ifndef HB_NO_OT_SHAPE
258 if (unlikely (!shape_plan->ot.init0 (face, &shape_plan->key))(__builtin_expect (!!(!shape_plan->ot.init0 (face, &shape_plan
->key)), 0))
)
259 goto bail3;
260#endif
261
262 return shape_plan;
263
264#ifndef HB_NO_OT_SHAPE
265bail3:
266#endif
267 shape_plan->key.free ();
268bail2:
269 free (shape_plan);
270bail:
271 return hb_shape_plan_get_empty ();
272}
273
274/**
275 * hb_shape_plan_get_empty:
276 *
277 * Fetches the singleton empty shaping plan.
278 *
279 * Return value: (transfer full): The empty shaping plan
280 *
281 * Since: 0.9.7
282 **/
283hb_shape_plan_t *
284hb_shape_plan_get_empty ()
285{
286 return const_cast<hb_shape_plan_t *> (&Null (hb_shape_plan_t)NullHelper<hb_shape_plan_t>::get_null ());
287}
288
289/**
290 * hb_shape_plan_reference: (skip)
291 * @shape_plan: A shaping plan
292 *
293 * Increases the reference count on the given shaping plan.
294 *
295 * Return value: (transfer full): @shape_plan
296 *
297 * Since: 0.9.7
298 **/
299hb_shape_plan_t *
300hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
301{
302 return hb_object_reference (shape_plan);
303}
304
305/**
306 * hb_shape_plan_destroy: (skip)
307 * @shape_plan: A shaping plan
308 *
309 * Decreases the reference count on the given shaping plan. When the
310 * reference count reaches zero, the shaping plan is destroyed,
311 * freeing all memory.
312 *
313 * Since: 0.9.7
314 **/
315void
316hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
317{
318 if (!hb_object_destroy (shape_plan)) return;
12
Taking false branch
319
320#ifndef HB_NO_OT_SHAPE
321 shape_plan->ot.fini ();
322#endif
323 shape_plan->key.free ();
324 free (shape_plan);
13
Argument to free() is the address of the global variable '_hb_NullPool', which is not memory allocated by malloc()
325}
326
327/**
328 * hb_shape_plan_set_user_data: (skip)
329 * @shape_plan: A shaping plan
330 * @key: The user-data key to set
331 * @data: A pointer to the user data
332 * @destroy: (nullable): A callback to call when @data is not needed anymore
333 * @replace: Whether to replace an existing data with the same key
334 *
335 * Attaches a user-data key/data pair to the given shaping plan.
336 *
337 * Return value: %true if success, %false otherwise.
338 *
339 * Since: 0.9.7
340 **/
341hb_bool_t
342hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
343 hb_user_data_key_t *key,
344 void * data,
345 hb_destroy_func_t destroy,
346 hb_bool_t replace)
347{
348 return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
349}
350
351/**
352 * hb_shape_plan_get_user_data: (skip)
353 * @shape_plan: A shaping plan
354 * @key: The user-data key to query
355 *
356 * Fetches the user data associated with the specified key,
357 * attached to the specified shaping plan.
358 *
359 * Return value: (transfer none): A pointer to the user data
360 *
361 * Since: 0.9.7
362 **/
363void *
364hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
365 hb_user_data_key_t *key)
366{
367 return hb_object_get_user_data (shape_plan, key);
368}
369
370/**
371 * hb_shape_plan_get_shaper:
372 * @shape_plan: A shaping plan
373 *
374 * Fetches the shaper from a given shaping plan.
375 *
376 * Return value: (transfer none): The shaper
377 *
378 * Since: 0.9.7
379 **/
380const char *
381hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
382{
383 return shape_plan->key.shaper_name;
384}
385
386
387static bool
388_hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
389 hb_font_t *font,
390 hb_buffer_t *buffer,
391 const hb_feature_t *features,
392 unsigned int num_features)
393{
394 DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "num_features=%d shaper_func=%p, shaper_name=%s"
, num_features, shape_plan->key.shaper_func, shape_plan->
key.shaper_name)
395 "num_features=%d shaper_func=%p, shaper_name=%s",_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "num_features=%d shaper_func=%p, shaper_name=%s"
, num_features, shape_plan->key.shaper_func, shape_plan->
key.shaper_name)
396 num_features,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "num_features=%d shaper_func=%p, shaper_name=%s"
, num_features, shape_plan->key.shaper_func, shape_plan->
key.shaper_name)
397 shape_plan->key.shaper_func,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "num_features=%d shaper_func=%p, shaper_name=%s"
, num_features, shape_plan->key.shaper_func, shape_plan->
key.shaper_name)
398 shape_plan->key.shaper_name)_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "num_features=%d shaper_func=%p, shaper_name=%s"
, num_features, shape_plan->key.shaper_func, shape_plan->
key.shaper_name)
;
399
400 if (unlikely (!buffer->len)(__builtin_expect (!!(!buffer->len), 0)))
401 return true;
402
403 assert (!hb_object_is_immutable (buffer))(static_cast <bool> (!hb_object_is_immutable (buffer)) ?
void (0) : __assert_fail ("!hb_object_is_immutable (buffer)"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc"
, 403, __extension__ __PRETTY_FUNCTION__))
;
404
405 buffer->assert_unicode ();
406
407 if (unlikely (hb_object_is_inert (shape_plan))(__builtin_expect (!!(hb_object_is_inert (shape_plan)), 0)))
408 return false;
409
410 assert (shape_plan->face_unsafe == font->face)(static_cast <bool> (shape_plan->face_unsafe == font
->face) ? void (0) : __assert_fail ("shape_plan->face_unsafe == font->face"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc"
, 410, __extension__ __PRETTY_FUNCTION__))
;
411 assert (hb_segment_properties_equal (&shape_plan->key.props, &buffer->props))(static_cast <bool> (hb_segment_properties_equal (&
shape_plan->key.props, &buffer->props)) ? void (0) :
__assert_fail ("hb_segment_properties_equal (&shape_plan->key.props, &buffer->props)"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc"
, 411, __extension__ __PRETTY_FUNCTION__))
;
412
413#define HB_SHAPER_EXECUTE(shaper) \
414 HB_STMT_STARTdo { \
415 return font->data.shaper && \
416 _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
417 } HB_STMT_ENDwhile (0)
418
419 if (false)
420 ;
421#define HB_SHAPER_IMPLEMENT(shaper) \
422 else if (shape_plan->key.shaper_func == _hb_##shaper##_shape) \
423 HB_SHAPER_EXECUTE (shaper);
424#include "hb-shaper-list.hh"
425#undef HB_SHAPER_IMPLEMENT
426
427#undef HB_SHAPER_EXECUTE
428
429 return false;
430}
431/**
432 * hb_shape_plan_execute:
433 * @shape_plan: A shaping plan
434 * @font: The #hb_font_t to use
435 * @buffer: The #hb_buffer_t to work upon
436 * @features: (array length=num_features): Features to enable
437 * @num_features: The number of features to enable
438 *
439 * Executes the given shaping plan on the specified buffer, using
440 * the given @font and @features.
441 *
442 * Return value: %true if success, %false otherwise.
443 *
444 * Since: 0.9.7
445 **/
446hb_bool_t
447hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
448 hb_font_t *font,
449 hb_buffer_t *buffer,
450 const hb_feature_t *features,
451 unsigned int num_features)
452{
453 bool ret = _hb_shape_plan_execute_internal (shape_plan, font, buffer,
454 features, num_features);
455
456 if (ret && buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
457 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
458
459 return ret;
460}
461
462
463/*
464 * Caching
465 */
466
467/**
468 * hb_shape_plan_create_cached:
469 * @face: #hb_face_t to use
470 * @props: The #hb_segment_properties_t of the segment
471 * @user_features: (array length=num_user_features): The list of user-selected features
472 * @num_user_features: The number of user-selected features
473 * @shaper_list: (array zero-terminated=1): List of shapers to try
474 *
475 * Creates a cached shaping plan suitable for reuse, for a combination
476 * of @face, @user_features, @props, and @shaper_list.
477 *
478 * Return value: (transfer full): The shaping plan
479 *
480 * Since: 0.9.7
481 **/
482hb_shape_plan_t *
483hb_shape_plan_create_cached (hb_face_t *face,
484 const hb_segment_properties_t *props,
485 const hb_feature_t *user_features,
486 unsigned int num_user_features,
487 const char * const *shaper_list)
488{
489 return hb_shape_plan_create_cached2 (face, props,
1
Calling 'hb_shape_plan_create_cached2'
490 user_features, num_user_features,
491 nullptr, 0,
492 shaper_list);
493}
494
495/**
496 * hb_shape_plan_create_cached2:
497 * @face: #hb_face_t to use
498 * @props: The #hb_segment_properties_t of the segment
499 * @user_features: (array length=num_user_features): The list of user-selected features
500 * @num_user_features: The number of user-selected features
501 * @coords: (array length=num_coords): The list of variation-space coordinates
502 * @num_coords: The number of variation-space coordinates
503 * @shaper_list: (array zero-terminated=1): List of shapers to try
504 *
505 * The variable-font version of #hb_shape_plan_create_cached.
506 * Creates a cached shaping plan suitable for reuse, for a combination
507 * of @face, @user_features, @props, and @shaper_list, plus the
508 * variation-space coordinates @coords.
509 *
510 * Return value: (transfer full): The shaping plan
511 *
512 * Since: 1.4.0
513 **/
514hb_shape_plan_t *
515hb_shape_plan_create_cached2 (hb_face_t *face,
516 const hb_segment_properties_t *props,
517 const hb_feature_t *user_features,
518 unsigned int num_user_features,
519 const int *coords,
520 unsigned int num_coords,
521 const char * const *shaper_list)
522{
523 DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d shaper_list=%p", face
, num_user_features, shaper_list)
524 "face=%p num_features=%d shaper_list=%p",_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d shaper_list=%p", face
, num_user_features, shaper_list)
525 face,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d shaper_list=%p", face
, num_user_features, shaper_list)
526 num_user_features,_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d shaper_list=%p", face
, num_user_features, shaper_list)
527 shaper_list)_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (nullptr), __PRETTY_FUNCTION__
, false, 0, 0, "face=%p num_features=%d shaper_list=%p", face
, num_user_features, shaper_list)
;
528
529retry:
530 hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans;
531
532 bool dont_cache = hb_object_is_inert (face);
533
534 if (likely (!dont_cache)(__builtin_expect (!!(!dont_cache), 1)))
2
Assuming 'dont_cache' is false
3
Taking true branch
535 {
536 hb_shape_plan_key_t key;
537 if (!key.init (false,
4
Taking false branch
538 face,
539 props,
540 user_features,
541 num_user_features,
542 coords,
543 num_coords,
544 shaper_list))
545 return hb_shape_plan_get_empty ();
546
547 for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
5
Loop condition is false. Execution continues on line 555
548 if (node->shape_plan->key.equal (&key))
549 {
550 DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache")_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (node->shape_plan
), __PRETTY_FUNCTION__, false, 0, 0, "fulfilled from cache")
;
551 return hb_shape_plan_reference (node->shape_plan);
552 }
553 }
554
555 hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
556 user_features, num_user_features,
557 coords, num_coords,
558 shaper_list);
559
560 if (unlikely (dont_cache)(__builtin_expect (!!(dont_cache), 0)))
6
Taking false branch
561 return shape_plan;
562
563 hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
564 if (unlikely (!node)(__builtin_expect (!!(!node), 0)))
7
Assuming 'node' is non-null
8
Taking false branch
565 return shape_plan;
566
567 node->shape_plan = shape_plan;
568 node->next = cached_plan_nodes;
569
570 if (unlikely (!face->shape_plans.cmpexch (cached_plan_nodes, node))(__builtin_expect (!!(!face->shape_plans.cmpexch (cached_plan_nodes
, node)), 0))
)
9
Assuming the condition is true
10
Taking true branch
571 {
572 hb_shape_plan_destroy (shape_plan);
11
Calling 'hb_shape_plan_destroy'
573 free (node);
574 goto retry;
575 }
576 DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "inserted into cache")_hb_debug_msg<(0 +0)> ("SHAPE_PLAN", (shape_plan), __PRETTY_FUNCTION__
, false, 0, 0, "inserted into cache")
;
577
578 return hb_shape_plan_reference (shape_plan);
579}