forked from minhngoc25a/freetype2
Removed `demos' tree. Use `ft2demos' module instead.
This commit is contained in:
parent
415cc7c905
commit
7b5c4a96e1
288
demos/Makefile
288
demos/Makefile
|
@ -1,288 +0,0 @@
|
|||
all: exes
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# TOP is the directory where the main FreeType source is found,
|
||||
# as well as the 'config.mk' file
|
||||
#
|
||||
# TOP2 is the directory is the top of the demonstration
|
||||
# programs directory
|
||||
#
|
||||
|
||||
ifndef TOP
|
||||
TOP := ..
|
||||
endif
|
||||
|
||||
ifndef TOP2
|
||||
TOP2 := $(TOP)/demos
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# MY_CONFIG_MK points to the current "config.mk" to use. It is
|
||||
# defined by default as $(TOP)/config.mk
|
||||
#
|
||||
ifndef CONFIG_MK
|
||||
CONFIG_MK := $(TOP)/config.mk
|
||||
endif
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# Check that we have a working `config.mk' in the above directory.
|
||||
# If not, issue a warning message, then stop there..
|
||||
#
|
||||
ifeq ($(wildcard $(CONFIG_MK)),)
|
||||
no_config_mk := 1
|
||||
endif
|
||||
|
||||
ifdef no_config_mk
|
||||
exes:
|
||||
@echo Please compile the library before the demo programs!
|
||||
clean distclean:
|
||||
@echo "I need \`$(TOP)/config.mk' to do that!"
|
||||
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)
|
||||
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# Define a few important variables now
|
||||
#
|
||||
TOP_ := $(TOP)$(SEP)
|
||||
TOP2_ := $(TOP2)$(SEP)
|
||||
SRC_ := $(TOP)$(SEP)src$(SEP)
|
||||
|
||||
BIN_ := bin$(SEP)
|
||||
OBJ_ := obj$(SEP)
|
||||
|
||||
GRAPH_DIR := graph
|
||||
|
||||
ifeq ($(TOP),..)
|
||||
SRC_DIR := src
|
||||
else
|
||||
SRC_DIR := $(TOP2_)src
|
||||
endif
|
||||
|
||||
SRC_DIR_ := $(SRC_DIR)$(SEP)
|
||||
|
||||
FT_INCLUDES := $(BUILD) $(TOP_)config $(TOP_)include $(SRC_) $(SRC_DIR)
|
||||
|
||||
COMPILE = $(CC) $(CFLAGS) $(INCLUDES:%=$I%)
|
||||
FTLIB := $(TOP_)$(LIB_DIR)$(SEP)$(LIBRARY).$A
|
||||
|
||||
# the default commands used to link the executables. These can
|
||||
# be re-defined for platform-specific stuff..
|
||||
#
|
||||
LINK = $(CC) $T$@ $< $(FTLIB) $(EFENCE) $(LDFLAGS)
|
||||
|
||||
# the program "src/ftstring.c" used the math library which isn't linked
|
||||
# with the program by default on Unix, we thus add it whenever appropriate
|
||||
#
|
||||
ifeq ($(PLATFORM),unix)
|
||||
LINK += -lm
|
||||
endif
|
||||
|
||||
COMMON_LINK = $(LINK) $(COMMON_OBJ)
|
||||
GRAPH_LINK = $(COMMON_LINK) $(GRAPH_LIB)
|
||||
GRAPH_LINK2 = $(GRAPH_LINK) $(EXTRA_GRAPH_OBJS)
|
||||
|
||||
.PHONY: exes clean distclean
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# 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
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
ifdef DOSLIKE
|
||||
|
||||
clean_demo:
|
||||
-del obj\*.$O 2> nul
|
||||
-del $(subst /,\,$(TOP2))\src\*.bak 2> nul
|
||||
|
||||
distclean_demo: clean_demo
|
||||
-del obj\*.lib 2> nul
|
||||
-del bin\*.exe 2> nul
|
||||
|
||||
else
|
||||
|
||||
clean_demo:
|
||||
-$(DELETE) $(OBJ_)*.$O
|
||||
-$(DELETE) $(SRC_)*.bak graph$(SEP)*.bak
|
||||
-$(DELETE) $(SRC_)*~ graph$(SEP)*~
|
||||
|
||||
distclean_demo: clean_demo
|
||||
-$(DELETE) $(EXES:%=$(BIN_)%$E)
|
||||
-$(DELETE) $(GRAPH_LIB)
|
||||
|
||||
endif
|
||||
|
||||
clean: clean_demo
|
||||
distclean: distclean_demo
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# 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 ftview fttimer compos ftstring memtest ftmulti
|
||||
EXES := ftlint ftview fttimer ftstring memtest ftmulti
|
||||
|
||||
ifneq ($(findstring $(PLATFORM),os2 unix win32),)
|
||||
EXES += ttdebug
|
||||
endif
|
||||
|
||||
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
|
||||
ifdef DOSLIKE
|
||||
$(COMPILE) $T$@ $< $DEXPAND_WILDCARDS
|
||||
else
|
||||
$(COMPILE) $T$@ $<
|
||||
endif
|
||||
|
||||
|
||||
$(OBJ_)%.$O: $(SRC_DIR_)%.c $(FTLIB)
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)ftlint.$O: $(SRC_DIR_)ftlint.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)compos.$O: $(SRC_DIR_)compos.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)memtest.$O: $(SRC_DIR_)memtest.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
$(OBJ_)fttry.$O: $(SRC_DIR_)fttry.c
|
||||
$(COMPILE) $T$@ $<
|
||||
|
||||
|
||||
$(OBJ_)ftview.$O: $(SRC_DIR_)ftview.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)ftmulti.$O: $(SRC_DIR_)ftmulti.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)ftstring.$O: $(SRC_DIR_)ftstring.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
$(OBJ_)fttimer.$O: $(SRC_DIR_)fttimer.c $(GRAPH_LIB)
|
||||
$(COMPILE) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
|
||||
|
||||
|
||||
|
||||
# $(OBJ_)ftsbit.$O: $(SRC_DIR)/ftsbit.c $(GRAPH_LIB)
|
||||
# $(COMPILE) $T$@ $<
|
||||
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# Special rule to compile the `t1dump' program as it includes
|
||||
# the Type1 source path
|
||||
#
|
||||
$(OBJ_)t1dump.$O: $(SRC_DIR)/t1dump.c
|
||||
$(COMPILE) $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
|
||||
$(COMPILE) $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) $(COMMON_OBJ)
|
||||
$(COMMON_LINK)
|
||||
|
||||
$(BIN_)memtest$E: $(OBJ_)memtest.$O $(FTLIB) $(COMMON_OBJ)
|
||||
$(COMMON_LINK)
|
||||
|
||||
$(BIN_)compos$E: $(OBJ_)compos.$O $(FTLIB) $(COMMON_OBJ)
|
||||
$(COMMON_LINK)
|
||||
|
||||
$(BIN_)fttry$E: $(OBJ_)fttry.$O $(FTLIB)
|
||||
$(LINK)
|
||||
|
||||
$(BIN_)ftsbit$E: $(OBJ_)ftsbit.$O $(FTLIB)
|
||||
$(LINK)
|
||||
|
||||
$(BIN_)t1dump$E: $(OBJ_)t1dump.$O $(FTLIB)
|
||||
$(LINK)
|
||||
|
||||
$(BIN_)ttdebug$E: $(OBJ_)ttdebug.$O $(FTLIB)
|
||||
$(LINK)
|
||||
|
||||
|
||||
$(BIN_)ftview$E: $(OBJ_)ftview.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
|
||||
$(GRAPH_LINK)
|
||||
|
||||
$(BIN_)ftmulti$E: $(OBJ_)ftmulti.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
|
||||
$(GRAPH_LINK)
|
||||
|
||||
$(BIN_)ftstring$E: $(OBJ_)ftstring.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
|
||||
$(GRAPH_LINK)
|
||||
|
||||
$(BIN_)fttimer$E: $(OBJ_)fttimer.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
|
||||
$(GRAPH_LINK)
|
||||
|
||||
|
||||
endif
|
||||
|
||||
# EOF
|
|
@ -1 +0,0 @@
|
|||
This directory contains all executables for the FreeType demo programs
|
|
@ -1,632 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* graph.h
|
||||
*
|
||||
* Graphics Subsystem interface
|
||||
*
|
||||
* Copyright 1999 - The FreeType Development Team - www.freetype.org
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
#include "grevents.h"
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/******** ********/
|
||||
/******** GENERAL DEFINITIONS AND BLITTING ROUTINES ********/
|
||||
/******** ********/
|
||||
/******** ********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* define the global error variable */
|
||||
extern int grError;
|
||||
|
||||
/* initialisation */
|
||||
extern int grInit( void );
|
||||
|
||||
/* finalisation */
|
||||
extern void grDone( void );
|
||||
|
||||
|
||||
/* pixel mode constants */
|
||||
typedef enum grPixelMode
|
||||
{
|
||||
gr_pixel_mode_none = 0,
|
||||
gr_pixel_mode_mono, /* monochrome bitmaps */
|
||||
gr_pixel_mode_pal4, /* 4-bit paletted - 16 colors */
|
||||
gr_pixel_mode_pal8, /* 8-bit paletted - 256 colors */
|
||||
gr_pixel_mode_gray, /* 8-bit gray levels */
|
||||
gr_pixel_mode_rgb555, /* 15-bits mode - 32768 colors */
|
||||
gr_pixel_mode_rgb565, /* 16-bits mode - 65536 colors */
|
||||
gr_pixel_mode_rgb24, /* 24-bits mode - 16 million colors */
|
||||
gr_pixel_mode_rgb32, /* 32-bits mode - 16 million colors */
|
||||
|
||||
gr_pixel_mode_max /* don't remove */
|
||||
|
||||
} grPixelMode;
|
||||
|
||||
|
||||
/* forward declaration of the surface class */
|
||||
typedef struct grSurface_ grSurface;
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* grBitmap
|
||||
*
|
||||
* <Description>
|
||||
* a simple bitmap descriptor
|
||||
*
|
||||
* <Fields>
|
||||
* rows :: height in pixels
|
||||
* width :: width in pixels
|
||||
* pitch :: + or - the number of bytes per row
|
||||
* mode :: pixel mode of bitmap buffer
|
||||
* grays :: number of grays in palette for PAL8 mode. 0 otherwise
|
||||
* buffer :: pointer to pixel buffer
|
||||
*
|
||||
* <Note>
|
||||
* the 'pitch' is positive for downward flows, and negative otherwise
|
||||
* Its absolute value is always the number of bytes taken by each
|
||||
* bitmap row.
|
||||
*
|
||||
* All drawing operations will be performed within the first
|
||||
* "width" pixels of each row (clipping is always performed).
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
typedef struct grBitmap_
|
||||
{
|
||||
int rows;
|
||||
int width;
|
||||
int pitch;
|
||||
grPixelMode mode;
|
||||
int grays;
|
||||
char* buffer;
|
||||
|
||||
} grBitmap;
|
||||
|
||||
|
||||
|
||||
typedef long grPos;
|
||||
typedef char grBool;
|
||||
|
||||
typedef struct grVector_
|
||||
{
|
||||
grPos x;
|
||||
grPos y;
|
||||
|
||||
} grVector;
|
||||
|
||||
|
||||
typedef union grColor_
|
||||
{
|
||||
long value;
|
||||
unsigned char chroma[4];
|
||||
|
||||
} grColor;
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grNewBitmap
|
||||
*
|
||||
* <Description>
|
||||
* creates a new bitmap
|
||||
*
|
||||
* <Input>
|
||||
* pixel_mode :: the target surface's pixel_mode
|
||||
* num_grays :: number of grays levels for PAL8 pixel mode
|
||||
* width :: width in pixels
|
||||
* height :: height in pixels
|
||||
*
|
||||
* <Output>
|
||||
* bit :: descriptor of the new bitmap
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success.
|
||||
*
|
||||
* <Note>
|
||||
* This function really allocates a pixel buffer, zero it, then
|
||||
* returns a descriptor for it.
|
||||
*
|
||||
* Call grDoneBitmap when you're done with it..
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern int grNewBitmap( grPixelMode pixel_mode,
|
||||
int num_grays,
|
||||
int width,
|
||||
int height,
|
||||
grBitmap *bit );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grBlitGlyphToBitmap
|
||||
*
|
||||
* <Description>
|
||||
* writes a given glyph bitmap to a target surface.
|
||||
*
|
||||
* <Input>
|
||||
* target :: handle to target bitmap
|
||||
* glyph :: handle to source glyph bitmap
|
||||
* x :: position of left-most pixel of glyph image in target surface
|
||||
* y :: position of top-most pixel of glyph image in target surface
|
||||
* color :: color to be used to draw a monochrome glyph
|
||||
*
|
||||
* <Return>
|
||||
* Error code. 0 means success
|
||||
*
|
||||
* <Note>
|
||||
* There are only two supported source pixel modes : monochrome
|
||||
* and gray. The 8-bit images can have any number of grays between
|
||||
* 2 and 128, and conversions to the target surface is handled
|
||||
* _automatically_.
|
||||
*
|
||||
* Note however that you should avoid blitting a gray glyph to a gray
|
||||
* bitmap with fewer levels of grays, as this would much probably
|
||||
* give unpleasant results..
|
||||
*
|
||||
* This function performs clipping
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern int grBlitGlyphToBitmap( grBitmap* target,
|
||||
grBitmap* glyph,
|
||||
grPos x,
|
||||
grPos y,
|
||||
grColor color );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grFillRectangle
|
||||
*
|
||||
* <Description>
|
||||
* this function is used to fill a given rectangle on a surface
|
||||
*
|
||||
* <Input>
|
||||
* surface :: handle to target surface
|
||||
* x :: x coordinate of the top-left corner of the rectangle
|
||||
* y :: y coordinate of the top-left corner of the rectangle
|
||||
* width :: rectangle width in pixels
|
||||
* height :: rectangle height in pixels
|
||||
* color :: fill color
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grFillRectangle( grBitmap* surface,
|
||||
grPos x,
|
||||
grPos y,
|
||||
grPos width,
|
||||
grPos height,
|
||||
grColor color );
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grWriteCellChar
|
||||
*
|
||||
* <Description>
|
||||
* The graphics sub-system contains an internal Latin1 8x8 font
|
||||
* which can be used to display simple strings of text without
|
||||
* using FreeType.
|
||||
*
|
||||
* This function writes a single 8x8 character on the target bitmap.
|
||||
*
|
||||
* <Input>
|
||||
* target :: handle to target surface
|
||||
* x :: x pixel position of character cell's top left corner
|
||||
* y :: y pixel position of character cell's top left corner
|
||||
* charcode :: Latin-1 character code
|
||||
* color :: color to be used to draw the character
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
void grWriteCellChar( grBitmap* target,
|
||||
int x,
|
||||
int y,
|
||||
int charcode,
|
||||
grColor color );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grWriteCellString
|
||||
*
|
||||
* <Description>
|
||||
* The graphics sub-system contains an internal Latin1 8x8 font
|
||||
* which can be used to display simple strings of text without
|
||||
* using FreeType.
|
||||
*
|
||||
* This function writes a string with the internal font
|
||||
*
|
||||
* <Input>
|
||||
* target :: handle to target bitmap
|
||||
* x :: x pixel position of string's top left corner
|
||||
* y :: y pixel position of string's top left corner
|
||||
* string :: Latin-1 text string
|
||||
* color :: color to be used to draw the character
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
void grWriteCellString( grBitmap* target,
|
||||
int x,
|
||||
int y,
|
||||
const char* string,
|
||||
grColor color );
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grDoneBitmap
|
||||
*
|
||||
* <Description>
|
||||
* destroys a bitmap
|
||||
*
|
||||
* <Input>
|
||||
* bitmap :: handle to bitmap descriptor
|
||||
*
|
||||
* <Note>
|
||||
* This function does NOT release the bitmap descriptor, only
|
||||
* the pixel buffer.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grDoneBitmap( grBitmap* bit );
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/******** ********/
|
||||
/******** DEVICE-SPECIFIC DEFINITIONS AND ROUTINES ********/
|
||||
/******** ********/
|
||||
/******** ********/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* forward declaration - the definition of grDevice is not visible */
|
||||
/* to clients.. */
|
||||
typedef struct grDevice_ grDevice;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Struct>
|
||||
* grDeviceChain
|
||||
*
|
||||
* <Description>
|
||||
* a simple structure used to implement a linked list of
|
||||
* graphics device descriptors. The list is called a
|
||||
* "device chain"
|
||||
*
|
||||
* <Fields>
|
||||
* name :: ASCII name of the device, e.g. "x11", "os2pm", etc..
|
||||
* device :: handle to the device descriptor.
|
||||
* next :: next element in chain
|
||||
*
|
||||
* <Note>
|
||||
* the 'device' field is a blind pointer; it is thus unusable by
|
||||
* client applications..
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
typedef struct grDeviceChain_ grDeviceChain;
|
||||
|
||||
struct grDeviceChain_
|
||||
{
|
||||
const char* name;
|
||||
grDevice* device;
|
||||
grDeviceChain* next;
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grInitDevices
|
||||
*
|
||||
* <Description>
|
||||
* This function is in charge of initialising all system-specific
|
||||
* devices. A device is responsible for creating and managing one
|
||||
* or more "surfaces". A surface is either a window or a screen,
|
||||
* depending on the system.
|
||||
*
|
||||
* <Return>
|
||||
* a pointer to the first element of a device chain. The chain can
|
||||
* be parsed to find the available devices on the current system
|
||||
*
|
||||
* <Note>
|
||||
* If a device cannot be initialised correctly, it is not part of
|
||||
* the device chain returned by this function. For example, if an
|
||||
* X11 device was compiled in the library, it will be part of
|
||||
* the returned device chain only if a connection to the display
|
||||
* could be establisged
|
||||
*
|
||||
* If no driver could be initialised, this function returns NULL.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
grDeviceChain* grInitDevices( void );
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grGetDeviceModes
|
||||
*
|
||||
* <Description>
|
||||
* queries the available pixel modes for a device.
|
||||
*
|
||||
* <Input>
|
||||
* device_name :: name of device to be used. 0 for the default
|
||||
* device. For a list of available devices, see
|
||||
* grInitDevices.
|
||||
*
|
||||
* <Output>
|
||||
* num_modes :: number of available modes. 0 in case of error,
|
||||
* which really is an invalid device name.
|
||||
*
|
||||
* pixel_modes :: array of available pixel modes for this device
|
||||
* this table is internal to the device and should
|
||||
* not be freed by client applications.
|
||||
*
|
||||
* <Return>
|
||||
* error code. 0 means success. invalid device name otherwise
|
||||
*
|
||||
* <Note>
|
||||
* All drivers are _required_ to support at least the following
|
||||
* pixel formats :
|
||||
*
|
||||
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
|
||||
* - gr_pixel_mode_gray : with any number of gray levels between
|
||||
* 2 and 256.
|
||||
*
|
||||
* the pixel modes do not provide the number of grays in the case
|
||||
* of "gray" devices. You should try to create a surface with the
|
||||
* maximal number (256, that is) and see the value returned in
|
||||
* the bitmap descriptor.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grGetDeviceModes( const char* device_name,
|
||||
int *num_modes,
|
||||
grPixelMode* *pixel_modes );
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grNewSurface
|
||||
*
|
||||
* <Description>
|
||||
* creates a new device-specific surface. A surface is either
|
||||
* a window or a screen, depending on the device.
|
||||
*
|
||||
* <Input>
|
||||
* device :: name of the device to use. A value of NULL means
|
||||
* the default device (which depends on the system).
|
||||
* for a list of available devices, see grInitDevices.
|
||||
*
|
||||
* <InOut>
|
||||
* bitmap :: handle to a bitmap descriptor containing the
|
||||
* requested pixel mode, number of grays and dimensions
|
||||
* for the surface. the bitmap's 'pitch' and 'buffer'
|
||||
* fields are ignored on input.
|
||||
*
|
||||
* On output, the bitmap describes the surface's image
|
||||
* completely. It is possible to write directly in it
|
||||
* with grBlitGlyphToBitmap, even though the use of
|
||||
* grBlitGlyphToSurface is recommended.
|
||||
*
|
||||
* <Return>
|
||||
* handle to the corresponding surface object. 0 in case of error
|
||||
*
|
||||
* <Note>
|
||||
* All drivers are _required_ to support at least the following
|
||||
* pixel formats :
|
||||
*
|
||||
* - gr_pixel_mode_mono : i.e. monochrome bitmaps
|
||||
* - gr_pixel_mode_gray : with any number of gray levels between
|
||||
* 2 and 256.
|
||||
*
|
||||
* This function might change the bitmap descriptor's fields. For
|
||||
* example, when displaying a full-screen surface, the bitmap's
|
||||
* dimensions will be set to those of the screen (e.g. 640x480
|
||||
* or 800x600); also, the bitmap's 'buffer' field might point to
|
||||
* the Video Ram depending on the mode requested..
|
||||
*
|
||||
* The surface contains a copy of the returned bitmap descriptor,
|
||||
* you can thus discard the 'bitmap' parameter after the call.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern grSurface* grNewSurface( const char* device,
|
||||
grBitmap* bitmap );
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grRefreshRectangle
|
||||
*
|
||||
* <Description>
|
||||
* this function is used to indicate that a given surface rectangle
|
||||
* was modified and thus needs re-painting. It really is useful for
|
||||
* windowed or gray surfaces.
|
||||
*
|
||||
* <Input>
|
||||
* surface :: handle to target surface
|
||||
* x :: x coordinate of the top-left corner of the rectangle
|
||||
* y :: y coordinate of the top-left corner of the rectangle
|
||||
* width :: rectangle width in pixels
|
||||
* height :: rectangle height in pixels
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grRefreshRectangle( grSurface* surface,
|
||||
grPos x,
|
||||
grPos y,
|
||||
grPos width,
|
||||
grPos height );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grRefreshSurface
|
||||
*
|
||||
* <Description>
|
||||
* a variation of grRefreshRectangle which repaints the whole surface
|
||||
* to the screen.
|
||||
*
|
||||
* <Input>
|
||||
* surface :: handle to target surface
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grRefreshSurface( grSurface* surface );
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grWriteSurfaceChar
|
||||
*
|
||||
* <Description>
|
||||
* This function is equivalent to calling grWriteCellChar on the
|
||||
* surface's bitmap, then invoking grRefreshRectangle.
|
||||
*
|
||||
* The graphics sub-system contains an internal Latin1 8x8 font
|
||||
* which can be used to display simple strings of text without
|
||||
* using FreeType.
|
||||
*
|
||||
* This function writes a single 8x8 character on the target bitmap.
|
||||
*
|
||||
* <Input>
|
||||
* target :: handle to target surface
|
||||
* x :: x pixel position of character cell's top left corner
|
||||
* y :: y pixel position of character cell's top left corner
|
||||
* charcode :: Latin-1 character code
|
||||
* color :: color to be used to draw the character
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
void grWriteSurfaceChar( grSurface* target,
|
||||
int x,
|
||||
int y,
|
||||
int charcode,
|
||||
grColor color );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grWriteSurfaceString
|
||||
*
|
||||
* <Description>
|
||||
* This function is equivalent to calling grWriteCellString on the
|
||||
* surface's bitmap, then invoking grRefreshRectangle.
|
||||
*
|
||||
* The graphics sub-system contains an internal Latin1 8x8 font
|
||||
* which can be used to display simple strings of text without
|
||||
* using FreeType.
|
||||
*
|
||||
* This function writes a string with the internal font
|
||||
*
|
||||
* <Input>
|
||||
* target :: handle to target bitmap
|
||||
* x :: x pixel position of string's top left corner
|
||||
* y :: y pixel position of string's top left corner
|
||||
* string :: Latin-1 text string
|
||||
* color :: color to be used to draw the character
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
void grWriteSurfaceString( grSurface* target,
|
||||
int x,
|
||||
int y,
|
||||
const char* string,
|
||||
grColor color );
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grSetTitle
|
||||
*
|
||||
* <Description>
|
||||
* set the window title of a given windowed surface.
|
||||
*
|
||||
* <Input>
|
||||
* surface :: handle to target surface
|
||||
* title_string :: the new title
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern void grSetTitle( grSurface* surface,
|
||||
const char* title_string );
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* <Function>
|
||||
* grListenSurface
|
||||
*
|
||||
* <Description>
|
||||
* listen the events for a given surface
|
||||
*
|
||||
* <Input>
|
||||
* surface :: handle to target surface
|
||||
* event_mask :: the event mask (mode)
|
||||
*
|
||||
* <Output>
|
||||
* event :: the returned event
|
||||
*
|
||||
* <Note>
|
||||
* XXX : For now, only keypresses are supported.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
extern
|
||||
int grListenSurface( grSurface* surface,
|
||||
int event_mask,
|
||||
grEvent *event );
|
||||
|
||||
|
||||
#endif /* GRAPH_H */
|
1268
demos/graph/grblit.c
1268
demos/graph/grblit.c
File diff suppressed because it is too large
Load Diff
|
@ -1,25 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef GRCONFIG_H
|
||||
#define GRCONFIG_H
|
||||
|
||||
#define GR_MAX_SATURATIONS 8
|
||||
#define GR_MAX_CONVERSIONS 16
|
||||
|
||||
#define GR_MAX_DEVICES 8
|
||||
|
||||
#endif /* GRCONFIG_H */
|
|
@ -1,362 +0,0 @@
|
|||
#include "grobjs.h"
|
||||
#include "grdevice.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.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
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -1,117 +0,0 @@
|
|||
#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 */
|
||||
|
|
@ -1,358 +0,0 @@
|
|||
#include "grfont.h"
|
||||
#include <string.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)
|
||||
{
|
||||
grColor color;
|
||||
|
||||
color.value = 127;
|
||||
grWriteCellString( gr_text_bitmap,
|
||||
gr_margin_right + (gr_cursor_x << 3),
|
||||
gr_margin_top + (gr_cursor_y << 3),
|
||||
string,
|
||||
color );
|
||||
|
||||
gr_cursor_x += strlen(string);
|
||||
}
|
||||
}
|
||||
|
||||
extern void grLn()
|
||||
{
|
||||
gr_cursor_y ++;
|
||||
gr_cursor_x = 0;
|
||||
}
|
||||
|
||||
extern void grWriteln( const char* string )
|
||||
{
|
||||
grWrite( string );
|
||||
grLn();
|
||||
}
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#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 */
|
|
@ -1,85 +0,0 @@
|
|||
#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
|
||||
|
||||
#ifdef DEVICE_WIN32
|
||||
#include "grwin32.h"
|
||||
#endif
|
||||
|
||||
#ifdef macintosh
|
||||
#include "grmac.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)
|
||||
{
|
||||
/* initialize 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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
#include "grobjs.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -1,52 +0,0 @@
|
|||
/***************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -1,348 +0,0 @@
|
|||
/*******************************************************************
|
||||
*
|
||||
* grmac.c graphics driver for MacOS platform. 0.1
|
||||
*
|
||||
* This is the driver for displaying inside a window under MacOS,
|
||||
* used by the graphics utility of the FreeType test suite.
|
||||
*
|
||||
* Largely written by Just van Rossum, but derived from grwin32.c.
|
||||
* Copyright 1999-2000 by Just van Rossum, Antoine Leca,
|
||||
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
*
|
||||
* Borrowing liberally from the other FreeType drivers.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
/* ANSI C */
|
||||
#include <string.h>
|
||||
|
||||
/* Mac Toolbox */
|
||||
#include <Windows.h>
|
||||
|
||||
/* FT graphics subsystem */
|
||||
#include "grmac.h"
|
||||
#include "grdevice.h"
|
||||
|
||||
/* CodeWarrior's poor excuse for a console */
|
||||
#include <SIOUX.h>
|
||||
|
||||
|
||||
/* Mac function key definitions. The 0x100 is a kludge, see listen_event(). */
|
||||
#define KEY_F1 (0x7A | 0x100)
|
||||
#define KEY_F2 (0x78 | 0x100)
|
||||
#define KEY_F3 (0x63 | 0x100)
|
||||
#define KEY_F4 (0x76 | 0x100)
|
||||
#define KEY_F5 (0x60 | 0x100)
|
||||
#define KEY_F6 (0x61 | 0x100)
|
||||
#define KEY_F7 (0x62 | 0x100)
|
||||
#define KEY_F8 (0x64 | 0x100)
|
||||
#define KEY_F9 (0x65 | 0x100)
|
||||
#define KEY_F10 (0x6D | 0x100)
|
||||
#define KEY_F11 (0x67 | 0x100)
|
||||
#define KEY_F12 (0x6F | 0x100)
|
||||
#define KEY_F13 (0x69 | 0x100)
|
||||
#define KEY_F14 (0x6B | 0x100)
|
||||
#define KEY_F15 (0x71 | 0x100)
|
||||
|
||||
|
||||
/* Mac to FT key mapping */
|
||||
|
||||
typedef struct _Translator
|
||||
{
|
||||
short mackey;
|
||||
grKey grkey;
|
||||
|
||||
} Translator;
|
||||
|
||||
static
|
||||
Translator key_translators[] =
|
||||
{
|
||||
{ kBackspaceCharCode, grKeyBackSpace },
|
||||
{ kTabCharCode, grKeyTab },
|
||||
{ kReturnCharCode, grKeyReturn },
|
||||
{ kEscapeCharCode, grKeyEsc },
|
||||
{ kHomeCharCode, grKeyHome },
|
||||
{ kLeftArrowCharCode, grKeyLeft },
|
||||
{ kUpArrowCharCode, grKeyUp },
|
||||
{ kRightArrowCharCode, grKeyRight },
|
||||
{ kDownArrowCharCode, grKeyDown },
|
||||
{ kPageUpCharCode, grKeyPageUp },
|
||||
{ kPageDownCharCode, grKeyPageDown },
|
||||
{ kEndCharCode, grKeyEnd },
|
||||
{ kHelpCharCode, grKeyF1 }, /* map Help key to F1... */
|
||||
{ KEY_F1, grKeyF1 },
|
||||
{ KEY_F2, grKeyF2 },
|
||||
{ KEY_F3, grKeyF3 },
|
||||
{ KEY_F4, grKeyF4 },
|
||||
{ KEY_F5, grKeyF5 },
|
||||
{ KEY_F6, grKeyF6 },
|
||||
{ KEY_F7, grKeyF7 },
|
||||
{ KEY_F8, grKeyF8 },
|
||||
{ KEY_F9, grKeyF9 },
|
||||
{ KEY_F10, grKeyF10 },
|
||||
{ KEY_F11, grKeyF11 },
|
||||
{ KEY_F12, grKeyF12 }
|
||||
};
|
||||
|
||||
|
||||
/* This is a minimalist driver, it is only able to display */
|
||||
/* a _single_ window. Moreover, only monochrome and gray */
|
||||
/* bitmaps are supported.. */
|
||||
|
||||
/* pointer to the window. */
|
||||
static WindowPtr theWindow = NULL;
|
||||
|
||||
/* the pixmap */
|
||||
static PixMap thePixMap;
|
||||
|
||||
|
||||
/* destroys the window */
|
||||
static
|
||||
void done_window( )
|
||||
{
|
||||
if ( theWindow )
|
||||
{
|
||||
DisposeWindow ( theWindow );
|
||||
}
|
||||
theWindow = NULL;
|
||||
}
|
||||
|
||||
/* destroys the surface*/
|
||||
static
|
||||
void done_surface( grSurface* surface )
|
||||
{
|
||||
/* ick! this never gets called... */
|
||||
done_window();
|
||||
grDoneBitmap( &surface->bitmap );
|
||||
}
|
||||
|
||||
static
|
||||
void refresh_rectangle( grSurface* surface,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h )
|
||||
{
|
||||
Rect bounds;
|
||||
SetRect( &bounds, x, y, x+w, y+h );
|
||||
if ( theWindow )
|
||||
CopyBits( (BitMap*)&thePixMap, &theWindow->portBits,
|
||||
&bounds, &bounds, srcCopy, theWindow->visRgn );
|
||||
}
|
||||
|
||||
static
|
||||
void set_title( grSurface* surface, const char* title )
|
||||
{
|
||||
Str255 pTitle;
|
||||
strcpy( (char*)pTitle+1, title );
|
||||
pTitle[0] = strlen( title );
|
||||
if ( theWindow )
|
||||
SetWTitle( theWindow, pTitle );
|
||||
}
|
||||
|
||||
static
|
||||
void listen_event( grSurface* surface,
|
||||
int event_mask,
|
||||
grEvent* grevent )
|
||||
{
|
||||
grEvent our_grevent;
|
||||
EventRecord mac_event;
|
||||
short theEventMask = keyDownMask | autoKeyMask /* | updateEvtMask */ ;
|
||||
|
||||
our_grevent.type = gr_event_none;
|
||||
our_grevent.key = grKeyNone;
|
||||
|
||||
for ( ;; )
|
||||
/* The event loop. Sorry, but I'm too lazy to split the various events
|
||||
to proper event handler functions. This whole app is rather ad hoc
|
||||
anyway, so who cares ;-) */
|
||||
{
|
||||
if ( WaitNextEvent( everyEvent, &mac_event, 10, NULL ) )
|
||||
{
|
||||
switch ( mac_event.what )
|
||||
{
|
||||
case autoKey:
|
||||
case keyDown:
|
||||
{
|
||||
int count = sizeof( key_translators ) / sizeof( key_translators[0] );
|
||||
Translator* trans = key_translators;
|
||||
Translator* limit = trans + count;
|
||||
short char_code;
|
||||
|
||||
char_code = mac_event.message & charCodeMask;
|
||||
if ( char_code == kFunctionKeyCharCode )
|
||||
/* Le kluge. Add a flag to differentiate the F-keys from normal keys. */
|
||||
char_code = 0x100 | ((mac_event.message & keyCodeMask) >> 8);
|
||||
|
||||
our_grevent.key = char_code;
|
||||
|
||||
for ( ; trans < limit; trans++ )
|
||||
/* see if the key maps to a special "gr" key */
|
||||
if ( char_code == trans->mackey )
|
||||
{
|
||||
our_grevent.key = trans->grkey;
|
||||
}
|
||||
our_grevent.type = gr_event_key;
|
||||
}
|
||||
if ( our_grevent.key == grKEY('q') || our_grevent.key == grKeyEsc )
|
||||
/* destroy the window here, since done_surface() doesn't get called */
|
||||
done_window();
|
||||
*grevent = our_grevent;
|
||||
return;
|
||||
case updateEvt:
|
||||
if ( theWindow && (WindowPtr)mac_event.message == theWindow )
|
||||
{
|
||||
SetPort( theWindow );
|
||||
BeginUpdate( theWindow );
|
||||
refresh_rectangle( surface,
|
||||
0, 0,
|
||||
thePixMap.bounds.right, thePixMap.bounds.bottom );
|
||||
EndUpdate( theWindow );
|
||||
}
|
||||
else
|
||||
{
|
||||
SIOUXHandleOneEvent( &mac_event );
|
||||
}
|
||||
break;
|
||||
case mouseDown:
|
||||
{
|
||||
short part;
|
||||
WindowPtr wid;
|
||||
|
||||
part = FindWindow( mac_event.where, &wid );
|
||||
if ( wid == theWindow )
|
||||
{
|
||||
if ( theWindow && part == inDrag)
|
||||
DragWindow( wid, mac_event.where, &qd.screenBits.bounds );
|
||||
else if (part == inGoAway)
|
||||
{
|
||||
if ( TrackGoAway( theWindow, mac_event.where ) )
|
||||
{
|
||||
/* The user clicked the window away, emulate quit event */
|
||||
done_window();
|
||||
our_grevent.type = gr_event_key;
|
||||
our_grevent.key = grKeyEsc;
|
||||
*grevent = our_grevent;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (part == inContent)
|
||||
{
|
||||
SelectWindow( theWindow );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SIOUXHandleOneEvent( &mac_event );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
InitCursor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
grSurface* init_surface( grSurface* surface,
|
||||
grBitmap* bitmap )
|
||||
{
|
||||
Rect bounds;
|
||||
SetRect(&bounds, 0, 0, bitmap->width, bitmap->rows);
|
||||
|
||||
/* create the bitmap - under MacOS, we support all modes as the GDI */
|
||||
/* handles all conversions automatically.. */
|
||||
if ( grNewBitmap( bitmap->mode,
|
||||
bitmap->grays,
|
||||
bitmap->width,
|
||||
bitmap->rows,
|
||||
bitmap ) )
|
||||
return 0;
|
||||
|
||||
surface->bitmap = *bitmap;
|
||||
|
||||
/* initialize the PixMap to appropriate values */
|
||||
thePixMap.baseAddr = bitmap->buffer;
|
||||
thePixMap.rowBytes = bitmap->pitch;
|
||||
if (thePixMap.rowBytes < 0)
|
||||
thePixMap.rowBytes = -thePixMap.rowBytes;
|
||||
thePixMap.rowBytes |= 0x8000; /* flag indicating it's a PixMap, not a BitMap */
|
||||
thePixMap.bounds = bounds;
|
||||
thePixMap.pmVersion = 0;
|
||||
thePixMap.packType = 0;
|
||||
thePixMap.packSize = 0;
|
||||
thePixMap.hRes = 72 << 16;
|
||||
thePixMap.vRes = 72 << 16;
|
||||
thePixMap.pixelType = 0;
|
||||
thePixMap.cmpCount = 1;
|
||||
thePixMap.pmTable = 0;
|
||||
thePixMap.planeBytes = 0;
|
||||
thePixMap.pmReserved = 0;
|
||||
|
||||
switch ( bitmap->mode )
|
||||
{
|
||||
case gr_pixel_mode_mono:
|
||||
thePixMap.cmpSize = 1;
|
||||
thePixMap.pixelSize = 1;
|
||||
break;
|
||||
|
||||
case gr_pixel_mode_gray:
|
||||
thePixMap.cmpSize = 8;
|
||||
thePixMap.pixelSize = 8;
|
||||
thePixMap.pmTable = GetCTable(256); /* color palette matching FT's idea
|
||||
of grayscale. See ftview.rsrc */
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0; /* Unknown mode */
|
||||
}
|
||||
|
||||
/* create the window */
|
||||
OffsetRect(&bounds, 10, 44); /* place it at a decent location */
|
||||
theWindow = NewCWindow(NULL, &bounds, "\p???", 1, 0, (GrafPtr)-1, 1, 0);
|
||||
|
||||
/* fill in surface interface */
|
||||
surface->done = (grDoneSurfaceFunc) done_surface;
|
||||
surface->refresh_rect = (grRefreshRectFunc) refresh_rectangle;
|
||||
surface->set_title = (grSetTitleFunc) set_title;
|
||||
surface->listen_event = (grListenEventFunc) listen_event;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
static int init_device( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void done_device( void )
|
||||
{
|
||||
/* won't get called either :-( */
|
||||
}
|
||||
|
||||
grDevice gr_mac_device =
|
||||
{
|
||||
sizeof( grSurface ),
|
||||
"mac",
|
||||
|
||||
init_device,
|
||||
done_device,
|
||||
|
||||
(grDeviceInitSurfaceFunc) init_surface,
|
||||
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* End */
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef GRMAC_H
|
||||
#define GRMAC_H
|
||||
|
||||
#include "grobjs.h"
|
||||
|
||||
extern
|
||||
grDevice gr_mac_device;
|
||||
|
||||
#ifdef GR_INIT_BUILD
|
||||
static
|
||||
grDeviceChain gr_mac_device_chain =
|
||||
{
|
||||
"mac",
|
||||
&gr_mac_device,
|
||||
GR_INIT_DEVICE_CHAIN
|
||||
};
|
||||
|
||||
#undef GR_INIT_DEVICE_CHAIN
|
||||
#define GR_INIT_DEVICE_CHAIN &gr_mac_device_chain
|
||||
|
||||
#endif /* GR_INIT_BUILD */
|
||||
|
||||
#endif /* GRMAC_H */
|
|
@ -1,304 +0,0 @@
|
|||
<!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>
|
|
@ -1,754 +0,0 @@
|
|||
#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>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define DEBUGxxx
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(x) LogMessage##x
|
||||
#else
|
||||
#define LOG(x) /* rien */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void LogMessage( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
#endif
|
||||
|
||||
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 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;
|
||||
|
||||
/* we use a static variable to pass a pointer to the PM Surface */
|
||||
/* to the client window. This is a bit ugly, but it makes things */
|
||||
/* a lot more simple.. */
|
||||
static grPMSurface* the_surface;
|
||||
|
||||
static int window_created = 0;
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
LOG(( "Os2PM: done_surface(%08lx)\n", (long)surface ));
|
||||
|
||||
if ( surface->frame_window )
|
||||
WinDestroyWindow( surface->frame_window );
|
||||
|
||||
WinReleasePS( surface->image_ps );
|
||||
|
||||
grDoneBitmap( &surface->image );
|
||||
grDoneBitmap( &surface->root.bitmap );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#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 the graph library 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 refresh_rectangle( grPMSurface* surface,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h )
|
||||
{
|
||||
LOG(( "Os2PM: refresh_rectangle( %08lx, %d, %d, %d, %d )\n",
|
||||
(long)surface, x, y, w, h ));
|
||||
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)w;
|
||||
(void)h;
|
||||
|
||||
/*
|
||||
convert_rectangle( surface, x, y, w, h );
|
||||
*/
|
||||
DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
|
||||
GpiSetBitmapBits( surface->image_ps,
|
||||
0,
|
||||
surface->root.bitmap.rows,
|
||||
surface->root.bitmap.buffer,
|
||||
surface->bitmap_header );
|
||||
DosReleaseMutexSem( surface->image_lock );
|
||||
|
||||
WinInvalidateRect( surface->client_window, NULL, FALSE );
|
||||
WinUpdateWindow( surface->frame_window );
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void set_title( grPMSurface* surface,
|
||||
const char* title )
|
||||
{
|
||||
ULONG rc;
|
||||
|
||||
#if 1
|
||||
LOG(( "Os2PM: set_title( %08lx == %08lx, %s )\n",
|
||||
(long)surface, surface->client_window, title ));
|
||||
#endif
|
||||
LOG(( " -- frame = %08lx\n",
|
||||
(long)surface->frame_window ));
|
||||
|
||||
LOG(( " -- client parent = %08lx\n",
|
||||
(long)WinQueryWindow( surface->client_window, QW_PARENT ) ));
|
||||
|
||||
rc = WinSetWindowText( surface->client_window, (PSZ)title );
|
||||
LOG(( " -- returned rc = %ld\n",rc ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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];
|
||||
|
||||
LOG(( "Os2PM: init_surface( %08lx, %08lx )\n",
|
||||
(long)surface, (long)bitmap ));
|
||||
|
||||
LOG(( " -- input bitmap =\n" ));
|
||||
LOG(( " -- mode = %d\n", bitmap->mode ));
|
||||
LOG(( " -- grays = %d\n", bitmap->grays ));
|
||||
LOG(( " -- width = %d\n", bitmap->width ));
|
||||
LOG(( " -- height = %d\n", bitmap->rows ));
|
||||
|
||||
/* 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;
|
||||
|
||||
LOG(( " -- output bitmap =\n" ));
|
||||
LOG(( " -- mode = %d\n", bitmap->mode ));
|
||||
LOG(( " -- grays = %d\n", bitmap->grays ));
|
||||
LOG(( " -- width = %d\n", bitmap->width ));
|
||||
LOG(( " -- height = %d\n", bitmap->rows ));
|
||||
|
||||
bitmap->pitch = -bitmap->pitch;
|
||||
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 = 255;
|
||||
bit->argbColor[0].bGreen = 0;
|
||||
bit->argbColor[0].bRed = 0;
|
||||
|
||||
bit->argbColor[1].bBlue = 0;
|
||||
bit->argbColor[1].bGreen = 255;
|
||||
bit->argbColor[1].bRed = 0;
|
||||
|
||||
bit->cBitCount = (bitmap->mode == gr_pixel_mode_gray ? 8 : 1 );
|
||||
|
||||
if (bitmap->mode == gr_pixel_mode_gray)
|
||||
{
|
||||
RGB2* color = bit->argbColor;
|
||||
int x, count;
|
||||
|
||||
count = bitmap->grays;
|
||||
for ( x = 0; x < count; x++, color++ )
|
||||
{
|
||||
color->bBlue =
|
||||
color->bGreen =
|
||||
color->bRed = (((count-x)*255)/count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RGB2* color = bit->argbColor;
|
||||
|
||||
color[0].bBlue =
|
||||
color[0].bGreen =
|
||||
color[0].bRed = 0;
|
||||
|
||||
color[1].bBlue =
|
||||
color[1].bGreen =
|
||||
color[1].bRed = 255;
|
||||
}
|
||||
|
||||
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 );
|
||||
surface->bitmap_header = 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];
|
||||
|
||||
window_created = 0;
|
||||
|
||||
/* Finally, create the event handling thread for the surface's window */
|
||||
DosCreateThread( &surface->message_thread,
|
||||
(PFNTHREAD) RunPMWindow,
|
||||
(ULONG) surface,
|
||||
0UL,
|
||||
32920 );
|
||||
|
||||
/* wait for the window creation */
|
||||
for ( ; window_created == 0; )
|
||||
|
||||
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;
|
||||
|
||||
/* store the current surface pointer in "the_surface". It is a static */
|
||||
/* variable that is only used to retrieve the pointer in the client */
|
||||
/* window procedure the first time is is called.. */
|
||||
the_surface = surface;
|
||||
|
||||
LOG(( "Os2PM: RunPMWindow( %08lx )\n", (long)surface ));
|
||||
|
||||
/* 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;
|
||||
|
||||
LOG(( "Os2PM: RunPMWindow: Creating window\n" ));
|
||||
surface->frame_window = WinCreateStdWindow(
|
||||
HWND_DESKTOP,
|
||||
WS_VISIBLE,
|
||||
&class_flags,
|
||||
(PSZ) class_name,
|
||||
(PSZ) "FreeType Viewer - press F1 for help",
|
||||
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 );
|
||||
LOG (( "Os2PM: RunPMWIndow: Creation succeeded\n" ));
|
||||
LOG (( " -- frame = %08lx\n", surface->frame_window ));
|
||||
LOG (( " -- client = %08lx\n", surface->client_window ));
|
||||
|
||||
/* 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 );
|
||||
|
||||
#if 0
|
||||
/* save the handle to the current surface within the window words */
|
||||
WinSetWindowPtr( surface->client_window,QWL_USER, surface );
|
||||
#endif
|
||||
|
||||
window_created = 1;
|
||||
|
||||
/* 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 -- note that this */
|
||||
/* value will be null when the window is created */
|
||||
surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
|
||||
if (!surface)
|
||||
{
|
||||
surface = the_surface;
|
||||
WinSetWindowPtr( handle, QWL_USER, surface );
|
||||
}
|
||||
|
||||
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 );
|
||||
LOG(( "screen_dc and screen_ps have been created\n" ));
|
||||
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_HELP: /* this really is a F1 Keypress !! */
|
||||
surface->event.key = grKeyF1;
|
||||
goto Do_Key_Event;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
grDevice gr_os2pm_device =
|
||||
{
|
||||
sizeof( grPMSurface ),
|
||||
"os2pm",
|
||||
|
||||
init_device,
|
||||
done_device,
|
||||
|
||||
(grDeviceInitSurfaceFunc) init_surface,
|
||||
|
||||
0,
|
||||
0
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
NAME WINDOWCOMPAT
|
||||
|
||||
DESCRIPTION 'FreeType Graphics'
|
||||
HEAPSIZE 8192
|
||||
STACKSIZE 40888
|
|
@ -1,23 +0,0 @@
|
|||
#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 */
|
|
@ -1,32 +0,0 @@
|
|||
#**************************************************************************
|
||||
#*
|
||||
#* OS/2 specific rules file, used to compile the OS/2 graphics driver
|
||||
#* to the graphics subsystem
|
||||
#*
|
||||
#**************************************************************************
|
||||
|
||||
ifeq ($(PLATFORM),os2)
|
||||
|
||||
GR_OS2 := $(GRAPH_)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
|
||||
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
#**************************************************************************
|
||||
#*
|
||||
#* 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 := $(TOP2_)graph
|
||||
GRAPH_LIB := $(OBJ_)graph.$A
|
||||
#GRAPH_LINK := $(GRAPH_LIB)
|
||||
|
||||
GRAPH_ := $(TOP2_)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
|
||||
|
||||
|
||||
# Default value for COMPILE_GRAPH_LIB
|
||||
# this value can be modified by the system-specific graphics drivers..
|
||||
#
|
||||
COMPILE_GRAPH_LIB = ar -r $@ $(GRAPH_OBJS)
|
||||
|
||||
# Add the rules used to detect and compile graphics driver depending
|
||||
# on the current platform..
|
||||
#
|
||||
include $(wildcard $(TOP2)/graph/*/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 now, I'll stick to
|
||||
# unix, Win32 and OS/2-gcc..
|
||||
#
|
||||
#
|
||||
$(GRAPH_LIB): $(GRAPH_OBJS)
|
||||
$(COMPILE_GRAPH_LIB)
|
||||
|
||||
|
||||
# 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 $(GRAPH_H)
|
||||
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) \
|
||||
$(DEVICE_INCLUDES:%=$I%) \
|
||||
$(DEVICES:%=$DDEVICE_%) $T$@ $<
|
||||
|
|
@ -1,525 +0,0 @@
|
|||
/*******************************************************************
|
||||
*
|
||||
* grwin32.c graphics driver for Win32 platform. 0.1
|
||||
*
|
||||
* This is the driver for displaying inside a window under Win32,
|
||||
* used by the graphics utility of the FreeType test suite.
|
||||
*
|
||||
* Written by Antoine Leca.
|
||||
* Copyright 1999-2000 by Antoine Leca, David Turner
|
||||
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
*
|
||||
* Borrowing liberally from the other FreeType drivers.
|
||||
*
|
||||
* 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>
|
||||
#include <string.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "grwin32.h"
|
||||
#include "grdevice.h"
|
||||
|
||||
|
||||
/* logging facility */
|
||||
#include <stdarg.h>
|
||||
|
||||
#define DEBUGxxx
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(x) LogMessage##x
|
||||
#else
|
||||
#define LOG(x) /* rien */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void LogMessage( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
#endif
|
||||
/*-------------------*/
|
||||
|
||||
/* Size of the window. */
|
||||
#define WIN_WIDTH 640u
|
||||
#define WIN_HEIGHT 450u
|
||||
|
||||
/* These values can be changed, but WIN_WIDTH should remain for now a */
|
||||
/* multiple of 32 to avoid padding issues. */
|
||||
|
||||
typedef struct _Translator
|
||||
{
|
||||
ULONG winkey;
|
||||
grKey grkey;
|
||||
|
||||
} Translator;
|
||||
|
||||
static
|
||||
Translator key_translators[] =
|
||||
{
|
||||
{ VK_BACK, grKeyBackSpace },
|
||||
{ VK_TAB, grKeyTab },
|
||||
{ VK_RETURN, grKeyReturn },
|
||||
{ VK_ESCAPE, grKeyEsc },
|
||||
{ VK_HOME, grKeyHome },
|
||||
{ VK_LEFT, grKeyLeft },
|
||||
{ VK_UP, grKeyUp },
|
||||
{ VK_RIGHT, grKeyRight },
|
||||
{ VK_DOWN, grKeyDown },
|
||||
{ VK_PRIOR, grKeyPageUp },
|
||||
{ VK_NEXT, 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 }
|
||||
};
|
||||
|
||||
static
|
||||
Translator syskey_translators[] =
|
||||
{
|
||||
{ VK_F1, grKeyF1 }
|
||||
};
|
||||
|
||||
/* This is a minimalist driver, it is only able to display */
|
||||
/* a _single_ window. Moreover, only monochrome and gray */
|
||||
/* bitmaps are supported.. */
|
||||
|
||||
/* handle of the window. */
|
||||
static HWND hwndGraphic;
|
||||
|
||||
static int window_width, window_height;
|
||||
|
||||
/* the following variables are used to set the window title lazily */
|
||||
static int title_set = 1;
|
||||
static const char* the_title;
|
||||
|
||||
/* bitmap information */
|
||||
static LPBITMAPINFO pbmi;
|
||||
static HBITMAP hbm;
|
||||
|
||||
/* local event to pass on */
|
||||
static grEvent ourevent;
|
||||
static int eventToProcess = 0;
|
||||
|
||||
/* destroys the surface*/
|
||||
static
|
||||
void done_surface( grSurface* surface )
|
||||
{
|
||||
/* The graphical window has perhaps already destroyed itself */
|
||||
if ( hwndGraphic )
|
||||
{
|
||||
DestroyWindow ( hwndGraphic );
|
||||
PostMessage( hwndGraphic, WM_QUIT, 0, 0 );
|
||||
}
|
||||
grDoneBitmap( &surface->bitmap );
|
||||
if ( pbmi ) free ( pbmi );
|
||||
}
|
||||
|
||||
static
|
||||
const int pixel_mode_bit_count[] =
|
||||
{
|
||||
0,
|
||||
1, /* mono */
|
||||
4, /* pal4 */
|
||||
8, /* pal8 */
|
||||
8, /* grays */
|
||||
15, /* rgb15 */
|
||||
16, /* rgb16 */
|
||||
24, /* rgb24 */
|
||||
32 /* rgb32 */
|
||||
};
|
||||
|
||||
static
|
||||
void refresh_rectangle( grSurface* surface,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h )
|
||||
{
|
||||
HDC hDC;
|
||||
int row_bytes;
|
||||
|
||||
LOG(( "Win32: refresh_rectangle( %08lx, %d, %d, %d, %d )\n",
|
||||
(long)surface, x, y, w, h ));
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)w;
|
||||
(void)h;
|
||||
|
||||
row_bytes = surface->bitmap.pitch;
|
||||
if (row_bytes < 0) row_bytes = -row_bytes;
|
||||
|
||||
if ( row_bytes*8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount )
|
||||
pbmi->bmiHeader.biWidth = row_bytes * 8 / pbmi->bmiHeader.biBitCount;
|
||||
|
||||
hDC = GetDC ( hwndGraphic );
|
||||
SetDIBits ( hDC, hbm,
|
||||
0,
|
||||
surface->bitmap.rows,
|
||||
surface->bitmap.buffer,
|
||||
pbmi,
|
||||
DIB_RGB_COLORS );
|
||||
|
||||
ReleaseDC ( hwndGraphic, hDC );
|
||||
|
||||
ShowWindow( hwndGraphic, SW_SHOW );
|
||||
InvalidateRect ( hwndGraphic, NULL, FALSE );
|
||||
UpdateWindow ( hwndGraphic );
|
||||
}
|
||||
|
||||
static
|
||||
void set_title( grSurface* surface, const char* title )
|
||||
{
|
||||
(void)surface;
|
||||
|
||||
/* the title will be set on the next listen_event, just */
|
||||
/* record it there.. */
|
||||
the_title = title;
|
||||
title_set = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void listen_event( grSurface* surface,
|
||||
int event_mask,
|
||||
grEvent* grevent )
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
(void)surface;
|
||||
(void)event_mask;
|
||||
|
||||
if ( hwndGraphic && !title_set )
|
||||
{
|
||||
SetWindowText( hwndGraphic, the_title );
|
||||
title_set = 1;
|
||||
}
|
||||
|
||||
eventToProcess = 0;
|
||||
while (GetMessage( &msg, 0, 0, 0 ))
|
||||
{
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
if (eventToProcess)
|
||||
break;
|
||||
}
|
||||
|
||||
*grevent = ourevent;
|
||||
}
|
||||
|
||||
/*
|
||||
* set graphics mode
|
||||
* and create the window class and the message handling.
|
||||
*/
|
||||
|
||||
/* Declarations of the Windows-specific functions that are below. */
|
||||
static BOOL RegisterTheClass ( void );
|
||||
static BOOL CreateTheWindow ( int width, int height );
|
||||
|
||||
static
|
||||
grSurface* init_surface( grSurface* surface,
|
||||
grBitmap* bitmap )
|
||||
{
|
||||
static RGBQUAD black = { 0, 0, 0, 0 };
|
||||
static RGBQUAD white = { 0xFF, 0xFF, 0xFF, 0 };
|
||||
|
||||
if( ! RegisterTheClass() ) return 0; /* if already running, fails. */
|
||||
|
||||
/* find some memory for the bitmap header */
|
||||
if ( (pbmi = malloc ( sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ) )
|
||||
/* 256 should really be 2 if not grayscale */
|
||||
== NULL )
|
||||
/* lack of memory; fails the process */
|
||||
return 0;
|
||||
|
||||
LOG(( "Win32: init_surface( %08lx, %08lx )\n",
|
||||
(long)surface, (long)bitmap ));
|
||||
|
||||
LOG(( " -- input bitmap =\n" ));
|
||||
LOG(( " -- mode = %d\n", bitmap->mode ));
|
||||
LOG(( " -- grays = %d\n", bitmap->grays ));
|
||||
LOG(( " -- width = %d\n", bitmap->width ));
|
||||
LOG(( " -- height = %d\n", bitmap->rows ));
|
||||
|
||||
/* create the bitmap - under Win32, we support all modes as the GDI */
|
||||
/* handles all conversions automatically.. */
|
||||
if ( grNewBitmap( bitmap->mode,
|
||||
bitmap->grays,
|
||||
bitmap->width,
|
||||
bitmap->rows,
|
||||
bitmap ) )
|
||||
return 0;
|
||||
|
||||
LOG(( " -- output bitmap =\n" ));
|
||||
LOG(( " -- mode = %d\n", bitmap->mode ));
|
||||
LOG(( " -- grays = %d\n", bitmap->grays ));
|
||||
LOG(( " -- width = %d\n", bitmap->width ));
|
||||
LOG(( " -- height = %d\n", bitmap->rows ));
|
||||
|
||||
bitmap->pitch = -bitmap->pitch;
|
||||
surface->bitmap = *bitmap;
|
||||
|
||||
/* initialize the header to appropriate values */
|
||||
memset( pbmi, 0, sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 );
|
||||
|
||||
switch ( bitmap->mode )
|
||||
{
|
||||
case gr_pixel_mode_mono:
|
||||
pbmi->bmiHeader.biBitCount = 1;
|
||||
pbmi->bmiColors[0] = white;
|
||||
pbmi->bmiColors[1] = black;
|
||||
break;
|
||||
|
||||
case gr_pixel_mode_gray:
|
||||
pbmi->bmiHeader.biBitCount = 8;
|
||||
pbmi->bmiHeader.biClrUsed = bitmap->grays;
|
||||
{
|
||||
int count = bitmap->grays;
|
||||
int x;
|
||||
RGBQUAD* color = pbmi->bmiColors;
|
||||
|
||||
for ( x = 0; x < count; x++, color++ )
|
||||
{
|
||||
color->rgbRed =
|
||||
color->rgbGreen =
|
||||
color->rgbBlue = (((count-x)*255)/count);
|
||||
color->rgbReserved = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
free ( pbmi );
|
||||
return 0; /* Unknown mode */
|
||||
}
|
||||
|
||||
pbmi->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER );
|
||||
pbmi->bmiHeader.biWidth = bitmap->width;
|
||||
pbmi->bmiHeader.biHeight = bitmap->rows;
|
||||
pbmi->bmiHeader.biPlanes = 1;
|
||||
|
||||
if( ! CreateTheWindow( bitmap->width, bitmap->rows ) )
|
||||
{
|
||||
free ( pbmi );
|
||||
return 0;
|
||||
}
|
||||
|
||||
surface->done = (grDoneSurfaceFunc) done_surface;
|
||||
surface->refresh_rect = (grRefreshRectFunc) refresh_rectangle;
|
||||
surface->set_title = (grSetTitleFunc) set_title;
|
||||
surface->listen_event = (grListenEventFunc) listen_event;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
/* ---- Windows-specific stuff ------------------------------------------- */
|
||||
|
||||
LRESULT CALLBACK Message_Process( HWND, UINT, WPARAM, LPARAM );
|
||||
|
||||
static
|
||||
BOOL RegisterTheClass ( void )
|
||||
{
|
||||
WNDCLASS ourClass = {
|
||||
/* UINT style */ 0,
|
||||
/* WNDPROC lpfnWndProc */ Message_Process,
|
||||
/* int cbClsExtra */ 0,
|
||||
/* int cbWndExtra */ 0,
|
||||
/* HANDLE hInstance */ 0,
|
||||
/* HICON hIcon */ 0,
|
||||
/* HCURSOR hCursor */ 0,
|
||||
/* HBRUSH hbrBackground*/ 0,
|
||||
/* LPCTSTR lpszMenuName */ NULL,
|
||||
/* LPCTSTR lpszClassName*/ "FreeTypeTestGraphicDriver"
|
||||
};
|
||||
|
||||
ourClass.hInstance = GetModuleHandle( NULL );
|
||||
ourClass.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
ourClass.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
ourClass.hbrBackground= GetStockObject(BLACK_BRUSH);
|
||||
|
||||
return RegisterClass(&ourClass) != 0; /* return False if it fails. */
|
||||
}
|
||||
|
||||
static
|
||||
BOOL CreateTheWindow ( int width, int height )
|
||||
{
|
||||
window_width = width;
|
||||
window_height = height;
|
||||
|
||||
if ( ! (hwndGraphic = CreateWindow(
|
||||
/* LPCSTR lpszClassName; */ "FreeTypeTestGraphicDriver",
|
||||
/* LPCSTR lpszWindowName; */ "FreeType Test Graphic Driver",
|
||||
/* DWORD dwStyle; */ WS_OVERLAPPED | WS_SYSMENU,
|
||||
/* int x; */ CW_USEDEFAULT,
|
||||
/* int y; */ CW_USEDEFAULT,
|
||||
/* int nWidth; */ width + 2*GetSystemMetrics(SM_CXBORDER),
|
||||
/* int nHeight; */ height+ GetSystemMetrics(SM_CYBORDER)
|
||||
+ GetSystemMetrics(SM_CYCAPTION),
|
||||
/* HWND hwndParent; */ HWND_DESKTOP,
|
||||
/* HMENU hmenu; */ 0,
|
||||
/* HINSTANCE hinst; */ GetModuleHandle( NULL ),
|
||||
/* void FAR* lpvParam; */ NULL))
|
||||
)
|
||||
/* creation failed... */
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Message processing for our Windows class */
|
||||
LRESULT CALLBACK Message_Process( HWND handle, UINT mess,
|
||||
WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
|
||||
switch( mess )
|
||||
{
|
||||
case WM_DESTROY:
|
||||
/* warn the main thread to quit if it didn't know */
|
||||
ourevent.type = gr_event_key;
|
||||
ourevent.key = grKeyEsc;
|
||||
eventToProcess = 1;
|
||||
hwndGraphic = 0;
|
||||
PostQuitMessage ( 0 );
|
||||
DeleteObject ( hbm );
|
||||
return 0;
|
||||
|
||||
case WM_CREATE:
|
||||
{
|
||||
HDC hDC;
|
||||
|
||||
hDC = GetDC ( handle );
|
||||
hbm = CreateDIBitmap (
|
||||
/* HDC hdc; handle of device context */ hDC,
|
||||
/* BITMAPINFOHEADER FAR* lpbmih; addr.of header*/ &pbmi->bmiHeader,
|
||||
/* DWORD dwInit; CBM_INIT to initialize bitmap */ 0,
|
||||
/* const void FAR* lpvBits; address of values */ NULL,
|
||||
/* BITMAPINFO FAR* lpbmi; addr.of bitmap data */ pbmi,
|
||||
/* UINT fnColorUse; RGB or palette indices */ DIB_RGB_COLORS);
|
||||
ReleaseDC ( handle, hDC );
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
HDC hDC, memDC;
|
||||
HANDLE oldbm;
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
hDC = BeginPaint ( handle, &ps );
|
||||
memDC = CreateCompatibleDC(hDC);
|
||||
oldbm = SelectObject(memDC, hbm);
|
||||
BitBlt ( hDC, 0, 0, window_width, window_height, memDC, 0, 0, SRCCOPY);
|
||||
ReleaseDC ( handle, hDC );
|
||||
SelectObject ( memDC, oldbm );
|
||||
DeleteObject ( memDC );
|
||||
EndPaint ( handle, &ps );
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
int count = sizeof( syskey_translators )/sizeof( syskey_translators[0] );
|
||||
Translator* trans = syskey_translators;
|
||||
Translator* limit = trans + count;
|
||||
for ( ; trans < limit; trans++ )
|
||||
if ( wParam == trans->winkey )
|
||||
{
|
||||
ourevent.key = trans->grkey;
|
||||
goto Do_Key_Event;
|
||||
}
|
||||
return DefWindowProc( handle, mess, wParam, lParam );
|
||||
}
|
||||
|
||||
|
||||
case WM_KEYDOWN:
|
||||
switch ( wParam )
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
ourevent.type = gr_event_key;
|
||||
ourevent.key = grKeyEsc;
|
||||
eventToProcess = 1;
|
||||
PostQuitMessage ( 0 );
|
||||
return 0;
|
||||
|
||||
default:
|
||||
/* lookup list of translated keys */
|
||||
{
|
||||
int count = sizeof( key_translators )/sizeof( key_translators[0] );
|
||||
Translator* trans = key_translators;
|
||||
Translator* limit = trans + count;
|
||||
for ( ; trans < limit; trans++ )
|
||||
if ( wParam == trans->winkey )
|
||||
{
|
||||
ourevent.key = trans->grkey;
|
||||
goto Do_Key_Event;
|
||||
}
|
||||
}
|
||||
|
||||
/* the key isn't found, default processing */
|
||||
/* return DefWindowProc( handle, mess, wParam, lParam ); */
|
||||
return DefWindowProc( handle, mess, wParam, lParam );
|
||||
}
|
||||
|
||||
case WM_CHAR:
|
||||
{
|
||||
ourevent.key = wParam;
|
||||
|
||||
Do_Key_Event:
|
||||
ourevent.type = gr_event_key;
|
||||
eventToProcess = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc( handle, mess, wParam, lParam );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_device( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void done_device( void )
|
||||
{
|
||||
}
|
||||
|
||||
grDevice gr_win32_device =
|
||||
{
|
||||
sizeof( grSurface ),
|
||||
"win32",
|
||||
|
||||
init_device,
|
||||
done_device,
|
||||
|
||||
(grDeviceInitSurfaceFunc) init_surface,
|
||||
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* End */
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef GRWIN32_H
|
||||
#define GRWIN32_H
|
||||
|
||||
#include "grobjs.h"
|
||||
|
||||
extern
|
||||
grDevice gr_win32_device;
|
||||
|
||||
#ifdef GR_INIT_BUILD
|
||||
static
|
||||
grDeviceChain gr_win32_device_chain =
|
||||
{
|
||||
"win32",
|
||||
&gr_win32_device,
|
||||
GR_INIT_DEVICE_CHAIN
|
||||
};
|
||||
|
||||
#undef GR_INIT_DEVICE_CHAIN
|
||||
#define GR_INIT_DEVICE_CHAIN &gr_win32_device_chain
|
||||
|
||||
#endif /* GR_INIT_BUILD */
|
||||
|
||||
#endif /* GRWIN32_H */
|
|
@ -1,52 +0,0 @@
|
|||
#**************************************************************************
|
||||
#*
|
||||
#* Win32 specific rules file, used to compile the Win32 graphics driver
|
||||
#* to the graphics subsystem
|
||||
#*
|
||||
#**************************************************************************
|
||||
|
||||
ifeq ($(PLATFORM),win32)
|
||||
|
||||
# directory of the Win32 graphics driver
|
||||
#
|
||||
GR_WIN32 := $(GRAPH_)win32
|
||||
GR_WIN32_ := $(GR_WIN32)$(SEP)
|
||||
|
||||
# Add the Win32 driver object file to the graphics library "graph.a"
|
||||
#
|
||||
GRAPH_OBJS += $(OBJ_)grwin32.$O
|
||||
|
||||
DEVICES += WIN32
|
||||
DEVICE_INCLUDES += $(GR_WIN32)
|
||||
|
||||
# the rule used to compile the graphics driver
|
||||
#
|
||||
$(OBJ_)grwin32.$O: $(GR_WIN32_)grwin32.c $(GR_WIN32_)grwin32.h
|
||||
$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_WIN32) $T$@ $<
|
||||
|
||||
# Now update COMPILE_GRAPH_LIB according to the compiler used on Win32
|
||||
#
|
||||
ifeq ($(firstword $(CC)),gcc) # test for GCC
|
||||
LINK = $(CC) $T$@ $< $(FTLIB)
|
||||
COMMON_LINK = $(LINK) $(COMMON_OBJ)
|
||||
GRAPH_LINK = $(COMMON_LINK) $(GRAPH_LIB) -luser32 -lgdi32
|
||||
endif
|
||||
|
||||
ifeq ($(CC),cl) # test for Visual C++
|
||||
COMPILE_GRAPH_LIB = lib /nologo /out:$(GRAPH_LIB) $(GRAPH_OBJS)
|
||||
LINK = cl /nologo /MD -o $@ $< $(FTLIB)
|
||||
COMMON_LINK = $(LINK) $(COMMON_OBJ)
|
||||
GRAPH_LINK = $(COMMON_LINK) $(GRAPH_LIB) user32.lib gdi32.lib
|
||||
endif
|
||||
|
||||
ifeq ($(CC),lcc) # test for LCC-Win32
|
||||
COMPILE_GRAPH_LIB = lcclib /out:$(subst /,\\,$(GRAPH_LIB)) $(subst /,\\,$(GRAPH_OBJS))
|
||||
GRAPH_LINK = $(subst /,\\,$(GRAPH_LIB)) user32.lib gdi32.lib
|
||||
LINK_ROOT = lcclnk -o $(subst /,\\,$@) $(subst /,\\,$<)
|
||||
LINK = $(LINK_ROOT) $(subst /,\\,$(FTLIB))
|
||||
COMMON_LINK = $(LINK_ROOT) $(subst /,\\,$(COMMON_OBJ)) $(subst /,\\,$(FTLIB))
|
||||
GRAPH_LINK = $(LINK_ROOT) $(subst /,\\,$(COMMON_OBJ)) $(subst /,\\,$(GRAPH_LIB)) $(subst /,\\,$(FTLIB))
|
||||
GRAPH_LINK2 = $(GRAPH_LINK) $(subst /,\\,$(EXTRA_GRAPH_OBJS))
|
||||
endif
|
||||
endif
|
||||
|
|
@ -1,981 +0,0 @@
|
|||
#include "grx11.h"
|
||||
|
||||
#define TEST
|
||||
|
||||
#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;
|
||||
XDepth* xdepth;
|
||||
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 )
|
||||
{
|
||||
#ifdef TEST
|
||||
{
|
||||
int count2;
|
||||
XVisualInfo* visuals;
|
||||
XVisualInfo* visual;
|
||||
const char* string = "unknown";
|
||||
|
||||
template.depth = format->depth;
|
||||
visuals = XGetVisualInfo( display,
|
||||
VisualDepthMask,
|
||||
&template,
|
||||
&count2 );
|
||||
visual = visuals;
|
||||
|
||||
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 %04lx:%04lx:%04lx, colors %3d, bits %2d %s\n",
|
||||
visual->red_mask,
|
||||
visual->green_mask,
|
||||
visual->blue_mask,
|
||||
visual->colormap_size,
|
||||
visual->bits_per_rgb,
|
||||
string );
|
||||
visual++;
|
||||
}
|
||||
#endif
|
||||
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 %04lx:%04lx:%04lx, 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++ )
|
||||
{
|
||||
XColor* color = surface->color + *_read;
|
||||
|
||||
_write[0] = color->red;
|
||||
_write[1] = color->green;
|
||||
_write[2] = color->blue;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (sizeof(long) > 4)
|
||||
{
|
||||
for ( ; _write < limit; _write += 4, _read++ )
|
||||
{
|
||||
byte color = *_read;
|
||||
|
||||
*(unsigned int*)_write = surface->color[color].pixel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( ; _write < limit; _write += 4, _read++ )
|
||||
{
|
||||
byte color = *_read;
|
||||
|
||||
*(unsigned long*)_write = surface->color[color].pixel;
|
||||
}
|
||||
}
|
||||
|
||||
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->xdepth->bits_per_pixel)
|
||||
{
|
||||
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;
|
||||
surface->xdepth = format;
|
||||
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;
|
||||
surface->xdepth = format;
|
||||
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" }
|
||||
};
|
||||
|
||||
#if 0
|
||||
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 /* O */
|
||||
#endif /* TEST */
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#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 */
|
|
@ -1,88 +0,0 @@
|
|||
#**************************************************************************
|
||||
#*
|
||||
#* X11-specific rules files, used to compile the X11 graphics driver
|
||||
#* when supported by the current platform
|
||||
#*
|
||||
#**************************************************************************
|
||||
|
||||
#########################################################################
|
||||
#
|
||||
# Try to detect an X11 setup.
|
||||
#
|
||||
# We try to detect the following directories (in that order) in the current
|
||||
# path:
|
||||
#
|
||||
# X11 (usually a symlink to the current release)
|
||||
# X11R6
|
||||
# X11R5
|
||||
#
|
||||
# If the variable X11_PATH is set (to specify unusual locations of X11), no
|
||||
# other directory is searched. More than one directory must be separated
|
||||
# with spaces. Example:
|
||||
#
|
||||
# make X11_PATH="/usr/openwin /usr/local/X11R6"
|
||||
#
|
||||
ifndef X11_PATH
|
||||
ifneq ($(findstring X11$(SEP)bin,$(PATH)),)
|
||||
xversion := X11
|
||||
else
|
||||
ifneq ($(findstring X11R6$(SEP)bin,$(PATH)),)
|
||||
xversion := X11R6
|
||||
else
|
||||
ifneq ($(findstring X11R5$(SEP)bin,$(PATH)),)
|
||||
xversion := X11R5
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef xversion
|
||||
X11_PATH := $(subst ;, ,$(PATH)) $(subst :, ,$(PATH))
|
||||
X11_PATH := $(filter %$(xversion)$(SEP)bin,$(X11_PATH))
|
||||
X11_PATH := $(X11_PATH:%$(SEP)bin=%)
|
||||
endif
|
||||
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' in GRAPH_LINK
|
||||
#
|
||||
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 += $(X11_LIB:%=-L%) -lX11
|
||||
|
||||
# Solaris needs a -lsocket in GRAPH_LINK ..
|
||||
#
|
||||
UNAME := $(shell uname)
|
||||
ifneq ($(findstring $(UNAME),SunOS Solaris),)
|
||||
GRAPH_LINK += -lsocket
|
||||
endif
|
||||
|
||||
|
||||
# add the X11 driver object file to the graphics library
|
||||
#
|
||||
GRAPH_OBJS += $(OBJ_)grx11.$O
|
||||
|
||||
|
||||
GR_X11 := $(GRAPH_)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
|
||||
|
||||
# EOF
|
|
@ -1,125 +0,0 @@
|
|||
#include "graph.h"
|
||||
#include "grfont.h" /* dispara^itra bientot */
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static
|
||||
void Panic( const char* message )
|
||||
{
|
||||
fprintf( stderr, "PANIC: %s\n", message );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
typedef struct grKeyName
|
||||
{
|
||||
grKey key;
|
||||
const char* name;
|
||||
|
||||
} grKeyName;
|
||||
|
||||
|
||||
static
|
||||
const grKeyName key_names[] =
|
||||
{
|
||||
{ grKeyF1, "F1" },
|
||||
{ grKeyF2, "F2" },
|
||||
{ grKeyF3, "F3" },
|
||||
{ grKeyF4, "F4" },
|
||||
{ grKeyF5, "F5" },
|
||||
{ grKeyF6, "F6" },
|
||||
{ grKeyF7, "F7" },
|
||||
{ grKeyF8, "F8" },
|
||||
{ grKeyF9, "F9" },
|
||||
{ grKeyF10, "F10" },
|
||||
{ grKeyF11, "F11" },
|
||||
{ grKeyF12, "F12" },
|
||||
{ grKeyEsc, "Esc" },
|
||||
{ grKeyHome, "Home" },
|
||||
{ grKeyEnd, "End" },
|
||||
|
||||
{ grKeyPageUp, "Page_Up" },
|
||||
{ grKeyPageDown, "Page_Down" },
|
||||
{ grKeyLeft, "Left" },
|
||||
{ grKeyRight, "Right" },
|
||||
{ grKeyUp, "Up" },
|
||||
{ grKeyDown, "Down" },
|
||||
{ grKeyBackSpace, "BackSpace" },
|
||||
{ grKeyReturn, "Return" }
|
||||
};
|
||||
|
||||
int main( void )
|
||||
{
|
||||
grSurface* surface;
|
||||
int n;
|
||||
|
||||
grInit();
|
||||
surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
|
||||
if (!surface)
|
||||
Panic("Could not create window\n" );
|
||||
else
|
||||
{
|
||||
grColor color;
|
||||
grEvent event;
|
||||
const char* string;
|
||||
int x;
|
||||
|
||||
grSetSurfaceRefresh( surface, 1 );
|
||||
grSetTitle(surface,"X11 driver demonstration" );
|
||||
|
||||
for ( x = -10; x < 10; x++ )
|
||||
{
|
||||
for ( n = 0; n < 128; n++ )
|
||||
{
|
||||
color.value = (n*3) & 127;
|
||||
grWriteCellChar( surface,
|
||||
x + ((n % 60) << 3),
|
||||
80 + (x+10)*8*3 + ((n/60) << 3), n, color );
|
||||
}
|
||||
|
||||
}
|
||||
color.value = 64;
|
||||
grWriteCellString( surface, 0, 0, "just an example", color );
|
||||
|
||||
do
|
||||
{
|
||||
grListenSurface( surface, 0, &event);
|
||||
|
||||
/* return if ESC was pressed */
|
||||
if ( event.key == grKeyEsc )
|
||||
return 0;
|
||||
|
||||
/* otherwise, display key string */
|
||||
color.value = (color.value + 8) & 127;
|
||||
{
|
||||
int count = sizeof(key_names)/sizeof(key_names[0]);
|
||||
grKeyName* name = (grKeyName*)key_names;
|
||||
grKeyName* limit = name + count;
|
||||
const char* kname = 0;
|
||||
char kname_temp[16];
|
||||
|
||||
while (name < limit)
|
||||
{
|
||||
if ( name->key == event.key )
|
||||
{
|
||||
kname = (const char*)name->name;
|
||||
break;
|
||||
}
|
||||
name++;
|
||||
}
|
||||
|
||||
if (!kname)
|
||||
{
|
||||
sprintf( kname_temp, "char '%c'", (char)event.key );
|
||||
kname = kname_temp;
|
||||
}
|
||||
|
||||
grWriteCellString( surface, 30, 30, kname, color );
|
||||
grRefreshSurface(surface);
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
This folder contains supporting code and CodeWarrior Pro 4 project
|
||||
files to build the FreeType demo programs ftlint and ftview for MacOS.
|
||||
|
||||
Building
|
||||
To build these apps, you'll first need to build the FreeType library
|
||||
(see config/mac). The applications get built in the demos/bin folder.
|
||||
|
||||
Notes
|
||||
Since the Mac doesn't have the notion of argc/argv, we'll emulate
|
||||
this: each file dropped onto the application will be translated
|
||||
to a command line argument. Both ftlint and ftview take a ppem
|
||||
value as their first command line argument: for the Mac version
|
||||
this has been hard-coded into the source. Also: the additional
|
||||
options for ftview cannot be set.
|
||||
|
||||
Have fun with FreeType on the Mac!
|
||||
|
||||
Just van Rossum, <just@letterror.com>
|
||||
|
||||
DISCLAIMER: this subdirectory is *not* being maintained by the
|
||||
FreeType team, but by Just van Rossum. It's being released under
|
||||
the same terms as FreeType (see license.txt).
|
Binary file not shown.
Binary file not shown.
|
@ -1,59 +0,0 @@
|
|||
/* minimal Mac wrapper for the ftlint.c program */
|
||||
|
||||
|
||||
int original_main( int argc, char** argv );
|
||||
|
||||
/* We rename the original main() program to original_main,
|
||||
so we can provide a wrapper around it */
|
||||
#define main original_main
|
||||
#include "ftlint.c"
|
||||
#undef main
|
||||
|
||||
|
||||
#define PPEM "24" /* hard-code the ppem size */
|
||||
|
||||
|
||||
#include <SIOUX.h>
|
||||
#include "getargv.h"
|
||||
#include <Windows.h>
|
||||
#include <Dialogs.h>
|
||||
#include <Fonts.h>
|
||||
#include <TextEdit.h>
|
||||
|
||||
static void
|
||||
init_toolbox()
|
||||
{
|
||||
InitGraf(&qd.thePort);
|
||||
InitFonts();
|
||||
InitWindows();
|
||||
TEInit();
|
||||
InitDialogs((long)0);
|
||||
InitMenus();
|
||||
InitCursor();
|
||||
SIOUXSettings.asktosaveonclose = 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int argc, i;
|
||||
char** argv;
|
||||
|
||||
init_toolbox();
|
||||
|
||||
/* put paths of all files dropped onto the app into argv */
|
||||
argc = FTMac_GetArgv(&argv);
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Please drop one or more font files onto the app (but quit first!)\n");
|
||||
exit(1);
|
||||
}
|
||||
/* move argv[1:] to argv[2:] and fill in the ppem arg */
|
||||
for (i = argc; i > 1; i--)
|
||||
{
|
||||
argv[i] = argv[i-1];
|
||||
}
|
||||
argc++;
|
||||
argv[1] = PPEM;
|
||||
/* call the original main() program */
|
||||
original_main(argc, argv);
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/* minimal Mac wrapper for the ftview.c program */
|
||||
|
||||
|
||||
int original_main( int argc, char** argv );
|
||||
|
||||
/* We rename the original main() program to original_main,
|
||||
so we can provide a wrapper around it */
|
||||
#define main original_main
|
||||
#include "ftview.c"
|
||||
#undef main
|
||||
|
||||
|
||||
#define PPEM "24" /* hard-code the ppem size */
|
||||
|
||||
|
||||
#include <SIOUX.h>
|
||||
#include "getargv.h"
|
||||
#include <Windows.h>
|
||||
#include <Dialogs.h>
|
||||
#include <Fonts.h>
|
||||
#include <TextEdit.h>
|
||||
|
||||
static void
|
||||
init_toolbox()
|
||||
{
|
||||
InitGraf(&qd.thePort);
|
||||
InitFonts();
|
||||
InitWindows();
|
||||
TEInit();
|
||||
InitDialogs((long)0);
|
||||
InitMenus();
|
||||
InitCursor();
|
||||
SIOUXSettings.asktosaveonclose = 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int argc, i;
|
||||
char** argv;
|
||||
|
||||
init_toolbox();
|
||||
|
||||
/* put paths of all files dropped onto the app into argv */
|
||||
argc = FTMac_GetArgv(&argv);
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Please drop one or more font files onto the app (but quit first!)\n");
|
||||
exit(1);
|
||||
}
|
||||
/* move argv[1:] to argv[2:] and fill in the ppem arg */
|
||||
for (i = argc; i > 1; i--)
|
||||
{
|
||||
argv[i] = argv[i-1];
|
||||
}
|
||||
argc++;
|
||||
argv[1] = PPEM;
|
||||
/* call the original main() program */
|
||||
original_main(argc, argv);
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
/***********************************************************
|
||||
Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
|
||||
The Netherlands.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/* Construct argc and argv for main() by using Apple Events */
|
||||
/* From Jack's implementation for STDWIN */
|
||||
|
||||
/* Modified for use with FreeType from MacPython's macgetargv.c
|
||||
by Just van Rossum <just@letterror.com> */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getargv.h"
|
||||
|
||||
#include <Types.h>
|
||||
#include <Files.h>
|
||||
#include <Events.h>
|
||||
#include <Processes.h>
|
||||
#include <Errors.h>
|
||||
#include <AppleEvents.h>
|
||||
#include <AEObjects.h>
|
||||
|
||||
#ifdef GENERATINGCFM /* Defined to 0 or 1 in Universal headers */
|
||||
#define HAVE_UNIVERSAL_HEADERS
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UNIVERSAL_HEADERS
|
||||
#define NewAEEventHandlerProc(x) (x)
|
||||
#define AEEventHandlerUPP EventHandlerProcPtr
|
||||
#endif
|
||||
|
||||
static int arg_count;
|
||||
static char *arg_vector[256];
|
||||
static char app_name[256];
|
||||
static int app_name_inited;
|
||||
|
||||
|
||||
/* Duplicate a string to the heap. */
|
||||
|
||||
static char *
|
||||
strdup(char *src)
|
||||
{
|
||||
char *dst = malloc(strlen(src) + 1);
|
||||
if (dst)
|
||||
strcpy(dst, src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/* Given an FSSpec, return the FSSpec of the parent folder */
|
||||
|
||||
static OSErr
|
||||
get_folder_parent (FSSpec * fss, FSSpec * parent)
|
||||
{
|
||||
CInfoPBRec rec;
|
||||
short err;
|
||||
|
||||
* parent = * fss;
|
||||
rec.hFileInfo.ioNamePtr = parent->name;
|
||||
rec.hFileInfo.ioVRefNum = parent->vRefNum;
|
||||
rec.hFileInfo.ioDirID = parent->parID;
|
||||
rec.hFileInfo.ioFDirIndex = -1;
|
||||
rec.hFileInfo.ioFVersNum = 0;
|
||||
if (err = PBGetCatInfoSync (& rec))
|
||||
return err;
|
||||
parent->parID = rec.dirInfo.ioDrParID;
|
||||
/* parent->name[0] = 0; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Given an FSSpec return a full, colon-separated pathname */
|
||||
|
||||
static OSErr
|
||||
FTMac_GetFullPath (FSSpec *fss, char *buf)
|
||||
{
|
||||
short err;
|
||||
FSSpec fss_parent, fss_current;
|
||||
char tmpbuf[256];
|
||||
int plen;
|
||||
|
||||
fss_current = *fss;
|
||||
plen = fss_current.name[0];
|
||||
memcpy(buf, &fss_current.name[1], plen);
|
||||
buf[plen] = 0;
|
||||
/* Special case for disk names */
|
||||
if ( fss_current.parID <= 1 ) {
|
||||
buf[plen++] = ':';
|
||||
buf[plen] = 0;
|
||||
return 0;
|
||||
}
|
||||
while (fss_current.parID > 1) {
|
||||
/* Get parent folder name */
|
||||
if (err = get_folder_parent(&fss_current, &fss_parent))
|
||||
return err;
|
||||
fss_current = fss_parent;
|
||||
/* Prepend path component just found to buf */
|
||||
plen = fss_current.name[0];
|
||||
if (strlen(buf) + plen + 1 > 256) {
|
||||
/* Oops... Not enough space (shouldn't happen) */
|
||||
*buf = 0;
|
||||
return -1;
|
||||
}
|
||||
memcpy(tmpbuf, &fss_current.name[1], plen);
|
||||
tmpbuf[plen] = ':';
|
||||
strcpy(&tmpbuf[plen+1], buf);
|
||||
strcpy(buf, tmpbuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize name of current application */
|
||||
|
||||
static OSErr
|
||||
init_app_name()
|
||||
{
|
||||
ProcessSerialNumber currentPSN;
|
||||
ProcessInfoRec info;
|
||||
OSErr err;
|
||||
FSSpec appSpec;
|
||||
|
||||
if ( app_name_inited ) return 0;
|
||||
currentPSN.highLongOfPSN = 0;
|
||||
currentPSN.lowLongOfPSN = kCurrentProcess;
|
||||
info.processInfoLength = sizeof(ProcessInfoRec);
|
||||
info.processName = NULL;
|
||||
info.processAppSpec = &appSpec;
|
||||
if ( err=GetProcessInformation(¤tPSN, &info))
|
||||
return err;
|
||||
strncpy(app_name, (char*)appSpec.name + 1, appSpec.name[0]);
|
||||
app_name[appSpec.name[0]] = '\0';
|
||||
app_name_inited = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check that there aren't any args remaining in the event */
|
||||
|
||||
static OSErr
|
||||
get_missing_params(AppleEvent *theAppleEvent)
|
||||
{
|
||||
DescType theType;
|
||||
Size actualSize;
|
||||
OSErr err;
|
||||
|
||||
err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
|
||||
&theType, nil, 0, &actualSize);
|
||||
if (err == errAEDescNotFound)
|
||||
return noErr;
|
||||
else
|
||||
return errAEEventNotHandled;
|
||||
}
|
||||
|
||||
static int got_one; /* Flag that we can stop getting events */
|
||||
|
||||
|
||||
/* Handle the Print or Quit events (by failing) */
|
||||
|
||||
static pascal OSErr
|
||||
handle_not(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
|
||||
{
|
||||
#pragma unused (reply, refCon)
|
||||
got_one = 1;
|
||||
return errAEEventNotHandled;
|
||||
}
|
||||
|
||||
|
||||
/* Handle the Open Application event (by ignoring it) */
|
||||
|
||||
static pascal OSErr
|
||||
handle_open_app(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
|
||||
{
|
||||
#pragma unused (reply, refCon)
|
||||
#if 0
|
||||
/* Test by Jack: would removing this facilitate debugging? */
|
||||
got_one = 1;
|
||||
#endif
|
||||
return get_missing_params(theAppleEvent);
|
||||
}
|
||||
|
||||
|
||||
/* Handle the Open Document event, by adding an argument */
|
||||
|
||||
static pascal OSErr
|
||||
handle_open_doc(AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
|
||||
{
|
||||
#pragma unused (reply, refCon)
|
||||
OSErr err;
|
||||
AEDescList doclist;
|
||||
AEKeyword keywd;
|
||||
DescType rttype;
|
||||
long i, ndocs, size;
|
||||
FSSpec fss;
|
||||
char path[256];
|
||||
|
||||
got_one = 1;
|
||||
if (err = AEGetParamDesc(theAppleEvent,
|
||||
keyDirectObject, typeAEList, &doclist))
|
||||
return err;
|
||||
if (err = get_missing_params(theAppleEvent))
|
||||
return err;
|
||||
if (err = AECountItems(&doclist, &ndocs))
|
||||
return err;
|
||||
for(i = 1; i <= ndocs; i++) {
|
||||
err = AEGetNthPtr(&doclist, i, typeFSS,
|
||||
&keywd, &rttype, &fss, sizeof(fss), &size);
|
||||
if (err)
|
||||
break;
|
||||
FTMac_GetFullPath(&fss, path);
|
||||
arg_vector[arg_count++] = strdup(path);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Install standard core event handlers */
|
||||
static AEEventHandlerUPP open_doc_upp;
|
||||
static AEEventHandlerUPP open_app_upp;
|
||||
static AEEventHandlerUPP not_upp;
|
||||
|
||||
static void
|
||||
set_ae_handlers()
|
||||
{
|
||||
open_doc_upp = NewAEEventHandlerProc(handle_open_doc);
|
||||
open_app_upp = NewAEEventHandlerProc(handle_open_app);
|
||||
not_upp = NewAEEventHandlerProc(handle_not);
|
||||
|
||||
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
|
||||
open_app_upp, 0L, false);
|
||||
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
|
||||
open_doc_upp, 0L, false);
|
||||
AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
|
||||
not_upp, 0L, false);
|
||||
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
|
||||
not_upp, 0L, false);
|
||||
}
|
||||
|
||||
/* Uninstall standard core event handlers */
|
||||
|
||||
static void
|
||||
reset_ae_handlers()
|
||||
{
|
||||
AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
|
||||
open_app_upp, false);
|
||||
AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
|
||||
open_doc_upp, false);
|
||||
AERemoveEventHandler(kCoreEventClass, kAEPrintDocuments,
|
||||
not_upp, false);
|
||||
AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
|
||||
not_upp, false);
|
||||
}
|
||||
|
||||
/* Wait for events until a core event has been handled */
|
||||
|
||||
static void
|
||||
event_loop()
|
||||
{
|
||||
EventRecord event;
|
||||
int n;
|
||||
int ok;
|
||||
|
||||
got_one = 0;
|
||||
for (n = 0; n < 100 && !got_one; n++) {
|
||||
SystemTask();
|
||||
ok = GetNextEvent(everyEvent, &event);
|
||||
if (ok && event.what == kHighLevelEvent) {
|
||||
AEProcessAppleEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the argv vector, return argc. See macgetargv.h for more doco. */
|
||||
|
||||
int
|
||||
FTMac_GetArgv(pargv)
|
||||
char ***pargv;
|
||||
{
|
||||
|
||||
arg_count = 0;
|
||||
(void)init_app_name();
|
||||
arg_vector[arg_count++] = strdup(app_name);
|
||||
|
||||
set_ae_handlers();
|
||||
event_loop();
|
||||
reset_ae_handlers();
|
||||
|
||||
arg_vector[arg_count] = NULL;
|
||||
|
||||
*pargv = arg_vector;
|
||||
return arg_count;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
<Function>
|
||||
FTMac_GetArgv
|
||||
|
||||
<Description>
|
||||
argc/argv emulation for the Mac. Converts files dropped
|
||||
onto the application to full paths, and stuff them into
|
||||
argv.
|
||||
|
||||
<Output>
|
||||
pargv :: a pointer to an argv array. The array doesn't need to
|
||||
exist before calling this function.
|
||||
|
||||
<Return>
|
||||
The number of files dropped onto the app (ie. argc)
|
||||
*/
|
||||
|
||||
int FTMac_GetArgv(char ***pargv);
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
(This file must be converted with BinHex 4.0)
|
||||
:$(*PFfpeFQ0P,R0TG!"6594%8dP8)3%!!!!'[!!!!!!REP0*9#%!!J!!"Vab6'&
|
||||
e!RX!!!!@EhX0!!YQG'aTER3ZFR0bB`K"ST!!!%9qHJ!!!)!!!!!!#%PXcPl2#BB
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!"R`!!!!$rrrrrFR0bBe*6483"!,6HlZHdhZmk!!!
|
||||
"Q3!!!!!!!!%C!!!!!"2I!!!!!!!!!!#2I4%!#"`XG3MLeZTM1d$2c[ec0aXql5S
|
||||
ShPIL[&U,h14S@fT@KjEj-dK+IjNHBG)R-N9+9!`J2MP%TSHT%#Nd-qT*elC3-#N
|
||||
4JA)Hkc6qlRVSqDHb&A*3a9&1cdmjhEbBUHN9ad&X+`E&1ceI!Y68j0ki6qFA)(r
|
||||
b,FRGeI4f6k%5&4RNVXbJD-emb41U6CZldibq,@I[0+0[hAC1Pd8qb1GJMXlkGX[
|
||||
Qi$6*5FhCV+hMcp9GjDB!CG6%FFi-Y%hSD+RR#(40DQ1''@VI1VRml-&F9CdAA5b
|
||||
'mAYaP!drhR!2h3*kJDG9FQ)R4mZIfD4`CM-&4Q9IJU0XbMdc06QfE,r!c)B,BXZ
|
||||
5lI0h(XbS`)*QmLcRP#B"!!!!$3!,CR4fD@9h,R*cFQ-)3D+3!!"&IRS!!!#!!!!
|
||||
!!!K*E-kIZJQ'!!!!!!!!!!!!!!!!!!!!&J!!!!!!!!!!rrrrrh*cFQ058d9%!3#
|
||||
dhZlRY0pi`J!!#Fd!!!!!!!!%V3!!!!#NcJ!!!!!!!!!!i8X,3,6cZVA1c0lNY)[
|
||||
f+j[)D@pq&ff8&[hml++YG5DRR()cQTfYCHr*j#YEf5Jc%CLIXrbFjqFX2cmr2dr
|
||||
ZTpFJfU$ca31a!b+85iiI35I(Bq'a#e!!VJ6J!#F!VSd!Nr('42m&cC%BQfS+kII
|
||||
X%,b5(HDLA-XlBDbP"ISMY'LUSfGRDkm!HhGl5NUk05!P)laE*h[lM)b!S+!8DhG
|
||||
VJA4q'GFk-X)*HFCMl1QrCp29l+`h+kl(I3FBqcaJl-h0E-YliEX#cZ%fH-9NHb2
|
||||
[J5A*h#if"qk@8jD%["I4@8lH[MDBr'c`$(5cE+ral1fF[*0$mqINR4`FEH`P-!"
|
||||
ZaYZ$[j86fKM'6M`k&3TTDRc[bEfDM@PAb0Zc`KL$6e6mrPk'RD,L)U0H$fC!XbD
|
||||
@b[N$+ecGH0iXmEpL-Vhq#F#BEGiV"UHAIc%8q2X*3m(RMaLFRfBcZ16HC5Mdq$C
|
||||
$iBFh'%`j9aPFlepL+(,[2%241fFBh,*1-"5lGC6"rHBKKZ,Apc&iA0[&81,+GSD
|
||||
5PlF`P,UiJF(c`PU'dZG@-ALGAFE`cZP&$0iRjc'816k,SHbaD3c[(TR%i(0i(%1
|
||||
jJk-BbZmIaP"Klb!'mqlq$"9hpQ@SY+-R3q9YGSBU@fd-96GhBI$GQ-V`h[S1$(l
|
||||
VNKLUV@R$8(ee!N10PDdBr*HhB+LjY"P$`1*)KX#&B3a"md-BDXeY`&"lGKf'pfI
|
||||
@BJLHAT1KcY4U$(8R9f@S0l%L3rhaj4JDM#h$d("dDBB24TCJD$5m'%2)8&H'aS0
|
||||
G'$iFk-33f[mP3eLrj`cKIA-CQ[4qb"$4mcj$T1-13j6p&N26c1X-dEBV$-h5,c)
|
||||
dlh+1iD1dd``aUFFC@R3m`Q$TF*!!)6Cj,d2,T*d-VGTZBiKVXjQKGH*kK[L%03`
|
||||
IakpJ5)KE`["*b`8-LCBj$*r'c'"Sdh`+`fI4%aMD4SeKq$aL"%05q"#'GU%$'*)
|
||||
Epf0ShkJh3iH'$SD8qTN-(HZQ-eL$daK5DhGNk"58c*!!&Y#@SE0r)N1Ak[%-AIe
|
||||
D-U6laM"N9)PQX&@+B1KQ$QA),0q)i3ZIqJcfXX%-hEf$'"aHrJ`p22dBHTDX`Y$
|
||||
,`mc3fpf(SBqE0d2I)Ti-AjSm'2S9FQ2ibYR%d,q!-m2A1KN-d2PQS$a)(L`2NBI
|
||||
+`q6KmJKjT$a+(Lf2NFI+iq6amJ4jSMa*RLa2NDI+dq6TmJajTMa,RLh2NHI+mq6
|
||||
jmJ*jSEa)AL`[NCI+bq6PmJTjTEa+ALer)kq4emVVj'rPpI)'HD1m5GiXEj'hbYr
|
||||
*fq6YmJljHhQR[%[H,Hq4pmVlj2hb!IQJI%Jq,2mJ(j'2bXIN(qAMmJRjT(a+2Lf
|
||||
INFr+2mRRj22b"IPRqD*m5EiXrb*INDr+eq4IjH[b$IQQr*Ym5liYCmQrbhINZr)
|
||||
pq3rj[T`YjmJ2j)Ib)rQar+HF+cq4RmV2j1IbAr,ImJ[jTIa+cVrAq2IZa#8h`e(
|
||||
[M,(L!aX+KPXLBSbe5VT9#0!Y3m18p"i1`e(jTiGr6K,QYpFN0E5riJD$A(+l,R'
|
||||
2l@@cfXefDrGZ2H`TeP*4GUXe[NqQe4`@CXjXRfje1+cr!`IL!!!:
|
|
@ -1 +0,0 @@
|
|||
This directory contains all the object files generated for the demonstration programs
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
* 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 )
|
||||
{
|
||||
#ifndef macintosh
|
||||
if ( c == '/' || c == '\\' )
|
||||
#else
|
||||
if ( c == ':' )
|
||||
#endif
|
||||
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 */
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -1,191 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* The FreeType project -- a free and portable quality TrueType renderer. */
|
||||
/* */
|
||||
/* Copyright 1996-1998 by */
|
||||
/* D. Turner, R.Wilhelm, and W. Lemberg */
|
||||
/* */
|
||||
/* compos: this is a very simple program used to test the flag */
|
||||
/* FT_LOAD_NO_RECURSE */
|
||||
/* */
|
||||
/* NOTE: This is just a test program that is used to show off and */
|
||||
/* debug the current engine. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#include <freetype/freetype.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( "compos: test FT_LOAD_NO_RECURSE load flag - www.freetype.org\n" );
|
||||
printf( "------------------------------------------------------------\n" );
|
||||
printf( "\n" );
|
||||
printf( "Usage: %s 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 < 2 )
|
||||
Usage( execname );
|
||||
|
||||
error = FT_Init_FreeType( &library );
|
||||
if (error) Panic( "Could not create library object" );
|
||||
|
||||
/* Now check all files */
|
||||
for ( file_index = 1; 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 );
|
||||
|
||||
#ifndef macintosh
|
||||
if ( i >= 0 )
|
||||
{
|
||||
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||
}
|
||||
#endif
|
||||
i = strlen( filename );
|
||||
fname = filename;
|
||||
|
||||
while ( i >= 0 )
|
||||
#ifndef macintosh
|
||||
if ( filename[i] == '/' || filename[i] == '\\' )
|
||||
#else
|
||||
if ( filename[i] == ':' )
|
||||
#endif
|
||||
{
|
||||
fname = filename + i + 1;
|
||||
i = -1;
|
||||
}
|
||||
else
|
||||
i--;
|
||||
|
||||
printf( "%s:\n", fname );
|
||||
|
||||
/* Load face */
|
||||
error = FT_New_Face( library, filename, 0, &face );
|
||||
if (error)
|
||||
{
|
||||
if (error == FT_Err_Invalid_File_Format)
|
||||
printf( "unknown format\n" );
|
||||
else
|
||||
printf( "could not find/open file (error: %d)\n", error );
|
||||
continue;
|
||||
}
|
||||
|
||||
num_glyphs = face->num_glyphs;
|
||||
slot = face->glyph;
|
||||
|
||||
Fail = 0;
|
||||
{
|
||||
for ( id = 0; id < num_glyphs; id++ )
|
||||
{
|
||||
int has_scale;
|
||||
|
||||
error = FT_Load_Glyph( face, id, FT_LOAD_NO_RECURSE );
|
||||
if (!error && slot->format == ft_glyph_format_composite)
|
||||
{
|
||||
int n;
|
||||
FT_SubGlyph* subg = slot->subglyphs;
|
||||
|
||||
printf( "%4d:", id );
|
||||
for ( n = 0; n < slot->num_subglyphs; n++, subg++ )
|
||||
{
|
||||
has_scale = subg->flags & (
|
||||
FT_SUBGLYPH_FLAG_SCALE |
|
||||
FT_SUBGLYPH_FLAG_XY_SCALE |
|
||||
FT_SUBGLYPH_FLAG_2X2 );
|
||||
|
||||
printf( " [%d%c",
|
||||
subg->index,
|
||||
subg->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ? '*' : ' ' );
|
||||
|
||||
if ( subg->arg1|subg->arg2 )
|
||||
{
|
||||
if ( subg->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES )
|
||||
printf( "(%d,%d)", subg->arg1, subg->arg2 );
|
||||
else
|
||||
printf( "<%d,%d>", subg->arg1, subg->arg2 );
|
||||
}
|
||||
|
||||
if (has_scale)
|
||||
printf( "-{%0.3f %0.3f %0.3f %0.3f}",
|
||||
subg->transform.xx/65536.0,
|
||||
subg->transform.xy/65536.0,
|
||||
subg->transform.yx/65536.0,
|
||||
subg->transform.yy/65536.0 );
|
||||
printf( "]" );
|
||||
}
|
||||
printf( " adv=%ld lsb=%ld\n",
|
||||
slot->metrics.horiAdvance,
|
||||
slot->metrics.horiBearingX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FT_Done_Face( face );
|
||||
}
|
||||
|
||||
FT_Done_FreeType(library);
|
||||
exit( 0 ); /* for safety reasons */
|
||||
|
||||
return 0; /* never reached */
|
||||
}
|
||||
|
||||
|
||||
/* End */
|
|
@ -1,192 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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/freetype.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];
|
||||
|
||||
/* try to open the file with no extra extension first */
|
||||
error = FT_New_Face( library, fname, 0, &face );
|
||||
if (!error)
|
||||
{
|
||||
printf( "%s: ", fname );
|
||||
goto Success;
|
||||
}
|
||||
|
||||
|
||||
if ( error == FT_Err_Unknown_File_Format )
|
||||
{
|
||||
printf( "unknown format\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ok, we could not load the file, try to add an extension to */
|
||||
/* its name if possible.. */
|
||||
|
||||
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 );
|
||||
|
||||
#ifndef macintosh
|
||||
if ( i >= 0 )
|
||||
{
|
||||
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||
}
|
||||
#endif
|
||||
i = strlen( filename );
|
||||
fname = filename;
|
||||
|
||||
while ( i >= 0 )
|
||||
#ifndef macintosh
|
||||
if ( filename[i] == '/' || filename[i] == '\\' )
|
||||
#else
|
||||
if ( filename[i] == ':' )
|
||||
#endif
|
||||
{
|
||||
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_Unknown_File_Format)
|
||||
printf( "unknown format\n" );
|
||||
else
|
||||
printf( "could not find/open file (error: %d)\n", error );
|
||||
continue;
|
||||
}
|
||||
if (error) Panic( "Could not open file" );
|
||||
|
||||
Success:
|
||||
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 */
|
|
@ -1,833 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* The FreeType project -- a free and portable quality TrueType renderer. */
|
||||
/* */
|
||||
/* Copyright 1996-2000 by */
|
||||
/* D. Turner, R.Wilhelm, and W. Lemberg */
|
||||
/* */
|
||||
/* */
|
||||
/* FTMulti- a simple multiple masters font viewer */
|
||||
/* */
|
||||
/* Press F1 when running this program to have a list of key-bindings */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftmm.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.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;
|
||||
|
||||
const unsigned char* Text = (unsigned char*)
|
||||
"The quick brown fox jumped over the lazy dog 0123456789 "
|
||||
"\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347 "
|
||||
"&#~\"\'(-`_^@)=+\260 ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
"$\243^\250*\265\371%!\247:/;.,?<>";
|
||||
|
||||
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 antialias = 1; /* is anti-aliasing active? */
|
||||
int use_sbits = 1; /* do we use embedded bitmaps? */
|
||||
int low_prec = 0; /* force low precision */
|
||||
int Num; /* current first glyph index */
|
||||
|
||||
int res = 72;
|
||||
|
||||
static grColor fore_color = { 255 };
|
||||
|
||||
int Fail;
|
||||
unsigned char autorun;
|
||||
|
||||
int graph_init = 0;
|
||||
|
||||
int render_mode = 1;
|
||||
int use_grays = 1;
|
||||
|
||||
FT_Multi_Master multimaster;
|
||||
FT_Long design_pos[T1_MAX_MM_AXIS];
|
||||
|
||||
#define RASTER_BUFF_SIZE 32768
|
||||
char raster_buff[RASTER_BUFF_SIZE];
|
||||
|
||||
#define DEBUGxxx
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG( x ) LogMessage##x
|
||||
#else
|
||||
#define LOG( x ) /* empty */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static
|
||||
void LogMessage( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
if ( size < 0 )
|
||||
size = -size;
|
||||
memset( bit.buffer, 0, size );
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the display bitmap named `bit' */
|
||||
static
|
||||
void Init_Display( void )
|
||||
{
|
||||
grInitDevices();
|
||||
|
||||
bit.mode = gr_pixel_mode_gray;
|
||||
bit.width = DIM_X;
|
||||
bit.rows = DIM_Y;
|
||||
bit.grays = 256;
|
||||
|
||||
surface = grNewSurface( 0, &bit );
|
||||
if ( !surface )
|
||||
PanicZ( "could not allocate display surface\n" );
|
||||
|
||||
graph_init = 1;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_BUFFER 300000
|
||||
|
||||
#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 with the `grays' component */
|
||||
static
|
||||
FT_Error Render_Glyph( int x_offset,
|
||||
int y_offset )
|
||||
{
|
||||
grBitmap bit3;
|
||||
FT_Pos x_top, y_top;
|
||||
|
||||
/* first, render the glyph image into a bitmap */
|
||||
if (glyph->format != ft_glyph_format_bitmap)
|
||||
{
|
||||
error = FT_Render_Glyph( glyph, antialias ? ft_render_mode_normal : ft_render_mode_mono );
|
||||
if (error) return error;
|
||||
|
||||
}
|
||||
|
||||
/* now blit it to our display screen */
|
||||
bit3.rows = glyph->bitmap.rows;
|
||||
bit3.width = glyph->bitmap.width;
|
||||
bit3.pitch = glyph->bitmap.pitch;
|
||||
bit3.buffer = glyph->bitmap.buffer;
|
||||
|
||||
switch (glyph->bitmap.pixel_mode)
|
||||
{
|
||||
case ft_pixel_mode_mono:
|
||||
bit3.mode = gr_pixel_mode_mono;
|
||||
bit3.grays = 0;
|
||||
break;
|
||||
|
||||
case ft_pixel_mode_grays:
|
||||
bit3.mode = gr_pixel_mode_gray;
|
||||
bit3.grays = glyph->bitmap.num_grays;
|
||||
}
|
||||
|
||||
/* Then, blit the image to the target surface */
|
||||
x_top = x_offset + glyph->bitmap_left;
|
||||
y_top = y_offset - glyph->bitmap_top;
|
||||
|
||||
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
FT_Error Reset_Scale( int pointSize )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
|
||||
error = FT_Set_Char_Size( face, pointSize << 6,
|
||||
pointSize << 6,
|
||||
res,
|
||||
res );
|
||||
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 = 36 + ptsize;
|
||||
|
||||
step_x = size->metrics.x_ppem + 4;
|
||||
step_y = size->metrics.y_ppem + 10;
|
||||
|
||||
x = start_x;
|
||||
y = start_y;
|
||||
|
||||
i = first_glyph;
|
||||
|
||||
#if 0
|
||||
while ( i < first_glyph + 1 )
|
||||
#else
|
||||
while ( i < num_glyphs )
|
||||
#endif
|
||||
{
|
||||
if ( !( error = LoadChar( i, hinted ) ) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if ( i <= first_glyph + 6 )
|
||||
{
|
||||
LOG(( "metrics[%02d] = [%x %x]\n",
|
||||
i,
|
||||
glyph->metrics.horiBearingX,
|
||||
glyph->metrics.horiAdvance ));
|
||||
|
||||
if ( i == first_glyph + 6 )
|
||||
LOG(( "-------------------------\n" ));
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
FT_Error Render_Text( int first_glyph,
|
||||
int ptsize )
|
||||
{
|
||||
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
|
||||
int i;
|
||||
|
||||
FT_Error error;
|
||||
const unsigned char* p;
|
||||
|
||||
|
||||
ptsize=ptsize;
|
||||
|
||||
start_x = 4;
|
||||
start_y = 32 + size->metrics.y_ppem;
|
||||
|
||||
step_x = size->metrics.x_ppem + 4;
|
||||
step_y = size->metrics.y_ppem + 10;
|
||||
|
||||
x = start_x;
|
||||
y = start_y;
|
||||
|
||||
i = first_glyph;
|
||||
p = Text;
|
||||
while ( i > 0 && *p )
|
||||
{
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
|
||||
while ( *p )
|
||||
{
|
||||
if ( !( error = LoadChar( FT_Get_Char_Index( face,
|
||||
(unsigned char)*p ),
|
||||
hinted ) ) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if ( i <= first_glyph + 6 )
|
||||
{
|
||||
LOG(( "metrics[%02d] = [%x %x]\n",
|
||||
i,
|
||||
glyph->metrics.horiBearingX,
|
||||
glyph->metrics.horiAdvance ));
|
||||
|
||||
if ( i == first_glyph + 6 )
|
||||
LOG(( "-------------------------\n" ));
|
||||
}
|
||||
#endif
|
||||
|
||||
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++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void Help( void )
|
||||
{
|
||||
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" );
|
||||
grWriteln(" space : toggle rendering mode" );
|
||||
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(" F3 : decrement first axis position by 20" );
|
||||
grWriteln(" F4 : increment first axis position by 20" );
|
||||
grWriteln(" F5 : decrement second axis position by 20" );
|
||||
grWriteln(" F6 : increment second axis position by 20" );
|
||||
grWriteln(" F7 : decrement third axis position by 20" );
|
||||
grWriteln(" F8 : increment third axis position by 20" );
|
||||
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, axis;
|
||||
|
||||
switch ( event->key )
|
||||
{
|
||||
case grKeyEsc: /* ESC or q */
|
||||
case grKEY( 'q' ):
|
||||
return 0;
|
||||
|
||||
case grKeyF1:
|
||||
case grKEY( '?' ):
|
||||
Help();
|
||||
return 1;
|
||||
|
||||
/* mode keys */
|
||||
|
||||
case grKEY( 'a' ):
|
||||
antialias = !antialias;
|
||||
new_header = antialias ? "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 if 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 grKEY( ' ' ):
|
||||
render_mode ^= 1;
|
||||
new_header = render_mode ? "rendering all glyphs in font"
|
||||
: "rendering test text string";
|
||||
break;
|
||||
|
||||
/* MM related keys */
|
||||
|
||||
case grKeyF3:
|
||||
i = -20;
|
||||
axis = 0;
|
||||
goto Do_Axis;
|
||||
|
||||
case grKeyF4:
|
||||
i = 20;
|
||||
axis = 0;
|
||||
goto Do_Axis;
|
||||
|
||||
case grKeyF5:
|
||||
i = -20;
|
||||
axis = 1;
|
||||
goto Do_Axis;
|
||||
|
||||
case grKeyF6:
|
||||
i = 20;
|
||||
axis = 1;
|
||||
goto Do_Axis;
|
||||
|
||||
case grKeyF7:
|
||||
i = -20;
|
||||
axis = 2;
|
||||
goto Do_Axis;
|
||||
|
||||
case grKeyF8:
|
||||
i = 20;
|
||||
axis = 2;
|
||||
goto Do_Axis;
|
||||
|
||||
/* scaling related keys */
|
||||
|
||||
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;
|
||||
|
||||
/* glyph index related keys */
|
||||
|
||||
case grKeyLeft:
|
||||
i = -1;
|
||||
goto Do_Glyph;
|
||||
|
||||
case grKeyRight:
|
||||
i = 1;
|
||||
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;
|
||||
|
||||
Do_Axis:
|
||||
if ( axis < (int)multimaster.num_axis )
|
||||
{
|
||||
FT_MM_Axis* a = multimaster.axis + axis;
|
||||
FT_Long pos = design_pos[axis];
|
||||
|
||||
|
||||
pos += i;
|
||||
if ( pos < a->minimum ) pos = a->minimum;
|
||||
if ( pos > a->maximum ) pos = a->maximum;
|
||||
|
||||
design_pos[axis] = pos;
|
||||
|
||||
FT_Set_MM_Design_Coordinates( face, multimaster.num_axis, design_pos );
|
||||
}
|
||||
return 1;
|
||||
|
||||
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, "ftmulti: multiple masters font viewer - part of FreeType\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 old_ptsize, orig_ptsize, file;
|
||||
int first_glyph = 0;
|
||||
int XisSetup = 0;
|
||||
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 initialize FreeType library" );
|
||||
|
||||
NewFile:
|
||||
ptsize = orig_ptsize;
|
||||
hinted = 1;
|
||||
file_loaded = 0;
|
||||
|
||||
/* Load face */
|
||||
error = FT_New_Face( library, argv[file], 0, &face );
|
||||
if ( error )
|
||||
goto Display_Font;
|
||||
|
||||
/* retrieve multiple master information */
|
||||
error = FT_Get_Multi_Master( face, &multimaster );
|
||||
if ( error )
|
||||
goto Display_Font;
|
||||
|
||||
/* set the current position to the median of each axis */
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
for ( n = 0; n < (int)multimaster.num_axis; n++ )
|
||||
design_pos[n] =
|
||||
( multimaster.axis[n].minimum + multimaster.axis[n].maximum ) / 2;
|
||||
}
|
||||
|
||||
error = FT_Set_MM_Design_Coordinates( face,
|
||||
multimaster.num_axis,
|
||||
design_pos );
|
||||
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:
|
||||
/* initialize 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 )
|
||||
{
|
||||
switch ( render_mode )
|
||||
{
|
||||
case 0:
|
||||
Render_Text( Num, ptsize );
|
||||
break;
|
||||
|
||||
default:
|
||||
Render_All( Num, ptsize );
|
||||
}
|
||||
|
||||
sprintf( Header, "%s %s (file %s)",
|
||||
face->family_name,
|
||||
face->style_name,
|
||||
ft_basename( argv[file] ) );
|
||||
|
||||
if ( !new_header )
|
||||
new_header = Header;
|
||||
|
||||
grWriteCellString( &bit, 0, 0, new_header, fore_color );
|
||||
new_header = 0;
|
||||
|
||||
sprintf( Header, "axis: " );
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
for ( n = 0; n < (int)multimaster.num_axis; n++ )
|
||||
{
|
||||
char temp[32];
|
||||
|
||||
|
||||
sprintf( temp, " %s:%ld",
|
||||
multimaster.axis[n].name,
|
||||
design_pos[n] );
|
||||
strcat( Header, temp );
|
||||
}
|
||||
}
|
||||
grWriteCellString( &bit, 0, 16, Header, fore_color );
|
||||
|
||||
sprintf( Header, "at %d points, first glyph = %d",
|
||||
ptsize,
|
||||
Num );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( Header, "%s : not an MM font file, or could not be opened",
|
||||
ft_basename( argv[file] ) );
|
||||
}
|
||||
|
||||
grWriteCellString( &bit, 0, 8, Header, fore_color );
|
||||
grRefreshSurface( surface );
|
||||
|
||||
grListenSurface( surface, 0, &event );
|
||||
if ( !( key = Process_Event( &event ) ) )
|
||||
goto End;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
End:
|
||||
#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 */
|
|
@ -1,313 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
|
@ -1,777 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* The FreeType project -- a free and portable quality TrueType renderer. */
|
||||
/* */
|
||||
/* Copyright 1996-1999 by */
|
||||
/* D. Turner, R.Wilhelm, and W. Lemberg */
|
||||
/* */
|
||||
/* */
|
||||
/* FTString.c - simple text string display */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.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 */
|
||||
|
||||
static char Header[128];
|
||||
static char* new_header = 0;
|
||||
|
||||
static char* Text = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
static FT_Library library; /* the FreeType library */
|
||||
static FT_Face face; /* the font face */
|
||||
static FT_Error error; /* error returned by FreeType ? */
|
||||
|
||||
static grSurface* surface; /* current display surface */
|
||||
static grBitmap bit; /* current display bitmap */
|
||||
|
||||
static int ptsize; /* current point size */
|
||||
static int Num;
|
||||
static int Rotation = 0;
|
||||
static int Fail;
|
||||
|
||||
static int hinted = 1; /* is glyph hinting active ? */
|
||||
static int antialias = 1; /* is anti-aliasing active ? */
|
||||
static int use_sbits = 1; /* do we use embedded bitmaps ? */
|
||||
static int kerning = 1;
|
||||
|
||||
static int res = 72; /* default resolution in dpi */
|
||||
|
||||
static grColor fore_color = { 255 };
|
||||
|
||||
static int graph_init = 0;
|
||||
static int render_mode = 1;
|
||||
|
||||
static FT_Matrix trans_matrix;
|
||||
static int transform = 0;
|
||||
|
||||
static FT_Vector string_center;
|
||||
|
||||
typedef struct TGlyph_
|
||||
{
|
||||
FT_UInt glyph_index; /* glyph index in face */
|
||||
FT_Vector pos; /* position of glyph origin */
|
||||
FT_Glyph image; /* glyph image */
|
||||
|
||||
} TGlyph, *PGlyph;
|
||||
|
||||
#define FLOOR(x) ((x) & -64)
|
||||
#define CEIL(x) (((x)+63) & -64)
|
||||
#define TRUNC(x) ((x) >> 6)
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**** ****/
|
||||
/**** U T I L I T Y F U N C T I O N S ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define DEBUGxxx
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(x) LogMessage##x
|
||||
#else
|
||||
#define LOG(x) /* rien */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void LogMessage( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PanicZ */
|
||||
static void PanicZ( const char* message )
|
||||
{
|
||||
fprintf( stderr, "%s\n error = 0x%04x\n", message, error );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**** ****/
|
||||
/**** D I S P L A Y M A N A G E M E N T ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define MAX_GLYPHS 512
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* The following arrays are used to store the glyph set that makes
|
||||
* up a string of text..
|
||||
*
|
||||
*/
|
||||
static TGlyph glyphs[ MAX_GLYPHS ];
|
||||
static int num_glyphs;
|
||||
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Initialise the display surface
|
||||
*
|
||||
*/
|
||||
static int init_display( void )
|
||||
{
|
||||
grInitDevices();
|
||||
|
||||
bit.mode = gr_pixel_mode_gray;
|
||||
bit.width = DIM_X;
|
||||
bit.rows = DIM_Y;
|
||||
bit.grays = 256;
|
||||
|
||||
surface = grNewSurface( 0, &bit );
|
||||
if (!surface)
|
||||
PanicZ( "could not allocate display surface\n" );
|
||||
|
||||
graph_init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Clears the display surface
|
||||
*
|
||||
*/
|
||||
static void clear_display( void )
|
||||
{
|
||||
long size = (long)bit.pitch * bit.rows;
|
||||
|
||||
if (size < 0) size = -size;
|
||||
memset( bit.buffer, 0, size );
|
||||
}
|
||||
|
||||
|
||||
static FT_Error reset_scale( int pointSize )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
error = FT_Set_Char_Size( face, pointSize << 6,
|
||||
pointSize << 6,
|
||||
res,
|
||||
res );
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Layout a string of glyphs, the glyphs are untransformed..
|
||||
*
|
||||
*/
|
||||
static void layout_glyphs( void )
|
||||
{
|
||||
PGlyph glyph = glyphs;
|
||||
FT_Error error;
|
||||
int n;
|
||||
FT_Vector origin;
|
||||
FT_Pos origin_x = 0;
|
||||
FT_UInt load_flags;
|
||||
FT_UInt num_grays;
|
||||
FT_UInt prev_index = 0;
|
||||
|
||||
load_flags = FT_LOAD_DEFAULT;
|
||||
if( !hinted )
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
|
||||
num_grays = 256;
|
||||
if (!antialias)
|
||||
num_grays = 0;
|
||||
|
||||
for ( n = 0; n < num_glyphs; n++, glyph++ )
|
||||
{
|
||||
/* compute glyph origin */
|
||||
if (kerning)
|
||||
{
|
||||
if (prev_index)
|
||||
{
|
||||
FT_Vector kern;
|
||||
|
||||
FT_Get_Kerning( face, prev_index, glyph->glyph_index,
|
||||
hinted ? ft_kerning_default : ft_kerning_unfitted,
|
||||
&kern );
|
||||
|
||||
origin_x += kern.x;
|
||||
}
|
||||
prev_index = glyph->glyph_index;
|
||||
}
|
||||
|
||||
origin.x = origin_x;
|
||||
origin.y = 0;
|
||||
|
||||
/* clear existing image if there is one */
|
||||
if (glyph->image)
|
||||
FT_Done_Glyph(glyph->image);
|
||||
|
||||
/* load the glyph image (in its native format) */
|
||||
/* for now, we take a monochrome glyph bitmap */
|
||||
error = FT_Load_Glyph( face, glyph->glyph_index,
|
||||
hinted ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING ) ||
|
||||
FT_Get_Glyph ( face->glyph, &glyph->image );
|
||||
if (error) continue;
|
||||
|
||||
glyph->pos = origin;
|
||||
|
||||
origin_x += face->glyph->advance.x;
|
||||
}
|
||||
string_center.x = origin_x / 2;
|
||||
string_center.y = 0;
|
||||
|
||||
if (transform)
|
||||
FT_Vector_Transform( &string_center, &trans_matrix );
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Renders a given glyph vector set
|
||||
*
|
||||
*/
|
||||
static void render_string( FT_Pos x, FT_Pos y )
|
||||
{
|
||||
PGlyph glyph = glyphs;
|
||||
grBitmap bit3;
|
||||
int n;
|
||||
FT_Vector delta;
|
||||
|
||||
/* first of all, we must compute the general delta for the glyph */
|
||||
/* set.. */
|
||||
delta.x = (x << 6) - string_center.x;
|
||||
delta.y = ((bit.rows-y) << 6) - string_center.y;
|
||||
|
||||
for ( n = 0; n < num_glyphs; n++, glyph++ )
|
||||
{
|
||||
FT_Glyph image;
|
||||
FT_Vector vec;
|
||||
|
||||
if (!glyph->image)
|
||||
continue;
|
||||
|
||||
/* copy image */
|
||||
error = FT_Glyph_Copy( glyph->image, &image );
|
||||
if (error) continue;
|
||||
|
||||
/* transform it */
|
||||
vec = glyph->pos;
|
||||
FT_Vector_Transform( &vec, &trans_matrix );
|
||||
vec.x += delta.x;
|
||||
vec.y += delta.y;
|
||||
error = FT_Glyph_Transform( image, &trans_matrix, &vec );
|
||||
if (!error)
|
||||
{
|
||||
FT_BBox bbox;
|
||||
|
||||
/* check bounding box, if it's not within the display surface, we */
|
||||
/* don't need to render it.. */
|
||||
|
||||
FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
|
||||
|
||||
if ( bbox.xMax > 0 && bbox.yMax > 0 &&
|
||||
bbox.xMin < bit.width && bbox.yMin < bit.rows )
|
||||
{
|
||||
/* convert to a bitmap - destroy native image */
|
||||
error = FT_Glyph_To_Bitmap( &image,
|
||||
antialias ? ft_render_mode_normal
|
||||
: ft_render_mode_mono,
|
||||
0, 1 );
|
||||
if (!error)
|
||||
{
|
||||
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)image;
|
||||
FT_Bitmap* source = &bitmap->bitmap;
|
||||
FT_Pos x_top, y_top;
|
||||
|
||||
bit3.rows = source->rows;
|
||||
bit3.width = source->width;
|
||||
bit3.pitch = source->pitch;
|
||||
bit3.buffer = source->buffer;
|
||||
|
||||
switch (source->pixel_mode)
|
||||
{
|
||||
case ft_pixel_mode_mono:
|
||||
bit3.mode = gr_pixel_mode_mono;
|
||||
break;
|
||||
|
||||
case ft_pixel_mode_grays:
|
||||
bit3.mode = gr_pixel_mode_gray;
|
||||
bit3.grays = source->num_grays;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* now render the bitmap into the display surface */
|
||||
x_top = bitmap->left;
|
||||
y_top = bit.rows - bitmap->top;
|
||||
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
|
||||
}
|
||||
}
|
||||
}
|
||||
FT_Done_Glyph( image );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Convert a string of text into a glyph vector
|
||||
*
|
||||
* XXX: For now, we perform a trivial conversion
|
||||
*
|
||||
*/
|
||||
static void prepare_text( const unsigned char* string )
|
||||
{
|
||||
const unsigned char* p = (const unsigned char*)string;
|
||||
PGlyph glyph = glyphs;
|
||||
FT_UInt glyph_index;
|
||||
|
||||
num_glyphs = 0;
|
||||
while (*p)
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index( face, (FT_ULong)*p );
|
||||
glyph->glyph_index = glyph_index;
|
||||
glyph++;
|
||||
num_glyphs++;
|
||||
if (num_glyphs >= MAX_GLYPHS)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void reset_transform( void )
|
||||
{
|
||||
double angle = Rotation*3.14159/64.0;
|
||||
FT_Fixed cosinus = (FT_Fixed)(cos(angle)*65536.0);
|
||||
FT_Fixed sinus = (FT_Fixed)(sin(angle)*65536.0);
|
||||
|
||||
transform = (angle != 0);
|
||||
trans_matrix.xx = cosinus;
|
||||
trans_matrix.xy = -sinus;
|
||||
trans_matrix.yx = sinus;
|
||||
trans_matrix.yy = cosinus;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**** ****/
|
||||
/**** E V E N T H A N D L I N G ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static void Help( )
|
||||
{
|
||||
grEvent dummy_event;
|
||||
|
||||
clear_display();
|
||||
grGotoxy( 0, 0 );
|
||||
grSetMargin( 2, 1 );
|
||||
grGotobitmap( &bit );
|
||||
|
||||
grWriteln("FreeType String Viewer - part of the FreeType test suite" );
|
||||
grLn();
|
||||
grWriteln("This program is used to display a string of text using" );
|
||||
grWriteln("the new convenience API of the FreeType 2 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(" k : toggle kerning" );
|
||||
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 : rotate counter-clockwise" );
|
||||
grWriteln(" Left : rotate clockwise" );
|
||||
grWriteln(" F7 : big rotate counter-clockwise");
|
||||
grWriteln(" F8 : big rotate clockwise");
|
||||
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('k'):
|
||||
kerning = !kerning;
|
||||
new_header = ( kerning
|
||||
? "kerning is now active"
|
||||
: "kerning is now ignored" );
|
||||
return 1;
|
||||
|
||||
case grKEY('a'):
|
||||
antialias = !antialias;
|
||||
new_header = ( antialias
|
||||
? "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('h'):
|
||||
hinted = !hinted;
|
||||
new_header = ( hinted
|
||||
? "glyph hinting is now active"
|
||||
: "glyph hinting is now ignored" );
|
||||
break;
|
||||
|
||||
case grKEY(' '):
|
||||
render_mode ^= 1;
|
||||
new_header = ( render_mode
|
||||
? "rendering all glyphs in font"
|
||||
: "rendering test text string" );
|
||||
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_Rotate;
|
||||
case grKeyRight: i = 1; goto Do_Rotate;
|
||||
case grKeyF7: i = -10; goto Do_Rotate;
|
||||
case grKeyF8: i = 10; goto Do_Rotate;
|
||||
default:
|
||||
;
|
||||
}
|
||||
return 1;
|
||||
|
||||
Do_Rotate:
|
||||
Rotation = (Rotation + i) & 127;
|
||||
return 1;
|
||||
|
||||
Do_Scale:
|
||||
ptsize += i;
|
||||
if (ptsize < 1) ptsize = 1;
|
||||
if (ptsize > MAXPTSIZE) ptsize = MAXPTSIZE;
|
||||
return 1;
|
||||
|
||||
#if 0
|
||||
Do_Glyph:
|
||||
Num += i;
|
||||
if (Num < 0) Num = 0;
|
||||
if (Num >= num_glyphs) Num = num_glyphs-1;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**** ****/
|
||||
/**** M A I N P R O G R A M ****/
|
||||
/**** ****/
|
||||
/**** ****/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static void usage( char* execname )
|
||||
{
|
||||
fprintf( stderr, "\n" );
|
||||
fprintf( stderr, "ftstring: string 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, " -m message message 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, "m:r:" );
|
||||
|
||||
if ( option == -1 )
|
||||
break;
|
||||
|
||||
switch ( option )
|
||||
{
|
||||
case 'r':
|
||||
res = atoi( optarg );
|
||||
if ( res < 1 )
|
||||
usage( execname );
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (argc < 3)
|
||||
usage( execname );
|
||||
Text = optarg;
|
||||
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" );
|
||||
|
||||
NewFile:
|
||||
ptsize = orig_ptsize;
|
||||
hinted = 1;
|
||||
file_loaded = 0;
|
||||
|
||||
#ifndef macintosh
|
||||
i = strlen( argv[file] );
|
||||
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
|
||||
{
|
||||
if ( argv[file][i] == '.' )
|
||||
i = 0;
|
||||
i--;
|
||||
}
|
||||
#endif
|
||||
|
||||
filename[128] = '\0';
|
||||
alt_filename[128] = '\0';
|
||||
|
||||
strncpy( filename, argv[file], 128 );
|
||||
strncpy( alt_filename, argv[file], 128 );
|
||||
|
||||
/* first, try to load the glyph name as-is */
|
||||
error = FT_New_Face( library, filename, 0, &face );
|
||||
if (!error) goto Success;
|
||||
|
||||
#ifndef macintosh
|
||||
if ( i >= 0 )
|
||||
{
|
||||
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if it didn't work, try to add ".ttf" at the end */
|
||||
error = FT_New_Face( library, filename, 0, &face );
|
||||
if (error) goto Display_Font;
|
||||
|
||||
Success:
|
||||
/* prepare the text to be rendered */
|
||||
prepare_text( (unsigned char*)Text );
|
||||
|
||||
file_loaded++;
|
||||
|
||||
error = reset_scale( ptsize );
|
||||
if (error) goto Display_Font;
|
||||
|
||||
Display_Font:
|
||||
/* initialise graphics if needed */
|
||||
if ( !XisSetup )
|
||||
{
|
||||
XisSetup = 1;
|
||||
init_display();
|
||||
}
|
||||
|
||||
grSetTitle( surface, "FreeType String 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 )
|
||||
{
|
||||
/* layout & render string */
|
||||
{
|
||||
reset_transform();
|
||||
layout_glyphs();
|
||||
render_string( bit.width/2, bit.rows/2 );
|
||||
}
|
||||
|
||||
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, fore_color );
|
||||
new_header = 0;
|
||||
|
||||
sprintf( Header, "at %d points, rotation = %d",
|
||||
ptsize,
|
||||
Rotation );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( Header, "%s : is not a font file or could not be opened",
|
||||
ft_basename(filename) );
|
||||
}
|
||||
|
||||
grWriteCellString( &bit, 0, 8, Header, fore_color );
|
||||
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 */
|
||||
|
|
@ -1,341 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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/freetype.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h> /* for clock() */
|
||||
|
||||
/* 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;
|
||||
|
||||
int num_glyphs;
|
||||
FT_Glyph glyphs[MAX_GLYPHS];
|
||||
|
||||
int tab_glyphs;
|
||||
int cur_glyph;
|
||||
|
||||
int pixel_size = CHARSIZE;
|
||||
int repeat_count = 1;
|
||||
|
||||
int Fail;
|
||||
int Num;
|
||||
|
||||
short antialias = 1; /* smooth fonts with gray levels */
|
||||
short force_low;
|
||||
|
||||
|
||||
static
|
||||
void Panic( const char* message )
|
||||
{
|
||||
fprintf( stderr, "%s\n", message );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* Get_Time: */
|
||||
/* */
|
||||
/* Returns the current time in milliseconds. */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
long Get_Time( void )
|
||||
{
|
||||
return clock() * 10000 / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* LoadChar: */
|
||||
/* */
|
||||
/* Loads a glyph into memory. */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
FT_Error LoadChar( int idx )
|
||||
{
|
||||
FT_Glyph glyph;
|
||||
|
||||
/* loads the glyph in the glyph slot */
|
||||
error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) ||
|
||||
FT_Get_Glyph ( face->glyph, &glyph );
|
||||
if ( !error )
|
||||
{
|
||||
glyphs[cur_glyph++] = glyph;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* ConvertRaster: */
|
||||
/* */
|
||||
/* Performs scan conversion. */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
FT_Error ConvertRaster( int index )
|
||||
{
|
||||
FT_Glyph bitmap;
|
||||
FT_Error error;
|
||||
|
||||
bitmap = glyphs[index];
|
||||
error = FT_Glyph_To_Bitmap( &bitmap,
|
||||
antialias ? ft_render_mode_normal
|
||||
: ft_render_mode_mono,
|
||||
0,
|
||||
0 );
|
||||
if (!error)
|
||||
FT_Done_Glyph( bitmap );
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
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, " -m : render monochrome glyphs (default is anti-aliased)\n" );
|
||||
fprintf( stderr, " -a : use smooth anti-aliaser\n" );
|
||||
fprintf( stderr, " -l : force low quality even at small sizes\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;
|
||||
|
||||
long t, t0, tz0;
|
||||
|
||||
|
||||
execname = argv[0];
|
||||
|
||||
antialias = 1;
|
||||
force_low = 0;
|
||||
|
||||
while ( argc > 1 && argv[1][0] == '-' )
|
||||
{
|
||||
switch ( argv[1][1] )
|
||||
{
|
||||
case 'm':
|
||||
antialias = 0;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
force_low = 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;
|
||||
|
||||
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" );
|
||||
|
||||
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;
|
||||
|
||||
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 ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_Glyph( glyphs[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 */
|
|
@ -1,155 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
|
@ -1,776 +0,0 @@
|
|||
/****************************************************************************/
|
||||
/* */
|
||||
/* The FreeType project -- a free and portable quality TrueType renderer. */
|
||||
/* */
|
||||
/* Copyright 1996-2000 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/freetype.h>
|
||||
|
||||
/* the following header shouldn't be used in normal programs */
|
||||
#include <freetype/internal/ftdebug.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.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;
|
||||
|
||||
const unsigned char* Text = (unsigned char*)
|
||||
"The quick brown fox jumped over the lazy dog 0123456789 "
|
||||
"\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347 "
|
||||
"&#~\"\'(-`_^@)=+\260 ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
"$\243^\250*\265\371%!\247:/;.,?<>";
|
||||
|
||||
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 code 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 antialias = 1; /* is anti-aliasing active? */
|
||||
int use_sbits = 1; /* do we use embedded bitmaps? */
|
||||
int low_prec = 0; /* force low precision */
|
||||
int Num; /* current first glyph index */
|
||||
|
||||
int res = 72;
|
||||
|
||||
static grColor fore_color = { 255 };
|
||||
|
||||
int Fail;
|
||||
|
||||
int graph_init = 0;
|
||||
|
||||
int render_mode = 1;
|
||||
int debug = 0;
|
||||
int trace_level = 0;
|
||||
|
||||
|
||||
#define RASTER_BUFF_SIZE 32768
|
||||
char raster_buff[RASTER_BUFF_SIZE];
|
||||
|
||||
|
||||
#define LOG( x ) LogMessage##x
|
||||
|
||||
static
|
||||
void LogMessage( const char* fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start( ap, fmt );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
if ( size < 0 )
|
||||
size = -size;
|
||||
memset( bit.buffer, 0, size );
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the display bitmap `bit' */
|
||||
static
|
||||
void Init_Display( void )
|
||||
{
|
||||
grInitDevices();
|
||||
|
||||
bit.mode = gr_pixel_mode_gray;
|
||||
bit.width = DIM_X;
|
||||
bit.rows = DIM_Y;
|
||||
bit.grays = 256;
|
||||
|
||||
surface = grNewSurface( 0, &bit );
|
||||
if ( !surface )
|
||||
PanicZ( "could not allocate display surface\n" );
|
||||
|
||||
graph_init = 1;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_BUFFER 300000
|
||||
|
||||
#define FLOOR( x ) ( (x) & -64 )
|
||||
#define CEIL( x ) ( ( (x) + 63 ) & -64 )
|
||||
#define TRUNC( x ) ( (x) >> 6 )
|
||||
|
||||
|
||||
/* Render a single glyph with the `grays' component */
|
||||
static
|
||||
FT_Error Render_Glyph( int x_offset,
|
||||
int y_offset )
|
||||
{
|
||||
grBitmap bit3;
|
||||
FT_Pos x_top, y_top;
|
||||
|
||||
/* first, render the glyph image into a bitmap */
|
||||
if (glyph->format != ft_glyph_format_bitmap)
|
||||
{
|
||||
error = FT_Render_Glyph( glyph, antialias ? ft_render_mode_normal : ft_render_mode_mono );
|
||||
if (error) return error;
|
||||
|
||||
}
|
||||
|
||||
/* now blit it to our display screen */
|
||||
bit3.rows = glyph->bitmap.rows;
|
||||
bit3.width = glyph->bitmap.width;
|
||||
bit3.pitch = glyph->bitmap.pitch;
|
||||
bit3.buffer = glyph->bitmap.buffer;
|
||||
|
||||
switch (glyph->bitmap.pixel_mode)
|
||||
{
|
||||
case ft_pixel_mode_mono:
|
||||
bit3.mode = gr_pixel_mode_mono;
|
||||
bit3.grays = 0;
|
||||
break;
|
||||
|
||||
case ft_pixel_mode_grays:
|
||||
bit3.mode = gr_pixel_mode_gray;
|
||||
bit3.grays = glyph->bitmap.num_grays;
|
||||
}
|
||||
|
||||
/* Then, blit the image to the target surface */
|
||||
x_top = x_offset + glyph->bitmap_left;
|
||||
y_top = y_offset - glyph->bitmap_top;
|
||||
|
||||
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
|
||||
|
||||
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 )
|
||||
{
|
||||
/* to be written */
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#if 0
|
||||
while ( i < first_glyph + 1 )
|
||||
#else
|
||||
while ( i < num_glyphs )
|
||||
#endif
|
||||
{
|
||||
if ( !( error = LoadChar( i, hinted ) ) )
|
||||
{
|
||||
if ( debug && trace_level > 1 )
|
||||
{
|
||||
if ( i <= first_glyph + 6 )
|
||||
{
|
||||
LOG(( "metrics[%02d] = [%x %x]\n",
|
||||
i,
|
||||
glyph->metrics.horiBearingX,
|
||||
glyph->metrics.horiAdvance ));
|
||||
|
||||
if ( i == first_glyph + 6 )
|
||||
LOG(( "-------------------------\n" ));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
FT_Error Render_Text( int first_glyph,
|
||||
int ptsize )
|
||||
{
|
||||
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
|
||||
int i;
|
||||
|
||||
FT_Error error;
|
||||
const unsigned char* p;
|
||||
|
||||
|
||||
start_x = 4;
|
||||
start_y = 12 + size->metrics.y_ppem;
|
||||
|
||||
step_x = size->metrics.x_ppem + 4;
|
||||
step_y = size->metrics.y_ppem + 10;
|
||||
|
||||
x = start_x;
|
||||
y = start_y;
|
||||
|
||||
i = first_glyph;
|
||||
p = Text;
|
||||
while ( i > 0 && *p )
|
||||
{
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
|
||||
while ( *p )
|
||||
{
|
||||
if ( !( error = LoadChar( FT_Get_Char_Index( face,
|
||||
(unsigned char)*p ),
|
||||
hinted ) ) )
|
||||
{
|
||||
if ( debug && trace_level > 1 )
|
||||
{
|
||||
if ( i <= first_glyph + 6 )
|
||||
{
|
||||
LOG(( "metrics[%02d] = [%x %x]\n",
|
||||
i,
|
||||
glyph->metrics.horiBearingX,
|
||||
glyph->metrics.horiAdvance ));
|
||||
|
||||
if ( i == first_glyph + 6 )
|
||||
LOG(( "-------------------------\n" ));
|
||||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void Help( void )
|
||||
{
|
||||
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" );
|
||||
grWriteln(" space : toggle rendering mode" );
|
||||
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(" F7 : decrement first glyph index by 10" );
|
||||
grWriteln(" F8 : increment first glyph index by 10" );
|
||||
grWriteln(" F9 : decrement first glyph index by 100");
|
||||
grWriteln(" F10 : increment first glyph index by 100");
|
||||
grWriteln(" F11 : decrement first glyph index by 1000");
|
||||
grWriteln(" F12 : 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' ):
|
||||
antialias = !antialias;
|
||||
new_header = antialias ? "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 grKEY( ' ' ):
|
||||
render_mode ^= 1;
|
||||
new_header = render_mode ? "rendering all glyphs in font"
|
||||
: "rendering test text string" ;
|
||||
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, " -d enable debugging messages\n" );
|
||||
fprintf( stderr, " -l N set debugging trace level to N (default: 0, max: 7)\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, "df:l:r:" );
|
||||
|
||||
if ( option == -1 )
|
||||
break;
|
||||
|
||||
switch ( option )
|
||||
{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
first_glyph = atoi( optarg );
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
trace_level = atoi( optarg );
|
||||
if ( trace_level < 1 || trace_level > 7 )
|
||||
usage( execname );
|
||||
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;
|
||||
|
||||
if ( debug )
|
||||
{
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
FT_SetTraceLevel( trace_any, (FT_Byte)trace_level );
|
||||
#else
|
||||
trace_level = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize engine */
|
||||
error = FT_Init_FreeType( &library );
|
||||
if ( error )
|
||||
PanicZ( "Could not initialize FreeType library" );
|
||||
|
||||
NewFile:
|
||||
ptsize = orig_ptsize;
|
||||
hinted = 1;
|
||||
file_loaded = 0;
|
||||
|
||||
filename[128] = '\0';
|
||||
alt_filename[128] = '\0';
|
||||
|
||||
strncpy( filename, argv[file], 128 );
|
||||
strncpy( alt_filename, argv[file], 128 );
|
||||
|
||||
/* try to load the file name as is, first */
|
||||
error = FT_New_Face( library, argv[file], 0, &face );
|
||||
if ( !error )
|
||||
goto Success;
|
||||
|
||||
#ifndef macintosh
|
||||
i = strlen( argv[file] );
|
||||
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
|
||||
{
|
||||
if ( argv[file][i] == '.' )
|
||||
i = 0;
|
||||
i--;
|
||||
}
|
||||
|
||||
if ( i >= 0 )
|
||||
{
|
||||
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load face */
|
||||
error = FT_New_Face( library, filename, 0, &face );
|
||||
if ( error )
|
||||
goto Display_Font;
|
||||
|
||||
Success:
|
||||
file_loaded++;
|
||||
|
||||
error = Reset_Scale( ptsize );
|
||||
if ( error )
|
||||
goto Display_Font;
|
||||
|
||||
num_glyphs = face->num_glyphs;
|
||||
glyph = face->glyph;
|
||||
size = face->size;
|
||||
|
||||
Display_Font:
|
||||
/* initialize 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 )
|
||||
{
|
||||
switch ( render_mode )
|
||||
{
|
||||
case 0:
|
||||
Render_Text( Num, ptsize );
|
||||
break;
|
||||
|
||||
default:
|
||||
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, fore_color );
|
||||
new_header = 0;
|
||||
|
||||
sprintf( Header, "at %d points, first glyph = %d",
|
||||
ptsize,
|
||||
Num );
|
||||
}
|
||||
else
|
||||
sprintf( Header, "`%s': not a font file or could not be opened",
|
||||
ft_basename( filename ) );
|
||||
|
||||
grWriteCellString( &bit, 0, 8, Header, fore_color );
|
||||
grRefreshSurface( surface );
|
||||
|
||||
grListenSurface( surface, 0, &event );
|
||||
if ( !( key = Process_Event( &event ) ) )
|
||||
goto End;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
End:
|
||||
#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 */
|
|
@ -1,333 +0,0 @@
|
|||
/* memtest.c */
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftmodule.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
FT_Error error;
|
||||
|
||||
FT_Library library;
|
||||
FT_Face face;
|
||||
|
||||
unsigned int num_glyphs;
|
||||
int ptsize;
|
||||
|
||||
int Fail;
|
||||
int Num;
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
/* Our own memory allocator. To check that a single block isn't freed */
|
||||
/* several time, we simply do not call "free".. */
|
||||
|
||||
#define MAX_RECORDED_BLOCKS 1638400
|
||||
#define CHECK_DUPLICATES
|
||||
|
||||
typedef struct MyBlock
|
||||
{
|
||||
void* base;
|
||||
long size;
|
||||
|
||||
} MyBlock;
|
||||
|
||||
static MyBlock my_blocks[ MAX_RECORDED_BLOCKS ];
|
||||
static int num_my_blocks = 0;
|
||||
|
||||
|
||||
/* record a new block in the table, check for duplicates too */
|
||||
static
|
||||
void record_my_block( void* base, long size )
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
fprintf( stderr, "adding a block with non-positive length - should not happen \n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( num_my_blocks < MAX_RECORDED_BLOCKS )
|
||||
{
|
||||
MyBlock* block;
|
||||
|
||||
#ifdef CHECK_DUPLICATES
|
||||
MyBlock* limit;
|
||||
block = my_blocks;
|
||||
limit = block + num_my_blocks;
|
||||
for ( ; block < limit; block++ )
|
||||
{
|
||||
if ( block->base == base && block->size != 0 )
|
||||
{
|
||||
fprintf( stderr, "duplicate memory block at %08lx\n", (long)block->base );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
block = my_blocks + num_my_blocks++;
|
||||
block->base = base;
|
||||
block->size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Too many memory blocks -- test exited !!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* forget a block, and check that it isn't part of our table already */
|
||||
static
|
||||
void forget_my_block( void* base )
|
||||
{
|
||||
MyBlock* block = my_blocks + num_my_blocks-1;
|
||||
|
||||
/* we scan in reverse, because transient blocks are always located */
|
||||
/* at the end of the table.. (it supposedly faster then..) */
|
||||
for ( ; block >= my_blocks; block-- )
|
||||
{
|
||||
if ( block->base == base )
|
||||
{
|
||||
if (block->size > 0)
|
||||
{
|
||||
block->size = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Block at %p released twice \n", base );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf( stderr, "Trying to release an unallocated block at %p\n",
|
||||
base );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void* my_alloc( FT_Memory memory,
|
||||
long size )
|
||||
{
|
||||
void* p = malloc(size);
|
||||
if (p)
|
||||
record_my_block(p,size);
|
||||
|
||||
memory=memory;
|
||||
return p;
|
||||
}
|
||||
|
||||
static
|
||||
void my_free( FT_Memory memory, void* block )
|
||||
{
|
||||
memory=memory;
|
||||
forget_my_block(block);
|
||||
/* free(block); WE DO NOT REALLY FREE THE BLOCK */
|
||||
}
|
||||
|
||||
static
|
||||
void* my_realloc( FT_Memory memory,
|
||||
long cur_size,
|
||||
long new_size,
|
||||
void* block )
|
||||
{
|
||||
void* p;
|
||||
|
||||
p = my_alloc( memory, new_size );
|
||||
if (p)
|
||||
{
|
||||
long size;
|
||||
|
||||
size = cur_size;
|
||||
if (new_size < size)
|
||||
size = new_size;
|
||||
|
||||
memcpy( p, block, size );
|
||||
my_free( memory, block );
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
struct FT_MemoryRec_ my_memory =
|
||||
{
|
||||
0,
|
||||
my_alloc,
|
||||
my_free,
|
||||
my_realloc
|
||||
};
|
||||
|
||||
static void dump_mem( void )
|
||||
{
|
||||
MyBlock* block = my_blocks + num_my_blocks-1;
|
||||
int bad = 0;
|
||||
|
||||
printf( "total allocated blocks = %d\n", num_my_blocks );
|
||||
|
||||
/* we scan in reverse, because transient blocks are always located */
|
||||
/* at the end of the table.. (it supposedly faster then..) */
|
||||
for ( ; block >= my_blocks; block-- )
|
||||
{
|
||||
if (block->size > 0)
|
||||
{
|
||||
fprintf( stderr, "%p (%6ld bytes) leaked !!\n", block->base, (long)block->size );
|
||||
bad = 1;
|
||||
}
|
||||
}
|
||||
if (!bad)
|
||||
fprintf( stderr, "no leaked memory block\n\n" );
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static void Usage( char* name )
|
||||
{
|
||||
printf( "memtest: simple memory 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 );
|
||||
|
||||
/* Create a new library with our own memory manager */
|
||||
error = FT_New_Library( &my_memory, &library );
|
||||
if (error) Panic( "Could not create library object" );
|
||||
|
||||
/* the new library has no drivers in it, add the default ones */
|
||||
/* (implemented in ftinit.c).. */
|
||||
FT_Add_Default_Modules(library);
|
||||
|
||||
|
||||
/* 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 );
|
||||
|
||||
#ifndef macintosh
|
||||
if ( i >= 0 )
|
||||
{
|
||||
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||
}
|
||||
#endif
|
||||
i = strlen( filename );
|
||||
fname = filename;
|
||||
|
||||
while ( i >= 0 )
|
||||
#ifndef macintosh
|
||||
if ( filename[i] == '/' || filename[i] == '\\' )
|
||||
#else
|
||||
if ( filename[i] == ':' )
|
||||
#endif
|
||||
{
|
||||
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( "unknown format\n" );
|
||||
else
|
||||
printf( "could not find/open file (error: %d)\n", error );
|
||||
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_RENDER | FT_LOAD_ANTI_ALIAS );
|
||||
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);
|
||||
|
||||
dump_mem();
|
||||
|
||||
exit( 0 ); /* for safety reasons */
|
||||
return 0; /* never reached */
|
||||
}
|
||||
|
||||
|
||||
|
1260
demos/src/ttdebug.c
1260
demos/src/ttdebug.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue