EotWriter.vala
/*
Copyright (C) 2012 Johan Mattsson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Math;
namespace Supplement {
class EotWriter : GLib.Object {
string ttf_file_name;
string eot_file_name;
public EotWriter (string ttf_file, string eot_file) {
ttf_file_name = ttf_file;
eot_file_name = eot_file;
}
public void write () throws Error {
FontData fd = new FontData ();
FontData ttf_data = new FontData ();
OpenFontFormatReader input;
uint32 ttf_length;
File ttf_file;
File eot_file;
FileInfo file_info;
OtfInputStream dis;
DataOutputStream os;
uint8* data;
uint32 l;
NameTable names;
string tn;
ttf_file = File.new_for_path (ttf_file_name);
if (!ttf_file.query_exists ()) {
warning (@"EotWriter: file does not exist. $((!) ttf_file.get_path ())");
return;
}
eot_file = File.new_for_path (eot_file_name);
if (eot_file.query_exists ()) {
warning ("File exists in eot export.");
return;
}
os = new DataOutputStream(eot_file.create (FileCreateFlags.REPLACE_DESTINATION));
file_info = ttf_file.query_info ("*", FileQueryInfoFlags.NONE);
ttf_length = (uint32) file_info.get_size ();
if (ttf_length == 0) {
warning ("TTF file is of zero length.");
return;
}
dis = new OtfInputStream (ttf_file.read ());
ttf_data.write_table (dis, 0, ttf_length);
// parse file to find head checksum
input = new OpenFontFormatReader ();
input.parse_index (ttf_file_name);
names = input.directory_table.name_table;
fd.add_littleendian_u32 (0); // table length
fd.add_littleendian_u32 (ttf_length);
fd.add_littleendian_u32 (0x00020001); // table format version
fd.add_littleendian_u32 (0); // flags
// panose
for (int i = 0; i < 10; i++) {
fd.add (0);
}
// according to specification should charset and italic be added the
// other way around, but it does not work
fd.add (1); // default charset
fd.add (0); // italic set to regular
fd.add_littleendian_u32 (400); // weight
fd.add_littleendian_u16 (0); // 0 drm, designer must know that notified
fd.add_littleendian_u16 (0x504C); // magic number
// FIXA:
// unicode ranges
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
// FIXA:
// code page range
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (input.get_head_checksum ()); // head checksum adjustment
// reserved
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u32 (0);
fd.add_littleendian_u16 (0); // padding
tn = names.get_name (names.FONT_NAME);
fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
fd.add_str_littleendian_utf16 (tn);
fd.add_littleendian_u16 (0); // padding
tn = names.get_name (names.SUBFAMILY_NAME);
fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
fd.add_str_littleendian_utf16 (tn);
fd.add_littleendian_u16 (0); // padding
// FIXA version or name + version
tn = names.get_name (names.VERSION);
fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
fd.add_str_littleendian_utf16 (tn);
fd.add_littleendian_u16 (0); // padding
tn = names.get_name (names.FULL_FONT_NAME);
fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
fd.add_str_littleendian_utf16 (tn);
fd.add_littleendian_u16 (0); // padding
fd.add_littleendian_u16 (0); // length of root string
// the root string goes here.
// update length of this table
fd.seek (0);
fd.add_littleendian_u32 (fd.length () + ttf_length);
l = fd.length_with_padding ();
data = fd.table_data;
for (int i = 0; i < l; i++) {
os.put_byte (data[i]);
}
l = ttf_data.length_with_padding ();
data = ttf_data.table_data;
for (int i = 0; i < l; i++) {
os.put_byte (data[i]);
}
dis.close ();
os.close ();
input.close ();
}
}
}