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
fdd8454e
Commit
fdd8454e
authored
Sep 30, 2014
by
Nikolay Sivov
Committed by
Alexandre Julliard
Oct 01, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Implement AnalyzeBidi().
parent
b2c65c29
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1322 additions
and
7 deletions
+1322
-7
Makefile.in
dlls/dwrite/Makefile.in
+2
-0
analyzer.c
dlls/dwrite/analyzer.c
+76
-7
bidi.c
dlls/dwrite/bidi.c
+1130
-0
bracket.c
dlls/dwrite/bracket.c
+106
-0
dwrite_private.h
dlls/dwrite/dwrite_private.h
+7
-0
make_unicode
tools/make_unicode
+1
-0
No files found.
dlls/dwrite/Makefile.in
View file @
fdd8454e
...
...
@@ -4,6 +4,8 @@ IMPORTS = user32 gdi32
C_SRCS
=
\
analyzer.c
\
bidi.c
\
bracket.c
\
font.c
\
gdiinterop.c
\
layout.c
\
...
...
dlls/dwrite/analyzer.c
View file @
fdd8454e
...
...
@@ -165,11 +165,6 @@ static const struct dwritescript_properties dwritescripts_properties[Script_Last
{
/* Yiii */
{
0x69696959
,
460
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
},
TRUE
}
};
static
inline
unsigned
short
get_table_entry
(
const
unsigned
short
*
table
,
WCHAR
ch
)
{
return
table
[
table
[
table
[
ch
>>
8
]
+
((
ch
>>
4
)
&
0x0f
)]
+
(
ch
&
0xf
)];
}
static
inline
UINT16
get_char_script
(
WCHAR
c
)
{
UINT16
script
=
get_table_entry
(
wine_scripts_table
,
c
);
...
...
@@ -671,8 +666,82 @@ static HRESULT WINAPI dwritetextanalyzer_AnalyzeScript(IDWriteTextAnalyzer2 *ifa
static
HRESULT
WINAPI
dwritetextanalyzer_AnalyzeBidi
(
IDWriteTextAnalyzer2
*
iface
,
IDWriteTextAnalysisSource
*
source
,
UINT32
position
,
UINT32
length
,
IDWriteTextAnalysisSink
*
sink
)
{
FIXME
(
"(%p %u %u %p): stub
\n
"
,
source
,
position
,
length
,
sink
);
return
E_NOTIMPL
;
UINT8
*
levels
=
NULL
,
*
explicit
=
NULL
;
UINT8
baselevel
,
level
,
explicit_level
;
WCHAR
*
buff
=
NULL
;
const
WCHAR
*
text
;
UINT32
len
,
pos
,
i
;
HRESULT
hr
;
TRACE
(
"(%p %u %u %p)
\n
"
,
source
,
position
,
length
,
sink
);
if
(
length
==
0
)
return
S_OK
;
/* get some, check for length */
text
=
NULL
;
len
=
0
;
hr
=
IDWriteTextAnalysisSource_GetTextAtPosition
(
source
,
position
,
&
text
,
&
len
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
len
<
length
)
{
UINT32
read
;
buff
=
heap_alloc
(
length
*
sizeof
(
WCHAR
));
if
(
!
buff
)
return
E_OUTOFMEMORY
;
memcpy
(
buff
,
text
,
len
*
sizeof
(
WCHAR
));
read
=
len
;
while
(
read
<
length
&&
text
)
{
text
=
NULL
;
len
=
0
;
hr
=
IDWriteTextAnalysisSource_GetTextAtPosition
(
source
,
read
,
&
text
,
&
len
);
if
(
FAILED
(
hr
))
goto
done
;
memcpy
(
&
buff
[
read
],
text
,
min
(
len
,
length
-
read
)
*
sizeof
(
WCHAR
));
read
+=
len
;
}
text
=
buff
;
}
levels
=
heap_alloc
(
length
*
sizeof
(
*
levels
));
explicit
=
heap_alloc
(
length
*
sizeof
(
*
explicit
));
if
(
!
levels
||
!
explicit
)
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
baselevel
=
IDWriteTextAnalysisSource_GetParagraphReadingDirection
(
source
);
hr
=
bidi_computelevels
(
text
,
length
,
baselevel
,
explicit
,
levels
);
if
(
FAILED
(
hr
))
goto
done
;
level
=
levels
[
0
];
explicit_level
=
explicit
[
0
];
pos
=
0
;
for
(
i
=
1
;
i
<
length
;
i
++
)
{
if
(
levels
[
i
]
!=
level
||
explicit
[
i
]
!=
explicit_level
)
{
hr
=
IDWriteTextAnalysisSink_SetBidiLevel
(
sink
,
pos
,
i
-
pos
,
explicit_level
,
level
);
if
(
FAILED
(
hr
))
break
;
level
=
levels
[
i
];
explicit_level
=
explicit
[
i
];
pos
=
i
;
}
if
(
i
==
length
-
1
)
hr
=
IDWriteTextAnalysisSink_SetBidiLevel
(
sink
,
pos
,
length
-
pos
,
explicit_level
,
level
);
}
done:
heap_free
(
explicit
);
heap_free
(
levels
);
heap_free
(
buff
);
return
hr
;
}
static
HRESULT
WINAPI
dwritetextanalyzer_AnalyzeNumberSubstitution
(
IDWriteTextAnalyzer2
*
iface
,
...
...
dlls/dwrite/bidi.c
0 → 100644
View file @
fdd8454e
/*
* Unicode Bidirectional Algorithm implementation
*
* Copyright 2003 Shachar Shemesh
* Copyright 2007 Maarten Lankhorst
* Copyright 2010 CodeWeavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Code derived from the modified reference implementation
* that was found in revision 17 of http://unicode.org/reports/tr9/
* "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
*
* -- Copyright (C) 1999-2005, ASMUS, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of the Unicode data files and any associated documentation (the
* "Data Files") or Unicode software and any associated documentation (the
* "Software") to deal in the Data Files or Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, and/or sell copies of the Data Files or Software,
* and to permit persons to whom the Data Files or Software are furnished
* to do so, provided that (a) the above copyright notice(s) and this
* permission notice appear with all copies of the Data Files or Software,
* (b) both the above copyright notice(s) and this permission notice appear
* in associated documentation, and (c) there is clear notice in each
* modified Data File or in the Software as well as in the documentation
* associated with the Data File(s) or Software that the data or software
* has been modified.
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "dwrite.h"
#include "dwrite_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
bidi
);
extern
const
unsigned
short
bidi_bracket_table
[];
#define ASSERT(x) do { if (!(x)) FIXME("assert failed: %s\n", #x); } while(0)
#define MAX_DEPTH 125
#define odd(x) ((x) & 1)
/*------------------------------------------------------------------------
Bidirectional Character Types
as defined by the Unicode Bidirectional Algorithm Table 3-7.
Note:
The list of bidirectional character types here is not grouped the
same way as the table 3-7, since the numberic values for the types
are chosen to keep the state and action tables compact.
------------------------------------------------------------------------*/
enum
directions
{
/* input types */
/* ON MUST be zero, code relies on ON = NI = 0 */
ON
=
0
,
/* Other Neutral */
L
,
/* Left Letter */
R
,
/* Right Letter */
AN
,
/* Arabic Number */
EN
,
/* European Number */
AL
,
/* Arabic Letter (Right-to-left) */
NSM
,
/* Non-spacing Mark */
CS
,
/* Common Separator */
ES
,
/* European Separator */
ET
,
/* European Terminator (post/prefix e.g. $ and %) */
/* resolved types */
BN
,
/* Boundary neutral (type of RLE etc after explicit levels) */
/* input types, */
S
,
/* Segment Separator (TAB) // used only in L1 */
WS
,
/* White space // used only in L1 */
B
,
/* Paragraph Separator (aka as PS) */
/* types for explicit controls */
RLO
,
/* these are used only in X1-X9 */
RLE
,
LRO
,
LRE
,
PDF
,
LRI
,
/* Isolate formatting characters new with 6.3 */
RLI
,
FSI
,
PDI
,
/* resolved types, also resolved directions */
NI
=
ON
,
/* alias, where ON, WS, S and Isolates are treated the same */
};
static
const
char
debug_type
[][
4
]
=
{
"ON"
,
/* Other Neutral */
"L"
,
/* Left Letter */
"R"
,
/* Right Letter */
"AN"
,
/* Arabic Number */
"EN"
,
/* European Number */
"AL"
,
/* Arabic Letter (Right-to-left) */
"NSM"
,
/* Non-spacing Mark */
"CS"
,
/* Common Separator */
"ES"
,
/* European Separator */
"ET"
,
/* European Terminator (post/prefix e.g. $ and %) */
"BN"
,
/* Boundary neutral (type of RLE etc after explicit levels) */
"S"
,
/* Segment Separator (TAB) used only in L1 */
"WS"
,
/* White space used only in L1 */
"B"
,
/* Paragraph Separator (aka as PS) */
"RLO"
,
/* these are used only in X1-X9 */
"RLE"
,
"LRO"
,
"LRE"
,
"PDF"
,
"LRI"
,
/* Isolate formatting characters new with 6.3 */
"RLI"
,
"FSI"
,
"PDI"
,
};
static
inline
void
bidi_dump_types
(
const
char
*
header
,
const
UINT8
*
types
,
UINT32
start
,
UINT32
end
)
{
int
i
,
len
=
0
;
TRACE
(
"%s:"
,
header
);
for
(
i
=
start
;
i
<
end
&&
len
<
200
;
i
++
)
{
TRACE
(
" %s"
,
debug_type
[
types
[
i
]]);
len
+=
strlen
(
debug_type
[
types
[
i
]])
+
1
;
}
if
(
i
!=
end
)
TRACE
(
"..."
);
TRACE
(
"
\n
"
);
}
/* Convert the libwine information to the direction enum */
static
void
bidi_classify
(
const
WCHAR
*
string
,
UINT8
*
chartype
,
UINT32
count
)
{
static
const
enum
directions
dir_map
[
16
]
=
{
L
,
/* unassigned defaults to L */
L
,
R
,
EN
,
ES
,
ET
,
AN
,
CS
,
B
,
S
,
WS
,
ON
,
AL
,
NSM
,
BN
,
PDF
/* also LRE, LRO, RLE, RLO */
};
UINT32
i
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
chartype
[
i
]
=
dir_map
[
get_char_typeW
(
string
[
i
])
>>
12
];
switch
(
chartype
[
i
])
{
case
ES
:
break
;
case
PDF
:
switch
(
string
[
i
])
{
case
0x202a
:
chartype
[
i
]
=
LRE
;
break
;
case
0x202b
:
chartype
[
i
]
=
RLE
;
break
;
case
0x202c
:
chartype
[
i
]
=
PDF
;
break
;
case
0x202d
:
chartype
[
i
]
=
LRO
;
break
;
case
0x202e
:
chartype
[
i
]
=
RLO
;
break
;
case
0x2066
:
chartype
[
i
]
=
LRI
;
break
;
case
0x2067
:
chartype
[
i
]
=
RLI
;
break
;
case
0x2068
:
chartype
[
i
]
=
FSI
;
break
;
case
0x2069
:
chartype
[
i
]
=
PDI
;
break
;
}
break
;
}
}
}
/* RESOLVE EXPLICIT */
static
inline
UINT8
get_greater_even_level
(
UINT8
level
)
{
return
odd
(
level
)
?
level
+
1
:
level
+
2
;
}
static
inline
UINT8
get_greater_odd_level
(
UINT8
level
)
{
return
odd
(
level
)
?
level
+
2
:
level
+
1
;
}
static
inline
UINT8
get_embedding_direction
(
UINT8
level
)
{
return
odd
(
level
)
?
R
:
L
;
}
/*------------------------------------------------------------------------
Function: bidi_resolve_explicit
Recursively resolves explicit embedding levels and overrides.
Implements rules X1-X9, of the Unicode Bidirectional Algorithm.
Input: Base embedding level and direction
Character count
Output: Array of embedding levels
In/Out: Array of direction classes
Note: The function uses two simple counters to keep track of
matching explicit codes and PDF. Use the default argument for
the outermost call. The nesting counter counts the recursion
depth and not the embedding level.
------------------------------------------------------------------------*/
typedef
struct
tagStackItem
{
UINT8
level
;
UINT8
override
;
BOOL
isolate
;
}
StackItem
;
#define push_stack(l,o,i) \
do { stack_top--; \
stack[stack_top].level = l; \
stack[stack_top].override = o; \
stack[stack_top].isolate = i;} while(0)
#define pop_stack() do { stack_top++; } while(0)
#define valid_level(x) (x <= MAX_DEPTH && overflow_isolate_count == 0 && overflow_embedding_count == 0)
static
void
bidi_resolve_explicit
(
UINT8
baselevel
,
UINT8
*
classes
,
UINT8
*
levels
,
UINT32
count
)
{
/* X1 */
int
overflow_isolate_count
=
0
;
int
overflow_embedding_count
=
0
;
int
valid_isolate_count
=
0
;
UINT32
i
;
StackItem
stack
[
MAX_DEPTH
+
2
];
int
stack_top
=
MAX_DEPTH
+
1
;
stack
[
stack_top
].
level
=
baselevel
;
stack
[
stack_top
].
override
=
NI
;
stack
[
stack_top
].
isolate
=
FALSE
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
UINT8
least_odd
,
least_even
;
switch
(
classes
[
i
])
{
/* X2 */
case
RLE
:
least_odd
=
get_greater_odd_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_odd
))
push_stack
(
least_odd
,
NI
,
FALSE
);
else
if
(
overflow_isolate_count
==
0
)
overflow_embedding_count
++
;
break
;
/* X3 */
case
LRE
:
least_even
=
get_greater_even_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_even
))
push_stack
(
least_even
,
NI
,
FALSE
);
else
if
(
overflow_isolate_count
==
0
)
overflow_embedding_count
++
;
break
;
/* X4 */
case
RLO
:
least_odd
=
get_greater_odd_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_odd
))
push_stack
(
least_odd
,
R
,
FALSE
);
else
if
(
overflow_isolate_count
==
0
)
overflow_embedding_count
++
;
break
;
/* X5 */
case
LRO
:
least_even
=
get_greater_even_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_even
))
push_stack
(
least_even
,
L
,
FALSE
);
else
if
(
overflow_isolate_count
==
0
)
overflow_embedding_count
++
;
break
;
/* X5a */
case
RLI
:
least_odd
=
get_greater_odd_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_odd
))
{
valid_isolate_count
++
;
push_stack
(
least_odd
,
NI
,
TRUE
);
}
else
overflow_isolate_count
++
;
break
;
/* X5b */
case
LRI
:
least_even
=
get_greater_even_level
(
stack
[
stack_top
].
level
);
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
valid_level
(
least_even
))
{
valid_isolate_count
++
;
push_stack
(
least_even
,
NI
,
TRUE
);
}
else
overflow_isolate_count
++
;
break
;
/* X5c */
case
FSI
:
{
UINT8
new_level
=
0
;
int
skipping
=
0
;
int
j
;
levels
[
i
]
=
stack
[
stack_top
].
level
;
for
(
j
=
i
+
1
;
j
<
count
;
j
++
)
{
if
(
classes
[
j
]
==
LRI
||
classes
[
j
]
==
RLI
||
classes
[
j
]
==
FSI
)
{
skipping
++
;
continue
;
}
else
if
(
classes
[
j
]
==
PDI
)
{
if
(
skipping
)
skipping
--
;
else
break
;
continue
;
}
if
(
skipping
)
continue
;
if
(
classes
[
j
]
==
L
)
{
new_level
=
0
;
break
;
}
else
if
(
classes
[
j
]
==
R
||
classes
[
j
]
==
AL
)
{
new_level
=
1
;
break
;
}
}
if
(
odd
(
new_level
))
{
least_odd
=
get_greater_odd_level
(
stack
[
stack_top
].
level
);
if
(
valid_level
(
least_odd
))
{
valid_isolate_count
++
;
push_stack
(
least_odd
,
NI
,
TRUE
);
}
else
overflow_isolate_count
++
;
}
else
{
least_even
=
get_greater_even_level
(
stack
[
stack_top
].
level
);
if
(
valid_level
(
least_even
))
{
valid_isolate_count
++
;
push_stack
(
least_even
,
NI
,
TRUE
);
}
else
overflow_isolate_count
++
;
}
break
;
}
/* X6 */
case
ON
:
case
L
:
case
R
:
case
AN
:
case
EN
:
case
AL
:
case
NSM
:
case
CS
:
case
ES
:
case
ET
:
case
S
:
case
WS
:
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
stack
[
stack_top
].
override
!=
NI
)
classes
[
i
]
=
stack
[
stack_top
].
override
;
break
;
/* X6a */
case
PDI
:
if
(
overflow_isolate_count
)
overflow_isolate_count
--
;
else
if
(
!
valid_isolate_count
)
{
/* do nothing */
}
else
{
overflow_embedding_count
=
0
;
while
(
!
stack
[
stack_top
].
isolate
)
pop_stack
();
pop_stack
();
valid_isolate_count
--
;
}
levels
[
i
]
=
stack
[
stack_top
].
level
;
break
;
/* X7 */
case
PDF
:
levels
[
i
]
=
stack
[
stack_top
].
level
;
if
(
overflow_isolate_count
)
{
/* do nothing */
}
else
if
(
overflow_embedding_count
)
overflow_embedding_count
--
;
else
if
(
!
stack
[
stack_top
].
isolate
&&
stack_top
<
(
MAX_DEPTH
+
1
))
pop_stack
();
break
;
/* X8: Nothing */
default:
break
;
}
}
/* X9: Based on 5.2 Retaining Explicit Formatting Characters */
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
classes
[
i
]
==
RLE
||
classes
[
i
]
==
LRE
||
classes
[
i
]
==
RLO
||
classes
[
i
]
==
LRO
||
classes
[
i
]
==
PDF
)
classes
[
i
]
=
BN
;
}
static
inline
int
get_prev_valid_char_index
(
const
UINT8
*
classes
,
int
index
,
int
back_fence
)
{
if
(
index
==
-
1
||
index
==
back_fence
)
return
index
;
index
--
;
while
(
index
>
back_fence
&&
classes
[
index
]
==
BN
)
index
--
;
return
index
;
}
static
inline
int
get_next_valid_char_index
(
const
UINT8
*
classes
,
int
index
,
int
front_fence
)
{
if
(
index
==
front_fence
)
return
index
;
index
++
;
while
(
index
<
front_fence
&&
classes
[
index
]
==
BN
)
index
++
;
return
index
;
}
typedef
struct
tagRun
{
int
start
;
int
end
;
UINT8
e
;
}
Run
;
typedef
struct
tagRunChar
{
WCHAR
ch
;
UINT8
*
class
;
}
RunChar
;
typedef
struct
tagIsolatedRun
{
struct
list
entry
;
int
length
;
UINT8
sos
;
UINT8
eos
;
UINT8
e
;
RunChar
item
[
1
];
}
IsolatedRun
;
static
inline
int
get_next_valid_char_from_run
(
IsolatedRun
*
run
,
int
index
)
{
if
(
index
>=
(
run
->
length
-
1
))
return
-
1
;
index
++
;
while
(
index
<
run
->
length
&&
*
run
->
item
[
index
].
class
==
BN
)
index
++
;
if
(
index
==
run
->
length
)
return
-
1
;
return
index
;
}
static
inline
int
get_prev_valid_char_from_run
(
IsolatedRun
*
run
,
int
index
)
{
if
(
index
<=
0
)
return
-
1
;
index
--
;
while
(
index
>
-
1
&&
*
run
->
item
[
index
].
class
==
BN
)
index
--
;
return
index
;
}
static
inline
int
iso_previousChar
(
IsolatedRun
*
run
,
int
index
)
{
if
(
index
<=
0
)
return
-
1
;
return
index
--
;
}
static
inline
void
iso_dump_types
(
const
char
*
header
,
IsolatedRun
*
run
)
{
int
i
,
len
=
0
;
TRACE
(
"%s:"
,
header
);
TRACE
(
"[ "
);
for
(
i
=
0
;
i
<
run
->
length
&&
len
<
200
;
i
++
)
{
TRACE
(
" %s"
,
debug_type
[
*
run
->
item
[
i
].
class
]);
len
+=
strlen
(
debug_type
[
*
run
->
item
[
i
].
class
])
+
1
;
}
if
(
i
!=
run
->
length
)
TRACE
(
"..."
);
TRACE
(
" ]
\n
"
);
}
/*------------------------------------------------------------------------
Function: bidi_resolve_weak
Resolves the directionality of numeric and other weak character types
Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.
Input: Array of embedding levels
Character count
In/Out: Array of directional classes
Note: On input only these directional classes are expected
AL, HL, R, L, ON, BN, NSM, AN, EN, ES, ET, CS,
------------------------------------------------------------------------*/
static
void
bidi_resolve_weak
(
IsolatedRun
*
iso_run
)
{
int
i
;
/* W1 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
NSM
)
{
int
j
=
get_prev_valid_char_from_run
(
iso_run
,
i
);
if
(
j
==
-
1
)
*
iso_run
->
item
[
i
].
class
=
iso_run
->
sos
;
else
if
(
*
iso_run
->
item
[
j
].
class
>=
LRI
)
*
iso_run
->
item
[
i
].
class
=
ON
;
else
*
iso_run
->
item
[
i
].
class
=
*
iso_run
->
item
[
j
].
class
;
}
}
/* W2 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
EN
)
{
int
j
=
get_prev_valid_char_from_run
(
iso_run
,
i
);
while
(
j
>
-
1
)
{
if
(
*
iso_run
->
item
[
j
].
class
==
R
||
*
iso_run
->
item
[
j
].
class
==
L
||
*
iso_run
->
item
[
j
].
class
==
AL
)
{
if
(
*
iso_run
->
item
[
j
].
class
==
AL
)
*
iso_run
->
item
[
i
].
class
=
AN
;
break
;
}
j
=
get_prev_valid_char_from_run
(
iso_run
,
j
);
}
}
}
/* W3 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
AL
)
*
iso_run
->
item
[
i
].
class
=
R
;
}
/* W4 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
ES
)
{
int
b
=
get_prev_valid_char_from_run
(
iso_run
,
i
);
int
f
=
get_next_valid_char_from_run
(
iso_run
,
i
);
if
(
b
>
-
1
&&
f
>
-
1
&&
*
iso_run
->
item
[
b
].
class
==
EN
&&
*
iso_run
->
item
[
f
].
class
==
EN
)
*
iso_run
->
item
[
i
].
class
=
EN
;
}
else
if
(
*
iso_run
->
item
[
i
].
class
==
CS
)
{
int
b
=
get_prev_valid_char_from_run
(
iso_run
,
i
);
int
f
=
get_next_valid_char_from_run
(
iso_run
,
i
);
if
(
b
>
-
1
&&
f
>
-
1
&&
*
iso_run
->
item
[
b
].
class
==
EN
&&
*
iso_run
->
item
[
f
].
class
==
EN
)
*
iso_run
->
item
[
i
].
class
=
EN
;
else
if
(
b
>
-
1
&&
f
>
-
1
&&
*
iso_run
->
item
[
b
].
class
==
AN
&&
*
iso_run
->
item
[
f
].
class
==
AN
)
*
iso_run
->
item
[
i
].
class
=
AN
;
}
}
/* W5 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
ET
)
{
int
j
;
for
(
j
=
i
-
1
;
j
>
-
1
;
j
--
)
{
if
(
*
iso_run
->
item
[
j
].
class
==
BN
)
continue
;
if
(
*
iso_run
->
item
[
j
].
class
==
ET
)
continue
;
else
if
(
*
iso_run
->
item
[
j
].
class
==
EN
)
*
iso_run
->
item
[
i
].
class
=
EN
;
else
break
;
}
if
(
*
iso_run
->
item
[
i
].
class
==
ET
)
{
for
(
j
=
i
+
1
;
j
<
iso_run
->
length
;
j
++
)
{
if
(
*
iso_run
->
item
[
j
].
class
==
BN
)
continue
;
if
(
*
iso_run
->
item
[
j
].
class
==
ET
)
continue
;
else
if
(
*
iso_run
->
item
[
j
].
class
==
EN
)
*
iso_run
->
item
[
i
].
class
=
EN
;
else
break
;
}
}
}
}
/* W6 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
ET
||
*
iso_run
->
item
[
i
].
class
==
ES
||
*
iso_run
->
item
[
i
].
class
==
CS
||
*
iso_run
->
item
[
i
].
class
==
ON
)
{
int
b
=
i
-
1
;
int
f
=
i
+
1
;
if
(
b
>
-
1
&&
*
iso_run
->
item
[
b
].
class
==
BN
)
*
iso_run
->
item
[
b
].
class
=
ON
;
if
(
f
<
iso_run
->
length
&&
*
iso_run
->
item
[
f
].
class
==
BN
)
*
iso_run
->
item
[
f
].
class
=
ON
;
*
iso_run
->
item
[
i
].
class
=
ON
;
}
}
/* W7 */
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
if
(
*
iso_run
->
item
[
i
].
class
==
EN
)
{
int
j
;
for
(
j
=
get_prev_valid_char_from_run
(
iso_run
,
i
);
j
>
-
1
;
j
=
get_prev_valid_char_from_run
(
iso_run
,
j
))
if
(
*
iso_run
->
item
[
j
].
class
==
R
||
*
iso_run
->
item
[
j
].
class
==
L
)
{
if
(
*
iso_run
->
item
[
j
].
class
==
L
)
*
iso_run
->
item
[
i
].
class
=
L
;
break
;
}
if
(
iso_run
->
sos
==
L
&&
j
==
-
1
)
*
iso_run
->
item
[
i
].
class
=
L
;
}
}
}
typedef
struct
tagBracketPair
{
int
start
;
int
end
;
}
BracketPair
;
static
int
bracketpair_compr
(
const
void
*
a
,
const
void
*
b
)
{
return
((
BracketPair
*
)
a
)
->
start
-
((
BracketPair
*
)
b
)
->
start
;
}
static
BracketPair
*
bidi_compute_bracket_pairs
(
IsolatedRun
*
iso_run
)
{
WCHAR
*
open_stack
;
int
*
stack_index
;
int
stack_top
=
iso_run
->
length
;
BracketPair
*
out
=
NULL
;
int
pair_count
=
0
;
int
i
;
open_stack
=
heap_alloc
(
sizeof
(
WCHAR
)
*
iso_run
->
length
);
stack_index
=
heap_alloc
(
sizeof
(
int
)
*
iso_run
->
length
);
for
(
i
=
0
;
i
<
iso_run
->
length
;
i
++
)
{
unsigned
short
ubv
=
get_table_entry
(
bidi_bracket_table
,
iso_run
->
item
[
i
].
ch
);
if
(
ubv
)
{
if
(
!
out
)
{
out
=
heap_alloc
(
sizeof
(
BracketPair
));
out
[
0
].
start
=
-
1
;
}
if
((
ubv
>>
8
)
==
0
)
{
stack_top
--
;
open_stack
[
stack_top
]
=
iso_run
->
item
[
i
].
ch
+
(
signed
char
)(
ubv
&
0xff
);
/* deal with canonical equivalent U+2329/232A and U+3008/3009 */
if
(
open_stack
[
stack_top
]
==
0x232A
)
open_stack
[
stack_top
]
=
0x3009
;
stack_index
[
stack_top
]
=
i
;
}
else
if
((
ubv
>>
8
)
==
1
)
{
int
j
;
if
(
stack_top
==
iso_run
->
length
)
continue
;
for
(
j
=
stack_top
;
j
<
iso_run
->
length
;
j
++
)
{
WCHAR
c
=
iso_run
->
item
[
i
].
ch
;
if
(
c
==
0x232A
)
c
=
0x3009
;
if
(
c
==
open_stack
[
j
])
{
out
[
pair_count
].
start
=
stack_index
[
j
];
out
[
pair_count
].
end
=
i
;
pair_count
++
;
out
=
heap_realloc
(
out
,
sizeof
(
BracketPair
)
*
(
pair_count
+
1
));
out
[
pair_count
].
start
=
-
1
;
stack_top
=
j
+
1
;
break
;
}
}
}
}
}
if
(
pair_count
==
0
)
{
heap_free
(
out
);
out
=
NULL
;
}
else
if
(
pair_count
>
1
)
qsort
(
out
,
pair_count
,
sizeof
(
BracketPair
),
bracketpair_compr
);
heap_free
(
open_stack
);
heap_free
(
stack_index
);
return
out
;
}
static
inline
UINT8
get_rule_N0_class
(
UINT8
class
)
{
return
(
class
==
AN
||
class
==
EN
)
?
R
:
class
;
}
/*------------------------------------------------------------------------
Function: bidi_resolve_neutrals
Resolves the directionality of neutral character types.
Implements rules N1 and N2 of the Unicode Bidi Algorithm.
Input: Array of embedding levels
Character count
Baselevel
In/Out: Array of directional classes
Note: On input only these directional classes are expected
R, L, NI, AN, EN and BN
W8 resolves a number of ENs to L
------------------------------------------------------------------------*/
static
void
bidi_resolve_neutrals
(
IsolatedRun
*
run
)
{
BracketPair
*
pairs
;
int
i
;
/* Translate isolates into NI */
for
(
i
=
0
;
i
<
run
->
length
;
i
++
)
{
if
(
*
run
->
item
[
i
].
class
>=
LRI
)
*
run
->
item
[
i
].
class
=
NI
;
switch
(
*
run
->
item
[
i
].
class
)
{
case
B
:
case
S
:
case
WS
:
*
run
->
item
[
i
].
class
=
NI
;
}
ASSERT
(
*
run
->
item
[
i
].
class
<
5
||
*
run
->
item
[
i
].
class
==
BN
);
/* "Only NI, L, R, AN, EN and BN are allowed" */
}
/* N0: Skipping bracketed pairs for now */
pairs
=
bidi_compute_bracket_pairs
(
run
);
if
(
pairs
)
{
BracketPair
*
p
=
pairs
;
int
i
=
0
;
while
(
p
->
start
>=
0
)
{
UINT8
e
=
get_embedding_direction
(
run
->
e
);
UINT8
o
=
get_embedding_direction
(
run
->
e
+
1
);
BOOL
flag_o
=
FALSE
;
int
j
;
TRACE
(
"Bracket Pair [%i - %i]
\n
"
,
p
->
start
,
p
->
end
);
/* N0.b */
for
(
j
=
p
->
start
+
1
;
j
<
p
->
end
;
j
++
)
{
if
(
get_rule_N0_class
(
*
run
->
item
[
j
].
class
)
==
e
)
{
*
run
->
item
[
p
->
start
].
class
=
e
;
*
run
->
item
[
p
->
end
].
class
=
e
;
break
;
}
else
if
(
get_rule_N0_class
(
*
run
->
item
[
j
].
class
)
==
o
)
flag_o
=
TRUE
;
}
/* N0.c */
if
(
j
==
p
->
end
&&
flag_o
)
{
for
(
j
=
p
->
start
;
j
>=
0
;
j
--
)
{
if
(
get_rule_N0_class
(
*
run
->
item
[
j
].
class
)
==
o
)
{
*
run
->
item
[
p
->
start
].
class
=
o
;
*
run
->
item
[
p
->
end
].
class
=
o
;
break
;
}
else
if
(
get_rule_N0_class
(
*
run
->
item
[
j
].
class
)
==
e
)
{
*
run
->
item
[
p
->
start
].
class
=
e
;
*
run
->
item
[
p
->
end
].
class
=
e
;
break
;
}
}
if
(
j
<
0
)
{
*
run
->
item
[
p
->
start
].
class
=
run
->
sos
;
*
run
->
item
[
p
->
end
].
class
=
run
->
sos
;
}
}
i
++
;
p
=
&
pairs
[
i
];
}
heap_free
(
pairs
);
}
/* N1 */
for
(
i
=
0
;
i
<
run
->
length
;
i
++
)
{
UINT8
l
,
r
;
if
(
*
run
->
item
[
i
].
class
==
NI
)
{
int
b
=
get_prev_valid_char_from_run
(
run
,
i
);
int
j
;
if
(
b
==
-
1
)
{
l
=
run
->
sos
;
b
=
0
;
}
else
{
if
(
*
run
->
item
[
b
].
class
==
R
||
*
run
->
item
[
b
].
class
==
AN
||
*
run
->
item
[
b
].
class
==
EN
)
l
=
R
;
else
if
(
*
run
->
item
[
b
].
class
==
L
)
l
=
L
;
else
/* No string type */
continue
;
}
j
=
get_next_valid_char_from_run
(
run
,
i
);
while
(
j
>
-
1
&&
*
run
->
item
[
j
].
class
==
NI
)
j
=
get_next_valid_char_from_run
(
run
,
j
);
if
(
j
==
-
1
)
{
r
=
run
->
eos
;
j
=
run
->
length
;
}
else
if
(
*
run
->
item
[
j
].
class
==
R
||
*
run
->
item
[
j
].
class
==
AN
||
*
run
->
item
[
j
].
class
==
EN
)
r
=
R
;
else
if
(
*
run
->
item
[
j
].
class
==
L
)
r
=
L
;
else
/* No string type */
continue
;
if
(
r
==
l
)
{
for
(
b
=
i
;
b
<
j
&&
b
<
run
->
length
;
b
++
)
*
run
->
item
[
b
].
class
=
r
;
}
}
}
/* N2 */
for
(
i
=
0
;
i
<
run
->
length
;
i
++
)
{
if
(
*
run
->
item
[
i
].
class
==
NI
)
{
int
b
=
i
-
1
;
int
f
=
i
+
1
;
*
run
->
item
[
i
].
class
=
get_embedding_direction
(
run
->
e
);
if
(
b
>
-
1
&&
*
run
->
item
[
b
].
class
==
BN
)
*
run
->
item
[
b
].
class
=
get_embedding_direction
(
run
->
e
);
if
(
f
<
run
->
length
&&
*
run
->
item
[
f
].
class
==
BN
)
*
run
->
item
[
f
].
class
=
get_embedding_direction
(
run
->
e
);
}
}
}
/*------------------------------------------------------------------------
Function: bidi_resolve_implicit
Recursively resolves implicit embedding levels.
Implements rules I1 and I2 of the Unicode Bidirectional Algorithm.
Input: Array of direction classes
Character count
Base level
In/Out: Array of embedding levels
Note: levels may exceed 15 on output.
Accepted subset of direction classes
R, L, AN, EN
------------------------------------------------------------------------*/
static
void
bidi_resolve_implicit
(
const
UINT8
*
classes
,
UINT8
*
levels
,
int
sos
,
int
eos
)
{
int
i
;
/* I1/2 */
for
(
i
=
sos
;
i
<=
eos
;
i
++
)
{
if
(
classes
[
i
]
==
BN
)
continue
;
ASSERT
(
classes
[
i
]
>
0
);
/* "No Neutrals allowed to survive here." */
ASSERT
(
classes
[
i
]
<
5
);
/* "Out of range." */
if
(
odd
(
levels
[
i
])
&&
(
classes
[
i
]
==
L
||
classes
[
i
]
==
EN
||
classes
[
i
]
==
AN
))
levels
[
i
]
++
;
else
if
(
!
odd
(
levels
[
i
])
&&
classes
[
i
]
==
R
)
levels
[
i
]
++
;
else
if
(
!
odd
(
levels
[
i
])
&&
(
classes
[
i
]
==
EN
||
classes
[
i
]
==
AN
))
levels
[
i
]
+=
2
;
}
}
static
inline
BOOL
is_rule_L1_reset_class
(
UINT8
class
)
{
switch
(
class
)
{
case
WS
:
case
FSI
:
case
LRI
:
case
RLI
:
case
PDI
:
case
LRE
:
case
RLE
:
case
LRO
:
case
RLO
:
case
PDF
:
case
BN
:
return
TRUE
;
default:
return
FALSE
;
}
}
static
void
bidi_resolve_resolved
(
UINT8
baselevel
,
const
UINT8
*
classes
,
UINT8
*
levels
,
int
sos
,
int
eos
)
{
int
i
;
/* L1 */
for
(
i
=
sos
;
i
<=
eos
;
i
++
)
{
if
(
classes
[
i
]
==
B
||
classes
[
i
]
==
S
)
{
int
j
=
i
-
1
;
while
(
i
>
sos
&&
j
>=
sos
&&
is_rule_L1_reset_class
(
classes
[
j
]))
levels
[
j
--
]
=
baselevel
;
levels
[
i
]
=
baselevel
;
}
if
(
i
==
eos
&&
is_rule_L1_reset_class
(
classes
[
i
]))
{
int
j
=
i
;
while
(
j
>=
sos
&&
is_rule_L1_reset_class
(
classes
[
j
]))
levels
[
j
--
]
=
baselevel
;
}
}
}
static
HRESULT
bidi_compute_isolating_runs_set
(
UINT8
baselevel
,
UINT8
*
classes
,
UINT8
*
levels
,
const
WCHAR
*
string
,
UINT32
count
,
struct
list
*
set
)
{
int
run_start
,
run_end
,
i
;
int
run_count
=
0
;
HRESULT
hr
=
S_OK
;
Run
*
runs
;
runs
=
heap_alloc
(
count
*
sizeof
(
Run
));
if
(
!
runs
)
return
E_OUTOFMEMORY
;
list_init
(
set
);
/* Build Runs */
run_start
=
0
;
while
(
run_start
<
count
)
{
run_end
=
get_next_valid_char_index
(
classes
,
run_start
,
count
);
while
(
run_end
<
count
&&
levels
[
run_end
]
==
levels
[
run_start
])
run_end
=
get_next_valid_char_index
(
classes
,
run_end
,
count
);
run_end
--
;
runs
[
run_count
].
start
=
run_start
;
runs
[
run_count
].
end
=
run_end
;
runs
[
run_count
].
e
=
levels
[
run_start
];
run_start
=
get_next_valid_char_index
(
classes
,
run_end
,
count
);
run_count
++
;
}
/* Build Isolating Runs */
i
=
0
;
while
(
i
<
run_count
)
{
int
k
=
i
;
if
(
runs
[
k
].
start
>=
0
)
{
IsolatedRun
*
current_isolated
;
int
type_fence
,
real_end
;
int
j
;
current_isolated
=
heap_alloc
(
sizeof
(
IsolatedRun
)
+
sizeof
(
RunChar
)
*
count
);
if
(
!
current_isolated
)
{
hr
=
E_OUTOFMEMORY
;
break
;
}
run_start
=
runs
[
k
].
start
;
current_isolated
->
e
=
runs
[
k
].
e
;
current_isolated
->
length
=
(
runs
[
k
].
end
-
runs
[
k
].
start
)
+
1
;
for
(
j
=
0
;
j
<
current_isolated
->
length
;
j
++
)
{
current_isolated
->
item
[
j
].
class
=
&
classes
[
runs
[
k
].
start
+
j
];
current_isolated
->
item
[
j
].
ch
=
string
[
runs
[
k
].
start
+
j
];
}
run_end
=
runs
[
k
].
end
;
TRACE
(
"{ [%i -- %i]"
,
run_start
,
run_end
);
if
(
classes
[
run_end
]
==
BN
)
run_end
=
get_prev_valid_char_index
(
classes
,
run_end
,
runs
[
k
].
start
);
while
(
run_end
<
count
&&
(
classes
[
run_end
]
==
RLI
||
classes
[
run_end
]
==
LRI
||
classes
[
run_end
]
==
FSI
))
{
j
=
k
+
1
;
search:
while
(
j
<
run_count
&&
classes
[
runs
[
j
].
start
]
!=
PDI
)
j
++
;
if
(
j
<
run_count
&&
runs
[
i
].
e
!=
runs
[
j
].
e
)
{
j
++
;
goto
search
;
}
if
(
j
!=
run_count
)
{
int
l
=
current_isolated
->
length
;
int
m
;
current_isolated
->
length
+=
(
runs
[
j
].
end
-
runs
[
j
].
start
)
+
1
;
for
(
m
=
0
;
l
<
current_isolated
->
length
;
l
++
,
m
++
)
{
current_isolated
->
item
[
l
].
class
=
&
classes
[
runs
[
j
].
start
+
m
];
current_isolated
->
item
[
l
].
ch
=
string
[
runs
[
j
].
start
+
m
];
}
TRACE
(
"[%i -- %i]"
,
runs
[
j
].
start
,
runs
[
j
].
end
);
run_end
=
runs
[
j
].
end
;
if
(
classes
[
run_end
]
==
BN
)
run_end
=
get_prev_valid_char_index
(
classes
,
run_end
,
runs
[
i
].
start
);
runs
[
j
].
start
=
-
1
;
k
=
j
;
}
else
{
run_end
=
count
;
break
;
}
}
type_fence
=
get_prev_valid_char_index
(
classes
,
run_start
,
-
1
);
if
(
type_fence
==
-
1
)
current_isolated
->
sos
=
(
baselevel
>
levels
[
run_start
])
?
baselevel
:
levels
[
run_start
];
else
current_isolated
->
sos
=
(
levels
[
type_fence
]
>
levels
[
run_start
])
?
levels
[
type_fence
]
:
levels
[
run_start
];
current_isolated
->
sos
=
get_embedding_direction
(
current_isolated
->
sos
);
if
(
run_end
==
count
)
current_isolated
->
eos
=
current_isolated
->
sos
;
else
{
/* eos could be an BN */
if
(
classes
[
run_end
]
==
BN
)
{
real_end
=
get_prev_valid_char_index
(
classes
,
run_end
,
run_start
-
1
);
if
(
real_end
<
run_start
)
real_end
=
run_start
;
}
else
real_end
=
run_end
;
type_fence
=
get_next_valid_char_index
(
classes
,
run_end
,
count
);
if
(
type_fence
==
count
)
current_isolated
->
eos
=
(
baselevel
>
levels
[
real_end
])
?
baselevel
:
levels
[
real_end
];
else
current_isolated
->
eos
=
(
levels
[
type_fence
]
>
levels
[
real_end
])
?
levels
[
type_fence
]
:
levels
[
real_end
];
current_isolated
->
eos
=
get_embedding_direction
(
current_isolated
->
eos
);
}
list_add_tail
(
set
,
&
current_isolated
->
entry
);
TRACE
(
" } level %i {%s <--> %s}
\n
"
,
current_isolated
->
e
,
debug_type
[
current_isolated
->
sos
],
debug_type
[
current_isolated
->
eos
]);
}
i
++
;
}
heap_free
(
runs
);
return
hr
;
}
HRESULT
bidi_computelevels
(
const
WCHAR
*
string
,
UINT32
count
,
UINT8
baselevel
,
UINT8
*
explicit
,
UINT8
*
levels
)
{
IsolatedRun
*
iso_run
,
*
next
;
struct
list
IsolatingRuns
;
UINT8
*
chartype
;
HRESULT
hr
;
TRACE
(
"%s, %u
\n
"
,
debugstr_wn
(
string
,
count
),
count
);
chartype
=
heap_alloc
(
count
*
sizeof
(
*
chartype
));
if
(
!
chartype
)
return
E_OUTOFMEMORY
;
bidi_classify
(
string
,
chartype
,
count
);
if
(
TRACE_ON
(
bidi
))
bidi_dump_types
(
"start "
,
chartype
,
0
,
count
);
bidi_resolve_explicit
(
baselevel
,
chartype
,
levels
,
count
);
memcpy
(
explicit
,
levels
,
count
*
sizeof
(
*
explicit
));
if
(
TRACE_ON
(
bidi
))
bidi_dump_types
(
"after explicit"
,
chartype
,
0
,
count
);
/* X10/BD13: Compute Isolating runs */
hr
=
bidi_compute_isolating_runs_set
(
baselevel
,
chartype
,
levels
,
string
,
count
,
&
IsolatingRuns
);
if
(
FAILED
(
hr
))
goto
done
;
LIST_FOR_EACH_ENTRY_SAFE
(
iso_run
,
next
,
&
IsolatingRuns
,
IsolatedRun
,
entry
)
{
if
(
TRACE_ON
(
bidi
))
iso_dump_types
(
"run"
,
iso_run
);
bidi_resolve_weak
(
iso_run
);
if
(
TRACE_ON
(
bidi
))
iso_dump_types
(
"after weak"
,
iso_run
);
bidi_resolve_neutrals
(
iso_run
);
if
(
TRACE_ON
(
bidi
))
iso_dump_types
(
"after neutrals"
,
iso_run
);
list_remove
(
&
iso_run
->
entry
);
heap_free
(
iso_run
);
}
if
(
TRACE_ON
(
bidi
))
bidi_dump_types
(
"before implicit"
,
chartype
,
0
,
count
);
bidi_resolve_implicit
(
chartype
,
levels
,
0
,
count
-
1
);
bidi_classify
(
string
,
chartype
,
count
);
bidi_resolve_resolved
(
baselevel
,
chartype
,
levels
,
0
,
count
-
1
);
done:
heap_free
(
chartype
);
return
hr
;
}
dlls/dwrite/bracket.c
0 → 100644
View file @
fdd8454e
/* Unicode Bidirectional Bracket table */
/* generated from http://www.unicode.org/Public/7.0.0/ucd/BidiBrackets.txt */
/* DO NOT EDIT!! */
const
unsigned
short
bidi_bracket_table
[
768
]
=
{
/* level 1 offsets */
0x0100
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0120
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0130
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0140
,
0x0110
,
0x0110
,
0x0150
,
0x0110
,
0x0110
,
0x0110
,
0x0160
,
0x0110
,
0x0170
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0180
,
0x0110
,
0x0190
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x0110
,
0x01a0
,
0x01b0
,
/* level 2 offsets */
0x01c0
,
0x01c0
,
0x01d0
,
0x01c0
,
0x01c0
,
0x01e0
,
0x01c0
,
0x01e0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01f0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0200
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0210
,
0x01c0
,
0x01c0
,
0x0220
,
0x0220
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0230
,
0x01c0
,
0x0240
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0250
,
0x0260
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0210
,
0x01c0
,
0x0270
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0280
,
0x0290
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0230
,
0x01c0
,
0x02a0
,
0x01c0
,
0x01c0
,
0x02b0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x0250
,
0x02c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x02d0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01d0
,
0x01c0
,
0x01c0
,
0x01e0
,
0x01c0
,
0x02e0
,
0x02f0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
0x01c0
,
/* values */
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0002
,
0x0000
,
0x01fd
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0003
,
0x0101
,
0x00fe
,
0x01fc
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0002
,
0x0000
,
0x01fd
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0001
,
0x01fe
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
};
dlls/dwrite/dwrite_private.h
View file @
fdd8454e
...
...
@@ -82,6 +82,11 @@ static inline const char *debugstr_range(const DWRITE_TEXT_RANGE *range)
return
wine_dbg_sprintf
(
"%u:%u"
,
range
->
startPosition
,
range
->
length
);
}
static
inline
unsigned
short
get_table_entry
(
const
unsigned
short
*
table
,
WCHAR
ch
)
{
return
table
[
table
[
table
[
ch
>>
8
]
+
((
ch
>>
4
)
&
0x0f
)]
+
(
ch
&
0xf
)];
}
extern
HRESULT
create_font_from_logfont
(
const
LOGFONTW
*
,
IDWriteFont
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
convert_fontface_to_logfont
(
IDWriteFontFace
*
,
LOGFONTW
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_textformat
(
const
WCHAR
*
,
IDWriteFontCollection
*
,
DWRITE_FONT_WEIGHT
,
DWRITE_FONT_STYLE
,
DWRITE_FONT_STRETCH
,
...
...
@@ -104,3 +109,5 @@ extern HRESULT analyze_opentype_font(const void* font_data, UINT32* font_count,
extern
HRESULT
find_font_table
(
IDWriteFontFileStream
*
stream
,
UINT32
font_index
,
UINT32
tag
,
const
void
**
table_data
,
void
**
table_context
,
UINT32
*
table_size
,
BOOL
*
found
)
DECLSPEC_HIDDEN
;
extern
VOID
OpenType_CMAP_GetGlyphIndex
(
LPVOID
data
,
DWORD
utf32c
,
LPWORD
pgi
,
DWORD
flags
)
DECLSPEC_HIDDEN
;
extern
VOID
get_font_properties
(
LPCVOID
os2
,
LPCVOID
head
,
LPCVOID
post
,
DWRITE_FONT_METRICS
*
metrics
,
DWRITE_FONT_STRETCH
*
stretch
,
DWRITE_FONT_WEIGHT
*
weight
,
DWRITE_FONT_STYLE
*
style
)
DECLSPEC_HIDDEN
;
extern
HRESULT
bidi_computelevels
(
const
WCHAR
*
,
UINT32
,
UINT8
,
UINT8
*
,
UINT8
*
);
tools/make_unicode
View file @
fdd8454e
...
...
@@ -2384,6 +2384,7 @@ DUMP_COMPOSE_TABLES( "libs/wine/compose.c" );
DUMP_CTYPE_TABLES
(
"libs/wine/wctype.c"
);
dump_mirroring
(
"dlls/usp10/mirror.c"
);
dump_bracket
(
"dlls/usp10/bracket.c"
);
dump_bracket
(
"dlls/dwrite/bracket.c"
);
dump_shaping
(
"dlls/usp10/shaping.c"
);
dump_linebreak
(
"dlls/usp10/linebreak.c"
);
dump_linebreak
(
"dlls/dwrite/linebreak.c"
);
...
...
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