Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ftsystem.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftsystem.c */
4 /* */
5 /* Amiga-specific FreeType low-level system interface (body). */
6 /* */
7 /* Copyright 1996-2001, 2002, 2005, 2006, 2007, 2010 by */
8 /* David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18  /*************************************************************************/
19  /* */
20  /* This file contains the Amiga interface used by FreeType to access */
21  /* low-level, i.e. memory management, i/o access as well as thread */
22  /* synchronisation. */
23  /* */
24  /*************************************************************************/
25 
26 
27  /*************************************************************************/
28  /* */
29  /* Maintained by Detlef Würkner <TetiSoft@apg.lahn.de> */
30  /* */
31  /* Based on the original ftsystem.c, */
32  /* modified to avoid fopen(), fclose(), fread(), fseek(), ftell(), */
33  /* malloc(), realloc(), and free(). */
34  /* */
35  /* Those C library functions are often not thread-safe or cant be */
36  /* used in a shared Amiga library. If that's not a problem for you, */
37  /* you can of course use the default ftsystem.c with C library calls */
38  /* instead. */
39  /* */
40  /* This implementation needs exec V39+ because it uses AllocPooled() etc */
41  /* */
42  /*************************************************************************/
43 
44 #define __NOLIBBASE__
45 #define __NOGLOBALIFACE__
46 #define __USE_INLINE__
47 #include <proto/exec.h>
48 #include <dos/stdio.h>
49 #include <proto/dos.h>
50 #ifdef __amigaos4__
51 extern struct ExecIFace *IExec;
52 extern struct DOSIFace *IDOS;
53 #else
54 extern struct Library *SysBase;
55 extern struct Library *DOSBase;
56 #endif
57 
58 #define IOBUF_SIZE 512
59 
60 /* structure that helps us to avoid
61  * useless calls of Seek() and Read()
62  */
63 struct SysFile
64 {
65  BPTR file;
66  ULONG iobuf_start;
67  ULONG iobuf_end;
68  UBYTE iobuf[IOBUF_SIZE];
69 };
70 
71 #ifndef __amigaos4__
72 /* C implementation of AllocVecPooled (see autodoc exec/AllocPooled) */
73 APTR
74 Alloc_VecPooled( APTR poolHeader,
75  ULONG memSize )
76 {
77  ULONG newSize = memSize + sizeof ( ULONG );
78  ULONG *mem = AllocPooled( poolHeader, newSize );
79 
80  if ( !mem )
81  return NULL;
82  *mem = newSize;
83  return mem + 1;
84 }
85 
86 /* C implementation of FreeVecPooled (see autodoc exec/AllocPooled) */
87 void
88 Free_VecPooled( APTR poolHeader,
89  APTR memory )
90 {
91  ULONG *realmem = (ULONG *)memory - 1;
92 
93  FreePooled( poolHeader, realmem, *realmem );
94 }
95 #endif
96 
97 #include <ft2build.h>
98 #include FT_CONFIG_CONFIG_H
99 #include FT_INTERNAL_DEBUG_H
100 #include FT_SYSTEM_H
101 #include FT_ERRORS_H
102 #include FT_TYPES_H
103 
104 #include <stdio.h>
105 #include <stdlib.h>
106 #include <string.h>
107 
108 
109  /*************************************************************************/
110  /* */
111  /* MEMORY MANAGEMENT INTERFACE */
112  /* */
113  /*************************************************************************/
114 
115  /*************************************************************************/
116  /* */
117  /* It is not necessary to do any error checking for the */
118  /* allocation-related functions. This is done by the higher level */
119  /* routines like ft_mem_alloc() or ft_mem_realloc(). */
120  /* */
121  /*************************************************************************/
122 
123 
124  /*************************************************************************/
125  /* */
126  /* <Function> */
127  /* ft_alloc */
128  /* */
129  /* <Description> */
130  /* The memory allocation function. */
131  /* */
132  /* <Input> */
133  /* memory :: A pointer to the memory object. */
134  /* */
135  /* size :: The requested size in bytes. */
136  /* */
137  /* <Return> */
138  /* The address of newly allocated block. */
139  /* */
140  FT_CALLBACK_DEF( void* )
142  long size )
143  {
144 #ifdef __amigaos4__
145  return AllocVecPooled( memory->user, size );
146 #else
147  return Alloc_VecPooled( memory->user, size );
148 #endif
149  }
150 
151 
152  /*************************************************************************/
153  /* */
154  /* <Function> */
155  /* ft_realloc */
156  /* */
157  /* <Description> */
158  /* The memory reallocation function. */
159  /* */
160  /* <Input> */
161  /* memory :: A pointer to the memory object. */
162  /* */
163  /* cur_size :: The current size of the allocated memory block. */
164  /* */
165  /* new_size :: The newly requested size in bytes. */
166  /* */
167  /* block :: The current address of the block in memory. */
168  /* */
169  /* <Return> */
170  /* The address of the reallocated memory block. */
171  /* */
172  FT_CALLBACK_DEF( void* )
174  long cur_size,
175  long new_size,
176  void* block )
177  {
178  void* new_block;
179 
180 #ifdef __amigaos4__
181  new_block = AllocVecPooled ( memory->user, new_size );
182 #else
183  new_block = Alloc_VecPooled ( memory->user, new_size );
184 #endif
185  if ( new_block != NULL )
186  {
187  CopyMem ( block, new_block,
188  ( new_size > cur_size ) ? cur_size : new_size );
189 #ifdef __amigaos4__
190  FreeVecPooled ( memory->user, block );
191 #else
192  Free_VecPooled ( memory->user, block );
193 #endif
194  }
195  return new_block;
196  }
197 
198 
199  /*************************************************************************/
200  /* */
201  /* <Function> */
202  /* ft_free */
203  /* */
204  /* <Description> */
205  /* The memory release function. */
206  /* */
207  /* <Input> */
208  /* memory :: A pointer to the memory object. */
209  /* */
210  /* block :: The address of block in memory to be freed. */
211  /* */
212  FT_CALLBACK_DEF( void )
214  void* block )
215  {
216 #ifdef __amigaos4__
217  FreeVecPooled( memory->user, block );
218 #else
219  Free_VecPooled( memory->user, block );
220 #endif
221  }
222 
223 
224  /*************************************************************************/
225  /* */
226  /* RESOURCE MANAGEMENT INTERFACE */
227  /* */
228  /*************************************************************************/
229 
230 
231  /*************************************************************************/
232  /* */
233  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
234  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
235  /* messages during execution. */
236  /* */
237 #undef FT_COMPONENT
238 #define FT_COMPONENT trace_io
239 
240  /* We use the macro STREAM_FILE for convenience to extract the */
241  /* system-specific stream handle from a given FreeType stream object */
242 #define STREAM_FILE( stream ) ( (struct SysFile *)stream->descriptor.pointer )
243 
244 
245  /*************************************************************************/
246  /* */
247  /* <Function> */
248  /* ft_amiga_stream_close */
249  /* */
250  /* <Description> */
251  /* The function to close a stream. */
252  /* */
253  /* <Input> */
254  /* stream :: A pointer to the stream object. */
255  /* */
256  FT_CALLBACK_DEF( void )
258  {
259  struct SysFile* sysfile;
260 
261  sysfile = STREAM_FILE( stream );
262  Close ( sysfile->file );
263  FreeMem ( sysfile, sizeof ( struct SysFile ));
264 
265  stream->descriptor.pointer = NULL;
266  stream->size = 0;
267  stream->base = 0;
268  }
269 
270 
271  /*************************************************************************/
272  /* */
273  /* <Function> */
274  /* ft_amiga_stream_io */
275  /* */
276  /* <Description> */
277  /* The function to open a stream. */
278  /* */
279  /* <Input> */
280  /* stream :: A pointer to the stream object. */
281  /* */
282  /* offset :: The position in the data stream to start reading. */
283  /* */
284  /* buffer :: The address of buffer to store the read data. */
285  /* */
286  /* count :: The number of bytes to read from the stream. */
287  /* */
288  /* <Return> */
289  /* The number of bytes actually read. */
290  /* */
291  FT_CALLBACK_DEF( unsigned long )
293  unsigned long offset,
294  unsigned char* buffer,
295  unsigned long count )
296  {
297  struct SysFile* sysfile;
298  unsigned long read_bytes;
299 
300  if ( count != 0 )
301  {
302  sysfile = STREAM_FILE( stream );
303 
304  /* handle the seek */
305  if ( (offset < sysfile->iobuf_start) || (offset + count > sysfile->iobuf_end) )
306  {
307  /* requested offset implies we need a buffer refill */
308  if ( !sysfile->iobuf_end || offset != sysfile->iobuf_end )
309  {
310  /* a physical seek is necessary */
311  Seek( sysfile->file, offset, OFFSET_BEGINNING );
312  }
313  sysfile->iobuf_start = offset;
314  sysfile->iobuf_end = 0; /* trigger a buffer refill */
315  }
316 
317  /* handle the read */
318  if ( offset + count <= sysfile->iobuf_end )
319  {
320  /* we have buffer and requested bytes are all inside our buffer */
321  CopyMem( &sysfile->iobuf[offset - sysfile->iobuf_start], buffer, count );
322  read_bytes = count;
323  }
324  else
325  {
326  /* (re)fill buffer */
327  if ( count <= IOBUF_SIZE )
328  {
329  /* requested bytes is a subset of the buffer */
330  read_bytes = Read( sysfile->file, sysfile->iobuf, IOBUF_SIZE );
331  if ( read_bytes == -1UL )
332  {
333  /* error */
334  read_bytes = 0;
335  }
336  else
337  {
338  sysfile->iobuf_end = offset + read_bytes;
339  CopyMem( sysfile->iobuf, buffer, count );
340  if ( read_bytes > count )
341  {
342  read_bytes = count;
343  }
344  }
345  }
346  else
347  {
348  /* we actually need more than our buffer can hold, so we decide
349  ** to do a single big read, and then copy the last IOBUF_SIZE
350  ** bytes of that to our internal buffer for later use */
351  read_bytes = Read( sysfile->file, buffer, count );
352  if ( read_bytes == -1UL )
353  {
354  /* error */
355  read_bytes = 0;
356  }
357  else
358  {
359  ULONG bufsize;
360 
361  bufsize = ( read_bytes > IOBUF_SIZE ) ? IOBUF_SIZE : read_bytes;
362  sysfile->iobuf_end = offset + read_bytes;
363  sysfile->iobuf_start = sysfile->iobuf_end - bufsize;
364  CopyMem( &buffer[read_bytes - bufsize] , sysfile->iobuf, bufsize );
365  }
366  }
367  }
368  }
369  else
370  {
371  read_bytes = 0;
372  }
373 
374  return read_bytes;
375  }
376 
377 
378  /* documentation is in ftobjs.h */
379 
382  const char* filepathname )
383  {
384  struct FileInfoBlock* fib;
385  struct SysFile* sysfile;
386 
387 
388  if ( !stream )
389  return FT_Err_Invalid_Stream_Handle;
390 
391 #ifdef __amigaos4__
392  sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_SHARED );
393 #else
394  sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_PUBLIC );
395 #endif
396  if ( !sysfile )
397  {
398  FT_ERROR(( "FT_Stream_Open:" ));
399  FT_ERROR(( " could not open `%s'\n", filepathname ));
400 
401  return FT_Err_Cannot_Open_Resource;
402  }
403  sysfile->file = Open( (STRPTR)filepathname, MODE_OLDFILE );
404  if ( !sysfile->file )
405  {
406  FreeMem ( sysfile, sizeof ( struct SysFile ));
407  FT_ERROR(( "FT_Stream_Open:" ));
408  FT_ERROR(( " could not open `%s'\n", filepathname ));
409 
410  return FT_Err_Cannot_Open_Resource;
411  }
412 
413  fib = AllocDosObject( DOS_FIB, NULL );
414  if ( !fib )
415  {
416  Close ( sysfile->file );
417  FreeMem ( sysfile, sizeof ( struct SysFile ));
418  FT_ERROR(( "FT_Stream_Open:" ));
419  FT_ERROR(( " could not open `%s'\n", filepathname ));
420 
421  return FT_Err_Cannot_Open_Resource;
422  }
423  if ( !( ExamineFH( sysfile->file, fib ) ) )
424  {
425  FreeDosObject( DOS_FIB, fib );
426  Close ( sysfile->file );
427  FreeMem ( sysfile, sizeof ( struct SysFile ));
428  FT_ERROR(( "FT_Stream_Open:" ));
429  FT_ERROR(( " could not open `%s'\n", filepathname ));
430 
431  return FT_Err_Cannot_Open_Resource;
432  }
433  stream->size = fib->fib_Size;
434  FreeDosObject( DOS_FIB, fib );
435 
436  stream->descriptor.pointer = (void *)sysfile;
437  stream->pathname.pointer = (char*)filepathname;
438  sysfile->iobuf_start = 0;
439  sysfile->iobuf_end = 0;
440  stream->pos = 0;
441 
442  stream->read = ft_amiga_stream_io;
443  stream->close = ft_amiga_stream_close;
444 
445  if ( !stream->size )
446  {
448  FT_ERROR(( "FT_Stream_Open:" ));
449  FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
450  return FT_Err_Cannot_Open_Stream;;
451  }
452 
453  FT_TRACE1(( "FT_Stream_Open:" ));
454  FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
455  filepathname, stream->size ));
456 
457  return FT_Err_Ok;
458  }
459 
460 
461 #ifdef FT_DEBUG_MEMORY
462 
463  extern FT_Int
464  ft_mem_debug_init( FT_Memory memory );
465 
466  extern void
467  ft_mem_debug_done( FT_Memory memory );
468 
469 #endif
470 
471 
472  /* documentation is in ftobjs.h */
473 
476  {
477  FT_Memory memory;
478 
479 
480 #ifdef __amigaos4__
481  memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_SHARED );
482 #else
483  memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_PUBLIC );
484 #endif
485  if ( memory )
486  {
487 #ifdef __amigaos4__
488  memory->user = CreatePool( MEMF_SHARED, 16384, 16384 );
489 #else
490  memory->user = CreatePool( MEMF_PUBLIC, 16384, 16384 );
491 #endif
492  if ( memory->user == NULL )
493  {
494  FreeVec( memory );
495  memory = NULL;
496  }
497  else
498  {
499  memory->alloc = ft_alloc;
500  memory->realloc = ft_realloc;
501  memory->free = ft_free;
502 #ifdef FT_DEBUG_MEMORY
503  ft_mem_debug_init( memory );
504 #endif
505  }
506  }
507 
508  return memory;
509  }
510 
511 
512  /* documentation is in ftobjs.h */
513 
514  FT_BASE_DEF( void )
516  {
517 #ifdef FT_DEBUG_MEMORY
518  ft_mem_debug_done( memory );
519 #endif
520 
521  DeletePool( memory->user );
522  FreeVec( memory );
523  }
524 
525 /*
526 Local Variables:
527 coding: latin-1
528 End:
529 */
530 /* END */
GLenum GLuint GLsizei bufsize
int FT_Error
Definition: fttypes.h:296
FT_New_Memory(void)
Definition: ftsystem.c:475
GLuint GLuint stream
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
struct Library * SysBase
return FT_Err_Ok
Definition: ftbbox.c:645
ft_amiga_stream_close(FT_Stream stream)
Definition: ftsystem.c:257
struct Library * DOSBase
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define const
Definition: zconf.h:91
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_BASE_DEF(x)
Definition: ftconfig.h:258
FT_Stream_Open(FT_Stream stream, const char *filepathname)
Definition: ftsystem.c:381
void Free_VecPooled(APTR poolHeader, APTR memory)
Definition: ftsystem.c:88
GLuint buffer
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:323
GLintptr offset
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
ft_free(FT_Memory memory, void *block)
Definition: ftsystem.c:213
ft_amiga_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count)
Definition: ftsystem.c:292
APTR Alloc_VecPooled(APTR poolHeader, ULONG memSize)
Definition: ftsystem.c:74
#define IOBUF_SIZE
Definition: ftsystem.c:58
GLuint GLuint GLsizei count
ft_alloc(FT_Memory memory, long size)
Definition: ftsystem.c:141
FT_Done_Memory(FT_Memory memory)
Definition: ftsystem.c:515
#define STREAM_FILE(stream)
Definition: ftsystem.c:242
GLsizeiptr size
ft_realloc(FT_Memory memory, long cur_size, long new_size, void *block)
Definition: ftsystem.c:173