ItextSharp font color issue in ver 5.5.4+

前端 未结 1 863
慢半拍i
慢半拍i 2021-01-23 05:43

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.         


        
相关标签:
1条回答
  • 2021-01-23 06:20

    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;
    

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

    enter image description here

    In contrast to your observation

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

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

    I tested using iTextSharp 5.5.5.

    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.

    Reproducing the issue using the file provided by the OP

    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:

    enter image description here

    Thus, there indeed is an issue.

    Analysis

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

    • 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
      
    • 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
      

    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.

    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).

    And indeed, PdfContentByte.beginText ends with:

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

    Backgrounds

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

    Looking through the code history gives some hints

    • Revision 5499 Tagged PDF support: keeping graphics and text in one canvas. Not yet ready...

    • Revision 5515 Now iText can write both text and graphics into 1 canvas. For that you should set PdfDocument.putTextAndGraphicsTogether to true.

      Here the block above first appears with a slight difference

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

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

    • ...

    • Revision 5533 writer.isTagged property now decides whether to write all content in one canvas or into separate ones.

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

    My interpretation:

    • 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).

    • 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.

    • 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.

    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.

    Work-around

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

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

    results in

    enter image description here

    Resolution

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

    commit 301a45b57dcef37ae0ec3625fbdd6caaf4004a3a

    Removed deprecated logic of saving and restoring color for tagged pdf documents in PdfContentByte class (DEV-1371).

    0 讨论(0)
提交回复
热议问题