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).
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.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream). One can open local file for that, or use existing std::string or char* buffer.
#include<fstream> std::ifstreamis("path/to/local/file.pcf",std::ifstream::binary);
#include<sstream> std::istringstreamis(str);
#include<sstream> constcharbuf[]={...}; std::stringstr(buf,sizeofbuf); std::istringstreamis(str);
#include"kaitai/kaitaistream.h" kaitai::kstreamks(&is);
pcf_font_tdata(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.magic()// => get magic
#pragma once // This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild classpcf_font_t; #include"kaitai/kaitaistruct.h" #include<stdint.h> #include<memory> #include"bytes_with_io.h" #include<set> #include<vector> #if KAITAI_STRUCT_VERSION < 11000L #error "Incompatible Kaitai Struct C++/STL API: version 0.11 or later is required" #endif /** * 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). * \sa https://fontforge.org/docs/techref/pcf-format.html Source */ classpcf_font_t:publickaitai::kstruct{ public: classformat_t; classtable_t; enumtypes_t{ TYPES_PROPERTIES=1, TYPES_ACCELERATORS=2, TYPES_METRICS=4, TYPES_BITMAPS=8, TYPES_INK_METRICS=16, TYPES_BDF_ENCODINGS=32, TYPES_SWIDTHS=64, TYPES_GLYPH_NAMES=128, TYPES_BDF_ACCELERATORS=256 }; staticbool_is_defined_types_t(types_tv); private: staticconststd::set<types_t>_values_types_t; public: pcf_font_t(kaitai::kstream*p__io,kaitai::kstruct*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~pcf_font_t(); /** * 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. * \sa https://fontforge.org/docs/techref/pcf-format.html#file-header Source */ classformat_t:publickaitai::kstruct{ public: format_t(kaitai::kstream*p__io,kaitai::kstruct*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~format_t(); private: uint64_tm_padding1; uint64_tm_scan_unit_mask; boolm_is_most_significant_bit_first; boolm_is_big_endian; uint64_tm_glyph_pad_mask; uint8_tm_format; uint16_tm_padding; pcf_font_t*m__root; kaitai::kstruct*m__parent; public: uint64_tpadding1()const{returnm_padding1;} uint64_tscan_unit_mask()const{returnm_scan_unit_mask;} boolis_most_significant_bit_first()const{returnm_is_most_significant_bit_first;} /** * If set, then all integers in the table are treated as big-endian */ boolis_big_endian()const{returnm_is_big_endian;} uint64_tglyph_pad_mask()const{returnm_glyph_pad_mask;} uint8_tformat()const{returnm_format;} uint16_tpadding()const{returnm_padding;} pcf_font_t*_root()const{returnm__root;} kaitai::kstruct*_parent()const{returnm__parent;} }; /** * 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. */ classtable_t:publickaitai::kstruct{ public: classbdf_encodings_t; classbitmaps_t; classglyph_names_t; classproperties_t; classswidths_t; table_t(kaitai::kstream*p__io,pcf_font_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~table_t(); /** * 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`. * \sa https://fontforge.org/docs/techref/pcf-format.html#the-encoding-table Source */ classbdf_encodings_t:publickaitai::kstruct{ public: bdf_encodings_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~bdf_encodings_t(); private: std::unique_ptr<format_t>m_format; uint16_tm_min_char_or_byte2; uint16_tm_max_char_or_byte2; uint16_tm_min_byte1; uint16_tm_max_byte1; uint16_tm_default_char; std::unique_ptr<std::vector<uint16_t>>m_glyph_indexes; pcf_font_t*m__root; pcf_font_t::table_t*m__parent; public: format_t*format()const{returnm_format.get();} uint16_tmin_char_or_byte2()const{returnm_min_char_or_byte2;} uint16_tmax_char_or_byte2()const{returnm_max_char_or_byte2;} uint16_tmin_byte1()const{returnm_min_byte1;} uint16_tmax_byte1()const{returnm_max_byte1;} uint16_tdefault_char()const{returnm_default_char;} std::vector<uint16_t>*glyph_indexes()const{returnm_glyph_indexes.get();} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t*_parent()const{returnm__parent;} }; /** * Table containing uncompressed glyph bitmaps. * \sa https://fontforge.org/docs/techref/pcf-format.html#the-bitmap-table Source */ classbitmaps_t:publickaitai::kstruct{ public: bitmaps_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~bitmaps_t(); private: std::unique_ptr<format_t>m_format; uint32_tm_num_glyphs; std::unique_ptr<std::vector<uint32_t>>m_offsets; std::unique_ptr<std::vector<uint32_t>>m_bitmap_sizes; pcf_font_t*m__root; pcf_font_t::table_t*m__parent; public: format_t*format()const{returnm_format.get();} uint32_tnum_glyphs()const{returnm_num_glyphs;} std::vector<uint32_t>*offsets()const{returnm_offsets.get();} std::vector<uint32_t>*bitmap_sizes()const{returnm_bitmap_sizes.get();} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t*_parent()const{returnm__parent;} }; /** * Table containing character names for every glyph. * \sa https://fontforge.org/docs/techref/pcf-format.html#the-glyph-names-table Source */ classglyph_names_t:publickaitai::kstruct{ public: classstring_ref_t; glyph_names_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~glyph_names_t(); classstring_ref_t:publickaitai::kstruct{ public: string_ref_t(kaitai::kstream*p__io,pcf_font_t::table_t::glyph_names_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~string_ref_t(); private: boolf_value; std::stringm_value; public: std::stringvalue(); private: uint32_tm_ofs_string; pcf_font_t*m__root; pcf_font_t::table_t::glyph_names_t*m__parent; public: uint32_tofs_string()const{returnm_ofs_string;} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t::glyph_names_t*_parent()const{returnm__parent;} }; private: std::unique_ptr<format_t>m_format; uint32_tm_num_glyphs; std::unique_ptr<std::vector<std::unique_ptr<string_ref_t>>>m_names; uint32_tm_len_strings; std::unique_ptr<bytes_with_io_t>m_strings; pcf_font_t*m__root; pcf_font_t::table_t*m__parent; std::stringm__raw_strings; std::unique_ptr<kaitai::kstream>m__io__raw_strings; public: format_t*format()const{returnm_format.get();} uint32_tnum_glyphs()const{returnm_num_glyphs;} /** * Glyph names are represented as string references in strings buffer. */ std::vector<std::unique_ptr<string_ref_t>>*names()const{returnm_names.get();} uint32_tlen_strings()const{returnm_len_strings;} /** * Strings buffer which contains all glyph names. */ bytes_with_io_t*strings()const{returnm_strings.get();} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t*_parent()const{returnm__parent;} std::string_raw_strings()const{returnm__raw_strings;} kaitai::kstream*_io__raw_strings()const{returnm__io__raw_strings.get();} }; /** * Array of properties (key-value pairs), used to convey different X11 * settings of a font. Key is always an X font atom. * \sa https://fontforge.org/docs/techref/pcf-format.html#properties-table Source */ classproperties_t:publickaitai::kstruct{ public: classprop_t; properties_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~properties_t(); /** * 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. */ classprop_t:publickaitai::kstruct{ public: prop_t(kaitai::kstream*p__io,pcf_font_t::table_t::properties_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~prop_t(); private: boolf_int_value; uint32_tm_int_value; booln_int_value; public: bool_is_null_int_value(){int_value();returnn_int_value;}; private: public: /** * Value of the property, if this is an integer value. */ uint32_tint_value(); private: boolf_name; std::stringm_name; public: /** * Name of the property addressed in the strings buffer. */ std::stringname(); private: boolf_str_value; std::stringm_str_value; booln_str_value; public: bool_is_null_str_value(){str_value();returnn_str_value;}; private: public: /** * Value of the property addressed in the strings * buffer, if this is a string value. */ std::stringstr_value(); private: uint32_tm_ofs_name; uint8_tm_is_string; uint32_tm_value_or_ofs_value; pcf_font_t*m__root; pcf_font_t::table_t::properties_t*m__parent; public: /** * Offset to name in the strings buffer. */ uint32_tofs_name()const{returnm_ofs_name;} /** * Designates if value is an integer (zero) or a string (non-zero). */ uint8_tis_string()const{returnm_is_string;} /** * 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. */ uint32_tvalue_or_ofs_value()const{returnm_value_or_ofs_value;} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t::properties_t*_parent()const{returnm__parent;} }; private: std::unique_ptr<format_t>m_format; uint32_tm_num_props; std::unique_ptr<std::vector<std::unique_ptr<prop_t>>>m_props; std::stringm_padding; uint32_tm_len_strings; std::unique_ptr<bytes_with_io_t>m_strings; pcf_font_t*m__root; pcf_font_t::table_t*m__parent; std::stringm__raw_strings; std::unique_ptr<kaitai::kstream>m__io__raw_strings; public: format_t*format()const{returnm_format.get();} uint32_tnum_props()const{returnm_num_props;} std::vector<std::unique_ptr<prop_t>>*props()const{returnm_props.get();} std::stringpadding()const{returnm_padding;} uint32_tlen_strings()const{returnm_len_strings;} /** * Strings buffer. Never used directly, but instead is * addressed by offsets from the properties. */ bytes_with_io_t*strings()const{returnm_strings.get();} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t*_parent()const{returnm__parent;} std::string_raw_strings()const{returnm__raw_strings;} kaitai::kstream*_io__raw_strings()const{returnm__io__raw_strings.get();} }; /** * Table containing scalable widths of characters. * \sa https://fontforge.org/docs/techref/pcf-format.html#the-scalable-widths-table Source */ classswidths_t:publickaitai::kstruct{ public: swidths_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent=nullptr,pcf_font_t*p__root=nullptr); private: void_read(); void_clean_up(); public: ~swidths_t(); private: std::unique_ptr<format_t>m_format; uint32_tm_num_glyphs; std::unique_ptr<std::vector<uint32_t>>m_swidths; pcf_font_t*m__root; pcf_font_t::table_t*m__parent; public: format_t*format()const{returnm_format.get();} uint32_tnum_glyphs()const{returnm_num_glyphs;} /** * The scalable width of a character is the width of the corresponding * PostScript character in em-units (1/1000ths of an em). */ std::vector<uint32_t>*swidths()const{returnm_swidths.get();} pcf_font_t*_root()const{returnm__root;} pcf_font_t::table_t*_parent()const{returnm__parent;} }; private: boolf_body; std::unique_ptr<kaitai::kstruct>m_body; booln_body; public: bool_is_null_body(){body();returnn_body;}; private: public: kaitai::kstruct*body(); private: types_tm_type; std::unique_ptr<format_t>m_format; uint32_tm_len_body; uint32_tm_ofs_body; pcf_font_t*m__root; pcf_font_t*m__parent; std::stringm__raw_body; std::unique_ptr<kaitai::kstream>m__io__raw_body; public: types_ttype()const{returnm_type;} format_t*format()const{returnm_format.get();} uint32_tlen_body()const{returnm_len_body;} uint32_tofs_body()const{returnm_ofs_body;} pcf_font_t*_root()const{returnm__root;} pcf_font_t*_parent()const{returnm__parent;} std::string_raw_body()const{returnm__raw_body;} kaitai::kstream*_io__raw_body()const{returnm__io__raw_body.get();} }; private: std::stringm_magic; uint32_tm_num_tables; std::unique_ptr<std::vector<std::unique_ptr<table_t>>>m_tables; pcf_font_t*m__root; kaitai::kstruct*m__parent; public: std::stringmagic()const{returnm_magic;} uint32_tnum_tables()const{returnm_num_tables;} std::vector<std::unique_ptr<table_t>>*tables()const{returnm_tables.get();} pcf_font_t*_root()const{returnm__root;} kaitai::kstruct*_parent()const{returnm__parent;} };
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild #include"pcf_font.h" #include"kaitai/exceptions.h" conststd::set<pcf_font_t::types_t>pcf_font_t::_values_types_t{ pcf_font_t::TYPES_PROPERTIES, pcf_font_t::TYPES_ACCELERATORS, pcf_font_t::TYPES_METRICS, pcf_font_t::TYPES_BITMAPS, pcf_font_t::TYPES_INK_METRICS, pcf_font_t::TYPES_BDF_ENCODINGS, pcf_font_t::TYPES_SWIDTHS, pcf_font_t::TYPES_GLYPH_NAMES, pcf_font_t::TYPES_BDF_ACCELERATORS, }; boolpcf_font_t::_is_defined_types_t(pcf_font_t::types_tv){ returnpcf_font_t::_values_types_t.find(v)!=pcf_font_t::_values_types_t.end(); } pcf_font_t::pcf_font_t(kaitai::kstream*p__io,kaitai::kstruct*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root?p__root:this; m_tables=nullptr; _read(); } voidpcf_font_t::_read(){ m_magic=m__io->read_bytes(4); if(!(m_magic==std::string("\x01\x66\x63\x70",4))){ throwkaitai::validation_not_equal_error<std::string>(std::string("\x01\x66\x63\x70",4),m_magic,m__io,std::string("/seq/0")); } m_num_tables=m__io->read_u4le(); m_tables=std::unique_ptr<std::vector<std::unique_ptr<table_t>>>(newstd::vector<std::unique_ptr<table_t>>()); constintl_tables=num_tables(); for(inti=0;i<l_tables;i++){ m_tables->push_back(std::move(std::unique_ptr<table_t>(newtable_t(m__io,this,m__root)))); } } pcf_font_t::~pcf_font_t(){ _clean_up(); } voidpcf_font_t::_clean_up(){ } pcf_font_t::format_t::format_t(kaitai::kstream*p__io,kaitai::kstruct*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; _read(); } voidpcf_font_t::format_t::_read(){ m_padding1=m__io->read_bits_int_be(2); m_scan_unit_mask=m__io->read_bits_int_be(2); m_is_most_significant_bit_first=m__io->read_bits_int_be(1); m_is_big_endian=m__io->read_bits_int_be(1); m_glyph_pad_mask=m__io->read_bits_int_be(2); m__io->align_to_byte(); m_format=m__io->read_u1(); m_padding=m__io->read_u2le(); } pcf_font_t::format_t::~format_t(){ _clean_up(); } voidpcf_font_t::format_t::_clean_up(){ } pcf_font_t::table_t::table_t(kaitai::kstream*p__io,pcf_font_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m__io__raw_body=nullptr; f_body=false; _read(); } voidpcf_font_t::table_t::_read(){ m_type=static_cast<pcf_font_t::types_t>(m__io->read_u4le()); m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_len_body=m__io->read_u4le(); m_ofs_body=m__io->read_u4le(); } pcf_font_t::table_t::~table_t(){ _clean_up(); } voidpcf_font_t::table_t::_clean_up(){ if(f_body&&!n_body){ } } pcf_font_t::table_t::bdf_encodings_t::bdf_encodings_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m_glyph_indexes=nullptr; _read(); } voidpcf_font_t::table_t::bdf_encodings_t::_read(){ m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_min_char_or_byte2=m__io->read_u2le(); m_max_char_or_byte2=m__io->read_u2le(); m_min_byte1=m__io->read_u2le(); m_max_byte1=m__io->read_u2le(); m_default_char=m__io->read_u2le(); m_glyph_indexes=std::unique_ptr<std::vector<uint16_t>>(newstd::vector<uint16_t>()); constintl_glyph_indexes=((max_char_or_byte2()-min_char_or_byte2())+1)*((max_byte1()-min_byte1())+1); for(inti=0;i<l_glyph_indexes;i++){ m_glyph_indexes->push_back(std::move(m__io->read_u2le())); } } pcf_font_t::table_t::bdf_encodings_t::~bdf_encodings_t(){ _clean_up(); } voidpcf_font_t::table_t::bdf_encodings_t::_clean_up(){ } pcf_font_t::table_t::bitmaps_t::bitmaps_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m_offsets=nullptr; m_bitmap_sizes=nullptr; _read(); } voidpcf_font_t::table_t::bitmaps_t::_read(){ m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_num_glyphs=m__io->read_u4le(); m_offsets=std::unique_ptr<std::vector<uint32_t>>(newstd::vector<uint32_t>()); constintl_offsets=num_glyphs(); for(inti=0;i<l_offsets;i++){ m_offsets->push_back(std::move(m__io->read_u4le())); } m_bitmap_sizes=std::unique_ptr<std::vector<uint32_t>>(newstd::vector<uint32_t>()); constintl_bitmap_sizes=4; for(inti=0;i<l_bitmap_sizes;i++){ m_bitmap_sizes->push_back(std::move(m__io->read_u4le())); } } pcf_font_t::table_t::bitmaps_t::~bitmaps_t(){ _clean_up(); } voidpcf_font_t::table_t::bitmaps_t::_clean_up(){ } pcf_font_t::table_t::glyph_names_t::glyph_names_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m_names=nullptr; m_strings=nullptr; m__io__raw_strings=nullptr; _read(); } voidpcf_font_t::table_t::glyph_names_t::_read(){ m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_num_glyphs=m__io->read_u4le(); m_names=std::unique_ptr<std::vector<std::unique_ptr<string_ref_t>>>(newstd::vector<std::unique_ptr<string_ref_t>>()); constintl_names=num_glyphs(); for(inti=0;i<l_names;i++){ m_names->push_back(std::move(std::unique_ptr<string_ref_t>(newstring_ref_t(m__io,this,m__root)))); } m_len_strings=m__io->read_u4le(); m__raw_strings=m__io->read_bytes(len_strings()); m__io__raw_strings=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_strings)); m_strings=std::unique_ptr<bytes_with_io_t>(newbytes_with_io_t(m__io__raw_strings.get())); } pcf_font_t::table_t::glyph_names_t::~glyph_names_t(){ _clean_up(); } voidpcf_font_t::table_t::glyph_names_t::_clean_up(){ } pcf_font_t::table_t::glyph_names_t::string_ref_t::string_ref_t(kaitai::kstream*p__io,pcf_font_t::table_t::glyph_names_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; f_value=false; _read(); } voidpcf_font_t::table_t::glyph_names_t::string_ref_t::_read(){ m_ofs_string=m__io->read_u4le(); } pcf_font_t::table_t::glyph_names_t::string_ref_t::~string_ref_t(){ _clean_up(); } voidpcf_font_t::table_t::glyph_names_t::string_ref_t::_clean_up(){ if(f_value){ } } std::stringpcf_font_t::table_t::glyph_names_t::string_ref_t::value(){ if(f_value) returnm_value; f_value=true; kaitai::kstream*io=_parent()->strings()->_io(); std::streampos_pos=io->pos(); io->seek(ofs_string()); m_value=kaitai::kstream::bytes_to_str(io->read_bytes_term(0,false,true,true),"UTF-8"); io->seek(_pos); returnm_value; } pcf_font_t::table_t::properties_t::properties_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m_props=nullptr; m_strings=nullptr; m__io__raw_strings=nullptr; _read(); } voidpcf_font_t::table_t::properties_t::_read(){ m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_num_props=m__io->read_u4le(); m_props=std::unique_ptr<std::vector<std::unique_ptr<prop_t>>>(newstd::vector<std::unique_ptr<prop_t>>()); constintl_props=num_props(); for(inti=0;i<l_props;i++){ m_props->push_back(std::move(std::unique_ptr<prop_t>(newprop_t(m__io,this,m__root)))); } m_padding=m__io->read_bytes((((num_props()&3)==0)?(0):(4-(num_props()&3)))); m_len_strings=m__io->read_u4le(); m__raw_strings=m__io->read_bytes(len_strings()); m__io__raw_strings=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_strings)); m_strings=std::unique_ptr<bytes_with_io_t>(newbytes_with_io_t(m__io__raw_strings.get())); } pcf_font_t::table_t::properties_t::~properties_t(){ _clean_up(); } voidpcf_font_t::table_t::properties_t::_clean_up(){ } pcf_font_t::table_t::properties_t::prop_t::prop_t(kaitai::kstream*p__io,pcf_font_t::table_t::properties_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; f_int_value=false; f_name=false; f_str_value=false; _read(); } voidpcf_font_t::table_t::properties_t::prop_t::_read(){ m_ofs_name=m__io->read_u4le(); m_is_string=m__io->read_u1(); m_value_or_ofs_value=m__io->read_u4le(); } pcf_font_t::table_t::properties_t::prop_t::~prop_t(){ _clean_up(); } voidpcf_font_t::table_t::properties_t::prop_t::_clean_up(){ if(f_name){ } if(f_str_value&&!n_str_value){ } } uint32_tpcf_font_t::table_t::properties_t::prop_t::int_value(){ if(f_int_value) returnm_int_value; f_int_value=true; n_int_value=true; if(is_string()==0){ n_int_value=false; m_int_value=value_or_ofs_value(); } returnm_int_value; } std::stringpcf_font_t::table_t::properties_t::prop_t::name(){ if(f_name) returnm_name; f_name=true; kaitai::kstream*io=_parent()->strings()->_io(); std::streampos_pos=io->pos(); io->seek(ofs_name()); m_name=kaitai::kstream::bytes_to_str(io->read_bytes_term(0,false,true,true),"UTF-8"); io->seek(_pos); returnm_name; } std::stringpcf_font_t::table_t::properties_t::prop_t::str_value(){ if(f_str_value) returnm_str_value; f_str_value=true; n_str_value=true; if(is_string()!=0){ n_str_value=false; kaitai::kstream*io=_parent()->strings()->_io(); std::streampos_pos=io->pos(); io->seek(value_or_ofs_value()); m_str_value=kaitai::kstream::bytes_to_str(io->read_bytes_term(0,false,true,true),"UTF-8"); io->seek(_pos); } returnm_str_value; } pcf_font_t::table_t::swidths_t::swidths_t(kaitai::kstream*p__io,pcf_font_t::table_t*p__parent,pcf_font_t*p__root):kaitai::kstruct(p__io){ m__parent=p__parent; m__root=p__root; m_format=nullptr; m_swidths=nullptr; _read(); } voidpcf_font_t::table_t::swidths_t::_read(){ m_format=std::unique_ptr<format_t>(newformat_t(m__io,this,m__root)); m_num_glyphs=m__io->read_u4le(); m_swidths=std::unique_ptr<std::vector<uint32_t>>(newstd::vector<uint32_t>()); constintl_swidths=num_glyphs(); for(inti=0;i<l_swidths;i++){ m_swidths->push_back(std::move(m__io->read_u4le())); } } pcf_font_t::table_t::swidths_t::~swidths_t(){ _clean_up(); } voidpcf_font_t::table_t::swidths_t::_clean_up(){ } kaitai::kstruct*pcf_font_t::table_t::body(){ if(f_body) returnm_body.get(); f_body=true; std::streampos_pos=m__io->pos(); m__io->seek(ofs_body()); n_body=true; switch(type()){ casepcf_font_t::TYPES_BDF_ENCODINGS:{ n_body=false; m__raw_body=m__io->read_bytes(len_body()); m__io__raw_body=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_body)); m_body=std::unique_ptr<bdf_encodings_t>(newbdf_encodings_t(m__io__raw_body.get(),this,m__root)); break; } casepcf_font_t::TYPES_BITMAPS:{ n_body=false; m__raw_body=m__io->read_bytes(len_body()); m__io__raw_body=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_body)); m_body=std::unique_ptr<bitmaps_t>(newbitmaps_t(m__io__raw_body.get(),this,m__root)); break; } casepcf_font_t::TYPES_GLYPH_NAMES:{ n_body=false; m__raw_body=m__io->read_bytes(len_body()); m__io__raw_body=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_body)); m_body=std::unique_ptr<glyph_names_t>(newglyph_names_t(m__io__raw_body.get(),this,m__root)); break; } casepcf_font_t::TYPES_PROPERTIES:{ n_body=false; m__raw_body=m__io->read_bytes(len_body()); m__io__raw_body=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_body)); m_body=std::unique_ptr<properties_t>(newproperties_t(m__io__raw_body.get(),this,m__root)); break; } casepcf_font_t::TYPES_SWIDTHS:{ n_body=false; m__raw_body=m__io->read_bytes(len_body()); m__io__raw_body=std::unique_ptr<kaitai::kstream>(newkaitai::kstream(m__raw_body)); m_body=std::unique_ptr<swidths_t>(newswidths_t(m__io__raw_body.get(),this,m__root)); break; } default:{ m__raw_body=m__io->read_bytes(len_body()); break; } } m__io->seek(_pos); returnm_body.get(); }