Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Vincent Wei
harfbuzz
Commits
99502b32
Commit
99502b32
authored
6 years ago
by
Michiharu Ariza
Browse files
Options
Download
Email Patches
Plain Diff
add gvar::get_extents
parent
23e2d5ac
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/hb-ot-face.hh
+1
-0
src/hb-ot-face.hh
src/hb-ot-font.cc
+3
-0
src/hb-ot-font.cc
src/hb-ot-glyf-table.hh
+15
-6
src/hb-ot-glyf-table.hh
src/hb-ot-var-gvar-table.hh
+156
-8
src/hb-ot-var-gvar-table.hh
with
175 additions
and
14 deletions
+175
-14
src/hb-ot-face.hh
View file @
99502b32
...
...
@@ -72,6 +72,7 @@
HB_OT_TABLE(OT, fvar) \
HB_OT_TABLE(OT, avar) \
HB_OT_TABLE(OT, MVAR) \
HB_OT_ACCELERATOR(OT, gvar) \
/* OpenType math. */
\
HB_OT_TABLE(OT, MATH) \
/* OpenType color fonts. */
\
...
...
This diff is collapsed.
Click to expand it.
src/hb-ot-font.cc
View file @
99502b32
...
...
@@ -42,6 +42,7 @@
#include "hb-ot-post-table.hh"
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-vorg-table.hh"
#include "hb-ot-var-gvar-table.hh"
#include "hb-ot-color-cbdt-table.hh"
#include "hb-ot-color-sbix-table.hh"
...
...
@@ -181,6 +182,8 @@ hb_ot_get_glyph_extents (hb_font_t *font,
{
const
hb_ot_face_t
*
ot_face
=
(
const
hb_ot_face_t
*
)
font_data
;
bool
ret
=
ot_face
->
sbix
->
get_extents
(
font
,
glyph
,
extents
);
if
(
!
ret
)
ret
=
ot_face
->
gvar
->
get_extents
(
font
,
glyph
,
extents
);
if
(
!
ret
)
ret
=
ot_face
->
glyf
->
get_extents
(
glyph
,
extents
);
if
(
!
ret
)
...
...
This diff is collapsed.
Click to expand it.
src/hb-ot-glyf-table.hh
View file @
99502b32
...
...
@@ -306,7 +306,7 @@ struct glyf
bool
in_range
(
const
T
*
p
)
const
{
return
((
const
char
*
)
p
)
>=
table
+
start_offset
&&
((
const
char
*
)
(
p
+
T
::
static_size
)
)
<=
table
+
end_offset
;
&&
((
const
char
*
)
p
+
T
::
static_size
)
<=
table
+
end_offset
;
}
protected:
...
...
@@ -366,9 +366,9 @@ struct glyf
* in both cases points trailed with four phantom points
*/
bool
get_contour_points
(
hb_codepoint_t
glyph
,
bool
phantom_only
,
hb_vector_t
<
contour_point_t
>
&
_points
/* OUT */
,
hb_vector_t
<
unsigned
int
>
&
_end_points
/* OUT */
)
const
hb_vector_t
<
unsigned
int
>
&
_end_points
/* OUT */
,
const
bool
phantom_only
=
false
)
const
{
unsigned
int
num_points
=
0
;
unsigned
int
start_offset
,
end_offset
;
...
...
@@ -377,8 +377,17 @@ struct glyf
if
(
end_offset
-
start_offset
<
GlyphHeader
::
static_size
)
return
false
;
glyf
::
CompositeGlyphHeader
::
Iterator
composite
;
if
(
get_composite
(
glyph
,
&
composite
))
{
/* For a composite glyph, add one pseudo point for each component */
do
{
num_points
++
;
}
while
(
composite
.
move_to_next
());
_points
.
resize
(
num_points
+
PHANTOM_COUNT
);
for
(
unsigned
int
i
=
0
;
i
<
_points
.
length
;
i
++
)
_points
[
i
].
init
();
return
true
;
}
const
GlyphHeader
&
glyph_header
=
StructAtOffset
<
GlyphHeader
>
(
glyf_table
,
start_offset
);
if
(
unlikely
(
glyph_header
.
numberOfContours
<
0
))
return
false
;
int16_t
num_contours
=
(
int16_t
)
glyph_header
.
numberOfContours
;
const
HBUINT16
*
end_pts
=
&
StructAfter
<
HBUINT16
,
GlyphHeader
>
(
glyph_header
);
...
...
@@ -428,8 +437,8 @@ struct glyf
}
/* Read x & y coordinates */
return
(
!
read_points
<
x_setter_t
>
(
p
,
_points
,
checker
)
&&
!
read_points
<
y_setter_t
>
(
p
,
_points
,
checker
));
return
(
read_points
<
x_setter_t
>
(
p
,
_points
,
checker
)
&&
read_points
<
y_setter_t
>
(
p
,
_points
,
checker
));
}
/* based on FontTools _g_l_y_f.py::trim */
...
...
This diff is collapsed.
Click to expand it.
src/hb-ot-var-gvar-table.hh
View file @
99502b32
...
...
@@ -31,6 +31,8 @@
#include "hb-ot-glyf-table.hh"
#include "hb-ot-var-fvar-table.hh"
#include <float.h>
/*
* gvar -- Glyph Variation Table
* https://docs.microsoft.com/en-us/typography/opentype/spec/gvar
...
...
@@ -376,6 +378,24 @@ struct gvar
glyf_accel
.
fini
();
}
protected:
typedef
glyf
::
accelerator_t
glyf_acc_t
;
static
float
infer_delta
(
float
target_val
,
float
pre_val
,
float
fol_val
,
float
pre_delta
,
float
fol_delta
)
{
if
(
pre_val
==
fol_val
)
return
(
pre_delta
==
fol_delta
)
?
pre_delta
:
0.
f
;
else
if
(
target_val
<=
MIN
(
pre_val
,
fol_val
))
return
(
pre_val
<
fol_val
)
?
pre_delta
:
fol_delta
;
else
if
(
target_val
>=
MAX
(
pre_val
,
fol_val
))
return
(
pre_val
>
fol_val
)
?
pre_delta
:
fol_delta
;
/* linear interpolation */
float
r
=
(
target_val
-
pre_val
)
/
(
fol_val
-
pre_val
);
return
(
1.
f
-
r
)
*
pre_delta
+
r
*
fol_delta
;
}
bool
apply_deltas_to_points
(
hb_codepoint_t
glyph
,
const
int
*
coords
,
unsigned
int
coord_count
,
const
hb_array_t
<
contour_point_t
>
points
,
...
...
@@ -391,6 +411,11 @@ struct gvar
&
iterator
))
return
false
;
hb_vector_t
<
contour_point_t
>
deltas
;
/* flag is used to indicate referenced point */
deltas
.
resize
(
points
.
length
);
for
(
unsigned
int
i
=
0
;
i
<
deltas
.
length
;
i
++
)
deltas
[
i
].
init
();
do
{
float
scalar
=
iterator
.
current_tuple
->
calculate_scalar
(
coords
,
coord_count
,
shared_tuples
.
as_array
());
if
(
scalar
==
0.
f
)
continue
;
...
...
@@ -419,12 +444,49 @@ struct gvar
for
(
unsigned
int
i
=
0
;
i
<
num_deltas
;
i
++
)
{
unsigned
int
pt_index
=
apply_to_all
?
i
:
indices
[
i
];
points
[
pt_index
].
x
+=
x_deltas
[
i
]
*
scalar
;
points
[
pt_index
].
y
+=
y_deltas
[
i
]
*
scalar
;
deltas
[
pt_index
].
flag
=
1
;
/* this point is referenced, i.e., explicit deltas specified */
deltas
[
pt_index
].
x
+=
x_deltas
[
i
]
*
scalar
;
deltas
[
pt_index
].
y
+=
y_deltas
[
i
]
*
scalar
;
}
/* TODO: interpolate untouched points for glyph extents */
}
while
(
iterator
.
move_to_next
());
/* infer deltas for unreferenced points */
unsigned
int
start_point
=
0
;
for
(
unsigned
int
c
=
0
;
c
<
end_points
.
length
;
c
++
)
{
unsigned
int
end_point
=
end_points
[
c
];
for
(
unsigned
int
i
=
start_point
;
i
<
end_point
;
i
++
)
{
if
(
deltas
[
i
].
flag
)
continue
;
/* search in both directions within the contour for a pair of referenced points */
unsigned
int
pre
;
for
(
pre
=
i
;;)
{
if
(
pre
--
<=
start_point
)
pre
=
end_point
;
if
(
pre
==
i
||
deltas
[
pre
].
flag
)
break
;
}
if
(
pre
==
i
)
continue
;
/* no (preceeding) referenced point was found */
unsigned
int
fol
;
for
(
fol
=
i
;;)
{
if
(
fol
++
>=
end_point
)
fol
=
start_point
;
if
(
fol
==
i
||
deltas
[
fol
].
flag
)
break
;
}
assert
(
fol
!=
i
);
deltas
[
i
].
x
=
infer_delta
(
points
[
i
].
x
,
points
[
pre
].
x
,
points
[
fol
].
x
,
deltas
[
pre
].
x
,
deltas
[
fol
].
x
);
deltas
[
i
].
y
=
infer_delta
(
points
[
i
].
y
,
points
[
pre
].
y
,
points
[
fol
].
y
,
deltas
[
pre
].
y
,
deltas
[
fol
].
y
);
}
start_point
=
end_point
+
1
;
}
/* apply accumulated / inferred deltas to points */
for
(
unsigned
int
i
=
0
;
i
<
points
.
length
;
i
++
)
{
points
[
i
].
x
+=
deltas
[
i
].
x
;
points
[
i
].
y
+=
deltas
[
i
].
y
;
}
return
true
;
}
...
...
@@ -435,11 +497,11 @@ struct gvar
{
hb_vector_t
<
contour_point_t
>
points
;
hb_vector_t
<
unsigned
int
>
end_points
;
if
(
!
glyf_accel
.
get_contour_points
(
glyph
,
true
,
points
,
end_points
))
return
false
;
if
(
!
glyf_accel
.
get_contour_points
(
glyph
,
points
,
end_points
,
true
/*phantom_only*/
))
return
false
;
if
(
!
apply_deltas_to_points
(
glyph
,
coords
,
coord_count
,
points
.
as_array
(),
end_points
.
as_array
()))
return
false
;
for
(
unsigned
int
i
=
0
;
i
<
glyf
::
acc
elerator
_t
::
PHANTOM_COUNT
;
i
++
)
phantoms
[
i
]
=
points
[
points
.
length
-
glyf
::
acc
elerator
_t
::
PHANTOM_COUNT
+
i
];
for
(
unsigned
int
i
=
0
;
i
<
glyf
_
acc_t
::
PHANTOM_COUNT
;
i
++
)
phantoms
[
i
]
=
points
[
points
.
length
-
glyf
_
acc_t
::
PHANTOM_COUNT
+
i
];
glyf
::
CompositeGlyphHeader
::
Iterator
composite
;
if
(
!
glyf_accel
.
get_composite
(
glyph
,
&
composite
))
return
true
;
/* simple glyph */
...
...
@@ -453,6 +515,57 @@ struct gvar
return
true
;
}
struct
bounds_t
{
bounds_t
()
{
min
.
x
=
min
.
y
=
FLT_MAX
;
max
.
x
=
max
.
y
=
FLT_MIN
;
}
void
add
(
const
contour_point_t
&
p
)
{
min
.
x
=
MIN
(
min
.
x
,
p
.
x
);
min
.
y
=
MIN
(
min
.
y
,
p
.
y
);
max
.
x
=
MAX
(
max
.
x
,
p
.
x
);
max
.
y
=
MAX
(
max
.
y
,
p
.
y
);
}
void
_union
(
const
bounds_t
&
b
)
{
add
(
b
.
min
);
add
(
b
.
max
);
}
contour_point_t
min
;
contour_point_t
max
;
};
/* Note: Recursively calls itself. Who's checking recursively nested composite glyph BTW? */
bool
get_bounds_var
(
hb_codepoint_t
glyph
,
const
int
*
coords
,
unsigned
int
coord_count
,
bounds_t
&
bounds
)
const
{
hb_vector_t
<
contour_point_t
>
points
;
hb_vector_t
<
unsigned
int
>
end_points
;
if
(
!
glyf_accel
.
get_contour_points
(
glyph
,
points
,
end_points
))
return
false
;
if
(
!
apply_deltas_to_points
(
glyph
,
coords
,
coord_count
,
points
.
as_array
(),
end_points
.
as_array
()))
return
false
;
glyf
::
CompositeGlyphHeader
::
Iterator
composite
;
if
(
!
glyf_accel
.
get_composite
(
glyph
,
&
composite
))
{
/* simple glyph */
for
(
unsigned
int
i
=
0
;
i
+
glyf_acc_t
::
PHANTOM_COUNT
<
points
.
length
;
i
++
)
bounds
.
add
(
points
[
i
]);
return
true
;
}
/* composite glyph */
do
{
bounds_t
comp_bounds
;
if
(
!
get_bounds_var
(
composite
.
current
->
glyphIndex
,
coords
,
coord_count
,
comp_bounds
))
return
false
;
/* TODO: support component scale/transformation */
bounds
.
_union
(
comp_bounds
);
}
while
(
composite
.
move_to_next
());
return
true
;
}
public:
float
get_advance_var
(
hb_codepoint_t
glyph
,
const
int
*
coords
,
unsigned
int
coord_count
,
bool
vertical
)
const
...
...
@@ -461,15 +574,48 @@ struct gvar
if
(
coord_count
!=
gvar_table
->
axisCount
)
return
advance
;
hb_vector_t
<
contour_point_t
>
points
;
points
.
resize
(
glyf
::
acc
elerator
_t
::
PHANTOM_COUNT
);
points
.
resize
(
glyf
_
acc_t
::
PHANTOM_COUNT
);
if
(
!
get_var_metrics
(
glyph
,
coords
,
coord_count
,
points
))
return
advance
;
if
(
vertical
)
return
-
(
points
[
glyf
::
acc
elerator
_t
::
PHANTOM_BOTTOM
].
y
-
points
[
glyf
::
acc
elerator
_t
::
PHANTOM_TOP
].
y
);
// is this sign correct?
return
-
(
points
[
glyf
_
acc_t
::
PHANTOM_BOTTOM
].
y
-
points
[
glyf
_
acc_t
::
PHANTOM_TOP
].
y
);
// is this sign correct?
else
return
points
[
glyf
::
accelerator_t
::
PHANTOM_RIGHT
].
x
-
points
[
glyf
::
accelerator_t
::
PHANTOM_LEFT
].
x
;
return
points
[
glyf_acc_t
::
PHANTOM_RIGHT
].
x
-
points
[
glyf_acc_t
::
PHANTOM_LEFT
].
x
;
}
bool
get_extents
(
hb_font_t
*
font
,
hb_codepoint_t
glyph
,
hb_glyph_extents_t
*
extents
)
const
{
unsigned
int
coord_count
;
const
int
*
coords
=
hb_font_get_var_coords_normalized
(
font
,
&
coord_count
);
if
(
!
coords
||
coord_count
!=
gvar_table
->
axisCount
)
return
false
;
/* fallback on glyf */
bounds_t
bounds
;
if
(
unlikely
(
!
get_bounds_var
(
glyph
,
coords
,
coord_count
,
bounds
)))
return
false
;
if
(
bounds
.
min
.
x
>=
bounds
.
max
.
x
)
{
extents
->
width
=
0
;
extents
->
x_bearing
=
0
;
}
else
{
extents
->
x_bearing
=
(
int32_t
)
floorf
(
bounds
.
min
.
x
);
extents
->
width
=
(
int32_t
)
ceilf
(
bounds
.
max
.
x
)
-
extents
->
x_bearing
;
}
if
(
bounds
.
min
.
y
>=
bounds
.
max
.
y
)
{
extents
->
height
=
0
;
extents
->
y_bearing
=
0
;
}
else
{
extents
->
y_bearing
=
(
int32_t
)
ceilf
(
bounds
.
max
.
y
);
extents
->
height
=
(
int32_t
)
floorf
(
bounds
.
min
.
y
)
-
extents
->
y_bearing
;
}
return
true
;
}
protected:
...
...
@@ -590,6 +736,8 @@ struct gvar
DEFINE_SIZE_MIN
(
20
);
};
struct
gvar_accelerator_t
:
gvar
::
accelerator_t
{};
}
/* namespace OT */
#endif
/* HB_OT_VAR_GVAR_TABLE_HH */
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help