Add image.Image wrapper

This commit is contained in:
David Vogel 2024-12-20 21:12:59 +01:00
parent d9b6725592
commit 5cd261c199
4 changed files with 85 additions and 2 deletions

View File

@ -16,7 +16,7 @@ The supported and tested versions right now are:
- PDF, SVG and PNG generation.
- All typst-cli parameters are [available as a struct](cli-options.go), which makes it easy to discover all available options.
- Encoder to convert go values into typst markup which can be injected into typst documents.
- Encoder to convert go values into typst markup which can be injected into typst documents. This includes image.Image by using the [Image wrapper](image.go).
- Any stderr will be returned as go error value, including line number, column and file path of the error.
- Uses stdio; No temporary files will be created.
- Good unit test coverage.

2
cli.go
View File

@ -12,7 +12,7 @@ import (
"os/exec"
)
// TODO: Add docker support to CLI
// TODO: Add docker support to CLI, by calling docker run instead
type CLI struct {
ExecutablePath string // The typst executable path can be overridden here. Otherwise the default path will be used.

33
image.go Normal file
View File

@ -0,0 +1,33 @@
package typst
import (
"bytes"
"fmt"
"image"
"image/png"
"strconv"
)
// Image can be used to encode any image.Image into a typst image.
//
// For this, just wrap any image.Image with this type before passing it to MarshalVariable or a VariableEncoder.
type Image struct{ image.Image }
func (i Image) MarshalTypstVariable() ([]byte, error) {
var buffer bytes.Buffer
if err := png.Encode(&buffer, i); err != nil {
return nil, fmt.Errorf("failed to encode image as PNG: %w", err)
}
// TODO: Make image encoding more efficient: Use reader/writer, baseXX encoding
var buf bytes.Buffer
buf.WriteString("image.decode(bytes((")
for _, b := range buffer.Bytes() {
buf.WriteString(strconv.FormatUint(uint64(b), 10) + ",")
}
buf.WriteString(")))")
return buf.Bytes(), nil
}

50
image_test.go Normal file
View File

@ -0,0 +1,50 @@
package typst_test
import (
"bytes"
"image"
"image/color"
"io"
"testing"
"github.com/Dadido3/go-typst"
)
type testImage struct {
Rect image.Rectangle
}
func (p *testImage) ColorModel() color.Model { return color.RGBAModel }
func (p *testImage) Bounds() image.Rectangle { return p.Rect }
func (p *testImage) At(x, y int) color.Color { return p.RGBAAt(x, y) }
func (p *testImage) RGBAAt(x, y int) color.RGBA {
if !(image.Point{x, y}.In(p.Rect)) {
return color.RGBA{}
}
return color.RGBA{uint8(x), uint8(y), uint8(x + y), 255}
}
// Opaque scans the entire image and reports whether it is fully opaque.
func (p *testImage) Opaque() bool {
return true
}
func TestImage(t *testing.T) {
img := &testImage{image.Rect(0, 0, 255, 255)}
// Wrap image.
typstImage := typst.Image{img}
cli := typst.CLI{}
r := bytes.NewBufferString(`= Image test
#TestImage`)
if err := cli.CompileWithVariables(r, io.Discard, nil, map[string]any{"TestImage": typstImage}); err != nil {
t.Fatalf("Failed to compile document: %v.", err)
}
}