| /* 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__ |