|
1 /* GRAPHITE2 LICENSING |
|
2 |
|
3 Copyright 2012, SIL International |
|
4 All rights reserved. |
|
5 |
|
6 This library is free software; you can redistribute it and/or modify |
|
7 it under the terms of the GNU Lesser General Public License as published |
|
8 by the Free Software Foundation; either version 2.1 of License, or |
|
9 (at your option) any later version. |
|
10 |
|
11 This program is distributed in the hope that it will be useful, |
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 Lesser General Public License for more details. |
|
15 |
|
16 You should also have received a copy of the GNU Lesser General Public |
|
17 License along with this library in the file named "LICENSE". |
|
18 If not, write to the Free Software Foundation, 51 Franklin Street, |
|
19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the |
|
20 internet at http://www.fsf.org/licenses/lgpl.html. |
|
21 |
|
22 Alternatively, the contents of this file may be used under the terms of the |
|
23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public |
|
24 License, as published by the Free Software Foundation, either version 2 |
|
25 of the License or (at your option) any later version. |
|
26 */ |
|
27 #include <cstring> |
|
28 #include "inc/FileFace.h" |
|
29 |
|
30 |
|
31 #ifndef GRAPHITE2_NFILEFACE |
|
32 |
|
33 using namespace graphite2; |
|
34 |
|
35 FileFace::FileFace(const char *filename) |
|
36 : _file(fopen(filename, "rb")), |
|
37 _file_len(0), |
|
38 _header_tbl(NULL), |
|
39 _table_dir(NULL) |
|
40 { |
|
41 if (!_file) return; |
|
42 |
|
43 if (fseek(_file, 0, SEEK_END)) return; |
|
44 _file_len = ftell(_file); |
|
45 if (fseek(_file, 0, SEEK_SET)) return; |
|
46 |
|
47 size_t tbl_offset, tbl_len; |
|
48 |
|
49 // Get the header. |
|
50 if (!TtfUtil::GetHeaderInfo(tbl_offset, tbl_len)) return; |
|
51 if (fseek(_file, tbl_offset, SEEK_SET)) return; |
|
52 _header_tbl = (TtfUtil::Sfnt::OffsetSubTable*)gralloc<char>(tbl_len); |
|
53 if (_header_tbl) |
|
54 { |
|
55 if (fread(_header_tbl, 1, tbl_len, _file) != tbl_len) return; |
|
56 if (!TtfUtil::CheckHeader(_header_tbl)) return; |
|
57 } |
|
58 |
|
59 // Get the table directory |
|
60 if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return; |
|
61 _table_dir = (TtfUtil::Sfnt::OffsetSubTable::Entry*)gralloc<char>(tbl_len); |
|
62 if (fseek(_file, tbl_offset, SEEK_SET)) return; |
|
63 if (_table_dir) |
|
64 if (fread(_table_dir, 1, tbl_len, _file) != tbl_len) return; |
|
65 } |
|
66 |
|
67 FileFace::~FileFace() |
|
68 { |
|
69 free(_table_dir); |
|
70 free(_header_tbl); |
|
71 if (_file) |
|
72 fclose(_file); |
|
73 } |
|
74 |
|
75 |
|
76 const void *FileFace::get_table_fn(const void* appFaceHandle, unsigned int name, size_t *len) |
|
77 { |
|
78 if (appFaceHandle == 0) return 0; |
|
79 const FileFace & file_face = *static_cast<const FileFace *>(appFaceHandle); |
|
80 |
|
81 void *tbl; |
|
82 size_t tbl_offset, tbl_len; |
|
83 if (!TtfUtil::GetTableInfo(name, file_face._header_tbl, file_face._table_dir, tbl_offset, tbl_len)) |
|
84 return 0; |
|
85 |
|
86 if (tbl_offset + tbl_len > file_face._file_len |
|
87 || fseek(file_face._file, tbl_offset, SEEK_SET) != 0) |
|
88 return 0; |
|
89 |
|
90 tbl = malloc(tbl_len); |
|
91 if (fread(tbl, 1, tbl_len, file_face._file) != tbl_len) |
|
92 { |
|
93 free(tbl); |
|
94 return 0; |
|
95 } |
|
96 |
|
97 if (len) *len = tbl_len; |
|
98 return tbl; |
|
99 } |
|
100 |
|
101 void FileFace::rel_table_fn(const void* appFaceHandle, const void *table_buffer) |
|
102 { |
|
103 if (appFaceHandle == 0) return; |
|
104 |
|
105 free(const_cast<void *>(table_buffer)); |
|
106 } |
|
107 |
|
108 const gr_face_ops FileFace::ops = { sizeof FileFace::ops, &FileFace::get_table_fn, &FileFace::rel_table_fn }; |
|
109 |
|
110 |
|
111 #endif //!GRAPHITE2_NFILEFACE |