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

     1  package core
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  )
     7  
     8  // ParseCmapFormat12 parse cmap table format 12 https://www.microsoft.com/typography/otspec/cmap.htm
     9  func (t *TTFParser) ParseCmapFormat12(fd *bytes.Reader) (bool, error) {
    10  
    11  	t.Seek(fd, "cmap")
    12  	t.Skip(fd, 2) //skip version
    13  	numTables, err := t.ReadUShort(fd)
    14  	if err != nil {
    15  		return false, err
    16  	}
    17  	var cEncodingSubtables []cmapFormat12EncodingSubtable
    18  	for i := 0; i < int(numTables); i++ {
    19  		platformID, err := t.ReadUShort(fd)
    20  		if err != nil {
    21  			return false, err
    22  		}
    23  		encodingID, err := t.ReadUShort(fd)
    24  		if err != nil {
    25  			return false, err
    26  		}
    27  		offset, err := t.ReadULong(fd)
    28  		if err != nil {
    29  			return false, err
    30  		}
    31  
    32  		var ce cmapFormat12EncodingSubtable
    33  		ce.platformID = platformID
    34  		ce.encodingID = encodingID
    35  		ce.offset = offset
    36  		cEncodingSubtables = append(cEncodingSubtables, ce)
    37  	}
    38  
    39  	isFound := false
    40  	offset := uint(0)
    41  	for _, ce := range cEncodingSubtables {
    42  		if ce.platformID == 3 && ce.encodingID == 10 {
    43  			offset = ce.offset
    44  			isFound = true
    45  			break
    46  		}
    47  	}
    48  
    49  	if !isFound {
    50  		return false, nil
    51  	}
    52  
    53  	_, err = fd.Seek(int64(t.tables["cmap"].Offset+offset), 0)
    54  	if err != nil {
    55  		return false, err
    56  	}
    57  
    58  	format, err := t.ReadUShort(fd)
    59  	if err != nil {
    60  		return false, err
    61  	}
    62  
    63  	if format != 12 {
    64  		return false, errors.New("format != 12")
    65  	}
    66  
    67  	reserved, err := t.ReadUShort(fd)
    68  	if err != nil {
    69  		return false, err
    70  	}
    71  
    72  	if reserved != 0 {
    73  		return false, errors.New("reserved != 0")
    74  	}
    75  
    76  	err = t.Skip(fd, 4) //skip length
    77  	if err != nil {
    78  		return false, err
    79  	}
    80  
    81  	err = t.Skip(fd, 4) //skip language
    82  	if err != nil {
    83  		return false, err
    84  	}
    85  
    86  	nGroups, err := t.ReadULong(fd)
    87  	if err != nil {
    88  		return false, err
    89  	}
    90  
    91  	g := uint(0)
    92  	for g < nGroups {
    93  		startCharCode, err := t.ReadULong(fd)
    94  		if err != nil {
    95  			return false, err
    96  		}
    97  
    98  		endCharCode, err := t.ReadULong(fd)
    99  		if err != nil {
   100  			return false, err
   101  		}
   102  
   103  		glyphID, err := t.ReadULong(fd)
   104  		if err != nil {
   105  			return false, err
   106  		}
   107  
   108  		var gTb CmapFormat12GroupingTable
   109  		gTb.StartCharCode = startCharCode
   110  		gTb.EndCharCode = endCharCode
   111  		gTb.GlyphID = glyphID
   112  		t.groupingTables = append(t.groupingTables, gTb)
   113  		g++
   114  	}
   115  
   116  	return true, nil
   117  }
   118  
   119  type cmapFormat12EncodingSubtable struct {
   120  	platformID uint
   121  	encodingID uint
   122  	offset     uint
   123  }
   124  
   125  type CmapFormat12GroupingTable struct {
   126  	StartCharCode, EndCharCode, GlyphID uint
   127  }