Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
53b4c8ee
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看板
提交
53b4c8ee
编写于
10月 02, 2013
作者:
P
prr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7179526: xrender : closed/sun/java2d/volatileImage/LineClipTest.java failed since jdk8b36
Reviewed-by: prr, jchen
上级
6ca73ed3
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
988 addition
and
142 deletion
+988
-142
src/solaris/classes/sun/java2d/xr/GrowableRectArray.java
src/solaris/classes/sun/java2d/xr/GrowableRectArray.java
+14
-0
src/solaris/classes/sun/java2d/xr/MaskTile.java
src/solaris/classes/sun/java2d/xr/MaskTile.java
+0
-92
src/solaris/classes/sun/java2d/xr/MaskTileManager.java
src/solaris/classes/sun/java2d/xr/MaskTileManager.java
+7
-32
src/solaris/classes/sun/java2d/xr/XRDrawLine.java
src/solaris/classes/sun/java2d/xr/XRDrawLine.java
+425
-0
src/solaris/classes/sun/java2d/xr/XRRenderer.java
src/solaris/classes/sun/java2d/xr/XRRenderer.java
+38
-18
test/java/awt/Graphics/LineClipTest.java
test/java/awt/Graphics/LineClipTest.java
+504
-0
未找到文件。
src/solaris/classes/sun/java2d/xr/GrowableRectArray.java
浏览文件 @
53b4c8ee
...
@@ -38,6 +38,20 @@ public class GrowableRectArray extends GrowableIntArray {
...
@@ -38,6 +38,20 @@ public class GrowableRectArray extends GrowableIntArray {
super
(
RECT_SIZE
,
initialSize
);
super
(
RECT_SIZE
,
initialSize
);
}
}
public
final
void
pushRectValues
(
int
x
,
int
y
,
int
width
,
int
height
)
{
int
currSize
=
size
;
size
+=
RECT_SIZE
;
if
(
size
>=
array
.
length
)
{
growArray
();
}
array
[
currSize
]
=
x
;
array
[
currSize
+
1
]
=
y
;
array
[
currSize
+
2
]
=
width
;
array
[
currSize
+
3
]
=
height
;
}
public
final
void
setX
(
int
index
,
int
x
)
{
public
final
void
setX
(
int
index
,
int
x
)
{
array
[
getCellIndex
(
index
)]
=
x
;
array
[
getCellIndex
(
index
)]
=
x
;
}
}
...
...
src/solaris/classes/sun/java2d/xr/MaskTile.java
浏览文件 @
53b4c8ee
...
@@ -41,98 +41,6 @@ public class MaskTile {
...
@@ -41,98 +41,6 @@ public class MaskTile {
dirtyArea
=
new
DirtyRegion
();
dirtyArea
=
new
DirtyRegion
();
}
}
public
void
addRect
(
int
x
,
int
y
,
int
width
,
int
height
)
{
int
index
=
rects
.
getNextIndex
();
rects
.
setX
(
index
,
x
);
rects
.
setY
(
index
,
y
);
rects
.
setWidth
(
index
,
width
);
rects
.
setHeight
(
index
,
height
);
}
public
void
addLine
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
/*
* EXA is not able to accalerate diagonal lines, we try to "guide" it a
* bit to avoid excessive migration See project documentation for an
* detailed explanation
*/
DirtyRegion
region
=
new
DirtyRegion
();
region
.
setDirtyLineRegion
(
x1
,
y1
,
x2
,
y2
);
int
xDiff
=
region
.
x2
-
region
.
x
;
int
yDiff
=
region
.
y2
-
region
.
y
;
if
(
xDiff
==
0
||
yDiff
==
0
)
{
addRect
(
region
.
x
,
region
.
y
,
region
.
x2
-
region
.
x
+
1
,
region
.
y2
-
region
.
y
+
1
);
}
else
if
(
xDiff
==
1
&&
yDiff
==
1
)
{
addRect
(
x1
,
y1
,
1
,
1
);
addRect
(
x2
,
y2
,
1
,
1
);
}
else
{
lineToRects
(
x1
,
y1
,
x2
,
y2
);
}
}
private
void
lineToRects
(
int
xstart
,
int
ystart
,
int
xend
,
int
yend
)
{
int
x
,
y
,
t
,
dx
,
dy
,
incx
,
incy
,
pdx
,
pdy
,
ddx
,
ddy
,
es
,
el
,
err
;
/* Entfernung in beiden Dimensionen berechnen */
dx
=
xend
-
xstart
;
dy
=
yend
-
ystart
;
/* Vorzeichen des Inkrements bestimmen */
incx
=
dx
>
0
?
1
:
(
dx
<
0
)
?
-
1
:
0
;
incy
=
dy
>
0
?
1
:
(
dy
<
0
)
?
-
1
:
0
;
if
(
dx
<
0
)
dx
=
-
dx
;
if
(
dy
<
0
)
dy
=
-
dy
;
/* feststellen, welche Entfernung groesser ist */
if
(
dx
>
dy
)
{
/* x ist schnelle Richtung */
pdx
=
incx
;
pdy
=
0
;
/* pd. ist Parallelschritt */
ddx
=
incx
;
ddy
=
incy
;
/* dd. ist Diagonalschritt */
es
=
dy
;
el
=
dx
;
/* Fehlerschritte schnell, langsam */
}
else
{
/* y ist schnelle Richtung */
pdx
=
0
;
pdy
=
incy
;
/* pd. ist Parallelschritt */
ddx
=
incx
;
ddy
=
incy
;
/* dd. ist Diagonalschritt */
es
=
dx
;
el
=
dy
;
/* Fehlerschritte schnell, langsam */
}
/* Initialisierungen vor Schleifenbeginn */
x
=
xstart
;
y
=
ystart
;
err
=
el
/
2
;
addRect
(
x
,
y
,
1
,
1
);
/* Pixel berechnen */
for
(
t
=
0
;
t
<
el
;
++
t
)
/* t zaehlt die Pixel, el ist auch Anzahl */
{
/* Aktualisierung Fehlerterm */
err
-=
es
;
if
(
err
<
0
)
{
/* Fehlerterm wieder positiv (>=0) machen */
err
+=
el
;
/* Schritt in langsame Richtung, Diagonalschritt */
x
+=
ddx
;
y
+=
ddy
;
}
else
{
/* Schritt in schnelle Richtung, Parallelschritt */
x
+=
pdx
;
y
+=
pdy
;
}
addRect
(
x
,
y
,
1
,
1
);
// SetPixel(x,y);
// System.out.println(x+":"+y);
}
}
public
void
calculateDirtyAreas
()
public
void
calculateDirtyAreas
()
{
{
for
(
int
i
=
0
;
i
<
rects
.
getSize
();
i
++)
{
for
(
int
i
=
0
;
i
<
rects
.
getSize
();
i
++)
{
...
...
src/solaris/classes/sun/java2d/xr/MaskTileManager.java
浏览文件 @
53b4c8ee
...
@@ -54,10 +54,6 @@ public class MaskTileManager {
...
@@ -54,10 +54,6 @@ public class MaskTileManager {
int
maskPixmap
;
int
maskPixmap
;
int
maskPicture
;
int
maskPicture
;
long
maskGC
;
long
maskGC
;
int
lineMaskPixmap
;
int
lineMaskPicture
;
long
drawLineGC
;
long
clearLineGC
;
public
MaskTileManager
(
XRCompositeManager
xrMgr
,
int
parentXid
)
{
public
MaskTileManager
(
XRCompositeManager
xrMgr
,
int
parentXid
)
{
tileList
=
new
ArrayList
<
MaskTile
>();
tileList
=
new
ArrayList
<
MaskTile
>();
...
@@ -71,34 +67,6 @@ public class MaskTileManager {
...
@@ -71,34 +67,6 @@ public class MaskTileManager {
0
,
0
,
MASK_SIZE
,
MASK_SIZE
);
0
,
0
,
MASK_SIZE
,
MASK_SIZE
);
maskGC
=
con
.
createGC
(
maskPixmap
);
maskGC
=
con
.
createGC
(
maskPixmap
);
con
.
setGCExposures
(
maskGC
,
false
);
con
.
setGCExposures
(
maskGC
,
false
);
lineMaskPixmap
=
con
.
createPixmap
(
parentXid
,
8
,
MASK_SIZE
,
MASK_SIZE
);
lineMaskPicture
=
con
.
createPicture
(
lineMaskPixmap
,
XRUtils
.
PictStandardA8
);
con
.
renderRectangle
(
lineMaskPicture
,
XRUtils
.
PictOpClear
,
new
XRColor
(
Color
.
black
),
0
,
0
,
MASK_SIZE
,
MASK_SIZE
);
drawLineGC
=
con
.
createGC
(
lineMaskPixmap
);
con
.
setGCExposures
(
drawLineGC
,
false
);
con
.
setGCForeground
(
drawLineGC
,
255
);
clearLineGC
=
con
.
createGC
(
lineMaskPixmap
);
con
.
setGCExposures
(
clearLineGC
,
false
);
con
.
setGCForeground
(
clearLineGC
,
0
);
}
/**
* Adds a rectangle to the mask.
*/
public
void
addRect
(
int
x
,
int
y
,
int
width
,
int
height
)
{
mainTile
.
addRect
(
x
,
y
,
width
,
height
);
}
/**
* Adds a line to the mask.
*/
public
void
addLine
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
mainTile
.
addLine
(
x1
,
y1
,
x2
,
y2
);
}
}
/**
/**
...
@@ -324,4 +292,11 @@ public class MaskTileManager {
...
@@ -324,4 +292,11 @@ public class MaskTileManager {
rects
.
setY
(
index
,
0
);
rects
.
setY
(
index
,
0
);
}
}
}
}
/**
* @return MainTile to which rectangles are added before composition.
*/
public
MaskTile
getMainTile
()
{
return
mainTile
;
}
}
}
src/solaris/classes/sun/java2d/xr/XRDrawLine.java
0 → 100644
浏览文件 @
53b4c8ee
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
/**
* Bresenham line-drawing implementation decomposing line segments
* into a series of rectangles.
* This is required, because xrender doesn't support line primitives directly.
* The code here is an almost 1:1 port of the existing C-source contained in
* sun/java2d/loop/DrawLine.c and sun/java2d/loop/LoopMacros.h
*/
package
sun.java2d.xr
;
public
class
XRDrawLine
{
static
final
int
BIG_MAX
=
((
1
<<
29
)
-
1
);
static
final
int
BIG_MIN
=
(-(
1
<<
29
));
static
final
int
OUTCODE_TOP
=
1
;
static
final
int
OUTCODE_BOTTOM
=
2
;
static
final
int
OUTCODE_LEFT
=
4
;
static
final
int
OUTCODE_RIGHT
=
8
;
int
x1
,
y1
,
x2
,
y2
;
int
ucX1
,
ucY1
,
ucX2
,
ucY2
;
DirtyRegion
region
=
new
DirtyRegion
();
protected
void
rasterizeLine
(
GrowableRectArray
rectBuffer
,
int
_x1
,
int
_y1
,
int
_x2
,
int
_y2
,
int
cxmin
,
int
cymin
,
int
cxmax
,
int
cymax
,
boolean
clip
,
boolean
overflowCheck
)
{
float
diagF
;
int
error
;
int
steps
;
int
errminor
,
errmajor
;
boolean
xmajor
;
int
dx
,
dy
,
ax
,
ay
;
initCoordinates
(
_x1
,
_y1
,
_x2
,
_y2
,
overflowCheck
);
dx
=
x2
-
x1
;
dy
=
y2
-
y1
;
ax
=
Math
.
abs
(
dx
);
ay
=
Math
.
abs
(
dy
);
xmajor
=
(
ax
>=
ay
);
diagF
=
((
float
)
ax
)
/
ay
;
if
(
clip
&&
!
clipCoordinates
(
cxmin
,
cymin
,
cxmax
,
cymax
,
xmajor
,
dx
,
dy
,
ax
,
ay
))
{
// whole line was clipped away
return
;
}
region
.
setDirtyLineRegion
(
x1
,
y1
,
x2
,
y2
);
int
xDiff
=
region
.
x2
-
region
.
x
;
int
yDiff
=
region
.
y2
-
region
.
y
;
if
(
xDiff
==
0
||
yDiff
==
0
)
{
// horizontal / diagonal lines can be represented by a single
// rectangle
rectBuffer
.
pushRectValues
(
region
.
x
,
region
.
y
,
region
.
x2
-
region
.
x
+
1
,
region
.
y2
-
region
.
y
+
1
);
return
;
}
// Setup bresenham
if
(
xmajor
)
{
errmajor
=
ay
*
2
;
errminor
=
ax
*
2
;
ax
=
-
ax
;
/* For clipping adjustment below */
steps
=
x2
-
x1
;
}
else
{
errmajor
=
ax
*
2
;
errminor
=
ay
*
2
;
ay
=
-
ay
;
/* For clipping adjustment below */
steps
=
y2
-
y1
;
}
if
((
steps
=
(
Math
.
abs
(
steps
)
+
1
))
==
0
)
{
return
;
}
error
=
-(
errminor
/
2
);
if
(
y1
!=
ucY1
)
{
int
ysteps
=
y1
-
ucY1
;
if
(
ysteps
<
0
)
{
ysteps
=
-
ysteps
;
}
error
+=
ysteps
*
ax
*
2
;
}
if
(
x1
!=
ucX1
)
{
int
xsteps
=
x1
-
ucX1
;
if
(
xsteps
<
0
)
{
xsteps
=
-
xsteps
;
}
error
+=
xsteps
*
ay
*
2
;
}
error
+=
errmajor
;
errminor
-=
errmajor
;
int
xStep
=
(
dx
>
0
?
1
:
-
1
);
int
yStep
=
(
dy
>
0
?
1
:
-
1
);
int
orthogonalXStep
=
xmajor
?
xStep
:
0
;
int
orthogonalYStep
=
!
xmajor
?
yStep
:
0
;
/*
* For lines which proceed in one direction faster, we try to generate
* rectangles instead of points. Otherwise we try to avoid the extra
* work...
*/
if
(
diagF
<=
0.9
||
diagF
>=
1.1
)
{
lineToRects
(
rectBuffer
,
steps
,
error
,
errmajor
,
errminor
,
xStep
,
yStep
,
orthogonalXStep
,
orthogonalYStep
);
}
else
{
lineToPoints
(
rectBuffer
,
steps
,
error
,
errmajor
,
errminor
,
xStep
,
yStep
,
orthogonalXStep
,
orthogonalYStep
);
}
}
private
void
lineToPoints
(
GrowableRectArray
rectBuffer
,
int
steps
,
int
error
,
int
errmajor
,
int
errminor
,
int
xStep
,
int
yStep
,
int
orthogonalXStep
,
int
orthogonalYStep
)
{
int
x
=
x1
,
y
=
y1
;
do
{
rectBuffer
.
pushRectValues
(
x
,
y
,
1
,
1
);
// "Traditional" Bresenham line drawing
if
(
error
<
0
)
{
error
+=
errmajor
;
x
+=
orthogonalXStep
;
y
+=
orthogonalYStep
;
}
else
{
error
-=
errminor
;
x
+=
xStep
;
y
+=
yStep
;
}
}
while
(--
steps
>
0
);
}
private
void
lineToRects
(
GrowableRectArray
rectBuffer
,
int
steps
,
int
error
,
int
errmajor
,
int
errminor
,
int
xStep
,
int
yStep
,
int
orthogonalXStep
,
int
orthogonalYStep
)
{
int
x
=
x1
,
y
=
y1
;
int
rectX
=
Integer
.
MIN_VALUE
,
rectY
=
0
;
int
rectW
=
0
,
rectH
=
0
;
do
{
// Combine the resulting rectangles
// for steps performed in a single direction.
if
(
y
==
rectY
)
{
if
(
x
==
(
rectX
+
rectW
))
{
rectW
++;
}
else
if
(
x
==
(
rectX
-
1
))
{
rectX
--;
rectW
++;
}
}
else
if
(
x
==
rectX
)
{
if
(
y
==
(
rectY
+
rectH
))
{
rectH
++;
}
else
if
(
y
==
(
rectY
-
1
))
{
rectY
--;
rectH
++;
}
}
else
{
// Diagonal step: add the previous rectangle to the list,
// iff it was "real" (= not initialized before the first
// iteration)
if
(
rectX
!=
Integer
.
MIN_VALUE
)
{
rectBuffer
.
pushRectValues
(
rectX
,
rectY
,
rectW
,
rectH
);
}
rectX
=
x
;
rectY
=
y
;
rectW
=
rectH
=
1
;
}
// "Traditional" Bresenham line drawing
if
(
error
<
0
)
{
error
+=
errmajor
;
x
+=
orthogonalXStep
;
y
+=
orthogonalYStep
;
}
else
{
error
-=
errminor
;
x
+=
xStep
;
y
+=
yStep
;
}
}
while
(--
steps
>
0
);
// Add last rectangle which isn't handled by the combination-code
// anymore
rectBuffer
.
pushRectValues
(
rectX
,
rectY
,
rectW
,
rectH
);
}
private
boolean
clipCoordinates
(
int
cxmin
,
int
cymin
,
int
cxmax
,
int
cymax
,
boolean
xmajor
,
int
dx
,
int
dy
,
int
ax
,
int
ay
)
{
int
outcode1
,
outcode2
;
outcode1
=
outcode
(
x1
,
y1
,
cxmin
,
cymin
,
cxmax
,
cymax
);
outcode2
=
outcode
(
x2
,
y2
,
cxmin
,
cymin
,
cxmax
,
cymax
);
while
((
outcode1
|
outcode2
)
!=
0
)
{
int
xsteps
=
0
,
ysteps
=
0
;
if
((
outcode1
&
outcode2
)
!=
0
)
{
return
false
;
}
if
(
outcode1
!=
0
)
{
if
((
outcode1
&
(
OUTCODE_TOP
|
OUTCODE_BOTTOM
))
!=
0
)
{
if
((
outcode1
&
OUTCODE_TOP
)
!=
0
)
{
y1
=
cymin
;
}
else
{
y1
=
cymax
;
}
ysteps
=
y1
-
ucY1
;
if
(
ysteps
<
0
)
{
ysteps
=
-
ysteps
;
}
xsteps
=
2
*
ysteps
*
ax
+
ay
;
if
(
xmajor
)
{
xsteps
+=
ay
-
ax
-
1
;
}
xsteps
=
xsteps
/
(
2
*
ay
);
if
(
dx
<
0
)
{
xsteps
=
-
xsteps
;
}
x1
=
ucX1
+
(
int
)
xsteps
;
}
else
if
((
outcode1
&
(
OUTCODE_LEFT
|
OUTCODE_RIGHT
))
!=
0
)
{
if
((
outcode1
&
OUTCODE_LEFT
)
!=
0
)
{
x1
=
cxmin
;
}
else
{
x1
=
cxmax
;
}
xsteps
=
x1
-
ucX1
;
if
(
xsteps
<
0
)
{
xsteps
=
-
xsteps
;
}
ysteps
=
2
*
xsteps
*
ay
+
ax
;
if
(!
xmajor
)
{
ysteps
+=
ax
-
ay
-
1
;
}
ysteps
=
ysteps
/
(
2
*
ax
);
if
(
dy
<
0
)
{
ysteps
=
-
ysteps
;
}
y1
=
ucY1
+
(
int
)
ysteps
;
}
outcode1
=
outcode
(
x1
,
y1
,
cxmin
,
cymin
,
cxmax
,
cymax
);
}
else
{
if
((
outcode2
&
(
OUTCODE_TOP
|
OUTCODE_BOTTOM
))
!=
0
)
{
if
((
outcode2
&
OUTCODE_TOP
)
!=
0
)
{
y2
=
cymin
;
}
else
{
y2
=
cymax
;
}
ysteps
=
y2
-
ucY2
;
if
(
ysteps
<
0
)
{
ysteps
=
-
ysteps
;
}
xsteps
=
2
*
ysteps
*
ax
+
ay
;
if
(
xmajor
)
{
xsteps
+=
ay
-
ax
;
}
else
{
xsteps
-=
1
;
}
xsteps
=
xsteps
/
(
2
*
ay
);
if
(
dx
>
0
)
{
xsteps
=
-
xsteps
;
}
x2
=
ucX2
+
(
int
)
xsteps
;
}
else
if
((
outcode2
&
(
OUTCODE_LEFT
|
OUTCODE_RIGHT
))
!=
0
)
{
if
((
outcode2
&
OUTCODE_LEFT
)
!=
0
)
{
x2
=
cxmin
;
}
else
{
x2
=
cxmax
;
}
xsteps
=
x2
-
ucX2
;
if
(
xsteps
<
0
)
{
xsteps
=
-
xsteps
;
}
ysteps
=
2
*
xsteps
*
ay
+
ax
;
if
(
xmajor
)
{
ysteps
-=
1
;
}
else
{
ysteps
+=
ax
-
ay
;
}
ysteps
=
ysteps
/
(
2
*
ax
);
if
(
dy
>
0
)
{
ysteps
=
-
ysteps
;
}
y2
=
ucY2
+
(
int
)
ysteps
;
}
outcode2
=
outcode
(
x2
,
y2
,
cxmin
,
cymin
,
cxmax
,
cymax
);
}
}
return
true
;
}
private
void
initCoordinates
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
boolean
checkOverflow
)
{
/*
* Part of calculating the Bresenham parameters for line stepping
* involves being able to store numbers that are twice the magnitude of
* the biggest absolute difference in coordinates. Since we want the
* stepping parameters to be stored in jints, we then need to avoid any
* absolute differences more than 30 bits. Thus, we need to preprocess
* the coordinates to reduce their range to 30 bits regardless of
* clipping. We need to cut their range back before we do the clipping
* because the Bresenham stepping values need to be calculated based on
* the "unclipped" coordinates.
*
* Thus, first we perform a "pre-clipping" stage to bring the
* coordinates within the 30-bit range and then we proceed to the
* regular clipping procedure, pretending that these were the original
* coordinates all along. Since this operation occurs based on a
* constant "pre-clip" rectangle of +/- 30 bits without any
* consideration for the final clip, the rounding errors that occur here
* will depend only on the line coordinates and be invariant with
* respect to the particular device/user clip rectangles in effect at
* the time. Thus, rendering a given large-range line will be consistent
* under a variety of clipping conditions.
*/
if
(
checkOverflow
&&
(
OverflowsBig
(
x1
)
||
OverflowsBig
(
y1
)
||
OverflowsBig
(
x2
)
||
OverflowsBig
(
y2
)))
{
/*
* Use doubles to get us into range for "Big" arithmetic.
*
* The math of adjusting an endpoint for clipping can involve an
* intermediate result with twice the number of bits as the original
* coordinate range. Since we want to maintain as much as 30 bits of
* precision in the resulting coordinates, we will get roundoff here
* even using IEEE double-precision arithmetic which cannot carry 60
* bits of mantissa. Since the rounding errors will be consistent
* for a given set of input coordinates the potential roundoff error
* should not affect the consistency of our rendering.
*/
double
x1d
=
x1
;
double
y1d
=
y1
;
double
x2d
=
x2
;
double
y2d
=
y2
;
double
dxd
=
x2d
-
x1d
;
double
dyd
=
y2d
-
y1d
;
if
(
x1
<
BIG_MIN
)
{
y1d
=
y1
+
(
BIG_MIN
-
x1
)
*
dyd
/
dxd
;
x1d
=
BIG_MIN
;
}
else
if
(
x1
>
BIG_MAX
)
{
y1d
=
y1
-
(
x1
-
BIG_MAX
)
*
dyd
/
dxd
;
x1d
=
BIG_MAX
;
}
/* Use Y1d instead of _y1 for testing now as we may have modified it */
if
(
y1d
<
BIG_MIN
)
{
x1d
=
x1
+
(
BIG_MIN
-
y1
)
*
dxd
/
dyd
;
y1d
=
BIG_MIN
;
}
else
if
(
y1d
>
BIG_MAX
)
{
x1d
=
x1
-
(
y1
-
BIG_MAX
)
*
dxd
/
dyd
;
y1d
=
BIG_MAX
;
}
if
(
x2
<
BIG_MIN
)
{
y2d
=
y2
+
(
BIG_MIN
-
x2
)
*
dyd
/
dxd
;
x2d
=
BIG_MIN
;
}
else
if
(
x2
>
BIG_MAX
)
{
y2d
=
y2
-
(
x2
-
BIG_MAX
)
*
dyd
/
dxd
;
x2d
=
BIG_MAX
;
}
/* Use Y2d instead of _y2 for testing now as we may have modified it */
if
(
y2d
<
BIG_MIN
)
{
x2d
=
x2
+
(
BIG_MIN
-
y2
)
*
dxd
/
dyd
;
y2d
=
BIG_MIN
;
}
else
if
(
y2d
>
BIG_MAX
)
{
x2d
=
x2
-
(
y2
-
BIG_MAX
)
*
dxd
/
dyd
;
y2d
=
BIG_MAX
;
}
x1
=
(
int
)
x1d
;
y1
=
(
int
)
y1d
;
x2
=
(
int
)
x2d
;
y2
=
(
int
)
y2d
;
}
this
.
x1
=
ucX1
=
x1
;
this
.
y1
=
ucY1
=
y1
;
this
.
x2
=
ucX2
=
x2
;
this
.
y2
=
ucY2
=
y2
;
}
private
boolean
OverflowsBig
(
int
v
)
{
return
((
v
)
!=
(((
v
)
<<
2
)
>>
2
));
}
private
int
out
(
int
v
,
int
vmin
,
int
vmax
,
int
cmin
,
int
cmax
)
{
return
((
v
<
vmin
)
?
cmin
:
((
v
>
vmax
)
?
cmax
:
0
));
}
private
int
outcode
(
int
x
,
int
y
,
int
xmin
,
int
ymin
,
int
xmax
,
int
ymax
)
{
return
out
(
y
,
ymin
,
ymax
,
OUTCODE_TOP
,
OUTCODE_BOTTOM
)
|
out
(
x
,
xmin
,
xmax
,
OUTCODE_LEFT
,
OUTCODE_RIGHT
);
}
}
src/solaris/classes/sun/java2d/xr/XRRenderer.java
浏览文件 @
53b4c8ee
...
@@ -53,10 +53,15 @@ import static sun.java2d.xr.XRUtils.clampToUShort;
...
@@ -53,10 +53,15 @@ import static sun.java2d.xr.XRUtils.clampToUShort;
public
class
XRRenderer
implements
PixelDrawPipe
,
PixelFillPipe
,
ShapeDrawPipe
{
public
class
XRRenderer
implements
PixelDrawPipe
,
PixelFillPipe
,
ShapeDrawPipe
{
XRDrawHandler
drawHandler
;
XRDrawHandler
drawHandler
;
MaskTileManager
tileManager
;
MaskTileManager
tileManager
;
XRDrawLine
lineGen
;
GrowableRectArray
rectBuffer
;
public
XRRenderer
(
MaskTileManager
tileManager
)
{
public
XRRenderer
(
MaskTileManager
tileManager
)
{
this
.
tileManager
=
tileManager
;
this
.
tileManager
=
tileManager
;
this
.
rectBuffer
=
tileManager
.
getMainTile
().
getRects
();
this
.
drawHandler
=
new
XRDrawHandler
();
this
.
drawHandler
=
new
XRDrawHandler
();
this
.
lineGen
=
new
XRDrawLine
();
}
}
/**
/**
...
@@ -77,19 +82,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
...
@@ -77,19 +82,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
int
transX2
=
Region
.
clipAdd
(
x2
,
sg2d
.
transX
);
int
transX2
=
Region
.
clipAdd
(
x2
,
sg2d
.
transX
);
int
transY2
=
Region
.
clipAdd
(
y2
,
sg2d
.
transY
);
int
transY2
=
Region
.
clipAdd
(
y2
,
sg2d
.
transY
);
// Non clipped fast path
SunToolkit
.
awtLock
();
if
(
compClip
.
contains
(
transX1
,
transY1
)
try
{
&&
compClip
.
contains
(
transX2
,
transY2
))
{
validateSurface
(
sg2d
);
SunToolkit
.
awtLock
();
lineGen
.
rasterizeLine
(
rectBuffer
,
transX1
,
transY1
,
try
{
transX2
,
transY2
,
compClip
.
getLoX
(),
compClip
.
getLoY
(),
validateSurface
(
sg2d
);
compClip
.
getHiX
(),
compClip
.
getHiY
(),
true
,
true
);
tileManager
.
addLine
(
transX1
,
transY1
,
transX2
,
transY2
);
tileManager
.
fillMask
((
XRSurfaceData
)
sg2d
.
surfaceData
);
tileManager
.
fillMask
((
XRSurfaceData
)
sg2d
.
surfaceData
);
}
finally
{
}
finally
{
SunToolkit
.
awtUnlock
();
SunToolkit
.
awtUnlock
();
}
}
else
{
draw
(
sg2d
,
new
Line2D
.
Float
(
x1
,
y1
,
x2
,
y2
));
}
}
}
}
...
@@ -148,7 +149,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
...
@@ -148,7 +149,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
SunToolkit
.
awtLock
();
SunToolkit
.
awtLock
();
try
{
try
{
validateSurface
(
sg2d
);
validateSurface
(
sg2d
);
tileManager
.
addRect
(
x
,
y
,
width
,
height
);
rectBuffer
.
pushRectValues
(
x
,
y
,
width
,
height
);
tileManager
.
fillMask
((
XRSurfaceData
)
sg2d
.
surfaceData
);
tileManager
.
fillMask
((
XRSurfaceData
)
sg2d
.
surfaceData
);
}
finally
{
}
finally
{
SunToolkit
.
awtUnlock
();
SunToolkit
.
awtUnlock
();
...
@@ -199,11 +200,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
...
@@ -199,11 +200,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
}
}
private
class
XRDrawHandler
extends
ProcessPath
.
DrawHandler
{
private
class
XRDrawHandler
extends
ProcessPath
.
DrawHandler
{
DirtyRegion
region
;
XRDrawHandler
()
{
XRDrawHandler
()
{
// these are bogus values; the caller will use validate()
// these are bogus values; the caller will use validate()
// to ensure that they are set properly prior to each usage
// to ensure that they are set properly prior to each usage
super
(
0
,
0
,
0
,
0
);
super
(
0
,
0
,
0
,
0
);
this
.
region
=
new
DirtyRegion
();
}
}
/**
/**
...
@@ -218,15 +221,32 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
...
@@ -218,15 +221,32 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
}
}
public
void
drawLine
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
public
void
drawLine
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
tileManager
.
addLine
(
x1
,
y1
,
x2
,
y2
);
region
.
setDirtyLineRegion
(
x1
,
y1
,
x2
,
y2
);
int
xDiff
=
region
.
x2
-
region
.
x
;
int
yDiff
=
region
.
y2
-
region
.
y
;
if
(
xDiff
==
0
||
yDiff
==
0
)
{
// horizontal / diagonal lines can be represented by a single
// rectangle
rectBuffer
.
pushRectValues
(
region
.
x
,
region
.
y
,
region
.
x2
-
region
.
x
+
1
,
region
.
y2
-
region
.
y
+
1
);
}
else
if
(
xDiff
==
1
&&
yDiff
==
1
)
{
// fast path for pattern commonly generated by
// ProcessPath.DrawHandler
rectBuffer
.
pushRectValues
(
x1
,
y1
,
1
,
1
);
rectBuffer
.
pushRectValues
(
x2
,
y2
,
1
,
1
);
}
else
{
lineGen
.
rasterizeLine
(
rectBuffer
,
x1
,
y1
,
x2
,
y2
,
0
,
0
,
0
,
0
,
false
,
false
);
}
}
}
public
void
drawPixel
(
int
x
,
int
y
)
{
public
void
drawPixel
(
int
x
,
int
y
)
{
tileManager
.
addRect
(
x
,
y
,
1
,
1
);
rectBuffer
.
pushRectValues
(
x
,
y
,
1
,
1
);
}
}
public
void
drawScanline
(
int
x1
,
int
x2
,
int
y
)
{
public
void
drawScanline
(
int
x1
,
int
x2
,
int
y
)
{
tileManager
.
addRect
(
x1
,
y
,
x2
-
x1
+
1
,
1
);
rectBuffer
.
pushRectValues
(
x1
,
y
,
x2
-
x1
+
1
,
1
);
}
}
}
}
...
@@ -263,7 +283,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
...
@@ -263,7 +283,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
validateSurface
(
sg2d
);
validateSurface
(
sg2d
);
int
[]
spanBox
=
new
int
[
4
];
int
[]
spanBox
=
new
int
[
4
];
while
(
si
.
nextSpan
(
spanBox
))
{
while
(
si
.
nextSpan
(
spanBox
))
{
tileManager
.
addRect
(
spanBox
[
0
]
+
transx
,
rectBuffer
.
pushRectValues
(
spanBox
[
0
]
+
transx
,
spanBox
[
1
]
+
transy
,
spanBox
[
1
]
+
transy
,
spanBox
[
2
]
-
spanBox
[
0
],
spanBox
[
2
]
-
spanBox
[
0
],
spanBox
[
3
]
-
spanBox
[
1
]);
spanBox
[
3
]
-
spanBox
[
1
]);
...
...
test/java/awt/Graphics/LineClipTest.java
0 → 100644
浏览文件 @
53b4c8ee
/*
* Copyright (c) 2002, 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 4780022 4862193 7179526
* @summary Tests that clipped lines are drawn over the same pixels
* as unclipped lines (within the clip bounds)
* @run main/timeout=600/othervm -Dsun.java2d.ddforcevram=true LineClipTest
* @run main/timeout=600/othervm LineClipTest
*/
/**
* This app tests whether we are drawing clipped lines the same
* as unclipped lines. The problem occurred when we started
* clipping d3d lines using simple integer clipping, which did not
* account for sub-pixel precision and ended up drawing very different
* pixels than the same line drawn unclipped. A supposed fix
* to that problem used floating-point clipping instead, but there
* was some problem with very limited precision inside of d3d
* (presumably in hardware) that caused some variation in pixels.
* We decided that whatever the fix was, we needed a serious
* line check test to make sure that all kinds of different
* lines would be drawn exactly the same inside the clip area,
* regardless of whether clipping was enabled. This test should
* check all kinds of different cases, such as lines that fall
* completely outside, completely inside, start outside and
* end inside, etc., and lines should end and originate in
* all quadrants of the space divided up by the clip box.
*
* The test works as follows:
* We create nine quadrants using the spaces bisected by the
* edges of the clip bounds (note that only one of these
* quadrants is actually visible when clipping is enabled).
* We create several points in each of these quadrants
* (three in each of the invisible quadrants, nine in the
* center/visible quadrant). Our resulting grid looks like
* this:
*
* x x|x x x|x x
* | |
* | |
* | |
* | |
* | |
* x | | x
* -----------------------------------
* x |x x x| x
* | |
* | |
* x |x x x| x
* | |
* | |
* x |x x x| x
* -----------------------------------
* x | | x
* | |
* | |
* | |
* | |
* | |
* x x|x x x|x x
*
* The test then draws lines from every point to every other
* point. First, we draw unclipped lines in blue and
* then we draw clipped lines in red.
* At certain times (after every point during the default
* test, after every quadrant of lines if you run with the -quick
* option), we check for errors and draw the current image
* to the screen. Error checking consists of copying the
* VolatileImage to a BufferedImage (because we need access
* to the pixels directly) and checking every pixel in the
* image. The check is simple: everything outside the
* clip bounds should be blue (or the background color) and
* everything inside the clip bounds should be red (or the
* background color). So any blue pixel inside or red
* pixel outside means that there was a drawing error and
* the test fails.
* There are 4 modes that the test can run in (dynamic mode is
* exclusive to the other modes, but the other modes are combinable):
*
* (default): the clip is set
* to a default size (100x100) and the test is run.
*
* -quick: The error
* check is run only after every quadrant of lines is
* drawn. This speeds up the test considerably with
* some less accuracy in error checking (because pixels
* from some lines may overdrawn pixels from other lines
* before we have verified the correctness of those
* pixels).
*
* -dynamic: There is no error checking, but this version
* of the test automatically resizes the clip bounds and
* reruns the test over and over. Nothing besides the
* visual check verifies that the test is running correctly.
*
* -rect: Instead of drawing lines, the test draws rectangles
* to/from all points in all quadrants. This tests similar
* clipping functionality for drawRect().
*
* n (where "n" is a number): sets the clip size to the
* given value. Just like the default test except that
* the clip size is as specified.
*
* Note: this test must be run with the -Dsun.java2d.ddforcevram=true
* option to force the test image to stay in VRAM. We currently
* punt VRAM images to system memory when we detect lots of
* reads. Since we read the whole buffer on every error check
* to copy it to the BufferedImage), this causes us to punt the
* buffer. A system memory surface will have no d3d capabilities,
* thus we are not testing the d3d line quality when this happens.
* By using the ddforcevram flag, we make sure the buffer
* stays put in VRAM and d3d is used to draw the lines.
*/
import
javax.swing.*
;
import
java.awt.*
;
import
java.awt.image.*
;
public
class
LineClipTest
extends
Component
implements
Runnable
{
int
clipBumpVal
=
5
;
static
int
clipSize
=
100
;
int
clipX1
;
int
clipY1
;
static
final
int
NUM_QUADS
=
9
;
Point
quadrants
[][]
=
new
Point
[
NUM_QUADS
][];
static
boolean
dynamic
=
false
;
BufferedImage
imageChecker
=
null
;
Color
unclippedColor
=
Color
.
blue
;
Color
clippedColor
=
Color
.
red
;
int
testW
=
-
1
,
testH
=
-
1
;
VolatileImage
testImage
=
null
;
static
boolean
keepRunning
=
false
;
static
boolean
quickTest
=
false
;
static
boolean
rectTest
=
false
;
static
boolean
runTestDone
=
false
;
static
Frame
f
=
null
;
/**
* Check for errors in the grid. This error check consists of
* copying the buffer into a BufferedImage and reading all pixels
* in that image. No pixel outside the clip bounds should be
* of the color clippedColor and no pixel inside should be
* of the color unclippedColor. Any wrong color returns an error.
*/
boolean
gridError
(
Graphics
g
)
{
boolean
error
=
false
;
if
(
imageChecker
==
null
||
(
imageChecker
.
getWidth
()
!=
testW
)
||
(
imageChecker
.
getHeight
()
!=
testH
))
{
// Recreate BufferedImage as necessary
GraphicsConfiguration
gc
=
getGraphicsConfiguration
();
ColorModel
cm
=
gc
.
getColorModel
();
WritableRaster
wr
=
cm
.
createCompatibleWritableRaster
(
getWidth
(),
getHeight
());
imageChecker
=
new
BufferedImage
(
cm
,
wr
,
cm
.
isAlphaPremultiplied
(),
null
);
}
// Copy buffer to BufferedImage
Graphics
gChecker
=
imageChecker
.
getGraphics
();
gChecker
.
drawImage
(
testImage
,
0
,
0
,
this
);
// Set up pixel colors to check against
int
clippedPixelColor
=
clippedColor
.
getRGB
();
int
unclippedPixelColor
=
unclippedColor
.
getRGB
();
int
wrongPixelColor
=
clippedPixelColor
;
boolean
insideClip
=
false
;
for
(
int
row
=
0
;
row
<
getHeight
();
++
row
)
{
for
(
int
col
=
0
;
col
<
getWidth
();
++
col
)
{
if
(
row
>=
clipY1
&&
row
<
(
clipY1
+
clipSize
)
&&
col
>=
clipX1
&&
col
<
(
clipX1
+
clipSize
))
{
// Inside clip bounds - should not see unclipped color
wrongPixelColor
=
unclippedPixelColor
;
}
else
{
// Outside clip - should not see clipped color
wrongPixelColor
=
clippedPixelColor
;
}
int
pixel
=
imageChecker
.
getRGB
(
col
,
row
);
if
(
pixel
==
wrongPixelColor
)
{
System
.
out
.
println
(
"FAILED: pixel = "
+
Integer
.
toHexString
(
pixel
)
+
" at (x, y) = "
+
col
+
", "
+
row
);
// Draw magenta rectangle around problem pixel in buffer
// for visual feedback to user
g
.
setColor
(
Color
.
magenta
);
g
.
drawRect
(
col
-
1
,
row
-
1
,
2
,
2
);
error
=
true
;
}
}
}
return
error
;
}
/**
* Draw all test lines and check for errors (unless running
* with -dynamic option)
*/
void
drawLineGrid
(
Graphics
screenGraphics
,
Graphics
g
)
{
// Fill buffer with background color
g
.
setColor
(
Color
.
white
);
g
.
fillRect
(
0
,
0
,
getWidth
(),
getHeight
());
// Now, iterate through all quadrants
for
(
int
srcQuad
=
0
;
srcQuad
<
NUM_QUADS
;
++
srcQuad
)
{
// Draw lines to all other quadrants
for
(
int
dstQuad
=
0
;
dstQuad
<
NUM_QUADS
;
++
dstQuad
)
{
for
(
int
srcPoint
=
0
;
srcPoint
<
quadrants
[
srcQuad
].
length
;
++
srcPoint
)
{
// For every point in the source quadrant
int
sx
=
quadrants
[
srcQuad
][
srcPoint
].
x
;
int
sy
=
quadrants
[
srcQuad
][
srcPoint
].
y
;
for
(
int
dstPoint
=
0
;
dstPoint
<
quadrants
[
dstQuad
].
length
;
++
dstPoint
)
{
int
dx
=
quadrants
[
dstQuad
][
dstPoint
].
x
;
int
dy
=
quadrants
[
dstQuad
][
dstPoint
].
y
;
if
(!
rectTest
)
{
// Draw unclipped/clipped lines to every
// point in the dst quadrant
g
.
setColor
(
unclippedColor
);
g
.
drawLine
(
sx
,
sy
,
dx
,
dy
);
g
.
setClip
(
clipX1
,
clipY1
,
clipSize
,
clipSize
);
g
.
setColor
(
clippedColor
);
g
.
drawLine
(
sx
,
sy
,
dx
,
dy
);
}
else
{
// Draw unclipped/clipped rectangles to every
// point in the dst quadrant
g
.
setColor
(
unclippedColor
);
int
w
=
dx
-
sx
;
int
h
=
dy
-
sy
;
g
.
drawRect
(
sx
,
sy
,
w
,
h
);
g
.
setClip
(
clipX1
,
clipY1
,
clipSize
,
clipSize
);
g
.
setColor
(
clippedColor
);
g
.
drawRect
(
sx
,
sy
,
w
,
h
);
}
g
.
setClip
(
null
);
}
if
(!
dynamic
)
{
// Draw screen update for visual feedback
screenGraphics
.
drawImage
(
testImage
,
0
,
0
,
this
);
// On default test, check for errors after every
// src point
if
(!
quickTest
&&
gridError
(
g
))
{
throw
new
java
.
lang
.
RuntimeException
(
"Failed"
);
}
}
}
}
if
(!
dynamic
&&
quickTest
&&
gridError
(
g
))
{
// On quick test, check for errors only after every
// src quadrant
throw
new
java
.
lang
.
RuntimeException
(
"Failed"
);
//return;
}
}
if
(!
dynamic
)
{
System
.
out
.
println
(
"PASSED"
);
if
(!
keepRunning
)
{
f
.
dispose
();
}
}
}
/**
* If we have not yet run the test, or if the window size has
* changed, or if we are running the test in -dynamic mode,
* run the test. Then draw the test buffer to the screen
*/
public
void
paint
(
Graphics
g
)
{
if
(
dynamic
||
testImage
==
null
||
getWidth
()
!=
testW
||
getHeight
()
!=
testH
)
{
runTest
(
g
);
}
if
(
testImage
!=
null
)
{
g
.
drawImage
(
testImage
,
0
,
0
,
this
);
}
}
/*
* Create the quadrant of points and run the test to draw all the lines
*/
public
void
runTest
(
Graphics
screenGraphics
)
{
if
(
getWidth
()
==
0
||
getHeight
()
==
0
)
{
// May get here before window is really ready
return
;
}
clipX1
=
(
getWidth
()
-
clipSize
)
/
2
;
clipY1
=
(
getHeight
()
-
clipSize
)
/
2
;
int
clipX2
=
clipX1
+
clipSize
;
int
clipY2
=
clipY1
+
clipSize
;
int
centerX
=
getWidth
()/
2
;
int
centerY
=
getHeight
()/
2
;
int
leftX
=
0
;
int
topY
=
0
;
int
rightX
=
getWidth
()
-
1
;
int
bottomY
=
getHeight
()
-
1
;
int
quadIndex
=
0
;
// Offsets are used to force diagonal (versus hor/vert) lines
int
xOffset
=
0
;
int
yOffset
=
0
;
if
(
quadrants
[
0
]
==
null
)
{
for
(
int
i
=
0
;
i
<
9
;
++
i
)
{
int
numPoints
=
(
i
==
4
)
?
9
:
3
;
quadrants
[
i
]
=
new
Point
[
numPoints
];
}
}
// Upper-left
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
leftX
+
xOffset
,
clipY1
-
1
-
yOffset
),
new
Point
(
leftX
+
xOffset
,
topY
+
yOffset
),
new
Point
(
clipX1
-
1
-
xOffset
,
topY
+
yOffset
),
};
quadIndex
++;
yOffset
++;
// Upper-middle
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
clipX1
+
1
+
xOffset
,
topY
+
yOffset
),
new
Point
(
centerX
+
xOffset
,
topY
+
yOffset
),
new
Point
(
clipX2
-
1
-
xOffset
,
topY
+
yOffset
),
};
quadIndex
++;
++
yOffset
;
// Upper-right
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
clipX2
+
1
+
xOffset
,
topY
+
yOffset
),
new
Point
(
rightX
-
xOffset
,
topY
+
yOffset
),
new
Point
(
rightX
-
xOffset
,
clipY1
-
1
-
yOffset
),
};
quadIndex
++;
yOffset
=
0
;
++
xOffset
;
// Middle-left
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
leftX
+
xOffset
,
clipY1
+
1
+
yOffset
),
new
Point
(
leftX
+
xOffset
,
centerY
+
yOffset
),
new
Point
(
leftX
+
xOffset
,
clipY2
-
1
-
yOffset
),
};
quadIndex
++;
++
yOffset
;
// Middle-middle
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
clipX1
+
1
+
xOffset
,
clipY1
+
1
+
yOffset
),
new
Point
(
centerX
+
xOffset
,
clipY1
+
1
+
yOffset
),
new
Point
(
clipX2
-
1
-
xOffset
,
clipY1
+
1
+
yOffset
),
new
Point
(
clipX1
+
1
+
xOffset
,
centerY
+
yOffset
),
new
Point
(
centerX
+
xOffset
,
centerY
+
yOffset
),
new
Point
(
clipX2
-
1
-
xOffset
,
centerY
+
yOffset
),
new
Point
(
clipX1
+
1
+
xOffset
,
clipY2
-
1
-
yOffset
),
new
Point
(
centerX
+
xOffset
,
clipY2
-
1
-
yOffset
),
new
Point
(
clipX2
-
1
-
xOffset
,
clipY2
-
1
-
yOffset
),
};
quadIndex
++;
++
yOffset
;
// Middle-right
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
rightX
-
xOffset
,
clipY1
+
1
+
yOffset
),
new
Point
(
rightX
-
xOffset
,
centerY
+
yOffset
),
new
Point
(
rightX
-
xOffset
,
clipY2
-
1
-
yOffset
),
};
quadIndex
++;
yOffset
=
0
;
++
xOffset
;
// Lower-left
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
leftX
+
xOffset
,
clipY2
+
1
+
yOffset
),
new
Point
(
leftX
+
xOffset
,
bottomY
-
yOffset
),
new
Point
(
clipX1
-
1
-
xOffset
,
bottomY
-
yOffset
),
};
quadIndex
++;
++
yOffset
;
// Lower-middle
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
clipX1
+
1
+
xOffset
,
bottomY
-
yOffset
),
new
Point
(
centerX
+
xOffset
,
bottomY
-
yOffset
),
new
Point
(
clipX2
-
1
-
xOffset
,
bottomY
-
yOffset
),
};
quadIndex
++;
++
yOffset
;
// Lower-right
quadrants
[
quadIndex
]
=
new
Point
[]
{
new
Point
(
clipX2
+
1
+
xOffset
,
bottomY
-
yOffset
),
new
Point
(
rightX
-
xOffset
,
bottomY
-
yOffset
),
new
Point
(
rightX
-
xOffset
,
clipY2
+
1
+
yOffset
),
};
if
(
testImage
!=
null
)
{
testImage
.
flush
();
}
testW
=
getWidth
();
testH
=
getHeight
();
testImage
=
createVolatileImage
(
testW
,
testH
);
Graphics
g
=
testImage
.
getGraphics
();
do
{
int
valCode
=
testImage
.
validate
(
getGraphicsConfiguration
());
if
(
valCode
==
VolatileImage
.
IMAGE_INCOMPATIBLE
)
{
testImage
.
flush
();
testImage
=
createVolatileImage
(
testW
,
testH
);
g
=
testImage
.
getGraphics
();
}
drawLineGrid
(
screenGraphics
,
g
);
}
while
(
testImage
.
contentsLost
());
if
(
dynamic
)
{
// Draw clip box if dynamic
g
.
setClip
(
null
);
g
.
setColor
(
Color
.
black
);
g
.
drawRect
(
clipX1
,
clipY1
,
clipSize
,
clipSize
);
screenGraphics
.
drawImage
(
testImage
,
0
,
0
,
this
);
}
runTestDone
=
true
;
}
/**
* When running -dynamic, resize the clip bounds and run the test
* over and over
*/
public
void
run
()
{
while
(
true
)
{
clipSize
+=
clipBumpVal
;
if
(
clipSize
>
getWidth
()
||
clipSize
<
0
)
{
clipBumpVal
=
-
clipBumpVal
;
clipSize
+=
clipBumpVal
;
}
update
(
getGraphics
());
try
{
Thread
.
sleep
(
50
);
}
catch
(
Exception
e
)
{}
}
}
public
static
void
main
(
String
args
[])
{
for
(
int
i
=
0
;
i
<
args
.
length
;
++
i
)
{
if
(
args
[
i
].
equals
(
"-dynamic"
))
{
dynamic
=
true
;
}
else
if
(
args
[
i
].
equals
(
"-rect"
))
{
rectTest
=
true
;
}
else
if
(
args
[
i
].
equals
(
"-quick"
))
{
quickTest
=
true
;
}
else
if
(
args
[
i
].
equals
(
"-keep"
))
{
keepRunning
=
true
;
}
else
{
// could be clipSize
try
{
clipSize
=
Integer
.
parseInt
(
args
[
i
]);
}
catch
(
Exception
e
)
{}
}
}
f
=
new
Frame
();
f
.
setSize
(
500
,
500
);
LineClipTest
test
=
new
LineClipTest
();
f
.
add
(
test
);
if
(
dynamic
)
{
Thread
t
=
new
Thread
(
test
);
t
.
start
();
}
f
.
setVisible
(
true
);
while
(!
runTestDone
)
{
// need to make sure jtreg doesn't exit before the
// test is done...
try
{
Thread
.
sleep
(
50
);
}
catch
(
Exception
e
)
{}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录