We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
This is a remaining task from #124 (comment).
I used NotoSansJP-VF.otf from https://github.com/notofonts/noto-cjk/releases/tag/Sans2.004 ("All Variables OTF/OTC)".
package main import ( "bufio" "bytes" _ "embed" "flag" "image" "image/draw" "image/png" "os" "strings" "github.com/go-text/typesetting/di" "github.com/go-text/typesetting/font" "github.com/go-text/typesetting/language" "github.com/go-text/typesetting/opentype/api" "github.com/go-text/typesetting/shaping" "golang.org/x/image/math/fixed" "golang.org/x/image/vector" ) //go:embed NotoSansJP-VF.otf var notoSansJP []byte type singleFontmap struct { face font.Face } func (s *singleFontmap) ResolveFace(r rune) font.Face { return s.face } func render(dst draw.Image, origX, origY float32, text string) { f, err := font.ParseTTF(bytes.NewReader(notoSansJP)) if err != nil { panic(err) } script, err := language.ParseScript("jpan") if err != nil { panic(err) } str := []rune(text) input := shaping.Input{ Text: str, RunStart: 0, RunEnd: len(str), Direction: di.DirectionTTB, Face: f, Size: fixed.I(32), Script: script, Language: language.NewLanguage("jp"), } var segmenter shaping.Segmenter inputs := segmenter.Split(input, &singleFontmap{face: f}) for _, input := range inputs { out := (&shaping.HarfbuzzShaper{}).Shape(input) (shaping.Line{out}).AdjustBaselines() for _, g := range out.Glyphs { data := f.GlyphData(g.GlyphID).(api.GlyphOutline) if out.Direction.IsSideways() { data.Sideways(fixed26_6ToFloat32(-g.YOffset) / fixed26_6ToFloat32(out.Size) * float32(f.Upem())) } segs := data.Segments scaledSegs := make([]api.Segment, len(segs)) scale := fixed26_6ToFloat32(out.Size) / float32(f.Upem()) for i, seg := range segs { scaledSegs[i] = seg for j := range seg.Args { scaledSegs[i].Args[j].X *= scale scaledSegs[i].Args[j].Y *= -scale } } drawSegments(dst, origX+fixed26_6ToFloat32(g.XOffset), origY+fixed26_6ToFloat32(-g.YOffset), scaledSegs) origX += fixed26_6ToFloat32(g.XAdvance) origY += fixed26_6ToFloat32(-g.YAdvance) } } } func fixed26_6ToFloat32(x fixed.Int26_6) float32 { return float32(x) / (1 << 6) } func drawSegments(dst draw.Image, origX, origY float32, segs []api.Segment) { if len(segs) == 0 { return } rast := vector.NewRasterizer(dst.Bounds().Max.X, dst.Bounds().Max.Y) for _, seg := range segs { switch seg.Op { case api.SegmentOpMoveTo: rast.MoveTo(seg.Args[0].X+origX, seg.Args[0].Y+origY) case api.SegmentOpLineTo: rast.LineTo(seg.Args[0].X+origX, seg.Args[0].Y+origY) case api.SegmentOpQuadTo: rast.QuadTo( seg.Args[0].X+origX, seg.Args[0].Y+origY, seg.Args[1].X+origX, seg.Args[1].Y+origY, ) case api.SegmentOpCubeTo: rast.CubeTo( seg.Args[0].X+origX, seg.Args[0].Y+origY, seg.Args[1].X+origX, seg.Args[1].Y+origY, seg.Args[2].X+origX, seg.Args[2].Y+origY, ) } } rast.ClosePath() rast.DrawOp = draw.Over rast.Draw(dst, dst.Bounds(), image.Opaque, image.Point{}) } func main() { flag.Parse() dst := image.NewRGBA(image.Rect(0, 0, 640, 480)) draw.Draw(dst, dst.Bounds(), image.Black, image.Point{}, draw.Src) text := "あgo-textあ\nあisあ\nあawesomeあ" for i, line := range strings.Split(text, "\n") { render(dst, 400-float32(i)*40, 100, line) } f, err := os.Create("output.png") if err != nil { panic(err) } defer f.Close() out := bufio.NewWriter(f) defer out.Flush() if err := png.Encode(out, dst); err != nil { panic(err) } }
module foo go 1.21.6 require ( github.com/go-text/typesetting v0.1.1-0.20231231232151-8d81c02dc157 golang.org/x/image v0.15.0 ) require golang.org/x/text v0.14.0 // indirect
The output is:
The baselines for "go-text", "is", and "awesome" are different for each line.
The expected result is what Chrome browser does:
<style> body { font-size: 32px; font-family: sans-serif; writing-mode: vertical-rl; } </style> <p>あgo-textあ<br> あisあ<br> あawersomeあ</p>
Thanks!
The text was updated successfully, but these errors were encountered:
No branches or pull requests
This is a remaining task from #124 (comment).
I used NotoSansJP-VF.otf from https://github.com/notofonts/noto-cjk/releases/tag/Sans2.004 ("All Variables OTF/OTC)".
The output is:
The baselines for "go-text", "is", and "awesome" are different for each line.
The expected result is what Chrome browser does:
Thanks!
The text was updated successfully, but these errors were encountered: