diff --git a/freetype/truetype/truetype.go b/freetype/truetype/truetype.go index fda3689..60453cd 100644 --- a/freetype/truetype/truetype.go +++ b/freetype/truetype/truetype.go @@ -323,14 +323,17 @@ func (f *Font) FUnitsPerEm() int32 { // Index returns a Font's index for the given rune. func (f *Font) Index(x rune) Index { c := uint32(x) - n := len(f.cm) - // TODO: binary search. - for i := 0; i < n; i++ { - if f.cm[i].start <= c && c <= f.cm[i].end { - if f.cm[i].offset == 0 { - return Index(c + f.cm[i].delta) - } - offset := int(f.cm[i].offset) + 2*(i-n+int(c-f.cm[i].start)) + for i, j := 0, len(f.cm); i < j; { + h := i + (j-i)/2 + cm := &f.cm[h] + if c < cm.start { + j = h + } else if cm.end < c { + i = h + 1 + } else if cm.offset == 0 { + return Index(c + cm.delta) + } else { + offset := int(cm.offset) + 2*(h-len(f.cm)+int(c-cm.start)) return Index(u16(f.cmapIndexes, offset)) } } diff --git a/freetype/truetype/truetype_test.go b/freetype/truetype/truetype_test.go index c812b45..1853b13 100644 --- a/freetype/truetype/truetype_test.go +++ b/freetype/truetype/truetype_test.go @@ -177,7 +177,7 @@ func TestIndex(t *testing.T) { } for r, want := range wants { if got := font.Index(r); got != want { - t.Errorf("%s: Index(%q): got %d, want %d", name, r, got, want) + t.Errorf("%s: Index of %q, aka %U: got %d, want %d", name, r, r, got, want) } } }