diff --git a/draw/segdisp/segment/segment.go b/draw/segdisp/segment/segment.go index 91d40fb..7e07dc2 100644 --- a/draw/segdisp/segment/segment.go +++ b/draw/segdisp/segment/segment.go @@ -61,7 +61,7 @@ type Option interface { // options stores the provided options. type options struct { cellOpts []cell.Option - skipSlopes bool + skipSlopesLTE int reverseSlopes bool } @@ -82,10 +82,12 @@ func CellOpts(cOpts ...cell.Option) Option { }) } -// SkipSlopes if provided instructs HV to not create slopes at the ends of a segment. -func SkipSlopes() Option { +// SkipSlopesLTE if provided instructs HV to not create slopes at the ends of a +// segment if the height of the horizontal or the width of the vertical segment +// is less or equal to the provided value. +func SkipSlopesLTE(v int) Option { return option(func(opts *options) { - opts.skipSlopes = true + opts.skipSlopesLTE = v }) } @@ -94,12 +96,12 @@ func SkipSlopes() Option { // or the vertical segment has width of two. // Without this option segments with height / width of two look like this: // - | -// --- || +// --- || // | // // With this option: // --- | -// - || +// - || // | func ReverseSlopes() Option { return option(func(opts *options) { @@ -171,7 +173,7 @@ func nextHorizLine(num int, ar image.Rectangle, opt *options) (image.Point, imag height := ar.Dy() width := ar.Dx() - if opt.skipSlopes || height < 2 || width < 3 { + if height <= opt.skipSlopesLTE || height < 2 || width < 3 { // No slopes under these dimensions as we don't have the resolution. return start, end } @@ -226,7 +228,7 @@ func nextVertLine(num int, ar image.Rectangle, opt *options) (image.Point, image height := ar.Dy() width := ar.Dx() - if opt.skipSlopes || height < 3 || width < 2 { + if width <= opt.skipSlopesLTE || height < 3 || width < 2 { // No slopes under these dimensions as we don't have the resolution. return start, end } @@ -336,16 +338,16 @@ func (dt DiagonalType) String() string { // diagonalTypeNames maps DiagonalType values to human readable names. var diagonalTypeNames = map[DiagonalType]string{ - DiagonalTypeLeftToRight: "DiagonalTypeLeftToRight", - DiagonalTypeRightToLeft: "DiagonalTypeRightToLeft", + LeftToRight: "LeftToRight", + RightToLeft: "RightToLeft", } const ( diagonalTypeUnknown DiagonalType = iota - // DiagonalTypeLeftToRight is a diagonal segment from top left to bottom right. - DiagonalTypeLeftToRight - // DiagonalTypeRightToLeft is a diagonal segment from top right to bottom left. - DiagonalTypeRightToLeft + // LeftToRight is a diagonal segment from top left to bottom right. + LeftToRight + // RightToLeft is a diagonal segment from top right to bottom left. + RightToLeft diagonalTypeMax // Used for validation. ) @@ -401,12 +403,12 @@ func Diagonal(bc *braille.Canvas, ar image.Rectangle, width int, dt DiagonalType var start, end image.Point var nextFn nextDiagLineFn switch dt { - case DiagonalTypeLeftToRight: + case LeftToRight: start = ar.Min end = image.Point{ar.Max.X - 1, ar.Max.Y - 1} nextFn = nextLRLine - case DiagonalTypeRightToLeft: + case RightToLeft: start = image.Point{ar.Max.X - 1, ar.Min.Y} end = image.Point{ar.Min.X, ar.Max.Y - 1} nextFn = nextRLLine diff --git a/draw/segdisp/segment/segment_test.go b/draw/segdisp/segment/segment_test.go index aa2dcdd..2da9697 100644 --- a/draw/segdisp/segment/segment_test.go +++ b/draw/segdisp/segment/segment_test.go @@ -366,7 +366,7 @@ func TestHV(t *testing.T) { { desc: "horizontal, segment 3x3, skip slopes", opts: []Option{ - SkipSlopes(), + SkipSlopesLTE(3), }, cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 3, 3), @@ -382,6 +382,25 @@ func TestHV(t *testing.T) { return ft }, }, + { + desc: "horizontal, segment 3x3, doesn't skip slopes because is taller", + opts: []Option{ + SkipSlopesLTE(2), + }, + cellCanvas: image.Rect(0, 0, 2, 1), + ar: image.Rect(0, 0, 3, 3), + st: Horizontal, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testdraw.MustBrailleLine(bc, image.Point{1, 0}, image.Point{1, 0}) + testdraw.MustBrailleLine(bc, image.Point{0, 1}, image.Point{2, 1}) + testdraw.MustBrailleLine(bc, image.Point{1, 2}, image.Point{1, 2}) + testbraille.MustApply(bc, ft) + return ft + }, + }, { desc: "horizontal, segment 3x4", cellCanvas: image.Rect(0, 0, 2, 1), @@ -823,7 +842,7 @@ func TestHV(t *testing.T) { { desc: "vertical, segment 3x3, skips slopes", opts: []Option{ - SkipSlopes(), + SkipSlopesLTE(3), }, cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 3, 3), @@ -839,6 +858,25 @@ func TestHV(t *testing.T) { return ft }, }, + { + desc: "vertical, segment 3x3, doesn't skips slopes because is wider", + opts: []Option{ + SkipSlopesLTE(2), + }, + cellCanvas: image.Rect(0, 0, 2, 1), + ar: image.Rect(0, 0, 3, 3), + st: Vertical, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testdraw.MustBrailleLine(bc, image.Point{1, 0}, image.Point{1, 0}) + testdraw.MustBrailleLine(bc, image.Point{0, 1}, image.Point{2, 1}) + testdraw.MustBrailleLine(bc, image.Point{1, 2}, image.Point{1, 2}) + testbraille.MustApply(bc, ft) + return ft + }, + }, { desc: "vertical, segment 3x4", cellCanvas: image.Rect(0, 0, 2, 1), @@ -1226,7 +1264,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(-1, 0, 1, 1), width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1234,7 +1272,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, -1, 1, 1), width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1242,7 +1280,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rectangle{image.Point{0, 0}, image.Point{-1, 1}}, width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1250,7 +1288,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rectangle{image.Point{0, 0}, image.Point{1, -1}}, width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1258,7 +1296,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, 0, 0, 1), width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1266,7 +1304,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, 0, 1, 0), width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1282,7 +1320,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, 0, 2, 2), width: 1, - dt: DiagonalType(int(DiagonalTypeRightToLeft) + 1), + dt: DiagonalType(int(RightToLeft) + 1), wantErr: true, }, { @@ -1290,7 +1328,7 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, 0, 3, 1), width: 1, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { @@ -1298,14 +1336,14 @@ func TestDiagonal(t *testing.T) { cellCanvas: image.Rect(0, 0, 1, 1), ar: image.Rect(0, 0, 3, 1), width: 0, - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, wantErr: true, }, { desc: "left to right, area 4x4, width 1", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 1, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1321,7 +1359,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 1", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 1, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1337,7 +1375,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 2", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 2, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1354,7 +1392,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 2", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 2, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1371,7 +1409,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 3", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1389,7 +1427,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 3", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1407,7 +1445,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 8x4, width 3", cellCanvas: image.Rect(0, 0, 4, 1), ar: image.Rect(0, 0, 8, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1425,7 +1463,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 8x4, width 3", cellCanvas: image.Rect(0, 0, 4, 1), ar: image.Rect(0, 0, 8, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1443,7 +1481,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x8, width 3", cellCanvas: image.Rect(0, 0, 2, 2), ar: image.Rect(0, 0, 4, 8), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1461,7 +1499,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x8, width 3", cellCanvas: image.Rect(0, 0, 2, 2), ar: image.Rect(0, 0, 4, 8), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 3, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1479,7 +1517,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 4", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 4, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1498,7 +1536,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 4", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 4, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1517,7 +1555,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 5", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 5, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1537,7 +1575,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 5", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 5, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1557,7 +1595,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 6", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 6, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1578,7 +1616,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 6", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 6, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1599,7 +1637,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, area 4x4, width 7", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 7, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1621,7 +1659,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, area 4x4, width 7", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 7, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) @@ -1643,7 +1681,7 @@ func TestDiagonal(t *testing.T) { desc: "left to right, fails when width is larger than area", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 8, wantErr: true, }, @@ -1651,7 +1689,7 @@ func TestDiagonal(t *testing.T) { desc: "right to left, fails when width is larger than area", cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeRightToLeft, + dt: RightToLeft, width: 8, wantErr: true, }, @@ -1665,7 +1703,7 @@ func TestDiagonal(t *testing.T) { }, cellCanvas: image.Rect(0, 0, 2, 1), ar: image.Rect(0, 0, 4, 4), - dt: DiagonalTypeLeftToRight, + dt: LeftToRight, width: 2, want: func(size image.Point) *faketerm.Terminal { ft := faketerm.MustNew(size) diff --git a/draw/segdisp/sixteen/sixteen.go b/draw/segdisp/sixteen/sixteen.go index d47b2a7..5dc646e 100644 --- a/draw/segdisp/sixteen/sixteen.go +++ b/draw/segdisp/sixteen/sixteen.go @@ -13,10 +13,11 @@ // limitations under the License. /* -Package segdisp simulates a 16-segment display drawn on a canvas. +Package sixteen simulates a 16-segment display drawn on a canvas. Given a canvas, determines the placement and size of the individual -segments and exposes API that can turn individual segments on and off. +segments and exposes API that can turn individual segments on and off or +display characters. The following outlines segments in the display and their names. @@ -36,7 +37,7 @@ The following outlines segments in the display and their names. ------- ------- D1 D2 */ -package segdisp +package sixteen import ( "errors" @@ -49,8 +50,8 @@ import ( "github.com/mum4k/termdash/canvas" "github.com/mum4k/termdash/canvas/braille" "github.com/mum4k/termdash/cell" + "github.com/mum4k/termdash/draw/segdisp/segment" "github.com/mum4k/termdash/numbers" - "github.com/mum4k/termdash/segdisp/segment" ) // Segment represents a single segment in the display. @@ -308,31 +309,32 @@ func (d *Display) Draw(cvs *canvas.Canvas, opts ...Option) error { d2Ar := image.Rect(d1Ar.Max.X+ptp, botStart, d1Ar.Max.X+ptp+shortL, botStart+segW) for _, segArg := range []struct { - s Segment - st segment.SegmentType - ar image.Rectangle + s Segment + st segment.SegmentType + ar image.Rectangle + opts []segment.Option }{ - {A1, segment.SegmentTypeHorizontal, a1Ar}, - {A2, segment.SegmentTypeHorizontal, a2Ar}, + {A1, segment.Horizontal, a1Ar, nil}, + {A2, segment.Horizontal, a2Ar, nil}, - {F, segment.SegmentTypeVertical, fAr}, - {J, segment.SegmentTypeVertical, jAr}, - {B, segment.SegmentTypeVertical, bAr}, + {F, segment.Vertical, fAr, nil}, + {J, segment.Vertical, jAr, []segment.Option{segment.SkipSlopesLTE(2)}}, + {B, segment.Vertical, bAr, []segment.Option{segment.ReverseSlopes()}}, - {G1, segment.SegmentTypeHorizontal, g1Ar}, - {G2, segment.SegmentTypeHorizontal, g2Ar}, + {G1, segment.Horizontal, g1Ar, []segment.Option{segment.SkipSlopesLTE(2)}}, + {G2, segment.Horizontal, g2Ar, []segment.Option{segment.SkipSlopesLTE(2)}}, - {E, segment.SegmentTypeVertical, eAr}, - {M, segment.SegmentTypeVertical, mAr}, - {C, segment.SegmentTypeVertical, cAr}, + {E, segment.Vertical, eAr, nil}, + {M, segment.Vertical, mAr, []segment.Option{segment.SkipSlopesLTE(2)}}, + {C, segment.Vertical, cAr, []segment.Option{segment.ReverseSlopes()}}, - {D1, segment.SegmentTypeHorizontal, d1Ar}, - {D2, segment.SegmentTypeHorizontal, d2Ar}, + {D1, segment.Horizontal, d1Ar, []segment.Option{segment.ReverseSlopes()}}, + {D2, segment.Horizontal, d2Ar, []segment.Option{segment.ReverseSlopes()}}, } { if !d.segments[segArg.s] { continue } - if err := segment.HV(bc, segArg.ar, segArg.st); err != nil { + if err := segment.HV(bc, segArg.ar, segArg.st, segArg.opts...); err != nil { return fmt.Errorf("failed to draw segment %v, segment.HV => %v", segArg.s, err) } } @@ -366,10 +368,10 @@ func (d *Display) Draw(cvs *canvas.Canvas, opts ...Option) error { dt segment.DiagonalType ar image.Rectangle }{ - {H, segment.DiagonalTypeLeftToRight, hAr}, - {K, segment.DiagonalTypeRightToLeft, kAr}, - {N, segment.DiagonalTypeRightToLeft, nAr}, - {L, segment.DiagonalTypeLeftToRight, lAr}, + {H, segment.LeftToRight, hAr}, + {K, segment.RightToLeft, kAr}, + {N, segment.RightToLeft, nAr}, + {L, segment.LeftToRight, lAr}, } { if !d.segments[segArg.s] { continue diff --git a/draw/segdisp/sixteen/sixteen_test.go b/draw/segdisp/sixteen/sixteen_test.go index c2c9d00..db81ed4 100644 --- a/draw/segdisp/sixteen/sixteen_test.go +++ b/draw/segdisp/sixteen/sixteen_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package segdisp +package sixteen import ( "image"