From e21dad5cc8329223c673056eb1b0493f4c245095 Mon Sep 17 00:00:00 2001 From: Randall O'Reilly Date: Thu, 16 Aug 2018 01:05:50 -0600 Subject: [PATCH 01/13] minor fixes to prevent crashing on linux and eliminate error msgs about kern tables --- freetype.go | 6 +++--- raster/raster.go | 2 +- truetype/face.go | 2 +- truetype/glyph.go | 3 +++ truetype/truetype.go | 13 ++++++++----- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/freetype.go b/freetype.go index 9603586..f0e678f 100644 --- a/freetype.go +++ b/freetype.go @@ -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 ( "errors" "image" "image/draw" - "github.com/golang/freetype/raster" - "github.com/golang/freetype/truetype" + "github.com/goki/freetype/raster" + "github.com/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/raster/raster.go b/raster/raster.go index 7e6cd4e..995925e 100644 --- a/raster/raster.go +++ b/raster/raster.go @@ -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 ( "strconv" diff --git a/truetype/face.go b/truetype/face.go index 099006f..20611fa 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -9,7 +9,7 @@ import ( "image" "math" - "github.com/golang/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/truetype/glyph.go b/truetype/glyph.go index 6157ad8..5bb236a 100644 --- a/truetype/glyph.go +++ b/truetype/glyph.go @@ -175,6 +175,9 @@ func (g *GlyphBuf) load(recursion uint32, i Index, useMyMetrics bool) (err error if recursion >= 32 { return UnsupportedError("excessive compound glyph recursion") } + if g.font.loca == nil { + return UnsupportedError("no glyph location data") + } // Find the relevant slice of g.font.glyf. var g0, g1 uint32 if g.font.locaOffsetFormat == locaOffsetFormatShort { diff --git a/truetype/truetype.go b/truetype/truetype.go index 7270bbf..703fee8 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -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 ( "fmt" @@ -312,9 +312,10 @@ func (f *Font) parseKern() error { // Since we expect that almost all fonts aim to be Windows-compatible, we only parse the "older" format, // just like the C Freetype implementation. if len(f.kern) == 0 { - if f.nKern != 0 { - return FormatError("bad kern table length") - } + // if f.nKern != 0 { + // return FormatError("bad kern table length") + // } + f.nKern = 0 // just reset and move on return nil } if len(f.kern) < 18 { @@ -346,7 +347,9 @@ func (f *Font) parseKern() error { } f.nKern, offset = int(u16(f.kern, offset)), offset+2 if 6*f.nKern != length-14 { - return FormatError("bad kern table length") + f.nKern = 0 + return nil + // return FormatError("bad kern table length") } return nil } From 7946394216f347739cfd0e45357bafc3a15bafbf Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Thu, 16 Aug 2018 23:41:02 -0600 Subject: [PATCH 02/13] add advanceCache map[rune] -- easy and major speedup; add reading of lineGap; fix Height computation to use ascent - descent + lineGap --- truetype/face.go | 14 +++++++++++++- truetype/truetype.go | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/truetype/face.go b/truetype/face.go index 20611fa..f8697d1 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -229,6 +229,7 @@ type face struct { maxh int glyphBuf GlyphBuf indexCache [indexCacheLen]indexCacheEntry + advanceCache map[rune]fixed.Int26_6 // TODO: clip rectangle? } @@ -255,9 +256,12 @@ func (a *face) Metrics() font.Metrics { scale := float64(a.scale) fupe := float64(a.f.FUnitsPerEm()) return font.Metrics{ - Height: a.scale, + Height: fixed.Int26_6(math.Ceil(scale * float64(a.f.ascent-a.f.descent+a.f.lineGap) / fupe)), Ascent: fixed.Int26_6(math.Ceil(scale * float64(+a.f.ascent) / fupe)), Descent: fixed.Int26_6(math.Ceil(scale * float64(-a.f.descent) / fupe)), + // TODO: Metrics should include LineGap as a separate measure + // TODO: Would also be great to include Ex as in the height of an "x" -- + // used widely for layout } } @@ -342,9 +346,17 @@ func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.In } func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) { + if a.advanceCache == nil { + a.advanceCache = make(map[rune]fixed.Int26_6, 1024) + } + advance, ok = a.advanceCache[r] + if ok { + return + } if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil { return 0, false } + a.advanceCache[r] = a.glyphBuf.AdvanceWidth return a.glyphBuf.AdvanceWidth, true } diff --git a/truetype/truetype.go b/truetype/truetype.go index 703fee8..2ae677a 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -187,6 +187,7 @@ type Font struct { fUnitsPerEm int32 ascent int32 // In FUnits. descent int32 // In FUnits; typically negative. + lineGap int32 // In FUnits. bounds fixed.Rectangle26_6 // In FUnits. // Values from the maxp section. maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16 @@ -294,6 +295,7 @@ func (f *Font) parseHhea() error { } f.ascent = int32(int16(u16(f.hhea, 4))) f.descent = int32(int16(u16(f.hhea, 6))) + f.lineGap = int32(int16(u16(f.hhea, 8))) f.nHMetric = int(u16(f.hhea, 34)) if 4*f.nHMetric+2*(f.nGlyph-f.nHMetric) != len(f.hmtx) { return FormatError(fmt.Sprintf("bad hmtx length: %d", len(f.hmtx))) @@ -323,7 +325,9 @@ func (f *Font) parseKern() error { } version, offset := u16(f.kern, 0), 2 if version != 0 { - return UnsupportedError(fmt.Sprintf("kern version: %d", version)) + f.nKern = 0 + return nil + // return UnsupportedError(fmt.Sprintf("kern version: %d", version)) } n, offset := u16(f.kern, offset), offset+2 From 7349a45553e7494381d3ba9c8afc7109a1830676 Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Fri, 17 Aug 2018 00:57:27 -0600 Subject: [PATCH 03/13] merged changes from tdewolff-master --- README | 2 +- example/capjoin/main.go | 4 ++-- example/drawer/main.go | 4 ++-- example/freetype/main.go | 4 ++-- example/gamma/main.go | 4 ++-- example/genbasicfont/main.go | 4 ++-- example/raster/main.go | 4 ++-- example/round/main.go | 4 ++-- example/truetype/main.go | 4 ++-- raster/stroke.go | 18 ++++++++++++----- truetype/face.go | 38 ++++++++++++++++++++++++++++++------ truetype/truetype.go | 1 + 12 files changed, 63 insertions(+), 28 deletions(-) diff --git a/README b/README index 39b3d82..a0d70bc 100644 --- a/README +++ b/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. diff --git a/example/capjoin/main.go b/example/capjoin/main.go index 71f3356..a349ee7 100644 --- a/example/capjoin/main.go +++ b/example/capjoin/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/drawer/main.go b/example/drawer/main.go index d26d066..cc78df0 100644 --- a/example/drawer/main.go +++ b/example/drawer/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/freetype/main.go b/example/freetype/main.go index dfbde9a..beb3022 100644 --- a/example/freetype/main.go +++ b/example/freetype/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype" "golang.org/x/image/font" ) diff --git a/example/gamma/main.go b/example/gamma/main.go index cdd50bc..71c73c8 100644 --- a/example/gamma/main.go +++ b/example/gamma/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/genbasicfont/main.go b/example/genbasicfont/main.go index 5b2f2bc..4d59c64 100644 --- a/example/genbasicfont/main.go +++ b/example/genbasicfont/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/raster/main.go b/example/raster/main.go index 3e572e1..e4f9f00 100644 --- a/example/raster/main.go +++ b/example/raster/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/round/main.go b/example/round/main.go index 2920e83..12b26f6 100644 --- a/example/round/main.go +++ b/example/round/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/truetype/main.go b/example/truetype/main.go index e7db2d0..b5c738d 100644 --- a/example/truetype/main.go +++ b/example/truetype/main.go @@ -5,7 +5,7 @@ // +build example // -// This build tag means that "go install github.com/golang/freetype/..." +// This build tag means that "go install ..." // 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/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/raster/stroke.go b/raster/stroke.go index bcc66b2..84a62f9 100644 --- a/raster/stroke.go +++ b/raster/stroke.go @@ -438,12 +438,20 @@ func (k *stroker) stroke(q Path) { if len(k.r) == 0 { return } - // TODO(nigeltao): if q is a closed curve then we should join the first and - // last segments instead of capping them. - k.cr.Cap(k.p, k.u, q.lastPoint(), pNeg(k.anorm)) + + closed := q.firstPoint() == q.lastPoint() + if !closed { + k.cr.Cap(k.p, k.u, q.lastPoint(), pNeg(k.anorm)) + } else { + pivot := q.firstPoint() + k.jr.Join(k.p, &k.r, k.u, pivot, k.anorm, pivot.Sub(fixed.Point26_6{k.r[1], k.r[2]})) + k.p.Start(fixed.Point26_6{k.r[len(k.r)-3], k.r[len(k.r)-2]}) // reverse path is now separate + } addPathReversed(k.p, k.r) - pivot := q.firstPoint() - k.cr.Cap(k.p, k.u, pivot, pivot.Sub(fixed.Point26_6{k.r[1], k.r[2]})) + if !closed { + pivot := q.firstPoint() + k.cr.Cap(k.p, k.u, pivot, pivot.Sub(fixed.Point26_6{k.r[1], k.r[2]})) + } } // Stroke adds q stroked with the given width to p. The result is typically diff --git a/truetype/face.go b/truetype/face.go index f8697d1..b6abe82 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -66,6 +66,11 @@ type Options struct { // // A zero value means to use 1 sub-pixel location. SubPixelsY int + + // Stroke is the number of pixels that the font glyphs are being stroked. + // + // A zero values means no stroke. + Stroke int } func (o *Options) size() float64 { @@ -182,6 +187,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 +213,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 +230,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 @@ -333,6 +344,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, @@ -376,6 +391,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 @@ -446,7 +465,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{ @@ -456,9 +476,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 { @@ -468,16 +488,22 @@ 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 { + path.Add2(q0, start) + } + + if a.stroke == 0 { + a.r.AddPath(path) } else { - a.r.Add2(q0, start) + a.r.AddStroke(path, a.stroke, raster.ButtCapper, raster.RoundJoiner) } } diff --git a/truetype/truetype.go b/truetype/truetype.go index 2ae677a..50320fa 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -15,6 +15,7 @@ // // To measure a TrueType font in ideal FUnit space, use scale equal to // font.FUnitsPerEm(). + package truetype import ( From 9c0c85f17044d7040cdabc372b3e2706ec9f631b Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Thu, 30 Aug 2018 17:02:03 -0600 Subject: [PATCH 04/13] guard on weird index access error in glyph.go:234 --- truetype/glyph.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/truetype/glyph.go b/truetype/glyph.go index 5bb236a..ceafd42 100644 --- a/truetype/glyph.go +++ b/truetype/glyph.go @@ -6,6 +6,8 @@ package truetype import ( + "fmt" + "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) @@ -231,7 +233,11 @@ func (g *GlyphBuf) load(recursion uint32, i Index, useMyMetrics bool) (err error np0, ne0 := len(g.Points), len(g.Ends) program := g.loadSimple(glyf, ne) g.addPhantomsAndScale(np0, np0, true, true) - pp1x = g.Points[len(g.Points)-4].X + idx := len(g.Points) - 4 + if idx < 0 { + return fmt.Errorf("points out of range error") + } + pp1x = g.Points[idx].X if g.hinting != font.HintingNone { if len(program) != 0 { err := g.hinter.run( From fa8a33aabaff00cee178fe14212e0a308a87ea5d Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Mon, 31 Dec 2018 03:13:11 -0700 Subject: [PATCH 05/13] adityaddy PR #67 on main golang branch --- testdata/luxisr-12pt-sans-hinting.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/luxisr-12pt-sans-hinting.txt b/testdata/luxisr-12pt-sans-hinting.txt index e276164..6509f94 100644 --- a/testdata/luxisr-12pt-sans-hinting.txt +++ b/testdata/luxisr-12pt-sans-hinting.txt @@ -5,7 +5,7 @@ freetype version 2.5.1 213 0 0 0 0; 213 70 0 144 555;70 0 1, 70 74 1, 144 74 1, 144 0 1, 79 148 1, 70 444 1, 70 555 1, 144 555 1, 144 444 1, 135 148 1 273 35 407 238 592;44 407 1, 35 592 1, 108 592 1, 99 407 1, 173 407 1, 164 592 1, 238 592 1, 229 407 1 -427 9 0 418 555;47 0 1, 89 167 1, 9 167 1, 18 213 1, 100 213 1, 133 342 1, 44 342 1, 54 389 1, 144 389 1, 186 555 1, 234 555 1, 192 389 1, 291 389 1, 332 555 1, 380 555 1, 339 389 1, 418 389 1, 409 342 1, 327 342 1, 294 213 1, 383 213 1, 374 167 1, 283 167 1, 242 0 1, 194 0 1, 235 167 1, 137 167 1, 95 0 1, 148 213 1, 247 213 1, 279 342 1, 180 342 1 +427 9 0 418 555;47 0 1, 89 167 1, 9 167 1, 18 213 1, 100 213 1, 133 342 1, 44 342 1, 54 389 1, 144 389 1, 186 555 10000, 234 555 1, 192 389 1, 291 389 1, 332 555 1, 380 555 1, 339 389 1, 418 389 1, 409 342 1, 327 342 1, 294 213 1, 383 213 1, 374 167 1, 283 167 1, 242 0 1, 194 0 1, 235 167 1, 137 167 1, 95 0 1, 148 213 1, 247 213 1, 279 342 1, 180 342 1 427 39 -46 353 602;187 -46 1, 187 0 1, 121 0 0, 39 31 1, 39 95 1, 123 56 0, 187 56 1, 187 255 1, 117 298 0, 88 330 1, 55 368 0, 55 422 1, 55 486 0, 103 524 1, 135 550 0, 187 555 1, 187 602 1, 224 602 1, 224 555 1, 278 555 0, 344 530 1, 344 470 1, 273 501 0, 224 504 1, 224 307 1, 228 304 1, 238 298 0, 247 293 1, 251 290 1, 299 262 0, 322 237 1, 353 205 0, 353 155 1, 353 87 0, 308 42 1, 276 12 0, 224 0 1, 224 -46 1, 224 60 1, 288 85 0, 288 144 1, 288 175 0, 270 195 1, 257 210 0, 224 233 1, 187 331 1, 187 502 1, 120 479 0, 120 425 1, 120 376 0 683 42 -14 641 569;94 -14 1, 531 569 1, 589 569 1, 152 -14 1, 161 555 1, 216 555 0, 248 518 1, 280 480 0, 280 416 1, 280 352 0, 248 315 1, 216 278 0, 161 278 1, 106 278 0, 74 315 1, 42 353 0, 42 418 1, 42 475 0, 68 511 1, 101 555 0, 161 518 1, 134 518 0, 117 491 1, 100 462 0, 100 419 1, 100 375 0, 114 348 1, 131 315 0, 161 315 1, 189 315 0, 206 343 1, 222 371 0, 222 416 1, 222 462 0, 206 490 1, 188 518 0, 522 278 1, 577 278 0, 609 240 1, 641 203 0, 641 139 1, 641 75 0, 609 38 1, 577 0 0, 522 0 1, 467 0 0, 435 38 1, 403 75 0, 403 141 1, 403 198 0, 429 233 1, 462 278 0, 522 241 1, 494 241 0, 477 213 1, 461 185 0, 461 141 1, 461 98 0, 474 71 1, 491 37 0, 522 37 1, 549 37 0, 566 65 1, 583 93 0, 583 139 1, 583 185 0, 566 213 1, 549 241 0 512 21 -14 485 569;384 0 1, 357 33 1, 282 -14 0, 214 -14 1, 132 -14 0, 77 37 1, 21 88 0, 21 166 1, 21 243 0, 69 290 1, 98 318 0, 152 339 1, 119 400 0, 119 445 1, 119 501 0, 153 535 1, 188 569 0, 247 569 1, 303 569 0, 336 539 1, 368 508 0, 368 457 1, 368 401 0, 325 360 1, 298 335 0, 248 312 1, 311 198 0, 373 123 1, 410 171 0, 410 265 1, 410 295 1, 483 295 1, 483 165 0, 408 83 1, 441 41 0, 485 0 1, 325 76 1, 251 160 0, 178 296 1, 141 279 0, 123 257 1, 95 225 0, 95 179 1, 95 122 0, 134 82 1, 172 42 0, 226 42 1, 268 42 0, 220 359 1, 256 374 0, 273 392 1, 299 419 0, 299 456 1, 299 513 0, 246 513 1, 191 513 0, 191 453 1, 191 416 0, 217 365 1 From 030bad7091e2a7205c2c0f6a833fb5da2daa9d5d Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 18 Jan 2022 16:01:26 -0800 Subject: [PATCH 06/13] Support getting the glyph details at a specific Index --- truetype/face.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/truetype/face.go b/truetype/face.go index b6abe82..53e580b 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -180,8 +180,24 @@ type indexCacheEntry struct { index Index } +type IndexableFace interface { + font.Face + + // GlyphAtIndex returns the draw.DrawMask parameters (dr, mask, maskp) to draw the + // glyph identified by gid at the sub-pixel destination location dot, and that glyph's + // advance width. + // + // It returns !ok if the face does not contain a glyph for r. + // + // The contents of the mask image returned by one Glyph call may change + // after the next Glyph call. Callers that want to cache the mask must make + // a copy. + GlyphAtIndex(dot fixed.Point26_6, gid Index) ( + dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) +} + // NewFace returns a new font.Face for the given Font. -func NewFace(f *Font, opts *Options) font.Face { +func NewFace(f *Font, opts *Options) IndexableFace { a := &face{ f: f, hinting: opts.hinting(), @@ -291,6 +307,13 @@ func (a *face) Kern(r0, r1 rune) fixed.Int26_6 { func (a *face) Glyph(dot fixed.Point26_6, r rune) ( dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) { + return a.GlyphAtIndex(dot, a.index(r)) +} + +// GlyphAtIndex satisfies the IndexableFace interface. +func (a *face) GlyphAtIndex(dot fixed.Point26_6, index Index) ( + dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) { + // Quantize to the sub-pixel granularity. dotX := (dot.X + a.subPixelBiasX) & a.subPixelMaskX dotY := (dot.Y + a.subPixelBiasY) & a.subPixelMaskY @@ -299,7 +322,6 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) ( ix, fx := int(dotX>>6), dotX&0x3f iy, fy := int(dotY>>6), dotY&0x3f - index := a.index(r) cIndex := uint32(index) cIndex = cIndex*a.subPixelX - uint32(fx/a.subPixelMaskX) cIndex = cIndex*a.subPixelY - uint32(fy/a.subPixelMaskY) From fad812166f95e04ff37112fe810eb95598a8aa5c Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Tue, 28 Mar 2023 16:36:10 -0700 Subject: [PATCH 07/13] apply PRs from golang/freetype: #70, #86; set UseNonZeroWinding = true in rasterizer; return !ok in GlyphAdvance if rune index == 0, consistent with opentype. --- CONTRIBUTORS | 2 ++ freetype.go | 8 +++++--- freetype_test.go | 25 +++++++++++++++++++++++++ truetype/face.go | 20 ++++++++++++-------- truetype/truetype.go | 28 +++++++++++++++++++--------- 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 7a1b0a2..0133ca3 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -27,10 +27,12 @@ # Please keep the list sorted. Andrew Gerrand +Dmitri Shuralyov Jeff R. Allen Maksim Kochkin Michael Fogleman Nigel Tao +Randall O'Reilly Rémy Oudompheng Rob Pike Roger Peppe diff --git a/freetype.go b/freetype.go index f0e678f..193eed0 100644 --- a/freetype.go +++ b/freetype.go @@ -78,7 +78,7 @@ type Context struct { // PointToFixed converts the given number of points (as in "a 12 point font") // into a 26.6 fixed point number of pixels. func (c *Context) PointToFixed(x float64) fixed.Int26_6 { - return fixed.Int26_6(x * float64(c.dpi) * (64.0 / 72.0)) + return fixed.Int26_6(0.5 + (x * c.dpi * 64 / 72)) } // drawContour draws the given closed contour with the given offset. @@ -260,7 +260,7 @@ func (c *Context) DrawString(s string, p fixed.Point26_6) (fixed.Point26_6, erro // recalc recalculates scale and bounds values from the font size, screen // resolution and font metrics, and invalidates the glyph cache. func (c *Context) recalc() { - c.scale = fixed.Int26_6(c.fontSize * c.dpi * (64.0 / 72.0)) + c.scale = fixed.Int26_6(0.5 + (c.fontSize * c.dpi * 64 / 72)) if c.f == nil { c.r.SetBounds(0, 0) } else { @@ -332,10 +332,12 @@ func (c *Context) SetClip(clip image.Rectangle) { // NewContext creates a new Context. func NewContext() *Context { - return &Context{ + c := &Context{ r: raster.NewRasterizer(0, 0), fontSize: 12, dpi: 72, scale: 12 << 6, } + c.r.UseNonZeroWinding = true // needed for font rendering + return c } diff --git a/freetype_test.go b/freetype_test.go index 348c411..24c8b51 100644 --- a/freetype_test.go +++ b/freetype_test.go @@ -12,6 +12,8 @@ import ( "runtime" "strings" "testing" + + "golang.org/x/image/math/fixed" ) func BenchmarkDrawString(b *testing.B) { @@ -57,3 +59,26 @@ func BenchmarkDrawString(b *testing.B) { mallocs = ms.Mallocs - mallocs b.Logf("%d iterations, %d mallocs per iteration\n", b.N, int(mallocs)/b.N) } + +func TestScaling(t *testing.T) { + c := NewContext() + for _, tc := range [...]struct { + in float64 + want fixed.Int26_6 + }{ + {in: 12, want: fixed.I(12)}, + {in: 11.992, want: fixed.I(12) - 1}, + {in: 11.993, want: fixed.I(12)}, + {in: 12.007, want: fixed.I(12)}, + {in: 12.008, want: fixed.I(12) + 1}, + {in: 86.4, want: fixed.Int26_6(86<<6 + 26)}, // Issue https://github.com/golang/freetype/issues/85. + } { + c.SetFontSize(tc.in) + if got, want := c.scale, tc.want; got != want { + t.Errorf("scale after SetFontSize(%v) = %v, want %v", tc.in, got, want) + } + if got, want := c.PointToFixed(tc.in), tc.want; got != want { + t.Errorf("PointToFixed(%v) = %v, want %v", tc.in, got, want) + } + } +} diff --git a/truetype/face.go b/truetype/face.go index 53e580b..cd243ae 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -139,11 +139,12 @@ func (o *Options) subPixelsY() (value uint32, halfQuantum, mask fixed.Int26_6) { // // For example, q == 4 leads to a bias of 8 and a mask of 0xfffffff0, or -16, // because we want to round fractions of fixed.Int26_6 as: -// - 0 to 7 rounds to 0. -// - 8 to 23 rounds to 16. -// - 24 to 39 rounds to 32. -// - 40 to 55 rounds to 48. -// - 56 to 63 rounds to 64. +// - 0 to 7 rounds to 0. +// - 8 to 23 rounds to 16. +// - 24 to 39 rounds to 32. +// - 40 to 55 rounds to 48. +// - 56 to 63 rounds to 64. +// // which means to add 8 and then bitwise-and with -16, in two's complement // representation. // @@ -205,6 +206,7 @@ func NewFace(f *Font, opts *Options) IndexableFace { glyphCache: make([]glyphCacheEntry, opts.glyphCacheEntries()), stroke: fixed.I(opts.Stroke * 2), } + a.r.UseNonZeroWinding = true // key for fonts a.subPixelX, a.subPixelBiasX, a.subPixelMaskX = opts.subPixelsX() a.subPixelY, a.subPixelBiasY, a.subPixelMaskY = opts.subPixelsY() @@ -388,13 +390,15 @@ func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) { } advance, ok = a.advanceCache[r] if ok { - return + idx := a.index(r) + return advance, (idx != 0) } - if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil { + idx := a.index(r) + if err := a.glyphBuf.Load(a.f, a.scale, idx, a.hinting); err != nil { return 0, false } a.advanceCache[r] = a.glyphBuf.AdvanceWidth - return a.glyphBuf.AdvanceWidth, true + return a.glyphBuf.AdvanceWidth, (idx != 0) } // rasterize returns the advance width, integer-pixel offset to render at, and diff --git a/truetype/truetype.go b/truetype/truetype.go index 50320fa..0d39514 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -19,7 +19,10 @@ package truetype import ( + "bytes" "fmt" + "unicode/utf16" + "unicode/utf8" "golang.org/x/image/math/fixed" ) @@ -429,20 +432,27 @@ func (f *Font) Name(id NameID) string { // Return the ASCII value of the encoded string. // The string is encoded as UTF-16 on non-Apple platformIDs; Apple is platformID 1. src := f.name[offset : offset+length] - var dst []byte if platformID != 1 { // UTF-16. if len(src)&1 != 0 { return "" } - dst = make([]byte, len(src)/2) - for i := range dst { - dst[i] = printable(u16(src, 2*i)) - } - } else { // ASCII. - dst = make([]byte, len(src)) - for i, c := range src { - dst[i] = printable(uint16(c)) + lb := len(src) / 2 + b8buf := make([]byte, 4) + u16s := make([]uint16, 1) + var buf bytes.Buffer + for i := 0; i < lb; i++ { + u16s[0] = u16(src, i) + r := utf16.Decode(u16s) + n := utf8.EncodeRune(b8buf, r[0]) + buf.Write([]byte(string(b8buf[:n]))) } + return buf.String() + } + // ASCII. + var dst []byte + dst = make([]byte, len(src)) + for i, c := range src { + dst[i] = printable(uint16(c)) } return string(dst) } From 8d06c8a34d05058795a412b415d9f99bfbf2c30b Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Tue, 28 Mar 2023 21:13:56 -0700 Subject: [PATCH 08/13] applied golang/freetype #88 --- truetype/truetype.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/truetype/truetype.go b/truetype/truetype.go index 0d39514..8892e3b 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -137,7 +137,7 @@ func parseSubtables(table []byte, name string, offset, size int, pred func([]byt if len(table) < size*nSubtables+offset { return 0, 0, FormatError(name + " too short") } - ok := false + bestScore := -1 for i := 0; i < nSubtables; i, offset = i+1, offset+size { if pred != nil && !pred(table[offset:]) { continue @@ -147,19 +147,24 @@ func parseSubtables(table []byte, name string, offset, size int, pred func([]byt pidPsid := u32(table, offset) // We prefer the Unicode cmap encoding. Failing to find that, we fall // back onto the Microsoft cmap encoding. + // And we prefer full/UCS4 encoding over BMP/UCS2. So the priority goes: + // unicodeEncodingFull > microsoftUCS4Encoding > unicodeEncodingBMPOnly > microsoftUCS2Encoding > microsoftSymbolEncoding + // It is in accord with the Psid part. + score := int(pidPsid & 0xFFFF) + if score <= bestScore { + continue + } if pidPsid == unicodeEncodingBMPOnly || pidPsid == unicodeEncodingFull { - bestOffset, bestPID, ok = offset, pidPsid>>16, true + bestOffset, bestPID, bestScore = offset, pidPsid>>16, score break } else if pidPsid == microsoftSymbolEncoding || pidPsid == microsoftUCS2Encoding || pidPsid == microsoftUCS4Encoding { - - bestOffset, bestPID, ok = offset, pidPsid>>16, true - // We don't break out of the for loop, so that Unicode can override Microsoft. + bestOffset, bestPID, bestScore = offset, pidPsid>>16, score } } - if !ok { + if bestScore < 0 { return 0, 0, UnsupportedError(name + " encoding") } return bestOffset, bestPID, nil From 4e73317ab185ee91275c2ecb2fd2b446b7b38a92 Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Tue, 28 Mar 2023 21:21:03 -0700 Subject: [PATCH 09/13] add go.mod, Makefile for updating version --- Makefile | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 ++++ go.sum | 33 +++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 Makefile create mode 100644 go.mod create mode 100644 go.sum diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..46b9c67 --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +# Basic Go makefile + +GOCMD=go +GOBUILD=$(GOCMD) build +GOCLEAN=$(GOCMD) clean +GOTEST=$(GOCMD) test +GOGET=$(GOCMD) get + +DIRS=`go list ./...` + +all: build + +build: + @echo "GO111MODULE = $(value GO111MODULE)" + $(GOBUILD) -v $(DIRS) + +test: + @echo "GO111MODULE = $(value GO111MODULE)" + $(GOTEST) -v $(DIRS) + +clean: + @echo "GO111MODULE = $(value GO111MODULE)" + $(GOCLEAN) ./... + +fmts: + gofmt -s -w . + +vet: + @echo "GO111MODULE = $(value GO111MODULE)" + $(GOCMD) vet $(DIRS) | grep -v unkeyed + +tidy: export GO111MODULE = on +tidy: + @echo "GO111MODULE = $(value GO111MODULE)" + go mod tidy + +mod-update: export GO111MODULE = on +mod-update: + @echo "GO111MODULE = $(value GO111MODULE)" + go get -u ./... + go mod tidy + +# gopath-update is for GOPATH to get most things updated. +# need to call it in a target executable directory +gopath-update: export GO111MODULE = off +gopath-update: + @echo "GO111MODULE = $(value GO111MODULE)" + go get -u ./... + +# NOTE: MUST update version number here prior to running 'make release' and edit this file! +VERS=v1.0.0 +PACKAGE=freetype +GIT_COMMIT=`git rev-parse --short HEAD` +VERS_DATE=`date -u +%Y-%m-%d\ %H:%M` +VERS_FILE=version.go + +release: + /bin/rm -f $(VERS_FILE) + @echo "// WARNING: auto-generated by Makefile release target -- run 'make release' to update" > $(VERS_FILE) + @echo "" >> $(VERS_FILE) + @echo "package $(PACKAGE)" >> $(VERS_FILE) + @echo "" >> $(VERS_FILE) + @echo "const (" >> $(VERS_FILE) + @echo " Version = \"$(VERS)\"" >> $(VERS_FILE) + @echo " GitCommit = \"$(GIT_COMMIT)\" // the commit JUST BEFORE the release" >> $(VERS_FILE) + @echo " VersionDate = \"$(VERS_DATE)\" // UTC" >> $(VERS_FILE) + @echo ")" >> $(VERS_FILE) + @echo "" >> $(VERS_FILE) + goimports -w $(VERS_FILE) + /bin/cat $(VERS_FILE) + git commit -am "$(VERS) release" + git tag -a $(VERS) -m "$(VERS) release" + git push + git push origin --tags + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e131112 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/goki/freetype + +go 1.18 + +require golang.org/x/image v0.6.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..64dc9f5 --- /dev/null +++ b/go.sum @@ -0,0 +1,33 @@ +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= +golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 1e754d5ebc5cb1bb055d800dc588c3d6567e44b5 Mon Sep 17 00:00:00 2001 From: "Randall C. O'Reilly" Date: Tue, 28 Mar 2023 21:22:06 -0700 Subject: [PATCH 10/13] v1.0.1 release --- Makefile | 2 +- version.go | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 version.go diff --git a/Makefile b/Makefile index 46b9c67..e9dc81f 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ gopath-update: go get -u ./... # NOTE: MUST update version number here prior to running 'make release' and edit this file! -VERS=v1.0.0 +VERS=v1.0.1 PACKAGE=freetype GIT_COMMIT=`git rev-parse --short HEAD` VERS_DATE=`date -u +%Y-%m-%d\ %H:%M` diff --git a/version.go b/version.go new file mode 100644 index 0000000..9b45b04 --- /dev/null +++ b/version.go @@ -0,0 +1,9 @@ +// WARNING: auto-generated by Makefile release target -- run 'make release' to update + +package freetype + +const ( + Version = "v1.0.1" + GitCommit = "4e73317" // the commit JUST BEFORE the release + VersionDate = "2023-03-29 04:22" // UTC +) From 23e59fe467d6be0a6692b34d472e83efe683c4ce Mon Sep 17 00:00:00 2001 From: Kai O'Reilly Date: Sat, 5 Aug 2023 15:22:34 -0600 Subject: [PATCH 11/13] formatted code --- example/capjoin/main.go | 2 ++ example/drawer/main.go | 2 ++ example/freetype/main.go | 2 ++ example/gamma/main.go | 2 ++ example/genbasicfont/main.go | 2 ++ example/raster/main.go | 2 ++ example/round/main.go | 2 ++ example/truetype/main.go | 2 ++ truetype/hint.go | 2 ++ 9 files changed, 18 insertions(+) diff --git a/example/capjoin/main.go b/example/capjoin/main.go index a349ee7..4295215 100644 --- a/example/capjoin/main.go +++ b/example/capjoin/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/drawer/main.go b/example/drawer/main.go index cc78df0..4eda98f 100644 --- a/example/drawer/main.go +++ b/example/drawer/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/freetype/main.go b/example/freetype/main.go index beb3022..f609ad4 100644 --- a/example/freetype/main.go +++ b/example/freetype/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/gamma/main.go b/example/gamma/main.go index 71c73c8..bf1d28a 100644 --- a/example/gamma/main.go +++ b/example/gamma/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/genbasicfont/main.go b/example/genbasicfont/main.go index 4d59c64..d106e1f 100644 --- a/example/genbasicfont/main.go +++ b/example/genbasicfont/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/raster/main.go b/example/raster/main.go index e4f9f00..359ec39 100644 --- a/example/raster/main.go +++ b/example/raster/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/round/main.go b/example/round/main.go index 12b26f6..79468b0 100644 --- a/example/round/main.go +++ b/example/round/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/example/truetype/main.go b/example/truetype/main.go index b5c738d..75f9a9c 100644 --- a/example/truetype/main.go +++ b/example/truetype/main.go @@ -3,7 +3,9 @@ // FreeType License or the GNU General Public License version 2 (or // any later version), both of which can be found in the LICENSE file. +//go:build example // +build example + // // This build tag means that "go install ..." // doesn't install this example program. Use "go run main.go" to run it or "go diff --git a/truetype/hint.go b/truetype/hint.go index 13f785b..9fbf411 100644 --- a/truetype/hint.go +++ b/truetype/hint.go @@ -1677,11 +1677,13 @@ func fmul(x, y fixed.Int26_6) fixed.Int26_6 { } // dotProduct returns the dot product of [x, y] and q. It is almost the same as +// // px := int64(x) // py := int64(y) // qx := int64(q[0]) // qy := int64(q[1]) // return fixed.Int26_6((px*qx + py*qy + 1<<13) >> 14) +// // except that the computation is done with 32-bit integers to produce exactly // the same rounding behavior as C Freetype. func dotProduct(x, y fixed.Int26_6, q [2]f2dot14) fixed.Int26_6 { From 4d2d9181f366bcc166d8ba5f6c3383a626e16744 Mon Sep 17 00:00:00 2001 From: Kai O'Reilly Date: Sun, 27 Aug 2023 13:34:34 -0700 Subject: [PATCH 12/13] updated mod url --- example/capjoin/main.go | 2 +- example/drawer/main.go | 2 +- example/freetype/main.go | 2 +- example/gamma/main.go | 2 +- example/genbasicfont/main.go | 2 +- example/raster/main.go | 2 +- example/round/main.go | 2 +- example/truetype/main.go | 2 +- freetype.go | 4 ++-- go.mod | 2 +- truetype/face.go | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/capjoin/main.go b/example/capjoin/main.go index 4295215..41e2797 100644 --- a/example/capjoin/main.go +++ b/example/capjoin/main.go @@ -23,7 +23,7 @@ import ( "log" "os" - "github.com/goki/freetype/raster" + "goki.dev/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/drawer/main.go b/example/drawer/main.go index 4eda98f..c28d1c0 100644 --- a/example/drawer/main.go +++ b/example/drawer/main.go @@ -26,7 +26,7 @@ import ( "math" "os" - "github.com/goki/freetype/truetype" + "goki.dev/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/freetype/main.go b/example/freetype/main.go index f609ad4..1dd92dc 100644 --- a/example/freetype/main.go +++ b/example/freetype/main.go @@ -25,7 +25,7 @@ import ( "log" "os" - "github.com/goki/freetype" + "goki.dev/freetype" "golang.org/x/image/font" ) diff --git a/example/gamma/main.go b/example/gamma/main.go index bf1d28a..4f0675c 100644 --- a/example/gamma/main.go +++ b/example/gamma/main.go @@ -22,7 +22,7 @@ import ( "log" "os" - "github.com/goki/freetype/raster" + "goki.dev/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/genbasicfont/main.go b/example/genbasicfont/main.go index d106e1f..11c944b 100644 --- a/example/genbasicfont/main.go +++ b/example/genbasicfont/main.go @@ -28,7 +28,7 @@ import ( "strings" "unicode" - "github.com/goki/freetype/truetype" + "goki.dev/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/raster/main.go b/example/raster/main.go index 359ec39..68554d6 100644 --- a/example/raster/main.go +++ b/example/raster/main.go @@ -23,7 +23,7 @@ import ( "log" "os" - "github.com/goki/freetype/raster" + "goki.dev/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/round/main.go b/example/round/main.go index 79468b0..443765f 100644 --- a/example/round/main.go +++ b/example/round/main.go @@ -29,7 +29,7 @@ import ( "math" "os" - "github.com/goki/freetype/raster" + "goki.dev/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/truetype/main.go b/example/truetype/main.go index 75f9a9c..3bc1bd9 100644 --- a/example/truetype/main.go +++ b/example/truetype/main.go @@ -19,7 +19,7 @@ import ( "io/ioutil" "log" - "github.com/goki/freetype/truetype" + "goki.dev/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/freetype.go b/freetype.go index 193eed0..98b764c 100644 --- a/freetype.go +++ b/freetype.go @@ -13,8 +13,8 @@ import ( "image" "image/draw" - "github.com/goki/freetype/raster" - "github.com/goki/freetype/truetype" + "goki.dev/freetype/raster" + "goki.dev/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/go.mod b/go.mod index e131112..ca9a50a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/goki/freetype +module goki.dev/freetype go 1.18 diff --git a/truetype/face.go b/truetype/face.go index cd243ae..7b0b5bf 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -9,7 +9,7 @@ import ( "image" "math" - "github.com/goki/freetype/raster" + "goki.dev/freetype/raster" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) From f8c5926a521f802aaec54ab23d0a7e711d3d14df Mon Sep 17 00:00:00 2001 From: Kai O'Reilly Date: Sun, 27 Aug 2023 15:18:42 -0700 Subject: [PATCH 13/13] Revert "updated mod url" This reverts commit 4d2d9181f366bcc166d8ba5f6c3383a626e16744. --- example/capjoin/main.go | 2 +- example/drawer/main.go | 2 +- example/freetype/main.go | 2 +- example/gamma/main.go | 2 +- example/genbasicfont/main.go | 2 +- example/raster/main.go | 2 +- example/round/main.go | 2 +- example/truetype/main.go | 2 +- freetype.go | 4 ++-- go.mod | 2 +- truetype/face.go | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/capjoin/main.go b/example/capjoin/main.go index 41e2797..4295215 100644 --- a/example/capjoin/main.go +++ b/example/capjoin/main.go @@ -23,7 +23,7 @@ import ( "log" "os" - "goki.dev/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/drawer/main.go b/example/drawer/main.go index c28d1c0..4eda98f 100644 --- a/example/drawer/main.go +++ b/example/drawer/main.go @@ -26,7 +26,7 @@ import ( "math" "os" - "goki.dev/freetype/truetype" + "github.com/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/freetype/main.go b/example/freetype/main.go index 1dd92dc..f609ad4 100644 --- a/example/freetype/main.go +++ b/example/freetype/main.go @@ -25,7 +25,7 @@ import ( "log" "os" - "goki.dev/freetype" + "github.com/goki/freetype" "golang.org/x/image/font" ) diff --git a/example/gamma/main.go b/example/gamma/main.go index 4f0675c..bf1d28a 100644 --- a/example/gamma/main.go +++ b/example/gamma/main.go @@ -22,7 +22,7 @@ import ( "log" "os" - "goki.dev/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/genbasicfont/main.go b/example/genbasicfont/main.go index 11c944b..d106e1f 100644 --- a/example/genbasicfont/main.go +++ b/example/genbasicfont/main.go @@ -28,7 +28,7 @@ import ( "strings" "unicode" - "goki.dev/freetype/truetype" + "github.com/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/example/raster/main.go b/example/raster/main.go index 68554d6..359ec39 100644 --- a/example/raster/main.go +++ b/example/raster/main.go @@ -23,7 +23,7 @@ import ( "log" "os" - "goki.dev/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/round/main.go b/example/round/main.go index 443765f..79468b0 100644 --- a/example/round/main.go +++ b/example/round/main.go @@ -29,7 +29,7 @@ import ( "math" "os" - "goki.dev/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/math/fixed" ) diff --git a/example/truetype/main.go b/example/truetype/main.go index 3bc1bd9..75f9a9c 100644 --- a/example/truetype/main.go +++ b/example/truetype/main.go @@ -19,7 +19,7 @@ import ( "io/ioutil" "log" - "goki.dev/freetype/truetype" + "github.com/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/freetype.go b/freetype.go index 98b764c..193eed0 100644 --- a/freetype.go +++ b/freetype.go @@ -13,8 +13,8 @@ import ( "image" "image/draw" - "goki.dev/freetype/raster" - "goki.dev/freetype/truetype" + "github.com/goki/freetype/raster" + "github.com/goki/freetype/truetype" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) diff --git a/go.mod b/go.mod index ca9a50a..e131112 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module goki.dev/freetype +module github.com/goki/freetype go 1.18 diff --git a/truetype/face.go b/truetype/face.go index 7b0b5bf..cd243ae 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -9,7 +9,7 @@ import ( "image" "math" - "goki.dev/freetype/raster" + "github.com/goki/freetype/raster" "golang.org/x/image/font" "golang.org/x/image/math/fixed" )