【问题标题】:FileFormatException when serializing a FixedDocument序列化 FixedDocument 时出现 FileFormatException
【发布时间】:2017-08-29 07:48:17
【问题描述】:

在将 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.

【问题讨论】:

  • 您是否将 xaml 中的文化设置设置为德语?即xml:lang="de-DE".
  • @XAMlMAX 感谢您的建议,我不太确定这会有什么帮助,但还是尝试了但没有成功。
  • 我可以复制。如果我删除了FontStyle = FontStyles.Italic,那么它就可以工作了……对我来说似乎是一个错误(你不是唯一一个:questarter.com/q/…),你应该向 Microsoft Connect 报告connect.microsoft.com
  • @SimonMourier 是的,它确实看起来像一个错误......我会在报告之前等待一段时间,以防万一有人看到究竟是什么错误(或者有一个很好的解决方法,目前我猜我会重复这个过程,直到它起作用,这显然不是一个很好的修复)。
  • XPS 内部是一个固定文档的 zip 存档,其中包含用于文档演示的所有内容。它在内部尝试将您的字体作为内存流打包到 xps zip 存档中。您无法将字体打包到 XPS 存档中。字体可能会被混淆。检查下面的 URL 和链接末尾的代码下载,看起来很旧的链接。可能是,提到的解决方案可以解决您的问题。 blogs.microsoft.co.il/tamir/2008/04/17/…

标签: c# xpsdocument


【解决方案1】:

Source code in Question

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

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

祝你好运!

【讨论】:

    猜你喜欢
    • 2015-12-05
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多