Skip to content
GitLab
About GitLab
GitLab: the DevOps platform
Explore GitLab
Install GitLab
How GitLab compares
Get started
GitLab docs
GitLab Learn
Pricing
Talk to an expert
/
Help
What's new
2
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Projects
Groups
Snippets
Register
Sign in
Toggle navigation
Menu
Open sidebar
Inkscape
inkscape
Commits
0dacc4ed
Verified
Commit
0dacc4ed
authored
Aug 19, 2021
by
Alba Mendez
Committed by
Marc Jeanmougin
Sep 08, 2021
Browse files
fix GSUB table reading
parent
9d6915ef
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/libnrtype/OpenTypeUtil.cpp
View file @
0dacc4ed
...
...
@@ -15,6 +15,7 @@
#include
<iostream>
// For debugging
#include
<memory>
#include
<unordered_map>
// FreeType
#include FT_FREETYPE_H
...
...
@@ -60,19 +61,69 @@ Glib::ustring extract_tag( guint32 *tag ) {
#if HB_VERSION_ATLEAST(1,2,3) // Released Feb 2016
void
get_glyphs
(
hb_font_t
*
font
,
HbSet
&
set
,
Glib
::
ustring
&
characters
)
{
// There is a unicode to glyph mapping function but not the inverse!
hb_codepoint_t
codepoint
=
-
1
;
while
(
hb_set_next
(
set
.
get
(),
&
codepoint
))
{
for
(
hb_codepoint_t
unicode_i
=
0
;
unicode_i
<
0xffff
;
++
unicode_i
)
{
hb_codepoint_t
glyph
=
0
;
hb_font_get_nominal_glyph
(
font
,
unicode_i
,
&
glyph
);
if
(
glyph
==
codepoint
)
{
characters
+=
(
gunichar
)
unicode_i
;
break
;
}
// Later (see get_glyphs) we need to lookup the Unicode codepoint for a glyph
// but there's no direct API for that. So, we need a way to iterate over all
// glyph mappings and build a reverse map.
// FIXME: we should handle UVS at some point... or better, work with glyphs directly
// Iterates over all *possibly* mapped Unicode codepoints of a font, sorted.
class
FontUnicodeSet
{
public:
#if HB_VERSION_ATLEAST(1,9,0) && !defined(HB_NO_FACE_COLLECT_UNICODES) // Released Sep 2018
HbSet
set
;
FontUnicodeSet
(
hb_font_t
*
font
)
:
set
(
hb_set_create
())
{
hb_face_collect_unicodes
(
hb_font_get_face
(
font
),
set
.
get
());
}
inline
bool
next
(
hb_codepoint_t
*
x
)
{
return
hb_set_next
(
set
.
get
(),
x
);
}
#else
// if hb_face_collect_unicodes() is not available, fall back to old behavior by
// simulating a set with all BMP codepoints (non-BMP codepoints are ignored)
FontUnicodeSet
(
hb_font_t
*
font
)
{}
inline
bool
next
(
hb_codepoint_t
*
x
)
{
if
(
*
x
==
HB_SET_VALUE_INVALID
)
*
x
=
0
;
else
++
(
*
x
);
return
(
*
x
)
<
0x10000
;
}
#endif
};
// Allows looking up the lowest Unicode codepoint mapped to a given glyph.
// To do so, it lazily builds a reverse map.
class
GlyphToUnicodeMap
{
protected:
hb_font_t
*
font
;
FontUnicodeSet
codepointSet
;
std
::
unordered_map
<
hb_codepoint_t
,
hb_codepoint_t
>
mappings
;
bool
more
=
true
;
// false if we have finished iterating the set
hb_codepoint_t
codepoint
=
HB_SET_VALUE_INVALID
;
// current iteration
public:
GlyphToUnicodeMap
(
hb_font_t
*
font
)
:
font
(
font
),
codepointSet
(
font
)
{}
hb_codepoint_t
lookup
(
hb_codepoint_t
glyph
)
{
// first, try to find it in the mappings we've seen so far
if
(
auto
it
=
mappings
.
find
(
glyph
);
it
!=
mappings
.
end
())
return
it
->
second
;
// populate more mappings from the set
while
(
more
=
more
&&
codepointSet
.
next
(
&
codepoint
))
{
// get the glyph that this codepoint is associated with, if any
hb_codepoint_t
tGlyph
;
if
(
!
hb_font_get_nominal_glyph
(
font
,
codepoint
,
&
tGlyph
))
continue
;
// save the mapping, and return if this is the one we were looking for
mappings
.
emplace
(
tGlyph
,
codepoint
);
if
(
tGlyph
==
glyph
)
return
codepoint
;
}
return
0
;
}
};
void
get_glyphs
(
GlyphToUnicodeMap
&
glyphMap
,
HbSet
&
set
,
Glib
::
ustring
&
characters
)
{
hb_codepoint_t
glyph
=
-
1
;
while
(
hb_set_next
(
set
.
get
(),
&
glyph
))
{
if
(
auto
codepoint
=
glyphMap
.
lookup
(
glyph
))
characters
+=
codepoint
;
}
}
#endif
...
...
@@ -143,6 +194,8 @@ void readOpenTypeGsubTable (hb_font_t* hb_font,
// Find glyphs in OpenType substitution tables ('gsub').
// Note that pango's functions are just dummies. Must use harfbuzz.
GlyphToUnicodeMap
glyphMap
(
hb_font
);
// Loop over all tables
for
(
auto
table
:
tables
)
{
...
...
@@ -217,10 +270,10 @@ void readOpenTypeGsubTable (hb_font_t* hb_font,
// << " " << hb_set_get_population (glyphs_output)
// << std::endl;
get_glyphs
(
hb_font
,
glyphs_before
,
tables
[
table
.
first
].
before
);
get_glyphs
(
hb_font
,
glyphs_input
,
tables
[
table
.
first
].
input
);
get_glyphs
(
hb_font
,
glyphs_after
,
tables
[
table
.
first
].
after
);
get_glyphs
(
hb_font
,
glyphs_output
,
tables
[
table
.
first
].
output
);
get_glyphs
(
glyphMap
,
glyphs_before
,
tables
[
table
.
first
].
before
);
get_glyphs
(
glyphMap
,
glyphs_input
,
tables
[
table
.
first
].
input
);
get_glyphs
(
glyphMap
,
glyphs_after
,
tables
[
table
.
first
].
after
);
get_glyphs
(
glyphMap
,
glyphs_output
,
tables
[
table
.
first
].
output
);
// std::cout << " Before: " << tables[table.first].before.c_str() << std::endl;
// std::cout << " Input: " << tables[table.first].input.c_str() << std::endl;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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