版本5.5.4+中的ItextSharp字体颜色问题 [英] ItextSharp font color issue in ver 5.5.4+

查看:1261
本文介绍了版本5.5.4+中的ItextSharp字体颜色问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用红色字体颜色创建红色图章的代码:

I have some code that creates a red "stamp" using a red font color:

    string StampDate = DateTime.Now.ToString("MM/dd/yyyy");
    string FontPath = Server.MapPath("/assets/Fonts");
    string OrigFile = Server.MapPath("/test.pdf");
    const int OpacityPercent = 80;
    const float PDFPaidFontSize = 28;
    const float PDFCopyX = 170;
    const float PDFPaidX = 385;
    const float PDFY = 20;
    const float PDFDateXOffset = 7;
    const float PDFDateYOffset = 12;
    const float PDFDateFontSize = 10;
    const string PaidStampTxt = "PAID";
    const string CopyStampTxt = "COPY";
    const string ArialFilename = "arialbd.ttf";
    PdfStamper stamper = null;
    PdfReader reader = null;
    PdfReader.unethicalreading = true;
    MemoryStream streamPDF;
    try
    {
        reader = new PdfReader(OrigFile);
        streamPDF = new MemoryStream();
        stamper = new PdfStamper(reader, streamPDF);
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            PdfGState gstate = new PdfGState();
            gstate.FillOpacity = gstate.StrokeOpacity = OpacityPercent / 100F;
            PdfContentByte overContent = stamper.GetOverContent(i);
            overContent.SaveState();
            overContent.SetGState(gstate);
            overContent.SetColorFill(BaseColor.RED);
            overContent.BeginText();
            BaseFont font = BaseFont.CreateFont(BaseFont.TIMES_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            overContent.SetFontAndSize(font, PDFPaidFontSize);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, CopyStampTxt, PDFCopyX, PDFY, 0);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, PaidStampTxt, PDFPaidX, PDFY, 0);
            overContent.SetColorFill(BaseColor.BLACK);
            font = BaseFont.CreateFont(Path.Combine(FontPath, ArialFilename), BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            overContent.SetFontAndSize(font, PDFDateFontSize);
            overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, StampDate, PDFPaidX + PDFDateXOffset, PDFY - PDFDateYOffset, 0);
            overContent.EndText();
            overContent.RestoreState();
        }
    }
    finally
    {
        if (stamper != null)
        {
            stamper.Close();
        }
        if (reader != null)
        {
            reader.Close();
        }
    }
    byte[] pdf = streamPDF.ToArray();
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.Buffer = false;
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.Charset = string.Empty;
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-length", pdf.Length.ToString());
    Response.AddHeader("Content-Disposition", "inline;filename=test.pdf;");
    Response.BinaryWrite(pdf);
    Response.Close();

生成的pdf文本为灰色而不是红色。
当我恢复到版本5.5.3时,它再次显示为红色。我已经尝试过5.5.4和5.5.5并且他们似乎都有相同的问题。

The resulting pdf text has a gray color instead of red. When i reverted back to ver 5.5.3 it shows up as red again. I have tried 5.5.4 and 5.5.5 and they both appear to have the same issue.

我的问题是:这是一个错误还是我需要改变我的代码更新?

My question is: Is this a bug or do I need to change my code to something newer?

编辑:这似乎只是某些pdf文件的问题。更改字体和pdf文件版本似乎没有效果。

This appears to only be an issue with certain pdf files. Changing the fonts and pdf file versions did not seem to have an effect.

比较有效的pdf和不起作用的pdf(我都不能公开分享)我注意到,不起作用的pdf是带标记的pdf,启用了快速Web视图,并由adobe pdf库生成。一个工作的pdf不是标记的pdf,没有启用快速Web视图,并且是由itextsharp创建的。

Comparing a pdf that does work and a pdf that does not work (neither i can share publicly) I noticed that the pdf that does NOT work is a tagged pdf, has fast web view enabled, and was produced by adobe pdf library. A pdf that DOES work is NOT a tagged pdf, does NOT have fast web view enabled, and was created by itextsharp.

因为我无法控制源pdf文件将会是什么是的,我恢复到一个似乎一直有效的itextsharp的早期版本。

Since I cannot control what the source pdf files will be, I reverted to an earlier version of itextsharp that seems to work all the time.

推荐答案

重现问题的第一次尝试



我刚刚执行了这些值的代码:

A first attempt to reproduce the issue

I just executed your code for these values:

        int OpacityPercent = 70;
        int PDFPaidFontSize = 20;
        string CopyStampTxt = "COPY";
        string PaidStampTxt = "PAID";
        int PDFCopyX = 100;
        int PDFPaidX = 250;
        int PDFY = 500;
        string FontPath = @"C:\Windows\Fonts";
        string ArialFilename = "ariali.ttf";
        int PDFDateFontSize = 30;
        string StampDate = "TODAY";
        int PDFDateXOffset = 0;
        int PDFDateYOffset = 35;

使用简单的源PDF,结果PDF如下所示:

with a simple source PDF, and the result PDF looks like this:

与您的观察相反


生成的pdf文字为灰色而不是红色。

The resulting pdf text has a gray color instead of red.

生成的文字颜色偏红(白色部分透明的红色)。

the resulting text color is reddish (a partially transparent red on white).

我使用iTextSharp 5.5测试过.5。

I tested using iTextSharp 5.5.5.

因此,要获得灰色而不是红色,您的变量值或源PDF必须有特别之处,它不是一般的iTextSharp问题。

