1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 /*
  31  * Copyright © 2012  Google, Inc.
  32  *
  33  *  This is part of HarfBuzz, a text shaping library.
  34  *
  35  * Permission is hereby granted, without written agreement and without
  36  * license or royalty fees, to use, copy, modify, and distribute this
  37  * software and its documentation for any purpose, provided that the
  38  * above copyright notice and the following two paragraphs appear in
  39  * all copies of this software.
  40  *
  41  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  42  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  43  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  44  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  45  * DAMAGE.
  46  *
  47  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  48  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  49  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  50  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  51  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  52  *
  53  * Google Author(s): Behdad Esfahbod
  54  */
  55 
  56 #ifndef HB_SHAPER_PRIVATE_HH
  57 #define HB_SHAPER_PRIVATE_HH
  58 
  59 #include "hb-private.hh"
  60 
  61 typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t    *shape_plan,
  62                                    hb_font_t          *font,
  63                                    hb_buffer_t        *buffer,
  64                                    const hb_feature_t *features,
  65                                    unsigned int        num_features);
  66 
  67 #define HB_SHAPER_IMPLEMENT(name) \
  68         extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
  69 #include "hb-shaper-list.hh"
  70 #undef HB_SHAPER_IMPLEMENT
  71 
  72 struct hb_shaper_pair_t {
  73   char name[16];
  74   hb_shape_func_t *func;
  75 };
  76 
  77 HB_INTERNAL const hb_shaper_pair_t *
  78 _hb_shapers_get (void);
  79 
  80 
  81 /* For embedding in face / font / ... */
  82 struct hb_shaper_data_t {
  83 #define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
  84 #include "hb-shaper-list.hh"
  85 #undef HB_SHAPER_IMPLEMENT
  86 };
  87 
  88 #define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
  89 
  90 /* Means: succeeded, but don't need to keep any data. */
  91 #define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
  92 
  93 /* Means: tried but failed to create. */
  94 #define HB_SHAPER_DATA_INVALID ((void *) -1)
  95 #define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
  96 
  97 #define HB_SHAPER_DATA_TYPE(shaper, object)             struct hb_##shaper##_shaper_##object##_data_t
  98 #define HB_SHAPER_DATA_INSTANCE(shaper, object, instance)       (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
  99 #define HB_SHAPER_DATA(shaper, object)                  HB_SHAPER_DATA_INSTANCE (shaper, object, object)
 100 #define HB_SHAPER_DATA_CREATE_FUNC(shaper, object)      _hb_##shaper##_shaper_##object##_data_create
 101 #define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object)     _hb_##shaper##_shaper_##object##_data_destroy
 102 
 103 #define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
 104         HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
 105         extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
 106         HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
 107         extern "C" HB_INTERNAL void \
 108         HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
 109 
 110 #define HB_SHAPER_DATA_DESTROY(shaper, object) \
 111     if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
 112       if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
 113         HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
 114 
 115 #define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
 116 static inline bool \
 117 hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
 118 {\
 119   retry: \
 120   HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
 121   if (unlikely (!data)) { \
 122     data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
 123     if (unlikely (!data)) \
 124       data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
 125     if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
 126       if (data && \
 127           data != HB_SHAPER_DATA_INVALID && \
 128           data != HB_SHAPER_DATA_SUCCEEDED) \
 129         HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
 130       goto retry; \
 131     } \
 132   } \
 133   return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
 134 }
 135 
 136 
 137 #endif /* HB_SHAPER_PRIVATE_HH */