Skip to content

Commit

Permalink
Add a test of the selection code
Browse files Browse the repository at this point in the history
Add a test that demonstrates that selecting a single character is correct along
with its necessary dependencies:

* had to add functionality to compute blended image colours
* so rebase the tests for the visually indistinguishable slightly different colours
* add functionality to record fills with arbitrary colours
  • Loading branch information
rjkroege committed Mar 10, 2023
1 parent 0f7cef0 commit dd8fcfc
Show file tree
Hide file tree
Showing 35 changed files with 337 additions and 176 deletions.
2 changes: 2 additions & 0 deletions draw/9fans.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ const (
KeyRight = draw.KeyRight
KeyUp = draw.KeyUp

Black = draw.Black
Darkyellow = draw.Darkyellow
Medblue = draw.Medblue
Nofill = draw.Nofill
Notacolor = draw.Notacolor
Opaque = draw.Opaque
Palebluegreen = draw.Palebluegreen
Palegreygreen = draw.Palegreygreen
Paleyellow = draw.Paleyellow
Expand Down
2 changes: 2 additions & 0 deletions draw/duitdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ const (
KeyRight = draw.KeyRight
KeyUp = draw.KeyUp

Black = draw.Black
Darkyellow = draw.Darkyellow
Medblue = draw.Medblue
Nofill = draw.Nofill
Notacolor = draw.Notacolor
Opaque = draw.Opaque
Palebluegreen = draw.Palebluegreen
Palegreygreen = draw.Palegreygreen
Paleyellow = draw.Paleyellow
Expand Down
11 changes: 11 additions & 0 deletions draw/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,14 @@ type fontImpl struct {

func (f *fontImpl) Name() string { return f.drawFont.Name }
func (f *fontImpl) Height() int { return f.drawFont.Height }

// Imported from a newer version of 9fans.draw
func WithAlpha(c Color, alpha uint8) Color {
r := uint32(c >> 24)
g := uint32(c>>16) & 0xFF
b := uint32(c>>8) & 0xFF
r = (r * uint32(alpha)) / 255
g = (g * uint32(alpha)) / 255
b = (b * uint32(alpha)) / 255
return Color(r<<24 | g<<16 | b<<8 | uint32(alpha))
}
88 changes: 63 additions & 25 deletions edwoodtest/draw.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func NewDisplay(rectofi image.Rectangle) draw.Display {
md := &mockDisplay{
rectofi: rectofi,
}
md.screenimage = newimageimpl(md, "screen-800x600", image.Rect(0, 0, 800, 600))
md.screenimage = newimageimpl(md, "screen-800x600", draw.Notacolor, image.Rect(0, 0, 800, 600))
md.svgdrawops = append(md.svgdrawops, boundingboxsvg(0, rectofi))
md.annotations = append(md.annotations, fmt.Sprintf("target rect %v", rectofi))
return md
Expand All @@ -69,11 +69,17 @@ func (d *mockDisplay) ScreenImage() draw.Image {
return d.screenimage
}

func (d *mockDisplay) White() draw.Image { return newimageimpl(d, "white", image.Rectangle{}) }
func (d *mockDisplay) Black() draw.Image { return newimageimpl(d, "black", image.Rectangle{}) }
func (d *mockDisplay) Opaque() draw.Image { return newimageimpl(d, "opaque", image.Rectangle{}) }
func (d *mockDisplay) White() draw.Image {
return newimageimpl(d, "white", draw.White, image.Rectangle{})
}
func (d *mockDisplay) Black() draw.Image {
return newimageimpl(d, "black", draw.Black, image.Rectangle{})
}
func (d *mockDisplay) Opaque() draw.Image {
return newimageimpl(d, "opaque", draw.Opaque, image.Rectangle{})
}
func (d *mockDisplay) Transparent() draw.Image {
return newimageimpl(d, "transparent", image.Rectangle{})
return newimageimpl(d, "transparent", draw.Transparent, image.Rectangle{})
}
func (d *mockDisplay) InitKeyboard() *draw.Keyboardctl { return &draw.Keyboardctl{} }
func (d *mockDisplay) InitMouse() *draw.Mousectl { return &draw.Mousectl{} }
Expand All @@ -84,23 +90,24 @@ func (d *mockDisplay) InitMouse() *draw.Mousectl { return &draw.Mousectl{}
func (d *mockDisplay) OpenFont(name string) (draw.Font, error) { return NewFont(fwidth, fheight), nil }

func (d *mockDisplay) AllocImage(r image.Rectangle, pix draw.Pix, repl bool, val draw.Color) (draw.Image, error) {
name := fmt.Sprintf("%s-%v", NiceColourName(val), r)
if repl {
name += ",tiled"
}

return &mockImage{
d: d,
r: r,
n: name,
d: d,
r: r,
c: val,
repl: repl,
}, nil
}

func (d *mockDisplay) AllocImageMix(color1, color3 draw.Color) draw.Image {
name := fmt.Sprintf("mix(%s,%s)", NiceColourName(color1), NiceColourName(color3))
c1 := draw.WithAlpha(color1, 0x3f) >> 8
c3 := draw.WithAlpha(color3, 0xbf) >> 8
c := ((c1 + c3) << 8) | 0xff

return &mockImage{
d: d,
n: name,
d: d,
r: image.Rect(0, 0, 1, 1),
repl: true,
c: c,
}
}

Expand Down Expand Up @@ -146,23 +153,28 @@ var _ = draw.Image((*mockImage)(nil))

// mockImage implements draw.Image.
type mockImage struct {
r image.Rectangle
d *mockDisplay
n string
r image.Rectangle
d *mockDisplay
n string
c draw.Color
repl bool
}

func newimageimpl(d *mockDisplay, name string, r image.Rectangle) draw.Image {
// newimage creates a new mockImage. Use Notacolor for the situation
// where the name of the image takes precedence.
func newimageimpl(d *mockDisplay, name string, c draw.Color, r image.Rectangle) draw.Image {
return &mockImage{
r: r,
n: name,
d: d,
c: c,
n: name,
}
}

// NewImage returns a mock draw.Image with the given bounds.
func NewImage(display draw.Display, name string, r image.Rectangle) draw.Image {
d := display.(*mockDisplay)
return newimageimpl(d, name, r)
return newimageimpl(d, name, draw.Notacolor, r)
}

func (i *mockImage) Display() draw.Display { return i.d }
Expand Down Expand Up @@ -219,11 +231,11 @@ func pointochars(p image.Point) string {
func (i *mockImage) Draw(r image.Rectangle, src, mask draw.Image, p1 image.Point) {
srcname := "nil"
if msrc, ok := src.(*mockImage); ok {
srcname = msrc.n
srcname = msrc.N()
}
maskname := "nil"
if mmask, ok := src.(*mockImage); ok {
maskname = mmask.n
maskname = mmask.N()
}

op := fmt.Sprintf("%s <- draw r: %v src: %s mask %s p1: %v",
Expand All @@ -233,6 +245,11 @@ func (i *mockImage) Draw(r image.Rectangle, src, mask draw.Image, p1 image.Point
maskname,
p1,
)

// It's arguable that my logic to separate blit from fill is slightly
// specious. The actual draw API deosn't (rightly) differentiate between
// these and the distinction that I'm creating is only to make nicer test
// output.
switch {
case i.r.Dx() > 0 && i.r.Dy() > 0 && maskname == srcname && srcname == i.n:
sr := r.Sub(r.Min).Add(p1)
Expand All @@ -253,7 +270,7 @@ func (i *mockImage) Draw(r image.Rectangle, src, mask draw.Image, p1 image.Point
))
i.d.annotations = append(i.d.annotations, op)
}
case src != nil && i.r.Dx() > 0 && i.r.Dy() > 0 && maskname == srcname && src.R().Dx() == 0 && src.R().Dy() == 0:
case src != nil && i.r.Dx() > 0 && i.r.Dy() > 0 && maskname == srcname:
op = fmt.Sprintf("fill %v %s",
r, rectochars(r),
)
Expand All @@ -266,6 +283,7 @@ func (i *mockImage) Draw(r image.Rectangle, src, mask draw.Image, p1 image.Point
len(i.d.svgdrawops),
r,
i.d.rectofi,
src,
))
i.d.annotations = append(i.d.annotations, op)
}
Expand Down Expand Up @@ -322,6 +340,26 @@ func (i *mockImage) Bytes(pt image.Point, src draw.Image, sp image.Point, f draw

func (i *mockImage) Free() error { return nil }

// N returns a nicename for the image colour.
func (i *mockImage) N() string {
name := i.n
if i.c != draw.Notacolor {
name = fmt.Sprintf("%s-%v", NiceColourName(i.c), i.r)
}

if i.repl {
name += ",tiled"
}
return name
}

func (i *mockImage) HtmlString() string {
if i.c == draw.Notacolor {
return "white"
}
return fmt.Sprintf("#%x", i.c>>8)
}

var _ = draw.Font((*mockFont)(nil))

// mockFont implements draw.Font and mocks as a fixed width font.
Expand Down
30 changes: 20 additions & 10 deletions edwoodtest/svg_drawops.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"io"
"log"
"strings"

"github.com/rjkroege/edwood/draw"
)

var tmpl *template.Template
Expand Down Expand Up @@ -76,24 +78,32 @@ func bytessvg(id int, sp image.Point, b []byte) string {
}

// TODO(rjk): refactor this together with the other code.
// TODO(rjk): I wrote the above at some point without saying what I was
// actually suppose to do. Maybe figure out what I meant to fix.
type Fillargs struct {
Id int
SrcId int
Box image.Rectangle
Rect image.Rectangle
Id int
SrcId int
Box image.Rectangle
Rect image.Rectangle
Fillcol string
Fillcolhtml string
}

const filltemplate = `<g id="draw{{.Id}}">
<use href="#draw{{.SrcId}}" />
<rect x="{{.Rect.Min.X}}" y="{{.Rect.Min.Y}}" width="{{.Rect.Dx}}" height="{{.Rect.Dy}}" fill="#ffffdd"/>
<rect x="{{.Rect.Min.X}}" y="{{.Rect.Min.Y}}" width="{{.Rect.Dx}}" height="{{.Rect.Dy}}" fill="{{.Fillcolhtml}}"/>
</g>`

func fillsvg(id int, rect, box image.Rectangle) string {
func fillsvg(id int, rect, box image.Rectangle, img draw.Image) string {
ai := img.(*mockImage)

fillargs := Fillargs{
Id: id,
SrcId: id - 1,
Rect: rect,
Box: box,
Id: id,
SrcId: id - 1,
Rect: rect,
Box: box,
Fillcol: ai.N(),
Fillcolhtml: ai.HtmlString(),
}

swr := new(strings.Builder)
Expand Down
6 changes: 3 additions & 3 deletions frame/testdata/TestDelete/deleteCharBeforeTab.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</g>
<g id="draw1">
<use href="#draw0" />
<rect x="20" y="10" width="120" height="10" fill="#ffffdd"/>
<rect x="20" y="10" width="120" height="10" fill="#fefee9"/>
</g>
</g>

Expand All @@ -35,7 +35,7 @@
</g>
<g id="draw2">
<use href="#draw1" />
<rect x="20" y="20" width="78" height="10" fill="#ffffdd"/>
<rect x="20" y="20" width="78" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down Expand Up @@ -81,7 +81,7 @@
</g>
<g id="draw6">
<use href="#draw5" />
<rect x="33" y="10" width="91" height="10" fill="#ffffdd"/>
<rect x="33" y="10" width="91" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</g>
<g id="draw1">
<use href="#draw0" />
<rect x="20" y="10" width="40" height="10" fill="#ffffdd"/>
<rect x="20" y="10" width="40" height="10" fill="#fefee9"/>
</g>
</g>

Expand All @@ -35,7 +35,7 @@
</g>
<g id="draw2">
<use href="#draw1" />
<rect x="20" y="20" width="40" height="10" fill="#ffffdd"/>
<rect x="20" y="20" width="40" height="10" fill="#fefee9"/>
</g>
</g>

Expand All @@ -45,7 +45,7 @@
</g>
<g id="draw3">
<use href="#draw2" />
<rect x="20" y="30" width="39" height="10" fill="#ffffdd"/>
<rect x="20" y="30" width="39" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down Expand Up @@ -110,7 +110,7 @@
</g>
<g id="draw8">
<use href="#draw7" />
<rect x="59" y="20" width="0" height="10" fill="#ffffdd"/>
<rect x="59" y="20" width="0" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down
4 changes: 2 additions & 2 deletions frame/testdata/TestDelete/deleteSingleCharacterAtLineEnd.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</g>
<g id="draw1">
<use href="#draw0" />
<rect x="20" y="10" width="39" height="10" fill="#ffffdd"/>
<rect x="20" y="10" width="39" height="10" fill="#fefee9"/>
</g>
</g>

Expand All @@ -47,7 +47,7 @@
</g>
<g id="draw3">
<use href="#draw2" />
<rect x="46" y="10" width="13" height="10" fill="#ffffdd"/>
<rect x="46" y="10" width="13" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down
6 changes: 3 additions & 3 deletions frame/testdata/TestDelete/deleteSingleCharacterInMiddle.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</g>
<g id="draw1">
<use href="#draw0" />
<rect x="20" y="10" width="39" height="10" fill="#ffffdd"/>
<rect x="20" y="10" width="39" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down Expand Up @@ -66,7 +66,7 @@
</g>
<g id="draw4">
<use href="#draw3" />
<rect x="46" y="10" width="0" height="10" fill="#ffffdd"/>
<rect x="46" y="10" width="0" height="10" fill="#fefee9"/>
</g>
</g>

Expand All @@ -76,7 +76,7 @@
</g>
<g id="draw5">
<use href="#draw4" />
<rect x="46" y="10" width="13" height="10" fill="#ffffdd"/>
<rect x="46" y="10" width="13" height="10" fill="#fefee9"/>
</g>
</g>

Expand Down
Loading

0 comments on commit dd8fcfc

Please sign in to comment.