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
b9c30445
Commit
b9c30445
authored
Apr 13, 2010
by
Aric Stewart
Committed by
Alexandre Julliard
Apr 14, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ups10: Reimplement ScriptLayout to properly handle mixed runs.
parent
6c3659c3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
197 additions
and
106 deletions
+197
-106
bidi.c
dlls/gdi32/bidi.c
+23
-82
bidi.c
dlls/usp10/bidi.c
+95
-0
usp10.c
dlls/usp10/tests/usp10.c
+47
-12
usp10.c
dlls/usp10/usp10.c
+29
-12
usp10_internal.h
dlls/usp10/usp10_internal.h
+3
-0
No files found.
dlls/gdi32/bidi.c
View file @
b9c30445
...
...
@@ -192,22 +192,9 @@ static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount)
}
}
/* reverse cch characters */
static
void
reverse
(
LPWSTR
psz
,
int
cch
)
{
WCHAR
chTemp
;
int
ich
=
0
;
for
(;
ich
<
--
cch
;
ich
++
)
{
chTemp
=
psz
[
ich
];
psz
[
ich
]
=
psz
[
cch
];
psz
[
cch
]
=
chTemp
;
}
}
/* Set a run of cval values at locations all prior to, but not including */
/* iStart, to the new value nval. */
static
void
SetDeferredRun
(
WORD
*
pval
,
int
cval
,
int
iStart
,
int
nval
)
static
void
SetDeferredRun
(
BYTE
*
pval
,
int
cval
,
int
iStart
,
int
nval
)
{
int
i
=
iStart
-
1
;
for
(;
i
>=
iStart
-
cval
;
i
--
)
...
...
@@ -299,10 +286,10 @@ static int resolveLines(LPCWSTR pszInput, BOOL * pbrk, int cch)
a real implementation, cch and the initial pointer values
would have to be adjusted.
------------------------------------------------------------------------*/
static
void
resolveWhitespace
(
int
baselevel
,
const
WORD
*
pcls
,
WORD
*
plevel
,
int
cch
)
static
void
resolveWhitespace
(
int
baselevel
,
const
WORD
*
pcls
,
BYTE
*
plevel
,
int
cch
)
{
int
cchrun
=
0
;
int
oldlevel
=
baselevel
;
BYTE
oldlevel
=
baselevel
;
int
ich
=
0
;
for
(;
ich
<
cch
;
ich
++
)
...
...
@@ -340,67 +327,6 @@ static void resolveWhitespace(int baselevel, const WORD *pcls, WORD *plevel, int
SetDeferredRun
(
plevel
,
cchrun
,
ich
,
baselevel
);
}
/*------------------------------------------------------------------------
Functions: reorder/reorderLevel
Recursively reorders the display string
"From the highest level down, reverse all characters at that level and
higher, down to the lowest odd level"
Implements rule L2 of the Unicode bidi Algorithm.
Input: Array of embedding levels
Character count
Flag enabling reversal (set to false by initial caller)
In/Out: Text to reorder
Note: levels may exceed 15 resp. 61 on input.
Rule L3 - reorder combining marks is not implemented here
Rule L4 - glyph mirroring is implemented as a display option below
Note: this should be applied a line at a time
-------------------------------------------------------------------------*/
static
int
reorderLevel
(
int
level
,
LPWSTR
pszText
,
const
WORD
*
plevel
,
int
cch
,
BOOL
fReverse
)
{
int
ich
=
0
;
/* true as soon as first odd level encountered */
fReverse
=
fReverse
||
odd
(
level
);
for
(;
ich
<
cch
;
ich
++
)
{
if
(
plevel
[
ich
]
<
level
)
{
break
;
}
else
if
(
plevel
[
ich
]
>
level
)
{
ich
+=
reorderLevel
(
level
+
1
,
pszText
+
ich
,
plevel
+
ich
,
cch
-
ich
,
fReverse
)
-
1
;
}
}
if
(
fReverse
)
{
reverse
(
pszText
,
ich
);
}
return
ich
;
}
static
int
reorder
(
int
baselevel
,
LPWSTR
pszText
,
const
WORD
*
plevel
,
int
cch
)
{
int
ich
=
0
;
while
(
ich
<
cch
)
{
ich
+=
reorderLevel
(
baselevel
,
pszText
+
ich
,
plevel
+
ich
,
cch
-
ich
,
FALSE
);
}
return
ich
;
}
/* DISPLAY OPTIONS */
/*-----------------------------------------------------------------------
Function: mirror
...
...
@@ -418,7 +344,7 @@ static int reorder(int baselevel, LPWSTR pszText, const WORD* plevel, int cch)
A full implementation would need to substitute mirrored glyphs even
for characters that are not paired (e.g. integral sign).
-----------------------------------------------------------------------*/
static
void
mirror
(
LPWSTR
pszInput
,
const
WORD
*
plevel
,
int
cch
)
static
void
mirror
(
LPWSTR
pszInput
,
const
BYTE
*
plevel
,
int
cch
)
{
static
int
warn_once
;
int
i
;
...
...
@@ -448,9 +374,18 @@ static void mirror(LPWSTR pszInput, const WORD* plevel, int cch)
------------------------------------------------------------------------*/
static
void
BidiLines
(
int
baselevel
,
LPWSTR
pszOutLine
,
LPCWSTR
pszLine
,
WORD
*
pclsLine
,
WORD
*
plevelLine
,
int
cchPara
,
int
fMirror
,
BOOL
*
pbrk
)
BYTE
*
plevelLine
,
int
cchPara
,
int
fMirror
,
BOOL
*
pbrk
)
{
int
cchLine
=
0
;
int
done
=
0
;
int
*
run
;
run
=
HeapAlloc
(
GetProcessHeap
(),
0
,
cchPara
*
sizeof
(
int
));
if
(
!
run
)
{
WARN
(
"Out of memory
\n
"
);
return
;
}
do
{
...
...
@@ -462,11 +397,14 @@ static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, WORD *
if
(
pszOutLine
)
{
int
i
;
if
(
fMirror
)
mirror
(
pszOutLine
,
plevelLine
,
cchLine
);
/* reorder each line in place */
reorder
(
baselevel
,
pszOutLine
,
plevelLine
,
cchLine
);
ScriptLayout
(
cchLine
,
plevelLine
,
run
,
NULL
);
for
(
i
=
0
;
i
<
cchLine
;
i
++
)
pszOutLine
[
done
+
run
[
i
]]
=
pszLine
[
i
];
}
pszLine
+=
cchLine
;
...
...
@@ -474,8 +412,11 @@ static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, WORD *
pbrk
+=
pbrk
?
cchLine
:
0
;
pclsLine
+=
cchLine
;
cchPara
-=
cchLine
;
done
+=
cchLine
;
}
while
(
cchPara
);
HeapFree
(
GetProcessHeap
(),
0
,
run
);
}
/*************************************************************
...
...
@@ -492,7 +433,7 @@ BOOL BIDI_Reorder(
)
{
WORD
*
chartype
;
WORD
*
levels
;
BYTE
*
levels
;
unsigned
i
,
done
;
int
maxItems
;
...
...
@@ -556,7 +497,7 @@ BOOL BIDI_Reorder(
}
}
levels
=
HeapAlloc
(
GetProcessHeap
(),
0
,
uCount
*
sizeof
(
WORD
));
levels
=
HeapAlloc
(
GetProcessHeap
(),
0
,
uCount
*
sizeof
(
BYTE
));
if
(
!
levels
)
{
WARN
(
"Out of memory
\n
"
);
...
...
dlls/usp10/bidi.c
View file @
b9c30445
...
...
@@ -827,3 +827,98 @@ BOOL BIDI_DetermineLevels(
HeapFree
(
GetProcessHeap
(),
0
,
chartype
);
return
TRUE
;
}
/* reverse cch indexes */
static
void
reverse
(
int
*
pidx
,
int
cch
)
{
int
temp
;
int
ich
=
0
;
for
(;
ich
<
--
cch
;
ich
++
)
{
temp
=
pidx
[
ich
];
pidx
[
ich
]
=
pidx
[
cch
];
pidx
[
cch
]
=
temp
;
}
}
/*------------------------------------------------------------------------
Functions: reorder/reorderLevel
Recursively reorders the display string
"From the highest level down, reverse all characters at that level and
higher, down to the lowest odd level"
Implements rule L2 of the Unicode bidi Algorithm.
Input: Array of embedding levels
Character count
Flag enabling reversal (set to false by initial caller)
In/Out: Text to reorder
Note: levels may exceed 15 resp. 61 on input.
Rule L3 - reorder combining marks is not implemented here
Rule L4 - glyph mirroring is implemented as a display option below
Note: this should be applied a line at a time
-------------------------------------------------------------------------*/
int
BIDI_ReorderV2lLevel
(
int
level
,
int
*
pIndexs
,
const
BYTE
*
plevel
,
int
cch
,
BOOL
fReverse
)
{
int
ich
=
0
;
/* true as soon as first odd level encountered */
fReverse
=
fReverse
||
odd
(
level
);
for
(;
ich
<
cch
;
ich
++
)
{
if
(
plevel
[
ich
]
<
level
)
{
break
;
}
else
if
(
plevel
[
ich
]
>
level
)
{
ich
+=
BIDI_ReorderV2lLevel
(
level
+
1
,
pIndexs
+
ich
,
plevel
+
ich
,
cch
-
ich
,
fReverse
)
-
1
;
}
}
if
(
fReverse
)
{
reverse
(
pIndexs
,
ich
);
}
return
ich
;
}
/* Applies the reorder in reverse. Taking an already reordered string and returing the original */
int
BIDI_ReorderL2vLevel
(
int
level
,
int
*
pIndexs
,
const
BYTE
*
plevel
,
int
cch
,
BOOL
fReverse
)
{
int
ich
=
0
;
int
newlevel
=
-
1
;
/* true as soon as first odd level encountered */
fReverse
=
fReverse
||
odd
(
level
);
for
(;
ich
<
cch
;
ich
++
)
{
if
(
plevel
[
ich
]
<
level
)
break
;
else
if
(
plevel
[
ich
]
>
level
)
newlevel
=
ich
;
}
if
(
fReverse
)
{
reverse
(
pIndexs
,
ich
);
}
if
(
newlevel
>
1
)
{
ich
=
0
;
for
(;
ich
<
cch
;
ich
++
)
if
(
plevel
[
ich
]
>
level
)
ich
+=
BIDI_ReorderL2vLevel
(
level
+
1
,
pIndexs
+
ich
,
plevel
+
ich
,
cch
-
ich
,
fReverse
)
-
1
;
}
return
ich
;
}
dlls/usp10/tests/usp10.c
View file @
b9c30445
...
...
@@ -1379,20 +1379,55 @@ static void test_ScriptGetGlyphABCWidth(HDC hdc)
static
void
test_ScriptLayout
(
void
)
{
HRESULT
hr
;
static
const
BYTE
levels
[][
5
]
=
static
const
BYTE
levels
[][
10
]
=
{
{
0
,
0
,
0
,
0
,
0
},
{
1
,
1
,
1
,
1
,
1
},
{
2
,
2
,
2
,
2
,
2
},
{
3
,
3
,
3
,
3
,
3
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
},
{
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
},
{
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
},
{
0
,
0
,
0
,
0
,
0
,
1
,
1
,
1
,
1
,
1
},
{
1
,
1
,
1
,
2
,
2
,
2
,
1
,
1
,
1
,
1
},
{
2
,
2
,
2
,
1
,
1
,
1
,
2
,
2
,
2
,
2
},
{
0
,
0
,
1
,
1
,
2
,
2
,
1
,
1
,
0
,
0
},
{
1
,
1
,
2
,
2
,
3
,
3
,
2
,
2
,
1
,
1
},
{
0
,
0
,
1
,
1
,
2
,
2
,
1
,
1
,
0
,
1
},
{
1
,
0
,
1
,
2
,
2
,
1
,
2
,
1
,
0
,
1
},
};
static
const
int
expect
[][
5
]
=
static
const
int
expect
_l2v
[][
10
]
=
{
{
0
,
1
,
2
,
3
,
4
},
{
4
,
3
,
2
,
1
,
0
},
{
0
,
1
,
2
,
3
,
4
},
{
4
,
3
,
2
,
1
,
0
}
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
},
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
},
{
0
,
1
,
2
,
3
,
4
,
9
,
8
,
7
,
6
,
5
},
/**/
{
9
,
8
,
7
,
4
,
5
,
6
,
3
,
2
,
1
,
0
},
/**/
{
7
,
8
,
9
,
6
,
5
,
4
,
0
,
1
,
2
,
3
},
{
0
,
1
,
7
,
6
,
4
,
5
,
3
,
2
,
8
,
9
},
{
9
,
8
,
2
,
3
,
5
,
4
,
6
,
7
,
1
,
0
},
{
0
,
1
,
7
,
6
,
4
,
5
,
3
,
2
,
8
,
9
},
/**/
{
0
,
1
,
7
,
5
,
6
,
4
,
3
,
2
,
8
,
9
},
};
static
const
int
expect_v2l
[][
10
]
=
{
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
},
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
},
{
0
,
1
,
2
,
3
,
4
,
9
,
8
,
7
,
6
,
5
},
{
9
,
8
,
7
,
6
,
3
,
4
,
5
,
2
,
1
,
0
},
{
6
,
7
,
8
,
9
,
5
,
4
,
3
,
0
,
1
,
2
},
{
0
,
1
,
7
,
6
,
4
,
5
,
3
,
2
,
8
,
9
},
{
9
,
8
,
2
,
3
,
5
,
4
,
6
,
7
,
1
,
0
},
{
0
,
1
,
7
,
6
,
4
,
5
,
3
,
2
,
8
,
9
},
{
0
,
1
,
7
,
6
,
5
,
3
,
4
,
2
,
8
,
9
},
};
int
i
,
j
,
vistolog
[
sizeof
(
levels
[
0
])],
logtovis
[
sizeof
(
levels
[
0
])];
hr
=
ScriptLayout
(
sizeof
(
levels
[
0
]),
NULL
,
vistolog
,
logtovis
);
...
...
@@ -1408,14 +1443,14 @@ static void test_ScriptLayout(void)
for
(
j
=
0
;
j
<
sizeof
(
levels
[
i
]);
j
++
)
{
ok
(
expect
[
i
][
j
]
==
vistolog
[
j
],
ok
(
expect
_v2l
[
i
][
j
]
==
vistolog
[
j
],
"failure: levels[%d][%d] = %d, vistolog[%d] = %d
\n
"
,
i
,
j
,
levels
[
i
][
j
],
j
,
vistolog
[
j
]
);
}
for
(
j
=
0
;
j
<
sizeof
(
levels
[
i
]);
j
++
)
{
ok
(
expect
[
i
][
j
]
==
logtovis
[
j
],
ok
(
expect
_l2v
[
i
][
j
]
==
logtovis
[
j
],
"failure: levels[%d][%d] = %d, logtovis[%d] = %d
\n
"
,
i
,
j
,
levels
[
i
][
j
],
j
,
logtovis
[
j
]
);
}
...
...
dlls/usp10/usp10.c
View file @
b9c30445
...
...
@@ -1619,28 +1619,45 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB
*/
HRESULT
WINAPI
ScriptLayout
(
int
runs
,
const
BYTE
*
level
,
int
*
vistolog
,
int
*
logtovis
)
{
int
i
,
j
=
runs
-
1
,
k
=
0
;
int
*
indexs
;
int
ich
;
TRACE
(
"(%d, %p, %p, %p)
\n
"
,
runs
,
level
,
vistolog
,
logtovis
);
if
(
!
level
||
(
!
vistolog
&&
!
logtovis
))
return
E_INVALIDARG
;
for
(
i
=
0
;
i
<
runs
;
i
++
)
{
if
(
level
[
i
]
%
2
)
indexs
=
heap_alloc
(
sizeof
(
int
)
*
runs
);
if
(
!
indexs
)
return
E_OUTOFMEMORY
;
if
(
vistolog
)
{
if
(
vistolog
)
*
vistolog
++
=
j
;
if
(
logtovis
)
*
logtovis
++
=
j
;
j
--
;
for
(
ich
=
0
;
ich
<
runs
;
ich
++
)
indexs
[
ich
]
=
ich
;
ich
=
0
;
while
(
ich
<
runs
)
ich
+=
BIDI_ReorderV2lLevel
(
0
,
indexs
+
ich
,
level
+
ich
,
runs
-
ich
,
FALSE
);
for
(
ich
=
0
;
ich
<
runs
;
ich
++
)
vistolog
[
ich
]
=
indexs
[
ich
];
}
else
if
(
logtovis
)
{
if
(
vistolog
)
*
vistolog
++
=
k
;
if
(
logtovis
)
*
logtovis
++
=
k
;
k
++
;
}
for
(
ich
=
0
;
ich
<
runs
;
ich
++
)
indexs
[
ich
]
=
ich
;
ich
=
0
;
while
(
ich
<
runs
)
ich
+=
BIDI_ReorderL2vLevel
(
0
,
indexs
+
ich
,
level
+
ich
,
runs
-
ich
,
FALSE
);
for
(
ich
=
0
;
ich
<
runs
;
ich
++
)
logtovis
[
ich
]
=
indexs
[
ich
];
}
heap_free
(
indexs
);
return
S_OK
;
}
...
...
dlls/usp10/usp10_internal.h
View file @
b9c30445
...
...
@@ -23,3 +23,6 @@
BOOL
BIDI_DetermineLevels
(
LPCWSTR
lpString
,
INT
uCount
,
const
SCRIPT_STATE
*
s
,
const
SCRIPT_CONTROL
*
c
,
WORD
*
lpOutLevels
);
INT
BIDI_ReorderV2lLevel
(
int
level
,
int
*
pIndexs
,
const
BYTE
*
plevel
,
int
cch
,
BOOL
fReverse
);
INT
BIDI_ReorderL2vLevel
(
int
level
,
int
*
pIndexs
,
const
BYTE
*
plevel
,
int
cch
,
BOOL
fReverse
);
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