michael@0: /* GRAPHITE2 LICENSING michael@0: michael@0: Copyright 2012, SIL International michael@0: All rights reserved. michael@0: michael@0: This library is free software; you can redistribute it and/or modify michael@0: it under the terms of the GNU Lesser General Public License as published michael@0: by the Free Software Foundation; either version 2.1 of License, or michael@0: (at your option) any later version. michael@0: michael@0: This program is distributed in the hope that it will be useful, michael@0: but WITHOUT ANY WARRANTY; without even the implied warranty of michael@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU michael@0: Lesser General Public License for more details. michael@0: michael@0: You should also have received a copy of the GNU Lesser General Public michael@0: License along with this library in the file named "LICENSE". michael@0: If not, write to the Free Software Foundation, 51 Franklin Street, michael@0: Suite 500, Boston, MA 02110-1335, USA or visit their web page on the michael@0: internet at http://www.fsf.org/licenses/lgpl.html. michael@0: michael@0: Alternatively, the contents of this file may be used under the terms of the michael@0: Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public michael@0: License, as published by the Free Software Foundation, either version 2 michael@0: of the License or (at your option) any later version. michael@0: */ michael@0: #include michael@0: #include "inc/FileFace.h" michael@0: michael@0: michael@0: #ifndef GRAPHITE2_NFILEFACE michael@0: michael@0: using namespace graphite2; michael@0: michael@0: FileFace::FileFace(const char *filename) michael@0: : _file(fopen(filename, "rb")), michael@0: _file_len(0), michael@0: _header_tbl(NULL), michael@0: _table_dir(NULL) michael@0: { michael@0: if (!_file) return; michael@0: michael@0: if (fseek(_file, 0, SEEK_END)) return; michael@0: _file_len = ftell(_file); michael@0: if (fseek(_file, 0, SEEK_SET)) return; michael@0: michael@0: size_t tbl_offset, tbl_len; michael@0: michael@0: // Get the header. michael@0: if (!TtfUtil::GetHeaderInfo(tbl_offset, tbl_len)) return; michael@0: if (fseek(_file, tbl_offset, SEEK_SET)) return; michael@0: _header_tbl = (TtfUtil::Sfnt::OffsetSubTable*)gralloc(tbl_len); michael@0: if (_header_tbl) michael@0: { michael@0: if (fread(_header_tbl, 1, tbl_len, _file) != tbl_len) return; michael@0: if (!TtfUtil::CheckHeader(_header_tbl)) return; michael@0: } michael@0: michael@0: // Get the table directory michael@0: if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return; michael@0: _table_dir = (TtfUtil::Sfnt::OffsetSubTable::Entry*)gralloc(tbl_len); michael@0: if (fseek(_file, tbl_offset, SEEK_SET)) return; michael@0: if (_table_dir) michael@0: if (fread(_table_dir, 1, tbl_len, _file) != tbl_len) return; michael@0: } michael@0: michael@0: FileFace::~FileFace() michael@0: { michael@0: free(_table_dir); michael@0: free(_header_tbl); michael@0: if (_file) michael@0: fclose(_file); michael@0: } michael@0: michael@0: michael@0: const void *FileFace::get_table_fn(const void* appFaceHandle, unsigned int name, size_t *len) michael@0: { michael@0: if (appFaceHandle == 0) return 0; michael@0: const FileFace & file_face = *static_cast(appFaceHandle); michael@0: michael@0: void *tbl; michael@0: size_t tbl_offset, tbl_len; michael@0: if (!TtfUtil::GetTableInfo(name, file_face._header_tbl, file_face._table_dir, tbl_offset, tbl_len)) michael@0: return 0; michael@0: michael@0: if (tbl_offset + tbl_len > file_face._file_len michael@0: || fseek(file_face._file, tbl_offset, SEEK_SET) != 0) michael@0: return 0; michael@0: michael@0: tbl = malloc(tbl_len); michael@0: if (fread(tbl, 1, tbl_len, file_face._file) != tbl_len) michael@0: { michael@0: free(tbl); michael@0: return 0; michael@0: } michael@0: michael@0: if (len) *len = tbl_len; michael@0: return tbl; michael@0: } michael@0: michael@0: void FileFace::rel_table_fn(const void* appFaceHandle, const void *table_buffer) michael@0: { michael@0: if (appFaceHandle == 0) return; michael@0: michael@0: free(const_cast(table_buffer)); michael@0: } michael@0: michael@0: const gr_face_ops FileFace::ops = { sizeof FileFace::ops, &FileFace::get_table_fn, &FileFace::rel_table_fn }; michael@0: michael@0: michael@0: #endif //!GRAPHITE2_NFILEFACE