Background Color:
 
Background Pattern:
Reset
Search
Home Recent Changes Show All Pages

Units and measurement

Not Rated Yet

When working with page layout in scryber, it is important to understand the default units and how measurements are made on the page.
At the heart of these are the main structures : PDFUnit; PDFSize; PDFPoint; PDFRect and PDFThickness

Article Contents

Scryber.Drawing.PDFUnit

A single unit is a combination of a magnitude and a scale.
For example 72pt or 1in or 25.4mm. All these are equivalent as there are 72 points in an inch and 25.4 millimetres. If no scale is provided then Points (a typographic Point, not an XY position) is used by the scryber library. There is no equivalent of the pixel measurement in scryber as it is a display agnostic description of a page.

    <pdf:Page style:width="210mm" style:height="290mm" style:border-width="1" >
    .....
    </pdf:Page>
    PDFPage page = new PDFPage();
    page.Width = new PDFUnit(210, PageUnits.Millimeters);
    page.Height = new PDFUnit(290, PageUnits.Millimeters);
    page.BorderWidth = 1;//implicict cast to point value

The PDFUnit supports only the 3 units specified

pt
PageUnits.Points
in
PageUnits.Inches.
mm
PageUnits.Millimeters

However the actual value is always stored within the PDFUnit structure as a double representation of Points.

This makes calculations fast and accurate with no required conversions during calculation, and only the extraction of the value requiring re-conversion back to the specified unit. This is actually done very infrequently within the library and most extraction is to retrieve the PointsValue rather than the units value - because points are what PDF documents use (by default).


Unit Calculations

For .NET languages that support operator overloading (inc. C#) the PDFUnit structure offers full comparison and calculation operators, that can be used within program flow.
PDFUnits also include conversion to and from string values with units (mm, pt, in).

            PDFUnit seventytwo = new PDFUnit(72, PageUnits.Points); // 72pt
            PDFUnit oneIn = PDFUnit.Inch(1); // 1in

            System.Diagnostics.Debug.Assert(seventytwo == oneIn) //compare independant of units
     
            PDFUnit sum = seventytwo + oneIn;
            PDFUnit converted = PDFUnit.Convert(sum, PageUnits.Millimeters);

            string s = converted.ToString(); 
            System.Diagnostics.Debug.Assert(s == "50.8mm");

            PDFUnit parsed = PDFUnit.Parse(s); //conversion back from a string

            parsed *= 2; //double it, retaining units

            s = parsed.ToString();
            System.Diagnostics.Debug.Assert(s == "101.6mm");

            System.Diagnostics.Debug.Assert(parsed / 4 == 72); //implicit conversion from number to Points value
            

For those languages that do not support operator overloading there are matching static methods on the PDFUnit class - Add, Subtract, Divide, Multiply, Equals, NotEquals etc.

Points, Sizes, Rects and Thickness

Most of these structures are direct matches to the System.Drawing structures in the core framework. but store their values as PDFUnits, rather than integers or floats

PDFPoint
A location specified in vertical and horizontal units (X,Y). Supports comparison to another PDFPoint or Empty and the equatable operators.
PDFSize
A vertical and horizontal dimension (Width and Height). Also supports comparison to another PDFSize or Empty and the equatable operators.
PDFRect
A rectangle structure with a top, left, width and height. Includes properties for Location and Size of PDFPoint and PDFSize, a property for IsEmpty - if all values are zero, and also calculation and manipulation methods for comparison, containment, insetting inflating, union and intersection.
PDFThickness
Whilst there is no direct .NET matching structure, the PDFThickness encapsulates dimensions on each side of the rectangle (top, left, bottom and right). The PDFThickness is used in Padding and Margin calculations, and supports addition, subtraction, equality comparison and also parsing from a string value.

Page location and positioning

All drawing operations and layout within scryber is by default done from the top left of the page. This is in contrast to the native positioning within a PDF document where all positioning is from the bottom left of the page

The top left is a more natural origin (within western cultures at least) for page layout and flowing. Content moves down the page as it fills up.
It is the PDFGraphics class that handles this translation from top left measurement to bottom left PDF native positioning, but any output that does not go through the PDFGraphics class must handle this conversion before writing.

            using (PDFDocument doc = new PDFDocument())
            {
                doc.Compression = OutputCompression.None;
                PDFPage pg = new PDFPage();
                doc.Pages.Add(pg);

                PDFLabel lbl = new PDFLabel();
                lbl.Text = "Positioned text";
                lbl.X = 100;
                lbl.Y = 200;

                pg.Contents.Add(lbl);

                doc.ProcessDocument(this.Response);
            }
3 0 obj
<< /Type /Page
/Parent 2 0 R
/MediaBox  [0.00 0.00 596.13 841.89 ]
/Contents 4 0 R
/Resources 7 0 R
 >>
endobj

4 0 obj
<< /Length  199
 >>
stream
 q BT  0.00  0.00  0.00 rg  /frsc1  24.00 Tf  0 Tr  100.00  620.16 Td <003300520056004C0057004C0052005100480047000300570048005B0057> Tj ET Q q  72.00  0.00  0.00  19.50  495.78  28.35 cm  /imgx1 Do Q
endstream
endobj

As we can see the label was defined as position 100pt, 200pt. and is at this position from the top left of the rendered page, but within the actual generated PDF document it's rendered position is 100.00 620.16.
This is because the page is 841 points high (so 200 points down is 641 points up) and the base line height, where text is rendered from in PDF, for a 24 point font pushes this down to 620.16. Exactly where we wanted this text to be.



  Rating
Rate This Page: Poor Great   |  Rate Content |
Average rating:  No Ratings Yet   
Number of Ratings : 0
  Comments
Add Comment
No Comments Yet