github.com/signintech/pdft@v0.5.0/minigopdf/fontmaker/core/ttfparser_kern.go (about)

     1  package core
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  )
     7  
     8  // Parsekern parse kerning table  https://www.microsoft.com/typography/otspec/kern.htm
     9  func (t *TTFParser) Parsekern(fd *bytes.Reader) error {
    10  
    11  	t.kern = nil //clear
    12  	err := t.Seek(fd, "kern")
    13  	if err == ErrTableNotFound {
    14  		return nil
    15  	} else if err != nil {
    16  		return err
    17  	}
    18  
    19  	t.kern = new(KernTable) //init
    20  
    21  	version, err := t.ReadUShort(fd)
    22  	if err != nil {
    23  		return err
    24  	}
    25  	t.kern.Version = version
    26  
    27  	nTables, err := t.ReadUShort(fd)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	t.kern.NTables = nTables
    32  
    33  	i := uint(0)
    34  	for i < nTables {
    35  		err = t.parsekernSubTable(fd)
    36  		if err != nil {
    37  			return err
    38  		}
    39  		i++
    40  	}
    41  
    42  	return nil
    43  }
    44  
    45  func (t *TTFParser) parsekernSubTable(fd *bytes.Reader) error {
    46  
    47  	t.Skip(fd, 2+2) //skip version and length
    48  
    49  	coverage, err := t.ReadUShort(fd)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	format := coverage & 0xf0
    55  	//fmt.Printf("format = %d\n", format) //debug
    56  	t.kern.Kerning = make(KernMap) //init
    57  	if format == 0 {
    58  		t.parsekernSubTableFormat0(fd)
    59  	} else {
    60  		//not support other format yet
    61  		return fmt.Errorf("not support kerning format %d", format)
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  func (t *TTFParser) parsekernSubTableFormat0(fd *bytes.Reader) error {
    68  	nPairs, err := t.ReadUShort(fd)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	t.Skip(fd, 2+2+2) //skip searchRange , entrySelector , rangeShift
    73  
    74  	i := uint(0)
    75  	for i < nPairs {
    76  		left, err := t.ReadUShort(fd)
    77  		if err != nil {
    78  			return err
    79  		}
    80  
    81  		right, err := t.ReadUShort(fd)
    82  		if err != nil {
    83  			return err
    84  		}
    85  
    86  		value, err := t.ReadShortInt16(fd)
    87  		if err != nil {
    88  			return err
    89  		}
    90  
    91  		if _, ok := t.kern.Kerning[left]; !ok {
    92  			kval := make(KernValue)
    93  			kval[right] = value
    94  			t.kern.Kerning[left] = kval
    95  		} else {
    96  			(t.kern.Kerning[left])[right] = value
    97  		}
    98  		//_ = fmt.Sprintf("nPairs %d left %d right %d value %d\n", nPairs, left, right, value) //debug
    99  		i++
   100  	}
   101  	return nil
   102  }