From d225778e9a63e2d6b90c7730b591cc5edfd46852 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Sun, 9 Jan 2005 17:42:53 +0000 Subject: [PATCH] Added scaling ability and visualization of the options Reverse and Collate. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10619 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../shared/libprint/GraphicsDriver.cpp | 20 ++- .../print/drivers/shared/libprint/Jamfile | 1 + .../print/drivers/shared/libprint/JobData.cpp | 158 ++++++++++-------- .../drivers/shared/libprint/JobSetupDlg.cpp | 55 ++++-- .../drivers/shared/libprint/PageSetupDlg.cpp | 53 +++++- 5 files changed, 198 insertions(+), 89 deletions(-) diff --git a/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp b/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp index 4e21094a5f..8f168104aa 100644 --- a/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp +++ b/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp @@ -147,7 +147,7 @@ void GraphicsDriver::cleanupBitmap() fView = NULL; } -BPoint get_scale(JobData *org_job_data) +static BPoint get_scale(JobData *org_job_data) { float width; float height; @@ -224,11 +224,14 @@ BPoint get_scale(JobData *org_job_data) break; } + scale.x = scale.x * org_job_data->getScaling() / 100.0; + scale.y = scale.y * org_job_data->getScaling() / 100.0; + DBGMSG(("real scale = %f, %f\n", scale.x, scale.y)); return scale; } -BPoint get_offset( +static BPoint get_offset( int index, const BPoint *scale, JobData *org_job_data) @@ -237,8 +240,8 @@ BPoint get_offset( offset.x = 0; offset.y = 0; - float width = org_job_data->getPrintableRect().Width(); - float height = org_job_data->getPrintableRect().Height(); + float width = org_job_data->getScaledPrintableRect().Width(); + float height = org_job_data->getScaledPrintableRect().Height(); switch (org_job_data->getNup()) { case 1: @@ -321,6 +324,7 @@ BPoint get_offset( return offset; } +// print the specified pages on a physical page bool GraphicsDriver::printPage(PageDataList *pages) { #ifndef USE_PREVIEW_FOR_DEBUG @@ -333,11 +337,13 @@ bool GraphicsDriver::printPage(PageDataList *pages) } do { + // clear the physical page fView->SetScale(1.0); fView->SetHighColor(255, 255, 255); fView->ConstrainClippingRegion(NULL); fView->FillRect(fView->Bounds()); + BPoint scale = get_scale(fOrgJobData); float real_scale = min(scale.x, scale.y) * fOrgJobData->getXres() / 72.0f; fView->SetScale(real_scale); @@ -349,7 +355,7 @@ bool GraphicsDriver::printPage(PageDataList *pages) BPoint left_top(get_offset(page_index++, &scale, fOrgJobData)); left_top.x -= x; left_top.y -= y; - BRect clip(fOrgJobData->getPrintableRect()); + BRect clip(fOrgJobData->getScaledPrintableRect()); clip.OffsetTo(left_top); BRegion *region = new BRegion(); region->Set(clip); @@ -438,6 +444,7 @@ bool GraphicsDriver::printDocument(SpoolData *spool_data) do { DBGMSG(("page index = %d\n", page_index)); + // collect the pages to be printed on the physical page nup = fOrgJobData->getNup(); PageDataList pages; do { @@ -450,7 +457,8 @@ bool GraphicsDriver::printDocument(SpoolData *spool_data) success = startPage(page_index); if (!success) break; - + + // print the pages on the physical page fView->Window()->Lock(); success = printPage(&pages); fView->Window()->Unlock(); diff --git a/src/add-ons/print/drivers/shared/libprint/Jamfile b/src/add-ons/print/drivers/shared/libprint/Jamfile index 5cea7e8e3a..404398deec 100644 --- a/src/add-ons/print/drivers/shared/libprint/Jamfile +++ b/src/add-ons/print/drivers/shared/libprint/Jamfile @@ -17,6 +17,7 @@ StaticLibrary print : JobSetupDlg.cpp PackBits.cpp PageSetupDlg.cpp + PagesView.cpp Preview.cpp PrinterData.cpp PrinterDriver.cpp diff --git a/src/add-ons/print/drivers/shared/libprint/JobData.cpp b/src/add-ons/print/drivers/shared/libprint/JobData.cpp index 1390a20cbc..a3a5468873 100644 --- a/src/add-ons/print/drivers/shared/libprint/JobData.cpp +++ b/src/add-ons/print/drivers/shared/libprint/JobData.cpp @@ -9,28 +9,30 @@ #include "PrinterCap.h" #include "DbgMsg.h" -const char *kJDXRes = "xres"; -const char *kJDYRes = "yres"; -const char *kJDCopies = "copies"; -const char *kJDOrientation = "orientation"; -const char *kJDScaling = "scaling"; -const char *kJDPaperRect = "paper_rect"; -const char *kJDPrintableRect = "printable_rect"; -const char *kJDFirstPage = "first_page"; -const char *kJDLastPage = "last_page"; +static const char *kJDXRes = "xres"; +static const char *kJDYRes = "yres"; +static const char *kJDCopies = "copies"; +static const char *kJDOrientation = "orientation"; +static const char *kJDScaling = "scale"; +static const char *kJDScaledPaperRect = "paper_rect"; +static const char *kJDScaledPrintableRect = "printable_rect"; +static const char *kJDFirstPage = "first_page"; +static const char *kJDLastPage = "last_page"; -const char *kJDPaper = "JJJJ_paper"; -const char *kJDNup = "JJJJ_nup"; -const char *kJDGamma = "JJJJ_gamma"; -const char *kJDInkDensity = "JJJJ_ink_density"; -const char *kJDPaperSource = "JJJJ_paper_source"; -const char *kJDCollate = "JJJJ_collate"; -const char *kJDReverse = "JJJJ_reverse"; -const char *kJDPrintStyle = "JJJJ_print_style"; -const char *kJDBindingLocation = "JJJJ_binding_location"; -const char *kJDPageOrder = "JJJJ_page_order"; -const char *kJDColor = "JJJJ_color"; -const char *kJDDitherType = "JJJJ_dither_type"; +static const char *kJDPaper = "JJJJ_paper"; +static const char *kJDNup = "JJJJ_nup"; +static const char *kJDGamma = "JJJJ_gamma"; +static const char *kJDInkDensity = "JJJJ_ink_density"; +static const char *kJDPaperSource = "JJJJ_paper_source"; +static const char *kJDCollate = "JJJJ_collate"; +static const char *kJDReverse = "JJJJ_reverse"; +static const char *kJDPrintStyle = "JJJJ_print_style"; +static const char *kJDBindingLocation = "JJJJ_binding_location"; +static const char *kJDPageOrder = "JJJJ_page_order"; +static const char *kJDColor = "JJJJ_color"; +static const char *kJDDitherType = "JJJJ_dither_type"; +static const char *kJDPaperRect = "JJJJ_paper_rect"; +static const char* kJDPrintableRect = "JJJJ_printable_rect"; JobData::JobData(BMessage *msg, const PrinterCap *cap, Settings settings) { @@ -43,56 +45,60 @@ JobData::~JobData() JobData::JobData(const JobData &job_data) { - fPaper = job_data.fPaper; - fXRes = job_data.fXRes; - fYRes = job_data.fYRes; - fOrientation = job_data.fOrientation; - fScaling = job_data.fScaling; - fPaperRect = job_data.fPaperRect; - fPrintableRect = job_data.fPrintableRect; - fNup = job_data.fNup; - fFirstPage = job_data.fFirstPage; - fLastPage = job_data.fLastPage; - fGamma = job_data.fGamma; - fInkDensity = job_data.fInkDensity; - fPaperSource = job_data.fPaperSource; - fCopies = job_data.fCopies; - fCollate = job_data.fCollate; - fReverse = job_data.fReverse; - fPrintStyle = job_data.fPrintStyle; - fBindingLocation = job_data.fBindingLocation; - fPageOrder = job_data.fPageOrder; - fSettings = job_data.fSettings; - fMsg = job_data.fMsg; - fColor = job_data.fColor; - fDitherType = job_data.fDitherType; + fPaper = job_data.fPaper; + fXRes = job_data.fXRes; + fYRes = job_data.fYRes; + fOrientation = job_data.fOrientation; + fScaling = job_data.fScaling; + fPaperRect = job_data.fPaperRect; + fScaledPaperRect = job_data.fScaledPaperRect; + fPrintableRect = job_data.fPrintableRect; + fScaledPrintableRect = job_data.fScaledPrintableRect; + fNup = job_data.fNup; + fFirstPage = job_data.fFirstPage; + fLastPage = job_data.fLastPage; + fGamma = job_data.fGamma; + fInkDensity = job_data.fInkDensity; + fPaperSource = job_data.fPaperSource; + fCopies = job_data.fCopies; + fCollate = job_data.fCollate; + fReverse = job_data.fReverse; + fPrintStyle = job_data.fPrintStyle; + fBindingLocation = job_data.fBindingLocation; + fPageOrder = job_data.fPageOrder; + fSettings = job_data.fSettings; + fMsg = job_data.fMsg; + fColor = job_data.fColor; + fDitherType = job_data.fDitherType; } JobData &JobData::operator = (const JobData &job_data) { - fPaper = job_data.fPaper; - fXRes = job_data.fXRes; - fYRes = job_data.fYRes; - fOrientation = job_data.fOrientation; - fScaling = job_data.fScaling; - fPaperRect = job_data.fPaperRect; - fPrintableRect = job_data.fPrintableRect; - fNup = job_data.fNup; - fFirstPage = job_data.fFirstPage; - fLastPage = job_data.fLastPage; - fGamma = job_data.fGamma; - fInkDensity = job_data.fInkDensity; - fPaperSource = job_data.fPaperSource; - fCopies = job_data.fCopies; - fCollate = job_data.fCollate; - fReverse = job_data.fReverse; - fPrintStyle = job_data.fPrintStyle; - fBindingLocation = job_data.fBindingLocation; - fPageOrder = job_data.fPageOrder; - fSettings = job_data.fSettings; - fMsg = job_data.fMsg; - fColor = job_data.fColor; - fDitherType = job_data.fDitherType; + fPaper = job_data.fPaper; + fXRes = job_data.fXRes; + fYRes = job_data.fYRes; + fOrientation = job_data.fOrientation; + fScaling = job_data.fScaling; + fPaperRect = job_data.fPaperRect; + fScaledPaperRect = job_data.fScaledPaperRect; + fPrintableRect = job_data.fPrintableRect; + fScaledPrintableRect = job_data.fScaledPrintableRect; + fNup = job_data.fNup; + fFirstPage = job_data.fFirstPage; + fLastPage = job_data.fLastPage; + fGamma = job_data.fGamma; + fInkDensity = job_data.fInkDensity; + fPaperSource = job_data.fPaperSource; + fCopies = job_data.fCopies; + fCollate = job_data.fCollate; + fReverse = job_data.fReverse; + fPrintStyle = job_data.fPrintStyle; + fBindingLocation = job_data.fBindingLocation; + fPageOrder = job_data.fPageOrder; + fSettings = job_data.fSettings; + fMsg = job_data.fMsg; + fColor = job_data.fColor; + fDitherType = job_data.fDitherType; return *this; } @@ -144,10 +150,18 @@ void JobData::load(BMessage *msg, const PrinterCap *cap, Settings settings) fPaperRect = msg->FindRect(kJDPaperRect); } + if (msg->HasRect(kJDScaledPaperRect)) { + fScaledPaperRect = msg->FindRect(kJDScaledPaperRect); + } + if (msg->HasRect(kJDPrintableRect)) { fPrintableRect = msg->FindRect(kJDPrintableRect); } + if (msg->HasRect(kJDScaledPrintableRect)) { + fScaledPrintableRect = msg->FindRect(kJDScaledPrintableRect); + } + if (msg->HasInt32(kJDFirstPage)) fFirstPage = msg->FindInt32(kJDFirstPage); else @@ -262,11 +276,21 @@ void JobData::save(BMessage *msg) else msg->AddRect(kJDPaperRect, fPaperRect); + if (msg->HasRect(kJDScaledPaperRect)) + msg->ReplaceRect(kJDScaledPaperRect, fScaledPaperRect); + else + msg->AddRect(kJDScaledPaperRect, fScaledPaperRect); + if (msg->HasRect(kJDPrintableRect)) msg->ReplaceRect(kJDPrintableRect, fPrintableRect); else msg->AddRect(kJDPrintableRect, fPrintableRect); + if (msg->HasRect(kJDScaledPrintableRect)) + msg->ReplaceRect(kJDScaledPrintableRect, fScaledPrintableRect); + else + msg->AddRect(kJDScaledPrintableRect, fScaledPrintableRect); + // page settings end here; don't store job settings in message if (fSettings == kPageSettings) return; diff --git a/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp b/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp index eceb3a7be6..5b17b992c9 100644 --- a/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp +++ b/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp @@ -36,6 +36,7 @@ #include "JobSetupDlg.h" #include "JobData.h" #include "JSDSlider.h" +#include "PagesView.h" #include "PrinterData.h" #include "PrinterCap.h" #include "DbgMsg.h" @@ -138,6 +139,11 @@ using namespace std; #define REVERSE_WIDTH PAPERFEED_WIDTH #define REVERSE_HEIGHT 16 +#define PAGES_H PAPERFEED_H +#define PAGES_V REVERSE_V + COLLATE_HEIGHT + 5 +#define PAGES_WIDTH PAPERFEED_WIDTH +#define PAGES_HEIGHT 40 + #define PRINT_BUTTON_WIDTH 70 #define PRINT_BUTTON_HEIGHT 20 @@ -251,6 +257,12 @@ const BRect reverse_rect( REVERSE_H + REVERSE_WIDTH, REVERSE_V + REVERSE_HEIGHT); +const BRect pages_rect( + PAGES_H, + PAGES_V, + PAGES_H + PAGES_WIDTH, + PAGES_V + PAGES_HEIGHT); + const BRect ok_rect( PRINT_OK_BUTTON_H, PRINT_OK_BUTTON_V, @@ -330,6 +342,8 @@ enum { kMsgCancel, kMsgOK, kMsgQuality, + kCollateChanged, + kReverseChanged, }; JobSetupView::JobSetupView(BRect frame, JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) @@ -397,10 +411,10 @@ void JobSetupView::AttachedToWindow() } if (!marked && item) item->SetMarked(true); - menufield = new BMenuField(bpp_rect, "", "Color", fColorType); + menufield = new BMenuField(bpp_rect, "", "Color:", fColorType); box->AddChild(menufield); - width = StringWidth("Color") + 10; + width = StringWidth("Color:") + 10; menufield->SetDivider(width); fColorType->SetTargetForItems(this); @@ -422,10 +436,10 @@ void JobSetupView::AttachedToWindow() } if (!marked && item) item->SetMarked(true); - menufield = new BMenuField(dither_rect, "", "Dithering", fDitherType); + menufield = new BMenuField(dither_rect, "", "Dithering:", fDitherType); box->AddChild(menufield); - width = StringWidth("Dithering") + 10; + width = StringWidth("Dithering:") + 10; menufield->SetDivider(width); fDitherType->SetTargetForItems(this); @@ -527,9 +541,9 @@ void JobSetupView::AttachedToWindow() } if (!marked) item->SetMarked(true); - menufield = new BMenuField(paperfeed_rect, "", "Paper Source", fPaperFeed); + menufield = new BMenuField(paperfeed_rect, "", "Paper Source:", fPaperFeed); AddChild(menufield); - width = StringWidth("Number of Copies") + 7; + width = StringWidth("Number of Copies:") + 7; menufield->SetDivider(width); /* Page Per Sheet */ @@ -550,7 +564,7 @@ void JobSetupView::AttachedToWindow() } if (!marked) item->SetMarked(true); - menufield = new BMenuField(nup_rect, "", "Page Per Sheet", fNup); + menufield = new BMenuField(nup_rect, "", "Page Per Sheet:", fNup); menufield->SetDivider(width); AddChild(menufield); @@ -566,7 +580,7 @@ void JobSetupView::AttachedToWindow() /* copies */ - copies = new BTextControl(copies_rect, "", "Number of Copies", "", NULL); + copies = new BTextControl(copies_rect, "", "Number of Copies:", "", NULL); AddChild(copies); copies->SetDivider(width); @@ -576,19 +590,28 @@ void JobSetupView::AttachedToWindow() /* collate */ - fCollate = new BCheckBox(collate_rect, "Collate", "Collate", NULL); + fCollate = new BCheckBox(collate_rect, "Collate", "Collate", new BMessage(kCollateChanged)); AddChild(fCollate); if (fJobData->getCollate()) { fCollate->SetValue(B_CONTROL_ON); } + fCollate->SetTarget(this); /* reverse */ - fReverse = new BCheckBox(reverse_rect, "Reverse", "Reverse", NULL); + fReverse = new BCheckBox(reverse_rect, "Reverse", "Reverse", new BMessage(kReverseChanged)); AddChild(fReverse); if (fJobData->getReverse()) { fReverse->SetValue(B_CONTROL_ON); } + fReverse->SetTarget(this); + + /* pages view */ + + fPages = new PagesView(pages_rect, "Pages", B_FOLLOW_ALL, B_WILL_DRAW); + AddChild(fPages); + fPages->setCollate(fJobData->getCollate()); + fPages->setReverse(fJobData->getReverse()); /* cancel */ @@ -623,6 +646,14 @@ void JobSetupView::MessageReceived(BMessage *msg) fHalftone->preview(getGamma(), getInkDensity(), getDitherType(), getColor() == JobData::kColor); break; + case kCollateChanged: + fPages->setCollate(fCollate->Value() == B_CONTROL_ON); + break; + + case kReverseChanged: + fPages->setReverse(fReverse->Value() == B_CONTROL_ON); + break; + } } @@ -738,7 +769,7 @@ bool JobSetupView::UpdateJobData() //==================================================================== -filter_result PrintKeyFilter(BMessage *msg, BHandler **target, BMessageFilter *filter) +static filter_result PrintKeyFilter(BMessage *msg, BHandler **target, BMessageFilter *filter) { BWindow *window = (BWindow *)filter->Looper(); @@ -809,7 +840,7 @@ void JobSetupDlg::MessageReceived(BMessage *msg) case kMsgCancel: PostMessage(B_QUIT_REQUESTED); break; - + default: DialogWindow::MessageReceived(msg); break; diff --git a/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp b/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp index ef7d42b768..109558cb13 100644 --- a/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp +++ b/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include "PrinterData.h" #include "PrinterCap.h" #include "DbgMsg.h" +#include "BeUtils.h" #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) using namespace std; @@ -40,11 +42,12 @@ using namespace std; #endif #define PAGESETUP_WIDTH 270 -#define PAGESETUP_HEIGHT 125 +#define PAGESETUP_HEIGHT 135 #define MENU_HEIGHT 16 #define BUTTON_WIDTH 70 #define BUTTON_HEIGHT 20 +#define TEXT_HEIGHT 16 #define ORIENT_H 10 #define ORIENT_V 10 @@ -57,13 +60,19 @@ using namespace std; #define PAPER_V 20 #define PAPER_WIDTH 200 #define PAPER_HEIGHT MENU_HEIGHT -#define PAPER_TEXT "Paper Size" +#define PAPER_TEXT "Paper Size:" #define RES_H PAPER_H #define RES_V PAPER_V + 24 #define RES_WIDTH 150 #define RES_HEIGHT MENU_HEIGHT -#define RES_TEXT "Resolution" +#define RES_TEXT "Resolution:" + +#define SCALE_H PAPER_H +#define SCALE_V RES_V + 24 +#define SCALE_WIDTH 100 +#define SCALE_HEIGHT TEXT_HEIGHT +#define SCALE_TEXT "Scale [%]:" #define OK_H (PAGESETUP_WIDTH - BUTTON_WIDTH - 11) #define OK_V (PAGESETUP_HEIGHT - BUTTON_HEIGHT - 11) @@ -96,6 +105,12 @@ const BRect RESOLUTION_RECT( RES_H + RES_WIDTH, RES_V + RES_HEIGHT); +const BRect SCALE_RECT( + SCALE_H, + SCALE_V, + SCALE_H + SCALE_WIDTH, + SCALE_V + SCALE_HEIGHT); + const BRect OK_RECT( OK_H, OK_V, @@ -195,6 +210,24 @@ void PageSetupView::AttachedToWindow() AddChild(menufield); menufield->SetDivider(width); + /* scale */ + BString scale; + scale << (int)fJobData->getScaling(); + fScaling = new BTextControl(SCALE_RECT, "scale", "Scale [%]:", + scale.String(), + NULL, B_FOLLOW_RIGHT); + int num; + for (num = 0; num <= 255; num++) { + fScaling->TextView()->DisallowChar(num); + } + for (num = 0; num <= 9; num++) { + fScaling->TextView()->AllowChar('0' + num); + } + fScaling->TextView()->SetMaxBytes(3); + fScaling->SetDivider(width); + + AddChild(fScaling); + /* cancel */ button = new BButton(CANCEL_RECT, "", CANCEL_TEXT, new BMessage(kMsgCancel)); @@ -259,9 +292,21 @@ bool PageSetupView::UpdateJobData() swap(&printable_rect.right, &printable_rect.bottom); } - fJobData->setScaling(100.0); + float scaling = atoi(fScaling->Text()); + if (scaling <= 0.0) { // sanity check + scaling = 100.0; + } + if (scaling > 1000.0) { + scaling = 1000.0; + } + + float scalingR = 100.0 / scaling; + + fJobData->setScaling(scaling); fJobData->setPaperRect(paper_rect); + fJobData->setScaledPaperRect(ScaleRect(paper_rect, scalingR)); fJobData->setPrintableRect(printable_rect); + fJobData->setScaledPrintableRect(ScaleRect(printable_rect, scalingR)); fJobData->save(); return true;