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
43c16a25
Commit
43c16a25
authored
Sep 25, 2017
by
Nikolay Sivov
Committed by
Alexandre Julliard
Sep 25, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Use single per-process local file loader.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3b18054f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
122 additions
and
78 deletions
+122
-78
dwrite_private.h
dlls/dwrite/dwrite_private.h
+2
-1
font.c
dlls/dwrite/font.c
+74
-52
main.c
dlls/dwrite/main.c
+7
-24
font.c
dlls/dwrite/tests/font.c
+39
-1
No files found.
dlls/dwrite/dwrite_private.h
View file @
43c16a25
...
...
@@ -177,7 +177,8 @@ extern HRESULT get_system_fontcollection(IDWriteFactory5*,IDWriteFontCollection1
extern
HRESULT
get_eudc_fontcollection
(
IDWriteFactory5
*
,
IDWriteFontCollection1
**
)
DECLSPEC_HIDDEN
;
extern
IDWriteTextAnalyzer
*
get_text_analyzer
(
void
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_font_file
(
IDWriteFontFileLoader
*
loader
,
const
void
*
reference_key
,
UINT32
key_size
,
IDWriteFontFile
**
font_file
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_localfontfileloader
(
IDWriteLocalFontFileLoader
**
iface
)
DECLSPEC_HIDDEN
;
extern
void
init_local_fontfile_loader
(
void
)
DECLSPEC_HIDDEN
;
extern
IDWriteFontFileLoader
*
get_local_fontfile_loader
(
void
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_fontface
(
const
struct
fontface_desc
*
,
struct
list
*
,
IDWriteFontFace4
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_font_collection
(
IDWriteFactory5
*
,
IDWriteFontFileEnumerator
*
,
BOOL
,
IDWriteFontCollection1
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_glyphrunanalysis
(
const
struct
glyphrunanalysis_desc
*
,
IDWriteGlyphRunAnalysis
**
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/font.c
View file @
43c16a25
...
...
@@ -497,10 +497,10 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
if
(
!
ref
)
{
UINT32
i
;
factory_lock
(
This
->
factory
);
if
(
This
->
cached
)
{
factory_lock
(
This
->
factory
);
list_remove
(
&
This
->
cached
->
entry
);
factory_unlock
(
This
->
factory
);
heap_free
(
This
->
cached
);
}
...
...
@@ -528,7 +528,6 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
freetype_notify_cacheremove
(
iface
);
factory_unlock
(
This
->
factory
);
IDWriteFactory5_Release
(
This
->
factory
);
heap_free
(
This
);
}
...
...
@@ -4476,8 +4475,11 @@ struct dwrite_localfontfileloader {
LONG
ref
;
struct
list
streams
;
CRITICAL_SECTION
cs
;
};
static
struct
dwrite_localfontfileloader
local_fontfile_loader
;
static
inline
struct
dwrite_localfontfileloader
*
impl_from_IDWriteLocalFontFileLoader
(
IDWriteLocalFontFileLoader
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
dwrite_localfontfileloader
,
IDWriteLocalFontFileLoader_iface
);
...
...
@@ -4491,11 +4493,18 @@ static inline struct dwrite_localfontfilestream *impl_from_IDWriteFontFileStream
static
HRESULT
WINAPI
localfontfilestream_QueryInterface
(
IDWriteFontFileStream
*
iface
,
REFIID
riid
,
void
**
obj
)
{
struct
dwrite_localfontfilestream
*
This
=
impl_from_IDWriteFontFileStream
(
iface
);
TRACE_
(
dwrite_file
)(
"(%p)->(%s %p)
\n
"
,
This
,
debugstr_guid
(
riid
),
obj
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IDWriteFontFileStream
))
if
(
IsEqualIID
(
riid
,
&
IID_IDWriteFontFileStream
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
IDWriteFontFileStream_AddRef
(
iface
);
if
(
InterlockedIncrement
(
&
This
->
ref
)
==
1
)
{
InterlockedDecrement
(
&
This
->
ref
);
*
obj
=
NULL
;
return
E_FAIL
;
}
return
S_OK
;
}
...
...
@@ -4529,7 +4538,11 @@ static ULONG WINAPI localfontfilestream_Release(IDWriteFontFileStream *iface)
if
(
!
ref
)
{
UnmapViewOfFile
(
This
->
file_ptr
);
EnterCriticalSection
(
&
local_fontfile_loader
.
cs
);
release_cached_stream
(
This
->
entry
);
LeaveCriticalSection
(
&
local_fontfile_loader
.
cs
);
heap_free
(
This
);
}
...
...
@@ -4621,7 +4634,9 @@ static HRESULT WINAPI localfontfileloader_QueryInterface(IDWriteLocalFontFileLoa
TRACE
(
"(%p)->(%s %p)
\n
"
,
This
,
debugstr_guid
(
riid
),
obj
);
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IDWriteFontFileLoader
)
||
IsEqualIID
(
riid
,
&
IID_IDWriteLocalFontFileLoader
))
if
(
IsEqualIID
(
riid
,
&
IID_IDWriteLocalFontFileLoader
)
||
IsEqualIID
(
riid
,
&
IID_IDWriteFontFileLoader
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
IDWriteLocalFontFileLoader_AddRef
(
iface
);
...
...
@@ -4649,49 +4664,27 @@ static ULONG WINAPI localfontfileloader_Release(IDWriteLocalFontFileLoader *ifac
TRACE
(
"(%p)->(%d)
\n
"
,
This
,
ref
);
if
(
!
ref
)
{
struct
local_cached_stream
*
stream
,
*
stream2
;
/* This will detach all entries from cache. Entries are released together with streams,
so stream controls cache entry lifetime. */
LIST_FOR_EACH_ENTRY_SAFE
(
stream
,
stream2
,
&
This
->
streams
,
struct
local_cached_stream
,
entry
)
list_init
(
&
stream
->
entry
);
heap_free
(
This
);
}
return
ref
;
}
static
HRESULT
WINAPI
localfontfileloader_CreateStreamFromKey
(
IDWriteLocalFontFileLoader
*
iface
,
const
void
*
key
,
UINT32
key_size
,
IDWriteFontFileS
tream
**
ret
)
static
HRESULT
create_local_cached_stream
(
const
void
*
key
,
UINT32
key_size
,
struct
local_cached_s
tream
**
ret
)
{
struct
dwrite_localfontfileloader
*
This
=
impl_from_IDWriteLocalFontFileLoader
(
iface
);
const
struct
local_refkey
*
refkey
=
key
;
struct
local_cached_stream
*
stream
;
IDWriteFontFileStream
*
filestream
;
HANDLE
file
,
mapping
;
LARGE_INTEGER
size
;
void
*
file_ptr
;
HRESULT
hr
;
TRACE
(
"(%p)->(%p, %i, %p)
\n
"
,
This
,
key
,
key_size
,
ret
);
TRACE
(
"name: %s
\n
"
,
debugstr_w
(
refkey
->
name
));
/* search cache first */
LIST_FOR_EACH_ENTRY
(
stream
,
&
This
->
streams
,
struct
local_cached_stream
,
entry
)
{
if
(
key_size
==
stream
->
key_size
&&
!
memcmp
(
stream
->
key
,
key
,
key_size
))
{
*
ret
=
stream
->
stream
;
IDWriteFontFileStream_AddRef
(
*
ret
);
return
S_OK
;
}
}
HRESULT
hr
=
S_OK
;
*
ret
=
NULL
;
file
=
CreateFileW
(
refkey
->
name
,
GENERIC_READ
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
file
==
INVALID_HANDLE_VALUE
)
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
file
==
INVALID_HANDLE_VALUE
)
{
WARN_
(
dwrite_file
)(
"Failed to open the file %s, error %d.
\n
"
,
debugstr_w
(
refkey
->
name
),
GetLastError
());
return
E_FAIL
;
}
GetFileSizeEx
(
file
,
&
size
);
mapping
=
CreateFileMappingW
(
file
,
NULL
,
PAGE_READONLY
,
0
,
0
,
NULL
);
...
...
@@ -4731,13 +4724,45 @@ static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFi
}
stream
->
stream
=
filestream
;
list_add_head
(
&
This
->
streams
,
&
stream
->
entry
);
*
ret
=
stream
->
stream
;
*
ret
=
stream
;
return
S_OK
;
}
static
HRESULT
WINAPI
localfontfileloader_CreateStreamFromKey
(
IDWriteLocalFontFileLoader
*
iface
,
const
void
*
key
,
UINT32
key_size
,
IDWriteFontFileStream
**
ret
)
{
struct
dwrite_localfontfileloader
*
This
=
impl_from_IDWriteLocalFontFileLoader
(
iface
);
const
struct
local_refkey
*
refkey
=
key
;
struct
local_cached_stream
*
stream
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->(%p, %u, %p)
\n
"
,
This
,
key
,
key_size
,
ret
);
TRACE
(
"name: %s
\n
"
,
debugstr_w
(
refkey
->
name
));
EnterCriticalSection
(
&
This
->
cs
);
*
ret
=
NULL
;
/* search cache first */
LIST_FOR_EACH_ENTRY
(
stream
,
&
This
->
streams
,
struct
local_cached_stream
,
entry
)
{
if
(
key_size
==
stream
->
key_size
&&
!
memcmp
(
stream
->
key
,
key
,
key_size
))
{
IDWriteFontFileStream_QueryInterface
(
stream
->
stream
,
&
IID_IDWriteFontFileStream
,
(
void
**
)
ret
);
break
;
}
}
if
(
*
ret
==
NULL
&&
(
hr
=
create_local_cached_stream
(
key
,
key_size
,
&
stream
))
==
S_OK
)
{
list_add_head
(
&
This
->
streams
,
&
stream
->
entry
);
*
ret
=
stream
->
stream
;
}
LeaveCriticalSection
(
&
This
->
cs
);
return
hr
;
}
static
HRESULT
WINAPI
localfontfileloader_GetFilePathLengthFromKey
(
IDWriteLocalFontFileLoader
*
iface
,
void
const
*
key
,
UINT32
key_size
,
UINT32
*
length
)
{
struct
dwrite_localfontfileloader
*
This
=
impl_from_IDWriteLocalFontFileLoader
(
iface
);
...
...
@@ -4763,12 +4788,13 @@ static HRESULT WINAPI localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFil
return
S_OK
;
}
static
HRESULT
WINAPI
localfontfileloader_GetLastWriteTimeFromKey
(
IDWriteLocalFontFileLoader
*
iface
,
void
const
*
key
,
UINT32
key_size
,
FILETIME
*
writetime
)
static
HRESULT
WINAPI
localfontfileloader_GetLastWriteTimeFromKey
(
IDWriteLocalFontFileLoader
*
iface
,
void
const
*
key
,
UINT32
key_size
,
FILETIME
*
writetime
)
{
struct
dwrite_localfontfileloader
*
This
=
impl_from_IDWriteLocalFontFileLoader
(
iface
);
const
struct
local_refkey
*
refkey
=
key
;
TRACE
(
"(%p)->(%p, %
i
, %p)
\n
"
,
This
,
key
,
key_size
,
writetime
);
TRACE
(
"(%p)->(%p, %
u
, %p)
\n
"
,
This
,
key
,
key_size
,
writetime
);
*
writetime
=
refkey
->
writetime
;
return
S_OK
;
...
...
@@ -4784,22 +4810,18 @@ static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl = {
localfontfileloader_GetLastWriteTimeFromKey
};
HRESULT
create_localfontfileloader
(
IDWriteLocalFontFileLoader
**
ret
)
void
init_local_fontfile_loader
(
void
)
{
struct
dwrite_localfontfileloader
*
This
;
*
ret
=
NULL
;
This
=
heap_alloc
(
sizeof
(
struct
dwrite_localfontfileloader
));
if
(
!
This
)
return
E_OUTOFMEMORY
;
This
->
IDWriteLocalFontFileLoader_iface
.
lpVtbl
=
&
localfontfileloadervtbl
;
This
->
ref
=
1
;
list_init
(
&
This
->
streams
);
local_fontfile_loader
.
IDWriteLocalFontFileLoader_iface
.
lpVtbl
=
&
localfontfileloadervtbl
;
local_fontfile_loader
.
ref
=
1
;
list_init
(
&
local_fontfile_loader
.
streams
);
InitializeCriticalSection
(
&
local_fontfile_loader
.
cs
);
local_fontfile_loader
.
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": localfileloader.lock"
);
}
*
ret
=
&
This
->
IDWriteLocalFontFileLoader_iface
;
return
S_OK
;
IDWriteFontFileLoader
*
get_local_fontfile_loader
(
void
)
{
return
(
IDWriteFontFileLoader
*
)
&
local_fontfile_loader
.
IDWriteLocalFontFileLoader_iface
;
}
HRESULT
get_local_refkey
(
const
WCHAR
*
path
,
const
FILETIME
*
writetime
,
void
**
key
,
UINT32
*
size
)
...
...
dlls/dwrite/main.c
View file @
43c16a25
...
...
@@ -44,6 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hinstDLL
);
init_freetype
();
init_local_fontfile_loader
();
break
;
case
DLL_PROCESS_DETACH
:
if
(
reserved
)
break
;
...
...
@@ -542,7 +543,7 @@ struct dwritefactory {
IDWriteGdiInterop1
*
gdiinterop
;
IDWriteFontFallback
*
fallback
;
IDWrite
LocalFontFileLoader
*
localfontfileloader
;
IDWrite
FontFileLoader
*
localfontfileloader
;
struct
list
localfontfaces
;
struct
list
collection_loaders
;
...
...
@@ -580,9 +581,6 @@ static void release_dwritefactory(struct dwritefactory *factory)
struct
fileloader
*
fileloader
,
*
fileloader2
;
struct
collectionloader
*
loader
,
*
loader2
;
if
(
factory
->
localfontfileloader
)
IDWriteLocalFontFileLoader_Release
(
factory
->
localfontfileloader
);
EnterCriticalSection
(
&
factory
->
cs
);
release_fontface_cache
(
&
factory
->
localfontfaces
);
LeaveCriticalSection
(
&
factory
->
cs
);
...
...
@@ -806,19 +804,12 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory5 *ifa
*
font_file
=
NULL
;
if
(
!
This
->
localfontfileloader
)
{
hr
=
create_localfontfileloader
(
&
This
->
localfontfileloader
);
if
(
FAILED
(
hr
))
return
hr
;
}
/* get a reference key used by local loader */
/* Get a reference key in local file loader format. */
hr
=
get_local_refkey
(
path
,
writetime
,
&
key
,
&
key_size
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
create_font_file
(
(
IDWriteFontFileLoader
*
)
This
->
localfontfileloader
,
key
,
key_size
,
font_file
);
hr
=
create_font_file
(
This
->
localfontfileloader
,
key
,
key_size
,
font_file
);
heap_free
(
key
);
return
hr
;
...
...
@@ -833,9 +824,7 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
*
font_file
=
NULL
;
/* local loader is accepted as well */
if
(
!
loader
||
!
(
factory_get_file_loader
(
This
,
loader
)
||
(
IDWriteFontFileLoader
*
)
This
->
localfontfileloader
==
loader
))
if
(
!
loader
||
!
(
factory_get_file_loader
(
This
,
loader
)
||
This
->
localfontfileloader
==
loader
))
return
E_INVALIDARG
;
return
create_font_file
(
loader
,
reference_key
,
key_size
,
font_file
);
...
...
@@ -875,7 +864,7 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
if
(
FAILED
(
hr
))
return
hr
;
if
(
loader
==
(
IDWriteFontFileLoader
*
)
factory
->
localfontfileloader
)
{
if
(
loader
==
factory
->
localfontfileloader
)
{
fontfaces
=
&
factory
->
localfontfaces
;
IDWriteFontFileLoader_Release
(
loader
);
}
...
...
@@ -1066,9 +1055,6 @@ static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory5 *ifac
if
(
!
loader
)
return
E_INVALIDARG
;
if
((
IDWriteFontFileLoader
*
)
This
->
localfontfileloader
==
loader
)
return
S_OK
;
if
(
factory_get_file_loader
(
This
,
loader
))
return
DWRITE_E_ALREADYREGISTERED
;
...
...
@@ -1094,9 +1080,6 @@ static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory5 *if
if
(
!
loader
)
return
E_INVALIDARG
;
if
((
IDWriteFontFileLoader
*
)
This
->
localfontfileloader
==
loader
)
return
S_OK
;
found
=
factory_get_file_loader
(
This
,
loader
);
if
(
!
found
)
return
E_INVALIDARG
;
...
...
@@ -1789,7 +1772,7 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP
factory
->
IDWriteFactory5_iface
.
lpVtbl
=
type
==
DWRITE_FACTORY_TYPE_SHARED
?
&
shareddwritefactoryvtbl
:
&
dwritefactoryvtbl
;
factory
->
ref
=
1
;
factory
->
localfontfileloader
=
NULL
;
factory
->
localfontfileloader
=
get_local_fontfile_loader
()
;
factory
->
system_collection
=
NULL
;
factory
->
eudc_collection
=
NULL
;
factory
->
gdiinterop
=
NULL
;
...
...
dlls/dwrite/tests/font.c
View file @
43c16a25
...
...
@@ -340,7 +340,7 @@ static IDWriteFactory *create_factory(void)
{
IDWriteFactory
*
factory
;
HRESULT
hr
=
DWriteCreateFactory
(
DWRITE_FACTORY_TYPE_ISOLATED
,
&
IID_IDWriteFactory
,
(
IUnknown
**
)
&
factory
);
ok
(
hr
==
S_OK
,
"
got 0x%08x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"
Failed to create factory, hr %#x.
\n
"
,
hr
);
return
factory
;
}
...
...
@@ -7964,6 +7964,43 @@ static void test_CreateCustomRenderingParams(void)
ok
(
ref
==
0
,
"factory not released, %u
\n
"
,
ref
);
}
static
void
test_localfontfileloader
(
void
)
{
IDWriteFontFileLoader
*
loader
,
*
loader2
;
IDWriteFactory
*
factory
,
*
factory2
;
IDWriteFontFile
*
file
,
*
file2
;
WCHAR
*
path
;
HRESULT
hr
;
ULONG
ref
;
factory
=
create_factory
();
factory2
=
create_factory
();
path
=
create_testfontfile
(
test_fontfile
);
hr
=
IDWriteFactory_CreateFontFileReference
(
factory
,
path
,
NULL
,
&
file
);
ok
(
hr
==
S_OK
,
"Failed to create file reference, hr %#x.
\n
"
,
hr
);
hr
=
IDWriteFactory_CreateFontFileReference
(
factory2
,
path
,
NULL
,
&
file2
);
ok
(
hr
==
S_OK
,
"Failed to create file reference, hr %#x.
\n
"
,
hr
);
ok
(
file
!=
file2
,
"Unexpected file instance.
\n
"
);
hr
=
IDWriteFontFile_GetLoader
(
file
,
&
loader
);
ok
(
hr
==
S_OK
,
"Failed to get loader, hr %#x.
\n
"
,
hr
);
hr
=
IDWriteFontFile_GetLoader
(
file2
,
&
loader2
);
ok
(
hr
==
S_OK
,
"Failed to get loader, hr %#x.
\n
"
,
hr
);
ok
(
loader
==
loader2
,
"Unexpected loader instance
\n
"
);
IDWriteFontFile_Release
(
file
);
IDWriteFontFile_Release
(
file2
);
IDWriteFontFileLoader_Release
(
loader
);
IDWriteFontFileLoader_Release
(
loader2
);
ref
=
IDWriteFactory_Release
(
factory
);
ok
(
ref
==
0
,
"factory not released, %u
\n
"
,
ref
);
DELETE_FONTFILE
(
path
);
}
START_TEST
(
font
)
{
IDWriteFactory
*
factory
;
...
...
@@ -8028,6 +8065,7 @@ START_TEST(font)
test_inmemory_file_loader
();
test_GetGlyphImageFormats
();
test_CreateCustomRenderingParams
();
test_localfontfileloader
();
IDWriteFactory_Release
(
factory
);
}
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