Portable Compiled Format (PCF) font: Go parsing library

Portable Compiled Format (PCF) font is a bitmap font format originating from X11 Window System. It matches BDF format (which is text-based) closely, but instead being binary and platform-independent (as opposed to previously used SNF binary format) due to introduced features to handle different endianness and bit order.

The overall composition of the format is straightforward: it's more or less classic directory of type-offset-size pointers, pointing to what PCF format calls "tables". Each table carries a certain piece of information related to the font (metadata properties, metrics, bitmaps, mapping of glyphs to characters, etc).

File extension

pcf

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.9

References

This page hosts a formal specification of Portable Compiled Format (PCF) font using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Go source code to parse Portable Compiled Format (PCF) font

pcf_font.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"bytes"
	"io"
)


/**
 * Portable Compiled Format (PCF) font is a bitmap font format
 * originating from X11 Window System. It matches BDF format (which is
 * text-based) closely, but instead being binary and
 * platform-independent (as opposed to previously used SNF binary
 * format) due to introduced features to handle different endianness
 * and bit order.
 * 
 * The overall composition of the format is straightforward: it's more
 * or less classic directory of type-offset-size pointers, pointing to
 * what PCF format calls "tables". Each table carries a certain
 * piece of information related to the font (metadata properties,
 * metrics, bitmaps, mapping of glyphs to characters, etc).
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html">Source</a>
 */

type PcfFont_Types int
const (
	PcfFont_Types__Properties PcfFont_Types = 1
	PcfFont_Types__Accelerators PcfFont_Types = 2
	PcfFont_Types__Metrics PcfFont_Types = 4
	PcfFont_Types__Bitmaps PcfFont_Types = 8
	PcfFont_Types__InkMetrics PcfFont_Types = 16
	PcfFont_Types__BdfEncodings PcfFont_Types = 32
	PcfFont_Types__Swidths PcfFont_Types = 64
	PcfFont_Types__GlyphNames PcfFont_Types = 128
	PcfFont_Types__BdfAccelerators PcfFont_Types = 256
)
var values_PcfFont_Types = map[PcfFont_Types]struct{}{1: {}, 2: {}, 4: {}, 8: {}, 16: {}, 32: {}, 64: {}, 128: {}, 256: {}}
func (v PcfFont_Types) isDefined() bool {
	_, ok := values_PcfFont_Types[v]
	return ok
}
type PcfFont struct {
	Magic []byte
	NumTables uint32
	Tables []*PcfFont_Table
	_io *kaitai.Stream
	_root *PcfFont
	_parent kaitai.Struct
}
func NewPcfFont() *PcfFont {
	return &PcfFont{
	}
}

func (this PcfFont) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont) Read(io *kaitai.Stream, parent kaitai.Struct, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp1 = tmp1
	this.Magic = tmp1
	if !(bytes.Equal(this.Magic, []uint8{1, 102, 99, 112})) {
		return kaitai.NewValidationNotEqualError([]uint8{1, 102, 99, 112}, this.Magic, this._io, "/seq/0")
	}
	tmp2, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumTables = uint32(tmp2)
	for i := 0; i < int(this.NumTables); i++ {
		_ = i
		tmp3 := NewPcfFont_Table()
		err = tmp3.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Tables = append(this.Tables, tmp3)
	}
	return err
}

/**
 * Table format specifier, always 4 bytes. Original implementation treats
 * it as always little-endian and makes liberal use of bitmasking to parse
 * various parts of it.
 * 
 * TODO: this format specification recognizes endianness and bit
 * order format bits, but it does not really takes any parsing
 * decisions based on them.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#file-header">Source</a>
 */
type PcfFont_Format struct {
	Padding1 uint64
	ScanUnitMask uint64
	IsMostSignificantBitFirst bool
	IsBigEndian bool
	GlyphPadMask uint64
	Format uint8
	Padding uint16
	_io *kaitai.Stream
	_root *PcfFont
	_parent kaitai.Struct
}
func NewPcfFont_Format() *PcfFont_Format {
	return &PcfFont_Format{
	}
}

