github.com/jmigpin/editor@v1.6.0/util/fontutil/facerunes.go (about)

     1  package fontutil
     2  
     3  import (
     4  	"image"
     5  
     6  	"golang.org/x/image/font"
     7  	"golang.org/x/image/math/fixed"
     8  )
     9  
    10  var TabWidth = 8 // n times the space glyph
    11  var CarriageReturnRune = '♪'
    12  var NullRune = '◦'
    13  
    14  // Special runes face
    15  type FaceRunes struct {
    16  	font.Face
    17  }
    18  
    19  func NewFaceRunes(face font.Face) *FaceRunes {
    20  	return &FaceRunes{face}
    21  }
    22  
    23  func (fr *FaceRunes) Glyph(dot fixed.Point26_6, ru rune) (
    24  	dr image.Rectangle,
    25  	mask image.Image,
    26  	maskp image.Point,
    27  	advance fixed.Int26_6,
    28  	ok bool,
    29  ) {
    30  	ru2, adv, ok := fr.replace(ru)
    31  	if ok {
    32  		dr, mask, maskp, _, ok := fr.Face.Glyph(dot, ru2)
    33  		return dr, mask, maskp, adv, ok
    34  	}
    35  	return fr.Face.Glyph(dot, ru)
    36  }
    37  
    38  func (fr *FaceRunes) GlyphBounds(ru rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
    39  	ru2, adv, ok := fr.replace(ru)
    40  	if ok {
    41  		bounds, _, ok := fr.Face.GlyphBounds(ru2)
    42  		return bounds, adv, ok
    43  	}
    44  	return fr.Face.GlyphBounds(ru)
    45  }
    46  
    47  func (fr *FaceRunes) GlyphAdvance(ru rune) (advance fixed.Int26_6, ok bool) {
    48  	_, adv, ok := fr.replace(ru)
    49  	if ok {
    50  		return adv, ok
    51  	}
    52  	return fr.Face.GlyphAdvance(ru)
    53  }
    54  
    55  //----------
    56  
    57  func (fr *FaceRunes) replace(ru0 rune) (rune, fixed.Int26_6, bool) {
    58  	switch ru0 {
    59  	case '\t':
    60  		ru := ' '
    61  		adv, ok := fr.Face.GlyphAdvance(ru)
    62  		adv *= fixed.Int26_6(TabWidth)
    63  		return ru, adv, ok
    64  	case '\n':
    65  		ru := ' '
    66  		adv, ok := fr.Face.GlyphAdvance(ru)
    67  		adv /= 2
    68  		return ru, adv, ok
    69  	case '\r':
    70  		ru := CarriageReturnRune
    71  		adv, ok := fr.Face.GlyphAdvance(ru)
    72  		return ru, adv, ok
    73  	case 0:
    74  		ru := NullRune
    75  		adv, ok := fr.Face.GlyphAdvance(ru)
    76  		return ru, adv, ok
    77  	case -1: // -1=eof
    78  		ru := ' '
    79  		return ru, 0, true
    80  	}
    81  	return 0, 0, false
    82  }