font/plan9font: optimize the conversion to image.Alpha.
Also remove the dependency on the image/draw package. That package will give the right answer for arbitrary source images, including those of type plan9Image, but doing the conversion directly avoids bouncing uint8 or color.Alpha values through the general-purpose draw.Image, image.Image and color.Color interfaces. It is possible to optimize this even further, but this will do for now. benchmark old ns/op new ns/op delta BenchmarkParseSubfont-8 2298492 492443 -78.58% Change-Id: Iea9436bffa097a1ba0052dbabf21516bce8b61e0 Reviewed-on: https://go-review.googlesource.com/21693 Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
parent
7a320489ae
commit
22f1b5f81b
|
@ -13,7 +13,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"image/draw"
|
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -297,8 +296,18 @@ func ParseSubfont(data []byte, firstRune rune) (font.Face, error) {
|
||||||
if len(data) != 6*(n+1) {
|
if len(data) != 6*(n+1) {
|
||||||
return nil, errors.New("plan9font: invalid subfont: data length mismatch")
|
return nil, errors.New("plan9font: invalid subfont: data length mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert from plan9Image to image.Alpha, as the standard library's
|
||||||
|
// image/draw package works best when glyph masks are of that type.
|
||||||
img := image.NewAlpha(m.Bounds())
|
img := image.NewAlpha(m.Bounds())
|
||||||
draw.Draw(img, img.Bounds(), m, image.ZP, draw.Over)
|
for y := img.Rect.Min.Y; y < img.Rect.Max.Y; y++ {
|
||||||
|
i := img.PixOffset(img.Rect.Min.X, y)
|
||||||
|
for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
|
||||||
|
img.Pix[i] = m.at(x, y)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &subface{
|
return &subface{
|
||||||
firstRune: firstRune,
|
firstRune: firstRune,
|
||||||
n: n,
|
n: n,
|
||||||
|
@ -339,15 +348,21 @@ func (m *plan9Image) ColorModel() color.Model { return color.AlphaModel }
|
||||||
|
|
||||||
func (m *plan9Image) At(x, y int) color.Color {
|
func (m *plan9Image) At(x, y int) color.Color {
|
||||||
if (image.Point{x, y}).In(m.rect) {
|
if (image.Point{x, y}).In(m.rect) {
|
||||||
|
return color.Alpha{m.at(x, y)}
|
||||||
|
}
|
||||||
|
return color.Alpha{0x00}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *plan9Image) at(x, y int) uint8 {
|
||||||
b := m.pix[m.byteoffset(x, y)]
|
b := m.pix[m.byteoffset(x, y)]
|
||||||
switch m.depth {
|
switch m.depth {
|
||||||
case 1:
|
case 1:
|
||||||
// CGrey, 1.
|
// CGrey, 1.
|
||||||
mask := uint8(1 << uint8(7-x&7))
|
mask := uint8(1 << uint8(7-x&7))
|
||||||
if (b & mask) != 0 {
|
if (b & mask) != 0 {
|
||||||
return color.Alpha{0xff}
|
return 0xff
|
||||||
}
|
}
|
||||||
return color.Alpha{0x00}
|
return 0
|
||||||
case 2:
|
case 2:
|
||||||
// CGrey, 2.
|
// CGrey, 2.
|
||||||
shift := uint(x&3) << 1
|
shift := uint(x&3) << 1
|
||||||
|
@ -357,10 +372,9 @@ func (m *plan9Image) At(x, y int) color.Color {
|
||||||
// Replicate throughout.
|
// Replicate throughout.
|
||||||
y |= y >> 2
|
y |= y >> 2
|
||||||
y |= y >> 4
|
y |= y >> 4
|
||||||
return color.Alpha{y}
|
return y
|
||||||
}
|
}
|
||||||
}
|
return 0
|
||||||
return color.Alpha{0x00}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var compressed = []byte("compressed\n")
|
var compressed = []byte("compressed\n")
|
||||||
|
|
24
font/plan9font/plan9font_test.go
Normal file
24
font/plan9font/plan9font_test.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package plan9font
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkParseSubfont(b *testing.B) {
|
||||||
|
subfontData, err := ioutil.ReadFile(filepath.FromSlash("../testdata/fixed/7x13.0000"))
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := ParseSubfont(subfontData, 0); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user