Initial revision
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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'
|
||||
;
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
NAME WINDOWCOMPAT
|
||||
|
||||
DESCRIPTION 'FreeType Graphics'
|
||||
HEAPSIZE 8192
|
||||
STACKSIZE 40888
|
|
@ -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 */
|
|
@ -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
|
||||
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
NAME WINDOWCOMPAT
|
||||
|
||||
DESCRIPTION 'FreeType Graphics'
|
||||
HEAPSIZE 8192
|
||||
STACKSIZE 40888
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
|
@ -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> </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 &
|
||||
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> </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>
|
||||
<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> </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. 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>
|
|
@ -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_%)
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
This directory contains all the object files generated for the demonstration programs
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.2 KiB |