C# PDFSharp and MigraDoc generating a table without wasting space - c#

I recently started a project using PDF sharp + Migra Doc and I encounter a problem which I have seen in other posts, there is no fixing automatically. Table row will be generated on the next page if it doesn't have enough space and if there is still not enough space it will just go into the border and the text is lost. I am thinking of a workaround but I am not sure exactly how it can be done.
My think is as follows:
If I am able to check how many lines of text can fit in cell with the given string I can create a variable and increase it every time I add text. with the excess of text I can simply create a new row (which will be automatically be added on the next page) and thus fixing my problem. Even if I am not counting lines, is there a way to check if the row becomes too large for the current page? If at a given time I can check if the cell is too large and will be automatically sent to the next page I can trim the string up to the point it will fit, save the remaining words that didn't fit and maximise the space within the page.
this is how the document is generated currently
Is there a way to workaround this? That white space is useless and a waste of resources when it comes to a 30-40 pages document.

One extreme option: Make the layout in your code and use PDFsharp to draw the text.
See also:
https://forum.pdfsharp.net/viewtopic.php?f=8&t=3192
A MigraDoc cell can contain a mix of different fonts with different font attributes (regular, bold, ...) and sizes. Measuring the size and creating a new row can become complicated if you mix different fonts, but it can be simple if you only use a single font for your cell.
See also:
https://forum.pdfsharp.net/viewtopic.php?f=8&t=3196
The space problem with tables occur if table rows are rather large (more than just one or two lines of text). Maybe tables are not the best option to present the information. How strict are your requirements? Can you get away from tables?

The solution that finally worked was as follows:
set up the style for the document including the header
depending on the data used create a for-loop which will input the desired rows in the table
top of the loop must add a row in the document
save in a variable how many pages the document currently contains(initially declare as 1 before entering the loop)
clone the document checking if the document you are passing contains the same number or more than the current document. If the document contains more pages means that the row you inputted exceeds the page. I was able to achieve this by rendering the document every time I was adding a new row.
an inner loop is necessary to trim the text within the row. The way I did it is split the text into sentences and if it contains more than 3 sentences trim, otherwise just let go to the next page.
make sure you always delete the last row on the inner loop otherwise you will end up with the same data
It might not be the most efficient way but it renders 30+ pages documents in tables under 2 seconds on Azure servers. I hope this helps someone at some point.

Related

Procedurally generating a maze without 'cycles'

