1
0
mirror of https://github.com/gdamore/tcell.git synced 2025-04-24 13:48:51 +08:00

fixes #50 Expose CanDisplay(rune)

This commit is contained in:
Garrett D'Amore 2015-10-14 19:46:35 -07:00
parent 5bef83acf3
commit 6939959660
5 changed files with 133 additions and 0 deletions

View File

@ -918,3 +918,10 @@ func (s *cScreen) RegisterRuneFallback(r rune, subst string) {
func (s *cScreen) UnregisterRuneFallback(r rune) {
}
func (s *cScreen) CanDisplay(r rune, checkFallbacks bool) bool {
// We presume we can display anything -- we're Unicode.
// (Sadly this not precisely true. Combinings are especially
// poorly supported under Windows.)
return true
}

66
runes_test.go Normal file
View File

@ -0,0 +1,66 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestCanDisplay(t *testing.T) {
Convey("With a UTF-8 screen", t,
WithScreen(t, "UTF-8", func(s SimulationScreen) {
So(s.CharacterSet(), ShouldEqual, "UTF-8")
So(s.CanDisplay('a', true), ShouldBeTrue)
So(s.CanDisplay(RuneHLine, true), ShouldBeTrue)
So(s.CanDisplay(RuneHLine, false), ShouldBeTrue)
So(s.CanDisplay('⌀', false), ShouldBeTrue)
}))
Convey("With an ASCII screen", t,
WithScreen(t, "US-ASCII", func(s SimulationScreen) {
So(s.CharacterSet(), ShouldEqual, "US-ASCII")
So(s.CanDisplay('a', true), ShouldBeTrue)
So(s.CanDisplay(RuneHLine, true), ShouldBeTrue)
So(s.CanDisplay(RunePi, false), ShouldBeFalse)
So(s.CanDisplay('⌀', false), ShouldBeFalse)
}))
}
func TestRegisterFallback(t *testing.T) {
Convey("With an ASCII screen", t,
WithScreen(t, "US-ASCII", func(s SimulationScreen) {
So(s.CharacterSet(), ShouldEqual, "US-ASCII")
s.RegisterRuneFallback('⌀', "o")
So(s.CanDisplay('⌀', false), ShouldBeFalse)
So(s.CanDisplay('⌀', true), ShouldBeTrue)
s.UnregisterRuneFallback('⌀')
So(s.CanDisplay('⌀', false), ShouldBeFalse)
So(s.CanDisplay('⌀', true), ShouldBeFalse)
}))
}
func TestUnregisterFallback(t *testing.T) {
Convey("With an ASCII screen (HLine)", t,
WithScreen(t, "US-ASCII", func(s SimulationScreen) {
So(s.CharacterSet(), ShouldEqual, "US-ASCII")
So(s.CanDisplay(RuneHLine, true), ShouldBeTrue)
s.UnregisterRuneFallback(RuneHLine)
So(s.CanDisplay(RuneHLine, true), ShouldBeFalse)
}))
}

View File

@ -146,6 +146,17 @@ type Screen interface {
// to "disable" the use of alternate characters that are supported
// by your terminal except by changing the terminal database.
UnregisterRuneFallback(r rune)
// CanDisplay returns true if the given rune can be displayed on
// this screen. Note that this is a best guess effort -- whether
// your fonts support the character or not may be questionable.
// Mostly this is for folks who work outside of Unicode.
//
// If checkFallbacks is true, then if any (possibly imperfect)
// fallbacks are registered, this will return true. This will
// also return true if the terminal can replace the glyph with
// one that is visually indistinguishable from the one requested.
CanDisplay(r rune, checkFallbacks bool) bool
}
// NewScreen returns a default Screen suitable for the user's terminal

View File

@ -497,3 +497,25 @@ func (s *simscreen) UnregisterRuneFallback(r rune) {
delete(s.fallback, r)
s.Unlock()
}
func (s *simscreen) CanDisplay(r rune, checkFallbacks bool) bool {
if enc := s.encoder; enc != nil {
nb := make([]byte, 6)
ob := make([]byte, 6)
num := utf8.EncodeRune(ob, r)
enc.Reset()
dst, _, err := enc.Transform(nb, ob[:num], true)
if dst != 0 && err == nil && nb[0] != '\x1A' {
return true
}
}
if !checkFallbacks {
return false
}
if _, ok := s.fallback[r]; ok {
return true
}
return false
}

View File

@ -1033,3 +1033,30 @@ func (t *tScreen) UnregisterRuneFallback(orig rune) {
delete(t.fallback, orig)
t.Unlock()
}
func (t *tScreen) CanDisplay(r rune, checkFallbacks bool) bool {
if enc := t.encoder; enc != nil {
nb := make([]byte, 6)
ob := make([]byte, 6)
num := utf8.EncodeRune(ob, r)
enc.Reset()
dst, _, err := enc.Transform(nb, ob[:num], true)
if dst != 0 && err == nil && nb[0] != '\x1A' {
return true
}
}
// Terminal fallbacks always permitted, since we assume they are
// basically nearly perfect renditions.
if _, ok := t.acs[r]; ok {
return true
}
if !checkFallbacks {
return false
}
if _, ok := t.fallback[r]; ok {
return true
}
return false
}