【发布时间】: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