Skip to content

Commit

Permalink
Merge branch 'feature/IndividualPageSizes'
Browse files Browse the repository at this point in the history
This merge closes #27
  • Loading branch information
jpt13653903 committed Jan 13, 2024
2 parents 130f898 + 4dcb398 commit 29d919c
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 131 deletions.
6 changes: 6 additions & 0 deletions Docs/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Usage: Gerber2pdf [-silentexit] [-nowarnings] [-CMYK] ...
[-background=R,G,B[,A]] [-backgroundCMYK=C,M,Y,K[,A]] ...
[-strokes2fills] [-page_size=extents|A3|A4|letter] ...
[-orientation=portrait|landscape] [-scale_to_fit] ...
[-next_page_size=extents|A3|A4|letter] ...
[-next_orientation=portrait|landscape] [-next_scale_to_fit] ...
file_1 [-combine] file_2 file_3 file_4...
[-colour=R,G,B[,A]] [-colourCMYK=C,M,Y,K[,A]] [-mirror] ...
[-nomirror] [-nocombine] ... file_N
Expand Down Expand Up @@ -50,5 +52,9 @@ The -page_size option takes global effect and can have one of 4 values:
The -orientation and -scale_to_fit options only take effect
on standard paper sizes (i.e. A3, A4 and letter).
The -next_page_size, -next_orientation and -next_scale_to_fit options
only take effect for the next page created. Define before calling the
first Gerber of that page. These override the "global" options.
```

271 changes: 152 additions & 119 deletions Engine/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,14 @@ ENGINE::OUTLINE::~OUTLINE(){
ENGINE::ENGINE(){
ConvertStrokesToFills = false;
ScaleToFit = false;
NextScaleToFit = false;
UseCMYK = false;

PageSize = PS_Tight;
PageOrientation = PO_Auto;
PageSize = PS_Tight;
Orientation = PO_Auto;

NextPageSize = PS_Tight;
NextOrientation = PO_Auto;

OpaqueCount = 0;
OpaqueStack = 0;
Expand Down Expand Up @@ -639,6 +643,119 @@ ENGINE::LAYER* ENGINE::FindLayer(
}
//------------------------------------------------------------------------------

void ENGINE::SetMediaBox(
PAGE* Page,
double Left, double Bottom, double Right, double Top
){
if(!Page->Contents) return;

double Width = Right - Left;
double Height = Top - Bottom;

double PaperWidth;
double PaperHeight;
double Delta;

PAGE_SIZE PageSize = this->PageSize;
PAGE_ORIENTATION Orientation = this->Orientation;
bool ScaleToFit = this->ScaleToFit;

bool LocalOverride = false;
if(Page->PageSize != PS_Tight){
PageSize = Page->PageSize;
LocalOverride = true;
}
if(Page->Orientation != PO_Auto){
Orientation = Page->Orientation;
LocalOverride = true;
}
if(Page->ScaleToFit){
ScaleToFit = true;
LocalOverride = true;
}

if(PageSize == PS_Tight) return;

if(LocalOverride && PageSize != PS_Extents){
Left = Page->Page->MediaBox.Left .Value;
Bottom = Page->Page->MediaBox.Bottom.Value;
Right = Page->Page->MediaBox.Right .Value;
Top = Page->Page->MediaBox.Top .Value;
Width = Right - Left;
Height = Top - Bottom;
}

if(Orientation == PO_Auto){
if(Width > Height) Orientation = PO_Landscape;
else Orientation = PO_Portrait;
}

// Centre on standard sizes
switch(PageSize){
case PS_A3:
if(Orientation == PO_Landscape){
PaperWidth = 420/25.4*72.0;
PaperHeight = 297/25.4*72.0;
}else{
PaperWidth = 297/25.4*72.0;
PaperHeight = 420/25.4*72.0;
}
break;

case PS_A4:
if(Orientation == PO_Landscape){
PaperWidth = 297/25.4*72.0;
PaperHeight = 210/25.4*72.0;
}else{
PaperWidth = 210/25.4*72.0;
PaperHeight = 297/25.4*72.0;
}
break;

case PS_Letter:
if(Orientation == PO_Landscape){
PaperWidth = 11.0*72.0;
PaperHeight = 8.5*72.0;
}else{
PaperWidth = 8.5*72.0;
PaperHeight = 11.0*72.0;
}
break;

default:
PaperWidth = Width;
PaperHeight = Height;
ScaleToFit = false;
}

if(ScaleToFit){
double ScaleX = (PaperWidth - 10.0/25.4*72.0) / Width * 1.05;
double ScaleY = (PaperHeight - 10.0/25.4*72.0) / Height * 1.05;
double Scale = ScaleX;
if(ScaleX > ScaleY) Scale = ScaleY;
Left *= Scale;
Bottom *= Scale;
Right *= Scale;
Top *= Scale;
Width *= Scale;
Height *= Scale;

Page->Contents->Prescale(Scale, Scale);
}

Delta = (PaperWidth - Width) / 2.0;
Left -= Delta;
Right += Delta;

Delta = (PaperHeight - Height) / 2.0;
Bottom -= Delta;
Top += Delta;

Page->Contents->Pretranslate(-Left, -Bottom);
Page->Page->MediaBox.Set(0, 0, Right-Left, Top-Bottom);
}
//------------------------------------------------------------------------------

int ENGINE::Run(const char* FileName, const char* Title){
int j;
bool Reusing = false;
Expand Down Expand Up @@ -696,9 +813,15 @@ int ENGINE::Run(const char* FileName, const char* Title){

// Write the PDF
if(!ThePage || NewPage || !Combine){
Page = new PAGE(Page, UseCMYK);
ThePage = Page->Page;
ThePageUsed = false;
Page = new PAGE(Page, UseCMYK);
ThePage = Page->Page;
ThePageUsed = false;
Page->PageSize = NextPageSize;
Page->Orientation = NextOrientation;
Page->ScaleToFit = NextScaleToFit;
NextPageSize = PS_Tight;
NextOrientation = PO_Auto;
NextScaleToFit = false;
}
NewPage = false;

Expand Down Expand Up @@ -897,127 +1020,37 @@ int ENGINE::Run(const char* FileName, const char* Title){
void ENGINE::Finish(const char* OutputFileName){
PAGE* page;

if(PageSize != PS_Tight){
double Left = 1e100;
double Bottom = 1e100;
double Right = -1e100;
double Top = -1e100;
double Width;
double Height;
double PaperWidth;
double PaperHeight;
double Delta;

// Calculate the extents
page = Page;
while(page){
if(page->Page->MediaBox.Left .Value < page->Page->MediaBox.Right.Value &&
page->Page->MediaBox.Bottom.Value < page->Page->MediaBox.Top .Value ){
if(Left > page->Page->MediaBox.Left .Value)
Left = page->Page->MediaBox.Left .Value;
if(Bottom > page->Page->MediaBox.Bottom.Value)
Bottom = page->Page->MediaBox.Bottom.Value;
if(Right < page->Page->MediaBox.Right .Value)
Right = page->Page->MediaBox.Right .Value;
if(Top < page->Page->MediaBox.Top .Value)
Top = page->Page->MediaBox.Top .Value;
}
page = page->Next;
}
Width = Right - Left;
Height = Top - Bottom;

if(PageOrientation == PO_Auto){
if(Width > Height) PageOrientation = PO_Landscape;
else PageOrientation = PO_Portrait;
}

// Centre on standard sizes
switch(PageSize){
case PS_A3:
if(PageOrientation == PO_Landscape){
PaperWidth = 420/25.4*72.0;
PaperHeight = 297/25.4*72.0;
}else{
PaperWidth = 297/25.4*72.0;
PaperHeight = 420/25.4*72.0;
}
break;

case PS_A4:
if(PageOrientation == PO_Landscape){
PaperWidth = 297/25.4*72.0;
PaperHeight = 210/25.4*72.0;
}else{
PaperWidth = 210/25.4*72.0;
PaperHeight = 297/25.4*72.0;
}
break;

case PS_Letter:
if(PageOrientation == PO_Landscape){
PaperWidth = 11.0*72.0;
PaperHeight = 8.5*72.0;
}else{
PaperWidth = 8.5*72.0;
PaperHeight = 11.0*72.0;
}
break;
double Left = 1e100;
double Bottom = 1e100;
double Right = -1e100;
double Top = -1e100;

default:
PaperWidth = Width;
PaperHeight = Height;
ScaleToFit = false;
}

if(ScaleToFit){
double ScaleX = (PaperWidth - 10.0/25.4*72.0) / Width * 1.05;
double ScaleY = (PaperHeight - 10.0/25.4*72.0) / Height * 1.05;
double Scale = ScaleX;
if(ScaleX > ScaleY) Scale = ScaleY;
Left *= Scale;
Bottom *= Scale;
Right *= Scale;
Top *= Scale;
Width *= Scale;
Height *= Scale;

page = Page;
while(page){
if(page->Contents) page->Contents->Prescale(Scale, Scale);
page = page->Next;
}
// Calculate the extents
page = Page;
while(page){
if(page->Page->MediaBox.Left .Value < page->Page->MediaBox.Right.Value &&
page->Page->MediaBox.Bottom.Value < page->Page->MediaBox.Top .Value ){
if(Left > page->Page->MediaBox.Left .Value)
Left = page->Page->MediaBox.Left .Value;
if(Bottom > page->Page->MediaBox.Bottom.Value)
Bottom = page->Page->MediaBox.Bottom.Value;
if(Right < page->Page->MediaBox.Right .Value)
Right = page->Page->MediaBox.Right .Value;
if(Top < page->Page->MediaBox.Top .Value)
Top = page->Page->MediaBox.Top .Value;
}
page = page->Next;
}

Delta = (PaperWidth - Width) / 2.0;
Left -= Delta;
Right += Delta;

Delta = (PaperHeight - Height) / 2.0;
Bottom -= Delta;
Top += Delta;

page = Page;
while(page){
page->Page->MediaBox.Set(Left, Bottom, Right, Top);
page = page->Next;
}
page = Page;
while(page){
SetMediaBox(page, Left, Bottom, Right, Top);
page = page->Next;
}

page = Page;
while(page){
if(page->Contents){
page->Contents->Pretranslate(
-page->Page->MediaBox.Left .Value,
-page->Page->MediaBox.Bottom.Value
);
page->Page->MediaBox.Set(
0, 0,
page->Page->MediaBox.Right.Value - page->Page->MediaBox.Left .Value,
page->Page->MediaBox.Top .Value - page->Page->MediaBox.Bottom.Value
);
page->Contents->Deflate();
}
if(page->Contents) page->Contents->Deflate();
page = page->Next;
}

Expand Down
20 changes: 14 additions & 6 deletions Engine/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ struct ENGINE{
PS_A3,
PS_A4,
PS_Letter
} PageSize;
} PageSize, NextPageSize;

enum PAGE_ORIENTATION{
PO_Auto = 0,
PO_Portrait,
PO_Landscape
} PageOrientation;
} Orientation, NextOrientation;

bool Mirror;
bool Combine;
Expand All @@ -69,6 +69,7 @@ struct ENGINE{

bool ConvertStrokesToFills;
bool ScaleToFit;
bool NextScaleToFit;
bool UseCMYK;
//------------------------------------------------------------------------------

Expand Down Expand Up @@ -114,9 +115,12 @@ struct ENGINE{

// These stacks keep track of objects to be deleted at the end
struct PAGE{
pdfPage* Page;
pdfContents* Contents;
PAGE* Next;
pdfPage* Page;
pdfContents* Contents;
PAGE_SIZE PageSize = PS_Tight;
PAGE_ORIENTATION Orientation = PO_Auto;
bool ScaleToFit = false;
PAGE* Next;

PAGE(PAGE* Next, bool UseCMYK);
~PAGE();
Expand All @@ -126,7 +130,7 @@ struct ENGINE{
struct OUTLINE{
pdfOutlineItems* Item;
OUTLINE* Next;

OUTLINE(OUTLINE* Next);
~OUTLINE();
};
Expand Down Expand Up @@ -205,6 +209,10 @@ struct ENGINE{
bool ConvertStrokesToFills,
COLOUR& Light
);
void SetMediaBox(
PAGE* Page,
double Left, double Bottom, double Right, double Top
);
//------------------------------------------------------------------------------

public: // Functions
Expand Down
2 changes: 1 addition & 1 deletion Engine/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Libraries =
LibInclude =
#-------------------------------------------------------------------------------

Version = -DMAJOR_VERSION=1 -DMINOR_VERSION=9
Version = -DMAJOR_VERSION=1 -DMINOR_VERSION=10

Objects = $(shell find Tools -iname "*.cpp")
Objects += $(shell find Toolbox/Cpp -iname "*.cpp")
Expand Down
Loading

0 comments on commit 29d919c

Please sign in to comment.