Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
bbb70c58
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看板
提交
bbb70c58
编写于
12月 16, 2015
作者:
L
lbourges
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8144718: Pisces / Marlin Strokers may generate invalid curves with huge coordinates and round joins
Reviewed-by: flar, prr
上级
32f3be23
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
351 addition
and
11 deletion
+351
-11
src/share/classes/sun/java2d/marlin/Stroker.java
src/share/classes/sun/java2d/marlin/Stroker.java
+15
-5
src/share/classes/sun/java2d/pisces/Stroker.java
src/share/classes/sun/java2d/pisces/Stroker.java
+14
-6
test/sun/java2d/marlin/TextClipErrorTest.java
test/sun/java2d/marlin/TextClipErrorTest.java
+322
-0
未找到文件。
src/share/classes/sun/java2d/marlin/Stroker.java
浏览文件 @
bbb70c58
...
...
@@ -87,6 +87,7 @@ final class Stroker implements PathConsumer2D, MarlinConst {
private
int
joinStyle
;
private
float
lineWidth2
;
private
float
invHalfLineWidth2Sq
;
private
final
float
[]
offset0
=
new
float
[
2
];
private
final
float
[]
offset1
=
new
float
[
2
];
...
...
@@ -158,6 +159,7 @@ final class Stroker implements PathConsumer2D, MarlinConst {
this
.
out
=
pc2d
;
this
.
lineWidth2
=
lineWidth
/
2
f
;
this
.
invHalfLineWidth2Sq
=
1
f
/
(
2
f
*
lineWidth2
*
lineWidth2
);
this
.
capStyle
=
capStyle
;
this
.
joinStyle
=
joinStyle
;
...
...
@@ -252,11 +254,11 @@ final class Stroker implements PathConsumer2D, MarlinConst {
// The sign of the dot product of mx,my and omx,omy is equal to the
// the sign of the cosine of ext
// (ext is the angle between omx,omy and mx,my).
double
cosext
=
omx
*
mx
+
omy
*
my
;
final
float
cosext
=
omx
*
mx
+
omy
*
my
;
// If it is >=0, we know that abs(ext) is <= 90 degrees, so we only
// need 1 curve to approximate the circle section that joins omx,omy
// and mx,my.
final
int
numCurves
=
cosext
>=
0
?
1
:
2
;
final
int
numCurves
=
(
cosext
>=
0
f
)
?
1
:
2
;
switch
(
numCurves
)
{
case
1
:
...
...
@@ -302,14 +304,22 @@ final class Stroker implements PathConsumer2D, MarlinConst {
final
float
mx
,
final
float
my
,
boolean
rev
)
{
float
cosext2
=
(
omx
*
mx
+
omy
*
my
)
/
(
2
f
*
lineWidth2
*
lineWidth2
);
final
float
cosext2
=
(
omx
*
mx
+
omy
*
my
)
*
invHalfLineWidth2Sq
;
// check round off errors producing cos(ext) > 1 and a NaN below
// cos(ext) == 1 implies colinear segments and an empty join anyway
if
(
cosext2
>=
0.5f
)
{
// just return to avoid generating a flat curve:
return
;
}
// cv is the length of P1-P0 and P2-P3 divided by the radius of the arc
// (so, cv assumes the arc has radius 1). P0, P1, P2, P3 are the points that
// define the bezier curve we're computing.
// It is computed using the constraints that P1-P0 and P3-P2 are parallel
// to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|.
float
cv
=
(
float
)
((
4.0
/
3.0
)
*
sqrt
(
0.5
-
cosext2
)
/
(
1.0
+
sqrt
(
cosext2
+
0.5
)));
float
cv
=
(
float
)
((
4.0
/
3.0
)
*
sqrt
(
0.5
-
cosext2
)
/
(
1.0
+
sqrt
(
cosext2
+
0.5
)));
// if clockwise, we need to negate cv.
if
(
rev
)
{
// rev is equivalent to isCW(omx, omy, mx, my)
cv
=
-
cv
;
...
...
src/share/classes/sun/java2d/pisces/Stroker.java
浏览文件 @
bbb70c58
/*
* Copyright (c) 2007, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 201
5
, 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
...
...
@@ -193,11 +193,11 @@ final class Stroker implements PathConsumer2D {
// The sign of the dot product of mx,my and omx,omy is equal to the
// the sign of the cosine of ext
// (ext is the angle between omx,omy and mx,my).
double
cosext
=
omx
*
mx
+
omy
*
my
;
final
float
cosext
=
omx
*
mx
+
omy
*
my
;
// If it is >=0, we know that abs(ext) is <= 90 degrees, so we only
// need 1 curve to approximate the circle section that joins omx,omy
// and mx,my.
final
int
numCurves
=
cosext
>=
0
?
1
:
2
;
final
int
numCurves
=
(
cosext
>=
0
f
)
?
1
:
2
;
switch
(
numCurves
)
{
case
1
:
...
...
@@ -242,14 +242,22 @@ final class Stroker implements PathConsumer2D {
final
float
mx
,
final
float
my
,
boolean
rev
)
{
float
cosext2
=
(
omx
*
mx
+
omy
*
my
)
/
(
2
*
lineWidth2
*
lineWidth2
);
final
float
cosext2
=
(
omx
*
mx
+
omy
*
my
)
/
(
2
f
*
lineWidth2
*
lineWidth2
);
// check round off errors producing cos(ext) > 1 and a NaN below
// cos(ext) == 1 implies colinear segments and an empty join anyway
if
(
cosext2
>=
0.5f
)
{
// just return to avoid generating a flat curve:
return
;
}
// cv is the length of P1-P0 and P2-P3 divided by the radius of the arc
// (so, cv assumes the arc has radius 1). P0, P1, P2, P3 are the points that
// define the bezier curve we're computing.
// It is computed using the constraints that P1-P0 and P3-P2 are parallel
// to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|.
float
cv
=
(
float
)
((
4.0
/
3.0
)
*
sqrt
(
0.5
-
cosext2
)
/
(
1.0
+
sqrt
(
cosext2
+
0.5
)));
float
cv
=
(
float
)
((
4.0
/
3.0
)
*
sqrt
(
0.5
-
cosext2
)
/
(
1.0
+
sqrt
(
cosext2
+
0.5
)));
// if clockwise, we need to negate cv.
if
(
rev
)
{
// rev is equivalent to isCW(omx, omy, mx, my)
cv
=
-
cv
;
...
...
test/sun/java2d/marlin/TextClipErrorTest.java
0 → 100644
浏览文件 @
bbb70c58
/*
* Copyright (c) 2015, 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.
*/
import
java.awt.BasicStroke
;
import
java.awt.Color
;
import
java.awt.Font
;
import
java.awt.Graphics2D
;
import
java.awt.RenderingHints
;
import
java.awt.Shape
;
import
java.awt.font.FontRenderContext
;
import
java.awt.font.GlyphVector
;
import
java.awt.geom.AffineTransform
;
import
java.awt.geom.Line2D
;
import
java.awt.geom.Path2D
;
import
java.awt.geom.PathIterator
;
import
static
java
.
awt
.
geom
.
PathIterator
.
SEG_CLOSE
;
import
static
java
.
awt
.
geom
.
PathIterator
.
SEG_CUBICTO
;
import
static
java
.
awt
.
geom
.
PathIterator
.
SEG_LINETO
;
import
static
java
.
awt
.
geom
.
PathIterator
.
SEG_MOVETO
;
import
static
java
.
awt
.
geom
.
PathIterator
.
SEG_QUADTO
;
import
java.awt.image.BufferedImage
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Locale
;
import
java.util.logging.Handler
;
import
java.util.logging.LogRecord
;
import
java.util.logging.Logger
;
import
javax.imageio.ImageIO
;
/**
* @test @bug 8144718
* @summary Check the Stroker.drawBezApproxForArc() bug (stoke with round
* joins): if cosext2 > 0.5, it generates curves with NaN coordinates
* @run main TextClipErrorTest
*/
public
class
TextClipErrorTest
{
static
final
boolean
SAVE_IMAGE
=
false
;
static
final
boolean
SERIALIZE
=
false
;
public
static
void
main
(
String
[]
args
)
{
Locale
.
setDefault
(
Locale
.
US
);
// initialize j.u.l Looger:
final
Logger
log
=
Logger
.
getLogger
(
"sun.java2d.marlin"
);
log
.
addHandler
(
new
Handler
()
{
@Override
public
void
publish
(
LogRecord
record
)
{
Throwable
th
=
record
.
getThrown
();
// detect potential Throwable thrown by XxxArrayCache.check():
if
(
th
!=
null
&&
th
.
getClass
()
==
Throwable
.
class
)
{
StackTraceElement
[]
stackElements
=
th
.
getStackTrace
();
for
(
int
i
=
0
;
i
<
stackElements
.
length
;
i
++)
{
StackTraceElement
e
=
stackElements
[
i
];
if
(
e
.
getClassName
().
startsWith
(
"sun.java2d.marlin"
)
&&
e
.
getClassName
().
contains
(
"ArrayCache"
)
&&
"check"
.
equals
(
e
.
getMethodName
()))
{
System
.
out
.
println
(
"Test failed:\n"
+
record
.
getMessage
());
th
.
printStackTrace
(
System
.
out
);
throw
new
RuntimeException
(
"Test failed: "
,
th
);
}
}
}
}
@Override
public
void
flush
()
{
}
@Override
public
void
close
()
throws
SecurityException
{
}
});
log
.
info
(
"TextClipErrorTest: start"
);
// enable Marlin logging & internal checks:
System
.
setProperty
(
"sun.java2d.renderer.log"
,
"true"
);
System
.
setProperty
(
"sun.java2d.renderer.useLogger"
,
"true"
);
System
.
setProperty
(
"sun.java2d.renderer.doChecks"
,
"true"
);
BufferedImage
image
=
new
BufferedImage
(
256
,
256
,
BufferedImage
.
TYPE_INT_ARGB
);
Graphics2D
g2d
=
image
.
createGraphics
();
g2d
.
setColor
(
Color
.
red
);
try
{
g2d
.
setRenderingHint
(
RenderingHints
.
KEY_ANTIALIASING
,
RenderingHints
.
VALUE_ANTIALIAS_ON
);
Font
font
=
g2d
.
getFont
();
FontRenderContext
frc
=
new
FontRenderContext
(
new
AffineTransform
(),
true
,
true
);
g2d
.
setStroke
(
new
BasicStroke
(
4.0f
,
BasicStroke
.
CAP_ROUND
,
BasicStroke
.
JOIN_ROUND
));
final
Shape
badShape
;
if
(
SERIALIZE
)
{
final
GlyphVector
gv1
=
font
.
createGlyphVector
(
frc
,
"\u00d6"
);
final
Shape
textShape
=
gv1
.
getOutline
();
final
AffineTransform
at1
=
AffineTransform
.
getTranslateInstance
(
-
2091202.554154681
,
5548.601436981691
);
badShape
=
at1
.
createTransformedShape
(
textShape
);
serializeShape
(
badShape
);
}
else
{
badShape
=
deserializeShape
();
}
g2d
.
draw
(
badShape
);
// Draw anything within bounds and it fails:
g2d
.
draw
(
new
Line2D
.
Double
(
10
,
20
,
30
,
40
));
if
(
SAVE_IMAGE
)
{
final
File
file
=
new
File
(
"TextClipErrorTest.png"
);
System
.
out
.
println
(
"Writing file: "
+
file
.
getAbsolutePath
());
ImageIO
.
write
(
image
,
"PNG"
,
file
);
}
}
catch
(
IOException
ex
)
{
ex
.
printStackTrace
();
}
finally
{
g2d
.
dispose
();
log
.
info
(
"TextClipErrorTest: end"
);
}
}
private
static
void
serializeShape
(
Shape
shape
)
{
final
double
[]
coords
=
new
double
[
6
];
final
int
len
=
32
;
final
ArrayList
<
Integer
>
typeList
=
new
ArrayList
<
Integer
>(
len
);
final
ArrayList
<
double
[]>
coordsList
=
new
ArrayList
<
double
[]>(
len
);
for
(
PathIterator
pi
=
shape
.
getPathIterator
(
null
);
!
pi
.
isDone
();
pi
.
next
())
{
switch
(
pi
.
currentSegment
(
coords
))
{
case
SEG_MOVETO:
typeList
.
add
(
SEG_MOVETO
);
coordsList
.
add
(
Arrays
.
copyOf
(
coords
,
2
));
break
;
case
SEG_LINETO:
typeList
.
add
(
SEG_LINETO
);
coordsList
.
add
(
Arrays
.
copyOf
(
coords
,
2
));
break
;
case
SEG_QUADTO:
typeList
.
add
(
SEG_QUADTO
);
coordsList
.
add
(
Arrays
.
copyOf
(
coords
,
4
));
break
;
case
SEG_CUBICTO:
typeList
.
add
(
SEG_CUBICTO
);
coordsList
.
add
(
Arrays
.
copyOf
(
coords
,
6
));
break
;
case
SEG_CLOSE:
typeList
.
add
(
SEG_CLOSE
);
coordsList
.
add
(
null
);
break
;
default
:
}
}
final
StringBuilder
sb
=
new
StringBuilder
(
1024
);
// types:
sb
.
append
(
"private static final int[] SHAPE_TYPES = new int[]{\n"
);
for
(
Integer
i
:
typeList
)
{
sb
.
append
(
i
).
append
(
",\n"
);
}
sb
.
append
(
"};\n"
);
// coords:
sb
.
append
(
"private static final double[][] SHAPE_COORDS = new double[][]{\n"
);
for
(
double
[]
c
:
coordsList
)
{
if
(
c
==
null
)
{
sb
.
append
(
"null,\n"
);
}
else
{
sb
.
append
(
"new double[]{"
);
for
(
int
i
=
0
;
i
<
c
.
length
;
i
++)
{
sb
.
append
(
c
[
i
]).
append
(
","
);
}
sb
.
append
(
"},\n"
);
}
}
sb
.
append
(
"};\n"
);
System
.
out
.
println
(
"Shape size: "
+
typeList
.
size
());
System
.
out
.
println
(
"Serialized shape:\n"
+
sb
.
toString
());
}
private
static
Shape
deserializeShape
()
{
final
Path2D
.
Double
path
=
new
Path2D
.
Double
();
for
(
int
i
=
0
;
i
<
SHAPE_TYPES
.
length
;
i
++)
{
double
[]
coords
=
SHAPE_COORDS
[
i
];
switch
(
SHAPE_TYPES
[
i
])
{
case
SEG_MOVETO:
path
.
moveTo
(
coords
[
0
],
coords
[
1
]);
break
;
case
SEG_LINETO:
path
.
lineTo
(
coords
[
0
],
coords
[
1
]);
break
;
case
SEG_QUADTO:
path
.
quadTo
(
coords
[
0
],
coords
[
1
],
coords
[
2
],
coords
[
3
]);
break
;
case
SEG_CUBICTO:
path
.
curveTo
(
coords
[
0
],
coords
[
1
],
coords
[
2
],
coords
[
3
],
coords
[
4
],
coords
[
5
]);
break
;
case
SEG_CLOSE:
path
.
closePath
();
break
;
default
:
}
}
return
path
;
}
// generated code:
private
static
final
int
[]
SHAPE_TYPES
=
new
int
[]{
0
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
4
,
0
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
4
,
0
,
1
,
1
,
1
,
1
,
4
,
0
,
1
,
1
,
1
,
1
,
4
,
};
private
static
final
double
[][]
SHAPE_COORDS
=
new
double
[][]{
new
double
[]{-
2091197.819779681
,
5540.648311981691
,},
new
double
[]{-
2091199.116654681
,
5540.648311981691
,
-
2091199.874467181
,
5541.609249481691
,},
new
double
[]{-
2091200.632279681
,
5542.570186981691
,
-
2091200.632279681
,
5544.242061981691
,},
new
double
[]{-
2091200.632279681
,
5545.882686981691
,
-
2091199.874467181
,
5546.843624481691
,},
new
double
[]{-
2091199.116654681
,
5547.804561981691
,
-
2091197.819779681
,
5547.804561981691
,},
new
double
[]{-
2091196.538529681
,
5547.804561981691
,
-
2091195.780717181
,
5546.843624481691
,},
new
double
[]{-
2091195.022904681
,
5545.882686981691
,
-
2091195.022904681
,
5544.242061981691
,},
new
double
[]{-
2091195.022904681
,
5542.570186981691
,
-
2091195.780717181
,
5541.609249481691
,},
new
double
[]{-
2091196.538529681
,
5540.648311981691
,
-
2091197.819779681
,
5540.648311981691
,},
null
,
new
double
[]{-
2091197.819779681
,
5539.695186981691
,},
new
double
[]{-
2091195.991654681
,
5539.695186981691
,
-
2091194.890092181
,
5540.929561981691
,},
new
double
[]{-
2091193.788529681
,
5542.163936981691
,
-
2091193.788529681
,
5544.242061981691
,},
new
double
[]{-
2091193.788529681
,
5546.304561981691
,
-
2091194.890092181
,
5547.538936981691
,},
new
double
[]{-
2091195.991654681
,
5548.773311981691
,
-
2091197.819779681
,
5548.773311981691
,},
new
double
[]{-
2091199.663529681
,
5548.773311981691
,
-
2091200.772904681
,
5547.538936981691
,},
new
double
[]{-
2091201.882279681
,
5546.304561981691
,
-
2091201.882279681
,
5544.242061981691
,},
new
double
[]{-
2091201.882279681
,
5542.163936981691
,
-
2091200.772904681
,
5540.929561981691
,},
new
double
[]{-
2091199.663529681
,
5539.695186981691
,
-
2091197.819779681
,
5539.695186981691
,},
null
,
new
double
[]{-
2091197.210404681
,
5537.835811981691
,},
new
double
[]{-
2091196.022904681
,
5537.835811981691
,},
new
double
[]{-
2091196.022904681
,
5539.023311981691
,},
new
double
[]{-
2091197.210404681
,
5539.023311981691
,},
new
double
[]{-
2091197.210404681
,
5537.835811981691
,},
null
,
new
double
[]{-
2091199.632279681
,
5537.835811981691
,},
new
double
[]{-
2091198.444779681
,
5537.835811981691
,},
new
double
[]{-
2091198.444779681
,
5539.023311981691
,},
new
double
[]{-
2091199.632279681
,
5539.023311981691
,},
new
double
[]{-
2091199.632279681
,
5537.835811981691
,},
null
,
};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录