To get a gray color instead of red, therefore, there must be something special about your variable values or source PDF, it is not a general iTextSharp issue.

第一个问题之后尝试重现的问题,提供OP一个示例文件检验.pdf ,的确如此此文件的相同代码的结果是:

After the first attempt to reproduce the issue, the OP provided a sample file Test.pdf, and indeed, for this file the result of the same code is:

因此,确实存在问题。

两种情况下添加的内容流操作的比较显示:

A comparison of the added content stream operations in both cases shows:


  • 第一个尝试使用我的样本PDF:

  • For the first attempt using my sample PDF:

/Xi0 gs
1 0 0 rg
BT
/Xi1 20 Tf
1 0 0 1 100 500 Tm
(COPY) Tj


  • 使用OP的示例文件进行第二次尝试:

  • for the second attempt using the OP's sample file:

    /Xi0 gs
    1 0 0 rg
    BT
    0 g
    /Xi1 20 Tf
    1 0 0 1 100 500 Tm
    (COPY) Tj
    


  • 因此,尽管使用了相同的代码,但还有一个 0 g 在后一种情况下操作,并且操作选择黑色作为填充颜色。

    Thus, in spite of the same code been used, there is an additional 0 g operation in the latter case, and that operations selects black as fill color.

    这令人非常惊讶。因此,我查看了iText代码和代码历史以获得解释(我选择了iText / Java代码,因为原始开发发生的地方和更改可以更彻底地检查)。

    This came as quite a surprise. Thus, I looked through the iText code and code history for an explanation (I chose the iText/Java code as that's where the original development takes place and changes can be inspected more thoroughly).

    事实上, PdfContentByte.beginText 以:

    if (isTagged()) {
        try {
            restoreColor();
        } catch (IOException ioe) {
    
        }
    }
    



    背景



    因此,在标记PDF的情况下,此方法重置颜色。为什么?

    Backgrounds

    Thus, in case of tagged PDFs this method "resets the color". Why that?

    查看代码历史记录会给出一些提示

    Looking through the code history gives some hints


    • 修订版5499 标记PDF支持:将图形和文本保存在一个画布中。还没准备好......

    修订版5515 现在iText可以将文本和图形写入1个画布。对于你应该设置PdfDocument.putTextAndGraphicsTogether为true。

    下面似乎有轻微的差别上述的第一块

    Here the block above first appears with a slight difference

    if (autoControlTextBlocks) {
        try {
            restoreColor();
        } catch (IOException ioe) {
    
        }
    }
    

    即只有当 autoControlTextBlocks true 时才会恢复颜色。

    i.e. here the color is restored only if autoControlTextBlocks is true.

    ...

    修订版5533 writer.isTagged属性现在决定是将所有内容写入一个画布还是单独写入。

    此处标志 autoControlTextBlocks isTagged 调用相关作家。

    Here the flag autoControlTextBlocks is replaced by a isTagged call of the associated writer.

    我的解释:


    • 为了正确支持标记的PDF,将图形和文本保存在一个画布(以前它们是在不同的创建中)是必要的或者至少是有利的最终被连接起来的画布,因此相关的图形和文本在内容中彼此远离。

    • To properly support tagged PDFs, it was necessary or at least advantageous to keep graphics and text in one canvas (formerly they were created in different canvasses which eventually were concatenated, so related graphics and texts were distant from each other in the content).

    将图形和文本保持在一起,同时保持最小的开销高级代码,一个新的 autoControlTextBlocks 模式已添加到 PdfContentByte ,它启动和停止文本ob在需要的地方自动显示并保存和恢复单独的文本颜色集。

    To keep graphics and text together with minimal overhead in the highlevel code, a new autoControlTextBlocks mode has been added to PdfContentByte which starts and stops text objects automatically where needed and saves and restores a separate color set for texts.

    此模式似乎已被选为支持iText中标记内容的方式,同时它似乎没有被认为对其他情况有用。因此,此模式现在自动用于标记文件。

    This mode seems to have been chosen as means for support of tagged content in iText while it seems to not have been considered useful for other contexts. Thus, this mode now automatically is used for tagged files.

    在我看来,这种选择并不是最佳选择。 PdfContentByte 是公开发布的iText API的一部分,它是公开宣传的(作为over content),用于对生成的或预先存在的PDF进行低级调整。引入这样的副作用违反了API合同,至少这会让人们无法升级。

    In my opinion this choice is not optimal. PdfContentByte is part of the publicly available iText API and it is publicly advertised (as "over content") for low-level tweaking of generated or pre-existing PDFs. Introducing such side-effects violates the API contract, at least it is a nuisance keeping people from upgrading.

    只需切换颜色设置和文本对象开始操作的顺序,使用

    Simply switch the order of the color setting and text object starting operations, using

    ...
    overContent.BeginText();
    overContent.SetColorFill(BaseColor.RED);
    ...
    

    结果

    如果我正确解释了最终签到,则应在iText版本5.5.6中修复此问题。

    If I interpret the final check-ins correctly, this issue should be fixed in iText version 5.5.6.

    <强> 提交 301a45b57dcef37ae0ec3625fbdd6caaf4004a3a

    commit 301a45b57dcef37ae0ec3625fbdd6caaf4004a3a

    保存和还原颜色在PdfContentByte类标签PDF文档的删除弃用逻辑(DEV-1371)。

    这篇关于版本5.5.4+中的ItextSharp字体颜色问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