You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PdfSharp(C#)生成PDF时古吉拉特语文字显示异常求助

问题分析与解决方案

古吉拉特语属于复杂书写系统,需要OpenType字体的GPOS/GSUB表支持(处理连字、字符重组、字形变换等),而传统PdfSharp(尤其是旧版本)原生不支持这类复杂文本布局,仅简单输出Unicode字符,导致显示错乱。

核心问题

PdfSharp的默认DrawString/XTextFormatter仅处理简单拉丁系文本,无法解析古吉拉特语所需的字形组合规则,因此会出现字符拆分、顺序错乱的问题。

解决方案

1. 切换到支持复杂脚本的PdfSharp变体

使用PdfSharpCore(适配.NET Core/.NET 5+)或MigraDocFoundation/PdfSharp的最新版本,这类版本对OpenType字体的高级特性支持更好。

2. 结合HarfBuzzSharp处理文本布局

HarfBuzz是开源的专业文本布局引擎,可处理复杂脚本的字形重组,配合PdfSharpCore实现正确渲染:

步骤1:安装依赖NuGet包

Install-Package PdfSharpCore
Install-Package HarfBuzzSharp
Install-Package HarfBuzzSharp.NativeAssets.Windows # Windows平台,其他平台对应原生包

步骤2:修改代码实现

using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;
using HarfBuzzSharp;
using System.IO;

// 加载本地字体文件(避免系统字体查找的不确定性)
var fontFilePath = @"你的NotoSansGujarati-Regular.ttf文件路径";
using var fontStream = File.OpenRead(fontFilePath);
var hbFont = new Font(fontStream);
var fontFace = new FontFace(hbFont);

using (var document = new PdfDocument())
{
    document.Info.Title = "My Gujarati Test Document";
    document.Info.Author = "snj886";

    var page = document.AddPage();
    page.Size = PdfSharpCore.PageSize.A4;

    using (var gfx = XGraphics.FromPdfPage(page))
    {
        var targetText = "સભ્યના બિલ ઓર્ડર નંબરની વિગતો";
        var textBuffer = new Buffer(targetText);
        var textShaper = new Shape(hbFont, textBuffer);
        textShaper.Position();

        float startX = 45;
        float startY = 45;
        float fontSize = 12;
        float unitsPerEm = fontFace.UnitsPerEm;

        // 逐个绘制处理后的字形
        foreach (var glyph in textShaper.Glyphs)
        {
            // 计算字形的位置和宽度
            float glyphAdvance = fontFace.GetGlyphHorizontalAdvance(glyph.GlyphIndex) * fontSize / unitsPerEm;
            float offsetX = glyph.Position.XOffset * fontSize / unitsPerEm;
            float offsetY = glyph.Position.YOffset * fontSize / unitsPerEm;

            // 绘制字形
            gfx.DrawGlyph(hbFont, fontSize, XBrushes.Black,
                new XPoint(startX + offsetX, startY - offsetY),
                glyph.GlyphIndex);

            // 更新下一个字形的起始X坐标
            startX += glyphAdvance + (glyph.Position.XAdvance * fontSize / unitsPerEm);
        }
    }

    document.Save("GujaratiTest.pdf");
}

3. 备选方案:改用iText 7

如果项目允许切换PDF库,iText 7原生支持复杂脚本和OpenType字体特性,无需额外布局引擎,代码更简洁:

using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;

var fontFilePath = @"你的NotoSansGujarati-Regular.ttf文件路径";
var pdfFont = PdfFontFactory.CreateFont(fontFilePath, PdfEncodings.IDENTITY_H);

using (var writer = new PdfWriter("GujaratiTest.pdf"))
using (var pdfDoc = new PdfDocument(writer))
{
    var document = new Document(pdfDoc);
    document.Add(new Paragraph("સભ્યના બિલ ઓર્ડર નંબરની વિગતો")
        .SetFont(pdfFont)
        .SetFontSize(12)
        .SetMarginLeft(45)
        .SetMarginTop(45));
}

关键注意事项

  • 始终直接加载本地字体文件,避免依赖系统字体名称匹配问题。
  • 旧版PdfSharp无复杂脚本支持,不建议继续使用。

内容的提问来源于stack exchange,提问作者hsCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:54:55