-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitmap.go
More file actions
95 lines (80 loc) · 2.29 KB
/
Copy pathbitmap.go
File metadata and controls
95 lines (80 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package textrender
import (
"image"
"image/color"
"image/png"
"io"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
)
// BitmapRenderer renders text layout as a bitmap image
type BitmapRenderer struct {
FontFace font.Face // Font to use for rendering
Background color.Color // Background color
TextColor color.Color // Text color
Padding int // Padding around text in pixels
}
// DefaultBitmapRenderer returns a renderer with default settings
func DefaultBitmapRenderer() *BitmapRenderer {
return &BitmapRenderer{
FontFace: basicfont.Face7x13,
Background: color.White,
TextColor: color.Black,
Padding: 10,
}
}
// Render renders the text layout as a PNG image
func (r *BitmapRenderer) Render(layout *TextLayout) image.Image {
if r.FontFace == nil {
r.FontFace = basicfont.Face7x13
}
if r.Background == nil {
r.Background = color.White
}
if r.TextColor == nil {
r.TextColor = color.Black
}
// Calculate image dimensions
bounds := r.FontFace.Metrics().Height
lineHeight := bounds.Ceil()
// For fixed-width fonts, calculate character width
advance, _ := r.FontFace.GlyphAdvance('M')
charWidth := advance.Ceil()
numLines := len(layout.Lines)
width := layout.Options.Width*charWidth + 2*r.Padding
height := numLines*lineHeight + 2*r.Padding
// Create image
img := image.NewRGBA(image.Rect(0, 0, width, height))
// Fill background
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
img.Set(x, y, r.Background)
}
}
// Create drawer
drawer := &font.Drawer{
Dst: img,
Src: image.NewUniform(r.TextColor),
Face: r.FontFace,
}
// Draw each line
ascent := r.FontFace.Metrics().Ascent.Ceil()
for i, line := range layout.Lines {
y := r.Padding + ascent + i*lineHeight
drawer.Dot = fixed.P(r.Padding, y)
drawer.DrawString(line)
}
return img
}
// RenderToPNG renders the text layout and writes it as PNG to the writer
func (r *BitmapRenderer) RenderToPNG(layout *TextLayout, w io.Writer) error {
img := r.Render(layout)
return png.Encode(w, img)
}
// RenderBitmap is a convenience function to render text as a bitmap image
func RenderBitmap(text string, options LayoutOptions) image.Image {
layout := Layout(text, options)
renderer := DefaultBitmapRenderer()
return renderer.Render(layout)
}