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
105caa28
Commit
105caa28
authored
Mar 28, 2012
by
Huw Davies
Committed by
Alexandre Julliard
Mar 29, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Implement CreateScalableFontResource.
Based on patches by Jeremy White and Dmitry Timoshkov.
parent
7ac623f3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
334 additions
and
25 deletions
+334
-25
font.c
dlls/gdi32/font.c
+7
-21
freetype.c
dlls/gdi32/freetype.c
+326
-2
gdi_private.h
dlls/gdi32/gdi_private.h
+1
-0
font.c
dlls/gdi32/tests/font.c
+0
-2
No files found.
dlls/gdi32/font.c
View file @
105caa28
...
...
@@ -2873,28 +2873,14 @@ BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
/***********************************************************************
* CreateScalableFontResourceW (GDI32.@)
*/
BOOL
WINAPI
CreateScalableFontResourceW
(
DWORD
fHidden
,
LPCWSTR
lpszResourceFile
,
LPCWSTR
lpszFontFile
,
LPCWSTR
lpszCurrentPath
)
{
HANDLE
f
;
FIXME
(
"(%d,%s,%s,%s): stub
\n
"
,
fHidden
,
debugstr_w
(
lpszResourceFile
),
debugstr_w
(
lpszFontFile
),
debugstr_w
(
lpszCurrentPath
)
);
/* fHidden=1 - only visible for the calling app, read-only, not
* enumerated with EnumFonts/EnumFontFamilies
* lpszCurrentPath can be NULL
*/
BOOL
WINAPI
CreateScalableFontResourceW
(
DWORD
hidden
,
LPCWSTR
resource_file
,
LPCWSTR
font_file
,
LPCWSTR
font_path
)
{
TRACE
(
"(%d, %s, %s, %s)
\n
"
,
hidden
,
debugstr_w
(
resource_file
),
debugstr_w
(
font_file
),
debugstr_w
(
font_path
)
);
/* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
if
((
f
=
CreateFileW
(
lpszResourceFile
,
0
,
0
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
0
))
!=
INVALID_HANDLE_VALUE
)
{
CloseHandle
(
f
);
SetLastError
(
ERROR_FILE_EXISTS
);
return
FALSE
;
}
return
FALSE
;
/* create failed */
return
WineEngCreateScalableFontResource
(
hidden
,
resource_file
,
font_file
,
font_path
);
}
/*************************************************************************
...
...
dlls/gdi32/freetype.c
View file @
105caa28
...
...
@@ -278,8 +278,8 @@ typedef struct tagFace {
typedef
struct
tagFamily
{
struct
list
entry
;
const
WCHAR
*
FamilyName
;
const
WCHAR
*
EnglishName
;
WCHAR
*
FamilyName
;
WCHAR
*
EnglishName
;
struct
list
faces
;
struct
list
*
replacement
;
}
Family
;
...
...
@@ -1662,6 +1662,20 @@ static inline void free_face( Face *face )
HeapFree
(
GetProcessHeap
(),
0
,
face
);
}
static
inline
void
free_family
(
Family
*
family
)
{
Face
*
face
,
*
cursor2
;
LIST_FOR_EACH_ENTRY_SAFE
(
face
,
cursor2
,
&
family
->
faces
,
Face
,
entry
)
{
list_remove
(
&
face
->
entry
);
free_face
(
face
);
}
HeapFree
(
GetProcessHeap
(),
0
,
family
->
FamilyName
);
HeapFree
(
GetProcessHeap
(),
0
,
family
->
EnglishName
);
HeapFree
(
GetProcessHeap
(),
0
,
family
);
}
#define ADDFONT_EXTERNAL_FONT 0x01
#define ADDFONT_FORCE_BITMAP 0x02
#define ADDFONT_ADD_TO_CACHE 0x04
...
...
@@ -2729,6 +2743,309 @@ BOOL WineEngRemoveFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
return
TRUE
;
}
static
char
*
get_ttf_file_name
(
LPCWSTR
font_file
,
LPCWSTR
font_path
)
{
WCHAR
*
fullname
;
char
*
unix_name
;
int
file_len
;
if
(
!
font_file
)
return
NULL
;
file_len
=
strlenW
(
font_file
);
if
(
font_path
&&
font_path
[
0
])
{
int
path_len
=
strlenW
(
font_path
);
fullname
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
file_len
+
path_len
+
2
)
*
sizeof
(
WCHAR
)
);
if
(
!
fullname
)
return
NULL
;
memcpy
(
fullname
,
font_path
,
path_len
*
sizeof
(
WCHAR
)
);
fullname
[
path_len
]
=
'\\'
;
memcpy
(
fullname
+
path_len
+
1
,
font_file
,
(
file_len
+
1
)
*
sizeof
(
WCHAR
)
);
}
else
{
int
len
=
GetFullPathNameW
(
font_file
,
0
,
NULL
,
NULL
);
if
(
!
len
)
return
NULL
;
fullname
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
)
);
if
(
!
fullname
)
return
NULL
;
GetFullPathNameW
(
font_file
,
len
,
fullname
,
NULL
);
}
unix_name
=
wine_get_unix_file_name
(
fullname
);
HeapFree
(
GetProcessHeap
(),
0
,
fullname
);
return
unix_name
;
}
#include <pshpack1.h>
struct
fontdir
{
WORD
num_of_resources
;
WORD
res_id
;
WORD
dfVersion
;
DWORD
dfSize
;
CHAR
dfCopyright
[
60
];
WORD
dfType
;
WORD
dfPoints
;
WORD
dfVertRes
;
WORD
dfHorizRes
;
WORD
dfAscent
;
WORD
dfInternalLeading
;
WORD
dfExternalLeading
;
BYTE
dfItalic
;
BYTE
dfUnderline
;
BYTE
dfStrikeOut
;
WORD
dfWeight
;
BYTE
dfCharSet
;
WORD
dfPixWidth
;
WORD
dfPixHeight
;
BYTE
dfPitchAndFamily
;
WORD
dfAvgWidth
;
WORD
dfMaxWidth
;
BYTE
dfFirstChar
;
BYTE
dfLastChar
;
BYTE
dfDefaultChar
;
BYTE
dfBreakChar
;
WORD
dfWidthBytes
;
DWORD
dfDevice
;
DWORD
dfFace
;
DWORD
dfReserved
;
CHAR
szFaceName
[
LF_FACESIZE
];
};
#include <poppack.h>
static
void
GetEnumStructs
(
Face
*
face
,
LPENUMLOGFONTEXW
pelf
,
NEWTEXTMETRICEXW
*
pntm
,
LPDWORD
ptype
);
static
BOOL
get_fontdir
(
const
char
*
unix_name
,
struct
fontdir
*
fd
)
{
FT_Face
ft_face
=
new_ft_face
(
unix_name
,
NULL
,
0
,
0
,
FALSE
);
Face
*
face
;
Family
*
family
;
WCHAR
*
name
,
*
english_name
;
ENUMLOGFONTEXW
elf
;
NEWTEXTMETRICEXW
ntm
;
DWORD
type
;
if
(
!
ft_face
)
return
FALSE
;
face
=
create_face
(
ft_face
,
0
,
unix_name
,
NULL
,
0
,
0
,
FALSE
);
get_family_names
(
ft_face
,
&
name
,
&
english_name
,
FALSE
);
family
=
create_family
(
name
,
english_name
);
insert_face_in_family_list
(
face
,
family
);
pFT_Done_Face
(
ft_face
);
GetEnumStructs
(
face
,
&
elf
,
&
ntm
,
&
type
);
free_family
(
family
);
if
((
type
&
TRUETYPE_FONTTYPE
)
==
0
)
return
FALSE
;
memset
(
fd
,
0
,
sizeof
(
*
fd
)
);
fd
->
num_of_resources
=
1
;
fd
->
res_id
=
0
;
fd
->
dfVersion
=
0x200
;
fd
->
dfSize
=
sizeof
(
*
fd
);
strcpy
(
fd
->
dfCopyright
,
"Wine fontdir"
);
fd
->
dfType
=
0x4003
;
/* 0x0080 set if private */
fd
->
dfPoints
=
ntm
.
ntmTm
.
ntmSizeEM
;
fd
->
dfVertRes
=
72
;
fd
->
dfHorizRes
=
72
;
fd
->
dfAscent
=
ntm
.
ntmTm
.
tmAscent
;
fd
->
dfInternalLeading
=
ntm
.
ntmTm
.
tmInternalLeading
;
fd
->
dfExternalLeading
=
ntm
.
ntmTm
.
tmExternalLeading
;
fd
->
dfItalic
=
ntm
.
ntmTm
.
tmItalic
;
fd
->
dfUnderline
=
ntm
.
ntmTm
.
tmUnderlined
;
fd
->
dfStrikeOut
=
ntm
.
ntmTm
.
tmStruckOut
;
fd
->
dfWeight
=
ntm
.
ntmTm
.
tmWeight
;
fd
->
dfCharSet
=
ntm
.
ntmTm
.
tmCharSet
;
fd
->
dfPixWidth
=
0
;
fd
->
dfPixHeight
=
ntm
.
ntmTm
.
tmHeight
;
fd
->
dfPitchAndFamily
=
ntm
.
ntmTm
.
tmPitchAndFamily
;
fd
->
dfAvgWidth
=
ntm
.
ntmTm
.
tmAveCharWidth
;
fd
->
dfMaxWidth
=
ntm
.
ntmTm
.
tmMaxCharWidth
;
fd
->
dfFirstChar
=
ntm
.
ntmTm
.
tmFirstChar
;
fd
->
dfLastChar
=
ntm
.
ntmTm
.
tmLastChar
;
fd
->
dfDefaultChar
=
ntm
.
ntmTm
.
tmDefaultChar
;
fd
->
dfBreakChar
=
ntm
.
ntmTm
.
tmBreakChar
;
fd
->
dfWidthBytes
=
0
;
fd
->
dfDevice
=
0
;
fd
->
dfFace
=
FIELD_OFFSET
(
struct
fontdir
,
szFaceName
);
fd
->
dfReserved
=
0
;
WideCharToMultiByte
(
CP_ACP
,
0
,
elf
.
elfLogFont
.
lfFaceName
,
-
1
,
fd
->
szFaceName
,
LF_FACESIZE
,
NULL
,
NULL
);
return
TRUE
;
}
#define NE_FFLAGS_LIBMODULE 0x8000
#define NE_OSFLAGS_WINDOWS 0x02
static
const
char
dos_string
[
0x40
]
=
"This is a TrueType resource file"
;
static
const
char
FONTRES
[]
=
{
'F'
,
'O'
,
'N'
,
'T'
,
'R'
,
'E'
,
'S'
,
':'
};
#include <pshpack2.h>
struct
ne_typeinfo
{
WORD
type_id
;
WORD
count
;
DWORD
res
;
};
struct
ne_nameinfo
{
WORD
off
;
WORD
len
;
WORD
flags
;
WORD
id
;
DWORD
res
;
};
struct
rsrc_tab
{
WORD
align
;
struct
ne_typeinfo
fontdir_type
;
struct
ne_nameinfo
fontdir_name
;
struct
ne_typeinfo
scalable_type
;
struct
ne_nameinfo
scalable_name
;
WORD
end_of_rsrc
;
BYTE
fontdir_res_name
[
8
];
};
#include <poppack.h>
static
BOOL
create_fot
(
const
WCHAR
*
resource
,
const
WCHAR
*
font_file
,
const
struct
fontdir
*
fontdir
)
{
BOOL
ret
=
FALSE
;
HANDLE
file
;
DWORD
size
,
written
;
BYTE
*
ptr
,
*
start
;
BYTE
import_name_len
,
res_name_len
,
non_res_name_len
,
font_file_len
;
char
*
font_fileA
,
*
last_part
,
*
ext
;
IMAGE_DOS_HEADER
dos
;
IMAGE_OS2_HEADER
ne
=
{
IMAGE_OS2_SIGNATURE
,
5
,
1
,
0
,
0
,
0
,
NE_FFLAGS_LIBMODULE
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
sizeof
(
ne
),
sizeof
(
ne
),
0
,
0
,
0
,
0
,
0
,
4
,
2
,
NE_OSFLAGS_WINDOWS
,
0
,
0
,
0
,
0
,
0x300
};
struct
rsrc_tab
rsrc_tab
=
{
4
,
{
0x8007
,
1
,
0
},
{
0
,
0
,
0x0c50
,
0x2c
,
0
},
{
0x80cc
,
1
,
0
},
{
0
,
0
,
0x0c50
,
0x8001
,
0
},
0
,
{
7
,
'F'
,
'O'
,
'N'
,
'T'
,
'D'
,
'I'
,
'R'
}
};
memset
(
&
dos
,
0
,
sizeof
(
dos
)
);
dos
.
e_magic
=
IMAGE_DOS_SIGNATURE
;
dos
.
e_lfanew
=
sizeof
(
dos
)
+
sizeof
(
dos_string
);
/* import name is last part\0, resident name is last part without extension
non-resident name is "FONTRES:" + lfFaceName */
font_file_len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
font_file
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
font_fileA
=
HeapAlloc
(
GetProcessHeap
(),
0
,
font_file_len
);
WideCharToMultiByte
(
CP_ACP
,
0
,
font_file
,
-
1
,
font_fileA
,
font_file_len
,
NULL
,
NULL
);
last_part
=
strrchr
(
font_fileA
,
'\\'
);
if
(
last_part
)
last_part
++
;
else
last_part
=
font_fileA
;
import_name_len
=
strlen
(
last_part
)
+
1
;
ext
=
strchr
(
last_part
,
'.'
);
if
(
ext
)
res_name_len
=
ext
-
last_part
;
else
res_name_len
=
import_name_len
-
1
;
non_res_name_len
=
sizeof
(
FONTRES
)
+
strlen
(
fontdir
->
szFaceName
);
ne
.
ne_cbnrestab
=
1
+
non_res_name_len
+
2
+
1
;
/* len + string + (WORD) ord_num + 1 byte eod */
ne
.
ne_restab
=
ne
.
ne_rsrctab
+
sizeof
(
rsrc_tab
);
ne
.
ne_modtab
=
ne
.
ne_imptab
=
ne
.
ne_restab
+
1
+
res_name_len
+
2
+
3
;
/* len + string + (WORD) ord_num + 3 bytes eod */
ne
.
ne_enttab
=
ne
.
ne_imptab
+
1
+
import_name_len
;
/* len + string */
ne
.
ne_cbenttab
=
2
;
ne
.
ne_nrestab
=
ne
.
ne_enttab
+
ne
.
ne_cbenttab
+
2
+
dos
.
e_lfanew
;
/* there are 2 bytes of 0 after entry tab */
rsrc_tab
.
scalable_name
.
off
=
(
ne
.
ne_nrestab
+
ne
.
ne_cbnrestab
+
0xf
)
>>
4
;
rsrc_tab
.
scalable_name
.
len
=
(
font_file_len
+
0xf
)
>>
4
;
rsrc_tab
.
fontdir_name
.
off
=
rsrc_tab
.
scalable_name
.
off
+
rsrc_tab
.
scalable_name
.
len
;
rsrc_tab
.
fontdir_name
.
len
=
(
fontdir
->
dfSize
+
0xf
)
>>
4
;
size
=
(
rsrc_tab
.
fontdir_name
.
off
+
rsrc_tab
.
fontdir_name
.
len
)
<<
4
;
start
=
ptr
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
size
);
if
(
!
ptr
)
{
HeapFree
(
GetProcessHeap
(),
0
,
font_fileA
);
return
FALSE
;
}
memcpy
(
ptr
,
&
dos
,
sizeof
(
dos
)
);
memcpy
(
ptr
+
sizeof
(
dos
),
dos_string
,
sizeof
(
dos_string
)
);
memcpy
(
ptr
+
dos
.
e_lfanew
,
&
ne
,
sizeof
(
ne
)
);
ptr
=
start
+
dos
.
e_lfanew
+
ne
.
ne_rsrctab
;
memcpy
(
ptr
,
&
rsrc_tab
,
sizeof
(
rsrc_tab
)
);
ptr
=
start
+
dos
.
e_lfanew
+
ne
.
ne_restab
;
*
ptr
++
=
res_name_len
;
memcpy
(
ptr
,
last_part
,
res_name_len
);
ptr
=
start
+
dos
.
e_lfanew
+
ne
.
ne_imptab
;
*
ptr
++
=
import_name_len
;
memcpy
(
ptr
,
last_part
,
import_name_len
);
ptr
=
start
+
ne
.
ne_nrestab
;
*
ptr
++
=
non_res_name_len
;
memcpy
(
ptr
,
FONTRES
,
sizeof
(
FONTRES
)
);
memcpy
(
ptr
+
sizeof
(
FONTRES
),
fontdir
->
szFaceName
,
strlen
(
fontdir
->
szFaceName
)
);
ptr
=
start
+
(
rsrc_tab
.
scalable_name
.
off
<<
4
);
memcpy
(
ptr
,
font_fileA
,
font_file_len
);
ptr
=
start
+
(
rsrc_tab
.
fontdir_name
.
off
<<
4
);
memcpy
(
ptr
,
fontdir
,
fontdir
->
dfSize
);
file
=
CreateFileW
(
resource
,
GENERIC_READ
|
GENERIC_WRITE
,
0
,
NULL
,
CREATE_NEW
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
file
!=
INVALID_HANDLE_VALUE
)
{
if
(
WriteFile
(
file
,
start
,
size
,
&
written
,
NULL
)
&&
written
==
size
)
ret
=
TRUE
;
CloseHandle
(
file
);
}
HeapFree
(
GetProcessHeap
(),
0
,
start
);
HeapFree
(
GetProcessHeap
(),
0
,
font_fileA
);
return
ret
;
}
/*************************************************************
* WineEngCreateScalableFontResource
*
*/
BOOL
WineEngCreateScalableFontResource
(
DWORD
hidden
,
LPCWSTR
resource
,
LPCWSTR
font_file
,
LPCWSTR
font_path
)
{
char
*
unix_name
=
get_ttf_file_name
(
font_file
,
font_path
);
struct
fontdir
fontdir
;
BOOL
ret
=
FALSE
;
if
(
!
unix_name
||
!
get_fontdir
(
unix_name
,
&
fontdir
))
SetLastError
(
ERROR_INVALID_PARAMETER
);
else
{
if
(
hidden
)
fontdir
.
dfType
|=
0x80
;
ret
=
create_fot
(
resource
,
font_file
,
&
fontdir
);
}
HeapFree
(
GetProcessHeap
(),
0
,
unix_name
);
return
ret
;
}
static
const
struct
nls_update_font_list
{
UINT
ansi_cp
,
oem_cp
;
...
...
@@ -7478,6 +7795,13 @@ HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD
return
NULL
;
}
BOOL
WineEngCreateScalableFontResource
(
DWORD
hidden
,
LPCWSTR
resource
,
LPCWSTR
font_file
,
LPCWSTR
font_path
)
{
FIXME
(
"stub
\n
"
);
return
FALSE
;
}
BOOL
WineEngGetLinkedHFont
(
DC
*
dc
,
WCHAR
c
,
HFONT
*
new_hfont
,
UINT
*
glyph
)
{
return
FALSE
;
...
...
dlls/gdi32/gdi_private.h
View file @
105caa28
...
...
@@ -289,6 +289,7 @@ typedef struct
extern
INT
WineEngAddFontResourceEx
(
LPCWSTR
,
DWORD
,
PVOID
)
DECLSPEC_HIDDEN
;
extern
HANDLE
WineEngAddFontMemResourceEx
(
PVOID
,
DWORD
,
PVOID
,
LPDWORD
)
DECLSPEC_HIDDEN
;
extern
BOOL
WineEngCreateScalableFontResource
(
DWORD
,
LPCWSTR
,
LPCWSTR
,
LPCWSTR
)
DECLSPEC_HIDDEN
;
extern
BOOL
WineEngDestroyFontInstance
(
HFONT
handle
)
DECLSPEC_HIDDEN
;
extern
BOOL
WineEngGetLinkedHFont
(
DC
*
dc
,
WCHAR
c
,
HFONT
*
new_hfont
,
UINT
*
glyph
)
DECLSPEC_HIDDEN
;
extern
BOOL
WineEngInit
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/gdi32/tests/font.c
View file @
105caa28
...
...
@@ -3989,13 +3989,11 @@ static void test_CreateScalableFontResource(void)
SetLastError
(
0xdeadbeef
);
ret
=
CreateScalableFontResource
(
0
,
fot_name
,
"random file name"
,
tmp_path
);
ok
(
!
ret
,
"CreateScalableFontResource() should fail
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"not expected error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
CreateScalableFontResource
(
0
,
fot_name
,
NULL
,
ttf_name
);
ok
(
!
ret
,
"CreateScalableFontResource() should fail
\n
"
);
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"not expected error %d
\n
"
,
GetLastError
());
ret
=
DeleteFile
(
fot_name
);
...
...
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