How to read the text of the appearance stream?

I have a PDF where the text shown in the annotation (as shown in Adobe Reader) is different from the text specified in its / Contents and / RC . This is due to the problem I encountered in this question:

Unable to edit / Annotation content

In this case, instead of changing the appearance in accordance with the contents of the annotation, I want to do the opposite: get the text of the appearance and change the / Content and / RC values ​​to match. For example, if the annotation displays “appearance” and / Content is set to “content”, I want to do something like:

void setContent(PdfDictionary dict)
{
 PdfString str = dict.GetAsString(new PdfName("KeyForAppearanceText"));
 dict.Put(PdfName.CONTENTS,str);
}

But I can not find where the text of the appearance is stored. I got the dictionary referenced by / AP with this code:

private PdfDictionary getAPAnnot(PdfArray annotArray,PdfDictionary annot)
        {
            PdfDictionary apDict = annot.GetAsDict(PdfName.AP);
            if (apDict!=null)
            {
                PdfIndirectReference ap = (PdfIndirectReference)apDict.Get(PdfName.N);
                PdfDictionary apRefDict = (PdfDictionary)pdfController.pdfReader.GetPdfObject(ap.Number);
                return apRefDict;
            }
            else
            {
                return null;
            }
        }

This dictionary has the following hashMap:

{[/BBox, [-38.7578, -144.058, 62.0222, 1]]} 
{[/Filter, /FlateDecode]}   
{[/Length, 172]}    
{[/Matrix, [1, 0, 0, 1, 0, 0]]} 
{[/Resources, Dictionary]}

/ Resources has indirect links to fonts, but without content. Thus, it seems that the appearance stream does not include content data.

Other than / Content and / RC , it looks like there should be nothing in the annotation data structure that stores content data. Where should I look for the contents of the look?

+1
source share
1 answer

, OP PDF. , , , , . , PDF . , :

sampleTypewriter.pdf screenshot


/ /RC, , , , . ?

OP , PdfDictionary:

PdfIndirectReference ap = (PdfIndirectReference)apDict.Get(PdfName.N);
PdfDictionary apRefDict = (PdfDictionary)pdfController.pdfReader.GetPdfObject(ap.Number);

PdfStream, , - , .

, , OP:

PdfString str = dict.GetAsString(new PdfName("KeyForAppearanceText"));

, . :

0 w
131.2646 564.8243 180.008 30.984 re
n
q
1 0 0 1 0 0 cm
131.2646 564.8243 180.008 30.984 re
W
n
0 g
1 w
BT
/Cour 12 Tf
0 g
131.265 587.96 Td
(This ) Tj
35.999 0 Td
(is ) Tj
21.6 0 Td
(written ) Tj
57.599 0 Td
(using ) Tj
43.2 0 Td
(the ) Tj
-158.398 -16.3 Td
(typewriter ) Tj
79.199 0 Td
(tool.) Tj
ET
Q

, - , , " ".

, .

:

for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
    Console.Write("\nPage {0}\n", page);
    PdfDictionary pageDictionary = pdfReader.GetPageNRelease(page);
    PdfArray annotsArray = pageDictionary.GetAsArray(PdfName.ANNOTS);
    if (annotsArray == null || annotsArray.IsEmpty())
    {
        Console.Write("  No annotations.\n");
        continue;
    }
    foreach (PdfObject pdfObject in annotsArray)
    {
        PdfObject direct = PdfReader.GetPdfObject(pdfObject);
        if (direct.IsDictionary())
        {
            PdfDictionary annotDictionary = (PdfDictionary)direct;
            Console.Write("  SubType: {0}\n", annotDictionary.GetAsName(PdfName.SUBTYPE));
            PdfDictionary appearancesDictionary = annotDictionary.GetAsDict(PdfName.AP);
            if (appearancesDictionary == null)
            {
                Console.Write("    No appearances.\n");
                continue;
            }
            foreach (PdfName key in appearancesDictionary.Keys)
            {
                Console.Write("    Appearance: {0}\n", key);
                PdfStream value = appearancesDictionary.GetAsStream(key);
                if (value != null)
                {
                    String text = ExtractAnnotationText(value);
                    Console.Write("    Text:\n---\n{0}\n---\n", text);
                }
            }
        }
    }
}

public String ExtractAnnotationText(PdfStream xObject)
{
    PdfDictionary resources = xObject.GetAsDict(PdfName.RESOURCES);
    ITextExtractionStrategy strategy = new LocationTextExtractionStrategy();

    PdfContentStreamProcessor processor = new PdfContentStreamProcessor(strategy);
    processor.ProcessContent(ContentByteUtils.GetContentBytesFromContentObject(xObject), resources);
    return strategy.GetResultantText();
}

,

Page 1
  SubType: /FreeText
    Appearance: /N
    Text:
---
This is written using the 
typewriter tool.
---

, , , , .

+3

All Articles