Created Date: Oct 05, 2021 11:04
Last Modifed Date: Oct 05, 2021 17:01


The basics

Every page in a PDF defines two rectangles that define a media box (the overall size of the media, such as an 8½" x 11" sheet of paper), and a crop box, which defines the viewable area of the page. The crop box cannot not be larger than the media box, or more accurately, may not extend outside the media box. For the majority of PDFs, the media size and the crop box have the same dimensions.

PDF 1.3 introduced three further boxes to support print workflows. They are the trim box, bleed box, and art box. As with the crop box, they cannot extend outside the media box. Their purposes:

  • Trim box – specifies the trimmed size of the final printed product, often a specific page size such as A5 or US Letter
  • Bleed box – extends the edge of the page by a small amount so that images or areas of color can print right to the edge of trimmed area. It is typically 3mm larger than the trimmed size in all dimensions
  • Art box – For a page that contains artwork as well as other information, the art box defines the area of the page that comprises the artwork. It is intended to speed up placing PDF content on to a layout in a program such as Adobe InDesign

The following diagram shows a practical application of the different page dimensions:

The two most important sets of dimensions are the MediaBox and the CropBox.

Page boxes in Mako

As stated above, the various dimensions are properties of a page. Thus, they can be obtained from an IPage object:

auto mako = IJawsMako::create();
IJawsMako::enableAllFeatures(mako);

// Open the PDF
auto assembly = IPDFInput::create(mako)->open(L"..\\..\\TestFiles\\EdgeTestA5.pdf");

// Get the first page
auto page = assembly->getDocument()->getPage(0);

// Get all the boxes
FBox mediaFBox = page->getMediaBox();
FRect mediaBox = page->getMediaBox().asRect();
FRect cropBox = page->getCropBox();
FRect bleedBox = page->getBleedBox();
FRect trimBox = page->getTrimBox();
FRect artBox = page->getContentBox();
CPP

FRect and FBox

FRect and FBox are structs that express dimensions, but they are defined in different ways.

An FRect defines a top left origin (X, Y), a horizontal, left-to-right dimension (dX) and a vertical, top-to-bottom dimension (dY).

From the example above, the width of the crop box (in 1/96th inch) is given by:

double cropWidth = cropBox.dX;
CPP

An FBox, on the other hand, defines values for left (left), bottom (bottom), top (top), right (right). The origin in this case is bottom left, so the top value increases from bottom to top, and the right value increases from left to right.

From the example above, the width of the media (in 1/72nd inch) is given by:

double mediaWidth = mediaFBox.right - mediaFBox.left
CPP

The distinction between these two definitions is relevant because both have their purposes.

Mako APIs

A typical PDF consisting of a single A5 portrait page reports these dimensions, all in millimeters:

FBox  ------------- Dimensions -------------
          Left       Top      Right   Bottom
Media    0.000   210.000   148.000     0.000

FRect ----- Origin -----  --- Dimensions ---
             X         Y     Width    Height
Media    0.000     0.000   148.000   210.000
Crop     0.000     0.000   148.000   210.000
Bleed    0.000     0.000   148.000   210.000
Trim     0.000     0.000   148.000   210.000
Art      0.000     0.000   148.000   210.000

The code to produce the table above can be found at the end of this page.

The following code was then used to modify the media size, specifically to expand it by 25mm in every direction:

#define MM2PDFUNITS(value) ((value) / 25.4 * 72.0)

// Modify size
mediaFBox.left -= MM2PDFUNITS(25);
mediaFBox.top += MM2PDFUNITS(25);
mediaFBox.right += MM2PDFUNITS(25);
mediaFBox.bottom -= MM2PDFUNITS(25);
page->setMediaBox(mediaFBox);
CPP

These images represent the page before and after the change. In the second image we can see a wide margin around the content, which is centered, as all the dimensions were altered by the same amount. Note that to increase the left and bottom margin, a negative value is required.

The media size can be obtained from the page both as an FBox (the default) or an FRect (by appending .asRect()). Both methods return their values in PDF units (1/72nd inch).

However, only an FBox can be used to set the media box values, so it is more convenient to use an FBox to begin with.

Here we compare the box dimensions, before and after:

Numeric results of expanding

Before
FBox  ------------- Dimensions -------------
          Left       Top      Right   Bottom
Media    0.000   210.000   148.000     0.000

FRect ----- Origin -----  --- Dimensions ---
             X         Y      Width   Height
Media    0.000     0.000   148.000   210.000
Crop     0.000     0.000   148.000   210.000
Bleed    0.000     0.000   148.000   210.000
Trim     0.000     0.000   148.000   210.000
Art      0.000     0.000   148.000   210.000
After
FBox  ------------- Dimensions -------------
          Left       Top      Right   Bottom
Media  -25.000   235.000   173.000   -25.000

FRect ----- Origin -----  --- Dimensions ---
             X         Y      Width   Height
Media  -25.000   -25.000   198.000   260.000
Crop    25.000    25.000   148.000   210.000
Bleed   25.000    25.000   148.000   210.000
Trim    25.000    25.000   148.000   210.000
Art     25.000    25.000   148.000   210.000

