golang/go

x/image/font: rendering texts in Arabic

Open

#27,281 opened on Aug 27, 2018

View on GitHub
 (13 comments) (3 reactions) (0 assignees)Go (19,008 forks)batch import
FeatureRequestNeedsInvestigationhelp wanted

Repository metrics

Stars
 (133,883 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

What version of Go are you using (go version)?

go version go1.11 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/hajimehoshi/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/hajimehoshi/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/hajimehoshi/fonttest/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/b7/w11sqqrx7kx6fqfbn24wdsmh0000gn/T/go-build758210799=/tmp/go-build -gno-record-gcc-switches -fno-common"       

What did you do?

I tested to render a text in Arabic language:

package main

import (
        "flag"
        "image"
        "image/color"
        "image/draw"
        "image/png"
        "io/ioutil"
        "os"
        "strings"

        "github.com/golang/freetype/truetype"
        "github.com/pkg/browser"
        "golang.org/x/image/font"
        "golang.org/x/image/math/fixed"
)

const (
        // https://www.unicode.org/udhr/                                                                                                                                                                                                      
        text = "قوقحلاو ةماركلا يف نيواستم ارًارحأ سانلا عيمج دلوي."
)

func run() error {
        const (
                ox = 16
                oy = 16
        )

        width := 640
        height := 16*len(strings.Split(strings.TrimSpace(text), "\n")) + 8

        dst := image.NewRGBA(image.Rect(0, 0, width, height))
        draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.ZP, draw.Src)

        // I tested an arg "/Library/Fonts/Al Nile.ttc" on macOS.                                                                                                                                                                             
        f, err := ioutil.ReadFile(os.Args[1])
        if err != nil {
                return err
        }

        tt, err := truetype.Parse(f)
        if err != nil {
                return err
        }

        face := truetype.NewFace(tt, &truetype.Options{
                Size:    16,
                DPI:     72,
                Hinting: font.HintingFull,
        })

        d := font.Drawer{
                Dst:  dst,
                Src:  image.NewUniform(color.Black),
                Face: face,
                Dot:  fixed.P(ox, oy),
        }

        for _, l := range strings.Split(text, "\n") {
                d.DrawString(l)
                d.Dot.X = fixed.I(ox)
                d.Dot.Y += face.Metrics().Height
        }

        path := "example.png"
        fout, err := os.Create(path)
        if err != nil {
                return err
        }
        defer fout.Close()

        if err := png.Encode(fout, d.Dst); err != nil {
                return err
        }

        if err := browser.OpenFile(path); err != nil {
                return err
        }
        return nil
}

func main() {
        flag.Parse()
        if err := run(); err != nil {
                panic(err)
        }
}

What did you expect to see?

The text is rendered correctly in an image.

What did you see instead?

The text is rendered wrongly:

example

I was also wondering how to render texts in complex languages like Thai or Hindi.

Contributor guide