Initial revision

This commit is contained in:
David Turner 1999-12-16 23:11:37 +00:00
commit d2b1f35704
210 changed files with 84971 additions and 0 deletions

176
CHANGES Normal file
View File

@ -0,0 +1,176 @@
This file summarizes the changes that occured since the last "beta" of FreeType 2.
Because the list is important, it has been divided into separate sections:
-----------------------------------------------------------------------------------------
High-Level Interface :
The high-level API has been considerably simplified. Here is how :
- resource objects have disappeared. this means that face objects can now
be created with a single function call (see FT_New_Face and
FT_Open_Face)
- when calling either FT_New_Face & FT_Open_Face, a size object and a
glyph slot object are automatically created for the face, and can be
accessed through "face->glyph" and "face->size" if one really needs to.
In most cases, there's no need to call FT_New_Size or FT_New_Glyph.
- similarly, FT_Load_Glyph now only takes a "face" argument (instead of
a glyph slot and a size). Also, it's "result" parameter is gone, as
the glyph image type is returned in the field "face->glyph.format"
- the list of available charmaps is directly accessible through
"face->charmaps", counting "face->num_charmaps" elements. Each
charmap has an 'encoding' field which specifies which known encoding
it deals with. Valid values are, for example :
ft_encoding_unicode (for ASCII, Latin-1 and Unicode)
ft_encoding_apple_roman
ft_encoding_sjis
ft_encoding_adobe_standard
other values may be added in the future. Each charmap still holds its
"platform_id" and "encoding_id" values in case the encoding is too
exotic for the current library
-----------------------------------------------------------------------------------------
Directory Structure:
Should seem obvious to most of you:
freetype/
config/ -- configuration sub-makefiles
ansi/
unix/
win32/
os2/
msdos/
include/ -- public header files, those to be included directly
by client apps
src/ -- sources of the library
base/ -- the base layer
sfnt/ -- the sfnt "driver" (see the drivers section below)
truetype/ -- the truetype driver
type1/ -- the type1 driver
shared/ -- some header files shared between drivers
demos/ -- demos/tools
docs/ -- documentation (a bit empty for now)
-----------------------------------------------------------------------------------------
Glyph Image Formats :
Drivers are now able to register new glyph image formats within the library.
For now, the base layer supports of course bitmaps and vector outlines, but
one could imagine something different like colored bitmaps, bi-color
vectors or wathever else (Metafonts anyone ??).
See the file `include/ftimage.h'. Note also that the type FT_Raster_Map is
gone, and is now replaced by FT_Bitmap, which should encompass all known
bitmap types.
Each new image format must provide at least one "raster", i.e. a module
capable of transforming the glyph image into a bitmap. It is also possible
to change the default raster used for a given glyph image format.
The default outline scan-converter now uses 128 levels of grays by default,
which tends to smooth many things. Note that the demo programs have been
updated significantly to be able to display these..
-----------------------------------------------------------------------------------------
Build system :
You still need GNU Make to build the library. The build system has been
very seriously re-vamped in order to provide things like :
- automatic host platform detection (reverting to 'config/ansi'
if it is not detected, with pseudo-standard compilation flags)
- the ability to compile from the Makefiles with very different and
exotic compilers. Note that linking the library can be difficult for
some platforms.
For example, the file `config/win32/lcclib.bat' is invoked by the
build system to create the ".lib" file with LCC-Win32 because its
librarian has too many flaws to be invoked directly from the Makefile.
Here's how it works :
- the first time you type `make', the build system runs a series of
sub-makefiles in order to detect your host platform. It then dumps
what it found, and creates a file called `config.mk' in the current
directory. This is a sub-Makefile used to define many important Make
variables used to build the library.
- the second time, the build system detects the `config.mk' then use it
to build the library. All object files go into 'obj' by default, as
well as the library file, but this can easily be changed.
Note that you can run "make setup" to force another host platform detection
even if a `config.mk' is present in the current directory. Another solution
is simply to delete the file, then re-run make.
Finally, the default compiler for all platforms is gcc (for now, this will
hopefully changed in the future). You can however specify a different
compiler by specifying it after the 'setup' target as in :
gnumake setup lcc on Win32 to use the LCC compiler
gnumake setup visualc on Win32 to use Visual C++
See the file `config/<system>/detect.mk' for a list of supported compilers
for your platforms.
It should be relatively easy to write new detection rules files and
config.mk..
Finally, to build the demo programs, go to `demos' and launch GNU Make,
it will use the `config.mk' in the top directory to build the test
programs..
-----------------------------------------------------------------------------------------
Portability :
In the previous beta, a single FT_System object was used to encompass
all low-level operations like thread synchronisation, memory management
and i/o access. This has been greatly simplified :
- thread synchronisation has been dropped, for the simple reason that
the library is already re-entrant, and that if you really need two
threads accessing the same FT_Library, you should really synchronize
access to it yourself with a simple mutex.
- memory management is performed through a very simple object called
"FT_Memory", which really is a table containing a table of pointers
to functions like malloc, realloc and free as well as some user data
(closure).
- resources have disappeared (they created more problems than they
solved), and i/o management have been simplified greatly as a
result. Streams are defined through FT_Stream objects, which can
be either memory-based or disk-based.
Note that each face has its own stream, which is closed only when
the face object is destroyed. Hence, a function like TT_Flush_Face
in 1.x cannot be directly supported. However, if you really need
something like this, you can easily tailor your own streams to achieve
the same feature at a lower level (and use FT_Open_Face instead of
FT_New_Face to create the face).
See the file "include/ftsystem.h" for more details, as well as the
implementations found in "config/unix" and "config/ansi".
-----------------------------------------------------------------------------------------
Drivers Interface :
(To be written)
-----------------------------------------------------------------------------------------
Extensions support :
(To be defined)

90
Makefile Normal file
View File

@ -0,0 +1,90 @@
#******************************************************************************
#*
#* FreeType build system - top-level Makefile
#*
#* This file is designed for GNU Make, do not use it with another Make tool.
#* It works as follows :
#*
#* - when invoked for the first time, this Makefile will include
#* the rules found in `freetype/config/detect.mk'. They are in charge
#* of detecting the current platform.
#*
#* A summary of the detection will be displayed, and the file `config.mk'
#* will be created in the current directory
#*
#*
#* - when invoked later, this Makefile will include the rules found in
#* `config.mk'. This sub-Makefile will define some system-specific
#* variables (like compiler, compilation flags, object suffix, etc..),
#* then include the rules found in `freetype/config/freetype.mk',
#* used to build the library.
#*
#* See the comments in `config/detect.mk' and `config/freetype.mk' for
#* more details on host platform detection and library builds..
#*
#******************************************************************************
.PHONY: setup
#
# The variable TOP holds the path to the topmost directory in the FreeType
# engine source hierarchy. If it is not defined, default it to '.'
#
ifndef TOP
TOP := .
endif
CONFIG_MK := config.mk
#############################################################################
#
# If no configuration sub-makefile is present, or if "setup" is the target
# to be built, run the auto-detection rules to figure out which configuration
# rules file to use..
#
# Note that the configuration file is put in the current directory, which is
# not necessarily TOP.
#
# if `config.mk' is not present, set "check_platform" and "first_time"
#
ifeq ($(wildcard $(CONFIG_MK)),)
check_platform := 1
first_time := 1
endif
# if `setup' is one of the targets requested, set "check_platform"
#
ifneq ($(findstring setup,$(MAKECMDGOALS)),)
check_platform := 1
endif
#########################################################################
#
# include the automatic host platform detection rules when we need to
# check the platform.
#
#
ifdef check_platform
all: setup
include $(TOP)/config/detect.mk
# "setup" must be defined by the host platform detection rules
else
########################################################################
#
# A configuration sub-Makefile is present, simply run it..
#
#
all: build_freetype
BUILD_FREETYPE := yes
include $(CONFIG_MK)
endif #test check_platform

178
config/ansi/Makefile Normal file
View File

@ -0,0 +1,178 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for a `normal' ANSI compiler
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := rm -f
SEP := /
BUILD := $(TOP)/config/ansi
PLATFORM := ansi
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c
endif
# Now include the main sub-makefile. It contains all the rules used
# to build the library with the previous variables defined
#
include $(TOP)/config/freetype.mk
# Librarian to use to build the static library
#
FT_LIBRARIAN := $(AR) -r
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)

182
config/ansi/ftconfig.h Normal file
View File

@ -0,0 +1,182 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* ANSI-specific configuration file (specification only). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This header file contains a number of macro definitions that are used */
/* by the rest of the engine. Porters are free to copy this file and */
/* adapt it to suit their own system. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in `ftsys.h' before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#ifndef FTCONFIG_H
#define FTCONFIG_H
/* Include the header file containing all developer build options */
#include <ftoption.h>
/*************************************************************************/
/* */
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
/* */
/* These macros can be toggled to suit a specific system. The current */
/* ones are defaults used to compile FreeType in an ANSI C environment */
/* (16bit compilers are also supported). Copy this file to your own */
/* `freetype/arch/<system>' directory, and edit it to port the engine. */
/* */
/*************************************************************************/
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* We use <limits.h> values to know the sizes of the types. */
#include <limits.h>
/* The number of bytes in an `int' type. */
#if UINT_MAX == 0xFFFFFFFF
#define SIZEOF_INT 4
#elif UINT_MAX == 0xFFFF
#define SIZEOF_INT 2
#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_INT 8
#else
#error "Unsupported number of bytes in `int' type!"
#endif
/* The number of bytes in a `long' type. */
#if ULONG_MAX == 0xFFFFFFFF
#define SIZEOF_LONG 4
#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_LONG 8
#else
#error "Unsupported number of bytes in `long' type!"
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 0
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/*************************************************************************/
/* */
/* AUTOMATIC CONFIGURATION MACROS */
/* */
/* These macros are computed from the ones defined above. Don't touch */
/* their definition, unless you know precisely what you're doing. No */
/* porter should need to mess with them. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* IntN types */
/* */
/* Used to guarantee the size of some specific integers. */
/* */
typedef signed short FT_Int16;
typedef unsigned short FT_Word16;
#if SIZEOF_INT == 4
typedef signed int FT_Int32;
typedef unsigned int FT_Word32;
#elif SIZEOF_LONG == 4
typedef signed long FT_Int32;
typedef unsigned long FT_Word32;
#else
#error "no 32bit type found - please check your configuration files"
#endif
#if SIZEOF_LONG == 8
/* LONG64 must be defined when a 64-bit type is available */
#define LONG64
#define INT64 long
#else
/*************************************************************************/
/* */
/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
/* that this will produce many -ansi warnings during library */
/* compilation. */
/* */
#ifdef FTCALC_USE_LONG_LONG
#define LONG64
#define INT64 long long
#endif /* FTCALC_USE_LONG_LONG */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define LOCAL_DEF static
#define LOCAL_FUNC static
#else
#define LOCAL_DEF extern
#define LOCAL_FUNC /* nothing */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
#define BASE_DEF LOCAL_DEF
#define BASE_FUNC LOCAL_FUNC
#else
#define BASE_DEF extern
#define BASE_FUNC /* nothing */
#endif
#ifndef EXPORT_DEF
#define EXPORT_DEF extern
#endif
#ifndef EXPORT_FUNC
#define EXPORT_FUNC /* nothing */
#endif
#endif /* FTCONFIG_H */
/* END */

162
config/ansi/ftoption.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_EXTENSIONS */
/* */
/* The maximum number of extensions that can be registered in a */
/* single font driver. 8 seems to be a good choice for now.. */
/* */
#define FT_MAX_EXTENSIONS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

971
config/ansi/ftsys.c Normal file
View File

@ -0,0 +1,971 @@
/***************************************************************************/
/* */
/* ftsys.c */
/* */
/* ANSI-specific system operations (body). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This implementation of the `ftsys' component uses the standard ANSI C */
/* library. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in ftsys.h before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#include "ftsys.h"
#include "ftstream.h"
#include "ftdebug.h"
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
#include "memdebug.c"
#endif
/*************************************************************************/
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_io
#undef CUR_SYSTEM /* just in case */
/*************************************************************************/
/* */
/* To ease porting, we use the macro SYS_STREAM to name the */
/* system-specific stream type. For example, it is a `FILE*' with the */
/* ANSI libc, it will be a file descriptor, i.e. an integer, when using */
/* the Unix system API, etc. */
/* */
#define SYS_STREAM FILE*
/*************************************************************************/
/* */
/* This implementation of ftsys uses the ANSI C library. Memory */
/* management is performed through malloc/free, i/o access through */
/* fopen/fread/fseek, and no synchronisation primitive is implemented */
/* (they contain dummy code) */
/* */
/*************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/*************************************************************************/
/* */
/* I/O ACCESS AND MANAGEMENT */
/* */
/* We only define the `ANSI' resource class in this class. It is */
/* disk-based and provides a MRU cache in order to only keep the file */
/* descriptors of the 10 most recently used resource files. */
/* */
/* It simply contains two lists. One contains the `cached' resources */
/* with a valid FILE* pointer, the second contains all other `flushed' */
/* resource objects. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Struct> */
/* FT_AnsiFileRec */
/* */
/* <Description> */
/* The FT_AnsiFile class derives from FT_ResourceRec. */
/* */
/* <Fields> */
/* root :: The root resource class fields. */
/* */
/* pathname :: This is a copy of the ANSI file pathname used to open */
/* streams for the resource. A different implementation */
/* is free to use Unicode chars, or file i-node numbers, */
/* etc. */
/* */
/* file_size :: The size in bytes of the resource. This field should */
/* be set to -1 until the resource is first opened. */
/* */
typedef struct FT_AnsiFileRec_
{
FT_ResourceRec root;
char* pathname; /* the font file's pathname */
FT_Long file_size; /* file size in bytes */
} FT_AnsiFileRec, *FT_AnsiFile;
/*************************************************************************/
/* */
/* We use the macro STREAM_Name() as a convenience to return a given */
/* ANSI resource's pathname. Its `stream' argument is a FT_Resource */
/* which is typecasted to the FT_AnsiFile class. */
/* */
#define STREAM_Name( stream ) ((FT_AnsiFile)stream->resource)->pathname
/*************************************************************************/
/* */
/* We use the macro STREAM_File() as a convenience to extract the */
/* system-specific stream handle from a given FreeType stream object. */
/* */
#define STREAM_File( stream ) ((FILE*)stream->stream_id.pointer)
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Open */
/* */
/* <Description> */
/* This function is used to open a system-stream for a given */
/* resource. */
/* */
/* Note that it must update the target FreeType stream object with */
/* the system-stream handle and the resource's size. */
/* */
/* Also, the `stream->base' field must be set to NULL for disk-based */
/* resources, and to the address in memory of the resource's first */
/* byte for memory-based ones. */
/* */
/* <Input> */
/* resource :: The source resource. */
/* stream :: The target stream object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls fopen() in the resource's file */
/* pathname. */
/* */
/* The stream object IS NOT CREATED by this function, but by its */
/* caller. */
/* */
static
FT_Error AnsiFile_Open( FT_AnsiFile resource,
FT_Stream stream )
{
FILE* file;
/* open the file */
file = fopen( resource->pathname, "rb" );
if ( !file )
{
PERROR(( "AnsiFile_Open: Could not open file `%s'\n",
resource->pathname ));
return FT_Err_Cannot_Open_Stream;
}
/* compute file size if necessary */
if ( resource->file_size < 0 )
{
fseek( file, 0, SEEK_END );
resource->file_size = ftell( file );
fseek( file, 0, SEEK_SET );
}
stream->resource = (FT_Resource)resource;
stream->stream_id.pointer = file;
stream->size = resource->file_size;
/* it's a disk-based resource, we don't need to use the `base' and */
/* `cursor' fields of the stream objects */
stream->base = NULL;
stream->cursor = NULL;
PTRACE1(( "AnsiFile_Open: Opened `%s' (%d bytes) successfully\n",
resource->pathname, resource->file_size ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Close */
/* */
/* <Description> */
/* Closes a given stream. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls fclose() on the stream's ANSI FILE */
/* object. */
/* */
static
FT_Error AnsiFile_Close( FT_Stream stream )
{
PTRACE1(( "AnsiFile_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
fclose( STREAM_File( stream ) );
stream->resource = NULL;
stream->stream_id.pointer = NULL;
stream->size = 0;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Seek */
/* */
/* <Description> */
/* Seeks a stream to a given position. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* position :: The offset in bytes from the start of the */
/* resource/stream. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls fseek() on the stream. */
/* */
/* The `seek' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error AnsiFile_Seek( FT_Stream stream,
FT_Long position )
{
if ( fseek( STREAM_File( stream ), position, SEEK_SET ) )
{
PERROR(( "AnsiFile_Seek: FAILED! Pos. %ld of `%s'\n",
position, STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Seek: Pos. %ld of `%s'\n",
position, STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Skip */
/* */
/* <Description> */
/* Skips a given number of bytes in an ANSI stream. Useful to skip */
/* pad bytes, for example. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* count :: The number of bytes to skip in the stream. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls fseek() on the stream. */
/* */
/* The `skip' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error AnsiFile_Skip( FT_Stream stream,
FT_Long count )
{
if ( fseek( STREAM_File( stream ), count, SEEK_CUR ) )
{
PERROR(( "AnsiFile_Skip: FAILED! %ld bytes in `%s'\n",
count, STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Skip: %ld bytes in `%s'\n",
count, STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Pos */
/* */
/* <Description> */
/* Returns the current offset within an ANSI stream's resource. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* */
/* <Output> */
/* position :: The current offset. -1 in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls ftell() on the stream. */
/* */
/* The `pos' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error AnsiFile_Pos( FT_Stream stream,
FT_Long* position )
{
*position = ftell( STREAM_File( stream ) );
if ( *position == -1 )
{
PTRACE2(( "AnsiFile_Pos: FAILED! In `%s'\n", STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Pos: For `%s'\n", STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* AnsiFile_Read */
/* */
/* <Description> */
/* Reads a given number of bytes from an ANSI stream into memory. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* buffer :: The target read buffer where data is copied. */
/* size :: The number of bytes to read from the stream. */
/* */
/* <Output> */
/* read_bytes :: The number of bytes effectively read from the */
/* stream. Used in case of error */
/* (i.e. FT_Err_Invalid_Stream_Read) by some parts of */
/* the library. */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* This function simply calls fread() on the stream. */
/* */
/* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
/* an over-read (i.e., reading more bytes from the stream that what */
/* is left), as the stream component checks for this specific value. */
/* */
/* The `read' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error AnsiFile_Read( FT_Stream stream,
FT_Char* buffer,
FT_Long size,
FT_Long* read_bytes )
{
*read_bytes = fread( buffer, 1, size, STREAM_File( stream ) );
if ( *read_bytes != size )
{
/* Note : we can have an over-read here when called by the */
/* function FT_Access_Compressed_Frame. This means */
/* that the following message should be a trace, */
/* rather than an error for disk-based resources.. */
/* */
/* the function must set the value of 'read_bytes' */
/* even if it returns an error code.. */
PTRACE2(( "AnsiFile_Read: FAILED! Read %ld bytes from '%s'\n",
size, STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Read;
}
PTRACE2(( "AnsiFile_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
size, (long)buffer, STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* The following table is the `virtual method table' for the `ANSI */
/* resource class', which methods are defined above. Its address is set */
/* in the `interface' field of all resource objects created by the */
/* function FT_Create_AnsiFile() (see below). */
/* */
static
FTRes_InterfaceRec FT_AnsiFile_Interface =
{
(FTRes_Open_Func) AnsiFile_Open,
(FTRes_Close_Func)AnsiFile_Close,
(FTRes_Seek_Func) AnsiFile_Seek,
(FTRes_Skip_Func) AnsiFile_Skip,
(FTRes_Pos_Func) AnsiFile_Pos,
(FTRes_Read_Func) AnsiFile_Read,
};
/*************************************************************************/
/* */
/* <Function> */
/* FT_Create_Resource */
/* */
/* <Description> */
/* Creates a new resource object. This function is called by the */
/* FT_New_Resource() function of the base layer. */
/* */
/* <Input> */
/* library :: The input library object. */
/* pathname :: The file's pathname as an ASCII string. */
/* */
/* <Output> */
/* aresource :: A handle to new resource object. */
/* */
/* <Return> */
/* Error code. 0 means success. */
/* */
/* <Note> */
/* This functions does not open a stream. It simply copies the */
/* pathname within a fresh new resource object. */
/* */
EXPORT_FUNC
FT_Error FT_Create_Resource( FT_Library library,
const char* pathname,
FT_Resource* aresource )
{
FT_Int len;
FT_AnsiFile resource;
FT_Error error;
FT_System system;
if ( !library )
return FT_Err_Invalid_Library_Handle;
system = library->system;
if ( !pathname )
goto Fail_Null;
len = strlen( pathname );
if ( len == 0 )
goto Fail_Null;
resource = NULL;
if ( ALLOC( resource, sizeof ( *resource ) ) ||
ALLOC( resource->pathname, len + 1 ) )
goto Fail_Memory;
resource->root.library = library;
resource->root.interface = &FT_AnsiFile_Interface;
resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
resource->file_size = -1;
strcpy( resource->pathname, pathname );
PTRACE1(( "Create_AnsiFile: Ansi resource created for `%s'\n",
pathname ));
*aresource = (FT_Resource)resource;
return FT_Err_Ok;
Fail_Null:
PERROR(( "Create_AnsiFile: Null pathname!\n" ));
return FT_Err_Invalid_Argument;
Fail_Memory:
if ( resource )
FREE( resource->pathname );
FREE( resource );
PERROR(( "Create_AnsiFile: Not enough memory to create resource!\n" ));
return error;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Destroy_Resource */
/* */
/* <Description> */
/* Discards a given resource object explicitly. */
/* */
/* <Input> */
/* resource :: The ANSI resource object. */
/* */
/* <Note> */
/* This function does not check whether runs or streams are opened */
/* for the resource (for now, we assume developer intelligence. */
/* We'll most probably lower our standard later to ease debugging :-) */
/* */
EXPORT_FUNC
FT_Error FT_Destroy_Resource( FT_Resource resource )
{
FT_System system = resource->library->system;
FT_AnsiFile ansi = (FT_AnsiFile)resource;
if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
{
PERROR((
"Destroy_AnsiFile: Trying to destroy an invalid resource!\n" ));
return FT_Err_Invalid_Resource_Handle;
}
PTRACE1(( "Destroy_AnsiFile: Destroying resource for `%s'\n",
ansi->pathname ));
FREE( ansi->pathname );
FREE( ansi );
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* MEMORY MANAGEMENT */
/* */
/* */
/* This part copies the old FreeType 1.0 and 1.1 memory management */
/* scheme that was defined in the file `ttmemory.h'. One can see that */
/* */
/* - a set of macros is defined for the memory operations used by the */
/* engine (MEM_Copy(), MEM_Move(), MEM_Set()). This comes from the */
/* fact that many compilers are able to inline these operations */
/* directly within the compiled code, rather than generating a call */
/* to the C library. However, this obliges us to include the */
/* `<string.h>' header file. */
/* */
/* If you provide your own memory operations, you can get rid of the */
/* `#include <string.h>' below. */
/* */
/* */
/* - the FT_Alloc() function has several essential properties that MUST */
/* be retained by each port: */
/* */
/* - It returns an error code, NOT the allocated block's base */
/* address. */
/* */
/* - It takes the address of a target pointer, where the block's base */
/* address will be set. If the size is zero, its value will be */
/* NULL, and the function returns successfully. */
/* */
/* - In case of error, the pointer's value is set to NULL and an */
/* error code is returned. */
/* */
/* - The new allocated block MUST be zero-filled. This is a strong */
/* convention the rest of the engine relies on. */
/* */
/* */
/* - the FT_Free() function has also its essentials: */
/* */
/* - It takes the address of a pointer which value is the block's */
/* base address. This is UNLIKE a standard `free()' which takes */
/* the block's base directly. */
/* */
/* - It accepts successfully the address of a pointer which value is */
/* NULL, in which case it simply returns. */
/* */
/* - The pointer is always set to NULL by the function. */
/* */
/* */
/* - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
/* library and should NOT be modified by porters! */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_memory
/*************************************************************************/
/* */
/* <Function> */
/* FT_Alloc */
/* */
/* <Description> */
/* Allocates a new block of memory. The returned area is always */
/* zero-filled, this is a strong convention in many FreeType parts. */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occurs. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <Output> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
FT_Error FT_Alloc( FT_System system,
FT_Long size,
void** P )
{
if ( !P )
{
PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
return FT_Err_Invalid_Argument;
}
if ( size > 0 )
{
*P = malloc( size );
if ( !*P )
{
PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
size ));
return FT_Err_Out_Of_Memory;
}
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Record( (char*)*P, size );
#endif
system->total_alloc += size;
/* ALWAYS ZERO-FILL THE BLOCK! */
MEM_Set( *P, 0, size );
}
else
*P = NULL;
PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
size, (long)P, (long)*P ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Realloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
/* from the heap, possibly changing `*P'. */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occurs. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <InOut> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
FT_Error FT_Realloc( FT_System system,
FT_Long size,
void* *P )
{
void* Q;
if ( !P )
{
PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
return FT_Err_Invalid_Argument;
}
/* if the original pointer is NULL, call FT_Alloc() */
if ( !*P )
return FT_Alloc( system, size, P );
/* if the new block if zero-sized, clear the current one */
if ( size <= 0 )
return FT_Free( system, P );
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Forget( (char*)*P );
#endif
Q = (void*)realloc( *P, size );
if ( !Q )
{
PERROR(( "FT_Realloc: Reallocation failed!\n" ));
return FT_Err_Out_Of_Memory;
}
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Record( (char*)Q, size );
#endif
*P = Q;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Free */
/* */
/* <Description> */
/* Releases a given block of memory allocated through FT_Alloc(). */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occured. */
/* */
/* P :: This is the _address_ of a _pointer_ which points to the */
/* allocated block. It is always set to NULL on exit. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* If P or *P are NULL, this function should return successfully. */
/* This is a strong convention within all of FreeType and its */
/* drivers. */
/* */
BASE_FUNC
FT_Error FT_Free( FT_System system,
void* *P )
{
UNUSED( system );
PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
(long)P, (P ? (long)*P : -1) ));
if ( !P || !*P )
return FT_Err_Ok;
free( *P );
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Forget( (char*)*P );
#endif
*P = NULL;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* SYNCHRONIZATION MANAGEMENT */
/* */
/* */
/* This section deals with mutexes. The library can be compiled to */
/* two distinct thread support levels (namely single threaded and */
/* re-entrant modes). */
/* */
/* It protects its variables through the MUTEX_Lock() and */
/* MUTEX_Release() macros which are void in single threaded mode. */
/* */
/* It defines a typeless mutex reference type, `FT_Mutex', that you're */
/* free to redefine for your system's needs. */
/* */
/* The default implementation of ftsys.c contains only dummy functions */
/* which always return successfully. You NEED to specialize them in */
/* order to port ftsys.c to any multi-threaded environment. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_sync
#ifdef FT_CONFIG_THREADS
BASE_FUNC
FT_Error FT_Mutex_Create( FT_System system,
TMutex* mutex )
{
UNUSED( system );
mutex = (void*)-1;
system->num_mutexes++;
/* Insert your own mutex creation code here */
return FT_Err_Ok;
}
BASE_FUNC
void FT_Mutex_Delete( FT_System system,
TMutex* mutex )
{
UNUSED( system );
mutex = (void*)0;
system->num_mutexes--;
/* Insert your own mutex destruction code here */
}
BASE_FUNC
void FT_Mutex_Lock( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate. */
UNUSED( system );
if ( !mutex )
return;
/* Insert your own mutex locking code here */
}
BASE_FUNC
void FT_Mutex_Release( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate */
UNUSED( system );
if ( !mutex )
return;
/* Insert your own mutex release code here */
}
#endif /* FT_CONFIG_THREADS */
/*************************************************************************/
/* */
/* <Function> */
/* FT_New_System */
/* */
/* <Description> */
/* This function is used to create and initialize new system objects. */
/* These are mainly used to let client applications and font servers */
/* specify their own memory allocators and synchronization */
/* procedures. */
/* */
/* <Output> */
/* system :: A handle to a given `system object'. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
EXPORT_FUNC
FT_Error FT_New_System( FT_System* system )
{
*system = (FT_System)malloc( sizeof ( **system ) );
if ( !*system )
return FT_Err_Out_Of_Memory;
/* the ANSI function `free()' is unable to return the number */
/* of released bytes. Hence, the `current_alloc' field of the */
/* system object cannot be used. */
(*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
FT_SYSTEM_FLAG_MUTEXES;
(*system)->total_alloc = 0;
(*system)->num_mutexes = 0;
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Init_Mem();
#endif
/* initialize i/o management (nothing) */
/* initialize synchronisation (nothing) */
/* initialize streams (nothing) */
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Done_System */
/* */
/* <Description> */
/* Destroys a given FreeType system object. */
/* */
/* <Input> */
/* system :: A handle to a given `system object'. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
EXPORT_FUNC
FT_Error FT_Done_System( FT_System system )
{
/* finalize synchronization (nothing) */
/* finalize i/o management (nothing) */
/* finalize memory management */
#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
DM_Done_Mem();
#endif
free( system );
return FT_Err_Ok;
}
/* END */

214
config/ansi/ftsystem.c Normal file
View File

@ -0,0 +1,214 @@
/**************************************************************************
*
* ftsystem.h 1.0
*
* ANSI-specific FreeType low-level system interface
*
* This file contains the definition of interface used by FreeType
* to access low-level, i.e. memory management, i/o access as well
* as thread synchronisation.
*
*
* Copyright 1996-1999 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
**************************************************************************/
#include <ftsystem.h>
#include <fterrors.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/************************************************************************
*
* <FuncType>
* FT_Alloc_Func
*
* <Description>
* The memory allocator function type
*
* <Input>
* system :: pointer to the system object
* size :: requested size in bytes
*
* <Output>
* block :: address of newly allocated block
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* If your allocation routine ALWAYS zeroes the new block, you
* should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
* object 'flags' field.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_alloc( FT_Memory memory,
long size )
{
(void)memory;
return malloc(size);
}
/************************************************************************
*
* <FuncType>
* FT_Realloc_Func
*
* <Description>
* The memory reallocator function type
*
* <Input>
* system :: pointer to the system object
* new_size :: new requested size in bytes
*
* <InOut>
* block :: address of block in memory
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function is _never_ called when the system flag
* FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
* realloc through "alloc" and "free".
*
* Note that this is possible due to the fact that FreeType's
* "FT_Realloc" always requests the _current_ size of the reallocated
* block as a parameter, thus avoiding memory leaks.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
(void)memory;
(void)cur_size;
return realloc( block, new_size );
}
/************************************************************************
*
* <FuncType>
* FT_Free_Func
*
* <Description>
* The memory release function type
*
* <Input>
* system :: pointer to the system object
* block :: address of block in memory
*
* <Note>
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void ft_free( FT_Memory memory,
void* block )
{
(void)memory;
free( block );
}
/*********************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
static
void ft_close_stream( FT_Stream stream )
{
fclose( STREAM_FILE(stream) );
}
static
unsigned long ft_io_stream( FT_Stream stream,
unsigned long offset,
char* buffer,
unsigned long count )
{
FILE* file;
file = STREAM_FILE(stream);
fseek( file, offset, SEEK_SET );
return (unsigned long)fread( buffer, count, 1, file );
}
extern
int FT_New_Stream( const char* filepathname,
FT_Stream stream )
{
FILE* file;
file = fopen( filepathname, "rb" );
if (!file)
return FT_Err_Cannot_Open_Resource;
fseek( file, 0, SEEK_END );
stream->size = ftell(file);
fseek( file, 0, SEEK_SET );
stream->descriptor.pointer = file;
stream->pos = 0;
stream->read = ft_io_stream;
stream->close = ft_close_stream;
return 0;
}
extern
FT_Memory FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)malloc( sizeof(*memory) );
if (memory)
{
memory->user = 0;
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
}
return memory;
}

143
config/ansi/memdebug.c Normal file
View File

@ -0,0 +1,143 @@
/***************************************************************************/
/* */
/* memdebug.c */
/* */
/* Memory debugging functions (body only). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct TBlockRec_
{
char* base;
long size;
} TBlockRec;
static TBlockRec* mem_blocks;
static int num_mem_blocks;
static int max_mem_blocks;
void DM_Init_Mem()
{
num_mem_blocks = 0;
max_mem_blocks = 4096;
mem_blocks = (TBlockRec*)malloc( max_mem_blocks *
sizeof ( *mem_blocks ) );
}
void DM_Done_Mem()
{
/* Now print the remaining blocks */
if ( num_mem_blocks == 0 )
{
fprintf( stderr, "No memory leaked!\n" );
}
else
{
int i;
fprintf( stderr, "There were %d leaked memory blocks\n\n",
num_mem_blocks );
fprintf( stderr, "base size\n" );
fprintf( stderr, "------------------\n" );
for ( i = 0; i < num_mem_blocks; i++ )
{
fprintf( stderr, "%08lx %04lx\n",
(long)mem_blocks[i].base, mem_blocks[i].size );
}
}
free( mem_blocks );
}
void DM_Record( char* base,
long size )
{
TBlockRec* block;
#if 0
/* First, check that the block is not located within one of the */
/* recorded blocks */
for ( i = 0; i < num_mem_blocks; i++ )
{
char *start, *end, *_limit, *_base;
_base = mem_blocks[i].base;
_limit = _base + mem_blocks[i].size;
start = base;
end = base + size - 1;
if ( ( start >= base && start < limit ) ||
( end >= base && end < limit ) )
{
fprintf( stderr, "Warning: Recording an invalid block!\n" );
}
}
#endif
/* Add block to list */
if ( num_mem_blocks >= max_mem_blocks )
{
max_mem_blocks *= 2;
mem_blocks = realloc( mem_blocks,
max_mem_blocks * sizeof ( *mem_blocks ) );
}
block = mem_blocks + num_mem_blocks;
block->base = base;
block->size = size;
num_mem_blocks++;
}
void DM_Forget( char* base )
{
TBlockRec* block = mem_blocks;
int i;
for ( i = 0; i < num_mem_blocks; i++, block++ )
{
if ( block->base == base )
{
/* simply move last block to the current position */
if ( num_mem_blocks > 1 )
*block = mem_blocks[num_mem_blocks - 1];
num_mem_blocks--;
return;
}
#if 1
if ( base >= block->base && base < block->base + block->size )
{
fprintf( stderr, "Invalid block forgotten!\n" );
}
#endif
}
}
/* END */

127
config/detect.mk Normal file
View File

@ -0,0 +1,127 @@
#****************************************************************************
#* *
#* FreeType host platform detection rules *
#* *
#* Copyright 1996-1999 by *
#* David Turner, Robert Wilhelm, and Werner Lemberg. *
#* *
#* This file is part of the FreeType project, and may only be used *
#* modified and distributed under the terms of the FreeType project *
#* license, LICENSE.TXT. By continuing to use, modify, or distribute *
#* this file you indicate that you have read the license and *
#* understand and accept it fully. *
#* *
#* *
#* This sub-Makefile is in charge of detecting the current platform *
#* It sets some variables accordingly. Namely : *
#* *
#* PLATFORM The detected platform. This will default to "ansi" if *
#* auto-detection fails. *
#* *
#* BUILD The configuration and system-specific directory. Usually *
#* 'freetype/config/$(PLATFORM)' but can be different when *
#* a specific compiler has been requested on the *
#* command line.. *
#* *
#* CONFIG_RULES The Makefile to use. This usually depends on the compiler *
#* defined in the 'CC' environment variable. *
#* *
#* DELETE The shell command used to remove a given file *
#* COPY The shell command used to copy one file *
#* *
#* You need to set the following variable(s) before calling it: *
#* *
#* TOP The top-most directory in the FreeType library source *
#* hierarchy. If not defined, it will default to '.' *
#* *
#****************************************************************************
# If TOP is not defined, default it to '.'
#
ifndef TOP
TOP := .
endif
#
# set auto-detection default to ANSI.
# Note that we delay the valuation of BUILD and RULES
#
PLATFORM := ansi
CONFIG = $(TOP)$(SEP)config
DELETE := $(RM)
COPY := cp
SEP := /
BUILD = $(CONFIG)$(SEP)$(PLATFORM)
CONFIG_FILE = $(BUILD)/Makefile
###########################################################################
#
# Now, include each detection rules file found in a `config/<system>'
# directory..
#
#
# we define the BACKSLASH variable to hold a single back-slash character
# This is needed because a line like
#
# SEP := \
#
# does not work with GNU Make (the back-slash is interpreted as a line
# continuation). While a line like :
#
# SEP := \\
#
# really define $(SEP) as "\" on Unix, and "\\" on Dos and Windows !!
#
BACKSLASH := $(strip \ )
include $(wildcard $(CONFIG)/*/detect.mk)
# The following targets are equivalent, with the exception that they use
# slightly different syntaxes for the `echo' command. This is due to
#
# std_setup: is defined for most platforms
# dos_setup: is defined for Dos-ish platforms like Dos, Windows & OS/2
#
.PHONY: std_setup dos_setup
std_setup:
@echo ""
@echo "FreeType build system - automatic system detection"
@echo ""
@echo "The following settings were detected :"
@echo ""
@echo " platform : $(PLATFORM)"
@echo " compiler : $(CC)"
@echo " configuration directory : $(BUILD)"
@echo " configuration rules : $(CONFIG_RULES)"
@echo ""
@echo "If this does not correspond to your system or settings please remove the file"
@echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help."
@echo ""
@echo "Otherwise, simple type \`make' again to build the library"
@echo ""
@$(COPY) $(CONFIG_RULES) $(CONFIG_MK)
dos_setup:
@echo ÿ
@echo FreeType build system - automatic system detection
@echo ÿ
@echo The following settings were detected :
@echo ÿ
@echo ÿÿplatformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ: $(PLATFORM)
@echo ÿÿcompilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ: $(CC)
@echo ÿÿconfiguration directoryÿÿ: $(BUILD)
@echo ÿÿconfiguration rulesÿÿÿÿÿÿ: $(CONFIG_RULES)
@echo ÿ
@echo If this does not correspond to your system or settings please remove the file
@echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help.
@echo ÿ
@echo Otherwise, simple type 'make' again to build the library
@echo ÿ
@$(COPY) $(CONFIG_RULES) $(CONFIG_MK) > nul

182
config/dos/FTCONFIG.H Normal file
View File

@ -0,0 +1,182 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* ANSI-specific configuration file (specification only). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This header file contains a number of macro definitions that are used */
/* by the rest of the engine. Porters are free to copy this file and */
/* adapt it to suit their own system. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in `ftsys.h' before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#ifndef FTCONFIG_H
#define FTCONFIG_H
/* Include the header file containing all developer build options */
#include <ftoption.h>
/*************************************************************************/
/* */
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
/* */
/* These macros can be toggled to suit a specific system. The current */
/* ones are defaults used to compile FreeType in an ANSI C environment */
/* (16bit compilers are also supported). Copy this file to your own */
/* `freetype/arch/<system>' directory, and edit it to port the engine. */
/* */
/*************************************************************************/
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* We use <limits.h> values to know the sizes of the types. */
#include <limits.h>
/* The number of bytes in an `int' type. */
#if UINT_MAX == 0xFFFFFFFF
#define SIZEOF_INT 4
#elif UINT_MAX == 0xFFFF
#define SIZEOF_INT 2
#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_INT 8
#else
#error "Unsupported number of bytes in `int' type!"
#endif
/* The number of bytes in a `long' type. */
#if ULONG_MAX == 0xFFFFFFFF
#define SIZEOF_LONG 4
#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_LONG 8
#else
#error "Unsupported number of bytes in `long' type!"
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 0
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/*************************************************************************/
/* */
/* AUTOMATIC CONFIGURATION MACROS */
/* */
/* These macros are computed from the ones defined above. Don't touch */
/* their definition, unless you know precisely what you're doing. No */
/* porter should need to mess with them. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* IntN types */
/* */
/* Used to guarantee the size of some specific integers. */
/* */
typedef signed short FT_Int16;
typedef unsigned short FT_Word16;
#if SIZEOF_INT == 4
typedef signed int FT_Int32;
typedef unsigned int FT_Word32;
#elif SIZEOF_LONG == 4
typedef signed long FT_Int32;
typedef unsigned long FT_Word32;
#else
#error "no 32bit type found - please check your configuration files"
#endif
#if SIZEOF_LONG == 8
/* LONG64 must be defined when a 64-bit type is available */
#define LONG64
#define INT64 long
#else
/*************************************************************************/
/* */
/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
/* that this will produce many -ansi warnings during library */
/* compilation. */
/* */
#ifdef FTCALC_USE_LONG_LONG
#define LONG64
#define INT64 long long
#endif /* FTCALC_USE_LONG_LONG */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define LOCAL_DEF static
#define LOCAL_FUNC static
#else
#define LOCAL_DEF extern
#define LOCAL_FUNC /* nothing */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
#define BASE_DEF LOCAL_DEF
#define BASE_FUNC LOCAL_FUNC
#else
#define BASE_DEF extern
#define BASE_FUNC /* nothing */
#endif
#ifndef EXPORT_DEF
#define EXPORT_DEF extern
#endif
#ifndef EXPORT_FUNC
#define EXPORT_FUNC /* nothing */
#endif
#endif /* FTCONFIG_H */
/* END */

152
config/dos/FTOPTION.H Normal file
View File

@ -0,0 +1,152 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

214
config/dos/FTSYSTEM.C Normal file
View File

@ -0,0 +1,214 @@
/**************************************************************************
*
* ftsystem.h 1.0
*
* ANSI-specific FreeType low-level system interface
*
* This file contains the definition of interface used by FreeType
* to access low-level, i.e. memory management, i/o access as well
* as thread synchronisation.
*
*
* Copyright 1996-1999 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
**************************************************************************/
#include <ftsystem.h>
#include <fterrors.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/************************************************************************
*
* <FuncType>
* FT_Alloc_Func
*
* <Description>
* The memory allocator function type
*
* <Input>
* system :: pointer to the system object
* size :: requested size in bytes
*
* <Output>
* block :: address of newly allocated block
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* If your allocation routine ALWAYS zeroes the new block, you
* should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
* object 'flags' field.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_alloc( FT_Memory memory,
long size )
{
(void)memory;
return malloc(size);
}
/************************************************************************
*
* <FuncType>
* FT_Realloc_Func
*
* <Description>
* The memory reallocator function type
*
* <Input>
* system :: pointer to the system object
* new_size :: new requested size in bytes
*
* <InOut>
* block :: address of block in memory
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function is _never_ called when the system flag
* FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
* realloc through "alloc" and "free".
*
* Note that this is possible due to the fact that FreeType's
* "FT_Realloc" always requests the _current_ size of the reallocated
* block as a parameter, thus avoiding memory leaks.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
(void)memory;
(void)cur_size;
return realloc( block, new_size );
}
/************************************************************************
*
* <FuncType>
* FT_Free_Func
*
* <Description>
* The memory release function type
*
* <Input>
* system :: pointer to the system object
* block :: address of block in memory
*
* <Note>
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void ft_free( FT_Memory memory,
void* block )
{
(void)memory;
free( block );
}
/*********************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
static
void ft_close_stream( FT_Stream stream )
{
fclose( STREAM_FILE(stream) );
}
static
unsigned long ft_io_stream( FT_Stream stream,
unsigned long offset,
char* buffer,
unsigned long count )
{
FILE* file;
file = STREAM_FILE(stream);
fseek( file, offset, SEEK_SET );
return (unsigned long)fread( buffer, count, 1, file );
}
extern
int FT_New_Stream( const char* filepathname,
FT_Stream stream )
{
FILE* file;
file = fopen( filepathname, "rb" );
if (!file)
return FT_Err_Cannot_Open_Resource;
fseek( file, 0, SEEK_END );
stream->size = ftell(file);
fseek( file, 0, SEEK_SET );
stream->descriptor.pointer = file;
stream->pos = 0;
stream->read = ft_io_stream;
stream->close = ft_close_stream;
return 0;
}
extern
FT_Memory FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)malloc( sizeof(*memory) );
if (memory)
{
memory->user = 0;
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
}
return memory;
}

172
config/dos/MAKEFILE.GCC Normal file
View File

@ -0,0 +1,172 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := rm -f
SEP := /
BUILD := $(TOP)/config/dos
PLATFORM := dos
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O6 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(AR) -r $@ $(OBJECTS_LIST)
endif

87
config/dos/detect.mk Normal file
View File

@ -0,0 +1,87 @@
#
# This file is used to detect a DOS host platform.
#
# This configuration file to be used depends on the value of the CC
# environment variable.
#
#
# We test for the COMSPEC environment variable, then run the 'ver'
# command-line program to see if its output contains the word "Dos"
#
# If this is true, we're running a Dos-ish platform (or an emulation)
#
ifeq ($(PLATFORM),ansi)
ifdef COMSPEC
is_dos := $(findstring Dos,$(shell ver))
# We try to recognize a Dos session under OS/2. The "ver" command
# returns 'Operating System/2 ...' there so 'is_dos' should be empty
# there.
#
# To recognize a Dos session under OS/2, we check COMSPEC for the
# substring "MDOS\COMMAND"
#
ifeq ($(is_dos),)
is_dos := $(findstring MDOS\COMMAND,$(COMSPEC))
endif
ifneq ($(is_dos),)
PLATFORM := dos
DELETE := del
COPY := copy
#####################################################################
#
# Use gcc, i.e. DJGPP by default. Aren't we biased ;-)
#
#
CONFIG_FILE := Makefile.gcc
SEP := /
ifndef CC
CC := gcc
endif
ifneq ($(findstring turboc,$(MAKECMDGOALS)),) # Turbo C
CONFIG_FILE := Makefile.tcc
SEP := $(BACKSLASH)
CC := tcc
.PHONY: turboc
endif
ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
CONFIG_FILE := Makefile.wat
SEP := $(BACKSLASH)
CC := wcc386
.PHONY: watcom
endif
ifneq ($(findstring borlandc16,$(MAKECMDGOALS)),) # Borland C/C++ 16 bits
CONFIG_FILE := Makefile.bcc
SEP := $(BACKSLASH)
CC := bcc
.PHONY: borlandc16
endif
ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C/C++ 32 bits
CONFIG_FILE := Makefile.bcc
SEP := $(BACKSLASH)
CC := bcc32
.PHONY: borlandc
endif
CONFIG_RULES := $(TOP)\config\dos\$(CONFIG_FILE)
# use the Dos version of the "setup dump"
#
setup: dos_setup
endif # test Dos
endif # test COMSPEC
endif # test PLATFORM

162
config/dos/ftoption.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_EXTENSIONS */
/* */
/* The maximum number of extensions that can be registered in a */
/* single font driver. 8 seems to be a good choice for now.. */
/* */
#define FT_MAX_EXTENSIONS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

866
config/dos/ftsys.c Normal file
View File

@ -0,0 +1,866 @@
/*******************************************************************
*
* ftsys.c
*
* ANSI-specific system operations.
*
* Copyright 1996-1998 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*
* This implementation of the 'ftsys' component uses the standard
* ANSI C library.
*
* IMPORTANT NOTE :
*
* Porters, read carefully the comments in ftsys.h before trying
* to port this file to your system. It contains many essential
* remarks, and will ease your work greatly..
*
******************************************************************/
#include "ftsys.h"
#include "ftstream.h"
#include "ftdebug.h"
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_io
#undef CUR_SYSTEM /* just in case */
/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
#define SYS_STREAM FILE*
/* This implementation of ftsys uses the ANSI C library. Memory */
/* management is performed through malloc/free, i/o access through */
/* fopen/fread/fseek, and no synchronisation primitive is implemented */
/* (they contain dummy code) */
/**************************************************************************/
/* */
/* I/O ACCESS AND MANAGEMENT */
/* */
/* We only define the "ANSI" resource class in this class. It is */
/* disk-based, and provides a MRU cache, in order to only keep the file */
/* descriptors of the 10 most recently used resource files. */
/* */
/* it simply contains two lists. One contains the "cached" resources */
/* with a valid FILE* pointer, the second contains all other "flushed" */
/* resource objects. */
/* */
/* The FT_ANSI_File class derives from FT_ResourceRec - description : */
/* */
/* <Struct> FT_AnsiFileRec */
/* */
/* <Fields> */
/* */
/* root :: */
/* the root resource class fields. */
/* */
/* pathname :: */
/* this is a copy of the ANSI file pathname used to open streams */
/* for the resource. A different implementation is free to use */
/* unicode chars, or file i-node numbers, etc.. */
/* */
/* file_size :: */
/* the size in bytes of the resource. This field should be set to */
/* -1 until the resource is first opened.. */
/* */
#include <stdio.h>
typedef struct FT_AnsiFileRec_
{
FT_ResourceRec root;
char* pathname; /* the font file's pathname */
FT_Long file_size; /* file size in bytes */
} FT_AnsiFileRec, *FT_AnsiFile;
/* We use the macro STREAM_Name as a convenience to return a given */
/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
/* which is typecasted to the FT_AnsiFile class */
#define STREAM_Name(stream) ((FT_AnsiFile)stream->resource)->pathname
/* We use the macro STREAM_File as a convenience to extract the */
/* system-specific stream handle from a given FreeType stream object */
#define STREAM_File(stream) ((FILE*)stream->stream_id.pointer)
/***************************************************************************/
/* */
/* <Function> AnsiFile_Open */
/* */
/* <Description> */
/* This function is used to open a system-stream for a given resource. */
/* */
/* Note that it must update the target FreeType stream object with the */
/* system-stream handle and the resource's size. */
/* */
/* Also, the 'stream->base' field must be set to NULL for disk-based */
/* resource, and to the address in memory of the resource's first byte */
/* for a memory-based one. */
/* */
/* <Input> */
/* resource :: the source resource */
/* stream :: the target stream object */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply calls fopen in the resource's file pathname */
/* */
/* The stream object IS NOT CREATED by this function, but by its caller. */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Open( FT_AnsiFile resource,
FT_Stream stream )
{
FILE* file;
/* open the file */
file = fopen( resource->pathname, "rb" );
if (!file)
{
PERROR(( "AnsiFile_Open: could not open file '%s'\n",
resource->pathname ));
return FT_Err_Cannot_Open_Stream;
}
/* compute file size if necessary */
if ( resource->file_size < 0 )
{
fseek( file, 0, SEEK_END );
resource->file_size = ftell(file);
fseek( file, 0, SEEK_SET );
}
stream->resource = (FT_Resource)resource;
stream->stream_id.pointer = file;
stream->size = resource->file_size;
/* it's a disk-based resource, we don't need to use the "base" and */
/* "cursor" fields of the stream objects */
stream->base = NULL;
stream->cursor = NULL;
PTRACE1(( "AnsiFile_Open: opened '%s' (%d bytes) succesfully\n",
resource->pathname, resource->file_size ));
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> AnsiFile_Close */
/* */
/* <Description> Closes a given stream */
/* */
/* <Input> */
/* stream :: the target stream object */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply calls fclose on the stream's ANSI FILE object */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Close( FT_Stream stream )
{
PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
fclose( STREAM_File(stream) );
stream->resource = NULL;
stream->stream_id.pointer = NULL;
stream->size = 0;
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> AnsiFile_Seek */
/* */
/* <Description> Seek a stream to a given position */
/* */
/* <Input> */
/* stream :: the target stream object */
/* position :: offset in bytes from start of resource/stream */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply calls fseek on the stream. */
/* */
/* The "seek" method is never called by the stream manager in the case */
/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Seek( FT_Stream stream,
FT_Long position )
{
if ( fseek( STREAM_File(stream), position, SEEK_SET ) )
{
PERROR(( "AnsiFile_Seek : FAILED !! pos. %ld of '%s'\n",
position, STREAM_Name(stream) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Seek : pos. %ld of '%s'\n",
position, STREAM_Name(stream) ));
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> AnsiFile_Skip */
/* */
/* <Description> Skip a given number of bytes in an ANSI stream. */
/* Useful to skip pad bytes, for example. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* count :: number of bytes to skip in the stream */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply calls fseek on the stream. */
/* */
/* The "skip" method is never called by the stream manager in the case */
/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Skip( FT_Stream stream,
FT_Long count )
{
if ( fseek( STREAM_File(stream), count, SEEK_CUR ) )
{
PERROR(( "AnsiFile_Skip : FAILED !! %ld bytes in '%s'\n",
count, STREAM_Name(stream) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Skip : %ld bytes in '%s'\n",count,
STREAM_Name(stream) ));
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> AnsiFile_Pos */
/* */
/* <Description> Returns the current offset within an ANSI stream's */
/* resource. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* */
/* <Output> */
/* position :: current offset. -1 in case of error */
/* */
/* <Return> */
/* Error code. */
/* */
/* <Note> */
/* This function simply calls ftell on the stream. */
/* */
/* The "pos" method is never called by the stream manager in the case */
/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Pos( FT_Stream stream,
FT_Long* position )
{
*position = ftell( STREAM_File(stream) );
if ( *position == -1 )
{
PTRACE2(( "AnsiFile_Pos : FAILED !! in '%s'\n", STREAM_Name(stream) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "AnsiFile_Pos : for '%s'\n", STREAM_Name(stream) ));
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> AnsiFile_Read */
/* */
/* <Description> Read a given number of bytes from an ANSI stream into */
/* memory. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* buffer :: the target read buffer where data is copied */
/* size :: number of bytes to read from the stream */
/* */
/* <Output> */
/* read_bytes :: the number of bytes effectively read from the stream */
/* used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
/* by some parts of the library.. */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply calls fread on the stream. */
/* */
/* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
/* an over-read (i.e. reading more bytes from the stream that what */
/* is left int), as the stream component checks for this specific */
/* value.. */
/* */
/* The "read" method is never called by the stream manager in the case */
/* of a memory-based resource (i.e. when 'stream->base' isn't NULL). */
/* */
/***************************************************************************/
static
FT_Error AnsiFile_Read( FT_Stream stream,
FT_Char* buffer,
FT_Long size,
FT_Long* read_bytes )
{
*read_bytes = fread( buffer, 1, size, STREAM_File(stream) );
if ( *read_bytes != size )
{
/* Note : we can have an over-read here when called by the */
/* function FT_Access_Compressed_Frame. This means */
/* that the following message should be a trace, */
/* rather than an error for disk-based resources.. */
/* */
/* the function must set the value of 'read_bytes' */
/* even if it returns an error code.. */
PTRACE2(( "AnsiFile_Read : FAILED !! read %ld bytes from '%s'\n",
size, STREAM_Name(stream) ));
return FT_Err_Invalid_Stream_Read;
}
PTRACE2(( "AnsiFile_Read : read %ld bytes to buffer 0x%08lx from '%s'\n",
size, (long)buffer, STREAM_Name(stream) ));
return FT_Err_Ok;
}
/* The following table is the "virtual method table" for the 'ANSI */
/* resource class', which methods are defined above. Its address is */
/* set in the 'interface' field of all resource objects created by */
/* the function FT_Create_AnsiFile (see below) */
static
FTRes_InterfaceRec FT_AnsiFile_Interface =
{
(FTRes_Open_Func) AnsiFile_Open,
(FTRes_Close_Func) AnsiFile_Close,
(FTRes_Seek_Func) AnsiFile_Seek,
(FTRes_Skip_Func) AnsiFile_Skip,
(FTRes_Pos_Func) AnsiFile_Pos,
(FTRes_Read_Func) AnsiFile_Read,
};
/***************************************************************************/
/* */
/* <Function> FT_Create_Resource */
/* */
/* <Description> Creates a new resource object, of class "AnsiFile". */
/* This function is never called directly by the font */
/* drivers. Only by the higher-level part of FreeType */
/* (called the HLib), or client applications */
/* */
/* <Input> */
/* pathname :: the file's pathname, in ASCII */
/* */
/* <Return> */
/* Handle/pointer to the new resource object. NULL in case of error */
/* */
/* <Note> */
/* This functions does not open a stream. It simply copies the */
/* pathname within a fresh new resource object. */
/* */
/***************************************************************************/
EXPORT_FUNC
FT_Error FT_Create_Resource( FT_Library library,
const char* pathname,
FT_Resource* aresource )
{
FT_Int len;
FT_AnsiFile resource;
FT_Error error;
FT_System system = library->system;
if ( !pathname )
goto Fail_Null;
len = strlen(pathname);
if (len == 0)
goto Fail_Null;
resource = NULL;
if ( ALLOC( resource, sizeof(*resource) ) ||
ALLOC( resource->pathname, len+1 ) )
goto Fail_Memory;
resource->root.library = library;
resource->root.interface = &FT_AnsiFile_Interface;
resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
resource->file_size = -1;
strcpy( resource->pathname, pathname );
PTRACE1(( "Create_AnsiFile : Ansi resource created for '%s'\n",
pathname ));
*aresource = (FT_Resource)resource;
return FT_Err_Ok;
Fail_Null:
PERROR(( "Create_AnsiFile : null pathname !!\n" ));
return FT_Err_Invalid_Argument;
Fail_Memory:
if (resource)
FREE( resource->pathname );
FREE( resource );
PERROR(( "Create_AnsiFile : not enough memory to create resource !\n" ));
return error;
}
/***************************************************************************/
/* */
/* <Function> FT_Destroy_Resource */
/* */
/* <Description> Destroys an ANSI resource object. */
/* This function is never called directly by the font */
/* drivers. Only by the higher-level part of FreeType */
/* (called the HLib), or client applications */
/* */
/* <Input> */
/* resource :: the Ansi resource object */
/* */
/* <Note> */
/* This functions does not check that runs or streams are opened for */
/* the resource (for now, we assume developer intelligence. We'll most */
/* probably lower our standard later to ease debugging ;-) */
/* */
/***************************************************************************/
EXPORT_FUNC
FT_Error FT_Destroy_Resource( FT_Resource resource )
{
FT_System system = resource->library->system;
FT_AnsiFile ansi = (FT_AnsiFile)resource;
if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
{
PERROR((
"Destroy_AnsiFile : Trying to destroy an invalid resource !!\n" ));
return FT_Err_Invalid_Resource_Handle;
}
PTRACE1(( "Destroy_AnsiFile : destroying resource for '%s'\n",
ansi->pathname ));
FREE( ansi->pathname );
FREE( ansi );
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* MEMORY MANAGEMENT */
/* */
/* */
/* This part copies the old FreeType 1.0 and 1.1 memory management */
/* scheme that was defined in the file "ttmemory.h". One can see that */
/* */
/* - a set of macros is defined for the memory operations used */
/* by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from */
/* the fact that many compilers are able to inline these ops directly */
/* within the compiled code, rather than generating a call to the */
/* C library. However, this obliges us to include the <string.h> */
/* header file. */
/* */
/* If you provide your own memory operations routine, you can get */
/* rid of the #include <string.h> below. */
/* */
/* */
/* - the FT_Alloc function has several essential properties that */
/* MUST be retained by each port : */
/* */
/* - it returns an error code, NOT the allocated block's base */
/* address */
/* */
/* - it takes the address of a target pointer, where the block's */
/* base address will be set. if the size is zero, its value */
/* will be NULL and the function returns successfully */
/* */
/* - in case of error, the pointer's value is set to NULL and */
/* an error code is returned.. */
/* */
/* - the new allocated block MUST be zero-filled. This is a strong */
/* convetion the rest of the engine relies on */
/* */
/* */
/* */
/* - the FT_Free function has also its essentials : */
/* */
/* - it takes the address of a pointer which value is the block's */
/* base address. This is UNLIKE a standard "free" which takes the */
/* the block's base directly. */
/* */
/* - it accepts succesfully the address of a pointer which value */
/* is NULL, in which case it simply returns. */
/* */
/* - the pointer is always set to NULL by the function */
/* */
/* */
/* - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the */
/* library, and should NOT be modified by porters !! */
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_memory
#include <stdlib.h>
/**************************************************************************/
/* */
/* <Function> FT_Alloc */
/* */
/* <Description> */
/* Allocates a new bloc of memory. The returned area is always */
/* zero-filled, this is a strong convention in many FreeType parts */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occurs.. */
/* */
/* size :: size in bytes of the block to allocate */
/* */
/* <Output> */
/* P :: pointer to the fresh new block. It should be set */
/* to NULL if 'size' is 0, of in case of error.. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/**************************************************************************/
BASE_FUNC
FT_Error FT_Alloc( FT_System system,
long size,
void* *P )
{
if (!P)
{
PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
return FT_Err_Invalid_Argument;
}
if ( size > 0 )
{
*P = malloc( size );
if ( !*P )
{
PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
size ));
return FT_Err_Out_Of_Memory;
}
system->total_alloc += size;
/* ALWAYS ZERO-FILL THE BLOCK !!!!! */
MEM_Set( *P, 0, size );
}
else
*P = NULL;
PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
size, (long)P, (long)*P ));
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* <Function> FT_Realloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by '*P' to 'Size' */
/* bytes from the hea^, possibly changing '*P'. */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occurs.. */
/* */
/* size :: size in bytes of the block to allocate */
/* */
/* <InOut> */
/* P :: pointer to the fresh new block. It should be set */
/* to NULL if 'size' is 0, of in case of error.. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
int FT_Realloc( FT_System system,
long size,
void* *P )
{
void* Q;
if (!P)
{
PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
return FT_Err_Invalid_Argument;
}
/* if the original pointer is NULL, call FT_Alloc */
if (!*P)
return FT_Alloc( system, size, P );
/* if the new block if zero-sized, clear the current one */
if (size <= 0)
return FT_Free( system, P );
Q = (void*)realloc( *P, size );
if (!Q)
{
PERROR(( "FT_Realloc : reallocation failed\n" ));
return FT_Err_Out_Of_Memory;
}
*P = Q;
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* <Function> FT_Free */
/* */
/* <Description> */
/* Releases a given block of memory allocated through FT_Alloc */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occured.. */
/* */
/* P :: This is the _address_ of a _pointer_ which points to */
/* the allocated block. It is always set to NULL on exit */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* If P or *P are NULL, this function should return successfuly. This */
/* is a strong convention within all of FreeType and its drivers.. */
/* */
BASE_FUNC
FT_Error FT_Free( FT_System system,
void* *P )
{
(void)system; /* unused parameter. Gets rid of warnings */
PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
(long)P, (P ? (long)*P : -1) ));
if ( !P || !*P )
return FT_Err_Ok;
free( *P );
*P = NULL;
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* SYNCHRONIZATION MANAGEMENT */
/* */
/* */
/* This section deals with mutexes. The library can be compiled to */
/* three distinct thread-support levels ( namely single-threaded, */
/* thread-safe and re-entrant modes ). */
/* */
/* It protects its variables through the MUTEX_Lock and MUTEX_Release */
/* macros which are void in single-threaded mode. */
/* */
/* */
/* It defines a type-less mutex reference type, "TMutex", that you're */
/* free to redefine for your system's needs.. */
/* */
/* The default implementation of ftsys.c contains only dummy functions */
/* which always return succesfully. you NEED to specialize them in */
/* order to port ftsys.c in any multi-threaded environment... */
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_sync
#ifdef FT_CONFIG_THREADS
BASE_FUNC
FT_Error FT_Mutex_Create ( FT_System system,
TMutex* mutex )
{
(void)system; /* unused parameter. Gets rid of warnings */
mutex = (void*)-1;
system->num_mutexes++;
return FT_Err_Ok;
/* Replace this line with your own mutex creation code */
}
BASE_FUNC
void FT_Mutex_Delete ( FT_System system,
TMutex* mutex )
{
(void)system; /* unused parameter. Gets rid of warnings */
mutex = (void*)0;
system->num_mutexes--;
/* Replace this line with your own mutex destruction code */
}
BASE_FUNC
void FT_Mutex_Lock ( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate. */
(void)system; /* unused parameter. Gets rid of warnings */
if ( !mutex )
return;
; /* Insert your own mutex locking code here */
}
void FT_Mutex_Release( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate */
(void)system; /* unused parameter. Gets rid of warnings */
if ( !mutex )
return;
; /* Insert your own mutex release code here */
}
#endif /* FT_CONFIG_THREADS */
EXPORT_FUNC
FT_Error FT_New_System( FT_System* system )
{
*system = (FT_System)malloc( sizeof(**system) );
if ( !*system )
return FT_Err_Out_Of_Memory;
/* the ANSI function 'free' is unable to return the number */
/* of released bytes. Hence, the 'current_alloc' field of the */
/* system object cannot be used */
(*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
FT_SYSTEM_FLAG_MUTEXES;
(*system)->total_alloc = 0;
(*system)->num_mutexes = 0;
/* initialise i/o management (nothing) */
/* initialise synchronisation (nothing) */
/* initialise streams */
return FT_Err_Ok;
}
EXPORT_FUNC
FT_Error FT_Done_System( FT_System system )
{
/* finalise syncrhonisation (nothing) */
/* finalise i/o management (nothing) */
/* finalise memory management */
free( system );
return FT_Err_Ok;
}

199
config/freetype.mk Normal file
View File

@ -0,0 +1,199 @@
#****************************************************************************
#* *
#* FreeType library sub-Makefile *
#* *
#* Copyright 1996-1999 by *
#* David Turner, Robert Wilhelm, and Werner Lemberg. *
#* *
#* This file is part of the FreeType project, and may only be used *
#* modified and distributed under the terms of the FreeType project *
#* license, LICENSE.TXT. By continuing to use, modify, or distribute *
#* this file you indicate that you have read the license and *
#* understand and accept it fully. *
#* *
#* *
#* *
#* DO NOT INVOKE THIS MAKEFILE DIRECTLY. IT IS MEANT TO BE INCLUDED BY *
#* OTHER MAKEFILES. *
#* *
#****************************************************************************
# The targets `objects', `library' and `multiple' are defined
# at the end of this Makefile when all rules have been included..
#
.PHONY: build_freetype objects library
# default target - build objects and library
#
build_freetype: objects library
# `multi' target - build multiple objects and library
#
multi: objects library
# The FreeType sources directory.
#
SRC := $(TOP)$(SEP)src
# The directory where the base layer components are placed.
# By default, this is 'freetype/src/base'
#
BASE_DIR := $(SRC)$(SEP)base
# A Few short-cuts in order to avoid typing $(SEP) all the time for
# the directory separator
#
# For example: SRC_ equals to './src/' where '.' is $(TOP)
#
#
SRC_ := $(SRC)$(SEP)
BASE_ := $(BASE_DIR)$(SEP)
OBJ_ := $(OBJ_DIR)$(SEP)
LIB_ := $(LIB_DIR)$(SEP)
PUBLIC_ := $(TOP)$(SEP)include$(SEP)
# The name of the final library file.
#
FT_LIBRARY := $(LIB_DIR)$(SEP)$(LIBRARY).$A
# include paths
#
# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed
# in front of the include list. Porters are then able to put
# their own version of some of the FreeType components in
# the 'freetype/arch/<system>' directory, as these files
# will override the default sources.
#
INCLUDES := $(BUILD) $(TOP)$(SEP)include $(INCLUDES)
INCLUDE_FLAGS = $(INCLUDES:%=$I%)
# C flags used for the compilation of an object file. This must include at
# least the paths for the 'base' and 'config/<system>' directories,
# debug/optimization/warning flags + ansi compliance if needed.
#
FT_CFLAGS = $(CFLAGS) $(INCLUDE_FLAGS)
FT_CC = $(CC) $(FT_CFLAGS)
FT_COMPILE = $(FT_CC)
#
# Free the lists of driver objects
#
COMPONENTS_LIST :=
DRIVERS_LIST :=
OBJECTS_LIST :=
# free the list of 'ftinit' variables
#
FTINIT_DRIVER_PATHS :=
FTINIT_DRIVER_H :=
FTINIT_DRIVER_MACROS :=
# System-specific component - this must be defined in this Makefile
# for easy updates
#
# BASE_H is defined in src/base/rules.mk and contains the list of all
# base layer header files.
#
FTSYS_SRC = $(BUILD)$(SEP)ftsystem.c
FTSYS_OBJ = $(OBJ_DIR)$(SEP)ftsystem.$O
OBJECTS_LIST += $(FTSYS_OBJ)
$(FTSYS_OBJ): $(FTSYS_SRC) $(BASE_H)
$(FT_COMPILE) $T$@ $<
# ftdebug component
#
#
#
FTDEBUG_SRC = $(BASE_)ftdebug.c
FTDEBUG_OBJ = $(OBJ_)ftdebug.$O
OBJECTS_LIST += $(FTDEBUG_OBJ)
$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(BASE_H)
$(FT_COMPILE) $T$@ $<
# Define PUBLIC_H as the list of all public header files located in
# `$(TOP)/include'
#
PUBLIC_H := $(wildcard $(PUBLIC_)*.h)
# Include all rule files from FreeType components
#
#
include $(wildcard $(SRC)/*/rules.mk)
# FTInit file:
#
# The C source 'ftinit.c' contains the FreeType initialisation routines.
# It is able to automatically register one or more drivers when the API
# function FT_Init_FreeType() is called.
#
# The set of initial drivers is determined by the driver Makefiles
# includes above. Each driver Makefile updates the FTINIT_xxxx lists
# which contain additional include paths and macros used to compile the
# single 'ftapi.c' source.
#
FTINIT_SRC := $(BASE_DIR)$(SEP)ftinit.c
FTINIT_OBJ := $(OBJ_)ftinit.$O
$(FTINIT_OBJ): $(FTINIT_SRC) $(BASE_H) $(FTINIT_DRIVER_H)
$(FT_COMPILE) $(FTINIT_DRIVER_PATHS:%=$I%) \
$(FTINIT_DRIVER_MACROS:%=$D%) $T$@ $<
# All FreeType library objects
#
# By default, we include the base layer extensions. These could be
# ommitted on builds which do not want them.
#
OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) \
$(FTSYS_OBJ) $(FTINIT_OBJ) $(FTDEBUG_OBJ)
OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) \
$(FTSYS_OBJ) $(FTINIT_OBJ) $(FTDEBUG_OBJ)
ifneq ($(findstring multi,$(MAKECMDGOALS)),)
OBJECTS_LIST += $(OBJ_M)
else
OBJECTS_LIST += $(OBJ_S)
endif
objects: $(OBJECTS_LIST)
library: $(FT_LIBRARY)
.c.$O:
$(FT_COMPILE) $T$@ $<
clean_freetype:
-$(DELETE) $(OBJ_S:/=$(SEP)) $(OBJ_M:/=$(SEP))
distclean_freetype: clean_freetype
-$(DELETE) $(FT_LIBRARY:/=$(SEP))
-$(DELETE) *.orig *~ core *.core
remove_config_mk:
-$(DELETE) $(CONFIG_MK:/=$(SEP))
clean: clean_freetype
distclean: distclean_freetype remove_config_mk
# END

196
config/os2/Makefile.emx Normal file
View File

@ -0,0 +1,196 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := del
SEP := /
BUILD := $(TOP)/config/os2
PLATFORM := os2
CC := gcc
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O6 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# Librarian to use to build the static library
#
FT_LIBRARIAN := $(AR) -r
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
# Cleaning rules
#
DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
clean_freetype_objects:
-del $(DIR_OBJ)\*.$O
clean_freetype_lib:
-del $(subst $(SEP),\,$(FT_LIBRARY))
clean: clean_freetype_objects
endif

47
config/os2/detect.mk Normal file
View File

@ -0,0 +1,47 @@
#
# This file is used to detect an OS/2 host, and set the build variables
# accordingly..
#
# which Makefile to use based on the value of the CC environment variable.
#
# OS/2
#
#
ifeq ($(PLATFORM),ansi)
ifdef OS2_SHELL
PLATFORM := os2
COPY := copy
DELETE := del
CONFIG_FILE := Makefile.emx # gcc-emx by default
SEP := /
ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++
CONFIG_FILE := Makefile.icc
SEP := $(BACKSLASH)
CC := icc
.PHONY: visualage
endif
ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
CONFIG_FILE := Makefile.wat
SEP := $(BACKSLASH)
CC := wcc386
.PHONY: watcom
endif
ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C++ 32 bits
CONFIG_FILE := Makefile.bcc
SEP := $(BACKSLASH)
CC := bcc32
.PHONY: borlandc
endif
CONFIG_RULES := $(TOP)\config\os2\$(CONFIG_FILE)
setup: dos_setup
endif #test OS2_SHELL
endif #test PLATFORM

182
config/os2/ftconfig.h Normal file
View File

@ -0,0 +1,182 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* ANSI-specific configuration file (specification only). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This header file contains a number of macro definitions that are used */
/* by the rest of the engine. Porters are free to copy this file and */
/* adapt it to suit their own system. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in `ftsys.h' before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#ifndef FTCONFIG_H
#define FTCONFIG_H
/* Include the header file containing all developer build options */
#include <ftoption.h>
/*************************************************************************/
/* */
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
/* */
/* These macros can be toggled to suit a specific system. The current */
/* ones are defaults used to compile FreeType in an ANSI C environment */
/* (16bit compilers are also supported). Copy this file to your own */
/* `freetype/arch/<system>' directory, and edit it to port the engine. */
/* */
/*************************************************************************/
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* We use <limits.h> values to know the sizes of the types. */
#include <limits.h>
/* The number of bytes in an `int' type. */
#if UINT_MAX == 0xFFFFFFFF
#define SIZEOF_INT 4
#elif UINT_MAX == 0xFFFF
#define SIZEOF_INT 2
#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_INT 8
#else
#error "Unsupported number of bytes in `int' type!"
#endif
/* The number of bytes in a `long' type. */
#if ULONG_MAX == 0xFFFFFFFF
#define SIZEOF_LONG 4
#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_LONG 8
#else
#error "Unsupported number of bytes in `long' type!"
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 0
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/*************************************************************************/
/* */
/* AUTOMATIC CONFIGURATION MACROS */
/* */
/* These macros are computed from the ones defined above. Don't touch */
/* their definition, unless you know precisely what you're doing. No */
/* porter should need to mess with them. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* IntN types */
/* */
/* Used to guarantee the size of some specific integers. */
/* */
typedef signed short FT_Int16;
typedef unsigned short FT_Word16;
#if SIZEOF_INT == 4
typedef signed int FT_Int32;
typedef unsigned int FT_Word32;
#elif SIZEOF_LONG == 4
typedef signed long FT_Int32;
typedef unsigned long FT_Word32;
#else
#error "no 32bit type found - please check your configuration files"
#endif
#if SIZEOF_LONG == 8
/* LONG64 must be defined when a 64-bit type is available */
#define LONG64
#define INT64 long
#else
/*************************************************************************/
/* */
/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
/* that this will produce many -ansi warnings during library */
/* compilation. */
/* */
#ifdef FTCALC_USE_LONG_LONG
#define LONG64
#define INT64 long long
#endif /* FTCALC_USE_LONG_LONG */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define LOCAL_DEF static
#define LOCAL_FUNC static
#else
#define LOCAL_DEF extern
#define LOCAL_FUNC /* nothing */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
#define BASE_DEF LOCAL_DEF
#define BASE_FUNC LOCAL_FUNC
#else
#define BASE_DEF extern
#define BASE_FUNC /* nothing */
#endif
#ifndef EXPORT_DEF
#define EXPORT_DEF extern
#endif
#ifndef EXPORT_FUNC
#define EXPORT_FUNC /* nothing */
#endif
#endif /* FTCONFIG_H */
/* END */

162
config/os2/ftoption.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_EXTENSIONS */
/* */
/* The maximum number of extensions that can be registered in a */
/* single font driver. 8 seems to be a good choice for now.. */
/* */
#define FT_MAX_EXTENSIONS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

940
config/os2/ftsys.c Normal file
View File

@ -0,0 +1,940 @@
/***************************************************************************/
/* */
/* ftsys.c */
/* */
/* OS/2-specific system operations (body). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This implementation of the `ftsys' component uses malloc()/free() for */
/* memory management, and the OS/2 DosXXXXX() API functionss for file */
/* access. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in ftsys.h before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#include "ftsys.h"
#include "ftstream.h"
#include "ftdebug.h"
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/*************************************************************************/
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_io
#undef CUR_SYSTEM /* just in case */
/*************************************************************************/
/* */
/* To ease porting, we use the macro SYS_STREAM to name the */
/* system-specific stream type. For example, it is a `FILE*' with the */
/* ANSI libc, it will be a file descriptor, i.e. an integer, when using */
/* the Unix system API, etc. */
/* */
#define SYS_STREAM HFILE
/*************************************************************************/
/* */
/* I/O ACCESS AND MANAGEMENT */
/* */
/* We only define the `ANSI' resource class in this class. It is */
/* disk-based and provides a MRU cache in order to only keep the file */
/* descriptors of the 10 most recently used resource files. */
/* */
/* It simply contains two lists. One contains the `cached' resources */
/* with a valid FILE* pointer, the second contains all other `flushed' */
/* resource objects. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Struct> */
/* FT_Os2FileRec */
/* */
/* <Description> */
/* The FT_Os2File class derives from FT_ResourceRec. */
/* */
/* <Fields> */
/* root :: The root resource class fields. */
/* */
/* pathname :: This is a copy of the ANSI file pathname used to open */
/* streams for the resource. A different implementation */
/* is free to use Unicode chars, or file i-node numbers, */
/* etc. */
/* */
/* file_size :: The size in bytes of the resource. This field should */
/* be set to -1 until the resource is first opened. */
/* */
typedef struct FT_Os2FileRec_
{
FT_ResourceRec root;
char* pathname; /* the font file's pathname */
FT_Long file_size; /* file size in bytes */
} FT_Os2FileRec, *FT_Os2File;
/*************************************************************************/
/* */
/* We use the macro STREAM_Name() as a convenience to return a given */
/* ANSI resource's pathname. Its `stream' argument is a FT_Resource */
/* which is typecasted to the FT_Os2File class. */
/* */
#define STREAM_Name( stream ) ((FT_Os2File)stream->resource)->pathname
/*************************************************************************/
/* */
/* We use the macro STREAM_File() as a convenience to extract the */
/* system-specific stream handle from a given FreeType stream object. */
/* */
#define STREAM_File(stream) ((HFILE)stream->stream_id.pointer)
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Open */
/* */
/* <Description> */
/* This function is used to open a system-stream for a given */
/* resource. */
/* */
/* Note that it must update the target FreeType stream object with */
/* the system-stream handle and the resource's size. */
/* */
/* Also, the `stream->base' field must be set to NULL for disk-based */
/* resources, and to the address in memory of the resource's first */
/* byte for memory-based ones. */
/* */
/* <Input> */
/* resource :: The source resource. */
/* stream :: The target stream object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream object IS NOT CREATED by this function, but by its */
/* caller. */
/* */
static
FT_Error Os2File_Open( FT_Os2File resource,
FT_Stream stream )
{
HFILE file;
ULONG ulAction;
/* open the file */
#ifdef __EMX__
if ( DosOpen( (FT_Byte*)resource->pathname,
&file,
&ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
NULL ) )
#else
if ( DosOpen( resource->pathname,
&file,
&ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
NULL ) )
#endif /* __EMX__ */
{
PERROR(( "Os2File_Open: Could not open file `%s'\n",
resource->pathname ));
return FT_Err_Cannot_Open_Stream;
}
/* compute file size if necessary */
if ( resource->file_size < 0 )
{
DosSetFilePtr( file, 0, FILE_END, (ULONG*)&resource->file_size );
DosSetFilePtr( file, 0, FILE_BEGIN, &ulAction );
}
stream->resource = (FT_Resource)resource;
stream->stream_id.pointer = (void*)file;
stream->size = resource->file_size;
/* it's a disk-based resource, we don't need to use the "base" and */
/* "cursor" fields of the stream objects */
stream->base = NULL;
stream->cursor = NULL;
PTRACE1(( "Os2File_Open: Opened `%s' (%d bytes) successfully\n",
resource->pathname, resource->file_size ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Close */
/* */
/* <Description> */
/* Closes a given stream. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
static
FT_Error Os2File_Close( FT_Stream stream )
{
PTRACE1(( "OS2File_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
DosClose( STREAM_File( stream ) );
stream->resource = NULL;
stream->stream_id.pointer = NULL;
stream->size = 0;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Seek */
/* */
/* <Description> */
/* Seeks a stream to a given position. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* position :: The offset in bytes from the start of the */
/* resource/stream. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The `seek' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error Os2File_Seek( FT_Stream stream,
FT_Long position )
{
ULONG ibActual;
if ( DosSetFilePtr( STREAM_File( stream ), position,
FILE_BEGIN, &ibActual ) )
{
PERROR(( "Os2File_Seek: FAILED! Pos. %ld of `%s'\n",
position, STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Seek;
}
PTRACE2(( "Os2File_Seek: Pos. %ld of `%s'\n",
position, STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Skip */
/* */
/* <Description> */
/* Skips a given number of bytes in an OS/2 stream. Useful to skip */
/* pad bytes, for example. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* count :: The number of bytes to skip in the stream. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The `skip' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error Os2File_Skip( FT_Stream stream,
FT_Long count )
{
ULONG ibActual;
DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual );
return Os2File_Seek( stream, ibActual + count );
}
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Pos */
/* */
/* <Description> */
/* Returns the current offset within an OS/2 stream's resource. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* */
/* <Output> */
/* position :: The current offset. -1 in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The `pos' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error Os2File_Pos( FT_Stream stream,
FT_Long* position )
{
ULONG ibActual;
if ( DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual ) )
{
PTRACE2(( "Os2File_Pos: FAILED! in `%s'\n", STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Seek;
}
*position = ibActual;
PTRACE2(( "Os2File_Pos: For `%s'\n", STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* Os2File_Read */
/* */
/* <Description> */
/* Reads a given number of bytes from an OS/2 stream into memory. */
/* */
/* <Input> */
/* stream :: The target stream object. */
/* buffer :: The target read buffer where data is copied. */
/* size :: The number of bytes to read from the stream. */
/* */
/* <Output> */
/* read_bytes :: The number of bytes effectively read from the */
/* stream. Used in case of error */
/* (i.e. FT_Err_Invalid_Stream_Read) by some parts of */
/* the library. */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* It MUST return the error FT_Err_Invalid_Stream_Read in case of */
/* an over-read (i.e., reading more bytes from the stream that what */
/* is left), as the stream component checks for this specific value. */
/* */
/* The `read' method is never called by the stream manager in case */
/* of a memory-based resource (i.e., when `stream->base' isn't NULL). */
/* */
static
FT_Error Os2File_Read( FT_Stream stream,
char* buffer,
FT_Long size,
FT_Long* read_bytes )
{
ULONG cbActual;
DosRead( STREAM_File( stream ), buffer, size, &cbActual );
*read_bytes = cbActual;
if ( cbActual != (ULONG)size )
{
/* Note : we can have an over-read here when called by the */
/* function FT_Access_Compressed_Frame. This means */
/* that the following message should be a trace, */
/* rather than an error for disk-based resources.. */
/* */
/* the function must set the value of 'read_bytes' */
/* even if it returns an error code.. */
PTRACE2(( "Os2File_Read: FAILED! Read %ld bytes from '%s'\n",
size, STREAM_Name( stream ) ));
return FT_Err_Invalid_Stream_Read;
}
PTRACE2(( "Os2File_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
size, (long)buffer, STREAM_Name( stream ) ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* The following table is the `virtual method table' for the `OS/2 */
/* resource class', which methods are defined above. Its address is set */
/* in the `interface' field of all resource objects created by the */
/* function FT_Create_Os2File() (see below). */
/* */
static
FTRes_InterfaceRec FT_Os2File_Interface =
{
(FTRes_Open_Func) Os2File_Open,
(FTRes_Close_Func) Os2File_Close,
(FTRes_Seek_Func) Os2File_Seek,
(FTRes_Skip_Func) Os2File_Skip,
(FTRes_Pos_Func) Os2File_Pos,
(FTRes_Read_Func) Os2File_Read,
};
/*************************************************************************/
/* */
/* <Function> */
/* FT_Create_Resource */
/* */
/* <Description> */
/* Creates a new resource object. This function is called by the */
/* FT_New_Resource() function of the base layer. */
/* */
/* <Input> */
/* library :: The input library object. */
/* pathname :: The file's pathname as an ASCII string. */
/* */
/* <Output> */
/* aresource :: A handle to new resource object. */
/* */
/* <Return> */
/* Error code. 0 means success. */
/* */
/* <Note> */
/* This functions does not open a stream. It simply copies the */
/* pathname within a fresh new resource object. */
/* */
EXPORT_FUNC
FT_Error FT_Create_Resource( FT_Library library,
const char* pathname,
FT_Resource* aresource )
{
FT_Int len;
FT_Os2File resource;
FT_Error error;
FT_System system;
if ( !library )
return FT_Err_Invalid_Library_Handle;
system = library->system;
if ( !pathname )
goto Fail_Null;
len = strlen( pathname );
if ( len == 0 )
goto Fail_Null;
resource = NULL;
if ( ALLOC( resource, sizeof ( *resource ) ) ||
ALLOC( resource->pathname, len + 1 ) )
goto Fail_Memory;
resource->root.library = library;
resource->root.interface = &FT_Os2File_Interface;
resource->root.flags = FT_RESOURCE_TYPE_DISK_BASED;
resource->file_size = -1;
strcpy( resource->pathname, pathname );
PTRACE1(( "Create_Os2File: OS/2 resource created for '%s'\n",
pathname ));
*aresource = (FT_Resource)resource;
return FT_Err_Ok;
Fail_Null:
PERROR(( "Create_Os2File: Null pathname!\n" ));
return FT_Err_Invalid_Argument;
Fail_Memory:
if ( resource )
FREE( resource->pathname );
FREE( resource );
PERROR(( "Create_Os2File: Not enough memory to create resource!\n" ));
return error;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Destroy_Resource */
/* */
/* <Description> */
/* Discards a given resource object explicitly. */
/* */
/* <Input> */
/* resource :: The OS/2 resource object. */
/* */
/* <Note> */
/* This function does not check whether runs or streams are opened */
/* for the resource (for now, we assume developer intelligence. */
/* We'll most probably lower our standard later to ease debugging :-) */
/* */
EXPORT_FUNC
FT_Error FT_Destroy_Resource( FT_Resource resource )
{
FT_System system = resource->library->system;
FT_Os2File ansi = (FT_Os2File)resource;
if ( !ansi || ansi->root.interface != &FT_Os2File_Interface )
{
PERROR((
"Destroy_Os2File: Trying to destroy an invalid resource!\n" ));
return FT_Err_Invalid_Resource_Handle;
}
PTRACE1(( "Destroy_Os2File: Destroying resource for `%s'\n",
ansi->pathname ));
FREE( ansi->pathname );
FREE( ansi );
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* MEMORY MANAGEMENT */
/* */
/* */
/* This part copies the old FreeType 1.0 and 1.1 memory management */
/* scheme that was defined in the file `ttmemory.h'. One can see that */
/* */
/* - a set of macros is defined for the memory operations used by the */
/* engine (MEM_Copy(), MEM_Move(), MEM_Set()). This comes from the */
/* fact that many compilers are able to inline these operations */
/* directly within the compiled code, rather than generating a call */
/* to the C library. However, this obliges us to include the */
/* `<string.h>' header file. */
/* */
/* If you provide your own memory operations, you can get rid of the */
/* `#include <string.h>' below. */
/* */
/* */
/* - the FT_Alloc() function has several essential properties that MUST */
/* be retained by each port: */
/* */
/* - It returns an error code, NOT the allocated block's base */
/* address. */
/* */
/* - It takes the address of a target pointer, where the block's base */
/* address will be set. If the size is zero, its value will be */
/* NULL, and the function returns successfully. */
/* */
/* - In case of error, the pointer's value is set to NULL and an */
/* error code is returned. */
/* */
/* - The new allocated block MUST be zero-filled. This is a strong */
/* convention the rest of the engine relies on. */
/* */
/* */
/* - the FT_Free() function has also its essentials: */
/* */
/* - It takes the address of a pointer which value is the block's */
/* base address. This is UNLIKE a standard `free()' which takes */
/* the block's base directly. */
/* */
/* - It accepts successfully the address of a pointer which value is */
/* NULL, in which case it simply returns. */
/* */
/* - The pointer is always set to NULL by the function. */
/* */
/* */
/* - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
/* library and should NOT be modified by porters! */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_memory
/*************************************************************************/
/* */
/* <Function> */
/* FT_Alloc */
/* */
/* <Description> */
/* Allocates a new block of memory. The returned area is always */
/* zero-filled, this is a strong convention in many FreeType parts. */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occurs. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <Output> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
FT_Error FT_Alloc( FT_System system,
FT_Long size,
void** P )
{
if ( !P )
{
PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
return FT_Err_Invalid_Argument;
}
if ( size > 0 )
{
*P = malloc( size );
if ( !*P )
{
PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
size ));
return FT_Err_Out_Of_Memory;
}
system->total_alloc += size;
/* ALWAYS ZERO-FILL THE BLOCK! */
MEM_Set( *P, 0, size );
}
else
*P = NULL;
PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
size, (long)P, (long)*P ));
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Realloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
/* from the heap, possibly changing `*P'. */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occurs. */
/* */
/* size :: The size in bytes of the block to allocate. */
/* */
/* <InOut> */
/* P :: A pointer to the fresh new block. It should be set to */
/* NULL if `size' is 0, or in case of error. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
FT_Error FT_Realloc( FT_System system,
FT_Long size,
void** P )
{
void* Q;
if ( !P )
{
PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
return FT_Err_Invalid_Argument;
}
/* if the original pointer is NULL, call FT_Alloc() */
if ( !*P )
return FT_Alloc( system, size, P );
/* if the new block if zero-sized, clear the current one */
if ( size <= 0 )
return FT_Free( system, P );
Q = (void*)realloc( *P, size );
if ( !Q )
{
PERROR(( "FT_Realloc: Reallocation failed!\n" ));
return FT_Err_Out_Of_Memory;
}
*P = Q;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Free */
/* */
/* <Description> */
/* Releases a given block of memory allocated through FT_Alloc(). */
/* */
/* <Input> */
/* system :: A handle to a given `system object' where allocation */
/* occured. */
/* */
/* P :: This is the _address_ of a _pointer_ which points to the */
/* allocated block. It is always set to NULL on exit. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* If P or *P are NULL, this function should return successfully. */
/* This is a strong convention within all of FreeType and its */
/* drivers. */
/* */
BASE_FUNC
FT_Error FT_Free( FT_System system,
void* *P )
{
UNUSED( system );
PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
(long)P, (P ? (long)*P : -1) ));
if ( !P || !*P )
return FT_Err_Ok;
free( *P );
*P = NULL;
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* SYNCHRONIZATION MANAGEMENT */
/* */
/* */
/* This section deals with mutexes. The library can be compiled to */
/* two distinct thread support levels (namely single threaded and */
/* re-entrant modes). */
/* */
/* It protects its variables through the MUTEX_Lock() and */
/* MUTEX_Release() macros which are void in single threaded mode. */
/* */
/* It defines a typeless mutex reference type, `FT_Mutex', that you're */
/* free to redefine for your system's needs. */
/* */
/* The default implementation of ftsys.c contains only dummy functions */
/* which always return successfully. You NEED to specialize them in */
/* order to port ftsys.c to any multi-threaded environment. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE() and PERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_sync
#ifdef FT_CONFIG_THREADS
BASE_FUNC
FT_Error FT_Mutex_Create( FT_System system,
TMutex* mutex )
{
UNUSED( system );
mutex = (void*)-1;
system->num_mutexes++;
/* Insert your own mutex creation code here */
return FT_Err_Ok;
}
BASE_FUNC
void FT_Mutex_Delete( FT_System system,
TMutex* mutex )
{
UNUSED( system );
mutex = (void*)0;
system->num_mutexes--;
/* Insert your own mutex destruction code here */
}
BASE_FUNC
void FT_Mutex_Lock( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate. */
UNUSED( system );
if ( !mutex )
return;
/* Insert your own mutex locking code here */
}
BASE_FUNC
void FT_Mutex_Release( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate */
UNUSED( system );
if ( !mutex )
return;
/* Insert your own mutex release code here */
}
#endif /* FT_CONFIG_THREADS */
/*************************************************************************/
/* */
/* <Function> */
/* FT_New_System */
/* */
/* <Description> */
/* This function is used to create and initialize new system objects. */
/* These are mainly used to let client applications and font servers */
/* specify their own memory allocators and synchronization */
/* procedures. */
/* */
/* <Output> */
/* system :: A handle to a given `system object'. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
EXPORT_FUNC
FT_Error FT_New_System( FT_System* system )
{
*system = (FT_System)malloc( sizeof ( **system ) );
if ( !*system )
return FT_Err_Out_Of_Memory;
/* initialize memory management */
(*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
FT_SYSTEM_FLAG_MUTEXES;
(*system)->total_alloc = 0;
(*system)->num_mutexes = 0;
/* initialize i/o management (nothing) */
/* initialize synchronisation (nothing) */
/* initialize streams (nothing) */
return FT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Done_System */
/* */
/* <Description> */
/* Destroys a given FreeType system object. */
/* */
/* <Input> */
/* system :: A handle to a given `system object'. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
EXPORT_FUNC
FT_Error FT_Done_System( FT_System system )
{
/* finalize synchronization (nothing) */
/* finalize i/o management (nothing) */
/* finalize memory management */
free( system );
return FT_Err_Ok;
}
/* END */

214
config/os2/ftsystem.c Normal file
View File

@ -0,0 +1,214 @@
/**************************************************************************
*
* ftsystem.h 1.0
*
* ANSI-specific FreeType low-level system interface
*
* This file contains the definition of interface used by FreeType
* to access low-level, i.e. memory management, i/o access as well
* as thread synchronisation.
*
*
* Copyright 1996-1999 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
**************************************************************************/
#include <ftsystem.h>
#include <fterrors.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/************************************************************************
*
* <FuncType>
* FT_Alloc_Func
*
* <Description>
* The memory allocator function type
*
* <Input>
* system :: pointer to the system object
* size :: requested size in bytes
*
* <Output>
* block :: address of newly allocated block
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* If your allocation routine ALWAYS zeroes the new block, you
* should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
* object 'flags' field.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_alloc( FT_Memory memory,
long size )
{
(void)memory;
return malloc(size);
}
/************************************************************************
*
* <FuncType>
* FT_Realloc_Func
*
* <Description>
* The memory reallocator function type
*
* <Input>
* system :: pointer to the system object
* new_size :: new requested size in bytes
*
* <InOut>
* block :: address of block in memory
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function is _never_ called when the system flag
* FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
* realloc through "alloc" and "free".
*
* Note that this is possible due to the fact that FreeType's
* "FT_Realloc" always requests the _current_ size of the reallocated
* block as a parameter, thus avoiding memory leaks.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
(void)memory;
(void)cur_size;
return realloc( block, new_size );
}
/************************************************************************
*
* <FuncType>
* FT_Free_Func
*
* <Description>
* The memory release function type
*
* <Input>
* system :: pointer to the system object
* block :: address of block in memory
*
* <Note>
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void ft_free( FT_Memory memory,
void* block )
{
(void)memory;
free( block );
}
/*********************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
static
void ft_close_stream( FT_Stream stream )
{
fclose( STREAM_FILE(stream) );
}
static
unsigned long ft_io_stream( FT_Stream stream,
unsigned long offset,
char* buffer,
unsigned long count )
{
FILE* file;
file = STREAM_FILE(stream);
fseek( file, offset, SEEK_SET );
return (unsigned long)fread( buffer, count, 1, file );
}
extern
int FT_New_Stream( const char* filepathname,
FT_Stream stream )
{
FILE* file;
file = fopen( filepathname, "rb" );
if (!file)
return FT_Err_Cannot_Open_Resource;
fseek( file, 0, SEEK_END );
stream->size = ftell(file);
fseek( file, 0, SEEK_SET );
stream->descriptor.pointer = file;
stream->pos = 0;
stream->read = ft_io_stream;
stream->close = ft_close_stream;
return 0;
}
extern
FT_Memory FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)malloc( sizeof(*memory) );
if (memory)
{
memory->user = 0;
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
}
return memory;
}

192
config/os2/makefile.devel Normal file
View File

@ -0,0 +1,192 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
DELETE := del
SEP := /
BUILD := $(TOP)/config/os2
PLATFORM := os2
CC := gcc
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -L
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O0 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# Librarian to use to build the static library
#
FT_LIBRARIAN := $(AR) -r
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
# Cleaning rules
#
DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
clean_freetype_objects:
-del $(DIR8OBJ)\*.$O
clean_freetype_lib:
-del $(FT_LIBRARY)
clean: clean_freetype_objects
endif

190
config/os2/makefile.gcc Normal file
View File

@ -0,0 +1,190 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
DELETE := del
SEP := /
BUILD := $(TOP)/config/os2
PLATFORM := os2
CC := gcc
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -L
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O0 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# A rule used to clean all objects from OBJ_DIR
#
# The OS/2 command shell does not support very long list of arguments
# so we're stuck with wildcards
#
DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
clean_freetype_objects:
-del $(DIR8OBJ)\*.$O
clean_freetype_lib:
-del $(FT_LIBRARY)
clean: clean_freetype_objects
# Librarian to use to build the static library
#
FT_LIBRARIAN := $(AR) -r
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
endif

172
config/unix/Makefile Normal file
View File

@ -0,0 +1,172 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := rm -f
SEP := /
BUILD := $(TOP)/config/unix
PLATFORM := unix
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O6 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(AR) -r $@ $(OBJECTS_LIST)
endif

172
config/unix/Makefile.devel Normal file
View File

@ -0,0 +1,172 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := rm -f
SEP := /
BUILD := $(TOP)/config/unix
PLATFORM := unix
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O0 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(AR) -r $@ $(OBJECTS_LIST)
endif

31
config/unix/detect.mk Normal file
View File

@ -0,0 +1,31 @@
#
# This file is used to detect which Makefile to use based on the
# value of the CC environment variable.
#
# Unix
#
#
# This will _much_ probably change in the future if we're going to use
# Automake/Autoconf..
#
ifeq ($(PLATFORM),ansi)
has_inittab := $(strip $(wildcard /etc/inittab))
ifneq ($(has_inittab),)
PLATFORM := unix
COPY := cp
DELETE := rm -f
CONFIG_RULES := $(BUILD)$(SEP)Makefile
setup: std_setup
endif # test Unix
endif # test PLATFORM

172
config/unix/ftconfig.h Normal file
View File

@ -0,0 +1,172 @@
/*******************************************************************
*
* ftconfig.h
*
* Unix-specific configuration file
*
* Copyright 1996-1998 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*
* This header file contains a number of macro definitions that are
* used by the rest of the engine. Porters are free to copy this file
* and adapt it to suit their own system..
*
* IMPORTANT NOTE :
*
* Porters, read carefully the comments in ftsys.h before trying
* to port this file to your system. It contains many essential
* remarks, and will ease your work greatly..
*
******************************************************************/
#ifndef FTCONFIG_H
#define FTCONFIG_H
/*************************************************************************/
/* */
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
/* */
/* These macros can be toggled to suit a specific system. The current */
/* ones are defaults used to compile FreeType in a 32-bits ANSI C */
/* environment. Copy this file to your own "freetype/arch/<system>" */
/* directory, and edit it to port the engine.. */
/* */
/*************************************************************************/
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you have a working `mmap' system call. */
#define HAVE_MMAP
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if your processor stores words with the most significant
byte first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define if the X Window System is missing or not being used. */
/* #undef X_DISPLAY_MISSING */
/* The number of bytes in a int. */
#define SIZEOF_INT 4
/* The number of bytes in a long. */
#define SIZEOF_LONG 4
/* Define if you have the getpagesize function. */
#define HAVE_GETPAGESIZE 1
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H
/* Define if you have the libintl library. */
/* #undef HAVE_LIBINTL */
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/* See the definition of the macro FT_CONFIG_OPTION_LITTLE_ENDIAN */
/* and FT_CONFIG_OPTION_BIG_ENDIAN below, they may need to be set */
/* according to the platform too.. */
#include <ftoption.h>
/*************************************************************************/
/* */
/* AUTOMATIC CONFIGURATION MACROS */
/* */
/* These macros are computed from the ones defined above. Don't touch */
/* their definition, unless you know precisely what you're doing. No */
/* porter should need to mess with them. */
/* */
/*************************************************************************/
/* IntN types: */
/* */
/* Used to guarantee the size of some specific integers. */
/* */
typedef signed short FT_Int16;
typedef unsigned short FT_Word16;
#if SIZEOF_INT == 4
typedef signed int FT_Int32;
typedef unsigned int FT_Word32;
#elif SIZEOF_LONG == 4
typedef signed long FT_Int32;
typedef unsigned long FT_Word32;
#else
#error "no 32bit type found - please check your configuration files"
#endif
#if SIZEOF_LONG == 8
/* LONG64 must be defined when a 64-bit type is available */
#define LONG64
#define INT64 long
#else
/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate it */
/* by defining the FTCALC_USE_LONG_LONG macro in 'ftconfig.h'. Note that */
/* this will produce many -ansi warnings during library compilation. */
#ifdef FTCALC_USE_LONG_LONG
#define LONG64
#define INT64 long long
#endif /* FTCALC_USE_LONG_LONG */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define LOCAL_DEF static
#define LOCAL_FUNC static
#else
#define LOCAL_DEF extern
#define LOCAL_FUNC /* nothing */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
#define BASE_DEF LOCAL_DEF
#define BASE_FUNC LOCAL_FUNC
#else
#define BASE_DEF extern
#define BASE_FUNC /* nothing */
#endif
#ifndef EXPORT_DEF
#define EXPORT_DEF extern
#endif
#ifndef EXPORT_FUNC
#define EXPORT_FUNC /* nothing */
#endif
#endif /* FTCONFIG_H */

162
config/unix/ftoption.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_EXTENSIONS */
/* */
/* The maximum number of extensions that can be registered in a */
/* single font driver. 8 seems to be a good choice for now.. */
/* */
#define FT_MAX_EXTENSIONS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

871
config/unix/ftsys.c Normal file
View File

@ -0,0 +1,871 @@
/*******************************************************************
*
* ftsys.c
*
* Unix-specific system operations.
*
* Copyright 1996-1998 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*
* This implementation of the 'ftsys' component uses memory-mapped
* files, as well as the ANSI malloc/free functions..
*
* IMPORTANT NOTE :
*
* Porters, read carefully the comments in ftsys.h before trying
* to port this file to your system. It contains many essential
* remarks, and will ease your work greatly..
*
******************************************************************/
#include "ftsys.h"
#include "ftobjs.h"
#include "ftstream.h"
#include "ftdebug.h"
/* Memory-mapping includes and definitions.. */
/* */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/mman.h>
#ifndef MAP_FILE
#define MAP_FILE 0x00
#endif
/*
* The prototype for munmap() is not provided on SunOS. This needs to
* have a check added later to see if the GNU C library is being used.
* If so, then this prototype is not needed.
*/
#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
extern int munmap( caddr_t addr, int len );
#endif
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_io
/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
/* we identify each memory-mapped file through its address in memory */
/* hence the following macro definition.. */
#define SYS_STREAM void*
/**************************************************************************/
/* */
/* I/O ACCESS AND MANAGEMENT */
/* */
/* We only define the "ANSI" resource class in this class. It is */
/* disk-based, and provides a MRU cache, in order to only keep the file */
/* descriptors of the 10 most recently used resource files. */
/* */
/* it simply contains two lists. One contains the "cached" resources */
/* with a valid FILE* pointer, the second contains all other "flushed" */
/* resource objects. */
/* */
/* The FT_MMapFile class derives from FT_ResourceRec - description : */
/* */
/* <Struct> FT_AnsiFileRec */
/* */
/* <Fields> */
/* */
/* root :: */
/* the root resource class fields. */
/* */
/* pathname :: */
/* the file's pathname. Needed because we open and close font */
/* resources dynamically in order to limit the number of */
/* concurrently active mappings (this saves kernel resources). */
/* */
/* file_size :: */
/* the size in bytes of the resource. This field should be set to */
/* -1 until the resource is first opened.. */
/* */
#include <stdio.h>
typedef struct FT_MMapFileRec_
{
FT_ResourceRec root;
const char* pathname;
FT_Long file_size; /* file size in bytes */
} FT_MMapFileRec, *FT_MMapFile;
/* We use the macro STREAM_Name as a convenience to return a given */
/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
/* which is typecasted to the FT_AnsiFile class */
#define STREAM_Name(stream) ((FT_MMapFile)stream->resource)->pathname
/* We use the macro STREAM_File as a convenience to extract the */
/* system-specific stream handle from a given FreeType stream object */
#define STREAM_File(stream) ((void*)stream->stream_id.pointer)
/***************************************************************************/
/* */
/* <Function> MMapFile_Open */
/* */
/* <Description> */
/* This function is used to open a system-stream for a given resource. */
/* */
/* Note that it must update the target FreeType stream object with the */
/* system-stream handle and the resource's size. */
/* */
/* Also, the 'stream->base' field must be set to NULL for disk-based */
/* resource, and to the address in memory of the resource's first byte */
/* for a memory-based one. */
/* */
/* <Input> */
/* resource :: the source resource */
/* stream :: the target stream object */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply opens and maps the resource's file pathname */
/* */
/* The stream object IS NOT CREATED by this function, but by its caller. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Open( FT_MMapFile resource,
FT_Stream stream )
{
int file;
struct stat stat_buf;
/* open the file */
file = open( resource->pathname, O_RDONLY );
if (file < 0)
{
PERROR(( "UnixSys.MMapFile_Open : could not open '%s'\n",
resource->pathname ));
return FT_Err_Cannot_Open_Stream;
}
if (fstat( file, &stat_buf ) < 0)
{
PERROR(( "UnixSys.MMapFile_Open : could not 'fstat' file '%s'\n",
resource->pathname ));
goto Fail_Map;
}
if ( resource->file_size < 0 )
resource->file_size = stat_buf.st_size;
stream->resource = (FT_Resource)resource;
stream->system = resource->root.driver->system;
stream->size = resource->file_size;
stream->stream_id.pointer = mmap( NULL,
resource->file_size,
PROT_READ,
MAP_FILE | MAP_PRIVATE,
file,
0 );
if ( (long)stream->stream_id.pointer == -1 )
{
PERROR(( "UnixSys.MMapFile_Open : Could not map file '%s'\n",
resource->pathname ));
goto Fail_Map;
}
close(file);
stream->base = (FT_Byte*)stream->stream_id.pointer;
stream->cursor = stream->base;
PTRACE1(( "UnixSys.MMapFile_Open: opened '%s' (%d bytes) succesfully\n",
resource->pathname, resource->file_size ));
return FT_Err_Ok;
Fail_Map:
close(file);
stream->resource = NULL;
stream->size = 0;
stream->stream_id.pointer = NULL;
stream->base = NULL;
stream->cursor = NULL;
return FT_Err_Cannot_Open_Stream;
}
/***************************************************************************/
/* */
/* <Function> MMapFile_Close */
/* */
/* <Description> Closes a given stream */
/* */
/* <Input> */
/* stream :: the target stream object */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function simply unmaps the resource.. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Close( FT_Stream stream )
{
PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
munmap ( (void*)stream->stream_id.pointer, stream->size );
stream->resource = NULL;
stream->stream_id.pointer = NULL;
stream->size = 0;
stream->base = NULL;
stream->cursor = NULL;
return FT_Err_Ok;
}
/***************************************************************************/
/* */
/* <Function> MMapFile_Seek */
/* */
/* <Description> Seek a stream to a given position */
/* */
/* <Input> */
/* stream :: the target stream object */
/* position :: offset in bytes from start of resource/stream */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function should never be called for memory-based resources.. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Seek( FT_Stream stream,
FT_Long position )
{
(void)stream;
(void)position;
return FT_Err_Invalid_Stream_Operation;
}
/***************************************************************************/
/* */
/* <Function> MMapFile_Skip */
/* */
/* <Description> Skip a given number of bytes in an MMap stream. */
/* Useful to skip pad bytes, for example. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* count :: number of bytes to skip in the stream */
/* */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function should never be called for memory-based resources.. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Skip( FT_Stream stream,
FT_Long count )
{
(void)stream;
(void)count;
return FT_Err_Invalid_Stream_Operation;
}
/***************************************************************************/
/* */
/* <Function> MMapFile_Pos */
/* */
/* <Description> Returns the current offset within an MMap stream's */
/* resource. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* */
/* <Output> */
/* position :: current offset. -1 in case of error */
/* */
/* <Return> */
/* Error code. */
/* */
/* <Note> */
/* This function should never be called for memory-based resources.. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Pos( FT_Stream stream,
FT_Long* position )
{
(void)stream;
(void)position;
return FT_Err_Invalid_Stream_Operation;
}
/***************************************************************************/
/* */
/* <Function> MMapFile_Read */
/* */
/* <Description> Read a given number of bytes from an MMap stream into */
/* memory. */
/* */
/* <Input> */
/* stream :: the target stream object */
/* buffer :: the target read buffer where data is copied */
/* size :: number of bytes to read from the stream */
/* */
/* <Output> */
/* read_bytes :: the number of bytes effectively read from the stream */
/* used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
/* by some parts of the library.. */
/* <Return> */
/* Error code */
/* */
/* <Note> */
/* This function should never be called for memory-based resources.. */
/* */
/***************************************************************************/
static
FT_Error MMapFile_Read( FT_Stream stream,
FT_Byte* buffer,
FT_Long size,
FT_Long* read_bytes )
{
(void)stream;
(void)buffer;
(void)size;
(void)read_bytes;
return FT_Err_Invalid_Stream_Operation;
}
/* The following table is the "virtual method table" for the 'MMap */
/* resource class', which methods are defined above. Its address is */
/* set in the 'interface' field of all resource objects created by */
/* the function FT_Create_MMapFile (see below) */
static
FTRes_InterfaceRec FT_MMapFile_Interface =
{
(FTRes_Open_Func) MMapFile_Open,
(FTRes_Close_Func) MMapFile_Close,
(FTRes_Seek_Func) MMapFile_Seek,
(FTRes_Skip_Func) MMapFile_Skip,
(FTRes_Pos_Func) MMapFile_Pos,
(FTRes_Read_Func) MMapFile_Read,
};
/************************************************************************/
/* */
/* <Function> FT_Create_Resource */
/* */
/* <Description> */
/* Create a new resource object for a given library. Note that this */
/* function takes an ASCII 'pathname' as an argument. */
/* */
/* <Input> */
/* library :: handle to target library object */
/* pathanme :: ASCII pathname of the font file */
/* */
/* <Output> */
/* resource :: handle to new resource object */
/* */
/* <Return> */
/* Error code. 0 means success */
/* */
/* <Note> */
/* When porting the library to exotic environments, where an */
/* ASCII pathname isn't used to name files, developers should */
/* invoke directly their own resource creation function which */
/* must be placed in their port of the "ftsys" component. */
/* */
/* See the porting guide for more information.. */
/* */
EXPORT_FUNC
FT_Error FT_Create_Resource( FT_Library library,
const char* pathname,
FT_Resource* aresource )
{
FT_Int len;
FT_System system;
FT_MMapFile resource;
FT_Error error;
*aresource = NULL;
if (!library)
{
PERROR(( "Unix.New_Resource : null library handle\n" ));
return FT_Err_Invalid_Library_Handle;
}
system = library->system;
if ( !pathname )
goto Fail_Null;
len = strlen(pathname);
if (len == 0)
goto Fail_Null;
resource = NULL;
if ( ALLOC( resource, sizeof(*resource) ) ||
ALLOC( resource->pathname, len+1 ) )
goto Fail_Memory;
resource->root.library = library;
resource->root.interface = &FT_MMapFile_Interface;
resource->root.flags = FT_RESOURCE_TYPE_MEMORY_BASED;
resource->file_size = -1;
strcpy( (char*)resource->pathname, pathname );
PTRACE1(( "Create_MMapFile : MMap resource created for '%s'\n",
pathname ));
*aresource = (FT_Resource)resource;
return FT_Err_Ok;
Fail_Null:
PERROR(( "Create_MMapFile : null pathname !!\n" ));
return FT_Err_Invalid_Argument;
Fail_Memory:
if (resource)
FREE( resource->pathname );
FREE( resource );
PERROR(( "Create_MMapFile : error when creating resource !\n" ));
return error;
}
/***************************************************************************/
/* */
/* <Function> FT_Destroy_Resource */
/* */
/* <Description> Destroys an MMap resource object. */
/* This function is never called directly by the font */
/* drivers. Only by the higher-level part of FreeType */
/* (called the HLib), or client applications */
/* */
/* <Input> */
/* resource :: the MMap resource object */
/* */
/* <Note> */
/* This functions does not check that runs or streams are opened for */
/* the resource (for now, we assume developer intelligence. We'll most */
/* probably lower our standard later to ease debugging ;-) */
/* */
/***************************************************************************/
EXPORT_FUNC
FT_Error FT_Destroy_Resource( FT_Resource resource )
{
FT_System system = resource->library->system;
FT_MMapFile res = (FT_MMapFile)resource;
if ( !res || res->root.interface != &FT_MMapFile_Interface )
{
PERROR((
"Destroy_MMapFile : Trying to destroy an invalid resource !!\n" ));
return FT_Err_Invalid_Resource_Handle;
}
PTRACE1(( "Destroy_MMapFile : destroying resource for '%s'\n",
res->pathname ));
FREE( res->pathname );
FREE( res );
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* MEMORY MANAGEMENT */
/* */
/* */
/* This part copies the old FreeType 1.0 and 1.1 memory management */
/* scheme that was defined in the file "ttmemory.h". One can see that */
/* */
/* - a set of macros is defined for the memory operations used */
/* by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from */
/* the fact that many compilers are able to inline these ops directly */
/* within the compiled code, rather than generating a call to the */
/* C library. However, this obliges us to include the <string.h> */
/* header file. */
/* */
/* If you provide your own memory operations routine, you can get */
/* rid of the #include <string.h> below. */
/* */
/* */
/* - the FT_Alloc function has several essential properties that */
/* MUST be retained by each port : */
/* */
/* - it returns an error code, NOT the allocated block's base */
/* address */
/* */
/* - it takes the address of a target pointer, where the block's */
/* base address will be set. if the size is zero, its value */
/* will be NULL and the function returns successfully */
/* */
/* - in case of error, the pointer's value is set to NULL and */
/* an error code is returned.. */
/* */
/* - the new allocated block MUST be zero-filled. This is a strong */
/* convetion the rest of the engine relies on */
/* */
/* */
/* */
/* - the FT_Free function has also its essentials : */
/* */
/* - it takes the address of a pointer which value is the block's */
/* base address. This is UNLIKE a standard "free" which takes the */
/* the block's base directly. */
/* */
/* - it accepts succesfully the address of a pointer which value */
/* is NULL, in which case it simply returns. */
/* */
/* - the pointer is always set to NULL by the function */
/* */
/* */
/* - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the */
/* library, and should NOT be modified by porters !! */
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_memory
#include <stdlib.h>
/**************************************************************************/
/* */
/* <Function> FT_Alloc */
/* */
/* <Description> */
/* Allocates a new bloc of memory. The returned area is always */
/* zero-filled, this is a strong convention in many FreeType parts */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occurs.. */
/* */
/* size :: size in bytes of the block to allocate */
/* */
/* <Output> */
/* P :: pointer to the fresh new block. It should be set */
/* to NULL if 'size' is 0, of in case of error.. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/**************************************************************************/
BASE_FUNC
FT_Error FT_Alloc( FT_System system,
long size,
void* *P )
{
if (!P)
{
PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
return FT_Err_Invalid_Argument;
}
if ( size > 0 )
{
*P = malloc( size );
if ( !*P )
{
PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
size ));
return FT_Err_Out_Of_Memory;
}
system->total_alloc += size;
/* ALWAYS ZERO-FILL THE BLOCK !!!!! */
MEM_Set( *P, 0, size );
}
else
*P = NULL;
PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
size, (long)P, (long)*P ));
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* <Function> FT_Realloc */
/* */
/* <Description> */
/* Reallocates a block of memory pointed to by '*P' to 'Size' */
/* bytes from the hea^, possibly changing '*P'. */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occurs.. */
/* */
/* size :: size in bytes of the block to allocate */
/* */
/* <InOut> */
/* P :: pointer to the fresh new block. It should be set */
/* to NULL if 'size' is 0, of in case of error.. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
BASE_FUNC
int FT_Realloc( FT_System system,
long size,
void* *P )
{
void* Q;
if (!P)
{
PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
return FT_Err_Invalid_Argument;
}
/* if the original pointer is NULL, call FT_Alloc */
if (!*P)
return FT_Alloc( system, size, P );
/* if the new block if zero-sized, clear the current one */
if (size <= 0)
return FT_Free( system, P );
Q = (void*)realloc( *P, size );
if (!Q)
{
PERROR(( "FT_Realloc : reallocation failed\n" ));
return FT_Err_Out_Of_Memory;
}
*P = Q;
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* <Function> FT_Free */
/* */
/* <Description> */
/* Releases a given block of memory allocated through FT_Alloc */
/* */
/* <Input> */
/* system :: handle to a given 'system object' where allocation */
/* occured.. */
/* */
/* P :: This is the _address_ of a _pointer_ which points to */
/* the allocated block. It is always set to NULL on exit */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* If P or *P are NULL, this function should return successfuly. This */
/* is a strong convention within all of FreeType and its drivers.. */
/* */
BASE_FUNC
FT_Error FT_Free( FT_System system,
void* *P )
{
(void)system; /* unused parameter. Gets rid of warnings */
PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
(long)P, (P ? (long)*P : -1) ));
if ( !P || !*P )
return FT_Err_Ok;
free( *P );
*P = NULL;
return FT_Err_Ok;
}
/**************************************************************************/
/* */
/* SYNCHRONIZATION MANAGEMENT */
/* */
/* */
/* This section deals with mutexes. The library can be compiled to */
/* three distinct thread-support levels ( namely single-threaded, */
/* thread-safe and re-entrant modes ). */
/* */
/* It protects its variables through the MUTEX_Lock and MUTEX_Release */
/* macros which are void in single-threaded mode. */
/* */
/* */
/* It defines a type-less mutex reference type, "TMutex", that you're */
/* free to redefine for your system's needs.. */
/* */
/* The default implementation of ftsys.c contains only dummy functions */
/* which always return succesfully. you NEED to specialize them in */
/* order to port ftsys.c in any multi-threaded environment... */
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the PTRACE and PERROR macros, used to print/log */
/* messages during execution.. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_sync
#ifdef FT_CONFIG_THREADS
BASE_FUNC
FT_Error FT_Mutex_Create ( FT_System system,
TMutex* mutex )
{
(void)system; /* unused parameter. Gets rid of warnings */
mutex = (void*)-1;
system->num_mutexes++;
return FT_Err_Ok;
/* Replace this line with your own mutex creation code */
}
BASE_FUNC
void FT_Mutex_Delete ( FT_System system,
TMutex* mutex )
{
(void)system; /* unused parameter. Gets rid of warnings */
mutex = (void*)0;
system->num_mutexes--;
/* Replace this line with your own mutex destruction code */
}
BASE_FUNC
void FT_Mutex_Lock ( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate. */
(void)system; /* unused parameter. Gets rid of warnings */
if ( !mutex )
return;
; /* Insert your own mutex locking code here */
}
void FT_Mutex_Release( FT_System system,
TMutex* mutex )
{
/* NOTE: It is legal to call this function with a NULL argument */
/* in which case an immediate return is appropriate */
(void)system; /* unused parameter. Gets rid of warnings */
if ( !mutex )
return;
; /* Insert your own mutex release code here */
}
#endif /* FT_CONFIG_THREADS */
EXPORT_FUNC
FT_Error FT_New_System( FT_System* system )
{
*system = (FT_System)malloc( sizeof(FT_SystemRec) );
if ( !*system )
return FT_Err_Out_Of_Memory;
/* the ANSI function 'free' is unable to return the number */
/* of released bytes. Hence, the 'current_alloc' field of the */
/* system object cannot be used */
(*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
FT_SYSTEM_FLAG_MUTEXES;
(*system)->total_alloc = 0;
(*system)->num_mutexes = 0;
/* initialise i/o management (nothing) */
/* initialise synchronisation (nothing) */
/* initialise streams */
return FT_Err_Ok;
}
EXPORT_FUNC
FT_Error FT_Done_System( FT_System system )
{
/* finalise syncrhonisation (nothing) */
/* finalise i/o management (nothing) */
/* finalise memory management */
free( system );
return FT_Err_Ok;
}

277
config/unix/ftsystem.c Normal file
View File

@ -0,0 +1,277 @@
/**************************************************************************
*
* ftsystem.h 1.0
*
* Unix-specific FreeType low-level system interface
*
* This file contains the definition of interface used by FreeType
* to access low-level, i.e. memory management, i/o access as well
* as thread synchronisation.
*
*
* Copyright 1996-1999 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
**************************************************************************/
#include <ftsystem.h>
#include <fterrors.h>
#include <ftconfig.h>
#include <ftdebug.h>
/* Memory-mapping includes and definitions.. */
/* */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/mman.h>
#ifndef MAP_FILE
#define MAP_FILE 0x00
#endif
/*
* The prototype for munmap() is not provided on SunOS. This needs to
* have a check added later to see if the GNU C library is being used.
* If so, then this prototype is not needed.
*/
#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
extern int munmap( caddr_t addr, int len );
#endif
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/************************************************************************
*
* <FuncType>
* FT_Alloc_Func
*
* <Description>
* The memory allocator function type
*
* <Input>
* system :: pointer to the system object
* size :: requested size in bytes
*
* <Output>
* block :: address of newly allocated block
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* If your allocation routine ALWAYS zeroes the new block, you
* should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
* object 'flags' field.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_alloc( FT_Memory memory,
long size )
{
(void)memory;
return malloc(size);
}
/************************************************************************
*
* <FuncType>
* FT_Realloc_Func
*
* <Description>
* The memory reallocator function type
*
* <Input>
* system :: pointer to the system object
* new_size :: new requested size in bytes
*
* <InOut>
* block :: address of block in memory
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function is _never_ called when the system flag
* FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
* realloc through "alloc" and "free".
*
* Note that this is possible due to the fact that FreeType's
* "FT_Realloc" always requests the _current_ size of the reallocated
* block as a parameter, thus avoiding memory leaks.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
(void)memory;
(void)cur_size;
return realloc( block, new_size );
}
/************************************************************************
*
* <FuncType>
* FT_Free_Func
*
* <Description>
* The memory release function type
*
* <Input>
* system :: pointer to the system object
* block :: address of block in memory
*
* <Note>
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void ft_free( FT_Memory memory,
void* block )
{
(void)memory;
free( block );
}
/*********************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
/* We use the macro STREAM_File as a convenience to extract the */
/* system-specific stream handle from a given FreeType stream object */
#define STREAM_File(stream) ((void*)stream->descriptor.pointer)
#undef FT_COMPONENT
#define FT_COMPONENT trace_io
static
void ft_close_stream( FT_Stream stream )
{
munmap ( stream->descriptor.pointer, stream->size );
stream->descriptor.pointer = NULL;
stream->size = 0;
stream->base = 0;
}
extern
int FT_New_Stream( const char* filepathname,
FT_Stream stream )
{
int file;
struct stat stat_buf;
/* open the file */
file = open( filepathname, O_RDONLY );
if (file < 0)
{
FT_ERROR(( "FT.Unix.Open:" ));
FT_ERROR(( " could not open '%s'\n", filepathname ));
return FT_Err_Cannot_Open_Stream;
}
if (fstat( file, &stat_buf ) < 0)
{
FT_ERROR(( "FT.Unix.Open:" ));
FT_ERROR(( " could not 'fstat' file '%s'\n", filepathname ));
goto Fail_Map;
}
stream->size = stat_buf.st_size;
stream->pos = 0;
stream->base = mmap( NULL,
stream->size,
PROT_READ,
MAP_FILE | MAP_PRIVATE,
file,
0 );
if ( (long)stream->base == -1 )
{
FT_ERROR(( "FT.Unix.Open:" ));
FT_ERROR(( " Could not map file '%s'\n", filepathname ));
goto Fail_Map;
}
close(file);
stream->descriptor.pointer = stream->base;
stream->pathname.pointer = (char*)filepathname;
stream->close = ft_close_stream;
stream->read = 0;
FT_TRACE1(( "FT.Unix.Open:" ));
FT_TRACE1(( " opened '%s' (%d bytes) succesfully\n",
filepathname, stream->size ));
return FT_Err_Ok;
Fail_Map:
close(file);
stream->base = NULL;
stream->size = 0;
stream->pos = 0;
return FT_Err_Cannot_Open_Stream;
}
extern
FT_Memory FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)malloc( sizeof(*memory) );
if (memory)
{
memory->user = 0;
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
}
return memory;
}

179
config/win32/Makefile.gcc Normal file
View File

@ -0,0 +1,179 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := del
SEP := /
BUILD := $(TOP)/config/win32
PLATFORM := win32
CC := gcc
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)/obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := o
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := a
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := libfreetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -l
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - beware, there is a space after the 'o' !!
#
#
T := -o
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g -O6 -Wall
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# Librarian to use to build the static library
#
FT_LIBRARIAN := $(AR) -r
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
$(FT_LIBRARY): $(OBJECTS_LIST)
-$(DELETE) $@
$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
endif

180
config/win32/Makefile.lcc Normal file
View File

@ -0,0 +1,180 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Unix + gcc
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
ifndef TOP
TOP := .
endif
DELETE := del
SEP := /
BUILD := $(TOP)$(SEP)config$(SEP)win32
PLATFORM := win32
CC := lcc
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)$(SEP)obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := obj
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := lib
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := freetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := -I
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := -D
# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
#
#
T := -Fo
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := -Fl
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := -c -g2 -O
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
# directory. That _is_ stupid, but we'll have to deal with it..
#
DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
$(FT_LIBRARY): $(OBJECTS_LIST)
@$(TOP)/config/win32/lcclib.bat
endif

174
config/win32/Makefile.vcc Normal file
View File

@ -0,0 +1,174 @@
#*******************************************************************
#*
#* FreeType 2 Configuration rules for Visual C++ on Win32
#*
#* Copyright 1996-1999 by
#* David Turner, Robert Wilhelm, and Werner Lemberg.
#*
#* This file is part of the FreeType project, and may only be used
#* modified and distributed under the terms of the FreeType project
#* license, LICENSE.TXT. By continuing to use, modify, or distribute
#* this file you indicate that you have read the license and
#* understand and accept it fully.
#*
#*
#* The purpose of this sub-Makefile is to define various build and
#* platform specific variables before including the sub-Makefile
#* containing the FreeType library rules, found in
#*
#* $(TOP)/config/freetype.mk
#*
#* The following variables must be defined before including this
#* file :
#*
#* TOP Pathname to the top of the FreeType sources
#* hierarchy
#*
#* This file should define the following variables before including
#* the FreeType library rules file :
#*
#* BUILD Pathname to the platform-specific files used
#* for the build. Usually `$(TOP)/config/<system>'
#*
#* SEP Directory separator for the current platform.
#* Either / or \ (maybe : on Macs)
#*
#* DELETE The forced remove/delete command to erase one or more
#* files
#*
#* INCLUDE The location of all public header files. e.g.
#* `$(TOP)/include'include' *
#*
#* SRC The directory containing all sources. e.g.
#* '$(TOP)/src'
#*
#* OBJ_DIR The location where compiled object files will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIB_DIR The location where the resulting library file will be
#* placed, e.g. '$(TOP)/obj'
#*
#* LIBRARY The filename of the resulting library file, without
#* its extension.. e.g. 'libfreetype' or 'freetype'
#*
#* O The object file suffix. Can be '.o', '.obj,' '.lo,'
#* ';coff,' etc.
#*
#* A The library file suffix. Can be '.a' '.so,' '.lib'
#* '.dll,' etc.
#*
#* I The path inclusion flag. Some compilers use a
#* different flag than '-I' to specify an additional
#* include path. Examples are '/i=' or '-J ', etc.
#*
#* D The macro definition flag. I haven't met compilers
#* which don't use the '-D' switch to define a macro, but
#* who knows...
#*
#* T The compilation flag used to identify the target. Some
#* compilers use a different flag than '-o ' to specify
#* the name of the target object file.
#*
#* CFLAGS The set of flags used to compile object files.
#* (usually contains the flag '-c').
#*
#*
#*
#*******************************************************************
DELETE := del
SEP := /
BUILD := $(TOP)$(SEP)config$(SEP)win32
PLATFORM := win32
CC := cl
# the directory where all object files are placed
#
OBJ_DIR := $(TOP)$(SEP)obj
# the directory where all library files are placed
#
# by default, this is the same as OBJ_DIR, however, this can be
# changed to suit particular needs..
#
LIB_DIR := $(OBJ_DIR)
# the object file extension, this can be .o, .tco, .obj, etc..
# depending on the platform
#
O := obj
# the library file extension, this can be .a, .lib, etc..
# depending on the platform
#
A := lib
# The name of the final library file.
# Note that the DOS-specific Makefile uses a shorter (8.3) name
#
LIBRARY := freetype
# path inclusion flag.
#
# Some compilers use a different flag than '-I' to specify an
# additional include path. Examples are "/i=" or "-J", etc...
#
I := /I
# The link flag used to specify a given library file on link.
# Note that this is only used to compile the demo programs, not
# the library itself.
#
L := /Fl
# C flag used to define a macro before the compilation of a given
# source object. Usually is '-D' like in "-DDEBUG"
#
D := /D
# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
#
#
T := /Fo
# C flags
#
# These should concern :
#
# - debug output
# - optimization
# - warnings
# - ansi compliance..
#
ifndef CFLAGS
CFLAGS := /nologo /c /Ox /G5 /Za /W3 /WX
endif
ifdef BUILD_FREETYPE
include $(TOP)/config/freetype.mk
# This final rule is used to link all object files into a single
# library. It is part of the system-specific sub-Makefile because not
# all librarians accept a simple syntax like :
#
# librarian library_file {list of object files}
#
# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
# directory. That _is_ stupid, but we'll have to deal with it..
#
DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
$(FT_LIBRARY): $(OBJECTS_LIST)
lib /out:$@ $(OBJECTS_LIST)
endif

66
config/win32/detect.mk Normal file
View File

@ -0,0 +1,66 @@
#
# This file is used to detect a Win32 host platform.
#
# This configuration file to be used depends on the value of the CC
# environment variable.
#
#
# We test for the COMSPEC environment variable, then run the 'ver'
# command-line program to see if its output contains the word "Windows"
#
# If this is true, we're running a win32 platform (or an emulation)
#
ifeq ($(PLATFORM),ansi)
ifdef COMSPEC
is_windows := $(findstring Windows,$(strip $(shell ver)))
ifneq ($(is_windows),)
PLATFORM := win32
DELETE := del
COPY := copy
CONFIG_FILE := Makefile.gcc # gcc Makefile by default - aren't we biased ;-)
SEP := /
ifeq ($(CC),cc)
CC := gcc
endif
ifneq ($(findstring visualc,$(MAKECMDGOALS)),) # Visual C/C++
CONFIG_FILE := Makefile.vcc
SEP := $(BACKSLASH)
CC := cl
visualc: setup
endif
ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++
CONFIG_FILE := Makefile.wat
SEP := $(BACKSLASH)
CC := wcc386
watcom: setup
endif
ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++
CONFIG_FILE := Makefile.icc
SEP := $(BACKSLASH)
CC := icc
visualage: setup
endif
ifneq ($(findstring lcc,$(MAKECMDGOALS)),) # LCC-Win32
CONFIG_FILE := Makefile.lcc
SEP := $(BACKSLASH)
CC := lcc
lcc: setup
endif
CONFIG_RULES := $(TOP)\config\win32\$(CONFIG_FILE)
setup: dos_setup
endif #test Windows
endif #test COMSPEC
endif #test PLATFORM

182
config/win32/ftconfig.h Normal file
View File

@ -0,0 +1,182 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* ANSI-specific configuration file (specification only). */
/* */
/* Copyright 1996-1999 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used */
/* modified and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This header file contains a number of macro definitions that are used */
/* by the rest of the engine. Porters are free to copy this file and */
/* adapt it to suit their own system. */
/* */
/* IMPORTANT NOTE: */
/* */
/* Porters, read carefully the comments in `ftsys.h' before trying to */
/* port this file to your system. It contains many essential */
/* remarks, and will ease your work greatly. */
/* */
/*************************************************************************/
#ifndef FTCONFIG_H
#define FTCONFIG_H
/* Include the header file containing all developer build options */
#include <ftoption.h>
/*************************************************************************/
/* */
/* PLATFORM-SPECIFIC CONFIGURATION MACROS */
/* */
/* These macros can be toggled to suit a specific system. The current */
/* ones are defaults used to compile FreeType in an ANSI C environment */
/* (16bit compilers are also supported). Copy this file to your own */
/* `freetype/arch/<system>' directory, and edit it to port the engine. */
/* */
/*************************************************************************/
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* We use <limits.h> values to know the sizes of the types. */
#include <limits.h>
/* The number of bytes in an `int' type. */
#if UINT_MAX == 0xFFFFFFFF
#define SIZEOF_INT 4
#elif UINT_MAX == 0xFFFF
#define SIZEOF_INT 2
#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_INT 8
#else
#error "Unsupported number of bytes in `int' type!"
#endif
/* The number of bytes in a `long' type. */
#if ULONG_MAX == 0xFFFFFFFF
#define SIZEOF_LONG 4
#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
#define SIZEOF_LONG 8
#else
#error "Unsupported number of bytes in `long' type!"
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 0
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Preferred alignment of data */
#define FT_ALIGNMENT 8
/*************************************************************************/
/* */
/* AUTOMATIC CONFIGURATION MACROS */
/* */
/* These macros are computed from the ones defined above. Don't touch */
/* their definition, unless you know precisely what you're doing. No */
/* porter should need to mess with them. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* IntN types */
/* */
/* Used to guarantee the size of some specific integers. */
/* */
typedef signed short FT_Int16;
typedef unsigned short FT_Word16;
#if SIZEOF_INT == 4
typedef signed int FT_Int32;
typedef unsigned int FT_Word32;
#elif SIZEOF_LONG == 4
typedef signed long FT_Int32;
typedef unsigned long FT_Word32;
#else
#error "no 32bit type found - please check your configuration files"
#endif
#if SIZEOF_LONG == 8
/* LONG64 must be defined when a 64-bit type is available */
#define LONG64
#define INT64 long
#else
/*************************************************************************/
/* */
/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'. Note */
/* that this will produce many -ansi warnings during library */
/* compilation. */
/* */
#ifdef FTCALC_USE_LONG_LONG
#define LONG64
#define INT64 long long
#endif /* FTCALC_USE_LONG_LONG */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
#define LOCAL_DEF static
#define LOCAL_FUNC static
#else
#define LOCAL_DEF extern
#define LOCAL_FUNC /* nothing */
#endif
#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
#define BASE_DEF LOCAL_DEF
#define BASE_FUNC LOCAL_FUNC
#else
#define BASE_DEF extern
#define BASE_FUNC /* nothing */
#endif
#ifndef EXPORT_DEF
#define EXPORT_DEF extern
#endif
#ifndef EXPORT_FUNC
#define EXPORT_FUNC /* nothing */
#endif
#endif /* FTCONFIG_H */
/* END */

162
config/win32/ftoption.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef FTOPTION_H
#define FTOPTION_H
/*************************************************************************/
/* */
/* USER-SELECTABLE CONFIGURATION MACROS */
/* */
/* These macros can be toggled by developers to enable or disable */
/* certain aspects of FreeType. This file contains macros that apply to */
/* all of FreeType. Driver-specific configurations are placed in each */
/* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h'). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Alternate Glyph Image Format support */
/* */
/* By default, the glyph images returned by the FreeType glyph loader */
/* can either be a pixmap or a vectorial outline defined through */
/* bezier control points. When defining the following configuration */
/* macro, some font drivers will be able to register alternate */
/* glyph image formats. */
/* */
/* Unset this macro if you're sure that you'll never use a font driver */
/* with an alternate glyph format, this will reduce the size of the */
/* base layer code. */
/* */
#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
/*************************************************************************/
/* */
/* GCC provides the non-ANSI `long long' 64-bit type. You can activate */
/* it by defining the FTCALC_USE_LONG_LONG macro here. Note however */
/* that we did not experience any improvement in speed with gcc, and */
/* that the final code seems bigger when linked. */
/* */
#undef FTCALC_USE_LONG_LONG
/*************************************************************************/
/* */
/* When compiling FreeType as a DLL, some systems/compilers need a */
/* special keyword in front of each function definition instead of */
/* `extern'. */
/* */
/* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define */
/* exported library function interfaces and exported library functions */
/* implementations respectively. */
/* */
/* If not defined here, they automatically default to `extern' and void */
/* later in this header file. */
/* */
#undef EXPORT_DEF
#undef EXPORT_FUNC
/*************************************************************************/
/* */
/* Debug level */
/* */
/* FreeType can be compiled in debug or trace mode. In debug mode, */
/* errors are reported through the `ftdebug' component. In trace */
/* mode, additional messages are sent to the standard output during */
/* execution. */
/* */
/* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */
/* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */
/* */
/* Don't define any of these macros to compile in `release' mode. */
/* */
#undef FT_DEBUG_LEVEL_ERROR
#undef FT_DEBUG_LEVEL_TRACE
/*************************************************************************/
/* */
/* Anti-aliasing support */
/* */
/* Undefine this macro only if you want to disable the anti-aliasing */
/* support in FreeType. This will save you about 5 Kb of code. It */
/* may be important for some embedded systems. */
/* */
#define FT_CONFIG_OPTION_ANTI_ALIAS
/*************************************************************************/
/* */
/* Endianess performance improvement */
/* */
/* FreeType is completely endian-independent, and can thus be compiled */
/* directly on _any_ machine. However, some components of the library */
/* provide improved routines for the cases where endianess is known. */
/* */
/* It usually results in speed-ups and reduced code size. Note that */
/* you should not define both of these macros. */
/* */
/* */
/* NOTE: For now, only the scan-line converter (base/ftraster.c) uses */
/* these macros to speed-up some anti-alias rendering routines. */
/* */
#undef FT_CONFIG_OPTION_LITTLE_ENDIAN
#undef FT_CONFIG_OPTION_BIG_ENDIAN
/*************************************************************************/
/* */
/* Define this configuration macro whenever you want to build a version */
/* of FreeType that does not include a default `system' component. */
/* */
/* Note that this will prevent the compilation of `ftinit', hence the */
/* function FT_Init_FreeType */
/* */
#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
/*************************************************************************/
/* */
/* The size in bytes of the render pool used by the scan-line */
/* converter to do all of its work. */
/* */
/* This must be greater than 4 Kb */
/* */
#define FT_RENDER_POOL_SIZE 32768
/*************************************************************************/
/* */
/* FT_MAX_DRIVERS */
/* */
/* The maximum number of font drivers that can be registered in a */
/* single FreeType library object. 8 seems to be a good choice due */
/* to the relative low actual number of drivers ;-) */
/* */
#define FT_MAX_DRIVERS 8
/*************************************************************************/
/* */
/* FT_MAX_EXTENSIONS */
/* */
/* The maximum number of extensions that can be registered in a */
/* single font driver. 8 seems to be a good choice for now.. */
/* */
#define FT_MAX_EXTENSIONS 8
/*************************************************************************/
/* */
/* FT_MAX_GLYPH_FORMATS */
/* */
/* The maximum number of glyph image formats that might be registered */
/* in a given library instance. 8 seems to be a good choice due to */
/* the relatively low number of current formats ;-) */
/* */
#define FT_MAX_GLYPH_FORMATS 8
#endif /* FTOPTION_H */

214
config/win32/ftsystem.c Normal file
View File

@ -0,0 +1,214 @@
/**************************************************************************
*
* ftsystem.h 1.0
*
* ANSI-specific FreeType low-level system interface
*
* This file contains the definition of interface used by FreeType
* to access low-level, i.e. memory management, i/o access as well
* as thread synchronisation.
*
*
* Copyright 1996-1999 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
**************************************************************************/
#include <ftsystem.h>
#include <fterrors.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/************************************************************************
*
* <FuncType>
* FT_Alloc_Func
*
* <Description>
* The memory allocator function type
*
* <Input>
* system :: pointer to the system object
* size :: requested size in bytes
*
* <Output>
* block :: address of newly allocated block
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* If your allocation routine ALWAYS zeroes the new block, you
* should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
* object 'flags' field.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_alloc( FT_Memory memory,
long size )
{
(void)memory;
return malloc(size);
}
/************************************************************************
*
* <FuncType>
* FT_Realloc_Func
*
* <Description>
* The memory reallocator function type
*
* <Input>
* system :: pointer to the system object
* new_size :: new requested size in bytes
*
* <InOut>
* block :: address of block in memory
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function is _never_ called when the system flag
* FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
* realloc through "alloc" and "free".
*
* Note that this is possible due to the fact that FreeType's
* "FT_Realloc" always requests the _current_ size of the reallocated
* block as a parameter, thus avoiding memory leaks.
*
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void* ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
(void)memory;
(void)cur_size;
return realloc( block, new_size );
}
/************************************************************************
*
* <FuncType>
* FT_Free_Func
*
* <Description>
* The memory release function type
*
* <Input>
* system :: pointer to the system object
* block :: address of block in memory
*
* <Note>
* If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
* your system's "system_flags" field, this function should update
* the "current_alloc" field of the system object.
*
************************************************************************/
static
void ft_free( FT_Memory memory,
void* block )
{
(void)memory;
free( block );
}
/*********************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
#define STREAM_FILE(stream) ((FILE*)stream->descriptor.pointer)
static
void ft_close_stream( FT_Stream stream )
{
fclose( STREAM_FILE(stream) );
}
static
unsigned long ft_io_stream( FT_Stream stream,
unsigned long offset,
char* buffer,
unsigned long count )
{
FILE* file;
file = STREAM_FILE(stream);
fseek( file, offset, SEEK_SET );
return (unsigned long)fread( buffer, count, 1, file );
}
extern
int FT_New_Stream( const char* filepathname,
FT_Stream stream )
{
FILE* file;
file = fopen( filepathname, "rb" );
if (!file)
return FT_Err_Cannot_Open_Resource;
fseek( file, 0, SEEK_END );
stream->size = ftell(file);
fseek( file, 0, SEEK_SET );
stream->descriptor.pointer = file;
stream->pos = 0;
stream->read = ft_io_stream;
stream->close = ft_close_stream;
return 0;
}
extern
FT_Memory FT_New_Memory( void )
{
FT_Memory memory;
memory = (FT_Memory)malloc( sizeof(*memory) );
if (memory)
{
memory->user = 0;
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
}
return memory;
}

12
config/win32/lcclib.bat Normal file
View File

@ -0,0 +1,12 @@
@cd obj
@LCCLIB /out:freetype.lib *.obj
@echo The library file `obj/freetype.lib' was generated.
@exit 0
; the LCC Librarian has many flaws, one of them is that it *requires* that
; all object files be placed in the current directory. Another flaw is that
; it cannot accept a long list of object files.
;
; this file is used to build the library file `obj/freetype.lib'
;

227
demos/Makefile Normal file
View File

@ -0,0 +1,227 @@
.PHONY: exes
all: exes
####################################################################
#
# TOP is the directory where the main FreeType source is found,
# as well as the 'config.mk' file
#
ifndef TOP
TOP := ..
endif
####################################################################
#
# Check that we have a working `config.mk' in the above directory.
# If not, issue a warning message, then stop there..
#
ifeq ($(wildcard $(TOP)/config.mk),)
no_config_mk := 1
endif
ifdef no_config_mk
exes:
@echo Please compile the library before the demo programs !!
else
####################################################################
#
# Good, now include the `config.mk' in order to know how to build
# object files from sources, as well as other things (compiler flags)
#
include ../config.mk
####################################################################
#
# Detect DOS-like platforms, currently DOS, Win 3.1, Win32 & OS/2
#
#
ifneq ($(findstring $(PLATFORM),os2 win16 win32 dos),)
DOSLIKE := 1
endif
###################################################################
#
# Clean-up rules. Because the `del' command on DOS-like platforms
# cannot take a long list of arguments, we simply erase the directory
# contents..
#
.PHONY: clean distclean
ifdef DOSLIKE
clean_demo:
-del obj\*.$O
-del src\*.bak
distclean_demo: clean_demo
-del obj\*.*
-del bin\*.exe
else
clean_demo:
-$(DELETE) $(OBJ_)*.$O
-$(DELETE) $(SRC_)*.bak graph$(SEP)*.bak
-$(DELETE) $(SRC_)*~ graph$(SEP)*~
distclean_demo: clean_demo
-$(DELETE) $(BIN_)*
endif
clean: clean_demo
distclean: distclean_demo
####################################################################
#
# Define a few important variables now
#
#
TOP_ := $(TOP)$(SEP)
SRC_ := $(TOP)$(SEP)src$(SEP)
BIN_ := bin$(SEP)
OBJ_ := obj$(SEP)
GRAPH_DIR := graph
SRC_DIR := src
SRC_DIR_ := $(SRC_DIR)$(SEP)
FT_INCLUDES := $(BUILD) $(TOP_)include $(SRC_)base
TT_INCLUDES := $(SRC_)shared $(SRC_)truetype
T1_INCLUDES := $(SRC_)shared $(SRC_)type1
CFLAGS = -c -O0 -g $(INCLUDES:%=$I%) -Wall -W -ansi
CC := $(CC)
LINK := $(CC)
FTLIB := $(LIB_DIR)$(SEP)$(LIBRARY).$A
####################################################################
#
# Compute the executable suffix to use, and put it in `E'.
# It is ".exe" on DOS-ish platforms, and nothing otherwise
#
ifdef DOSLIKE
E := .exe
else
E :=
endif
###################################################################
#
# The list of demonstration programs to build.
#
EXES := ftlint t1dump ftview fttimer
ifneq ($(findstring $(PLATFORM),os2 unix),)
EXES += ttdebug
endif
###################################################################
#
# Include the rules needed to compile the graphics sub-system.
# This will also select which graphics driver to compile to the
# sub-system..
#
include $(GRAPH_DIR)/rules.mk
exes: $(EXES:%=$(BIN_)%$E)
INCLUDES := $(FT_INCLUDES)
####################################################################
#
# Rules for compiling object files for text-only demos
#
COMMON_OBJ := $(OBJ_)common.o
$(COMMON_OBJ): $(SRC_DIR_)common.c
$(CC) $(CFLAGS) $T$@ $<
$(OBJ_)%.$O: $(SRC_DIR_)%.c $(FTLIB)
$(CC) $(CFLAGS) $T$@ $<
$(OBJ_)ftlint.$O: $(SRC_DIR_)ftlint.c
$(CC) $(CFLAGS) $T$@ $<
$(OBJ_)fttry.$O: $(SRC_DIR_)fttry.c
$(CC) $(CFLAGS) $T$@ $<
$(OBJ_)ftview.$O: $(SRC_DIR_)ftview.c $(GRAPH_LIB)
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
$(OBJ_)fttimer.$O: $(SRC_DIR_)fttimer.c $(GRAPH_LIB)
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
#$(OBJ_)ftsbit.$O: $(SRC_DIR)/ftsbit.c $(GRAPH_LIB)
# $(CC) $(CFLAGS) $T$@ $<
####################################################################
#
# Special rule to compile the `t1dump' program as it includes
# the Type1 source path
#
$(OBJ_)t1dump.$O: $(SRC_DIR)/t1dump.c
$(CC) $(CFLAGS) $(T1_INCLUDES:%=$I%) $T$@ $<
####################################################################
#
# Special rule to compile the `ttdebug' program as it includes
# the TrueType source path and needs extra flags for correct keyboard
# handling on Unix
#
# POSIX TERMIOS: Do not define if you use OLD U*ix like 4.2BSD.
#
# detect a Unix system
ifeq ($(PLATFORM),unix)
EXTRAFLAGS = $DUNIX $DHAVE_POSIX_TERMIOS
endif
$(OBJ_)ttdebug.$O: $(SRC_DIR)/ttdebug.c
$(CC) $(CFLAGS) $(TT_INCLUDES:%=$I%) $T$@ $< $(EXTRAFLAGS)
####################################################################
#
# Rules used to link the executables. Note that they could be
# over-ridden by system-specific things..
#
$(BIN_)ftlint$E: $(OBJ_)ftlint.$O $(FTLIB)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
$(BIN_)fttry$E: $(OBJ_)fttry.$O $(FTLIB)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
$(BIN_)ftsbit$E: $(OBJ_)ftsbit.$O $(FTLIB)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
$(BIN_)t1dump$E: $(OBJ_)t1dump.$O $(FTLIB)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
$(BIN_)ttdebug$E: $(OBJ_)ttdebug.$O $(FTLIB)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
$(BIN_)ftview$E: $(OBJ_)ftview.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(COMMON_OBJ) $(EFENCE)
$(BIN_)fttimer$E: $(OBJ_)fttimer.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(EFENCE)
endif

887
demos/config/os2/gros2pm.c Normal file
View File

@ -0,0 +1,887 @@
#include "gros2pm.h"
#include "grdevice.h"
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#define INCL_SUB
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void Panic( const char* message )
{
fprintf( stderr, "%s", message );
exit(1);
}
typedef struct Translator
{
ULONG os2key;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ VK_BACKSPACE, grKeyBackSpace },
{ VK_TAB, grKeyTab },
{ VK_ENTER, grKeyReturn },
{ VK_ESC, grKeyEsc },
{ VK_HOME, grKeyHome },
{ VK_LEFT, grKeyLeft },
{ VK_UP, grKeyUp },
{ VK_RIGHT, grKeyRight },
{ VK_DOWN, grKeyDown },
{ VK_PAGEUP, grKeyPageUp },
{ VK_PAGEDOWN, grKeyPageDown },
{ VK_END, grKeyEnd },
{ VK_F1, grKeyF1 },
{ VK_F2, grKeyF2 },
{ VK_F3, grKeyF3 },
{ VK_F4, grKeyF4 },
{ VK_F5, grKeyF5 },
{ VK_F6, grKeyF6 },
{ VK_F7, grKeyF7 },
{ VK_F8, grKeyF8 },
{ VK_F9, grKeyF9 },
{ VK_F10, grKeyF10 },
{ VK_F11, grKeyF11 },
{ VK_F12, grKeyF12 }
};
#define MAX_PIXEL_MODES 32
static int num_pixel_modes = 0;
static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
static int pixel_depth[ MAX_PIXEL_MODES ];
static HAB gr_anchor; /* device anchor block */
typedef POINTL PMBlitPoints[4];
typedef struct grPMSurface_
{
grSurface root;
grBitmap image;
HAB anchor; /* handle to anchor block for surface's window */
HWND frame_window; /* handle to window's frame */
HWND client_window; /* handle to window's client */
HWND title_window; /* handle to window's title bar */
HPS image_ps; /* memory presentation space used to hold */
/* the surface's content under PM */
HDC image_dc; /* memory device context for the image */
HEV event_lock; /* semaphore used in listen_surface */
HMTX image_lock; /* a mutex used to synchronise access */
/* to the memory presentation space */
/* used to hold the surface */
TID message_thread; /* thread used to process this surface's */
/* messages.. */
PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor */
HBITMAP os2_bitmap; /* Handle to OS/2 bitmap contained in image */
BOOL ready; /* ??? */
long shades[256]; /* indices of gray levels in pixel_mode_gray */
POINTL surface_blit[4]; /* surface blitting table */
POINTL magnify_blit[4]; /* magnifier blitting table */
int magnification; /* level of magnification */
POINTL magnify_center;
SIZEL magnify_size;
grEvent event;
PMBlitPoints blit_points;
} grPMSurface;
static
void enable_os2_iostreams( void )
{
PTIB thread_block;
PPIB process_block;
/* XXX : This is a very nasty hack, it fools OS/2 and let the program */
/* call PM functions, even though stdin/stdout/stderr are still */
/* directed to the standard i/o streams.. */
/* The program must be compiled with WINDOWCOMPAT */
/* */
/* Credits go to Michal for finding this !! */
/* */
DosGetInfoBlocks( &thread_block, &process_block );
process_block->pib_ultype = 3;
}
static
int init_device( void )
{
enable_os2_iostreams();
/* create an anchor block. This will allow this thread (i.e. the */
/* main one) to call Gpi functions.. */
gr_anchor = WinInitialize(0);
if (!gr_anchor)
{
/* could not initialise Presentation Manager */
return -1;
}
return 0;
}
static
void done_device( void )
{
/* Indicates that we do not use the Presentation Manager, this */
/* will also release all associated resources.. */
WinTerminate( gr_anchor );
}
/* close a given window */
static
void done_surface( grPMSurface* surface )
{
if ( surface->frame_window )
WinDestroyWindow( surface->frame_window );
WinReleasePS( surface->image_ps );
grDoneBitmap( &surface->image );
grDoneBitmap( &surface->root.bitmap );
}
static
void add_pixel_mode( grPixelMode pixel_mode,
int depth )
{
if ( num_pixel_modes >= MAX_PIXEL_MODES )
Panic( "X11.Too many pixel modes\n" );
pixel_modes[ num_pixel_modes ] = pixel_mode;
pixel_depth[ num_pixel_modes ] = depth;
num_pixel_modes++;
}
#define LOCK(x) DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
#define UNLOCK(x) DosReleaseMutexSem( x )
static
const int pixel_mode_bit_count[] =
{
0,
1, /* mono */
4, /* pal4 */
8, /* pal8 */
8, /* grays */
15, /* rgb15 */
16, /* rgb16 */
24, /* rgb24 */
32 /* rgb32 */
};
/************************************************************************
*
* Technical note : how the OS/2 Presntation Manager driver works
*
* PM is, in my opinion, a bloated and over-engineered graphics
* sub-system, even though it has lots of nice features. Here are
* a few tidbits about it :
*
*
* - under PM, a "bitmap" is a device-specific object whose bits are
* not directly accessible to the client application. This means
* that we must use a scheme like the following to display our
* surfaces :
*
* - hold, for each surface, its own bitmap buffer where the
* rest of MiGS writes directly.
*
* - create a PM bitmap object with the same dimensions (and
* possibly format).
*
* - copy the content of each updated rectangle into the
* PM bitmap with the function 'GpiSetBitmapBits'.
*
* - finally, "blit" the PM bitmap to the screen calling
* 'GpiBlitBlt'
*
* - but there is more : you cannot directly blit a PM bitmap to the
* screen with PM. The 'GpiBlitBlt' only works with presentation
* spaces. This means that we also need to create, for each surface :
*
* - a memory presentation space, used to hold the PM bitmap
* - a "memory device context" for the presentation space
*
* The blit is then performed from the memory presentation space
* to the screen's presentation space..
*
*
* - because each surface creates its own event-handling thread,
* we must protect the surface's presentation space from concurrent
* accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
* surface, and calls to 'GpiBlitBlt' when drawing it on the screen
* are performed in two different threads).
*
* we use a simple mutex to do this.
*
*
* - we also use a semaphore to perform a rendez-vous between the
* main and event-handling threads (needed in "listen_event").
*
************************************************************************/
static
void RunPMWindow( grPMSurface* surface );
static
void convert_gray_to_pal8( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
long* palette = surface->shades;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + w;
for ( ; _write < limit; _write++, _read++ )
*_write = (byte) palette[ *_read ];
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_16( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
long* palette = surface->shades;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 2*w;
for ( ; _write < limit; _write += 2, _read++ )
*(short*)_write = (short)palette[ *_read ];
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_24( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 3*w;
for ( ; _write < limit; _write += 3, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_32( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 4*w;
for ( ; _write < limit; _write += 4, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] =
_write[3] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_rectangle( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
int z;
/* first of all, clip to the surface's area */
if ( x >= surface->image.width ||
x+w <= 0 ||
y >= surface->image.rows ||
y+h <= 0 )
return;
if ( x < 0 )
{
w += x;
x = 0;
}
z = (x + w) - surface->image.width;
if (z > 0)
w -= z;
z = (y + h) - surface->image.rows;
if (z > 0)
h -= z;
/* convert the rectangle to the target depth for gray surfaces */
if (surface->root.bitmap.mode == gr_pixel_mode_gray)
{
switch (surface->image.mode)
{
case gr_pixel_mode_pal8 :
convert_gray_to_pal8( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb555:
case gr_pixel_mode_rgb565:
convert_gray_to_16 ( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb24:
convert_gray_to_24 ( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb32:
convert_gray_to_32 ( surface, x, y, w, h );
break;
default:
;
}
}
}
static
void refresh_rectangle( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
convert_rectangle( surface, x, y, w, h );
WinInvalidateRect( surface->client_window, NULL, FALSE );
WinUpdateWindow( surface->frame_window );
}
static
void set_title( grPMSurface* surface,
const char* title )
{
WinSetWindowText( surface->title_window, (PSZ)title );
}
static
void listen_event( grPMSurface* surface,
int event_mask,
grEvent* grevent )
{
ULONG ulRequestCount;
(void) event_mask; /* ignored for now */
/* the listen_event function blocks until there is an event to process */
DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
DosQueryEventSem( surface->event_lock, &ulRequestCount );
*grevent = surface->event;
DosResetEventSem( surface->event_lock, &ulRequestCount );
return;
}
static
grPMSurface* init_surface( grPMSurface* surface,
grBitmap* bitmap )
{
PBITMAPINFO2 bit;
SIZEL sizl = { 0, 0 };
LONG palette[256];
/* create the bitmap - under OS/2, we support all modes as PM */
/* handles all conversions automatically.. */
if ( grNewBitmap( bitmap->mode,
bitmap->grays,
bitmap->width,
bitmap->rows,
bitmap ) )
return 0;
surface->root.bitmap = *bitmap;
/* create the image and event lock */
DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE );
DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
/* create the image's presentation space */
surface->image_dc = DevOpenDC( gr_anchor,
OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
surface->image_ps = GpiCreatePS( gr_anchor,
surface->image_dc,
&sizl,
PU_PELS | GPIT_MICRO |
GPIA_ASSOC | GPIF_DEFAULT );
GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
/* create the image's PM bitmap */
bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
surface->bitmap_header = bit;
bit->cbFix = sizeof( BITMAPINFOHEADER2 );
bit->cx = surface->root.bitmap.width;
bit->cy = surface->root.bitmap.rows;
bit->cPlanes = 1;
bit->argbColor[0].bBlue = 0;
bit->argbColor[0].bGreen = 0;
bit->argbColor[0].bRed = 0;
bit->argbColor[1].bBlue = 255;
bit->argbColor[1].bGreen = 255;
bit->argbColor[1].bRed = 255;
bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
(PBITMAPINFOHEADER2)bit,
0L, NULL, NULL );
GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
bit->cbFix = sizeof( BITMAPINFOHEADER2 );
GpiQueryBitmapInfoHeader( surface->os2_bitmap,
(PBITMAPINFOHEADER2)bit );
/* for gr_pixel_mode_gray, create a gray-levels logical palette */
if ( bitmap->mode == gr_pixel_mode_gray )
{
int x, count;
count = bitmap->grays;
for ( x = 0; x < count; x++ )
palette[x] = (((count-x)*255)/count) * 0x010101;
/* create logical color table */
GpiCreateLogColorTable( surface->image_ps,
(ULONG) LCOL_PURECOLOR,
(LONG) LCOLF_CONSECRGB,
(LONG) 0L,
(LONG) count,
(PLONG) palette );
/* now, copy the color indexes to surface->shades */
for ( x = 0; x < count; x++ )
surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
0, palette[x] );
}
/* set up the blit points array */
surface->blit_points[1].x = surface->root.bitmap.width;
surface->blit_points[1].y = surface->root.bitmap.rows;
surface->blit_points[3] = surface->blit_points[1];
/* Finally, create the event handling thread for the surface's window */
DosCreateThread( &surface->message_thread,
(PFNTHREAD) RunPMWindow,
(ULONG) surface,
0UL,
32920 );
surface->root.done = (grDoneSurfaceFunc) done_surface;
surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
surface->root.set_title = (grSetTitleFunc) set_title;
surface->root.listen_event = (grListenEventFunc) listen_event;
convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
return surface;
}
MRESULT EXPENTRY Message_Process( HWND handle,
ULONG mess,
MPARAM parm1,
MPARAM parm2 );
static
void RunPMWindow( grPMSurface* surface )
{
unsigned char class_name[] = "DisplayClass";
ULONG class_flags;
static HMQ queue;
QMSG message;
/* create an anchor to allow this thread to use PM */
surface->anchor = WinInitialize(0);
if (!surface->anchor)
{
printf( "Error doing WinInitialize()\n" );
return;
}
/* create a message queue */
queue = WinCreateMsgQueue( surface->anchor, 0 );
if (!queue)
{
printf( "Error doing >inCreateMsgQueue()\n" );
return;
}
/* register the window class */
if ( !WinRegisterClass( surface->anchor,
(PSZ) class_name,
(PFNWP) Message_Process,
CS_SIZEREDRAW,
0 ) )
{
printf( "Error doing WinRegisterClass()\n" );
return;
}
/* create the PM window */
class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER |
FCF_TASKLIST | FCF_SYSMENU;
surface->frame_window = WinCreateStdWindow(
HWND_DESKTOP,
WS_VISIBLE,
&class_flags,
(PSZ) class_name,
(PSZ) "FreeType PM Graphics",
WS_VISIBLE,
0, 0,
&surface->client_window );
if (!surface->frame_window)
{
printf( "Error doing WinCreateStdWindow()\n" );
return;
}
/* find the title window handle */
surface->title_window = WinWindowFromID( surface->frame_window,
FID_TITLEBAR );
/* set Window size and position */
WinSetWindowPos( surface->frame_window,
0L,
(SHORT) 60,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
surface->root.bitmap.rows + 100,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
surface->root.bitmap.width,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
surface->root.bitmap.rows,
SWP_SIZE | SWP_MOVE );
/* save the handle to the current surface within the window words */
WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
/* run the message queue till the end */
while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
WinDispatchMsg( surface->anchor, &message );
/* clean-up */
WinDestroyWindow( surface->frame_window );
surface->frame_window = 0;
WinDestroyMsgQueue( queue );
WinTerminate( surface->anchor );
/* await death... */
while ( 1 )
DosSleep( 100 );
}
/* Message processing for our PM Window class */
MRESULT EXPENTRY Message_Process( HWND handle,
ULONG mess,
MPARAM parm1,
MPARAM parm2 )
{
static HDC screen_dc;
static HPS screen_ps;
static BOOL minimized;
SIZEL sizl;
SWP swp;
grPMSurface* surface;
/* get the handle to the window's surface */
surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
switch( mess )
{
case WM_DESTROY:
/* warn the main thread to quit if it didn't know */
surface->event.type = gr_event_key;
surface->event.key = grKeyEsc;
DosPostEventSem( surface->event_lock );
break;
case WM_CREATE:
/* set original magnification */
minimized = FALSE;
/* create Device Context and Presentation Space for screen. */
screen_dc = WinOpenWindowDC( handle );
screen_ps = GpiCreatePS( surface->anchor,
screen_dc,
&sizl,
PU_PELS | GPIT_MICRO |
GPIA_ASSOC | GPIF_DEFAULT );
/* take the input focus */
WinFocusChange( HWND_DESKTOP, handle, 0L );
break;
case WM_MINMAXFRAME:
/* to update minimized if changed */
swp = *((PSWP) parm1);
if ( swp.fl & SWP_MINIMIZE )
minimized = TRUE;
if ( swp.fl & SWP_RESTORE )
minimized = FALSE;
return WinDefWindowProc( handle, mess, parm1, parm2 );
break;
case WM_ERASEBACKGROUND:
case WM_PAINT:
/* copy the memory image of the screen out to the real screen */
DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
WinBeginPaint( handle, screen_ps, NULL );
/* main image and magnified picture */
GpiBitBlt( screen_ps,
surface->image_ps,
4L,
surface->blit_points,
ROP_SRCCOPY, BBO_AND );
WinEndPaint( screen_ps );
DosReleaseMutexSem( surface->image_lock );
break;
case WM_CHAR:
if ( CHARMSG( &mess )->fs & KC_KEYUP )
break;
/* look for a specific vkey */
{
int count = sizeof( key_translators )/sizeof( key_translators[0] );
Translator* trans = key_translators;
Translator* limit = trans + count;
for ( ; trans < limit; trans++ )
if ( CHARMSG(&mess)->vkey == trans->os2key )
{
surface->event.key = trans->grkey;
goto Do_Key_Event;
}
}
/* otherwise, simply record the character code */
if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
break;
surface->event.key = CHARMSG(&mess)->chr;
Do_Key_Event:
surface->event.type = gr_event_key;
DosPostEventSem( surface->event_lock );
break;
default:
return WinDefWindowProc( handle, mess, parm1, parm2 );
}
return (MRESULT) FALSE;
}
#if 0
static
grKey KeySymTogrKey( key )
{
grKey k;
int count = sizeof(key_translators)/sizeof(key_translators[0]);
Translator* trans = key_translators;
Translator* limit = trans + count;
k = grKeyNone;
while ( trans < limit )
{
if ( trans->xkey == key )
{
k = trans->grkey;
break;
}
trans++;
}
return k;
}
static
void listen_event( grPMSurface* surface,
int event_mask,
grEvent* grevent )
{
grKey grkey;
/* XXXX : For now, ignore the event mask, and only exit when */
/* a key is pressed.. */
(void)event_mask;
/* Now, translate the keypress to a grKey */
/* If this wasn't part of the simple translated keys, simply get the charcode */
/* from the character buffer */
grkey = grKEY(key_buffer[key_cursor++]);
Set_Key:
grevent->type = gr_key_down;
grevent->key = grkey;
}
#endif
grDevice gr_os2pm_device =
{
sizeof( grPMSurface ),
"os2pm",
init_device,
done_device,
(grDeviceInitSurfaceFunc) init_surface,
0,
0
};

View File

@ -0,0 +1,5 @@
NAME WINDOWCOMPAT
DESCRIPTION 'FreeType Graphics'
HEAPSIZE 8192
STACKSIZE 40888

View File

@ -0,0 +1,23 @@
#ifndef GROS2PM_H
#define GROS2PM_H
#include "grobjs.h"
extern
grDevice gr_os2pm_device;
#ifdef GR_INIT_BUILD
static
grDeviceChain gr_os2pm_device_chain =
{
"os2pm",
&gr_os2pm_device,
GR_INIT_DEVICE_CHAIN
};
#undef GR_INIT_DEVICE_CHAIN
#define GR_INIT_DEVICE_CHAIN &gr_os2pm_device_chain
#endif /* GR_INIT_BUILD */
#endif /* GROS2PM_H */

32
demos/config/os2/rules.mk Normal file
View File

@ -0,0 +1,32 @@
#**************************************************************************
#*
#* OS/2 specific rules file, used to compile the OS/2 graphics driver
#* to the graphics subsystem
#*
#**************************************************************************
ifeq ($(PLATFORM),os2)
GR_OS2 := config$(SEP)os2
GR_OS2_ := $(GR_OS2)$(SEP)
# the GRAPH_LINK is expanded each time an executable is linked with the
# graphics library.
#
GRAPH_LINK += $(GR_OS2_)gros2pm.def
# Add the OS/2 driver object file to the graphics library "graph.a"
#
GRAPH_OBJS += $(OBJ_)gros2pm.$O
DEVICES += OS2_PM
DEVICE_INCLUDES += $(GR_OS2)
# the rule used to compile the graphics driver
#
$(OBJ_)gros2pm.$O: $(GR_OS2_)gros2pm.c $(GR_OS2_)gros2pm.h
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_OS2) $T$@ $<
endif

936
demos/config/x11/grx11.c Normal file
View File

@ -0,0 +1,936 @@
#include "grx11.h"
#ifdef TEST
#include "grfont.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
static void Panic( const char* message )
{
fprintf( stderr, "%s", message );
exit(1);
}
typedef struct Translator
{
KeySym xkey;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ XK_BackSpace, grKeyBackSpace },
{ XK_Tab, grKeyTab },
{ XK_Return, grKeyReturn },
{ XK_Escape, grKeyEsc },
{ XK_Home, grKeyHome },
{ XK_Left, grKeyLeft },
{ XK_Up, grKeyUp },
{ XK_Right, grKeyRight },
{ XK_Down, grKeyDown },
{ XK_Page_Up, grKeyPageUp },
{ XK_Page_Down, grKeyPageDown },
{ XK_End, grKeyEnd },
{ XK_Begin, grKeyHome },
{ XK_F1, grKeyF1 },
{ XK_F2, grKeyF2 },
{ XK_F3, grKeyF3 },
{ XK_F4, grKeyF4 },
{ XK_F5, grKeyF5 },
{ XK_F6, grKeyF6 },
{ XK_F7, grKeyF7 },
{ XK_F8, grKeyF8 },
{ XK_F9, grKeyF9 },
{ XK_F10, grKeyF10 },
{ XK_F11, grKeyF11 },
{ XK_F12, grKeyF12 }
};
#ifdef TEST
#define grAlloc malloc
#endif
static Display* display;
static char* displayname = "";
static Cursor idle;
static Cursor busy;
#define MAX_PIXEL_MODES 32
typedef XPixmapFormatValues XDepth;
static int num_pixel_modes = 0;
static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
static XDepth pixel_depth[ MAX_PIXEL_MODES ];
typedef struct grXSurface_
{
grSurface root;
grBitmap image;
Window win;
Visual* visual;
Colormap colormap;
int depth;
Bool gray;
GC gc;
XColor color[256]; /* gray levels palette for 8-bit modes */
XImage* ximage;
int win_org_x;
int win_org_y;
int win_width;
int win_height;
int image_width;
int image_height;
} grXSurface;
/* close a given window */
static
void done_surface( grXSurface* surface )
{
XUnmapWindow( display, surface->win );
}
/* close the device, i.e. the display connection */
static
void done_device( void )
{
XCloseDisplay( display );
}
static
void add_pixel_mode( grPixelMode pixel_mode,
XDepth* depth )
{
if ( num_pixel_modes >= MAX_PIXEL_MODES )
Panic( "X11.Too many pixel modes\n" );
pixel_modes[ num_pixel_modes ] = pixel_mode;
pixel_depth[ num_pixel_modes ] = *depth;
num_pixel_modes++;
}
static
int init_device( void )
{
XDepth dummy;
XrmInitialize();
display = XOpenDisplay( displayname );
if (!display)
{
return -1;
/* Panic( "Gr:error: cannot open X11 display\n" ); */
}
idle = XCreateFontCursor( display, XC_left_ptr );
busy = XCreateFontCursor( display, XC_watch );
num_pixel_modes = 0;
/* always enable the 8-bit gray levels pixel mode */
/* even if its display is emulated through a constrained palette */
/* or another color mode */
dummy.depth = 8;
dummy.bits_per_pixel = 8;
dummy.scanline_pad = 8;
add_pixel_mode( gr_pixel_mode_gray, &dummy );
{
int count;
XDepth* format;
XDepth* formats;
XVisualInfo template;
formats = XListPixmapFormats( display, &count );
format = formats;
#ifdef TEST
printf( "available pixmap formats\n" );
printf( "depth pixbits scanpad\n" );
#endif
while ( count-- > 0 )
{
#ifdef TEST
printf( " %3d %3d %3d\n",
format->depth,
format->bits_per_pixel,
format->scanline_pad );
#endif
if ( format->depth == 1 )
/* usually, this should be the first format */
add_pixel_mode( gr_pixel_mode_mono, format );
else if ( format->depth == 8 )
add_pixel_mode( gr_pixel_mode_pal8, format );
/* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */
else if ( format->depth == 24 )
{
if ( format->bits_per_pixel == 24 )
add_pixel_mode( gr_pixel_mode_rgb24, format );
else if ( format->bits_per_pixel == 32 )
add_pixel_mode( gr_pixel_mode_rgb32, format );
}
else if ( format->depth == 16 )
{
int count2;
XVisualInfo* visuals;
XVisualInfo* visual;
template.depth = format->depth;
visuals = XGetVisualInfo( display,
VisualDepthMask,
&template,
&count2 );
visual = visuals;
while ( count2-- > 0 )
{
#ifdef TEST
const char* string = "unknown";
switch (visual->class)
{
case TrueColor: string = "TrueColor"; break;
case DirectColor: string = "DirectColor"; break;
case PseudoColor: string = "PseudoColor"; break;
case StaticGray : string = "StaticGray"; break;
case StaticColor: string = "StaticColor"; break;
case GrayScale: string = "GrayScale"; break;
}
printf( "> RGB %02x:%02x:%02x, colors %3d, bits %2d %s\n",
visual->red_mask,
visual->green_mask,
visual->blue_mask,
visual->colormap_size,
visual->bits_per_rgb,
string );
#endif
if ( visual->red_mask == 0xf800 &&
visual->green_mask == 0x07e0 &&
visual->blue_mask == 0x001f )
add_pixel_mode( gr_pixel_mode_rgb565, format );
else if ( visual->red_mask == 0x7c00 &&
visual->green_mask == 0x03e0 &&
visual->blue_mask == 0x001f )
add_pixel_mode( gr_pixel_mode_rgb555, format );
/* other 16-bit modes are ignored */
visual++;
}
XFree( visuals );
}
format++;
}
XFree( formats );
}
gr_x11_device.num_pixel_modes = num_pixel_modes;
gr_x11_device.pixel_modes = pixel_modes;
return 0;
}
static
void convert_gray_to_pal8( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
XColor* palette = surface->color;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + w;
for ( ; _write < limit; _write++, _read++ )
*_write = (byte) palette[ *_read ].pixel;
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_16( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
XColor* palette = surface->color;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 2*w;
for ( ; _write < limit; _write += 2, _read++ )
*(short*)_write = (short)palette[ *_read ].pixel;
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_24( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 3*w;
for ( ; _write < limit; _write += 3, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_32( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 4*w;
for ( ; _write < limit; _write += 4, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] =
_write[3] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_rectangle( grXSurface* surface,
int x,
int y,
int w,
int h )
{
int z;
/* first of all, clip to the surface's area */
if ( x >= surface->image.width ||
x+w <= 0 ||
y >= surface->image.rows ||
y+h <= 0 )
return;
if ( x < 0 )
{
w += x;
x = 0;
}
z = (x + w) - surface->image.width;
if (z > 0)
w -= z;
z = (y + h) - surface->image.rows;
if (z > 0)
h -= z;
/* convert the rectangle to the target depth for gray surfaces */
if (surface->gray)
{
switch (surface->depth)
{
case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
case 16: convert_gray_to_16 ( surface, x, y, w, h ); break;
case 24: convert_gray_to_24 ( surface, x, y, w, h ); break;
case 32: convert_gray_to_32 ( surface, x, y, w, h ); break;
}
}
}
static
void refresh_rectangle( grXSurface* surface,
int x,
int y,
int w,
int h )
{
if (surface->gray)
convert_rectangle( surface, x, y, w, h );
XPutImage( display,
surface->win,
surface->gc,
surface->ximage,
x, y, x, y, w, h );
}
static
void set_title( grXSurface* surface,
const char* title )
{
XStoreName( display, surface->win, title );
}
static
grKey KeySymTogrKey( KeySym key )
{
grKey k;
int count = sizeof(key_translators)/sizeof(key_translators[0]);
Translator* trans = key_translators;
Translator* limit = trans + count;
k = grKeyNone;
while ( trans < limit )
{
if ( trans->xkey == key )
{
k = trans->grkey;
break;
}
trans++;
}
return k;
}
static
void listen_event( grXSurface* surface,
int event_mask,
grEvent* grevent )
{
static char key_buffer[10];
static int key_cursor = 0;
static int key_number = 0;
static XEvent x_event;
KeySym key;
int bool_exit;
grKey grkey;
XComposeStatus compose;
/* XXXX : For now, ignore the event mask, and only exit when */
/* a key is pressed.. */
(void)event_mask;
bool_exit = key_cursor < key_number;
XDefineCursor( display, surface->win, idle );
while ( !bool_exit )
{
XNextEvent( display, &x_event );
switch ( x_event.type )
{
case KeyPress:
key_number = XLookupString( &x_event.xkey,
key_buffer,
sizeof ( key_buffer ),
&key,
&compose );
key_cursor = 0;
if ( key_number == 0 ||
key > 512 )
{
/* this may be a special key like F1, F2, etc.. */
grkey = KeySymTogrKey(key);
if (grkey != grKeyNone)
goto Set_Key;
}
else
bool_exit = 1;
break;
case MappingNotify:
XRefreshKeyboardMapping( &x_event.xmapping );
break;
case Expose:
refresh_rectangle( surface,
x_event.xexpose.x,
x_event.xexpose.y,
x_event.xexpose.width,
x_event.xexpose.height );
break;
/* You should add more cases to handle mouse events, etc. */
}
}
XDefineCursor( display, surface->win, busy );
XFlush ( display );
/* Now, translate the keypress to a grKey */
/* If this wasn't part of the simple translated keys, simply get the charcode */
/* from the character buffer */
grkey = grKEY(key_buffer[key_cursor++]);
Set_Key:
grevent->type = gr_key_down;
grevent->key = grkey;
}
grXSurface* init_surface( grXSurface* surface,
grBitmap* bitmap )
{
int screen;
grBitmap* image;
char grays;
XDepth* format;
int image_depth;
screen = DefaultScreen( display );
surface->colormap = DefaultColormap( display, screen );
surface->depth = DefaultDepth( display, screen );
surface->visual = DefaultVisual( display, screen );
image = &surface->image;
/* force the surface image depth to 1 if necessary */
/* as this should be supported by all windows */
image_depth = surface->depth;
if (bitmap->mode == gr_pixel_mode_mono)
image_depth = 1;
grays = ( bitmap->mode == gr_pixel_mode_gray &&
bitmap->grays >= 2 );
surface->gray = grays;
/* copy dimensions */
image->width = bitmap->width;
image->rows = bitmap->rows;
image->mode = bitmap->mode;
image->pitch = 0;
image->grays = 0;
image->buffer = 0;
/* find the supported format corresponding to the request */
format = 0;
if (grays)
{
/* choose the default depth in case of grays rendering */
int i;
for ( i = 0; i < num_pixel_modes; i++ )
if ( image_depth == pixel_depth[i].depth )
{
format = pixel_depth + i;
break;
}
}
else
{
/* otherwise, select the format depending on the pixel mode */
int i;
format = 0;
for ( i = 0; i < num_pixel_modes; i++ )
if ( pixel_modes[i] == bitmap->mode )
{
format = pixel_depth + i;
break;
}
}
if (!format)
{
grError = gr_err_bad_argument;
return 0;
}
/* correct surface.depth. This is required because in the case */
/* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
if ( format->depth == 24 &&
format->bits_per_pixel == 32 )
image_depth = 32;
/* allocate surface image */
{
int bits, over;
bits = image->width * format->bits_per_pixel;
over = bits % format->scanline_pad;
if (over)
bits += format->scanline_pad - over;
if (!grays)
{
image->width = bits;
bitmap->width = bits;
}
image->pitch = bits >> 3;
}
image->buffer = grAlloc( image->pitch * image->rows );
if (!image->buffer) return 0;
/* now, allocate a gray pal8 pixmap, only when we asked */
/* for an 8-bit pixmap */
if ( grays )
{
/* pad pitch to 32 bits */
bitmap->pitch = (bitmap->width + 3) & -4;
bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
if (!bitmap->buffer)
Panic( "grX11: could not allocate surface bitmap!\n" );
}
else /* otherwise */
{
*bitmap = *image;
}
surface->root.bitmap = *bitmap;
/* Now create the surface X11 image */
surface->ximage = XCreateImage( display,
surface->visual,
format->depth,
format->depth == 1 ? XYBitmap : ZPixmap,
0,
(char*)image->buffer,
image->width,
image->rows,
8,
0 );
if ( !surface->ximage )
Panic( "grX11: cannot create surface X11 image\n" );
/* allocate gray levels in the case of gray surface */
if ( grays )
{
XColor* color = surface->color;
int i;
for ( i = 0; i < bitmap->grays; i++, color++ )
{
color->red =
color->green =
color->blue = 65535 - ( i * 65535 ) / bitmap->grays;
if ( !XAllocColor( display, surface->colormap, color ) )
Panic( "ERROR: cannot allocate Color\n" );
}
}
else if ( image_depth == 1 )
{
surface->ximage->byte_order = MSBFirst;
surface->ximage->bitmap_bit_order = MSBFirst;
}
{
XTextProperty xtp;
XSizeHints xsh;
XSetWindowAttributes xswa;
xswa.border_pixel = BlackPixel( display, screen );
xswa.background_pixel = WhitePixel( display, screen );
xswa.cursor = busy;
xswa.event_mask = KeyPressMask | ExposureMask;
surface->win = XCreateWindow( display,
RootWindow( display, screen ),
0,
0,
image->width,
image->rows,
10,
surface->depth,
InputOutput,
surface->visual,
CWBackPixel | CWBorderPixel |
CWEventMask | CWCursor,
&xswa );
XMapWindow( display, surface->win );
surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
XSetForeground( display, surface->gc, xswa.border_pixel );
XSetBackground( display, surface->gc, xswa.background_pixel );
/* make window manager happy :-) */
xtp.value = (unsigned char*)"FreeType";
xtp.encoding = 31;
xtp.format = 8;
xtp.nitems = strlen( (char*)xtp.value );
xsh.x = 0;
xsh.y = 0;
xsh.width = image->width;
xsh.height = image->rows;
xsh.flags = (PPosition | PSize);
xsh.flags = 0;
XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
}
surface->root.done = (grDoneSurfaceFunc) done_surface;
surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
surface->root.set_title = (grSetTitleFunc) set_title;
surface->root.listen_event = (grListenEventFunc) listen_event;
convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
return surface;
}
grDevice gr_x11_device =
{
sizeof( grXSurface ),
"x11",
init_device,
done_device,
(grDeviceInitSurfaceFunc) init_surface,
0,
0
};
#ifdef TEST
typedef struct grKeyName
{
grKey key;
const char* name;
} grKeyName;
static
const grKeyName key_names[] =
{
{ grKeyF1, "F1" },
{ grKeyF2, "F2" },
{ grKeyF3, "F3" },
{ grKeyF4, "F4" },
{ grKeyF5, "F5" },
{ grKeyF6, "F6" },
{ grKeyF7, "F7" },
{ grKeyF8, "F8" },
{ grKeyF9, "F9" },
{ grKeyF10, "F10" },
{ grKeyF11, "F11" },
{ grKeyF12, "F12" },
{ grKeyEsc, "Esc" },
{ grKeyHome, "Home" },
{ grKeyEnd, "End" },
{ grKeyPageUp, "Page_Up" },
{ grKeyPageDown, "Page_Down" },
{ grKeyLeft, "Left" },
{ grKeyRight, "Right" },
{ grKeyUp, "Up" },
{ grKeyDown, "Down" },
{ grKeyBackSpace, "BackSpace" },
{ grKeyReturn, "Return" }
};
int main( void )
{
grSurface* surface;
int n;
grInit();
surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
if (!surface)
Panic("Could not create window\n" );
else
{
grColor color;
grEvent event;
const char* string;
int x;
grSetSurfaceRefresh( surface, 1 );
grSetTitle(surface,"X11 driver demonstration" );
for ( x = -10; x < 10; x++ )
{
for ( n = 0; n < 128; n++ )
{
color.value = (n*3) & 127;
grWriteCellChar( surface,
x + ((n % 60) << 3),
80 + (x+10)*8*3 + ((n/60) << 3), n, color );
}
}
color.value = 64;
grWriteCellString( surface, 0, 0, "just an example", color );
do
{
listen_event((grXSurface*)surface, 0, &event);
/* return if ESC was pressed */
if ( event.key == grKeyEsc )
return 0;
/* otherwise, display key string */
color.value = (color.value + 8) & 127;
{
int count = sizeof(key_names)/sizeof(key_names[0]);
grKeyName* name = key_names;
grKeyName* limit = name + count;
const char* kname = 0;
char kname_temp[16];
while (name < limit)
{
if ( name->key == event.key )
{
kname = name->name;
break;
}
name++;
}
if (!kname)
{
sprintf( kname_temp, "char '%c'", (char)event.key );
kname = kname_temp;
}
grWriteCellString( surface, 30, 30, kname, color );
grRefreshSurface(surface);
paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
}
} while (1);
}
return 0;
}
#endif /* TEST */

24
demos/config/x11/grx11.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef GRX11_H
#define GRX11_H
#include "grobjs.h"
#include "grdevice.h"
extern
grDevice gr_x11_device;
#ifdef GR_INIT_BUILD
static
grDeviceChain gr_x11_device_chain =
{
"x11",
&gr_x11_device,
GR_INIT_DEVICE_CHAIN
};
#undef GR_INIT_DEVICE_CHAIN
#define GR_INIT_DEVICE_CHAIN &gr_x11_device_chain
#endif /* GR_INIT_BUILD */
#endif /* GRX11_H */

69
demos/config/x11/rules.mk Normal file
View File

@ -0,0 +1,69 @@
#**************************************************************************
#*
#* X11-specific rules files, used to compile the X11 graphics driver
#* when supported by the current platform
#*
#**************************************************************************
#########################################################################
#
# Try to detect an X11 setup.
#
# We simply try to detect a `X11R6/bin', `X11R5/bin' or `X11/bin' in
# the current path.
#
ifneq ($(findstring X11R6$(SEP)bin,$(PATH)),)
xversion := X11R6
endif
ifneq ($(findstring X11R5$(SEP)bin,$(PATH)),)
xversion := X11R5
endif
ifneq ($(findstring X11$(SEP)bin,$(PATH)),)
xversion := X11
endif
ifdef xversion
X11_PATH := $(subst ;, ,$(PATH)) $(subst :, ,$(PATH))
X11_PATH := $(filter %$(xversion)$(SEP)bin,$(X11_PATH))
X11_PATH := $(X11_PATH:%$(SEP)bin=%)
endif
##########################################################################
#
# Update some variables to compile the X11 graphics module. Note that
# X11 is available on Unix, or on OS/2. However, it only compiles with
# gcc on the latter platform, which is why it is safe to use the flags
# `-L' and `-l'
#
ifneq ($(X11_PATH),)
X11_INCLUDE := $(X11_PATH)$(SEP)include
X11_LIB := $(X11_PATH)$(SEP)lib
# the GRAPH_LINK variable is expanded each time an executable is linked against
# the graphics library..
#
GRAPH_LINK += -L$(X11_LIB) -lX11
# add the X11 driver object file to the graphics library
#
GRAPH_OBJS += $(OBJ_)grx11.$O
GR_X11 := config$(SEP)x11
GR_X11_ := $(GR_X11)$(SEP)
DEVICES += X11
DEVICE_INCLUDES += $(GR_X11)
# the rule used to compile the X11 driver
#
$(OBJ_)grx11.$O: $(GR_X11_)grx11.c $(GR_X11_)grx11.h
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_X11) \
$(X11_INCLUDE:%=$I%) $T$@ $<
endif

5
demos/graph/gpm_os2.def Normal file
View File

@ -0,0 +1,5 @@
NAME WINDOWCOMPAT
DESCRIPTION 'FreeType Graphics'
HEAPSIZE 8192
STACKSIZE 40888

632
demos/graph/graph.h Normal file
View File

@ -0,0 +1,632 @@
/***************************************************************************
*
* graph.h
*
* Graphics Subsystem interface
*
* Copyright 1999 - The FreeType Development Team - www.freetype.org
*
*
*
*
***************************************************************************/
#ifndef GRAPH_H
#define GRAPH_H
#include "grevents.h"
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/******** ********/
/******** GENERAL DEFINITIONS AND BLITTING ROUTINES ********/
/******** ********/
/******** ********/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* define the global error variable */
extern int grError;
/* initialisation */
extern int grInit( void );
/* finalisation */
extern void grDone( void );
/* pixel mode constants */
typedef enum grPixelMode
{
gr_pixel_mode_none = 0,
gr_pixel_mode_mono, /* monochrome bitmaps */
gr_pixel_mode_pal4, /* 4-bit paletted - 16 colors */
gr_pixel_mode_pal8, /* 8-bit paletted - 256 colors */
gr_pixel_mode_gray, /* 8-bit gray levels */
gr_pixel_mode_rgb555, /* 15-bits mode - 32768 colors */
gr_pixel_mode_rgb565, /* 16-bits mode - 65536 colors */
gr_pixel_mode_rgb24, /* 24-bits mode - 16 million colors */
gr_pixel_mode_rgb32, /* 32-bits mode - 16 million colors */
gr_pixel_mode_max /* don't remove */
} grPixelMode;
/* forward declaration of the surface class */
typedef struct grSurface_ grSurface;
/*********************************************************************
*
* <Struct>
* grBitmap
*
* <Description>
* a simple bitmap descriptor
*
* <Fields>
* rows :: height in pixels
* width :: width in pixels
* pitch :: + or - the number of bytes per row
* mode :: pixel mode of bitmap buffer
* grays :: number of grays in palette for PAL8 mode. 0 otherwise
* buffer :: pointer to pixel buffer
*
* <Note>
* the 'pitch' is positive for downward flows, and negative otherwise
* Its absolute value is always the number of bytes taken by each
* bitmap row.
*
* All drawing operations will be performed within the first
* "width" pixels of each row (clipping is always performed).
*
********************************************************************/
typedef struct grBitmap_
{
int rows;
int width;
int pitch;
grPixelMode mode;
int grays;
char* buffer;
} grBitmap;
typedef long grPos;
typedef char grBool;
typedef struct grVector_
{
grPos x;
grPos y;
} grVector;
typedef union grColor_
{
long value;
unsigned char chroma[4];
} grColor;
/**********************************************************************
*
* <Function>
* grNewBitmap
*
* <Description>
* creates a new bitmap
*
* <Input>
* pixel_mode :: the target surface's pixel_mode
* num_grays :: number of grays levels for PAL8 pixel mode
* width :: width in pixels
* height :: height in pixels
*
* <Output>
* bit :: descriptor of the new bitmap
*
* <Return>
* Error code. 0 means success.
*
* <Note>
* This function really allocates a pixel buffer, zero it, then
* returns a descriptor for it.
*
* Call grDoneBitmap when you're done with it..
*
**********************************************************************/
extern int grNewBitmap( grPixelMode pixel_mode,
int num_grays,
int width,
int height,
grBitmap *bit );
/**********************************************************************
*
* <Function>
* grBlitGlyphToBitmap
*
* <Description>
* writes a given glyph bitmap to a target surface.
*
* <Input>
* target :: handle to target bitmap
* glyph :: handle to source glyph bitmap
* x :: position of left-most pixel of glyph image in target surface
* y :: position of top-most pixel of glyph image in target surface
* color :: color to be used to draw a monochrome glyph
*
* <Return>
* Error code. 0 means success
*
* <Note>
* There are only two supported source pixel modes : monochrome
* and gray. The 8-bit images can have any number of grays between
* 2 and 128, and conversions to the target surface is handled
* _automatically_.
*
* Note however that you should avoid blitting a gray glyph to a gray
* bitmap with fewer levels of grays, as this would much probably
* give unpleasant results..
*
* This function performs clipping
*
**********************************************************************/
extern int grBlitGlyphToBitmap( grBitmap* target,
grBitmap* glyph,
grPos x,
grPos y,
grColor color );
/**********************************************************************
*
* <Function>
* grFillRectangle
*
* <Description>
* this function is used to fill a given rectangle on a surface
*
* <Input>
* surface :: handle to target surface
* x :: x coordinate of the top-left corner of the rectangle
* y :: y coordinate of the top-left corner of the rectangle
* width :: rectangle width in pixels
* height :: rectangle height in pixels
* color :: fill color
*
**********************************************************************/
extern void grFillRectangle( grBitmap* surface,
grPos x,
grPos y,
grPos width,
grPos height,
grColor color );
/**********************************************************************
*
* <Function>
* grWriteCellChar
*
* <Description>
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a single 8x8 character on the target bitmap.
*
* <Input>
* target :: handle to target surface
* x :: x pixel position of character cell's top left corner
* y :: y pixel position of character cell's top left corner
* charcode :: Latin-1 character code
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteCellChar( grBitmap* target,
int x,
int y,
int charcode,
grColor color );
/**********************************************************************
*
* <Function>
* grWriteCellString
*
* <Description>
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a string with the internal font
*
* <Input>
* target :: handle to target bitmap
* x :: x pixel position of string's top left corner
* y :: y pixel position of string's top left corner
* string :: Latin-1 text string
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteCellString( grBitmap* target,
int x,
int y,
const char* string,
grColor color );
/**********************************************************************
*
* <Function>
* grDoneBitmap
*
* <Description>
* destroys a bitmap
*
* <Input>
* bitmap :: handle to bitmap descriptor
*
* <Note>
* This function does NOT release the bitmap descriptor, only
* the pixel buffer.
*
**********************************************************************/
extern void grDoneBitmap( grBitmap* bit );
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/******** ********/
/******** DEVICE-SPECIFIC DEFINITIONS AND ROUTINES ********/
/******** ********/
/******** ********/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* forward declaration - the definition of grDevice is not visible */
/* to clients.. */
typedef struct grDevice_ grDevice;
/**********************************************************************
*
* <Struct>
* grDeviceChain
*
* <Description>
* a simple structure used to implement a linked list of
* graphics device descriptors. The list is called a
* "device chain"
*
* <Fields>
* name :: ASCII name of the device, e.g. "x11", "os2pm", etc..
* device :: handle to the device descriptor.
* next :: next element in chain
*
* <Note>
* the 'device' field is a blind pointer; it is thus unusable by
* client applications..
*
**********************************************************************/
typedef struct grDeviceChain_ grDeviceChain;
struct grDeviceChain_
{
const char* name;
grDevice* device;
grDeviceChain* next;
};
/**********************************************************************
*
* <Function>
* grInitDevices
*
* <Description>
* This function is in charge of initialising all system-specific
* devices. A device is responsible for creating and managing one
* or more "surfaces". A surface is either a window or a screen,
* depending on the system.
*
* <Return>
* a pointer to the first element of a device chain. The chain can
* be parsed to find the available devices on the current system
*
* <Note>
* If a device cannot be initialised correctly, it is not part of
* the device chain returned by this function. For example, if an
* X11 device was compiled in the library, it will be part of
* the returned device chain only if a connection to the display
* could be establisged
*
* If no driver could be initialised, this function returns NULL.
*
**********************************************************************/
extern
grDeviceChain* grInitDevices( void );
/**********************************************************************
*
* <Function>
* grGetDeviceModes
*
* <Description>
* queries the available pixel modes for a device.
*
* <Input>
* device_name :: name of device to be used. 0 for the default
* device. For a list of available devices, see
* grInitDevices.
*
* <Output>
* num_modes :: number of available modes. 0 in case of error,
* which really is an invalid device name.
*
* pixel_modes :: array of available pixel modes for this device
* this table is internal to the device and should
* not be freed by client applications.
*
* <Return>
* error code. 0 means success. invalid device name otherwise
*
* <Note>
* All drivers are _required_ to support at least the following
* pixel formats :
*
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
* - gr_pixel_mode_gray : with any number of gray levels between
* 2 and 256.
*
* the pixel modes do not provide the number of grays in the case
* of "gray" devices. You should try to create a surface with the
* maximal number (256, that is) and see the value returned in
* the bitmap descriptor.
*
**********************************************************************/
extern void grGetDeviceModes( const char* device_name,
int *num_modes,
grPixelMode* *pixel_modes );
/**********************************************************************
*
* <Function>
* grNewSurface
*
* <Description>
* creates a new device-specific surface. A surface is either
* a window or a screen, depending on the device.
*
* <Input>
* device :: name of the device to use. A value of NULL means
* the default device (which depends on the system).
* for a list of available devices, see grInitDevices.
*
* <InOut>
* bitmap :: handle to a bitmap descriptor containing the
* requested pixel mode, number of grays and dimensions
* for the surface. the bitmap's 'pitch' and 'buffer'
* fields are ignored on input.
*
* On output, the bitmap describes the surface's image
* completely. It is possible to write directly in it
* with grBlitGlyphToBitmap, even though the use of
* grBlitGlyphToSurface is recommended.
*
* <Return>
* handle to the corresponding surface object. 0 in case of error
*
* <Note>
* All drivers are _required_ to support at least the following
* pixel formats :
*
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
* - gr_pixel_mode_gray : with any number of gray levels between
* 2 and 256.
*
* This function might change the bitmap descriptor's fields. For
* example, when displaying a full-screen surface, the bitmap's
* dimensions will be set to those of the screen (e.g. 640x480
* or 800x600); also, the bitmap's 'buffer' field might point to
* the Video Ram depending on the mode requested..
*
* The surface contains a copy of the returned bitmap descriptor,
* you can thus discard the 'bitmap' parameter after the call.
*
**********************************************************************/
extern grSurface* grNewSurface( const char* device,
grBitmap* bitmap );
/**********************************************************************
*
* <Function>
* grRefreshRectangle
*
* <Description>
* this function is used to indicate that a given surface rectangle
* was modified and thus needs re-painting. It really is useful for
* windowed or gray surfaces.
*
* <Input>
* surface :: handle to target surface
* x :: x coordinate of the top-left corner of the rectangle
* y :: y coordinate of the top-left corner of the rectangle
* width :: rectangle width in pixels
* height :: rectangle height in pixels
*
**********************************************************************/
extern void grRefreshRectangle( grSurface* surface,
grPos x,
grPos y,
grPos width,
grPos height );
/**********************************************************************
*
* <Function>
* grRefreshSurface
*
* <Description>
* a variation of grRefreshRectangle which repaints the whole surface
* to the screen.
*
* <Input>
* surface :: handle to target surface
*
**********************************************************************/
extern void grRefreshSurface( grSurface* surface );
/**********************************************************************
*
* <Function>
* grWriteSurfaceChar
*
* <Description>
* This function is equivalent to calling grWriteCellChar on the
* surface's bitmap, then invoking grRefreshRectangle.
*
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a single 8x8 character on the target bitmap.
*
* <Input>
* target :: handle to target surface
* x :: x pixel position of character cell's top left corner
* y :: y pixel position of character cell's top left corner
* charcode :: Latin-1 character code
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteSurfaceChar( grSurface* target,
int x,
int y,
int charcode,
grColor color );
/**********************************************************************
*
* <Function>
* grWriteSurfaceString
*
* <Description>
* This function is equivalent to calling grWriteCellString on the
* surface's bitmap, then invoking grRefreshRectangle.
*
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a string with the internal font
*
* <Input>
* target :: handle to target bitmap
* x :: x pixel position of string's top left corner
* y :: y pixel position of string's top left corner
* string :: Latin-1 text string
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteSurfaceString( grSurface* target,
int x,
int y,
const char* string,
grColor color );
/**********************************************************************
*
* <Function>
* grSetTitle
*
* <Description>
* set the window title of a given windowed surface.
*
* <Input>
* surface :: handle to target surface
* title_string :: the new title
*
**********************************************************************/
extern void grSetTitle( grSurface* surface,
const char* title_string );
/**********************************************************************
*
* <Function>
* grListenSurface
*
* <Description>
* listen the events for a given surface
*
* <Input>
* surface :: handle to target surface
* event_mask :: the event mask (mode)
*
* <Output>
* event :: the returned event
*
* <Note>
* XXX : For now, only keypresses are supported.
*
**********************************************************************/
extern
int grListenSurface( grSurface* surface,
int event_mask,
grEvent *event );
#endif /* GRAPH_H */

1268
demos/graph/grblit.c Normal file

File diff suppressed because it is too large Load Diff

25
demos/graph/grblit.h Normal file
View File

@ -0,0 +1,25 @@
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1999 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* blitter.h: Support for blitting of bitmaps with various depth. */
/* */
/****************************************************************************/
#ifndef GRBLIT_H
#define GRBLIT_H
#include "grobjs.h"
int grBlitMono( grBitmap* target,
grBitmap* source,
int x_offset,
int y_offset,
grColor color );
#endif /* GRBLIT_H */
/* End */

9
demos/graph/grconfig.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef GRCONFIG_H
#define GRCONFIG_H
#define GR_MAX_SATURATIONS 8
#define GR_MAX_CONVERSIONS 16
#define GR_MAX_DEVICES 8
#endif /* GRCONFIG_H */

361
demos/graph/grdevice.c Normal file
View File

@ -0,0 +1,361 @@
#include "grobjs.h"
#include "grdevice.h"
#include <stdlib.h>
grDeviceChain gr_device_chain[ GR_MAX_DEVICES ];
int gr_num_devices = 0;
static
grDevice* find_device( const char* device_name )
{
int index = 0;
if (device_name)
{
for ( index = gr_num_devices-1; index > 0; index-- )
if ( strcmp( device_name, gr_device_chain[index].name ) == 0 )
break;
}
if ( index < 0 || gr_num_devices <= 0 || !gr_device_chain[index].device )
{
grError = gr_err_invalid_device;
return 0;
}
return gr_device_chain[index].device;
}
/**********************************************************************
*
* <Function>
* grGetDeviceModes
*
* <Description>
* queries the available pixel modes for a device.
*
* <Input>
* device_name :: name of device to be used. 0 for the default
* device. For a list of available devices, see
* grInitDevices.
*
* <Output>
* num_modes :: number of available modes. 0 in case of error,
* which really is an invalid device name.
*
* pixel_modes :: array of available pixel modes for this device
* this table is internal to the device and should
* not be freed by client applications.
*
* <Return>
* error code. 0 means success. invalid device name otherwise
*
* <Note>
* All drivers are _required_ to support at least the following
* pixel formats :
*
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
* - gr_pixel_mode_gray : with any number of gray levels between
* 2 and 256.
*
* the pixel modes do not provide the number of grays in the case
* of "gray" devices. You should try to create a surface with the
* maximal number (256, that is) and see the value returned in
* the bitmap descriptor.
*
**********************************************************************/
extern void grGetDeviceModes( const char* device_name,
int *num_modes,
grPixelMode* *pixel_modes )
{
grDevice* device;
*num_modes = 0;
*pixel_modes = 0;
device = find_device( device_name );
if (device)
{
*num_modes = device->num_pixel_modes;
*pixel_modes = device->pixel_modes;
}
}
/**********************************************************************
*
* <Function>
* grNewSurface
*
* <Description>
* creates a new device-specific surface. A surface is either
* a window or a screen, depending on the device.
*
* <Input>
* device :: name of the device to use. A value of NULL means
* the default device (which depends on the system).
* for a list of available devices, see grInitDevices.
*
* <InOut>
* bitmap :: handle to a bitmap descriptor containing the
* requested pixel mode, number of grays and dimensions
* for the surface. the bitmap's 'pitch' and 'buffer'
* fields are ignored on input.
*
* On output, the bitmap describes the surface's image
* completely. It is possible to write directly in it
* with grBlitGlyphToBitmap, even though the use of
* grBlitGlyphToSurface is recommended.
*
* <Return>
* handle to the corresponding surface object. 0 in case of error
*
* <Note>
* All drivers are _required_ to support at least the following
* pixel formats :
*
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
* - gr_pixel_mode_gray : with any number of gray levels between
* 2 and 256.
*
* This function might change the bitmap descriptor's fields. For
* example, when displaying a full-screen surface, the bitmap's
* dimensions will be set to those of the screen (e.g. 640x480
* or 800x600); also, the bitmap's 'buffer' field might point to
* the Video Ram depending on the mode requested..
*
* The surface contains a copy of the returned bitmap descriptor,
* you can thus discard the 'bitmap' parameter after the call.
*
**********************************************************************/
extern grSurface* grNewSurface( const char* device_name,
grBitmap* bitmap )
{
grDevice* device;
grSurface* surface;
/* Now find the device */
device = find_device( device_name );
if (!device) return 0;
surface = (grSurface*)grAlloc( device->surface_objsize );
if (!surface) return 0;
if ( !device->init_surface( surface, bitmap ) )
{
grFree( surface );
surface = 0;
}
return surface;
}
/**********************************************************************
*
* <Function>
* grRefreshRectangle
*
* <Description>
* this function is used to indicate that a given surface rectangle
* was modified and thus needs re-painting. It really is useful for
* windowed or gray surfaces.
*
* <Input>
* surface :: handle to target surface
* x :: x coordinate of the top-left corner of the rectangle
* y :: y coordinate of the top-left corner of the rectangle
* width :: rectangle width in pixels
* height :: rectangle height in pixels
*
**********************************************************************/
extern void grRefreshRectangle( grSurface* surface,
grPos x,
grPos y,
grPos width,
grPos height )
{
if (surface->refresh_rect)
surface->refresh_rect( surface, x, y, width, height );
}
/**********************************************************************
*
* <Function>
* grWriteSurfaceChar
*
* <Description>
* This function is equivalent to calling grWriteCellChar on the
* surface's bitmap, then invoking grRefreshRectangle.
*
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a single 8x8 character on the target bitmap.
*
* <Input>
* target :: handle to target surface
* x :: x pixel position of character cell's top left corner
* y :: y pixel position of character cell's top left corner
* charcode :: Latin-1 character code
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteSurfaceChar( grSurface* target,
int x,
int y,
int charcode,
grColor color )
{
grWriteCellChar( &target->bitmap, x, y, charcode, color );
if (target->refresh_rect)
target->refresh_rect( target, x, y, 8, 8 );
}
/**********************************************************************
*
* <Function>
* grWriteSurfaceString
*
* <Description>
* This function is equivalent to calling grWriteCellString on the
* surface's bitmap, then invoking grRefreshRectangle.
*
* The graphics sub-system contains an internal Latin1 8x8 font
* which can be used to display simple strings of text without
* using FreeType.
*
* This function writes a string with the internal font
*
* <Input>
* target :: handle to target bitmap
* x :: x pixel position of string's top left corner
* y :: y pixel position of string's top left corner
* string :: Latin-1 text string
* color :: color to be used to draw the character
*
**********************************************************************/
extern
void grWriteSurfaceString( grSurface* target,
int x,
int y,
const char* string,
grColor color )
{
int len;
len = strlen(string);
grWriteCellString( &target->bitmap, x, y, string, color );
if (target->refresh_rect)
target->refresh_rect( target, x, y, 8*len, 8 );
}
/**********************************************************************
*
* <Function>
* grRefreshSurface
*
* <Description>
* a variation of grRefreshRectangle which repaints the whole surface
* to the screen.
*
* <Input>
* surface :: handle to target surface
*
**********************************************************************/
extern void grRefreshSurface( grSurface* surface )
{
if (surface->refresh_rect)
surface->refresh_rect( surface, 0, 0,
surface->bitmap.width,
surface->bitmap.rows );
}
/**********************************************************************
*
* <Function>
* grSetTitle
*
* <Description>
* set the window title of a given windowed surface.
*
* <Input>
* surface :: handle to target surface
* title_string :: the new title
*
**********************************************************************/
extern void grSetTitle( grSurface* surface,
const char* title_string )
{
if (surface->set_title)
surface->set_title( surface, title_string );
}
/**********************************************************************
*
* <Function>
* grListenSurface
*
* <Description>
* listen the events for a given surface
*
* <Input>
* surface :: handle to target surface
* event_mask :: the event mask (mode)
*
* <Output>
* event :: the returned event
*
* <Note>
* XXX : For now, only keypresses are supported.
*
**********************************************************************/
extern
int grListenSurface( grSurface* surface,
int event_mask,
grEvent *event )
{
return surface->listen_event( surface, event_mask, event );
}
#if 0
static
void gr_done_surface( grSurface* surface )
{
if (surface)
{
/* first of all, call the device-specific destructor */
surface->done(surface);
/* then remove the bitmap if we're owner */
if (surface->owner)
grFree( surface->bitmap.buffer );
surface->owner = 0;
surface->bitmap.buffer = 0;
grFree( surface );
}
}
#endif

126
demos/graph/grdevice.h Normal file
View File

@ -0,0 +1,126 @@
/***************************************************************************
*
* grdevice.h
*
* Graphics device interface
*
* Copyright 1999 - The FreeType Development Team - www.freetype.org
*
*
***************************************************************************/
#ifndef GRDEVICE_H
#define GRDEVICE_H
#include "graph.h"
/********************************************************************
*
* <FuncType>
* grDeviceInitFunc
*
* <Description>
* Simple device initialiser function
*
* <Return>
* error code. 0 means success
*
********************************************************************/
typedef int (*grDeviceInitFunc)( void );
/********************************************************************
*
* <FuncType>
* grDeviceDoneFunc
*
* <Description>
* Simple device finaliser function
*
* <Return>
* error code. 0 means success
*
********************************************************************/
typedef void (*grDeviceDoneFunc)( void );
/********************************************************************
*
* <FuncType>
* grDeviceInitSurfaceFunc
*
* <Description>
* initializes a new surface for the device. This may be a window
* or a video screen, depending on the device.
*
* <Input>
* surface :: handle to target surface
*
* <InOut>
* bitmap :: handle to bitmap descriptor
*
********************************************************************/
typedef int (*grDeviceInitSurfaceFunc)( grSurface* surface,
grBitmap* bitmap );
/********************************************************************
*
* <Struct>
* grDevice
*
* <Description>
* Simple device interface structure
*
* <Fields>
* surface_objsize :: size in bytes of a single surface object for
* this device.
*
* device_name :: name of device, e.g. "x11", "os2pm", "directx" etc..
* init :: device initialisation routine
* done :: device finalisation
* new_surface :: function used to create a new surface (screen or
* window) from the device
*
* num_pixel_modes :: the number of pixel modes supported by this
* device. This value _must_ be set to -1
* default, unless the device provides a
* static set of pixel modes (fullscreen).
*
* pixel_modes :: an array of pixel modes supported by this
* device
*
* <Note>
* the fields "num_pixel_modes" and "pixel_modes" must be
* set by the "init" function.
*
* This allows windowed devices to "discover" at run-time the
* available pixel modes they can provide depending on the
* current screen depth.
*
********************************************************************/
struct grDevice_
{
int surface_objsize;
const char* device_name; /* name of device */
grDeviceInitFunc init;
grDeviceDoneFunc done;
grDeviceInitSurfaceFunc init_surface;
int num_pixel_modes;
grPixelMode* pixel_modes;
};
extern grDeviceChain gr_device_chain[];
extern int gr_num_devices;
#endif /* GRDEVICE_H */

117
demos/graph/grevents.h Normal file
View File

@ -0,0 +1,117 @@
#ifndef GREVENTS_H
#define GREVENTS_H
#define gr_event_none 0
#define gr_event_wait 1
#define gr_event_poll 2
#define gr_event_flush 3
#define gr_mouse_down 0x04
#define gr_mouse_move 0x08
#define gr_mouse_up 0x10
#define gr_mouse_drag 0x20
#define gr_key_down 0x40
#define gr_key_up 0x80
#define gr_event_mouse 0x3C
#define gr_event_key 0xC0
#define gr_event_type (gr_event_mouse | gr_event_key)
typedef enum grKey_
{
grKeyNone = 0,
grKeyF1,
grKeyF2,
grKeyF3,
grKeyF4,
grKeyF5,
grKeyF6,
grKeyF7,
grKeyF8,
grKeyF9,
grKeyF10,
grKeyF11,
grKeyF12,
grKeyLeft,
grKeyRight,
grKeyUp,
grKeyDown,
grKeyIns,
grKeyDel,
grKeyHome,
grKeyEnd,
grKeyPageUp,
grKeyPageDown,
grKeyEsc,
grKeyTab,
grKeyBackSpace,
grKeyReturn,
grKeyMax,
grKeyForceShort = 0x7FFF /* this forces the grKey to be stored */
/* on at least one short ! */
} grKey;
#define grKEY(c) ((grKey)(c))
#define grKeyAlt ((grKey)0x8000)
#define grKeyCtrl ((grKey)0x4000)
#define grKeyShift ((grKey)0x2000)
#define grKeyModifiers ((grKey)0xE000)
#define grKey0 grKEY('0')
#define grKey1 grKEY('1')
#define grKey2 grKEY('2')
#define grKey3 grKEY('3')
#define grKey4 grKEY('4')
#define grKey5 grKEY('5')
#define grKey6 grKEY('6')
#define grKey7 grKEY('7')
#define grKey8 grKEY('8')
#define grKey9 grKEY('9')
#define grKeyPlus grKEY('+')
#define grKeyLess grKEY('-')
#define grKeyEqual grKEY('=')
#define grKeyMult grKEY('*')
#define grKeyDollar grKEY('$')
#define grKeySmaller grKEY('<')
#define grKeyGreater grKEY('>')
#define grKeyQuestion grKEY('?')
#define grKeyComma grKEY(',')
#define grKeyDot grKEY('.')
#define grKeySemiColumn grKEY(';')
#define grKeyColumn grKEY(':')
#define grKeyDiv grKEY('/')
#define grKeyExclam grKEY('!')
#define grKeyPercent grKEY('%')
#define grKeyLeftParen grKEY('(')
#define grKeyRightParen grKEY('(')
#define grKeyAt grKEY('@')
#define grKeyUnder grKEY('_')
typedef struct grEvent_
{
int type;
grKey key;
int x, y;
} grEvent;
#endif /* GREVENTS_H */

354
demos/graph/grfont.c Normal file
View File

@ -0,0 +1,354 @@
#include "grfont.h"
/* font characters */
const unsigned char font_8x8[2048] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static
grBitmap gr_charcell =
{
8, /* rows */
8, /* width */
gr_pixel_mode_mono, /* mode */
1, /* pitch */
0, /* grays */
0 /* buffer */
};
void grWriteCellChar( grBitmap* target,
int x,
int y,
int charcode,
grColor color )
{
if (charcode < 0 || charcode > 255)
return;
gr_charcell.buffer = (char*)font_8x8 + 8*charcode;
grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
}
void grWriteCellString( grBitmap* target,
int x,
int y,
const char* string,
grColor color )
{
while (*string)
{
gr_charcell.buffer = (char*)font_8x8 + 8*(int)(unsigned char)*string++;
grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
x += 8;
}
}
static int gr_cursor_x = 0;
static int gr_cursor_y = 0;
static grBitmap* gr_text_bitmap = 0;
static int gr_margin_right = 0;
static int gr_margin_top = 0;
extern void grGotobitmap( grBitmap* bitmap )
{
gr_text_bitmap = bitmap;
}
extern void grSetMargin( int right, int top )
{
gr_margin_top = top << 3;
gr_margin_right = right << 3;
}
extern void grGotoxy ( int x, int y )
{
gr_cursor_x = x;
gr_cursor_y = y;
}
extern void grWrite ( const char* string )
{
if (string)
{
grWriteCellString( gr_text_bitmap,
gr_margin_right + (gr_cursor_x << 3),
gr_margin_top + (gr_cursor_y << 3),
string,
(grColor)127L );
gr_cursor_x += strlen(string);
}
}
extern void grLn()
{
gr_cursor_y ++;
gr_cursor_x = 0;
}
extern void grWriteln( const char* string )
{
grWrite( string );
grLn();
}

16
demos/graph/grfont.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GRFONT_H
#define GRFONT_H
#include "graph.h"
extern const unsigned char font_8x8[];
extern void grGotobitmap( grBitmap* bitmap );
extern void grSetMargin( int right, int top );
extern void grGotoxy ( int x, int y );
extern void grWrite ( const char* string );
extern void grWriteln( const char* string );
extern void grLn();
#endif /* GRFONT_H */

78
demos/graph/grinit.c Normal file
View File

@ -0,0 +1,78 @@
#include "grobjs.h"
#include "grdevice.h"
#include <stdio.h>
#define GR_INIT_DEVICE_CHAIN ((grDeviceChain*)0)
#define GR_INIT_BUILD
#ifdef DEVICE_X11
#include "grx11.h"
#endif
#ifdef DEVICE_OS2_PM
#include "gros2pm.h"
#endif
/**********************************************************************
*
* <Function>
* grInitDevices
*
* <Description>
* This function is in charge of initialising all system-specific
* devices. A device is responsible for creating and managing one
* or more "surfaces". A surface is either a window or a screen,
* depending on the system.
*
* <Return>
* a pointer to the first element of a device chain. The chain can
* be parsed to find the available devices on the current system
*
* <Note>
* If a device cannot be initialised correctly, it is not part of
* the device chain returned by this function. For example, if an
* X11 device was compiled in the library, it will be part of
* the returned device chain only if a connection to the display
* could be establisged
*
* If no driver could be initialised, this function returns NULL.
*
**********************************************************************/
extern
grDeviceChain* grInitDevices( void )
{
grDeviceChain* chain = GR_INIT_DEVICE_CHAIN;
grDeviceChain* cur = gr_device_chain;
while (chain)
{
/* initialie the device */
grDevice* device;
device = chain->device;
if ( device->init() == 0 &&
gr_num_devices < GR_MAX_DEVICES )
{
/* successful device initialisation - add it to our chain */
cur->next = 0;
cur->device = device;
cur->name = device->device_name;
if (cur > gr_device_chain)
cur[-1].next = cur;
cur++;
gr_num_devices++;
}
chain = chain->next;
}
return (gr_num_devices > 0 ? gr_device_chain : 0 );
}

213
demos/graph/grobjs.c Normal file
View File

@ -0,0 +1,213 @@
#include "grobjs.h"
#include <stdlib.h>
int grError = 0;
/********************************************************************
*
* <Function>
* grRealloc
*
* <Description>
* Simple memory re-allocation.
*
* <Input>
* block :: original memory block address
* size :: new requested block size in bytes
*
* <Return>
* the memory block address. 0 in case of error
*
********************************************************************/
char* grAlloc( long size )
{
char* p;
p = (char*)malloc(size);
if (!p && size > 0)
{
grError = gr_err_memory;
}
if (p)
memset( p, 0, size );
return p;
}
/********************************************************************
*
* <Function>
* grRealloc
*
* <Description>
* Simple memory re-allocation.
*
* <Input>
* block :: original memory block address
* size :: new requested block size in bytes
*
* <Return>
* the memory block address. 0 in case of error
*
********************************************************************/
char* grRealloc( const char* block, long size )
{
char* p;
p = realloc( (char*)block, size );
if (!p && size > 0)
{
grError = gr_err_memory;
}
return p;
}
/********************************************************************
*
* <Function>
* grFree
*
* <Description>
* Simple memory release
*
* <Input>
* block :: target block
*
********************************************************************/
void grFree( const void* block )
{
if (block)
free( (char*)block );
}
static
int check_mode( grPixelMode pixel_mode,
int num_grays )
{
if ( pixel_mode <= gr_pixel_mode_none ||
pixel_mode >= gr_pixel_mode_max )
goto Fail;
if ( pixel_mode != gr_pixel_mode_gray ||
( num_grays >= 2 && num_grays < 256 ) )
return 0;
Fail:
grError = gr_err_bad_argument;
return grError;
}
/**********************************************************************
*
* <Function>
* grNewBitmap
*
* <Description>
* creates a new bitmap
*
* <Input>
* pixel_mode :: the target surface's pixel_mode
* num_grays :: number of grays levels for PAL8 pixel mode
* width :: width in pixels
* height :: height in pixels
*
* <Output>
* bit :: descriptor of the new bitmap
*
* <Return>
* Error code. 0 means success.
*
**********************************************************************/
extern int grNewBitmap( grPixelMode pixel_mode,
int num_grays,
int width,
int height,
grBitmap *bit )
{
int pitch;
/* check mode */
if (check_mode(pixel_mode,num_grays))
goto Fail;
/* check dimensions */
if (width < 0 || height < 0)
{
grError = gr_err_bad_argument;
goto Fail;
}
bit->width = width;
bit->rows = height;
bit->mode = pixel_mode;
bit->grays = num_grays;
pitch = width;
switch (pixel_mode)
{
case gr_pixel_mode_mono : pitch = (width+7) >> 3; break;
case gr_pixel_mode_pal4 : pitch = (width+3) >> 2; break;
case gr_pixel_mode_pal8 :
case gr_pixel_mode_gray : pitch = width; break;
case gr_pixel_mode_rgb555:
case gr_pixel_mode_rgb565: pitch = width*2; break;
case gr_pixel_mode_rgb24 : pitch = width*3; break;
case gr_pixel_mode_rgb32 : pitch = width*4; break;
default:
grError = gr_err_bad_target_depth;
return 0;
}
bit->pitch = pitch;
bit->buffer = grAlloc( (long)bit->pitch * bit->rows );
if (!bit->buffer) goto Fail;
return 0;
Fail:
return grError;
}
/**********************************************************************
*
* <Function>
* grDoneBitmap
*
* <Description>
* destroys a bitmap
*
* <Input>
* bitmap :: handle to bitmap descriptor
*
* <Note>
* This function does NOT release the bitmap descriptor, only
* the pixel buffer.
*
**********************************************************************/
extern void grDoneBitmap( grBitmap* bit )
{
grFree( bit->buffer );
bit->buffer = 0;
}

186
demos/graph/grobjs.h Normal file
View File

@ -0,0 +1,186 @@
/***************************************************************************
*
* grobjs.h
*
* basic object classes defintions
*
* Copyright 1999 - The FreeType Development Team - www.freetype.org
*
*
*
*
***************************************************************************/
#ifndef GROBJS_H
#define GROBJS_H
#include "graph.h"
#include "grconfig.h"
#include "grtypes.h"
typedef struct grBiColor_
{
grColor foreground;
grColor background;
int num_levels;
int max_levels;
grColor* levels;
} grBiColor;
/**********************************************************************
*
* Technical note : explaining how the blitter works.
*
* The blitter is used to "draw" a given source bitmap into
* a given target bitmap.
*
* The function called 'compute_clips' is used to compute clipping
* constraints. These lead us to compute two areas :
*
* - the read area : is the rectangle, within the source bitmap,
* which will be effectively "drawn" in the
* target bitmap.
*
* - the write area : is the rectangle, within the target bitmap,
* which will effectively "receive" the pixels
* from the read area
*
* Note that both areas have the same dimensions, but are
* located in distinct surfaces.
*
* These areas are computed by 'compute_clips' which is called
* by each blitting function.
*
* Note that we use the Y-downwards convention within the blitter
*
**********************************************************************/
typedef struct grBlitter_
{
int width; /* width in pixels of the areas */
int height; /* height in pixels of the areas */
int xread; /* x position of start point in read area */
int yread; /* y position of start point in read area */
int xwrite; /* x position of start point in write area */
int ywrite; /* y position of start point in write area */
int right_clip; /* amount of right clip */
unsigned char* read; /* top left corner of read area in source map */
unsigned char* write; /* top left corner of write area in target map */
int read_line; /* byte increment to go down one row in read area */
int write_line; /* byte increment to go down one row in write area */
grBitmap source; /* source bitmap descriptor */
grBitmap target; /* target bitmap descriptor */
} grBlitter;
typedef void (*grBlitterFunc)( grBlitter* blitter,
grColor color );
typedef void (*grSetTitleFunc)( grSurface* surface,
const char* title_string );
typedef void (*grRefreshRectFunc)( grSurface* surface,
int x,
int y,
int width,
int height );
typedef void (*grDoneSurfaceFunc)( grSurface* surface );
typedef int (*grListenEventFunc)( grSurface* surface,
int event_mode,
grEvent *event );
struct grSurface_
{
grDevice* device;
grBitmap bitmap;
grBool refresh;
grBool owner;
const byte* saturation; /* used for gray surfaces only */
grBlitterFunc blit_mono; /* 0 by default, set by grBlit.. */
grRefreshRectFunc refresh_rect;
grSetTitleFunc set_title;
grListenEventFunc listen_event;
grDoneSurfaceFunc done;
};
/********************************************************************
*
* <Function>
* grAlloc
*
* <Description>
* Simple memory allocation. The returned block is always zero-ed
*
* <Input>
* size :: size in bytes of the requested block
*
* <Return>
* the memory block address. 0 in case of error
*
********************************************************************/
extern char* grAlloc( long size );
/********************************************************************
*
* <Function>
* grRealloc
*
* <Description>
* Simple memory re-allocation.
*
* <Input>
* block :: original memory block address
* size :: new requested block size in bytes
*
* <Return>
* the memory block address. 0 in case of error
*
********************************************************************/
extern char* grRealloc( const char* block, long size );
/********************************************************************
*
* <Function>
* grFree
*
* <Description>
* Simple memory release
*
* <Input>
* block :: target block
*
********************************************************************/
extern void grFree( const void* block );
extern grDevice* gr_devices[];
extern int gr_num_devices;
extern int gr_max_devices;
#endif /* GROBJS_H */

895
demos/graph/gros2pm.c Normal file
View File

@ -0,0 +1,895 @@
#include "gros2pm.h"
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#define INCL_SUB
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void Panic( const char* message )
{
fprintf( stderr, "%s", message );
exit(1);
}
typedef struct Translator
{
ULONG os2key;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ VK_BACKSPACE, grKeyBackSpace },
{ VK_TAB, grKeyTab },
{ VK_ENTER, grKeyReturn },
{ VK_ESC, grKeyEsc },
{ VK_HOME, grKeyHome },
{ VK_LEFT, grKeyLeft },
{ VK_UP, grKeyUp },
{ VK_RIGHT, grKeyRight },
{ VK_DOWN, grKeyDown },
{ VK_PAGEUP, grKeyPageUp },
{ VK_PAGEDOWN, grKeyPageDown },
{ VK_END, grKeyEnd },
{ VK_F1, grKeyF1 },
{ VK_F2, grKeyF2 },
{ VK_F3, grKeyF3 },
{ VK_F4, grKeyF4 },
{ VK_F5, grKeyF5 },
{ VK_F6, grKeyF6 },
{ VK_F7, grKeyF7 },
{ VK_F8, grKeyF8 },
{ VK_F9, grKeyF9 },
{ VK_F10, grKeyF10 },
{ VK_F11, grKeyF11 },
{ VK_F12, grKeyF12 }
};
#define MAX_PIXEL_MODES 32
static int num_pixel_modes = 0;
static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
static int pixel_depth[ MAX_PIXEL_MODES ];
static HAB gr_anchor; /* device anchor block */
typedef POINTL PMBlitPoints[4];
typedef struct grPMSurface_
{
grSurface root;
grBitmap image;
HAB anchor; /* handle to anchor block for surface's window */
HWND frame_window; /* handle to window's frame */
HWND client_window; /* handle to window's client */
HWND title_window; /* handle to window's title bar */
HPS image_ps; /* memory presentation space used to hold */
/* the surface's content under PM */
HDC image_dc; /* memory device context for the image */
HEV event_lock; /* semaphore used in listen_surface */
HMTX image_lock; /* a mutex used to synchronise access */
/* to the memory presentation space */
/* used to hold the surface */
TID message_thread; /* thread used to process this surface's */
/* messages.. */
PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor */
HBITMAP os2_bitmap; /* Handle to OS/2 bitmap contained in image */
BOOL ready; /* ??? */
long shades[256]; /* indices of gray levels in pixel_mode_gray */
POINTL surface_blit[4]; /* surface blitting table */
POINTL magnify_blit[4]; /* magnifier blitting table */
int magnification; /* level of magnification */
POINTL magnify_center;
SIZEL magnify_size;
grEvent event;
PMBlitPoints blit_points;
} grPMSurface;
static
void enable_os2_iostreams( void )
{
PTIB thread_block;
PPIB process_block;
/* XXX : This is a very nasty hack, it fools OS/2 and let the program */
/* call PM functions, even though stdin/stdout/stderr are still */
/* directed to the standard i/o streams.. */
/* The program must be compiled with WINDOWCOMPAT */
/* */
/* Credits go to Michal for finding this !! */
/* */
DosGetInfoBlocks( &thread_block, &process_block );
process_block->pib_ultype = 3;
}
static
int init_device( void )
{
enable_os2_iostreams();
/* create an anchor block. This will allow this thread (i.e. the */
/* main one) to call Gpi functions.. */
gr_anchor = WinInitialize(0);
if (!gr_anchor)
{
/* could not initialise Presentation Manager */
return -1;
}
return 0;
}
static
void done_device( void )
{
/* Indicates that we do not use the Presentation Manager, this */
/* will also release all associated resources.. */
WinTerminate( gr_anchor );
}
/* close a given window */
static
void done_surface( grPMSurface* surface )
{
if ( surface->frame_window )
WinDestroyWindow( surface->frame_window );
WinReleasePS( surface->image_ps );
grDoneBitmap( &surface->image );
grDoneBitmap( &surface->root.bitmap );
}
static
void add_pixel_mode( grPixelMode pixel_mode,
int depth )
{
if ( num_pixel_modes >= MAX_PIXEL_MODES )
Panic( "X11.Too many pixel modes\n" );
pixel_modes[ num_pixel_modes ] = pixel_mode;
pixel_depth[ num_pixel_modes ] = depth;
num_pixel_modes++;
}
#define LOCK(x) DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
#define UNLOCK(x) DosReleaseMutexSem( x )
static
const int pixel_mode_bit_count[] =
{
0,
1,
4,
8, /* pal8 */
8, /* gray */
15,
16,
24,
32
};
/************************************************************************
*
* Technical note : how the OS/2 Presntation Manager driver works
*
* PM is, in my opinion, a bloated and over-engineered graphics
* sub-system, even though it has lots of nice features. Here are
* a few tidbits about it :
*
*
* - under PM, a "bitmap" is a device-specific object whose bits are
* not directly accessible to the client application. This means
* that we must use a scheme like the following to display our
* surfaces :
*
* - hold, for each surface, its own bitmap buffer where the
* rest of MiGS writes directly.
*
* - create a PM bitmap object with the same dimensions (and
* possibly format).
*
* - copy the content of each updated rectangle into the
* PM bitmap with the function 'GpiSetBitmapBits'.
*
* - finally, "blit" the PM bitmap to the screen calling
* 'GpiBlitBlt'
*
* - but there is more : you cannot directly blit a PM bitmap to the
* screen with PM. The 'GpiBlitBlt' only works with presentation
* spaces. This means that we also need to create, for each surface :
*
* - a memory presentation space, used to hold the PM bitmap
* - a "memory device context" for the presentation space
*
* The blit is then performed from the memory presentation space
* to the screen's presentation space..
*
*
* - because each surface creates its own event-handling thread,
* we must protect the surface's presentation space from concurrent
* accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
* surface, and calls to 'GpiBlitBlt' when drawing it on the screen
* are performed in two different threads).
*
* we use a simple mutex to do this.
*
*
* - we also use a semaphore to perform a rendez-vous between the
* main and event-handling threads (needed in "listen_event").
*
************************************************************************/
static
void RunPMWindow( grPMSurface* surface );
static
void convert_gray_to_pal8( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
long* palette = surface->shades;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + w;
for ( ; _write < limit; _write++, _read++ )
*_write = (byte) palette[ *_read ];
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_16( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
long* palette = surface->shades;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 2*w;
for ( ; _write < limit; _write += 2, _read++ )
*(short*)_write = (short)palette[ *_read ];
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_24( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 3*w;
for ( ; _write < limit; _write += 3, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_32( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 4*w;
for ( ; _write < limit; _write += 4, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] =
_write[3] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_rectangle( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
int z;
/* first of all, clip to the surface's area */
if ( x >= surface->image.width ||
x+w <= 0 ||
y >= surface->image.rows ||
y+h <= 0 )
return;
if ( x < 0 )
{
w += x;
x = 0;
}
z = (x + w) - surface->image.width;
if (z > 0)
w -= z;
z = (y + h) - surface->image.rows;
if (z > 0)
h -= z;
/* convert the rectangle to the target depth for gray surfaces */
if (surface->root.bitmap.mode == gr_pixel_mode_gray)
{
switch (surface->image.mode)
{
case gr_pixel_mode_pal8 :
convert_gray_to_pal8( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb555:
case gr_pixel_mode_rgb565:
convert_gray_to_16 ( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb24:
convert_gray_to_24 ( surface, x, y, w, h );
break;
case gr_pixel_mode_rgb32:
convert_gray_to_32 ( surface, x, y, w, h );
break;
default:
;
}
}
}
static
void refresh_rectangle( grPMSurface* surface,
int x,
int y,
int w,
int h )
{
convert_rectangle( surface, x, y, w, h );
WinInvalidateRect( surface->client_window, NULL, FALSE );
WinUpdateWindow( surface->frame_window );
}
static
void set_title( grPMSurface* surface,
const char* title )
{
WinSetWindowText( surface->title_window, (PSZ)title );
}
static
void listen_event( grPMSurface* surface,
int event_mask,
grEvent* grevent )
{
ULONG ulRequestCount;
(void) event_mask; /* ignored for now */
/* the listen_event function blocks until there is an event to process */
DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
DosQueryEventSem( surface->event_lock, &ulRequestCount );
*grevent = surface->event;
DosResetEventSem( surface->event_lock, &ulRequestCount );
return;
}
static
int init_surface( grPMSurface* surface,
grBitmap* bitmap )
{
PBITMAPINFO2 bit;
SIZEL sizl = { 0, 0 };
LONG palette[256];
/* create the bitmap - under OS/2, we support all modes as PM */
/* handles all conversions automatically.. */
if ( grNewBitmap( surface->root.bitmap.mode,
surface->root.bitmap.grays,
surface->root.bitmap.width,
surface->root.bitmap.rows,
bitmap ) )
return grError;
surface->root.bitmap = *bitmap;
/* create the image and event lock */
DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE );
DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
/* create the image's presentation space */
surface->image_dc = DevOpenDC( gr_anchor,
OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
surface->image_ps = GpiCreatePS( gr_anchor,
surface->image_dc,
&sizl,
PU_PELS | GPIT_MICRO |
GPIA_ASSOC | GPIF_DEFAULT );
GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
/* create the image's PM bitmap */
bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
surface->bitmap_header = bit;
bit->cbFix = sizeof( BITMAPINFOHEADER2 );
bit->cx = surface->root.bitmap.width;
bit->cy = surface->root.bitmap.rows;
bit->cPlanes = 1;
bit->argbColor[0].bBlue = 0;
bit->argbColor[0].bGreen = 0;
bit->argbColor[0].bRed = 0;
bit->argbColor[1].bBlue = 255;
bit->argbColor[1].bGreen = 255;
bit->argbColor[1].bRed = 255;
bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
(PBITMAPINFOHEADER2)bit,
0L, NULL, NULL );
GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
bit->cbFix = sizeof( BITMAPINFOHEADER2 );
GpiQueryBitmapInfoHeader( surface->os2_bitmap,
(PBITMAPINFOHEADER2)bit );
/* for gr_pixel_mode_gray, create a gray-levels logical palette */
if ( bitmap->mode == gr_pixel_mode_gray )
{
int x, count;
count = bitmap->grays;
for ( x = 0; x < count; x++ )
palette[x] = (((count-x)*255)/count) * 0x010101;
/* create logical color table */
GpiCreateLogColorTable( surface->image_ps,
(ULONG) LCOL_PURECOLOR,
(LONG) LCOLF_CONSECRGB,
(LONG) 0L,
(LONG) count,
(PLONG) palette );
/* now, copy the color indexes to surface->shades */
for ( x = 0; x < count; x++ )
surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
0, palette[x] );
}
/* set up the blit points array */
surface->blit_points[1].x = surface->root.bitmap.width;
surface->blit_points[1].y = surface->root.bitmap.rows;
surface->blit_points[3] = surface->blit_points[1];
/* Finally, create the event handling thread for the surface's window */
DosCreateThread( &surface->message_thread,
(PFNTHREAD) RunPMWindow,
(ULONG) surface,
0UL,
32920 );
surface->root.done = (grDoneSurfaceFunc) done_surface;
surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
surface->root.set_title = (grSetTitleFunc) set_title;
surface->root.listen_event = (grListenEventFunc) listen_event;
convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
return 0;
}
MRESULT EXPENTRY Message_Process( HWND handle,
ULONG mess,
MPARAM parm1,
MPARAM parm2 );
static
void RunPMWindow( grPMSurface* surface )
{
unsigned char class_name[] = "DisplayClass";
ULONG class_flags;
static HMQ queue;
QMSG message;
/* create an anchor to allow this thread to use PM */
surface->anchor = WinInitialize(0);
if (!surface->anchor)
{
printf( "Error doing WinInitialize()\n" );
return;
}
/* create a message queue */
queue = WinCreateMsgQueue( surface->anchor, 0 );
if (!queue)
{
printf( "Error doing >inCreateMsgQueue()\n" );
return;
}
/* register the window class */
if ( !WinRegisterClass( surface->anchor,
(PSZ) class_name,
(PFNWP) Message_Process,
CS_SIZEREDRAW,
0 ) )
{
printf( "Error doing WinRegisterClass()\n" );
return;
}
/* create the PM window */
class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER |
FCF_TASKLIST | FCF_SYSMENU;
surface->frame_window = WinCreateStdWindow(
HWND_DESKTOP,
WS_VISIBLE,
&class_flags,
(PSZ) class_name,
(PSZ) "FreeType PM Graphics",
WS_VISIBLE,
0, 0,
&surface->client_window );
if (!surface->frame_window)
{
printf( "Error doing WinCreateStdWindow()\n" );
return;
}
/* find the title window handle */
surface->title_window = WinWindowFromID( surface->frame_window,
FID_TITLEBAR );
/* set Window size and position */
WinSetWindowPos( surface->frame_window,
0L,
(SHORT) 60,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
surface->root.bitmap.rows + 100,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
surface->root.bitmap.width,
(SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
surface->root.bitmap.rows,
SWP_SIZE | SWP_MOVE );
/* save the handle to the current surface within the window words */
WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
/* run the message queue till the end */
while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
WinDispatchMsg( surface->anchor, &message );
/* clean-up */
WinDestroyWindow( surface->frame_window );
surface->frame_window = 0;
WinDestroyMsgQueue( queue );
WinTerminate( surface->anchor );
/* await death... */
while ( 1 )
DosSleep( 100 );
}
/* Message processing for our PM Window class */
MRESULT EXPENTRY Message_Process( HWND handle,
ULONG mess,
MPARAM parm1,
MPARAM parm2 )
{
static HDC screen_dc;
static HPS screen_ps;
static BOOL minimized;
SIZEL sizl;
SWP swp;
grPMSurface* surface;
/* get the handle to the window's surface */
surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
switch( mess )
{
case WM_DESTROY:
/* warn the main thread to quit if it didn't know */
surface->event.type = gr_event_key;
surface->event.key = grKeyEsc;
DosPostEventSem( surface->event_lock );
break;
case WM_CREATE:
/* set original magnification */
minimized = FALSE;
/* create Device Context and Presentation Space for screen. */
screen_dc = WinOpenWindowDC( handle );
screen_ps = GpiCreatePS( surface->anchor,
screen_dc,
&sizl,
PU_PELS | GPIT_MICRO |
GPIA_ASSOC | GPIF_DEFAULT );
/* take the input focus */
WinFocusChange( HWND_DESKTOP, handle, 0L );
break;
case WM_MINMAXFRAME:
/* to update minimized if changed */
swp = *((PSWP) parm1);
if ( swp.fl & SWP_MINIMIZE )
minimized = TRUE;
if ( swp.fl & SWP_RESTORE )
minimized = FALSE;
return WinDefWindowProc( handle, mess, parm1, parm2 );
break;
case WM_ERASEBACKGROUND:
case WM_PAINT:
/* copy the memory image of the screen out to the real screen */
DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
WinBeginPaint( handle, screen_ps, NULL );
/* main image and magnified picture */
GpiBitBlt( screen_ps,
surface->image_ps,
4L,
surface->blit_points,
ROP_SRCCOPY, BBO_AND );
WinEndPaint( screen_ps );
DosReleaseMutexSem( surface->image_lock );
break;
case WM_CHAR:
if ( CHARMSG( &mess )->fs & KC_KEYUP )
break;
/* look for a specific vkey */
{
int count = sizeof( key_translators )/sizeof( key_translators[0] );
Translator* trans = key_translators;
Translator* limit = trans + count;
for ( ; trans < limit; trans++ )
if ( CHARMSG(&mess)->vkey == trans->os2key )
{
surface->event.key = trans->grkey;
goto Do_Key_Event;
}
}
/* otherwise, simply record the character code */
if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
break;
surface->event.key = CHARMSG(&mess)->chr;
Do_Key_Event:
surface->event.type = gr_event_key;
DosPostEventSem( surface->event_lock );
break;
default:
return WinDefWindowProc( handle, mess, parm1, parm2 );
}
return (MRESULT) FALSE;
}
#if 0
static
grKey KeySymTogrKey( key )
{
grKey k;
int count = sizeof(key_translators)/sizeof(key_translators[0]);
Translator* trans = key_translators;
Translator* limit = trans + count;
k = grKeyNone;
while ( trans < limit )
{
if ( trans->xkey == key )
{
k = trans->grkey;
break;
}
trans++;
}
return k;
}
static
void listen_event( grPMSurface* surface,
int event_mask,
grEvent* grevent )
{
grKey grkey;
/* XXXX : For now, ignore the event mask, and only exit when */
/* a key is pressed.. */
(void)event_mask;
/* Now, translate the keypress to a grKey */
/* If this wasn't part of the simple translated keys, simply get the charcode */
/* from the character buffer */
grkey = grKEY(key_buffer[key_cursor++]);
Set_Key:
grevent->type = gr_key_down;
grevent->key = grkey;
}
#endif
grDevice gr_os2pm_device =
{
sizeof( grPMSurface ),
"os2pm",
init_device,
done_device,
(grDeviceInitSurfaceFunc) init_surface,
0,
0
};

23
demos/graph/gros2pm.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef GROS2PM_H
#define GROS2PM_H
#include "grobjs.h"
extern
grDevice gr_os2pm_device;
#ifdef GR_INIT_BUILD
static
grDeviceChain gr_os2pm_device_chain =
{
"os2pm",
&gr_os2pm_device,
GR_INIT_DEVICE_CHAIN
};
#undef GR_INIT_DEVICE_CHAIN
#define GR_INIT_DEVICE_CHAIN &gr_os2pm_device_chain
#endif /* GR_INIT_BUILD */
#endif /* GROS2PM_H */

52
demos/graph/grtypes.h Normal file
View File

@ -0,0 +1,52 @@
/***************************************************************************
*
* grtypes.h
*
* basic type defintions
*
* Copyright 1999 - The FreeType Development Team - www.freetype.org
*
*
*
*
***************************************************************************/
#ifndef GRTYPES_H
#define GRTYPES_H
typedef unsigned char byte;
#if 0
typedef signed char uchar;
typedef unsigned long ulong;
typedef unsigned short ushort;
typedef unsigned int uint;
#endif
typedef struct grDimension_
{
int x;
int y;
} grDimension;
#define gr_err_ok 0
#define gr_err_memory -1
#define gr_err_bad_argument -2
#define gr_err_bad_target_depth -3
#define gr_err_bad_source_depth -4
#define gr_err_saturation_overflow -5
#define gr_err_conversion_overflow -6
#define gr_err_invalid_device -7
#ifdef GR_MAKE_OPTION_SINGLE_OBJECT
#define GR_LOCAL_DECL static
#define GR_LOCAL_FUNC static
#else
#define GR_LOCAL_DECL extern
#define GR_LOCAL_FUNC /* void */
#endif
#endif /* GRTYPES_H */

936
demos/graph/grx11.c Normal file
View File

@ -0,0 +1,936 @@
#include "grx11.h"
#ifdef TEST
#include "grfont.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
static void Panic( const char* message )
{
fprintf( stderr, "%s", message );
exit(1);
}
typedef struct Translator
{
KeySym xkey;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ XK_BackSpace, grKeyBackSpace },
{ XK_Tab, grKeyTab },
{ XK_Return, grKeyReturn },
{ XK_Escape, grKeyEsc },
{ XK_Home, grKeyHome },
{ XK_Left, grKeyLeft },
{ XK_Up, grKeyUp },
{ XK_Right, grKeyRight },
{ XK_Down, grKeyDown },
{ XK_Page_Up, grKeyPageUp },
{ XK_Page_Down, grKeyPageDown },
{ XK_End, grKeyEnd },
{ XK_Begin, grKeyHome },
{ XK_F1, grKeyF1 },
{ XK_F2, grKeyF2 },
{ XK_F3, grKeyF3 },
{ XK_F4, grKeyF4 },
{ XK_F5, grKeyF5 },
{ XK_F6, grKeyF6 },
{ XK_F7, grKeyF7 },
{ XK_F8, grKeyF8 },
{ XK_F9, grKeyF9 },
{ XK_F10, grKeyF10 },
{ XK_F11, grKeyF11 },
{ XK_F12, grKeyF12 }
};
#ifdef TEST
#define grAlloc malloc
#endif
static Display* display;
static char* displayname = "";
static Cursor idle;
static Cursor busy;
#define MAX_PIXEL_MODES 32
typedef XPixmapFormatValues XDepth;
static int num_pixel_modes = 0;
static grPixelMode pixel_modes[ MAX_PIXEL_MODES ];
static XDepth pixel_depth[ MAX_PIXEL_MODES ];
typedef struct grXSurface_
{
grSurface root;
grBitmap image;
Window win;
Visual* visual;
Colormap colormap;
int depth;
Bool gray;
GC gc;
XColor color[256]; /* gray levels palette for 8-bit modes */
XImage* ximage;
int win_org_x;
int win_org_y;
int win_width;
int win_height;
int image_width;
int image_height;
} grXSurface;
/* close a given window */
static
void done_surface( grXSurface* surface )
{
XUnmapWindow( display, surface->win );
}
/* close the device, i.e. the display connection */
static
void done_device( void )
{
XCloseDisplay( display );
}
static
void add_pixel_mode( grPixelMode pixel_mode,
XDepth* depth )
{
if ( num_pixel_modes >= MAX_PIXEL_MODES )
Panic( "X11.Too many pixel modes\n" );
pixel_modes[ num_pixel_modes ] = pixel_mode;
pixel_depth[ num_pixel_modes ] = *depth;
num_pixel_modes++;
}
static
int init_device( void )
{
XDepth dummy;
XrmInitialize();
display = XOpenDisplay( displayname );
if (!display)
{
return -1;
/* Panic( "Gr:error: cannot open X11 display\n" ); */
}
idle = XCreateFontCursor( display, XC_left_ptr );
busy = XCreateFontCursor( display, XC_watch );
num_pixel_modes = 0;
/* always enable the 8-bit gray levels pixel mode */
/* even if its display is emulated through a constrained palette */
/* or another color mode */
dummy.depth = 8;
dummy.bits_per_pixel = 8;
dummy.scanline_pad = 8;
add_pixel_mode( gr_pixel_mode_gray, &dummy );
{
int count;
XDepth* format;
XDepth* formats;
XVisualInfo template;
formats = XListPixmapFormats( display, &count );
format = formats;
#ifdef TEST
printf( "available pixmap formats\n" );
printf( "depth pixbits scanpad\n" );
#endif
while ( count-- > 0 )
{
#ifdef TEST
printf( " %3d %3d %3d\n",
format->depth,
format->bits_per_pixel,
format->scanline_pad );
#endif
if ( format->depth == 1 )
/* usually, this should be the first format */
add_pixel_mode( gr_pixel_mode_mono, format );
else if ( format->depth == 8 )
add_pixel_mode( gr_pixel_mode_pal8, format );
/* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */
else if ( format->depth == 24 )
{
if ( format->bits_per_pixel == 24 )
add_pixel_mode( gr_pixel_mode_rgb24, format );
else if ( format->bits_per_pixel == 32 )
add_pixel_mode( gr_pixel_mode_rgb32, format );
}
else if ( format->depth == 16 )
{
int count2;
XVisualInfo* visuals;
XVisualInfo* visual;
template.depth = format->depth;
visuals = XGetVisualInfo( display,
VisualDepthMask,
&template,
&count2 );
visual = visuals;
while ( count2-- > 0 )
{
#ifdef TEST
const char* string = "unknown";
switch (visual->class)
{
case TrueColor: string = "TrueColor"; break;
case DirectColor: string = "DirectColor"; break;
case PseudoColor: string = "PseudoColor"; break;
case StaticGray : string = "StaticGray"; break;
case StaticColor: string = "StaticColor"; break;
case GrayScale: string = "GrayScale"; break;
}
printf( "> RGB %02x:%02x:%02x, colors %3d, bits %2d %s\n",
visual->red_mask,
visual->green_mask,
visual->blue_mask,
visual->colormap_size,
visual->bits_per_rgb,
string );
#endif
if ( visual->red_mask == 0xf800 &&
visual->green_mask == 0x07e0 &&
visual->blue_mask == 0x001f )
add_pixel_mode( gr_pixel_mode_rgb565, format );
else if ( visual->red_mask == 0x7c00 &&
visual->green_mask == 0x03e0 &&
visual->blue_mask == 0x001f )
add_pixel_mode( gr_pixel_mode_rgb555, format );
/* other 16-bit modes are ignored */
visual++;
}
XFree( visuals );
}
format++;
}
XFree( formats );
}
gr_x11_device.num_pixel_modes = num_pixel_modes;
gr_x11_device.pixel_modes = pixel_modes;
return 0;
}
static
void convert_gray_to_pal8( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
XColor* palette = surface->color;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + w;
for ( ; _write < limit; _write++, _read++ )
*_write = (byte) palette[ *_read ].pixel;
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_16( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 2*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
XColor* palette = surface->color;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 2*w;
for ( ; _write < limit; _write += 2, _read++ )
*(short*)_write = (short)palette[ *_read ].pixel;
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_24( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 3*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 3*w;
for ( ; _write < limit; _write += 3, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_gray_to_32( grXSurface* surface,
int x,
int y,
int w,
int h )
{
grBitmap* target = &surface->image;
grBitmap* source = &surface->root.bitmap;
byte* write = (byte*)target->buffer + y*target->pitch + 4*x;
byte* read = (byte*)source->buffer + y*source->pitch + x;
while (h > 0)
{
byte* _write = write;
byte* _read = read;
byte* limit = _write + 4*w;
for ( ; _write < limit; _write += 4, _read++ )
{
byte color = *_read;
_write[0] =
_write[1] =
_write[2] =
_write[3] = color;
}
write += target->pitch;
read += source->pitch;
h--;
}
}
static
void convert_rectangle( grXSurface* surface,
int x,
int y,
int w,
int h )
{
int z;
/* first of all, clip to the surface's area */
if ( x >= surface->image.width ||
x+w <= 0 ||
y >= surface->image.rows ||
y+h <= 0 )
return;
if ( x < 0 )
{
w += x;
x = 0;
}
z = (x + w) - surface->image.width;
if (z > 0)
w -= z;
z = (y + h) - surface->image.rows;
if (z > 0)
h -= z;
/* convert the rectangle to the target depth for gray surfaces */
if (surface->gray)
{
switch (surface->depth)
{
case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
case 16: convert_gray_to_16 ( surface, x, y, w, h ); break;
case 24: convert_gray_to_24 ( surface, x, y, w, h ); break;
case 32: convert_gray_to_32 ( surface, x, y, w, h ); break;
}
}
}
static
void refresh_rectangle( grXSurface* surface,
int x,
int y,
int w,
int h )
{
if (surface->gray)
convert_rectangle( surface, x, y, w, h );
XPutImage( display,
surface->win,
surface->gc,
surface->ximage,
x, y, x, y, w, h );
}
static
void set_title( grXSurface* surface,
const char* title )
{
XStoreName( display, surface->win, title );
}
static
grKey KeySymTogrKey( KeySym key )
{
grKey k;
int count = sizeof(key_translators)/sizeof(key_translators[0]);
Translator* trans = key_translators;
Translator* limit = trans + count;
k = grKeyNone;
while ( trans < limit )
{
if ( trans->xkey == key )
{
k = trans->grkey;
break;
}
trans++;
}
return k;
}
static
void listen_event( grXSurface* surface,
int event_mask,
grEvent* grevent )
{
static char key_buffer[10];
static int key_cursor = 0;
static int key_number = 0;
static XEvent x_event;
KeySym key;
int bool_exit;
grKey grkey;
XComposeStatus compose;
/* XXXX : For now, ignore the event mask, and only exit when */
/* a key is pressed.. */
(void)event_mask;
bool_exit = key_cursor < key_number;
XDefineCursor( display, surface->win, idle );
while ( !bool_exit )
{
XNextEvent( display, &x_event );
switch ( x_event.type )
{
case KeyPress:
key_number = XLookupString( &x_event.xkey,
key_buffer,
sizeof ( key_buffer ),
&key,
&compose );
key_cursor = 0;
if ( key_number == 0 ||
key > 512 )
{
/* this may be a special key like F1, F2, etc.. */
grkey = KeySymTogrKey(key);
if (grkey != grKeyNone)
goto Set_Key;
}
else
bool_exit = 1;
break;
case MappingNotify:
XRefreshKeyboardMapping( &x_event.xmapping );
break;
case Expose:
refresh_rectangle( surface,
x_event.xexpose.x,
x_event.xexpose.y,
x_event.xexpose.width,
x_event.xexpose.height );
break;
/* You should add more cases to handle mouse events, etc. */
}
}
XDefineCursor( display, surface->win, busy );
XFlush ( display );
/* Now, translate the keypress to a grKey */
/* If this wasn't part of the simple translated keys, simply get the charcode */
/* from the character buffer */
grkey = grKEY(key_buffer[key_cursor++]);
Set_Key:
grevent->type = gr_key_down;
grevent->key = grkey;
}
grXSurface* init_surface( grXSurface* surface,
grBitmap* bitmap )
{
int screen;
grBitmap* image;
char grays;
XDepth* format;
int image_depth;
screen = DefaultScreen( display );
surface->colormap = DefaultColormap( display, screen );
surface->depth = DefaultDepth( display, screen );
surface->visual = DefaultVisual( display, screen );
image = &surface->image;
/* force the surface image depth to 1 if necessary */
/* as this should be supported by all windows */
image_depth = surface->depth;
if (bitmap->mode == gr_pixel_mode_mono)
image_depth = 1;
grays = ( bitmap->mode == gr_pixel_mode_gray &&
bitmap->grays >= 2 );
surface->gray = grays;
/* copy dimensions */
image->width = bitmap->width;
image->rows = bitmap->rows;
image->mode = bitmap->mode;
image->pitch = 0;
image->grays = 0;
image->buffer = 0;
/* find the supported format corresponding to the request */
format = 0;
if (grays)
{
/* choose the default depth in case of grays rendering */
int i;
for ( i = 0; i < num_pixel_modes; i++ )
if ( image_depth == pixel_depth[i].depth )
{
format = pixel_depth + i;
break;
}
}
else
{
/* otherwise, select the format depending on the pixel mode */
int i;
format = 0;
for ( i = 0; i < num_pixel_modes; i++ )
if ( pixel_modes[i] == bitmap->mode )
{
format = pixel_depth + i;
break;
}
}
if (!format)
{
grError = gr_err_bad_argument;
return 0;
}
/* correct surface.depth. This is required because in the case */
/* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
if ( format->depth == 24 &&
format->bits_per_pixel == 32 )
image_depth = 32;
/* allocate surface image */
{
int bits, over;
bits = image->width * format->bits_per_pixel;
over = bits % format->scanline_pad;
if (over)
bits += format->scanline_pad - over;
if (!grays)
{
image->width = bits;
bitmap->width = bits;
}
image->pitch = bits >> 3;
}
image->buffer = grAlloc( image->pitch * image->rows );
if (!image->buffer) return 0;
/* now, allocate a gray pal8 pixmap, only when we asked */
/* for an 8-bit pixmap */
if ( grays )
{
/* pad pitch to 32 bits */
bitmap->pitch = (bitmap->width + 3) & -4;
bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
if (!bitmap->buffer)
Panic( "grX11: could not allocate surface bitmap!\n" );
}
else /* otherwise */
{
*bitmap = *image;
}
surface->root.bitmap = *bitmap;
/* Now create the surface X11 image */
surface->ximage = XCreateImage( display,
surface->visual,
format->depth,
format->depth == 1 ? XYBitmap : ZPixmap,
0,
(char*)image->buffer,
image->width,
image->rows,
8,
0 );
if ( !surface->ximage )
Panic( "grX11: cannot create surface X11 image\n" );
/* allocate gray levels in the case of gray surface */
if ( grays )
{
XColor* color = surface->color;
int i;
for ( i = 0; i < bitmap->grays; i++, color++ )
{
color->red =
color->green =
color->blue = 65535 - ( i * 65535 ) / bitmap->grays;
if ( !XAllocColor( display, surface->colormap, color ) )
Panic( "ERROR: cannot allocate Color\n" );
}
}
else if ( image_depth == 1 )
{
surface->ximage->byte_order = MSBFirst;
surface->ximage->bitmap_bit_order = MSBFirst;
}
{
XTextProperty xtp;
XSizeHints xsh;
XSetWindowAttributes xswa;
xswa.border_pixel = BlackPixel( display, screen );
xswa.background_pixel = WhitePixel( display, screen );
xswa.cursor = busy;
xswa.event_mask = KeyPressMask | ExposureMask;
surface->win = XCreateWindow( display,
RootWindow( display, screen ),
0,
0,
image->width,
image->rows,
10,
surface->depth,
InputOutput,
surface->visual,
CWBackPixel | CWBorderPixel |
CWEventMask | CWCursor,
&xswa );
XMapWindow( display, surface->win );
surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
XSetForeground( display, surface->gc, xswa.border_pixel );
XSetBackground( display, surface->gc, xswa.background_pixel );
/* make window manager happy :-) */
xtp.value = (unsigned char*)"FreeType";
xtp.encoding = 31;
xtp.format = 8;
xtp.nitems = strlen( (char*)xtp.value );
xsh.x = 0;
xsh.y = 0;
xsh.width = image->width;
xsh.height = image->rows;
xsh.flags = (PPosition | PSize);
xsh.flags = 0;
XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
}
surface->root.done = (grDoneSurfaceFunc) done_surface;
surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
surface->root.set_title = (grSetTitleFunc) set_title;
surface->root.listen_event = (grListenEventFunc) listen_event;
convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
return surface;
}
grDevice gr_x11_device =
{
sizeof( grXSurface ),
"x11",
init_device,
done_device,
(grDeviceInitSurfaceFunc) init_surface,
0,
0
};
#ifdef TEST
typedef struct grKeyName
{
grKey key;
const char* name;
} grKeyName;
static
const grKeyName key_names[] =
{
{ grKeyF1, "F1" },
{ grKeyF2, "F2" },
{ grKeyF3, "F3" },
{ grKeyF4, "F4" },
{ grKeyF5, "F5" },
{ grKeyF6, "F6" },
{ grKeyF7, "F7" },
{ grKeyF8, "F8" },
{ grKeyF9, "F9" },
{ grKeyF10, "F10" },
{ grKeyF11, "F11" },
{ grKeyF12, "F12" },
{ grKeyEsc, "Esc" },
{ grKeyHome, "Home" },
{ grKeyEnd, "End" },
{ grKeyPageUp, "Page_Up" },
{ grKeyPageDown, "Page_Down" },
{ grKeyLeft, "Left" },
{ grKeyRight, "Right" },
{ grKeyUp, "Up" },
{ grKeyDown, "Down" },
{ grKeyBackSpace, "BackSpace" },
{ grKeyReturn, "Return" }
};
int main( void )
{
grSurface* surface;
int n;
grInit();
surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
if (!surface)
Panic("Could not create window\n" );
else
{
grColor color;
grEvent event;
const char* string;
int x;
grSetSurfaceRefresh( surface, 1 );
grSetTitle(surface,"X11 driver demonstration" );
for ( x = -10; x < 10; x++ )
{
for ( n = 0; n < 128; n++ )
{
color.value = (n*3) & 127;
grWriteCellChar( surface,
x + ((n % 60) << 3),
80 + (x+10)*8*3 + ((n/60) << 3), n, color );
}
}
color.value = 64;
grWriteCellString( surface, 0, 0, "just an example", color );
do
{
listen_event((grXSurface*)surface, 0, &event);
/* return if ESC was pressed */
if ( event.key == grKeyEsc )
return 0;
/* otherwise, display key string */
color.value = (color.value + 8) & 127;
{
int count = sizeof(key_names)/sizeof(key_names[0]);
grKeyName* name = key_names;
grKeyName* limit = name + count;
const char* kname = 0;
char kname_temp[16];
while (name < limit)
{
if ( name->key == event.key )
{
kname = name->name;
break;
}
name++;
}
if (!kname)
{
sprintf( kname_temp, "char '%c'", (char)event.key );
kname = kname_temp;
}
grWriteCellString( surface, 30, 30, kname, color );
grRefreshSurface(surface);
paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
}
} while (1);
}
return 0;
}
#endif /* TEST */

24
demos/graph/grx11.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef GRX11_H
#define GRX11_H
#include "grobjs.h"
#include "grdevice.h"
extern
grDevice gr_x11_device;
#ifdef GR_INIT_BUILD
static
grDeviceChain gr_x11_device_chain =
{
"x11",
&gr_x11_device,
GR_INIT_DEVICE_CHAIN
};
#undef GR_INIT_DEVICE_CHAIN
#define GR_INIT_DEVICE_CHAIN &gr_x11_device_chain
#endif /* GR_INIT_BUILD */
#endif /* GRX11_H */

304
demos/graph/migs.html Normal file
View File

@ -0,0 +1,304 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.6 [en] (X11; I; Linux 2.2.9-19mdk i586) [Netscape]">
</head>
<body>
<center><font size=+2>MiGS Overview</font>
<br><font size=+2>A Minimalist Graphics Subsystem</font>
<p>
<hr WIDTH="100%"></center>
<h1>
<font size=+0>Introduction</font></h1>
<blockquote>This document details the design and implementation of MiGS,
the minimalist graphics subsystem used by the FreeType 2 demonstration
programs. Its purpose is mainly to help writers of new demo programs, as
well as developers who would like port the subsystem to other platforms.</blockquote>
<hr WIDTH="100%">
<h1>
I - Design goals</h1>
<blockquote>MiGS is a tiny graphics subsystem used to demo text rendering
through the FreeType library. It was mainly written to provide the abilities
to :</blockquote>
<ul>
<ul>
<li>
draw a monochrome glyph bitmap to many kinds of target surfaces (i.e. really
bitmaps/pixmaps)</li>
<li>
draw an anti-aliased glyph bitmap, with any level of grays, to many kinds
of target surfaces</li>
<li>
display a simple window on many systems like X11, OS/2 and Windows</li>
<li>
accept simple events (keypresses and mouse buttons) in this window.</li>
<li>
to be portable and present a unified API on all running systems</li>
</ul>
<p><br>MiGS uses system-specific "drivers" in order to perform display
and event handling. The blitting functions are not device-specific. MiGS
can be built and/or used with no system-specific features, like for example,
to generate simple GIF, PNG, TIFF, etc.. images without ever needing to
display them.</ul>
<h1>
<hr WIDTH="100%"></h1>
<h1>
II - Surfaces, bitmaps and windows</h1>
<blockquote>A surface in MiGS models a drawable region where glyph images
can be rendered, a surface always contains a bitmap descriptor as well
as a few other things that will be described later in this section.
<p>Some surfaces can be displayed, they are then either called <i>windowed
surfaces</i> or <i>screen surfaces</i> depending on the nature of the <i>device</i>
used to display them. Each <i>device</i> is implemented by a very simple
<i>driver</i> in the MiGS code. Here are a few example devices that are
or could be written to display surfaces :
<p>- an X11 device
<br>- a Win 32 GDI device
<br>- an OS/2 Presentation Manager device
<br>- a fullscreen SVGALib device on Linux
<br>- a GGI visual device
<br>- an OS/2 "Dive" device, or the equivalent Win32 "DirectX" device
<p>etc..
<p><b>NOTE: </b>For now, only the X11 device was written and tested.. More
devices should come later
<p>Before explaining how to create a surface, we need to explain how MiGS
manages bitmaps and renders glyph images to them.
<h3>
1. Bitmaps :</h3>
<blockquote>A bitmap in MiGS features the following things :
<ul>
<li>
a <b><i>width</i></b> in pixels</li>
<li>
a <b><i>height</i></b> in pixels</li>
<li>
a <b><i>pixel mode</i></b>, which indicates how the pixels are stored in
the surface's buffer</li>
<li>
a <b><i>pitch</i></b>, whose absolute values is the number of bytes taken
by each surface row</li>
<li>
a <b><i>number</i></b> of valid <b><i>gray</i></b> levels (see below)</li>
<li>
a <b><i>buffer</i></b>, holding the surface's pixels</li>
</ul>
<p><br>MiGS uses the <i>"Y downwards"</i> convention, which means that
<i>increasing
Y</i> coordinates correspond to <i>lower rows</i> of the bitmap. Hence,
the coordinate <i>(0,0)</i> always corresponds to the bitmap's
<i>top-left
pixel</i>.
<p>The bitmap's rows can be stored either <i>"downwards"</i> or <i>"upwards"</i>
in the pixel buffer.
<p>In the first case (<i>downwards</i>), increasing memory addresses in
the pixel buffer correspond to lower rows of the bitmap(e.g. PC video modes),
and the <b><i>pitch</i></b> should be equal to <b><i>the number of bytes
taken by each row</i></b>. The first pixel buffer byte corresponds to the
upper row.
<p>In the second case (<i>upwards</i>), increasing memory addresses in
the pixel buffer correspond to upper rows of the bitmap and the <b><i>pitch</i></b>
should be equal to the <b><i>opposite</i></b> of <i>the number of bytes
taken by each row</i>. The first pixel buffer byte corresponds to the lower
row.
<p>In all cases, the <b><i>pitch</i></b> is the <i>increment to be used
to go from one bitmap row to the one below it</i>.
<p>The supported pixel modes are :
<ul>
<li>
1-bit monochrome bitmaps. With "0" as the background, and "1" as the foreground.</li>
<li>
4-bit color bitmaps, using an arbitrary palette.</li>
<li>
8-bit color bitmaps, using an arbitrary palette.</li>
<li>
8-bit gray bitmaps, using a given N number of gray levels in the range
0..N-1.</li>
<li>
15-bit color bitmaps, also known as RGB555</li>
<li>
16-bit color bitmaps, also known as RGB565</li>
<li>
24-bit color bitmaps, also known as RGB</li>
<li>
32-bit color bitmaps, also known as RGBA (though the A is ignored by MiGS)</li>
</ul>
The bitmap's <b><i>number of gray levels</i></b> is only relevant for <b><i>8-bit
gray bitmaps</i></b>, and indicates the range of gray levels that can be
found in the bitmap. If a bitmap as N gray levels, it is said to be <i>N-grayscales</i>,
and the pixels within it must all have values between 0, considered as
the <i>background</i> color, and N-1, considered as the <i>foreground</i>
color.
<p>N-grayscale bitmaps are crucial for the rendering of anti-aliased text.
<br>&nbsp;</blockquote>
<h3>
2. Glyph images :</h3>
<blockquote>The glyph images that can be drawn on bitmaps through MiGS
are bitmaps themselves, though limited to the following pixel modes :
<p><b>1-bit monochrome glyph bitmaps</b>
<blockquote>These can be drawn on any kind of bitmap. Note that <i>only
the "lit" pixels</i> (i.e. the bits set to 1) are effectively drawn to
the target, as opaque blitting isn't supported (remember, it's a minimalist
library !)</blockquote>
<p><br><b>N-grayscales glyph images </b>(with any value of N >= 2)
<blockquote>These can be drawn to <i>all RGB bitmaps</i> (15, 16, 24 &amp;
32 bits/pixel), as well as any other M-grayscales bitmaps. In the latter
case, the values of N and M <i>need not be equal</i>, as the library is
able to perform automatic conversions <i>on the fly</i>.
<p>For example, it is possible to render a 5-grayscales glyph image into
a 128-grayscales bitmap. Moreover, it is also possible to render a 17-grayscales
glyph image into a 5-grayscales bitmap, even if this will result in <i>a
loss of quality</i>. This feature is crucial in order to experiment easily
with other anti-aliasing algorithms for FreeType
<br>&nbsp;</blockquote>
Note that you can <i>only</i> draw <i>monochrome</i> bitmaps to the following
pixel modes : monochrome, 4-bit color and 8-bit color.</blockquote>
<h3>
3. Windows and Screens:</h3>
<blockquote>In order to debug FreeType, displaying a surface in a window
or in full-screen mode, is required. MiGS thus makes a difference between
<i>simple
surfaces</i>, which only contain a bitmap, <i>windowed surfaces</i>, which
are used to display their content in a window, and <i>screen surfaces</i>,
which are used to display their content in a full-screen mode (SVGAlib,
DirectX, GGI or wathever).
<p>A few important things must be said about non-simple surfaces.
<br>&nbsp;
<ul>
<li>
First, they might contain some system-specific data which is used to manage
the display in a window or on the screen. This must be <i>completely hidden</i>
to MiGS clients. Indeed, rendering to any kind of surface is achieved through
<i>exactly
the same function calls</i>.</li>
</ul>
<ul>
<li>
Second, they may contain a bitmap whose pixel mode doesn't correspond to
the screen's depth used to display it. For example, the surface might contain
an 128-grayscale bitmap, while the screen is in RGB24 mode. Some conversion
must be performed to display the surface. This can either happen in the
system-specific graphics library (e.g. on OS/2, a single Presentation Manager
call is used to blit a N-grayscale image to <i>any</i> kind of window)
or in the system-specific part of MiGS (e.g. the X11 MiGS driver must convert
the surface's bitmap into the appropriate <i>X11 image</i> each time a
repaint is requested). Again this must be completely hidden to MiGS clients</li>
</ul>
Surfaces have also a few fields that are only used when displaying them
in Windows :
<p><b>a title string</b>
<blockquote>This is simply a text string that is displayed on the title
bar of the surface's window. It can also appear at the top or bottom of
full-screen surfaces if the MiGS driver supports it. The title string can
be changed with a call to <tt>grSetTitle</tt>, and is ignored for simple
surfaces.</blockquote>
<p><br><b>a refresh flag</b>
<blockquote>This boolean flag is only used for window surfaces, and some
fullscreen ones (depending on the driver implementation). When set, it
indicates that each glyph image blit must be displayed immediately. By
default, this flag is set to False, which means that demo programs must
call the <tt>grRefreshSurface(surface)</tt> function to display the whole
contents of a surface one it has been updated.
<p>The refresh flag can be set with <tt>grSetSurfaceRefresh(surface,flag)</tt>.
Note that a single surface rectangle can be forced to be displayed with
a call to <tt>grRefreshRectangle(surface,x,y,w,h)</tt> at any time.</blockquote>
</blockquote>
<h3>
4. Devices :</h3>
<blockquote>As said before, each device is in charge of displaying a surface
in a given window or screen. Each device is managed through a very simple
driver, described to MiGS through a very simple "grDevice" structure.
<p>A grDevice contains, among other things, pointers to the functions used
to:
<p>- refresh/display a given rectangle of the surface to the window/screen
<br>- listen events (key presses and mouse) and send them back to client
apps.
<br>- for windowed devices, update the title bar.
<p>As said before, this is a highly minimalist system..
<br>&nbsp;</blockquote>
</blockquote>
<hr WIDTH="100%">
<h1>
III - Important implementation issues :</h1>
<blockquote>
<h3>
1. Display surface negociation :</h3>
<blockquote>A display surface is created with the function grNewScreenSurface
which takes parameters indicating which device should be used, the pixel
dimensions of the requested surface, as well as its pixel mode.
<p>Because of some device-specific limitations, the resulting surface's
properties might not match exactly those requested for the call. Hence,
a developper should <b>always take care </b>of reading a new display surface's
<b>bitmap</b> descriptor in order to get its <i>real</i> dimensions, pixel
mode and eventually number of grays.
<p>The function grNewSurface will create a memory surface with the corresponding
bitmap.
<br>The function grNewBitmapSurface will create a surface from a pre-existing
bitmap.&nbsp;This is useful to draw text on loaded images, for example.
<p>Any surface (display or not) is destroyed with grDoneSurface.</blockquote>
<h3>
</h3>
<h3>
2. Supporting 8-bit grayscale mode :</h3>
<blockquote>It is important, for the debugging of FreeType anti-aliased
renderer(s), that <b><i>_all_ devices should support the 8-bit gray mode</i></b>.
The number of gray levels can be fixed or negociated as required by implementation-specific
issues.
<p>As most existing devices do not provide direct support for such a mode,
each 8-bit surface must thus contain :
<p>- an internal N-grayscale bitmap, used as the target of all glyph drawings
<br>- its own device-specific "image", which matches the display depth.
<p>Each time the device's "refresh_rect" function is called, it should
then :
<br>- convert the grayscales within the bitmap's rectangle into the image's
buffer and format.
<br>- display the corresponding image rectangle.
<p>This scheme is used, for example, by the X11 device.</blockquote>
</blockquote>
</body>
</html>

99
demos/graph/rules.mk Normal file
View File

@ -0,0 +1,99 @@
#**************************************************************************
#*
#* FreeType demo utilities sub-Makefile
#*
#* This Makefile is to be included by "freetype/demo/Makefile". Its
#* purpose is to compile MiGS (the Minimalist Graphics Subsystem)
#*
#* It is written for GNU Make. Other make utilities are not
#* supported.. !!
#*
#*
#* The following variables must be defined :
#*
#* CFLAGS : C flags to use when compiling the utilities. This
#* must NOT include the '-c' flag used to specify a
#* simple compilation.
#*
#* IFLAG : include path flag. This is typically "-I" but some
#* compilers use a different convention..
#*
#* LFLAG : add link directory flag. Usually '-L' but could be
#* different..
#*
#* OBJ_DIR : target location of the object files
#*
#* UTIL_DIR : location of the utilities sources. I.e. this
#* directory (usually "freetype/demo/graph").
#*
#*
#* It also defines the following variables
#*
#* SIMPLE_UTILS : list of object files for the non-graphical utilities
#*
#* GRAPH_UTILS : all object files, including the graphics sub-system
#*
#* GRAPH_FLAGS : additional compile flags for graphical apps
#* GRAPH_LINK : additional link flags for graphical apps
#*
#**************************************************************************
##########################################################################
#
#
#
#
#
GRAPH_INCLUDES := graph
GRAPH_LIB := $(OBJ_)graph.a
GRAPH_LINK := $(GRAPH_LIB)
GRAPH_ := graph$(SEP)
GRAPH_H := $(GRAPH_)graph.h \
$(GRAPH_)grtypes.h \
$(GRAPH_)grobjs.h \
$(GRAPH_)grdevice.h \
$(GRAPH_)grblit.h
GRAPH_OBJS := $(OBJ_)grblit.$O \
$(OBJ_)grobjs.$O \
$(OBJ_)grfont.$O \
$(OBJ_)grdevice.$O \
$(OBJ_)grinit.$O
# Add the rules used to detect and compile graphics driver depending
# on the current platform..
#
include $(wildcard config/*/rules.mk)
#########################################################################
#
# Build the "graph" library from its objects. This should be changed
# in the future in order to support more systems. Probably something
# like a `config/<system>' hierarchy with a system-specific rules file
# to indicate how to make a library file, but for know, I'll stick to
# unix and OS/2-gcc..
#
#
$(GRAPH_LIB): $(GRAPH_OBJS)
ar -r $@ $(GRAPH_OBJS)
# pattern rule for normal sources
#
$(OBJ_)%.$O: $(GRAPH_)%.c $(GRAPH_H)
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
# a special rule is used for 'grinit.o' as it needs the definition
# of some macros like "-DDEVICE_X11" or "-DDEVICE_OS2_PM"
#
$(OBJ_)grinit.$O: $(GRAPH_)grinit.c
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(DEVICE_INCLUDES:%=$I%) $T$@ $< \
$(DEVICES:%=$DDEVICE_%)

125
demos/graph/xtest.c Normal file
View File

@ -0,0 +1,125 @@
#include "graph.h"
#include "grfont.h" /* dispara^itra bientot */
#include <stdio.h>
static
void Panic( const char* message )
{
fprintf( stderr, "PANIC: %s\n", message );
exit(1);
}
typedef struct grKeyName
{
grKey key;
const char* name;
} grKeyName;
static
const grKeyName key_names[] =
{
{ grKeyF1, "F1" },
{ grKeyF2, "F2" },
{ grKeyF3, "F3" },
{ grKeyF4, "F4" },
{ grKeyF5, "F5" },
{ grKeyF6, "F6" },
{ grKeyF7, "F7" },
{ grKeyF8, "F8" },
{ grKeyF9, "F9" },
{ grKeyF10, "F10" },
{ grKeyF11, "F11" },
{ grKeyF12, "F12" },
{ grKeyEsc, "Esc" },
{ grKeyHome, "Home" },
{ grKeyEnd, "End" },
{ grKeyPageUp, "Page_Up" },
{ grKeyPageDown, "Page_Down" },
{ grKeyLeft, "Left" },
{ grKeyRight, "Right" },
{ grKeyUp, "Up" },
{ grKeyDown, "Down" },
{ grKeyBackSpace, "BackSpace" },
{ grKeyReturn, "Return" }
};
int main( void )
{
grSurface* surface;
int n;
grInit();
surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
if (!surface)
Panic("Could not create window\n" );
else
{
grColor color;
grEvent event;
const char* string;
int x;
grSetSurfaceRefresh( surface, 1 );
grSetTitle(surface,"X11 driver demonstration" );
for ( x = -10; x < 10; x++ )
{
for ( n = 0; n < 128; n++ )
{
color.value = (n*3) & 127;
grWriteCellChar( surface,
x + ((n % 60) << 3),
80 + (x+10)*8*3 + ((n/60) << 3), n, color );
}
}
color.value = 64;
grWriteCellString( surface, 0, 0, "just an example", color );
do
{
grListenSurface( surface, 0, &event);
/* return if ESC was pressed */
if ( event.key == grKeyEsc )
return 0;
/* otherwise, display key string */
color.value = (color.value + 8) & 127;
{
int count = sizeof(key_names)/sizeof(key_names[0]);
grKeyName* name = (grKeyName*)key_names;
grKeyName* limit = name + count;
const char* kname = 0;
char kname_temp[16];
while (name < limit)
{
if ( name->key == event.key )
{
kname = (const char*)name->name;
break;
}
name++;
}
if (!kname)
{
sprintf( kname_temp, "char '%c'", (char)event.key );
kname = kname_temp;
}
grWriteCellString( surface, 30, 30, kname, color );
grRefreshSurface(surface);
}
} while (1);
}
return 0;
}

1
demos/obj/README Normal file
View File

@ -0,0 +1 @@
This directory contains all the object files generated for the demonstration programs

244
demos/src/common.c Normal file
View File

@ -0,0 +1,244 @@
/*
* This is a cheap replacement for getopt() because that routine is not
* available on some platforms and behaves differently on other platforms.
* This code was written from scratch without looking at any other
* implementation.
*
* This code is hereby expressly placed in the public domain.
* mleisher@crl.nmsu.edu (Mark Leisher)
* 10 October 1997
*/
#ifndef lint
#ifdef __GNUC__
static char rcsid[] __attribute__ ((unused)) = "$Id$";
#else
static char rcsid[] = "$Id$";
#endif
#endif
#include "common.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
/*
* Externals visible to programs.
*/
int opterr = 1;
int optind = 1;
char* optarg;
/*
* Internal variables that are used to detect when the global values
* need to be reset.
*/
static int cmdac;
#ifdef __STDC__
static const char* cmdname;
static char* const* cmdav;
#else
static char* cmdname;
static char** cmdav;
#endif
int
#ifdef __STDC__
getopt( int ac, char* const* av, const char* pat )
#else
getopt( ac, av, pat )
int ac;
char** av;
char* pat;
#endif
{
int opt;
#ifdef __STDC__
const char* p;
const char* pp;
#else
char* p;
char* pp;
#endif
/*
* If there is no pattern, indicate the parsing is done.
*/
if ( pat == 0 || *pat == 0 )
return -1;
/*
* Always reset the option argument to NULL.
*/
optarg = 0;
/*
* If the number of arguments or argument list do not match the last
* values seen, reset the internal pointers and the globals.
*/
if ( ac != cmdac || av != cmdav )
{
optind = 1;
cmdac = ac;
cmdav = av;
/*
* Determine the command name in case it is needed for warning
* messages.
*/
for ( cmdname = 0, p = av[0]; *p; p++ )
{
if ( *p == '/' || *p == '\\' )
cmdname = p;
}
/*
* Skip the path separator if the name was assigned.
*/
if ( cmdname )
cmdname++;
else
cmdname = av[0];
}
/*
* If the next index is greater than or equal to the number of
* arguments, then the command line is done.
*/
if ( optind >= ac )
return -1;
/*
* Test the next argument for one of three cases:
* 1. The next argument does not have an initial '-'.
* 2. The next argument is '-'.
* 3. The next argument is '--'.
*
* In either of these cases, command line processing is done.
*/
if ( av[optind][0] != '-' ||
strcmp( av[optind], "-" ) == 0 ||
strcmp( av[optind], "--" ) == 0 )
return -1;
/*
* Point at the next command line argument and increment the
* command line index.
*/
p = av[optind++];
/*
* Look for the first character of the command line option.
*/
for ( opt = *(p + 1), pp = pat; *pp && *pp != opt; pp++ )
;
/*
* If nothing in the pattern was recognized, then issue a warning
* and return a '?'.
*/
if ( *pp == 0 )
{
if ( opterr )
fprintf( stderr, "%s: illegal option -- %c\n", cmdname, opt );
return '?';
}
/*
* If the option expects an argument, get it.
*/
if ( *(pp + 1) == ':' && (optarg = av[optind]) == 0 )
{
/*
* If the option argument is NULL, issue a warning and return a '?'.
*/
if ( opterr )
fprintf( stderr, "%s: option requires an argument -- %c\n",
cmdname, opt );
opt = '?';
}
else if ( optarg )
/*
* Increment the option index past the argument.
*/
optind++;
/*
* Return the option character.
*/
return opt;
}
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1998 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* ft_basename(): */
/* */
/* a stupid but useful function... */
/* */
/* rewritten by DavidT to get rid of GPLed programs in the FreeType demos. */
/* */
/****************************************************************************/
char*
#ifdef __STDC__
ft_basename ( const char* name )
#else
ft_basename ( name )
char* name;
#endif
{
#ifdef __STDC__
const char* base;
const char* current;
#else
char* base;
char* current;
#endif
char c;
base = name;
current = name;
c = *current;
while ( c )
{
if ( c == '/' || c == '\\' )
base = current + 1;
current++;
c = *current;
}
return (char*)base;
}
#ifdef __STDC__
void Panic( const char* fmt, ... )
#else
void Panic( fmt )
const char* fmt;
#endif
{
va_list ap;
va_start( ap, fmt );
vprintf( fmt, ap );
va_end( ap );
exit( 1 );
}
/* End */

53
demos/src/common.h Normal file
View File

@ -0,0 +1,53 @@
/*
* This is a cheap replacement for getopt() because that routine is not
* available on some platforms and behaves differently on other platforms.
*
* This code is hereby expressly placed in the public domain.
* mleisher@crl.nmsu.edu (Mark Leisher)
* 10 October 1997
*/
#ifndef _H_COMMON
#define _H_COMMON
/* Note that by default, both functions are implemented in common.c */
#ifdef __cplusplus
extern "C" {
#endif
extern int opterr;
extern int optind;
extern char* optarg;
extern int getopt(
#ifdef __STDC__
int argc,
char* const* argv,
const char* pattern
#endif
);
extern char* ft_basename(
#ifdef __STDC__
const char* name
#endif
);
/* print a message and exit */
extern void Panic (
#ifdef __STDC__
const char* fmt, ...
#endif
);
#ifdef __cplusplus
}
#endif
#endif /* _H_COMMON */
/* End */

169
demos/src/ftlint.c Normal file
View File

@ -0,0 +1,169 @@
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1998 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* ftlint: a simple font tester. This program tries to load all the */
/* glyphs of a given font. */
/* */
/* NOTE: This is just a test program that is used to show off and */
/* debug the current engine. */
/* */
/****************************************************************************/
#include "freetype.h"
#include "ftobjs.h"
#include "ftdriver.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define gettext( x ) ( x )
FT_Error error;
FT_Library library;
FT_Face face;
FT_Size size;
FT_GlyphSlot slot;
unsigned int num_glyphs;
int ptsize;
int Fail;
int Num;
static void Usage( char* name )
{
printf( "ftlint: simple font tester -- part of the FreeType project\n" );
printf( "----------------------------------------------------------\n" );
printf( "\n" );
printf( "Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n", name );
printf( "\n" );
exit( 1 );
}
static void Panic( const char* message )
{
fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
exit(1);
}
int main( int argc, char** argv )
{
int i, file_index;
unsigned int id;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
char* fname;
execname = argv[0];
if ( argc < 3 )
Usage( execname );
if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
Usage( execname );
error = FT_Init_FreeType( &library );
if (error) Panic( "Could not create library object" );
/* Now check all files */
for ( file_index = 2; file_index < argc; file_index++ )
{
fname = argv[file_index];
i = strlen( fname );
while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
{
if ( fname[i] == '.' )
i = 0;
i--;
}
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, fname, 128 );
strncpy( alt_filename, fname, 128 );
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
i = strlen( filename );
fname = filename;
while ( i >= 0 )
if ( filename[i] == '/' || filename[i] == '\\' )
{
fname = filename + i + 1;
i = -1;
}
else
i--;
printf( "%s: ", fname );
/* Load face */
error = FT_New_Face( library, filename, 0, &face );
if (error)
{
if (error == FT_Err_Invalid_File_Format)
printf( "unknow format\n" );
else
printf( "could not find/open file\n" );
continue;
}
if (error) Panic( "Could not open file" );
num_glyphs = face->num_glyphs;
error = FT_Set_Char_Size( face, ptsize << 6, ptsize << 6, 72, 72 );
if (error) Panic( "Could not set character size" );
Fail = 0;
{
for ( id = 0; id < num_glyphs; id++ )
{
error = FT_Load_Glyph( face, id, FT_LOAD_DEFAULT );
if (error)
{
if ( Fail < 10 )
printf( "glyph %4u: 0x%04x\n" , id, error );
Fail++;
}
}
}
if ( Fail == 0 )
printf( "OK.\n" );
else
if ( Fail == 1 )
printf( "1 fail.\n" );
else
printf( "%d fails.\n", Fail );
FT_Done_Face( face );
}
FT_Done_FreeType(library);
exit( 0 ); /* for safety reasons */
return 0; /* never reached */
}
/* End */

313
demos/src/ftsbit.c Normal file
View File

@ -0,0 +1,313 @@
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1998 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* ftsbit: a _very_ simple embedded bitmap dumper for FreeType 1.x. */
/* */
/* NOTE: This is just a test program that is used to show off and */
/* debug the current engine. */
/* */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freetype.h"
#ifdef HAVE_LIBINTL_H
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include <libintl.h>
#include "ftxerr18.h"
#else /* !HAVE_LIBINTL */
#define gettext( x ) ( x )
/* We ignore error message strings with this function */
static char* TT_ErrToString18( FT_Error error )
{
static char temp[32];
sprintf( temp, "0x%04lx", error );
return temp;
}
#endif /* !HAVE_LIBINTL */
FT_Error error;
FT_Library engine;
FT_Resource resource;
FT_Face face;
FT_Size instance;
FT_GlyphSlot glyph;
unsigned int num_glyphs;
int ptsize;
int Fail;
int Num;
static void Usage( char* name )
{
printf( gettext( "ftsbit: simple TrueType 'sbit' dumper -- part of the FreeType project\n" ) );
printf( "---------------------------------------------------------------------\n" );
printf( "\n" );
printf( gettext( "Usage: %s ppem fontname (index)* (index1-index2)*\n\n" ), name );
printf( gettext( " or %s -a ppem fontname (dumps all glyphs)\n" ), name );
printf( "\n" );
exit( EXIT_FAILURE );
}
static
void dump_bitmap( FT_GlyphSlot glyph, int glyph_index )
{
/* Dump the resulting bitmap */
{
int y;
unsigned char* line = (unsigned char*)glyph->bitmap.buffer;
printf( "glyph index %d = %dx%d pixels, ",
glyph_index, glyph->bitmap.rows, glyph->bitmap.width );
printf( "advance = %d, minBearing = [%d,%d]\n",
glyph->metrics.horiAdvance >> 6,
glyph->metrics.horiBearingX >> 6,
glyph->metrics.horiBearingY >> 6 );
for ( y = 0; y < glyph->bitmap.rows; y++, line += glyph->bitmap.cols )
{
unsigned char* ptr = line;
int x;
unsigned char mask = 0x80;
for ( x = 0; x < glyph->bitmap.width; x++ )
{
printf( "%c", (ptr[0] & mask) ? '*' : '.' );
mask >>= 1;
if (mask == 0)
{
mask = 0x80;
ptr++;
}
}
printf( "\n" );
}
}
}
static
void dump_range( FT_GlyphSlot glyph,
int first_glyph,
int last_glyph )
{
int i;
for ( i = first_glyph; i <= last_glyph; i++ )
{
error = FT_Load_Glyph( glyph,
instance,
(unsigned short)i,
FT_LOAD_NO_OUTLINE,
0 );
if (error)
{
printf( " no bitmap for glyph %d\n", i );
printf( gettext( "FreeType error message: %s\n" ),
TT_ErrToString18( error ) );
continue;
}
dump_bitmap(glyph,i);
}
}
int main( int argc, char** argv )
{
int i;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
char* fname;
int dump_all = 0;
#ifdef HAVE_LIBINTL_H
setlocale( LC_ALL, "" );
bindtextdomain( "freetype", LOCALEDIR );
textdomain( "freetype" );
#endif
execname = argv[0];
if ( argc < 3 )
Usage( execname );
if ( argv[1][0] == '-' &&
argv[1][1] == 'a' )
{
argv++;
argc--;
dump_all = 1;
}
if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
Usage( execname );
/* Initialize engine */
if ( (error = FT_Init_FreeType( &engine )) )
{
fprintf( stderr, gettext( "Error while initializing engine\n" ) );
goto Failure;
}
/* Now check all files */
fname = argv[2];
i = strlen( fname );
while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
{
if ( fname[i] == '.' )
i = 0;
i--;
}
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, fname, 128 );
strncpy( alt_filename, fname, 128 );
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
/* Load face */
error = FT_New_Resource( engine, filename, &resource );
if (error)
{
strcpy( filename, alt_filename );
error = FT_New_Resource( engine, alt_filename, &resource );
}
i = strlen( filename );
fname = filename;
while ( i >= 0 )
if ( filename[i] == '/' || filename[i] == '\\' )
{
fname = filename + i + 1;
i = -1;
}
else
i--;
if ( error )
{
printf( gettext( "Could not find or open file.\n" ) );
goto Failure;
}
error = FT_New_Face( resource, 0, &face );
if (error)
{
printf( gettext( "Could not create face object.\n " ) );
goto Failure;
}
/* get face properties */
num_glyphs = face->num_glyphs;
/* create instance */
error = FT_New_Size( face, &instance );
if ( error )
{
printf( gettext( "Could not create instance.\n" ) );
goto Failure;
}
error = FT_Set_Pixel_Sizes( instance, ptsize, ptsize );
if (error)
{
printf( gettext( "Could not set character size.\n" ) );
goto Failure;
}
glyph = face->slot;
if (dump_all)
dump_range( glyph, 0, num_glyphs-1 );
else
{
for ( i = 3; i < argc; i++ )
{
/* check for range in argument string */
int range_check = 0;
char* base = argv[i];
char* cur = base;
int first, last;
while (*cur)
{
if (*cur == '-')
{
range_check = 1;
break;
}
cur++;
}
if (range_check)
{
if ( sscanf( argv[i], "%d-%d", &first, &last ) != 2 )
Usage( execname );
dump_range( glyph, first, last );
}
else
{
if ( sscanf( argv[i], "%d", &first ) != 1 )
Usage( execname );
dump_range( glyph, first, first );
}
}
}
FT_Done_FreeType( engine );
exit( EXIT_SUCCESS ); /* for safety reasons */
return 0; /* never reached */
Failure:
printf( gettext( "FreeType error message: %s\n" ),
TT_ErrToString18( error ) );
exit( EXIT_FAILURE );
}
/* End */

460
demos/src/fttimer.c Normal file
View File

@ -0,0 +1,460 @@
/****************************************************************************/
/* */
/* The FreeType project - a Free and Portable Quality TrueType Renderer. */
/* */
/* Copyright 1996-1998 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* fttimer: A simple performance benchmark. Now with graylevel rendering */
/* with the '-g' option. */
/* */
/* Be aware that the timer program benchmarks different things */
/* in each release of the FreeType library. Thus, performance */
/* should only be compared between similar release numbers. */
/* */
/* */
/* NOTE: This is just a test program that is used to show off and */
/* debug the current engine. In no way does it shows the final */
/* high-level interface that client applications will use. */
/* */
/****************************************************************************/
#include "freetype.h"
#include "ftoutln.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h> /* for clock() */
#include "graph.h"
/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
/* to get the HZ macro which is the equivalent. */
#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
#include <sys/param.h>
#define CLOCKS_PER_SEC HZ
#endif
#define CHARSIZE 400 /* character point size */
#define MAX_GLYPHS 512 /* Maximum number of glyphs rendered at one time */
char Header[128];
FT_Error error;
FT_Library library;
FT_Face face;
FT_Size size;
FT_GlyphSlot glyph;
FT_Outline outline;
FT_Pos* cur_x;
FT_Pos* cur_y;
unsigned short* cur_endContour;
unsigned char* cur_touch;
FT_Outline outlines[MAX_GLYPHS];
int num_glyphs;
int tab_glyphs;
int cur_glyph;
int cur_point;
unsigned short cur_contour;
int pixel_size = CHARSIZE*96/72;
int repeat_count = 1;
FT_Bitmap Bit;
grBitmap bit;
int Fail;
int Num;
int vio_Height, vio_Width;
short visual; /* display glyphs while rendering */
short gray_render; /* smooth fonts with gray levels */
static void Clear_Buffer();
static void Panic( const char* message )
{
fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
}
/*******************************************************************/
/* */
/* Get_Time: */
/* */
/* Returns the current time in milliseconds. */
/* */
/*******************************************************************/
long Get_Time( void )
{
return clock() * 10000 / CLOCKS_PER_SEC;
}
/*******************************************************************/
/* */
/* Init_Engine: */
/* */
/* Allocates bitmap, render pool and other structs... */
/* */
/*******************************************************************/
void Init_Engine( void )
{
Bit.rows = bit.rows;
Bit.width = bit.width;
Bit.pitch = bit.pitch;
Bit.buffer = bit.buffer;
Bit.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
Bit.num_grays = bit.grays;
Clear_Buffer();
}
/*******************************************************************/
/* */
/* Clear_Buffer: */
/* */
/* Clears current bitmap. */
/* */
/*******************************************************************/
static void Clear_Buffer( void )
{
long size = Bit.rows * Bit.pitch;
memset( Bit.buffer, 0, size );
}
/*******************************************************************/
/* */
/* LoadTrueTypeChar: */
/* */
/* Loads a glyph into memory. */
/* */
/*******************************************************************/
FT_Error LoadChar( int idx )
{
error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT );
if ( error )
return error;
glyph->outline.second_pass = 0;
glyph->outline.high_precision = 0;
glyph->outline.dropout_mode = 0;
/* debugging */
#if 0
if ( idx == 0 && !visual )
{
printf( "points = %d\n", outline.points );
for ( j = 0; j < outline.points; j++ )
printf( "%02x (%01hx,%01hx)\n",
j, outline.xCoord[j], outline.yCoord[j] );
printf( "\n" );
}
#endif
/* create a new outline */
FT_New_Outline( library,
glyph->outline.n_points,
glyph->outline.n_contours,
&outlines[cur_glyph] );
/* copy the glyph outline into it */
glyph->outline.high_precision = 0;
glyph->outline.second_pass = 0;
FT_Copy_Outline( &glyph->outline, &outlines[cur_glyph] );
/* center outline around 0 */
{
FT_BBox bbox;
FT_Get_Outline_CBox( &glyph->outline, &bbox );
FT_Translate_Outline( &outlines[cur_glyph],
- ( bbox.xMax - bbox.xMin )/2,
- ( bbox.yMax - bbox.yMin )/2 );
}
/* translate it */
FT_Translate_Outline( &outlines[cur_glyph],
Bit.width * 32 ,
Bit.rows * 32 );
cur_glyph++;
return FT_Err_Ok;
}
/*******************************************************************/
/* */
/* ConvertRaster: */
/* */
/* Performs scan conversion. */
/* */
/*******************************************************************/
FT_Error ConvertRaster( int index )
{
outlines[index].second_pass = 0;
outlines[index].high_precision = 0;
return FT_Get_Outline_Bitmap( library, &outlines[index], &Bit );
}
static void Usage()
{
fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" );
fprintf( stderr, "-----------------------------------------------------------------\n\n" );
fprintf( stderr, "Usage: fttimer [options] fontname[.ttf|.ttc]\n\n" );
fprintf( stderr, "options:\n");
fprintf( stderr, " -r : repeat count to be used (default is 1)\n" );
fprintf( stderr, " -s : character pixel size (default is 600)\n" );
fprintf( stderr, " -v : display results..\n" );
fprintf( stderr, " -g : render anti-aliased glyphs\n" );
exit(1);
}
int main( int argc, char** argv )
{
int i, total, base, rendered_glyphs;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
grSurface* surface = 0;
long t, t0, tz0;
execname = argv[0];
gray_render = 0;
visual = 0;
while ( argc > 1 && argv[1][0] == '-' )
{
switch ( argv[1][1] )
{
case 'g':
gray_render = 1;
break;
case 'v':
visual = 1;
break;
case 's':
argc--;
argv++;
if ( argc < 2 ||
sscanf( argv[1], "%d", &pixel_size ) != 1 )
Usage();
break;
case 'r':
argc--;
argv++;
if ( argc < 2 ||
sscanf( argv[1], "%d", &repeat_count ) != 1 )
Usage();
if (repeat_count < 1)
repeat_count = 1;
break;
default:
fprintf( stderr, "Unknown argument '%s'!\n", argv[1] );
Usage();
}
argc--;
argv++;
}
if ( argc != 2 )
Usage();
i = strlen( argv[1] );
while ( i > 0 && argv[1][i] != '\\' )
{
if ( argv[1][i] == '.' )
i = 0;
i--;
}
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, argv[1], 128 );
strncpy( alt_filename, argv[1], 128 );
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
/* Initialize engine */
if ( (error = FT_Init_FreeType( &library )) )
Panic( "Error while initializing engine" );
/* Load face */
error = FT_New_Face( library, filename, 0, &face );
if ( error == FT_Err_Cannot_Open_Stream )
Panic( "Could not find/open font resource" );
else if ( error )
Panic( "Error while opening font resource" );
/* get face properties and allocate preload arrays */
num_glyphs = face->num_glyphs;
glyph = face->glyph;
tab_glyphs = MAX_GLYPHS;
if ( tab_glyphs > num_glyphs )
tab_glyphs = num_glyphs;
/* create size */
error = FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
if ( error ) Panic( "Could not reset instance" );
bit.mode = gray_render ? gr_pixel_mode_gray : gr_pixel_mode_mono;
bit.width = 640;
bit.rows = 480;
bit.grays = 128;
if ( visual )
{
if ( !grInitDevices() )
Panic( "Could not initialize graphics.\n" );
surface = grNewSurface( 0, &bit );
if (!surface)
Panic( "Could not open graphics window/screen.\n" );
}
else
{
if ( grNewBitmap( bit.mode,
bit.grays,
bit.width,
bit.rows,
&bit ) )
Panic( "Could not create rendering buffer.\n" );
}
Init_Engine();
Num = 0;
Fail = 0;
total = num_glyphs;
base = 0;
rendered_glyphs = 0;
t0 = 0; /* Initial time */
tz0 = Get_Time();
while ( total > 0 )
{
int repeat;
/* First, preload 'tab_glyphs' in memory */
cur_glyph = 0;
cur_point = 0;
cur_contour = 0;
printf( "loading %d glyphs", tab_glyphs );
for ( Num = 0; Num < tab_glyphs; Num++ )
{
error = LoadChar( base + Num );
if ( error )
Fail++;
total--;
}
base += tab_glyphs;
if ( tab_glyphs > total )
tab_glyphs = total;
printf( ", rendering... " );
/* Now, render the loaded glyphs */
t = Get_Time();
for ( repeat = 0; repeat < repeat_count; repeat++ )
{
for ( Num = 0; Num < cur_glyph; Num++ )
{
if ( (error = ConvertRaster( Num )) )
Fail++;
else
{
rendered_glyphs ++;
if ( Num == 0 && visual )
{
sprintf( Header, "Glyph: %5d", Num );
grSetTitle( surface, Header );
grRefreshSurface( surface );
Clear_Buffer();
}
}
}
}
t = Get_Time() - t;
if ( t < 0 )
t += 1000 * 60 * 60;
printf( " = %f s\n", (double)t / 10000 );
t0 += t;
/* Now free all loaded outlines */
for ( Num = 0; Num < cur_glyph; Num++ )
FT_Done_Outline( library, &outlines[Num] );
}
tz0 = Get_Time() - tz0;
FT_Done_Face( face );
printf( "\n" );
printf( "rendered glyphs = %d\n", rendered_glyphs );
printf( "render time = %f s\n", (double)t0 / 10000 );
printf( "fails = %d\n", Fail );
printf( "average glyphs/s = %f\n",
(double)rendered_glyphs / t0 * 10000 );
printf( "total timing = %f s\n", (double)tz0 / 10000 );
printf( "Fails = %d\n", Fail );
FT_Done_FreeType( library );
exit( 0 ); /* for safety reasons */
return 0; /* never reached */
}
/* End */

155
demos/src/fttry.c Normal file
View File

@ -0,0 +1,155 @@
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1998 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* ftlint: a simple TrueType instruction tester. */
/* */
/* NOTE: This is just a test program that is used to show off and */
/* debug the current engine. */
/* */
/****************************************************************************/
#include "freetype.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define gettext( x ) ( x )
FT_Error error;
FT_Library library;
FT_Face face;
unsigned int num_glyphs;
int ptsize;
int Fail;
int Num;
static void Usage( char* name )
{
printf( "fttry: simple TrueType instruction tester -- part of the FreeType project\n" );
printf( "--------------------------------------------------------------------------\n" );
printf( "\n" );
printf( "Usage: %s ppem glyph fontname [fontname2..]\n\n", name );
printf( " or %s -u glyph fontname [fontname2..]\n", name );
printf( " to load an unscaled glyph\n\n" );
exit( 1 );
}
static void Panic( const char* message )
{
fprintf( stderr, "%s\n error code = 0x%04x\n", message, error );
exit(1);
}
int main( int argc, char** argv )
{
int i, file_index, glyph_index;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
char* fname;
int load_unscaled = 0;
execname = argv[0];
if ( argc < 3 )
Usage( execname );
if ( argv[1][0] == '-' &&
argv[1][1] == 'u' )
{
load_unscaled = 1;
}
else
{
if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
Usage( execname );
}
argc--;
argv++;
if ( sscanf( argv[1], "%d", &glyph_index ) != 1 )
Usage( execname );
error = FT_Init_FreeType( &library );
if (error) Panic( "Could not create library object" );
/* Now check all files */
for ( file_index = 2; file_index < argc; file_index++ )
{
fname = argv[file_index];
i = strlen( fname );
while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
{
if ( fname[i] == '.' )
i = 0;
i--;
}
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, fname, 128 );
strncpy( alt_filename, fname, 128 );
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
i = strlen( filename );
fname = filename;
while ( i >= 0 )
if ( filename[i] == '/' || filename[i] == '\\' )
{
fname = filename + i + 1;
i = -1;
}
else
i--;
printf( "%s: ", fname );
/* Load face */
error = FT_New_Face( library, filename, 0, &face );
if (error) Panic( "Could not create face object" );
num_glyphs = face->num_glyphs;
error = FT_Set_Char_Size( face, ptsize << 6, 0, 0, 0 );
if (error) Panic( "Could not set character size" );
error = FT_Load_Glyph( face,
glyph_index,
load_unscaled ? FT_LOAD_NO_SCALE
: FT_LOAD_DEFAULT );
if ( error == 0 )
printf( "OK.\n" );
else
printf( "Fail with error 0x%04x\n", error );
FT_Done_Face( face );
}
FT_Done_FreeType(library);
exit( 0 ); /* for safety reasons */
return 0; /* never reached */
}
/* End */

615
demos/src/ftview.c Normal file
View File

@ -0,0 +1,615 @@
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-1999 by */
/* D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* */
/* FTView - a simple font viewer. */
/* */
/* This is a new version using the MiGS graphics subsystem for */
/* blitting and display. */
/* */
/* Press F1 when running this program to have a list of key-bindings */
/* */
/****************************************************************************/
#include "freetype.h"
#include "ftoutln.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
#include "grfont.h"
#define DIM_X 500
#define DIM_Y 400
#define CENTER_X (bit.width/2)
#define CENTER_Y (bit.rows/2)
#define MAXPTSIZE 500 /* dtp */
char Header[128];
char* new_header = 0;
FT_Library library; /* the FreeType library */
FT_Face face; /* the font face */
FT_Size size; /* the font size */
FT_GlyphSlot glyph; /* the glyph slot */
FT_Error error; /* error returned by FreeType ? */
grSurface* surface; /* current display surface */
grBitmap bit; /* current display bitmap */
int num_glyphs; /* number of glyphs */
int ptsize; /* current point size */
int hinted = 1; /* is glyph hinting active ? */
int gray_render = 1; /* is anti-aliasing active ? */
int use_sbits = 1; /* do we use embedded bitmaps ? */
int low_prec = 1; /* force low precision */
int Num; /* current first glyph index */
int res = 96;
int Fail;
unsigned char autorun;
int graph_init = 0;
/* PanicZ */
static void PanicZ( const char* message )
{
fprintf( stderr, "%s\n error = 0x%04x\n", message, error );
exit(1);
}
/* Clears the Bit bitmap/pixmap */
static void Clear_Display( void )
{
long size = (long)bit.pitch * bit.rows;
memset( bit.buffer, 0, size );
}
/* Initialize the display bitmap named Bit */
static int Init_Display()
{
grInitDevices();
bit.mode = gr_pixel_mode_gray;
bit.width = DIM_X;
bit.rows = DIM_Y;
bit.grays = 128;
surface = grNewSurface( 0, &bit );
if (!surface)
PanicZ( "could not allocate display surface\n" );
graph_init = 1;
return 0;
}
#define MAX_BUFFER 65000
#define FLOOR(x) ((x) & -64)
#define CEIL(x) (((x)+63) & -64)
#define TRUNC(x) ((x) >> 6)
static
char bit_buffer[ MAX_BUFFER ];
/* Render a single glyph */
static FT_Error Render_Glyph( int x_offset,
int y_offset )
{
/* first, render the glyph into an intermediate buffer */
FT_Bitmap bit2;
grBitmap bit3;
int width, height, pitch, size;
int left, right, top, bottom;
left = FLOOR( glyph->metrics.horiBearingX );
right = CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
width = TRUNC(right - left);
top = CEIL( glyph->metrics.horiBearingY );
bottom = FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
height = TRUNC( top - bottom );
if ( glyph->format == ft_glyph_format_outline )
{
pitch = ( gray_render ? (width+3) & -4 : (width+7) >> 3 );
size = pitch*height;
if (size > MAX_BUFFER)
return FT_Err_Out_Of_Memory;
bit2.width = width;
bit2.rows = height;
bit2.pitch = pitch;
bit2.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
bit2.buffer = bit_buffer;
bit3.rows = bit2.rows;
bit3.width = bit2.width;
bit3.pitch = bit2.pitch;
bit3.mode = gray_render ? bit.mode : gr_pixel_mode_mono;
bit3.buffer = bit_buffer;
bit3.grays = 128;
FT_Translate_Outline( &glyph->outline, -left, -bottom );
memset( bit_buffer, 0, size );
if (low_prec)
glyph->outline.high_precision = 0;
FT_Get_Outline_Bitmap( library, &glyph->outline, &bit2 );
}
else
{
bit3.rows = glyph->bitmap.rows;
bit3.width = glyph->bitmap.width;
bit3.pitch = glyph->bitmap.pitch;
bit3.mode = gr_pixel_mode_mono;
bit3.buffer = glyph->bitmap.buffer;
bit3.grays = 0;
}
/* Then, blit the image to the target surface */
grBlitGlyphToBitmap( &bit,
&bit3,
x_offset + TRUNC(left),
y_offset - TRUNC(top),
(grColor)127L );
return 0;
}
static FT_Error Reset_Scale( int pointSize )
{
FT_Error error;
error = FT_Set_Char_Size( face, pointSize << 6,
pointSize << 6,
res,
res );
if ( error )
{
}
return FT_Err_Ok;
}
static FT_Error LoadChar( int idx, int hint )
{
int flags;
flags = FT_LOAD_DEFAULT;
if ( !hint )
flags |= FT_LOAD_NO_HINTING;
if ( !use_sbits )
flags |= FT_LOAD_NO_BITMAP;
return FT_Load_Glyph( face, idx, flags );
}
static FT_Error Render_All( int first_glyph, int ptsize )
{
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
int i;
FT_Error error;
start_x = 4;
start_y = 16 + ptsize ;
step_x = size->metrics.x_ppem + 4;
step_y = size->metrics.y_ppem + 10;
x = start_x;
y = start_y;
i = first_glyph;
while ( i < num_glyphs )
{
if ( !(error = LoadChar( i, hinted )) )
{
Render_Glyph( x, y );
x += ( glyph->metrics.horiAdvance >> 6 ) + 1;
if ( x + size->metrics.x_ppem > bit.width )
{
x = start_x;
y += step_y;
if ( y >= bit.rows )
return FT_Err_Ok;
}
}
else
Fail++;
i++;
}
return FT_Err_Ok;
}
static void Help( )
{
grEvent dummy_event;
Clear_Display();
grGotoxy( 0, 0 );
grSetMargin( 2, 1 );
grGotobitmap( &bit );
grWriteln("FreeType Glyph Viewer - part of the FreeType test suite" );
grLn();
grWriteln("This program is used to display all glyphs from one or" );
grWriteln("several font files, with the FreeType library.");
grLn();
grWriteln("Use the following keys :");
grLn();
grWriteln(" F1 or ? : display this help screen" );
grWriteln(" a : toggle anti-aliasing" );
grWriteln(" h : toggle outline hinting" );
grWriteln(" b : toggle embedded bitmaps" );
grWriteln(" l : toggle low precision rendering" );
grLn();
grWriteln(" Up : increase pointsize by 1 unit" );
grWriteln(" Down : decrease pointsize by 1 unit" );
grWriteln(" Page Up : increase pointsize by 10 units" );
grWriteln(" Page Down : decrease pointsize by 10 units" );
grLn();
grWriteln(" Right : increment first glyph index" );
grWriteln(" Left : decrement first glyph index" );
grLn();
grWriteln(" F5 : decrement first glyph index by 10" );
grWriteln(" F6 : increment first glyph index by 10" );
grWriteln(" F7 : decrement first glyph index by 100");
grWriteln(" F8 : increment first glyph index by 100");
grWriteln(" F9 : decrement first glyph index by 1000");
grWriteln(" F10 : increment first glyph index by 1000");
grLn();
grWriteln("press any key to exit this help screen");
grRefreshSurface( surface );
grListenSurface( surface, gr_event_key, &dummy_event );
}
static int Process_Event( grEvent* event )
{
int i;
switch ( event->key )
{
case grKeyEsc: /* ESC or q */
case grKEY('q'):
return 0;
case grKEY('a'):
gray_render = !gray_render;
new_header = ( gray_render
? "anti-aliasing is now on"
: "anti-aliasing is now off" );
return 1;
case grKEY('b'):
use_sbits = !use_sbits;
new_header = ( use_sbits
? "embedded bitmaps are now used when available"
: "embedded bitmaps are now ignored" );
return 1;
case grKEY('n'):
case grKEY('p'):
return (int)event->key;
case grKEY('l'):
low_prec = !low_prec;
new_header = ( low_prec
? "rendering precision is now forced to low"
: "rendering precision is now normal" );
break;
case grKEY('h'):
hinted = !hinted;
new_header = ( hinted
? "glyph hinting is now active"
: "glyph hinting is now ignored" );
break;
case grKeyF1:
case grKEY('?'):
Help();
return 1;
#if 0
case grKeyF3: i = 16; goto Do_Rotate;
case grKeyF4: i = -16; goto Do_Rotate;
case grKeyF5: i = 1; goto Do_Rotate;
case grKeyF6: i = -1; goto Do_Rotate;
#endif
case grKeyPageUp: i = 10; goto Do_Scale;
case grKeyPageDown: i = -10; goto Do_Scale;
case grKeyUp: i = 1; goto Do_Scale;
case grKeyDown: i = -1; goto Do_Scale;
case grKeyLeft: i = -1; goto Do_Glyph;
case grKeyRight: i = 1; goto Do_Glyph;
case grKeyF7: i = -10; goto Do_Glyph;
case grKeyF8: i = 10; goto Do_Glyph;
case grKeyF9: i = -100; goto Do_Glyph;
case grKeyF10: i = 100; goto Do_Glyph;
case grKeyF11: i = -1000; goto Do_Glyph;
case grKeyF12: i = 1000; goto Do_Glyph;
default:
;
}
return 1;
#if 0
Do_Rotate:
Rotation = (Rotation + i) & 1023;
return 1;
#endif
Do_Scale:
ptsize += i;
if (ptsize < 1) ptsize = 1;
if (ptsize > MAXPTSIZE) ptsize = MAXPTSIZE;
return 1;
Do_Glyph:
Num += i;
if (Num < 0) Num = 0;
if (Num >= num_glyphs) Num = num_glyphs-1;
return 1;
}
static void usage( char* execname )
{
fprintf( stderr, "\n" );
fprintf( stderr, "ftview: simple glyph viewer -- part of the FreeType project\n" );
fprintf( stderr, "-----------------------------------------------------------\n" );
fprintf( stderr, "\n" );
fprintf( stderr, "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n",
execname );
fprintf( stderr, "\n" );
fprintf( stderr, " -r R use resolution R dpi (default: 72 dpi)\n" );
fprintf( stderr, " -f index specify first glyph index to display\n" );
fprintf( stderr, "\n" );
exit( 1 );
}
int main( int argc, char** argv )
{
int i, old_ptsize, orig_ptsize, file;
int first_glyph = 0;
int XisSetup = 0;
char filename[128 + 4];
char alt_filename[128 + 4];
char* execname;
int option;
int file_loaded;
FT_Error error;
grEvent event;
execname = ft_basename( argv[0] );
while ( 1 )
{
option = getopt( argc, argv, "f:r:" );
if ( option == -1 )
break;
switch ( option )
{
case 'f':
first_glyph = atoi( optarg );
break;
case 'r':
res = atoi( optarg );
if ( res < 1 )
usage( execname );
break;
default:
usage( execname );
break;
}
}
argc -= optind;
argv += optind;
if ( argc <= 1 )
usage( execname );
if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
orig_ptsize = 64;
file = 1;
/* Initialize engine */
error = FT_Init_FreeType( &library );
if (error) PanicZ( "Could not initialise FreeType library" );
/* FT_Set_Raster_Palette( library, 17, palette_17 ); */
NewFile:
ptsize = orig_ptsize;
hinted = 1;
file_loaded = 0;
i = strlen( argv[file] );
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
{
if ( argv[file][i] == '.' )
i = 0;
i--;
}
filename[128] = '\0';
alt_filename[128] = '\0';
strncpy( filename, argv[file], 128 );
strncpy( alt_filename, argv[file], 128 );
if ( i >= 0 )
{
strncpy( filename + strlen( filename ), ".ttf", 4 );
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
}
/* Load face */
error = FT_New_Face( library, filename, 0, &face );
if (error) goto Display_Font;
file_loaded++;
error = Reset_Scale( ptsize );
if (error) goto Display_Font;
num_glyphs = face->num_glyphs;
glyph = face->glyph;
size = face->size;
Display_Font:
/* initialise graphics if needed */
if ( !XisSetup )
{
XisSetup = 1;
Init_Display();
}
grSetTitle( surface, "FreeType Glyph Viewer - press F1 for help" );
old_ptsize = ptsize;
if ( file_loaded >= 1 )
{
Fail = 0;
Num = first_glyph;
if ( Num >= num_glyphs )
Num = num_glyphs-1;
if ( Num < 0 )
Num = 0;
}
for ( ;; )
{
int key;
Clear_Display();
if ( file_loaded >= 1 )
{
Render_All( Num, ptsize );
sprintf( Header, "%s %s (file %s)",
face->family_name,
face->style_name,
ft_basename( filename ) );
if (!new_header)
new_header = Header;
grWriteCellString( &bit, 0, 0, new_header, (grColor)127L );
new_header = 0;
sprintf( Header, "at %d points, first glyph = %d",
ptsize,
Num );
}
else
{
sprintf( Header, "%s : is not a font file or could not be opened",
ft_basename(filename) );
}
grWriteCellString( &bit, 0, 8, Header, (grColor)127L );
grRefreshSurface( surface );
grListenSurface( surface, 0, &event );
if ( !( key = Process_Event( &event ) ) )
goto Fin;
if ( key == 'n' )
{
if (file_loaded >= 1)
FT_Done_Face( face );
if ( file < argc - 1 )
file++;
goto NewFile;
}
if ( key == 'p' )
{
if (file_loaded >= 1)
FT_Done_Face( face );
if ( file > 1 )
file--;
goto NewFile;
}
if ( ptsize != old_ptsize )
{
if ( Reset_Scale( ptsize ) )
PanicZ( "Could not resize font." );
old_ptsize = ptsize;
}
}
Fin:
#if 0
grDoneSurface(surface);
grDone();
#endif
printf( "Execution completed successfully.\n" );
printf( "Fails = %d\n", Fail );
exit( 0 ); /* for safety reasons */
return 0; /* never reached */
}
/* End */

1031
demos/src/t1dump.c Normal file

File diff suppressed because it is too large Load Diff

1247
demos/src/ttdebug.c Normal file

File diff suppressed because it is too large Load Diff

375
docs/BUILD Normal file
View File

@ -0,0 +1,375 @@
The FreeType Build System Internals
-----------------------------------
Introduction:
This document describes the details of the FreeType build system. The
build system is a set of Makefiles and other configuration files used
to select, compile and link together the various FreeType components
according to the current platform, compiler and requested feature set.
This document also explains how to use the build system to develop
third-party font drivers or extensions to the engine, without altering
the general FreeType hierarchy;
I. Portability issues :
Given that the design of FreeType 2 is much more modular and flexible than
in previous versions, its build system is entirely based on GNU Make. There
are several reasons for this :
- It is by far the most available make tool on the planet, and
has probably been ported to every development environment known
to homo programmaticus.
- It provides useful features (like conditional defines, pattern
and wildcard matching) which are essential when implementing a
flexible configuration system, as described below
Note that you do not need to have a unix-like shell (like "sh" or "csh")
on your system in order to build FreeType.
II. The library design :
FreeType is made of several components, each with a specific role :
- THE BASE LAYER:
It is used to implement generic font services as well as provide
the high-level API used by client applications.
- ONE OR MORE FONT DRIVERS:
Each driver is a small component used to read and process a given
font format. Note that with FreeType 2, it is possible to add,
remove or upgrade a font driver at *runtime*.
- ONE OR MORE RASTERS:
A raster is a module used to render a vectorial glyph outline into
a bitmap or an anti-aliased pixmap. They differ in their output
quality, speed and memory usage.
- A LOW-LEVEL MODULE, CALLED "FTSYSTEM":
It is used to implement memory management and file i/o. Uses the
Ansi C Library by default, though some system-specific replacements
are provided in order to improve performance.
- AN "INIT" LAYER:
A tiny module used to implement the library initialisation routine,
i.e. FT_Init_FreeType. It is in charge of registering the font drivers
and rasters selected at build time.
- AN "OLD API" LAYER:
A simple layer used to link legacy applications using the FreeType
1.x API. Note that it is binary backwards compatible, which means that
applications do not need to be recompiled, only re-linked to this
layer.
For more details, please read the "FreeType Internals" Document.
The FreeType build system is in charge of the following tasks :
- detect (or select) the current platform in order to select the
best version of the "ftsystem" module. By default, it will use
the pure-ANSI version.
- determine which font drivers, and which rasters, should be
statically linked to the library at build time. These will always
be available after the library has been initialised through a call
to FT_Init_FreeType.
- eventually compile other font drivers or rasters in order to later
link them dynamically to the library at runtime, through
FT_Add_Driver / FT_Upgrade_Driver..
- compile the "init" layer, putting code in the implementation of
the FT_Init_FreeType function to register each selected font driver
or raster to the library.
III. General overview :
The FreeType build system uses a hierarchy of included sub-Makefiles
to compile and link the library.
Each included sub-Makefile is called a "rules" file, and has a very
specific purpose. The suffix for rules files is ".mk" as in :
detect.mk
config.mk
rules.mk
etc...
Here's a simple diagram of the build hierarchy, which is then explained
with details :
Makefile ( ./Makefile )
|
|
v
Config Rules ( ./config/<system>/config.mk )
|
|
v
Library Rules ( ./config/freetype.mk )
| | |
| | |
v v v
Component(s) Rules ( ./src/<component>/rules.mk )
1. The "root" Makefile :
This file must be invoked from the "freetype" directory with GNU Make.
a. Host platform auto-detection:
When run for the first time, this Makefile will try to auto-detect
the current host platform, by running the rules file named
`./config/detect.mk'. If the host system cannot be detected,
it will default to the `ansi' system.
It will then copy the rules file `./config/<system>/config.mk' to
the current directory and display the results of the auto-detection.
You can, at any time, re-run the auto-detection routine by invoking
the root Makefile with the "setup" target, as in :
% make setup
Note also that it is possible to use a second argument to indicate
a specific compiler. For example, here are the lignes to be used
in order to configure a build with LCC, Visual C++ and Visual Age
on a Win32 machine
> gmake setup lcc
> gmake setup visualc
> gmake setup visualage
The list of compilers is platform-specific and should be contained
in `config/<system>/detect.mk'.
If the detection results do not correspond to your platform or
settings, refer to chapter VI which describes the auto-detection
system in great details..
b. Building the library:
Once the host platform has been detected, you can run `make' once
again. The root Makefile will then detect the configuration rules
file in the current directory then include it.
Note also that the root Makefile is responsible for defining, if it
is not already part of the current environment, the variable TOP, which
designates the top of the FreeType source hierarchy.
When undefined, it defaults to `.'
2. The Configuration file :
The configuration rules file is used to set many important variables
before including/calling the library rules file (see below).
These variables are mainly used to describe the host environment
and compilers. Indeed, this file defines, among others, the following:
SEP The directory path separator. This can be `/',`\' or ':'
depending on the current platform. Note that all pathnames
are composed with $(SEP) in all rules file (except in
`include' statements which work well with '/' on all
platforms)
CC The compiler to use
CFLAGS The compiler flags used to compile a given source to an
object file. Usually contains flags for optimisation,
debugging and/or ansi-compliance
I The flag to be used to indicate an additionnal include path
to the compiler. This defaults to `-I' for an "ansi" system,
but can be different for others (e.g. `/i=',`-J ', etc..)
D The flag to be used to indicate a macro definition to the
compiler. This defaults to `-D' for an ANSI system.
T The flag to be used to indicate a target object file to the
compiler. This defaults to `-o ' for an ANSI system. Note the
space after the `o'.
O The object file extension to be used on the current platform.
Defaults to `o' for an ANSI system, but can be `obj', `coff'
or others.. There is no dot in the extension !
A The library file extension to be used on the current platform.
Defaults to 'a' for an ANSI system, but can be `lib', `so',
`dll' or others.. There is no dot in the extension !
BUILD The directory where the build system should grab the
configuration header file `ftconfig.h' as well as the
system-specific implementation of `ftsystem'.
OBJ The directory where all object files will be placed
3. The Library Rules files :
Once the variables defined in the configuration rules file, the
library rules file is included. This one contains all rules required
to build the library objects into OBJ
Its structure works as follows:
- provide rules to compile the low-level `ftsystem' module
- include the rules files from each font driver or component
- include the rules file for the "old api" layer
- provide rules to compile the initialisation layer
- provide additional targets like `clean', ..
Note that linking all objects files together into a library is not
performed in this file, though it might seem reasonable at first
glance. The reason for this is that not all linkers have a simple
syntax of the form:
librarian archive_file object1 object2 ....
hence, linking is performed through rules provided in the configuration
rules file, using the phony `library' target, which has been defined for
this very specific purpose.
4. The Components Rules files :
Each font driver has its own rules file, called `rules.mk' located
in its own directory. The library rules file includes these component
rules for each font driver.
These rules must perform the following:
- provide rules to compile the component, either into a single `large'
object, or into multiple small ones
- for font drivers and rasters, update some variables, that are
initially defined in the library rules file, which indicate wether
the component must be registered in the library initialisation code
a. Component Compile Modes :
There are two ways to compile a given component :
i. Single-object compilation:
In this mode, the component is compiled into a single object
file. This is performed easily by defining a single C file whose
sole purpose is to include all other component sources. For
example, the truetype driver is compiled as a single object
named `truetype.o'.
ii. Multiple objects compilation:
In this mode, all source files for a single component are compiled
individually into an object file.
Due to the way the FreeType source code is written, single mode
has the following advantages over multiple mode:
- with many compilers, the resulting object code is smaller than
the concatenation of all individual objects from multiple mode.
this, because all functions internal to the component as a whole
are declared static, allowing more optimisation. It often also
compiles much faster.
- most importantly, the single object only contains the external
symbols it needs to be linked to the base layer (all extern that
are due to inter-source calls within the component are removed).
this can reduce tremendously the size of dynamic libraries on
some platforms
Multiple mode is useful however to check some dependencies problems
that might not appear when compiling in single mode, so it has been
kept as a possibility.
b. Driver initialisation code :
The source file `./src/base/ftinit.c' contains the implementation
of the FT_Init_FreeType function which must, among other things,
register all font drivers that are statically linked to the library.
Controlling which drivers are registered at initialisation time is
performed by exploiting the state of the C-preprocessor in order to
build a linked list (a "chain") of driver interfaces.
More precisely, each font driver interface file (like `ttdriver.h'
or `t1driver.h') has some special lines that look like this :
#ifdef FTINIT_DRIVER_CHAIN
static
const FT_DriverChain ftinit_<FORMAT>_driver_chain =
{
FT_INIT_LAST_DRIVER_CHAIN,
&<FORMAT>_driver_interface
};
#undef FT_INIT_LAST_DRIVER_CHAIN
#define FT_INIT_LAST_DRIVER_CHAIN &ftinit_<FORMAT>_driver_chain
#endif
As one can see, this code is strictly reserved for `ftinit.c' which
defines FTINIT_DRIVER_CHAIN before including all font driver header
files.
When the C-processor parses these headers, it builds a linked list of
FT_DriverChain element. For exemple, the sequence :
#define FTINIT_DRIVER_CHAIN
#include <ttdriver.h>
#include <t1driver.h>
Will really generate something like:
static
*----> const FT_DriverChain ftinit_tt_driver_chain =
| {
| 0,
| &tt_driver_interface
| };
|
| static
| const FT_DriverChain ftinit_t1_driver_chain =
| {
*------ &ftinit_tt_driver_chain,
&t1_driver_interface
};
with the FT_INIT_LAST_DRIVER_CHAIN set to "&ftinit_t1_driver_chain"
Hence, the last included driver will be registered first in the library

216
docs/DESIGN Normal file
View File

@ -0,0 +1,216 @@
The Design of FreeType 2.0
==========================
Introduction:
This short document presents the design of version 2 of the FreeType
library. It is a must read for anyone willing to port, debug or hack
the FreeType sources.
I. Goals :
FreeType 2 was designed to provide a unified and universal API to
manage (i.e. read) the content of font files.
Its main features are :
- A FORMAT-INDEPENDENT HIGH-LEVEL API
Used to open, read and manage font files.
- THE USE OF PLUGGABLE "FONT DRIVERS"
Each font driver is used to support a given font format. For
example, the default build of FreeType 2 comes with drivers for the
TrueType and Type 1 font formats.
Font drivers can also be added, removed or upgraded at *runtime*,
in order to support more font formats, or improve the current ones.
Each font driver also provides its own "public interface" to client
applications who would like to use format-specific features.
- THE USE OF PLUGGABLE "RASTERS"
A raster is a tiny module used to render a glyph image
into a bitmap or anti-aliased pixmap. Rasters differ in their
output quality (especially with regards to anti-aliasing), speed
and memory usage.
An application can also provide its own raster if it needs to.
- HIGH PORTABILITY AND PERFORMANCE
The FreeType source code is written in industry-standard ANSI C.
Moreover, it abstracts memory management and i/o operations within
a single module, called "ftsystem". The FreeType build system tries
to auto-detect the host platform in order to select its most
efficient implementation. It defaults otherwise to using the
standard ANSI C Library.
Note that, independently of the host platform and build, an
application is able to provide its own memory and i/o routines.
This make FreeType suitable for use in any kind of environment,
from embedded to distributed systems.
II. Components Layout :
FreeType 2 is made of distinct components which relate directly to the
design described previously:
1. THE BASE LAYER:
The base layer implements the high-level API, as well as provide
generic font services that can be used by each font driver.
2. THE FONT DRIVERS:
Each font driver can be registered in the base layer by providing
an "interface", which really is a table of function pointers.
At build time, the set of default font drivers is selected. These
drivers are then compiled and statically linked to the library.
They will then be available after the library initialisation.
3. THE RASTERS:
FreeType 2 provides the ability to hook various raster modules into
its base layer. This provides several advantages :
- different systems mean different requirements, hence the need for
flexibility.
- for now, FreeType 2 only supports glyph images stored in the
following formats :
* bitmaps
* gray-level pixmaps
* monochrome vectorial outlines (using bezier control points)
should a new "technology" come for glyph images, it is possible
to write a new raster for it, without altering the rest of the
engine. Some examples could be :
* multi-colored vectorial outlines
* on-the-fly rendering of TeX's MetaFonts !!
4. THE SYSTEM MODULE "FTSYSTEM":
The system module is used to implement basic memory and i/o management
services. By default, it uses the ANSI C library, but some replacements
are also provided (and automatically selected by the build system) when
available.
As a simple example, the unix build uses memory-mapped files to read
font files, instead of the slow ANSI "fopen/fseek/fread". This results
in tremendous performance enhancements.
Note that, even if the build system chooses an implementation for
"ftsystem" at compile time, an application is still able to provide
its own memory or i/o routines to the library at runtime.
5. THE "INIT" LAYER:
A tiny module used to implement the function FT_Init_FreeType.
As its name suggests, it is responsible for initialising the library,
which really means the following :
- bind the implementation of "ftsystem" that best matches the
host platform to the library. This choice can be overriden
later by client applications however.
- register the set of default font drivers within the base layer.
these drivers are statically linked to the library. Other drivers
can be added at runtime later through FT_Add_Driver though..
- register the set of default rasters. Client applications are
able to add their own rasters at runtime though.
The details regarding these operations is given in the document
named "FreeType Build Internals"
III. Objects Layout :
Even though it is written in ANSI C, the desing of FreeType 2 is object
oriented, as it's the best way to implement the flexible font format
support that we wanted.
Indeed, the base layer defines a set of base classes that can be derived
by each font driver in order to support a given format. The base layer
also includes many book-keeping routines that need not be included in the
drivers.
The base classes are the following:
1. FACE OBJECTS:
As in FreeType 1.x, a face object models the content of a given font
that isn't dependent on a given size, transformation or glyph index.
This includes, for example, the font name, font style(s), available
charmaps and encodings, and all other kinds of data and tables that
help describe the font as a whole.
2. SIZE OBJECTS: (previously known as INSTANCE OBJECTS in 1.x)
A face object can have one or more associated size objects. A Size
object is used to stored the font data that is dependent on the current
character size or transform used to load glyphs.
Typical data in a size object include scaled metrics, factors, and
various kind of control data related to grid-fitting. The size object
is changed each time the character size is modified.
3. GLYPH SLOT OBJECTS:
Each face object has one "glyph slot", which is a simple container
where individual glyph images can be loaded and processed.
The glyph image can be stored in the following formats in the glyph
slot :
- monochrome bitmaps
- gray-level pixmaps
- vectorial glyph outlines (defined with bezier control points)
Note that a module, called the "raster" is provided to convert vector
outlines into either monochrome or anti-aliased bitmaps. The outline
is also directly accessible and can be walked or processed freely by
client applications.
more glyph images formats can be defined, but they will require
a specific raster module if one wants to display them on a typical
display surface.
4. CHARMAP OBJECTS:
A charmap is used to convert character codes, for a given encoding,
into glyph indices. A given face might contain several charmaps, for
example, most TrueType fonts contain both the "Windows Unicode" and
"
it is not rare to see TrueType fonts with both the
"Windows Unicode" and "Apple Roman" charmap

173
docs/essai Normal file
View File

@ -0,0 +1,173 @@
Un apercu du layout des fichiers sources de FreeType 2:
docs/ - documentation
html/ - documentation au format html
txt/ - documentation au format texte
include/ - les headers publiques de la librairie, ce sont ceux
qui sont installes avec le paquet freetype-devel.rpm
config/ - le repertoire de configuration.
ansi/
ft_conf.h - fichier de configuration
ftsys.c - fichier implementation bas-niveau
unix/
os2/
dos/
amiga/
debug/
src/ - sources de la librairie
base/ - couche de base (services generiques + API)
truetype/ - pilote truetype
options/ - options du pilote truetype
extend/ - extensions du pilote truetype
type1/ - pilote type 1
options/ - options du pilote type 1
extend/ - extensions du pilote type 1
type2/ - pilote type 2
speedo/ - pilote speedo
shared/ - sources partagees par plusieurs pilotes
tests/ - programmes de test
data/ - donnees des tests = fichiers de police => copies dans bin
test1/ - source du test numero 1
test2/ - source du test numero 2
test3/ - ...
...
obj/ - emplacement des fichiers objets compiles + librairie ?
bin/ - emplacement des executables (demos+tests)
demos/ - programmes de demonstration
graph/ - sous-systeme graphique des programmes de demo
contrib/ - contributions de toutes sortes..
=============================================================================
Quelques autres idees au hasard :
- virer le controle des threads, on s'en tape magistralement
- separer l'allocation memoire de l'acces disque (+flexible)
- l'api de base doit permettre "d'ouvrir" un fichier de police se trouvant
deja en memoire..
- expliquer les differents types de dictionnaires :
char_code -> glyph_index charmap (truetype)
char_code -> glyph_name encoding (type 1)
glyph_index -> glyph_name repertoire (...)
- plusieurs "raster" possibles (le raster par defaut peut etre déterminé à la compilation,
sinon l'ajout se fait simplement en passant un pointeur d'interface..)
- l'api de base doit etre simplifiee. La plupart des developpeurs ne veulent
pas savoir ce qu'est une "size", un "glyph_slot", etc.., on conseille donc
d'en creer une par defaut, lors de l'appel de :
------------------- initialisation et lecture des polices ------------
FT_Init_FreeType( &library );
FT_Set_Memory_Manager( library, &mem_manager_rec );
FT_Set_IO_Manager( library, &io_manager_rec );
FT_New_Face( library, file_pathname, face_index, &face );
FT_New_Memory_Face( library, first_byte, length, face_index, &face );
ou encore:
FT_New_Face( library, &new_face_rec, &face );
avec new_face_rec ::
face_index
pathname
memory_address
bytes_size
FT_Flush_Face( face ); // ferme le stream correspondant..
------------------------------------------ changement de taille ------
FT_Set_Size( face, &face_size_rec );
face_size_rec ::
char_height
char_width
horz_resolution
vert_resolution
FT_Set_Pixel_Sizes( face, 64, 64 );
----------------------------------------- selection de la charmap ----
FT_Select_Charmap( face, ft_charmap_unicode );
FT_Select_Charmap_Index( face, index );
FT_List_Charmaps( face, buffer, max, first );
face->charmap => pointe vers la charmap actuelle..
-------------------------------------- chargement des glyphes --------
FT_Load_Glyph( face, glyph_index );
FT_Load_Char( face, char_code );
FT_Transform_Glyph( face->glyph, &trans );
---------------------------------------------- rendu final -----------
FT_Get_Outline_Bitmap( library, face->glyph, &bit );
FT_Set_Raster( library, "default" );
FT_Set_Raster_Mode( library, major_mode, minor_mode );
=======================================================================================
Système de configuration automatique
freetype2/
Makefile
config/
ansi/
config.mk
make setup => autodetection du système + copie de fichier include ???
make

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Some files were not shown because too many files have changed in this diff Show More