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
8794f8f7
Commit
8794f8f7
authored
Feb 16, 2011
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Feb 22, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Implement in-memory font storage.
parent
130e38e0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
143 additions
and
2 deletions
+143
-2
font.c
dlls/gdiplus/font.c
+143
-2
No files found.
dlls/gdiplus/font.c
View file @
8794f8f7
...
...
@@ -930,17 +930,158 @@ GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection,
return
NotImplemented
;
}
/* Copied from msi/font.c */
typedef
struct
_tagTT_OFFSET_TABLE
{
USHORT
uMajorVersion
;
USHORT
uMinorVersion
;
USHORT
uNumOfTables
;
USHORT
uSearchRange
;
USHORT
uEntrySelector
;
USHORT
uRangeShift
;
}
TT_OFFSET_TABLE
;
typedef
struct
_tagTT_TABLE_DIRECTORY
{
char
szTag
[
4
];
/* table name */
ULONG
uCheckSum
;
/* Check sum */
ULONG
uOffset
;
/* Offset from beginning of file */
ULONG
uLength
;
/* length of the table in bytes */
}
TT_TABLE_DIRECTORY
;
typedef
struct
_tagTT_NAME_TABLE_HEADER
{
USHORT
uFSelector
;
/* format selector. Always 0 */
USHORT
uNRCount
;
/* Name Records count */
USHORT
uStorageOffset
;
/* Offset for strings storage,
* from start of the table */
}
TT_NAME_TABLE_HEADER
;
#define NAME_ID_FULL_FONT_NAME 4
#define NAME_ID_VERSION 5
typedef
struct
_tagTT_NAME_RECORD
{
USHORT
uPlatformID
;
USHORT
uEncodingID
;
USHORT
uLanguageID
;
USHORT
uNameID
;
USHORT
uStringLength
;
USHORT
uStringOffset
;
/* from start of storage area */
}
TT_NAME_RECORD
;
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
/*
* Code based off of code located here
* http://www.codeproject.com/gdi/fontnamefromfile.asp
*/
WCHAR
*
load_ttf_name_id
(
const
char
*
mem
,
DWORD_PTR
size
,
DWORD
id
,
WCHAR
*
ret
,
DWORD
len
)
{
const
TT_TABLE_DIRECTORY
*
tblDir
;
TT_OFFSET_TABLE
ttOffsetTable
;
TT_NAME_TABLE_HEADER
ttNTHeader
;
TT_NAME_RECORD
ttRecord
;
DWORD
ofs
,
pos
;
int
i
;
if
(
sizeof
(
TT_OFFSET_TABLE
)
>
size
)
return
NULL
;
ttOffsetTable
=
*
(
TT_OFFSET_TABLE
*
)
mem
;
ttOffsetTable
.
uNumOfTables
=
SWAPWORD
(
ttOffsetTable
.
uNumOfTables
);
ttOffsetTable
.
uMajorVersion
=
SWAPWORD
(
ttOffsetTable
.
uMajorVersion
);
ttOffsetTable
.
uMinorVersion
=
SWAPWORD
(
ttOffsetTable
.
uMinorVersion
);
if
(
ttOffsetTable
.
uMajorVersion
!=
1
||
ttOffsetTable
.
uMinorVersion
!=
0
)
return
NULL
;
pos
=
sizeof
(
ttOffsetTable
);
for
(
i
=
0
;
i
<
ttOffsetTable
.
uNumOfTables
;
i
++
)
{
tblDir
=
(
const
TT_TABLE_DIRECTORY
*
)
&
mem
[
pos
];
pos
+=
sizeof
(
*
tblDir
);
if
(
memcmp
(
tblDir
->
szTag
,
"name"
,
4
)
==
0
)
{
ofs
=
SWAPLONG
(
tblDir
->
uOffset
);
break
;
}
}
if
(
i
>=
ttOffsetTable
.
uNumOfTables
)
return
NULL
;
pos
=
ofs
+
sizeof
(
ttNTHeader
);
if
(
pos
>
size
)
return
NULL
;
ttNTHeader
=
*
(
TT_NAME_TABLE_HEADER
*
)
&
mem
[
ofs
];
ttNTHeader
.
uNRCount
=
SWAPWORD
(
ttNTHeader
.
uNRCount
);
ttNTHeader
.
uStorageOffset
=
SWAPWORD
(
ttNTHeader
.
uStorageOffset
);
for
(
i
=
0
;
i
<
ttNTHeader
.
uNRCount
;
i
++
)
{
ttRecord
=
*
(
TT_NAME_RECORD
*
)
&
mem
[
pos
];
pos
+=
sizeof
(
ttRecord
);
if
(
pos
>
size
)
return
NULL
;
ttRecord
.
uNameID
=
SWAPWORD
(
ttRecord
.
uNameID
);
if
(
ttRecord
.
uNameID
==
id
)
{
const
char
*
buf
;
ttRecord
.
uStringLength
=
SWAPWORD
(
ttRecord
.
uStringLength
);
ttRecord
.
uStringOffset
=
SWAPWORD
(
ttRecord
.
uStringOffset
);
if
(
ofs
+
ttRecord
.
uStringOffset
+
ttNTHeader
.
uStorageOffset
+
ttRecord
.
uStringLength
>
size
)
return
NULL
;
buf
=
mem
+
ofs
+
ttRecord
.
uStringOffset
+
ttNTHeader
.
uStorageOffset
;
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
buf
,
ttRecord
.
uStringLength
,
ret
,
len
-
1
);
ret
[
len
]
=
0
;
return
ret
;
}
}
return
NULL
;
}
static
INT
CALLBACK
add_font_proc
(
const
LOGFONTW
*
lfw
,
const
TEXTMETRICW
*
ntm
,
DWORD
type
,
LPARAM
lParam
);
/*****************************************************************************
* GdipPrivateAddMemoryFont [GDIPLUS.@]
*/
GpStatus
WINGDIPAPI
GdipPrivateAddMemoryFont
(
GpFontCollection
*
fontCollection
,
GDIPCONST
void
*
memory
,
INT
length
)
{
FIXME
(
"%p, %p, %d
\n
"
,
fontCollection
,
memory
,
length
);
WCHAR
buf
[
32
],
*
name
;
DWORD
count
=
0
;
HANDLE
font
;
TRACE
(
"%p, %p, %d
\n
"
,
fontCollection
,
memory
,
length
);
if
(
!
(
fontCollection
&&
memory
&&
length
)
)
if
(
!
fontCollection
||
!
memory
||
!
length
)
return
InvalidParameter
;
name
=
load_ttf_name_id
(
memory
,
length
,
NAME_ID_FULL_FONT_NAME
,
buf
,
sizeof
(
buf
)
/
sizeof
(
*
buf
));
if
(
!
name
)
return
OutOfMemory
;
font
=
AddFontMemResourceEx
((
void
*
)
memory
,
length
,
NULL
,
&
count
);
TRACE
(
"%s: %p/%u
\n
"
,
debugstr_w
(
name
),
font
,
count
);
if
(
!
font
||
!
count
)
return
InvalidParameter
;
if
(
count
)
{
HDC
hdc
;
LOGFONTW
lfw
;
hdc
=
GetDC
(
0
);
lfw
.
lfCharSet
=
DEFAULT_CHARSET
;
lstrcpyW
(
lfw
.
lfFaceName
,
name
);
lfw
.
lfPitchAndFamily
=
0
;
if
(
!
EnumFontFamiliesExW
(
hdc
,
&
lfw
,
add_font_proc
,
(
LPARAM
)
fontCollection
,
0
))
{
ReleaseDC
(
0
,
hdc
);
return
OutOfMemory
;
}
ReleaseDC
(
0
,
hdc
);
}
return
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