1/*
2 * Copyright © 2009, 2023 Red Hat, Inc.
3 * Copyright © 2015 Google, Inc.
4 *
5 * Permission is hereby granted, without written agreement and without
6 * license or royalty fees, to use, copy, modify, and distribute this
7 * software and its documentation for any purpose, provided that the
8 * above copyright notice and the following two paragraphs appear in
9 * all copies of this software.
10 *
11 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
12 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
13 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
14 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
15 * DAMAGE.
16 *
17 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
18 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
20 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
21 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
22 *
23 * Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
24 * Google Author(s): Behdad Esfahbod
25 */
26
27#include <freetype/freetype.h>
28#include <freetype/tttables.h>
29
30#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
31
32#include "ft-hb.h"
33
34/* The following three functions are a more or less verbatim
35 * copy of corresponding HarfBuzz code from hb-ft.cc
36 */
37
38static hb_blob_t *
39hb_ft_reference_table_ (hb_face_t *face, hb_tag_t tag, void *user_data)
40{
41 FT_Face ft_face = (FT_Face) user_data;
42 FT_Byte *buffer;
43 FT_ULong length = 0;
44 FT_Error error;
45
46 FT_UNUSED (face);
47
48 /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
49
50 error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
51 if (error)
52 return NULL;
53
54 buffer = (FT_Byte *) ft_smalloc (length);
55 if (!buffer)
56 return NULL;
57
58 error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
59 if (error)
60 {
61 free (buffer);
62 return NULL;
63 }
64
65 return hb_blob_create ((const char *) buffer, length,
66 HB_MEMORY_MODE_WRITABLE,
67 buffer, ft_sfree);
68}
69
70static hb_face_t *
71hb_ft_face_create_ (FT_Face ft_face,
72 hb_destroy_func_t destroy)
73{
74 hb_face_t *face;
75
76 if (!ft_face->stream->read) {
77 hb_blob_t *blob;
78
79 blob = hb_blob_create ((const char *) ft_face->stream->base,
80 (unsigned int) ft_face->stream->size,
81 HB_MEMORY_MODE_READONLY,
82 ft_face, destroy);
83 face = hb_face_create (blob, ft_face->face_index);
84 hb_blob_destroy (blob);
85 } else {
86 face = hb_face_create_for_tables (hb_ft_reference_table_, ft_face, destroy);
87 }
88
89 hb_face_set_index (face, ft_face->face_index);
90 hb_face_set_upem (face, ft_face->units_per_EM);
91
92 return face;
93}
94
95FT_LOCAL_DEF(hb_font_t *)
96hb_ft_font_create_ (FT_Face ft_face,
97 hb_destroy_func_t destroy)
98{
99 hb_font_t *font;
100 hb_face_t *face;
101
102 face = hb_ft_face_create_ (ft_face, destroy);
103 font = hb_font_create (face);
104 hb_face_destroy (face);
105 return font;
106}
107
108#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
109
110/* ANSI C doesn't like empty source files */
111typedef int ft_hb_dummy_;
112
113#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
114
115/* END */
116