I am trying to develop one prototype where user can modify pdf contents. The interface where user can select area and is shown what kind of text was in selected area, works fine. But now the creating does not. For some reason, i can't seem to understand why creating new element fails silently nor how to place new element correctly in the location of old element or elements.
The code i have for creating new element is this:
style = elements[0].GetStyle()
font = Font(style.GetFont())
fontsize = style.GetFontSize()
eb = ElementBuilder()
element = eb.CreateTextBegin(font, 10.0)
writer.WriteElement(element)
element = eb.CreateTextRun('My Name')
element.SetTextMatrix(10, 0, 0, 10, 100, 100)
gstate = element.GetGState()
gstate.SetTextRenderMode(GState.e_fill_text)
gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB())
gstate.SetStrokeColor(ColorPt(1, 1, 1))
element.UpdateTextMetrics()
writer.WriteElement(element)
writer.WriteElement(eb.CreateTextEnd())
writer.End()
from core.helpers import ensure_dir
ensure_dir(output_filename)
doc.Save(output_filename, SDFDoc.e_linearized)
doc.Close()
But when i save the element then nothing appears to have changed in .pdf file. I also created stack-overflow question for this same thing, so if anyone who can help me here, can just aswell earn some stackoverflow points:P
What are your high-level requirements? It would be useful to understand this because there may be simpler way to accomplish what you need (e.g. use ContentReplacer - http://www.pdftron.com/pdfnet/samplecode.html#ContentReplacer or Stamper?)
Based on the code below it looks like you want to append some extra text to an existing page based on the font style (font name + color) used by the first word on the page. One thing to consider are optional parameters in ElementWriter.Begin(). At the same time it looks like default params should work fine.
One thing I see in your code is that you are setting the stroke color rather than fill
gstate.SetTextRenderMode(GState.e_fill_text)
gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
gstate.SetStrokeColor(ColorPt(1, 1, 1))
try
gstate.SetTextRenderMode(GState.e_fill_text)
gstate.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
gstate.SetFillColor(ColorPt(1, 0, 0)) // hardcode to red … for testing purposes only
Another problem may be with the font. You are hijacking an existing font and are assuming that this font is using ‘standard encoding’. However this font is likely not using standard encoding. Furthermore, fonts in existing PDFs are usually subsetted (this means that the font does not contain a full list of glyphs, but only character references that are present in the document). As a result, you may see notdef or whitespace instead of the expected text. This and some other issues are covered here:
https://groups.google.com/d/msg/pdfnet-sdk/RBTuJG2uILk/pGkrKnqZ_YIJ
https://groups.google.com/d/msg/pdfnet-sdk/2y8s5aehq-c/xyknr9W5r-cJ
https://groups.google.com/d/msg/pdfnet-sdk/4yJNs0_Ne38/DftXPVWakLoJ
https://groups.google.com/d/msg/pdfnet-sdk/zidmrsPEj10/3zXNHuKWkuoJ
As an solution you can use the embedded font to find a matching system font (e.g. based on font name and other properties) and create a new font. PDFNet offers a utility method Font.Create(doc, font) , or Font.Create(doc, “Font name”)
This methods will create a Unicode font so you should use eb.CreateUnicodeTextRun() rather than eb.CreateTextRun
The code example is below. It is part of Django project. This code is beeing run from django shell not within a view. So you can exclude web-server related problems from the list, i guess.
from pdfprint.pdffile.models import FileTemplate, EditableArea
f = FileTemplate.objects.get(id = 1)
from PDFNetPython2 import *
a = EditableArea.objects.filter(template = f)[0]
PDFNet.Initialize()
doc = PDFDoc(f.file.file.path)
from django.conf import settings
output_path = settings.MEDIA_ROOT+ "files/output/"
output_filename = output_path + f.file.file.path.split('/')[-1].split('.')[0] + '_edit.pdf'
doc.InitSecurityHandler()
reader = ElementReader()
element = Element()
itr = doc.GetPageIterator()
page = itr.Current()
reader.Begin(page)
rect = Rect(float(a.x1), float(a.y1), float(a.x2), float(a.y2))
page_crop = page.GetCropBox()
page_media = page.GetMediaBox()
page_bounding = page.GetVisibleContentBox()
element = reader.Next()
elements = []
text = u''
extractor = TextExtractor()
extractor.Begin(page)
line = extractor.GetFirstLine()
elements = []
while line.IsValid():
word = line.GetFirstWord()
while word.IsValid():
elRect = word.GetBBox()
elRect.Normalize()
if elRect.IntersectRect(elRect, rect):
text += word.GetString()
elements.append(word)
word = word.GetNextWord()
line = line.GetNextLine()
writer = ElementWriter()
writer.Begin(page)
style = elements[0].GetStyle()
font = Font(style.GetFont())
fontsize = style.GetFontSize()
eb = ElementBuilder()
element = eb.CreateTextBegin(font, 10.0)
writer.WriteElement(element)
element = eb.CreateTextRun('My Name')
element.SetTextMatrix(10, 0, 0, 10, 100, 100)
gstate = element.GetGState()
gstate.SetTextRenderMode(GState.e_fill_text)
gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
gstate.SetStrokeColor(ColorPt(1, 1, 1))
element.UpdateTextMetrics()
writer.WriteElement(element)
writer.WriteElement(eb.CreateTextEnd())
writer.End()
from core.helpers import ensure_dir
ensure_dir(output_filename)
doc.Save(output_filename, SDFDoc.e_linearized)
doc.Close()