diff --git a/src/Makefile.am b/src/Makefile.am index a351fc879..7b10fe2ba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ HBCFLAGS = HBLIBS = HBSOURCES = \ hb-blob.c \ + hb-blob-private.h \ hb-buffer.c \ hb-buffer-private.h \ hb-font.cc \ diff --git a/src/hb-blob-private.h b/src/hb-blob-private.h new file mode 100644 index 000000000..26cad0ab6 --- /dev/null +++ b/src/hb-blob-private.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Red Hat, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_BLOB_PRIVATE_H +#define HB_BLOB_PRIVATE_H + +#include "hb-private.h" + +#include "hb-blob.h" + +HB_BEGIN_DECLS + +struct _hb_blob_t { + hb_reference_count_t ref_count; + + unsigned int length; + + hb_mutex_t lock; + /* the rest are protected by lock */ + + unsigned int lock_count; + hb_memory_mode_t mode; + + const char *data; + + hb_destroy_func_t destroy; + void *user_data; +}; + +HB_INTERNAL hb_blob_t _hb_blob_nil; + +HB_END_DECLS + +#endif /* HB_BLOB_PRIVATE_H */ diff --git a/src/hb-blob.c b/src/hb-blob.c index 8276d789d..8013de1ff 100644 --- a/src/hb-blob.c +++ b/src/hb-blob.c @@ -26,7 +26,7 @@ #include "hb-private.h" -#include "hb-blob.h" +#include "hb-blob-private.h" #ifdef HAVE_SYS_MMAN_H #ifdef HAVE_UNISTD_H @@ -44,23 +44,7 @@ #include #endif -struct _hb_blob_t { - hb_reference_count_t ref_count; - - unsigned int length; - - hb_mutex_t lock; - /* the rest are protected by lock */ - - unsigned int lock_count; - hb_memory_mode_t mode; - - const char *data; - - hb_destroy_func_t destroy; - void *user_data; -}; -static hb_blob_t _hb_blob_nil = { +hb_blob_t _hb_blob_nil = { HB_REFERENCE_COUNT_INVALID, /* ref_count */ 0, /* length */ diff --git a/src/hb-font-private.h b/src/hb-font-private.h index 65e54c958..2b024cc67 100644 --- a/src/hb-font-private.h +++ b/src/hb-font-private.h @@ -60,9 +60,6 @@ _hb_font_funcs_nil; struct _hb_face_t { hb_reference_count_t ref_count; - hb_blob_t *blob; - unsigned int index; - hb_get_table_func_t get_table; hb_destroy_func_t destroy; void *user_data; diff --git a/src/hb-font.cc b/src/hb-font.cc index f913f7e9b..3b1b6ca17 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -27,8 +27,8 @@ #include "hb-private.h" #include "hb-font-private.h" +#include "hb-blob-private.h" #include "hb-open-file-private.hh" -#include "hb-blob.h" #include "hb-ot-layout-private.h" @@ -218,33 +218,14 @@ hb_font_get_kerning (hb_font_t *font, hb_face_t *face, first_glyph, second_glyph); } + /* * hb_face_t */ -static hb_blob_t * -_hb_face_get_table_from_blob (hb_tag_t tag, void *user_data) -{ - hb_face_t *face = (hb_face_t *) user_data; - - const OpenTypeFontFile &ot_file = *CastP (hb_blob_lock (face->blob)); - const OpenTypeFontFace &ot_face = ot_file.get_face (face->index); - - const OpenTypeTable &table = ot_face.get_table_by_tag (tag); - - hb_blob_t *blob = hb_blob_create_sub_blob (face->blob, table.offset, table.length); - - hb_blob_unlock (face->blob); - - return blob; -} - static hb_face_t _hb_face_nil = { HB_REFERENCE_COUNT_INVALID, /* ref_count */ - NULL, /* blob */ - 0, /* index */ - NULL, /* get_table */ NULL, /* destroy */ NULL, /* user_data */ @@ -252,6 +233,7 @@ static hb_face_t _hb_face_nil = { {} /* ot_layout */ }; + hb_face_t * hb_face_create_for_tables (hb_get_table_func_t get_table, hb_destroy_func_t destroy, @@ -274,6 +256,58 @@ hb_face_create_for_tables (hb_get_table_func_t get_table, return face; } + +typedef struct _hb_face_for_data_closure_t { + hb_blob_t *blob; + unsigned int index; +} hb_face_for_data_closure_t; + +static hb_face_for_data_closure_t _hb_face_for_data_closure_nil = { + &_hb_blob_nil, + 0 +}; + +static hb_face_for_data_closure_t * +_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) +{ + hb_face_for_data_closure_t *closure; + + closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); + if (HB_UNLIKELY (!closure)) + return &_hb_face_for_data_closure_nil; + + closure->blob = hb_blob_reference (blob); + closure->index = index; + + return closure; +} + +static void +_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) +{ + if (HB_LIKELY (closure != &_hb_face_for_data_closure_nil)) { + hb_blob_destroy (closure->blob); + free (closure); + } +} + +static hb_blob_t * +_hb_face_for_data_get_table (hb_tag_t tag, void *user_data) +{ + hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + + const OpenTypeFontFile &ot_file = *CastP (hb_blob_lock (data->blob)); + const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + + const OpenTypeTable &table = ot_face.get_table_by_tag (tag); + + hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); + + hb_blob_unlock (data->blob); + + return blob; +} + hb_face_t * hb_face_create_for_data (hb_blob_t *blob, unsigned int index) @@ -283,16 +317,18 @@ hb_face_create_for_data (hb_blob_t *blob, if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) return &_hb_face_nil; - face->blob = Sanitizer::sanitize (hb_blob_reference (blob)); - face->index = index; - face->get_table = _hb_face_get_table_from_blob; - face->user_data = face; + face->get_table = _hb_face_for_data_get_table; + face->destroy = (hb_destroy_func_t) _hb_face_for_data_closure_destroy; + hb_blob_reference (blob); + face->user_data = _hb_face_for_data_closure_create (Sanitizer::sanitize (blob), index); + hb_blob_destroy (blob); _hb_ot_layout_init (face); return face; } + hb_face_t * hb_face_reference (hb_face_t *face) { @@ -312,8 +348,6 @@ hb_face_destroy (hb_face_t *face) _hb_ot_layout_fini (face); - hb_blob_destroy (face->blob); - if (face->destroy) face->destroy (face->user_data); @@ -327,11 +361,11 @@ hb_face_get_table (hb_face_t *face, hb_blob_t *blob; if (HB_UNLIKELY (!face || !face->get_table)) - return hb_blob_create_empty (); + return &_hb_blob_nil; blob = face->get_table (tag, face->user_data); - return blob? blob : hb_blob_create_empty (); + return blob? blob : &_hb_blob_nil; }