speedup and add the static library
[charfbuzz.git] / hb-ft.c
blob551d6e47f67a13ce27d21f4bfadc86a8091507ce
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
6 #include <stdlib.h>
8 #include <ft2build.h>
9 #include FT_FREETYPE_H
10 #include FT_TRUETYPE_TABLES_H
12 #include "hb.h"
13 #include "hb-private.h"
14 #include "hb-atomic-private.h"
15 #include "hb-ft.h"
16 #include "hb-shaper-private.h"
17 #include "hb-face-private.h"
19 static hb_blob_t *reference_table(hb_face_t * face HB_UNUSED, hb_tag_t tag,
20 void *user_data)
22 FT_Face ft_face;
23 FT_Byte *buffer;
24 FT_ULong length;
25 FT_Error error;
27 ft_face = (FT_Face) user_data;
28 length = 0;
30 /*Note: FreeType like HarfBuzz uses the NONE tag for fetching the
31 entire blob */
33 error = FT_Load_Sfnt_Table(ft_face, tag, 0, NULL, &length);
34 if (error)
35 return NULL;
37 buffer = (FT_Byte *) malloc(length);
38 if (buffer == NULL)
39 return NULL;
41 error = FT_Load_Sfnt_Table(ft_face, tag, 0, buffer, &length);
42 if (error)
43 return NULL;
45 return hb_blob_create((const char *)buffer, length,
46 HB_MEMORY_MODE_WRITABLE, buffer, free);
49 hb_face_t *hb_ft_face_create(FT_Face ft_face, hb_destroy_func_t destroy)
51 hb_face_t *face;
53 if (ft_face->stream->read == NULL) {
54 hb_blob_t *blob;
56 /*TODO: We assume that it's mmap()'ed, but FreeType
57 code suggests that there are cases we reach here
58 but font is not mmapped. For example, when mmap()
59 fails. No idea how to deal with it better here.*/
60 blob =
61 hb_blob_create((const char *)ft_face->stream->base,
62 (unsigned)ft_face->stream->size,
63 HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
64 ft_face, destroy);
65 face = hb_face_create(blob, ft_face->face_index);
66 hb_blob_destroy(blob);
67 } else {
68 face =
69 hb_face_create_for_tables(reference_table, ft_face,
70 destroy);
73 hb_face_set_index(face, ft_face->face_index);
74 hb_face_set_upem(face, ft_face->units_per_EM);
75 return face;
78 static void hb_ft_face_finalize(FT_Face ft_face)
80 hb_face_destroy((hb_face_t *) ft_face->generic.data);
83 hb_face_t *hb_ft_face_create_cached(FT_Face ft_face)
85 if (!ft_face->generic.data
86 || ft_face->generic.finalizer !=
87 (FT_Generic_Finalizer) hb_ft_face_finalize) {
88 if (ft_face->generic.finalizer)
89 ft_face->generic.finalizer(ft_face);
91 ft_face->generic.data = hb_ft_face_create(ft_face, NULL);
92 ft_face->generic.finalizer =
93 (FT_Generic_Finalizer) hb_ft_face_finalize;
95 return hb_face_reference((hb_face_t *) ft_face->generic.data);