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
addcf866
Commit
addcf866
authored
Oct 09, 2008
by
Hans Leidekker
Committed by
Alexandre Julliard
Oct 10, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
usp10: Store glyph mappings and widths in the script cache.
parent
fa6a31ab
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
152 additions
and
114 deletions
+152
-114
usp10.c
dlls/usp10/tests/usp10.c
+10
-1
usp10.c
dlls/usp10/usp10.c
+142
-113
No files found.
dlls/usp10/tests/usp10.c
View file @
addcf866
...
@@ -61,13 +61,22 @@ static void test_ScriptShape(HDC hdc)
...
@@ -61,13 +61,22 @@ static void test_ScriptShape(HDC hdc)
hr
=
ScriptShape
(
hdc
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
NULL
);
hr
=
ScriptShape
(
hdc
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"ScriptShape should return E_INVALIDARG not %08x
\n
"
,
hr
);
ok
(
hr
==
E_INVALIDARG
,
"ScriptShape should return E_INVALIDARG not %08x
\n
"
,
hr
);
hr
=
ScriptShape
(
NULL
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
&
nb
);
ok
(
hr
==
E_PENDING
,
"ScriptShape should return E_PENDING not %08x
\n
"
,
hr
);
hr
=
ScriptShape
(
hdc
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
&
nb
);
hr
=
ScriptShape
(
hdc
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
&
nb
);
ok
(
!
hr
,
"ScriptShape should return S_OK not %08x
\n
"
,
hr
);
ok
(
!
hr
,
"ScriptShape should return S_OK not %08x
\n
"
,
hr
);
ok
(
items
[
0
].
a
.
fNoGlyphIndex
==
FALSE
,
"fNoGlyphIndex TRUE
\n
"
);
ok
(
items
[
0
].
a
.
fNoGlyphIndex
==
FALSE
,
"fNoGlyphIndex TRUE
\n
"
);
hr
=
ScriptShape
(
NULL
,
&
sc
,
test1
,
4
,
4
,
&
items
[
0
].
a
,
glyphs
,
NULL
,
attrs
,
&
nb
);
ok
(
!
hr
,
"ScriptShape should return S_OK not %08x
\n
"
,
hr
);
hr
=
ScriptPlace
(
hdc
,
&
sc
,
glyphs
,
4
,
NULL
,
&
items
[
0
].
a
,
widths
,
NULL
,
NULL
);
hr
=
ScriptPlace
(
hdc
,
&
sc
,
glyphs
,
4
,
NULL
,
&
items
[
0
].
a
,
widths
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"ScriptPlace should return E_INVALIDARG not %08x
\n
"
,
hr
);
ok
(
hr
==
E_INVALIDARG
,
"ScriptPlace should return E_INVALIDARG not %08x
\n
"
,
hr
);
hr
=
ScriptPlace
(
NULL
,
&
sc
,
glyphs
,
4
,
attrs
,
&
items
[
0
].
a
,
widths
,
NULL
,
NULL
);
ok
(
hr
==
E_PENDING
,
"ScriptPlace should return E_PENDING not %08x
\n
"
,
hr
);
hr
=
ScriptPlace
(
hdc
,
&
sc
,
glyphs
,
4
,
attrs
,
&
items
[
0
].
a
,
widths
,
NULL
,
NULL
);
hr
=
ScriptPlace
(
hdc
,
&
sc
,
glyphs
,
4
,
attrs
,
&
items
[
0
].
a
,
widths
,
NULL
,
NULL
);
ok
(
!
hr
,
"ScriptPlace should return S_OK not %08x
\n
"
,
hr
);
ok
(
!
hr
,
"ScriptPlace should return S_OK not %08x
\n
"
,
hr
);
ok
(
items
[
0
].
a
.
fNoGlyphIndex
==
FALSE
,
"fNoGlyphIndex TRUE
\n
"
);
ok
(
items
[
0
].
a
.
fNoGlyphIndex
==
FALSE
,
"fNoGlyphIndex TRUE
\n
"
);
...
@@ -1394,7 +1403,7 @@ START_TEST(usp10)
...
@@ -1394,7 +1403,7 @@ START_TEST(usp10)
ok
(
hdc
!=
NULL
,
"HDC failed to be created %p
\n
"
,
hdc
);
ok
(
hdc
!=
NULL
,
"HDC failed to be created %p
\n
"
,
hdc
);
memset
(
&
lf
,
0
,
sizeof
(
LOGFONTA
));
memset
(
&
lf
,
0
,
sizeof
(
LOGFONTA
));
lstrcpyA
(
lf
.
lfFaceName
,
"
Symbol
"
);
lstrcpyA
(
lf
.
lfFaceName
,
"
Tahoma
"
);
lf
.
lfHeight
=
10
;
lf
.
lfHeight
=
10
;
lf
.
lfWeight
=
3
;
lf
.
lfWeight
=
3
;
lf
.
lfWidth
=
10
;
lf
.
lfWidth
=
10
;
...
...
dlls/usp10/usp10.c
View file @
addcf866
...
@@ -138,10 +138,16 @@ static const SCRIPT_PROPERTIES *script_props[] =
...
@@ -138,10 +138,16 @@ static const SCRIPT_PROPERTIES *script_props[] =
&
props
[
73
]
&
props
[
73
]
};
};
#define GLYPH_BLOCK_SHIFT 8
#define GLYPH_BLOCK_SIZE (1UL << GLYPH_BLOCK_SHIFT)
#define GLYPH_BLOCK_MASK (GLYPH_BLOCK_SIZE - 1)
#define GLYPH_MAX 65536
typedef
struct
{
typedef
struct
{
HDC
hdc
;
LOGFONTW
lf
;
LOGFONTW
lf
;
TEXTMETRICW
tm
;
TEXTMETRICW
tm
;
WORD
*
glyphs
[
GLYPH_MAX
/
GLYPH_BLOCK_SIZE
];
ABC
*
widths
[
GLYPH_MAX
/
GLYPH_BLOCK_SIZE
];
}
ScriptCache
;
}
ScriptCache
;
typedef
struct
{
typedef
struct
{
...
@@ -155,6 +161,7 @@ typedef struct {
...
@@ -155,6 +161,7 @@ typedef struct {
}
StringGlyphs
;
}
StringGlyphs
;
typedef
struct
{
typedef
struct
{
HDC
hdc
;
BOOL
invalid
;
BOOL
invalid
;
int
clip_len
;
int
clip_len
;
ScriptCache
*
sc
;
ScriptCache
*
sc
;
...
@@ -187,71 +194,80 @@ static inline BOOL heap_free(LPVOID mem)
...
@@ -187,71 +194,80 @@ static inline BOOL heap_free(LPVOID mem)
return
HeapFree
(
GetProcessHeap
(),
0
,
mem
);
return
HeapFree
(
GetProcessHeap
(),
0
,
mem
);
}
}
static
HDC
get_cache_hdc
(
SCRIPT_CACHE
*
psc
)
static
inline
WCHAR
get_cache_default_char
(
SCRIPT_CACHE
*
psc
)
{
return
((
ScriptCache
*
)
*
psc
)
->
hdc
;
}
static
WCHAR
get_cache_default_char
(
SCRIPT_CACHE
*
psc
)
{
{
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmDefaultChar
;
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmDefaultChar
;
}
}
static
LONG
get_cache_height
(
SCRIPT_CACHE
*
psc
)
static
inline
LONG
get_cache_height
(
SCRIPT_CACHE
*
psc
)
{
{
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmHeight
;
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmHeight
;
}
}
static
BYTE
get_cache_pitch_family
(
SCRIPT_CACHE
*
psc
)
static
inline
BYTE
get_cache_pitch_family
(
SCRIPT_CACHE
*
psc
)
{
{
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmPitchAndFamily
;
return
((
ScriptCache
*
)
*
psc
)
->
tm
.
tmPitchAndFamily
;
}
}
static
HRESULT
init_script_cache
(
const
HDC
hdc
,
ScriptCache
*
s
c
)
static
inline
WORD
get_cache_glyph
(
SCRIPT_CACHE
*
psc
,
WCHAR
c
)
{
{
if
(
!
GetTextMetricsW
(
hdc
,
&
sc
->
tm
))
return
E_INVALIDARG
;
WORD
*
block
=
((
ScriptCache
*
)
*
psc
)
->
glyphs
[
c
>>
GLYPH_BLOCK_SHIFT
]
;
if
(
!
GetObjectW
(
GetCurrentObject
(
hdc
,
OBJ_FONT
),
sizeof
(
LOGFONTW
),
&
sc
->
lf
))
return
E_INVALIDARG
;
sc
->
hdc
=
hdc
;
if
(
!
block
)
return
0
;
return
S_OK
;
return
block
[
c
&
GLYPH_BLOCK_MASK
]
;
}
}
static
HRESULT
get_script_cache
(
const
HDC
hdc
,
SCRIPT_CACHE
*
psc
)
static
inline
WORD
set_cache_glyph
(
SCRIPT_CACHE
*
psc
,
WCHAR
c
,
WORD
glyph
)
{
WORD
**
block
=
&
((
ScriptCache
*
)
*
psc
)
->
glyphs
[
c
>>
GLYPH_BLOCK_SHIFT
];
if
(
!*
block
&&
!
(
*
block
=
heap_alloc_zero
(
sizeof
(
WORD
)
*
GLYPH_BLOCK_SIZE
)))
return
0
;
return
((
*
block
)[
c
&
GLYPH_BLOCK_MASK
]
=
glyph
);
}
static
inline
BOOL
get_cache_glyph_widths
(
SCRIPT_CACHE
*
psc
,
WORD
glyph
,
ABC
*
abc
)
{
static
const
ABC
nil
;
ABC
*
block
=
((
ScriptCache
*
)
*
psc
)
->
widths
[
glyph
>>
GLYPH_BLOCK_SHIFT
];
if
(
!
block
||
!
memcmp
(
&
block
[
glyph
&
GLYPH_BLOCK_MASK
],
&
nil
,
sizeof
(
ABC
)))
return
FALSE
;
memcpy
(
abc
,
&
block
[
glyph
&
GLYPH_BLOCK_MASK
],
sizeof
(
ABC
));
return
TRUE
;
}
static
inline
BOOL
set_cache_glyph_widths
(
SCRIPT_CACHE
*
psc
,
WORD
glyph
,
ABC
*
abc
)
{
ABC
**
block
=
&
((
ScriptCache
*
)
*
psc
)
->
widths
[
glyph
>>
GLYPH_BLOCK_SHIFT
];
if
(
!*
block
&&
!
(
*
block
=
heap_alloc_zero
(
sizeof
(
ABC
)
*
GLYPH_BLOCK_SIZE
)))
return
FALSE
;
memcpy
(
&
(
*
block
)[
glyph
&
GLYPH_BLOCK_MASK
],
abc
,
sizeof
(
ABC
));
return
TRUE
;
}
static
HRESULT
init_script_cache
(
const
HDC
hdc
,
SCRIPT_CACHE
*
psc
)
{
{
if
(
!
psc
)
return
E_INVALIDARG
;
if
(
!*
psc
)
{
HRESULT
ret
;
ScriptCache
*
sc
;
ScriptCache
*
sc
;
if
(
!
psc
)
return
E_INVALIDARG
;
if
(
*
psc
)
return
S_OK
;
if
(
!
hdc
)
return
E_PENDING
;
if
(
!
hdc
)
return
E_PENDING
;
if
(
!
(
sc
=
heap_alloc_zero
(
sizeof
(
ScriptCache
))))
return
E_OUTOFMEMORY
;
if
(
!
(
sc
=
heap_alloc_zero
(
sizeof
(
ScriptCache
))))
return
E_OUTOFMEMORY
;
ret
=
init_script_cache
(
hdc
,
sc
);
if
(
!
GetTextMetricsW
(
hdc
,
&
sc
->
tm
))
if
(
ret
!=
S_OK
)
{
{
heap_free
(
sc
);
heap_free
(
sc
);
return
ret
;
return
E_INVALIDARG
;
}
}
*
psc
=
sc
;
if
(
!
GetObjectW
(
GetCurrentObject
(
hdc
,
OBJ_FONT
),
sizeof
(
LOGFONTW
),
&
sc
->
lf
))
{
heap_free
(
sc
);
return
E_INVALIDARG
;
}
}
TRACE
(
"<- %p
\n
"
,
*
psc
);
*
psc
=
sc
;
TRACE
(
"<- %p
\n
"
,
sc
);
return
S_OK
;
return
S_OK
;
}
}
static
HFONT
select_cached_font
(
SCRIPT_CACHE
*
psc
)
{
HFONT
old_font
;
ScriptCache
*
sc
=
*
psc
;
old_font
=
SelectObject
(
sc
->
hdc
,
CreateFontIndirectW
(
&
sc
->
lf
));
return
old_font
;
}
static
void
unselect_cached_font
(
SCRIPT_CACHE
*
psc
,
HFONT
old_font
)
{
ScriptCache
*
sc
=
*
psc
;
DeleteObject
(
SelectObject
(
sc
->
hdc
,
old_font
));
}
/***********************************************************************
/***********************************************************************
* DllMain
* DllMain
*
*
...
@@ -285,8 +301,14 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
...
@@ -285,8 +301,14 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
{
{
TRACE
(
"%p
\n
"
,
psc
);
TRACE
(
"%p
\n
"
,
psc
);
if
(
psc
)
if
(
psc
&&
*
psc
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
GLYPH_MAX
/
GLYPH_BLOCK_SIZE
;
i
++
)
{
{
heap_free
(((
ScriptCache
*
)
*
psc
)
->
glyphs
[
i
]);
heap_free
(((
ScriptCache
*
)
*
psc
)
->
widths
[
i
]);
}
heap_free
(
*
psc
);
heap_free
(
*
psc
);
*
psc
=
NULL
;
*
psc
=
NULL
;
}
}
...
@@ -338,10 +360,7 @@ HRESULT WINAPI ScriptGetFontProperties(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_FONTPR
...
@@ -338,10 +360,7 @@ HRESULT WINAPI ScriptGetFontProperties(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_FONTPR
TRACE
(
"%p,%p,%p
\n
"
,
hdc
,
psc
,
sfp
);
TRACE
(
"%p,%p,%p
\n
"
,
hdc
,
psc
,
sfp
);
if
(
!
sfp
)
return
E_INVALIDARG
;
if
(
!
sfp
)
return
E_INVALIDARG
;
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
hr
=
get_script_cache
(
hdc
,
psc
);
if
(
hr
!=
S_OK
)
return
hr
;
if
(
sfp
->
cBytes
!=
sizeof
(
SCRIPT_FONTPROPERTIES
))
if
(
sfp
->
cBytes
!=
sizeof
(
SCRIPT_FONTPROPERTIES
))
return
E_INVALIDARG
;
return
E_INVALIDARG
;
...
@@ -613,6 +632,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
...
@@ -613,6 +632,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
/* FIXME: handle clipping */
/* FIXME: handle clipping */
analysis
->
clip_len
=
cString
;
analysis
->
clip_len
=
cString
;
analysis
->
hdc
=
hdc
;
hr
=
ScriptItemize
(
pString
,
cString
,
num_items
,
psControl
,
psState
,
analysis
->
pItem
,
hr
=
ScriptItemize
(
pString
,
cString
,
num_items
,
psControl
,
psState
,
analysis
->
pItem
,
&
analysis
->
numItems
);
&
analysis
->
numItems
);
...
@@ -757,7 +777,7 @@ HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa,
...
@@ -757,7 +777,7 @@ HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa,
cnt
+=
analysis
->
glyphs
[
item
].
numGlyphs
;
/* point to the end of the copied text */
cnt
+=
analysis
->
glyphs
[
item
].
numGlyphs
;
/* point to the end of the copied text */
}
}
hr
=
ScriptTextOut
(
analysis
->
sc
->
hdc
,
(
SCRIPT_CACHE
*
)
&
analysis
->
sc
,
iX
,
iY
,
hr
=
ScriptTextOut
(
analysis
->
hdc
,
(
SCRIPT_CACHE
*
)
&
analysis
->
sc
,
iX
,
iY
,
uOptions
,
prc
,
&
analysis
->
pItem
->
a
,
NULL
,
0
,
glyphs
,
cnt
,
uOptions
,
prc
,
&
analysis
->
pItem
->
a
,
NULL
,
0
,
glyphs
,
cnt
,
analysis
->
glyphs
->
piAdvance
,
NULL
,
analysis
->
glyphs
->
pGoffset
);
analysis
->
glyphs
->
piAdvance
,
NULL
,
analysis
->
glyphs
->
pGoffset
);
TRACE
(
"ScriptTextOut hr=%08x
\n
"
,
hr
);
TRACE
(
"ScriptTextOut hr=%08x
\n
"
,
hr
);
...
@@ -1242,9 +1262,8 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
...
@@ -1242,9 +1262,8 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
SCRIPT_ANALYSIS
*
psa
,
WORD
*
pwOutGlyphs
,
WORD
*
pwLogClust
,
SCRIPT_ANALYSIS
*
psa
,
WORD
*
pwOutGlyphs
,
WORD
*
pwLogClust
,
SCRIPT_VISATTR
*
psva
,
int
*
pcGlyphs
)
SCRIPT_VISATTR
*
psva
,
int
*
pcGlyphs
)
{
{
int
cnt
;
HRESULT
hr
;
HRESULT
hr
;
HFONT
hfont
;
unsigned
int
i
;
TRACE
(
"(%p, %p, %p, %d, %d, %p)
\n
"
,
hdc
,
psc
,
pwcChars
,
cChars
,
cMaxGlyphs
,
psa
);
TRACE
(
"(%p, %p, %p, %d, %d, %p)
\n
"
,
hdc
,
psc
,
pwcChars
,
cChars
,
cMaxGlyphs
,
psa
);
if
(
psa
)
TRACE
(
"psa values: %d, %d, %d, %d, %d, %d, %d
\n
"
,
psa
->
eScript
,
psa
->
fRTL
,
psa
->
fLayoutRTL
,
if
(
psa
)
TRACE
(
"psa values: %d, %d, %d, %d, %d, %d, %d
\n
"
,
psa
->
eScript
,
psa
->
fRTL
,
psa
->
fLayoutRTL
,
...
@@ -1253,38 +1272,42 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
...
@@ -1253,38 +1272,42 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
if
(
!
psva
||
!
pcGlyphs
)
return
E_INVALIDARG
;
if
(
!
psva
||
!
pcGlyphs
)
return
E_INVALIDARG
;
if
(
cChars
>
cMaxGlyphs
)
return
E_OUTOFMEMORY
;
if
(
cChars
>
cMaxGlyphs
)
return
E_OUTOFMEMORY
;
hr
=
get_script_cache
(
hdc
,
psc
);
if
(
hr
!=
S_OK
)
return
hr
;
*
pcGlyphs
=
cChars
;
*
pcGlyphs
=
cChars
;
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
hfont
=
select_cached_font
(
psc
);
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
)
&&
!
psa
->
fNoGlyphIndex
)
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
)
&&
!
psa
->
fNoGlyphIndex
)
{
{
GetGlyphIndicesW
(
get_cache_hdc
(
psc
),
pwcChars
,
cChars
,
pwOutGlyphs
,
0
);
for
(
i
=
0
;
i
<
cChars
;
i
++
)
{
if
(
!
(
pwOutGlyphs
[
i
]
=
get_cache_glyph
(
psc
,
pwcChars
[
i
])))
{
WORD
glyph
;
if
(
!
hdc
)
return
E_PENDING
;
if
(
GetGlyphIndicesW
(
hdc
,
&
pwcChars
[
i
],
1
,
&
glyph
,
GGI_MARK_NONEXISTING_GLYPHS
)
==
GDI_ERROR
)
return
S_FALSE
;
pwOutGlyphs
[
i
]
=
set_cache_glyph
(
psc
,
pwcChars
[
i
],
glyph
);
}
}
}
}
else
else
{
{
TRACE
(
"no glyph translation
\n
"
);
TRACE
(
"no glyph translation
\n
"
);
for
(
cnt
=
0
;
cnt
<
cChars
;
cnt
++
)
pwOutGlyphs
[
cnt
]
=
pwcChars
[
cnt
];
for
(
i
=
0
;
i
<
cChars
;
i
++
)
pwOutGlyphs
[
i
]
=
pwcChars
[
i
];
}
}
if
(
psva
)
if
(
psva
)
{
{
/* set up a valid SCRIPT_VISATTR and LogClust for each char in this run */
/* set up a valid SCRIPT_VISATTR and LogClust for each char in this run */
for
(
cnt
=
0
;
cnt
<
cChars
;
cnt
++
)
for
(
i
=
0
;
i
<
cChars
;
i
++
)
{
{
/* FIXME: set to better values */
/* FIXME: set to better values */
psva
[
cnt
].
uJustification
=
2
;
psva
[
i
].
uJustification
=
2
;
psva
[
cnt
].
fClusterStart
=
1
;
psva
[
i
].
fClusterStart
=
1
;
psva
[
cnt
].
fDiacritic
=
0
;
psva
[
i
].
fDiacritic
=
0
;
psva
[
cnt
].
fZeroWidth
=
0
;
psva
[
i
].
fZeroWidth
=
0
;
if
(
pwLogClust
)
pwLogClust
[
cnt
]
=
cnt
;
if
(
pwLogClust
)
pwLogClust
[
i
]
=
i
;
}
}
}
}
unselect_cached_font
(
psc
,
hfont
);
return
S_OK
;
return
S_OK
;
}
}
...
@@ -1313,60 +1336,46 @@ HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs,
...
@@ -1313,60 +1336,46 @@ HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs,
SCRIPT_ANALYSIS
*
psa
,
int
*
piAdvance
,
GOFFSET
*
pGoffset
,
ABC
*
pABC
)
SCRIPT_ANALYSIS
*
psa
,
int
*
piAdvance
,
GOFFSET
*
pGoffset
,
ABC
*
pABC
)
{
{
HRESULT
hr
;
HRESULT
hr
;
LPABC
lpABC
;
HFONT
hfont
;
unsigned
int
i
;
unsigned
int
i
;
TRACE
(
"(%p, %p, %p, %s, %d, %p, %p, %p)
\n
"
,
hdc
,
psc
,
pwGlyphs
,
TRACE
(
"(%p, %p, %p, %s, %d, %p, %p, %p)
\n
"
,
hdc
,
psc
,
pwGlyphs
,
debugstr_wn
(
pwGlyphs
,
cGlyphs
),
cGlyphs
,
psva
,
psa
,
piAdvance
);
debugstr_wn
(
pwGlyphs
,
cGlyphs
),
cGlyphs
,
psva
,
psa
,
piAdvance
);
if
(
!
psva
)
return
E_INVALIDARG
;
if
(
!
psva
)
return
E_INVALIDARG
;
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
hr
=
get_script_cache
(
hdc
,
psc
);
if
(
hr
!=
S_OK
)
return
hr
;
hfont
=
select_cached_font
(
psc
);
/* Here we need to calculate the width of the run unit. At this point the input string
* has been converted to glyphs and we still need to translate back to the original chars
* to get the correct ABC widths. */
if
(
!
(
lpABC
=
heap_alloc_zero
(
sizeof
(
ABC
)
*
cGlyphs
)))
return
E_OUTOFMEMORY
;
if
(
pABC
)
memset
(
pABC
,
0
,
sizeof
(
ABC
));
if
(
pABC
)
memset
(
pABC
,
0
,
sizeof
(
ABC
));
for
(
i
=
0
;
i
<
cGlyphs
;
i
++
)
{
ABC
abc
;
if
(
!
get_cache_glyph_widths
(
psc
,
pwGlyphs
[
i
],
&
abc
))
{
if
(
!
hdc
)
return
E_PENDING
;
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
)
&&
!
psa
->
fNoGlyphIndex
)
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
)
&&
!
psa
->
fNoGlyphIndex
)
{
{
GetCharABCWidthsI
(
get_cache_hdc
(
psc
),
0
,
cGlyphs
,
(
WORD
*
)
pwGlyphs
,
lpABC
)
;
if
(
!
GetCharABCWidthsI
(
hdc
,
0
,
1
,
(
WORD
*
)
&
pwGlyphs
[
i
],
&
abc
))
return
S_FALSE
;
}
}
else
else
{
{
INT
width
;
INT
width
;
for
(
i
=
0
;
i
<
cGlyphs
;
i
++
)
if
(
!
GetCharWidth32W
(
hdc
,
pwGlyphs
[
i
],
pwGlyphs
[
i
],
&
width
))
return
S_FALSE
;
{
abc
.
abcB
=
width
;
GetCharWidth32W
(
get_cache_hdc
(
psc
),
pwGlyphs
[
i
],
pwGlyphs
[
i
],
&
width
);
abc
.
abcA
=
abc
.
abcC
=
0
;
lpABC
[
i
].
abcB
=
width
;
}
}
set_cache_glyph_widths
(
psc
,
pwGlyphs
[
i
],
&
abc
);
}
}
for
(
i
=
0
;
i
<
cGlyphs
;
i
++
)
{
TRACE
(
" Glyph=%04x, abcA=%d, abcB=%d, abcC=%d index=%d
\n
"
,
pwGlyphs
[
i
],
lpABC
[
i
].
abcA
,
lpABC
[
i
].
abcB
,
lpABC
[
i
].
abcC
,
i
);
if
(
pABC
)
if
(
pABC
)
{
{
pABC
->
abcA
+=
lpABC
[
i
]
.
abcA
;
pABC
->
abcA
+=
abc
.
abcA
;
pABC
->
abcB
+=
lpABC
[
i
]
.
abcB
;
pABC
->
abcB
+=
abc
.
abcB
;
pABC
->
abcC
+=
lpABC
[
i
]
.
abcC
;
pABC
->
abcC
+=
abc
.
abcC
;
}
}
/* FIXME: set to more reasonable values */
/* FIXME: set to more reasonable values */
if
(
pGoffset
)
pGoffset
[
i
].
du
=
pGoffset
[
i
].
dv
=
0
;
if
(
pGoffset
)
pGoffset
[
i
].
du
=
pGoffset
[
i
].
dv
=
0
;
if
(
piAdvance
)
piAdvance
[
i
]
=
lpABC
[
i
].
abcA
+
lpABC
[
i
].
abcB
+
lpABC
[
i
]
.
abcC
;
if
(
piAdvance
)
piAdvance
[
i
]
=
abc
.
abcA
+
abc
.
abcB
+
abc
.
abcC
;
}
}
if
(
pABC
)
TRACE
(
"Total for run: abcA=%d, abcB=%d, abcC=%d
\n
"
,
pABC
->
abcA
,
pABC
->
abcB
,
pABC
->
abcC
);
heap_free
(
lpABC
);
if
(
pABC
)
TRACE
(
"Total for run: abcA=%d, abcB=%d, abcC=%d
\n
"
,
pABC
->
abcA
,
pABC
->
abcB
,
pABC
->
abcC
);
unselect_cached_font
(
psc
,
hfont
);
return
S_OK
;
return
S_OK
;
}
}
...
@@ -1391,20 +1400,32 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars
...
@@ -1391,20 +1400,32 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars
int
cChars
,
DWORD
dwFlags
,
WORD
*
pwOutGlyphs
)
int
cChars
,
DWORD
dwFlags
,
WORD
*
pwOutGlyphs
)
{
{
HRESULT
hr
;
HRESULT
hr
;
HFONT
hfont
;
unsigned
int
i
;
TRACE
(
"(%p,%p,%s,%d,0x%x,%p)
\n
"
,
hdc
,
psc
,
debugstr_wn
(
pwcInChars
,
cChars
),
TRACE
(
"(%p,%p,%s,%d,0x%x,%p)
\n
"
,
hdc
,
psc
,
debugstr_wn
(
pwcInChars
,
cChars
),
cChars
,
dwFlags
,
pwOutGlyphs
);
cChars
,
dwFlags
,
pwOutGlyphs
);
hr
=
get_script_cache
(
hdc
,
psc
);
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
if
(
hr
!=
S_OK
)
return
hr
;
hfont
=
select_cached_font
(
psc
);
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
))
if
(
GetGlyphIndicesW
(
get_cache_hdc
(
psc
),
pwcInChars
,
cChars
,
pwOutGlyphs
,
0
)
==
GDI_ERROR
)
{
hr
=
S_FALSE
;
for
(
i
=
0
;
i
<
cChars
;
i
++
)
{
unselect_cached_font
(
psc
,
hfont
);
if
(
!
(
pwOutGlyphs
[
i
]
=
get_cache_glyph
(
psc
,
pwcInChars
[
i
])))
return
hr
;
{
WORD
glyph
;
if
(
!
hdc
)
return
E_PENDING
;
if
(
GetGlyphIndicesW
(
hdc
,
&
pwcInChars
[
i
],
1
,
&
glyph
,
GGI_MARK_NONEXISTING_GLYPHS
)
==
GDI_ERROR
)
return
S_FALSE
;
pwOutGlyphs
[
i
]
=
set_cache_glyph
(
psc
,
pwcInChars
[
i
],
glyph
);
}
}
}
else
{
TRACE
(
"no glyph translation
\n
"
);
for
(
i
=
0
;
i
<
cChars
;
i
++
)
pwOutGlyphs
[
i
]
=
pwcInChars
[
i
];
}
return
S_OK
;
}
}
/***********************************************************************
/***********************************************************************
...
@@ -1456,9 +1477,7 @@ HRESULT WINAPI ScriptCacheGetHeight(HDC hdc, SCRIPT_CACHE *psc, LONG *height)
...
@@ -1456,9 +1477,7 @@ HRESULT WINAPI ScriptCacheGetHeight(HDC hdc, SCRIPT_CACHE *psc, LONG *height)
TRACE
(
"(%p, %p, %p)
\n
"
,
hdc
,
psc
,
height
);
TRACE
(
"(%p, %p, %p)
\n
"
,
hdc
,
psc
,
height
);
if
(
!
height
)
return
E_INVALIDARG
;
if
(
!
height
)
return
E_INVALIDARG
;
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
hr
=
get_script_cache
(
hdc
,
psc
);
if
(
hr
!=
S_OK
)
return
hr
;
*
height
=
get_cache_height
(
psc
);
*
height
=
get_cache_height
(
psc
);
return
S_OK
;
return
S_OK
;
...
@@ -1481,19 +1500,29 @@ HRESULT WINAPI ScriptCacheGetHeight(HDC hdc, SCRIPT_CACHE *psc, LONG *height)
...
@@ -1481,19 +1500,29 @@ HRESULT WINAPI ScriptCacheGetHeight(HDC hdc, SCRIPT_CACHE *psc, LONG *height)
*/
*/
HRESULT
WINAPI
ScriptGetGlyphABCWidth
(
HDC
hdc
,
SCRIPT_CACHE
*
psc
,
WORD
glyph
,
ABC
*
abc
)
HRESULT
WINAPI
ScriptGetGlyphABCWidth
(
HDC
hdc
,
SCRIPT_CACHE
*
psc
,
WORD
glyph
,
ABC
*
abc
)
{
{
HFONT
hfont
;
HRESULT
hr
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p, %p, 0x%04x, %p)
\n
"
,
hdc
,
psc
,
glyph
,
abc
);
TRACE
(
"(%p, %p, 0x%04x, %p)
\n
"
,
hdc
,
psc
,
glyph
,
abc
);
hr
=
get_script_cache
(
hdc
,
psc
);
if
((
hr
=
init_script_cache
(
hdc
,
psc
))
!=
S_OK
)
return
hr
;
if
(
hr
!=
S_OK
)
return
hr
;
hfont
=
select_cached_font
(
psc
);
if
(
!
get_cache_glyph_widths
(
psc
,
glyph
,
abc
))
if
(
!
GetCharABCWidthsI
(
get_cache_hdc
(
psc
),
0
,
1
,
&
glyph
,
abc
))
hr
=
E_HANDLE
;
{
if
(
!
hdc
)
return
E_PENDING
;
unselect_cached_font
(
psc
,
hfont
);
if
((
get_cache_pitch_family
(
psc
)
&
TMPF_TRUETYPE
))
return
hr
;
{
if
(
!
GetCharABCWidthsI
(
hdc
,
0
,
1
,
&
glyph
,
abc
))
return
S_FALSE
;
}
else
{
INT
width
;
if
(
!
GetCharWidth32W
(
hdc
,
glyph
,
glyph
,
&
width
))
return
S_FALSE
;
abc
->
abcB
=
width
;
abc
->
abcA
=
abc
->
abcC
=
0
;
}
set_cache_glyph_widths
(
psc
,
glyph
,
abc
);
}
return
S_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