From 1452355de99d22b0cba6ccc17bf5cdf3682ef61e Mon Sep 17 00:00:00 2001
From: Werner Lemberg
diff --git a/builds/wince/vc2008-ce/index.html b/builds/wince/vc2008-ce/index.html index a6e74f893..80a30eb16 100644 --- a/builds/wince/vc2008-ce/index.html +++ b/builds/wince/vc2008-ce/index.html @@ -21,7 +21,7 @@ the following targets:
diff --git a/builds/windows/vc2010/index.html b/builds/windows/vc2010/index.html index ee9b59a2b..03149d223 100644 --- a/builds/windows/vc2010/index.html +++ b/builds/windows/vc2010/index.html @@ -12,7 +12,7 @@This directory contains solution and project files for Visual C++ 2010 or newer, named freetype.sln, and freetype.vcxproj. It compiles the following libraries -from the FreeType 2.13.2 sources:
+from the FreeType 2.13.3 sources:
This directory contains project files freetype.dsp for Visual C++ 6.0, and freetype.vcproj for Visual C++ 2002 through 2008, which you might need to upgrade automatically. -It compiles the following libraries from the FreeType 2.13.2 sources:
+It compiles the following libraries from the FreeType 2.13.3 sources:
diff --git a/docs/CHANGES b/docs/CHANGES
index 4c98128f8..bd7b12a8a 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,4 +1,4 @@
-CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Mmm-DD)
+CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Aug-11)
I. IMPORTANT CHANGES
@@ -17,8 +17,8 @@ CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Mmm-DD)
III. MISCELLANEOUS
- - The B/W rasterizer has received a major upkeep that resulted in
- large performance improvement. The rendering speed has increased
+ - The B/W rasterizer has received a major upkeep that results in
+ large performance improvements. The rendering speed has increased
and even doubled for very complex glyphs.
- If the new configuration option `TT_CONFIG_OPTION_GPOS_KERNING` is
diff --git a/docs/VERSIONS.TXT b/docs/VERSIONS.TXT
index 62481cb7f..a84067dfe 100644
--- a/docs/VERSIONS.TXT
+++ b/docs/VERSIONS.TXT
@@ -60,6 +60,7 @@ found on _most_ systems, but not all of them:
release libtool so
-------------------------------
+ 2.13.3 26.2.20 6.20.2
2.13.2 26.1.20 6.20.1
2.13.1 26.0.20 6.20.0
2.13.0 25.0.19 6.19.0
diff --git a/docs/freetype-config.1 b/docs/freetype-config.1
index 6ef1ac8f3..f52a4e6af 100644
--- a/docs/freetype-config.1
+++ b/docs/freetype-config.1
@@ -1,4 +1,4 @@
-.TH FREETYPE-CONFIG 1 "August 2023" "FreeType 2.13.2"
+.TH FREETYPE-CONFIG 1 "August 2024" "FreeType 2.13.3"
.
.
.SH NAME
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index b88ccc608..58fc33dfe 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -5174,7 +5174,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 13
-#define FREETYPE_PATCH 2
+#define FREETYPE_PATCH 3
/**************************************************************************
diff --git a/src/base/ftver.rc b/src/base/ftver.rc
index 62490c063..3175ab7de 100644
--- a/src/base/ftver.rc
+++ b/src/base/ftver.rc
@@ -18,8 +18,8 @@
#include
-#define FT_VERSION 2,13,2,0
-#define FT_VERSION_STR "2.13.2"
+#define FT_VERSION 2,13,3,0
+#define FT_VERSION_STR "2.13.3"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FT_VERSION
@@ -45,7 +45,7 @@ BEGIN
VALUE "FileVersion", FT_VERSION_STR
VALUE "ProductName", "FreeType"
VALUE "ProductVersion", FT_VERSION_STR
- VALUE "LegalCopyright", L"\x00A9 2000-2023 The FreeType Project www.freetype.org. All rights reserved."
+ VALUE "LegalCopyright", L"\x00A9 2000-2024 The FreeType Project www.freetype.org. All rights reserved."
VALUE "InternalName", "freetype"
VALUE "OriginalFilename", FT_FILENAME
END
From c4e6791f8286128714a9bd9d2be5b3a53ed8f89e Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Mon, 12 Aug 2024 20:19:19 -0400
Subject: [PATCH 19/94] * messon.build: Install `include/freetype/ftlogging.h`.
Fixes #1292.
---
meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/meson.build b/meson.build
index bedf13246..5126e0f82 100644
--- a/meson.build
+++ b/meson.build
@@ -159,6 +159,7 @@ ft2_public_headers = files([
'include/freetype/ftincrem.h',
'include/freetype/ftlcdfil.h',
'include/freetype/ftlist.h',
+ 'include/freetype/ftlogging.h',
'include/freetype/ftlzw.h',
'include/freetype/ftmac.h',
'include/freetype/ftmm.h',
From f92c96550ad763639158587974cf11067ace743d Mon Sep 17 00:00:00 2001
From: luz paz
Date: Tue, 13 Aug 2024 23:29:13 -0400
Subject: [PATCH 20/94] Fix various typos.
---
builds/cmake/FindHarfBuzz.cmake | 4 ++--
builds/wince/vc2005-ce/freetype.sln | 2 +-
builds/windows/ftdebug.c | 2 +-
docs/markdown/javascripts/extra.js | 2 +-
docs/oldlogs/ChangeLog.210 | 4 ++--
include/freetype/ftcolor.h | 4 ++--
include/freetype/internal/fttrace.h | 2 +-
include/freetype/internal/sfnt.h | 6 +++---
src/autofit/afcjk.c | 2 +-
src/autofit/aflatin.c | 2 +-
src/base/ftdebug.c | 2 +-
src/base/ftsynth.c | 2 +-
src/sdf/ftbsdf.c | 4 ++--
src/sdf/ftsdf.c | 2 +-
src/sdf/ftsdf.h | 2 +-
15 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/builds/cmake/FindHarfBuzz.cmake b/builds/cmake/FindHarfBuzz.cmake
index b481fa415..0f0e33a1a 100644
--- a/builds/cmake/FindHarfBuzz.cmake
+++ b/builds/cmake/FindHarfBuzz.cmake
@@ -28,8 +28,8 @@
# Try to find Harfbuzz include and library directories.
#
# After successful discovery, this will set for inclusion where needed:
-# HarfBuzz_INCLUDE_DIRS - containg the HarfBuzz headers
-# HarfBuzz_LIBRARIES - containg the HarfBuzz library
+# HarfBuzz_INCLUDE_DIRS - containing the HarfBuzz headers
+# HarfBuzz_LIBRARIES - containing the HarfBuzz library
#[=======================================================================[.rst:
FindHarfBuzz
diff --git a/builds/wince/vc2005-ce/freetype.sln b/builds/wince/vc2005-ce/freetype.sln
index ff4546388..62c6a657b 100644
--- a/builds/wince/vc2005-ce/freetype.sln
+++ b/builds/wince/vc2005-ce/freetype.sln
@@ -146,7 +146,7 @@ Global
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
- {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Releaase|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+ {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Standard SDK (ARMV4I)
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Standard SDK (ARMV4I)
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Standard SDK (ARMV4I)
diff --git a/builds/windows/ftdebug.c b/builds/windows/ftdebug.c
index 2c6996763..7d52de230 100644
--- a/builds/windows/ftdebug.c
+++ b/builds/windows/ftdebug.c
@@ -64,7 +64,7 @@
* with the actual log message if set to true.
*
* 5. The flag `ft_timestamp_flag` prints time along with the actual log
- * message if set to ture.
+ * message if set to true.
*
* 6. `ft_have_newline_char` is used to differentiate between a log
* message with and without a trailing newline character.
diff --git a/docs/markdown/javascripts/extra.js b/docs/markdown/javascripts/extra.js
index 00f167089..b1ce774fa 100644
--- a/docs/markdown/javascripts/extra.js
+++ b/docs/markdown/javascripts/extra.js
@@ -1,5 +1,5 @@
/*
-Internal link topbar offest adjust Javascript
+Internal link topbar offset adjust Javascript
Code provided by @makshh on GitHub
Bug report on material-mkdocs
diff --git a/docs/oldlogs/ChangeLog.210 b/docs/oldlogs/ChangeLog.210
index 3cf9ea961..135af9760 100644
--- a/docs/oldlogs/ChangeLog.210
+++ b/docs/oldlogs/ChangeLog.210
@@ -2983,7 +2983,7 @@
[raster] Tune SMART macro (#58352).
Windows seems to perform smart dropout control at 26.6 precision.
- To mimick Windows independent of increased precision, we need to tweak
+ To mimic Windows independent of increased precision, we need to tweak
the macro so that some close calls break down rather than up.
* src/raster/ftraster.c (SMART): Tweak the macro.
@@ -6484,7 +6484,7 @@
Add internal functions `FT_Trace_Disable' and `FT_Trace_Enable'.
- It sometimes makes sense to suppress tracing informations, for
+ It sometimes makes sense to suppress tracing information, for
example, if it outputs identical messages again and again.
* include/freetype/internal/ftdebug.h: Make `ft_trace_levels' a
diff --git a/include/freetype/ftcolor.h b/include/freetype/ftcolor.h
index 420720ddf..002d6c133 100644
--- a/include/freetype/ftcolor.h
+++ b/include/freetype/ftcolor.h
@@ -1518,7 +1518,7 @@ FT_BEGIN_HEADER
*
* @return:
* Value~1 if a clip box is found. If no clip box is found or an error
- * occured, value~0 is returned.
+ * occurred, value~0 is returned.
*
* @note:
* To retrieve the clip box in font units, reset scale to units-per-em
@@ -1646,7 +1646,7 @@ FT_BEGIN_HEADER
*
* @return:
* Value~1 if everything is OK. Value~0 if no details can be found for
- * this paint or any other error occured.
+ * this paint or any other error occurred.
*
* @since:
* 2.13
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index 42595a29f..f1ed81343 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -19,7 +19,7 @@
/* definitions of trace levels for FreeType 2 */
/* the maximum string length (if the argument to `FT_TRACE_DEF` */
- /* gets used as a string) plus one charachter for ':' plus */
+ /* gets used as a string) plus one character for ':' plus */
/* another one for the trace level */
#define FT_MAX_TRACE_LEVEL_LENGTH (9 + 1 + 1)
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 35e4e73af..69c81f6da 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -612,7 +612,7 @@ FT_BEGIN_HEADER
*
* @return:
* Value~1 if a ClipBox is found. If no clip box is found or an
- * error occured, value~0 is returned.
+ * error occurred, value~0 is returned.
*/
typedef FT_Bool
( *TT_Get_Color_Glyph_ClipBox_Func )( TT_Face face,
@@ -707,7 +707,7 @@ FT_BEGIN_HEADER
*
* @return:
* Value~1 if everything is OK. Value~0 if no details can be found for
- * this paint or any other error occured.
+ * this paint or any other error occurred.
*/
typedef FT_Bool
( *TT_Get_Paint_Func )( TT_Face face,
@@ -808,7 +808,7 @@ FT_BEGIN_HEADER
* corresponding (1,0) Apple entry.
*
* @return:
- * 1 if there is either a win or apple entry (or both), 0 otheriwse.
+ * 1 if there is either a win or apple entry (or both), 0 otherwise.
*/
typedef FT_Bool
(*TT_Get_Name_ID_Func)( TT_Face face,
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 869b60487..d24ad821f 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -1378,7 +1378,7 @@
}
- /* Initalize hinting engine. */
+ /* Initialize hinting engine. */
FT_LOCAL_DEF( FT_Error )
af_cjk_hints_init( AF_GlyphHints hints,
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 89287f7ea..87b56db61 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -2610,7 +2610,7 @@
}
- /* Initalize hinting engine. */
+ /* Initialize hinting engine. */
static FT_Error
af_latin_hints_init( AF_GlyphHints hints,
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
index 11307eaac..760003985 100644
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -64,7 +64,7 @@
* with the actual log message if set to true.
*
* 5. The flag `ft_timestamp_flag` prints time along with the actual log
- * message if set to ture.
+ * message if set to true.
*
* 6. `ft_have_newline_char` is used to differentiate between a log
* message with and without a trailing newline character.
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index ec05bce33..b5e361174 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -141,7 +141,7 @@
/*
* XXX: overflow check for 16-bit system, for compatibility
* with FT_GlyphSlot_Embolden() since FreeType 2.1.10.
- * unfortunately, this function return no informations
+ * unfortunately, this function return no information
* about the cause of error.
*/
if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index adde05ba1..10d1de8a3 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -373,7 +373,7 @@
* @Input:
* current ::
* Array of Euclidean distances. `current` must point to the position
- * for which the distance is to be caculated. We treat this array as
+ * for which the distance is to be calculated. We treat this array as
* a two-dimensional array mapped to a one-dimensional array.
*
* x ::
@@ -550,7 +550,7 @@
*
* @Description:
* Loops over all the pixels and call `compute_edge_distance` only for
- * edge pixels. This maked the process a lot faster since
+ * edge pixels. This makes the process a lot faster since
* `compute_edge_distance` uses functions such as `FT_Vector_NormLen',
* which are quite slow.
*
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index dc55d4263..8b3ff6776 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -3456,7 +3456,7 @@
* A complete shape which is used to generate SDF.
*
* spread ::
- * Maximum distances to be allowed inthe output bitmap.
+ * Maximum distances to be allowed in the output bitmap.
*
* @Output:
* bitmap ::
diff --git a/src/sdf/ftsdf.h b/src/sdf/ftsdf.h
index 25a0a13bb..d1ca8d375 100644
--- a/src/sdf/ftsdf.h
+++ b/src/sdf/ftsdf.h
@@ -57,7 +57,7 @@ FT_BEGIN_HEADER
* indicate positions inside of contours.
*
* flip_y ::
- * Setting this parameter to true maked the output image flipped
+ * Setting this parameter to true makes the output image flipped
* along the y-axis.
*
* overlaps ::
From 4f00846dde0a9d97e28b654665259ec3dc12d0d7 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sun, 25 Aug 2024 18:13:10 +0000
Subject: [PATCH 21/94] * include/freetype/ftimage.h (FT_Bitmap): Describe
empty bitmap.
---
include/freetype/ftimage.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 2b4b4ac60..33070fb12 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -267,6 +267,10 @@ FT_BEGIN_HEADER
* *logical* one. For example, if @FT_Pixel_Mode is set to
* `FT_PIXEL_MODE_LCD`, the logical width is a just a third of the
* physical one.
+ *
+ * An empty bitmap with a NULL `buffer` is valid, with `rows` and/or
+ * `pitch` also set to 0. Such bitmaps might be produced while rendering
+ * empty or degenerate outlines.
*/
typedef struct FT_Bitmap_
{
From d2612e1c3ff839595fbf67c8263a07d6bac3aaf5 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Mon, 26 Aug 2024 07:01:19 -0400
Subject: [PATCH 22/94] * src/sfnt/ttcmap.c (tt_cmap*_get_info): Remove
casting.
---
src/sfnt/ttcmap.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 28f4d1173..3e40da6b0 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -179,7 +179,7 @@
cmap_info->format = 0;
- cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
+ cmap_info->language = TT_PEEK_USHORT( p );
return FT_Err_Ok;
}
@@ -596,7 +596,7 @@
cmap_info->format = 2;
- cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
+ cmap_info->language = TT_PEEK_USHORT( p );
return FT_Err_Ok;
}
@@ -1539,7 +1539,7 @@
cmap_info->format = 4;
- cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
+ cmap_info->language = TT_PEEK_USHORT( p );
return FT_Err_Ok;
}
@@ -1712,7 +1712,7 @@
cmap_info->format = 6;
- cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
+ cmap_info->language = TT_PEEK_USHORT( p );
return FT_Err_Ok;
}
@@ -2009,7 +2009,7 @@
cmap_info->format = 8;
- cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
+ cmap_info->language = TT_PEEK_ULONG( p );
return FT_Err_Ok;
}
@@ -2184,7 +2184,7 @@
cmap_info->format = 10;
- cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
+ cmap_info->language = TT_PEEK_ULONG( p );
return FT_Err_Ok;
}
@@ -2528,7 +2528,7 @@
cmap_info->format = 12;
- cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
+ cmap_info->language = TT_PEEK_ULONG( p );
return FT_Err_Ok;
}
@@ -2844,7 +2844,7 @@
cmap_info->format = 13;
- cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
+ cmap_info->language = TT_PEEK_ULONG( p );
return FT_Err_Ok;
}
From e622c3c4cdbfd9549393a0f5866f6d5a3e67dd0a Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Tue, 3 Sep 2024 15:59:42 +0900
Subject: [PATCH 23/94] Improve the build rule for `apinames`.
* builds/unix/configure.raw: copy `CFLAGS` &
`LDFLAGS` values to `CFLAGS_BUILD` &
`LDFLAGS_BUILD`, in a self-hosting case.
* builds/unix/unix-cc.in: set `CCexe_CFLAGS` &
`CCexe_LDFLAGS` by `CFLAGS_BUILD` &
`LDFLAGS_BUILD`.
In some confused environments, simple building
like `cc -o apinames apinames.c` is no longer
able to build an executable running on the host.
The validity of `CC` is tested with consideration
of `CFLAGS` and `LDFLAGS`, thus, duplicating
`CFLAGS` & `LDFLAGS` to `CCexe_CFLAGS` &
`CCexe_LDFLAGS` (via XXX_BUILD) would be slightly
safer in a self-hosting build.
Fixes the issue #1296.
---
builds/unix/configure.raw | 6 ++++++
builds/unix/unix-cc.in | 4 +++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw
index 7a795cbc0..0aa5e6558 100644
--- a/builds/unix/configure.raw
+++ b/builds/unix/configure.raw
@@ -62,12 +62,18 @@ if test ${cross_compiling} = yes; then
fi
rm -f a.* b.* a_out.exe conftest.*
AC_MSG_RESULT($EXEEXT_BUILD)
+ CFLAGS_BUILD=
+ LDFLAGS_BUILD=
else
CC_BUILD=${CC}
+ CFLAGS_BUILD=${CFLAGS}
+ LDFLAGS_BUILD=${LDFLAGS}
EXEEXT_BUILD=${EXEEXT}
fi
AC_SUBST(CC_BUILD)
+AC_SUBST(CFLAGS_BUILD)
+AC_SUBST(LDFLAGS_BUILD)
AC_SUBST(EXEEXT_BUILD)
diff --git a/builds/unix/unix-cc.in b/builds/unix/unix-cc.in
index aafad2f97..9e329d23f 100644
--- a/builds/unix/unix-cc.in
+++ b/builds/unix/unix-cc.in
@@ -113,7 +113,9 @@ LDFLAGS := @LDFLAGS@
CCraw_build := @CC_BUILD@ # native CC of building system
E_BUILD := @EXEEXT_BUILD@ # extension for executable on building system
EXPORTS_LIST := $(OBJ_DIR)/ftexport.sym
-CCexe := $(CCraw_build) # used to compile `apinames' only
+CCexe := $(CCraw_build) # used to compile `apinames' only, see exports.mk
+CCexe_CFLAGS := @CFLAGS_BUILD@ # ditto.
+CCexe_LDFLAGS := @LDFLAGS_BUILD@ # ditto.
# Library linking.
From aaa559eaca14583b8e7851d1fa7e7231de140f6d Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Wed, 4 Sep 2024 22:33:01 +0900
Subject: [PATCH 24/94] Add `clang` to host compiler candidates in cross
building.
* builds/unix/configure.raw: In cross building,
`clang` is tried if there is no `gcc`, nor `cc`.
---
builds/unix/configure.raw | 1 +
1 file changed, 1 insertion(+)
diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw
index 0aa5e6558..46d957245 100644
--- a/builds/unix/configure.raw
+++ b/builds/unix/configure.raw
@@ -46,6 +46,7 @@ if test ${cross_compiling} = yes; then
AC_CHECK_PROG(CC_BUILD, ${build}-gcc, ${build}-gcc)
test -z "${CC_BUILD}" && AC_CHECK_PROG(CC_BUILD, gcc, gcc)
test -z "${CC_BUILD}" && AC_CHECK_PROG(CC_BUILD, cc, cc, , , /usr/ucb/cc)
+ test -z "${CC_BUILD}" && AC_CHECK_PROG(CC_BUILD, clang, clang)
test -z "${CC_BUILD}" && AC_MSG_ERROR([cannot find native C compiler])
AC_MSG_CHECKING([for suffix of native executables])
From 98283cb30f3f9776be67c089ef59fac00d9469a0 Mon Sep 17 00:00:00 2001
From: Andrew Murray
Date: Fri, 6 Sep 2024 17:03:58 +1000
Subject: [PATCH 25/94] [sfnt] Support sbix graphicType 'flip'.
* src/sfnt/ttsbit.c (tt_face_load_sbix_image): Currently undocumented by
Apple, this flips the bitmap data horizontally. It is used on macOS in
Apple Color Emoji; 19.4d6e1; 2024-02-05 (file `Apple Color Emoji.ttc`).
Fixes issue #1282.
---
src/sfnt/ttsbit.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index cb3a8abf1..9738d464f 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1462,6 +1462,7 @@
FT_Int originOffsetX, originOffsetY;
FT_Tag graphicType;
FT_Int recurse_depth = 0;
+ FT_Bool flipped = FALSE;
FT_Error error;
FT_Byte* p;
@@ -1517,12 +1518,17 @@
switch ( graphicType )
{
+ case FT_MAKE_TAG( 'f', 'l', 'i', 'p' ):
case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
if ( recurse_depth < 4 )
{
glyph_index = FT_GET_USHORT();
FT_FRAME_EXIT();
recurse_depth++;
+
+ if ( graphicType == FT_MAKE_TAG( 'f', 'l', 'i', 'p' ) )
+ flipped = TRUE;
+
goto retry;
}
error = FT_THROW( Invalid_File_Format );
@@ -1540,6 +1546,42 @@
glyph_end - glyph_start - 8,
TRUE,
metrics_only );
+ if ( !error && flipped )
+ {
+ FT_UInt32* curr_pos = (FT_UInt32*)map->buffer;
+
+ /* `Load_SBit_Png` always returns a pixmap with 32 bits per pixel */
+ /* and no extra pitch bytes. */
+ FT_UInt32 width = (FT_UInt32)( map->width );
+ FT_UInt32 half_width = (FT_UInt32)( map->width / 2 );
+
+ FT_UInt y;
+
+
+ for ( y = 0; y < map->rows; y++ )
+ {
+ FT_UInt32* left = curr_pos;
+ FT_UInt32* right = curr_pos + width - 1;
+
+ FT_UInt32 x;
+
+
+ for ( x = 0; x < half_width; x++ )
+ {
+ FT_UInt32 value;
+
+
+ value = *right;
+ *right = *left;
+ *left = value;
+
+ left++;
+ right--;
+ }
+
+ curr_pos += width;
+ }
+ }
#else
error = FT_THROW( Unimplemented_Feature );
#endif
From 3008032062e2ce8549c26b42ae55c6e02439f27c Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 6 Sep 2024 13:43:47 +0000
Subject: [PATCH 26/94] * src/sfnt/ttsbit.c (tt_face_load_sbix_image): Tweak
loop.
---
src/sfnt/ttsbit.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 9738d464f..94dcb52f9 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1552,9 +1552,7 @@
/* `Load_SBit_Png` always returns a pixmap with 32 bits per pixel */
/* and no extra pitch bytes. */
- FT_UInt32 width = (FT_UInt32)( map->width );
- FT_UInt32 half_width = (FT_UInt32)( map->width / 2 );
-
+ FT_UInt width = map->width;
FT_UInt y;
@@ -1563,10 +1561,8 @@
FT_UInt32* left = curr_pos;
FT_UInt32* right = curr_pos + width - 1;
- FT_UInt32 x;
-
- for ( x = 0; x < half_width; x++ )
+ while( left < right )
{
FT_UInt32 value;
From 83af801b552111e37d9466a887e1783a0fb5f196 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sat, 7 Sep 2024 13:44:57 -0400
Subject: [PATCH 27/94] * src/sfnt/ttsbit.c (tt_face_load_sbix_image): Respect
metrics_only.
Also fixes recursive flip.
---
src/sfnt/ttsbit.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 94dcb52f9..0b7227607 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1467,8 +1467,8 @@
FT_Error error;
FT_Byte* p;
- FT_UNUSED( map );
#ifndef FT_CONFIG_OPTION_USE_PNG
+ FT_UNUSED( map );
FT_UNUSED( metrics_only );
#endif
@@ -1527,7 +1527,7 @@
recurse_depth++;
if ( graphicType == FT_MAKE_TAG( 'f', 'l', 'i', 'p' ) )
- flipped = TRUE;
+ flipped = !flipped;
goto retry;
}
@@ -1546,7 +1546,7 @@
glyph_end - glyph_start - 8,
TRUE,
metrics_only );
- if ( !error && flipped )
+ if ( flipped && !metrics_only && !error )
{
FT_UInt32* curr_pos = (FT_UInt32*)map->buffer;
@@ -1562,7 +1562,7 @@
FT_UInt32* right = curr_pos + width - 1;
- while( left < right )
+ while ( left < right )
{
FT_UInt32 value;
From c82745878da1acef2ce6bd7e17a8d59b8612d509 Mon Sep 17 00:00:00 2001
From: Jouk Jansen
Date: Sat, 21 Sep 2024 06:41:47 +0200
Subject: [PATCH 28/94] Minor fixes for OpenVMS.
* vms_name.com: Suppress a warning with the latest Clang compiler.
* builds/vms/apinames_vms.bash: Use absolute path to avoid dependency on the
environment.
---
builds/vms/apinames_vms.bash | 2 +-
vms_make.com | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/builds/vms/apinames_vms.bash b/builds/vms/apinames_vms.bash
index e9b1b727b..1928d21ae 100644
--- a/builds/vms/apinames_vms.bash
+++ b/builds/vms/apinames_vms.bash
@@ -1,2 +1,2 @@
src/tools/apinames -wV include/freetype/*.h > freetype_vms0.opt
-mv freetype_vms0.opt freetype_vms.opt
+/gnu/bin/mv freetype_vms0.opt freetype_vms.opt
diff --git a/vms_make.com b/vms_make.com
index 65d2eb586..c766a80d3 100644
--- a/vms_make.com
+++ b/vms_make.com
@@ -1499,7 +1499,8 @@ $ deck
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.sfnt])
.ifdef X86
-CXXFLAGS=$(CXXCOMP_FLAGS) -I[] -I[--.include] -I[--.src.base] -Isys$library
+CXXFLAGS=$(CXXCOMP_FLAGS) -I[] -I[--.include] -I[--.src.base] -Isys$library\
+ -Wno-incompatible-pointer-types
.endif
.ifdef X86
From 0dd4eef68fb5f79e87d8cf61570faa2162f1190b Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Thu, 10 Oct 2024 15:56:22 +0900
Subject: [PATCH 29/94] Fix help message of apinames.
* src/tools/apinames.c: The first header file must be
given after the options. All arguments after the
first header file are dealt as header files to be
parsed, regardless with their leading "-".
For example,
"apinames include/freetype/freetype.h -dFREETYPE.DLL"
warns "unable to open -dFREETYPE.DLL".
Thus, the "header1" must be given after the arguments
to be parsed as the options.
---
src/tools/apinames.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tools/apinames.c b/src/tools/apinames.c
index 5a49b0649..38407b2d7 100644
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -380,7 +380,7 @@ usage( void )
"It receives a list of header files as an argument and\n"
"generates a sorted list of unique identifiers in various formats.\n"
"\n"
- "usage: %s header1 [options] [header2 ...]\n"
+ "usage: %s [options] header1 [header2 ...]\n"
"\n"
"options: - parse the contents of stdin, ignore arguments\n"
" -v verbose mode, output sent to standard error\n"
From f4c2a44ea98d0764262cb02e5d772f17daa36a56 Mon Sep 17 00:00:00 2001
From: Benoit Pierre
Date: Sat, 12 Oct 2024 10:47:38 +0000
Subject: [PATCH 30/94] * meson.build: Add support for compiling with error
strings. * meson_options.txt: Document it.
---
meson.build | 4 ++++
meson_options.txt | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/meson.build b/meson.build
index 5126e0f82..72b7f9900 100644
--- a/meson.build
+++ b/meson.build
@@ -363,6 +363,10 @@ if brotli_dep.found()
ft2_deps += [brotli_dep]
endif
+if get_option('error_strings')
+ ftoption_command += ['--enable=FT_CONFIG_OPTION_ERROR_STRINGS']
+endif
+
# We can now generate `ftoption.h`.
ftoption_h = custom_target('ftoption.h',
input: 'include/freetype/config/ftoption.h',
diff --git a/meson_options.txt b/meson_options.txt
index ce035b98d..d4aeb4a8b 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -52,4 +52,9 @@ option('zlib',
'disabled', 'enabled' ],
description: 'Support reading gzip-compressed font files')
+option('error_strings',
+ type: 'boolean',
+ value: false,
+ description: 'Enable support for meaningful error descriptions')
+
# EOF
From 34aed655f1696da774b5cdd4c5effb312153232f Mon Sep 17 00:00:00 2001
From: Benoit Pierre
Date: Sat, 12 Oct 2024 10:49:46 +0000
Subject: [PATCH 31/94] * meson.build: Fix `bzip2` option handling.
---
meson.build | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/meson.build b/meson.build
index 72b7f9900..2e8d5355e 100644
--- a/meson.build
+++ b/meson.build
@@ -320,11 +320,16 @@ else
endif
# BZip2 support.
-bzip2_dep = dependency('bzip2', required: false)
+bzip2_dep = dependency(
+ 'bzip2',
+ required: get_option('bzip2').disabled() ? get_option('bzip2') : false,
+)
if not bzip2_dep.found()
- bzip2_dep = cc.find_library('bz2',
+ bzip2_dep = cc.find_library(
+ 'bz2',
has_headers: ['bzlib.h'],
- required: get_option('bzip2'))
+ required: get_option('bzip2'),
+ )
endif
if bzip2_dep.found()
From 78ff353509efe159f685bac3719f0bec9f737a4f Mon Sep 17 00:00:00 2001
From: Benoit Pierre
Date: Sat, 12 Oct 2024 10:51:25 +0000
Subject: [PATCH 32/94] * meson.build: Minor improvements.
---
meson.build | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/meson.build b/meson.build
index 2e8d5355e..8fe11bb21 100644
--- a/meson.build
+++ b/meson.build
@@ -486,10 +486,10 @@ summary({'OS': host_machine.system(),
}, section: 'Operating System')
summary({'Zlib': zlib_option,
- 'Bzip2': bzip2_dep.found() ? 'yes' : 'no',
- 'Png': libpng_dep.found() ? 'yes' : 'no',
- 'Harfbuzz': harfbuzz_dep.found() ? 'yes' : 'no',
- 'Brotli': brotli_dep.found() ? 'yes' : 'no',
- }, section: 'Used Libraries')
+ 'Bzip2': bzip2_dep.found(),
+ 'Png': libpng_dep.found(),
+ 'Harfbuzz': harfbuzz_dep.found(),
+ 'Brotli': brotli_dep.found(),
+ }, bool_yn: true, section: 'Used Libraries')
# EOF
From b4ca23bed171ec8ed19b0e1b8d139ef617147729 Mon Sep 17 00:00:00 2001
From: Marian Klymov
Date: Sat, 12 Oct 2024 10:57:59 +0000
Subject: [PATCH 33/94] * meson.build: Define DLL_EXPORT for shared library
only.
Fixes #1298.
---
meson.build | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index 8fe11bb21..cfbb5b9f5 100644
--- a/meson.build
+++ b/meson.build
@@ -383,7 +383,8 @@ ftoption_h = custom_target('ftoption.h',
ft2_sources += ftoption_h
ft2_defines += ['-DFT_CONFIG_OPTIONS_H=']
-if host_machine.system() == 'windows'
+if host_machine.system() == 'windows' and \
+ get_option('default_library') == 'shared'
ft2_defines += ['-DDLL_EXPORT=1']
endif
From 7c09421d83d6d996a5cbefcbe79d81ca6e514a20 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sat, 12 Oct 2024 08:22:51 -0400
Subject: [PATCH 34/94] * vms_make.com: Format rules.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use tabs in rules only à la Makefile.
---
vms_make.com | 352 +++++++++++++++++++++++++--------------------------
1 file changed, 176 insertions(+), 176 deletions(-)
diff --git a/vms_make.com b/vms_make.com
index c766a80d3..03ecc721c 100644
--- a/vms_make.com
+++ b/vms_make.com
@@ -221,77 +221,77 @@ $ deck
all :
- define config [--.include.freetype.config]
- define internal [--.include.freetype.internal]
- define autofit [-.autofit]
- define base [-.base]
- define cache [-.cache]
- define cff [-.cff]
- define cid [-.cid]
- define freetype [--.include.freetype]
- define pcf [-.pcf]
- define psaux [-.psaux]
- define psnames [-.psnames]
- define raster [-.raster]
- define sfnt [-.sfnt]
- define smooth [-.smooth]
- define truetype [-.truetype]
- define type1 [-.type1]
- define winfonts [-.winfonts]
- if f$search("lib.dir") .eqs. "" then create/directory [.lib]
- set default [.builds.vms]
- $(MMS)$(MMSQUALIFIERS)
- set default [--.src.autofit]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.base]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.bdf]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.cache]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.cff]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.cid]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.gxvalid]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.gzip]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.bzip2]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.lzw]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.otvalid]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.pcf]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.pfr]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.psaux]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.pshinter]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.psnames]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.raster]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.sfnt]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.smooth]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.svg]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.truetype]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.type1]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.type42]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.winfonts]
- $(MMS)$(MMSQUALIFIERS)
- set default [-.sdf]
- $(MMS)$(MMSQUALIFIERS)
- set default [--]
+ define config [--.include.freetype.config]
+ define internal [--.include.freetype.internal]
+ define autofit [-.autofit]
+ define base [-.base]
+ define cache [-.cache]
+ define cff [-.cff]
+ define cid [-.cid]
+ define freetype [--.include.freetype]
+ define pcf [-.pcf]
+ define psaux [-.psaux]
+ define psnames [-.psnames]
+ define raster [-.raster]
+ define sfnt [-.sfnt]
+ define smooth [-.smooth]
+ define truetype [-.truetype]
+ define type1 [-.type1]
+ define winfonts [-.winfonts]
+ if f$search("lib.dir") .eqs. "" then create/directory [.lib]
+ set default [.builds.vms]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [--.src.autofit]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.base]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.bdf]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.cache]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.cff]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.cid]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.gxvalid]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.gzip]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.bzip2]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.lzw]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.otvalid]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.pcf]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.pfr]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.psaux]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.pshinter]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.psnames]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.raster]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.sfnt]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.smooth]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.svg]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.truetype]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.type1]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.type42]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.winfonts]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [-.sdf]
+ $(MMS)$(MMSQUALIFIERS)
+ set default [--]
# EOF
$ eod
@@ -348,11 +348,11 @@ OBJS64=ftsystem_64.obj
OBJSCXX=ftsystem_cxx.obj
all : $(OBJS)
- library/create [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library/create [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library/create [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library/create [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
ftsystem.obj : ftsystem.c ftconfig.h
@@ -411,11 +411,11 @@ OBJS64=autofit_64.obj
OBJSCXX=autofit_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -518,11 +518,11 @@ OBJSCXX=ftbase_cxx.obj,\
ftwinfnt_cxx.obj,ftpatent_cxx.obj,ftgxval_cxx.obj,ftotval_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
ftbase.obj : ftbase.c ftadvanc.c ftcalc.c ftcolor.c ftdbgmem.c fterrors.c\
@@ -585,11 +585,11 @@ OBJS64=bdf_64.obj
OBJSCXX=bdf_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -647,11 +647,11 @@ OBJS64=ftcache_64.obj
OBJSCXX=ftcache_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
ftcache.obj : ftcache.c ftcbasic.c ftccache.c ftccmap.c ftcglyph.c ftcimage.c \
@@ -712,11 +712,11 @@ OBJS64=cff_64.obj
OBJSCXX=cff_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -774,11 +774,11 @@ OBJS64=type1cid_64.obj
OBJSCXX=type1cid_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -836,11 +836,11 @@ OBJS64=gxvalid_64.obj
OBJSCXX=gxvalid_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -897,11 +897,11 @@ OBJS64=ftgzip_64.obj
OBJSCXX=ftgzip_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -960,11 +960,11 @@ OBJS64=ftbzip2_64.obj
OBJSCXX=ftbzip2_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1021,11 +1021,11 @@ OBJS64=ftlzw_64.obj
OBJSCXX=ftlzw_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1083,11 +1083,11 @@ OBJS64=otvalid_64.obj
OBJSCXX=otvalid_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1157,11 +1157,11 @@ OBJS64=pcf_64.obj
OBJSCXX=pcf_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1219,11 +1219,11 @@ OBJS64=pfr_64.obj
OBJSCXX=pfr_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1281,11 +1281,11 @@ OBJS64=psaux_64.obj
OBJSCXX=psaux_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1343,11 +1343,11 @@ OBJS64=pshinter_64.obj
OBJSCXX=pshinter_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1405,11 +1405,11 @@ OBJS64=psnames_64.obj
OBJSCXX=psnames_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1467,11 +1467,11 @@ OBJS64=raster_64.obj
OBJSCXX=raster_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1530,11 +1530,11 @@ OBJS64=sfnt_64.obj
OBJSCXX=sfnt_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1592,11 +1592,11 @@ OBJS64=smooth_64.obj
OBJSCXX=smooth_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1654,11 +1654,11 @@ OBJS64=svg_64.obj
OBJSCXX=svg_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1716,11 +1716,11 @@ OBJS64=truetype_64.obj
OBJSCXX=truetype_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1778,11 +1778,11 @@ OBJS64=type1_64.obj
OBJSCXX=type1_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
type1.obj : type1.c t1parse.c t1load.c t1objs.c t1driver.c t1gload.c t1afm.c
@@ -1842,11 +1842,11 @@ OBJS64=sdf_64.obj
OBJSCXX=sdf_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
sdf.obj : sdf.c ftbsdf.c ftsdf.c ftsdfcommon.c ftsdfrend.c
@@ -1906,11 +1906,11 @@ OBJS64=type42_64.obj
OBJSCXX=type42_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -1968,11 +1968,11 @@ OBJS64=winfnt_64.obj
OBJSCXX=winfnt_cxx.obj
all : $(OBJS)
- library [--.lib]freetype.olb $(OBJS)
- library [--.lib]freetype.olb $(OBJS64)
+ library [--.lib]freetype.olb $(OBJS)
+ library [--.lib]freetype.olb $(OBJS64)
.ifdef X86
- library [--.lib]freetype_cxx.olb $(OBJSCXX)
- library [--.lib]freetype_cxx.olb $(OBJS64)
+ library [--.lib]freetype_cxx.olb $(OBJSCXX)
+ library [--.lib]freetype_cxx.olb $(OBJS64)
.endif
# EOF
@@ -2015,7 +2015,7 @@ $ len = f$length(cparm) - start
$ cc_com = f$extract(start,len,cparm)
if (cc_com .nes. "DECC") .and. -
(cc_com .nes. "VAXC") .and. -
- (cc_com .nes. "GNUC")
+ (cc_com .nes. "GNUC")
$ then
$ write sys$output "Unsupported compiler choice ''cc_com' ignored"
$ write sys$output "Use DECC, VAXC, or GNUC instead"
From 26b545f36867508da2f2f318a93d78e673436598 Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Sun, 13 Oct 2024 11:09:40 +0900
Subject: [PATCH 35/94] apinames: Fix out-of-scope reference of a static array.
* apinames.c (names_dump): For WATCOM_LBC format, the
DLL name with no suffix is constructed on a static
array temp[], but the scope is closed before use it.
The declaration of temp[] is moved to the wider
scope for the dumping part to refer it.
---
src/tools/apinames.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tools/apinames.c b/src/tools/apinames.c
index 38407b2d7..343428bac 100644
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -181,6 +181,7 @@ names_dump( FILE* out,
case OUTPUT_WATCOM_LBC:
{
+ char temp[512];
const char* dot;
@@ -195,7 +196,6 @@ names_dump( FILE* out,
dot = strchr( dll_name, '.' );
if ( dot )
{
- char temp[512];
int len = dot - dll_name;
From 5f20c89215e13a6d2cfc2b5ddd2a15469f7c9621 Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Sun, 13 Oct 2024 10:20:42 +0900
Subject: [PATCH 36/94] apinames: Fix a buffer overrun for VMS platform.
Some output formats may rewrite symbol names during the output,
like the concatenation of "64__" suffix on VMS. To estimate
sufficient size to store symbol name, pass the output format
info to `names_add`. For VMS, `names_add` allocates longer
buffer to append "64__".
* apinames.c (SUFFIX_VMS_64ADDR): New macro of "64__".
(main): Pass the format info to `read_header_file`.
(read_header_file): Pass the format info to `names_add`.
(names_add): Receive the format info, and reserve the symbol
name buffer 4 byte longer in the case of VMS, to append the
suffix in `names_dump`.
---
src/tools/apinames.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/src/tools/apinames.c b/src/tools/apinames.c
index 343428bac..f64541ebb 100644
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -42,6 +42,7 @@ typedef enum OutputFormat_
} OutputFormat;
+#define SUFFIX_VMS_64ADDR "64__"
static void
panic( const char* fmt,
@@ -76,11 +77,12 @@ static int max_names;
static void
-names_add( const char* name,
- const char* end )
+names_add( const char* name,
+ const char* end,
+ OutputFormat format )
{
unsigned int h;
- int nn, len;
+ int nn, len, len_suffix;
Name nm;
@@ -116,8 +118,18 @@ names_add( const char* name,
}
nm = &the_names[num_names++];
+ switch ( format )
+ {
+ case OUTPUT_VMS_OPT:
+ /* VMS mode would join the symbol name with a suffix */
+ len_suffix = sizeof ( SUFFIX_VMS_64ADDR );
+ break;
+ default:
+ len_suffix = 0;
+ }
+
nm->hash = h;
- nm->name = (char*)malloc( len + 1 );
+ nm->name = (char*)malloc( len + len_suffix + 1 );
if ( !nm->name )
panic( "not enough memory" );
@@ -229,7 +241,7 @@ names_dump( FILE* out,
/* Also emit a 64-bit symbol, as created by the `vms_auto64` tool. */
/* It has the string '64__' appended to its name. */
- strcat( the_names[nn].name , "64__" );
+ strcat( the_names[nn].name , SUFFIX_VMS_64ADDR );
if ( vms_shorten_symbol( the_names[nn].name, short_symbol, 1 ) == -1 )
panic( "could not shorten name '%s'", the_names[nn].name );
fprintf( out, "symbol_vector = ( %s = PROCEDURE)\n", short_symbol );
@@ -277,8 +289,9 @@ typedef enum State_
static int
-read_header_file( FILE* file,
- int verbose )
+read_header_file( FILE* file,
+ int verbose,
+ OutputFormat format )
{
static char buff[LINEBUFF_SIZE + 1];
State state = STATE_START;
@@ -350,7 +363,7 @@ read_header_file( FILE* file,
if ( verbose )
fprintf( stderr, ">>> %.*s\n", (int)( p - name ), name );
- names_add( name, p );
+ names_add( name, p, format );
}
state = STATE_START;
@@ -519,7 +532,7 @@ main( int argc,
} /* end of while loop */
if ( from_stdin )
- read_header_file( stdin, verbose );
+ read_header_file( stdin, verbose, format );
else
{
for ( --argc, argv++; argc > 0; argc--, argv++ )
@@ -534,7 +547,7 @@ main( int argc,
if ( verbose )
fprintf( stderr, "opening '%s'\n", argv[0] );
- read_header_file( file, verbose );
+ read_header_file( file, verbose, format );
fclose( file );
}
}
From 089ccb1bfa95a0a0b854b372fe51baa8223d0367 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sun, 13 Oct 2024 12:14:43 -0400
Subject: [PATCH 37/94] * src/smooth/ftgrays.c (gray_convert_glyph): Clear
stack pointers.
Fixes a dangling pointer warning, see #1299.
---
src/smooth/ftgrays.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index b7c0632a6..24c119571 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1873,6 +1873,7 @@ typedef ptrdiff_t FT_PtrDist;
TCoord* band;
int continued = 0;
+ int error = Smooth_Err_Ok;
/* Initialize the null cell at the end of the poll. */
@@ -1907,7 +1908,6 @@ typedef ptrdiff_t FT_PtrDist;
do
{
TCoord i;
- int error;
ras.min_ex = band[1];
@@ -1936,7 +1936,7 @@ typedef ptrdiff_t FT_PtrDist;
continue;
}
else if ( error != Smooth_Err_Raster_Overflow )
- return error;
+ goto Exit;
/* render pool overflow; we will reduce the render band by half */
i = ( band[0] - band[1] ) >> 1;
@@ -1945,7 +1945,8 @@ typedef ptrdiff_t FT_PtrDist;
if ( i == 0 )
{
FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
- return FT_THROW( Raster_Overflow );
+ error = FT_THROW( Raster_Overflow );
+ goto Exit;
}
band++;
@@ -1954,7 +1955,11 @@ typedef ptrdiff_t FT_PtrDist;
} while ( band >= bands );
}
- return Smooth_Err_Ok;
+ Exit:
+ ras.cell = ras.cell_free = ras.cell_null = NULL;
+ ras.ycells = NULL;
+
+ return error;
}
From 5f2abe76fe7317ba3116505773d27a53141b0cca Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Sun, 13 Oct 2024 03:06:42 +0900
Subject: [PATCH 38/94] * autogen.sh: Fix for Solaris 10.
o Replace `test -e` by `test -d` (directory) and `-h`
(symlink), because pre-POSIX /bin/sh of Solaris 10
does not support `test -e`.
o Replace the combination of `head` and `sed ...` by
single sed command `sed -n 1...p`. GNU libtoolize
with Solaris 10 /bin/sh complains "Broken Pipe" for
the closure of stdout by `head`. Let `sed` receive
all stdout and discard.
---
autogen.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/autogen.sh b/autogen.sh
index 7285a0155..a9f9575ff 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -99,7 +99,7 @@ check_tool_version ()
if test "$field"x = x; then
field=3 # default to 3 for all GNU autotools, after filtering enclosed string
fi
- version=`$1 --version | head -1 | sed 's/([^)]*)/()/g' | cut -d ' ' -f $field`
+ version=`$1 --version | sed -n '1s/([^)]*)/()/gp' | cut -d ' ' -f $field`
version_check=`compare_to_minimum_version $version $4`
if test "$version_check"x = 0x; then
echo "ERROR: Your version of the \`$2' tool is too old."
@@ -182,7 +182,7 @@ copy_submodule_files ()
cp $DLG_SRC_DIR/* src/dlg
}
-if test -e ".git"; then
+if test -d ".git" -o -h ".git"; then
DLG_INC_DIR=subprojects/dlg/include/dlg
DLG_SRC_DIR=subprojects/dlg/src/dlg
From f02bffad0fd57f3acfa835c3f2899c5b71ff8be0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Mon, 14 Oct 2024 11:47:31 +0000
Subject: [PATCH 39/94] * src/truetype/ttgload.c (load_truetype_glyph):
Rearrange.
---
src/truetype/ttgload.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b656ccf04..732cedacd 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1566,13 +1566,14 @@
if ( header_only )
goto Exit;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ tt_get_metrics_incremental( loader, glyph_index );
+#endif
+ tt_loader_set_pp( loader );
+
+ /* shortcut for empty glyphs */
if ( loader->byte_len == 0 || loader->n_contours == 0 )
{
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
- tt_get_metrics_incremental( loader, glyph_index );
-#endif
- tt_loader_set_pp( loader );
-
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
@@ -1627,11 +1628,6 @@
goto Exit;
}
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
- tt_get_metrics_incremental( loader, glyph_index );
-#endif
- tt_loader_set_pp( loader );
-
/***********************************************************************/
/***********************************************************************/
From 139443663368617b30b70cf6912e9577ecbb845f Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod
Date: Tue, 15 Oct 2024 18:07:55 -0600
Subject: [PATCH 40/94] Move generic destroy to later in the face and size
destruction.
* src/base/ftobjs.c (destroy_size, destroy_face): This is such that the
generic destroy can be used to call `FT_Done_Library`. For that to work,
it needs to call it *after* having removed the face from the respective
module.
---
src/base/ftobjs.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 9b97820c3..720a3f4b6 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1253,14 +1253,14 @@
FT_Driver driver = (FT_Driver)driver_;
- /* finalize client-specific data */
- if ( size->generic.finalizer )
- size->generic.finalizer( size );
-
/* finalize format-specific stuff */
if ( driver->clazz->done_size )
driver->clazz->done_size( size );
+ /* finalize client-specific data */
+ if ( size->generic.finalizer )
+ size->generic.finalizer( size );
+
FT_FREE( size->internal );
FT_FREE( size );
}
@@ -1322,10 +1322,6 @@
driver );
face->size = NULL;
- /* now discard client data */
- if ( face->generic.finalizer )
- face->generic.finalizer( face );
-
/* discard charmaps */
destroy_charmaps( face, memory );
@@ -1340,6 +1336,10 @@
face->stream = NULL;
+ /* now discard client data */
+ if ( face->generic.finalizer )
+ face->generic.finalizer( face );
+
/* get rid of it */
if ( face->internal )
{
From 0ae7e607370cc66218ccfacf5de4db8a35424c2f Mon Sep 17 00:00:00 2001
From: suzuki toshiya
Date: Fri, 18 Oct 2024 14:02:22 +0900
Subject: [PATCH 41/94] Download the latest gnu-config files in `make dist`.
* builds/toplevel.mk: In `make dist`, checkout gnu-config
git repository at savannah, copy the latest versions of
`config.guess` and `config.sub` to builds/unix/. Also
the latest version of `gitlog-to-changelog` is used to
generate `ChangeLog`.
---
builds/toplevel.mk | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/builds/toplevel.mk b/builds/toplevel.mk
index 4b7b148c5..0beda9441 100644
--- a/builds/toplevel.mk
+++ b/builds/toplevel.mk
@@ -274,12 +274,16 @@ dist:
# GNU `config' git repository), relative to the `tmp' directory used during
# `make dist'.
#
-CONFIG_GUESS = ~/git/config/config.guess
-CONFIG_SUB = ~/git/config/config.sub
+# GNU_CONFIG_GIT_URL = git://git.savannah.gnu.org/config.git
+GNU_CONFIG_GIT_URL = https://git.savannah.gnu.org/git/config.git
+GNU_CONFIG_DESTDIR = $(TOP_DIR)/subprojects/gnu-config
+
+CONFIG_GUESS = $(GNU_CONFIG_DESTDIR)/config.guess
+CONFIG_SUB = $(GNU_CONFIG_DESTDIR)/config.sub
# We also use this repository to access the gnulib script that converts git
# commit messages to a ChangeLog file.
-CHANGELOG_SCRIPT = ~/git/config/gitlog-to-changelog
+CHANGELOG_SCRIPT = $(GNU_CONFIG_DESTDIR)/gitlog-to-changelog
# Don't say `make do-dist'. Always use `make dist' instead.
@@ -295,6 +299,8 @@ do-dist: distclean refdoc
sh autogen.sh
rm -rf $(TOP_DIR)/builds/unix/autom4te.cache
+ rm -rf $(GNU_CONFIG_DESTDIR)
+ git clone https://git.savannah.gnu.org/git/config.git $(GNU_CONFIG_DESTDIR)
cp $(CONFIG_GUESS) $(TOP_DIR)/builds/unix
cp $(CONFIG_SUB) $(TOP_DIR)/builds/unix
@@ -312,5 +318,6 @@ do-dist: distclean refdoc
@# Remove more stuff related to git.
rm -rf $(TOP_DIR)/subprojects/dlg
+ rm -rf $(TOP_DIR)/subprojects/gnu-config
# EOF
From 3f3e3de34ee3613d621b643c58a40b93148e0932 Mon Sep 17 00:00:00 2001
From: Honnesh Ramachandra
Date: Wed, 6 Nov 2024 06:28:41 +0100
Subject: [PATCH 42/94] * src/cff/cffobjs.c (cff_face_init): Better handling of
Type0 fonts.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This issue relates to the PDF specification and its usage of CFF-based
embedded Type0 fonts. For Type0 fonts containing CID-keyed descendant
CFF-based fonts, the glyph index is the CID present in the content stream.
As a result, there is no requirement for a 'cmap' table to be present in the
font since the glyph indices are derived directly from the CIDs. FreeType
throws an error when it doesn’t find a 'cmap' table for such an Open Type
font containing CFF outlines. This commit relaxes this requirement for a
'cmap' table for such fonts.
---
src/cff/cffobjs.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 7c6713739..dd4e82122 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -550,13 +550,13 @@
if ( error )
goto Exit;
}
- else
- {
- /* load the `cmap' table explicitly */
- error = sfnt->load_cmap( face, stream );
- if ( error )
- goto Exit;
- }
+
+ /* load the `cmap' table explicitly */
+ error = sfnt->load_cmap( face, stream );
+
+ /* this may fail because CID-keyed fonts don't have a cmap */
+ if ( FT_ERR_NEQ( error, Table_Missing ) && FT_ERR_NEQ( error, Ok ) )
+ goto Exit;
/* now load the CFF part of the file; */
/* give priority to CFF2 */
From 59320b2d3c2584ac01914ed0deff64bcc8fb23b2 Mon Sep 17 00:00:00 2001
From: Ben Wagner
Date: Wed, 4 Dec 2024 16:55:10 -0500
Subject: [PATCH 43/94] [cff] Fix leak of cmap data
When `sfnt->load_face` succeeds it has already loaded any (optional)
cmap data. As a result, a subsequent call to `sfnt->load_cmap` will
overwrite the cmap data pointer with a new copy of the data but not free
the old, leading to a leak.
This is a fix for "* src/cff/cffobjs.c (cff_face_init): Better handling
of Type0 fonts.". This still allows the cmap to be missing but avoids
the leak by only calling `sfnt->load_cmap` when there is no `head`
table (the font data is not being loaded as OpenType/CFF).
* src/cff/cffobjs.c (cff_face_init): Fix leak
Fixes: #1306
---
src/cff/cffobjs.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index dd4e82122..77dce2818 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -537,8 +537,8 @@
sfnt_format = 1;
- /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
- /* font; in the latter case it doesn't have a `head' table */
+ /* the font may be OpenType/CFF, SVG CEF, or sfnt/CFF; a `head' table */
+ /* implies OpenType/CFF, otherwise just look for an optional cmap */
error = face->goto_table( face, TTAG_head, stream, 0 );
if ( !error )
{
@@ -550,13 +550,15 @@
if ( error )
goto Exit;
}
+ else
+ {
+ /* load the `cmap' table explicitly */
+ error = sfnt->load_cmap( face, stream );
- /* load the `cmap' table explicitly */
- error = sfnt->load_cmap( face, stream );
-
- /* this may fail because CID-keyed fonts don't have a cmap */
- if ( FT_ERR_NEQ( error, Table_Missing ) && FT_ERR_NEQ( error, Ok ) )
- goto Exit;
+ /* this may fail because CID-keyed fonts don't have a cmap */
+ if ( FT_ERR_NEQ( error, Table_Missing ) && FT_ERR_NEQ( error, Ok ) )
+ goto Exit;
+ }
/* now load the CFF part of the file; */
/* give priority to CFF2 */
From 38272bf85341348eb0a5162ba4e1c95d370f9bce Mon Sep 17 00:00:00 2001
From: Ben Wagner
Date: Mon, 16 Dec 2024 14:29:36 -0500
Subject: [PATCH 44/94] [ftstroke] Fix invalid pointer assignement to `arc`
In `FT_Stroker_ConicTo` and `FT_Stroker_CubicTo` there is a `bez_stack`.
`arc` is initialized with `arc = bez_stack` and is never set to point
into any different object. The main loop looks like `while ( arc >=
bez_stack )` which is depending on a later `arc -= 2` (or `arc -= 3`) to
make `arc` point to before `bez_stack`. However, using pointer
subtraction to make `arc` point outside the array is undefined behavior,
and attempting to use the value in the loop predicate is "very"
undefined behavior. (C99 "Additive operators" 6.5.6.8.)
This particular undefined behavior was discovered as either hangs or
MemorySantizer issues after "[InstCombine] Infer nuw for gep inbounds
from base of object" [0]. With this change, clang can infer that `arc`
must always point into the `bez_stack` object and therefore cannot be at
a "negative index" so the predicate is always true.
[0] https://github.com/llvm/llvm-project/commit/e21ab4d16b555c28ded307571d138f594f33e325
* src/base/ftstroke.c (FT_Stroker_ConicTo, FT_Stroker_CubicTo): test
loop exit condition (there are no more arcs to process) before
decrementing `arc`
Fixes: #1307
---
src/base/ftstroke.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 64f46ce43..40d74d6e4 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -1371,7 +1371,7 @@
arc[1] = *control;
arc[2] = stroker->center;
- while ( arc >= bez_stack )
+ do
{
FT_Angle angle_in, angle_out;
@@ -1524,10 +1524,12 @@
}
}
- arc -= 2;
-
stroker->angle_in = angle_out;
- }
+
+ if ( arc == bez_stack )
+ break;
+ arc -= 2;
+ } while ( 1 );
stroker->center = *to;
stroker->line_length = 0;
@@ -1577,7 +1579,7 @@
arc[2] = *control1;
arc[3] = stroker->center;
- while ( arc >= bez_stack )
+ do
{
FT_Angle angle_in, angle_mid, angle_out;
@@ -1741,10 +1743,12 @@
}
}
- arc -= 3;
-
stroker->angle_in = angle_out;
- }
+
+ if ( arc == bez_stack )
+ break;
+ arc -= 3;
+ } while ( 1 );
stroker->center = *to;
stroker->line_length = 0;
From 4ef8eed11b719409d9fc284fb80d886e5bd0b28f Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 31 Dec 2024 16:25:50 -0500
Subject: [PATCH 45/94] [truetype] Ingnore FT_LOAD_NO_BITMAP in bitmap-only
fonts.
For consistency with other bitmap-only fonts, we should ignore this
flag of the font is not scalable.
* src/truetype/ttgload.c (TT_Load_Glyph): Check if face is scalable
when checking for FT_LOAD_NO_BITMAP.
* docs/CHANGES: Start new chapter wtith this change.
---
docs/CHANGES | 15 ++++++++++++++-
src/truetype/ttgload.c | 7 ++++---
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/docs/CHANGES b/docs/CHANGES
index bd7b12a8a..3b5d0d5ef 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,3 +1,16 @@
+CHANGES BETWEEN 2.13.3 and 2.13.4 (2025-Mmm-DD)
+
+ I. IMPORTANT CHANGES
+
+ - Bitmap-only TrueType fonts now ignore FT_LOAD_NO_BITMAP flag and
+ proceed loading bitmaps instead of giving an error. This behavior
+ is documented and implemented for other bitmap-only fonts. The
+ flag has always meant to suppress the bitmap strikes in favor of
+ outlines, not to ban them completely.
+
+
+======================================================================
+
CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Aug-11)
I. IMPORTANT CHANGES
@@ -579,7 +592,7 @@ CHANGES BETWEEN 2.9.1 and 2.10.0 (2019-Mar-15)
Set text foreground color for palette index 0xFFFF.
FT_Get_Color_Glyph_Layer
- Get color layers for a given glyph (using an interator
+ Get color layers for a given glyph (using an iterator
object).
FT_Bitmap_Blend
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 732cedacd..ea604adfe 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2427,9 +2427,10 @@
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* try to load embedded bitmap (if any) */
- if ( size->strike_index != 0xFFFFFFFFUL &&
- ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
- IS_DEFAULT_INSTANCE( glyph->face ) )
+ if ( size->strike_index != 0xFFFFFFFFUL &&
+ !( load_flags & FT_LOAD_NO_BITMAP &&
+ FT_IS_SCALABLE( glyph->face ) ) &&
+ IS_DEFAULT_INSTANCE( glyph->face ) )
{
FT_Fixed x_scale = size->root.metrics.x_scale;
FT_Fixed y_scale = size->root.metrics.y_scale;
From abed051e06a9f4bf906eaac182ccd96f9ebdb317 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 1 Jan 2025 14:40:58 -0500
Subject: [PATCH 46/94] [truetype] Consolidate bitmap strike handling.
* src/truetype/ttgload.c (TT_Load_Glyph): Relocate omitted whitespace
strike handling from here...
(load_sbit_image): ... to here.
---
src/truetype/ttgload.c | 127 ++++++++++++++++++-----------------------
1 file changed, 57 insertions(+), 70 deletions(-)
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index ea604adfe..926fd6155 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2149,6 +2149,53 @@
glyph->bitmap_top = sbit_metrics.horiBearingY;
}
}
+ /* a missing glyph in a bitmap-only font is assumed whitespace */
+ /* that needs to be constructed using metrics data from `hmtx' */
+ /* and, optionally, `vmtx' tables */
+ else if ( FT_ERR_EQ( error, Missing_Bitmap ) &&
+ !FT_IS_SCALABLE( glyph->face ) &&
+ face->horz_metrics_size )
+ {
+ FT_Fixed x_scale = size->root.metrics.x_scale;
+ FT_Fixed y_scale = size->root.metrics.y_scale;
+
+ FT_Short left_bearing = 0;
+ FT_Short top_bearing = 0;
+
+ FT_UShort advance_width = 0;
+ FT_UShort advance_height = 0;
+
+
+ TT_Get_HMetrics( face, glyph_index,
+ &left_bearing,
+ &advance_width );
+ TT_Get_VMetrics( face, glyph_index,
+ 0,
+ &top_bearing,
+ &advance_height );
+
+ glyph->outline.n_points = 0;
+ glyph->outline.n_contours = 0;
+
+ glyph->metrics.width = 0;
+ glyph->metrics.height = 0;
+
+ glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale );
+ glyph->metrics.horiBearingY = 0;
+ glyph->metrics.horiAdvance = FT_MulFix( advance_width, x_scale );
+
+ glyph->metrics.vertBearingX = 0;
+ glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale );
+ glyph->metrics.vertAdvance = FT_MulFix( advance_height, y_scale );
+
+ glyph->format = FT_GLYPH_FORMAT_BITMAP;
+ glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
+
+ glyph->bitmap_left = 0;
+ glyph->bitmap_top = 0;
+
+ error = FT_Err_Ok;
+ }
return error;
}
@@ -2432,75 +2479,16 @@
FT_IS_SCALABLE( glyph->face ) ) &&
IS_DEFAULT_INSTANCE( glyph->face ) )
{
- FT_Fixed x_scale = size->root.metrics.x_scale;
- FT_Fixed y_scale = size->root.metrics.y_scale;
-
-
error = load_sbit_image( size, glyph, glyph_index, load_flags );
- if ( FT_ERR_EQ( error, Missing_Bitmap ) )
- {
- /* the bitmap strike is incomplete and misses the requested glyph; */
- /* if we have a bitmap-only font, return an empty glyph */
- if ( !FT_IS_SCALABLE( glyph->face ) )
- {
- FT_Short left_bearing = 0;
- FT_Short top_bearing = 0;
-
- FT_UShort advance_width = 0;
- FT_UShort advance_height = 0;
-
-
- /* to return an empty glyph, however, we need metrics data */
- /* from the `hmtx' (or `vmtx') table; the assumption is that */
- /* empty glyphs are missing intentionally, representing */
- /* whitespace - not having at least horizontal metrics is */
- /* thus considered an error */
- if ( !face->horz_metrics_size )
- return error;
-
- /* we now construct an empty bitmap glyph */
- TT_Get_HMetrics( face, glyph_index,
- &left_bearing,
- &advance_width );
- TT_Get_VMetrics( face, glyph_index,
- 0,
- &top_bearing,
- &advance_height );
-
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
-
- glyph->metrics.width = 0;
- glyph->metrics.height = 0;
-
- glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale );
- glyph->metrics.horiBearingY = 0;
- glyph->metrics.horiAdvance = FT_MulFix( advance_width, x_scale );
-
- glyph->metrics.vertBearingX = 0;
- glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale );
- glyph->metrics.vertAdvance = FT_MulFix( advance_height, y_scale );
-
- glyph->format = FT_GLYPH_FORMAT_BITMAP;
- glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
-
- glyph->bitmap_left = 0;
- glyph->bitmap_top = 0;
-
- return FT_Err_Ok;
- }
- }
- else if ( error )
- {
- /* return error if font is not scalable */
- if ( !FT_IS_SCALABLE( glyph->face ) )
- return error;
- }
- else
+ if ( !error )
{
if ( FT_IS_SCALABLE( glyph->face ) ||
FT_HAS_SBIX( glyph->face ) )
{
+ FT_Fixed x_scale = size->root.metrics.x_scale;
+ FT_Fixed y_scale = size->root.metrics.y_scale;
+
+
/* for the bbox we need the header only */
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
@@ -2547,8 +2535,10 @@
y_scale );
}
- return FT_Err_Ok;
+ goto Exit;
}
+ else if ( !FT_IS_SCALABLE( glyph->face ) )
+ goto Exit;
}
if ( load_flags & FT_LOAD_SBITS_ONLY )
@@ -2724,11 +2714,8 @@
tt_loader_done( &loader );
Exit:
-#ifdef FT_DEBUG_LEVEL_TRACE
- if ( error )
- FT_TRACE1(( " failed (error code 0x%x)\n",
- error ));
-#endif
+ FT_TRACE1(( error ? " failed (error code 0x%x)\n" : "",
+ error ));
return error;
}
From 1beb83fd125d5565aedf85b6dc12d27e2423673e Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 1 Jan 2025 22:28:36 -0500
Subject: [PATCH 47/94] * src/sfnt/ttsbit.c (tt_face_load_sbix_image): Refactor
`flip`.
---
src/sfnt/ttsbit.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 0b7227607..cad24a5c8 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1519,15 +1519,14 @@
switch ( graphicType )
{
case FT_MAKE_TAG( 'f', 'l', 'i', 'p' ):
+ flipped = !flipped;
+ FALL_THROUGH;
+
case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
- if ( recurse_depth < 4 )
+ if ( recurse_depth++ < 4 )
{
glyph_index = FT_GET_USHORT();
FT_FRAME_EXIT();
- recurse_depth++;
-
- if ( graphicType == FT_MAKE_TAG( 'f', 'l', 'i', 'p' ) )
- flipped = !flipped;
goto retry;
}
From 10b3b14da2a60151dd9242364ad7a375d0d7590a Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 1 Jan 2025 23:04:14 -0500
Subject: [PATCH 48/94] * src/truetype/ttobjs.c: Abbreviate tracing.
---
src/truetype/ttobjs.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index d0ac31812..8033edb50 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -949,11 +949,8 @@
FT_TRACE4(( "Executing `fpgm' table.\n" ));
error = face->interpreter( exec );
-#ifdef FT_DEBUG_LEVEL_TRACE
- if ( error )
- FT_TRACE4(( " interpretation failed with error code 0x%x\n",
- error ));
-#endif
+ FT_TRACE4(( error ? " failed (error code 0x%x)\n" : "",
+ error ));
}
else
error = FT_Err_Ok;
@@ -1035,11 +1032,8 @@
FT_TRACE4(( "Executing `prep' table.\n" ));
error = face->interpreter( exec );
-#ifdef FT_DEBUG_LEVEL_TRACE
- if ( error )
- FT_TRACE4(( " interpretation failed with error code 0x%x\n",
- error ));
-#endif
+ FT_TRACE4(( error ? " failed (error code 0x%x)\n" : "",
+ error ));
}
else
error = FT_Err_Ok;
From 64f8b7fbd029a8715e01ba58de5119666be56811 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Thu, 2 Jan 2025 18:22:24 +0000
Subject: [PATCH 49/94] Remove superfluous outline zeroing.
This is already done by `ft_glyphslot_clear`.
* src/cff/cffgload.c (cff_slot_load): Do not zero outline fields.
* src/cid/cidgload.c (cid_slot_load_glyph: Ditto.
* src/pfr/pfrobjs.c (pfr_slot_load): Ditto.
* src/truetype/ttgload.c (load_sbit_image): Ditto.
* src/type1/t1gload.c (T1_Load_Glyph): Ditto.
---
src/cff/cffgload.c | 6 ------
src/cid/cidgload.c | 3 ---
src/pfr/pfrobjs.c | 2 --
src/truetype/ttgload.c | 6 ------
src/type1/t1gload.c | 3 ---
5 files changed, 20 deletions(-)
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index cbb071abd..e8be14945 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -284,9 +284,6 @@
FT_Short dummy;
- glyph->root.outline.n_points = 0;
- glyph->root.outline.n_contours = 0;
-
glyph->root.metrics.width = (FT_Pos)metrics.width * 64;
glyph->root.metrics.height = (FT_Pos)metrics.height * 64;
@@ -457,9 +454,6 @@
font_offset = cff->top_font.font_dict.font_offset;
}
- glyph->root.outline.n_points = 0;
- glyph->root.outline.n_contours = 0;
-
/* top-level code ensures that FT_LOAD_NO_HINTING is set */
/* if FT_LOAD_NO_SCALE is active */
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index 7b571322d..ab2f3f32e 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -452,9 +452,6 @@
glyph->x_scale = cidsize->metrics.x_scale;
glyph->y_scale = cidsize->metrics.y_scale;
- cidglyph->outline.n_points = 0;
- cidglyph->outline.n_contours = 0;
-
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
( load_flags & FT_LOAD_NO_HINTING ) == 0 );
scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index 084d2ef5a..39c7d2133 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -357,8 +357,6 @@
gchar = face->phy_font.chars + gindex;
pfrslot->format = FT_GLYPH_FORMAT_OUTLINE;
- outline->n_points = 0;
- outline->n_contours = 0;
gps_offset = face->header.gps_section_offset;
/* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 926fd6155..024d5c8ea 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2122,9 +2122,6 @@
&sbit_metrics );
if ( !error )
{
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
-
glyph->metrics.width = (FT_Pos)sbit_metrics.width * 64;
glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;
@@ -2174,9 +2171,6 @@
&top_bearing,
&advance_height );
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
-
glyph->metrics.width = 0;
glyph->metrics.height = 0;
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index c29e68251..cb668728b 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -398,9 +398,6 @@
glyph->y_scale = 0x10000L;
}
- t1glyph->outline.n_points = 0;
- t1glyph->outline.n_contours = 0;
-
hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) &&
!( load_flags & FT_LOAD_NO_HINTING ) );
scaled = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) );
From afc7000cacb8cc90ae61036858c5306defa1236a Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 3 Jan 2025 18:17:49 +0000
Subject: [PATCH 50/94] * builds/compiler/gcc-dev.mk: Silence some warnings.
---
builds/compiler/gcc-dev.mk | 1 +
1 file changed, 1 insertion(+)
diff --git a/builds/compiler/gcc-dev.mk b/builds/compiler/gcc-dev.mk
index e7121bec7..cdcd899f9 100644
--- a/builds/compiler/gcc-dev.mk
+++ b/builds/compiler/gcc-dev.mk
@@ -76,6 +76,7 @@ ifndef CFLAGS
-Wpointer-arith \
-Wwrite-strings \
-Wredundant-decls \
+ -Wno-format-extra-args \
-Wno-long-long \
$(nested_externs) \
$(strict_prototypes)
From 5245fd69fdc8e3a6db3d0ef12c2d7bd0f26c6251 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 3 Jan 2025 21:26:10 -0500
Subject: [PATCH 51/94] Delay FT_GLYPH_FORMAT_OUTLINE assignmets.
This assignmets used to be done prematurely before errors were checked
and outlines were actually loaded. Delaying the assignment provides
certain protection against careless usage of malformed input that
should now remain FT_GLYPH_FORMAT_NONE.
* src/cff/cffgload.c (cff_slot_load): Ditto.
* src/cid/cidgload.c (cid_slot_load_glyph): Ditto.
* src/pfr/pfrobjs.c (pfr_slot_load): Ditto.
* src/truetype/ttgload.c (TT_Load_Glyph): Ditto.
* src/type1/t1gload.c (T1_Load_Glyph): Ditto.
---
src/cff/cffgload.c | 21 ++++++++-------------
src/cid/cidgload.c | 21 +++++++++------------
src/pfr/pfrobjs.c | 10 ++++------
src/truetype/ttgload.c | 8 +++-----
src/type1/t1gload.c | 25 +++++++++++--------------
5 files changed, 35 insertions(+), 50 deletions(-)
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index e8be14945..727df9f8c 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -461,7 +461,6 @@
glyph->hint = hinting;
glyph->scaled = scaled;
- glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
{
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
@@ -596,10 +595,8 @@
{
/* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
- /* bearing the yMax. */
-
- /* For composite glyphs, return only left side bearing and */
- /* advance width. */
+ /* bearing the yMax. For composite glyphs, return only */
+ /* left side bearing and advance width. */
if ( load_flags & FT_LOAD_NO_RECURSE )
{
FT_Slot_Internal internal = glyph->root.internal;
@@ -618,6 +615,12 @@
FT_Bool has_vertical_info;
+ glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
+
+ glyph->root.outline.flags = FT_OUTLINE_REVERSE_FILL;
+ if ( size && size->root.metrics.y_ppem < 24 )
+ glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
+
if ( face->horizontal.number_Of_HMetrics )
{
FT_Short horiBearingX = 0;
@@ -671,14 +674,6 @@
glyph->root.linearVertAdvance = metrics->vertAdvance;
- glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
-
- glyph->root.outline.flags = 0;
- if ( size && size->root.metrics.y_ppem < 24 )
- glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
-
- glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
-
/* apply the font matrix, if any */
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
font_matrix.xy != 0 || font_matrix.yx != 0 )
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index ab2f3f32e..cb2861519 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -458,7 +458,6 @@
glyph->hint = hinting;
glyph->scaled = scaled;
- cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
error = psaux->t1_decoder_funcs->init( &decoder,
cidglyph->face,
@@ -498,12 +497,8 @@
/* now set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
- /* bearing the yMax */
- cidglyph->outline.flags &= FT_OUTLINE_OWNER;
- cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
-
- /* for composite glyphs, return only left side bearing and */
- /* advance width */
+ /* bearing the yMax; for composite glyphs, return only */
+ /* left side bearing and advance width */
if ( load_flags & FT_LOAD_NO_RECURSE )
{
FT_Slot_Internal internal = cidglyph->internal;
@@ -524,6 +519,13 @@
FT_Glyph_Metrics* metrics = &cidglyph->metrics;
+ cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
+
+ cidglyph->outline.flags &= FT_OUTLINE_OWNER;
+ cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
+ if ( cidsize->metrics.y_ppem < 24 )
+ cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
+
/* copy the _unscaled_ advance width */
metrics->horiAdvance =
FIXED_TO_INT( decoder.builder.advance.x );
@@ -536,11 +538,6 @@
face->cid.font_bbox.yMin ) >> 16;
cidglyph->linearVertAdvance = metrics->vertAdvance;
- cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
-
- if ( cidsize->metrics.y_ppem < 24 )
- cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
-
/* apply the font matrix, if any */
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
font_matrix.xy != 0 || font_matrix.yx != 0 )
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index 39c7d2133..79b8f629f 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -355,9 +355,8 @@
goto Exit;
}
- gchar = face->phy_font.chars + gindex;
- pfrslot->format = FT_GLYPH_FORMAT_OUTLINE;
- gps_offset = face->header.gps_section_offset;
+ gchar = face->phy_font.chars + gindex;
+ gps_offset = face->header.gps_section_offset;
/* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */
error = pfr_glyph_load( &slot->glyph, face->root.stream,
@@ -369,10 +368,9 @@
FT_Glyph_Metrics* metrics = &pfrslot->metrics;
FT_Pos advance;
FT_UInt em_metrics, em_outline;
- FT_Bool scaling;
- scaling = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) );
+ pfrslot->format = FT_GLYPH_FORMAT_OUTLINE;
/* copy outline data */
*outline = slot->glyph.loader->base.outline;
@@ -427,7 +425,7 @@
#endif
/* scale when needed */
- if ( scaling )
+ if ( !( load_flags & FT_LOAD_NO_SCALE ) )
{
FT_Int n;
FT_Fixed x_scale = pfrsize->metrics.x_scale;
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 024d5c8ea..0e2762400 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2595,7 +2595,7 @@
glyph->metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
glyph->metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
- return error;
+ goto Exit;
}
FT_TRACE3(( "Failed to load SVG glyph\n" ));
@@ -2623,10 +2623,6 @@
goto Done;
}
- glyph->format = FT_GLYPH_FORMAT_OUTLINE;
- glyph->num_subglyphs = 0;
- glyph->outline.flags = 0;
-
/* main loading loop */
error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
if ( !error )
@@ -2638,6 +2634,8 @@
}
else
{
+ glyph->format = FT_GLYPH_FORMAT_OUTLINE;
+
glyph->outline = loader.gloader->base.outline;
glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index cb668728b..b28976259 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -404,7 +404,6 @@
glyph->hint = hinting;
glyph->scaled = scaled;
- t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
error = decoder_funcs->init( &decoder,
t1glyph->face,
@@ -449,16 +448,12 @@
must_finish_decoder = FALSE;
- /* now, set the metrics -- this is rather simple, as */
- /* the left side bearing is the xMin, and the top side */
- /* bearing the yMax */
if ( !error )
{
- t1glyph->outline.flags &= FT_OUTLINE_OWNER;
- t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
-
- /* for composite glyphs, return only left side bearing and */
- /* advance width */
+ /* now, set the metrics -- this is rather simple, as */
+ /* the left side bearing is the xMin, and the top side */
+ /* bearing the yMax; for composite glyphs, return only */
+ /* left side bearing and advance width */
if ( load_flags & FT_LOAD_NO_RECURSE )
{
FT_Slot_Internal internal = t1glyph->internal;
@@ -479,6 +474,13 @@
FT_Glyph_Metrics* metrics = &t1glyph->metrics;
+ t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
+
+ t1glyph->outline.flags &= FT_OUTLINE_OWNER;
+ t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
+ if ( t1size && t1size->metrics.y_ppem < 24 )
+ t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
+
/* copy the _unscaled_ advance width */
metrics->horiAdvance =
FIXED_TO_INT( decoder.builder.advance.x );
@@ -501,11 +503,6 @@
FIXED_TO_INT( decoder.builder.advance.y );
}
- t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
-
- if ( t1size && t1size->metrics.y_ppem < 24 )
- t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
-
#if 1
/* apply the font matrix, if any */
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
From 81330e1f8aec49b4ad05c20f4f03497c473e10d0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 3 Jan 2025 22:54:20 -0500
Subject: [PATCH 52/94] * src/truetype/ttgload.c (TT_Load_Glyph): Consolidate
flag setting.
---
src/truetype/ttgload.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 0e2762400..e93f6a5c0 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2639,6 +2639,13 @@
glyph->outline = loader.gloader->base.outline;
glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
+ /* Set the `high precision' bit flag. This is _critical_ to */
+ /* get correct output for monochrome TrueType glyphs at all */
+ /* sizes using the bytecode interpreter. */
+ if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
+ size->metrics->y_ppem < 24 )
+ glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
+
/* Translate array so that (0,0) is the glyph's origin. Note */
/* that this behaviour is independent on the value of bit 1 of */
/* the `flags' field in the `head' table -- at least major */
@@ -2687,14 +2694,6 @@
error = compute_glyph_metrics( &loader, glyph_index );
}
- /* Set the `high precision' bit flag. */
- /* This is _critical_ to get correct output for monochrome */
- /* TrueType glyphs at all sizes using the bytecode interpreter. */
- /* */
- if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
- size->metrics->y_ppem < 24 )
- glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
-
FT_TRACE1(( " subglyphs = %u, contours = %hu, points = %hu,"
" flags = 0x%.3x\n",
loader.gloader->base.num_subglyphs,
From c7a255b46202a22ca4ab53e6a7983740e9979c6e Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 7 Jan 2025 19:52:29 -0500
Subject: [PATCH 53/94] * src/cff/cffdrivr.c (cff_get_advances): Do only fast
advances.
Otherwise, let TT_Get_Advances fall back on cff_load_glyph to do
slow advances. This avoids unchecked access to cff_load_glyph and
this is how tt_get_advances is implemented.
---
src/cff/cffdrivr.c | 125 ++++++++++++++++-----------------------------
1 file changed, 45 insertions(+), 80 deletions(-)
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index f6ebdb381..8a41371c9 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -205,105 +205,70 @@
FT_Int32 flags,
FT_Fixed* advances )
{
- FT_UInt nn;
- FT_Error error = FT_Err_Ok;
- FT_GlyphSlot slot = face->glyph;
+ CFF_Face cffface = (CFF_Face)face;
+ FT_Bool horz;
+ FT_UInt nn;
- if ( FT_IS_SFNT( face ) )
+ if ( !FT_IS_SFNT( face ) )
+ return FT_THROW( Unimplemented_Feature );
+
+ horz = !( flags & FT_LOAD_VERTICAL_LAYOUT );
+
+ if ( horz )
{
/* OpenType 1.7 mandates that the data from `hmtx' table be used; */
/* it is no longer necessary that those values are identical to */
/* the values in the `CFF' table */
+ if ( !cffface->horizontal.number_Of_HMetrics )
+ return FT_THROW( Unimplemented_Feature );
- CFF_Face cffface = (CFF_Face)face;
- FT_Short dummy;
-
-
- if ( flags & FT_LOAD_VERTICAL_LAYOUT )
- {
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- /* no fast retrieval for blended MM fonts without VVAR table */
- if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
- !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
- return FT_THROW( Unimplemented_Feature );
+ /* no fast retrieval for blended MM fonts without HVAR table */
+ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+ !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
#endif
+ }
+ else /* vertical */
+ {
+ /* check whether we have data from the `vmtx' table at all; */
+ /* otherwise we extract the info from the CFF glyphstrings */
+ /* (instead of synthesizing a global value using the `OS/2' */
+ /* table) */
+ if ( !cffface->vertical_info )
+ return FT_THROW( Unimplemented_Feature );
- /* check whether we have data from the `vmtx' table at all; */
- /* otherwise we extract the info from the CFF glyphstrings */
- /* (instead of synthesizing a global value using the `OS/2' */
- /* table) */
- if ( !cffface->vertical_info )
- goto Missing_Table;
-
- for ( nn = 0; nn < count; nn++ )
- {
- FT_UShort ah;
-
-
- ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
- 1,
- start + nn,
- &dummy,
- &ah );
-
- FT_TRACE5(( " idx %d: advance height %d font unit%s\n",
- start + nn,
- ah,
- ah == 1 ? "" : "s" ));
- advances[nn] = ah;
- }
- }
- else
- {
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- /* no fast retrieval for blended MM fonts without HVAR table */
- if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
- !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
- return FT_THROW( Unimplemented_Feature );
+ /* no fast retrieval for blended MM fonts without VVAR table */
+ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+ !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
#endif
-
- /* check whether we have data from the `hmtx' table at all */
- if ( !cffface->horizontal.number_Of_HMetrics )
- goto Missing_Table;
-
- for ( nn = 0; nn < count; nn++ )
- {
- FT_UShort aw;
-
-
- ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
- 0,
- start + nn,
- &dummy,
- &aw );
-
- FT_TRACE5(( " idx %d: advance width %d font unit%s\n",
- start + nn,
- aw,
- aw == 1 ? "" : "s" ));
- advances[nn] = aw;
- }
- }
-
- return error;
}
- Missing_Table:
- flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
-
+ /* proceed to fast advances */
for ( nn = 0; nn < count; nn++ )
{
- error = cff_glyph_load( slot, face->size, start + nn, flags );
- if ( error )
- break;
+ FT_UShort aw;
+ FT_Short dummy;
- advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
- ? slot->linearVertAdvance
- : slot->linearHoriAdvance;
+
+ ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
+ !horz,
+ start + nn,
+ &dummy,
+ &aw );
+
+ FT_TRACE5(( " idx %d: advance %s %d font unit%s\n",
+ start + nn,
+ horz ? "width" : "height",
+ aw,
+ aw == 1 ? "" : "s" ));
+ advances[nn] = aw;
}
- return error;
+ return FT_Err_Ok;
}
From 73318c864a1bd0b1f5c4638bbdc87b81176b844f Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 8 Jan 2025 15:45:32 -0500
Subject: [PATCH 54/94] [cff] Remove size/slot checks.
After the previous commit, cff_glyph_load is no longer called
without first checking for valid size and glyph objects in
FT_Glyph_Load and these checks can be removed downstream.
* src/cff/cffdrivr.c (cff_glyph_load): Remove `size` and `glyph` checks.
* src/cff/cffgload.c (cff_slot_load): Ditto.
---
src/cff/cffdrivr.c | 18 ------------------
src/cff/cffgload.c | 15 +++------------
2 files changed, 3 insertions(+), 30 deletions(-)
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 8a41371c9..bab7d349a 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -168,26 +168,8 @@
CFF_Size cffsize = (CFF_Size)size;
- if ( !cffslot )
- return FT_THROW( Invalid_Slot_Handle );
-
FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));
- /* check whether we want a scaled outline or bitmap */
- if ( !cffsize )
- load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
-
- /* reset the size object if necessary */
- if ( load_flags & FT_LOAD_NO_SCALE )
- size = NULL;
-
- if ( size )
- {
- /* these two objects must have the same parent */
- if ( size->face != slot->face )
- return FT_THROW( Invalid_Face_Handle );
- }
-
/* now load the glyph outline if necessary */
error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags );
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 727df9f8c..1abee3aec 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -238,24 +238,12 @@
else if ( glyph_index >= cff->num_glyphs )
return FT_THROW( Invalid_Argument );
- if ( load_flags & FT_LOAD_NO_RECURSE )
- load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
-
- glyph->x_scale = 0x10000L;
- glyph->y_scale = 0x10000L;
- if ( size )
- {
- glyph->x_scale = size->root.metrics.x_scale;
- glyph->y_scale = size->root.metrics.y_scale;
- }
-
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* try to load embedded bitmap if any */
/* */
/* XXX: The convention should be emphasized in */
/* the documents because it can be confusing. */
- if ( size )
{
CFF_Face cff_face = (CFF_Face)size->root.face;
SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
@@ -423,6 +411,9 @@
/* if we have a CID subfont, use its matrix (which has already */
/* been multiplied with the root matrix) */
+ glyph->x_scale = size->root.metrics.x_scale;
+ glyph->y_scale = size->root.metrics.y_scale;
+
/* this scaling is only relevant if the PS hinter isn't active */
if ( cff->num_subfonts )
{
From 1400b20ae8683315f53f00b6c3707fc64faeaa7b Mon Sep 17 00:00:00 2001
From: Heiko Lewin
Date: Thu, 9 Jan 2025 13:21:50 +0000
Subject: [PATCH 55/94] * CMakeLists.txt: Use modern IMPORTED targets.
This resolves build problems with newer libPNG versions by switching
to using IMPORTED CMake targets for common libraries where provided.
To do this the required CMake version is raised to version 3.12.
Doing this seems justified as using IMPORTED targets is a cleaner
and more powerful solution that can leverage advanced and CMake-specific
features that may be utilized by the referred dependencies' CMake modules.
Resolves #1311.
---
CMakeLists.txt | 27 ++++++---------------------
1 file changed, 6 insertions(+), 21 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36516e4ab..fa46044ce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -108,18 +108,8 @@
# (this is compatible with the same CMake variables in zlib's CMake
# support).
-# To minimize the number of cmake_policy() workarounds,
-# CMake >= 3 is requested.
-cmake_minimum_required(VERSION 3.0...3.5)
-
-if (NOT CMAKE_VERSION VERSION_LESS 3.3)
- # Allow symbol visibility settings also on static libraries. CMake < 3.3
- # only sets the property on a shared library build.
- cmake_policy(SET CMP0063 NEW)
-
- # Support new IN_LIST if() operator.
- cmake_policy(SET CMP0057 NEW)
-endif ()
+# CMake 3.12 provides for IMPORTED targets for common libraries like zlib, libpng and bzip2
+cmake_minimum_required(VERSION 3.12)
include(CheckIncludeFile)
include(CMakeDependentOption)
@@ -524,13 +514,11 @@ set(PKGCONFIG_LIBS "-L\${libdir} -lfreetype")
set(PKGCONFIG_LIBS_PRIVATE "")
if (ZLIB_FOUND)
- target_link_libraries(freetype PRIVATE ${ZLIB_LIBRARIES})
- target_include_directories(freetype PRIVATE ${ZLIB_INCLUDE_DIRS})
+ target_link_libraries(freetype PRIVATE ZLIB::ZLIB)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "zlib")
endif ()
if (BZIP2_FOUND)
- target_link_libraries(freetype PRIVATE ${BZIP2_LIBRARIES})
- target_include_directories(freetype PRIVATE ${BZIP2_INCLUDE_DIR}) # not BZIP2_INCLUDE_DIRS
+ target_link_libraries(freetype PRIVATE BZip2::BZip2)
if (PC_BZIP2_FOUND)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "bzip2")
else ()
@@ -538,14 +526,11 @@ if (BZIP2_FOUND)
endif ()
endif ()
if (PNG_FOUND)
- target_link_libraries(freetype PRIVATE ${PNG_LIBRARIES})
- target_compile_definitions(freetype PRIVATE ${PNG_DEFINITIONS})
- target_include_directories(freetype PRIVATE ${PNG_INCLUDE_DIRS})
+ target_link_libraries(freetype PRIVATE PNG::PNG)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "libpng")
endif ()
if (HarfBuzz_FOUND)
- target_link_libraries(freetype PRIVATE ${HarfBuzz_LIBRARY})
- target_include_directories(freetype PRIVATE ${HarfBuzz_INCLUDE_DIRS})
+ target_link_libraries(freetype PRIVATE HarfBuzz::HarfBuzz)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "harfbuzz >= ${HARFBUZZ_MIN_VERSION}")
endif ()
if (BROTLIDEC_FOUND)
From 704d540527ea04faa15ee23bf8fdfbfb9340ab35 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Thu, 9 Jan 2025 15:18:55 +0000
Subject: [PATCH 56/94] * MSBuild.rsp: Force console color for mintty.
---
MSBuild.rsp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/MSBuild.rsp b/MSBuild.rsp
index 3eba50762..8401e6030 100644
--- a/MSBuild.rsp
+++ b/MSBuild.rsp
@@ -1,2 +1,4 @@
+# MSBuild.rsp with default command-line switches
+/clp:ForceConsoleColor
+/p:Configuration=Release
#/p:WindowsTargetPlatformVersion=10.0.16299.0
-/p:Configuration="Release"
From 1f57020ff37a6c3ae43fc3fbe0fb547057877e2d Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 10 Jan 2025 03:23:41 +0000
Subject: [PATCH 57/94] * src/bdf/bdflib.c (bdf_parse_start_): Fix tracing
labels.
---
src/bdf/bdflib.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 813a4d839..d5f0710c4 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1975,7 +1975,7 @@
{
p->font->props_size = 0;
- FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG5, lineno, "STARTPROPERTIES" ));
+ FT_ERROR(( "bdf_parse_start_: " ERRMSG5, lineno, "STARTPROPERTIES" ));
error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -2127,7 +2127,7 @@
nbuf, lineno );
if ( error )
goto Exit;
- FT_TRACE2(( "bdf_parse_properties_: " ACMSG1, p->font->bbx.ascent ));
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG1, p->font->bbx.ascent ));
p->font->font_descent = p->font->bbx.descent;
ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent );
@@ -2135,7 +2135,7 @@
nbuf, lineno );
if ( error )
goto Exit;
- FT_TRACE2(( "bdf_parse_properties_: " ACMSG2, p->font->bbx.descent ));
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG2, p->font->bbx.descent ));
*next = bdf_parse_glyphs_;
From 8d536080eccb1355dcb567e10e6406f2040aaae7 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 10 Jan 2025 22:44:40 +0000
Subject: [PATCH 58/94] * builds/windows/ftsystem.c: Fix ancient condition.
---
builds/windows/ftsystem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/builds/windows/ftsystem.c b/builds/windows/ftsystem.c
index 477cad71f..36a2975f1 100644
--- a/builds/windows/ftsystem.c
+++ b/builds/windows/ftsystem.c
@@ -296,7 +296,7 @@
/* support for really old Windows */
#if defined( _WIN32_WCE ) || defined ( _WIN32_WINDOWS ) || \
- !defined( _WIN32_WINNT ) || _WIN32_WINNT <= 0x0400
+ ( defined( _WIN32_WINNT ) && _WIN32_WINNT <= 0x0400 )
FT_LOCAL_DEF( BOOL )
GetFileSizeEx( HANDLE hFile,
From cf451e5ff3d95fb34f3ffac7493506dd6e6f6d5b Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 10 Jan 2025 22:31:07 -0500
Subject: [PATCH 59/94] * src/bdf/bdf.h (bdf_font_t): Correct `internal` type.
* src/bdf/bdflib.c (*): Update users.
---
src/bdf/bdf.h | 2 +-
src/bdf/bdflib.c | 13 ++++++-------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index e2cb52c10..72a9853db 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -190,7 +190,7 @@ FT_BEGIN_HEADER
char* comments; /* Font comments. */
unsigned long comments_len; /* Length of comment string. */
- void* internal; /* Internal data for the font. */
+ FT_Hash internal; /* Internal data for the font. */
unsigned short bpp; /* Bits per pixel. */
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index d5f0710c4..60da71a0a 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1115,8 +1115,7 @@
/* First, check whether the property already exists in the font. */
- if ( ( propid = ft_hash_str_lookup( name,
- (FT_Hash)font->internal ) ) != NULL )
+ if ( ( propid = ft_hash_str_lookup( name, font->internal ) ) != NULL )
{
/* The property already exists in the font, so simply replace */
/* the value of the property with the current value. */
@@ -1210,7 +1209,7 @@
/* Add the property to the font property table. */
error = ft_hash_str_insert( fp->name,
font->props_used,
- (FT_Hash)font->internal,
+ font->internal,
memory );
if ( error )
goto Exit;
@@ -1942,9 +1941,9 @@
}
}
- if ( FT_QALLOC( p->font->internal, sizeof ( FT_HashRec ) ) )
+ if ( FT_QNEW( p->font->internal ) )
goto Exit;
- error = ft_hash_str_init( (FT_Hash)p->font->internal, memory );
+ error = ft_hash_str_init( p->font->internal, memory );
if ( error )
goto Exit;
p->font->spacing = p->opts->font_spacing;
@@ -2311,7 +2310,7 @@
/* Free up the internal hash table of property names. */
if ( font->internal )
{
- ft_hash_str_free( (FT_Hash)font->internal, memory );
+ ft_hash_str_free( font->internal, memory );
FT_FREE( font->internal );
}
@@ -2369,7 +2368,7 @@
if ( font == NULL || font->props_size == 0 || name == NULL || *name == 0 )
return 0;
- propid = ft_hash_str_lookup( name, (FT_Hash)font->internal );
+ propid = ft_hash_str_lookup( name, font->internal );
return propid ? ( font->props + *propid ) : 0;
}
From ff5872b4dae0437de07fcc4b0954def0479f31ac Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 10 Jan 2025 22:55:13 -0500
Subject: [PATCH 60/94] * src/bdf/bdflib.c (bdf_parse_*_): Minor improvements.
---
src/bdf/bdflib.c | 70 ++++++++++++++++++------------------------------
1 file changed, 26 insertions(+), 44 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 60da71a0a..b0acedd30 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1283,28 +1283,22 @@
void* call_data,
void* client_data )
{
+ bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
+ bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
+ bdf_font_t* font = p->font;
+ bdf_glyph_t* glyph;
+
+ FT_Memory memory = font->memory;
+ FT_Error error = FT_Err_Ok;
+
int c, mask_index;
char* s;
unsigned char* bp;
unsigned long i, slen, nibbles;
- bdf_line_func_t_* next;
- bdf_parse_t_* p;
- bdf_glyph_t* glyph;
- bdf_font_t* font;
-
- FT_Memory memory;
- FT_Error error = FT_Err_Ok;
-
FT_UNUSED( lineno ); /* only used in debug mode */
- next = (bdf_line_func_t_ *)call_data;
- p = (bdf_parse_t_ *) client_data;
-
- font = p->font;
- memory = font->memory;
-
/* Check for a comment. */
if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
@@ -1762,20 +1756,19 @@
void* call_data,
void* client_data )
{
+ bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
+ bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
+
+ FT_Error error = FT_Err_Ok;
+
unsigned long vlen;
- bdf_line_func_t_* next;
- bdf_parse_t_* p;
char* name;
char* value;
char nbuf[BUFSIZE];
- FT_Error error = FT_Err_Ok;
FT_UNUSED( lineno );
- next = (bdf_line_func_t_ *)call_data;
- p = (bdf_parse_t_ *) client_data;
-
/* Check for the end of the properties. */
if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
{
@@ -1865,24 +1858,18 @@
void* call_data,
void* client_data )
{
- unsigned long slen;
- bdf_line_func_t_* next;
- bdf_parse_t_* p;
- bdf_font_t* font;
- char *s;
+ bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
+ bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
- FT_Memory memory = NULL;
+ FT_Memory memory = p->memory;
FT_Error error = FT_Err_Ok;
+ unsigned long slen;
+ char *s;
+
FT_UNUSED( lineno ); /* only used in debug mode */
- next = (bdf_line_func_t_ *)call_data;
- p = (bdf_parse_t_ *) client_data;
-
- if ( p->font )
- memory = p->font->memory;
-
/* Check for a comment. This is done to handle those fonts that have */
/* comments before the STARTFONT line for some reason. */
if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
@@ -1904,8 +1891,6 @@
if ( !( p->flags & BDF_START_ ) )
{
- memory = p->memory;
-
if ( _bdf_strncmp( line, "STARTFONT", 9 ) != 0 )
{
/* we don't emit an error message since this code gets */
@@ -1915,27 +1900,24 @@
}
p->flags = BDF_START_;
- font = p->font = NULL;
- if ( FT_NEW( font ) )
+ if ( FT_NEW( p->font ) )
goto Exit;
- p->font = font;
- font->memory = p->memory;
+ p->font->memory = memory;
{ /* setup */
+ bdf_property_t* prop = (bdf_property_t*)bdf_properties_;
+ FT_Hash proptbl = &p->font->proptbl;
size_t i;
- bdf_property_t* prop;
- error = ft_hash_str_init( &(font->proptbl), memory );
+ error = ft_hash_str_init( proptbl, memory );
if ( error )
goto Exit;
- for ( i = 0, prop = (bdf_property_t*)bdf_properties_;
- i < num_bdf_properties_; i++, prop++ )
+ for ( i = 0; i < num_bdf_properties_; i++, prop++ )
{
- error = ft_hash_str_insert( prop->name, i,
- &(font->proptbl), memory );
+ error = ft_hash_str_insert( prop->name, i, proptbl, memory );
if ( error )
goto Exit;
}
From 4433c7b7bac3f50bbe5ce3062edec9a8a9fbaa28 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sat, 11 Jan 2025 18:54:04 -0500
Subject: [PATCH 61/94] * src/bdf/bdflib.c (a2i): Formatting.
---
src/bdf/bdflib.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index b0acedd30..6f5509823 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -673,17 +673,22 @@
static const unsigned char a2i[128] =
{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char ddigits[32] =
From bbc445e165c4bfa7571523cfbe8f164aaf02ea57 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sat, 11 Jan 2025 23:11:07 -0500
Subject: [PATCH 62/94] [bdf] Speed up bitmap parsing.
A dedicated parser of bitmap data with minimal error checking and
no string comparisons helps to improve performance.
* src/bdf/bdflib.c (bdf_parse_bitmap_): New dedicated bitmap parser.
(bdf_parse_glyphs_): Pass to `bdf_parse_bitmap_` on BITMAP.
---
docs/CHANGES | 7 ++-
src/bdf/bdflib.c | 136 +++++++++++++++++++++++------------------------
2 files changed, 72 insertions(+), 71 deletions(-)
diff --git a/docs/CHANGES b/docs/CHANGES
index 3b5d0d5ef..bf454f46e 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -5,10 +5,15 @@ CHANGES BETWEEN 2.13.3 and 2.13.4 (2025-Mmm-DD)
- Bitmap-only TrueType fonts now ignore FT_LOAD_NO_BITMAP flag and
proceed loading bitmaps instead of giving an error. This behavior
is documented and implemented for other bitmap-only fonts. The
- flag has always meant to suppress the bitmap strikes in favor of
+ flag was always meant to suppress the bitmap strikes in favor of
outlines, not to ban them completely.
+ III. MISCELLANEOUS
+
+ - The BDF driver now loads fonts noticeably faster.
+
+
======================================================================
CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Aug-11)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 6f5509823..d145080c1 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -268,6 +268,7 @@
char* glyph_name;
long glyph_enc;
+ bdf_glyph_t* glyph;
bdf_font_t* font;
bdf_options_t* opts;
@@ -940,9 +941,6 @@
BDF_BBX_ | \
BDF_BITMAP_ )
-#define BDF_GLYPH_WIDTH_CHECK_ 0x40000000UL
-#define BDF_GLYPH_HEIGHT_CHECK_ 0x80000000UL
-
static FT_Error
bdf_add_comment_( bdf_font_t* font,
@@ -1280,7 +1278,67 @@
}
- /* Actually parse the glyph info and bitmaps. */
+ /* Line function prototype. */
+ static FT_Error
+ bdf_parse_glyphs_( char* line,
+ unsigned long linelen,
+ unsigned long lineno,
+ void* call_data,
+ void* client_data );
+
+
+ /* Aggressively parse the glyph bitmaps. */
+ static FT_Error
+ bdf_parse_bitmap_( char* line,
+ unsigned long linelen,
+ unsigned long lineno,
+ void* call_data,
+ void* client_data )
+ {
+ bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
+ bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
+ bdf_glyph_t* glyph = p->glyph;
+
+ unsigned char* bp;
+ unsigned long i, nibbles;
+ int x;
+
+ FT_UNUSED( lineno ); /* only used in debug mode */
+
+
+ nibbles = glyph->bpr << 1;
+ bp = glyph->bitmap + p->row * glyph->bpr;
+
+ if ( nibbles > linelen )
+ {
+ FT_TRACE2(( "bdf_parse_bitmap_: " ACMSG16, glyph->encoding ));
+ nibbles = linelen;
+ }
+
+ for ( i = 0; i < nibbles; i++ )
+ {
+ /* char to hex without checks */
+ x = line[i];
+ x += ( x & 0x40 ) * 9 >> 6; /* for [A-Fa-f] */
+ x &= 0x0F;
+
+ if ( i & 1 )
+ *bp++ |= x;
+ else
+ *bp = x << 4;
+ }
+
+ p->row++;
+
+ /* When done, go back to parsing glyphs */
+ if ( p->row >= (unsigned long)glyph->bbx.height )
+ *next = bdf_parse_glyphs_;
+
+ return FT_Err_Ok;
+ }
+
+
+ /* Actually parse the glyph info. */
static FT_Error
bdf_parse_glyphs_( char* line,
unsigned long linelen,
@@ -1296,10 +1354,8 @@
FT_Memory memory = font->memory;
FT_Error error = FT_Err_Ok;
- int c, mask_index;
char* s;
- unsigned char* bp;
- unsigned long i, slen, nibbles;
+ unsigned long slen;
FT_UNUSED( lineno ); /* only used in debug mode */
@@ -1528,10 +1584,6 @@
}
}
- /* Clear the flags that might be added when width and height are */
- /* checked for consistency. */
- p->flags &= ~( BDF_GLYPH_WIDTH_CHECK_ | BDF_GLYPH_HEIGHT_CHECK_ );
-
p->flags |= BDF_ENCODING_;
goto Exit;
@@ -1546,64 +1598,6 @@
else
glyph = font->glyphs + ( font->glyphs_used - 1 );
- /* Check whether a bitmap is being constructed. */
- if ( p->flags & BDF_BITMAP_ )
- {
- /* If there are more rows than are specified in the glyph metrics, */
- /* ignore the remaining lines. */
- if ( p->row >= (unsigned long)glyph->bbx.height )
- {
- if ( !( p->flags & BDF_GLYPH_HEIGHT_CHECK_ ) )
- {
- FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG13, glyph->encoding ));
- p->flags |= BDF_GLYPH_HEIGHT_CHECK_;
- }
-
- goto Exit;
- }
-
- /* Only collect the number of nibbles indicated by the glyph */
- /* metrics. If there are more columns, they are simply ignored. */
- nibbles = glyph->bpr << 1;
- bp = glyph->bitmap + p->row * glyph->bpr;
-
- for ( i = 0; i < nibbles; i++ )
- {
- c = line[i];
- if ( !sbitset( hdigits, c ) )
- break;
- *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] );
- if ( i + 1 < nibbles && ( i & 1 ) )
- *++bp = 0;
- }
-
- /* If any line has not enough columns, */
- /* indicate they have been padded with zero bits. */
- if ( i < nibbles &&
- !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) )
- {
- FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG16, glyph->encoding ));
- p->flags |= BDF_GLYPH_WIDTH_CHECK_;
- }
-
- /* Remove possible garbage at the right. */
- mask_index = ( glyph->bbx.width * p->font->bpp ) & 7;
- if ( glyph->bbx.width )
- *bp &= nibble_mask[mask_index];
-
- /* If any line has extra columns, indicate they have been removed. */
- if ( i == nibbles &&
- sbitset( hdigits, line[nibbles] ) &&
- !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) )
- {
- FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG14, glyph->encoding ));
- p->flags |= BDF_GLYPH_WIDTH_CHECK_;
- }
-
- p->row++;
- goto Exit;
- }
-
/* Expect the SWIDTH (scalable width) field next. */
if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
{
@@ -1727,11 +1721,13 @@
else
glyph->bytes = (unsigned short)bitmap_size;
- if ( FT_ALLOC( glyph->bitmap, glyph->bytes ) )
+ if ( !bitmap_size || FT_ALLOC( glyph->bitmap, glyph->bytes ) )
goto Exit;
+ p->glyph = glyph;
p->row = 0;
p->flags |= BDF_BITMAP_;
+ *next = bdf_parse_bitmap_;
goto Exit;
}
From aab40d5cc4876d4004170d46e2718f9cd81b78dd Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sun, 12 Jan 2025 00:24:42 -0500
Subject: [PATCH 63/94] * src/bdf/bdflib.c (bdf_parse_glyphs_): Avoid possible
leak.
---
src/bdf/bdflib.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index d145080c1..00de85473 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1636,6 +1636,10 @@
goto Exit;
}
+ /* Do not leak the bitmap or reset its size */
+ if ( p->flags & BDF_BITMAP_ )
+ goto Exit;
+
/* Expect the BBX field next. */
if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
{
From f219996754c4df75b758983e18cabb401e5b93a1 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Mon, 13 Jan 2025 03:48:28 +0000
Subject: [PATCH 64/94] * src/bdf/bdflib.c (bdf_parse_glyphs_): Store glyph as
soon as possible.
---
src/bdf/bdflib.c | 62 +++++++++++++++++++-----------------------------
1 file changed, 24 insertions(+), 38 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 00de85473..0d7a27773 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1473,8 +1473,6 @@
/* Set the character name in the parse info first until the */
/* encoding can be checked for an unencoded character. */
- FT_FREE( p->glyph_name );
-
error = bdf_list_split_( &p->list, " +", line, linelen );
if ( error )
goto Exit;
@@ -1548,43 +1546,35 @@
glyph = font->glyphs + font->glyphs_used++;
glyph->name = p->glyph_name;
glyph->encoding = (unsigned long)p->glyph_enc;
+ }
+ else if ( p->opts->keep_unencoded )
+ {
+ /* Allocate the next unencoded glyph. */
+ if ( font->unencoded_used == font->unencoded_size )
+ {
+ if ( FT_RENEW_ARRAY( font->unencoded ,
+ font->unencoded_size,
+ font->unencoded_size + 4 ) )
+ goto Exit;
- /* Reset the initial glyph info. */
- p->glyph_name = NULL;
+ font->unencoded_size += 4;
+ }
+
+ glyph = font->unencoded + font->unencoded_used;
+ glyph->name = p->glyph_name;
+ glyph->encoding = font->unencoded_used++;
}
else
{
- /* Unencoded glyph. Check whether it should */
- /* be added or not. */
- if ( p->opts->keep_unencoded )
- {
- /* Allocate the next unencoded glyph. */
- if ( font->unencoded_used == font->unencoded_size )
- {
- if ( FT_RENEW_ARRAY( font->unencoded ,
- font->unencoded_size,
- font->unencoded_size + 4 ) )
- goto Exit;
-
- font->unencoded_size += 4;
- }
-
- glyph = font->unencoded + font->unencoded_used;
- glyph->name = p->glyph_name;
- glyph->encoding = font->unencoded_used++;
-
- /* Reset the initial glyph info. */
- p->glyph_name = NULL;
- }
- else
- {
- /* Free up the glyph name if the unencoded shouldn't be */
- /* kept. */
- FT_FREE( p->glyph_name );
- }
+ /* Free up the glyph name if the unencoded shouldn't be */
+ /* kept. */
+ FT_FREE( p->glyph_name );
+ glyph = NULL;
}
- p->flags |= BDF_ENCODING_;
+ p->glyph_name = NULL;
+ p->glyph = glyph;
+ p->flags |= BDF_ENCODING_;
goto Exit;
}
@@ -1593,10 +1583,7 @@
goto Missing_Encoding;
/* Point at the glyph being constructed. */
- if ( p->glyph_enc == -1 )
- glyph = font->unencoded + ( font->unencoded_used - 1 );
- else
- glyph = font->glyphs + ( font->glyphs_used - 1 );
+ glyph = p->glyph;
/* Expect the SWIDTH (scalable width) field next. */
if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
@@ -1728,7 +1715,6 @@
if ( !bitmap_size || FT_ALLOC( glyph->bitmap, glyph->bytes ) )
goto Exit;
- p->glyph = glyph;
p->row = 0;
p->flags |= BDF_BITMAP_;
*next = bdf_parse_bitmap_;
From ee1310ab5ca2897b760258b94f3d9230335cc2c0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Mon, 13 Jan 2025 17:19:31 +0000
Subject: [PATCH 65/94] * src/bdf/bdflib.c (bdf_parse_glyphs_): Free unused
glyph_name.
See https://issues.oss-fuzz.com/issues/389330334.
---
src/bdf/bdflib.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 0d7a27773..5e312bbaf 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1447,6 +1447,9 @@
/* Check for the ENDCHAR field. */
if ( _bdf_strncmp( line, "ENDCHAR", 7 ) == 0 )
{
+ /* Free unused glyph_name */
+ FT_FREE( p->glyph_name );
+
p->glyph_enc = 0;
p->flags &= ~BDF_GLYPH_BITS_;
From 0864367adabbd3dca964c2232b9b9e58ad940091 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 14 Jan 2025 18:39:50 -0500
Subject: [PATCH 66/94] * src/bdf/bdflib.c (bdf_readstream_): Tweak variables
and loop design.
---
src/bdf/bdflib.c | 37 +++++++++++++------------------------
1 file changed, 13 insertions(+), 24 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 5e312bbaf..438017a8b 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -526,8 +526,8 @@
{
bdf_line_func_t_ cb;
unsigned long lineno, buf_size;
- int refill, hold, to_skip;
- ptrdiff_t bytes, start, end, cursor, avail;
+ int hold, to_skip;
+ unsigned long bytes, start, end, cursor, avail;
char* buf = NULL;
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
@@ -549,26 +549,16 @@
lineno = 1;
buf[0] = 0;
start = 0;
- avail = 0;
cursor = 0;
- refill = 1;
to_skip = NO_SKIP;
- bytes = 0; /* make compiler happy */
+
+ Refill:
+ bytes = FT_Stream_TryRead( stream,
+ (FT_Byte*)buf + cursor, buf_size - cursor );
+ avail = cursor + bytes;
for (;;)
{
- if ( refill )
- {
- bytes = (ptrdiff_t)FT_Stream_TryRead(
- stream, (FT_Byte*)buf + cursor,
- buf_size - (unsigned long)cursor );
- avail = cursor + bytes;
- cursor = 0;
- refill = 0;
- }
-
- end = start;
-
/* should we skip an optional character like \n or \r? */
if ( start < avail && buf[start] == to_skip )
{
@@ -578,6 +568,7 @@
}
/* try to find the end of the line */
+ end = start;
while ( end < avail && buf[end] != '\n' && buf[end] != '\r' )
end++;
@@ -622,15 +613,13 @@
}
else
{
- bytes = avail - start;
+ cursor = avail - start;
- FT_MEM_MOVE( buf, buf + start, bytes );
+ FT_MEM_MOVE( buf, buf + start, cursor );
- cursor = bytes;
start = 0;
}
- refill = 1;
- continue;
+ goto Refill;
}
/* Temporarily NUL-terminate the line. */
@@ -640,11 +629,11 @@
/* XXX: Use encoding independent value for 0x1A */
if ( buf[start] != '#' && buf[start] != 0x1A && end > start )
{
- error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
+ error = (*cb)( buf + start, end - start, lineno,
(void*)&cb, client_data );
/* Redo if we have encountered CHARS without properties. */
if ( error == -1 )
- error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
+ error = (*cb)( buf + start, end - start, lineno,
(void*)&cb, client_data );
if ( error )
break;
From a05c22103defb49f8752147e20012aa33cd9b919 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 14 Jan 2025 21:11:33 -0500
Subject: [PATCH 67/94] [bdf] Adjust parsing flow and CHARS handling.
* src/bdf/bdflib.c (bdf_readstream_): Remove CHARS exception.
(bdf_parse_glyphs_): Move glyphs allocation...
(bdf_parse_properties_): and missing ascent and descent handling...
(bdf_parse_start_): ...to here under CHARS.
---
src/bdf/bdflib.c | 214 ++++++++++++++++++++---------------------------
1 file changed, 92 insertions(+), 122 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 438017a8b..081713979 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -631,10 +631,6 @@
{
error = (*cb)( buf + start, end - start, lineno,
(void*)&cb, client_data );
- /* Redo if we have encountered CHARS without properties. */
- if ( error == -1 )
- error = (*cb)( buf + start, end - start, lineno,
- (void*)&cb, client_data );
if ( error )
break;
}
@@ -1267,7 +1263,15 @@
}
- /* Line function prototype. */
+ /* Line function prototypes. */
+ static FT_Error
+ bdf_parse_start_( char* line,
+ unsigned long linelen,
+ unsigned long lineno,
+ void* call_data,
+ void* client_data );
+
+
static FT_Error
bdf_parse_glyphs_( char* line,
unsigned long linelen,
@@ -1367,49 +1371,6 @@
goto Exit;
}
- /* The very first thing expected is the number of glyphs. */
- if ( !( p->flags & BDF_GLYPHS_ ) )
- {
- if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 )
- {
- FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "CHARS" ));
- error = FT_THROW( Missing_Chars_Field );
- goto Exit;
- }
-
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
- p->cnt = font->glyphs_size = bdf_atoul_( p->list.field[1] );
-
- /* We need at least 20 bytes per glyph. */
- if ( p->cnt > p->size / 20 )
- {
- p->cnt = font->glyphs_size = p->size / 20;
- FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG17, p->cnt ));
- }
-
- /* Make sure the number of glyphs is non-zero. */
- if ( p->cnt == 0 )
- font->glyphs_size = 64;
-
- /* Limit ourselves to 1,114,112 glyphs in the font (this is the */
- /* number of code points available in Unicode). */
- if ( p->cnt >= 0x110000UL )
- {
- FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG5, lineno, "CHARS" ));
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
-
- if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) )
- goto Exit;
-
- p->flags |= BDF_GLYPHS_;
-
- goto Exit;
- }
-
/* Check for the ENDFONT field. */
if ( _bdf_strncmp( line, "ENDFONT", 7 ) == 0 )
{
@@ -1747,7 +1708,6 @@
unsigned long vlen;
char* name;
char* value;
- char nbuf[BUFSIZE];
FT_UNUSED( lineno );
@@ -1755,38 +1715,8 @@
/* Check for the end of the properties. */
if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
{
- /* If the FONT_ASCENT or FONT_DESCENT properties have not been */
- /* encountered yet, then make sure they are added as properties and */
- /* make sure they are set from the font bounding box info. */
- /* */
- /* This is *always* done regardless of the options, because X11 */
- /* requires these two fields to compile fonts. */
- if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 )
- {
- p->font->font_ascent = p->font->bbx.ascent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent );
- error = bdf_add_property_( p->font, "FONT_ASCENT",
- nbuf, lineno );
- if ( error )
- goto Exit;
-
- FT_TRACE2(( "bdf_parse_properties_: " ACMSG1, p->font->bbx.ascent ));
- }
-
- if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 )
- {
- p->font->font_descent = p->font->bbx.descent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent );
- error = bdf_add_property_( p->font, "FONT_DESCENT",
- nbuf, lineno );
- if ( error )
- goto Exit;
-
- FT_TRACE2(( "bdf_parse_properties_: " ACMSG2, p->font->bbx.descent ));
- }
-
p->flags &= ~BDF_PROPS_;
- *next = bdf_parse_glyphs_;
+ *next = bdf_parse_start_;
goto Exit;
}
@@ -1843,6 +1773,7 @@
{
bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
+ bdf_font_t* font;
FT_Memory memory = p->memory;
FT_Error error = FT_Err_Ok;
@@ -1917,6 +1848,9 @@
goto Exit;
}
+ /* Point at the font being constructed. */
+ font = p->font;
+
/* Check for the start of the properties. */
if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
{
@@ -1932,21 +1866,20 @@
if ( error )
goto Exit;
- /* at this point, `p->font' can't be NULL */
- p->cnt = p->font->props_size = bdf_atoul_( p->list.field[1] );
+ p->cnt = font->props_size = bdf_atoul_( p->list.field[1] );
/* We need at least 4 bytes per property. */
if ( p->cnt > p->size / 4 )
{
- p->font->props_size = 0;
+ font->props_size = 0;
FT_ERROR(( "bdf_parse_start_: " ERRMSG5, lineno, "STARTPROPERTIES" ));
error = FT_THROW( Invalid_Argument );
goto Exit;
}
- if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
+ if ( FT_NEW_ARRAY( font->props, p->cnt ) )
{
- p->font->props_size = 0;
+ font->props_size = 0;
goto Exit;
}
@@ -1971,16 +1904,16 @@
if ( error )
goto Exit;
- p->font->bbx.width = bdf_atous_( p->list.field[1] );
- p->font->bbx.height = bdf_atous_( p->list.field[2] );
+ font->bbx.width = bdf_atous_( p->list.field[1] );
+ font->bbx.height = bdf_atous_( p->list.field[2] );
- p->font->bbx.x_offset = bdf_atos_( p->list.field[3] );
- p->font->bbx.y_offset = bdf_atos_( p->list.field[4] );
+ font->bbx.x_offset = bdf_atos_( p->list.field[3] );
+ font->bbx.y_offset = bdf_atos_( p->list.field[4] );
- p->font->bbx.ascent = (short)( p->font->bbx.height +
- p->font->bbx.y_offset );
+ font->bbx.ascent = (short)( font->bbx.height +
+ font->bbx.y_offset );
- p->font->bbx.descent = (short)( -p->font->bbx.y_offset );
+ font->bbx.descent = (short)( -font->bbx.y_offset );
p->flags |= BDF_FONT_BBX_;
@@ -2005,14 +1938,14 @@
}
/* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */
- FT_FREE( p->font->name );
+ FT_FREE( font->name );
- if ( FT_DUP( p->font->name, s, slen + 1 ) )
+ if ( FT_DUP( font->name, s, slen + 1 ) )
goto Exit;
/* If the font name is an XLFD name, set the spacing to the one in */
/* the font name. If there is no spacing fall back on the default. */
- error = bdf_set_default_spacing_( p->font, p->opts, lineno );
+ error = bdf_set_default_spacing_( font, p->opts, lineno );
if ( error )
goto Exit;
@@ -2036,9 +1969,9 @@
if ( error )
goto Exit;
- p->font->point_size = bdf_atoul_( p->list.field[1] );
- p->font->resolution_x = bdf_atoul_( p->list.field[2] );
- p->font->resolution_y = bdf_atoul_( p->list.field[3] );
+ font->point_size = bdf_atoul_( p->list.field[1] );
+ font->resolution_x = bdf_atoul_( p->list.field[2] );
+ font->resolution_y = bdf_atoul_( p->list.field[3] );
/* Check for the bits per pixel field. */
if ( p->list.used == 5 )
@@ -2050,26 +1983,26 @@
/* Only values 1, 2, 4, 8 are allowed for greymap fonts. */
if ( bpp > 4 )
- p->font->bpp = 8;
+ font->bpp = 8;
else if ( bpp > 2 )
- p->font->bpp = 4;
+ font->bpp = 4;
else if ( bpp > 1 )
- p->font->bpp = 2;
+ font->bpp = 2;
else
- p->font->bpp = 1;
+ font->bpp = 1;
- if ( p->font->bpp != bpp )
- FT_TRACE2(( "bdf_parse_start_: " ACMSG11, p->font->bpp ));
+ if ( font->bpp != bpp )
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG11, font->bpp ));
}
else
- p->font->bpp = 1;
+ font->bpp = 1;
p->flags |= BDF_SIZE_;
goto Exit;
}
- /* Check for the CHARS field -- font properties are optional */
+ /* Check for the CHARS field */
if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 )
{
char nbuf[BUFSIZE];
@@ -2083,28 +2016,65 @@
goto Exit;
}
- /* Add the two standard X11 properties which are required */
- /* for compiling fonts. */
- p->font->font_ascent = p->font->bbx.ascent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent );
- error = bdf_add_property_( p->font, "FONT_ASCENT",
- nbuf, lineno );
+ /* If the FONT_ASCENT or FONT_DESCENT properties have not been */
+ /* encountered yet, then make sure they are added as properties and */
+ /* make sure they are set from the font bounding box info. */
+ /* */
+ /* This is *always* done regardless of the options, because X11 */
+ /* requires these two fields to compile fonts. */
+ if ( bdf_get_font_property( font, "FONT_ASCENT" ) == 0 )
+ {
+ font->font_ascent = font->bbx.ascent;
+ ft_snprintf( nbuf, BUFSIZE, "%hd", font->bbx.ascent );
+ error = bdf_add_property_( font, "FONT_ASCENT", nbuf, lineno );
+ if ( error )
+ goto Exit;
+
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG1, font->bbx.ascent ));
+ }
+
+ if ( bdf_get_font_property( font, "FONT_DESCENT" ) == 0 )
+ {
+ font->font_descent = font->bbx.descent;
+ ft_snprintf( nbuf, BUFSIZE, "%hd", font->bbx.descent );
+ error = bdf_add_property_( font, "FONT_DESCENT", nbuf, lineno );
+ if ( error )
+ goto Exit;
+
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG2, font->bbx.descent ));
+ }
+
+ error = bdf_list_split_( &p->list, " +", line, linelen );
if ( error )
goto Exit;
- FT_TRACE2(( "bdf_parse_start_: " ACMSG1, p->font->bbx.ascent ));
+ p->cnt = font->glyphs_size = bdf_atoul_( p->list.field[1] );
- p->font->font_descent = p->font->bbx.descent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent );
- error = bdf_add_property_( p->font, "FONT_DESCENT",
- nbuf, lineno );
- if ( error )
+ /* We need at least 20 bytes per glyph. */
+ if ( p->cnt > p->size / 20 )
+ {
+ p->cnt = font->glyphs_size = p->size / 20;
+ FT_TRACE2(( "bdf_parse_start_: " ACMSG17, p->cnt ));
+ }
+
+ /* Make sure the number of glyphs is non-zero. */
+ if ( p->cnt == 0 )
+ font->glyphs_size = 64;
+
+ /* Limit ourselves to 1,114,112 glyphs in the font (this is the */
+ /* number of code points available in Unicode). */
+ if ( p->cnt >= 0x110000UL )
+ {
+ FT_ERROR(( "bdf_parse_start_: " ERRMSG5, lineno, "CHARS" ));
+ error = FT_THROW( Invalid_Argument );
goto Exit;
- FT_TRACE2(( "bdf_parse_start_: " ACMSG2, p->font->bbx.descent ));
+ }
- *next = bdf_parse_glyphs_;
+ if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) )
+ goto Exit;
+
+ p->flags |= BDF_GLYPHS_;
+ *next = bdf_parse_glyphs_;
- /* A special return value. */
- error = -1;
goto Exit;
}
From a3c68e3b48b927a6c13b8a653ff3683e959ead98 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 14 Jan 2025 22:32:46 -0500
Subject: [PATCH 68/94] [bdf] Use flags instead of options.
* src/bdf/bdf.h (bdf_options_t): Removed.
(BDF_KEEP_COMMENTS, BDF_KEEP_UNENCODED, BDF_CORRECT_METRICS): Updated
to avoid collisions with the other parsing flags.
* src/bdf/bdfdrivr.c (BDF_Face_Init): Use default flags explicitly.
* src/bdf/bdflib.c (bdf_load_font): Use flags as an argument to
initialize the parser.
(bdf_set_fedault_spacing_): Default to BDF_PROPORTIONAL explicitly.
(bdf_parse_*_): Updated.
---
src/bdf/bdf.h | 40 +++++++-------------------------------
src/bdf/bdfdrivr.c | 9 ++-------
src/bdf/bdflib.c | 48 +++++++++++++++-------------------------------
3 files changed, 24 insertions(+), 73 deletions(-)
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index 72a9853db..2f866e874 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -57,39 +57,13 @@ FT_BEGIN_HEADER
*/
-#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */
-#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */
-#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */
-#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */
-#define BDF_MONOWIDTH 0x10 /* Font has mono width. */
-#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */
+#define BDF_CORRECT_METRICS 0x1000 /* Correct metrics when loading. */
+#define BDF_KEEP_COMMENTS 0x2000 /* Preserve the font comments. */
+#define BDF_KEEP_UNENCODED 0x4000 /* Keep the unencoded glyphs. */
-#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \
- BDF_MONOWIDTH | \
- BDF_CHARCELL )
-
-#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \
- BDF_KEEP_COMMENTS | \
- BDF_KEEP_UNENCODED | \
- BDF_PROPORTIONAL )
-
-
- typedef struct bdf_options_t_
- {
- int correct_metrics;
- int keep_unencoded;
- int keep_comments;
- int font_spacing;
-
- } bdf_options_t;
-
-
- /* Callback function type for unknown configuration options. */
- typedef int
- (*bdf_options_callback_t)( bdf_options_t* opts,
- char** params,
- unsigned long nparams,
- void* client_data );
+#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */
+#define BDF_MONOWIDTH 0x10 /* Font has mono width. */
+#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */
/**************************************************************************
@@ -233,7 +207,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
bdf_load_font( FT_Stream stream,
FT_Memory memory,
- bdf_options_t* opts,
+ unsigned long flags,
bdf_font_t* *font );
FT_LOCAL( void )
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 4b9d6347f..85a03152d 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -349,7 +349,6 @@ THE SOFTWARE.
FT_Memory memory = FT_FACE_MEMORY( face );
bdf_font_t* font = NULL;
- bdf_options_t options;
FT_UNUSED( num_params );
FT_UNUSED( params );
@@ -360,12 +359,8 @@ THE SOFTWARE.
if ( FT_STREAM_SEEK( 0 ) )
goto Exit;
- options.correct_metrics = 1; /* FZ XXX: options semantics */
- options.keep_unencoded = 1;
- options.keep_comments = 0;
- options.font_spacing = BDF_PROPORTIONAL;
-
- error = bdf_load_font( stream, memory, &options, &font );
+ error = bdf_load_font( stream, memory,
+ BDF_CORRECT_METRICS | BDF_KEEP_UNENCODED, &font );
if ( FT_ERR_EQ( error, Missing_Startfont_Field ) )
{
FT_TRACE2(( " not a BDF file\n" ));
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 081713979..18d41adb8 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -54,22 +54,6 @@
#define BUFSIZE 128
- /**************************************************************************
- *
- * Default BDF font options.
- *
- */
-
-
- static const bdf_options_t bdf_opts_ =
- {
- 1, /* Correct metrics. */
- 1, /* Preserve unencoded glyphs. */
- 0, /* Preserve comments. */
- BDF_PROPORTIONAL /* Default spacing. */
- };
-
-
/**************************************************************************
*
* Builtin BDF font properties.
@@ -270,7 +254,6 @@
bdf_glyph_t* glyph;
bdf_font_t* font;
- bdf_options_t* opts;
bdf_list_t_ list;
@@ -954,11 +937,10 @@
}
- /* Set the spacing from the font name if it exists, or set it to the */
- /* default specified in the options. */
+ /* Set the spacing from the font name if it exists, */
+ /* or use default */
static FT_Error
bdf_set_default_spacing_( bdf_font_t* font,
- bdf_options_t* opts,
unsigned long lineno )
{
size_t len;
@@ -980,7 +962,7 @@
bdf_list_init_( &list, memory );
- font->spacing = opts->font_spacing;
+ font->spacing = BDF_PROPORTIONAL; /* default */
len = ft_strlen( font->name ) + 1;
/* Limit ourselves to 256 characters in the font name. */
@@ -1356,7 +1338,7 @@
/* Check for a comment. */
if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
- if ( p->opts->keep_comments )
+ if ( p->flags & BDF_KEEP_COMMENTS )
{
linelen -= 7;
@@ -1408,9 +1390,9 @@
/* Check whether a glyph is being scanned but should be */
/* ignored because it is an unencoded glyph. */
- if ( ( p->flags & BDF_GLYPH_ ) &&
- p->glyph_enc == -1 &&
- p->opts->keep_unencoded == 0 )
+ if ( p->flags & BDF_GLYPH_ &&
+ p->glyph_enc == -1 &&
+ !( p->flags & BDF_KEEP_UNENCODED ) )
goto Exit;
/* Check for the STARTCHAR field. */
@@ -1500,7 +1482,7 @@
glyph->name = p->glyph_name;
glyph->encoding = (unsigned long)p->glyph_enc;
}
- else if ( p->opts->keep_unencoded )
+ else if ( p->flags & BDF_KEEP_UNENCODED )
{
/* Allocate the next unencoded glyph. */
if ( font->unencoded_used == font->unencoded_size )
@@ -1617,7 +1599,7 @@
/* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */
/* value if necessary. */
- if ( p->opts->correct_metrics )
+ if ( p->flags & BDF_CORRECT_METRICS )
{
/* Determine the point size of the glyph. */
unsigned short sw = (unsigned short)FT_MulDiv(
@@ -1788,7 +1770,7 @@
/* comments before the STARTFONT line for some reason. */
if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
- if ( p->opts->keep_comments && p->font )
+ if ( p->flags & BDF_KEEP_COMMENTS && p->font )
{
linelen -= 7;
@@ -1842,7 +1824,7 @@
error = ft_hash_str_init( p->font->internal, memory );
if ( error )
goto Exit;
- p->font->spacing = p->opts->font_spacing;
+ p->font->spacing = BDF_PROPORTIONAL;
p->font->default_char = ~0UL;
goto Exit;
@@ -1945,7 +1927,7 @@
/* If the font name is an XLFD name, set the spacing to the one in */
/* the font name. If there is no spacing fall back on the default. */
- error = bdf_set_default_spacing_( font, p->opts, lineno );
+ error = bdf_set_default_spacing_( font, lineno );
if ( error )
goto Exit;
@@ -2096,7 +2078,7 @@
FT_LOCAL_DEF( FT_Error )
bdf_load_font( FT_Stream stream,
FT_Memory memory,
- bdf_options_t* opts,
+ unsigned long flags,
bdf_font_t* *font )
{
unsigned long lineno = 0; /* make compiler happy */
@@ -2108,7 +2090,7 @@
if ( FT_NEW( p ) )
goto Exit;
- p->opts = (bdf_options_t*)( opts ? opts : &bdf_opts_ );
+ p->flags = flags; /* comments, metrics, unencoded */
p->minlb = 32767;
p->size = stream->size;
p->memory = memory; /* only during font creation */
@@ -2138,7 +2120,7 @@
/* Once the font has been loaded, adjust the overall font metrics if */
/* necessary. */
- if ( p->opts->correct_metrics != 0 &&
+ if ( p->flags & BDF_CORRECT_METRICS &&
( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) )
{
if ( p->maxrb - p->minlb != p->font->bbx.width )
From a0d86e5650a44bf58a9410964469d612ff3e5300 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Tue, 14 Jan 2025 22:58:04 -0500
Subject: [PATCH 69/94] * src/bdf/bdflib.c: Clean up.
---
src/bdf/bdflib.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 18d41adb8..e072ca432 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1220,12 +1220,6 @@
}
- static const unsigned char nibble_mask[8] =
- {
- 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
- };
-
-
static FT_Error
bdf_parse_end_( char* line,
unsigned long linelen,
@@ -1294,7 +1288,7 @@
{
/* char to hex without checks */
x = line[i];
- x += ( x & 0x40 ) * 9 >> 6; /* for [A-Fa-f] */
+ x += 9 * ( x & 0x40 ) >> 6; /* for [A-Fa-f] */
x &= 0x0F;
if ( i & 1 )
From ae11e18cbd274a7f20d977aa38de6534c32b60a0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 15 Jan 2025 15:50:12 +0000
Subject: [PATCH 70/94] * src/bdf/bdflib.c (bdf_add_property_): Add extra
protection.
See https://issues.oss-fuzz.com/issues/389972472
https://issues.oss-fuzz.com/issues/389968131
---
src/bdf/bdflib.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index e072ca432..a449b88d2 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1085,7 +1085,8 @@
/* First, check whether the property already exists in the font. */
- if ( ( propid = ft_hash_str_lookup( name, font->internal ) ) != NULL )
+ if ( font->props_used &&
+ ( propid = ft_hash_str_lookup( name, font->internal ) ) != NULL )
{
/* The property already exists in the font, so simply replace */
/* the value of the property with the current value. */
From 02953326d4bd164da638cc62c74eefb9c1a1a938 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Thu, 16 Jan 2025 03:47:14 +0000
Subject: [PATCH 71/94] * src/bdf/bdflib.c (bdf_parse_start_): Reserve space
for artificial properties.
---
src/bdf/bdflib.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index a449b88d2..66b97d3e3 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1085,8 +1085,7 @@
/* First, check whether the property already exists in the font. */
- if ( font->props_used &&
- ( propid = ft_hash_str_lookup( name, font->internal ) ) != NULL )
+ if ( ( propid = ft_hash_str_lookup( name, font->internal ) ) != NULL )
{
/* The property already exists in the font, so simply replace */
/* the value of the property with the current value. */
@@ -1993,6 +1992,15 @@
goto Exit;
}
+ /* Reserve space for artificial FONT_ASCENT or FONT_DESCENT. */
+ if ( font->props_size == 0 )
+ {
+ if ( FT_NEW_ARRAY( font->props, 2 ) )
+ goto Exit;
+
+ font->props_size = 2;
+ }
+
/* If the FONT_ASCENT or FONT_DESCENT properties have not been */
/* encountered yet, then make sure they are added as properties and */
/* make sure they are set from the font bounding box info. */
From d4631a2eb358783e34df47747085c839d854ed0a Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Thu, 16 Jan 2025 20:54:33 +0000
Subject: [PATCH 72/94] * src/bdf/bdflib.c (bdf_readstream_): Skip all control
characters.
This agrees with specifications and makes the code a lot simpler.
---
src/bdf/bdflib.c | 54 +++++++++++-------------------------------------
1 file changed, 12 insertions(+), 42 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 66b97d3e3..84e9d8d3e 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -509,7 +509,6 @@
{
bdf_line_func_t_ cb;
unsigned long lineno, buf_size;
- int hold, to_skip;
unsigned long bytes, start, end, cursor, avail;
char* buf = NULL;
FT_Memory memory = stream->memory;
@@ -530,44 +529,29 @@
cb = callback;
lineno = 1;
- buf[0] = 0;
start = 0;
cursor = 0;
- to_skip = NO_SKIP;
Refill:
bytes = FT_Stream_TryRead( stream,
(FT_Byte*)buf + cursor, buf_size - cursor );
avail = cursor + bytes;
- for (;;)
+ while ( bytes )
{
- /* should we skip an optional character like \n or \r? */
- if ( start < avail && buf[start] == to_skip )
- {
- start += 1;
- to_skip = NO_SKIP;
- continue;
- }
+ /* try to fine the start of the line */
+ while ( start < avail && buf[start] < ' ' )
+ start++;
/* try to find the end of the line */
- end = start;
- while ( end < avail && buf[end] != '\n' && buf[end] != '\r' )
+ end = start + 1;
+ while ( end < avail && buf[end] >= ' ' )
end++;
/* if we hit the end of the buffer, try shifting its content */
/* or even resizing it */
if ( end >= avail )
{
- if ( bytes == 0 )
- {
- /* last line in file doesn't end in \r or \n; */
- /* ignore it then exit */
- if ( lineno == 1 )
- error = FT_THROW( Missing_Startfont_Field );
- break;
- }
-
if ( start == 0 )
{
/* this line is definitely too long; try resizing the input */
@@ -577,17 +561,13 @@
if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */
{
- if ( lineno == 1 )
- error = FT_THROW( Missing_Startfont_Field );
- else
- {
- FT_ERROR(( "bdf_readstream_: " ERRMSG6, lineno ));
- error = FT_THROW( Invalid_Argument );
- }
+ FT_ERROR(( "bdf_readstream_: " ERRMSG6, lineno ));
+ error = FT_THROW( Invalid_File_Format );
+
goto Exit;
}
- new_size = buf_size * 2;
+ new_size = buf_size * 4;
if ( FT_QREALLOC( buf, buf_size, new_size ) )
goto Exit;
@@ -605,12 +585,10 @@
goto Refill;
}
- /* Temporarily NUL-terminate the line. */
- hold = buf[end];
+ /* NUL-terminate the line. */
buf[end] = 0;
- /* XXX: Use encoding independent value for 0x1A */
- if ( buf[start] != '#' && buf[start] != 0x1A && end > start )
+ if ( buf[start] != '#' )
{
error = (*cb)( buf + start, end - start, lineno,
(void*)&cb, client_data );
@@ -619,15 +597,7 @@
}
lineno += 1;
- buf[end] = (char)hold;
start = end + 1;
-
- if ( hold == '\n' )
- to_skip = '\r';
- else if ( hold == '\r' )
- to_skip = '\n';
- else
- to_skip = NO_SKIP;
}
*lno = lineno;
From e3a3b39dd0cf0a01ec8998cc760d01b9f0b1bac7 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Thu, 16 Jan 2025 23:25:08 +0000
Subject: [PATCH 73/94] * src/bdf/bdflib.c (bdf_parse_start_): Do not overwrite
flags.
---
src/bdf/bdflib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 84e9d8d3e..cb0b0f647 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1759,7 +1759,7 @@
goto Exit;
}
- p->flags = BDF_START_;
+ p->flags |= BDF_START_;
if ( FT_NEW( p->font ) )
goto Exit;
From ad7dce7751298e3d65752c5149f08892ff79bcb0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 17 Jan 2025 20:54:14 -0500
Subject: [PATCH 74/94] * src/bdf/bdflib.c (bdf_parse_start_): Prevent another
STARTPROPERTIES.
Only one STARTPROPERTIES was permitted in the old flow preventing
leaks and overflows.
See https://issues.oss-fuzz.com/issues/389968131
https://issues.oss-fuzz.com/issues/390464875
---
src/bdf/bdflib.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index cb0b0f647..ce8dfb1b6 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -539,7 +539,7 @@
while ( bytes )
{
- /* try to fine the start of the line */
+ /* try to find the start of the line */
while ( start < avail && buf[start] < ' ' )
start++;
@@ -1661,7 +1661,6 @@
/* Check for the end of the properties. */
if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
{
- p->flags &= ~BDF_PROPS_;
*next = bdf_parse_start_;
goto Exit;
@@ -1798,7 +1797,8 @@
font = p->font;
/* Check for the start of the properties. */
- if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
+ if ( !( p->flags & BDF_PROPS_ ) &&
+ _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
{
if ( !( p->flags & BDF_FONT_BBX_ ) )
{
@@ -1812,9 +1812,13 @@
if ( error )
goto Exit;
- p->cnt = font->props_size = bdf_atoul_( p->list.field[1] );
+ font->props_size = bdf_atoul_( p->list.field[1] );
+
+ if ( font->props_size < 2 )
+ font->props_size = 2;
+
/* We need at least 4 bytes per property. */
- if ( p->cnt > p->size / 4 )
+ if ( font->props_size > p->size / 4 )
{
font->props_size = 0;
@@ -1823,7 +1827,7 @@
goto Exit;
}
- if ( FT_NEW_ARRAY( font->props, p->cnt ) )
+ if ( FT_NEW_ARRAY( font->props, font->props_size ) )
{
font->props_size = 0;
goto Exit;
From 01c22b3668997e561612a9bd35e381535f57eb6f Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sun, 19 Jan 2025 11:19:10 -0500
Subject: [PATCH 75/94] [bdf] Tokenize input instead of listing.
Instead of cumbersome field list mamangement, we will tokenize input
using custom `bdf_strtok_`.
* src/bdf/bdflib.c (bdf_list_t_, bdf_list_init_, bdf_list_ensure_,
bdf_list_shift_, bdf_list_join_, bdf_list_split_,
bdf_set_default_spacing_): Removed.
(bdf_strtok_): New function which NUL-terminates the first token at
the delimiter position and returns the next token that follows
consequtive delimiters.
(bdf_parse_*_, bdf_load_font): Updated.
* docs/CHANGES: Claim overall 75% performance improvement.
---
docs/CHANGES | 2 +-
src/bdf/bdflib.c | 518 +++++++++--------------------------------------
2 files changed, 94 insertions(+), 426 deletions(-)
diff --git a/docs/CHANGES b/docs/CHANGES
index bf454f46e..1e0977b36 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -11,7 +11,7 @@ CHANGES BETWEEN 2.13.3 and 2.13.4 (2025-Mmm-DD)
III. MISCELLANEOUS
- - The BDF driver now loads fonts noticeably faster.
+ - The BDF driver now loads fonts 75% faster.
======================================================================
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index ce8dfb1b6..395150b61 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -221,18 +221,6 @@
void* client_data );
- /* List structure for splitting lines into fields. */
-
- typedef struct bdf_list_t__
- {
- char** field;
- unsigned long size;
- unsigned long used;
- FT_Memory memory;
-
- } bdf_list_t_;
-
-
/* Structure used while loading BDF fonts. */
typedef struct bdf_parse_t__
@@ -255,8 +243,6 @@
bdf_glyph_t* glyph;
bdf_font_t* font;
- bdf_list_t_ list;
-
FT_Memory memory;
unsigned long size; /* the stream size */
@@ -269,238 +255,23 @@
( m[(FT_Byte)(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) )
- static void
- bdf_list_init_( bdf_list_t_* list,
- FT_Memory memory )
+ static char*
+ bdf_strtok_( char* line,
+ int delim )
{
- FT_ZERO( list );
- list->memory = memory;
+ while ( *line && *line != delim )
+ line++;
+
+ if ( *line )
+ *line++ = '\0';
+
+ while ( *line && *line == delim )
+ line++;
+
+ return line;
}
- static void
- bdf_list_done_( bdf_list_t_* list )
- {
- FT_Memory memory = list->memory;
-
-
- if ( memory )
- {
- FT_FREE( list->field );
- FT_ZERO( list );
- }
- }
-
-
- static FT_Error
- bdf_list_ensure_( bdf_list_t_* list,
- unsigned long num_items ) /* same as bdf_list_t_.used */
- {
- FT_Error error = FT_Err_Ok;
-
-
- if ( num_items > list->size )
- {
- unsigned long oldsize = list->size; /* same as bdf_list_t_.size */
- unsigned long newsize = oldsize + ( oldsize >> 1 ) + 5;
- unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) );
- FT_Memory memory = list->memory;
-
-
- if ( oldsize == bigsize )
- {
- error = FT_THROW( Out_Of_Memory );
- goto Exit;
- }
- else if ( newsize < oldsize || newsize > bigsize )
- newsize = bigsize;
-
- if ( FT_QRENEW_ARRAY( list->field, oldsize, newsize ) )
- goto Exit;
-
- list->size = newsize;
- }
-
- Exit:
- return error;
- }
-
-
- static void
- bdf_list_shift_( bdf_list_t_* list,
- unsigned long n )
- {
- unsigned long i, u;
-
-
- if ( list == NULL || list->used == 0 || n == 0 )
- return;
-
- if ( n >= list->used )
- {
- list->used = 0;
- return;
- }
-
- for ( u = n, i = 0; u < list->used; i++, u++ )
- list->field[i] = list->field[u];
- list->used -= n;
- }
-
-
- /* An empty string for empty fields. */
-
- static const char empty[] = ""; /* XXX eliminate this */
-
-
- static char *
- bdf_list_join_( bdf_list_t_* list,
- int c,
- unsigned long *alen )
- {
- unsigned long i, j;
- char* dp;
-
-
- *alen = 0;
-
- if ( list == NULL || list->used == 0 )
- return NULL;
-
- dp = list->field[0];
- for ( i = j = 0; i < list->used; i++ )
- {
- char* fp = list->field[i];
-
-
- while ( *fp )
- dp[j++] = *fp++;
-
- if ( i + 1 < list->used )
- dp[j++] = (char)c;
- }
- if ( dp != empty )
- dp[j] = 0;
-
- *alen = j;
- return dp;
- }
-
-
- /* The code below ensures that we have at least 4 + 1 `field' */
- /* elements in `list' (which are possibly NULL) so that we */
- /* don't have to check the number of fields in most cases. */
-
- static FT_Error
- bdf_list_split_( bdf_list_t_* list,
- const char* separators,
- char* line,
- unsigned long linelen )
- {
- unsigned long final_empty;
- int mult;
- const char *sp, *end;
- char *ep;
- char seps[32];
- FT_Error error = FT_Err_Ok;
-
-
- /* Initialize the list. */
- list->used = 0;
- if ( list->size )
- {
- list->field[0] = (char*)empty;
- list->field[1] = (char*)empty;
- list->field[2] = (char*)empty;
- list->field[3] = (char*)empty;
- list->field[4] = (char*)empty;
- }
-
- /* If the line is empty, then simply return. */
- if ( linelen == 0 || line[0] == 0 )
- goto Exit;
-
- /* In the original code, if the `separators' parameter is NULL or */
- /* empty, the list is split into individual bytes. We don't need */
- /* this, so an error is signaled. */
- if ( separators == NULL || *separators == 0 )
- {
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
-
- /* Prepare the separator bitmap. */
- FT_MEM_ZERO( seps, 32 );
-
- /* If the very last character of the separator string is a plus, then */
- /* set the `mult' flag to indicate that multiple separators should be */
- /* collapsed into one. */
- for ( mult = 0, sp = separators; sp && *sp; sp++ )
- {
- if ( *sp == '+' && *( sp + 1 ) == 0 )
- mult = 1;
- else
- setsbit( seps, *sp );
- }
-
- /* Break the line up into fields. */
- for ( final_empty = 0, sp = ep = line, end = sp + linelen;
- sp < end && *sp; )
- {
- /* Collect everything that is not a separator. */
- for ( ; *ep && !sbitset( seps, *ep ); ep++ )
- ;
-
- /* Resize the list if necessary. */
- if ( list->used == list->size )
- {
- error = bdf_list_ensure_( list, list->used + 1 );
- if ( error )
- goto Exit;
- }
-
- /* Assign the field appropriately. */
- list->field[list->used++] = ( ep > sp ) ? (char*)sp : (char*)empty;
-
- sp = ep;
-
- if ( mult )
- {
- /* If multiple separators should be collapsed, do it now by */
- /* setting all the separator characters to 0. */
- for ( ; *ep && sbitset( seps, *ep ); ep++ )
- *ep = 0;
- }
- else if ( *ep != 0 )
- /* Don't collapse multiple separators by making them 0, so just */
- /* make the one encountered 0. */
- *ep++ = 0;
-
- final_empty = ( ep > sp && *ep == 0 );
- sp = ep;
- }
-
- /* Finally, NULL-terminate the list. */
- if ( list->used + final_empty >= list->size )
- {
- error = bdf_list_ensure_( list, list->used + final_empty + 1 );
- if ( error )
- goto Exit;
- }
-
- if ( final_empty )
- list->field[list->used++] = (char*)empty;
-
- list->field[list->used] = NULL;
-
- Exit:
- return error;
- }
-
-
-#define NO_SKIP 256 /* this value cannot be stored in a 'char' */
-
-
static FT_Error
bdf_readstream_( FT_Stream stream,
bdf_line_func_t_ callback,
@@ -907,75 +678,6 @@
}
- /* Set the spacing from the font name if it exists, */
- /* or use default */
- static FT_Error
- bdf_set_default_spacing_( bdf_font_t* font,
- unsigned long lineno )
- {
- size_t len;
- char name[256];
- bdf_list_t_ list;
- FT_Memory memory;
- FT_Error error = FT_Err_Ok;
-
- FT_UNUSED( lineno ); /* only used in debug mode */
-
-
- if ( font == NULL || font->name == NULL || font->name[0] == 0 )
- {
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
-
- memory = font->memory;
-
- bdf_list_init_( &list, memory );
-
- font->spacing = BDF_PROPORTIONAL; /* default */
-
- len = ft_strlen( font->name ) + 1;
- /* Limit ourselves to 256 characters in the font name. */
- if ( len >= 256 )
- {
- FT_ERROR(( "bdf_set_default_spacing_: " ERRMSG7, lineno ));
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
-
- FT_MEM_COPY( name, font->name, len );
-
- error = bdf_list_split_( &list, "-", name, (unsigned long)len );
- if ( error )
- goto Fail;
-
- if ( list.used == 15 )
- {
- switch ( list.field[11][0] )
- {
- case 'C':
- case 'c':
- font->spacing = BDF_CHARCELL;
- break;
- case 'M':
- case 'm':
- font->spacing = BDF_MONOWIDTH;
- break;
- case 'P':
- case 'p':
- font->spacing = BDF_PROPORTIONAL;
- break;
- }
- }
-
- Fail:
- bdf_list_done_( &list );
-
- Exit:
- return error;
- }
-
-
/* Determine whether the property is an atom or not. If it is, then */
/* clean it up so the double quotes are removed if they exist. */
static int
@@ -1293,9 +995,6 @@
FT_Memory memory = font->memory;
FT_Error error = FT_Err_Ok;
- char* s;
- unsigned long slen;
-
FT_UNUSED( lineno ); /* only used in debug mode */
@@ -1304,15 +1003,15 @@
{
if ( p->flags & BDF_KEEP_COMMENTS )
{
+ line += 7;
linelen -= 7;
- s = line + 7;
- if ( *s != 0 )
+ if ( *line )
{
- s++;
+ line++;
linelen--;
}
- error = bdf_add_comment_( p->font, s, linelen );
+ error = bdf_add_comment_( p->font, line, linelen );
}
goto Exit;
}
@@ -1370,24 +1069,9 @@
goto Exit;
}
- /* Set the character name in the parse info first until the */
- /* encoding can be checked for an unencoded character. */
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
+ line = bdf_strtok_( line, ' ' );
- bdf_list_shift_( &p->list, 1 );
-
- s = bdf_list_join_( &p->list, ' ', &slen );
-
- if ( !s )
- {
- FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG8, lineno, "STARTCHAR" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
-
- if ( FT_DUP( p->glyph_name, s, slen + 1 ) )
+ if ( FT_STRDUP( p->glyph_name, line ) )
goto Exit;
p->flags |= BDF_GLYPH_;
@@ -1408,11 +1092,9 @@
goto Exit;
}
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
+ line = bdf_strtok_( line, ' ' );
- p->glyph_enc = bdf_atol_( p->list.field[1] );
+ p->glyph_enc = bdf_atol_( line );
/* Normalize negative encoding values. The specification only */
/* allows -1, but we can be more generous here. */
@@ -1420,8 +1102,10 @@
p->glyph_enc = -1;
/* Check for alternative encoding format. */
- if ( p->glyph_enc == -1 && p->list.used > 2 )
- p->glyph_enc = bdf_atol_( p->list.field[2] );
+ line = bdf_strtok_( line, ' ' );
+
+ if ( p->glyph_enc == -1 && *line )
+ p->glyph_enc = bdf_atol_( line );
if ( p->glyph_enc < -1 || p->glyph_enc >= 0x110000L )
p->glyph_enc = -1;
@@ -1487,24 +1171,18 @@
/* Expect the SWIDTH (scalable width) field next. */
if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
{
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
+ line = bdf_strtok_( line, ' ' );
+ glyph->swidth = bdf_atous_( line );
- glyph->swidth = bdf_atous_( p->list.field[1] );
p->flags |= BDF_SWIDTH_;
-
goto Exit;
}
/* Expect the DWIDTH (device width) field next. */
if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 )
{
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
-
- glyph->dwidth = bdf_atous_( p->list.field[1] );
+ line = bdf_strtok_( line, ' ' );
+ glyph->dwidth = bdf_atous_( line );
if ( !( p->flags & BDF_SWIDTH_ ) )
{
@@ -1529,14 +1207,14 @@
/* Expect the BBX field next. */
if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
{
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
-
- glyph->bbx.width = bdf_atous_( p->list.field[1] );
- glyph->bbx.height = bdf_atous_( p->list.field[2] );
- glyph->bbx.x_offset = bdf_atos_( p->list.field[3] );
- glyph->bbx.y_offset = bdf_atos_( p->list.field[4] );
+ line = bdf_strtok_( line, ' ' );
+ glyph->bbx.width = bdf_atous_( line );
+ line = bdf_strtok_( line, ' ' );
+ glyph->bbx.height = bdf_atous_( line );
+ line = bdf_strtok_( line, ' ' );
+ glyph->bbx.x_offset = bdf_atos_( line );
+ line = bdf_strtok_( line, ' ' );
+ glyph->bbx.y_offset = bdf_atos_( line );
/* Generate the ascent and descent of the character. */
glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset );
@@ -1651,7 +1329,6 @@
FT_Error error = FT_Err_Ok;
- unsigned long vlen;
char* name;
char* value;
@@ -1690,15 +1367,9 @@
}
else
{
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
- name = p->list.field[0];
+ value = bdf_strtok_( line, ' ' );
- bdf_list_shift_( &p->list, 1 );
- value = bdf_list_join_( &p->list, ' ', &vlen );
-
- error = bdf_add_property_( p->font, name, value, lineno );
+ error = bdf_add_property_( p->font, line, value, lineno );
if ( error )
goto Exit;
}
@@ -1723,9 +1394,6 @@
FT_Memory memory = p->memory;
FT_Error error = FT_Err_Ok;
- unsigned long slen;
- char *s;
-
FT_UNUSED( lineno ); /* only used in debug mode */
@@ -1735,15 +1403,14 @@
{
if ( p->flags & BDF_KEEP_COMMENTS && p->font )
{
+ line += 7;
linelen -= 7;
-
- s = line + 7;
- if ( *s != 0 )
+ if ( *line )
{
- s++;
+ line++;
linelen--;
}
- error = bdf_add_comment_( p->font, s, linelen );
+ error = bdf_add_comment_( p->font, line, linelen );
}
goto Exit;
}
@@ -1787,7 +1454,7 @@
error = ft_hash_str_init( p->font->internal, memory );
if ( error )
goto Exit;
- p->font->spacing = BDF_PROPORTIONAL;
+ p->font->spacing = BDF_PROPORTIONAL; /* default */
p->font->default_char = ~0UL;
goto Exit;
@@ -1808,11 +1475,8 @@
goto Exit;
}
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
-
- font->props_size = bdf_atoul_( p->list.field[1] );
+ line = bdf_strtok_( line, ' ' );
+ font->props_size = bdf_atoul_( line );
if ( font->props_size < 2 )
font->props_size = 2;
@@ -1850,15 +1514,14 @@
goto Exit;
}
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
-
- font->bbx.width = bdf_atous_( p->list.field[1] );
- font->bbx.height = bdf_atous_( p->list.field[2] );
-
- font->bbx.x_offset = bdf_atos_( p->list.field[3] );
- font->bbx.y_offset = bdf_atos_( p->list.field[4] );
+ line = bdf_strtok_( line, ' ' );
+ font->bbx.width = bdf_atous_( line );
+ line = bdf_strtok_( line, ' ' );
+ font->bbx.height = bdf_atous_( line );
+ line = bdf_strtok_( line, ' ' );
+ font->bbx.x_offset = bdf_atos_( line );
+ line = bdf_strtok_( line, ' ' );
+ font->bbx.y_offset = bdf_atos_( line );
font->bbx.ascent = (short)( font->bbx.height +
font->bbx.y_offset );
@@ -1873,31 +1536,42 @@
/* The next thing to check for is the FONT field. */
if ( _bdf_strncmp( line, "FONT", 4 ) == 0 )
{
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
- bdf_list_shift_( &p->list, 1 );
+ int i;
- s = bdf_list_join_( &p->list, ' ', &slen );
- if ( !s )
- {
- FT_ERROR(( "bdf_parse_start_: " ERRMSG8, lineno, "FONT" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
+ line = bdf_strtok_( line, ' ' );
/* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */
FT_FREE( font->name );
- if ( FT_DUP( font->name, s, slen + 1 ) )
+ if ( FT_STRDUP( font->name, line ) )
goto Exit;
- /* If the font name is an XLFD name, set the spacing to the one in */
- /* the font name. If there is no spacing fall back on the default. */
- error = bdf_set_default_spacing_( font, lineno );
- if ( error )
- goto Exit;
+ /* If the font name is an XLFD name, set the spacing to the one in */
+ /* the font name after the 11th dash. */
+ for ( i = 0; i < 11; i++ )
+ {
+ while ( *line && *line != '-' )
+ line++;
+ if ( *line )
+ line++;
+ }
+
+ switch ( *line )
+ {
+ case 'C':
+ case 'c':
+ font->spacing = BDF_CHARCELL;
+ break;
+ case 'M':
+ case 'm':
+ font->spacing = BDF_MONOWIDTH;
+ break;
+ case 'P':
+ case 'p':
+ font->spacing = BDF_PROPORTIONAL;
+ break;
+ }
p->flags |= BDF_FONT_NAME_;
@@ -1915,21 +1589,21 @@
goto Exit;
}
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
-
- font->point_size = bdf_atoul_( p->list.field[1] );
- font->resolution_x = bdf_atoul_( p->list.field[2] );
- font->resolution_y = bdf_atoul_( p->list.field[3] );
+ line = bdf_strtok_( line, ' ' );
+ font->point_size = bdf_atoul_( line );
+ line = bdf_strtok_( line, ' ' );
+ font->resolution_x = bdf_atoul_( line );
+ line = bdf_strtok_( line, ' ' );
+ font->resolution_y = bdf_atoul_( line );
/* Check for the bits per pixel field. */
- if ( p->list.used == 5 )
+ line = bdf_strtok_( line, ' ' );
+ if ( *line )
{
unsigned short bpp;
- bpp = bdf_atous_( p->list.field[4] );
+ bpp = bdf_atous_( line );
/* Only values 1, 2, 4, 8 are allowed for greymap fonts. */
if ( bpp > 4 )
@@ -2003,10 +1677,8 @@
FT_TRACE2(( "bdf_parse_start_: " ACMSG2, font->bbx.descent ));
}
- error = bdf_list_split_( &p->list, " +", line, linelen );
- if ( error )
- goto Exit;
- p->cnt = font->glyphs_size = bdf_atoul_( p->list.field[1] );
+ line = bdf_strtok_( line, ' ' );
+ p->cnt = font->glyphs_size = bdf_atoul_( line );
/* We need at least 20 bytes per glyph. */
if ( p->cnt > p->size / 20 )
@@ -2072,8 +1744,6 @@
p->size = stream->size;
p->memory = memory; /* only during font creation */
- bdf_list_init_( &p->list, memory );
-
error = bdf_readstream_( stream, bdf_parse_start_,
(void *)p, &lineno );
if ( error )
@@ -2168,8 +1838,6 @@
Exit:
if ( p )
{
- bdf_list_done_( &p->list );
-
FT_FREE( p->glyph_name );
FT_FREE( p );
}
From b9e09e33fefaf77d119ef7f91f315648ac1bf812 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Sun, 19 Jan 2025 12:35:13 -0500
Subject: [PATCH 76/94] * src/bdf/bdflib.c (bdf_parse_glyphs_): Fix tracing.
---
src/bdf/bdflib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 395150b61..9feb5a004 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1076,7 +1076,7 @@
p->flags |= BDF_GLYPH_;
- FT_TRACE4(( DBGMSG1, lineno, s ));
+ FT_TRACE4(( DBGMSG1, lineno, line ));
goto Exit;
}
From a059b237bb01eb3e4f9f8b1618dda8c117498bab Mon Sep 17 00:00:00 2001
From: Chad Brokaw
Date: Sun, 19 Jan 2025 22:39:17 -0500
Subject: [PATCH 77/94] * src/truetype/ttgxvar.c (tt_face_vary_cvt): Fix all
shared values.
Applying cvar deltas to all shared points was incorrectly omitted.
Fixes #1314.
---
src/truetype/ttgxvar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 4f0083c96..20860665d 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -3676,7 +3676,7 @@
if ( !points || !deltas )
; /* failure, ignore it */
- else if ( localpoints == ALL_POINTS )
+ else if ( points == ALL_POINTS )
{
#ifdef FT_DEBUG_LEVEL_TRACE
int count = 0;
From c33da8fbbd59391be73fa512f6dfd74f6a6c01d0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 16:59:44 -0500
Subject: [PATCH 78/94] * src/bdf/bdflib.c (bdf_parse_start_): Relax the header
order.
We now check that the header is complete in no specific order.
---
src/bdf/bdflib.c | 42 ++++++++++++++++++------------------------
1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 9feb5a004..9c2a2e202 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -1467,14 +1467,6 @@
if ( !( p->flags & BDF_PROPS_ ) &&
_bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
{
- if ( !( p->flags & BDF_FONT_BBX_ ) )
- {
- /* Missing the FONTBOUNDINGBOX field. */
- FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
- error = FT_THROW( Missing_Fontboundingbox_Field );
- goto Exit;
- }
-
line = bdf_strtok_( line, ' ' );
font->props_size = bdf_atoul_( line );
@@ -1506,14 +1498,6 @@
/* Check for the FONTBOUNDINGBOX field. */
if ( _bdf_strncmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )
{
- if ( !( p->flags & BDF_SIZE_ ) )
- {
- /* Missing the SIZE field. */
- FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "SIZE" ));
- error = FT_THROW( Missing_Size_Field );
- goto Exit;
- }
-
line = bdf_strtok_( line, ' ' );
font->bbx.width = bdf_atous_( line );
line = bdf_strtok_( line, ' ' );
@@ -1581,14 +1565,6 @@
/* Check for the SIZE field. */
if ( _bdf_strncmp( line, "SIZE", 4 ) == 0 )
{
- if ( !( p->flags & BDF_FONT_NAME_ ) )
- {
- /* Missing the FONT field. */
- FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONT" ));
- error = FT_THROW( Missing_Font_Field );
- goto Exit;
- }
-
line = bdf_strtok_( line, ' ' );
font->point_size = bdf_atoul_( line );
line = bdf_strtok_( line, ' ' );
@@ -1632,6 +1608,24 @@
char nbuf[BUFSIZE];
+ /* Check the header for completeness before leaving. */
+
+ if ( !( p->flags & BDF_FONT_NAME_ ) )
+ {
+ /* Missing the FONT field. */
+ FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONT" ));
+ error = FT_THROW( Missing_Font_Field );
+ goto Exit;
+ }
+
+ if ( !( p->flags & BDF_SIZE_ ) )
+ {
+ /* Missing the SIZE field. */
+ FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "SIZE" ));
+ error = FT_THROW( Missing_Size_Field );
+ goto Exit;
+ }
+
if ( !( p->flags & BDF_FONT_BBX_ ) )
{
/* Missing the FONTBOUNDINGBOX field. */
From c0a7839e7d12919ac85c1a223dde671eabee6be0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 19:11:47 -0500
Subject: [PATCH 79/94] [bdf] Postpone font ascent and descent handling.
* src/bdf/bdflib.c (bdf_parse_start_, bdf_add_property_): Delay handling
of the font ascent and descent until...
* src/bdf/bdfdrivr.c (BDF_Face_Init): ... handles all other properties.
---
src/bdf/bdfdrivr.c | 32 ++++++++++++++++------------
src/bdf/bdflib.c | 52 +---------------------------------------------
2 files changed, 20 insertions(+), 64 deletions(-)
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 85a03152d..1eb4325f4 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -439,19 +439,25 @@ THE SOFTWARE.
long value;
- /* sanity checks */
- if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF )
- {
- font->font_ascent = font->font_ascent < 0 ? -0x7FFF : 0x7FFF;
- FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %ld\n",
- font->font_ascent ));
- }
- if ( font->font_descent > 0x7FFF || font->font_descent < -0x7FFF )
- {
- font->font_descent = font->font_descent < 0 ? -0x7FFF : 0x7FFF;
- FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %ld\n",
- font->font_descent ));
- }
+ prop = bdf_get_font_property( font, "FONT_ASCENT" );
+ if ( prop )
+ font->font_ascent = prop->value.l;
+ else
+ font->font_ascent = font->bbx.ascent;
+ if ( font->font_ascent > 0x7FFF )
+ font->font_ascent = 0x7FFF;
+ else if ( font->font_ascent < 0 )
+ font->font_ascent = 0;
+
+ prop = bdf_get_font_property( font, "FONT_DESCENT" );
+ if ( prop )
+ font->font_descent = prop->value.l;
+ else
+ font->font_descent = font->bbx.descent;
+ if ( font->font_descent > 0x7FFF )
+ font->font_descent = 0x7FFF;
+ else if ( font->font_descent < 0 )
+ font->font_descent = 0;
bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 9c2a2e202..0fa4736b3 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -51,9 +51,6 @@
#define FT_COMPONENT bdflib
-#define BUFSIZE 128
-
-
/**************************************************************************
*
* Builtin BDF font properties.
@@ -866,10 +863,6 @@
/* spacing. */
if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 )
font->default_char = fp->value.ul;
- else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 )
- font->font_ascent = fp->value.l;
- else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 )
- font->font_descent = fp->value.l;
else if ( _bdf_strncmp( name, "SPACING", 7 ) == 0 )
{
if ( !fp->value.atom )
@@ -1605,11 +1598,7 @@
/* Check for the CHARS field */
if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 )
{
- char nbuf[BUFSIZE];
-
-
- /* Check the header for completeness before leaving. */
-
+ /* Check the header for completeness before parsing glyphs. */
if ( !( p->flags & BDF_FONT_NAME_ ) )
{
/* Missing the FONT field. */
@@ -1617,7 +1606,6 @@
error = FT_THROW( Missing_Font_Field );
goto Exit;
}
-
if ( !( p->flags & BDF_SIZE_ ) )
{
/* Missing the SIZE field. */
@@ -1625,7 +1613,6 @@
error = FT_THROW( Missing_Size_Field );
goto Exit;
}
-
if ( !( p->flags & BDF_FONT_BBX_ ) )
{
/* Missing the FONTBOUNDINGBOX field. */
@@ -1634,43 +1621,6 @@
goto Exit;
}
- /* Reserve space for artificial FONT_ASCENT or FONT_DESCENT. */
- if ( font->props_size == 0 )
- {
- if ( FT_NEW_ARRAY( font->props, 2 ) )
- goto Exit;
-
- font->props_size = 2;
- }
-
- /* If the FONT_ASCENT or FONT_DESCENT properties have not been */
- /* encountered yet, then make sure they are added as properties and */
- /* make sure they are set from the font bounding box info. */
- /* */
- /* This is *always* done regardless of the options, because X11 */
- /* requires these two fields to compile fonts. */
- if ( bdf_get_font_property( font, "FONT_ASCENT" ) == 0 )
- {
- font->font_ascent = font->bbx.ascent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", font->bbx.ascent );
- error = bdf_add_property_( font, "FONT_ASCENT", nbuf, lineno );
- if ( error )
- goto Exit;
-
- FT_TRACE2(( "bdf_parse_start_: " ACMSG1, font->bbx.ascent ));
- }
-
- if ( bdf_get_font_property( font, "FONT_DESCENT" ) == 0 )
- {
- font->font_descent = font->bbx.descent;
- ft_snprintf( nbuf, BUFSIZE, "%hd", font->bbx.descent );
- error = bdf_add_property_( font, "FONT_DESCENT", nbuf, lineno );
- if ( error )
- goto Exit;
-
- FT_TRACE2(( "bdf_parse_start_: " ACMSG2, font->bbx.descent ));
- }
-
line = bdf_strtok_( line, ' ' );
p->cnt = font->glyphs_size = bdf_atoul_( line );
From 8bae87065addf10cf2b76f6a047ea54694b709a4 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 20:46:43 -0500
Subject: [PATCH 80/94] [bdf] Postpone font spacing handling.
* src/bdf/bdf.h (bdf_font_t): Remove `monowidth`.
* src/bdf/bdflib.c (bdf_parse_start_, bdf_add_property_): Delay handling
of the font spacing until...
* src/bdf/bdfdrivr.c (BDF_Face_Init): ... handles all other properties.
---
src/bdf/bdf.h | 3 ---
src/bdf/bdfdrivr.c | 16 ++++++++++++----
src/bdf/bdflib.c | 24 +-----------------------
3 files changed, 13 insertions(+), 30 deletions(-)
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index 2f866e874..85a9e4f2e 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -141,9 +141,6 @@ FT_BEGIN_HEADER
unsigned long resolution_y; /* Font vertical resolution. */
int spacing; /* Font spacing value. */
-
- unsigned short monowidth; /* Logical width for monowidth font. */
-
unsigned long default_char; /* Encoding of the default glyph. */
long font_ascent; /* Font ascent. */
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 1eb4325f4..22416e82a 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -403,10 +403,18 @@ THE SOFTWARE.
FT_FACE_FLAG_HORIZONTAL;
prop = bdf_get_font_property( font, "SPACING" );
- if ( prop && prop->format == BDF_ATOM &&
- prop->value.atom &&
- ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' ||
- *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) )
+ if ( prop && prop->value.atom )
+ {
+ if ( prop->value.atom[0] == 'p' || prop->value.atom[0] == 'P' )
+ font->spacing = BDF_PROPORTIONAL;
+ else if ( prop->value.atom[0] == 'm' || prop->value.atom[0] == 'M' )
+ font->spacing = BDF_MONOWIDTH;
+ else if ( prop->value.atom[0] == 'c' || prop->value.atom[0] == 'C' )
+ font->spacing = BDF_CHARCELL;
+ }
+
+ if ( font->spacing == BDF_MONOWIDTH ||
+ font->spacing == BDF_CHARCELL )
face->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
/* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 0fa4736b3..6d154da25 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -863,22 +863,6 @@
/* spacing. */
if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 )
font->default_char = fp->value.ul;
- else if ( _bdf_strncmp( name, "SPACING", 7 ) == 0 )
- {
- if ( !fp->value.atom )
- {
- FT_ERROR(( "bdf_add_property_: " ERRMSG8, lineno, "SPACING" ));
- error = FT_THROW( Invalid_File_Format );
- goto Exit;
- }
-
- if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' )
- font->spacing = BDF_PROPORTIONAL;
- else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' )
- font->spacing = BDF_MONOWIDTH;
- else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' )
- font->spacing = BDF_CHARCELL;
- }
Exit:
return error;
@@ -1447,7 +1431,6 @@
error = ft_hash_str_init( p->font->internal, memory );
if ( error )
goto Exit;
- p->font->spacing = BDF_PROPORTIONAL; /* default */
p->font->default_char = ~0UL;
goto Exit;
@@ -1546,6 +1529,7 @@
break;
case 'P':
case 'p':
+ default:
font->spacing = BDF_PROPORTIONAL;
break;
}
@@ -1695,12 +1679,6 @@
if ( p->font )
{
- /* If the font is not proportional, set the font's monowidth */
- /* field to the width of the font bounding box. */
-
- if ( p->font->spacing != BDF_PROPORTIONAL )
- p->font->monowidth = p->font->bbx.width;
-
/* If the number of glyphs loaded is not that of the original count, */
/* indicate the difference. */
if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used )
From 56131e4216d1638766b7fe32bed14f217e7a2858 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 20:47:56 -0500
Subject: [PATCH 81/94] [bdf] Postpone font default char handling.
* src/bdf/bdflib.c (bdf_parse_start_, bdf_add_property_): Delay handling
of the default char until...
* src/bdf/bdfdrivr.c (BDF_Face_Init): ... handles all other properties.
---
src/bdf/bdfdrivr.c | 6 ++++++
src/bdf/bdflib.c | 9 ---------
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 22416e82a..1995c36ac 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -600,6 +600,12 @@ THE SOFTWARE.
resolution_y );
else
bsize->x_ppem = bsize->y_ppem;
+
+ prop = bdf_get_font_property( font, "DEFAULT_CHAR" );
+ if ( prop )
+ font->default_char = prop->value.ul;
+ else
+ font->default_char = ~0UL;
}
/* encoding table */
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 6d154da25..5c6841c35 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -856,14 +856,6 @@
font->props_used++;
- /* Some special cases need to be handled here. The DEFAULT_CHAR */
- /* property needs to be located if it exists in the property list, the */
- /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */
- /* present, and the SPACING property should override the default */
- /* spacing. */
- if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 )
- font->default_char = fp->value.ul;
-
Exit:
return error;
}
@@ -1431,7 +1423,6 @@
error = ft_hash_str_init( p->font->internal, memory );
if ( error )
goto Exit;
- p->font->default_char = ~0UL;
goto Exit;
}
From 40a74585000a0d67cb1a5d49b59db95934cc810c Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 21:05:22 -0500
Subject: [PATCH 82/94] * src/bdf/bdflib.c (bdf_ato{i.ul.s.us}_]): Remove
uncecessary checks.
---
src/bdf/bdflib.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 5c6841c35..8d4a6e1ff 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -422,9 +422,6 @@
unsigned long v;
- if ( s == NULL || *s == 0 )
- return 0;
-
for ( v = 0; sbitset( ddigits, *s ); s++ )
{
if ( v < ( FT_ULONG_MAX - 9 ) / 10 )
@@ -447,16 +444,14 @@
long v, neg;
- if ( s == NULL || *s == 0 )
- return 0;
-
/* Check for a minus sign. */
- neg = 0;
if ( *s == '-' )
{
s++;
- neg = 1;
+ neg = -1;
}
+ else
+ neg = 1;
for ( v = 0; sbitset( ddigits, *s ); s++ )
{
@@ -469,7 +464,7 @@
}
}
- return ( !neg ) ? v : -v;
+ return neg * v;
}
@@ -505,16 +500,14 @@
short v, neg;
- if ( s == NULL || *s == 0 )
- return 0;
-
/* Check for a minus. */
- neg = 0;
if ( *s == '-' )
{
s++;
- neg = 1;
+ neg = -1;
}
+ else
+ neg = 1;
for ( v = 0; sbitset( ddigits, *s ); s++ )
{
@@ -527,7 +520,7 @@
}
}
- return (short)( ( !neg ) ? v : -v );
+ return neg * v;
}
@@ -1845,7 +1838,7 @@
propid = ft_hash_str_lookup( name, font->internal );
- return propid ? ( font->props + *propid ) : 0;
+ return propid ? ( font->props + *propid ) : NULL;
}
From bfe793ccecb910608f3930a04f3b4307ccb4b3a0 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Wed, 22 Jan 2025 21:17:57 -0500
Subject: [PATCH 83/94] * src/bdf/bdflib.c (bdf_atous_): Remove unnecessary
checks.
---
src/bdf/bdflib.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 8d4a6e1ff..ec1c24c25 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -475,9 +475,6 @@
unsigned short v;
- if ( s == NULL || *s == 0 )
- return 0;
-
for ( v = 0; sbitset( ddigits, *s ); s++ )
{
if ( v < ( FT_USHORT_MAX - 9 ) / 10 )
From fdae51ccb0a0ea5c33695dda60eece9a2d9355ca Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 24 Jan 2025 22:03:00 -0500
Subject: [PATCH 84/94] * src/bdf/bdflib.c (BDF_SWIDTH_ADJ_): Remove clashing
flag and update.
---
src/bdf/bdflib.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index ec1c24c25..00b1ff3a8 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -628,8 +628,6 @@
#define BDF_BBX_ 0x0400U
#define BDF_BITMAP_ 0x0800U
-#define BDF_SWIDTH_ADJ_ 0x1000U
-
#define BDF_GLYPH_BITS_ ( BDF_GLYPH_ | \
BDF_ENCODING_ | \
BDF_SWIDTH_ | \
@@ -1213,7 +1211,7 @@
{
glyph->swidth = sw;
- p->flags |= BDF_SWIDTH_ADJ_;
+ FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG8 ));
}
}
@@ -1708,9 +1706,6 @@
p->font->bbx.height, p->maxas + p->maxds ));
p->font->bbx.height = (unsigned short)( p->maxas + p->maxds );
}
-
- if ( p->flags & BDF_SWIDTH_ADJ_ )
- FT_TRACE2(( "bdf_load_font: " ACMSG8 ));
}
}
From 00a1567a13538c50c429ff59c916dcaab692b787 Mon Sep 17 00:00:00 2001
From: Alexei Podtelezhnikov
Date: Fri, 24 Jan 2025 22:36:56 -0500
Subject: [PATCH 85/94] [bdf] Treat all comments uniformly.
* src/bdf/bdflib.c (bdf_parse_start_): Reject fonts with initial
COMMENTs.
(bdf_parse_properties_): Skip COMMENTs so that...
(bdf_add_property_): Do not make exception for COMMENT.
(bdf_parse_glyphs_, bdf_add_comments): Updated.
---
src/bdf/bdflib.c | 97 +++++++++++++++++++-----------------------------
1 file changed, 39 insertions(+), 58 deletions(-)
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 00b1ff3a8..852707807 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -70,7 +70,6 @@
{ "CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } },
{ "CHARSET_ENCODING", BDF_ATOM, 1, { 0 } },
{ "CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } },
- { "COMMENT", BDF_ATOM, 1, { 0 } },
{ "COPYRIGHT", BDF_ATOM, 1, { 0 } },
{ "DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } },
{ "DESTINATION", BDF_CARDINAL, 1, { 0 } },
@@ -646,6 +645,13 @@
FT_Error error = FT_Err_Ok;
+ /* Skip keyword COMMENT. */
+ comment += 7;
+ len -= 7;
+
+ if ( len == 0 )
+ goto Exit;
+
if ( FT_QRENEW_ARRAY( font->comments,
font->comments_len,
font->comments_len + len + 1 ) )
@@ -829,18 +835,13 @@
break;
}
- /* If the property happens to be a comment, then it doesn't need */
- /* to be added to the internal hash table. */
- if ( _bdf_strncmp( name, "COMMENT", 7 ) != 0 )
- {
- /* Add the property to the font property table. */
- error = ft_hash_str_insert( fp->name,
- font->props_used,
- font->internal,
- memory );
- if ( error )
- goto Exit;
- }
+ /* Add the property to the font property table. */
+ error = ft_hash_str_insert( fp->name,
+ font->props_used,
+ font->internal,
+ memory );
+ if ( error )
+ goto Exit;
font->props_used++;
@@ -959,17 +960,8 @@
if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
if ( p->flags & BDF_KEEP_COMMENTS )
- {
- line += 7;
- linelen -= 7;
+ error = bdf_add_comment_( font, line, linelen );
- if ( *line )
- {
- line++;
- linelen--;
- }
- error = bdf_add_comment_( p->font, line, linelen );
- }
goto Exit;
}
@@ -1283,6 +1275,7 @@
{
bdf_line_func_t_* next = (bdf_line_func_t_ *)call_data;
bdf_parse_t_* p = (bdf_parse_t_ *) client_data;
+ bdf_font_t* font = p->font;
FT_Error error = FT_Err_Ok;
@@ -1292,6 +1285,15 @@
FT_UNUSED( lineno );
+ /* Check for a comment. */
+ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
+ {
+ if ( p->flags & BDF_KEEP_COMMENTS )
+ error = bdf_add_comment_( font, line, linelen );
+
+ goto Exit;
+ }
+
/* Check for the end of the properties. */
if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
{
@@ -1304,21 +1306,9 @@
if ( _bdf_strncmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 )
goto Exit;
- /* Handle COMMENT fields and properties in a special way to preserve */
- /* the spacing. */
- if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
+ if ( bdf_is_atom_( line, linelen, &name, &value, p->font ) )
{
- name = value = line;
- value += 7;
- if ( *value )
- *value++ = 0;
- error = bdf_add_property_( p->font, name, value, lineno );
- if ( error )
- goto Exit;
- }
- else if ( bdf_is_atom_( line, linelen, &name, &value, p->font ) )
- {
- error = bdf_add_property_( p->font, name, value, lineno );
+ error = bdf_add_property_( font, name, value, lineno );
if ( error )
goto Exit;
}
@@ -1326,7 +1316,7 @@
{
value = bdf_strtok_( line, ' ' );
- error = bdf_add_property_( p->font, line, value, lineno );
+ error = bdf_add_property_( font, line, value, lineno );
if ( error )
goto Exit;
}
@@ -1354,30 +1344,12 @@
FT_UNUSED( lineno ); /* only used in debug mode */
- /* Check for a comment. This is done to handle those fonts that have */
- /* comments before the STARTFONT line for some reason. */
- if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
- {
- if ( p->flags & BDF_KEEP_COMMENTS && p->font )
- {
- line += 7;
- linelen -= 7;
- if ( *line )
- {
- line++;
- linelen--;
- }
- error = bdf_add_comment_( p->font, line, linelen );
- }
- goto Exit;
- }
-
+ /* The first line must be STARTFONT. */
+ /* Otherwise, reject the font immediately. */
if ( !( p->flags & BDF_START_ ) )
{
if ( _bdf_strncmp( line, "STARTFONT", 9 ) != 0 )
{
- /* we don't emit an error message since this code gets */
- /* explicitly caught one level higher */
error = FT_THROW( Missing_Startfont_Field );
goto Exit;
}
@@ -1418,6 +1390,15 @@
/* Point at the font being constructed. */
font = p->font;
+ /* Check for a comment. */
+ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
+ {
+ if ( p->flags & BDF_KEEP_COMMENTS )
+ error = bdf_add_comment_( font, line, linelen );
+
+ goto Exit;
+ }
+
/* Check for the start of the properties. */
if ( !( p->flags & BDF_PROPS_ ) &&
_bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
From aaa0b7881b17d60a922812213f006eeddaf96745 Mon Sep 17 00:00:00 2001
From: Craig White
Date: Sun, 28 Jan 2024 07:38:41 +0100
Subject: [PATCH 86/94] [base] Make `find_unicode_charmap` a base function.
This is needed for forthcoming changes in the auto-hinter.
* include/freetype/internal/ftobjs.h, src/base/ftobjs.c: Updated.
---
include/freetype/internal/ftobjs.h | 22 ++++++++++++++++++++++
src/base/ftobjs.c | 18 +++---------------
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index a1e93298f..136aa8106 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -275,6 +275,28 @@ FT_BEGIN_HEADER
FT_GlyphSlot slot,
FT_Render_Mode mode );
+
+ /**************************************************************************
+ *
+ * @Function:
+ * find_unicode_charmap
+ *
+ * @Description:
+ * This function finds a Unicode charmap, if there is one. And if there
+ * is more than one, it tries to favour the more extensive one, i.e., one
+ * that supports UCS-4 against those which are limited to the BMP (UCS-2
+ * encoding.)
+ *
+ * If a unicode charmap is found, `face->charmap` is set to it.
+ *
+ * This function is called from `open_face`, from `FT_Select_Charmap(...,
+ * FT_ENCODING_UNICODE)`, and also from `afadjust.c` in the 'autofit'
+ * module.
+ */
+ FT_BASE( FT_Error )
+ find_unicode_charmap( FT_Face face );
+
+
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 720a3f4b6..f55078c16 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1359,21 +1359,9 @@
}
- /**************************************************************************
- *
- * @Function:
- * find_unicode_charmap
- *
- * @Description:
- * This function finds a Unicode charmap, if there is one.
- * And if there is more than one, it tries to favour the more
- * extensive one, i.e., one that supports UCS-4 against those which
- * are limited to the BMP (said UCS-2 encoding.)
- *
- * This function is called from open_face() (just below), and also
- * from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).
- */
- static FT_Error
+ /* documentation is in ftobjs.h */
+
+ FT_BASE_DEF( FT_Error )
find_unicode_charmap( FT_Face face )
{
FT_CharMap* first;
From abf35d5c673320df3a449b7c0f432d20c29e876b Mon Sep 17 00:00:00 2001
From: Craig White
Date: Sun, 28 Jan 2024 17:27:39 +0100
Subject: [PATCH 87/94] [autofit] Add adjustment database.
* src/autofit/afadjust.c, src/autofit/afadjust.h: New files.
* include/freetype/internal/fttrace.h: Add 'afadjust' component.
* src/autofit/autofit.c: Include `afadjust.c`.
* src/autofit/rules.mk (AUTOF_DRV_SRC): Add `afadjust.c`.
---
include/freetype/internal/fttrace.h | 1 +
src/autofit/afadjust.c | 185 ++++++++++++++++++++++++++++
src/autofit/afadjust.h | 66 ++++++++++
src/autofit/autofit.c | 1 +
src/autofit/rules.mk | 3 +-
5 files changed, 255 insertions(+), 1 deletion(-)
create mode 100644 src/autofit/afadjust.c
create mode 100644 src/autofit/afadjust.h
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index f1ed81343..bf0b60796 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -159,6 +159,7 @@ FT_TRACE_DEF( gxvprop )
FT_TRACE_DEF( gxvtrak )
/* autofit components */
+FT_TRACE_DEF( afadjust )
FT_TRACE_DEF( afcjk )
FT_TRACE_DEF( afglobal )
FT_TRACE_DEF( afhints )
diff --git a/src/autofit/afadjust.c b/src/autofit/afadjust.c
new file mode 100644
index 000000000..d7812a121
--- /dev/null
+++ b/src/autofit/afadjust.c
@@ -0,0 +1,185 @@
+/****************************************************************************
+ *
+ * afadjust.c
+ *
+ * Auto-fitter routines to adjust components based on charcode (body).
+ *
+ * Copyright (C) 2023-2024 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Craig White .
+ *
+ * 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 "afadjust.h"
+
+#include
+#include
+#include
+#include
+
+#define AF_ADJUSTMENT_DATABASE_LENGTH \
+ ( sizeof ( adjustment_database ) / \
+ sizeof ( adjustment_database[0] ) )
+
+#undef FT_COMPONENT
+#define FT_COMPONENT afadjust
+
+
+ /*
+ All entries in this list must be sorted by ascending Unicode code
+ points. The table entries are 3 numbers consisting of:
+
+ - Unicode code point.
+ - The vertical adjustment type. This should be one of the enum
+ constants in `AF_VerticalSeparationAdjustmentType`.
+ - Value 1 if the topmost contour is a tilde and should be prevented from
+ flattening, and 0 otherwise.
+ */
+ FT_LOCAL_ARRAY_DEF( AF_AdjustmentDatabaseEntry )
+ adjustment_database[] =
+ {
+ { 0x21, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ! */
+ { 0x69, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* i */
+ { 0x6A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* j */
+
+ { 0xA1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ¡ */
+ { 0xBF, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ¿ */
+
+ { 0xC0, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* À */
+ { 0xC1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Á */
+ { 0xC2, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Â */
+ { 0xC3, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* Ã */
+ { 0xC8, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* È */
+ { 0xC9, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* É */
+ { 0xCA, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ê */
+ { 0xCC, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ì */
+ { 0xCD, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Í */
+ { 0xCE, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Î */
+
+ { 0xD1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* Ñ */
+ { 0xD2, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ò */
+ { 0xD3, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ó */
+ { 0xD4, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ô */
+ { 0xD5, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* Õ */
+ { 0xD9, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ù */
+ { 0xDA, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ú */
+ { 0xDB, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Û */
+ { 0xDD, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ý */
+
+ { 0xE0, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* à */
+ { 0xE1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* á */
+ { 0xE2, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* â */
+ { 0xE3, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* ã */
+ { 0xE8, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* è */
+ { 0xE9, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* é */
+ { 0xEA, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ê */
+ { 0xEC, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ì */
+ { 0xED, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* í */
+ { 0xEE, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* î */
+
+ { 0xF1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* ñ */
+ { 0xF2, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ò */
+ { 0xF3, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ó */
+ { 0xF4, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ô */
+ { 0xF5, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* õ */
+ { 0xF9, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ù */
+ { 0xFA, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ú */
+ { 0xFB, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* û */
+ { 0xFD, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ý */
+
+ { 0x100, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ā */
+ { 0x101, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ā */
+ { 0x102, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ă */
+ { 0x103, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ă */
+ { 0x106, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ć */
+ { 0x107, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ć */
+ { 0x108, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĉ */
+ { 0x109, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĉ */
+ { 0x10A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ċ */
+ { 0x10B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ċ */
+ { 0x10C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Č */
+ { 0x10D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* č */
+ { 0x10E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ď */
+
+ { 0x112, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ē */
+ { 0x113, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ē */
+ { 0x114, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĕ */
+ { 0x115, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĕ */
+ { 0x116, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ė */
+ { 0x117, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ė */
+ { 0x11A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ě */
+ { 0x11B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ě */
+ { 0x11C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĝ */
+ { 0x11D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĝ */
+ { 0x11E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ğ */
+ { 0x11F, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ğ */
+
+ { 0x120, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ġ */
+ { 0x121, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ġ */
+ { 0x123, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ģ */
+ { 0x124, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĥ */
+ { 0x125, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĥ */
+ { 0x128, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* Ĩ */
+ { 0x129, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* ĩ */
+ { 0x12A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ī */
+ { 0x12B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ī */
+ { 0x12C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĭ */
+ { 0x12D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĭ */
+ { 0x12F, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* į */
+
+ { 0x130, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* İ */
+ { 0x133, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ij */
+ { 0x134, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĵ */
+ { 0x135, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĵ */
+ { 0x139, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ĺ */
+ { 0x13A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ĺ */
+
+ { 0x143, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ń */
+ { 0x144, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ń */
+ { 0x147, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ň */
+ { 0x148, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ň */
+ { 0x14C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ō */
+ { 0x14D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ō */
+ { 0x14E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŏ */
+ { 0x14F, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŏ */
+
+ { 0x154, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŕ */
+ { 0x155, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŕ */
+ { 0x158, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ř */
+ { 0x159, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ř */
+ { 0x15A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ś */
+ { 0x15B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ś */
+ { 0x15C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŝ */
+ { 0x15D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŝ */
+
+ { 0x160, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Š */
+ { 0x161, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* š */
+ { 0x164, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ť */
+ { 0x168, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* Ũ */
+ { 0x169, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1 }, /* ũ */
+ { 0x16A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ū */
+ { 0x16B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ū */
+ { 0x16C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŭ */
+ { 0x16D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŭ */
+
+ { 0x174, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŵ */
+ { 0x175, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŵ */
+ { 0x176, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ŷ */
+ { 0x177, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ŷ */
+ { 0x179, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ź */
+ { 0x17A, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ź */
+ { 0x17B, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ż */
+ { 0x17C, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* ż */
+ { 0x17D, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 }, /* Ž */
+ { 0x17E, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0 } /* ž */
+ };
+
+
+/* END */
diff --git a/src/autofit/afadjust.h b/src/autofit/afadjust.h
new file mode 100644
index 000000000..bee002a3e
--- /dev/null
+++ b/src/autofit/afadjust.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ *
+ * afadjust.h
+ *
+ * Auto-fitter routines to adjust components based on charcode (header).
+ *
+ * Copyright (C) 2023-2024 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Craig White .
+ *
+ * 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.
+ *
+ */
+
+
+#ifndef AFADJUST_H_
+#define AFADJUST_H_
+
+#include
+
+#include "afglobal.h"
+#include "aftypes.h"
+
+
+FT_BEGIN_HEADER
+
+
+ /* The type of adjustment that should be done to prevent cases where */
+ /* two parts of a character stacked vertically merge, even though they */
+ /* should be separate. */
+ typedef enum AF_VerticalSeparationAdjustmentType_
+ {
+ /* This means that the hinter should find the topmost contour and push */
+ /* it up until its lowest point is one pixel above the highest point */
+ /* not part of that contour. */
+ AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP,
+
+ /* This is the opposite direction. The hinter should find the */
+ /* bottommost contour and push it down until there is a one-pixel gap. */
+ AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN,
+
+ AF_VERTICAL_ADJUSTMENT_NONE
+
+ } AF_VerticalSeparationAdjustmentType;
+
+
+ typedef struct AF_AdjustmentDatabaseEntry_
+ {
+ FT_UInt32 codepoint;
+ AF_VerticalSeparationAdjustmentType vertical_separation_adjustment_type;
+ FT_Bool apply_tilde;
+
+ } AF_AdjustmentDatabaseEntry;
+
+
+FT_END_HEADER
+
+#endif /* AFADJUST_H_ */
+
+
+/* END */
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index de5ec7c7c..9d4540e0a 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -19,6 +19,7 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "ft-hb.c"
+#include "afadjust.c"
#include "afblue.c"
#include "afcjk.c"
#include "afdummy.c"
diff --git a/src/autofit/rules.mk b/src/autofit/rules.mk
index 682046f47..fb6265cee 100644
--- a/src/autofit/rules.mk
+++ b/src/autofit/rules.mk
@@ -28,7 +28,8 @@ AUTOF_COMPILE := $(CC) $(ANSIFLAGS) \
# AUTOF driver sources (i.e., C files)
#
-AUTOF_DRV_SRC := $(AUTOF_DIR)/afblue.c \
+AUTOF_DRV_SRC := $(AUTOF_DIR)/afadjust.c \
+ $(AUTOF_DIR)/afblue.c \
$(AUTOF_DIR)/afcjk.c \
$(AUTOF_DIR)/afdummy.c \
$(AUTOF_DIR)/afglobal.c \
From 36275cd1cd95ccb4c98c74b2807f67c060ad1db9 Mon Sep 17 00:00:00 2001
From: Craig White
Date: Sun, 28 Jan 2024 17:35:15 +0100
Subject: [PATCH 88/94] [autofit] Add code for reverse charmaps and adjustment
database lookup.
* src/autofit/aftypes.h (AF_ReverseMapEntry, AF_ReverseCharacterMap): New
structures.
* src/autofit/afadjust.c (af_adjustment_database_lookup,
af_reverse_character_map_entry_compare, af_reverse_character_map_lookup,
af_lookup_vertical_separation_type, af_lookup_tilde_correction_type,
af_reverse_character_map_expand, af_reverse_character_map_new,
af_reverse_character_map_done): New functions.
* src/autofit/afadjust.c: Updated.
---
src/autofit/afadjust.c | 253 +++++++++++++++++++++++++++++++++++++++++
src/autofit/afadjust.h | 20 ++++
src/autofit/aftypes.h | 21 ++++
3 files changed, 294 insertions(+)
diff --git a/src/autofit/afadjust.c b/src/autofit/afadjust.c
index d7812a121..c69960519 100644
--- a/src/autofit/afadjust.c
+++ b/src/autofit/afadjust.c
@@ -182,4 +182,257 @@
};
+ /* Helper function: get the adjustment database entry for a codepoint. */
+ static const AF_AdjustmentDatabaseEntry*
+ af_adjustment_database_lookup( FT_UInt32 codepoint )
+ {
+ /* Binary search for database entry */
+ FT_Int low = 0;
+ FT_Int high = AF_ADJUSTMENT_DATABASE_LENGTH - 1;
+
+
+ while ( high >= low )
+ {
+ FT_Int mid = ( low + high ) / 2;
+ FT_UInt32 mid_codepoint = adjustment_database[mid].codepoint;
+
+
+ if ( mid_codepoint < codepoint )
+ low = mid + 1;
+ else if ( mid_codepoint > codepoint )
+ high = mid - 1;
+ else
+ return &adjustment_database[mid];
+ }
+
+ return NULL;
+ }
+
+
+ /* `qsort` compare function for reverse character map. */
+ FT_COMPARE_DEF( FT_Int )
+ af_reverse_character_map_entry_compare( const void *a,
+ const void *b )
+ {
+ const AF_ReverseMapEntry entry_a = *((const AF_ReverseMapEntry *)a);
+ const AF_ReverseMapEntry entry_b = *((const AF_ReverseMapEntry *)b);
+
+
+ return entry_a.glyph_index < entry_b.glyph_index
+ ? -1
+ : entry_a.glyph_index > entry_b.glyph_index
+ ? 1
+ : 0;
+ }
+
+
+ static FT_UInt32
+ af_reverse_character_map_lookup( AF_ReverseCharacterMap map,
+ FT_Int glyph_index )
+ {
+ FT_Int low, high;
+ FT_Long length;
+
+
+ if ( !map )
+ return 0;
+
+ length = map->length;
+
+ /* Binary search for reverse character map entry. */
+ low = 0;
+ high = length - 1;
+
+ while ( high >= low )
+ {
+ FT_Int mid = ( high + low ) / 2;
+ FT_Int mid_glyph_index = map->entries[mid].glyph_index;
+
+
+ if ( glyph_index < mid_glyph_index )
+ high = mid - 1;
+ else if ( glyph_index > mid_glyph_index )
+ low = mid + 1;
+ else
+ return map->entries[mid].codepoint;
+ }
+
+ return 0;
+ }
+
+
+ FT_LOCAL_DEF( AF_VerticalSeparationAdjustmentType )
+ af_lookup_vertical_separation_type( AF_ReverseCharacterMap map,
+ FT_Int glyph_index )
+ {
+ FT_UInt32 codepoint = af_reverse_character_map_lookup( map,
+ glyph_index );
+
+ const AF_AdjustmentDatabaseEntry *entry =
+ af_adjustment_database_lookup( codepoint );
+
+
+ if ( !entry )
+ return AF_VERTICAL_ADJUSTMENT_NONE;
+
+ return entry->vertical_separation_adjustment_type;
+ }
+
+
+ /* Return 1 if tilde correction should be applied to the topmost */
+ /* contour, else 0. */
+ FT_LOCAL_DEF( FT_Bool )
+ af_lookup_tilde_correction_type( AF_ReverseCharacterMap map,
+ FT_Int glyph_index )
+ {
+ FT_UInt32 codepoint = af_reverse_character_map_lookup( map,
+ glyph_index );
+
+ const AF_AdjustmentDatabaseEntry *entry =
+ af_adjustment_database_lookup( codepoint );
+
+
+ if ( !entry )
+ return 0;
+
+ return entry->apply_tilde;
+ }
+
+
+ /* Prepare to add one more entry to the reverse character map. */
+ /* This is a helper function for `af_reverse_character_map_new`. */
+ static FT_Error
+ af_reverse_character_map_expand( AF_ReverseCharacterMap map,
+ FT_Long *capacity,
+ FT_Memory memory )
+ {
+ FT_Error error;
+
+
+ if ( map->length < *capacity )
+ return FT_Err_Ok;
+
+ if ( map->length == *capacity )
+ {
+ FT_Long new_capacity = *capacity + *capacity / 2;
+
+
+ if ( FT_RENEW_ARRAY( map->entries, map->length, new_capacity ) )
+ return error;
+
+ *capacity = new_capacity;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ af_reverse_character_map_new( AF_ReverseCharacterMap *map,
+ AF_FaceGlobals globals )
+ {
+ FT_Error error;
+
+ FT_Face face = globals->face;
+ FT_Memory memory = face->memory;
+
+ FT_CharMap old_charmap;
+
+ FT_Long capacity;
+
+
+ /* Search for a unicode charmap. */
+ /* If there isn't one, create a blank map. */
+
+ FT_TRACE4(( "af_reverse_character_map_new:"
+ " building reverse character map\n" ));
+
+ /* Back up `face->charmap` because `find_unicode_charmap` sets it. */
+ old_charmap = face->charmap;
+
+ if ( ( error = find_unicode_charmap( face ) ) )
+ goto Exit;
+
+ *map = NULL;
+ if ( FT_NEW( *map ) )
+ goto Exit;
+
+ /* Start with a capacity of 10 entries. */
+ capacity = 10;
+ ( *map )->length = 0;
+
+ if ( FT_NEW_ARRAY( ( *map )->entries, capacity ) )
+ goto Exit;
+
+ {
+ FT_UInt i;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int failed_lookups = 0;
+#endif
+
+
+ for ( i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ )
+ {
+ FT_UInt32 codepoint = adjustment_database[i].codepoint;
+ FT_Int glyph = FT_Get_Char_Index( face, codepoint );
+
+
+ if ( glyph == 0 )
+ {
+#ifdef FT_DEBUG_LEVEL_TRACE
+ failed_lookups++;
+#endif
+ continue;
+ }
+
+ error = af_reverse_character_map_expand( *map, &capacity, memory );
+ if ( error )
+ goto Exit;
+
+ ( *map )->length++;
+ ( *map )->entries[i].glyph_index = glyph;
+ ( *map )->entries[i].codepoint = codepoint;
+ }
+ }
+
+ ft_qsort( ( *map )->entries,
+ ( *map )->length,
+ sizeof ( AF_ReverseMapEntry ),
+ af_reverse_character_map_entry_compare );
+
+ FT_TRACE4(( " reverse character map built successfully"
+ " with %ld entries\n", (*map)->length ));
+
+ Exit:
+ face->charmap = old_charmap;
+
+ if ( error )
+ {
+ FT_TRACE4(( " error while building reverse character map."
+ " Using blank map.\n" ));
+
+ if ( *map )
+ FT_FREE( ( *map )->entries );
+
+ FT_FREE( *map );
+ *map = NULL;
+ return error;
+ }
+
+ return FT_Err_Ok;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ af_reverse_character_map_done( AF_ReverseCharacterMap map,
+ FT_Memory memory )
+ {
+ if ( map )
+ FT_FREE( map->entries );
+ FT_FREE( map );
+
+ return FT_Err_Ok;
+ }
+
+
/* END */
diff --git a/src/autofit/afadjust.h b/src/autofit/afadjust.h
index bee002a3e..37af7086c 100644
--- a/src/autofit/afadjust.h
+++ b/src/autofit/afadjust.h
@@ -58,6 +58,26 @@ FT_BEGIN_HEADER
} AF_AdjustmentDatabaseEntry;
+ FT_LOCAL( AF_VerticalSeparationAdjustmentType )
+ af_lookup_vertical_separation_type( AF_ReverseCharacterMap map,
+ FT_Int glyph_index );
+
+ FT_LOCAL( FT_Bool )
+ af_lookup_tilde_correction_type( AF_ReverseCharacterMap map,
+ FT_Int glyph_index );
+
+ /* Allocate and populate the reverse character map, */
+ /* using the character map within the face. */
+ FT_LOCAL( FT_Error )
+ af_reverse_character_map_new( AF_ReverseCharacterMap *map,
+ AF_FaceGlobals globals );
+
+ /* Free the reverse character map. */
+ FT_LOCAL( FT_Error )
+ af_reverse_character_map_done( AF_ReverseCharacterMap map,
+ FT_Memory memory );
+
+
FT_END_HEADER
#endif /* AFADJUST_H_ */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 27e4185e9..5d4aaa9ba 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -406,6 +406,27 @@ extern void* af_debug_hints_;
typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals;
+
+ /* Store a mapping from glyphs to unicode codepoints. */
+ /* See `afadjust.c` for details. */
+ typedef struct AF_ReverseMapEntry_
+ {
+ FT_Int glyph_index;
+ FT_UInt32 codepoint;
+
+ } AF_ReverseMapEntry;
+
+
+ typedef struct AF_ReverseCharacterMapRec_
+ {
+ FT_Long length;
+ AF_ReverseMapEntry *entries;
+
+ } AF_ReverseCharacterMapRec;
+
+ typedef struct AF_ReverseCharacterMapRec_* AF_ReverseCharacterMap;
+
+
/* This is the main structure that combines everything. Autofit modules */
/* specific to writing systems derive their structures from it, for */
/* example `AF_LatinMetrics'. */
From 03759a157a073ecde28e1e7a65921365db1e39e2 Mon Sep 17 00:00:00 2001
From: Craig White
Date: Mon, 29 Jan 2024 08:21:09 +0100
Subject: [PATCH 89/94] [autofit] Implement vertical separation adjustment.
* src/autofit/aflatin.c: Include `afadjust.h`.
(af_latin_metrics_init): Call `af_reverse_character_map_new`.
(af_latin_metrics_done): New function.
(af_move_contour_vertically, af_check_contour_horizontal_overlap,
af_glyph_hints_apply_vertical_separation_adjustments): New functions.
(af_latin_hints_apply): Call
`af_glyph_hints_apply_vertical_separation_adjustments`.
(af_latin_writing_system_class): Updated.
* src/autofit/aftypes.h (AF_StyleMetricsRec): Add `reverse_charmap` field.
---
src/autofit/aflatin.c | 320 +++++++++++++++++++++++++++++++++++++++++-
src/autofit/aftypes.h | 2 +
2 files changed, 321 insertions(+), 1 deletion(-)
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 87b56db61..5a48a47a1 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -22,6 +22,7 @@
#include "afglobal.h"
#include "aflatin.h"
#include "aferrors.h"
+#include "afadjust.h"
/**************************************************************************
@@ -1155,6 +1156,9 @@
af_latin_metrics_check_digits( metrics, face );
}
+ af_reverse_character_map_new( &metrics->root.reverse_charmap,
+ metrics->root.globals );
+
Exit:
face->charmap = oldmap;
return error;
@@ -1484,6 +1488,17 @@
}
+ FT_CALLBACK_DEF( void )
+ af_latin_metrics_done( AF_StyleMetrics metrics_ )
+ {
+ AF_LatinMetrics metrics = (AF_LatinMetrics)metrics_;
+
+
+ af_reverse_character_map_done( metrics->root.reverse_charmap,
+ metrics->root.globals->face->memory );
+ }
+
+
/* Scale global values in both directions. */
FT_LOCAL_DEF( void )
@@ -2737,6 +2752,304 @@
}
+#undef FT_COMPONENT
+#define FT_COMPONENT afadjust
+
+
+ static void
+ af_move_contour_vertically( AF_Point contour,
+ FT_Int movement )
+ {
+ AF_Point point = contour;
+ AF_Point first_point = point;
+
+
+ if ( point )
+ {
+ do
+ {
+ point->y += movement;
+ point = point->next;
+
+ } while ( point != first_point );
+ }
+ }
+
+
+ /* Return 1 if the given contour overlaps horizontally with the bounding */
+ /* box of all other contours combined. This is a helper for function */
+ /* `af_glyph_hints_apply_vertical_separation_adjustments`. */
+ static FT_Bool
+ af_check_contour_horizontal_overlap( AF_GlyphHints hints,
+ FT_Int contour_index )
+ {
+ FT_Pos contour_max_x = -32000;
+ FT_Pos contour_min_x = 32000;
+ FT_Pos others_max_x = -32000;
+ FT_Pos others_min_x = 32000;
+
+ FT_Int contour;
+
+ FT_Bool horizontal_overlap;
+
+
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point first_point = hints->contours[contour];
+ AF_Point p = first_point;
+
+
+ do
+ {
+ p = p->next;
+
+ if ( contour == contour_index )
+ {
+ if ( p->x < contour_min_x )
+ contour_min_x = p->x;
+ if ( p->x > contour_max_x )
+ contour_max_x = p->x;
+ }
+ else
+ {
+ if ( p->x < others_min_x )
+ others_min_x = p->x;
+ if ( p->x > others_max_x )
+ others_max_x = p->x;
+ }
+ } while ( p != first_point );
+ }
+
+ horizontal_overlap =
+ ( others_min_x <= contour_max_x && contour_max_x <= others_max_x ) ||
+ ( others_min_x <= contour_min_x && contour_min_x <= others_max_x ) ||
+ ( contour_max_x >= others_max_x && contour_min_x <= others_min_x );
+
+ return horizontal_overlap;
+ }
+
+
+ static void
+ af_glyph_hints_apply_vertical_separation_adjustments(
+ AF_GlyphHints hints,
+ AF_Dimension dim,
+ FT_Int glyph_index,
+ AF_ReverseCharacterMap reverse_charmap )
+ {
+ FT_TRACE4(( "Entering"
+ " af_glyph_hints_apply_vertical_separation_adjustments\n" ));
+
+ if ( dim != AF_DIMENSION_VERT )
+ return;
+
+ if ( af_lookup_vertical_separation_type( reverse_charmap,
+ glyph_index ) ==
+ AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP &&
+ hints->num_contours >= 2 )
+ {
+ FT_Int highest_contour = -1;
+ FT_Pos highest_min_y = 0;
+ FT_Pos current_min_y = 0;
+
+ FT_Int contour;
+ FT_Bool horizontal_overlap;
+ FT_Int adjustment_amount;
+
+ FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n"
+ " Applying vertical adjustment:"
+ " AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP\n" ));
+
+ /* Figure out which contour is the higher one by finding the one */
+ /* with the highest minimum y value. */
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point point = hints->contours[contour];
+ AF_Point first_point = point;
+
+
+ if ( !point )
+ continue;
+
+ current_min_y = point->y;
+
+ do
+ {
+ if ( point->y < current_min_y )
+ current_min_y = point->y;
+ point = point->next;
+
+ } while ( point != first_point );
+
+ if ( highest_contour == -1 || current_min_y > highest_min_y )
+ {
+ highest_min_y = current_min_y;
+ highest_contour = contour;
+ }
+ }
+
+ /* Check for a horizontal overlap between the top contour and the */
+ /* rest. If there is no overlap, do not adjust. */
+ horizontal_overlap =
+ af_check_contour_horizontal_overlap( hints, highest_contour );
+ if ( !horizontal_overlap )
+ {
+ FT_TRACE4(( " Top contour does not horizontally overlap"
+ " with other contours.\n"
+ " Skipping adjustment.\n" ));
+ return;
+ }
+
+ /* If there are any contours that have a maximum y coordinate */
+ /* greater than or equal to the minimum y coordinate of the */
+ /* previously found highest contour, bump the high contour up until */
+ /* the distance is one pixel. */
+ adjustment_amount = 0;
+
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point point;
+ AF_Point first_point;
+
+ FT_Pos max_y;
+
+
+ if ( contour == highest_contour )
+ continue;
+
+ point = hints->contours[contour];
+ first_point = point;
+ if ( !point )
+ continue;
+
+ max_y = point->y;
+ do
+ {
+ if ( point->y > max_y )
+ max_y = point->y;
+ point = point->next;
+
+ } while ( point != first_point );
+
+ if ( max_y >= highest_min_y - 64 )
+ adjustment_amount = 64 - ( highest_min_y - max_y );
+ }
+
+ if ( adjustment_amount > 64 )
+ FT_TRACE4(( " Calculated adjustment amount %d"
+ " was more than threshold of 64. Not adjusting\n",
+ adjustment_amount ));
+ else if ( adjustment_amount > 0 )
+ {
+ FT_TRACE4(( " Pushing top contour %d units up\n",
+ adjustment_amount ));
+
+ af_move_contour_vertically( hints->contours[highest_contour],
+ adjustment_amount );
+ }
+ }
+
+ else if ( af_lookup_vertical_separation_type( reverse_charmap,
+ glyph_index ) ==
+ AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN &&
+ hints->num_contours >= 2 )
+ {
+ FT_Int lowest_contour = -1;
+ FT_Pos lowest_max_y = 0;
+ FT_Pos current_max_y = 0;
+
+ FT_Int contour;
+ FT_Int adjustment_amount;
+
+
+ FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n"
+ " Applying vertical adjustment:"
+ " AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN\n" ));
+
+ /* Find lowest contour. */
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point point = hints->contours[contour];
+ AF_Point first_point = point;
+
+
+ if ( !point )
+ continue;
+
+ current_max_y = point->y;
+
+ do
+ {
+ if ( point->y > current_max_y )
+ current_max_y = point->y;
+ point = point->next;
+
+ } while ( point != first_point );
+
+ if ( lowest_contour == -1 || current_max_y < lowest_max_y )
+ {
+ lowest_max_y = current_max_y;
+ lowest_contour = contour;
+ }
+ }
+
+ adjustment_amount = 0;
+
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point point;
+ AF_Point first_point;
+
+ FT_Pos min_y;
+
+
+ if ( contour == lowest_contour )
+ continue;
+
+ point = hints->contours[contour];
+ first_point = point;
+ if ( !point )
+ continue;
+
+ min_y = point->y;
+ do
+ {
+ if ( point->y < min_y )
+ min_y = point->y;
+ point = point->next;
+
+ } while ( point != first_point );
+
+ if ( min_y <= lowest_max_y - 64 )
+ adjustment_amount = 64 - ( min_y - lowest_max_y );
+ }
+
+ if ( adjustment_amount > 64 )
+ FT_TRACE4(( " Calculated adjustment amount %d"
+ " was more than threshold of 64. Not adjusting\n",
+ adjustment_amount ));
+ else if ( adjustment_amount > 0 )
+ {
+ FT_TRACE4(( " Pushing bottom contour %d units down\n",
+ adjustment_amount ));
+
+ af_move_contour_vertically( hints->contours[lowest_contour],
+ -adjustment_amount );
+ }
+ }
+
+ else
+ FT_TRACE4(( "af_glyph_hints_apply_vertical_separation_adjustments:\n"
+ " No vertical adjustment needed\n" ));
+
+ FT_TRACE4(( "Exiting"
+ " af_glyph_hints_apply_vertical_separation_adjustments\n" ));
+ }
+
+
+#undef FT_COMPONENT
+#define FT_COMPONENT aflatin
+
+
/* Compute the snapped width of a given stem, ignoring very thin ones. */
/* There is a lot of voodoo in this function; changing the hard-coded */
/* parameters influence the whole hinting process. */
@@ -3604,6 +3917,11 @@
af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
+ af_glyph_hints_apply_vertical_separation_adjustments(
+ hints,
+ (AF_Dimension)dim,
+ glyph_index,
+ metrics->root.reverse_charmap );
}
}
@@ -3632,7 +3950,7 @@
(AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, /* style_metrics_init */
(AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, /* style_metrics_scale */
- (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */
+ (AF_WritingSystem_DoneMetricsFunc) af_latin_metrics_done, /* style_metrics_done */
(AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */
(AF_WritingSystem_InitHintsFunc) af_latin_hints_init, /* style_hints_init */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 5d4aaa9ba..259b555be 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -439,6 +439,8 @@ extern void* af_debug_hints_;
AF_FaceGlobals globals; /* to access properties */
+ AF_ReverseCharacterMap reverse_charmap;
+
} AF_StyleMetricsRec;
From aaf61efd2b0baa7e3142cebf1bba2ef895ec72fd Mon Sep 17 00:00:00 2001
From: Craig White
Date: Mon, 29 Jan 2024 08:32:21 +0100
Subject: [PATCH 90/94] [autofit] Add tilde-unflattening algorithm.
* src/autofit/aflatin.c (af_find_highest_contour,
af_remove_segments_containing_point,
af_latin_remove_tilde_points_from_edges, af_latin_stretch_tildes,
af_latin_align_tildes): New functions.
(af_latin_hints_apply): Call tilde-unflatting code if necessary.
---
src/autofit/aflatin.c | 358 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 358 insertions(+)
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 5a48a47a1..a75724f39 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -2776,6 +2776,300 @@
}
+ static FT_Int
+ af_find_highest_contour( AF_GlyphHints hints )
+ {
+ FT_Int highest_contour = -1;
+
+ FT_Pos highest_min_y = 0;
+ FT_Pos current_min_y = 0;
+
+ FT_Int contour;
+
+
+ for ( contour = 0; contour < hints->num_contours; contour++ )
+ {
+ AF_Point point = hints->contours[contour];
+ AF_Point first_point = point;
+
+
+ if ( !point )
+ continue;
+
+ current_min_y = point->y;
+
+ do
+ {
+ if ( point->y < current_min_y )
+ current_min_y = point->y;
+ point = point->next;
+
+ } while ( point != first_point );
+
+ if ( highest_contour == -1 || current_min_y > highest_min_y )
+ {
+ highest_min_y = current_min_y;
+ highest_contour = contour;
+ }
+ }
+
+ return highest_contour;
+ }
+
+
+ static void
+ af_remove_segments_containing_point( AF_GlyphHints hints,
+ AF_Point point )
+ {
+ AF_AxisHints axis = &hints->axis[AF_DIMENSION_VERT];
+ AF_Segment segments = axis->segments;
+
+ FT_UInt i;
+
+
+ for ( i = 0; i < axis->num_segments; i++ )
+ {
+ AF_Segment seg = &segments[i];
+ AF_Point p = seg->first;
+
+ FT_Bool remove = 0;
+
+
+ while ( 1 )
+ {
+ if ( p == point )
+ {
+ remove = 1;
+ break;
+ }
+
+ if ( p == seg->last )
+ break;
+
+ p = p->next;
+ }
+
+ if ( remove )
+ {
+ /* First, check the first and last segment of the edge. */
+ AF_Edge edge = seg->edge;
+
+
+ if ( edge->first == seg && edge->last == seg )
+ {
+ /* The edge only consists of the segment to be removed. */
+ /* Remove the edge. */
+ *edge = axis->edges[--axis->num_edges];
+ }
+ else
+ {
+ if ( edge->first == seg )
+ edge->first = seg->edge_next;
+
+ if ( edge->last == seg )
+ {
+ edge->last = edge->first;
+
+ while ( edge->last->edge_next != seg )
+ edge->last = edge->last->edge_next;
+ }
+ }
+
+ /* Now, delete the segment. */
+ *seg = axis->segments[--axis->num_segments];
+
+ i--; /* We have to check the new segment at this position. */
+ }
+ }
+ }
+
+
+ /* Remove all segments containing points on the tilde contour. */
+ static void
+ af_latin_remove_tilde_points_from_edges( AF_GlyphHints hints )
+ {
+ FT_Int highest_contour = af_find_highest_contour( hints );
+ AF_Point first_point = hints->contours[highest_contour];
+
+ AF_Point p = first_point;
+
+
+ do
+ {
+ p = p->next;
+ af_remove_segments_containing_point( hints, p );
+
+ } while ( p != first_point );
+ }
+
+
+ /*
+ The tilde-unflattening algorithm sometimes goes too far and makes an
+ unusually high tilde, where decreasing the ppem will increase the height
+ instead of a steady decrease in height as less pixels are used.
+
+ For example, the 'n tilde' glyph from 'Times New Roman', with forced
+ autofitting on, exhibits this behaviour in the font size range 16.5 to
+ 18 ppem.
+ */
+ static void
+ af_latin_stretch_tildes( AF_GlyphHints hints )
+ {
+ FT_Int highest_contour = af_find_highest_contour( hints );
+ AF_Point p = hints->contours[highest_contour];
+
+ AF_Point first_point = p;
+
+ FT_Pos min_y, max_y;
+ FT_Short min_fy, max_fy;
+
+ FT_Pos min_measurement;
+
+ FT_Pos height;
+ FT_Pos target_height;
+
+
+ min_y = max_y = p->y;
+ min_fy = max_fy = p->fy;
+
+ do
+ {
+ p = p->next;
+
+ if ( p->y < min_y )
+ min_y = p->y;
+ if ( p->y > max_y )
+ max_y = p->y;
+
+ if ( p->fy < min_fy )
+ min_fy = p->fy;
+ if ( p->fy > max_fy )
+ max_fy = p->fy;
+
+ } while ( p != first_point );
+
+ min_measurement = 32000;
+ do
+ {
+ p = p->next;
+
+ if ( !( p->flags & AF_FLAG_CONTROL ) &&
+ p->prev->y == p->y && p->next->y == p->y &&
+ p->y != min_y && p->y != max_y &&
+ p->prev->flags & AF_FLAG_CONTROL &&
+ p->next->flags & AF_FLAG_CONTROL )
+ {
+ /* This point could be a candidate. Find the next and previous */
+ /* on-curve points, and make sure they are both either above or */
+ /* below the point, then make the measurement. */
+ AF_Point prevOn = p->prev;
+ AF_Point nextOn = p->next;
+
+ FT_Pos measurement;
+
+
+ while ( prevOn->flags & AF_FLAG_CONTROL )
+ prevOn = prevOn->prev;
+ while ( nextOn->flags & AF_FLAG_CONTROL )
+ nextOn = nextOn->next;
+
+ if ( nextOn->y > p->y && prevOn->y > p->y )
+ measurement = p->y - min_y;
+ else if ( nextOn->y < p->y && prevOn->y < p->y )
+ measurement = max_y - p->y;
+ else
+ continue;
+
+ if ( measurement < min_measurement )
+ min_measurement = measurement;
+ }
+ } while ( p != first_point );
+
+ /* touch all points */
+ p = first_point;
+ do
+ {
+ p = p->next;
+ if ( !( p->flags & AF_FLAG_CONTROL ) )
+ p->flags |= AF_FLAG_TOUCH_Y;
+
+ } while ( p != first_point );
+
+ height = max_y - min_y;
+ target_height = min_measurement + 64;
+
+ if ( height >= target_height )
+ return;
+
+ p = first_point;
+ do
+ {
+ p = p->next;
+ p->y = ( ( p->y - min_y ) * target_height / height ) + min_y;
+ p->fy = ( ( p->fy - min_fy ) * target_height / height ) + min_fy;
+ p->oy = p->y;
+
+ } while ( p != first_point );
+ }
+
+
+ /*
+ As part of `af_latin_stretch_tildes`, all points in the tilde are marked
+ as touched, so the existing grid fitting will leave the tilde misaligned
+ with the grid.
+
+ This function moves the tilde contour down to be grid-fitted. We assume
+ that if moving the tilde down would cause it to touch or overlap another
+ countour, the vertical adjustment step will fix it.
+
+ Because the vertical adjustment step comes after all other grid-fitting
+ steps, the top edge of the contour under the tilde is usually aligned
+ with a horizontal grid line. The vertical gap enforced by the vertical
+ adjustment is exactly one pixel, so if the top edge of the contour below
+ the tilde is on a grid line, the resulting tilde contour will also be
+ grid-aligned.
+
+ But in cases where the gap is already big enough so that the vertical
+ adjustment does nothing, this function ensures that even without the
+ intervention of the vertical adjustment step, the tilde will be
+ grid-aligned.
+ */
+ static void
+ af_latin_align_tildes( AF_GlyphHints hints )
+ {
+ FT_Int highest_contour = af_find_highest_contour( hints );
+
+ AF_Point p = hints->contours[highest_contour];
+ AF_Point first_point = p;
+
+ FT_Pos min_y, max_y;
+ FT_Pos min_y_rounded;
+ FT_Pos delta;
+
+
+ do
+ {
+ p = p->next;
+ if ( p->y < min_y )
+ min_y = p->y;
+ if ( p->y > max_y )
+ max_y = p->y;
+
+ } while ( p != first_point );
+
+ // mid_y = ( min_y + max_y ) / 2;
+ min_y_rounded = FT_PIX_ROUND( min_y );
+ delta = min_y_rounded - min_y;
+
+ do
+ {
+ p = p->next;
+ p->y += delta;
+
+ } while ( p != first_point );
+ }
+
+
/* Return 1 if the given contour overlaps horizontally with the bounding */
/* box of all other contours combined. This is a helper for function */
/* `af_glyph_hints_apply_vertical_separation_adjustments`. */
@@ -2934,6 +3228,9 @@
adjustment_amount = 64 - ( highest_min_y - max_y );
}
+ FT_TRACE4(( " Calculated adjustment amount: %d\n",
+ adjustment_amount ));
+
if ( adjustment_amount > 64 )
FT_TRACE4(( " Calculated adjustment amount %d"
" was more than threshold of 64. Not adjusting\n",
@@ -3860,6 +4157,47 @@
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ /* Print the height of the topmost contour for debugging purposes. */
+ /* TODO: remove this once the tilde unflattening works. */
+ static void
+ af_latin_trace_height( FT_UInt num,
+ AF_GlyphHints hints )
+ {
+ AF_Point p = hints->contours[af_find_highest_contour(hints)];
+ AF_Point first_point = p;
+
+ FT_Pos min_y, max_y;
+
+
+ min_y = max_y = p->y;
+
+ do
+ {
+ p = p->next;
+ if ( !(p->flags & AF_FLAG_CONTROL) )
+ {
+ if ( p->y < min_y )
+ min_y = p->y;
+ if ( p->y > max_y )
+ max_y = p->y;
+ }
+
+ } while ( p != first_point );
+
+ FT_TRACE4(( "height %d: %ld\n", num, max_y - min_y ));
+ }
+#else
+ static void
+ af_latin_trace_height( FT_UInt num,
+ AF_GlyphHints hints )
+ {
+ FT_UNUSED( num );
+ FT_UNUSED( hints );
+ }
+#endif
+
+
/* Apply the complete hinting algorithm to a latin glyph. */
static FT_Error
@@ -3894,11 +4232,26 @@
if ( AF_HINTS_DO_VERTICAL( hints ) )
{
+ FT_Bool is_tilde = af_lookup_tilde_correction_type(
+ metrics->root.reverse_charmap, glyph_index );
+
+
+ if ( is_tilde )
+ {
+ af_latin_trace_height(0, hints );
+ af_latin_stretch_tildes( hints );
+ af_latin_align_tildes( hints );
+ af_latin_trace_height(1, hints );
+ }
+
axis = &metrics->axis[AF_DIMENSION_VERT];
error = af_latin_hints_detect_features( hints,
axis->width_count,
axis->widths,
AF_DIMENSION_VERT );
+ if ( is_tilde )
+ af_latin_remove_tilde_points_from_edges( hints );
+
if ( error )
goto Exit;
@@ -3914,14 +4267,19 @@
( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) )
{
af_latin_hint_edges( hints, (AF_Dimension)dim );
+ af_latin_trace_height(2, hints );
af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
+ af_latin_trace_height(3, hints );
af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
+ af_latin_trace_height(4, hints );
af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
+ af_latin_trace_height(5, hints );
af_glyph_hints_apply_vertical_separation_adjustments(
hints,
(AF_Dimension)dim,
glyph_index,
metrics->root.reverse_charmap );
+ af_latin_trace_height(6, hints );
}
}
From 2073452c43a159fe7240a3b7e52af96c39cec983 Mon Sep 17 00:00:00 2001
From: Craig White
Date: Mon, 29 Jan 2024 08:37:54 +0100
Subject: [PATCH 91/94] [autofit] Add GSUB table handling to reverse character
map generation.
If HarfBuzz is enabled, the reverse character map generation now considers
GSUB entries when looking for glyphs that correspond to a code point.
* src/autofit/afadjust.c (af_all_glyph_variants_helper,
af_all_glyph_variants) [FT_CONFIG_OPTION_USE_HARFBUZZ]: New functions.
(af_reverse_character_map_new) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Call new
code.
---
src/autofit/afadjust.c | 405 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 405 insertions(+)
diff --git a/src/autofit/afadjust.c b/src/autofit/afadjust.c
index c69960519..46745f9c8 100644
--- a/src/autofit/afadjust.c
+++ b/src/autofit/afadjust.c
@@ -327,6 +327,349 @@
}
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+
+ /*
+ Recursive algorithm to find all glyphs that a code point could turn into
+ from the 'GSUB' table.
+
+ buffer: a buffer containing only the input code point
+ feature_tag_pool: the current list of features under consideration
+ current_features: the current list of features being applied
+ num_features: length of current_features
+ result: the set of glyphs that the input code point can map to
+
+ The algorithm works by running the `hb_ot_shape_glyphs_closure` function
+ on different lists of features to check which features map the glyph onto
+ something different. This function returns the result of transforming a
+ glyph using a list of features as well as all intermediate forms if the
+ glyph was transformed multiple times.
+
+ With no features enabled, `hb_ot_shape_glyphs_closure` only returns the
+ glyph given by the cmap. This character is the first to be placed into
+ the result set.
+
+ Next, the algorithm tests the same lookup enabling one feature at a time
+ and check whether any of those features change the result.
+
+ If any new glyph variants are found this way, they are added to the
+ result set and the algorithm recurses, trying that feature in combination
+ with every other feature to look for further glyph variants.
+
+ Example:
+
+ suppose we have the following features in the GSUB table:
+
+ f1: a -> b
+ f2: b -> c
+ f3: d -> e
+
+ The algorithm takes the following steps to find all variants of 'a'.
+
+ - Add 'a' to the result.
+ - Look up with feature list {f1}, yielding {a, b}.
+ => Add 'b' to the result list, recurse.
+ - Look up with feature list {f1, f2}, yielding {a, b, c}.
+ => Add 'c' to the result list, recurse.
+ - Look up with feature list {f1, f2, f3}, yielding {a, b, c}.
+ => No new glyphs.
+ - Look up with feature list {f1, f3}, yielding {a, b}.
+ => No new glyphs.
+ - Look up with feature list {f2}, yielding {a}.
+ => No new glyphs.
+ - Look up with feature list {f3}, yielding {a}.
+ => No new glyphs.
+ */
+ static FT_Error
+ af_all_glyph_variants_helper( hb_font_t *font,
+ hb_buffer_t *buffer,
+ hb_set_t *feature_tag_pool,
+ hb_feature_t *current_features,
+ FT_UInt32 num_features,
+ hb_set_t* result )
+ {
+ FT_Error error;
+
+ hb_set_t *baseline_glyphs = NULL;
+ hb_set_t *new_glyphs = NULL;
+
+ hb_tag_t feature_tag;
+
+
+ /* Get the list of glyphs that are created by only transforming, */
+ /* based on the features in `current_features`. */
+ baseline_glyphs = hb_set_create();
+ if ( !hb_set_allocation_successful( baseline_glyphs ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ hb_ot_shape_glyphs_closure( font,
+ buffer,
+ current_features,
+ num_features,
+ baseline_glyphs );
+ if ( !hb_set_allocation_successful( baseline_glyphs ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ /* Add these baseline glyphs to the result. The baseline glyph set */
+ /* contains at least the glyph specified by the cmap. */
+ hb_set_union( result, baseline_glyphs );
+ if ( !hb_set_allocation_successful( result ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ if ( !hb_set_get_population( feature_tag_pool ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ /* Prepare for adding different features to `current_features` to */
+ /* check whether any of them have an effect of the glyphs we get from */
+ /* `hb_ot_shape_glyphs_closure`. */
+ current_features[num_features].start = HB_FEATURE_GLOBAL_START;
+ current_features[num_features].end = HB_FEATURE_GLOBAL_END;
+ current_features[num_features].value = 1; /* enable the feature */
+
+ /*
+ Quote from the HarfBuzz documentation about the `value` attribute:
+
+ 0 disables the feature, non-zero (usually 1) enables the feature.
+ For features implemented as lookup type 3 (like 'salt') the value is
+ a one-based index into the alternates. This algorithm does not
+ handle these lookup type 3 cases fully.
+ */
+
+ new_glyphs = hb_set_create();
+ if ( !hb_set_allocation_successful( new_glyphs ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ feature_tag = HB_SET_VALUE_INVALID;
+
+ while ( hb_set_next( feature_tag_pool, &feature_tag ) )
+ {
+ hb_set_clear( new_glyphs );
+
+ current_features[num_features].tag = feature_tag;
+
+ hb_ot_shape_glyphs_closure ( font,
+ buffer,
+ current_features,
+ num_features + 1,
+ new_glyphs );
+ if ( !hb_set_allocation_successful( new_glyphs ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ hb_set_subtract( new_glyphs, result );
+
+ /* `new_glyphs` now contains all glyphs that appeared in the result */
+ /* of `hb_ot_shape_glyphs_closure` that haven't already been */
+ /* accounted for in the result. If this contains any glyphs, we */
+ /* also need to try this feature in combination with other features */
+ /* by recursing. */
+ if ( hb_set_get_population( new_glyphs ) != 0 )
+ {
+ /* Remove this feature from the feature pool temporarily so that */
+ /* a later recursion won't try it. */
+ hb_set_del( feature_tag_pool, feature_tag );
+
+ error = af_all_glyph_variants_helper( font,
+ buffer,
+ feature_tag_pool,
+ current_features,
+ num_features + 1,
+ result );
+ if ( error )
+ goto Exit;
+
+ /* Add back the feature we removed. */
+ hb_set_add( feature_tag_pool, feature_tag );
+ if ( !hb_set_allocation_successful( feature_tag_pool ) )
+ return FT_Err_Out_Of_Memory;
+ }
+ }
+
+ Exit:
+ hb_set_destroy( baseline_glyphs );
+ hb_set_destroy( new_glyphs );
+ return FT_Err_Ok;
+ }
+
+
+ static FT_Error
+ af_all_glyph_variants( FT_Face face,
+ hb_font_t *hb_font,
+ FT_UInt32 codepoint,
+ hb_set_t* result )
+ {
+ FT_Error error;
+
+ FT_Memory memory = face->memory;
+ hb_face_t *hb_face = hb_font_get_face( hb_font );
+
+ FT_Bool feature_list_done;
+ unsigned int start_offset;
+
+ /* The set of all feature tags in the font. */
+ hb_set_t *feature_tags = hb_set_create();
+ hb_set_t *type_3_lookup_indices = hb_set_create();
+ hb_buffer_t *codepoint_buffer = hb_buffer_create();
+ hb_codepoint_t *type_3_alternate_glyphs_buffer;
+
+ hb_feature_t *feature_buffer;
+
+ /* List of features containing type 3 lookups. */
+ hb_tag_t feature_list[] =
+ {
+ HB_TAG( 's', 'a', 'l', 't' ),
+ HB_TAG( 's', 'w', 's', 'h' ),
+ HB_TAG( 'n', 'a', 'l', 't' ),
+ HB_TAG_NONE
+ };
+
+ hb_codepoint_t lookup_index;
+ FT_UInt base_glyph_index;
+
+
+ if ( !hb_set_allocation_successful( feature_tags ) ||
+ !hb_buffer_allocation_successful( codepoint_buffer ) ||
+ !hb_set_allocation_successful ( type_3_lookup_indices ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+ /* Populate `feature_tags` using the output of */
+ /* `hb_ot_layout_table_get_feature_tags`. */
+ feature_list_done = 0;
+ start_offset = 0;
+
+ while ( !feature_list_done )
+ {
+ unsigned int feature_count = 20;
+ hb_tag_t tags[20];
+
+ unsigned int i;
+
+
+ hb_ot_layout_table_get_feature_tags( hb_face,
+ HB_OT_TAG_GSUB,
+ start_offset,
+ &feature_count,
+ tags );
+ start_offset += 20;
+ if ( feature_count < 20 )
+ feature_list_done = 1;
+
+ for ( i = 0; i < feature_count; i++ )
+ hb_set_add( feature_tags, tags[i] );
+
+ if ( !hb_set_allocation_successful( feature_tags ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+ }
+
+ /* Make a buffer only consisting of the given code point. */
+ if ( !hb_buffer_pre_allocate( codepoint_buffer, 1 ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+ hb_buffer_set_direction( codepoint_buffer, HB_DIRECTION_LTR );
+ hb_buffer_add( codepoint_buffer, codepoint, 0 );
+
+ /* The array of features that is used by the recursive part has at */
+ /* most as many entries as there are features, so make the length */
+ /* equal to the length of `feature_tags`. */
+ if ( ( error = FT_NEW_ARRAY( feature_buffer,
+ hb_set_get_population( feature_tags ) ) ) )
+ goto Exit;
+
+ error = af_all_glyph_variants_helper( hb_font,
+ codepoint_buffer,
+ feature_tags,
+ feature_buffer,
+ 0,
+ result );
+ if ( error )
+ goto Exit;
+
+ /* Add the alternative glyph forms that come from features using
+ type 3 lookups.
+
+ This file from gtk was very useful in figuring out my approach:
+
+ https://gitlab.gnome.org/GNOME/gtk/-/blob/40f20fee3d8468749dfb233a6f95921c765c1163/gtk/gtkfontchooserwidget.c#L2100
+ */
+ hb_ot_layout_collect_lookups( hb_face,
+ HB_OT_TAG_GSUB,
+ NULL,
+ NULL,
+ feature_list,
+ type_3_lookup_indices );
+ if ( !hb_set_allocation_successful( type_3_lookup_indices ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto Exit;
+ }
+
+#define MAX_ALTERNATES 100 /* ad-hoc value */
+
+ if ( ( error = FT_NEW_ARRAY( type_3_alternate_glyphs_buffer,
+ MAX_ALTERNATES ) ) )
+ goto Exit;
+
+ lookup_index = HB_SET_VALUE_INVALID;
+ base_glyph_index = FT_Get_Char_Index( face, codepoint );
+
+ if ( base_glyph_index )
+ {
+ while ( hb_set_next( type_3_lookup_indices, &lookup_index ) )
+ {
+ unsigned alternate_count = MAX_ALTERNATES;
+ unsigned i;
+
+
+ hb_ot_layout_lookup_get_glyph_alternates(
+ hb_face,
+ lookup_index,
+ base_glyph_index,
+ 0,
+ &alternate_count,
+ type_3_alternate_glyphs_buffer );
+
+ for ( i = 0; i < alternate_count; i++ )
+ hb_set_add( result, type_3_alternate_glyphs_buffer[i] );
+ }
+ }
+
+ Exit:
+ hb_set_destroy( feature_tags );
+ hb_buffer_destroy( codepoint_buffer );
+ FT_FREE( feature_buffer );
+ FT_FREE( type_3_alternate_glyphs_buffer );
+
+ return error;
+ }
+
+#endif /*FT_CONFIG_OPTION_USE_HARFBUZZ*/
+
+
FT_LOCAL_DEF( FT_Error )
af_reverse_character_map_new( AF_ReverseCharacterMap *map,
AF_FaceGlobals globals )
@@ -364,6 +707,66 @@
if ( FT_NEW_ARRAY( ( *map )->entries, capacity ) )
goto Exit;
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+
+ {
+ hb_font_t *hb_font = globals->hb_font;
+ hb_set_t *result_set = hb_set_create();
+
+ FT_ULong i;
+
+
+ if ( !hb_set_allocation_successful( result_set ) )
+ {
+ error = FT_Err_Out_Of_Memory;
+ goto harfbuzz_path_Exit;
+ }
+
+ /* Find all glyph variants of the code points, then make an entry */
+ /* from the glyph to the code point for each one. */
+ for ( i = 0; i < AF_ADJUSTMENT_DATABASE_LENGTH; i++ )
+ {
+ FT_UInt32 codepoint = adjustment_database[i].codepoint;
+
+ hb_codepoint_t glyph;
+
+
+ error = af_all_glyph_variants( face,
+ hb_font,
+ codepoint,
+ result_set );
+ if ( error )
+ goto harfbuzz_path_Exit;
+
+ glyph = HB_SET_VALUE_INVALID;
+
+ while ( hb_set_next( result_set, &glyph ) )
+ {
+ FT_Long insert_point;
+
+
+ error = af_reverse_character_map_expand( *map, &capacity, memory );
+ if ( error )
+ goto harfbuzz_path_Exit;
+
+ insert_point = ( *map )->length;
+
+ ( *map )->length++;
+ ( *map )->entries[insert_point].glyph_index = glyph;
+ ( *map )->entries[insert_point].codepoint = codepoint;
+ }
+
+ hb_set_clear( result_set );
+ }
+
+ harfbuzz_path_Exit:
+ hb_set_destroy( result_set );
+ if ( error )
+ goto Exit;
+ }
+
+#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
{
FT_UInt i;
#ifdef FT_DEBUG_LEVEL_TRACE
@@ -395,6 +798,8 @@
}
}
+#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
ft_qsort( ( *map )->entries,
( *map )->length,
sizeof ( AF_ReverseMapEntry ),
From e8e944f5db516584cf401963ed275cb02d744ab8 Mon Sep 17 00:00:00 2001
From: Werner Lemberg
Date: Mon, 29 Jan 2024 08:59:18 +0100
Subject: [PATCH 92/94] * docs/CHANGES: Mention Craig's GSoC 2023 project.
---
docs/CHANGES | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/docs/CHANGES b/docs/CHANGES
index 1e0977b36..498caebb9 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -25,6 +25,21 @@ CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Aug-11)
usage. It is also an additional means to protect against
malformed input.
+ - The auto-hinter got new abilities.
+
+ . It can now better separate accents from base characters at small
+ sizes by artificially moving accents up if necessary.
+
+ . Tilde characters get vertically stretched at small sizes so that
+ they don't degenerate to horizontal lines.
+
+ Both features use a database, which currently has entries for
+ Unicode characters lower than U+0180. FreeType needs to access or
+ construct a proper Unicode character map from a given font to make
+ this work.
+
+ This was Craig White's GSoC 2023 project.
+
II. IMPORTANT BUG FIXES
From bc28bd77fc7458e76f75119e690d5dac23770e97 Mon Sep 17 00:00:00 2001
From: Craig White
Date: Sun, 20 Oct 2024 05:24:16 -0400
Subject: [PATCH 93/94] Rework autofitter to center tildes if they are small.
---
src/autofit/aflatin.c | 66 ++++++++++++++++++++++++++++++++-----------
1 file changed, 50 insertions(+), 16 deletions(-)
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index a75724f39..60613d25c 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -2984,18 +2984,20 @@
min_measurement = measurement;
}
} while ( p != first_point );
-
- /* touch all points */
- p = first_point;
- do
- {
- p = p->next;
- if ( !( p->flags & AF_FLAG_CONTROL ) )
- p->flags |= AF_FLAG_TOUCH_Y;
-
- } while ( p != first_point );
-
height = max_y - min_y;
+
+ if ( height < 256 ) {
+ /* touch all points */
+ p = first_point;
+ do
+ {
+ p = p->next;
+ if ( !( p->flags & AF_FLAG_CONTROL ) )
+ p->flags |= AF_FLAG_TOUCH_Y;
+
+ } while ( p != first_point );
+ }
+
target_height = min_measurement + 64;
if ( height >= target_height )
@@ -3043,7 +3045,6 @@
AF_Point first_point = p;
FT_Pos min_y, max_y;
- FT_Pos min_y_rounded;
FT_Pos delta;
@@ -3057,10 +3058,17 @@
} while ( p != first_point );
- // mid_y = ( min_y + max_y ) / 2;
- min_y_rounded = FT_PIX_ROUND( min_y );
- delta = min_y_rounded - min_y;
+ // If the tilde is less than 2 pixels tall, snap the center of it to
+ // the grid instead of the bottom to improve readability
+ //
+ FT_Pos min_y_rounded = FT_PIX_ROUND( min_y );
+ delta = min_y_rounded - min_y;
+ FT_Pos height = max_y - min_y;
+ if ( height < 64*3 ) {
+ delta += ( FT_PIX_ROUND( height ) - height ) / 2;
+ }
+ p = first_point;
do
{
p = p->next;
@@ -3193,6 +3201,17 @@
return;
}
+ AF_Point point = hints->contours[highest_contour];
+ AF_Point first_point = point;
+ FT_Pos highest_max_y = point->y;
+ do
+ {
+ if ( point->y > highest_max_y )
+ {
+ highest_max_y = point->y;
+ }
+ } while ( point != first_point );
+
/* If there are any contours that have a maximum y coordinate */
/* greater than or equal to the minimum y coordinate of the */
/* previously found highest contour, bump the high contour up until */
@@ -3225,7 +3244,20 @@
} while ( point != first_point );
if ( max_y >= highest_min_y - 64 )
+ {
adjustment_amount = 64 - ( highest_min_y - max_y );
+ }
+ }
+
+ FT_TRACE4(( " Calculated adjustment amount 1: %d\n",
+ adjustment_amount ));
+
+
+ if ( adjustment_amount > 0 && ( highest_max_y - highest_min_y ) < 128 )
+ {
+ adjustment_amount += ( 128 - ( highest_max_y - highest_min_y ) ) / 2;
+ FT_TRACE4(( " Additional push: %d\n",
+ ( 128 - ( highest_max_y - highest_min_y ) ) / 2 ));
}
FT_TRACE4(( " Calculated adjustment amount: %d\n",
@@ -4186,6 +4218,7 @@
} while ( p != first_point );
FT_TRACE4(( "height %d: %ld\n", num, max_y - min_y ));
+ FT_TRACE4(( "min y %d: %ld\n", num, min_y ));
}
#else
static void
@@ -4240,6 +4273,7 @@
{
af_latin_trace_height(0, hints );
af_latin_stretch_tildes( hints );
+ af_latin_trace_height(33, hints );
af_latin_align_tildes( hints );
af_latin_trace_height(1, hints );
}
@@ -4279,7 +4313,7 @@
(AF_Dimension)dim,
glyph_index,
metrics->root.reverse_charmap );
- af_latin_trace_height(6, hints );
+ af_latin_trace_height(99, hints );
}
}
From cb432ad21e53062253114f950af38ae829d9e45a Mon Sep 17 00:00:00 2001
From: Craig White
Date: Mon, 27 Jan 2025 04:40:31 -0500
Subject: [PATCH 94/94] [autofit] fix vertical separation bug and improve style
* src/autofit/afadjust.c (af_glyph_hints_apply_vertical_separation_adjustments)
improve code formatting, remove redundant trace calls,
fix bug causing vertical separation to fail for some small sizes.
(af_latin_hints_apply) make numbering of trace calls more logical.
---
src/autofit/aflatin.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 60613d25c..60c19fb20 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -3201,8 +3201,8 @@
return;
}
- AF_Point point = hints->contours[highest_contour];
- AF_Point first_point = point;
+ AF_Point point = hints->contours[highest_contour];
+ AF_Point first_point = point;
FT_Pos highest_max_y = point->y;
do
{
@@ -3249,11 +3249,7 @@
}
}
- FT_TRACE4(( " Calculated adjustment amount 1: %d\n",
- adjustment_amount ));
-
-
- if ( adjustment_amount > 0 && ( highest_max_y - highest_min_y ) < 128 )
+ if ( adjustment_amount > 0 && ( highest_max_y - highest_min_y ) < 128 && ( highest_max_y - highest_min_y ) > 100)
{
adjustment_amount += ( 128 - ( highest_max_y - highest_min_y ) ) / 2;
FT_TRACE4(( " Additional push: %d\n",
@@ -4271,11 +4267,11 @@
if ( is_tilde )
{
- af_latin_trace_height(0, hints );
+ af_latin_trace_height( 10, hints );
af_latin_stretch_tildes( hints );
- af_latin_trace_height(33, hints );
+ af_latin_trace_height( 11, hints );
af_latin_align_tildes( hints );
- af_latin_trace_height(1, hints );
+ af_latin_trace_height( 12, hints );
}
axis = &metrics->axis[AF_DIMENSION_VERT];
@@ -4301,19 +4297,19 @@
( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) )
{
af_latin_hint_edges( hints, (AF_Dimension)dim );
- af_latin_trace_height(2, hints );
+ af_latin_trace_height( 1, hints );
af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
- af_latin_trace_height(3, hints );
+ af_latin_trace_height( 2, hints );
af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
- af_latin_trace_height(4, hints );
+ af_latin_trace_height( 3, hints );
af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
- af_latin_trace_height(5, hints );
+ af_latin_trace_height( 4, hints );
af_glyph_hints_apply_vertical_separation_adjustments(
hints,
(AF_Dimension)dim,
glyph_index,
metrics->root.reverse_charmap );
- af_latin_trace_height(99, hints );
+ af_latin_trace_height(5, hints );
}
}