Welcome Guest Search | Active Topics | Sign In | Register

table of contents lines and page numbers Options
Becky
Posted: Wednesday, May 30, 2012 2:41:58 AM
Rank: Advanced Member
Groups: Member

Joined: 5/24/2012
Posts: 45
Hi,
I thought I had this figured out but I have two questions.

1. How do you set the line to be a dotted line?
I have content.linewidth = 1.0f
content.strokingcolor = new eo.pdf.drawing.pdfcolor(color.black)
content.action = eo.pdf.contents.pdfpathpaintaction.stroke

but I don't see what to set content.linedashstyle to in order to make it a dotted line.

Also - I am saving the location of my toc entries and their length after converting to pdf so I can draw a line in the toc from each entry on the left to its corresponding page number on the right.

Code: Visual Basic.NET
For n As Integer = 1 To TOC_ENTRIES_COUNT
            Dim tocEntryID As String = String.Format("TOCEntry_{0}_ID", n)
            Dim tocTargetID As String = String.Format("TOCEntry_{0}_Target_ID", n)
            refDiv = result.HtmlDocument.GetElementById(tocEntryID)
            refDivT = result.HtmlDocument.GetElementById(tocTargetID)
            arrTOC(n - 1, 0) = refDiv.Location.X   'x of toc entry
            arrTOC(n - 1, 1) = refDiv.Location.Y   'y of toc entry
            arrTOC(n - 1, 2) = refDiv.Location.Page.Index  '0 start, ok -this is actual page
            arrTOC(n - 1, 3) = refDivT.Location.Page.Index + 100 - arrPages(0, 1) 'page numbering starts at 100
            arrTOC(n - 1, 4) = Len(refDiv.InnerText)   'length of toc entry
        Next


The x location is always the same for every line even though the subheadings are indented.
And the length (arrTOC(n-1,4)) is different for each entry. It is counting the number of characters but the characters do not seem to be the same width so I cannot come up with a formula that will figure out where to start the line for each entry. Sometimes the line is too close and sometimes too far away. I have broken the entries up into groups by length but it is still not as uniform as I would like it to be.

Code: Visual Basic.NET
For K As Integer = 0 To TOC_ENTRIES_COUNT - 1
            Dim TOCNumber As Acm.AcmText
            Dim TOCpgNumRender As Acm.AcmRender

            'create line and page number for TOC entry
            'Create an AcmText representing the toc page number
            TOCNumber = New Acm.AcmText(arrTOC(K, 3).ToString)
            TOCNumber.Style.FontSize = 11.0F

            'Create an AcmRender to render the page number and line
            'The arguments are:
            ' First argument: the target page
            ' Second argument: the "Y" position
            ' Third argument: The paper margins in left, top, right, bottom order
            TOCpgNumRender = New Acm.AcmRender(doc.Pages(arrTOC(K, 2)), arrTOC(K, 1), _
                New Acm.AcmPageLayout( _
                    New Acm.AcmPadding(7.35, 0.004, 1, 0)))
            'Render the page number
            TOCpgNumRender.Render(TOCNumber)

            'now create the line between the toc entry and the page number
            'Add a new page
            Dim TOCpage As EO.Pdf.PdfPage = doc.Pages(arrTOC(K, 2))

            'Create a new PdfPathContent
            Dim content As New EO.Pdf.Contents.PdfPathContent()

            'Create a new sub path and set the sub path's starting point
            Dim subPath As New EO.Pdf.Drawing.PdfSubPath()
            'subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 0) * 72) + (arrTOC(K, 4) * 7.8), 785 - (arrTOC(K, 1) * 72))
            If arrTOC(K, 4) >= 69 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.02) + 20, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 60 And arrTOC(K, 4) < 69 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.1) + 25, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 52 And arrTOC(K, 4) <= 60 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.02) + 30, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 32 And arrTOC(K, 4) <= 52 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.7) + 45, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 22 And arrTOC(K, 4) <= 32 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.9) + 50, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 14 And arrTOC(K, 4) <= 22 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 7.9) + 70, 785 - (arrTOC(K, 1) * 72))
            ElseIf arrTOC(K, 4) > 8 And arrTOC(K, 4) <= 14 Then
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 8.2) + 75, 785 - (arrTOC(K, 1) * 72))
            Else
                subPath.From = New EO.Pdf.Drawing.PdfPoint((arrTOC(K, 4) * 8.3) + 80, 785 - (arrTOC(K, 1) * 72))
            End If
            'Draw a line from the current position to the right edge
            Dim line As New EO.Pdf.Drawing.PdfPathLineSegment(New EO.Pdf.Drawing.PdfPoint(527, 785 - (arrTOC(K, 1)) * 72))
            subPath.Segments.Add(line)

            'Add the sub path into the path
            content.Path.SubPaths.Add(subPath)

            'Stroke the path
            content.LineWidth = 0.75F
        '    content.LineDashStyle =
            ' If K Mod 2 = 0 Then
            '     content.StrokingColor = New EO.Pdf.Drawing.PdfColor(Color.Red)
            ' Else
            content.StrokingColor = New EO.Pdf.Drawing.PdfColor(Color.Black)
            ' End If
            content.Action = EO.Pdf.Contents.PdfPathPaintAction.Stroke

            'Add the path into the page
            TOCpage.Contents.Add(content)

        Next


