EDIT: Better explanation: Before setting a bounty for this question I want to state clearer what I need:
I need .NET library for generating printable documents. Users should be able to print exactly the same document that they see either using my application or using external tool (like Adobe Acrobat reader). It does not have to be library for generating PDF documents, any document format that satisfies above condition will do.
I need the library to support following scenarios:
Scenario 1:
Scenario 2:
Note for second scenario: I have text with some parts in superscript - example AAA{v-superscript text}BBB
(where text in {}
braces is superscript). The library needs to be able to print this text using correct kerning. Without right kerning there will be the same gap between last A
and first superscript v
as between last superscript t
and first B
. For the user it will look like there is a space between A
and superscript v
but no space after the last superscript letter. So the text will look ugly. If the library is to handle this correctly it would have method to print the whole text AAA{v-superscript text}BBB
at once with specification that a part of it is in superscript. Then it would use correct kerning between normal text and superscript.
Scenario 3:
The library should be free of charge and not GPL (LGPL is ok). Is there something that allows me to do what I need ? Can it be done with iTextSharp (version 4.1.6 that is LGPL not AGPL)? Or perhaps with Fixed document ? Thank you for any suggestions.
Original question:
I need to typeset complex documents in .NET (C#) application for the user. Primary use of those documents will be for printing.
Documents will contain text and simple generated graphics. Layout of text and graphic will be complex and needs to be computed (in another words text position in document needs to be controlled by my code, it will not be done automatically by chosen library).
Here are my API requirements:
It does not have to be library for creating PDF documents - any other "what you see is what will be printed" document format will also do. If there is WPF component that can displays such documents it is an advantage. I know there is iTextSharp but is not easy to achieve 4. requirement with iTextSharp. Of course some PDF generation library that satisfies requirements above will be great solution too.
Thank you for ANY suggestions, I'm also happy to provide details or clearer explanation.
You can look to Docotic.Pdf Library (disclaimer: I work for Bit Miracle). It has user-friendly API and good set of samples that you can view online or run in sample viewer application.
Also it satisfies your requirements:
You can use the PdfCanvas.MeasureText() method for this.
There are many overloads that allows to show text in arbitrary position or area.
http://bitmiracle.com/pdf-library/help/pdfcanvas.drawstring.aspx
http://bitmiracle.com/pdf-library/help/pdfcanvas.drawtext.aspx
The PdfCanvas.TextRise property allows to show superscript text. You can use it in combination with PdfCanvas.FontSize property for control a size of superscript text. The sample: http://bitmiracle.com/pdf-library/help/text-rise.aspx
If you will use different font or font size for superscript text the direct call of PdfCanvas.MeasureText() method will produce incorrect results.
There are workarounds:
-measure each part of string drawn with different fonts separately and then sum all widths.
-if you want to get width of drawn text you can simply subtract initial text position from the final text position after drawing.
Supported. Look at these samples:
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Graphics
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Images
PDF viewer component is in our plans, but currently Docotic.Pdf doesn't offer such functionality.
Update: You can now rasterize, render, or print PDF documents using Docotic.Pdf. Look at the following articles:
https://bitmiracle.com/pdf-library/convert-pdf-to-image.aspx
https://bitmiracle.com/pdf-library/draw-print-pdf.aspx
Rather than looking for other libraries, how about looking for a better way to compute the width of mixed-size/style text?
float width = ColumText.getWidth(phrase);
Phrase extends ArrayList with various text layout functions and attributes. Paragraph extends Phrase. Each chunk has a specific Font
with its own color, size, and underlying PDF font. Each chunk has its own "text rise" to adjust its baseline.
What version of iText are you using? ColumnText has been around for Quite Some Time.
So you want kerning between normal & superscript letters? That doesn't sound like a very good idea to me. Kerning is an adjustment so 'T' can overhang "j" for example. Kerning values assume a shared baseline and font size. You'll never share a baseline, and almost certainly have different font sizes when dealing with superscript text. And even if you decide it's a good idea to use those values (and I'd disagree), do you kern in the base text's point size, or the superscript's font size?
My point is that I think your goal here (kerned superscript/subscript text boundaries with normal text) is going to result in worse layout, not better.
Or am I misunderstanding you? Let me re-read your comment:
But when you also want to position it this text that includes superscript on the page you need to use PdfContentByte.
Not entirely sure what you mean there. If you want to place text in an arbitrary location on the page, yes, you're pretty much required to use PdfContentByte
.
When using it I did not find the way to print complex text that includes superscript at once.
All the text in a given "show text" command must share the same font/size/color/etc. That's the way PDF works, its not some limitation of iText.
I think it only allows to print one text chunk in the time.
Correct.
So I cannot measure text with superscript taking kerning into account and then put it on the some position on the page
You need to add all the widths of the different chunks together. I can't believe kerning between normal and superscript text is a good idea, but a PDF sample showing the problem could persuade me otherwise.
It seems to me you need to use BaseFont.getWidthPointKerned(String text, float fontSize)
. Superscript, subscript, or normal, it's all about the point size and font. And if you Absolutely Insist, you can use BaseFont.getKerning(int c1, int c2)
to get the kerning value between any two letters within the same font, and use that to determine inter-chunk kerning.
Another way to draw text with iText & PdfContentByte
is with ColumnText
. I believe iText uses ColumnText when laying out paragraphs, but I'd have to go look at the code to be sure.
At any rate, your code might look something like this:
ColumnText colTx = new ColumnText(contByte);
// paragraphs are phrases.
colTx.addText(phraseWithSuperAndSubScriptStuff);
colTx.setSimpleColumn(llx, lly, urx, ury);
colTx.go();
Here is an article on constructing FixedDocument objects on MSDN.
If you are using WPF, and you want to create Print Quality documents, the FixedDocument and XPS technologies built in are probably what you should be learning. And since you can eventually access the entire FixedDocument in the object model, it may tell you your width numbers as well. I haven't experimented with that yet.
I think you might be overthinking your problem, while WPF has great printing abilities. You can print any visual (visuals are almost all WPF classes) exactly as you see them on the screen in a really easy way. There is a good tutorial here: http://www.switchonthecode.com/tutorials/printing-in-wpf
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With