Add stroke functionality
This commit is contained in:
parent
bcfeb16b74
commit
d70502db33
13 changed files with 53 additions and 29 deletions
2
README
2
README
|
@ -1,7 +1,7 @@
|
|||
The Freetype font rasterizer in the Go programming language.
|
||||
|
||||
To download and install from source:
|
||||
$ go get github.com/golang/freetype
|
||||
$ go get github.com/tdewolff/freetype
|
||||
|
||||
It is an incomplete port:
|
||||
* It only supports TrueType fonts, and not Type 1 fonts nor bitmap fonts.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -21,7 +21,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -24,7 +24,7 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/tdewolff/freetype/truetype"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -23,7 +23,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype"
|
||||
"github.com/tdewolff/freetype"
|
||||
"golang.org/x/image/font"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -26,7 +26,7 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/tdewolff/freetype/truetype"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -21,7 +21,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -27,7 +27,7 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// +build example
|
||||
//
|
||||
// This build tag means that "go install github.com/golang/freetype/..."
|
||||
// This build tag means that "go install github.com/tdewolff/freetype/..."
|
||||
// doesn't install this example program. Use "go run main.go" to run it or "go
|
||||
// install -tags=example" to install it.
|
||||
|
||||
|
@ -17,7 +17,7 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/tdewolff/freetype/truetype"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
// The freetype package provides a convenient API to draw text onto an image.
|
||||
// Use the freetype/raster and freetype/truetype packages for lower level
|
||||
// control over rasterization and TrueType parsing.
|
||||
package freetype // import "github.com/golang/freetype"
|
||||
package freetype // import "github.com/tdewolff/freetype"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
"image/draw"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"github.com/tdewolff/freetype/truetype"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// the Freetype "smooth" module, and the Anti-Grain Geometry library. A
|
||||
// description of the area/coverage algorithm is at
|
||||
// http://projects.tuxee.net/cl-vectors/section-the-cl-aa-algorithm
|
||||
package raster // import "github.com/golang/freetype/raster"
|
||||
package raster // import "github.com/tdewolff/freetype/raster"
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"image"
|
||||
"math"
|
||||
|
||||
"github.com/golang/freetype/raster"
|
||||
"github.com/tdewolff/freetype/raster"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
@ -66,6 +66,8 @@ type Options struct {
|
|||
//
|
||||
// A zero value means to use 1 sub-pixel location.
|
||||
SubPixelsY int
|
||||
|
||||
Stroke int
|
||||
}
|
||||
|
||||
func (o *Options) size() float64 {
|
||||
|
@ -182,6 +184,7 @@ func NewFace(f *Font, opts *Options) font.Face {
|
|||
hinting: opts.hinting(),
|
||||
scale: fixed.Int26_6(0.5 + (opts.size() * opts.dpi() * 64 / 72)),
|
||||
glyphCache: make([]glyphCacheEntry, opts.glyphCacheEntries()),
|
||||
stroke: fixed.I(opts.Stroke * 2),
|
||||
}
|
||||
a.subPixelX, a.subPixelBiasX, a.subPixelMaskX = opts.subPixelsX()
|
||||
a.subPixelY, a.subPixelBiasY, a.subPixelMaskY = opts.subPixelsY()
|
||||
|
@ -207,6 +210,10 @@ func NewFace(f *Font, opts *Options) font.Face {
|
|||
a.r.SetBounds(a.maxw, a.maxh)
|
||||
a.p = facePainter{a}
|
||||
|
||||
if a.stroke != 0 {
|
||||
a.r.UseNonZeroWinding = true
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
|
@ -220,6 +227,7 @@ type face struct {
|
|||
subPixelY uint32
|
||||
subPixelBiasY fixed.Int26_6
|
||||
subPixelMaskY fixed.Int26_6
|
||||
stroke fixed.Int26_6
|
||||
masks *image.Alpha
|
||||
glyphCache []glyphCacheEntry
|
||||
r raster.Rasterizer
|
||||
|
@ -329,6 +337,10 @@ func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.In
|
|||
if xmin > xmax || ymin > ymax {
|
||||
return fixed.Rectangle26_6{}, 0, false
|
||||
}
|
||||
xmin -= a.stroke
|
||||
ymin -= a.stroke
|
||||
xmax += a.stroke
|
||||
ymax += a.stroke
|
||||
return fixed.Rectangle26_6{
|
||||
Min: fixed.Point26_6{
|
||||
X: xmin,
|
||||
|
@ -364,6 +376,10 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (v glyphCacheVal, ok
|
|||
if xmin > xmax || ymin > ymax {
|
||||
return glyphCacheVal{}, false
|
||||
}
|
||||
xmin -= int(a.stroke) >> 6
|
||||
ymin -= int(a.stroke) >> 6
|
||||
xmax += int(a.stroke) >> 6
|
||||
ymax += int(a.stroke) >> 6
|
||||
// A TrueType's glyph's nodes can have negative co-ordinates, but the
|
||||
// rasterizer clips anything left of x=0 or above y=0. xmin and ymin are
|
||||
// the pixel offsets, based on the font's FUnit metrics, that let a
|
||||
|
@ -434,7 +450,8 @@ func (a *face) drawContour(ps []Point, dx, dy fixed.Int26_6) {
|
|||
others = ps
|
||||
}
|
||||
}
|
||||
a.r.Start(start)
|
||||
path := raster.Path{}
|
||||
path.Start(start)
|
||||
q0, on0 := start, true
|
||||
for _, p := range others {
|
||||
q := fixed.Point26_6{
|
||||
|
@ -444,9 +461,9 @@ func (a *face) drawContour(ps []Point, dx, dy fixed.Int26_6) {
|
|||
on := p.Flags&0x01 != 0
|
||||
if on {
|
||||
if on0 {
|
||||
a.r.Add1(q)
|
||||
path.Add1(q)
|
||||
} else {
|
||||
a.r.Add2(q0, q)
|
||||
path.Add2(q0, q)
|
||||
}
|
||||
} else {
|
||||
if on0 {
|
||||
|
@ -456,16 +473,23 @@ func (a *face) drawContour(ps []Point, dx, dy fixed.Int26_6) {
|
|||
X: (q0.X + q.X) / 2,
|
||||
Y: (q0.Y + q.Y) / 2,
|
||||
}
|
||||
a.r.Add2(q0, mid)
|
||||
path.Add2(q0, mid)
|
||||
}
|
||||
}
|
||||
q0, on0 = q, on
|
||||
}
|
||||
// Close the curve.
|
||||
if on0 {
|
||||
a.r.Add1(start)
|
||||
path.Add1(start)
|
||||
} else {
|
||||
a.r.Add2(q0, start)
|
||||
path.Add2(q0, start)
|
||||
}
|
||||
|
||||
if a.stroke == 0 {
|
||||
a.r.AddPath(path)
|
||||
} else {
|
||||
path.Add1(start)
|
||||
a.r.AddStroke(path, a.stroke, raster.RoundCapper, raster.RoundJoiner)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
//
|
||||
// To measure a TrueType font in ideal FUnit space, use scale equal to
|
||||
// font.FUnitsPerEm().
|
||||
package truetype // import "github.com/golang/freetype/truetype"
|
||||
package truetype // import "github.com/tdewolff/freetype/truetype"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
Loading…
Reference in a new issue