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#ifndef HB_SHAPER_HH
28#define HB_SHAPER_HH
29
30#include "hb.hh"
31#include "hb-machinery.hh"
32
33typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
34 hb_font_t *font,
35 hb_buffer_t *buffer,
36 const hb_feature_t *features,
37 unsigned int num_features);
38
39#define HB_SHAPER_IMPLEMENT(name) \
40 extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
41#include "hb-shaper-list.hh"
42#undef HB_SHAPER_IMPLEMENT
43
44struct hb_shaper_entry_t {
45 char name[16];
46 hb_shape_func_t *func;
47};
48
49HB_INTERNAL const hb_shaper_entry_t *
50_hb_shapers_get ();
51
52
53template <typename Data, unsigned int WheresData, typename T>
54struct hb_shaper_lazy_loader_t;
55
56#define HB_SHAPER_ORDER(Shaper) \
57 HB_PASTE (HB_SHAPER_ORDER_, Shaper)
58enum hb_shaper_order_t
59{
60 _HB_SHAPER_ORDER_ORDER_ZERO,
61#define HB_SHAPER_IMPLEMENT(Shaper) \
62 HB_SHAPER_ORDER (Shaper),
63#include "hb-shaper-list.hh"
64#undef HB_SHAPER_IMPLEMENT
65 _HB_SHAPERS_COUNT_PLUS_ONE,
66 HB_SHAPERS_COUNT = _HB_SHAPERS_COUNT_PLUS_ONE - 1,
67};
68
69template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object_data_type_t;
70
71#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
72#define HB_SHAPER_DATA_TYPE(shaper, object) hb_##shaper##_##object##_data_t
73#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
74#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
75
76#define HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, object) \
77 \
78 struct HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
79 extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
80 HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object); \
81 extern "C" HB_INTERNAL void \
82 HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \
83 \
84 template <> \
85 struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \
86 { \
87 typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \
88 }; \
89 \
90 template <unsigned int WheresData> \
91 struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \
92 : hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \
93 hb_shaper_lazy_loader_t<hb_##object##_t, \
94 WheresData, \
95 HB_SHAPER_DATA_TYPE(shaper, object)>, \
96 hb_##object##_t, WheresData> \
97 { \
98 typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \
99 static Type* create (hb_##object##_t *data) \
100 { return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \
101 static Type *get_null () { return nullptr; } \
102 static void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
103 }; \
104 \
105 static_assert (true, "") /* Require semicolon after. */
106
107
108template <typename Object>
109struct hb_shaper_object_dataset_t
110{
111 void init0 (Object *parent_data)
112 {
113 this->parent_data = parent_data;
114#define HB_SHAPER_IMPLEMENT(shaper) shaper.init0 ();
115#include "hb-shaper-list.hh"
116#undef HB_SHAPER_IMPLEMENT
117 }
118 void fini ()
119 {
120#define HB_SHAPER_IMPLEMENT(shaper) shaper.fini ();
121#include "hb-shaper-list.hh"
122#undef HB_SHAPER_IMPLEMENT
123 }
124
125 Object *parent_data; /* MUST be JUST before the lazy loaders. */
126#define HB_SHAPER_IMPLEMENT(shaper) \
127 hb_shaper_lazy_loader_t<Object, HB_SHAPER_ORDER(shaper), \
128 typename hb_shaper_object_data_type_t<HB_SHAPER_ORDER(shaper), Object>::value \
129 > shaper;
130#include "hb-shaper-list.hh"
131#undef HB_SHAPER_IMPLEMENT
132};
133
134#endif /* HB_SHAPER_HH */
135