I know you mentioned drawing the line in the html but I think I would have the same problem. I want the line to start a space or two after the entry ends and go to a specified spot on the right side of the page. But each entry is a different length so how do I know how long to make the line? I do not want to use tables. I don't want things in columns but free-form more or less. And the table of contents is created on the fly since each user can add or delete each section so I never know ahead of time what is in the manual.

Oh - one last thing - The pdf file renders differently on my local machine than it does once I upload it to the server. Then my tester said it looked different on her machine (running from the server) than it does on my machine (running from the server) Is this due to different versions of web browsers on client machines? Or am I doing something wrong?

Thanks for any insights,
Becky
eo_support
Posted: Wednesday, May 30, 2012 9:40:35 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,195
Hi,

You are definitely doing things the hard way unnecessarily. ; ) Using HTML to render TOC would be much easier.

As to your questions:

1. You would set the Content's LineDashStyle to render dotted line. It will be something like this:

Code: Visual Basic.NET
content.LineDashStyle = New PdfDashStyle(New Single(){1, 1}, 0)


Here the two numbers {1, 1} are important. The exact meaning of these two numbers is a bit difficult to explain but you can roughly think they as the solid/space ratios. So if you increase the second number it would increase the space between the dots, and if you increase the first number it would become a dash line increase of a dotted line. You can play with these two numbers until you find the right one for you;

2. It is very normal that all the TOC's X position are the same for you. Usually for a text element, the element is the "box", inside the box there are paddings and the text and possibly other nodes such as images. When you get the element's position and size, you are getting the box's location and size, not the text's location and size. A very typical scenario is if you have a <P> element, then it's width is ALWAYS the same as page width (the same as <DIV>) even if you only have a single word in it. This is by definition a <P> takes full width. Here the "box" and the "text" are two different nodes, and their location and dimensions are different.

To solve this problem, you can make sure your text has its own inline element. Usually you can use a <SPAN> to achieve that. For example:

Code: HTML/ASPX
<p>
    <span>Chapter 1</span>
</p>


If you try to get the span element, you will get the exact location and size of text "Chapter 1". Note <span> is an inline element (as opposed to a "block" element). An inline element takes minimum width instead of full available width.

3. You can not use text length to calculate text width. Most fonts are variable width fonts. For example, "W" almost always takes more space than "I" is almost every font except for those stone age "type writer" or "terminal" style font. Use the method described in #2 to measure text width;

4. The result PDF file will be different if fonts are different on different systems. We do not rely on any external browsers ---- we have our own "browser" embedded inside our DLL, so our converter functions independently regardless what client browsers the user's machine has, or whether the client machine has a browser or not for that matter. However we do rely on fonts installed on the user's system (it is not technical possible for us to embed all possible fonts inside our product because there are so many fonts out there, nor is it legally doable due to copyright issues). And different systems, or different version of Windows do have different font files --- sometimes different version of the same font. In that case the result will be different. So it is normal that the final result varies slightly on different systems.

However once the PDF file is generated, the font data will all be embeded in the PDF file. So the same PDF file will look exactly the same on different system. In fact this is exactly what the "P" (portable) means in "PDF" and that's one of the key reason why PDF is so popular.

Hope this helps. In any case, using HTML to create lines will definitely be a lot easier for you. HTML is very expessive and can be easily verified/debugged with a browser before you feed it to the converter. Beside, there is no escape to all those HTML details (such as block element, inline element, text node, CSS, etc) regardless which method you use --- you will run into those issues as you did with the text location/size issue even using PDF Creator interface. You got to deal with them either way. So it would certainly make sense for you to just focus on HTML.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.