Skip to content
GitLab
Explore
Sign in
Register
FreeType
FreeType
Compare revisions
9a813d0c55d6be745e377e3a438e12fea6b00528 to 86e5080e863001fb6b79f78774a5af3774ae62f2
Commits on Source (2)
Improve validation for vertical seperation adjustments, and use new approach for tilde unflattening
· fa336db6
Craig White
authored
Aug 12, 2023
fa336db6
Add support for simple cases of GSUB lookups
· 86e5080e
Craig White
authored
Aug 26, 2023
86e5080e
Hide whitespace changes
Inline
Side-by-side
src/autofit/afadjust.c
View file @
86e5080e
...
...
@@ -8,12 +8,20 @@
#undef FT_COMPONENT
#define FT_COMPONENT afadjust
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
#include
<hb.h>
#include
<hb-ot.h>
#endif
/*TODO: find out whether capital u/U with accent entries are needed*/
/*the accent won't merge with the rest of the glyph because the accent mark is sitting above empty space*/
/*
All entries in this list must be sorted by unicode codepoint ascending
*/
FT_LOCAL_ARRAY_DEF
(
AF_AdjustmentDatabaseEntry
)
adjustment_database
[]
=
{
{
0x21
,
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
},
/* ! *
/
{
0x21
,
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
},
/* ! *
{0x69, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP}, /* i */
{
0x6A
,
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
},
/* j */
{
0xA1
,
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
},
/*Inverted Exclamation Mark*/
...
...
@@ -130,6 +138,12 @@ adjustment_database[] =
{
0x17E
,
AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP
}
};
FT_LOCAL_DEF
(
FT_Bool
)
af_adjustment_database_entry_equals
(
const
AF_AdjustmentDatabaseEntry
*
a
,
const
AF_AdjustmentDatabaseEntry
*
b
)
{
return
a
->
codepoint
==
b
->
codepoint
&&
a
->
vertical_separation_adjustment_type
==
b
->
vertical_separation_adjustment_type
;
}
/*Helper function: get the adjustment database entry for a codepoint*/
FT_LOCAL_DEF
(
const
AF_AdjustmentDatabaseEntry
*
)
af_adjustment_database_lookup
(
FT_UInt32
codepoint
)
{
...
...
@@ -187,12 +201,12 @@ typedef struct AF_ReverseMapEntry_
typedef
struct
AF_ReverseCharacterMap_
{
FT_
UInt
length
;
FT_
Long
length
;
AF_ReverseMapEntry
*
entries
;
}
AF_ReverseCharacterMap_Rec
;
FT_LOCAL_DEF
(
FT_UInt32
)
af_reverse_character_map_lookup
(
AF_ReverseCharacterMap
map
,
FT_Int
glyph_index
)
af_reverse_character_map_lookup
_
(
AF_ReverseCharacterMap
map
,
FT_Int
glyph_index
,
FT_Long
length
)
{
if
(
map
==
NULL
)
{
...
...
@@ -222,19 +236,59 @@ af_reverse_character_map_lookup( AF_ReverseCharacterMap map, FT_Int glyph_index
return
0
;
}
FT_LOCAL_DEF
(
FT_UInt32
)
af_reverse_character_map_lookup
(
AF_ReverseCharacterMap
map
,
FT_Int
glyph_index
)
{
return
af_reverse_character_map_lookup_
(
map
,
glyph_index
,
map
->
length
);
}
/*prepare to add one more entry to the reverse character map
this is a helper for af_reverse_character_map_new*/
FT_LOCAL_DEF
(
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
;
}
/* qsort compare function for reverse character map */
FT_LOCAL_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
;
}
FT_LOCAL_DEF
(
FT_Error
)
af_reverse_character_map_new
(
FT_Face
face
,
AF_ReverseCharacterMap
*
map
,
FT_Memory
memory
)
af_reverse_character_map_new
(
AF_ReverseCharacterMap
*
map
,
AF_FaceGlobals
globals
)
{
FT_Face
face
=
globals
->
face
;
FT_Memory
memory
=
face
->
memory
;
/* Search for a unicode charmap */
/* If there isn't one, create a blank map */
/*TODO: use GSUB lookups */
FT_TRACE4
((
"af_reverse_character_map_new: building reverse character map
\n
"
));
FT_Error
error
;
/* backup face->charmap because find_unicode_charmap sets it */
FT_CharMap
old_charmap
=
face
->
charmap
;
if
((
error
=
find_unicode_charmap
(
face
)
))
{
if
(
(
error
=
find_unicode_charmap
(
face
)
)
)
{
*
map
=
NULL
;
goto
Exit
;
}
...
...
@@ -244,8 +298,8 @@ af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memo
goto
Exit
;
}
FT_
Int
capacity
=
10
;
FT_Int
size
=
0
;
FT_
Long
capacity
=
10
;
(
*
map
)
->
length
=
0
;
if
(
FT_NEW_ARRAY
(
(
*
map
)
->
entries
,
capacity
)
)
{
...
...
@@ -265,19 +319,117 @@ af_reverse_character_map_new( FT_Face face, AF_ReverseCharacterMap *map, FT_Memo
#endif
continue
;
}
if
(
size
==
capacity
)
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
);
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
hb_font_t
*
hb_font
=
globals
->
hb_font
;
hb_face_t
*
hb_face
=
hb_font_get_face
(
hb_font
);
hb_set_t
*
feature_indicies
=
hb_set_create
();
FT_Long
oldlength
=
(
*
map
)
->
length
;
hb_ot_layout_collect_lookups
(
hb_face
,
HB_OT_TAG_GSUB
,
NULL
,
/*all scripts*/
NULL
,
/*all languages*/
NULL
,
/*all features*/
feature_indicies
);
hb_codepoint_t
feature_index
=
HB_SET_VALUE_INVALID
;
FT_UInt
added_entries
=
0
;
while
(
hb_set_next
(
feature_indicies
,
&
feature_index
)
)
{
hb_codepoint_t
output_glyph_index
;
/*TODO: find out whether I can reuse set instances instead of recreating*/
hb_set_t
*
glyphs_before
=
hb_set_create
();
hb_set_t
*
glyphs_input
=
hb_set_create
();
hb_set_t
*
glyphs_after
=
hb_set_create
();
hb_set_t
*
glyphs_output
=
hb_set_create
();
hb_ot_layout_lookup_collect_glyphs
(
hb_face
,
HB_OT_TAG_GSUB
,
feature_index
,
glyphs_before
,
glyphs_input
,
glyphs_after
,
glyphs_output
);
/*Don't consider anything involving context. Just do the
simple cases*/
if
(
hb_set_get_population
(
glyphs_before
)
>
0
||
hb_set_get_population
(
glyphs_after
)
>
0
)
{
continue
;
}
if
(
hb_set_get_population
(
glyphs_output
)
!=
1
)
{
capacity
+=
capacity
/
2
;
if
(
FT_RENEW_ARRAY
((
*
map
)
->
entries
,
size
,
capacity
)
)
continue
;
}
hb_codepoint_t
input_glyph_index
=
HB_SET_VALUE_INVALID
;
const
AF_AdjustmentDatabaseEntry
*
input_entry
=
NULL
;
FT_UInt32
input_codepoint
;
while
(
hb_set_next
(
glyphs_input
,
&
input_glyph_index
)
)
{
input_codepoint
=
af_reverse_character_map_lookup_
(
*
map
,
input_glyph_index
,
oldlength
);
if
(
input_codepoint
==
0
)
{
continue
;
}
const
AF_AdjustmentDatabaseEntry
*
entry
=
af_adjustment_database_lookup
(
input_codepoint
);
if
(
entry
==
NULL
)
{
goto
Exit
;
continue
;
}
if
(
input_entry
==
NULL
)
{
input_entry
=
entry
;
}
else
{
if
(
!
af_adjustment_database_entry_equals
(
input_entry
,
entry
)
)
{
goto
end
;
}
}
}
size
++
;
(
*
map
)
->
entries
[
i
].
glyph_index
=
glyph
;
(
*
map
)
->
entries
[
i
].
codepoint
=
codepoint
;
output_glyph_index
=
HB_SET_VALUE_INVALID
;
hb_set_next
(
glyphs_output
,
&
output_glyph_index
);
/*Make pair output glyph index -> input unicode*/
error
=
af_reverse_character_map_expand
(
*
map
,
&
capacity
,
memory
);
if
(
error
)
{
goto
Exit
;
}
FT_Long
index
=
(
*
map
)
->
length
++
;
(
*
map
)
->
entries
[
index
].
glyph_index
=
output_glyph_index
;
(
*
map
)
->
entries
[
index
].
codepoint
=
input_codepoint
;
FT_TRACE4
((
"Adding entry: %d -> %d
\n
"
,
output_glyph_index
,
input_codepoint
));
end:
;
}
(
*
map
)
->
length
=
size
;
ft_qsort
(
(
*
map
)
->
entries
,
(
*
map
)
->
length
,
sizeof
(
AF_ReverseMapEntry
),
af_reverse_character_map_entry_compare
);
#endif
/*FT_CONFIG_OPTION_USE_HARFBUZZ*/
Exit:
face
->
charmap
=
old_charmap
;
...
...
@@ -293,7 +445,7 @@ Exit:
}
#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE4
((
" reverse character map built successfully"
\
" with %d entries and %d failed lookups.
\n
"
,
size
,
failed_lookups
));
" with %d entries and %d failed lookups.
\n
"
,
(
*
map
)
->
length
,
failed_lookups
));
#endif
return
FT_Err_Ok
;
}
...
...
src/autofit/afadjust.h
View file @
86e5080e
#ifndef AFADJUST_H_
#define AFADJUST_H_
#include
<freetype/fttypes.h>
#include
"aftypes.h"
#include
"afglobal.h"
FT_BEGIN_HEADER
...
...
@@ -28,10 +29,6 @@ typedef struct AF_AdjustmentDatabaseEntry_
AF_VerticalSeparationAdjustmentType
vertical_separation_adjustment_type
;
}
AF_AdjustmentDatabaseEntry
;
struct
AF_ReverseCharacterMap_
;
typedef
struct
AF_ReverseCharacterMap_
*
AF_ReverseCharacterMap
;
FT_LOCAL
(
AF_VerticalSeparationAdjustmentType
)
af_lookup_vertical_seperation_type
(
AF_ReverseCharacterMap
map
,
FT_Int
glyph_index
);
...
...
@@ -43,7 +40,7 @@ af_reverse_character_map_lookup( 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
(
FT_Face
face
,
AF_ReverseCharacterMap
*
map
,
FT_Memory
memory
);
af_reverse_character_map_new
(
AF_ReverseCharacterMap
*
map
,
AF_FaceGlobals
globals
);
/*free the reverse character map*/
FT_LOCAL
(
FT_Error
)
...
...
src/autofit/aflatin.c
View file @
86e5080e
...
...
@@ -1154,7 +1154,7 @@
}
af_latin_metrics_check_digits
(
metrics
,
face
);
af_reverse_character_map_new
(
face
,
&
metrics
->
root
.
reverse_charmap
,
face
->
memory
);
af_reverse_character_map_new
(
&
metrics
->
root
.
reverse_charmap
,
metrics
->
root
.
globals
);
}
Exit:
...
...
@@ -2799,6 +2799,87 @@ af_find_highest_contour( AF_GlyphHints hints ) {
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
;
AF_Segment
segment_limit
=
FT_OFFSET
(
segments
,
axis
->
num_segments
);
for
(
FT_Int
i
=
0
;
i
<
axis
->
num_segments
;
i
++
)
{
AF_Segment
seg
=
&
segments
[
i
];
FT_Bool
remove
=
0
;
for
(
AF_Point
p
=
seg
->
first
;
p
<=
seg
->
last
;
p
=
p
->
next
)
{
if
(
p
==
point
)
{
remove
=
1
;
break
;
}
}
if
(
remove
)
{
FT_TRACE4
((
"Removing segment %d
\n
"
,
i
));
/* first, check the first and last fields 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 */
}
}
}
static
void
af_latin_stretch_tildes_step_2
(
AF_GlyphHints
hints
,
FT_Int
glyph_index
,
AF_ReverseCharacterMap
reverse_charmap
)
{
if
(
af_lookup_tilde_correction_type
(
reverse_charmap
,
glyph_index
))
{
FT_Int
highest_contour
=
af_find_highest_contour
(
hints
);
AF_Point
first_point
=
hints
->
contours
[
highest_contour
];
/* search for any curve tips that are on a y extrema, and delete any
segments that contain this point.*/
AF_Point
p
=
first_point
;
do
{
p
=
p
->
next
;
if
(
/*!(p->flags & AF_FLAG_CONTROL)
&& p->prev->y == p->y && p->next->y == p->y
&& p->prev->flags & AF_FLAG_CONTROL
&& p->next->flags & AF_FLAG_CONTROL*/
1
)
{
af_remove_segments_containing_point
(
hints
,
p
);
}
}
while
(
p
!=
first_point
);
}
}
void
af_latin_stretch_tildes
(
AF_GlyphHints
hints
,
FT_Int
glyph_index
,
...
...
@@ -2814,82 +2895,99 @@ af_latin_stretch_tildes( AF_GlyphHints hints,
FT_Short
min_fy
,
max_fy
;
min_fy
=
max_fy
=
p
->
fy
;
do
{
do
{
p
=
p
->
next
;
if
(
p
->
y
<
min_y
)
{
if
(
p
->
y
<
min_y
)
{
min_y
=
p
->
y
;
}
if
(
p
->
y
>
max_y
)
{
if
(
p
->
y
>
max_y
)
{
max_y
=
p
->
y
;
}
if
(
p
->
fy
<
min_fy
)
{
if
(
p
->
fy
<
min_fy
)
{
min_fy
=
p
->
fy
;
}
if
(
p
->
fy
>
max_fy
)
{
if
(
p
->
fy
>
max_fy
)
{
max_fy
=
p
->
fy
;
}
}
while
(
p
!=
first_point
);
}
while
(
p
!=
first_point
);
FT_Pos
min_measurement
=
32000
;
FT_UInt
measurements_taken
=
0
;
do
{
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
)
{
&&
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
;
while
(
prevOn
->
flags
&
AF_FLAG_CONTROL
)
{
while
(
prevOn
->
flags
&
AF_FLAG_CONTROL
)
{
prevOn
=
prevOn
->
prev
;
}
while
(
nextOn
->
flags
&
AF_FLAG_CONTROL
)
{
while
(
nextOn
->
flags
&
AF_FLAG_CONTROL
)
{
nextOn
=
nextOn
->
next
;
}
FT_Pos
measurement
;
if
(
nextOn
->
y
>
p
->
y
&&
prevOn
->
y
>
p
->
y
)
{
if
(
nextOn
->
y
>
p
->
y
&&
prevOn
->
y
>
p
->
y
)
{
measurement
=
p
->
y
-
min_y
;
}
else
if
(
nextOn
->
y
<
p
->
y
&&
prevOn
->
y
<
p
->
y
)
{
}
else
if
(
nextOn
->
y
<
p
->
y
&&
prevOn
->
y
<
p
->
y
)
{
measurement
=
max_y
-
p
->
y
;
}
else
{
}
else
{
continue
;
}
if
(
measurement
<
min_measurement
)
{
if
(
measurement
<
min_measurement
)
{
min_measurement
=
measurement
;
}
measurements_taken
++
;
}
}
while
(
p
!=
first_point
);
}
while
(
p
!=
first_point
);
FT_Pos
height
=
max_y
-
min_y
;
FT_Pos
target_height
=
min_measurement
+
64
;
if
(
height
>=
target_height
)
{
if
(
height
>=
target_height
)
{
return
;
}
p
=
first_point
;
do
{
do
{
p
=
p
->
next
;
/*if ( p->flags & AF_FLAG_CONTROL ) {
continue;
}*/
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
;
if
(
!
(
p
->
flags
&
AF_FLAG_CONTROL
)
)
p
->
flags
|=
AF_FLAG_TOUCH_Y
;
}
while
(
p
!=
first_point
);
}
while
(
p
!=
first_point
);
FT_TRACE4
((
"af_latin_stretch_tildes: Height: %d, measurement: %d, measurements taken: %d
\n
"
,
height
,
min_measurement
,
measurements_taken
));
...
...
@@ -2898,18 +2996,73 @@ af_latin_stretch_tildes( AF_GlyphHints hints,
p
=
first_point
;
do
{
p
=
p
->
next
;
if
(
p
->
y
<
new_min_y
)
{
if
(
p
->
y
<
new_min_y
)
{
new_min_y
=
p
->
y
;
}
if
(
p
->
y
>
new_max_y
)
{
if
(
p
->
y
>
new_max_y
)
{
new_max_y
=
p
->
y
;
}
}
while
(
p
!=
first_point
);
}
while
(
p
!=
first_point
);
FT_TRACE4
((
"af_latin_stretch_tildes: New height: %d
\n
, miny: %d, maxy: %d"
,
new_max_y
-
new_min_y
,
new_min_y
,
new_max_y
));
}
}
/*True if the given contour overlaps horizontally with the bounding box
Of all other contours combined.
This is a helper for af_glyph_hints_apply_vertical_separation_adjustments */
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_TRACE4
((
"af_latin_stretch_tildes_merp: New height: %d
\n
, miny: %d, maxy: %d"
,
new_max_y
-
new_min_y
,
new_min_y
,
new_max_y
));
for
(
FT_Int
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
/* ( contour != contour_index ) */
{
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
);
}
FT_Bool
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
;
}
void
...
...
@@ -2961,6 +3114,15 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
}
}
/* check for a horizontal overtap between the top contour and the rest */
/* if there is no overlap, do not adjust. */
FT_Bool
horizontal_overlap
=
af_check_contour_horizontal_overlap
(
hints
,
highest_contour
);
if
(
!
horizontal_overlap
)
{
FT_TRACE4
((
" Top contour does not horizontally overlap with other contours. Skipping adjustment.
\n
"
));
return
;
}
/* If there are any contours that have a maximum y coordinate */
/* greater or equal to the minimum y coordinate of the previously found highest*/
/* contour, bump the high contour up until the distance is one pixel */
...
...
@@ -2995,9 +3157,13 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
}
}
FT_TRACE4
((
" Pushing top contour %d units up
\n
"
,
adjustment_amount
));
if
(
adjustment_amount
>
0
)
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_seperation_type
(
reverse_charmap
,
glyph_index
)
==
AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN
...
...
@@ -3065,9 +3231,13 @@ af_glyph_hints_apply_vertical_separation_adjustments( AF_GlyphHints hints,
adjustment_amount
=
64
-
(
min_y
-
lowest_max_y
);
}
FT_TRACE4
((
" Pushing bottom contour %d units down
\n
"
,
adjustment_amount
));
if
(
adjustment_amount
>
0
)
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
);
}
}
...
...
@@ -3900,7 +4070,6 @@ static void traceheight(FT_UInt num, AF_GlyphHints hints) {
FT_Pos
min_y
,
max_y
;
min_y
=
max_y
=
p
->
y
;
FT_UInt
candidates
=
0
;
do
{
p
=
p
->
next
;
...
...
@@ -3952,12 +4121,13 @@ static void traceheight(FT_UInt num, AF_GlyphHints hints) {
if
(
AF_HINTS_DO_VERTICAL
(
hints
)
)
{
af_latin_stretch_tildes
(
hints
,
glyph_index
,
metrics
->
root
.
reverse_charmap
);
/*
af_latin_stretch_tildes( hints, glyph_index, metrics->root.reverse_charmap );
*/
axis
=
&
metrics
->
axis
[
AF_DIMENSION_VERT
];
error
=
af_latin_hints_detect_features
(
hints
,
axis
->
width_count
,
axis
->
widths
,
AF_DIMENSION_VERT
);
af_latin_stretch_tildes_step_2
(
hints
,
glyph_index
,
metrics
->
root
.
reverse_charmap
);
if
(
error
)
goto
Exit
;
...
...
src/autofit/aftypes.h
View file @
86e5080e
...
...
@@ -39,7 +39,6 @@
#include
<freetype/internal/ftdebug.h>
#include
"afblue.h"
#include
"afadjust.h"
#ifdef FT_DEBUG_AUTOFIT
#include FT_CONFIG_STANDARD_LIBRARY_H
...
...
@@ -411,6 +410,10 @@ extern void* af_debug_hints_;
/* specific to writing systems derive their structures from it, for */
/* example `AF_LatinMetrics'. */
struct
AF_ReverseCharacterMap_
;
typedef
struct
AF_ReverseCharacterMap_
*
AF_ReverseCharacterMap
;
typedef
struct
AF_StyleMetricsRec_
{
AF_StyleClass
style_class
;
...
...