func (this PcfFont_Format) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Format) Read(io *kaitai.Stream, parent kaitai.Struct, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp4, err := this._io.ReadBitsIntBe(2)
	if err != nil {
		return err
	}
	this.Padding1 = tmp4
	tmp5, err := this._io.ReadBitsIntBe(2)
	if err != nil {
		return err
	}
	this.ScanUnitMask = tmp5
	tmp6, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.IsMostSignificantBitFirst = tmp6 != 0
	tmp7, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.IsBigEndian = tmp7 != 0
	tmp8, err := this._io.ReadBitsIntBe(2)
	if err != nil {
		return err
	}
	this.GlyphPadMask = tmp8
	this._io.AlignToByte()
	tmp9, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Format = tmp9
	tmp10, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Padding = uint16(tmp10)
	return err
}

/**
 * If set, then all integers in the table are treated as big-endian
 */

/**
 * Table offers a offset + length pointer to a particular
 * table. "Type" of table references certain enum. Applications can
 * ignore enum values which they don't support.
 */
type PcfFont_Table struct {
	Type PcfFont_Types
	Format *PcfFont_Format
	LenBody uint32
	OfsBody uint32
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont
	_raw_body []byte
	_f_body bool
	body interface{}
}
func NewPcfFont_Table() *PcfFont_Table {
	return &PcfFont_Table{
	}
}

func (this PcfFont_Table) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table) Read(io *kaitai.Stream, parent *PcfFont, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp11, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.Type = PcfFont_Types(tmp11)
	tmp12 := NewPcfFont_Format()
	err = tmp12.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp12
	tmp13, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LenBody = uint32(tmp13)
	tmp14, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.OfsBody = uint32(tmp14)
	return err
}
func (this *PcfFont_Table) Body() (v interface{}, err error) {
	if (this._f_body) {
		return this.body, nil
	}
	this._f_body = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.OfsBody), io.SeekStart)
	if err != nil {
		return nil, err
	}
	switch (this.Type) {
	case PcfFont_Types__BdfEncodings:
		tmp15, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp15 = tmp15
		this._raw_body = tmp15
		_io__raw_body := kaitai.NewStream(bytes.NewReader(this._raw_body))
		tmp16 := NewPcfFont_Table_BdfEncodings()
		err = tmp16.Read(_io__raw_body, this, this._root)
		if err != nil {
			return nil, err
		}
		this.body = tmp16
	case PcfFont_Types__Bitmaps:
		tmp17, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp17 = tmp17
		this._raw_body = tmp17
		_io__raw_body := kaitai.NewStream(bytes.NewReader(this._raw_body))
		tmp18 := NewPcfFont_Table_Bitmaps()
		err = tmp18.Read(_io__raw_body, this, this._root)
		if err != nil {
			return nil, err
		}
		this.body = tmp18
	case PcfFont_Types__GlyphNames:
		tmp19, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp19 = tmp19
		this._raw_body = tmp19
		_io__raw_body := kaitai.NewStream(bytes.NewReader(this._raw_body))
		tmp20 := NewPcfFont_Table_GlyphNames()
		err = tmp20.Read(_io__raw_body, this, this._root)
		if err != nil {
			return nil, err
		}
		this.body = tmp20
	case PcfFont_Types__Properties:
		tmp21, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp21 = tmp21
		this._raw_body = tmp21
		_io__raw_body := kaitai.NewStream(bytes.NewReader(this._raw_body))
		tmp22 := NewPcfFont_Table_Properties()
		err = tmp22.Read(_io__raw_body, this, this._root)
		if err != nil {
			return nil, err
		}
		this.body = tmp22
	case PcfFont_Types__Swidths:
		tmp23, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp23 = tmp23
		this._raw_body = tmp23
		_io__raw_body := kaitai.NewStream(bytes.NewReader(this._raw_body))
		tmp24 := NewPcfFont_Table_Swidths()
		err = tmp24.Read(_io__raw_body, this, this._root)
		if err != nil {
			return nil, err
		}
		this.body = tmp24
	default:
		tmp25, err := this._io.ReadBytes(int(this.LenBody))
		if err != nil {
			return nil, err
		}
		tmp25 = tmp25
		this._raw_body = tmp25
	}
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.body, nil
}

