8
votes

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.

7
Have you looked at XPS/XpsDocumentWriter/etc. yet? - Logan Capaldo
@Logan Capaldo: That name sounds familiar to me... If it is that format that has native WPF control to display it than I have had look on it some time ago. But I did not figure out if there is simple way to generate such documents in WPF. I have question with no answers about it here: stackoverflow.com/questions/4634445/how-to-work-with-fixedpage . - Rasto
@Logan Capaldo: But XPS document is not fixed right ? So it does not display exactly the same layout as will be printed ? - Rasto
@drasto: Wikipedia says "Like Adobe Systems's PDF format, XPS is a fixed-layout document format designed to preserve document fidelity, providing device-independent document appearance." Seems like what you asked for. - R. Martinho Fernandes
Editing my answer again. - Mark Storer

7 Answers

4
votes

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

2
votes

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();
1
votes

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.

1
votes

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

1
votes

Sounds like you need to get some experience in GDI+.

I worked for a mortgage company and they are very particular on how they want their reports laid out. Down to pixel precision. Unfortunately GDI+ does not measure Text very well. Therefore your better alternative would be to use windows API

[DllImport("gdi32.dll")]
static extern bool GetTextExtentPoint(IntPtr hdc, string lpString, 
                                      int cbString, ref Size lpSize);

you pass the handle of the Bitmap you are drawing on. Much more accurate.

alternatively you may look into using TextRenderer

http://msdn.microsoft.com/en-us/library/system.windows.forms.textrenderer(v=VS.80).aspx

I cant make any claims as to how accurate it is.

1
votes

Our product, PDFOne .NET may suit your requirements. It comes with royalty-free commercial license.

  1. function that returns exact width for given string and given font in which text should appear
    You can use the PDFFont.GetTextWidth() method for this.
  2. ability to position text to exact position on the page
    You could use one of the many PDFDocument.WriteText() overloads for this
  3. have text with some part of it in super script
    PDF does not have any this concept in its textouts. What appears to us as a superstring is just another string with a different font size and position. You just need to call another textout for this.
  4. function to get exact width of some text that has some part of it in superscript
    Refer previous response.
  5. ability to add pictures or even better option to draw simple graphics (line of given thickness, filled circle of given radius/diameter) - PDFOne .NET has render images, squares, rectangles, arcs, Bezeir curves, ellipses, circles, rectangles, polylines, polygons, rectangles, watermarks, stamps, several types of annotations,...

PDFOne .NET also comes with a PDF printer component and PDF viewer component.

DISCLAIMER: I work for Gnostice.

0
votes
  1. LaTeX: LaTeX for PDF generation in production
  2. For Pay libraries like Aspose: http://www.aspose.com/categories/.net-components/aspose.pdf-for-.net/default.aspx
  3. plain HTML with good CSS can work pretty well too.
  4. Microsoft Open XML: http://msdn.microsoft.com/en-us/library/bb448854.aspx

For what it's worth, I think iTextSharp is the easiest one of the bunch. You can do what you want in all of them, but they each have pros and cons.