/// <summary> /// Save weight table to apl file. /// </summary> /// <param name="filePath">Target file path to save weight table data.</param> /// <param name="buildNumber">Voice font build number.</param> public void SaveAsApl(string filePath, FontBuildNumber buildNumber) { Helper.EnsureFolderExistForFile(filePath); if (buildNumber == null) { throw new ArgumentNullException("buildNumber"); } FileStream fs = new FileStream(filePath, FileMode.Create); try { using (BinaryWriter bw = new BinaryWriter(fs)) { fs = null; uint size = (uint)Marshal.SizeOf(typeof(WeightTableHeaderSerial)); // Write header WeightTableHeaderSerial aplHeader = new WeightTableHeaderSerial(); aplHeader.Tag = (uint)FontSectionTag.WeightTable; ////sizeFieldOffset = sizeof(aplHeader.Tag + aplHeader.FormatTag) int sizeFieldOffset = sizeof(uint) + aplHeader.FormatTag.Length; aplHeader.Size = 0; // Update after all other sections have been written. aplHeader.Version = (uint)FormatVersion.Tts30; aplHeader.Build = (uint)buildNumber.ToInt32(); aplHeader.LangNumber = 1; aplHeader.DataOffset = size; bw.Write(aplHeader.ToBytes()); // Write Section size += SaveSection(bw); // Update "size" field in the header to sizeof(Tag + FormatTag + Size). size -= sizeof(uint) + sizeof(uint) + (uint)aplHeader.FormatTag.Length; bw.Seek(sizeFieldOffset, SeekOrigin.Begin); bw.Write(size); } } finally { if (null != fs) { fs.Dispose(); } } }
/// <summary> /// Save domain index file. /// </summary> /// <param name="filePath">File path.</param> /// <param name="buildNumber">Build number.</param> public void Save(string filePath, FontBuildNumber buildNumber) { // Header size int headerSize = Marshal.SizeOf(typeof(DomainIndexFileHeaderSerial)); // Hash table size // One hash table item // 1. Offset in string pool (uint) // 2. Offset in feature data (uint) // 3. Index of next item in hash table (int) int hashTableSize = _items.Length * (sizeof(uint) + sizeof(uint) + sizeof(int)); // Feature data size & string pool size int featureDataSize = 0; int stringPoolSize = 0; for (int i = 0; i < _items.Length; i++) { Debug.Assert(_items[i] != null); featureDataSize += _items[i].FeatureItemBinarySize; stringPoolSize += _items[i].StringBinarySize; } DomainIndexFileHeaderSerial header; header.Tag = (uint)_tag; header.Size = (uint)(headerSize - 8 + hashTableSize + featureDataSize + stringPoolSize); header.VersionNumber = (uint)FormatVersion.Tts30; header.BuildNumber = (uint)buildNumber.ToInt32(); header.LanguageId = (uint)_language; header.HashTableItemCount = _items.Length; header.HashTableOffset = headerSize; header.HashTableSize = hashTableSize; header.FeatureDataOffset = header.HashTableOffset + hashTableSize; header.FeatureDataSize = featureDataSize; header.StringPoolOffset = header.FeatureDataOffset + featureDataSize; header.StringPoolSize = stringPoolSize; FileStream fs = new FileStream(filePath, FileMode.Create); try { using (BinaryWriter bw = new BinaryWriter(fs)) { fs = null; // Write header bw.Write(header.ToBytes()); // Write hash table foreach (DomainIndexItem item in _items) { item.WriteHashtable(bw); } // Write feature data foreach (DomainIndexItem item in _items) { item.WriteFeatureData(bw); } // Write string pool foreach (DomainIndexItem item in _items) { item.WriteWordText(bw); } } } finally { if (null != fs) { fs.Dispose(); } } }