/**
 * Table that allows mapping of character codes to glyphs present in the
 * font. Supports 1-byte and 2-byte character codes.
 * 
 * Note that this mapping is agnostic to character encoding itself - it
 * can represent ASCII, Unicode (ISO/IEC 10646), various single-byte
 * national encodings, etc. If application cares about it, normally
 * encoding will be specified in `properties` table, in the properties named
 * `CHARSET_REGISTRY` / `CHARSET_ENCODING`.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#the-encoding-table">Source</a>
 */
type PcfFont_Table_BdfEncodings struct {
	Format *PcfFont_Format
	MinCharOrByte2 uint16
	MaxCharOrByte2 uint16
	MinByte1 uint16
	MaxByte1 uint16
	DefaultChar uint16
	GlyphIndexes []uint16
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table
}
func NewPcfFont_Table_BdfEncodings() *PcfFont_Table_BdfEncodings {
	return &PcfFont_Table_BdfEncodings{
	}
}

func (this PcfFont_Table_BdfEncodings) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_BdfEncodings) Read(io *kaitai.Stream, parent *PcfFont_Table, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp26 := NewPcfFont_Format()
	err = tmp26.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp26
	tmp27, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.MinCharOrByte2 = uint16(tmp27)
	tmp28, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.MaxCharOrByte2 = uint16(tmp28)
	tmp29, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.MinByte1 = uint16(tmp29)
	tmp30, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.MaxByte1 = uint16(tmp30)
	tmp31, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.DefaultChar = uint16(tmp31)
	for i := 0; i < int(((this.MaxCharOrByte2 - this.MinCharOrByte2) + 1) * ((this.MaxByte1 - this.MinByte1) + 1)); i++ {
		_ = i
		tmp32, err := this._io.ReadU2le()
		if err != nil {
			return err
		}
		this.GlyphIndexes = append(this.GlyphIndexes, tmp32)
	}
	return err
}

/**
 * Table containing uncompressed glyph bitmaps.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#the-bitmap-table">Source</a>
 */
type PcfFont_Table_Bitmaps struct {
	Format *PcfFont_Format
	NumGlyphs uint32
	Offsets []uint32
	BitmapSizes []uint32
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table
}
func NewPcfFont_Table_Bitmaps() *PcfFont_Table_Bitmaps {
	return &PcfFont_Table_Bitmaps{
	}
}

func (this PcfFont_Table_Bitmaps) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_Bitmaps) Read(io *kaitai.Stream, parent *PcfFont_Table, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp33 := NewPcfFont_Format()
	err = tmp33.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp33
	tmp34, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumGlyphs = uint32(tmp34)
	for i := 0; i < int(this.NumGlyphs); i++ {
		_ = i
		tmp35, err := this._io.ReadU4le()
		if err != nil {
			return err
		}
		this.Offsets = append(this.Offsets, tmp35)
	}
	for i := 0; i < int(4); i++ {
		_ = i
		tmp36, err := this._io.ReadU4le()
		if err != nil {
			return err
		}
		this.BitmapSizes = append(this.BitmapSizes, tmp36)
	}
	return err
}

/**
 * Table containing character names for every glyph.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#the-glyph-names-table">Source</a>
 */
type PcfFont_Table_GlyphNames struct {
	Format *PcfFont_Format
	NumGlyphs uint32
	Names []*PcfFont_Table_GlyphNames_StringRef
	LenStrings uint32
	Strings *BytesWithIo
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table
	_raw_Strings []byte
}
func NewPcfFont_Table_GlyphNames() *PcfFont_Table_GlyphNames {
	return &PcfFont_Table_GlyphNames{
	}
}

func (this PcfFont_Table_GlyphNames) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_GlyphNames) Read(io *kaitai.Stream, parent *PcfFont_Table, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp37 := NewPcfFont_Format()
	err = tmp37.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp37
	tmp38, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumGlyphs = uint32(tmp38)
	for i := 0; i < int(this.NumGlyphs); i++ {
		_ = i
		tmp39 := NewPcfFont_Table_GlyphNames_StringRef()
		err = tmp39.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Names = append(this.Names, tmp39)
	}
	tmp40, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LenStrings = uint32(tmp40)
	tmp41, err := this._io.ReadBytes(int(this.LenStrings))
	if err != nil {
		return err
	}
	tmp41 = tmp41
	this._raw_Strings = tmp41
	_io__raw_Strings := kaitai.NewStream(bytes.NewReader(this._raw_Strings))
	tmp42 := NewBytesWithIo()
	err = tmp42.Read(_io__raw_Strings, nil, nil)
	if err != nil {
		return err
	}
	this.Strings = tmp42
	return err
}

