Skip to content

Commit 31299b8

Browse files
committed
preserve the arrow head when ReScale()
1 parent a426005 commit 31299b8

File tree

6 files changed

+141
-99
lines changed

6 files changed

+141
-99
lines changed

d2renderers/d2ascii/d2ascii.go

+53-11
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
6262
}
6363
}
6464

65-
// TODO: preserve arrow head
66-
// canvas.ReScale(canvas.w, canvas.AutoHeight())
65+
canvas.ReScale(canvas.w, canvas.AutoHeight())
6766
return canvas.TrimBytes(), nil
6867
}
6968

@@ -383,6 +382,10 @@ func (c *Canvas) AutoHeight() int {
383382
return maxH
384383
}
385384

385+
func isArrowHead(ch rune) bool {
386+
return ch == '>' || ch == '<' || ch == '^' || ch == 'v'
387+
}
388+
386389
// ReScale reduces the size of ASCII art using a pixel-like sampling technique
387390
func (c *Canvas) ReScale(targetWidth, targetHeight int) {
388391
scaleX := float64(targetWidth) / float64(c.w)
@@ -397,27 +400,67 @@ func (c *Canvas) ReScale(targetWidth, targetHeight int) {
397400
}
398401
}
399402

400-
// First scale the borders and lines (source -> target mapping)
401-
for y := 0; y < c.h; y++ {
403+
// First pass: scale borders and lines, but skip arrow heads
404+
for y := range c.h {
402405
targetY := int(float64(y) * scaleY)
403406
if targetY >= targetHeight {
404407
continue
405408
}
406409

407-
for x := 0; x < c.w; x++ {
410+
for x := range c.w {
408411
targetX := int(float64(x) * scaleX)
409412
if targetX >= targetWidth {
410413
continue
411414
}
412415

413416
ch := c.grid[y][x]
414-
if ch == '+' || ch == '-' || ch == '|' || ch == '/' || ch == '\\' || ch == '.' {
417+
if !isArrowHead(ch) && (ch == '+' || ch == '-' || ch == '|' || ch == '/' || ch == '\\') {
415418
newGrid[targetY][targetX] = ch
416419
}
417420
}
418421
}
419422

420-
// Then redraw text at scaled positions
423+
// Second pass: copy arrow heads with position adjustment
424+
for y := range c.h {
425+
targetY := int(float64(y) * scaleY)
426+
if targetY >= targetHeight {
427+
continue
428+
}
429+
430+
for x := range c.w {
431+
targetX := int(float64(x) * scaleX)
432+
if targetX >= targetWidth {
433+
continue
434+
}
435+
436+
ch := c.grid[y][x]
437+
if isArrowHead(ch) {
438+
// Determine offset based on arrow direction
439+
var dx, dy int
440+
switch ch {
441+
case '>':
442+
dx = -1
443+
case '<':
444+
dx = 1
445+
case 'v':
446+
dy = -1
447+
case '^':
448+
dy = 1
449+
}
450+
451+
// Apply offset and ensure we stay within bounds
452+
finalX := min(max(0, targetX+dx), targetWidth-1)
453+
finalY := min(max(0, targetY+dy), targetHeight-1)
454+
455+
// Only place arrow if target position is empty or has a line character
456+
if newGrid[finalY][finalX] == ' ' || newGrid[finalY][finalX] == '-' || newGrid[finalY][finalX] == '|' {
457+
newGrid[finalY][finalX] = ch
458+
}
459+
}
460+
}
461+
}
462+
463+
// Third pass: redraw text at scaled positions
421464
for _, label := range c.textPositions {
422465
// Get box dimensions in source coordinates first
423466
srcBoxCenterY := label.y + label.h/2
@@ -455,11 +498,10 @@ func (c *Canvas) ReScale(targetWidth, targetHeight int) {
455498
continue
456499
}
457500

458-
// Only overwrite space or existing text
501+
// Only overwrite if not an arrow head and not a border
459502
existing := newGrid[targetY][targetX]
460-
if existing == ' ' || (existing != '+' && existing != '-' &&
461-
existing != '|' && existing != '/' && existing != '\\' &&
462-
existing != '.') {
503+
if !isArrowHead(existing) && existing != '+' && existing != '-' &&
504+
existing != '|' && existing != '/' && existing != '\\' {
463505
newGrid[targetY][targetX] = ch
464506
}
465507
}

docs/examples/chess/dia.txt

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
|-----------------|
2-
/ Hans Niemann |
3-
///////////+---|||------|||--///////
4-
||////////// |||| ||| ///////|
2+
| Hans Niemann |
3+
///////////+---||--------||--+//////
4+
||////////// |||| ^ ^ ||| ///////|
55
||||| || || ||
6-
| || | ||
7-
|-|---------------------||---------------------|| ||
8-
| |--------------|---| || |
6+
v || | ||
7+
|-----------------------|----------------------|| ||
8+
| |------------------| || |
99
| | Magnus Carlsen | || |
1010
| +---------|--------+ || |
1111
| | || |
1212
| | || |
13-
| | || |
14-
| |----------|----------| || |
13+
| v || |
14+
| |---------------------| || |
1515
| | Play Magnus Group | || |
1616
| +----------|----------+ || |
1717
| | || |
1818
| || defendants |||| |
19-
| |||| //////|| | |
20-
| |---|----------|///// | |
19+
| |||| v //////|| | |
20+
| |--------------|///// | |
2121
| | Chess.com | | |
2222
| +-------|------+ | |
2323
| | | |
2424
| || | ||||
25-
| ||| | /////////|
26-
| |-------|------------|///|///
25+
| ||| v | /////////|
26+
| |--------------------|///|///
2727
| | Hikaru Nakamura | |
2828
| +--------------------+ |
2929
+----------------------------------------------+

docs/examples/flipt/output.txt

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
| | | | | | | | | | | | | |
88
| | +----+ +----+ +----+ +----+ | | | |-------| |
99
|------------------------------------------------------------------| | | | | | | | |
10-
| +----------+ | | | |----| |----| |----| |----| | | | ||//-----| | |
10+
| +----------+ | | | |----| |----| |----| |----| | | | ||//---> | | |
1111
| | | | | | | | | | | | | | | | | ||| +-------+ |
12-
| ///-----| linked |----///| | | | +----+ +----+ +----+ +----+ | | | |----|| |
13-
| |||| | | |||||-----------| | | | Test |--|-----------------|---| | Release |
14-
| |----------| +----------+ | | | | | |----| |----| |----| |----| | | | +----||| +-------+ |
15-
| | source | Build | |--|-----------------|---| | | | | | | | | | | | ||| | | |
16-
| | | | | | | | +----+ +----+ +----+ +----+ | | | ///-----| | |
12+
| ///---> | linked |----///| | | | +----+ +----+ +----+ +----+ | | | |----|| |
13+
| |||| | | |||||-----------| | | | Test |--|-----------------|-> | | Release |
14+
| |----------| +----------+ | | | | | |----| |----| |----| |----| | | | +----+|| +-------+ |
15+
| | source | Build | |--|-----------------|-> | | | | | | | | | | | | ||| | | |
16+
| | | | | | | | +----+ +----+ +----+ +----+ | | | ///---> | | |
1717
| +----------+||| |----------| ||| | | | | | | | | | |
18-
| |///------ assets -----///||| +-----------+ | | | |----| |----| |----| |----| | | | +-------+ |
18+
| |///---> | assets |----///||| +-----------+ | | | |----| |----| |----| |----| | | | +-------+ |
1919
| | | | | | | | | | | | | | | | +--------------------------------+
2020
| +----------+ | | | +----+ +----+ +----+ +----+ | |
2121
+------------------------------------------------------------------+ | | | |

0 commit comments

Comments
 (0)