blob: 228dce4dd8aa0333d392d97c600bc980599543a7 [file] [log] [blame]
/* ftglue.c: Glue code for compiling the OpenType code from
* FreeType 1 using only the public API of FreeType 2
*
* By David Turner, The FreeType Project (www.freetype.org)
*
* This code is explicitely put in the public domain
*
* See ftglue.h for more information.
*/
#include "ftglue.h"
#if 0
# include <stdio.h>
# define LOG(x) ftglue_log x
static void
ftglue_log( const char* format, ... )
{
va_list ap;
va_start( ap, format );
vfprintf( stderr, format, ap );
va_end( ap );
}
#else
# define LOG(x) \
do { \
} while (0)
#endif
/* only used internally */
static FT_Pointer
ftglue_qalloc (FT_Memory memory,
FT_ULong size,
FT_Error *perror)
{
FT_Error error = 0;
FT_Pointer block = NULL;
if (size > 0) {
block = memory->alloc (memory, size);
if (!block)
error = FT_Err_Out_Of_Memory;
}
*perror = error;
return block;
}
#undef QALLOC /* just in case */
#define QALLOC(ptr, size) ((ptr) = ftglue_qalloc (memory, (size), &error), error != 0)
#define FREE(_ptr) \
do { \
if ((_ptr)) { \
ftglue_free (memory, _ptr); \
_ptr = NULL; \
} \
} while (0)
static void
ftglue_free (FT_Memory memory,
FT_Pointer block)
{
if (block)
memory->free (memory, block);
}
FTGLUE_APIDEF (FT_Long)
ftglue_stream_pos (FT_Stream stream)
{
LOG (("ftglue:stream:pos() -> %ld\n", stream->pos));
return stream->pos;
}
FTGLUE_APIDEF (FT_Error)
ftglue_stream_seek (FT_Stream stream,
FT_Long pos)
{
FT_Error error = 0;
if (stream->read) {
if (stream->read (stream, pos, 0, 0))
error = FT_Err_Invalid_Stream_Operation;
} else if (pos < 0 || (FT_ULong)pos > stream->size)
error = FT_Err_Invalid_Stream_Operation;
if (!error)
stream->pos = pos;
LOG (("ftglue:stream:seek(%ld) -> %d\n", pos, error));
return error;
}
FTGLUE_APIDEF (FT_Error)
ftglue_stream_frame_enter (FT_Stream stream,
FT_ULong count)
{
FT_Error error = FT_Err_Ok;
FT_ULong read_bytes;
if (stream->read) {
/* allocate the frame in memory */
FT_Memory memory = stream->memory;
if (QALLOC (stream->base, count))
goto Exit;
/* read it */
read_bytes = stream->read (stream, stream->pos,
stream->base, count);
if (read_bytes < count) {
FREE (stream->base);
error = FT_Err_Invalid_Stream_Operation;
}
stream->cursor = stream->base;
stream->limit = stream->cursor + count;
stream->pos += read_bytes;
} else {
/* check current and new position */
if (stream->pos >= stream->size ||
stream->pos + count > stream->size) {
error = FT_Err_Invalid_Stream_Operation;
goto Exit;
}
/* set cursor */
stream->cursor = stream->base + stream->pos;
stream->limit = stream->cursor + count;
stream->pos += count;
}
Exit:
LOG (("ftglue:stream:frame_enter(%ld) -> %d\n", count, error));
return error;
}
FTGLUE_APIDEF (void)
ftglue_stream_frame_exit (FT_Stream stream)
{
if (stream->read) {
FT_Memory memory = stream->memory;
FREE (stream->base);
}
stream->cursor = 0;
stream->limit = 0;
LOG (("ftglue:stream:frame_exit()\n"));
}
FTGLUE_APIDEF (FT_Error)
ftglue_face_goto_table (FT_Face face,
FT_ULong the_tag,
FT_Stream stream,
FT_ULong *table_size)
{
FT_Error error;
LOG (("ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
face,
(int)((the_tag >> 24) & 0xFF),
(int)((the_tag >> 16) & 0xFF),
(int)((the_tag >> 8) & 0xFF),
(int)(the_tag & 0xFF),
stream));
if (!FT_IS_SFNT (face)) {
LOG (("not a SFNT face !!\n"));
error = FT_Err_Invalid_Face_Handle;
} else {
/* parse the directory table directly, without using
* FreeType's built-in data structures
*/
FT_ULong offset = 0, sig;
FT_UInt count, nn;
if (FILE_Seek (0) || ACCESS_Frame (4))
goto Exit;
sig = GET_Tag4();
FORGET_Frame();
if (sig == FT_MAKE_TAG ('t', 't', 'c', 'f')) {
/* deal with TrueType collections */
LOG ((">> This is a TrueType Collection\n"));
if (FILE_Seek (12 + face->face_index * 4) ||
ACCESS_Frame (4))
goto Exit;
offset = GET_ULong();
FORGET_Frame();
}
LOG (("TrueType offset = %ld\n", offset));
if (FILE_Seek (offset + 4) ||
ACCESS_Frame (2))
goto Exit;
count = GET_UShort();
FORGET_Frame();
if (FILE_Seek (offset + 12) ||
ACCESS_Frame (count * 16))
goto Exit;
for (nn = 0; nn < count; nn++) {
FT_ULong tag = GET_ULong();
FT_ULong checksum FC_UNUSED = GET_ULong();
FT_ULong start = GET_ULong();
FT_ULong size FC_UNUSED = GET_ULong();
if (tag == the_tag) {
LOG (("TrueType table (start: %ld) (size: %ld)\n", start, size));
error = ftglue_stream_seek (stream, start);
if (table_size)
*table_size = size;
goto FoundIt;
}
}
error = FT_Err_Table_Missing;
FoundIt:
FORGET_Frame();
}
Exit:
LOG (("TrueType error=%d\n", error));
return error;
}
#undef QALLOC
#include "fcaliastail.h"
#undef __ftglue__