/**
 * Glyph names are represented as string references in strings buffer.
 */

/**
 * Strings buffer which contains all glyph names.
 */
type PcfFont_Table_GlyphNames_StringRef struct {
	OfsString uint32
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table_GlyphNames
	_f_value bool
	value string
}
func NewPcfFont_Table_GlyphNames_StringRef() *PcfFont_Table_GlyphNames_StringRef {
	return &PcfFont_Table_GlyphNames_StringRef{
	}
}

func (this PcfFont_Table_GlyphNames_StringRef) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_GlyphNames_StringRef) Read(io *kaitai.Stream, parent *PcfFont_Table_GlyphNames, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp43, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.OfsString = uint32(tmp43)
	return err
}
func (this *PcfFont_Table_GlyphNames_StringRef) Value() (v string, err error) {
	if (this._f_value) {
		return this.value, nil
	}
	this._f_value = true
	thisIo := this._parent.Strings._io
	_pos, err := thisIo.Pos()
	if err != nil {
		return "", err
	}
	_, err = thisIo.Seek(int64(this.OfsString), io.SeekStart)
	if err != nil {
		return "", err
	}
	tmp44, err := thisIo.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return "", err
	}
	this.value = string(tmp44)
	_, err = thisIo.Seek(_pos, io.SeekStart)
	if err != nil {
		return "", err
	}
	return this.value, nil
}

/**
 * Array of properties (key-value pairs), used to convey different X11
 * settings of a font. Key is always an X font atom.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#properties-table">Source</a>
 */
type PcfFont_Table_Properties struct {
	Format *PcfFont_Format
	NumProps uint32
	Props []*PcfFont_Table_Properties_Prop
	Padding []byte
	LenStrings uint32
	Strings *BytesWithIo
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table
	_raw_Strings []byte
}
func NewPcfFont_Table_Properties() *PcfFont_Table_Properties {
	return &PcfFont_Table_Properties{
	}
}

func (this PcfFont_Table_Properties) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_Properties) Read(io *kaitai.Stream, parent *PcfFont_Table, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp45 := NewPcfFont_Format()
	err = tmp45.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp45
	tmp46, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumProps = uint32(tmp46)
	for i := 0; i < int(this.NumProps); i++ {
		_ = i
		tmp47 := NewPcfFont_Table_Properties_Prop()
		err = tmp47.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Props = append(this.Props, tmp47)
	}
	var tmp48 int8;
	if (this.NumProps & 3 == 0) {
		tmp48 = 0
	} else {
		tmp48 = 4 - this.NumProps & 3
	}
	tmp49, err := this._io.ReadBytes(int(tmp48))
	if err != nil {
		return err
	}
	tmp49 = tmp49
	this.Padding = tmp49
	tmp50, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LenStrings = uint32(tmp50)
	tmp51, err := this._io.ReadBytes(int(this.LenStrings))
	if err != nil {
		return err
	}
	tmp51 = tmp51
	this._raw_Strings = tmp51
	_io__raw_Strings := kaitai.NewStream(bytes.NewReader(this._raw_Strings))
	tmp52 := NewBytesWithIo()
	err = tmp52.Read(_io__raw_Strings, nil, nil)
	if err != nil {
		return err
	}
	this.Strings = tmp52
	return err
}

/**
 * Strings buffer. Never used directly, but instead is
 * addressed by offsets from the properties.
 */

/**
 * Property is a key-value pair, "key" being always a
 * string and "value" being either a string or a 32-bit
 * integer based on an additinal flag (`is_string`).
 * 
 * Simple offset-based mechanism is employed to keep this
 * type's sequence fixed-sized and thus have simple access
 * to property key/value by index.
 */