The crop, bleed, trim, and art boxes have a new origin (their top-left corner is now 25mm in and 25mm down on the page) but their size is unaltered.

Setting the media box

Setting the media box requires passing an FBox, with PDF units, as in the above example.

Scaling the media box

A convenience method to scale the media box is provided. For example, to scale an A5 media box to A4 (or to A4 to A3, etc.) simply apply a scale of 141.42%:

// Scale media box
mediaFBox.scale(1.4142);
page->setMediaBox(mediaFBox);
CPP

Numeric results of scaling

Before

FBox  ------------- Dimensions -------------
          Left       Top      Right   Bottom
Media    0.000   210.000   148.000     0.000

FRect ----- Origin -----  --- Dimensions ---
             X         Y      Width   Height
Media    0.000     0.000   148.000   210.000
Crop     0.000     0.000   148.000   210.000
Bleed    0.000     0.000   148.000   210.000
Trim     0.000     0.000   148.000   210.000
Art      0.000     0.000   148.000   210.000

After

FBox  ------------- Dimensions -------------
          Left       Top      Right   Bottom
Media    0.000   296.985   209.304     0.000

FRect ----- Origin -----  --- Dimensions ---
             X         Y      Width   Height
Media    0.000     0.000   209.304   296.985
Crop     0.000    86.985   148.000   210.000
Bleed    0.000    86.985   148.000   210.000
Trim     0.000    86.985   148.000   210.000
Art      0.000    86.985   148.000   210.000
  • Page content does not scale with the media box, and remains at the same size and in the same position, relative to the bottom-left corner of the page.
  • Scaling the media box with a value below 100% may result in page boxes acquiring negative origin values to compensate for their dimensions exceeding the size of the media box. This is expected and not invalid.
  • Saving to PDF/X-4 will "normalize" the page boxes, adjusting them to the same size or smaller than the MediaBox, as this is a requirement of the PDF/X-4 standard.

Appearance in Acrobat and other PDF viewers

Increasing the media size does not by itself change how the document is presented in Acrobat or other PDF viewer, since the crop box controls the apparent page size. Nor does it scale page content, as noted earlier.

Decreasing the media size may change how the document is presented in a viewer if one or both MediaBox dimensions are less than those of the original crop box, in which case the new dimensions take priority.

Scaling of content

If scaling the page and its content is required, it is necessary to obtain an IDOMFixedPage from an IPage first, and operate on that.

A code sample showing how this is done is available in the Mako SDK. Look in the simpleexamples folder for imposition.cpp. This shows a worked example of copying page content and scaling as needed (in this case for the purposes of creating a booklet imposition).


Code used to display page box dimensions

#define PDFUNITS2MM(value) ((value) / 72.0 * 25.4)
#define XPSUNITS2MM(value) ((value) / 96.0 * 25.4)

void reportPageDimensions(FRect mediaBox, FRect cropBox, FRect bleedBox, FRect trimBox, FRect artBox)
{
    printf("FRect ----- Origin -----  --- Dimensions ---\n");
    printf("             X         Y     Height    Width\n");
    printf("Media %8.3f  %8.3f  %8.3f  %8.3f\n", PDFUNITS2MM(mediaBox.x), PDFUNITS2MM(mediaBox.y),
           PDFUNITS2MM(mediaBox.dX), PDFUNITS2MM(mediaBox.dY));
    printf("Crop  %8.3f  %8.3f  %8.3f  %8.3f\n", XPSUNITS2MM(cropBox.x), XPSUNITS2MM(cropBox.y),
           XPSUNITS2MM(cropBox.dX), XPSUNITS2MM(cropBox.dY));
    printf("Bleed %8.3f  %8.3f  %8.3f  %8.3f\n", XPSUNITS2MM(bleedBox.x), XPSUNITS2MM(bleedBox.y),
           XPSUNITS2MM(bleedBox.dX), XPSUNITS2MM(bleedBox.dY));
    printf("Trim  %8.3f  %8.3f  %8.3f  %8.3f\n", XPSUNITS2MM(trimBox.x), XPSUNITS2MM(trimBox.y),
           XPSUNITS2MM(trimBox.dX), XPSUNITS2MM(trimBox.dY));
    printf("Art   %8.3f  %8.3f  %8.3f  %8.3f\n\n", XPSUNITS2MM(artBox.x), XPSUNITS2MM(artBox.y),
           XPSUNITS2MM(artBox.dX), XPSUNITS2MM(artBox.dY));
}

void reportMediaBoxDimensions(FBox mediaBox)
{
    printf("FBox  ------------- Dimensions -------------\n");
    printf("          Left       Top      Right   Bottom\n");
    printf("Media %8.3f  %8.3f  %8.3f  %8.3f\n\n", PDFUNITS2MM(mediaBox.left), PDFUNITS2MM(mediaBox.top),
           PDFUNITS2MM(mediaBox.right), PDFUNITS2MM(mediaBox.bottom));
}
CPP