150 lines
3.9 KiB
Plaintext
150 lines
3.9 KiB
Plaintext
/* ****************************************************************************
|
|
* fontchar/open.c -- parse the binary set file produced from the
|
|
* community-made FONTCHARACTER reference.
|
|
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
|
*
|
|
* This file is part of libcasio.
|
|
* libcasio is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 3.0 of the License,
|
|
* or (at your option) any later version.
|
|
*
|
|
* libcasio is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
|
|
* ************************************************************************* */
|
|
#include "fontchar.h"
|
|
#include "reference.h"
|
|
|
|
/* Globals. */
|
|
|
|
casio_uint8_t* CASIO_EXPORT casio_fontchar_leaders = NULL;
|
|
|
|
/**
|
|
* casio_open_fontchar_ref:
|
|
* Open the FONTCHARACTER reference.
|
|
*/
|
|
|
|
int CASIO_EXPORT casio_open_fontchar_ref(void)
|
|
{
|
|
int err, num, i;
|
|
casio_stream_t *stream;
|
|
struct file_magic magic;
|
|
struct file_header header;
|
|
size_t char_size;
|
|
const char *chars = NULL;
|
|
const char *pool = NULL;
|
|
|
|
/* Open the file. */
|
|
err = casio_open_nat(casio_local_fs, &stream, PATH,
|
|
0, CASIO_OPENMODE_READ);
|
|
if (err) return (err);
|
|
|
|
/* Read the magic. */
|
|
err = casio_read(stream, &magic, sizeof(magic));
|
|
if (err) goto fail;
|
|
if (memcmp(magic.magic, FONTCHAR_MAGIC, 8)) {
|
|
msg((ll_error, "Invalid FONTCHARACTER file magic."));
|
|
|
|
err = casio_error_magic;
|
|
goto fail;
|
|
}
|
|
if (magic.version != 0x01) {
|
|
msg((ll_error, "Unsupported FONTCHARACTER file version."))
|
|
|
|
err = casio_error_magic;
|
|
goto fail;
|
|
}
|
|
|
|
/* Read the rest of the header. */
|
|
err = casio_read(stream, &header, sizeof(header));
|
|
if (err) goto fail;
|
|
if (~header.flags & FONTCHAR_FLAG_UNI) {
|
|
msg((ll_error, "Unicode support is required by the library!"));
|
|
|
|
err = casio_error_magic;
|
|
goto fail;
|
|
}
|
|
|
|
header.total = be16toh(header.total);
|
|
header.format = be16toh(header.format);
|
|
header.checksum = be32toh(header.checksum);
|
|
header.filesize = be32toh(header.filesize);
|
|
header.datasize = be32toh(header.datasize);
|
|
|
|
char_size = 16;
|
|
if (header.flags & FONTCHAR_FLAG_CAT)
|
|
char_size += 4;
|
|
if (header.flags & FONTCHAR_FLAG_NEWCAT)
|
|
char_size += 4;
|
|
if (header.flags & FONTCHAR_FLAG_CTF)
|
|
char_size += 4;
|
|
if (header.flags & FONTCHAR_FLAG_CASEMUL)
|
|
char_size += 4;
|
|
|
|
/* Check that the filesize corresponds. */
|
|
if (header.filesize != sizeof(struct file_lead)
|
|
+ sizeof(struct file_header)
|
|
+ sizeof(struct file_lead) * header.leading
|
|
+ char_size * header.total) {
|
|
msg((ll_error, "Erroneous file size field!"));
|
|
|
|
err = casio_error_magic;
|
|
goto fail;
|
|
}
|
|
|
|
/* Get the leading characters. */
|
|
num = header.leading;
|
|
casio_fontchar_leaders = casio_alloc(num, 1);
|
|
for (i = 0; i < num; i++) {
|
|
struct file_lead lead;
|
|
|
|
err = casio_read(stream, &lead, sizeof(lead));
|
|
if (err) goto fail;
|
|
|
|
casio_fontchar_leaders[i] = lead.code;
|
|
}
|
|
|
|
/* Prepare gathering of the characters and data pool. */
|
|
chars = casio_alloc(char_size, num);
|
|
if (!chars) {
|
|
err = casio_error_alloc;
|
|
goto fail;
|
|
}
|
|
|
|
err = casio_read(stream, &chars, char_size * num);
|
|
if (err)
|
|
goto fail;
|
|
|
|
pool = casio_alloc(
|
|
|
|
/* Get the characters. */
|
|
num = header.total;
|
|
chars = casio_alloc(char_size, num);
|
|
if (!chars) {
|
|
err = casio_error_alloc;
|
|
goto fail;
|
|
}
|
|
for (i = 0; i < num; i++) {
|
|
struct file_char ch;
|
|
|
|
/* Careful: char_size can not be `sizeof(char_size)`!
|
|
* (but `ch` is always big enough to read the character data
|
|
* into it) */
|
|
err = casio_read(stream, &ch, char_size);
|
|
if (err) goto fail;
|
|
|
|
|
|
}
|
|
|
|
/* TODO */
|
|
return (0);
|
|
fail:
|
|
casio_free(stream);
|
|
return (casio_error_op);
|
|
}
|