diff --git a/src/add-ons/print/drivers/shared/libprint/AboutBox.cpp b/src/add-ons/print/drivers/shared/libprint/AboutBox.cpp new file mode 100644 index 0000000000..d94d716c74 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/AboutBox.cpp @@ -0,0 +1,107 @@ +/* + * AboutBox.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include + +#include +#include +#include + +#include "AboutBox.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +class AboutBoxView : public BView { +public: + AboutBoxView(BRect frame, const char *driver_name, const char *version, const char *copyright); + virtual void Draw(BRect); + virtual void AttachedToWindow(); + +private: + string __driver_name; + string __version; + string __copyright; +}; + +AboutBoxView::AboutBoxView(BRect rect, const char *driver_name, const char *version, const char *copyright) + : BView(rect, "", B_FOLLOW_ALL, B_WILL_DRAW) +{ + __driver_name = driver_name; + __version = version; + __copyright = copyright; + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + SetDrawingMode(B_OP_SELECT); +} + +void AboutBoxView::Draw(BRect) +{ + SetHighColor(0, 0, 0); + DrawString(__driver_name.c_str(), BPoint(10.0f, 16.0f)); + DrawString(" Driver for "); + SetHighColor(0, 0, 0xff); + DrawString("B"); + SetHighColor(0xff, 0, 0); + DrawString("e"); + SetHighColor(0, 0, 0); + DrawString("OS Version "); + DrawString(__version.c_str()); + DrawString(__copyright.c_str(), BPoint(10.0f, 30.0f)); +} + +#define M_OK 1 + +void AboutBoxView::AttachedToWindow() +{ + BRect rect; + rect.Set(110, 50, 175, 55); + BButton *button = new BButton(rect, "", "OK", new BMessage(M_OK)); + AddChild(button); + button->MakeDefault(true); +} + +class AboutBoxWindow : public BWindow { +public: + AboutBoxWindow(BRect frame, const char *driver_name, const char *version, const char *copyright); + virtual void MessageReceived(BMessage *msg); + virtual bool QuitRequested(); +}; + +AboutBoxWindow::AboutBoxWindow(BRect frame, const char *driver_name, const char *version, const char *copyright) + : BWindow(frame, "", B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE ) +{ + char title[256]; + sprintf(title, "About %s Driver", driver_name); + SetTitle(title); + AddChild(new AboutBoxView(Bounds(), driver_name, version, copyright)); +} + +void AboutBoxWindow::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case M_OK: + be_app->PostMessage(B_QUIT_REQUESTED); + break; + } +} + +bool AboutBoxWindow::QuitRequested() +{ + be_app->PostMessage(B_QUIT_REQUESTED); + return true; +} + +AboutBox::AboutBox(const char *signature, const char *driver_name, const char *version, const char *copyright) + : BApplication(signature) +{ + BRect rect; + rect.Set(100, 80, 400, 170); + AboutBoxWindow *window = new AboutBoxWindow(rect, driver_name, version, copyright); + window->Show(); +} diff --git a/src/add-ons/print/drivers/shared/libprint/DbgMsg.cpp b/src/add-ons/print/drivers/shared/libprint/DbgMsg.cpp new file mode 100644 index 0000000000..39825fb4d5 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/DbgMsg.cpp @@ -0,0 +1,237 @@ +/* + * DbgMsg.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include + +#include +#include +#include +#include + +#include "DbgMsg.h" + +#ifdef DBG + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +void write_debug_stream(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + FILE *f = fopen("/boot/home/libprint.log", "aw+"); + vfprintf(f, format, ap); + fclose(f); + va_end(ap); +} + + +void DUMP_BFILE(BFile *in, const char *path) +{ + off_t size; + if (B_NO_ERROR == in->GetSize(&size)) { + uchar *buffer = new uchar[size]; + in->Read(buffer, size); + BFile out(path, B_WRITE_ONLY | B_CREATE_FILE); + out.Write(buffer, size); + in->Seek(0, SEEK_SET); + delete [] buffer; + } +} + + +void DUMP_BMESSAGE(BMessage *msg) +{ + uint32 i; + int32 j; + char *name = ""; + uint32 type = 0; + int32 count = 0; + + DBGMSG(("\t************ START - DUMP BMessage ***********\n")); + DBGMSG(("\taddress: 0x%x\n", (int)msg)); + if (!msg) + return; + +// DBGMSG(("\tmsg->what: 0x%x\n", msg->what)); + DBGMSG(("\tmsg->what: %c%c%c%c\n", + *((char *)&msg->what + 3), + *((char *)&msg->what + 2), + *((char *)&msg->what + 1), + *((char *)&msg->what + 0))); + + for (i= 0; msg->GetInfo(B_ANY_TYPE, i, &name, &type, &count) == B_OK; i++) { + switch (type) { + case B_BOOL_TYPE: + for (j = 0; j < count; j++) { + bool aBool; + aBool = msg->FindBool(name, j); + DBGMSG(("\t%s, B_BOOL_TYPE[%d]: %s\n", + name, j, aBool ? "true" : "false")); + } + break; + + case B_INT8_TYPE: + for (j = 0; j < count; j++) { + int8 anInt8; + msg->FindInt8(name, j, &anInt8); + DBGMSG(("\t%s, B_INT8_TYPE[%d]: %d\n", name, j, (int)anInt8)); + } + break; + + case B_INT16_TYPE: + for (j = 0; j < count; j++) { + int16 anInt16; + msg->FindInt16(name, j, &anInt16); + DBGMSG(("\t%s, B_INT16_TYPE[%d]: %d\n", name, j, (int)anInt16)); + } + break; + + case B_INT32_TYPE: + for (j = 0; j < count; j++) { + int32 anInt32; + msg->FindInt32(name, j, &anInt32); + DBGMSG(("\t%s, B_INT32_TYPE[%d]: %d\n", name, j, (int)anInt32)); + } + break; + + case B_INT64_TYPE: + for (j = 0; j < count; j++) { + int64 anInt64; + msg->FindInt64(name, j, &anInt64); + DBGMSG(("\t%s, B_INT64_TYPE[%d]: %d\n", name, j, (int)anInt64)); + } + break; + + case B_FLOAT_TYPE: + for (j = 0; j < count; j++) { + float aFloat; + msg->FindFloat(name, j, &aFloat); + DBGMSG(("\t%s, B_FLOAT_TYPE[%d]: %f\n", name, j, aFloat)); + } + break; + + case B_DOUBLE_TYPE: + for (j = 0; j < count; j++) { + double aDouble; + msg->FindDouble(name, j, &aDouble); + DBGMSG(("\t%s, B_DOUBLE_TYPE[%d]: %f\n", name, j, (float)aDouble)); + } + break; + + case B_STRING_TYPE: + for (j = 0; j < count; j++) { + const char *string; + msg->FindString(name, j, &string); + DBGMSG(("\t%s, B_STRING_TYPE[%d]: %s\n", name, j, string)); + } + break; + + case B_POINT_TYPE: + for (j = 0; j < count; j++) { + BPoint aPoint; + msg->FindPoint(name, j, &aPoint); + DBGMSG(("\t%s, B_POINT_TYPE[%d]: %f, %f\n", + name, j, aPoint.x, aPoint.y)); + } + break; + + case B_RECT_TYPE: + for (j = 0; j < count; j++) { + BRect aRect; + msg->FindRect(name, j, &aRect); + DBGMSG(("\t%s, B_RECT_TYPE[%d]: %f, %f, %f, %f\n", + name, j, aRect.left, aRect.top, aRect.right, aRect.bottom)); + } + break; + + case B_REF_TYPE: + case B_MESSAGE_TYPE: + case B_MESSENGER_TYPE: + case B_POINTER_TYPE: + DBGMSG(("\t%s, 0x%x, count: %d\n", + name ? name : "(null)", type, count)); + break; + default: + DBGMSG(("\t%s, 0x%x, count: %d\n", + name ? name : "(null)", type, count)); + break; + } + + name = ""; + type = 0; + count = 0; + } + DBGMSG(("\t************ END - DUMP BMessage ***********\n")); +} + +#define PD_DRIVER_NAME "Driver Name" +#define PD_PRINTER_NAME "Printer Name" +#define PD_COMMENTS "Comments" + +void DUMP_BDIRECTORY(BDirectory *dir) +{ + DUMP_BNODE(dir); +} + +void DUMP_BNODE(BNode *dir) +{ + char buffer1[256]; + char buffer2[256]; + attr_info info; + int32 i; + float f; + BRect rc; + bool b; + + DBGMSG(("\t************ STRAT - DUMP BNode ***********\n")); + + dir->RewindAttrs(); + while (dir->GetNextAttrName(buffer1) == B_NO_ERROR) { + dir->GetAttrInfo(buffer1, &info); + switch (info.type) { + case B_ASCII_TYPE: + dir->ReadAttr(buffer1, info.type, 0, buffer2, sizeof(buffer2)); + DBGMSG(("\t%s, B_ASCII_TYPE: %s\n", buffer1, buffer2)); + break; + case B_STRING_TYPE: + dir->ReadAttr(buffer1, info.type, 0, buffer2, sizeof(buffer2)); + DBGMSG(("\t%s, B_STRING_TYPE: %s\n", buffer1, buffer2)); + break; + case B_INT32_TYPE: + dir->ReadAttr(buffer1, info.type, 0, &i, sizeof(i)); + DBGMSG(("\t%s, B_INT32_TYPE: %d\n", buffer1, i)); + break; + case B_FLOAT_TYPE: + dir->ReadAttr(buffer1, info.type, 0, &f, sizeof(f)); + DBGMSG(("\t%s, B_FLOAT_TYPE: %f\n", buffer1, f)); + break; + case B_RECT_TYPE: + dir->ReadAttr(buffer1, info.type, 0, &rc, sizeof(rc)); + DBGMSG(("\t%s, B_RECT_TYPE: %f, %f, %f, %f\n", buffer1, rc.left, rc.top, rc.right, rc.bottom)); + break; + case B_BOOL_TYPE: + dir->ReadAttr(buffer1, info.type, 0, &b, sizeof(b)); + DBGMSG(("\t%s, B_BOOL_TYPE: %d\n", buffer1, (int)b)); + break; + default: + DBGMSG(("\t%s, %c%c%c%c\n", + buffer1, + *((char *)&info.type + 3), + *((char *)&info.type + 2), + *((char *)&info.type + 1), + *((char *)&info.type + 0))); + break; + } + } + + DBGMSG(("\t************ END - DUMP BNode ***********\n")); +} + +#endif /* DBG */ diff --git a/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp b/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp new file mode 100644 index 0000000000..e710c88447 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/GraphicsDriver.cpp @@ -0,0 +1,654 @@ +/* + * GraphicsDriver.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GraphicsDriver.h" +#include "PrintProcess.h" +#include "JobData.h" +#include "PrinterData.h" +#include "PrinterCap.h" +#include "Preview.h" +#include "Transport.h" +#include "ValidRect.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +GraphicsDriver::GraphicsDriver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap) + : __msg(msg), __printer_data(printer_data), __printer_cap(printer_cap) +{ + __view = NULL; + __bitmap = NULL; + __transport = NULL; + __org_job_data = NULL; + __real_job_data = NULL; + __spool_meta_data = NULL; +} + +GraphicsDriver::~GraphicsDriver() +{ +} + +void GraphicsDriver::setupData(BFile *spool_file, long page_count) +{ + BMessage *msg = new BMessage(); + msg->Unflatten(spool_file); + __org_job_data = new JobData(msg, __printer_cap); + DUMP_BMESSAGE(msg); + delete msg; + + __real_job_data = new JobData(*__org_job_data); + BRect rc; + + switch (__org_job_data->getNup()) { + case 2: + case 8: + case 32: + case 128: + rc.left = __org_job_data->getPrintableRect().top; + rc.top = __org_job_data->getPrintableRect().left; + rc.right = __org_job_data->getPrintableRect().bottom; + rc.bottom = __org_job_data->getPrintableRect().right; + __real_job_data->setPrintableRect(rc); + if (JobData::PORTRAIT == __org_job_data->getOrientation()) + __real_job_data->setOrientation(JobData::LANDSCAPE); + else + __real_job_data->setOrientation(JobData::PORTRAIT); + break; + } + + if (__org_job_data->getCollate() && page_count > 1) { + __real_job_data->setCopies(1); + __internal_copies = __org_job_data->getCopies(); + } else { + __internal_copies = 1; + } + + __spool_meta_data = new SpoolMetaData(spool_file); +} + +void GraphicsDriver::cleanupData() +{ + delete __real_job_data; + delete __org_job_data; + delete __spool_meta_data; + __real_job_data = NULL; + __org_job_data = NULL; + __spool_meta_data = NULL; +} + +#define MAX_MEMORY_SIZE (4 *1024 *1024) + +void GraphicsDriver::setupBitmap() +{ + __pixel_depth = color_space2pixel_depth(__org_job_data->getSurfaceType()); + + __page_width = (__real_job_data->getPrintableRect().IntegerWidth() * __org_job_data->getXres() + 71) / 72; + __page_height = (__real_job_data->getPrintableRect().IntegerHeight() * __org_job_data->getYres() + 71) / 72; + + int widthByte = (__page_width * __pixel_depth + 7) / 8; + int size = widthByte * __page_height; + + if (size < MAX_MEMORY_SIZE) { + __band_count = 0; + __band_width = __page_width; + __band_height = __page_height; + } else { + __band_count = (size + MAX_MEMORY_SIZE - 1) / MAX_MEMORY_SIZE; + if ((JobData::LANDSCAPE == __real_job_data->getOrientation()) && (__flags & GDF_ROTATE_BAND_BITMAP)) { + __band_width = (__page_width + __band_count - 1) / __band_count; + __band_height = __page_height; + } else { + __band_width = __page_width; + __band_height = (__page_height + __band_count - 1) / __band_count; + } + } + + DBGMSG(("****************\n")); + DBGMSG(("page_width = %d\n", __page_width)); + DBGMSG(("page_height = %d\n", __page_height)); + DBGMSG(("band_count = %d\n", __band_count)); + DBGMSG(("band_height = %d\n", __band_height)); + DBGMSG(("****************\n")); + + BRect rect; + rect.Set(0, 0, __band_width - 1, __band_height - 1); + __bitmap = new BBitmap(rect, __org_job_data->getSurfaceType(), true); + __view = new BView(rect, "", B_FOLLOW_ALL, B_WILL_DRAW); + __bitmap->AddChild(__view); +} + +void GraphicsDriver::cleanupBitmap() +{ + delete __bitmap; + __bitmap = NULL; + __view = NULL; +} + +BPoint get_scale(JobData *org_job_data) +{ + float width; + float height; + BPoint scale; + + scale.x = scale.y = 1.0f; + + switch (org_job_data->getNup()) { + case 1: + scale.x = scale.y = 1.0f; + break; + case 2: /* 1x2 or 2x1 */ + width = org_job_data->getPrintableRect().Width(); + height = org_job_data->getPrintableRect().Height(); + if (width < height) { // portrait + scale.x = height / 2.0f / width; + scale.y = width / height; + } else { // landscape + scale.x = height / width; + scale.y = width / 2.0f / height; + } + break; + case 8: /* 2x4 or 4x2 */ + width = org_job_data->getPrintableRect().Width(); + height = org_job_data->getPrintableRect().Height(); + if (width < height) { + scale.x = height / 4.0f / width; + scale.y = width / height / 2.0f; + } else { + scale.x = height / width / 2.0f; + scale.y = width / 4.0f / height; + } + break; + case 32: /* 4x8 or 8x4 */ + width = org_job_data->getPrintableRect().Width(); + height = org_job_data->getPrintableRect().Height(); + if (width < height) { + scale.x = height / 8.0f / width; + scale.y = width / height / 4.0f; + } else { + scale.x = height / width / 4.0f; + scale.y = width / 8.0f / height; + } + break; + case 4: /* 2x2 */ + scale.x = scale.y = 1.0f / 2.0f; + break; + case 9: /* 3x3 */ + scale.x = scale.y = 1.0f / 3.0f; + break; + case 16: /* 4x4 */ + scale.x = scale.y = 1.0f / 4.0f; + break; + case 25: /* 5x5 */ + scale.x = scale.y = 1.0f / 5.0f; + break; + case 36: /* 6x6 */ + scale.x = scale.y = 1.0f / 6.0f; + break; + case 49: /* 7x7 */ + scale.x = scale.y = 1.0f / 7.0f; + break; + case 64: /* 8x8 */ + scale.x = scale.y = 1.0f / 8.0f; + break; + case 81: /* 9x9 */ + scale.x = scale.y = 1.0f / 9.0f; + break; + case 100: /* 10x10 */ + scale.x = scale.y = 1.0f / 10.0f; + break; + case 121: /* 11x11 */ + scale.x = scale.y = 1.0f / 11.0f; + break; + } + + DBGMSG(("real scale = %f, %f\n", scale.x, scale.y)); + return scale; +} + +BPoint get_offset( + int index, + const BPoint *scale, + JobData *org_job_data) +{ + BPoint offset; + offset.x = 0; + offset.y = 0; + + float width = org_job_data->getPrintableRect().Width(); + float height = org_job_data->getPrintableRect().Height(); + + switch (org_job_data->getNup()) { + case 1: + break; + case 2: + if (index == 1) { + if (JobData::PORTRAIT == org_job_data->getOrientation()) { + offset.x = width; + } else { + offset.y = height; + } + } + break; + case 8: + if (JobData::PORTRAIT == org_job_data->getOrientation()) { + offset.x = width * (index / 2); + offset.y = height * (index % 2); + } else { + offset.x = width * (index % 2); + offset.y = height * (index / 2); + } + break; + case 32: + if (JobData::PORTRAIT == org_job_data->getOrientation()) { + offset.x = width * (index / 4); + offset.y = height * (index % 4); + } else { + offset.x = width * (index % 4); + offset.y = height * (index / 4); + } + break; + case 4: + offset.x = width * (index / 2); + offset.y = height * (index % 2); + break; + case 9: + offset.x = width * (index / 3); + offset.y = height * (index % 3); + break; + case 16: + offset.x = width * (index / 4); + offset.y = height * (index % 4); + break; + case 25: + offset.x = width * (index / 5); + offset.y = height * (index % 5); + break; + case 36: + offset.x = width * (index / 6); + offset.y = height * (index % 6); + break; + case 49: + offset.x = width * (index / 7); + offset.y = height * (index % 7); + break; + case 64: + offset.x = width * (index / 8); + offset.y = height * (index % 8); + break; + case 81: + offset.x = width * (index / 9); + offset.y = height * (index % 9); + break; + case 100: + offset.x = width * (index / 10); + offset.y = height * (index % 10); + break; + case 121: + offset.x = width * (index / 11); + offset.y = height * (index % 11); + break; + } + + float real_scale = min(scale->x, scale->y); + if (real_scale != scale->x) + offset.x *= scale->x / real_scale; + else + offset.y *= scale->y / real_scale; + + return offset; +} + +bool GraphicsDriver::printPage(PageDataList *pages) +{ +#ifndef USE_PREVIEW_FOR_DEBUG + BPoint offset; + offset.x = 0.0f; + offset.y = 0.0f; + + if (pages == NULL) { + return nextBand(NULL, &offset); + } + + do { + __view->SetScale(1.0); + __view->SetHighColor(255, 255, 255); + __view->ConstrainClippingRegion(NULL); + __view->FillRect(__view->Bounds()); + + BPoint scale = get_scale(__org_job_data); + float real_scale = min(scale.x, scale.y) * __org_job_data->getXres() / 72.0f; + __view->SetScale(real_scale); + float x = offset.x / real_scale; + float y = offset.y / real_scale; + int page_index = 0; + + for (PageDataList::iterator it = pages->begin(); it != pages->end(); it++) { + BPoint left_top(get_offset(page_index++, &scale, __org_job_data)); + left_top.x -= x; + left_top.y -= y; + BRect clip(__org_job_data->getPrintableRect()); + clip.OffsetTo(left_top); + BRegion *region = new BRegion(); + region->Set(clip); + __view->ConstrainClippingRegion(region); + delete region; + if ((*it)->startEnum()) { + bool more; + do { + PictureData *picture_data; + more = (*it)->enumObject(&picture_data); + BPoint real_offset = left_top + picture_data->point; + __view->DrawPicture(picture_data->picture, real_offset); + __view->Sync(); + delete picture_data; + } while (more); + } + } + if (!nextBand(__bitmap, &offset)) { + return false; + } + } while (offset.x >= 0.0f && offset.y >= 0.0f); + + return true; +#else // !USE_PREVIEW_FOR_DEBUG + __view->SetScale(1.0); + __view->SetHighColor(255, 255, 255); + __view->ConstrainClippingRegion(NULL); + __view->FillRect(__view->Bounds()); + + BPoint scale = get_scale(__org_job_data); + __view->SetScale(min(scale.x, scale.y)); + + int page_index = 0; + PageDataList::iterator it; + + for (it = pages->begin() ; it != pages->end() ; it++) { + BPoint left_top(get_offset(page_index, &scale, __org_job_data)); + BRect clip(__org_job_data->getPrintableRect()); + clip.OffsetTo(left_top); + BRegion *region = new BRegion(); + region->Set(clip); + __view->ConstrainClippingRegion(region); + delete region; + if ((*it)->startEnum()) { + bool more; + do { + PictureData *picture_data; + more = (*it)->enumObject(&picture_data); + BPoint real_offset = left_top + picture_data->point; + __view->DrawPicture(picture_data->picture, real_offset); + __view->Sync(); + delete picture_data; + } while (more); + } + page_index++; + } + + BRect rc(__real_job_data->getPrintableRect()); + rc.OffsetTo(30.0, 30.0); + PreviewWindow *preview = new PreviewWindow(rc, "Preview", __bitmap); + preview->Go(); +#endif // USE_PREVIEW_FOR_DEBUG +} + +bool GraphicsDriver::printDocument(SpoolData *spool_data) +{ + bool more; + bool success; + PageData *page_data; + int page_index; + int nup; + + more = false; + success = true; + page_index = 0; + + if (spool_data->startEnum()) { + do { + DBGMSG(("page index = %d\n", page_index)); + if (!(success = startPage(page_index))) + break; + nup = __org_job_data->getNup(); + PageDataList pages; + do { + more = spool_data->enumObject(&page_data); + pages.push_back(page_data); + } while (more && --nup); + __view->Window()->Lock(); + success = printPage(&pages); + __view->Window()->Unlock(); + if (!success) + break; + if (!(success = endPage(page_index))) + break; + page_index++; + } while (more); + } + +#ifndef USE_PREVIEW_FOR_DEBUG + if (success + && __printer_cap->isSupport(PrinterCap::PRINTSTYLE) + && (__org_job_data->getPrintStyle() != JobData::SIMPLEX) + && (((page_index + __org_job_data->getNup() - 1) / __org_job_data->getNup()) % 2)) + { + success = startPage(page_index); + if (success) { + success = printPage(NULL); + if (success) { + success = endPage(page_index); + } + } + } +#endif + + return success; +} + +bool GraphicsDriver::printJob(BFile *spool_file) +{ + bool success = true; + print_file_header pfh; + + spool_file->Seek(0, SEEK_SET); + spool_file->Read(&pfh, sizeof(pfh)); + + DBGMSG(("print_file_header::version = 0x%x\n", pfh.version)); + DBGMSG(("print_file_header::page_count = %d\n", pfh.page_count)); + DBGMSG(("print_file_header::first_page = 0x%x\n", (int)pfh.first_page)); + + if (pfh.page_count <= 0) { + return true; + } + + __transport = new Transport(__printer_data); + + if (__transport->check_abort()) { + success = false; + } else { + setupData(spool_file, pfh.page_count); + setupBitmap(); + SpoolData spool_data(spool_file, pfh.page_count, __org_job_data->getNup(), __org_job_data->getReverse()); + success = startDoc(); + if (success) { + while (__internal_copies--) { + success = printDocument(&spool_data); + if (success == false) { + break; + } + } + endDoc(success); + } + cleanupBitmap(); + cleanupData(); + } + + if (success == false) { + BAlert *alert; + if (__transport->check_abort()) { + alert = new BAlert("", __transport->last_error().c_str(), "OK"); + } else { + alert = new BAlert("", "Printer not responding.", "OK"); + } + alert->Go(); + } + + delete __transport; + __transport = NULL; + + return success; +} + +BMessage *GraphicsDriver::takeJob(BFile* spool_file, uint32 flags) +{ + __flags = flags; + BMessage *msg; + if (printJob(spool_file)) { + msg = new BMessage('okok'); + } else { + msg = new BMessage('baad'); + } + return msg; +} + +bool GraphicsDriver::startDoc() +{ + return true; +} + +bool GraphicsDriver::startPage(int) +{ + return true; +} + +bool GraphicsDriver::nextBand(BBitmap *, BPoint *) +{ + return true; +} + +bool GraphicsDriver::endPage(int) +{ + return true; +} + +bool GraphicsDriver::endDoc(bool) +{ + return true; +} + +void GraphicsDriver::writeSpoolData(const void *buffer, size_t size) throw(TransportException) +{ + if (__transport) { + __transport->write(buffer, size); + } +} + +void GraphicsDriver::writeSpoolString(const char *format, ...) throw(TransportException) +{ + if (__transport) { + char buffer[256]; + va_list ap; + va_start(ap, format); + vsprintf(buffer, format, ap); + __transport->write(buffer, strlen(buffer)); + va_end(ap); + } +} + +void GraphicsDriver::writeSpoolChar(char c) throw(TransportException) +{ + if (__transport) { + __transport->write(&c, 1); + } +} + + +void GraphicsDriver::rgb32_to_rgb24(void* src, void* dst, int width) { + uint8* d = (uint8*)dst; + rgb_color* s = (rgb_color*)src; + for (int i = width; i > 0; i --) { + *d ++ = s->red; + *d ++ = s->green; + *d ++ = s->blue; + s++; + } +} + +void GraphicsDriver::cmap8_to_rgb24(void* src, void* dst, int width) { + uint8* d = (uint8*)dst; + uint8* s = (uint8*)src; + const color_map* cmap = system_colors(); + for (int i = width; i > 0; i --) { + const rgb_color* rgb = &cmap->color_list[*s]; + *d ++ = rgb->red; + *d ++ = rgb->green; + *d ++ = rgb->blue; + s ++; + } +} + +void GraphicsDriver::convert_to_rgb24(void* src, void* dst, int width, color_space cs) { + if (cs == B_RGB32) rgb32_to_rgb24(src, dst, width); + else if (cs == B_CMAP8) cmap8_to_rgb24(src, dst, width); + else { + DBGMSG(("color_space %d not supported", cs)); + } +} + +uint8 GraphicsDriver::gray(uint8 r, uint8 g, uint8 b) { + if (r == g && g == b) { + return r; + } else { + return (r * 3 + g * 6 + b) / 10; + } +} + + +void GraphicsDriver::rgb32_to_gray(void* src, void* dst, int width) { + uint8* d = (uint8*)dst; + rgb_color* s = (rgb_color*)src; + for (int i = width; i > 0; i --) { + *d ++ = gray(s->red, s->green, s->blue); + s++; + } +} + +void GraphicsDriver::cmap8_to_gray(void* src, void* dst, int width) { + uint8* d = (uint8*)dst; + uint8* s = (uint8*)src; + const color_map* cmap = system_colors(); + for (int i = width; i > 0; i --) { + const rgb_color* rgb = &cmap->color_list[*s]; + *d ++ = gray(rgb->red, rgb->green, rgb->blue); + s ++; + } +} + +void GraphicsDriver::convert_to_gray(void* src, void* dst, int width, color_space cs) { + if (cs == B_RGB32) rgb32_to_gray(src, dst, width); + else if (cs == B_CMAP8) cmap8_to_gray(src, dst, width); + else { + DBGMSG(("color_space %d not supported", cs)); + } +} + diff --git a/src/add-ons/print/drivers/shared/libprint/Halftone.cpp b/src/add-ons/print/drivers/shared/libprint/Halftone.cpp new file mode 100644 index 0000000000..3555caf6f7 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/Halftone.cpp @@ -0,0 +1,308 @@ +/* + * HalftoneEngine.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include +#include "Halftone.h" +#include "ValidRect.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +#include "Pattern.h" + +uint gray(rgb_color c) +{ + if (c.red == c.green && c.red == c.blue) { + return 255 - c.red; + } else { + return 255 - (c.red * 3 + c.green * 6 + c.blue) / 10; + } +} + +Halftone::Halftone(color_space cs, double gamma, DITHERTYPE dither_type) +{ + __pixel_depth = color_space2pixel_depth(cs); + __palette = system_colors()->color_list; + __gray = gray; + + createGammaTable(gamma); + memset(__cache_table, 0, sizeof(__cache_table)); + + switch (dither_type) { + case TYPE2: + __pattern = pattern16x16_type2; + break; + case TYPE3: + __pattern = pattern16x16_type3; + break; + default: + __pattern = pattern16x16_type1; + break; + } + + switch (cs) { + case B_GRAY1: + __dither = &Halftone::ditherGRAY1; + break; + case B_GRAY8: + __dither = &Halftone::ditherGRAY8; + break; + case B_RGB32: + case B_RGB32_BIG: + __dither = &Halftone::ditherRGB32; + break; +// case B_CMAP8: + default: + __dither = &Halftone::ditherCMAP8; + break; + } +} + +Halftone::~Halftone() +{ +} + +void Halftone::createGammaTable(double gamma) +{ +// gamma = 1.0f / gamma; + uint *g = __gamma_table; + for (int i = 0; i < 256; i++) { + *g++ = (uint)(pow((double)i / 255.0, gamma) * 256.0); + } +} + +void Halftone::initElements(int x, int y, uchar *elements) +{ + x &= 0x0F; + y &= 0x0F; + + const uchar *left = &__pattern[y * 16]; + const uchar *pos = left + x; + const uchar *right = left + 0x0F; + + for (int i = 0; i < 16; i++) { + *elements++ = *pos; + if (pos >= right) { + pos = left; + } else { + pos++; + } + } +} + +int Halftone::dither( + uchar *dst, + const uchar *src, + int x, + int y, + int width) +{ + return (this->*__dither)(dst, src, x, y, width); +} + +int Halftone::ditherGRAY1( + uchar *dst, + const uchar *src, + int, + int, + int width) +{ + int widthByte = (width + 7) / 8; + memcpy(dst, src, widthByte); + return widthByte; +} + +int Halftone::ditherGRAY8( + uchar *dst, + const uchar *src, + int x, + int y, + int width) +{ + uchar elements[16]; + initElements(x, y, elements); + + int widthByte = (width + 7) / 8; + int remainder = width % 8; + if (!remainder) + remainder = 8; + + uchar cur; + uint density; + int i, j; + uchar *e = elements; + uchar *last_e = elements + 16; + + if (width >= 8) { + for (i = 0; i < widthByte - 1; i++) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < 8; j++) { + density = __gamma_table[*src++]; + if (density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + } + if (remainder > 0) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < remainder; j++) { + density = __gamma_table[*src++]; + if (density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + + return widthByte; +} + +int Halftone::ditherCMAP8( + uchar *dst, + const uchar *src, + int x, + int y, + int width) +{ + uchar elements[16]; + initElements(x, y, elements); + + int widthByte = (width + 7) / 8; + int remainder = width % 8; + if (!remainder) + remainder = 8; + + rgb_color c; + uchar cur; + int i, j; + + uchar *e = elements; + uchar *last_e = elements + 16; + CACHE_FOR_CMAP8 *cache; + + if (width >= 8) { + for (i = 0; i < widthByte - 1; i++) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < 8; j++) { + cache = &__cache_table[*src]; + if (!cache->hit) { + cache->hit = true; + c = __palette[*src]; + cache->density = __gamma_table[__gray(c)]; + } + src++; + if (cache->density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + } + if (remainder > 0) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < remainder; j++) { + cache = &__cache_table[*src]; + if (!cache->hit) { + cache->hit = true; + c = __palette[*src]; + cache->density = __gamma_table[__gray(c)]; + } + src++; + if (cache->density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + + return widthByte; +} + +int Halftone::ditherRGB32( + uchar *dst, + const uchar *a_src, + int x, + int y, + int width) +{ + uchar elements[16]; + initElements(x, y, elements); + + const rgb_color *src = (const rgb_color *)a_src; + + int widthByte = (width + 7) / 8; + int remainder = width % 8; + if (remainder == 0) + remainder = 8; + + rgb_color c; + uchar cur; + uint density; + int i, j; + uchar *e = elements; + uchar *last_e = elements + 16; + + c = *src; + density = __gamma_table[__gray(c)]; + + if (width >= 8) { + for (i = 0; i < widthByte - 1; i++) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < 8; j++) { + if (c.red != src->red || c.green != src->green || c.blue != src->blue) { + c = *src; + density = __gamma_table[__gray(c)]; + } + src++; + if (density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + } + if (remainder > 0) { + cur = 0; + if (e == last_e) { + e = elements; + } + for (j = 0; j < remainder; j++) { + if (c.red != src->red || c.green != src->green || c.blue != src->blue) { + c = *src; + density = __gamma_table[__gray(c)]; + } + src++; + if (density > *e++) { + cur |= (0x80 >> j); + } + } + *dst++ = cur; + } + + return widthByte; +} diff --git a/src/add-ons/print/drivers/shared/libprint/Jamfile b/src/add-ons/print/drivers/shared/libprint/Jamfile new file mode 100644 index 0000000000..24f7a20978 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/Jamfile @@ -0,0 +1,23 @@ +SubDir OBOS_TOP src add-ons print drivers shared libprint ; + +SubDirHdrs [ FDirName $(OBOS_TOP) headers private print libprint ] ; + +StaticLibrary print : + AboutBox.cpp + DbgMsg.cpp + GraphicsDriver.cpp + Halftone.cpp + JobData.cpp + JobSetupDlg.cpp + PackBits.cpp + PageSetupDlg.cpp + Preview.cpp + PrinterData.cpp + PrinterCap.cpp + PrintProcess.cpp + SpoolMetaData.cpp + Transport.cpp + UIDriver.cpp + ValidRect.cpp +; + diff --git a/src/add-ons/print/drivers/shared/libprint/JobData.cpp b/src/add-ons/print/drivers/shared/libprint/JobData.cpp new file mode 100644 index 0000000000..6c56dbb1a4 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/JobData.cpp @@ -0,0 +1,322 @@ +/* + * JobData.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include "JobData.h" +#include "PrinterCap.h" +#include "DbgMsg.h" + +const char *JD_XRES = "xres"; +const char *JD_YRES = "yres"; +const char *JD_COPIES = "copies"; +const char *JD_ORIENTATION = "orientation"; +const char *JD_SCALING = "scaling"; +const char *JD_PAPER_RECT = "paper_rect"; +const char *JD_FIRST_PAGE = "first_page"; +const char *JD_LAST_PAGE = "last_page"; +const char *JD_PRINTABLE_RECT = "printable_rect"; + +const char *JD_PAPER = "JJJJ_paper"; +const char *JD_NUP = "JJJJ_nup"; +const char *JD_SURFACE_TYPE = "JJJJ_surface_type"; +const char *JD_GAMMA = "JJJJ_gamma"; +const char *JD_PAPER_SOURCE = "JJJJ_paper_source"; +const char *JD_COLLATE = "JJJJ_collate"; +const char *JD_REVERSE = "JJJJ_reverse"; +const char *JD_PRINT_STYLE = "JJJJ_print_style"; +const char *JD_BINDING_LOCATION = "JJJJ_binding_location"; +const char *JD_PAGE_ORDER = "JJJJ_page_order"; +const char *JD_COLOR = "JJJJ_color"; + +JobData::JobData(BMessage *msg, const PrinterCap *cap) +{ + load(msg, cap); +} + +JobData::~JobData() +{ +} + +JobData::JobData(const JobData &job_data) +{ + __paper = job_data.__paper; + __xres = job_data.__xres; + __yres = job_data.__yres; + __orientation = job_data.__orientation; + __scaling = job_data.__scaling; + __paper_rect = job_data.__paper_rect; + __printable_rect = job_data.__printable_rect; + __nup = job_data.__nup; + __first_page = job_data.__first_page; + __last_page = job_data.__last_page; + __surface_type = job_data.__surface_type; + __gamma = job_data.__gamma; + __paper_source = job_data.__paper_source; + __copies = job_data.__copies; + __collate = job_data.__collate; + __reverse = job_data.__reverse; + __print_style = job_data.__print_style; + __binding_location = job_data.__binding_location; + __page_order = job_data.__page_order; + __msg = job_data.__msg; + __color = job_data.__color; +} + +JobData &JobData::operator = (const JobData &job_data) +{ + __paper = job_data.__paper; + __xres = job_data.__xres; + __yres = job_data.__yres; + __orientation = job_data.__orientation; + __scaling = job_data.__scaling; + __paper_rect = job_data.__paper_rect; + __printable_rect = job_data.__printable_rect; + __nup = job_data.__nup; + __first_page = job_data.__first_page; + __last_page = job_data.__last_page; + __surface_type = job_data.__surface_type; + __gamma = job_data.__gamma; + __paper_source = job_data.__paper_source; + __copies = job_data.__copies; + __collate = job_data.__collate; + __reverse = job_data.__reverse; + __print_style = job_data.__print_style; + __binding_location = job_data.__binding_location; + __page_order = job_data.__page_order; + __msg = job_data.__msg; + __color = job_data.__color; + return *this; +} + +void JobData::load(BMessage *msg, const PrinterCap *cap) +{ + __msg = msg; + + if (msg->HasInt32(JD_PAPER)) + __paper = (PAPER)msg->FindInt32(JD_PAPER); + else if (cap->isSupport(PrinterCap::PAPER)) + __paper = ((const PaperCap *)cap->getDefaultCap(PrinterCap::PAPER))->paper; + else + __paper = A4; + + if (msg->HasInt64(JD_XRES)) { + int64 xres64; + msg->FindInt64(JD_XRES, &xres64); + __xres = xres64; + } else if (cap->isSupport(PrinterCap::RESOLUTION)) { + __xres = ((const ResolutionCap *)cap->getDefaultCap(PrinterCap::RESOLUTION))->xres; + } else { + __xres = 300; + } + + if (msg->HasInt64(JD_YRES)) { + int64 yres64; + msg->FindInt64(JD_YRES, &yres64); + __yres = yres64; + } else if (cap->isSupport(PrinterCap::RESOLUTION)) { + __yres = ((const ResolutionCap *)cap->getDefaultCap(PrinterCap::RESOLUTION))->yres; + } else { + __yres = 300; + } + + if (msg->HasInt32(JD_ORIENTATION)) + __orientation = (ORIENTATION)msg->FindInt32(JD_ORIENTATION); + else if (cap->isSupport(PrinterCap::ORIENTATION)) + __orientation = ((const OrientationCap *)cap->getDefaultCap(PrinterCap::ORIENTATION))->orientation; + else + __orientation = PORTRAIT; + + if (msg->HasFloat(JD_SCALING)) + __scaling = msg->FindFloat(JD_SCALING); + else + __scaling = 100.0f; + + if (msg->HasRect(JD_PAPER_RECT)) { + __paper_rect = msg->FindRect(JD_PAPER_RECT); + } + + if (msg->HasRect(JD_PRINTABLE_RECT)) { + __printable_rect = msg->FindRect(JD_PRINTABLE_RECT); + } + + if (msg->HasInt32(JD_FIRST_PAGE)) + __first_page = msg->FindInt32(JD_FIRST_PAGE); + else + __first_page = 1; + + if (msg->HasInt32(JD_LAST_PAGE)) + __last_page = msg->FindInt32(JD_LAST_PAGE); + else + __last_page = -1; + + if (msg->HasInt32(JD_NUP)) + __nup = msg->FindInt32(JD_NUP); + else + __nup = 1; + + if (msg->HasInt32(JD_SURFACE_TYPE)) + __surface_type = (color_space)msg->FindInt32(JD_SURFACE_TYPE); + else + __surface_type = B_CMAP8; + + if (msg->HasFloat(JD_GAMMA)) + __gamma = __msg->FindFloat(JD_GAMMA); + else + __gamma = 1.4f; + + if (msg->HasInt32(JD_PAPER_SOURCE)) + __paper_source = (PAPERSOURCE)__msg->FindInt32(JD_PAPER_SOURCE); + else if (cap->isSupport(PrinterCap::PAPERSOURCE)) + __paper_source = ((const PaperSourceCap *)cap->getDefaultCap(PrinterCap::PAPERSOURCE))->paper_source; + else + __paper_source = AUTO; + + if (msg->HasInt32(JD_COPIES)) + __copies = msg->FindInt32(JD_COPIES); + else + __copies = 1; + + if (msg->HasBool(JD_COLLATE)) + __collate = msg->FindBool(JD_COLLATE); + else + __collate = false; + + if (msg->HasBool(JD_REVERSE)) + __reverse = msg->FindBool(JD_REVERSE); + else + __reverse = false; + + if (msg->HasInt32(JD_PRINT_STYLE)) + __print_style = (PRINTSTYLE)msg->FindInt32(JD_PRINT_STYLE); + else if (cap->isSupport(PrinterCap::PRINTSTYLE)) + __print_style = ((const PrintStyleCap *)cap->getDefaultCap(PrinterCap::PRINTSTYLE))->print_style; + else + __print_style = SIMPLEX; + + if (msg->HasInt32(JD_BINDING_LOCATION)) + __binding_location = (BINDINGLOCATION)msg->FindInt32(JD_BINDING_LOCATION); + else if (cap->isSupport(PrinterCap::BINDINGLOCATION)) + __binding_location = ((const BindingLocationCap *)cap->getDefaultCap(PrinterCap::BINDINGLOCATION))->binding_location; + else + __binding_location = LONG_EDGE_LEFT; + + if (msg->HasInt32(JD_PAGE_ORDER)) + __page_order = (PAGEORDER)msg->FindInt32(JD_PAGE_ORDER); + else + __page_order = ACROSS_FROM_LEFT; + + if (msg->HasBool(JD_COLOR)) + __color = msg->FindBool(JD_COLOR); + else + __color = false; +} + +void JobData::save(BMessage *msg) +{ + if (msg == NULL) { + msg = __msg; + } + + if (msg->HasInt32(JD_PAPER)) + msg->ReplaceInt32(JD_PAPER, __paper); + else + msg->AddInt32(JD_PAPER, __paper); + + if (msg->HasInt64(JD_XRES)) + msg->ReplaceInt64(JD_XRES, __xres); + else + msg->AddInt64(JD_XRES, __xres); + + if (msg->HasInt64(JD_YRES)) + msg->ReplaceInt64(JD_YRES, __yres); + else + msg->AddInt64(JD_YRES, __yres); + + if (msg->HasInt32(JD_ORIENTATION)) + msg->ReplaceInt32(JD_ORIENTATION, __orientation); + else + msg->AddInt32(JD_ORIENTATION, __orientation); + + if (msg->HasFloat(JD_SCALING)) + msg->ReplaceFloat(JD_SCALING, __scaling); + else + msg->AddFloat(JD_SCALING, __scaling); + + if (msg->HasRect(JD_PAPER_RECT)) + msg->ReplaceRect(JD_PAPER_RECT, __paper_rect); + else + msg->AddRect(JD_PAPER_RECT, __paper_rect); + + if (msg->HasRect(JD_PRINTABLE_RECT)) + msg->ReplaceRect(JD_PRINTABLE_RECT, __printable_rect); + else + msg->AddRect(JD_PRINTABLE_RECT, __printable_rect); + + if (msg->HasInt32(JD_NUP)) + msg->ReplaceInt32(JD_NUP, __nup); + else + msg->AddInt32(JD_NUP, __nup); + + if (msg->HasInt32(JD_FIRST_PAGE)) + msg->ReplaceInt32(JD_FIRST_PAGE, __first_page); + else + msg->AddInt32(JD_FIRST_PAGE, __first_page); + + if (msg->HasInt32(JD_LAST_PAGE)) + msg->ReplaceInt32(JD_LAST_PAGE, __last_page); + else + msg->AddInt32(JD_LAST_PAGE, __last_page); + + if (msg->HasInt32(JD_SURFACE_TYPE)) + msg->ReplaceInt32(JD_SURFACE_TYPE, __surface_type); + else + msg->AddInt32(JD_SURFACE_TYPE, __surface_type); + + if (msg->HasFloat(JD_GAMMA)) + msg->ReplaceFloat(JD_GAMMA, __gamma); + else + msg->AddFloat(JD_GAMMA, __gamma); + + if (msg->HasInt32(JD_PAPER_SOURCE)) + msg->ReplaceInt32(JD_PAPER_SOURCE, __paper_source); + else + msg->AddInt32(JD_PAPER_SOURCE, __paper_source); + + if (msg->HasInt32(JD_COPIES)) + msg->ReplaceInt32(JD_COPIES, __copies); + else + msg->AddInt32(JD_COPIES, __copies); + + if (msg->HasBool(JD_COLLATE)) + msg->ReplaceBool(JD_COLLATE, __collate); + else + msg->AddBool(JD_COLLATE, __collate); + + if (msg->HasBool(JD_REVERSE)) + msg->ReplaceBool(JD_REVERSE, __reverse); + else + msg->AddBool(JD_REVERSE, __reverse); + + if (msg->HasInt32(JD_PRINT_STYLE)) + msg->ReplaceInt32(JD_PRINT_STYLE, __print_style); + else + msg->AddInt32(JD_PRINT_STYLE, __print_style); + + if (msg->HasInt32(JD_BINDING_LOCATION)) + msg->ReplaceInt32(JD_BINDING_LOCATION, __binding_location); + else + msg->AddInt32(JD_BINDING_LOCATION, __binding_location); + + if (msg->HasInt32(JD_PAGE_ORDER)) + msg->ReplaceInt32(JD_PAGE_ORDER, __page_order); + else + msg->AddInt32(JD_PAGE_ORDER, __page_order); + + if (msg->HasBool(JD_COLOR)) + msg->ReplaceBool(JD_COLOR, __color); + else + msg->AddBool(JD_COLOR, __color); +} diff --git a/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp b/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp new file mode 100644 index 0000000000..cfa13e0aec --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/JobSetupDlg.cpp @@ -0,0 +1,699 @@ +/* + * JobSetupDlg.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include +#include "_sstream" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "JobSetupDlg.h" +#include "JobData.h" +#include "PrinterData.h" +#include "PrinterCap.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +//#define PRINT_COPIES 100 + +#define PRINT_WIDTH 355 +#define PRINT_HEIGHT 210 + +#define QUALITY_H 10 +#define QUALITY_V 10 +#define QUALITY_WIDTH 180 +#define QUALITY_HEIGHT 70 + + #define BPP_H 10 + #define BPP_V 15 + #define BPP_WIDTH 140 + #define BPP_HEIGHT 16 + + #define GAMMA_H BPP_H + #define GAMMA_V BPP_V + BPP_HEIGHT + 10 + #define GAMMA_WIDTH 120 + #define GAMMA_HEIGHT BPP_HEIGHT + +#define PAGERABGE_H QUALITY_H +#define PAGERABGE_V QUALITY_V + QUALITY_HEIGHT + 5 +#define PAGERABGE_WIDTH QUALITY_WIDTH +#define PAGERABGE_HEIGHT 70 + + #define ALL_H 10 + #define ALL_V 20 + #define ALL_WIDTH 36 + #define ALL_HEIGHT 16 + + #define SELECTION_H ALL_H + #define SELECTION_V ALL_V + ALL_HEIGHT + 4 + #define SELECTION_WIDTH 16 + #define SELECTION_HEIGHT 16 + + #define FROM_H (SELECTION_H + SELECTION_WIDTH + 1) + #define FROM_V ALL_V + 19 + #define FROM_WIDTH 73 + #define FROM_HEIGHT 16 + + #define TO_H (FROM_H + FROM_WIDTH + 7) + #define TO_V FROM_V + #define TO_WIDTH 59 + #define TO_HEIGHT FROM_HEIGHT + +#define PAPERFEED_H QUALITY_H + QUALITY_WIDTH + 10 +#define PAPERFEED_V QUALITY_V + 5 +#define PAPERFEED_WIDTH 160 +#define PAPERFEED_HEIGHT 16 + +#define NUP_H PAPERFEED_H +#define NUP_V PAPERFEED_V + PAPERFEED_HEIGHT + 7 +#define NUP_WIDTH PAPERFEED_WIDTH +#define NUP_HEIGHT 16 +#define MENU_HEIGHT 16 + +#define COPIES_H PAPERFEED_H +#define COPIES_V NUP_V + NUP_HEIGHT + 10 +#define COPIES_WIDTH 140 +#define COPIES_HEIGHT 16 + +#define DUPLEX_H PAPERFEED_H +#define DUPLEX_V COPIES_V + COPIES_HEIGHT + 7 +#define DUPLEX_WIDTH PAPERFEED_WIDTH +#define DUPLEX_HEIGHT 16 + +#define COLLATE_H PAPERFEED_H +#define COLLATE_V DUPLEX_V + DUPLEX_HEIGHT + 5 +#define COLLATE_WIDTH PAPERFEED_WIDTH +#define COLLATE_HEIGHT 16 + +#define REVERSE_H PAPERFEED_H +#define REVERSE_V COLLATE_V + COLLATE_HEIGHT + 5 +#define REVERSE_WIDTH PAPERFEED_WIDTH +#define REVERSE_HEIGHT 16 + +#define PRINT_BUTTON_WIDTH 70 +#define PRINT_BUTTON_HEIGHT 20 + +#define PRINT_LINE_V (PRINT_HEIGHT - PRINT_BUTTON_HEIGHT - 23) + +#define PRINT_OK_BUTTON_H (PRINT_WIDTH - PRINT_BUTTON_WIDTH - 10) +#define PRINT_OK_BUTTON_V (PRINT_HEIGHT - PRINT_BUTTON_HEIGHT - 11) + +#define PRINT_CANCEL_BUTTON_H (PRINT_OK_BUTTON_H - PRINT_BUTTON_WIDTH - 12) +#define PRINT_CANCEL_BUTTON_V PRINT_OK_BUTTON_V + +const BRect quality_rect( + QUALITY_H, + QUALITY_V, + QUALITY_H + QUALITY_WIDTH, + QUALITY_V + QUALITY_HEIGHT); + +const BRect bpp_rect( + BPP_H, + BPP_V, + BPP_H + BPP_WIDTH, + BPP_V + BPP_HEIGHT); + +const BRect gamma_rect( + GAMMA_H, + GAMMA_V, + GAMMA_H + GAMMA_WIDTH, + GAMMA_V + GAMMA_HEIGHT); + +const BRect pagerange_rect( + PAGERABGE_H, + PAGERABGE_V, + PAGERABGE_H + PAGERABGE_WIDTH, + PAGERABGE_V + PAGERABGE_HEIGHT); + +const BRect all_button_rect( + ALL_H, + ALL_V, + ALL_H + ALL_WIDTH, + ALL_V + ALL_HEIGHT); + +const BRect selection_rect( + SELECTION_H, + SELECTION_V, + SELECTION_H + SELECTION_WIDTH, + SELECTION_V + SELECTION_HEIGHT); + +const BRect from_rect( + FROM_H, + FROM_V, + FROM_H + FROM_WIDTH, + FROM_V + FROM_HEIGHT); + +const BRect to_rect( + TO_H, + TO_V, + TO_H + TO_WIDTH, + TO_V + TO_HEIGHT); + +const BRect paperfeed_rect( + PAPERFEED_H, + PAPERFEED_V, + PAPERFEED_H + PAPERFEED_WIDTH, + PAPERFEED_V + PAPERFEED_HEIGHT); + +const BRect nup_rect( + NUP_H, + NUP_V, + NUP_H + NUP_WIDTH, + NUP_V + NUP_HEIGHT); + +const BRect copies_rect( + COPIES_H, + COPIES_V, + COPIES_H + COPIES_WIDTH, + COPIES_V + COPIES_HEIGHT); + +const BRect duplex_rect( + DUPLEX_H, + DUPLEX_V, + DUPLEX_H + DUPLEX_WIDTH, + DUPLEX_V + DUPLEX_HEIGHT); + +const BRect collate_rect( + COLLATE_H, + COLLATE_V, + COLLATE_H + COLLATE_WIDTH, + COLLATE_V + COLLATE_HEIGHT); + +const BRect reverse_rect( + REVERSE_H, + REVERSE_V, + REVERSE_H + REVERSE_WIDTH, + REVERSE_V + REVERSE_HEIGHT); + +const BRect ok_rect( + PRINT_OK_BUTTON_H, + PRINT_OK_BUTTON_V, + PRINT_OK_BUTTON_H + PRINT_BUTTON_WIDTH, + PRINT_OK_BUTTON_V + PRINT_BUTTON_HEIGHT); + +const BRect cancel_rect( + PRINT_CANCEL_BUTTON_H, + PRINT_CANCEL_BUTTON_V, + PRINT_CANCEL_BUTTON_H + PRINT_BUTTON_WIDTH, + PRINT_CANCEL_BUTTON_V + PRINT_BUTTON_HEIGHT); + +struct SurfaceCap : public BaseCap { + color_space surface_type; + SurfaceCap(const string &s, bool d, color_space cs) : BaseCap(s, d), surface_type(cs) {} +}; + +struct NupCap : public BaseCap { + int nup; + NupCap(const string &s, bool d, int n) : BaseCap(s, d), nup(n) {} +}; + +const SurfaceCap rgb32("RGB32", false, B_RGB32); +const SurfaceCap cmap8("CMAP8", true, B_CMAP8); +const SurfaceCap gray8("GRAY8", false, B_GRAY8); +const SurfaceCap gray1("GRAY1", false, B_GRAY1); + +const NupCap nup1("Normal", true, 1); +const NupCap nup2("2-up", false, 2); +const NupCap nup4("4-up", false, 4); +const NupCap nup8("8-up", false, 8); +const NupCap nup9("9-up", false, 9); +const NupCap nup16("16-up", false, 16); +const NupCap nup25("25-up", false, 25); +const NupCap nup32("32-up", false, 32); +const NupCap nup36("36-up", false, 36); + +const SurfaceCap *surfaces[] = { + &rgb32, + &cmap8, + &gray8, + &gray1 +}; + +const NupCap *nups[] = { + &nup1, + &nup2, + &nup4, + &nup8, + &nup9, + &nup16, + &nup25, + &nup32, + &nup36 +}; + +enum { + M_RANGE_ALL = 1, + M_RANGE_SELECTION, + M_CANCEL, + M_OK +}; + +JobSetupView::JobSetupView(BRect frame, JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) + : BView(frame, "", B_FOLLOW_ALL, B_WILL_DRAW), __job_data(job_data), __printer_data(printer_data), __printer_cap(printer_cap) +{ + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); +} + +void JobSetupView::AttachedToWindow() +{ + BBox *box; + BMenuItem *item = NULL; + BMenuField *menufield; + BButton *button; + float width; + bool marked; + int count; + + /* quality */ + + box = new BBox(quality_rect); + AddChild(box); + box->SetLabel("Quality"); + +/* + // always B_RGB32 + __surface_type = new BPopUpMenu(""); + __surface_type->SetRadioMode(true); + + count = sizeof(surfaces) / sizeof(surfaces[0]); + const SurfaceCap **surface_cap = surfaces; + uint32 support_flags; + while (count--) { + if (bitmaps_support_space((*surface_cap)->surface_type, &support_flags)) { + item = new BMenuItem((*surface_cap)->label.c_str(), NULL); + __surface_type->AddItem(item); + if ((*surface_cap)->surface_type == __job_data->getSurfaceType()) { + item->SetMarked(true); + marked = true; + } + } + surface_cap++; + } + menufield = new BMenuField(bpp_rect, "", "Surface Type", __surface_type); + box->AddChild(menufield); + width = StringWidth("Color") + 10; + menufield->SetDivider(width); +*/ + + /* color */ + marked = false; + __color_type = new BPopUpMenu(""); + __color_type->SetRadioMode(true); + + count = __printer_cap->countCap(PrinterCap::COLOR); + const ColorCap **color_cap = (const ColorCap **)__printer_cap->enumCap(PrinterCap::COLOR); + while (count--) { + item = new BMenuItem((*color_cap)->label.c_str(), NULL); + __color_type->AddItem(item); + if ((*color_cap)->color == __job_data->getColor()) { + item->SetMarked(true); + marked = true; + } + color_cap++; + } + if (!marked && item) + item->SetMarked(true); + menufield = new BMenuField(bpp_rect, "", "Color", __color_type); + + box->AddChild(menufield); + width = StringWidth("Color") + 10; + menufield->SetDivider(width); + + __gamma = new BTextControl(gamma_rect, "", "Gamma", "", NULL); + box->AddChild(__gamma); + __gamma->SetDivider(width); + ostringstream oss3; + oss3 << __job_data->getGamma(); + __gamma->SetText(oss3.str().c_str()); + + /* page range */ + + box = new BBox(pagerange_rect); + AddChild(box); + box->SetLabel("Page Range"); + + __all = new BRadioButton(all_button_rect, "", "All", new BMessage(M_RANGE_ALL)); + box->AddChild(__all); + + BRadioButton *from = new BRadioButton(selection_rect, "", "", new BMessage(M_RANGE_SELECTION)); + box->AddChild(from); + + from_page = new BTextControl(from_rect, "", "From", "", NULL); + box->AddChild(from_page); + from_page->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); + from_page->SetDivider(StringWidth("From") + 7); + + to_page = new BTextControl(to_rect, "", "To", "", NULL); + box->AddChild(to_page); + to_page->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT); + to_page->SetDivider(StringWidth("To") + 7); + + int first_page = __job_data->getFirstPage(); + int last_page = __job_data->getLastPage(); + + if (first_page <= 1 && last_page <= 0) { + __all->SetValue(B_CONTROL_ON); + from_page->SetEnabled(false); + to_page->SetEnabled(false); + } else { + from->SetValue(B_CONTROL_ON); + if (first_page < 1) + first_page = 1; + if (first_page > last_page) + last_page = -1; + + ostringstream oss1; + oss1 << first_page; + from_page->SetText(oss1.str().c_str()); + + ostringstream oss2; + oss2 << last_page; + to_page->SetText(oss2.str().c_str()); + } + + __all->SetTarget(this); + from->SetTarget(this); + + /* paper source */ + + marked = false; + __paper_feed = new BPopUpMenu(""); + __paper_feed->SetRadioMode(true); + count = __printer_cap->countCap(PrinterCap::PAPERSOURCE); + const PaperSourceCap **paper_source_cap = (const PaperSourceCap **)__printer_cap->enumCap(PrinterCap::PAPERSOURCE); + while (count--) { + item = new BMenuItem((*paper_source_cap)->label.c_str(), NULL); + __paper_feed->AddItem(item); + if ((*paper_source_cap)->paper_source == __job_data->getPaperSource()) { + item->SetMarked(true); + marked = true; + } + paper_source_cap++; + } + if (!marked) + item->SetMarked(true); + menufield = new BMenuField(paperfeed_rect, "", "Paper Source", __paper_feed); + AddChild(menufield); + width = StringWidth("Number of Copies") + 7; + menufield->SetDivider(width); + + /* Page Per Sheet */ + + marked = false; + __nup = new BPopUpMenu(""); + __nup->SetRadioMode(true); + count = sizeof(nups) / sizeof(nups[0]); + const NupCap **nup_cap = nups; + while (count--) { + item = new BMenuItem((*nup_cap)->label.c_str(), NULL); + __nup->AddItem(item); + if ((*nup_cap)->nup == __job_data->getNup()) { + item->SetMarked(true); + marked = true; + } + nup_cap++; + } + if (!marked) + item->SetMarked(true); + menufield = new BMenuField(nup_rect, "", "Page Per Sheet", __nup); + menufield->SetDivider(width); + AddChild(menufield); + + /* duplex */ + + if (__printer_cap->isSupport(PrinterCap::PRINTSTYLE)) { + __duplex = new BCheckBox(duplex_rect, "Duplex", "Duplex", NULL); + AddChild(__duplex); + if (__job_data->getPrintStyle() != JobData::SIMPLEX) { + __duplex->SetValue(B_CONTROL_ON); + } + } + + /* copies */ + + copies = new BTextControl(copies_rect, "", "Number of Copies", "", NULL); + AddChild(copies); + copies->SetDivider(width); + + ostringstream oss4; + oss4 << __job_data->getCopies(); + copies->SetText(oss4.str().c_str()); + + /* collate */ + + __collate = new BCheckBox(collate_rect, "Collate", "Collate", NULL); + AddChild(__collate); + if (__job_data->getCollate()) { + __collate->SetValue(B_CONTROL_ON); + } + + /* reverse */ + + __reverse = new BCheckBox(reverse_rect, "Reverse", "Reverse", NULL); + AddChild(__reverse); + if (__job_data->getReverse()) { + __reverse->SetValue(B_CONTROL_ON); + } + + /* cancel */ + + button = new BButton(cancel_rect, "", "Cancel", new BMessage(M_CANCEL)); + AddChild(button); + + /* ok */ + + button = new BButton(ok_rect, "", "OK", new BMessage(M_OK)); + AddChild(button); + button->MakeDefault(true); +} + +void JobSetupView::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case M_RANGE_ALL: + Window()->Lock(); + from_page->SetEnabled(false); + to_page->SetEnabled(false); + Window()->Unlock(); + break; + + case M_RANGE_SELECTION: + Window()->Lock(); + from_page->SetEnabled(true); + to_page->SetEnabled(true); + Window()->Unlock(); + break; + } +} + +bool JobSetupView::UpdateJobData() +{ + int count; + +/* + count = sizeof(surfaces) / sizeof(surfaces[0]); + const SurfaceCap **surface_cap = surfaces; + const char *surface_label = __surface_type->FindMarked()->Label(); + while (count--) { + if (!strcmp((*surface_cap)->label.c_str(), surface_label)) { + __job_data->setSurfaceType((*surface_cap)->surface_type); + break; + } + surface_cap++; + } +*/ + count = __printer_cap->countCap(PrinterCap::COLOR); + const ColorCap **color_cap = (const ColorCap**)__printer_cap->enumCap(PrinterCap::COLOR); + const char *color_label = __color_type->FindMarked()->Label(); + while (count--) { + if (!strcmp((*color_cap)->label.c_str(), color_label)) { + __job_data->setColor((*color_cap)->color); + break; + } + color_cap++; + } + + __job_data->setGamma(atof(__gamma->Text())); + + int first_page; + int last_page; + + if (B_CONTROL_ON == __all->Value()) { + first_page = 1; + last_page = -1; + } else { + first_page = atoi(from_page->Text()); + last_page = atoi(to_page->Text()); + } + + __job_data->setFirstPage(first_page); + __job_data->setLastPage(last_page); + + count = __printer_cap->countCap(PrinterCap::PAPERSOURCE); + const PaperSourceCap **paper_source_cap = (const PaperSourceCap **)__printer_cap->enumCap(PrinterCap::PAPERSOURCE); + const char *paper_source_label = __paper_feed->FindMarked()->Label(); + while (count--) { + if (!strcmp((*paper_source_cap)->label.c_str(), paper_source_label)) { + __job_data->setPaperSource((*paper_source_cap)->paper_source); + break; + } + paper_source_cap++; + } + + count = sizeof(nups) / sizeof(nups[0]); + const NupCap **nup_cap = nups; + const char *nup_label = __nup->FindMarked()->Label(); + while (count--) { + if (!strcmp((*nup_cap)->label.c_str(), nup_label)) { + __job_data->setNup((*nup_cap)->nup); + break; + } + nup_cap++; + } + + if (__printer_cap->isSupport(PrinterCap::PRINTSTYLE)) { + __job_data->setPrintStyle((B_CONTROL_ON == __duplex->Value()) ? JobData::DUPLEX : JobData::SIMPLEX); + } + + __job_data->setCopies(atoi(copies->Text())); + + __job_data->setCollate((B_CONTROL_ON == __collate->Value()) ? true : false); + __job_data->setReverse((B_CONTROL_ON == __reverse->Value()) ? true : false); + + __job_data->save(); + return true; +} + +//==================================================================== + +filter_result PrintKeyFilter(BMessage *msg, BHandler **target, BMessageFilter *filter) +{ + + BWindow *window = (BWindow *)filter->Looper(); + JobSetupView *view = (JobSetupView *)window->ChildAt(0); + + if ((*target != view->copies->ChildAt(0)) && + (*target != view->from_page->ChildAt(0)) && + (*target != view->to_page->ChildAt(0))) + { + return B_DISPATCH_MESSAGE; + } + + ulong mods = msg->FindInt32("modifiers"); + if (mods & B_COMMAND_KEY) + return B_DISPATCH_MESSAGE; + + const uchar *bytes = NULL; + if (msg->FindString("bytes", (const char **)&bytes) != B_NO_ERROR) + return B_DISPATCH_MESSAGE; + + long key = bytes[0]; + if (key < '0') { + if ((key != B_TAB) && (key != B_BACKSPACE) && (key != B_ENTER) && + (key != B_LEFT_ARROW) && (key != B_RIGHT_ARROW) && + (key != B_UP_ARROW) && (key != B_DOWN_ARROW)) + return B_SKIP_MESSAGE; + } + if (key > '9') + return B_SKIP_MESSAGE; + return B_DISPATCH_MESSAGE; +} + +//==================================================================== + +JobSetupDlg::JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) + : BWindow(BRect(100, 100, 100 + PRINT_WIDTH, 100 + PRINT_HEIGHT), + "PrintJob Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, + B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE) +{ + __result = 0; +/* + ostringstream oss; + oss << printer_data->get_printer_name() << " Print"; + SetTitle(oss.str().c_str()); +*/ + Lock(); + JobSetupView *view = new JobSetupView(Bounds(), job_data, printer_data, printer_cap); + AddChild(view); + __filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN, &PrintKeyFilter); + AddCommonFilter(__filter); + Unlock(); + + __semaphore = create_sem(0, "JobSetupSem"); +} + +JobSetupDlg::~JobSetupDlg() +{ + Lock(); + RemoveCommonFilter(__filter); + Unlock(); + delete __filter; +} + +bool JobSetupDlg::QuitRequested() +{ + __result = B_ERROR; + release_sem(__semaphore); + return true; +} + +void JobSetupDlg::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case M_OK: + Lock(); + ((JobSetupView *)ChildAt(0))->UpdateJobData(); + Unlock(); + __result = B_NO_ERROR; + release_sem(__semaphore); + break; + + case M_CANCEL: + __result = B_ERROR; + release_sem(__semaphore); + break; + + default: + BWindow::MessageReceived(msg); + break; + } +} + +int JobSetupDlg::Go() +{ + Show(); + acquire_sem(__semaphore); + delete_sem(__semaphore); + int value = __result; + Lock(); + Quit(); + return value; +} diff --git a/src/add-ons/print/drivers/shared/libprint/PackBits.cpp b/src/add-ons/print/drivers/shared/libprint/PackBits.cpp new file mode 100644 index 0000000000..409025ae7d --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/PackBits.cpp @@ -0,0 +1,158 @@ +/* + * PackBits.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +//#define DBG_CON_STREAM + +#ifdef DBG_CON_STREAM +#include +#endif + +#include +#include "PackBits.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +#define MAXINBYTES 127 +#define CONTROL1(i) -i +#define CONTROL2(i) i + +enum STATUS { + INITIAL, + UNDECIDED, + UNMATCHED, + MATCHED +}; + +int pack_bits(unsigned char *pOut, unsigned char *pIn, int n) +{ + int i; + unsigned char *control; + unsigned char *runbuf; + unsigned char thisbyte; + unsigned char runbyte; + STATUS status; + + i = 0; + status = INITIAL; + control = runbuf = pOut; + runbyte = *pIn++; + + while (--n) { + thisbyte = *pIn++; + switch (status) { + case INITIAL: + control = runbuf++; + *runbuf++ = runbyte; + if (thisbyte == runbyte) { + status = UNDECIDED; + } else { + runbyte = thisbyte; + status = UNMATCHED; + } + i = 1; + break; + + case UNDECIDED: + if (i == MAXINBYTES) { + *control = CONTROL2(i); + *runbuf++ = runbyte; + runbyte = thisbyte; + status = INITIAL; + } else if (thisbyte == runbyte) { + if (i > 1) { + *control = CONTROL2(i - 2); + control = runbuf - 1; + } + i = 2; + status = MATCHED; + } else { + *runbuf++ = runbyte; + runbyte = thisbyte; + status = UNMATCHED; + i++; + } + break; + + case UNMATCHED: + if (i == MAXINBYTES) { + *control = CONTROL2(i); + status = INITIAL; + } else { + if (thisbyte == runbyte) { + status = UNDECIDED; + } + i++; + } + *runbuf++ = runbyte; + runbyte = thisbyte; + break; + + case MATCHED: + if ((thisbyte != runbyte) || (i == MAXINBYTES)) { + runbuf = control; + *runbuf++ = CONTROL1(i); + *runbuf++ = runbyte; + runbyte = thisbyte; + status = INITIAL; + } else { + i++; + } + break; + } + } + + switch (status) { + case INITIAL: + *runbuf++ = CONTROL2(1); + break; + case UNDECIDED: + case UNMATCHED: + *control = CONTROL2(i); + break; + case MATCHED: + runbuf = control; + *runbuf++ = CONTROL1(i); + break; + } + *runbuf++ = runbyte; + + return runbuf - pOut; +} + +#ifdef DBG_CON_STREAM +int main(int argc, char **argv) +{ + if (argc < 2) { + return -1; + } + + ifstream ifs(*++argv, ios::binary | ios::nocreate); + if (!ifs) { + return -1; + } + + ifs.seekg(0, ios::end); + long size = ifs.tellg(); + ifs.seekg(0, ios::beg); + + unsigned char *pIn = new unsigned char[size]; + unsigned char *pOut = new unsigned char[size * 3]; + + ifs.read(pIn, size); + + int cnt = PackBits(pOut, pIn, size); + + ofstream ofs("test.bin", ios::binary); + ofs.write(pOut, cnt); + + delete [] pIn; + delete [] pOut; + +} +#endif diff --git a/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp b/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp new file mode 100644 index 0000000000..8d24502566 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/PageSetupDlg.cpp @@ -0,0 +1,334 @@ +/* + * PageSetupDlg.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PageSetupDlg.h" +#include "JobData.h" +#include "PrinterData.h" +#include "PrinterCap.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +#define PAGESETUP_WIDTH 270 +#define PAGESETUP_HEIGHT 125 + +#define MENU_HEIGHT 16 +#define BUTTON_WIDTH 70 +#define BUTTON_HEIGHT 20 + +#define ORIENT_H 10 +#define ORIENT_V 10 +#define ORIENT_WIDTH 100 +#define ORIENT_HEIGHT 60 +#define PORT_TEXT "Portrait" +#define RAND_TEXT "Landscape" + +#define PAPER_H ORIENT_H + ORIENT_WIDTH + 15 +#define PAPER_V 20 +#define PAPER_WIDTH 200 +#define PAPER_HEIGHT MENU_HEIGHT +#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 OK_H (PAGESETUP_WIDTH - BUTTON_WIDTH - 11) +#define OK_V (PAGESETUP_HEIGHT - BUTTON_HEIGHT - 11) +#define OK_TEXT "OK" + +#define CANCEL_H (OK_H - BUTTON_WIDTH - 12) +#define CANCEL_V OK_V +#define CANCEL_TEXT "Cancel" + +#define PRINT_LINE_V (PAGESETUP_HEIGHT - BUTTON_HEIGHT - 23) + +const BRect ORIENTAION_RECT( + ORIENT_H, + ORIENT_V, + ORIENT_H + ORIENT_WIDTH, + ORIENT_V + ORIENT_HEIGHT); + +const BRect PORT_RECT(10, 15, 80, 14); +const BRect LAND_RECT(10, 35, 80, 14); + +const BRect PAPER_RECT( + PAPER_H, + PAPER_V, + PAPER_H + PAPER_WIDTH, + PAPER_V + PAPER_HEIGHT); + +const BRect RESOLUTION_RECT( + RES_H, + RES_V, + RES_H + RES_WIDTH, + RES_V + RES_HEIGHT); + +const BRect OK_RECT( + OK_H, + OK_V, + OK_H + BUTTON_WIDTH, + OK_V + BUTTON_HEIGHT); + +const BRect CANCEL_RECT( + CANCEL_H, + CANCEL_V, + CANCEL_H + BUTTON_WIDTH, + CANCEL_V + BUTTON_HEIGHT); + +enum MSGS { + M_CANCEL = 1, + M_OK +}; + +PageSetupView::PageSetupView(BRect frame, JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) + : BView(frame, "", B_FOLLOW_ALL, B_WILL_DRAW), __job_data(job_data), __printer_data(printer_data), __printer_cap(printer_cap) +{ + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); +} + +PageSetupView::~PageSetupView() +{ +} + +void PageSetupView::AttachedToWindow() +{ + BMenuItem *item = NULL; + BMenuField *menufield; + BButton *button; + bool marked; + int count; + + /* orientaion */ + + BBox *box = new BBox(ORIENTAION_RECT); + AddChild(box); + box->SetLabel("Orientation"); + + __portrait = new BRadioButton(PORT_RECT, "", PORT_TEXT, NULL); + box->AddChild(__portrait); + + BRadioButton *landscape = new BRadioButton(LAND_RECT, "", RAND_TEXT, NULL); + box->AddChild(landscape); + + if (JobData::PORTRAIT == __job_data->getOrientation()) + __portrait->SetValue(B_CONTROL_ON); + else + landscape->SetValue(B_CONTROL_ON); + + /* paper selection */ + + marked = false; + __paper = new BPopUpMenu(""); + __paper->SetRadioMode(true); + count = __printer_cap->countCap(PrinterCap::PAPER); + PaperCap **paper_cap = (PaperCap **)__printer_cap->enumCap(PrinterCap::PAPER); + while (count--) { + item = new BMenuItem((*paper_cap)->label.c_str(), NULL); + __paper->AddItem(item); + item->SetTarget(this); + if ((*paper_cap)->paper == __job_data->getPaper()) { + item->SetMarked(true); + marked = true; + } + paper_cap++; + } + if (!marked) + item->SetMarked(true); + menufield = new BMenuField(PAPER_RECT, "", PAPER_TEXT, __paper); + AddChild(menufield); + float width = StringWidth(PAPER_TEXT) + 7; + menufield->SetDivider(width); + + /* resolution */ + + marked = false; + __resolution = new BPopUpMenu(""); + __resolution->SetRadioMode(true); + count = __printer_cap->countCap(PrinterCap::RESOLUTION); + ResolutionCap **resolution_cap = (ResolutionCap **)__printer_cap->enumCap(PrinterCap::RESOLUTION); + while (count--) { + item = new BMenuItem((*resolution_cap)->label.c_str(), NULL); + __resolution->AddItem(item); + item->SetTarget(this); + if (((*resolution_cap)->xres == __job_data->getXres()) && ((*resolution_cap)->yres == __job_data->getYres())) { + item->SetMarked(true); + marked = true; + } + resolution_cap++; + } + if (!marked) + item->SetMarked(true); + menufield = new BMenuField(RESOLUTION_RECT, "", RES_TEXT, __resolution); + AddChild(menufield); + menufield->SetDivider(width); + + /* cancel */ + + button = new BButton(CANCEL_RECT, "", CANCEL_TEXT, new BMessage(M_CANCEL)); + AddChild(button); + + /* ok */ + + button = new BButton(OK_RECT, "", OK_TEXT, new BMessage(M_OK)); + AddChild(button); + button->MakeDefault(true); +} + +inline void swap(float *e1, float *e2) +{ + float e = *e1; + *e1 = *e2; + *e2 = e; +} + +bool PageSetupView::UpdateJobData() +{ + if (B_CONTROL_ON == __portrait->Value()) { + __job_data->setOrientation(JobData::PORTRAIT); + } else { + __job_data->setOrientation(JobData::LANDSCAPE); + } + + BRect paper_rect; + BRect printable_rect; + + int count; + + count = __printer_cap->countCap(PrinterCap::PAPER); + PaperCap **paper_cap = (PaperCap **)__printer_cap->enumCap(PrinterCap::PAPER); + const char *paper_label = __paper->FindMarked()->Label(); + while (count--) { + if (!strcmp((*paper_cap)->label.c_str(), paper_label)) { + __job_data->setPaper((*paper_cap)->paper); + paper_rect = (*paper_cap)->paper_rect; + printable_rect = (*paper_cap)->printable_rect; + break; + } + paper_cap++; + } + + count = __printer_cap->countCap(PrinterCap::RESOLUTION); + ResolutionCap **resolution_cap = (ResolutionCap **)__printer_cap->enumCap(PrinterCap::RESOLUTION); + const char *resolution_label = __resolution->FindMarked()->Label(); + while (count--) { + if (!strcmp((*resolution_cap)->label.c_str(), resolution_label)) { + __job_data->setXres((*resolution_cap)->xres); + __job_data->setYres((*resolution_cap)->yres); + break; + } + resolution_cap++; + } + + if (JobData::LANDSCAPE == __job_data->getOrientation()) { + swap(&paper_rect.left, &paper_rect.top); + swap(&paper_rect.right, &paper_rect.bottom); + swap(&printable_rect.left, &printable_rect.top); + swap(&printable_rect.right, &printable_rect.bottom); + } + + __job_data->setScaling(100.0); + __job_data->setPaperRect(paper_rect); + __job_data->setPrintableRect(printable_rect); + + __job_data->save(); + return true; +} + +//==================================================================== + +PageSetupDlg::PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) + : BWindow(BRect(100, 100, 100 + PAGESETUP_WIDTH, 100 + PAGESETUP_HEIGHT), + "Page Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, + B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE) +{ + __result = 0; +/* + ostringstream oss; + oss << printer_data->get_printer_name() << " Setup"; + SetTitle(title.str().c_str()); +*/ + + Lock(); + PageSetupView *view = new PageSetupView(Bounds(), job_data, printer_data, printer_cap); + AddChild(view); + Unlock(); + + __semaphore = create_sem(0, "PageSetupSem"); +} + +PageSetupDlg::~PageSetupDlg() +{ +} + +bool PageSetupDlg::QuitRequested() +{ + __result = B_ERROR; + release_sem(__semaphore); + return true; +} + +void PageSetupDlg::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case M_OK: + Lock(); + ((PageSetupView *)ChildAt(0))->UpdateJobData(); + Unlock(); + __result = B_NO_ERROR; + release_sem(__semaphore); + break; + + case M_CANCEL: + __result = B_ERROR; + release_sem(__semaphore); + break; + + default: + BWindow::MessageReceived(msg); + break; + } +} + +int PageSetupDlg::Go() +{ + Show(); + acquire_sem(__semaphore); + delete_sem(__semaphore); + int value = __result; + Lock(); + Quit(); + return value; +} diff --git a/src/add-ons/print/drivers/shared/libprint/Preview.cpp b/src/add-ons/print/drivers/shared/libprint/Preview.cpp new file mode 100644 index 0000000000..b1b086115f --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/Preview.cpp @@ -0,0 +1,53 @@ +/* + * Preview.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include "Preview.h" + +#ifdef USE_PREVIEW_FOR_DEBUG + +class PreviewView : public BView { +public: + PreviewView(BRect, BBitmap *); + void Draw(BRect); +private: + BBitmap *__bitmap; +}; + +PreviewView::PreviewView(BRect frame, BBitmap *bitmap) + : BView(frame, "preview", B_FOLLOW_ALL, B_WILL_DRAW) +{ + __bitmap = bitmap; +} + +void PreviewView::Draw(BRect) +{ + DrawBitmap(__bitmap); +} + +PreviewWindow::PreviewWindow(BRect frame, const char *title, BBitmap *bitmap) + : BWindow(frame, title, B_TITLED_WINDOW, 0) +{ + AddChild(new PreviewView(Bounds(), bitmap)); + __semaphore = create_sem(0, "PreviewSem"); +} + +bool PreviewWindow::QuitRequested() +{ + release_sem(__semaphore); + return true; +} + +int PreviewWindow::Go() +{ + Show(); + acquire_sem(__semaphore); + delete_sem(__semaphore); + Lock(); + Quit(); + return 0; +} + +#endif /* USE_PREVIEW_FOR_DEBUG */ diff --git a/src/add-ons/print/drivers/shared/libprint/PrintProcess.cpp b/src/add-ons/print/drivers/shared/libprint/PrintProcess.cpp new file mode 100644 index 0000000000..49f3e86b40 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/PrintProcess.cpp @@ -0,0 +1,161 @@ +/* + * PrintProcess.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include + +#include "PrintProcess.h" +#include "DbgMsg.h" + +PictureData::PictureData(BFile *file) +{ + DBGMSG(("construct PictureData\n")); + DBGMSG(("1: current seek position = 0x%x\n", (int)file->Position())); + + file->Read(&point, sizeof(BPoint)); + file->Read(&rect, sizeof(BRect)); + + picture = new BPicture(); + + DBGMSG(("picture_data::point = %f, %f\n", point.x, point.y)); + DBGMSG(("picture_data::rect = %f, %f, %f, %f\n", + rect.left, rect.top, rect.right, rect.bottom)); + DBGMSG(("2: current seek position = 0x%x\n", (int)file->Position())); + + picture->Unflatten(file); + + DBGMSG(("3: current seek position = 0x%x\n", (int)file->Position())); +} + +PictureData::~PictureData() +{ + delete picture; +} + +/*--------------------------------------------------*/ + +PageData::PageData() +{ + __hollow = true; +} + +PageData::PageData(BFile *file, bool reverse) +{ + __file = file; + __reverse = reverse; + __picture_count = 0; + __rest = 0; + __offset = 0; + __hollow = false; + + if (reverse) { + file->Read(&__picture_count, sizeof(long)); + DBGMSG(("picture_count = %d\n", (int)__picture_count)); + __offset = __file->Position(); + off_t o = __offset; + // seek to start of next page + __file->Read(&o, sizeof(o)); + __file->Seek(o, SEEK_SET); + } +} + +bool PageData::startEnum() +{ + off_t offset; + uchar dummy[40]; + + if (__hollow) + return false; + + if (__offset == 0) { + __file->Read(&__picture_count, sizeof(long)); + DBGMSG(("picture_count = %d\n", (int)__picture_count)); + __offset = __file->Position(); + } else { + __file->Seek(__offset, SEEK_SET); + } + // skip page header + __file->Seek(sizeof(offset) + sizeof(dummy), SEEK_CUR); + + __rest = __picture_count; + return __picture_count > 0; +} + +bool PageData::enumObject(PictureData **picture_data) +{ + if (__hollow || __picture_count <= 0) { + *picture_data = NULL; + } else { + *picture_data = new PictureData(__file); + if (--__rest > 0) { + return true; + } + } + return false; +} + +/*--------------------------------------------------*/ + +SpoolData::SpoolData( + BFile *file, + int page_count, + int nup, + bool reverse) +{ + DBGMSG(("nup = %d\n", nup)); + DBGMSG(("page_count = %d\n", page_count)); + DBGMSG(("reverse = %s\n", reverse ? "true" : "false")); + + if (reverse) { + if (nup > 1) { + for (int page_index = 0; page_index < page_count; page_index++) { + if (page_index % nup == 0) { + __pages.push_front(new PageData(file, reverse)); + __it = __pages.begin(); + __it++; + } else { + __pages.insert(__it, new PageData(file, reverse)); + } + } + page_count = nup - page_count % nup; + if (page_count < nup) { + while (page_count--) { + __pages.insert(__it, new PageData); + } + } + } else { + while (page_count--) { + __pages.push_front(new PageData(file, reverse)); + } + } + } else { + while (page_count--) { + __pages.push_back(new PageData(file, reverse)); + } + } +} + +SpoolData::~SpoolData() +{ + for (__it = __pages.begin(); __it != __pages.end(); __it++) { + delete (*__it); + } +} + +bool SpoolData::startEnum() +{ + __it = __pages.begin(); + return true; +} + +bool SpoolData::enumObject(PageData **page_data) +{ + *page_data = *__it++; + if (__it == __pages.end()) { + return false; + } + return true; +} diff --git a/src/add-ons/print/drivers/shared/libprint/PrinterCap.cpp b/src/add-ons/print/drivers/shared/libprint/PrinterCap.cpp new file mode 100644 index 0000000000..886d072078 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/PrinterCap.cpp @@ -0,0 +1,45 @@ +/* + * PrinterCap.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include "PrinterCap.h" + +PrinterCap::PrinterCap(const PrinterData *printer_data) + : __printer_data(printer_data), __printer_id(UNKNOWN_PRINTER) +{ +} + +PrinterCap::~PrinterCap() +{ +} + +/* +PrinterCap::PrinterCap(const PrinterCap &printer_cap) +{ + __printer_data = printer_cap.__printer_data; + __printer_id = printer_cap.__printer_id; +} + +PrinterCap::PrinterCap &operator = (const PrinterCap &printer_cap) +{ + __printer_data = printer_cap.__printer_data; + __printer_id = printer_cap.__printer_id; + return *this; +} +*/ + +const BaseCap *PrinterCap::getDefaultCap(CAPID id) const +{ + int count = countCap(id); + if (count > 0) { + const BaseCap **base_cap = enumCap(id); + while (count--) { + if ((*base_cap)->is_default) { + return *base_cap; + } + base_cap++; + } + } + return NULL; +} diff --git a/src/add-ons/print/drivers/shared/libprint/PrinterData.cpp b/src/add-ons/print/drivers/shared/libprint/PrinterData.cpp new file mode 100644 index 0000000000..3ba1cd49df --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/PrinterData.cpp @@ -0,0 +1,97 @@ +/* + * PrinterData.cpp + * Copyright 1999-2000 Y.Takagi All Rights Reserved. + */ + +#include +#include +#include +#include + +#include "PrinterData.h" + +const char *PD_DRIVER_NAME = "Driver Name"; +const char *PD_PRINTER_NAME = "Printer Name"; +const char *PD_COMMENTS = "Comments"; +const char *PD_TRANSPORT = "transport"; + +PrinterData::PrinterData(BNode *node) +{ + if (node) { + load(node); + } +} + +PrinterData::~PrinterData() +{ +} + +/* +PrinterData::PrinterData(const PrinterData &printer_data) +{ + __driver_name = printer_data.__driver_name; + __printer_name = printer_data.__printer_name; + __comments = printer_data.__comments; + __transport = printer_data.__transport; + __node = printer_data.__node; +} + +PrinterData &PrinterData::operator = (const PrinterData &printer_data) +{ + __driver_name = printer_data.__driver_name; + __printer_name = printer_data.__printer_name; + __comments = printer_data.__comments; + __transport = printer_data.__transport; + __node = printer_data.__node; + return *this; +} +*/ + +void PrinterData::load(BNode *node) +{ + char buffer[512]; + + __node = node; + + __node->ReadAttr(PD_DRIVER_NAME, B_STRING_TYPE, 0, buffer, sizeof(buffer)); + __driver_name = buffer; + __node->ReadAttr(PD_PRINTER_NAME, B_STRING_TYPE, 0, buffer, sizeof(buffer)); + __printer_name = buffer; + __node->ReadAttr(PD_COMMENTS, B_STRING_TYPE, 0, buffer, sizeof(buffer)); + __comments = buffer; + __node->ReadAttr(PD_TRANSPORT, B_STRING_TYPE, 0, buffer, sizeof(buffer)); + __transport = buffer; +} + +/* +void PrinterData::save(BNode *node) +{ + BDirectory dir; + if (node == NULL) { + BPath path; + ::find_directory(B_USER_PRINTERS_DIRECTORY, &path, false); + path.Append(__printer_name.c_str()); + BDirectory base_dir; + base_dir.CreateDirectory(path.Path(), &dir); + node = &dir; + } + node->WriteAttr(PD_DRIVER_NAME, B_STRING_TYPE, 0, driver_name_.c_str(), driver_name_.length() + 1); + node->WriteAttr(PD_PRINTER_NAME, B_STRING_TYPE, 0, printer_name_.c_str(), printer_name_.length() + 1); + node->WriteAttr(PD_COMMENTS, B_STRING_TYPE, 0, comments_.c_str(), comments_.length() + 1); +} +*/ + +bool PrinterData::getPath(char *buf) const +{ + if (__node) { + node_ref nref; + __node->GetNodeRef(&nref); + BDirectory dir; + dir.SetTo(&nref); + BPath path(&dir, NULL); + strcpy(buf, path.Path()); + return true; + } + *buf = '\0'; + return false; +} diff --git a/src/add-ons/print/drivers/shared/libprint/SpoolMetaData.cpp b/src/add-ons/print/drivers/shared/libprint/SpoolMetaData.cpp new file mode 100644 index 0000000000..17ef8145a4 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/SpoolMetaData.cpp @@ -0,0 +1,30 @@ +/* + * SpoolMetaData.cpp + * Copyright 2003 Michael Pfeiffer. All Rights Reserved. + */ + +#include "SpoolMetaData.h" +#include + +const char *SD_DESCRIPTION = "_spool/Description"; +const char* SD_MIME_TYPE = "_spool/MimeType"; + +SpoolMetaData::SpoolMetaData(BFile* spool_file) +{ + BString string; + time_t time; + if (spool_file->ReadAttrString(SD_DESCRIPTION, &string) == B_OK) { + __description = string.String(); + } + if (spool_file->ReadAttrString(SD_MIME_TYPE, &string) == B_OK) { + __mime_type = string.String(); + } + if (spool_file->GetCreationTime(&time) == B_OK) { + __creation_time = ctime(&time); + } +} + +SpoolMetaData::~SpoolMetaData() +{ +} + diff --git a/src/add-ons/print/drivers/shared/libprint/Transport.cpp b/src/add-ons/print/drivers/shared/libprint/Transport.cpp new file mode 100644 index 0000000000..a5129460fc --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/Transport.cpp @@ -0,0 +1,111 @@ +/* + * Transport.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +#include "Transport.h" +#include "PrinterData.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +Transport::Transport(const PrinterData *printer_data) + : __image(-1), __init_transport(0), __exit_transport(0), __data_stream(0), __abort(false) +{ + BPath path; + + if (B_OK == find_directory(B_USER_ADDONS_DIRECTORY, &path)) { + path.Append("Print/transport"); + path.Append(printer_data->getTransport().c_str()); + DBGMSG(("load_add_on: %s\n", path.Path())); + __image = load_add_on(path.Path()); + } + if (__image < 0) { + if (B_OK == find_directory(B_BEOS_ADDONS_DIRECTORY, &path)) { + path.Append("Print/transport"); + path.Append(printer_data->getTransport().c_str()); + DBGMSG(("load_add_on: %s\n", path.Path())); + __image = load_add_on(path.Path()); + } + } + + if (__image < 0) { + set_last_error("cannot load a transport add-on"); + return; + } + + DBGMSG(("image id = %d\n", (int)__image)); + + get_image_symbol(__image, "init_transport", B_SYMBOL_TYPE_TEXT, (void **)&__init_transport); + get_image_symbol(__image, "exit_transport", B_SYMBOL_TYPE_TEXT, (void **)&__exit_transport); + + if (__init_transport == NULL) { + set_last_error("get_image_symbol failed."); + DBGMSG(("init_transport is NULL\n")); + } + + if (__exit_transport == NULL) { + set_last_error("get_image_symbol failed."); + DBGMSG(("exit_transport is NULL\n")); + } + + if (__init_transport) { + char spool_path[256]; + printer_data->getPath(spool_path); + BMessage *msg = new BMessage('TRIN'); + msg->AddString("printer_file", spool_path); + __data_stream = (*__init_transport)(msg); + delete msg; + if (__data_stream == 0) { + set_last_error("init_transport failed."); + } + } +} + +Transport::~Transport() +{ + if (__exit_transport) { + (*__exit_transport)(); + } + if (__image >= 0) { + unload_add_on(__image); + } +} + +bool Transport::check_abort() const +{ + return __data_stream == 0; +} + +const string &Transport::last_error() const +{ + return __last_error_string; +} + +void Transport::set_last_error(const char *e) +{ + __last_error_string = e; + __abort = true; +} + +void Transport::write(const void *buffer, size_t size) throw(TransportException) +{ + if (__data_stream) { + if (size == (size_t)__data_stream->Write(buffer, size)) { + return; + } + set_last_error("BDataIO::Write failed."); + } + throw TransportException(last_error()); +} diff --git a/src/add-ons/print/drivers/shared/libprint/UIDriver.cpp b/src/add-ons/print/drivers/shared/libprint/UIDriver.cpp new file mode 100644 index 0000000000..f17680141f --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/UIDriver.cpp @@ -0,0 +1,66 @@ +/* + * UIDriver.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include + +#include "UIDriver.h" +#include "JobData.h" +#include "PrinterData.h" +#include "JobSetupDlg.h" +#include "PageSetupDlg.h" +#include "DbgMsg.h" + +UIDriver::UIDriver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap) + : __msg(msg), __printer_data(printer_data), __printer_cap(printer_cap) +{ +} + +UIDriver::~UIDriver() +{ +} + +BMessage *UIDriver::configPage() +{ + BMessage *clone_msg = new BMessage(*__msg); + JobData *job_data = new JobData(clone_msg, __printer_cap); + + if (doPageSetup(job_data,__printer_data, __printer_cap) < 0) { + delete clone_msg; + clone_msg = NULL; + } else { + clone_msg->what = 'okok'; + } + + delete job_data; + return clone_msg; +} + +BMessage *UIDriver::configJob() +{ + BMessage *clone_msg = new BMessage(*__msg); + JobData *job_data = new JobData(clone_msg, __printer_cap); + + if (doJobSetup(job_data, __printer_data, __printer_cap) < 0) { + delete clone_msg; + clone_msg = NULL; + } else { + clone_msg->what = 'okok'; + } + + delete job_data; + return clone_msg; +} + +long UIDriver::doPageSetup(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) +{ + PageSetupDlg *dlg = new PageSetupDlg(job_data, printer_data, printer_cap); + return dlg->Go(); +} + +long UIDriver::doJobSetup(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap) +{ + JobSetupDlg *dlg = new JobSetupDlg(job_data, printer_data, printer_cap); + return dlg->Go(); +} diff --git a/src/add-ons/print/drivers/shared/libprint/ValidRect.cpp b/src/add-ons/print/drivers/shared/libprint/ValidRect.cpp new file mode 100644 index 0000000000..e2ba0eb022 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/ValidRect.cpp @@ -0,0 +1,253 @@ +/* + * ValidRect.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#include +#include "ValidRect.h" + +bool get_valid_line_RGB32( + const uchar *bits, + const rgb_color *, + int width, + int *left, + int *right) +{ + int i = 0; + rgb_color c; + const rgb_color *ptr = (const rgb_color *)bits; + + while (i < *left) { + c = *ptr++; + if (c.red != 0xff || c.green != 0xff || c.blue != 0xff) { + *left = i; + break; + } + i++; + } + + if (i == width) { + return false; + } + + i = width - 1; + ptr = (const rgb_color *)bits + width - 1; + + while (i > *right) { + c = *ptr--; + if (c.red != 0xff || c.green != 0xff || c.blue != 0xff) { + *right = i; + break; + } + i--; + } + return true; +} + +bool get_valid_line_CMAP8( + const uchar *bits, + const rgb_color *palette, + int width, + int *left, + int *right) +{ + int i = 0; + rgb_color c; + const uchar *ptr = bits; + + while (i < *left) { + c = palette[*ptr++]; + if (c.red != 0xff || c.green != 0xff || c.blue != 0xff) { + *left = i; + break; + } + i++; + } + + if (i == width) { + return false; + } + + i = width - 1; + ptr = bits + width - 1; + + while (i > *right) { + c = palette[*ptr--]; + if (c.red != 0xff || c.green != 0xff || c.blue != 0xff) { + *right = i; + break; + } + i--; + } + return true; +} + +bool get_valid_line_GRAY8( + const uchar *bits, + const rgb_color *, + int width, + int *left, + int *right) +{ + int i = 0; + const uchar *ptr = bits; + + while (i < *left) { + if (*ptr++) { + *left = i; + break; + } + i++; + } + + if (i == width) { + return false; + } + + i = width - 1; + ptr = bits + width - 1; + + while (i > *right) { + if (*ptr--) { + *right = i; + break; + } + i--; + } + return true; +} + +bool get_valid_line_GRAY1( + const uchar *bits, + const rgb_color *, + int width, + int *left, + int *right) +{ + int i = 0; + const uchar *ptr = bits; + + while (i < *left) { + if (*ptr++) { + *left = i; + break; + } + i += 8; + } + + if (i == width) { + return false; + } + + i = width - 1; + ptr = bits + ((width - 1) + 7) / 8; + + while (i > *right) { + if (*ptr--) { + *right = i; + break; + } + i -= 8; + } + return true; +} + +typedef bool (*PFN_GET_VALID_LINE)(const uchar *, const rgb_color *, int, int *, int *); + +bool get_valid_rect(BBitmap *a_bitmap, const rgb_color *palette, RECT *rc) +{ + int width = rc->right - rc->left + 1; + int height = rc->bottom - rc->top + 1; + int delta = a_bitmap->BytesPerRow(); + + int left = width; + int right = 0; + int top = 0; + int bottom = 0; + + PFN_GET_VALID_LINE get_valid_line; + + switch (a_bitmap->ColorSpace()) { + case B_RGB32: + case B_RGB32_BIG: + get_valid_line = get_valid_line_RGB32; + break; + case B_CMAP8: + get_valid_line = get_valid_line_CMAP8; + break; + case B_GRAY8: + get_valid_line = get_valid_line_GRAY8; + break; + case B_GRAY1: + get_valid_line = get_valid_line_GRAY1; + break; + default: + get_valid_line = get_valid_line_GRAY1; + break; + }; + + int i = 0; + uchar *ptr = (uchar *)a_bitmap->Bits(); + + while (i < height) { + if (get_valid_line(ptr, palette, width, &left, &right)) { + top = i; + break; + } + ptr += delta; + i++; + } + + if (i == height) { + return false; + } + + int j = height - 1; + ptr = (uchar *)a_bitmap->Bits() + (height - 1) * delta; + bool found_boundary = false; + + while (j >= i) { + if (get_valid_line(ptr, palette, width, &left, &right)) { + if (!found_boundary) { + bottom = j; + found_boundary = true; + } + } + ptr -= delta; + j--; + } + + rc->left = left; + rc->top = top; + rc->right = right; + rc->bottom = bottom; + + return true; +} + +int color_space2pixel_depth(color_space cs) +{ + int pixel_depth; + + switch (cs) { + case B_GRAY1: /* Y0[0],Y1[0],Y2[0],Y3[0],Y4[0],Y5[0],Y6[0],Y7[0] */ + pixel_depth = 1; + break; + case B_GRAY8: /* Y[7:0] */ + case B_CMAP8: /* D[7:0] */ + pixel_depth = 8; + break; + case B_RGB15: /* G[2:0],B[4:0] -[0],R[4:0],G[4:3] */ + case B_RGB15_BIG: /* -[0],R[4:0],G[4:3] G[2:0],B[4:0] */ + pixel_depth = 16; + break; + case B_RGB32: /* B[7:0] G[7:0] R[7:0] -[7:0] */ + case B_RGB32_BIG: /* -[7:0] R[7:0] G[7:0] B[7:0] */ + pixel_depth = 32; + break; + default: + pixel_depth = 0; + break; + } + return pixel_depth; +} diff --git a/src/add-ons/print/drivers/shared/libprint/_sstream b/src/add-ons/print/drivers/shared/libprint/_sstream new file mode 100644 index 0000000000..0239578396 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/_sstream @@ -0,0 +1,24 @@ +/* + * _sstream + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#if __MWERKS__ +#include +#else + +#ifndef __SSTREAM_H +#define __SSTREAM_H + +#include +#include + +class ostringstream : public ostrstream { +public: + ostringstream() : ostrstream() {} + ~ostringstream() { delete [] ostrstream::str(); } + string str() { *this << ends; return string(ostrstream::str()); } +}; + +#endif /* __SSTREAM_H */ +#endif /* USING_STRSTREAM */ diff --git a/src/add-ons/print/drivers/shared/libprint/tools/make_pattern.cpp b/src/add-ons/print/drivers/shared/libprint/tools/make_pattern.cpp new file mode 100644 index 0000000000..e4e7e3e681 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/tools/make_pattern.cpp @@ -0,0 +1,90 @@ +/* + * make_pattern.cpp + * Copyright 2000 Y.Takagi All Rights Reserved. + */ + +#include +#include + +using namespace std; + +#define MAX_HORTZ 4 +#define MAX_VERT 4 +#define MAX_ELEMENT (MAX_HORTZ * MAX_VERT) + +#include "original_dither_pattern.h" + +void create_index_table(const unsigned char *p1, unsigned char *p2) +{ + for (int i = 0 ; i < MAX_ELEMENT ; i++) { + p2[*p1] = i; + p1++; + } +} + +inline int index2horz(int index) +{ + return index % MAX_HORTZ; +} + +inline int index2vert(int index) +{ + return index / MAX_HORTZ; +} + +void create_pattern16x16(const unsigned char *pattern4x4, unsigned char *pattern16x16) +{ + unsigned char value2index[MAX_ELEMENT]; + create_index_table(pattern4x4, value2index); + + for (int i = 0 ; i < MAX_ELEMENT ; i++) { + int index = value2index[i]; + int h = index2horz(index); + int v = index2vert(index); + for (int j = 0 ; j < MAX_ELEMENT ; j++) { + int index2 = value2index[j]; + int h2 = index2horz(index2) * 4 + h; + int v2 = index2vert(index2) * 4 + v; + pattern16x16[h2 + v2 * MAX_ELEMENT] = j + i * MAX_ELEMENT; + } + } +} + +void print_pattern(ostream &os, const char *name, const unsigned char *pattern) +{ + os << "const unsigned char " << name << "[] = {" << '\n' << '\t'; + for (int i = 0 ; i < 256 ; i++) { + os << setw(3) << (int)pattern[i]; + if (i == MAX_ELEMENT * MAX_ELEMENT - 1) { + os << '\n'; + } else { + os << ','; + if (i % MAX_ELEMENT == MAX_ELEMENT - 1) { + os << '\n' << '\t'; + } + } + } + os << "};" << '\n'; +} + +int main() +{ + unsigned char pattern16x16_type1[MAX_ELEMENT * MAX_ELEMENT]; + create_pattern16x16(pattern4x4_type1, pattern16x16_type1); + print_pattern(cout, "pattern16x16_type1", pattern16x16_type1); + + cout << endl; + + unsigned char pattern16x16_type2[MAX_ELEMENT * MAX_ELEMENT]; + create_pattern16x16(pattern4x4_type2, pattern16x16_type2); + print_pattern(cout, "pattern16x16_type2", pattern16x16_type2); + + cout << endl; + + unsigned char pattern16x16_type3[MAX_ELEMENT * MAX_ELEMENT]; + create_pattern16x16(pattern4x4_type3, pattern16x16_type3); + print_pattern(cout, "pattern16x16_type3", pattern16x16_type3); + + cout << endl; + return 0; +} diff --git a/src/add-ons/print/drivers/shared/libprint/tools/original_dither_pattern.h b/src/add-ons/print/drivers/shared/libprint/tools/original_dither_pattern.h new file mode 100644 index 0000000000..b203a55204 --- /dev/null +++ b/src/add-ons/print/drivers/shared/libprint/tools/original_dither_pattern.h @@ -0,0 +1,24 @@ +/* + * These patterns are defined referring to Japanese Monthly C Magazine (May 2000 Vol.12 No.5). + */ + +const unsigned char pattern4x4_type1[MAX_ELEMENT] = { + 0, 8, 2, 10, + 12, 4, 14, 6, + 3, 11, 1, 9, + 15, 7, 13, 5 +}; + +const unsigned char pattern4x4_type2[MAX_ELEMENT] = { + 9, 8, 7, 6, + 10, 1, 0, 5, + 11, 2, 3, 4, + 12, 13, 14, 15 +}; + +const unsigned char pattern4x4_type3[MAX_ELEMENT] = { + 0, 2, 14, 12, + 8, 10, 5, 7, + 15, 13, 1, 3, + 4, 6, 9, 11 +};