Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f48ecfc8
Commit
f48ecfc8
authored
Jun 10, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jun 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Return ranges for selected cmap.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
87ca6a06
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
132 deletions
+81
-132
dwrite_private.h
dlls/dwrite/dwrite_private.h
+5
-2
font.c
dlls/dwrite/font.c
+4
-14
opentype.c
dlls/dwrite/opentype.c
+72
-116
No files found.
dlls/dwrite/dwrite_private.h
View file @
f48ecfc8
...
...
@@ -198,6 +198,8 @@ enum font_flags
struct
dwrite_cmap
;
typedef
UINT16
(
*
p_cmap_get_glyph_func
)(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
ch
);
typedef
unsigned
int
(
*
p_cmap_get_ranges_func
)(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
);
struct
dwrite_cmap
{
...
...
@@ -226,6 +228,7 @@ struct dwrite_cmap
}
format12_13
;
}
u
;
p_cmap_get_glyph_func
get_glyph
;
p_cmap_get_ranges_func
get_ranges
;
unsigned
short
symbol
:
1
;
IDWriteFontFileStream
*
stream
;
void
*
table_context
;
...
...
@@ -235,6 +238,8 @@ extern void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, un
DWRITE_FONT_FACE_TYPE
face_type
)
DECLSPEC_HIDDEN
;
extern
void
dwrite_cmap_release
(
struct
dwrite_cmap
*
cmap
)
DECLSPEC_HIDDEN
;
extern
UINT16
opentype_cmap_get_glyph
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
ch
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
DECLSPEC_HIDDEN
;
struct
dwrite_fontface
{
...
...
@@ -387,8 +392,6 @@ struct ot_gsubgpos_table
extern
HRESULT
opentype_analyze_font
(
IDWriteFontFileStream
*
,
BOOL
*
,
DWRITE_FONT_FILE_TYPE
*
,
DWRITE_FONT_FACE_TYPE
*
,
UINT32
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_try_get_font_table
(
const
struct
file_stream_desc
*
stream_desc
,
UINT32
tag
,
const
void
**
data
,
void
**
context
,
UINT32
*
size
,
BOOL
*
exists
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
file_stream_desc
*
stream_desc
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_properties
(
struct
file_stream_desc
*
,
struct
dwrite_font_props
*
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_metrics
(
struct
file_stream_desc
*
,
DWRITE_FONT_METRICS1
*
,
DWRITE_CARET_METRICS
*
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_typo_metrics
(
struct
file_stream_desc
*
stream_desc
,
unsigned
int
*
ascent
,
...
...
dlls/dwrite/font.c
View file @
f48ecfc8
...
...
@@ -1005,7 +1005,6 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace5 *iface,
DWRITE_UNICODE_RANGE
*
ranges
,
UINT32
*
count
)
{
struct
dwrite_fontface
*
fontface
=
impl_from_IDWriteFontFace5
(
iface
);
struct
file_stream_desc
stream_desc
;
TRACE
(
"%p, %u, %p, %p.
\n
"
,
iface
,
max_count
,
ranges
,
count
);
...
...
@@ -1013,10 +1012,8 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace5 *iface,
if
(
max_count
&&
!
ranges
)
return
E_INVALIDARG
;
stream_desc
.
stream
=
fontface
->
stream
;
stream_desc
.
face_index
=
fontface
->
index
;
stream_desc
.
face_type
=
fontface
->
type
;
return
opentype_cmap_get_unicode_ranges
(
&
stream_desc
,
max_count
,
ranges
,
count
);
dwrite_cmap_init
(
&
fontface
->
cmap
,
NULL
,
fontface
->
index
,
fontface
->
type
);
return
opentype_cmap_get_unicode_ranges
(
&
fontface
->
cmap
,
max_count
,
ranges
,
count
);
}
static
BOOL
WINAPI
dwritefontface1_IsMonospacedFont
(
IDWriteFontFace5
*
iface
)
...
...
@@ -2000,8 +1997,6 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m
UINT32
*
count
)
{
struct
dwrite_font
*
font
=
impl_from_IDWriteFont3
(
iface
);
struct
file_stream_desc
stream_desc
;
HRESULT
hr
;
TRACE
(
"%p, %u, %p, %p.
\n
"
,
iface
,
max_count
,
ranges
,
count
);
...
...
@@ -2009,13 +2004,8 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m
if
(
max_count
&&
!
ranges
)
return
E_INVALIDARG
;
if
(
FAILED
(
hr
=
get_filestream_from_file
(
font
->
data
->
file
,
&
stream_desc
.
stream
)))
return
hr
;
stream_desc
.
face_index
=
font
->
data
->
face_index
;
stream_desc
.
face_type
=
font
->
data
->
face_type
;
hr
=
opentype_cmap_get_unicode_ranges
(
&
stream_desc
,
max_count
,
ranges
,
count
);
IDWriteFontFileStream_Release
(
stream_desc
.
stream
);
return
hr
;
dwrite_cmap_init
(
&
font
->
data
->
cmap
,
font
->
data
->
file
,
font
->
data
->
face_index
,
font
->
data
->
face_type
);
return
opentype_cmap_get_unicode_ranges
(
&
font
->
data
->
cmap
,
max_count
,
ranges
,
count
);
}
static
BOOL
WINAPI
dwritefont1_IsMonospacedFont
(
IDWriteFont3
*
iface
)
...
...
dlls/dwrite/opentype.c
View file @
f48ecfc8
...
...
@@ -1571,6 +1571,18 @@ static UINT16 opentype_cmap_format0_get_glyph(const struct dwrite_cmap *cmap, un
return
(
ch
<
0xff
)
?
glyphs
[
ch
]
:
0
;
}
static
unsigned
int
opentype_cmap_format0_get_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
count
,
DWRITE_UNICODE_RANGE
*
ranges
)
{
if
(
count
>
0
)
{
ranges
->
first
=
0
;
ranges
->
last
=
255
;
}
return
1
;
}
struct
cmap_format4_compare_context
{
const
struct
dwrite_cmap
*
cmap
;
...
...
@@ -1627,6 +1639,22 @@ static UINT16 opentype_cmap_format4_get_glyph(const struct dwrite_cmap *cmap, un
return
glyph
&
0xffff
;
}
static
unsigned
int
opentype_cmap_format4_get_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
count
,
DWRITE_UNICODE_RANGE
*
ranges
)
{
unsigned
int
i
;
count
=
min
(
count
,
cmap
->
u
.
format4
.
seg_count
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
ranges
[
i
].
first
=
GET_BE_WORD
(
cmap
->
u
.
format4
.
starts
[
i
]);
ranges
[
i
].
last
=
GET_BE_WORD
(
cmap
->
u
.
format4
.
ends
[
i
]);
}
return
cmap
->
u
.
format4
.
seg_count
;
}
static
UINT16
opentype_cmap_format6_10_get_glyph
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
ch
)
{
const
UINT16
*
glyphs
=
cmap
->
data
;
...
...
@@ -1634,6 +1662,18 @@ static UINT16 opentype_cmap_format6_10_get_glyph(const struct dwrite_cmap *cmap,
return
glyphs
[
ch
-
cmap
->
u
.
format6_10
.
first
];
}
static
unsigned
int
opentype_cmap_format6_10_get_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
count
,
DWRITE_UNICODE_RANGE
*
ranges
)
{
if
(
count
>
0
)
{
ranges
->
first
=
cmap
->
u
.
format6_10
.
first
;
ranges
->
last
=
cmap
->
u
.
format6_10
.
last
;
}
return
1
;
}
static
int
cmap_format12_13_compare_group
(
const
void
*
a
,
const
void
*
b
)
{
const
unsigned
int
*
ch
=
a
;
...
...
@@ -1661,6 +1701,23 @@ static UINT16 opentype_cmap_format12_get_glyph(const struct dwrite_cmap *cmap, u
GET_BE_DWORD
(
group_found
[
2
])
+
(
ch
-
GET_BE_DWORD
(
group_found
[
0
]))
:
0
;
}
static
unsigned
int
opentype_cmap_format12_13_get_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
count
,
DWRITE_UNICODE_RANGE
*
ranges
)
{
unsigned
int
i
,
group_count
=
cmap
->
u
.
format12_13
.
group_count
;
const
UINT32
*
groups
=
cmap
->
data
;
count
=
min
(
count
,
group_count
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
ranges
[
i
].
first
=
GET_BE_DWORD
(
groups
[
3
*
i
]);
ranges
[
i
].
last
=
GET_BE_DWORD
(
groups
[
3
*
i
+
1
]);
}
return
group_count
;
}
static
UINT16
opentype_cmap_format13_get_glyph
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
ch
)
{
const
UINT32
*
groups
=
cmap
->
data
;
...
...
@@ -1678,6 +1735,12 @@ static UINT16 opentype_cmap_dummy_get_glyph(const struct dwrite_cmap *cmap, unsi
return
0
;
}
static
unsigned
int
opentype_cmap_dummy_get_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
count
,
DWRITE_UNICODE_RANGE
*
ranges
)
{
return
0
;
}
UINT16
opentype_cmap_get_glyph
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
ch
)
{
UINT16
glyph
;
...
...
@@ -1771,6 +1834,7 @@ void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned
case
0
:
cmap
->
data
=
table_read_ensure
(
&
table
,
offset
+
6
,
256
);
cmap
->
get_glyph
=
opentype_cmap_format0_get_glyph
;
cmap
->
get_ranges
=
opentype_cmap_format0_get_ranges
;
break
;
case
4
:
length
=
table_read_be_word
(
&
table
,
offset
+
2
);
...
...
@@ -1782,6 +1846,7 @@ void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned
cmap
->
u
.
format4
.
glyph_id_array
=
cmap
->
data
=
cmap
->
u
.
format4
.
id_range_offset
+
count
;
cmap
->
u
.
format4
.
glyph_id_array_len
=
(
length
-
16
-
8
*
count
)
/
2
;
cmap
->
get_glyph
=
opentype_cmap_format4_get_glyph
;
cmap
->
get_ranges
=
opentype_cmap_format4_get_ranges
;
break
;
case
6
:
case
10
:
...
...
@@ -1792,12 +1857,14 @@ void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned
cmap
->
u
.
format6_10
.
last
=
cmap
->
u
.
format6_10
.
first
+
count
;
cmap
->
data
=
table_read_ensure
(
&
table
,
offset
+
f
*
10
,
count
*
2
);
cmap
->
get_glyph
=
opentype_cmap_format6_10_get_glyph
;
cmap
->
get_ranges
=
opentype_cmap_format6_10_get_ranges
;
break
;
case
12
:
case
13
:
cmap
->
u
.
format12_13
.
group_count
=
count
=
table_read_be_dword
(
&
table
,
offset
+
12
);
cmap
->
data
=
table_read_ensure
(
&
table
,
offset
+
16
,
count
*
3
*
4
);
cmap
->
get_glyph
=
format
==
12
?
opentype_cmap_format12_get_glyph
:
opentype_cmap_format13_get_glyph
;
cmap
->
get_ranges
=
opentype_cmap_format12_13_get_ranges
;
break
;
default:
WARN
(
"Unhandled subtable format %u.
\n
"
,
format
);
...
...
@@ -1810,6 +1877,7 @@ failed:
/* Dummy implementation, returns 0 unconditionally. */
cmap
->
data
=
cmap
;
cmap
->
get_glyph
=
opentype_cmap_dummy_get_glyph
;
cmap
->
get_ranges
=
opentype_cmap_dummy_get_ranges
;
}
}
...
...
@@ -1824,125 +1892,13 @@ void dwrite_cmap_release(struct dwrite_cmap *cmap)
cmap
->
stream
=
NULL
;
}
static
unsigned
int
opentype_cmap_get_unicode_ranges_count
(
const
struct
dwrite_fonttable
*
cmap
)
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
dwrite_cmap
*
cmap
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
{
unsigned
int
i
,
num_tables
,
count
=
0
;
const
struct
cmap_header
*
header
;
num_tables
=
table_read_be_word
(
cmap
,
FIELD_OFFSET
(
struct
cmap_header
,
num_tables
));
header
=
table_read_ensure
(
cmap
,
0
,
FIELD_OFFSET
(
struct
cmap_header
,
tables
[
num_tables
]));
if
(
!
header
)
return
0
;
for
(
i
=
0
;
i
<
num_tables
;
++
i
)
{
unsigned
int
format
,
offset
;
if
(
GET_BE_WORD
(
header
->
tables
[
i
].
platformID
)
!=
3
)
continue
;
offset
=
GET_BE_DWORD
(
header
->
tables
[
i
].
offset
);
format
=
table_read_be_word
(
cmap
,
offset
);
switch
(
format
)
{
case
OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING
:
{
count
+=
table_read_be_word
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
seg_count_x2
))
/
2
;
break
;
}
case
OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE
:
{
count
+=
table_read_be_dword
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
num_groups
));
break
;
}
default:
FIXME
(
"table format %u is not supported.
\n
"
,
format
);
}
}
return
count
;
}
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
file_stream_desc
*
stream_desc
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
{
unsigned
int
i
,
num_tables
,
k
=
0
;
const
struct
cmap_header
*
header
;
struct
dwrite_fonttable
cmap
;
opentype_get_font_table
(
stream_desc
,
MS_CMAP_TAG
,
&
cmap
);
if
(
!
cmap
.
exists
)
if
(
!
cmap
->
data
)
return
E_FAIL
;
*
count
=
opentype_cmap_get_unicode_ranges_count
(
&
cmap
);
num_tables
=
table_read_be_word
(
&
cmap
,
FIELD_OFFSET
(
struct
cmap_header
,
num_tables
));
header
=
table_read_ensure
(
&
cmap
,
0
,
FIELD_OFFSET
(
struct
cmap_header
,
tables
[
num_tables
]));
if
(
!
header
)
{
IDWriteFontFileStream_ReleaseFileFragment
(
stream_desc
->
stream
,
cmap
.
context
);
return
S_OK
;
}
for
(
i
=
0
;
i
<
num_tables
&&
k
<
max_count
;
++
i
)
{
unsigned
int
j
,
offset
,
format
;
if
(
GET_BE_WORD
(
header
->
tables
[
i
].
platformID
)
!=
3
)
continue
;
offset
=
GET_BE_DWORD
(
header
->
tables
[
i
].
offset
);
format
=
table_read_be_word
(
&
cmap
,
offset
);
switch
(
format
)
{
case
OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING
:
{
unsigned
int
segment_count
=
table_read_be_word
(
&
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
seg_count_x2
))
/
2
;
const
UINT16
*
start_code
=
table_read_ensure
(
&
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
end_code
[
segment_count
])
+
2
/* reservedPad */
+
2
*
segment_count
/* start code array */
);
const
UINT16
*
end_code
=
table_read_ensure
(
&
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
end_code
[
segment_count
]));
if
(
!
start_code
||
!
end_code
)
continue
;
for
(
j
=
0
;
j
<
segment_count
&&
GET_BE_WORD
(
end_code
[
j
])
!=
0xffff
&&
k
<
max_count
;
++
j
,
++
k
)
{
ranges
[
k
].
first
=
GET_BE_WORD
(
start_code
[
j
]);
ranges
[
k
].
last
=
GET_BE_WORD
(
end_code
[
j
]);
}
break
;
}
case
OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE
:
{
unsigned
int
num_groups
=
table_read_be_dword
(
&
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
num_groups
));
const
struct
cmap_segmented_coverage
*
coverage
;
coverage
=
table_read_ensure
(
&
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
groups
[
num_groups
]));
for
(
j
=
0
;
j
<
num_groups
&&
k
<
max_count
;
j
++
,
k
++
)
{
ranges
[
k
].
first
=
GET_BE_DWORD
(
coverage
->
groups
[
j
].
startCharCode
);
ranges
[
k
].
last
=
GET_BE_DWORD
(
coverage
->
groups
[
j
].
endCharCode
);
}
break
;
}
default:
FIXME
(
"table format %u unhandled.
\n
"
,
format
);
}
}
IDWriteFontFileStream_ReleaseFileFragment
(
stream_desc
->
stream
,
cmap
.
context
);
*
count
=
cmap
->
get_ranges
(
cmap
,
max_count
,
ranges
);
return
*
count
>
max_count
?
E_NOT_SUFFICIENT_BUFFER
:
S_OK
;
}
...
...
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