* include/freetype/fttrigon.h, src/base/fttrigon.c, src/base/ftbase.c,
src/base/Jamfile, src/base/rules.mk: adding trigonometric functions to the core API (using Cordic algorithms). * builds/top_level.mk, builds/newline, builds/detect.mk: fixed problems with Make on Windows 2000, as well as problems when "make distclean" is invoked on a non-Unix platform when there is no "config.mk" in the current directory.. * builds/freetype.mk: fixed a problem with object deletions under Dos/Windows/OS/2 systems * src/tools: added new directory to hold tools and test programs moved docmaker.py, glnames.py to it.. * src/tools/docmaker.py: improved the script to add the current date at the footer of each web page (useful to distinguish between versions) * Jamfile: fixed incorrect HDRMACRO argument. * TODO: removed the cubic arc bbox computation note, since it has been fixed recently.. * include/freetype/t1tables.h, include/freetype/config/ftoption.h: formatting
This commit is contained in:
parent
b3de817acb
commit
ebe85f59c9
39
ChangeLog
39
ChangeLog
@ -1,3 +1,36 @@
|
||||
2001-05-11 David Turner <david@freetype.org>
|
||||
|
||||
* include/freetype/fttrigon.h, src/base/fttrigon.c, src/base/ftbase.c,
|
||||
src/base/Jamfile, src/base/rules.mk: adding trigonometric functions
|
||||
to the core API (using Cordic algorithms).
|
||||
|
||||
* builds/top_level.mk, builds/newline, builds/detect.mk: fixed problems
|
||||
with Make on Windows 2000, as well as problems when "make distclean" is
|
||||
invoked on a non-Unix platform when there is no "config.mk" in the
|
||||
current directory..
|
||||
|
||||
* builds/freetype.mk: fixed a problem with object deletions under
|
||||
Dos/Windows/OS/2 systems
|
||||
|
||||
* src/tools: added new directory to hold tools and test programs
|
||||
moved docmaker.py, glnames.py to it..
|
||||
|
||||
* src/tools/docmaker.py: improved the script to add the current date
|
||||
at the footer of each web page (useful to distinguish between versions)
|
||||
|
||||
* Jamfile: fixed incorrect HDRMACRO argument.
|
||||
|
||||
* TODO: removed the cubic arc bbox computation note, since it has been
|
||||
fixed recently..
|
||||
|
||||
* include/freetype/t1tables.h, include/freetype/config/ftoption.h:
|
||||
formatting
|
||||
|
||||
2001-05-10 David Turner <david@freetype.org>
|
||||
|
||||
* src/base/ftobjs.c (FT_Open_Face): fixed a small memory leaked
|
||||
which happened when trying to open 0-size font files !!
|
||||
|
||||
2001-05-09 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* include/freetype/internal/ftcalc.h: Move declaration of
|
||||
@ -21,8 +54,8 @@
|
||||
|
||||
2001-04-27 David Turner <david@freetype.org>
|
||||
|
||||
* src/base/ftbbox.c (BBox_Cubic_Check): Fixed the coefficient
|
||||
normalization algorithm (invalid final bit position, and invalid
|
||||
* src/base/ftbbox.c (BBox_Cubic_Check): Fixed the coefficient
|
||||
normalization algorithm (invalid final bit position, and invalid
|
||||
shift computation).
|
||||
|
||||
2001-04-26 Werner Lemberg <wl@gnu.org>
|
||||
@ -66,7 +99,7 @@
|
||||
types on platforms where Autoconf is not available). Also removed
|
||||
FTCALC_USE_LONG_LONG and replaced it with
|
||||
FT_CONFIG_OPTION_FORCE_INT64.
|
||||
|
||||
|
||||
* builds/win32/freetype.dsp: Updated the Visual C++ project file.
|
||||
Doesn't create a DLL yet.
|
||||
|
||||
|
@ -131,22 +131,25 @@ std_setup:
|
||||
@echo ""
|
||||
@$(COPY) $(CONFIG_RULES) $(CONFIG_MK)
|
||||
|
||||
|
||||
# special case for Dos, Windows, OS/2, where echo "" doesn't work correctly !!
|
||||
#
|
||||
dos_setup:
|
||||
@echo ÿ
|
||||
@type builds\newline
|
||||
@echo $(PROJECT_TITLE) build system -- automatic system detection
|
||||
@echo ÿ
|
||||
@type builds\newline
|
||||
@echo The following settings are used:
|
||||
@echo ÿ
|
||||
@echo ÿÿplatformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(PLATFORM)
|
||||
@echo ÿÿcompilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(CC)
|
||||
@echo ÿÿconfiguration directoryÿÿÿÿÿÿ$(BUILD)
|
||||
@echo ÿÿconfiguration rulesÿÿÿÿÿÿÿÿÿÿ$(CONFIG_RULES)
|
||||
@echo ÿ
|
||||
@type builds\newline
|
||||
@echo platformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(PLATFORM)
|
||||
@echo compilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(CC)
|
||||
@echo configuration directoryÿÿÿÿÿÿ$(BUILD)
|
||||
@echo configuration rulesÿÿÿÿÿÿÿÿÿÿ$(CONFIG_RULES)
|
||||
@type builds\newline
|
||||
@echo If this does not correspond to your system or settings please remove the file
|
||||
@echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help.
|
||||
@echo ÿ
|
||||
@type builds\newline
|
||||
@echo Otherwise, simply type 'make' again to build the library.
|
||||
@echo ÿ
|
||||
@type builds\newline
|
||||
@$(COPY) $(subst /,\,$(CONFIG_RULES) $(CONFIG_MK)) > nul
|
||||
|
||||
# EOF
|
||||
|
@ -273,13 +273,14 @@ distclean_project_std: clean_project_std
|
||||
# The Dos command shell does not support very long list of arguments, so
|
||||
# we are stuck with wildcards.
|
||||
#
|
||||
# don't break the command lines with, this prevents the "del" command from
|
||||
# working correctly on Win9x
|
||||
#
|
||||
clean_project_dos:
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(OBJ_))*.$O \
|
||||
$(CLEAN) $(NO_OUTPUT)
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(OBJ_))*.$O $(CLEAN) $(NO_OUTPUT)
|
||||
|
||||
distclean_project_dos: clean_project_dos
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) \
|
||||
$(DISTCLEAN) $(NO_OUTPUT)
|
||||
-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) $(DISTCLEAN) $(NO_OUTPUT)
|
||||
|
||||
|
||||
.PHONY: remove_config_mk
|
||||
|
@ -32,7 +32,7 @@ ifdef BUILD_PROJECT
|
||||
#
|
||||
$(PROJECT_LIBRARY): $(OBJECTS_LIST)
|
||||
ifdef CLEAN_LIBRARY
|
||||
-$(CLEAN_LIBRARY) $(NO_OUTPUT)
|
||||
-$(CLEAN_LIBRARY) xx $(NO_OUTPUT)
|
||||
endif
|
||||
$(LINK_LIBRARY)
|
||||
|
||||
|
1
builds/newline
Normal file
1
builds/newline
Normal file
@ -0,0 +1 @@
|
||||
|
@ -97,7 +97,12 @@ ifdef check_platform
|
||||
# GNU make. Similarly, `nul' is created if e.g. `make setup win32' has
|
||||
# been erroneously used.
|
||||
#
|
||||
distclean:
|
||||
# note: this test is duplicated in "builds/toplevel.mk"
|
||||
is_unix := $(strip $(wildcard /sbin/init) $(wildcard /hurd/auth))
|
||||
ifneq ($(is_unix),)
|
||||
|
||||
|
||||
distclean:
|
||||
$(RM) builds/unix/config.cache
|
||||
$(RM) builds/unix/config.log
|
||||
$(RM) builds/unix/config.status
|
||||
@ -105,6 +110,8 @@ ifdef check_platform
|
||||
$(RM) builds/unix/unix-cc.mk
|
||||
$(RM) nul
|
||||
|
||||
endif # test is_unix
|
||||
|
||||
# IMPORTANT:
|
||||
#
|
||||
# `setup' must be defined by the host platform detection rules to create
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
ifeq ($(PLATFORM),ansi)
|
||||
|
||||
# note: this test is duplicated in "builds/toplevel.mk"
|
||||
is_unix := $(strip $(wildcard /sbin/init) $(wildcard /hurd/auth))
|
||||
ifneq ($(is_unix),)
|
||||
|
||||
|
@ -127,6 +127,20 @@ FT_BEGIN_HEADER
|
||||
#error "no 32bit type found -- please check your configuration files"
|
||||
#endif
|
||||
|
||||
/* now, lookup for an integer type that is at least 32 bits */
|
||||
#if FT_SIZEOF_INT >= 4
|
||||
|
||||
typedef int FT_Fast;
|
||||
typedef unsigned int FT_UFast;
|
||||
|
||||
#elif FT_SIZEOF_LONG >= 4
|
||||
|
||||
typedef long FT_Fast
|
||||
typedef unsigned long FT_UFast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* determine whether we have a 64-bit int type for platforms without */
|
||||
/* Autoconf */
|
||||
|
@ -436,7 +436,7 @@
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
|
||||
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
|
||||
|
||||
#define FT_CACHE_MANAGER_H <freetype/cache/ftcmanag.h>
|
||||
|
213
include/freetype/fttrigon.h
Normal file
213
include/freetype/fttrigon.h
Normal file
@ -0,0 +1,213 @@
|
||||
#ifndef __FT_TRIGONOMETRY_H__
|
||||
#define __FT_TRIGONOMETRY_H__
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @section: computations
|
||||
*
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @type: FT_Angle
|
||||
*
|
||||
* @description:
|
||||
* this type is used to model angle values in FreeType. Note that
|
||||
* the angle is a 16.16 fixed float value expressed in _degrees_
|
||||
*/
|
||||
typedef FT_Fixed FT_Angle;
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @macro: FT_ANGLE_PI
|
||||
*
|
||||
* @description:
|
||||
* the angle pi expressed in @FT_Angle units
|
||||
*/
|
||||
#define FT_ANGLE_PI (180L << 16)
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @macro: FT_ANGLE_2PI
|
||||
*
|
||||
* @description:
|
||||
* the angle 2pi expressed in @FT_Angle units
|
||||
*/
|
||||
#define FT_ANGLE_2PI (FT_ANGLE_PI*2)
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @macro: FT_ANGLE_PI2
|
||||
*
|
||||
* @description:
|
||||
* the angle pi/2 expressed in @FT_Angle units
|
||||
*/
|
||||
#define FT_ANGLE_PI2 (FT_ANGLE_PI/2)
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @macro: FT_ANGLE_PI4
|
||||
*
|
||||
* @description:
|
||||
* the angle pi/4 expressed in @FT_Angle units
|
||||
*/
|
||||
#define FT_ANGLE_PI4 (FT_ANGLE_PI/4)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Sin
|
||||
*
|
||||
* @description:
|
||||
* return the sinus of a given angle in fixed point format
|
||||
*
|
||||
* @input:
|
||||
* angle :: input angle
|
||||
*
|
||||
* @return:
|
||||
* sinus value
|
||||
*
|
||||
* @note:
|
||||
* if you need both the sinus and cosinus for a given angle, you'd
|
||||
* better use the function @FT_Vector_Unit
|
||||
*/
|
||||
FT_EXPORT(FT_Fixed) FT_Sin( FT_Angle angle );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Cos
|
||||
*
|
||||
* @description:
|
||||
* return the cosinus of a given angle in fixed point format
|
||||
*
|
||||
* @input:
|
||||
* angle :: input angle
|
||||
*
|
||||
* @return:
|
||||
* cosinus value
|
||||
*
|
||||
* @note:
|
||||
* if you need both the sinus and cosinus for a given angle, you'd
|
||||
* better use the function @FT_Vector_Unit
|
||||
*/
|
||||
FT_EXPORT(FT_Fixed) FT_Cos( FT_Angle angle );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Tan
|
||||
*
|
||||
* @description:
|
||||
* return the tangent of a given angle in fixed point format
|
||||
*
|
||||
* @input:
|
||||
* angle :: input angle
|
||||
*
|
||||
* @return:
|
||||
* tangent value
|
||||
*/
|
||||
FT_EXPORT(FT_Fixed) FT_Tan( FT_Angle angle );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Atan2
|
||||
*
|
||||
* @description:
|
||||
* return the arc-tangent corresponding to a given vector (x,y) in
|
||||
* the 2d plane
|
||||
*
|
||||
* @input:
|
||||
* x :: horizontal vector coordinate
|
||||
* y :: vertical vector coordinate
|
||||
*
|
||||
* @return:
|
||||
* arc-tangent value (i.e. angle)
|
||||
*/
|
||||
FT_EXPORT(FT_Angle) FT_Atan2( FT_Fixed x, FT_Fixed y );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Vector_Unit
|
||||
*
|
||||
* @description:
|
||||
* return the unit vector corresponding to a given angle. After the call,
|
||||
* the value of "vec.x" will be "sin(theta)", and the value of "vec.y"
|
||||
* will be "cos(angle)"
|
||||
*
|
||||
* this function is useful to retrieve both the sinus and cosinus
|
||||
* of a given angle quickly
|
||||
*
|
||||
* @input:
|
||||
* vec :: address of target vector
|
||||
* angle :: address of angle
|
||||
*/
|
||||
FT_EXPORT(void) FT_Vector_Unit( FT_Vector* vec,
|
||||
FT_Angle angle );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Vector_Rotate
|
||||
*
|
||||
* @description:
|
||||
* rotate a given vector by a given angle
|
||||
*
|
||||
* @input:
|
||||
* vec :: address of target vector
|
||||
* angle :: address of angle
|
||||
*/
|
||||
FT_EXPORT(void) FT_Vector_Rotate( FT_Vector* vec,
|
||||
FT_Angle angle );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Vector_Length
|
||||
*
|
||||
* @description:
|
||||
* returns the length of a given vector
|
||||
*
|
||||
* @input:
|
||||
* vec :: address of target vector
|
||||
*
|
||||
* @return:
|
||||
* vector length, expressed in the same units that the original
|
||||
* vector coordinates !!
|
||||
*/
|
||||
FT_EXPORT(FT_Fixed) FT_Vector_Length( FT_Vector* vec );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Vector_Normalize
|
||||
*
|
||||
* @description:
|
||||
* normalize a given vector (i.e. compute the equivalent unit vector)
|
||||
*
|
||||
* @input:
|
||||
* vec :: address of target vector
|
||||
*/
|
||||
FT_EXPORT(void) FT_Vector_Normalize( FT_Vector* vec );
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* @function: FT_Vector_Polarize
|
||||
*
|
||||
* @description:
|
||||
* compute both the length and angle of a given vector
|
||||
*
|
||||
* @input:
|
||||
* vec :: address of source vector
|
||||
*
|
||||
* @output:
|
||||
* length :: vector length
|
||||
* angle :: vector angle
|
||||
*/
|
||||
FT_EXPORT(void) FT_Vector_Polarize( FT_Vector* vec,
|
||||
FT_Fixed *length,
|
||||
FT_Angle *angle );
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __FT_TRIGONOMETRY_H__ */
|
@ -113,8 +113,8 @@ FT_BEGIN_HEADER
|
||||
FT_Bool force_bold;
|
||||
FT_Bool round_stem_up;
|
||||
|
||||
FT_Short snap_widths [13]; /* reserve one place for the std */
|
||||
FT_Short snap_heights[13]; /* reserve one place for the std */
|
||||
FT_Short snap_widths [13]; /* including std width */
|
||||
FT_Short snap_heights[13]; /* including std height */
|
||||
|
||||
FT_Long language_group;
|
||||
FT_Long password;
|
||||
@ -136,12 +136,12 @@ FT_BEGIN_HEADER
|
||||
/* */
|
||||
typedef enum
|
||||
{
|
||||
/* required fields in a FontInfo blend dictionary */
|
||||
/*# required fields in a FontInfo blend dictionary */
|
||||
t1_blend_underline_position = 0,
|
||||
t1_blend_underline_thickness,
|
||||
t1_blend_italic_angle,
|
||||
|
||||
/* required fields in a Private blend dictionary */
|
||||
/*# required fields in a Private blend dictionary */
|
||||
t1_blend_blue_values,
|
||||
t1_blend_other_blues,
|
||||
t1_blend_standard_width,
|
||||
@ -154,7 +154,7 @@ FT_BEGIN_HEADER
|
||||
t1_blend_family_other_blues,
|
||||
t1_blend_force_bold,
|
||||
|
||||
/* never remove */
|
||||
/*# never remove */
|
||||
t1_blend_max
|
||||
|
||||
} T1_Blend_Flags;
|
||||
|
@ -359,7 +359,7 @@
|
||||
outline->horz_major_dir = ah_dir_right;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* !1 */
|
||||
|
||||
/* Compute the vertical and horizontal major directions; this is */
|
||||
/* currently done by inspecting the `ft_outline_reverse_fill' flag. */
|
||||
@ -374,7 +374,7 @@
|
||||
outline->horz_major_dir = ah_dir_right;
|
||||
}
|
||||
|
||||
#endif /* 1 */
|
||||
#endif /* !1 */
|
||||
|
||||
outline->x_scale = face->size->metrics.x_scale;
|
||||
outline->y_scale = face->size->metrics.y_scale;
|
||||
|
@ -10,7 +10,7 @@ SubDirHdrs [ FT2_SubDir src base ] ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ftcalc ftextend ftlist ftobjs ftstream ftoutln ftnames ;
|
||||
_sources = ftcalc ftextend ftlist ftobjs ftstream ftoutln ftnames fttrigon ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||
|
||||
#include "ftcalc.c"
|
||||
#include "fttrigon.c"
|
||||
#include "ftobjs.c"
|
||||
#include "ftstream.c"
|
||||
#include "ftlist.c"
|
||||
|
@ -278,13 +278,13 @@
|
||||
#else
|
||||
|
||||
static void
|
||||
test_cubic_zero( FT_Pos y1,
|
||||
FT_Pos y2,
|
||||
FT_Pos y3,
|
||||
FT_Pos y4,
|
||||
FT_Fixed u,
|
||||
FT_Pos* min,
|
||||
FT_Pos* max )
|
||||
test_cubic_extrema( FT_Pos y1,
|
||||
FT_Pos y2,
|
||||
FT_Pos y3,
|
||||
FT_Pos y4,
|
||||
FT_Fixed u,
|
||||
FT_Pos* min,
|
||||
FT_Pos* max )
|
||||
{
|
||||
/* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */
|
||||
FT_Pos b = y3 - 2*y2 + y1;
|
||||
@ -373,34 +373,81 @@
|
||||
int shift = 0;
|
||||
|
||||
|
||||
/* technical explanation of what's happening there */
|
||||
/* */
|
||||
/* the following computation is based on the fact that for */
|
||||
/* any value "y", if "n" is the position of the most */
|
||||
/* significant bit of "abs(y)" (starting from 0 for the */
|
||||
/* least significant bit), then y is in the range */
|
||||
/* */
|
||||
/* "-2^n..2^n-1" */
|
||||
/* */
|
||||
/* we want to shift "a", "b" and "c" concurrently in order */
|
||||
/* to ensure that they all fit in 8.16 values, which maps */
|
||||
/* to the integer range "-2^23..2^23-1" */
|
||||
/* */
|
||||
/* necessarily, we need to shift "a", "b" and "c" so that */
|
||||
/* the most significant bit of their absolute values is at */
|
||||
/* _most_ at position 23 */
|
||||
/* */
|
||||
/* we begin by computing "t1" as the bitwise "or" of the */
|
||||
/* absolute values of "a", "b", "c" */
|
||||
/* */
|
||||
t1 = (FT_ULong)((a >= 0) ? a : -a );
|
||||
t2 = (FT_ULong)((b >= 0) ? b : -b );
|
||||
t1 |= t2;
|
||||
t2 = (FT_ULong)((c >= 0) ? c : -c );
|
||||
t1 |= t2;
|
||||
|
||||
/* now, the most significant bit of "t1" is sure to be the */
|
||||
/* msb of one of "a", "b", "c", depending on which one is */
|
||||
/* expressed in the greatest integer range.. */
|
||||
/* */
|
||||
/* we will now compute the "shift", by shifting "t1" as many */
|
||||
/* times as necessary to move its msb to position 23. */
|
||||
/* */
|
||||
/* this corresponds to a value of t1 that is in the range */
|
||||
/* 0x40_0000..0x7F_FFFF */
|
||||
/* */
|
||||
/* finally, we shift "a", "b" and "c" by the same amount. */
|
||||
/* this ensure that all values are now in the range */
|
||||
/* -2^23..2^23, i.e. that they're now expressed as 8.16 */
|
||||
/* fixed float numbers.. */
|
||||
/* */
|
||||
/* this also means that we're using 24 bits of precision */
|
||||
/* to compute the zeros, independently of the range of */
|
||||
/* the original polynom coefficients. */
|
||||
/* */
|
||||
/* this should ensure reasonably accurate values for the */
|
||||
/* zeros. Note that the latter are only expressed with */
|
||||
/* 16 bits when computing the extrema (the zeros need to */
|
||||
/* be in 0..1 exclusive to be considered part of the arc) */
|
||||
/* */
|
||||
|
||||
if ( t1 == 0 ) /* all coefficients are 0! */
|
||||
return;
|
||||
|
||||
if ( t1 > 0x7FFFFFL )
|
||||
if ( t1 > 0x7FFFFFUL )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
t1 >>= 1;
|
||||
} while ( t1 > 0x7FFFFFL );
|
||||
} while ( t1 > 0x7FFFFFUL );
|
||||
|
||||
/* losing some bits of precision, but we'll use 24 of them */
|
||||
/* for the computation anyway.. */
|
||||
a >>= shift;
|
||||
b >>= shift;
|
||||
c >>= shift;
|
||||
}
|
||||
else if ( t1 < 0x400000L )
|
||||
else if ( t1 < 0x400000UL )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
t1 <<= 1;
|
||||
} while ( t1 < 0x400000L );
|
||||
} while ( t1 < 0x400000UL );
|
||||
|
||||
a <<= shift;
|
||||
b <<= shift;
|
||||
@ -414,7 +461,7 @@
|
||||
if ( b != 0 )
|
||||
{
|
||||
t = - FT_DivFix( c, b ) / 2;
|
||||
test_cubic_zero( y1, y2, y3, y4, t, min, max );
|
||||
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -428,17 +475,17 @@
|
||||
{
|
||||
/* there is a single split point at -b/a */
|
||||
t = - FT_DivFix( b, a );
|
||||
test_cubic_zero( y1, y2, y3, y4, t, min, max );
|
||||
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* there are two solutions; we need to filter them though */
|
||||
d = FT_SqrtFixed( (FT_Int32)d );
|
||||
t = - FT_DivFix( b - d, a );
|
||||
test_cubic_zero( y1, y2, y3, y4, t, min, max );
|
||||
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
|
||||
|
||||
t = - FT_DivFix( b + d, a );
|
||||
test_cubic_zero( y1, y2, y3, y4, t, min, max );
|
||||
test_cubic_extrema( y1, y2, y3, y4, t, min, max );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1240,14 +1240,15 @@
|
||||
goto Success;
|
||||
|
||||
if ( error != FT_Err_Unknown_File_Format )
|
||||
goto Fail;
|
||||
goto Fail2;
|
||||
}
|
||||
}
|
||||
|
||||
ft_done_stream( &stream, external_stream );
|
||||
|
||||
/* no driver is able to handle this format */
|
||||
error = FT_Err_Unknown_File_Format;
|
||||
|
||||
Fail2:
|
||||
ft_done_stream( &stream, external_stream );
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
|
404
src/base/fttrigon.c
Normal file
404
src/base/fttrigon.c
Normal file
@ -0,0 +1,404 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_TRIGONOMETRY_H
|
||||
|
||||
/* the following is 0.2715717684432231 * 2^30 */
|
||||
#define FT_TRIG_COSCALE 0x11616E8E /* 291597966 = 0.2715717684432241 * 2^30, valid for j>13 */
|
||||
|
||||
/* this table was generated for FT_PI = 180L << 16, i.e. degrees */
|
||||
#define FT_TRIG_MAX_ITERS 23
|
||||
|
||||
static const FT_Fixed
|
||||
ft_trig_arctan_table[ 24 ] =
|
||||
{
|
||||
4157273, 2949120, 1740967, 919879, 466945, 234379, 117304, 58666,
|
||||
29335, 14668, 7334, 3667, 1833, 917, 458, 229, 115, 57, 29, 14, 7,
|
||||
4, 2, 1
|
||||
};
|
||||
|
||||
|
||||
/* the Cordic shrink factor, multiplied by 2^32 */
|
||||
#define FT_TRIG_SCALE 1166391785 /* 0x4585BA38U */
|
||||
|
||||
#ifdef FT_CONFIG_HAS_INT64
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
FT_Fixed s;
|
||||
FT_Int64 v;
|
||||
|
||||
s = val;
|
||||
val = (val >= 0) ? val : -val;
|
||||
|
||||
v = (val * (FT_Int64)FT_TRIG_SCALE) + 0x100000000L;
|
||||
val = (FT_Fixed)(v >> 32);
|
||||
|
||||
return ( s >= 0 ) ? val : -val;
|
||||
}
|
||||
|
||||
#else /* !FT_CONFIG_HAS_INT64 */
|
||||
|
||||
/* multiply a given value by the CORDIC shrink factor */
|
||||
static FT_Fixed
|
||||
ft_trig_downscale( FT_Fixed val )
|
||||
{
|
||||
FT_Fixed s;
|
||||
FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3;
|
||||
|
||||
s = val;
|
||||
val = ( val >= 0 ) ? val : -val;
|
||||
|
||||
v1 = (FT_UInt32)val >> 16;
|
||||
v2 = (FT_UInt32)val & 0xFFFF;
|
||||
|
||||
k1 = FT_TRIG_SCALE >> 16; /* constant */
|
||||
k2 = FT_TRIG_SCALE & 0xFFFF; /* constant */
|
||||
|
||||
hi = k1*v1;
|
||||
lo1 = k1*v2 + k2*v1; /* can't overflow */
|
||||
|
||||
lo2 = k2*v2 >> 16;
|
||||
lo3 = ( lo1 >= lo2 ) ? lo1 : lo2;
|
||||
lo1 += lo2;
|
||||
|
||||
hi += lo1 >> 16;
|
||||
if (lo1 < lo3)
|
||||
hi += 0x10000U;
|
||||
|
||||
val = (FT_Fixed)hi;
|
||||
|
||||
return ( s >= 0 ) ? val : -val;
|
||||
}
|
||||
|
||||
#endif /* !FT_CONFIG_HAS_INT64 */
|
||||
|
||||
|
||||
static FT_Int
|
||||
ft_trig_prenorm( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed x, y, z;
|
||||
FT_Int shift;
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
z = (( x >= 0 ) ? x : - x) | ((y >= 0) ? y : -y);
|
||||
shift = 0;
|
||||
|
||||
if ( z < (1L << 27) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z <<= 1;
|
||||
}
|
||||
while ( z < (1L << 27) );
|
||||
|
||||
vec->x = (x << shift);
|
||||
vec->y = (y << shift);
|
||||
}
|
||||
else if ( z > (1L << 28 ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
z >>= 1;
|
||||
}
|
||||
while ( z > (1L << 28) );
|
||||
|
||||
vec->x = (x >> shift);
|
||||
vec->y = (y >> shift);
|
||||
shift = -shift;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_rotate( FT_Vector* vec, FT_Angle theta )
|
||||
{
|
||||
FT_Int i;
|
||||
FT_Fixed x, y, xtemp;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get angle between -90 and 90 degrees */
|
||||
while (theta <= -FT_ANGLE_PI2)
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta += FT_ANGLE_PI;
|
||||
}
|
||||
while (theta > FT_ANGLE_PI2)
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta -= FT_ANGLE_PI;
|
||||
}
|
||||
|
||||
/* Initial pseudorotation, with left shift */
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
if (theta < 0)
|
||||
{
|
||||
xtemp = x + (y << 1);
|
||||
y = y - (x << 1);
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - (y << 1);
|
||||
y = y + (x << 1);
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
|
||||
/* Subsequent pseudorotations, with right shifts */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if (theta < 0)
|
||||
{
|
||||
xtemp = x + (y >> i);
|
||||
y = y - (x >> i);
|
||||
x = xtemp;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtemp = x - (y >> i);
|
||||
y = y + (x >> i);
|
||||
x = xtemp;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
}
|
||||
while ( ++i < FT_TRIG_MAX_ITERS );
|
||||
|
||||
vec->x = x;
|
||||
vec->y = y;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_trig_pseudo_polarize( FT_Vector* vec )
|
||||
{
|
||||
FT_Fixed theta;
|
||||
FT_Fixed yi, i;
|
||||
FT_Fixed x, y;
|
||||
const FT_Fixed *arctanptr;
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
|
||||
/* Get the vector into the right half plane */
|
||||
theta = 0;
|
||||
if (x < 0)
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
theta = 2 * FT_ANGLE_PI2;
|
||||
}
|
||||
|
||||
if (y > 0)
|
||||
theta = - theta;
|
||||
|
||||
arctanptr = ft_trig_arctan_table;
|
||||
if (y < 0)
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + (x << 1);
|
||||
x = x - (y << 1);
|
||||
y = yi;
|
||||
theta -= *arctanptr++; /* Subtract angle */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - (x << 1);
|
||||
x = x + (y << 1);
|
||||
y = yi;
|
||||
theta += *arctanptr++; /* Add angle */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
if (y < 0)
|
||||
{
|
||||
/* Rotate positive */
|
||||
yi = y + (x >> i);
|
||||
x = x - (y >> i);
|
||||
y = yi;
|
||||
theta -= *arctanptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rotate negative */
|
||||
yi = y - (x >> i);
|
||||
x = x + (y >> i);
|
||||
y = yi;
|
||||
theta += *arctanptr++;
|
||||
}
|
||||
}
|
||||
while (++i < FT_TRIG_MAX_ITERS);
|
||||
|
||||
/* round theta */
|
||||
if ( theta >= 0 )
|
||||
theta = ( theta + 16 ) & -32;
|
||||
else
|
||||
theta = - (( -theta + 16 ) & -32);
|
||||
|
||||
vec->x = x;
|
||||
vec->y = theta;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(FT_Fixed)
|
||||
FT_Cos( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
v.x = FT_TRIG_COSCALE >> 2;
|
||||
v.y = 0;
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
|
||||
return v.x >> 12;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(FT_Fixed)
|
||||
FT_Sin( FT_Angle angle )
|
||||
{
|
||||
return FT_Cos( FT_ANGLE_PI2-angle );
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(FT_Fixed)
|
||||
FT_Tan( FT_Angle angle )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
v.x = FT_TRIG_COSCALE >> 2;
|
||||
v.y = 0;
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
|
||||
return FT_DivFix( v.y, v.x );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FT_EXPORT_DEF(FT_Angle)
|
||||
FT_Atan2( FT_Fixed dx,
|
||||
FT_Fixed dy )
|
||||
{
|
||||
FT_Vector v;
|
||||
|
||||
if ( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
v.x = dx;
|
||||
v.y = dy;
|
||||
ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
return v.y;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(void)
|
||||
FT_Vector_Unit( FT_Vector* vec,
|
||||
FT_Angle angle )
|
||||
{
|
||||
vec->x = FT_TRIG_COSCALE >> 2;
|
||||
vec->y = 0;
|
||||
ft_trig_pseudo_rotate( vec, angle );
|
||||
vec->x >>= 12;
|
||||
vec->y >>= 12;
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(void)
|
||||
FT_Vector_Rotate( FT_Vector* vec,
|
||||
FT_Angle angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
v.x = vec->x;
|
||||
v.y = vec->y;
|
||||
if ( angle && ( v.x != 0 || v.y != 0 ) )
|
||||
{
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_rotate( &v, angle );
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
v.y = ft_trig_downscale( v.y );
|
||||
|
||||
if ( shift >= 0 )
|
||||
{
|
||||
vec->x = v.x >> shift;
|
||||
vec->y = v.y >> shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = -shift;
|
||||
vec->x = v.x << shift;
|
||||
vec->y = v.y << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(FT_Fixed)
|
||||
FT_Vector_Length( FT_Vector* vec )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
v = *vec;
|
||||
|
||||
/* handle trivial cases */
|
||||
if ( v.x == 0 )
|
||||
{
|
||||
return ( v.y >= 0 ) ? v.y : -v.y;
|
||||
}
|
||||
else if ( v.y == 0 )
|
||||
{
|
||||
return ( v.x >= 0 ) ? v.x : -v.x;
|
||||
}
|
||||
|
||||
/* general case */
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
return ( shift >= 0 ) ? (v.x >> shift) : (v.x << -shift);
|
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF(void)
|
||||
FT_Vector_Polarize( FT_Vector* vec,
|
||||
FT_Fixed *length,
|
||||
FT_Angle *angle )
|
||||
{
|
||||
FT_Int shift;
|
||||
FT_Vector v;
|
||||
|
||||
v = *vec;
|
||||
|
||||
if ( v.x == 0 && v.y == 0 )
|
||||
return;
|
||||
|
||||
shift = ft_trig_prenorm( &v );
|
||||
ft_trig_pseudo_polarize( &v );
|
||||
|
||||
v.x = ft_trig_downscale( v.x );
|
||||
|
||||
*length = ( shift >= 0 ) ? (v.x >> shift) : (v.x << -shift);
|
||||
*angle = v.y;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ BASE_COMPILE := $(FT_COMPILE) $I$(SRC_)base
|
||||
# ftsystem, ftinit, and ftdebug are handled by freetype.mk
|
||||
#
|
||||
BASE_SRC := $(BASE_)ftcalc.c \
|
||||
$(BASE_)fttrigon.c \
|
||||
$(BASE_)ftextend.c \
|
||||
$(BASE_)ftlist.c \
|
||||
$(BASE_)ftobjs.c \
|
||||
|
78
src/tools/cordic.py
Normal file
78
src/tools/cordic.py
Normal file
@ -0,0 +1,78 @@
|
||||
# compute arctangent table for CORDIC computations in fttrigon.c
|
||||
import sys, math
|
||||
|
||||
units = 180*65536 # don't change !!
|
||||
scale = units/math.pi
|
||||
shrink = 1.0
|
||||
comma = ""
|
||||
|
||||
def calc_val( x ):
|
||||
global units, shrink
|
||||
angle = math.atan(x)
|
||||
shrink = shrink * math.cos(angle)
|
||||
return angle/math.pi * units
|
||||
|
||||
def print_val( n, x ):
|
||||
global comma
|
||||
|
||||
lo = int(x)
|
||||
hi = lo + 1
|
||||
alo = math.atan(lo)
|
||||
ahi = math.atan(hi)
|
||||
ax = math.atan(2.0**n)
|
||||
|
||||
errlo = abs( alo - ax )
|
||||
errhi = abs( ahi - ax )
|
||||
|
||||
if ( errlo < errhi ):
|
||||
hi = lo
|
||||
|
||||
sys.stdout.write( comma + repr( int(hi) ) )
|
||||
comma = ", "
|
||||
|
||||
|
||||
print ""
|
||||
print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units"
|
||||
|
||||
# compute range of "i"
|
||||
r = [-1]
|
||||
r = r + range(32)
|
||||
|
||||
for n in r:
|
||||
|
||||
if n >= 0:
|
||||
x = 1.0/(2.0**n) # tangent value
|
||||
else:
|
||||
x = 2.0**(-n)
|
||||
|
||||
angle = math.atan(x) # arctangent
|
||||
angle2 = angle*scale # arctangent in FT_Angle units
|
||||
|
||||
# determine which integer value for angle gives the best tangent
|
||||
lo = int(angle2)
|
||||
hi = lo + 1
|
||||
tlo = math.tan(lo/scale)
|
||||
thi = math.tan(hi/scale)
|
||||
|
||||
errlo = abs( tlo - x )
|
||||
errhi = abs( thi - x )
|
||||
|
||||
angle2 = hi
|
||||
if errlo < errhi:
|
||||
angle2 = lo
|
||||
|
||||
if angle2 <= 0:
|
||||
break
|
||||
|
||||
sys.stdout.write( comma + repr( int(angle2) ) )
|
||||
comma = ", "
|
||||
|
||||
shrink = shrink * math.cos( angle2/scale)
|
||||
|
||||
|
||||
print
|
||||
print "shrink factor = " + repr( shrink )
|
||||
print "shrink factor 2 = " + repr( shrink * (2.0**32) )
|
||||
print "expansion factor = " + repr(1/shrink)
|
||||
print ""
|
||||
|
@ -25,7 +25,7 @@
|
||||
# - David
|
||||
#
|
||||
|
||||
import fileinput, sys, os, string, glob, getopt
|
||||
import fileinput, sys, os, time, string, glob, getopt
|
||||
|
||||
# The Project's title. This can be overridden from the command line with
|
||||
# the options "-t" or "--title".
|
||||
@ -216,6 +216,11 @@ def check_output( ):
|
||||
output_dir = None
|
||||
|
||||
|
||||
def compute_time_html( ):
|
||||
global html_footer
|
||||
time_string = time.asctime( time.localtime( time.time() ) )
|
||||
html_footer = "<p><center><font size=""-2"">generated on " + time_string + "</font></p></center>" + html_footer
|
||||
|
||||
# The FreeType 2 reference is extracted from the source files. These
|
||||
# contain various comment blocks that follow one of the following formats:
|
||||
#
|
||||
@ -1628,6 +1633,7 @@ def main( argv ):
|
||||
|
||||
html_header = html_header_1 + project_title + html_header_2 + project_title + html_header_3
|
||||
check_output( )
|
||||
compute_time_html()
|
||||
|
||||
# we begin by simply building a list of DocBlock elements
|
||||
#
|
160
src/tools/test_bbox.c
Normal file
160
src/tools/test_bbox.c
Normal file
@ -0,0 +1,160 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_BBOX_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
|
||||
|
||||
static long
|
||||
get_time( void )
|
||||
{
|
||||
return clock() * 10000L / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* test bbox computations */
|
||||
|
||||
#define XSCALE 65536
|
||||
#define XX(x) ((FT_Pos)(x*XSCALE))
|
||||
#define XVEC(x,y) { XX(x), XX(y) }
|
||||
#define XVAL(x) ((x)/(1.0*XSCALE))
|
||||
|
||||
/* dummy outline #1 */
|
||||
static FT_Vector dummy_vec_1[4] =
|
||||
{
|
||||
#if 1
|
||||
XVEC( 408.9111, 535.3164 ),
|
||||
XVEC( 455.8887, 634.396 ),
|
||||
XVEC( -37.8765, 786.2207 ),
|
||||
XVEC( 164.6074, 535.3164 )
|
||||
#else
|
||||
{ (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */
|
||||
{ (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */
|
||||
{ (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */
|
||||
{ (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static char dummy_tag_1[4] =
|
||||
{
|
||||
FT_Curve_Tag_On,
|
||||
FT_Curve_Tag_Cubic,
|
||||
FT_Curve_Tag_Cubic,
|
||||
FT_Curve_Tag_On
|
||||
};
|
||||
|
||||
static short dummy_contour_1[1] =
|
||||
{
|
||||
3
|
||||
};
|
||||
|
||||
static FT_Outline dummy_outline_1 =
|
||||
{
|
||||
1,
|
||||
4,
|
||||
dummy_vec_1,
|
||||
dummy_tag_1,
|
||||
dummy_contour_1,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* dummy outline #2 */
|
||||
static FT_Vector dummy_vec_2[4] =
|
||||
{
|
||||
XVEC( 100.0, 100.0 ),
|
||||
XVEC( 100.0, 200.0 ),
|
||||
XVEC( 200.0, 200.0 ),
|
||||
XVEC( 200.0, 133.0 )
|
||||
};
|
||||
|
||||
static FT_Outline dummy_outline_2 =
|
||||
{
|
||||
1,
|
||||
4,
|
||||
dummy_vec_2,
|
||||
dummy_tag_1,
|
||||
dummy_contour_1,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
dump_outline( FT_Outline* outline )
|
||||
{
|
||||
FT_BBox bbox;
|
||||
|
||||
/* compute and display cbox */
|
||||
FT_Outline_Get_CBox( outline, &bbox );
|
||||
printf( "cbox = [%.2f %.2f %.2f %.2f]\n",
|
||||
XVAL( bbox.xMin ),
|
||||
XVAL( bbox.yMin ),
|
||||
XVAL( bbox.xMax ),
|
||||
XVAL( bbox.yMax ) );
|
||||
|
||||
/* compute and display bbox */
|
||||
FT_Outline_Get_BBox( outline, &bbox );
|
||||
printf( "bbox = [%.2f %.2f %.2f %.2f]\n",
|
||||
XVAL( bbox.xMin ),
|
||||
XVAL( bbox.yMin ),
|
||||
XVAL( bbox.xMax ),
|
||||
XVAL( bbox.yMax ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
profile_outline( FT_Outline* outline,
|
||||
long repeat )
|
||||
{
|
||||
FT_BBox bbox;
|
||||
long count;
|
||||
long time0;
|
||||
|
||||
time0 = get_time();
|
||||
for ( count = repeat; count > 0; count-- )
|
||||
FT_Outline_Get_CBox( outline, &bbox );
|
||||
|
||||
time0 = get_time() - time0;
|
||||
printf( "time = %5.2f cbox = [%.2f %.2f %.2f %.2f]\n",
|
||||
((double)time0/10000.0),
|
||||
XVAL( bbox.xMin ),
|
||||
XVAL( bbox.yMin ),
|
||||
XVAL( bbox.xMax ),
|
||||
XVAL( bbox.yMax ) );
|
||||
|
||||
|
||||
time0 = get_time();
|
||||
for ( count = repeat; count > 0; count-- )
|
||||
FT_Outline_Get_BBox( outline, &bbox );
|
||||
|
||||
time0 = get_time() - time0;
|
||||
printf( "time = %5.2f bbox = [%.2f %.2f %.2f %.2f]\n",
|
||||
((double)time0/10000.0),
|
||||
XVAL( bbox.xMin ),
|
||||
XVAL( bbox.yMin ),
|
||||
XVAL( bbox.xMax ),
|
||||
XVAL( bbox.yMax ) );
|
||||
}
|
||||
|
||||
#define REPEAT 100000L
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
printf( "outline #1\n" );
|
||||
profile_outline( &dummy_outline_1, REPEAT );
|
||||
|
||||
printf( "outline #2\n" );
|
||||
profile_outline( &dummy_outline_2, REPEAT );
|
||||
return 0;
|
||||
}
|
||||
|
236
src/tools/test_trig.c
Normal file
236
src/tools/test_trig.c
Normal file
@ -0,0 +1,236 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_TRIGONOMETRY_H
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
#define SPI (PI/FT_ANGLE_PI)
|
||||
|
||||
/* the precision in 16.16 fixed float points of the checks. Expect */
|
||||
/* between 2 and 5 noise LSB bits during operations, due to */
|
||||
/* rounding errors.. */
|
||||
#define THRESHOLD 64
|
||||
|
||||
static error = 0;
|
||||
|
||||
static void
|
||||
test_cos( void )
|
||||
{
|
||||
FT_Fixed f1, f2;
|
||||
double d1, d2;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
f1 = FT_Cos(i);
|
||||
d1 = f1/65536.0;
|
||||
d2 = cos( i*SPI );
|
||||
f2 = (FT_Fixed)(d2*65536.0);
|
||||
|
||||
if ( abs( f2-f1 ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n",
|
||||
(i >> 16), f1/65536.0, (i >> 16), d2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_sin( void )
|
||||
{
|
||||
FT_Fixed f1, f2;
|
||||
double d1, d2;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
f1 = FT_Sin(i);
|
||||
d1 = f1/65536.0;
|
||||
d2 = sin( i*SPI );
|
||||
f2 = (FT_Fixed)(d2*65536.0);
|
||||
|
||||
if ( abs( f2-f1 ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n",
|
||||
(i >> 16), f1/65536.0, (i >> 16), d2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_tan( void )
|
||||
{
|
||||
FT_Fixed f1, f2;
|
||||
double d1, d2;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_PI2-0x2000000; i += 0x10000 )
|
||||
{
|
||||
f1 = FT_Tan(i);
|
||||
d1 = f1/65536.0;
|
||||
d2 = tan( i*SPI );
|
||||
f2 = (FT_Fixed)(d2*65536.0);
|
||||
|
||||
if ( abs( f2-f1 ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n",
|
||||
(i >> 16), f1/65536.0, (i >> 16), d2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_atan2( void )
|
||||
{
|
||||
FT_Fixed c2, s2;
|
||||
double l, a, c1, s1;
|
||||
int i, j;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
l = 5.0;
|
||||
a = i*SPI;
|
||||
|
||||
c1 = l * cos(a);
|
||||
s1 = l * sin(a);
|
||||
|
||||
c2 = (FT_Fixed)(c1*65536.0);
|
||||
s2 = (FT_Fixed)(s1*65536.0);
|
||||
|
||||
j = FT_Atan2( c2, s2 );
|
||||
if ( j < 0 )
|
||||
j += FT_ANGLE_2PI;
|
||||
|
||||
if ( abs( i - j ) > 1 )
|
||||
{
|
||||
printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n",
|
||||
c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_unit( void )
|
||||
{
|
||||
FT_Vector v;
|
||||
double a, c1, s1;
|
||||
FT_Fixed c2, s2;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
FT_Vector_Unit( &v, i );
|
||||
a = ( i*SPI );
|
||||
c1 = cos(a);
|
||||
s1 = sin(a);
|
||||
c2 = (FT_Fixed)(c1*65536.0);
|
||||
s2 = (FT_Fixed)(s1*65536.0);
|
||||
|
||||
if ( abs( v.x-c2 ) > THRESHOLD ||
|
||||
abs( v.y-s2 ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n",
|
||||
(i >> 16),
|
||||
v.x/65536.0, v.y/65536.0,
|
||||
c1, s1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_length( void )
|
||||
{
|
||||
FT_Vector v;
|
||||
FT_Fixed l, l2;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
l = (FT_Fixed)(500.0*65536.0);
|
||||
v.x = (FT_Fixed)( l * cos( i*SPI ) );
|
||||
v.y = (FT_Fixed)( l * sin( i*SPI ) );
|
||||
l2 = FT_Vector_Length( &v );
|
||||
|
||||
if ( abs( l2-l ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n",
|
||||
v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_rotate( void )
|
||||
{
|
||||
FT_Fixed c2, s2, c4, s4;
|
||||
FT_Vector v;
|
||||
double l, ra, a, c1, s1, cra, sra, c3, s3;
|
||||
int i, j, rotate;
|
||||
|
||||
for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000 )
|
||||
{
|
||||
ra = rotate*SPI;
|
||||
cra = cos( ra );
|
||||
sra = sin( ra );
|
||||
|
||||
for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 )
|
||||
{
|
||||
l = 500.0;
|
||||
a = i*SPI;
|
||||
|
||||
c1 = l * cos(a);
|
||||
s1 = l * sin(a);
|
||||
|
||||
v.x = c2 = (FT_Fixed)(c1*65536.0);
|
||||
v.y = s2 = (FT_Fixed)(s1*65536.0);
|
||||
|
||||
FT_Vector_Rotate( &v, rotate );
|
||||
|
||||
c3 = c1 * cra - s1 * sra;
|
||||
s3 = c1 * sra + s1 * cra;
|
||||
|
||||
c4 = (FT_Fixed)(c3*65536.0);
|
||||
s4 = (FT_Fixed)(s3*65536.0);
|
||||
|
||||
if ( abs( c4 - v.x ) > THRESHOLD ||
|
||||
abs( s4 - v.y ) > THRESHOLD )
|
||||
{
|
||||
error = 1;
|
||||
printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n",
|
||||
c1, s1, ra,
|
||||
c2/65536.0, s2/65536.0,
|
||||
c4/65536.0, s4/65536.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main( void )
|
||||
{
|
||||
test_cos();
|
||||
test_sin();
|
||||
test_tan();
|
||||
test_atan2();
|
||||
test_unit();
|
||||
test_length();
|
||||
test_rotate();
|
||||
|
||||
if (!error)
|
||||
printf( "trigonometry test ok !\n" );
|
||||
|
||||
return !error;
|
||||
}
|
Loading…
Reference in New Issue
Block a user