I've edited a code I found to gets all the outline data of a text so I can manually draw it as lines in some other program.
My code works great in English, but when I try to send Hebrew text the outlines turn to be in gibberish font.
The main steps of the code are:
Typeface -> GlyphTypeface -> GlyphRun
And the main code is
Private m_gtf As System.Windows.Media.GlyphTypeface
Private m_glypText As GlyphRun
Private m_textFont As System.Drawing.Font
textFont = New Font("Aharoni", 12, FontStyle.Regular, GraphicsUnit.World, 177, False)
m_typeface = New Typeface(New System.Windows.Media.FontFamily(m_textFont.Name), m_fontStyle, _
m_fontWeight, New System.Windows.FontStretch())
m_typeface.TryGetGlyphTypeface(m_gtf)
'then use m_gtf to crate the m_glyphIndices and advanceWidths vectors
m_glypText = New GlyphRun(m_gtf, bidiLevel, False, m_height, m_glyphIndices, origin, advanceWidths, _
Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
I think that my problem is with the "m_typeface = New Typeface(…"
In this command there is no way to send the font gdiCharSet value.
Is there a way to get the typeface straight from the m_textFont?
Or is there another way to do this?
Zohar
Found the problem.
I was using:
Dim glyphIndex As UShort = m_gtf.CharacterToGlyphMap(Asc(m_textString(n)))
but I had to use AscW to get the correct ascii code:
Dim glyphIndex As UShort = m_gtf.CharacterToGlyphMap(AscW(m_textString(n)))
now it works!
Zohar
Related
I'm trying to convert some itextsharp code to use itext7 which stamps text on each page of a pdf at rotate 90 degrees. Unfortunately all the examples I can find are in c# and while I can use an online translator I'm having difficulties with this one.
The below code stamps my text on at the specified coords on each page of a given pdf:
Shared Sub itext7_stamp_text_on_pdf(mypdfname As String, myfoldername As String)
Dim src As String = myfoldername & "\" & mypdfname
Dim dest As String = myfoldername & "\Stamped " & mypdfname
Dim pdfDoc As PdfDocument = New PdfDocument(New PdfReader(src), New PdfWriter(dest))
Dim document As Document = New Document(pdfDoc)
Dim canvas As PdfCanvas
Dim n As Integer = pdfDoc.GetNumberOfPages()
For i = 1 To n
Dim page As PdfPage = pdfDoc.GetPage(i)
canvas = New PdfCanvas(page)
With canvas
.SetFontAndSize(PdfFontFactory.CreateFont(StandardFonts.HELVETICA), 12)
.BeginText()
.MoveText(100, 100)
.ShowText("SAMPLE TEXT 100,100")
.EndText()
End With
Next
pdfDoc.Close()
End Sub
... but I can't see a way of rotating it to 90 degrees.
There's an example here if you use a paragraph:
https://kb.itextpdf.com/home/it7kb/examples/itext-7-building-blocks-chapter-2-rootelement-examples#iText7BuildingBlocksChapter2:RootElementexamples-c02e14_showtextaligned
... but I can't seem to translate this to vb.net. I can specify where the errors I get are, but I thought I'd be better asking this general question first in case there's a way to do this without using a paragraph.
Can anyone help please?
Thanks!
Well, after some more digging this code seems to work OK on the rotation part:
Dim pdf As New PdfDocument(New PdfReader(inpdf), New PdfWriter(outpdf))
Dim document As New Document(pdf)
document.ShowTextAligned("This is some test text", 400, 750, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0.5F * CSng(Math.PI))
document.Close()
End Sub
.... but it gets hidden behind existing content, so I need a way to make sure it's set to over content.
I have added an image to my iTextSharp PDF document like this:
Public Sub CreatePDFFromBitmap(ByVal uPath As String, ByVal uBitmap As Bitmap)
Dim nFs As System.IO.FileStream = New FileStream(uPath, FileMode.Create)
Dim nDocument As iTextSharp.text.Document
Dim nWriter As iTextSharp.text.pdf.PdfWriter
Dim nCb As iTextSharp.text.pdf.PdfContentByte
Dim nImgFromBitmap As System.Drawing.Image = DirectCast(uBitmap, System.Drawing.Image)
Dim nImg As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(nImgFromBitmap, Imaging.ImageFormat.Png)
Dim bLandscape As Boolean = (nImg.Width > nImg.Height)
'rotation needs to be set before document is being opened
If bLandscape Then
nDocument = New iTextSharp.text.Document(PageSize.A4.Rotate, 0, 0, 0, 0)
Else
nDocument = New iTextSharp.text.Document(PageSize.A4, 0, 0, 0, 0)
End If
'if an exception is raised here, the following will help: https://stackoverflow.com/questions/15833285/pdfwriter-getinstance-throws-system-nullreferenceexception
nWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(nDocument, nFs)
nDocument.Open()
nCb = nWriter.DirectContent
nImg.ScaleToFit(nDocument.PageSize.Width, nDocument.PageSize.Height) 'raises dpi size :-)))
'X-Y-Koordinatensystem 0,0 startet also unten links, nicht oben-links
nImg.SetAbsolutePosition(0, nDocument.PageSize.Height - nImg.ScaledHeight)
nCb.AddImage(nImg)
nDocument.Close()
nWriter.Close()
nFs.Close()
End Sub
It works fine.
However, when I click the image in the PDF, it gets selected.
This is not what I want.
If I click the image in the PDF, it should not be selected.
This is what it looks like: The image becomes blue:
I want to add editable fields to the PDF, so I need to make the image not selectable, else it would confuse the user.
As Abdel-Rahman Al-Qawasmi mentions in his answer, it is completely up to the PDF viewer which entities it makes selectable and which not. Thus, there is no guaranteed way to get what you want.
Nonetheless, there are ways to put an image into a PDF which dissuade current versions of most PDF viewers from making it selectable. These ways either transform the bitmap image into a non-bitmap entity (e.g. by iterating over the pixels of the bitmap and drawing a little rectangle per pixel using vector graphics) or wrap the bitmap image into something that usually is not selectable.
Let's take the latter approach and wrap the image into a page-size PDF pattern with which we then fill the actual page. You can do that by replacing your
nCb.AddImage(nImg)
by
Dim painter As iTextSharp.text.pdf.PdfPatternPainter = nCb.CreatePattern(nDocument.PageSize.Width, nDocument.PageSize.Height)
painter.AddImage(nImg)
nCb.SetColorFill(New iTextSharp.text.pdf.PatternColor(painter))
nCb.Rectangle(0, 0, nDocument.PageSize.Width, nDocument.PageSize.Height)
nCb.Fill()
(This essentially is the VB/iTextSharp pendant of the Java/iText code from this answer.)
This is a pdf program specifications and not related to asp.net or vb.net programming. you need to have control of the pdf reader settings. Or try to use another format.
There is a group somewhere in our organization that scans documents and converts them to PDFs. They then associate those PDFs with an "event" record and store them in a database. On demand, my application -- which uses Winnovative HTML to PDF v9.0.0.0 -- has to retrieve the PDFs associated with an event, place a header on the first page of each, and store them on the file system. This header is a TextElement.
On some PDFs, the header displays beautifully. On others, the header does not appear. However, when viewing the PDF, the header can be "highlighted" with the cursor and its text successfully copied, so the header is indeed present and properly positioned. (See the green arrow in the inserted image.)
I have identified two PDFs that were scanned by the same person thirty minutes apart and associated with the same event in the database. On one, the header is displayed; on the other, it is not. To investigate, I have set the BackColor of the TextElement to Crimson. The Text appears and doesn't appear as before, but the TextElement always appears bright red.
The properties of the two Document and PDFPage objects are identical, including the TransparencyEnabled property. This phenomenon is present in PDFs of all sorts of documents scanned by various people over time. And it's not just this header TextElement, but TextElements everywhere on the PDF (e.g. Page X of Y, watermarks). On a given PDF, if the Text of one is visible, the Text of all is visible, and vice versa.
I can find no pattern or explanation. What could be causing some PDFs to "hide" the Text (and only the Text) of all TextElements that I put on them while others don't?
Private Sub AddTitleToFirstPage(ByRef pdf As Document)
Dim headerSystemFont As New Font("Arial", 10)
Dim headerFont As PdfFont = pdf.Fonts.Add(headerSystemFont)
Dim headerTextElement As New TextElement(65, 20, "My Page Title", headerFont)
headerTextElement.TextAlign = HorizontalTextAlign.Center
headerTextElement.ForeColor = Color.DarkBlue
headerTextElement.BackColor = Color.Crimson
pdf.Pages(0).AddElement(headerTextElement)
End Sub
Friend Function UpdatePdfDoc(pdfBytes As Byte()) As Byte()
Dim bytes As Byte()
Using docStream As New MemoryStream(pdfBytes, 0, pdfBytes.Length)
Dim returnDoc As Document = New Document(docStream)
returnDoc.LicenseKey = WinnovativeLicenceKey
AddTitleToFirstPage(returnDoc)
bytes = returnDoc.Save()
docStream.Close()
End Using
Return bytes
End Function
Friend Function GetEventObjectPdfSource(scannedDocIds As List(Of String)) As Object
Dim scannedDocObjectPdfSourceList As New List(Of Byte())()
For Each scannedDocId As String In scannedDocIds
Dim scannedDocObjectPdfSource As Byte() = GetScannedDocBlobById(scannedDocId)
scannedDocObjectPdfSource = UpdatePdfDoc(scannedDocObjectPdfSource)
scannedDocObjectPdfSourceList.Add(scannedDocObjectPdfSource)
Next
Return scannedDocObjectPdfSourceList
End Function
Friend Function GetEventObjectPdf(eventId As String) As String
Dim pdfFileName As String = GetPDFFileName(eventId)
Dim scannedDocIds As List(Of String) = GetScannedDocumentsForEvent(eventId)
Dim objectPdfSourceList As List(Of Byte()) = CType(GetEventObjectPdfSource1(scannedDocIds), List(Of Byte()))
For Each objectPdfSource As Byte() In objectPdfSourceList
Using docStream As New MemoryStream(objectPdfSource, 0, objectPdfSource.Length)
Dim masterDoc As New Document(docStream)
masterDoc.LicenseKey = WinnovativeLicenceKey
Do While masterDoc.Bookmarks.Count > 0
masterDoc.Bookmarks.Remove(0)
Loop
Try
masterDoc.AutoCloseAppendedDocs = True
masterDoc.Save(pdfFileName)
Catch ex As Threading.ThreadAbortException
Threading.Thread.ResetAbort()
Finally
masterDoc.DetachStream()
masterDoc.Close()
End Try
docStream.Close()
End Using
Next
Return pdfFileName
End Function
Please forgive the clunky code. I didn't write it. I just inherited it.
I want to add a new FreeText comment to a PDF file with vba.
Public Sub AddAnnot(Page As Object, Text As String)
Dim Rect As Object, Annot As Object
Set Rect = CreateObject("AcroExch.Rect")
Dim Space As Integer, Height As Integer
Space = 0
Height = 15
With Rect
.bottom = Space
.Left = Space
.Right = Page.GetSize.x - Space
.Top = Space + Height
End With
Set Annot = Page.AddNewAnnot(0, "FreeText", Rect)
With Annot
.SetTitle Text
.SetContents (Text)
.SetColor RGB(255, 255, 0)
.SetRect Rect
End With
End Sub
So this code worked with older versions of Acrobat, but now in Acrobat DC, it always fails at the line .SetContents (Text) with the simple error, that the method has failed. It doesnt matter, which pdf-file it is, it always fails.
What am i doing wrong?
Thanks in advance
For everyone who was desperately searching for a solution to this, but didn't find one: Before the whole procedure of adding Annots, open the document as an AVDoc, too. You don't have to use it, just opened and it works, even when you instantly hide it.
I am using the code blow to draw text on a image which i will be adding to PDF which is working fine when i am adding English text. I would like to know how i can do this and add Arabic text. when i step through the code i can clearly see that the sting 'txtModule' is holding the text in Arabic. currenlt it is changeing the text to ????
Dim page As PdfPage = document.AddPage
page.Orientation = PageOrientation.Landscape
Dim gfx As XGraphics = XGraphics.FromPdfPage(page)
Dim XImage As XImage = XImage.FromFile("C:\Projects\CISIPR\currentPr\images\Certificate\prCertificate.jpg")
gfx.DrawImage(XImage, 20, 20, 800, 564)
Dim fontModule As New XFont("arial", 20, XFontStyle.Bold)
' Draw the Module text box
gfx.DrawString(txtModule, fontModule, New PdfSharp.Drawing.XSolidBrush(PdfSharp.Drawing.XColor.FromArgb(103, 154, 165)), _
New XRect(0, 10, page.Width.Point, page.Height.Point), XStringFormats.Center)
this code here will work in converting the font so;
Dim options = New XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always)
Dim fontModule As New XFont("arial", 20, XFontStyle.Bold, options)
You should get more than "????", but you have to enable Unicode. See this sample:
http://pdfsharp.net/wiki/Unicode-sample.ashx
But there is a show stopper: PDFsharp does not (yet) support LTR and Arabic glyphs.
I don't know what this means. Maybe it is enough to reverse the string and select initial, middle, and final glyphs in your code, maybe you cannot get correct Arabic at all.