Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET library for typesetting documents (PDF or similar)?

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:

  1. I create text in some font and color.
  2. I ask the library for the width if this text if printed.
  3. I compute position([X,Y] coordinates on page) of this text based on information from 2. and have the library to print in at this position on a page.

Scenario 2:

  1. I create a text with some parts of it in superscript. All parts of text (normal and superscript) are in same (but variable) font.
  2. I ask the library what is the width if this text when printed. I get correct answer that also takes kerning between normal text and superscript into account.
  3. I compute position([X,Y] coordinates) on a page where this text should be printed (using its width from step 2.). I let the library to print it at this position. Printed on the page it has exactly the width that was returned by library in previous step.

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:

  1. I want to print picture that consists of lines, circles, filled circles, letters and bezier curves on exact point in a page. I need to specify width of lines and circles. All shapes needs to be printed in pixel precision.

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:

  1. function that returns exact width for given string and given font in which text should appear
  2. ability to position text to exact position on the page
  3. have text with some part of it in super script
  4. function to get exact width of some text that has some part of it in superscript
  5. ability to add pictures or even better option to draw simple graphics (line of given thickness, filled circle of given radius/diameter)

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.

like image 950
Rasto Avatar asked Apr 12 '11 00:04

Rasto


4 Answers

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:

  • function that returns exact width for given string and given font in which text should appear

You can use the PdfCanvas.MeasureText() method for this.

  • ability to position text to exact position on the page

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

  • have text with some part of it in super script

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

  • function to get exact width of some text that has some part of it in superscript

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.

  • ability to add pictures or even better option to draw simple graphics (line of given thickness, filled circle of given radius/diameter)

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

like image 186
Vitaliy Shibaev Avatar answered Oct 13 '22 16:10

Vitaliy Shibaev


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();
like image 33
Mark Storer Avatar answered Oct 13 '22 18:10

Mark Storer


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.

like image 40
Dave White Avatar answered Oct 13 '22 17:10

Dave White


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

like image 44
Martín Coll Avatar answered Oct 13 '22 16:10

Martín Coll