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
b3ad9000
Commit
b3ad9000
authored
Dec 07, 2021
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Move glyph box cache to PE side.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4ae2058e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
68 deletions
+88
-68
dwrite_private.h
dlls/dwrite/dwrite_private.h
+1
-1
font.c
dlls/dwrite/font.c
+57
-39
freetype.c
dlls/dwrite/freetype.c
+30
-28
No files found.
dlls/dwrite/dwrite_private.h
View file @
b3ad9000
...
...
@@ -734,7 +734,7 @@ struct font_backend_funcs
UINT16
(
CDECL
*
get_glyph_count
)(
font_object_handle
object
);
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
)(
void
*
key
,
struct
dwrite_glyphbitmap
*
bitmap_desc
);
void
(
CDECL
*
get_glyph_bbox
)(
font_object_handle
object
,
struct
dwrite_glyphbitmap
*
bitmap_desc
);
BOOL
(
CDECL
*
get_glyph_bitmap
)(
void
*
key
,
struct
dwrite_glyphbitmap
*
bitmap_desc
);
void
(
CDECL
*
get_design_glyph_metrics
)(
font_object_handle
object
,
UINT16
upem
,
UINT16
ascent
,
unsigned
int
simulations
,
UINT16
glyph
,
DWRITE_GLYPH_METRICS
*
metrics
);
...
...
dlls/dwrite/font.c
View file @
b3ad9000
...
...
@@ -47,11 +47,6 @@ static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f;
static
const
struct
font_backend_funcs
*
font_funcs
;
void
dwrite_fontface_get_glyph_bbox
(
IDWriteFontFace
*
fontface
,
struct
dwrite_glyphbitmap
*
bitmap
)
{
font_funcs
->
get_glyph_bbox
(
fontface
,
bitmap
);
}
struct
cache_key
{
float
size
;
...
...
@@ -65,40 +60,28 @@ struct cache_entry
struct
list
mru
;
struct
cache_key
key
;
float
advance
;
RECT
bbox
;
unsigned
int
has_contours
:
1
;
unsigned
int
has_advance
:
1
;
unsigned
int
has_bbox
:
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
)
static
struct
cache_entry
*
fontface_get_cache_entry
(
struct
dwrite_fontface
*
fontface
,
const
struct
cache_key
*
key
)
{
struct
cache_key
key
=
{
.
size
=
fontsize
,
.
glyph
=
glyph
,
.
mode
=
mode
};
struct
cache_entry
*
entry
,
*
old_entry
;
struct
wine_rb_entry
*
e
;
size_t
size
;
BOOL
value
;
if
(
!
(
e
ntry
=
fontface_get_cache_entry
(
fontface
,
&
key
)))
if
(
!
(
e
=
wine_rb_get
(
&
fontface
->
cache
.
tree
,
key
)))
{
if
(
!
(
entry
=
calloc
(
1
,
sizeof
(
*
entry
))))
return
0
.
0
f
;
entry
->
key
=
key
;
if
(
!
(
entry
=
calloc
(
1
,
sizeof
(
*
entry
))))
return
NULL
;
entry
->
key
=
*
key
;
list_init
(
&
entry
->
mru
)
;
size
=
fontface_get_cache_entry_size
(
entry
);
if
((
fontface
->
cache
.
size
+
size
>
fontface
->
cache
.
max_size
)
&&
!
list_empty
(
&
fontface
->
cache
.
mru
))
...
...
@@ -110,16 +93,33 @@ static float fontface_get_glyph_advance(struct dwrite_fontface *fontface, float
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
;
free
(
entry
);
return
NULL
;
}
fontface
->
cache
.
size
+=
size
;
}
else
entry
=
WINE_RB_ENTRY_VALUE
(
e
,
struct
cache_entry
,
entry
);
list_remove
(
&
entry
->
mru
);
list_add_head
(
&
fontface
->
cache
.
mru
,
&
entry
->
mru
);
return
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
;
BOOL
value
;
if
(
!
(
entry
=
fontface_get_cache_entry
(
fontface
,
&
key
)))
return
0
.
0
f
;
if
(
!
entry
->
has_advance
)
{
...
...
@@ -132,6 +132,32 @@ static float fontface_get_glyph_advance(struct dwrite_fontface *fontface, float
return
entry
->
advance
;
}
void
dwrite_fontface_get_glyph_bbox
(
IDWriteFontFace
*
iface
,
struct
dwrite_glyphbitmap
*
bitmap
)
{
struct
cache_key
key
=
{
.
size
=
bitmap
->
emsize
,
.
glyph
=
bitmap
->
glyph
,
.
mode
=
DWRITE_MEASURING_MODE_NATURAL
};
struct
dwrite_fontface
*
fontface
=
unsafe_impl_from_IDWriteFontFace
(
iface
);
struct
cache_entry
*
entry
;
EnterCriticalSection
(
&
fontface
->
cs
);
/* For now bypass cache for transformed cases. */
if
(
bitmap
->
m
&&
memcmp
(
bitmap
->
m
,
&
identity
,
sizeof
(
*
bitmap
->
m
)))
{
font_funcs
->
get_glyph_bbox
(
fontface
->
get_font_object
(
fontface
),
bitmap
);
}
else
if
((
entry
=
fontface_get_cache_entry
(
fontface
,
&
key
)))
{
if
(
entry
->
has_bbox
)
bitmap
->
bbox
=
entry
->
bbox
;
else
{
font_funcs
->
get_glyph_bbox
(
fontface
->
get_font_object
(
fontface
),
bitmap
);
entry
->
bbox
=
bitmap
->
bbox
;
entry
->
has_bbox
=
1
;
}
}
LeaveCriticalSection
(
&
fontface
->
cs
);
}
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
);
...
...
@@ -5819,8 +5845,6 @@ static UINT32 get_glyph_bitmap_pitch(DWRITE_RENDERING_MODE1 rendering_mode, INT
static
void
glyphrunanalysis_get_texturebounds
(
struct
dwrite_glyphrunanalysis
*
analysis
,
RECT
*
bounds
)
{
struct
dwrite_glyphbitmap
glyph_bitmap
;
IDWriteFontFace4
*
fontface
;
HRESULT
hr
;
UINT32
i
;
if
(
analysis
->
flags
&
RUNANALYSIS_BOUNDS_READY
)
{
...
...
@@ -5831,12 +5855,8 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
if
(
analysis
->
run
.
isSideways
)
FIXME
(
"sideways runs are not supported.
\n
"
);
hr
=
IDWriteFontFace_QueryInterface
(
analysis
->
run
.
fontFace
,
&
IID_IDWriteFontFace4
,
(
void
**
)
&
fontface
);
if
(
FAILED
(
hr
))
WARN
(
"failed to get IDWriteFontFace4, 0x%08x
\n
"
,
hr
);
memset
(
&
glyph_bitmap
,
0
,
sizeof
(
glyph_bitmap
));
glyph_bitmap
.
simulations
=
IDWriteFontFace
4_GetSimulations
(
fontf
ace
);
glyph_bitmap
.
simulations
=
IDWriteFontFace
_GetSimulations
(
analysis
->
run
.
fontF
ace
);
glyph_bitmap
.
emsize
=
analysis
->
run
.
fontEmSize
;
glyph_bitmap
.
nohint
=
is_natural_rendering_mode
(
analysis
->
rendering_mode
);
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
...
...
@@ -5847,7 +5867,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
UINT32
bitmap_size
;
glyph_bitmap
.
glyph
=
analysis
->
run
.
glyphIndices
[
i
];
font_funcs
->
get_glyph_bbox
(
fontf
ace
,
&
glyph_bitmap
);
dwrite_fontface_get_glyph_bbox
(
analysis
->
run
.
fontF
ace
,
&
glyph_bitmap
);
bitmap_size
=
get_glyph_bitmap_pitch
(
analysis
->
rendering_mode
,
bbox
->
right
-
bbox
->
left
)
*
(
bbox
->
bottom
-
bbox
->
top
);
...
...
@@ -5858,8 +5878,6 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
UnionRect
(
&
analysis
->
bounds
,
&
analysis
->
bounds
,
bbox
);
}
IDWriteFontFace4_Release
(
fontface
);
analysis
->
flags
|=
RUNANALYSIS_BOUNDS_READY
;
*
bounds
=
analysis
->
bounds
;
}
...
...
@@ -5946,7 +5964,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
BOOL
is_1bpp
;
glyph_bitmap
.
glyph
=
analysis
->
run
.
glyphIndices
[
i
];
font_funcs
->
get_glyph_bbox
(
fontf
ace
,
&
glyph_bitmap
);
dwrite_fontface_get_glyph_bbox
(
analysis
->
run
.
fontF
ace
,
&
glyph_bitmap
);
if
(
IsRectEmpty
(
bbox
))
continue
;
...
...
dlls/dwrite/freetype.c
View file @
b3ad9000
...
...
@@ -76,6 +76,7 @@ MAKE_FUNCPTR(FT_Done_FreeType);
MAKE_FUNCPTR
(
FT_Done_Glyph
);
MAKE_FUNCPTR
(
FT_Done_Size
);
MAKE_FUNCPTR
(
FT_Get_First_Char
);
MAKE_FUNCPTR
(
FT_Get_Glyph
);
MAKE_FUNCPTR
(
FT_Get_Kerning
);
MAKE_FUNCPTR
(
FT_Get_Sfnt_Table
);
MAKE_FUNCPTR
(
FT_Glyph_Copy
);
...
...
@@ -184,6 +185,7 @@ static BOOL init_freetype(void)
LOAD_FUNCPTR
(
FT_Done_Glyph
)
LOAD_FUNCPTR
(
FT_Done_Size
)
LOAD_FUNCPTR
(
FT_Get_First_Char
)
LOAD_FUNCPTR
(
FT_Get_Glyph
)
LOAD_FUNCPTR
(
FT_Get_Kerning
)
LOAD_FUNCPTR
(
FT_Get_Sfnt_Table
)
LOAD_FUNCPTR
(
FT_Glyph_Copy
)
...
...
@@ -572,7 +574,7 @@ static BOOL is_face_scalable(void *key)
return
FALSE
;
}
static
BOOL
get_glyph_transform
(
void
*
key
,
struct
dwrite_glyphbitmap
*
bitmap
,
FT_Matrix
*
ret
)
static
BOOL
get_glyph_transform
(
struct
dwrite_glyphbitmap
*
bitmap
,
FT_Matrix
*
ret
)
{
FT_Matrix
m
;
...
...
@@ -583,7 +585,7 @@ static BOOL get_glyph_transform(void *key, struct dwrite_glyphbitmap *bitmap, FT
/* Some fonts provide mostly bitmaps and very few outlines, for example for .notdef.
Disable transform if that's the case. */
if
(
!
is_face_scalable
(
key
)
||
(
!
bitmap
->
m
&&
!
bitmap
->
simulations
)
)
if
(
!
bitmap
->
m
&&
!
bitmap
->
simulations
)
return
FALSE
;
if
(
bitmap
->
simulations
&
DWRITE_FONT_SIMULATIONS_OBLIQUE
)
{
...
...
@@ -602,42 +604,42 @@ static BOOL get_glyph_transform(void *key, struct dwrite_glyphbitmap *bitmap, FT
return
TRUE
;
}
static
void
CDECL
freetype_get_glyph_bbox
(
void
*
key
,
struct
dwrite_glyphbitmap
*
bitmap
)
static
void
CDECL
freetype_get_glyph_bbox
(
font_object_handle
object
,
struct
dwrite_glyphbitmap
*
bitmap
)
{
FTC_ImageTypeRec
imagetype
;
FT_Face
face
=
object
;
FT_Glyph
glyph
=
NULL
;
FT_BBox
bbox
=
{
0
};
BOOL
needs_transform
;
FT_Glyph
glyph
;
FT_Matrix
m
;
FT_Size
size
;
RtlEnterCriticalSection
(
&
freetype_cs
);
SetRectEmpty
(
&
bitmap
->
bbox
);
needs_transform
=
get_glyph_transform
(
key
,
bitmap
,
&
m
);
if
(
!
(
size
=
freetype_set_face_size
(
face
,
bitmap
->
emsize
)))
return
;
imagetype
.
face_id
=
key
;
imagetype
.
width
=
0
;
imagetype
.
height
=
bitmap
->
emsize
;
imagetype
.
flags
=
needs_transform
?
FT_LOAD_NO_BITMAP
:
FT_LOAD_DEFAULT
;
needs_transform
=
FT_IS_SCALABLE
(
face
)
&&
get_glyph_transform
(
bitmap
,
&
m
);
if
(
pFTC_ImageCache_Lookup
(
image_cache
,
&
imagetype
,
bitmap
->
glyph
,
&
glyph
,
NULL
)
==
0
)
{
if
(
needs_transform
)
{
FT_Glyph
glyph_copy
;
if
(
pFT_Load_Glyph
(
face
,
bitmap
->
glyph
,
needs_transform
?
FT_LOAD_NO_BITMAP
:
0
))
{
WARN
(
"Failed to load glyph %u.
\n
"
,
bitmap
->
glyph
);
pFT_Done_Size
(
size
);
return
;
}
if
(
pFT_Glyph_Copy
(
glyph
,
&
glyph_copy
)
==
0
)
{
if
(
bitmap
->
simulations
&
DWRITE_FONT_SIMULATIONS_BOLD
)
embolden_glyph
(
glyph_copy
,
bitmap
->
emsize
);
pFT_Get_Glyph
(
face
->
glyph
,
&
glyph
);
if
(
needs_transform
)
{
if
(
bitmap
->
simulations
&
DWRITE_FONT_SIMULATIONS_BOLD
)
embolden_glyph
(
glyph
,
bitmap
->
emsize
);
/* Includes oblique and user transform. */
pFT_Glyph_Transform
(
glyph_copy
,
&
m
,
NULL
);
pFT_Glyph_Get_CBox
(
glyph_copy
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
pFT_Done_Glyph
(
glyph_copy
);
}
}
else
pFT_Glyph_Get_CBox
(
glyph
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
/* Includes oblique and user transform. */
pFT_Glyph_Transform
(
glyph
,
&
m
,
NULL
);
}
RtlLeaveCriticalSection
(
&
freetype_cs
);
pFT_Glyph_Get_CBox
(
glyph
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
pFT_Done_Glyph
(
glyph
);
pFT_Done_Size
(
size
);
/* flip Y axis */
SetRect
(
&
bitmap
->
bbox
,
bbox
.
xMin
,
-
bbox
.
yMax
,
bbox
.
xMax
,
-
bbox
.
yMin
);
...
...
@@ -744,7 +746,7 @@ static BOOL CDECL freetype_get_glyph_bitmap(void *key, struct dwrite_glyphbitmap
RtlEnterCriticalSection
(
&
freetype_cs
);
needs_transform
=
get_glyph_transform
(
key
,
bitmap
,
&
m
);
needs_transform
=
is_face_scalable
(
key
)
&&
get_glyph_transform
(
bitmap
,
&
m
);
imagetype
.
face_id
=
key
;
imagetype
.
width
=
0
;
...
...
@@ -865,7 +867,7 @@ static INT32 CDECL null_get_glyph_advance(font_object_handle object, float emsiz
return
0
;
}
static
void
CDECL
null_get_glyph_bbox
(
void
*
key
,
struct
dwrite_glyphbitmap
*
bitmap
)
static
void
CDECL
null_get_glyph_bbox
(
font_object_handle
object
,
struct
dwrite_glyphbitmap
*
bitmap
)
{
SetRectEmpty
(
&
bitmap
->
bbox
);
}
...
...
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