type PcfFont_Table_Properties_Prop struct {
	OfsName uint32
	IsString uint8
	ValueOrOfsValue uint32
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table_Properties
	_f_intValue bool
	intValue uint32
	_f_name bool
	name string
	_f_strValue bool
	strValue string
}
func NewPcfFont_Table_Properties_Prop() *PcfFont_Table_Properties_Prop {
	return &PcfFont_Table_Properties_Prop{
	}
}

func (this PcfFont_Table_Properties_Prop) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_Properties_Prop) Read(io *kaitai.Stream, parent *PcfFont_Table_Properties, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp53, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.OfsName = uint32(tmp53)
	tmp54, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.IsString = tmp54
	tmp55, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.ValueOrOfsValue = uint32(tmp55)
	return err
}

/**
 * Value of the property, if this is an integer value.
 */
func (this *PcfFont_Table_Properties_Prop) IntValue() (v uint32, err error) {
	if (this._f_intValue) {
		return this.intValue, nil
	}
	this._f_intValue = true
	if (this.IsString == 0) {
		this.intValue = uint32(this.ValueOrOfsValue)
	}
	return this.intValue, nil
}

/**
 * Name of the property addressed in the strings buffer.
 */
func (this *PcfFont_Table_Properties_Prop) Name() (v string, err error) {
	if (this._f_name) {
		return this.name, nil
	}
	this._f_name = true
	thisIo := this._parent.Strings._io
	_pos, err := thisIo.Pos()
	if err != nil {
		return "", err
	}
	_, err = thisIo.Seek(int64(this.OfsName), io.SeekStart)
	if err != nil {
		return "", err
	}
	tmp56, err := thisIo.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return "", err
	}
	this.name = string(tmp56)
	_, err = thisIo.Seek(_pos, io.SeekStart)
	if err != nil {
		return "", err
	}
	return this.name, nil
}

/**
 * Value of the property addressed in the strings
 * buffer, if this is a string value.
 */
func (this *PcfFont_Table_Properties_Prop) StrValue() (v string, err error) {
	if (this._f_strValue) {
		return this.strValue, nil
	}
	this._f_strValue = true
	if (this.IsString != 0) {
		thisIo := this._parent.Strings._io
		_pos, err := thisIo.Pos()
		if err != nil {
			return "", err
		}
		_, err = thisIo.Seek(int64(this.ValueOrOfsValue), io.SeekStart)
		if err != nil {
			return "", err
		}
		tmp57, err := thisIo.ReadBytesTerm(0, false, true, true)
		if err != nil {
			return "", err
		}
		this.strValue = string(tmp57)
		_, err = thisIo.Seek(_pos, io.SeekStart)
		if err != nil {
			return "", err
		}
	}
	return this.strValue, nil
}

/**
 * Offset to name in the strings buffer.
 */

/**
 * Designates if value is an integer (zero) or a string (non-zero).
 */

/**
 * If the value is an integer (`is_string` is false),
 * then it's stored here. If the value is a string
 * (`is_string` is true), then it stores offset to the
 * value in the strings buffer.
 */

/**
 * Table containing scalable widths of characters.
 * @see <a href="https://fontforge.org/docs/techref/pcf-format.html#the-scalable-widths-table">Source</a>
 */
type PcfFont_Table_Swidths struct {
	Format *PcfFont_Format
	NumGlyphs uint32
	Swidths []uint32
	_io *kaitai.Stream
	_root *PcfFont
	_parent *PcfFont_Table
}
func NewPcfFont_Table_Swidths() *PcfFont_Table_Swidths {
	return &PcfFont_Table_Swidths{
	}
}

func (this PcfFont_Table_Swidths) IO_() *kaitai.Stream {
	return this._io
}

func (this *PcfFont_Table_Swidths) Read(io *kaitai.Stream, parent *PcfFont_Table, root *PcfFont) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp58 := NewPcfFont_Format()
	err = tmp58.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Format = tmp58
	tmp59, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.NumGlyphs = uint32(tmp59)
	for i := 0; i < int(this.NumGlyphs); i++ {
		_ = i
		tmp60, err := this._io.ReadU4le()
		if err != nil {
			return err
		}
		this.Swidths = append(this.Swidths, tmp60)
	}
	return err
}

/**
 * The scalable width of a character is the width of the corresponding
 * PostScript character in em-units (1/1000ths of an em).
 */