序列化FixedDocument时的FileFormatException

时间:2017-08-29 07:48:18

标签: c# xpsdocument

当将FixedDocument序列化为XPS时,我有时会得到FileFormatException告诉我字体的格式(我假设)不符合预期的文件格式规范(请参阅下面的例外)。

神秘的部分是:

  • 异常只会偶尔发生一次
  • 只会出现某些FontFamily / Style / Weight组合(斜体和粗体的Segoe UI似乎触发它)

有人知道为什么会发生这种情况(特别是为什么它不会一直发生但只是在不可预测的时间间隔内发生)?

遵循最小可重复性示例将在每次运行时触发异常大约4到5次(在我的Windows 10计算机上,发生在.NET 4,4.6.1等):

private void TestXpsSerialization(object a)
{
    for (int i = 0; i < 400; ++i)
    {
        TextBlock block = new TextBlock
        {
            Text = "Test",
            FontFamily = new FontFamily("Segoe UI"),
            FontStyle = FontStyles.Italic,
            FontWeight = FontWeights.Bold,
            Background = null,
            FontSize = 12
        };
        FixedDocument fixedDoc = new FixedDocument();

        PageContent pageContent = new PageContent();
        FixedPage fixedPage = new FixedPage();
        fixedPage.Children.Add(block);
        ((IAddChild) pageContent).AddChild(fixedPage);
        fixedDoc.Pages.Add(pageContent);
        using (MemoryStream documentStream = new MemoryStream())
        {
            string inMemoryPackageName = string.Format("memorystream://{0}.xps", Guid.NewGuid());
            Uri packageUri = new Uri(inMemoryPackageName);
            using (Package package = Package.Open(documentStream, FileMode.CreateNew))
            {
                MemoryStream resultStream = new MemoryStream();
                PackageStore.AddPackage(packageUri, package);
                using (XpsDocument xpsd =
                new XpsDocument(package, CompressionOption.Maximum, inMemoryPackageName))
                {
                    XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsd);
                    writer.Write(fixedDoc);
                    package.Flush();

                    using (MemoryStream outputStream = new MemoryStream())
                    {
                        SerializerWriter serializerWriter =
                        new XpsSerializerFactory().CreateSerializerWriter(outputStream);

                        bool success = true;
                        try
                        {
                            serializerWriter.Write(xpsd.GetFixedDocumentSequence());
                        }
                        catch (Exception e)
                        {
                            success = false;
                            Debug.WriteLine(e);
                        }
                        if (success)
                        {
                            outputStream.Seek(0, SeekOrigin.Begin);
                            outputStream.CopyTo(resultStream);
                        }
                    }
                }
                PackageStore.RemovePackage(packageUri);
                Debug.WriteLine(resultStream.Length);
            }
        }
    }
}

提出异常(请原谅德语):

Ausnahme ausgelöst: "System.IO.FileFormatException" in PresentationCore.dll
System.IO.FileFormatException: Die Datei "pack://memorystream:,,62db450e-87fe-4246-a727-15ab02c5c55e.xps,/Resources/34890974-3e2d-4baf-9003-24c3375636b0.ODTTF" entspricht nicht der erwarteten Dateiformatspezifikation.
   bei MS.Internal.TrueTypeSubsetter.ComputeSubset(Void* fontData, Int32 fileSize, Uri sourceUri, Int32 directoryOffset, UInt16[] glyphArray)
   bei MS.Internal.FontFace.TrueTypeFontDriver.ComputeFontSubset(ICollection`1 glyphs)
   bei System.Windows.Media.GlyphTypeface.ComputeSubset(ICollection`1 glyphs)
   bei System.Windows.Xps.Serialization.FEMCacheItem.SubSetFont(ICollection`1 glyphs, Stream stream)
   bei System.Windows.Xps.Serialization.FEMCacheItem.Commit()
   bei System.Windows.Xps.Serialization.XpsFontSubsetter.CommitFontSubsetsSignal(FontSubsetterCommitPolicies signal)
   bei System.Windows.Xps.Serialization.XpsFontSerializationService.SignalCommit(Type type)
   bei System.Windows.Xps.Serialization.XpsSerializationManager.ReleaseXmlWriter(Type writerType)
   bei System.Windows.Xps.Serialization.DocumentSequenceSerializer.set_XmlWriter(XmlWriter value)
   bei System.Windows.Xps.Serialization.DocumentSequenceSerializer.PersistObjectData(SerializableObjectContext serializableObjectContext)
   bei System.Windows.Xps.Serialization.ReachSerializer.SerializeObject(Object serializedObject)
   bei System.Windows.Xps.Serialization.XpsSerializationManager.SaveAsXaml(Object serializedObject)
   bei System.Windows.Xps.XpsDocumentWriter.SaveAsXaml(Object serializedObject, Boolean isSync)
   bei System.Windows.Xps.XpsDocumentWriter.Write(FixedDocumentSequence fixedDocumentSequence)
   bei System.Windows.Xps.Serialization.XpsSerializerWriter.Write(FixedDocumentSequence fixedDocumentSequence)

第一行可以翻译成:

"System.IO.FileFormatException" in PresentationCore.dll
System.IO.FileFormatException: "pack://memorystream:,,62db450e-87fe-4246-a727-15ab02c5c55e.xps,/Resources/34890974-3e2d-4baf-9003-24c3375636b0.ODTTF" file does not conform to the expected file format specification.

1 个答案:

答案 0 :(得分:1)

Source code in Question

源代码中的注释似乎表明这会调用本机代码。字体驱动程序需要访问声明的字体。并非所有字体都支持所有变体。您应确认已选择字体系列,并支持斜体

如果api支持该选项,您应该尝试指出已经确认已安装的特定字体(而不是系列),并支持您选择的变体。

祝你好运!