How to rescale PDF pages?

Q:

I need to be able to take a pdf page and place a rescaled copy of it
into a new doc page. The copied page is an exact copy with full pdf
functionality but smaller. I can see how to do this at an object level
and I see how to do this as an image.
Is there a high level function to do this scaling/resizing that I am
missing?
-----
A:
Did you take a look at ImpositionTest sample project (http://
www.pdftron.com/net/samplecode.html#Imposition)?

Using this approach you can place the source page on the destination
page without element by element copy. Actually this approach is
recommended for situations where you need to rescale the page or to
place an existing pages onto another page.

I can see how to do this at an object level and I see how to do this as an image.

I agree that rasterizing the page is not a real solution. Also copying
element by element requires lots of coding, and as a result, is more
bug prone.

If the above approaches are for some reason not satisfactory, you
could also use the following trick to rescale or transform existing
page content:

// Assuming C# pseudocode
void ScalePage(Page page, double scale)
{
   string transf = scale.ToString() + " 0 0 " + scale.ToString() + " 0
0 cm ";
   Obj trans_stm = page.GetSDFDoc().GetDoc().CreateIndirectStream(
     new System.Text.UTF8Encoding().GetBytes(transf));

   Obj contents = page.GetContents();
   If (contents.IsStream()) {
     Obj arr = pdftron.SDF.Obj.CreateArray();
     arr.PushBack(trans_stm);
     arr.PushBack(contents);
     page.GetSDFObj().Put("Contents", arr);
   }
   else {
  contents.Insert(0, trans_stm);
   }
}

You may also want to adjust page media/crop box to account for new
page dimensions:

Rect box = page.GetCropBox();
box.x1 = box.x1 * scale;
box.y1 = box.y1 * scale;
box.x1 = box.x2 * scale;
box.y1 = box.y2 * scale;
box.Update();

Please take a look at RectTest for related sample code.

Q:

It seems that the code sample for rescaling the page does not
compile.
---

A:

The code snippet would look as follows:

static void ScalePage(Page page, double scale) {
  string transf = scale.ToString() + " 0 0 " + scale.ToString() + " 0 0
cm ";
  Obj trans_stm = page.GetSDFObj().GetDoc().CreateIndirectStream(
    new System.Text.UTF8Encoding().GetBytes(transf));

  Obj contents = page.GetContents();
  if (contents.IsStream())
  {
    Obj arr = pdftron.SDF.Obj.CreateArray();
    arr.PushBack(trans_stm);
    arr.PushBack(contents);
    page.GetSDFObj().Put("Contents", arr);
    }
  else
  {
    contents.Insert(0, trans_stm);
  }

  // Comment out the following lines to preserve physical dimensions of
the page:
  Rect r = page.GetCropBox();
  r.x1*=scale; r.y1*=scale; r.x2*=scale; r.y2*=scale;
  page.SetCropBox(r);

  r = page.GetMediaBox();
  r.x1*=scale; r.y1*=scale; r.x2*=scale; r.y2*=scale;
  page.SetMediaBox(new Rect(r.x1*scale, r.y1*scale, r.x2*scale,
r.y2*scale)); }

And you could call the function as follows:

  ScalePage(page, 0.5);

This will reduce physical dimensions of the page to half its original
size, whereas Scale(page, 2) will double the physical dimensions of
the page and will rescale all page content appropriately.

Also, in PDFNet 3.7 and above there is a utility method called
pdftron.PDF.Page.Scale(sc) perfroms a similar task.

Also I forgot to mention that page scaling effect can also be achieved
using page.SetUserUnitSize(unit_size). This feature is available only
in PDF 1.6 and above, and many PDF conumers still do not support this
feature.