make cleanup and some bash-ism removal
[charfbuzz.git] / hb-ft.c
blobbb44c035ff48e7655a397e5b95872d75b92945ad
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
4 #include <stdlib.h>
6 #include <ft2build.h>
7 #include FT_FREETYPE_H
8 #include FT_TRUETYPE_TABLES_H
10 #include "hb.h"
11 #include "hb-private.h"
12 #include "hb-atomic-private.h"
13 #include "hb-ft.h"
14 #include "hb-shaper-private.h"
15 #include "hb-face-private.h"
17 static hb_blob_t *
18 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
20 FT_Face ft_face = (FT_Face)user_data;
21 FT_Byte *buffer;
22 FT_ULong length = 0;
23 FT_Error error;
25 //Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob
27 error = FT_Load_Sfnt_Table(ft_face, tag, 0, NULL, &length);
28 if (error)
29 return NULL;
31 buffer = (FT_Byte*)malloc(length);
32 if (buffer == NULL)
33 return NULL;
35 error = FT_Load_Sfnt_Table(ft_face, tag, 0, buffer, &length);
36 if (error)
37 return NULL;
39 return hb_blob_create((const char*)buffer,
40 length,
41 HB_MEMORY_MODE_WRITABLE,
42 buffer,
43 free);
46 hb_face_t *
47 hb_ft_face_create(FT_Face ft_face, hb_destroy_func_t destroy)
49 hb_face_t *face;
51 if (ft_face->stream->read == NULL) {
52 hb_blob_t *blob;
54 blob = hb_blob_create((const char*)ft_face->stream->base,
55 (unsigned)ft_face->stream->size,
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 HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
61 ft_face, destroy);
62 face = hb_face_create(blob, ft_face->face_index);
63 hb_blob_destroy(blob);
64 } else {
65 face = hb_face_create_for_tables(reference_table, ft_face, destroy);
68 hb_face_set_index(face, ft_face->face_index);
69 hb_face_set_upem(face, ft_face->units_per_EM);
70 return face;
73 static void
74 hb_ft_face_finalize(FT_Face ft_face)
76 hb_face_destroy((hb_face_t*)ft_face->generic.data);
79 hb_face_t *
80 hb_ft_face_create_cached(FT_Face ft_face)
82 if (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer)hb_ft_face_finalize) {
83 if (ft_face->generic.finalizer)
84 ft_face->generic.finalizer(ft_face);
86 ft_face->generic.data = hb_ft_face_create(ft_face, NULL);
87 ft_face->generic.finalizer = (FT_Generic_Finalizer)hb_ft_face_finalize;
89 return hb_face_reference((hb_face_t*)ft_face->generic.data);