Contents
Introduction to Placing artwork files
into print documents. 1
Source Image size, dpi, and scaling. 1
Place your logo on your paper work. 1
Place an Illustration and rotate. 1
Using Trigonometry with a clock
design. 1
52 Million Card Pickup – PDF Meltdown. 1
Print Documents and creating PDFs directly allow placing
external files onto a page. Vector (PDF) and bitmap (PNG, PJG, TIF) files may
be placed.
External files will be automatically pulled from the source
host (where the print document was created). Files are cached on filename for
better efficiency.
NOTE: Print Documents can target bitmap, PDF, and any
Windows printers. If you only want to create a PDF it is much more efficient to
use the Spludlow.Drawing.PDF class directly in code.
NOTE: When placing PDF into bitmap then GhostScript must
be installed on the host, this includes the Intranet Print Preview page.
It makes sense to size your images to the size you want them
on the page in advance. It will just make your like much simpler when arranging
the page.
For vector images the size is defined by the size of the
objects, you can select all and resize in Illustrator, you may want to flatten
transparency (convert strokes to curves).
For bitmaps you can resize them and play with the DPI to
adjust the size in Photoshop.
The place methods have a scale parameter which may be used
to scale the image. 1.0 is actual size, 0.5 half, and 2.0 double.
X & Y scaling is always at 1:1, stretching images out
always makes them look awful, you will have to do it in advance if you require
it.
Putting your logo on your emailed PDF paperwork (order
confirmations, invoices) is probably the most obvious example of placing a
file.
void Place(string filename, float x,
float y, float scale, int sourcePageNumber);
The image is placed with the top left being at the X, Y
position. Scale if you like, specify the page number (starting at 1) in PDF
files.
You can get creative by placing images and rotating them.
void PlaceAngle(string
filename, float x, float y, float scale, float angle, int sourcePageNumber);
NOTE: When doing PlaceAngle the X & Y position is the
centre of the placed image (not top, left).
Most of the time page layout is pretty simple you just
measure across and down. It gets a little more complicated when working with
circular designs, like a clock. How do you get the X & Y positions of the
hours?
The answer is the trigonometry maths functions
Math.Sin(angle) and Math.Cos(angle). It doesn’t matter how they work just look
at this code snippet:
double radians = ((angle - 90) / 180) * Math.PI;
float x = originX + (float)Math.Cos(radians) * radius;
float y = originY + (float)Math.Sin(radians)
* radius;
This is how you get the X & Y of the hours around the
clock with the angle specified in degrees (360 in a circle), the 2 “origin”
variables specify the centre and the size of the circle specified in the
“radius” variable. You can have different X & Y radiuses for ellipses.
You like cards? You like knowing the time? Let’s write some
code to make a clock face:
public static void TimeToPlayCards()
{
string deckFilename = @"D:\SpludlowDeckOfCards.pdf";
// Register all installed fonts
Spludlow.Drawing.PDFFontChest.RegisterDirectory();
// A3 page size
using (Spludlow.Drawing.PDF pdf = new Spludlow.Drawing.PDF(@"E:\CardsClockFace.pdf", "A3"))
{
// Middle of Page
float originX = pdf.Width / 2;
float originY = pdf.Height / 2;
// Figure out some radiuses
float cardRadius = 110;
float innerRadius = cardRadius - 35;
float outerRadius = cardRadius + 37;
// Draw the circles
pdf.Cirlce(originX, originY, outerRadius, 0.25F,
Color.Black, Color.ForestGreen);
pdf.Cirlce(originX, originY, innerRadius, 0.25F,
Color.Black, Color.White);
pdf.Cirlce(originX, originY, 2.5F, 0.25F,
Color.Black, Color.White);
// Put the text around the centre (* on end of font
means embed in PDF)
string font = "Rockwell*, 65";
pdf.Text("It's Time to", font, originX,
originY - 20, Color.Black, 0, StringAlignment.Center, 0, Color.Empty);
pdf.Text("Play Cards", font, originX,
originY + 20, Color.Black, 0, StringAlignment.Center, 0, Color.Empty);
// For each hour (the overlap works better backwards)
for (int hour = 12; hour >= 1; --hour)
{
// figure out the angle 360degs / 12hours
= 30
float angle = hour * 30;
// Do the maths
double radians = ((angle - 90) / 180) * Math.PI;
float x = originX + (float)Math.Cos(radians) * cardRadius;
float y = originY + (float)Math.Sin(radians) *
cardRadius;
// Place the card 3/4 scale, page number
offset to give the spades suit
pdf.PlaceAngle(deckFilename, x, y, 0.75F,
angle, 26 + hour);
}
}
}
You can download the Spludlow Deck of Cards PDF
here. Each page is a card.
Radians are an alternative way to measure rotational angles
used by the Sin & Cos functions. A complete 360 degree circle is 2 X PI
(6.28) in radians. To convert divide by 180 (half circle in degrees) and
multiply by PI (half circle in radians).
Perform calculations using doubles as some precision is
required.
When using the Sin & Cos code snippet the angle is
offset back 90 degrees to make it start at “12 o’clock”, as all the Spludlow
drawing methods do like “PaceAngle()” used in this example.
If you want to rotate in the other direction then swap Sin
& Cos around.
NOTE: For heavy tasks like this always use
Spludlow.Drawing.PDF directly.
I started with some code to draw 52 card pickup actual size
on an A0 sheet, then upped the number of decks:
using (Spludlow.Drawing.PDF pdf = new Spludlow.Drawing.PDF(@"E:\52CardPickup.pdf", "A0*"))
{
Random random = new Random();
for (int step = 0; step < 52 * 1000; ++step)
{
int page = random.Next(52) + 1;
if (random.Next(4) == 0)
page = 55;
pdf.PlaceAngle(deckFilename, random.Next((int)pdf.Width),
random.Next((int)pdf.Height), 1, random.Next(360), page);
}
}
Sending a commercial printer or designer a 52,000 card
pickup PDF makes a good wind up but how many card pickup is possible in PDF?
Putting noughts on the end I found I was able to generate
5,200,000 card pickup in just under 2 minutes with a file size of 70MB the
generating processes did not seem to use much memory.
When attempting to generate the full 52 million card pickup PDF
it was performing as before gradually increasing memory usage. About 3 minutes
in, I was expecting to take about 20, it went meltdown, my test process all of
a sudden allocates a load of extra memory and the whole system starts
thrashing. Some sort of limit must have been hit in the iTextSharp code, I
don’t think it needed the memory it tried to grab, maybe something overflowed?
Opening 5,200,000 card pickup in Adobe Reader all looked
good at first steadily grabbing memory as it renders to screen. As the memory
used by Adobe Reader gets up to 4GB the process completely dies without warning
(32 bit process then 4GB is the maximum addresses space).
So it looks like the limits in ITextSharp and Adobe Reader
are so far off I wouldn’t worry about them.
You can benchmark vector drawing applications like
Illustrator, Corel Draw, and Inkscape to see how they perform with high object
count drawings, especially when moving things around.