Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
a60df3e4
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
a60df3e4
编写于
5月 31, 2013
作者:
P
prr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8015556: [macosx] surrogate pairs do not render properly.
Reviewed-by: bae, jchen
上级
2e74e136
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
210 addition
and
69 deletion
+210
-69
src/macosx/classes/sun/font/CCharToGlyphMapper.java
src/macosx/classes/sun/font/CCharToGlyphMapper.java
+83
-69
test/java/awt/FontClass/SurrogateTest/SuppCharTest.java
test/java/awt/FontClass/SurrogateTest/SuppCharTest.java
+127
-0
未找到文件。
src/macosx/classes/sun/font/CCharToGlyphMapper.java
浏览文件 @
a60df3e4
...
...
@@ -130,17 +130,27 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
}
public
synchronized
int
charToGlyph
(
int
unicode
)
{
if
(
unicode
>=
0x10000
)
{
int
[]
glyphs
=
new
int
[
2
];
char
[]
surrogates
=
new
char
[
2
];
int
base
=
unicode
-
0x10000
;
surrogates
[
0
]
=
(
char
)((
base
>>>
10
)
+
HI_SURROGATE_START
);
surrogates
[
1
]
=
(
char
)((
base
%
0x400
)
+
LO_SURROGATE_START
);
charsToGlyphs
(
2
,
surrogates
,
glyphs
);
return
glyphs
[
0
];
}
else
{
return
charToGlyph
((
char
)
unicode
);
}
}
public
synchronized
void
charsToGlyphs
(
int
count
,
char
[]
unicodes
,
int
[]
glyphs
)
{
cache
.
get
(
count
,
unicodes
,
glyphs
);
}
public
synchronized
void
charsToGlyphs
(
int
count
,
int
[]
unicodes
,
int
[]
glyphs
)
{
f
inal
char
[]
unicodeChars
=
new
char
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++)
unicodeChars
[
i
]
=
(
char
)
unicodes
[
i
]
;
cache
.
get
(
count
,
unicodeChars
,
glyphs
)
;
f
or
(
int
i
=
0
;
i
<
count
;
i
++)
{
glyphs
[
i
]
=
charToGlyph
(
unicodes
[
i
])
;
}
;
}
// This mapper returns either the glyph code, or if the character can be
...
...
@@ -166,7 +176,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
firstLayerCache
[
1
]
=
1
;
}
public
int
get
(
final
char
index
)
{
public
synchronized
int
get
(
final
int
index
)
{
if
(
index
<
FIRST_LAYER_SIZE
)
{
// catch common glyphcodes
return
firstLayerCache
[
index
];
...
...
@@ -179,12 +189,12 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
}
if
(
generalCache
==
null
)
return
0
;
final
Integer
value
=
generalCache
.
get
(
new
Integer
(
index
)
);
final
Integer
value
=
generalCache
.
get
(
index
);
if
(
value
==
null
)
return
0
;
return
value
.
intValue
();
}
public
void
put
(
final
char
index
,
final
int
value
)
{
public
synchronized
void
put
(
final
int
index
,
final
int
value
)
{
if
(
index
<
FIRST_LAYER_SIZE
)
{
// catch common glyphcodes
firstLayerCache
[
index
]
=
value
;
...
...
@@ -204,7 +214,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
generalCache
=
new
HashMap
<
Integer
,
Integer
>();
}
generalCache
.
put
(
new
Integer
(
index
),
new
Integer
(
value
)
);
generalCache
.
put
(
index
,
value
);
}
private
class
SparseBitShiftingTwoLayerArray
{
...
...
@@ -220,14 +230,14 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
this
.
secondLayerLength
=
size
>>
shift
;
}
public
int
get
(
final
char
index
)
{
public
int
get
(
final
int
index
)
{
final
int
firstIndex
=
index
>>
shift
;
final
int
[]
firstLayerRow
=
cache
[
firstIndex
];
if
(
firstLayerRow
==
null
)
return
0
;
return
firstLayerRow
[
index
-
(
firstIndex
*
(
1
<<
shift
))];
}
public
void
put
(
final
char
index
,
final
int
value
)
{
public
void
put
(
final
int
index
,
final
int
value
)
{
final
int
firstIndex
=
index
>>
shift
;
int
[]
firstLayerRow
=
cache
[
firstIndex
];
if
(
firstLayerRow
==
null
)
{
...
...
@@ -237,77 +247,81 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
}
}
public
void
get
(
int
count
,
char
[]
indicies
,
int
[]
values
){
public
synchronized
void
get
(
int
count
,
char
[]
indicies
,
int
[]
values
)
{
// "missed" is the count of 'char' that are not mapped.
// Surrogates count for 2.
// unmappedChars is the unique list of these chars.
// unmappedCharIndices is the location in the original array
int
missed
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++){
char
code
=
indicies
[
i
];
char
[]
unmappedChars
=
null
;
int
[]
unmappedCharIndices
=
null
;
for
(
int
i
=
0
;
i
<
count
;
i
++){
int
code
=
indicies
[
i
];
if
(
code
>=
HI_SURROGATE_START
&&
code
<=
HI_SURROGATE_END
&&
i
<
count
-
1
)
{
char
low
=
indicies
[
i
+
1
];
if
(
low
>=
LO_SURROGATE_START
&&
low
<=
LO_SURROGATE_END
)
{
code
=
(
code
-
HI_SURROGATE_START
)
*
0x400
+
low
-
LO_SURROGATE_START
+
0x10000
;
}
}
final
int
value
=
get
(
code
);
if
(
value
!=
0
)
{
if
(
value
!=
0
&&
value
!=
-
1
)
{
values
[
i
]
=
value
;
}
else
{
// zero this element out, because the caller does not
// promise to keep it clean
if
(
code
>=
0x10000
)
{
values
[
i
+
1
]
=
INVISIBLE_GLYPH_ID
;
i
++;
}
}
else
{
values
[
i
]
=
0
;
put
(
code
,
-
1
);
if
(
unmappedChars
==
null
)
{
// This is likely to be longer than we need,
// but is the simplest and cheapest option.
unmappedChars
=
new
char
[
indicies
.
length
];
unmappedCharIndices
=
new
int
[
indicies
.
length
];
}
unmappedChars
[
missed
]
=
indicies
[
i
];
unmappedCharIndices
[
missed
]
=
i
;
if
(
code
>=
0x10000
)
{
// was a surrogate pair
unmappedChars
[++
missed
]
=
indicies
[++
i
];
}
missed
++;
}
}
if
(
missed
==
0
)
return
;
// horray! everything is already cached!
final
char
[]
filteredCodes
=
new
char
[
missed
];
// all index codes requested (partially filled)
final
int
[]
filteredIndicies
=
new
int
[
missed
];
// local indicies into filteredCodes array (totally filled)
if
(
missed
==
0
)
{
return
;
}
// scan, mark, and store the index codes again to send into native
int
j
=
0
;
int
dupes
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++){
if
(
values
[
i
]
!=
0L
)
continue
;
// already filled
final
int
[]
glyphCodes
=
new
int
[
missed
];
final
char
code
=
indicies
[
i
];
// bulk call to fill in the unmapped code points.
nativeCharsToGlyphs
(
fFont
.
getNativeFontPtr
(),
missed
,
unmappedChars
,
glyphCodes
);
// we have already promised to fill this code - this is a dupe
if
(
get
(
code
)
==
-
1
){
filteredIndicies
[
j
]
=
-
1
;
dupes
++;
j
++;
continue
;
for
(
int
m
=
0
;
m
<
missed
;
m
++){
int
i
=
unmappedCharIndices
[
m
];
int
code
=
unmappedChars
[
m
];
if
(
code
>=
HI_SURROGATE_START
&&
code
<=
HI_SURROGATE_END
&&
m
<
missed
-
1
)
{
char
low
=
indicies
[
m
+
1
];
if
(
low
>=
LO_SURROGATE_START
&&
low
<=
LO_SURROGATE_END
)
{
code
=
(
code
-
HI_SURROGATE_START
)
*
0x400
+
low
-
LO_SURROGATE_START
+
0x10000
;
}
// this is a code we have not obtained before
// mark this one as "promise to get" in the global cache with a -1
final
int
k
=
j
-
dupes
;
filteredCodes
[
k
]
=
code
;
put
(
code
,
-
1
);
filteredIndicies
[
j
]
=
k
;
j
++;
}
final
int
filteredRunLen
=
j
-
dupes
;
final
int
[]
filteredValues
=
new
int
[
filteredRunLen
];
// bulk call to fill in the distinct values
nativeCharsToGlyphs
(
fFont
.
getNativeFontPtr
(),
filteredRunLen
,
filteredCodes
,
filteredValues
);
// scan the requested list, and fill in values from our
// distinct code list which has been filled from "getDistinct"
j
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++){
if
(
values
[
i
]
!=
0L
&&
values
[
i
]
!=
-
1L
)
continue
;
// already placed
final
int
k
=
filteredIndicies
[
j
];
// index into filteredImages array
final
char
code
=
indicies
[
i
];
if
(
k
==
-
1L
){
// we should have already filled the cache with this value
values
[
i
]
=
get
(
code
);
}
else
{
// fill the particular code request, and store in the cache
final
int
ptr
=
filteredValues
[
k
];
values
[
i
]
=
ptr
;
put
(
code
,
ptr
);
values
[
i
]
=
glyphCodes
[
m
];
put
(
code
,
values
[
i
]);
if
(
code
>=
0x10000
)
{
m
++;
values
[
i
+
1
]
=
INVISIBLE_GLYPH_ID
;
}
j
++;
}
}
}
...
...
test/java/awt/FontClass/SurrogateTest/SuppCharTest.java
0 → 100644
浏览文件 @
a60df3e4
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8015556
* @summary Surrogate pairs do not render properly on MacOS X.
*/
import
java.util.Locale
;
import
java.awt.*
;
import
java.awt.font.*
;
import
javax.swing.*
;
public
class
SuppCharTest
{
static
String
str
=
"ABC\uD840\uDC01\uD840\uDC00AB"
;
static
String
EXTB_FONT
=
"MingLiU-ExtB"
;
public
static
void
main
(
String
args
[])
throws
Exception
{
final
Font
font
=
new
Font
(
EXTB_FONT
,
Font
.
PLAIN
,
36
);
if
(!
EXTB_FONT
.
equalsIgnoreCase
(
font
.
getFamily
(
Locale
.
ENGLISH
)))
{
return
;
}
SwingUtilities
.
invokeLater
(
new
Runnable
(){
@Override
public
void
run
(){
JFrame
f
=
new
JFrame
(
"Test Supplementary Char Support"
);
Component
c
=
new
SuppCharComp
(
font
,
str
);
f
.
add
(
"Center"
,
c
);
JButton
b
=
new
JButton
(
str
);
b
.
setFont
(
font
);
f
.
add
(
"South"
,
b
);
f
.
pack
();
f
.
setVisible
(
true
);
}
});
/* If a supplementary character was found, 'invisible glyphs'
* with value 65535 will be inserted in the place of the 2nd (low)
* char index. So we are looking here to make sure such substitutions
* took place.
*/
FontRenderContext
frc
=
new
FontRenderContext
(
null
,
false
,
false
);
GlyphVector
gv
=
font
.
createGlyphVector
(
frc
,
str
);
int
numGlyphs
=
gv
.
getNumGlyphs
();
int
[]
codes
=
gv
.
getGlyphCodes
(
0
,
numGlyphs
,
null
);
boolean
foundInvisibleGlyph
=
false
;
for
(
int
i
=
0
;
i
<
numGlyphs
;
i
++)
{
if
(
codes
[
i
]
==
65535
)
{
foundInvisibleGlyph
=
true
;
break
;
}
}
if
(!
foundInvisibleGlyph
)
{
throw
new
RuntimeException
(
"No invisible glyphs"
);
}
if
(
font
.
canDisplayUpTo
(
str
)
!=
-
1
)
{
throw
new
RuntimeException
(
"Font can't display all chars"
);
}
}
}
class
SuppCharComp
extends
Component
{
static
final
int
w
=
400
,
h
=
250
;
public
Dimension
preferredSize
()
{
return
new
Dimension
(
w
,
h
);
}
String
str
=
null
;
Font
font
=
null
;
public
SuppCharComp
(
Font
font
,
String
str
)
{
this
.
font
=
font
;
this
.
str
=
str
;
}
public
void
paint
(
Graphics
g
)
{
Graphics2D
g2d
=
(
Graphics2D
)
g
.
create
();
g2d
.
setColor
(
Color
.
white
);
g2d
.
fillRect
(
0
,
0
,
w
,
h
);
g2d
.
setColor
(
Color
.
black
);
int
y
=
0
;
g2d
.
setRenderingHint
(
RenderingHints
.
KEY_FRACTIONALMETRICS
,
RenderingHints
.
VALUE_FRACTIONALMETRICS_ON
);
g2d
.
setRenderingHint
(
RenderingHints
.
KEY_TEXT_ANTIALIASING
,
RenderingHints
.
VALUE_TEXT_ANTIALIAS_ON
);
g2d
.
setFont
(
font
);
g2d
.
drawString
(
str
,
10
,
50
);
FontRenderContext
frc
=
g2d
.
getFontRenderContext
();
GlyphVector
gv
=
font
.
createGlyphVector
(
frc
,
str
);
g2d
.
drawGlyphVector
(
gv
,
10
,
100
);
TextLayout
tl
=
new
TextLayout
(
str
,
font
,
frc
);
tl
.
draw
(
g2d
,
10
,
150
);
char
[]
ca
=
str
.
toCharArray
();
g2d
.
drawChars
(
ca
,
0
,
ca
.
length
,
10
,
200
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录