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
85cff171
Commit
85cff171
authored
Oct 03, 2016
by
Akihiro Sagawa
Committed by
Alexandre Julliard
Oct 03, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Implement LCMAP_FULLWIDTH.
Signed-off-by:
Akihiro Sagawa
<
sagawa.aki@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
410a9832
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
179 additions
and
28 deletions
+179
-28
locale.c
dlls/kernel32/locale.c
+171
-24
locale.c
dlls/kernel32/tests/locale.c
+8
-4
No files found.
dlls/kernel32/locale.c
View file @
85cff171
...
...
@@ -3111,6 +3111,122 @@ BOOL WINAPI GetStringTypeExA( LCID locale, DWORD type, LPCSTR src, INT count, LP
return
GetStringTypeA
(
locale
,
type
,
src
,
count
,
chartype
);
}
/* compose a full-width katakana. return consumed source characters. */
static
INT
compose_katakana
(
LPCWSTR
src
,
INT
srclen
,
LPWSTR
dst
)
{
const
static
BYTE
katakana_map
[]
=
{
/* */
0x02
,
0x0c
,
0x0d
,
0x01
,
0xfb
,
0xf2
,
0xa1
,
/* U+FF61- */
0xa3
,
0xa5
,
0xa7
,
0xa9
,
0xe3
,
0xe5
,
0xe7
,
0xc3
,
/* U+FF68- */
0xfc
,
0xa2
,
0xa4
,
0xa6
,
0xa8
,
0xaa
,
0xab
,
0xad
,
/* U+FF70- */
0xaf
,
0xb1
,
0xb3
,
0xb5
,
0xb7
,
0xb9
,
0xbb
,
0xbd
,
/* U+FF78- */
0xbf
,
0xc1
,
0xc4
,
0xc6
,
0xc8
,
0xca
,
0xcb
,
0xcc
,
/* U+FF80- */
0xcd
,
0xce
,
0xcf
,
0xd2
,
0xd5
,
0xd8
,
0xdb
,
0xde
,
/* U+FF88- */
0xdf
,
0xe0
,
0xe1
,
0xe2
,
0xe4
,
0xe6
,
0xe8
,
0xe9
,
/* U+FF90- */
0xea
,
0xeb
,
0xec
,
0xed
,
0xef
,
0xf3
,
0x99
,
0x9a
,
/* U+FF98- */
};
WCHAR
before
,
dummy
;
if
(
!
dst
)
dst
=
&
dummy
;
switch
(
*
src
)
{
case
0x309b
:
case
0x309c
:
*
dst
=
*
src
-
2
;
return
1
;
case
0x30f0
:
case
0x30f1
:
case
0x30fd
:
*
dst
=
*
src
;
break
;
default:
{
int
shift
=
*
src
-
0xff61
;
if
(
shift
<
0
||
shift
>=
sizeof
(
katakana_map
)
/
sizeof
(
katakana_map
[
0
])
)
return
0
;
else
*
dst
=
katakana_map
[
shift
]
|
0x3000
;
}
}
if
(
srclen
<=
1
)
return
1
;
before
=
*
dst
;
/* datakuten (voiced sound) */
if
(
*
(
src
+
1
)
==
0xff9e
)
{
if
((
*
src
>=
0xff76
&&
*
src
<=
0xff84
)
||
(
*
src
>=
0xff8a
&&
*
src
<=
0xff8e
)
||
*
src
==
0x30fd
)
*
dst
+=
1
;
else
if
(
*
src
==
0xff73
)
*
dst
=
0x30f4
;
/* KATAKANA LETTER VU */
else
if
(
*
src
==
0xff9c
)
*
dst
=
0x30f7
;
/* KATAKANA LETTER VA */
else
if
(
*
src
==
0x30f0
)
*
dst
=
0x30f8
;
/* KATAKANA LETTER VI */
else
if
(
*
src
==
0x30f1
)
*
dst
=
0x30f9
;
/* KATAKANA LETTER VE */
else
if
(
*
src
==
0xff66
)
*
dst
=
0x30fa
;
/* KATAKANA LETTER VO */
}
/* handakuten (semi-voiced sound) */
if
(
*
(
src
+
1
)
==
0xff9f
)
if
(
*
src
>=
0xff8a
&&
*
src
<=
0xff8e
)
*
dst
+=
2
;
return
(
*
dst
!=
before
)
?
2
:
1
;
}
/* map one or two half-width characters to one full-width character */
static
INT
map_to_fullwidth
(
LPCWSTR
src
,
INT
srclen
,
LPWSTR
dst
)
{
INT
n
;
if
(
*
src
<=
'~'
&&
*
src
>
' '
&&
*
src
!=
'\\'
)
*
dst
=
*
src
-
0x20
+
0xff00
;
else
if
(
*
src
==
' '
)
*
dst
=
0x3000
;
else
if
(
*
src
<=
0x00af
&&
*
src
>=
0x00a2
)
{
const
static
BYTE
misc_symbols_table
[]
=
{
0xe0
,
0xe1
,
0x00
,
0xe5
,
0xe4
,
0x00
,
0x00
,
/* U+00A2- */
0x00
,
0x00
,
0x00
,
0xe2
,
0x00
,
0x00
,
0xe3
/* U+00A9- */
};
if
(
misc_symbols_table
[
*
src
-
0x00a2
])
*
dst
=
misc_symbols_table
[
*
src
-
0x00a2
]
|
0xff00
;
else
*
dst
=
*
src
;
}
else
if
(
*
src
==
0x20a9
)
/* WON SIGN */
*
dst
=
0xffe6
;
else
if
((
n
=
compose_katakana
(
src
,
srclen
,
dst
))
>
0
)
return
n
;
else
if
(
*
src
>=
0xffa0
&&
*
src
<=
0xffdc
)
{
const
static
BYTE
hangul_mapping_table
[]
=
{
0x64
,
0x31
,
0x32
,
0x33
,
0x34
,
0x35
,
0x36
,
0x37
,
/* U+FFA0- */
0x38
,
0x39
,
0x3a
,
0x3b
,
0x3c
,
0x3d
,
0x3e
,
0x3f
,
/* U+FFA8- */
0x40
,
0x41
,
0x42
,
0x43
,
0x44
,
0x45
,
0x46
,
0x47
,
/* U+FFB0- */
0x48
,
0x49
,
0x4a
,
0x4b
,
0x4c
,
0x4d
,
0x4e
,
0x00
,
/* U+FFB8- */
0x00
,
0x00
,
0x4f
,
0x50
,
0x51
,
0x52
,
0x53
,
0x54
,
/* U+FFC0- */
0x00
,
0x00
,
0x55
,
0x56
,
0x57
,
0x58
,
0x59
,
0x5a
,
/* U+FFC8- */
0x00
,
0x00
,
0x5b
,
0x5c
,
0x5d
,
0x5e
,
0x5f
,
0x60
,
/* U+FFD0- */
0x00
,
0x00
,
0x61
,
0x62
,
0x63
/* U+FFD8- */
};
if
(
hangul_mapping_table
[
*
src
-
0xffa0
])
*
dst
=
hangul_mapping_table
[
*
src
-
0xffa0
]
|
0x3100
;
else
*
dst
=
*
src
;
}
else
*
dst
=
*
src
;
return
1
;
}
/*************************************************************************
* LCMapStringEx (KERNEL32.@)
*
...
...
@@ -3194,7 +3310,7 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW
}
if
(((
flags
&
(
NORM_IGNORENONSPACE
|
NORM_IGNORESYMBOLS
))
&&
(
flags
&
~
(
NORM_IGNORENONSPACE
|
NORM_IGNORESYMBOLS
)))
||
((
flags
&
(
LCMAP_HIRAGANA
|
LCMAP_KATAKANA
))
&&
((
flags
&
(
LCMAP_HIRAGANA
|
LCMAP_KATAKANA
|
LCMAP_FULLWIDTH
))
&&
(
flags
&
(
LCMAP_SIMPLIFIED_CHINESE
|
LCMAP_TRADITIONAL_CHINESE
))))
{
SetLastError
(
ERROR_INVALID_FLAGS
);
...
...
@@ -3222,6 +3338,17 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW
len
++
;
}
}
else
if
(
flags
&
LCMAP_FULLWIDTH
)
{
for
(
len
=
0
;
srclen
;
src
++
,
srclen
--
,
len
++
)
{
if
(
compose_katakana
(
src
,
srclen
,
NULL
)
==
2
)
{
src
++
;
srclen
--
;
}
}
}
else
len
=
srclen
;
return
len
;
...
...
@@ -3246,6 +3373,49 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW
goto
done
;
}
if
(
flags
&
(
LCMAP_FULLWIDTH
|
LCMAP_HALFWIDTH
|
LCMAP_HIRAGANA
|
LCMAP_KATAKANA
))
{
for
(
len
=
dstlen
,
dst_ptr
=
dst
;
len
&&
srclen
;
src
++
,
srclen
--
,
len
--
,
dst_ptr
++
)
{
WCHAR
wch
;
if
(
flags
&
LCMAP_FULLWIDTH
)
{
/* map half-width character to full-width one,
e.g. U+FF71 -> U+30A2, U+FF8C U+FF9F -> U+30D7. */
if
(
map_to_fullwidth
(
src
,
srclen
,
&
wch
)
==
2
)
{
src
++
;
srclen
--
;
}
}
else
wch
=
*
src
;
if
(
flags
&
LCMAP_KATAKANA
)
{
/* map hiragana to katakana, e.g. U+3041 -> U+30A1.
we can't use C3_HIRAGANA as some characters can't map to katakana */
if
((
wch
>=
0x3041
&&
wch
<=
0x3096
)
||
wch
==
0x309D
||
wch
==
0x309E
)
wch
+=
0x60
;
}
else
if
(
flags
&
LCMAP_HIRAGANA
)
{
/* map katakana to hiragana, e.g. U+30A1 -> U+3041.
we can't use C3_KATAKANA as some characters can't map to hiragana */
if
((
wch
>=
0x30A1
&&
wch
<=
0x30F6
)
||
wch
==
0x30FD
||
wch
==
0x30FE
)
wch
-=
0x60
;
}
*
dst_ptr
=
wch
;
}
if
(
!
(
flags
&
(
LCMAP_UPPERCASE
|
LCMAP_LOWERCASE
)))
goto
done
;
srclen
=
dst_ptr
-
dst
;
src
=
dst
;
}
if
(
flags
&
LCMAP_UPPERCASE
)
{
for
(
len
=
dstlen
,
dst_ptr
=
dst
;
srclen
&&
len
;
src
++
,
srclen
--
)
...
...
@@ -3270,29 +3440,6 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW
srclen
-=
len
;
}
if
(
flags
&
LCMAP_HIRAGANA
)
{
/* map katakana to hiragana, e.g. U+30A1 -> U+3041.
we can't use C3_KATAKANA as some characters can't map to hiragana */
for
(
len
=
dst_ptr
-
dst
,
dst_ptr
=
dst
;
len
;
len
--
,
dst_ptr
++
)
{
if
((
*
dst_ptr
>=
0x30A1
&&
*
dst_ptr
<=
0x30F6
)
||
*
dst_ptr
==
0x30FD
||
*
dst_ptr
==
0x30FE
)
*
dst_ptr
-=
0x60
;
}
}
else
if
(
flags
&
LCMAP_KATAKANA
)
{
/* map hiragana to katakana, e.g. U+3041 -> U+30A1.
we can't use C3_HIRAGANA as some characters can't map to katakana */
for
(
len
=
dst_ptr
-
dst
,
dst_ptr
=
dst
;
len
;
len
--
,
dst_ptr
++
)
{
if
((
*
dst_ptr
>=
0x3041
&&
*
dst_ptr
<=
0x3096
)
||
*
dst_ptr
==
0x309D
||
*
dst_ptr
==
0x309E
)
*
dst_ptr
+=
0x60
;
}
}
done:
if
(
srclen
)
{
...
...
dlls/kernel32/tests/locale.c
View file @
85cff171
...
...
@@ -2214,6 +2214,10 @@ static const DWORD lcmap_invalid_flags[] = {
LCMAP_KATAKANA
|
NORM_IGNORESYMBOLS
,
LCMAP_KATAKANA
|
LCMAP_SIMPLIFIED_CHINESE
,
LCMAP_KATAKANA
|
LCMAP_TRADITIONAL_CHINESE
,
LCMAP_FULLWIDTH
|
NORM_IGNORENONSPACE
,
LCMAP_FULLWIDTH
|
NORM_IGNORESYMBOLS
,
LCMAP_FULLWIDTH
|
LCMAP_SIMPLIFIED_CHINESE
,
LCMAP_FULLWIDTH
|
LCMAP_TRADITIONAL_CHINESE
,
};
static
void
test_LCMapStringA
(
void
)
...
...
@@ -2461,9 +2465,9 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
/* test LCMAP_FULLWIDTH */
ret
=
func_ptr
(
LCMAP_FULLWIDTH
,
halfwidth_text
,
-
1
,
buf
,
sizeof
(
buf
)
/
sizeof
(
WCHAR
));
todo_wine
ok
(
ret
==
lstrlenW
(
japanese_text
)
+
1
,
"%s ret %d, error %d, expected value %d
\n
"
,
func_name
,
ok
(
ret
==
lstrlenW
(
japanese_text
)
+
1
,
"%s ret %d, error %d, expected value %d
\n
"
,
func_name
,
ret
,
GetLastError
(),
lstrlenW
(
japanese_text
)
+
1
);
todo_wine
ok
(
!
lstrcmpW
(
buf
,
japanese_text
),
"%s string compare mismatch
\n
"
,
func_name
);
ok
(
!
lstrcmpW
(
buf
,
japanese_text
),
"%s string compare mismatch
\n
"
,
func_name
);
ret2
=
func_ptr
(
LCMAP_FULLWIDTH
,
halfwidth_text
,
-
1
,
NULL
,
0
);
ok
(
ret
==
ret2
,
"%s ret %d, expected value %d
\n
"
,
func_name
,
ret2
,
ret
);
...
...
@@ -2472,9 +2476,9 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
(half-width katakana is converted into full-wdith hiragana) */
ret
=
func_ptr
(
LCMAP_FULLWIDTH
|
LCMAP_HIRAGANA
,
halfwidth_text
,
-
1
,
buf
,
sizeof
(
buf
)
/
sizeof
(
WCHAR
));
todo_wine
ok
(
ret
==
lstrlenW
(
hiragana_text
)
+
1
,
"%s ret %d, error %d, expected value %d
\n
"
,
func_name
,
ok
(
ret
==
lstrlenW
(
hiragana_text
)
+
1
,
"%s ret %d, error %d, expected value %d
\n
"
,
func_name
,
ret
,
GetLastError
(),
lstrlenW
(
hiragana_text
)
+
1
);
todo_wine
ok
(
!
lstrcmpW
(
buf
,
hiragana_text
),
"%s string compare mismatch
\n
"
,
func_name
);
ok
(
!
lstrcmpW
(
buf
,
hiragana_text
),
"%s string compare mismatch
\n
"
,
func_name
);
ret2
=
func_ptr
(
LCMAP_FULLWIDTH
|
LCMAP_HIRAGANA
,
halfwidth_text
,
-
1
,
NULL
,
0
);
ok
(
ret
==
ret2
,
"%s ret %d, expected value %d
\n
"
,
func_name
,
ret
,
ret2
);
...
...
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