Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
3dc04f4a
Commit
3dc04f4a
authored
Feb 17, 2010
by
Nigel Tao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Src and Over draw operators.
R=r, rsc CC=golang-dev
https://golang.org/cl/207096
parent
77525dc8
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
63 deletions
+95
-63
src/pkg/exp/4s/xs.go
src/pkg/exp/4s/xs.go
+9
-9
src/pkg/exp/draw/draw.go
src/pkg/exp/draw/draw.go
+58
-42
src/pkg/exp/draw/draw_test.go
src/pkg/exp/draw/draw_test.go
+28
-12
No files found.
src/pkg/exp/4s/xs.go
View file @
3dc04f4a
...
...
@@ -266,14 +266,14 @@ func setpiece(p *Piece) {
draw
.
Draw
(
bb2
,
r2
,
draw
.
White
,
draw
.
ZP
)
draw
.
Draw
(
bb2
,
r
.
Add
(
delta
),
bb
,
bbr
.
Min
)
draw
.
Draw
(
bb2mask
,
r2
,
draw
.
Transparent
,
draw
.
ZP
)
draw
.
DrawMask
(
bb2mask
,
r
,
draw
.
Opaque
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
bb2mask
,
r
.
Add
(
delta
),
draw
.
Opaque
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
bb2mask
,
r
,
draw
.
Opaque
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
Over
)
draw
.
DrawMask
(
bb2mask
,
r
.
Add
(
delta
),
draw
.
Opaque
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
Over
)
}
func
drawpiece
()
{
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
bb
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
bb
,
bbr
.
Min
,
bbmask
,
draw
.
ZP
,
draw
.
Over
)
if
suspended
{
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
Over
)
}
}
...
...
@@ -282,7 +282,7 @@ func undrawpiece() {
if
collider
(
pos
,
br
.
Max
)
{
mask
=
bbmask
}
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
draw
.
White
,
bbr
.
Min
,
mask
,
bbr
.
Min
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
br
.
Add
(
pos
),
draw
.
White
,
bbr
.
Min
,
mask
,
bbr
.
Min
,
draw
.
Over
)
}
func
rest
()
{
...
...
@@ -349,7 +349,7 @@ func drawboard() {
}
score
(
0
)
if
suspended
{
draw
.
DrawMask
(
screen
,
screenr
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
screenr
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
Over
)
}
}
...
...
@@ -375,7 +375,7 @@ func movepiece() bool {
if
collider
(
pos
,
br2
.
Max
)
{
mask
=
bb2mask
}
draw
.
DrawMask
(
screen
,
br2
.
Add
(
pos
),
bb2
,
bb2r
.
Min
,
mask
,
bb2r
.
Min
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
br2
.
Add
(
pos
),
bb2
,
bb2r
.
Min
,
mask
,
bb2r
.
Min
,
draw
.
Over
)
pos
.
Y
+=
DY
display
.
FlushImage
()
return
true
...
...
@@ -444,7 +444,7 @@ func horiz() bool {
for
j
:=
0
;
j
<
h
;
j
++
{
r
.
Min
.
Y
=
rboard
.
Min
.
Y
+
lev
[
j
]
*
pcsz
r
.
Max
.
Y
=
r
.
Min
.
Y
+
pcsz
draw
.
DrawMask
(
screen
,
r
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
r
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
Over
)
display
.
FlushImage
()
}
PlaySound
(
whoosh
)
...
...
@@ -457,7 +457,7 @@ func horiz() bool {
for
j
:=
0
;
j
<
h
;
j
++
{
r
.
Min
.
Y
=
rboard
.
Min
.
Y
+
lev
[
j
]
*
pcsz
r
.
Max
.
Y
=
r
.
Min
.
Y
+
pcsz
draw
.
DrawMask
(
screen
,
r
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
SoverD
)
draw
.
DrawMask
(
screen
,
r
,
draw
.
White
,
draw
.
ZP
,
whitemask
,
draw
.
ZP
,
draw
.
Over
)
}
display
.
FlushImage
()
}
...
...
src/pkg/exp/draw/draw.go
View file @
3dc04f4a
...
...
@@ -15,7 +15,14 @@ import "image"
// A Porter-Duff compositing operator.
type
Op
int
const
SoverD
Op
=
0
const
(
// Over specifies ``(src in mask) over dst''.
Over
Op
=
iota
// Src specifies ``src in mask''.
Src
)
var
zeroColor
image
.
Color
=
image
.
AlphaColor
{
0
}
// A draw.Image is an image.Image with a Set method to change a single pixel.
type
Image
interface
{
...
...
@@ -23,14 +30,13 @@ type Image interface {
Set
(
x
,
y
int
,
c
image
.
Color
)
}
// Draw calls DrawMask with a nil mask and an
SoverD
op.
// Draw calls DrawMask with a nil mask and an
Over
op.
func
Draw
(
dst
Image
,
r
Rectangle
,
src
image
.
Image
,
sp
Point
)
{
DrawMask
(
dst
,
r
,
src
,
sp
,
nil
,
ZP
,
SoverD
)
DrawMask
(
dst
,
r
,
src
,
sp
,
nil
,
ZP
,
Over
)
}
// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r
// in dst with the result of a Porter-Duff composition. For the SoverD operator, the result
// is ``(src in mask) over dst''. If mask is nil, this simplifies to ``src over dst''.
// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.
// The implementation is simple and slow.
// TODO(nigeltao): Optimize this.
func
DrawMask
(
dst
Image
,
r
Rectangle
,
src
image
.
Image
,
sp
Point
,
mask
image
.
Image
,
mp
Point
,
op
Op
)
{
...
...
@@ -54,7 +60,10 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
// TODO(nigeltao): Ensure that r is well formed, i.e. r.Max.X >= r.Min.X and likewise for Y.
// Fast paths for special cases. If none of them apply, then we fall back to a general but slow implementation.
if
dst0
,
ok
:=
dst
.
(
*
image
.
RGBA
);
ok
&&
op
==
SoverD
{
if
dst0
,
ok
:=
dst
.
(
*
image
.
RGBA
);
ok
{
if
op
==
Over
{
// TODO(nigeltao): Implement a fast path for font glyphs (i.e. when mask is an image.Alpha).
}
else
{
if
mask
==
nil
{
if
src0
,
ok
:=
src
.
(
image
.
ColorImage
);
ok
{
drawFill
(
dst0
,
r
,
src0
)
...
...
@@ -69,7 +78,7 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
}
}
}
// TODO(nigeltao): Implement a fast path for font glyphs (i.e. when mask is an image.Alpha).
}
}
x0
,
x1
,
dx
:=
r
.
Min
.
X
,
r
.
Max
.
X
,
1
...
...
@@ -89,42 +98,49 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
sx
:=
sp
.
X
+
x0
-
r
.
Min
.
X
mx
:=
mp
.
X
+
x0
-
r
.
Min
.
X
for
x
:=
x0
;
x
!=
x1
;
x
,
sx
,
mx
=
x
+
dx
,
sx
+
dx
,
mx
+
dx
{
// TODO(nigeltao): Check that op == SoverD.
if
mask
==
nil
{
dst
.
Set
(
x
,
y
,
src
.
At
(
sx
,
sy
))
continue
// A nil mask is equivalent to a fully opaque, infinitely large mask.
// We work in 16-bit color, so that multiplying two values does not overflow a uint32.
const
M
=
1
<<
16
-
1
ma
:=
uint32
(
M
)
if
mask
!=
nil
{
_
,
_
,
_
,
ma
=
mask
.
At
(
mx
,
my
)
.
RGBA
()
ma
>>=
16
}
_
,
_
,
_
,
ma
:=
mask
.
At
(
mx
,
my
)
.
RGBA
()
switch
ma
{
case
0
:
continue
case
0xFFFFFFFF
:
switch
{
case
ma
==
0
:
if
op
==
Over
{
// No-op.
}
else
{
dst
.
Set
(
x
,
y
,
zeroColor
)
}
case
ma
==
M
&&
op
==
Src
:
dst
.
Set
(
x
,
y
,
src
.
At
(
sx
,
sy
))
default
:
dr
,
dg
,
db
,
da
:=
dst
.
At
(
x
,
y
)
.
RGBA
()
dr
>>=
16
dg
>>=
16
db
>>=
16
da
>>=
16
sr
,
sg
,
sb
,
sa
:=
src
.
At
(
sx
,
sy
)
.
RGBA
()
sr
>>=
16
sg
>>=
16
sb
>>=
16
sa
>>=
16
ma
>>=
16
const
M
=
1
<<
16
-
1
a
:=
sa
*
ma
/
M
dr
=
(
dr
*
(
M
-
a
)
+
sr
*
ma
)
/
M
dg
=
(
dg
*
(
M
-
a
)
+
sg
*
ma
)
/
M
db
=
(
db
*
(
M
-
a
)
+
sb
*
ma
)
/
M
da
=
(
da
*
(
M
-
a
)
+
sa
*
ma
)
/
M
if
out
==
nil
{
out
=
new
(
image
.
RGBA64Color
)
}
out
.
R
=
uint16
(
dr
)
out
.
G
=
uint16
(
dg
)
out
.
B
=
uint16
(
db
)
out
.
A
=
uint16
(
da
)
if
op
==
Over
{
dr
,
dg
,
db
,
da
:=
dst
.
At
(
x
,
y
)
.
RGBA
()
dr
>>=
16
dg
>>=
16
db
>>=
16
da
>>=
16
a
:=
M
-
(
sa
*
ma
/
M
)
out
.
R
=
uint16
((
dr
*
a
+
sr
*
ma
)
/
M
)
out
.
G
=
uint16
((
dg
*
a
+
sg
*
ma
)
/
M
)
out
.
B
=
uint16
((
db
*
a
+
sb
*
ma
)
/
M
)
out
.
A
=
uint16
((
da
*
a
+
sa
*
ma
)
/
M
)
}
else
{
out
.
R
=
uint16
(
sr
*
ma
/
M
)
out
.
G
=
uint16
(
sg
*
ma
/
M
)
out
.
B
=
uint16
(
sb
*
ma
/
M
)
out
.
A
=
uint16
(
sa
*
ma
/
M
)
}
dst
.
Set
(
x
,
y
,
out
)
}
}
...
...
src/pkg/exp/draw/draw_test.go
View file @
3dc04f4a
...
...
@@ -57,31 +57,47 @@ type drawTest struct {
desc
string
src
image
.
Image
mask
image
.
Image
op
Op
expected
image
.
Color
}
var
drawTests
=
[]
drawTest
{
// Uniform mask (0% opaque) mask.
drawTest
{
"nop"
,
vgradGreen
(
255
),
fillAlpha
(
0
),
image
.
RGBAColor
{
136
,
0
,
0
,
255
}},
// Uniform mask (100%, 75%, nil) and vertical-gradient source.
drawTest
{
"copy"
,
vgradGreen
(
90
),
fillAlpha
(
255
),
image
.
RGBAColor
{
0
,
48
,
0
,
90
}},
drawTest
{
"copyAlpha"
,
vgradGreen
(
90
),
fillAlpha
(
192
),
image
.
RGBAColor
{
100
,
36
,
0
,
255
}},
drawTest
{
"copyNil"
,
vgradGreen
(
90
),
nil
,
image
.
RGBAColor
{
0
,
48
,
0
,
90
}},
// Uniform mask (0% opaque).
drawTest
{
"nop"
,
vgradGreen
(
255
),
fillAlpha
(
0
),
Over
,
image
.
RGBAColor
{
136
,
0
,
0
,
255
}},
drawTest
{
"clear"
,
vgradGreen
(
255
),
fillAlpha
(
0
),
Src
,
image
.
RGBAColor
{
0
,
0
,
0
,
0
}},
// Uniform mask (100%, 75%, nil) and uniform source.
drawTest
{
"fill"
,
fillBlue
(
90
),
fillAlpha
(
255
),
image
.
RGBAColor
{
0
,
0
,
90
,
90
}},
drawTest
{
"fillAlpha"
,
fillBlue
(
90
),
fillAlpha
(
192
),
image
.
RGBAColor
{
100
,
0
,
68
,
255
}},
drawTest
{
"fillNil"
,
fillBlue
(
90
),
nil
,
image
.
RGBAColor
{
0
,
0
,
90
,
90
}},
// Variable mask. In detail, at (x, y) == (8, 8):
// At (x, y) == (8, 8):
// The destination pixel is {136, 0, 0, 255}.
// The source pixel is {0, 0, 90, 90}.
drawTest
{
"fill"
,
fillBlue
(
90
),
fillAlpha
(
255
),
Over
,
image
.
RGBAColor
{
88
,
0
,
90
,
255
}},
drawTest
{
"fillSrc"
,
fillBlue
(
90
),
fillAlpha
(
255
),
Src
,
image
.
RGBAColor
{
0
,
0
,
90
,
90
}},
drawTest
{
"fillAlpha"
,
fillBlue
(
90
),
fillAlpha
(
192
),
Over
,
image
.
RGBAColor
{
100
,
0
,
68
,
255
}},
drawTest
{
"fillAlphaSrc"
,
fillBlue
(
90
),
fillAlpha
(
192
),
Src
,
image
.
RGBAColor
{
0
,
0
,
68
,
68
}},
drawTest
{
"fillNil"
,
fillBlue
(
90
),
nil
,
Over
,
image
.
RGBAColor
{
88
,
0
,
90
,
255
}},
drawTest
{
"fillNilSrc"
,
fillBlue
(
90
),
nil
,
Src
,
image
.
RGBAColor
{
0
,
0
,
90
,
90
}},
// Uniform mask (100%, 75%, nil) and variable source.
// At (x, y) == (8, 8):
// The destination pixel is {136, 0, 0, 255}.
// The source pixel is {0, 48, 0, 90}.
drawTest
{
"copy"
,
vgradGreen
(
90
),
fillAlpha
(
255
),
Over
,
image
.
RGBAColor
{
88
,
48
,
0
,
255
}},
drawTest
{
"copySrc"
,
vgradGreen
(
90
),
fillAlpha
(
255
),
Src
,
image
.
RGBAColor
{
0
,
48
,
0
,
90
}},
drawTest
{
"copyAlpha"
,
vgradGreen
(
90
),
fillAlpha
(
192
),
Over
,
image
.
RGBAColor
{
100
,
36
,
0
,
255
}},
drawTest
{
"copyAlphaSrc"
,
vgradGreen
(
90
),
fillAlpha
(
192
),
Src
,
image
.
RGBAColor
{
0
,
36
,
0
,
68
}},
drawTest
{
"copyNil"
,
vgradGreen
(
90
),
nil
,
Over
,
image
.
RGBAColor
{
88
,
48
,
0
,
255
}},
drawTest
{
"copyNilSrc"
,
vgradGreen
(
90
),
nil
,
Src
,
image
.
RGBAColor
{
0
,
48
,
0
,
90
}},
// Variable mask and variable source.
// At (x, y) == (8, 8):
// The destination pixel is {136, 0, 0, 255}.
// The source pixel is {0, 0, 255, 255}.
// The mask pixel's alpha is 102, or 40%.
drawTest
{
"generic"
,
fillBlue
(
255
),
vgradAlpha
(
192
),
image
.
RGBAColor
{
81
,
0
,
102
,
255
}},
drawTest
{
"generic"
,
fillBlue
(
255
),
vgradAlpha
(
192
),
Over
,
image
.
RGBAColor
{
81
,
0
,
102
,
255
}},
drawTest
{
"genericSrc"
,
fillBlue
(
255
),
vgradAlpha
(
192
),
Src
,
image
.
RGBAColor
{
0
,
0
,
102
,
102
}},
}
func
TestDraw
(
t
*
testing
.
T
)
{
for
_
,
test
:=
range
drawTests
{
dst
:=
hgradRed
(
255
)
DrawMask
(
dst
,
Rect
(
0
,
0
,
16
,
16
),
test
.
src
,
ZP
,
test
.
mask
,
ZP
,
SoverD
)
DrawMask
(
dst
,
Rect
(
0
,
0
,
16
,
16
),
test
.
src
,
ZP
,
test
.
mask
,
ZP
,
test
.
op
)
if
!
eq
(
dst
.
At
(
8
,
8
),
test
.
expected
)
{
t
.
Errorf
(
"draw %s: %v versus %v"
,
test
.
desc
,
dst
.
At
(
8
,
8
),
test
.
expected
)
}
...
...
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