I wanted to write an algorithm which could generate a 'maze' like structure within a closed room. [This is not a typical maze. I just want some walls here and there within the room.]
The catch is that I don't want any 'cycles'.
eg:
I want this:-
I do not want this:- [Here the bot is stuck as it cant access the rest of the room]
I understand this as not having cycles in the wall structure. So I thought of one solution: Generate a wall segment and then after generation check for cycles (if there are cycles, regenerate), but that seemed tedious as I'd have to encode stuff in a graph, so I thought of another solution.
Generate a wall segment and then choose an empty cell and see if you can reach all other empty cells from that cells (if not, regenerate). This one seemed promising but I did not know where to start.
Moreover these solutions don't address the elephant in the room: to generate the walls correctly in the first place! Moreover, one can't truly talk about the time complexity of the former algorithms.
How should I proceed with this problem?
P.S: I am using doing this in Unity with C#.
The recursive division maze generation method does what you want. https://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_division_method
From the pictures you posted, you want wide open 'rooms', so you will want to stop the algorithm early. Instead of "until all chambers are minimum sized" you can specify required minimum size greated than 1.
Generate a wall segment and then choose an empty cell and see if you can reach all other empty cells from that cells
If you still wanted to use that idea, then one way to do that is to use a flood-fill algorithm to count the reachable tiles from the start location and confirm that it is the same as the number of empty tiles in total.
This page is part of a larger tutorial that contains a more detailed description of this idea. See the “Banishing disconnected islands (a roguelike developer's greatest enemy)” section.
Your problem is a little different than the standard "maze generation" algorithms, because you want to allow cycles in the path, just no cycles in the walls, and I think this is an important part of the game.
So, I would solve this using a variant of Kruskal's algorithm that satisfies this requirement.
Level 1
Initialize a disjoint set data structure. Make a set for every cell. Whenever we fill a cell with wall, we will merge its set with the sets of all adjacent filled cells (including diagonal neighbors).
Fill in all the border cells and merge their sets as indicated above.
Make a list of all the unfilled cells
Repeat the following until the list of unfilled cells is empty:
Choose an unfilled cell from the list at random.
Check the sets of its 8 neighbors. If any two of them are in the same set, then filling this cell would create a wall cycle. Discard it.
Otherwise, fill the cell, merging its set with its filled neighbors, and go back to step 4.
When you're done, you will have a pretty dense maze -- it will be impossible to fill any empty cell without creating a wall cycle. If you want a bit more space, you can remember and undo the last fills, or you can just stop filling after a certain number of cells are filled.
Level 2
Instead of using just one list of unfilled cells, divide them into buckets based on the pattern of their neighbors -- eight neighbors filled or unfilled makes 256 possible neighbor patterns.
Then, instead of choosing from the whole bunch randomly, assign different weights to each pattern and assign cells in that bucket a different probability.
This gives you a lot of power to adjust the character of the mazes you create until you find one that's right for you. Maybe you want avoid filling cells adjacent to walls, because that makes your maze too blocky. Maybe you want to prefer filling cells that continue the end of an existing path. Maybe you want to avoid filling cells that make diagonal connections. You can play with the weights you want until you get mazes you like.
I've done a similar thing with more traditional mazes here. Try adjusting the weights.
Note that this algorithm is very fast, with or without level 2. There is no backtracking/retrying, and operations on the disjoint set structure are effectively constant time, which makes the whole thing pretty much O(n)

How to add a footer as a watermark so that it can be removed later

I have some scanned PDF documents (pretty flat, no selectable text, tags, objects, etc) and I would like to add a footer that can also be removed after being added. However, if it overwrites on top of anything, I want to remove the footer only. We can assume that, after the watermark is added, it won't be rescanned, changed, or flattened. (I should mention, in case any iText employees see this question, that my organization has recently purchased a license but I just started this project and I am waiting to have it sent to me so I can register for official support.)
I found an excellent answer for adding and removing watermarks here: iText 7 - Add and Remove Watermark on a PDF . My problem, as stupid as it might sound, is I'm really struggling with getting the variables right, even after lots of trial and error. The scanned documents seem to be coming in as portrait (when viewed in a PDF viewer) but they have a rotation of 270 such that, PdfDocument.GetPage(i).GetPageSize() and GetPageSizeWithRotation() have the height and width reversed and I need to take this into account but also don't want to assume that this is always the case. The footer should be centered at the bottom of the page.
The method signature can be as in the link provided (https://stackoverflow.com/a/45225597):
public static void WatermarkPDF(string sourceFile, string destinationPath)
Thank you in advance for the help and support.
Okay, BIG TIME EDIT: requirements are changing. In fact, they want to be able to have 2 lines of text as a left aligned header and have the ability to remove or replace either or or both AND additionally, have a right aligned footer that also can be removed or replaced. Not sure anymore if this should be implemented as a watermark. Again, I can assume that, once I add the headers and/or footers, the document won't be reflattened or edited in any major way... so, if they are added as elements, they should be able to be removed as elements but the problem is the scanned documents have no structure to begin with anyway (at least they don't seem to so far). So, there's no parent element, tag, or whatever.

how to manage space between growing parameter fields in Crystal reports?

In a Crystal report I am passing two text strings from C# application. Both parameters are text string paragraphs basically which can have any no of words in them.
The issue is I am not able to manage spacing between both paragraphcs. As they are dynamic I can't fix their hieghts. If there is more text passed one top paragraphc over laps the bottom paragraph but if there is less text in top paragraph report shows big area as empty space.
What ever the amount of text may be, the requriement is paragrachs should have constant space between them (two line breaks). Please guide me how I can manage it.
Thanks
Put these fields in different subsections.
Put those Parameteres inside a Text Object and then set Can Grow property of the Text Object as True.
Try this and get back with your results.

Simple Custom Grid Control

I'm designing a Point and Figure Charting program, and my first version used the DataGridView control, which I found to be too big and bloated for my needs. All I need is a simple control that displays a square grid which will be filled with X's and O's.
The data is parsed from yahoo finance as Open, High, Low, Close data, sorted by a set of rules and converted to an Int Array, which will correspond with the index of the rows, so the simpler the control is, and the less bloat is has the more efficient it will be when chewing through large amounts of data.
I also need to be able to easily adjust the size of the squares in the grid, to zoom in and out of the data.
I am unfamiliar with creating custom controls (But willing to learn), and I'm not having a lot of luck with the search terms I'm using, so any help pointing in the right direction would be appreciated.
I've implemented a couple of custom controls like this before usually colour/graphics related stuff and they usually end up being more work than you imagine.
In the last project where I needed to do custom display stuff (a massive matrix of TCPConnection status between many different machines) I just used Xceed's gridControl and dynamically added the columns to the control. I kept an internal dictionary of the index of the column I added so that subsequent rows could benefit from direct reference to the column.
There are many different grid controls that you could probably utilise. Or if you want to get down and dirty with a Custom Control using the *Pain*t stuff you can do that too.
property for Columns, Rows .. Calculate the Space available then draw your Horiz/Verticals then draw you other values in the correct spaces, but eek prepare to invest quite a bit of time getting it "just right"

Get height of rendered text and images in MS Word

I'm creating a newspaper authoring system. Today I'm using Aspose.Words library to generate newspaper using Docx format as output, based on a lot of other documents as input.
The basic idea is to load a lot of articles documents into a List, then generate a final docx with newspaper.
We need to get the total height of a text (with images and tables) inside columns. As libraries like Aspose.Words deal with Docx format like DOM, there isn't way to know how text will be arranged inside columns. Then I can't know the real height.
We've worked in our own way to get this height. I'm using MeasureString() function from System.Drawing.Graphics namespace. It returns width and height used by string and I can estimate how many lines (and points or inches) it will use inside a column.
But it is very poor and we need a more decent solution. We are thinking to use OpenXML SDK to get this Height, can we?
Aspose.Words doesn't support a way to know it and all Render classes are private to the library.
Can you think a new way to get this height?
Thank you,
Daniel Koch
This property isn't exposed in Open XML or the SDK (or VBA/VSTO for that matter). How exactly the height is calculated is not in any documentation. Possibly the way you are doing it is a way to proceed.
Another possible way is to put your TextColumns in a Table Column/Cell and grab that height (but if it is two text columns in the cell and the first one "fills" the cell top to bottom and the second one doesn't, you'll still have the issue of not being able to calculate the size of the second one).
I have almost the same problem that you have.. But in my case I'm dealing with Questions inside an Test Exam..
Well nowadays, we are using RTF to build the questions and a RichTextBox the measure the height.. Just like that (http://blogs.technet.com/david_bennett/archive/2005/04/06/403402.aspx)..
And I wanna to migrate to DOCX.. But still no luck on how to measure the question with tables and images.. :-(
Right now I'm studying the Document Members (http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word._document_members.aspx), to try to do with Word Automation..
Regards,
Bruno
Thank all for answer.
I finished it changing Aspose.Words to PDFLib. Now I can control pages, columns or anything using Postscript Points.
We keep Aspose.Words only to content import, but it isn't indicate to print newsletter.

Categories

Resources