]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/thirdparty/freetype/builds/amiga/src/base/ftsystem.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / thirdparty / freetype / builds / amiga / src / base / ftsystem.c
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* )
141   ft_alloc( FT_Memory  memory,
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* )
173   ft_realloc( FT_Memory  memory,
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 )
213   ft_free( FT_Memory  memory,
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 )
257   ft_amiga_stream_close( FT_Stream  stream )
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 )
292   ft_amiga_stream_io( FT_Stream       stream,
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
380   FT_BASE_DEF( FT_Error )
381   FT_Stream_Open( FT_Stream    stream,
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     {
447       ft_amiga_stream_close( stream );
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
474   FT_BASE_DEF( FT_Memory )
475   FT_New_Memory( void )
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 )
515   FT_Done_Memory( FT_Memory  memory )
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 */