Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
eef8a44d
Commit
eef8a44d
authored
Dec 06, 2021
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 06, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Move glyph advances cache to PE side.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b167df37
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
31 deletions
+150
-31
dwrite_private.h
dlls/dwrite/dwrite_private.h
+10
-2
font.c
dlls/dwrite/font.c
+124
-8
freetype.c
dlls/dwrite/freetype.c
+16
-21
No files found.
dlls/dwrite/dwrite_private.h
View file @
eef8a44d
...
...
@@ -22,6 +22,7 @@
#include "wine/debug.h"
#include "wine/list.h"
#include "wine/rbtree.h"
#define MS_GSUB_TAG DWRITE_MAKE_OPENTYPE_TAG('G','S','U','B')
#define MS_GPOS_TAG DWRITE_MAKE_OPENTYPE_TAG('G','P','O','S')
...
...
@@ -240,6 +241,13 @@ struct dwrite_fontface
font_object_handle
font_object
;
void
*
data_context
;
p_dwrite_fontface_get_font_object
get_font_object
;
struct
{
struct
wine_rb_tree
tree
;
struct
list
mru
;
size_t
max_size
;
size_t
size
;
}
cache
;
CRITICAL_SECTION
cs
;
USHORT
simulations
;
...
...
@@ -725,8 +733,8 @@ struct font_backend_funcs
int
(
CDECL
*
get_glyph_outline
)(
font_object_handle
object
,
float
emsize
,
unsigned
int
simulations
,
UINT16
glyph
,
struct
dwrite_outline
*
outline
);
UINT16
(
CDECL
*
get_glyph_count
)(
font_object_handle
object
);
INT32
(
CDECL
*
get_glyph_advance
)(
void
*
key
,
float
em_size
,
UINT16
index
,
DWRITE_MEASURING_MODE
measuring_mode
,
BOOL
*
has_contours
);
INT32
(
CDECL
*
get_glyph_advance
)(
font_object_handle
object
,
float
em_size
,
UINT16
glyph
,
DWRITE_MEASURING_MODE
measuring_mode
,
BOOL
*
has_contours
);
void
(
CDECL
*
get_glyph_bbox
)(
struct
dwrite_glyphbitmap
*
bitmap_desc
);
BOOL
(
CDECL
*
get_glyph_bitmap
)(
struct
dwrite_glyphbitmap
*
bitmap_desc
);
void
(
CDECL
*
get_design_glyph_metrics
)(
font_object_handle
object
,
UINT16
upem
,
UINT16
ascent
,
unsigned
int
simulations
,
...
...
dlls/dwrite/font.c
View file @
eef8a44d
...
...
@@ -52,6 +52,111 @@ void dwrite_fontface_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
font_funcs
->
get_glyph_bbox
(
bitmap
);
}
struct
cache_key
{
float
size
;
unsigned
short
glyph
;
unsigned
short
mode
;
};
struct
cache_entry
{
struct
wine_rb_entry
entry
;
struct
list
mru
;
struct
cache_key
key
;
float
advance
;
unsigned
int
has_contours
:
1
;
};
static
struct
cache_entry
*
fontface_get_cache_entry
(
struct
dwrite_fontface
*
fontface
,
const
struct
cache_key
*
key
)
{
struct
cache_entry
*
entry
;
struct
wine_rb_entry
*
e
;
if
(
!
(
e
=
wine_rb_get
(
&
fontface
->
cache
.
tree
,
key
)))
return
NULL
;
entry
=
WINE_RB_ENTRY_VALUE
(
e
,
struct
cache_entry
,
entry
);
list_remove
(
&
entry
->
mru
);
list_add_head
(
&
fontface
->
cache
.
mru
,
&
entry
->
mru
);
return
WINE_RB_ENTRY_VALUE
(
entry
,
struct
cache_entry
,
entry
);
}
static
size_t
fontface_get_cache_entry_size
(
const
struct
cache_entry
*
entry
)
{
return
sizeof
(
*
entry
);
}
static
float
fontface_get_glyph_advance
(
struct
dwrite_fontface
*
fontface
,
float
fontsize
,
unsigned
short
glyph
,
unsigned
short
mode
,
BOOL
*
has_contours
)
{
struct
cache_key
key
=
{
.
size
=
fontsize
,
.
glyph
=
glyph
,
.
mode
=
mode
};
struct
cache_entry
*
entry
,
*
old_entry
;
size_t
size
;
BOOL
value
;
if
(
!
(
entry
=
fontface_get_cache_entry
(
fontface
,
&
key
)))
{
if
(
!
(
entry
=
calloc
(
1
,
sizeof
(
*
entry
))))
return
0
.
0
f
;
entry
->
advance
=
font_funcs
->
get_glyph_advance
(
fontface
->
get_font_object
(
fontface
),
fontsize
,
glyph
,
mode
,
&
value
);
entry
->
has_contours
=
!!
value
;
entry
->
key
=
key
;
size
=
fontface_get_cache_entry_size
(
entry
);
if
((
fontface
->
cache
.
size
+
size
>
fontface
->
cache
.
max_size
)
&&
!
list_empty
(
&
fontface
->
cache
.
mru
))
{
old_entry
=
LIST_ENTRY
(
list_tail
(
&
fontface
->
cache
.
mru
),
struct
cache_entry
,
mru
);
fontface
->
cache
.
size
-=
fontface_get_cache_entry_size
(
old_entry
);
wine_rb_remove
(
&
fontface
->
cache
.
tree
,
&
old_entry
->
entry
);
list_remove
(
&
old_entry
->
mru
);
free
(
old_entry
);
}
list_add_head
(
&
fontface
->
cache
.
mru
,
&
entry
->
mru
);
if
(
wine_rb_put
(
&
fontface
->
cache
.
tree
,
&
key
,
&
entry
->
entry
)
==
-
1
)
{
WARN
(
"Failed to add cache entry.
\n
"
);
return
0
.
0
f
;
}
fontface
->
cache
.
size
+=
size
;
}
*
has_contours
=
entry
->
has_contours
;
return
entry
->
advance
;
}
static
int
fontface_cache_compare
(
const
void
*
k
,
const
struct
wine_rb_entry
*
e
)
{
const
struct
cache_entry
*
entry
=
WINE_RB_ENTRY_VALUE
(
e
,
const
struct
cache_entry
,
entry
);
const
struct
cache_key
*
key
=
k
,
*
key2
=
&
entry
->
key
;
if
(
key
->
size
!=
key2
->
size
)
return
key
->
size
<
key2
->
size
?
-
1
:
1
;
if
(
key
->
glyph
!=
key2
->
glyph
)
return
(
int
)
key
->
glyph
-
(
int
)
key2
->
glyph
;
if
(
key
->
mode
!=
key2
->
mode
)
return
(
int
)
key
->
mode
-
(
int
)
key2
->
mode
;
return
0
;
}
static
void
fontface_cache_init
(
struct
dwrite_fontface
*
fontface
)
{
wine_rb_init
(
&
fontface
->
cache
.
tree
,
fontface_cache_compare
);
list_init
(
&
fontface
->
cache
.
mru
);
fontface
->
cache
.
max_size
=
0x8000
;
}
static
void
fontface_cache_clear
(
struct
dwrite_fontface
*
fontface
)
{
struct
cache_entry
*
entry
,
*
entry2
;
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
entry2
,
&
fontface
->
cache
.
mru
,
struct
cache_entry
,
mru
)
{
list_remove
(
&
entry
->
mru
);
free
(
entry
);
}
memset
(
&
fontface
->
cache
,
0
,
sizeof
(
fontface
->
cache
));
}
struct
dwrite_font_propvec
{
FLOAT
stretch
;
FLOAT
style
;
...
...
@@ -656,6 +761,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
IDWriteFontFileStream_ReleaseFileFragment
(
fontface
->
stream
,
fontface
->
data_context
);
IDWriteFontFileStream_Release
(
fontface
->
stream
);
}
fontface_cache_clear
(
fontface
);
dwrite_cmap_release
(
&
fontface
->
cmap
);
IDWriteFactory7_Release
(
fontface
->
factory
);
...
...
@@ -1019,7 +1125,7 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
UINT32
adjustment
=
fontface_get_horz_metric_adjustment
(
fontface
);
DWRITE_MEASURING_MODE
mode
;
FLOAT
scale
,
size
;
HRESULT
hr
;
HRESULT
hr
=
S_OK
;
UINT32
i
;
TRACE
(
"%p, %.8e, %.8e, %p, %d, %p, %u, %p, %d.
\n
"
,
iface
,
emSize
,
ppdip
,
m
,
use_gdi_natural
,
glyphs
,
...
...
@@ -1032,16 +1138,18 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
scale
=
size
/
fontface
->
metrics
.
designUnitsPerEm
;
mode
=
use_gdi_natural
?
DWRITE_MEASURING_MODE_GDI_NATURAL
:
DWRITE_MEASURING_MODE_GDI_CLASSIC
;
for
(
i
=
0
;
i
<
glyph_count
;
i
++
)
{
EnterCriticalSection
(
&
fontface
->
cs
);
for
(
i
=
0
;
i
<
glyph_count
;
++
i
)
{
DWRITE_GLYPH_METRICS
*
ret
=
metrics
+
i
;
DWRITE_GLYPH_METRICS
design
;
BOOL
has_contours
;
hr
=
IDWriteFontFace5_GetDesignGlyphMetrics
(
iface
,
glyphs
+
i
,
1
,
&
design
,
is_sideways
);
if
(
FAILED
(
hr
))
return
hr
;
break
;
ret
->
advanceWidth
=
font
_funcs
->
get_glyph_advance
(
i
face
,
size
,
glyphs
[
i
],
mode
,
&
has_contours
);
ret
->
advanceWidth
=
font
face_get_glyph_advance
(
font
face
,
size
,
glyphs
[
i
],
mode
,
&
has_contours
);
if
(
has_contours
)
ret
->
advanceWidth
=
round_metric
(
ret
->
advanceWidth
*
fontface
->
metrics
.
designUnitsPerEm
/
size
+
adjustment
);
else
...
...
@@ -1056,6 +1164,7 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
SCALE_METRIC
(
verticalOriginY
);
#undef SCALE_METRIC
}
LeaveCriticalSection
(
&
fontface
->
cs
);
return
S_OK
;
}
...
...
@@ -1172,8 +1281,8 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_
switch
(
measuring_mode
)
{
case
DWRITE_MEASURING_MODE_NATURAL
:
advance
=
font
_funcs
->
get_glyph_advance
(
&
fontface
->
IDWriteFontFace5_iface
,
fontface
->
metrics
.
designUnitsPerEm
,
glyph
,
measuring_mode
,
&
has_contours
);
advance
=
font
face_get_glyph_advance
(
fontface
,
fontface
->
metrics
.
designUnitsPerEm
,
glyph
,
measuring_mode
,
&
has_contours
);
if
(
has_contours
)
advance
+=
adjustment
;
...
...
@@ -1187,8 +1296,7 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_
if
(
transform
&&
memcmp
(
transform
,
&
identity
,
sizeof
(
*
transform
)))
FIXME
(
"Transform is not supported.
\n
"
);
advance
=
font_funcs
->
get_glyph_advance
(
&
fontface
->
IDWriteFontFace5_iface
,
emsize
,
glyph
,
measuring_mode
,
&
has_contours
);
advance
=
fontface_get_glyph_advance
(
fontface
,
emsize
,
glyph
,
measuring_mode
,
&
has_contours
);
if
(
has_contours
)
advance
=
round_metric
(
advance
*
fontface
->
metrics
.
designUnitsPerEm
/
emsize
+
adjustment
);
else
...
...
@@ -1212,11 +1320,13 @@ static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace5 *i
if
(
is_sideways
)
FIXME
(
"sideways mode not supported
\n
"
);
EnterCriticalSection
(
&
fontface
->
cs
);
for
(
i
=
0
;
i
<
glyph_count
;
++
i
)
{
advances
[
i
]
=
fontface_get_design_advance
(
fontface
,
DWRITE_MEASURING_MODE_NATURAL
,
fontface
->
metrics
.
designUnitsPerEm
,
1
.
0
f
,
NULL
,
glyphs
[
i
],
is_sideways
);
}
LeaveCriticalSection
(
&
fontface
->
cs
);
return
S_OK
;
}
...
...
@@ -1243,11 +1353,14 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
}
measuring_mode
=
use_gdi_natural
?
DWRITE_MEASURING_MODE_GDI_NATURAL
:
DWRITE_MEASURING_MODE_GDI_CLASSIC
;
EnterCriticalSection
(
&
fontface
->
cs
);
for
(
i
=
0
;
i
<
glyph_count
;
++
i
)
{
advances
[
i
]
=
fontface_get_design_advance
(
fontface
,
measuring_mode
,
em_size
,
ppdip
,
transform
,
glyphs
[
i
],
is_sideways
);
}
LeaveCriticalSection
(
&
fontface
->
cs
);
return
S_OK
;
}
...
...
@@ -5101,6 +5214,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
fontface
->
stream
=
desc
->
stream
;
IDWriteFontFileStream_AddRef
(
fontface
->
stream
);
InitializeCriticalSection
(
&
fontface
->
cs
);
fontface_cache_init
(
fontface
);
stream_desc
.
stream
=
fontface
->
stream
;
stream_desc
.
face_type
=
desc
->
face_type
;
...
...
@@ -6027,7 +6141,9 @@ float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRIT
if
(
is_sideways
)
FIXME
(
"Sideways mode is not supported.
\n
"
);
EnterCriticalSection
(
&
fontface
->
cs
);
advance
=
fontface_get_design_advance
(
fontface
,
measuring_mode
,
emsize
,
ppdip
,
transform
,
glyph
,
is_sideways
);
LeaveCriticalSection
(
&
fontface
->
cs
);
switch
(
measuring_mode
)
{
...
...
dlls/dwrite/freetype.c
View file @
eef8a44d
...
...
@@ -781,30 +781,25 @@ static BOOL CDECL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
return
ret
;
}
static
INT32
CDECL
freetype_get_glyph_advance
(
void
*
key
,
float
emSize
,
UINT16
index
,
static
INT32
CDECL
freetype_get_glyph_advance
(
font_object_handle
object
,
float
emsize
,
UINT16
glyph
,
DWRITE_MEASURING_MODE
mode
,
BOOL
*
has_contours
)
{
FT
C_ImageTypeRec
imagetype
;
FT_Glyph
glyph
;
INT32
advanc
e
;
FT
_Face
face
=
object
;
INT32
advance
=
0
;
FT_Size
siz
e
;
imagetype
.
face_id
=
key
;
imagetype
.
width
=
0
;
imagetype
.
height
=
emSize
;
imagetype
.
flags
=
FT_LOAD_DEFAULT
;
if
(
mode
==
DWRITE_MEASURING_MODE_NATURAL
)
imagetype
.
flags
|=
FT_LOAD_NO_HINTING
;
*
has_contours
=
FALSE
;
RtlEnterCriticalSection
(
&
freetype_cs
);
if
(
pFTC_ImageCache_Lookup
(
image_cache
,
&
imagetype
,
index
,
&
glyph
,
NULL
)
==
0
)
{
*
has_contours
=
glyph
->
format
==
FT_GLYPH_FORMAT_OUTLINE
&&
((
FT_OutlineGlyph
)
glyph
)
->
outline
.
n_contours
;
advance
=
glyph
->
advance
.
x
>>
16
;
}
else
{
*
has_contours
=
FALSE
;
advance
=
0
;
if
(
!
(
size
=
freetype_set_face_size
(
face
,
emsize
)))
return
0
;
if
(
!
pFT_Load_Glyph
(
face
,
glyph
,
mode
==
DWRITE_MEASURING_MODE_NATURAL
?
FT_LOAD_NO_HINTING
:
0
))
{
advance
=
face
->
glyph
->
advance
.
x
>>
6
;
*
has_contours
=
freetype_glyph_has_contours
(
face
);
}
RtlLeaveCriticalSection
(
&
freetype_cs
);
pFT_Done_Size
(
size
);
return
advance
;
}
...
...
@@ -863,8 +858,8 @@ static UINT16 CDECL null_get_glyph_count(font_object_handle object)
return
0
;
}
static
INT32
CDECL
null_get_glyph_advance
(
void
*
key
,
float
emSize
,
UINT16
index
,
DWRITE_MEASURING_MODE
mode
,
BOOL
*
has_contours
)
static
INT32
CDECL
null_get_glyph_advance
(
font_object_handle
object
,
float
emsize
,
UINT16
glyph
,
DWRITE_MEASURING_MODE
mode
,
BOOL
*
has_contours
)
{
*
has_contours
=
FALSE
;
return
0
;
...
...
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