The main problems
-----------------
o If FT_STROKER_LINEJOIN_BEVEL was specified, unlimited miter
joins (not bevel joins) were generated. Indeed, the meanings of
`miter' and `bevel' were incorrectly reversed (consistently) in
both the code and comments.
o The way bevel joins were constructed (whether specified
explicitly, or created as a result of exceeding the miter limit)
did not match what is required for stroked text in PostScript or
PDF.
The main fixes
--------------
o The behaviour of FT_STROKER_LINEJOIN_BEVEL has been corrected.
o A new line join style, FT_STROKER_LINEJOIN_MITER_FIXED, has been
introduced to support PostScript and PDF miter joins.
o FT_STROKER_LINEJOIN_MITER_VARIABLE has been introduced as an
alias for FT_STROKER_LINEJOIN_MITER.
Additionally, a variety of stroking errors have been fixed. These
would cause various artifacts (including points `at infinity'),
especially when stroking poor quality fonts.
See
http://lists.gnu.org/archive/html/freetype-devel/2011-07/msg00001.html
for example documents. The FreeType stroker now produces results
very similar to that produced by GhostScript and Distiller for these
fonts.
Other problems
--------------
The following problems have been resolved:
o Inside corners could be generated incorrectly. Intersecting the
inside corner could cause a missing triangular area and other
effects.
The intersection point can only be used if the join is between
two lines and both lines are long enough. The `optimization'
condition in `ft_stroker_inside' has been corrected; this
requires the line length to be passed into various functions and
stored in `FT_StrokerRec'.
o Incorrect cubic curves could be generated. The angle
calculations in `FT_Stroker_CubicTo' have been corrected to
handle the case of the curve crossing the +/-PI direction.
o If the border radius was greater than the radius of curvature of
a curve, then the negative sector would end up outside (not
inside) the border. This situation is now recognized and the
negative sector is circumnavigated in the opposite direction.
(If round line joins are being used, this code is disabled
because the line join will always cover the negative sector.)
o When a curve is split, the arcs may not join smoothly (especially
if the curve turns sharply back on itself). Changes in
direction between adjacent arcs were not handled. A round
corner is now added if the deviation from one arc to the next is
greater than a suitable threshold.
o The current direction wasn't retained if a the outline contained
a zero length lineto or a curve that was determined to be
`basically a point'. This could cause a spurious join to be
added.
o Cubics with close control points could be mishandled. All eight
cases are now distinguished correctly.
Other improvements
------------------
o Borders for cubic curves could be too `flat'.
FT_SMALL_CUBIC_THRESHOLD has been reduced a little to prevent
this.
o The handling and use of movable points has been simplified a
little.
o Various values are now computed only if the results are actually
needed.
o The directions of the outer and inner borders have been swapped,
as recommended by Graham Asher.
* src/base/ftstroke.c: Revised.
* include/freetype/ftstroke.h: Updated.
Passing uninitialized pointer to the buffer allocator is
not problematic theoretically (as far as the returned
pointer is checked before writing), but g++4.6 dislikes
it and warns by -Wuninitialized. Initialize them by NULL.
* src/base/ftobjs.c (FT_Stream_New): Init `stream'.
(new_memory_stream): Ditto.
(FT_New_GlyphSlot): Init `slot'.
(FT_CMap_New): Init `cmap'.
(open_face_PS_from_sfnt_stream): Init `sfnt_ps'.
(Mac_Read_POST_Resource): Init `pfb_data'.
(Mac_Read_sfnt_Resource): Init `sfnt_data'.
* src/base/ftrfork.c (FT_Raccess_Get_DataOffsets):
Init `offsets_internal' and `ref'.
(raccess_guess_darwin_hfsplus): Init `newpath'.
(raccess_guess_darwin_newvfs): Ditto.
* src/base/ftbitmap.c (ft_bitmap_assure_buffer):
Init `buffer'.
* src/base/ftstroke.c (FT_Stroker_New): Init `stroker'.
Previously, signed integers were converted to unsigned integers, but
this can fail because of sign extension. For example, 0xa344a1eb
becomes 0xffffffffa344a1eb.
We now do the reverse which is always correct because the integer
size is the same during the cast from unsigned to signed.
* include/freetype/internal/ftstream.h, src/base/ftstream.c
(FT_Stream_Get*): Replace with...
(FT_Stream_GetU*): Functions which read unsigned integers.
Update all macros accordingly.
* src/gzip/ftgzip.c (ft_gzip_get_uncompressed_size): Updated.
Since 2010-07-04, find_variant_selector_charmap() returns
the first cmap subtable always under rogue-compatible
configuration, it causes NULL pointer dereference and
make UVS-related functions crashed.
* src/base/ftobjs.c (Fix find_variant_selector_charmap):
Returns UVS cmap correctly.
UVS supporting functions assume the variation handler functions
are valid. When a font without cmap format 14 is given, these
function pointers are left as NULL, so calling these functions
causes NULL pointer dereference.
* src/base/ftobjs.c (FT_Face_GetCharVariantIndex): Check the pointer
FT_CMap_Class->char_var_index before calling it.
(FT_Face_GetCharVariantIsDefault): Check the pointer
FT_CMap_Class->char_var_default before calling it.
(FT_Face_GetVariantSelectors): Check the pointer
FT_CMap_Class->variant_list before calling it.
(FT_Face_GetVariantsOfChar): Check the pointer
FT_CMap_Class->charvariant_list before calling it.
(FT_Face_GetCharsOfVariant): Check the pointer
FT_CMap_Class->variantchar_list before calling it.
On LLP64 platforms (e.g. Win64), unsigned long (32-bit)
cannot cover the memory address (64-bit). FT_MEM_VAL() is
used for hashing only and not dereferred, so using signed
type FT_PtrDist is safe.
* src/base/ftdbgmem.c (FT_MEM_VAL): Change the type of the
return value from FT_ULong to FT_PtrDist.
(ft_mem_table_resize): The type of hash is changed to
FT_PtrDist. (ft_mem_table_get_nodep): Ditto.
When a resource fork access rule by Darwin VFS could open the
resource fork but no font is found in it, the rest of rules
by Darwin VFS are skipped. It reduces the warnings of the
deprecated resource fork access method by recent Darwin kernel.
Fix MacPorts ticket #18859:
http://trac.macports.org/ticket/18859
* src/base/ftobjs.c (load_face_in_embedded_rfork):
When FT_Stream_New() returns FT_Err_Cannot_Open_Stream, it
means that the file is possible to be fopen()-ed but zero-sized.
Also there is a case that the resource fork is not zero-sized,
but no supported font exists in it. If a rule by Darwin VFS
falls into such cases, there is no need to try other Darwin VFS
rules anymore. Such cases are marked by vfs_rfork_has_no_font.
If it is TRUE, the Darwin VFS rules are skipped.
MacOS X/Darwin kernel supports a few tricky methods to access
a resource fork via ANSI C or POSIX interface. Current resource
fork accessor tries all possible methods to support all kernels.
But if a method could open a resource fork but no font is found,
there is no need to try other methods older than tested method.
To determine whether the rule index is for Darwin VFS, a local
function ftrfork.c::raccess_rule_by_darwin_vfs() is introduced.
To use this function in ftobjs.c etc but it should be inlined,
it is exposed by ftbase.h.
* src/base/ftrfork.c (FT_RFork_Rule): New enum type to identify
the rules to access the resource fork.
(raccess_guess_rec): New structure to bind the rule function and
rule enum type.
(FT_Raccess_Guess): The list of the rule functions is replaced by
(raccess_guess_table): This. This is exposed to be used by other
intra module functions.
(raccess_rule_by_darwin_vfs): A function to return a boolean
if the rule specified by the rule index is based on Darwin VFS.
builds/unix/ftsystem.c prevents to open an useless stream from
zero-sized file and returns FT_Err_Cannot_Open_Stream, but the
stream drivers for ANSI C, Amiga and VMS return useless streams.
For cross-platform consistency, all stream drivers should act
same.
* src/base/ftsystem.c (FT_Stream_Open): If the size of the opened
file is zero, FT_Err_Cannot_Open_Stream is returned.
* builds/amiga/src/base/ftsystem.c (FT_Stream_Open): Ditto.
* src/vms/ftsystem.c (FT_Stream_Open): Ditto.
* src/base/ftobjs.c (FT_Done_Library): Specify the order of font
drivers in face closing process. Type42 faces should be closed
before TrueType faces, because a Type42 face refers another
internal TrueType face which is created from sfnt[] array on the
memory.
Fix for Savannah bug #30059.
* src/cache/ftccmap.c (FTC_CMapCache_Lookup): Replace `16' the
minimum character code passed by a legacy rogue client by...
* include/freetype/config/ftoption.h (FT_MAX_CHARMAP_CACHEABLE):
This. It is undefined when FT_CONFIG_OPTION_OLD_INTERNALS is
undefined (thus the rogue client compatibility is not required).
* src/cff/cffobjs.c (cff_face_init): Abort the automatic
selection or synthesis of Unicode cmap subtable when the charmap
index exceeds FT_MAX_CHARMAP_CACHEABLE.
* src/sfnt/ttcmap.c (tt_face_build_cmaps): Issue error message
when the charmap index exceeds FT_MAX_CHARMAP_CACHEABLE.
* src/base/ftobjs.c (find_unicode_charmap): When Unicode charmap
is found after FT_MAX_CHARMAP_CACHEABLE, ignore it and search
earlier one.
(find_variant_selector_charmap): When UVS charmap is found after
FT_MAX_CHARMAP_CACHEABLE, ignore it and search earlier one.
(FT_Select_Charmap): When a charmap matching with requested
encoding but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Set_Charmap): When a charmap matching with requested
charmap but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Get_Charmap_Index): When a requested charmap is found
after FT_MAX_CHARMAP_CACHEABLE, return the inverted charmap
index.
* src/base/ftobjs.c (Mac_Read_POST_Resource): If the type
of the POST fragment is 0, the segment is completely ignored.
The declared length of the segment is not cared at all.
According to Adobe Technical Note 5040, type 0 segment is
comment only and should not be loaded for the interpreter.
Reported by Robert Swiecki.
* src/base/ftobjs.c (Mac_Read_POST_Resource): Check `rlen'
the length of fragment declared in the POST fragment header
and prevent an underflow in length calculation. Some fonts
set the length to zero in spite of the exist of following
16bit `type'. Reported by Robert Swiecki.
* src/base/ftobjs.c (Mac_Read_POST_Resource): Check the buffer
size during gathering PFB fragments embedded in LaserWriter PS
font for Macintosh. Reported by Robert Swiecki.
* src/base/ftstream.c (FT_Stream_EnterFrame): Exit with error
if the frame size is larger than the stream size.
* src/base/ftsystem.c (ft_ansi_stream_io): Exit with error if
seeking a position larger than the stream size.
* src/base/ftobjs.c (Mac_Read_POST_Resource): Check the error during
reading a PFB fragment embedded in LaserWriter PS font for Macintosh.
Reported by Robert Swiecki.
This bug has been introduced with commit 2415cbf3.
* src/base/ftobjs.c (FT_Get_First_Char, FT_Get_Next_Char): Protect
against endless loop in case of corrupted font header data.
This is based on code written by Lifter
<http://unixforum.org/index.php?showuser=11691>. It fixes
FreeDesktop bug #27386.
* src/base/ftlcdfil.c (FT_Library_SetLcdFilterWeights): New
function.
* include/freetype/ftlcdfil.h: Updated.
* docs/CHANGES: Updated.
==========================
Tag sources with `VER-2-3-12'.
* docs/CHANGES: Updated.
* docs/VERSION.DLL: Update documentation and bump version number to
2.3.12.
* README, Jamfile (RefDoc),
builds/win32/vc2005/freetype.vcproj, builds/win32/vc2005/index.html,
builds/win32/vc2008/freetype.vcproj, builds/win32/vc2008/index.html,
builds/win32/visualc/freetype.dsp,
builds/win32/visualc/freetype.vcproj,
builds/win32/visualc/index.html, builds/win32/visualce/freetype.dsp,
builds/win32/visualce/freetype.vcproj,
builds/win32/visualce/index.html,
builds/wince/vc2005-ce/freetype.vcproj,
builds/wince/vc2005-ce/index.html,
builds/wince/vc2008-ce/freetype.vcproj,
builds/wince/vc2008-ce/index.html: s/2.3.11/2.3.12/, s/2311/2312/.
* include/freetype/freetype.h (FREETYPE_PATCH): Set to 12.
* builds/unix/configure.raw (version_info): Set to 10:0:4.
* src/base/ftglyph.c (FT_Glyph_To_Bitmap) [FT_CONFIG_OPTION_PIC]:
Declare `library' for FT_BITMAP_GLYPH_CLASS_GET.
* src/base/ftinit.c (ft_destroy_default_module_classes,
ft_create_default_module_classes): Use proper casts (needed for C++
compilation).
* src/sfnt/ttcmap.c (tt_cmap13_class_rec): Use FT_DEFINE_TT_CMAP.
Reported by Sean.
* src/base/ftdbgmem.c [!FT_DEBUG_MEMORY]: ANSI C doesn't like empty
source files; however, some compilers warn about an unused variable
declaration. This is now replaced with a typedef.
The calculation of `vertBearingX' is not defined in the OTF font
spec so FreeType does a `best effort' attempt. However, this value
is defined in the PDF and PostScript specs, and that algorithm is
better than the one FreeType currently uses:
FreeType: Use the middle of the bounding box as the X coordinate
of the vertical origin.
Adobe PDF spec: Use the middle of the horizontal advance vector as
the X coordinate of the vertical origin.
FreeType's algorithm goes wrong if you have a really small glyph
(like the full-width, circle-like dot at the end of the sentence, as
used in CJK scripts) with large bearings. With the FreeType
algorithm this dot gets centered on the baseline; with the PDF
algorithm it gets the correct location (in the top right). Note
that this is a serious issue, it's like printing the dot at the end
of a Roman sentence at the center of the textline instead of on the
baseline like it should. So i believe the PDF spec's algorithm
should be used in FreeType as well.
The `vertBearingY' value for such small glyphs is also very strange
if no `vmtx' information is present, since the height of the bbox is
not representable for the height of the glyph visually (the
whitespace up to the baseline is part of the glyph). The fix also
includes some code for a better estimate of `vertBearingY'.
* src/base/ftobjs.c (ft_synthesize_vertical_metrics): `vertBearingX'
is now calculated as described by the Adobe PDF Spec. Estimate for
`vertBearingY' now works better for small glyphs completely above or
below the baseline into account.
* src/cff/cffgload.c (cff_slot_load): `vertBearingX' is now
calculated as described by the Adobe PDF Spec. Vertical metrics
information was always ignored when FT_CONFIG_OPTION_OLD_INTERNALS
was not defined.
* src/truetype/ttgload.c (compute_glyph_metrics): `vertBearingX' is
now calculated as described by the Adobe PDF Spec.