From 168f6abe51437dff1b055068ab60e607fc3d1bba Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Mon, 5 Jan 2026 00:41:30 +0100 Subject: [PATCH] fixes (#75) --- src/gui/print_window.cpp | 123 ++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/src/gui/print_window.cpp b/src/gui/print_window.cpp index 98007fa3..36cdcad5 100644 --- a/src/gui/print_window.cpp +++ b/src/gui/print_window.cpp @@ -29,50 +29,50 @@ void PrintJob::init(const RealSize& page_size) { layout_cards(); align_cards(); center_cards(); -} +} -void PrintJob::measure_cards() { +void PrintJob::measure_cards() { unordered_set already_measured_cards; FOR_EACH(card, cards) { - if (already_measured_cards.find(card) != already_measured_cards.end()) continue; + if (already_measured_cards.find(card) != already_measured_cards.end()) continue; already_measured_cards.emplace(card); - card_layouts.push_back(measure_card(card)); - CardP other_face = card->getLinkedOtherFace(cards); + card_layouts.push_back(measure_card(card)); + CardP other_face = card->getLinkedOtherFace(cards); if (other_face && already_measured_cards.find(other_face) == already_measured_cards.end()) { - already_measured_cards.emplace(other_face); - card_layouts.push_back(measure_card(other_face)); - int index = card_layouts.size()-1; - card_layouts[index].other_face = index-1; + already_measured_cards.emplace(other_face); + card_layouts.push_back(measure_card(other_face)); + int index = card_layouts.size()-1; + card_layouts[index].other_face = index-1; card_layouts[index-1].other_face = index; } - } + } sorted_layouts = vector(card_layouts); std::sort(sorted_layouts.begin(), sorted_layouts.end()); -} -PrintJob::CardLayout PrintJob::measure_card(const CardP& card) { - // initial measure +} +PrintJob::CardLayout PrintJob::measure_card(const CardP& card) { + // initial measure const StyleSheet& stylesheet = set->stylesheetFor(card); RealSize size_mm(stylesheet.card_width * 25.4 / stylesheet.card_dpi, stylesheet.card_height * 25.4 / stylesheet.card_dpi); RealSize size_px(stylesheet.card_width, stylesheet.card_height); - // check if we need to rotate to align best to default card height + // check if we need to rotate to align best to default card height Radians rotation = 0.0; if (abs(size_mm.width - default_size_mm.height) < abs(size_mm.height - default_size_mm.height)) { swap(size_mm.width, size_mm.height); swap(size_px.width, size_px.height); rotation = rad90; - } + } // snap to default_size_mm if we are close if (abs(size_mm.width - default_size_mm.width) < threshold_size.width) size_mm.width = default_size_mm.width; if (abs(size_mm.height - default_size_mm.height) < threshold_size.height) size_mm.height = default_size_mm.height; - // add bleed - double bleed_size_px = 0.0; - if (!almost_equal(settings.print_bleed, 0.0)) { + // add bleed + double bleed_size_px = 0.0; + if (!almost_equal(settings.print_bleed, 0.0)) { bleed_size_px = stylesheet.card_dpi * settings.print_bleed / 25.4; - size_mm = RealSize(size_mm.width + 2 * settings.print_bleed, size_mm.height + 2 * settings.print_bleed); + size_mm = RealSize(size_mm.width + 2 * settings.print_bleed, size_mm.height + 2 * settings.print_bleed); size_px = RealSize(size_px.width + 2 * bleed_size_px, size_px.height + 2 * bleed_size_px); } return CardLayout(card, size_mm, size_px, bleed_size_px, rotation); -} +} void PrintJob::layout_cards() { page_layouts.push_back(vector()); @@ -85,12 +85,12 @@ void PrintJob::layout_cards() { if (layout.other_face >= 0) { CardLayout& other_layout = card_layouts[layout.other_face]; if ( layout.size_mm.width + other_layout.size_mm.width + settings.print_spacing + row_width >= page_size.width) continue; - if (max(layout.size_mm.height, other_layout.size_mm.height) + row_top >= page_size.height) continue; - // the card and its other face fit + if (max(layout.size_mm.height, other_layout.size_mm.height) + row_top >= page_size.height) continue; + // the card and its other face fit layout.pos.width = row_width; layout.pos.height = row_top; page_layouts[page_layouts.size()-1].push_back(layout); - already_laidout_cards.emplace(layout.card); + already_laidout_cards.emplace(layout.card); other_layout.pos.width = row_width + layout.size_mm.width + settings.print_spacing; other_layout.pos.height = row_top; page_layouts[page_layouts.size()-1].push_back(other_layout); @@ -99,8 +99,8 @@ void PrintJob::layout_cards() { // move to next spot on the row row_width += layout.size_mm.width + other_layout.size_mm.width + 2 * settings.print_spacing; row_height = max(max(row_height, layout.size_mm.height + settings.print_spacing), other_layout.size_mm.height + settings.print_spacing); - } - else { + } + else { if (layout.size_mm.width + row_width >= page_size.width) continue; if (layout.size_mm.height + row_top >= page_size.height) continue; // the card fits @@ -111,7 +111,7 @@ void PrintJob::layout_cards() { if (already_laidout_cards.size() >= card_layouts.size()) return; // move to next spot on the row row_width += layout.size_mm.width + settings.print_spacing; - row_height = max(row_height, layout.size_mm.height + settings.print_spacing); + row_height = max(row_height, layout.size_mm.height + settings.print_spacing); } goto continue_outer; } @@ -133,7 +133,7 @@ void PrintJob::layout_cards() { row_width = row_height = 0.0; continue_outer:; } -} +} void PrintJob::align_cards() { // for each page @@ -184,7 +184,7 @@ void PrintJob::align_cards() { continue_outer:; } } -} +} void PrintJob::center_cards() { for (int p = 0; p < page_layouts.size(); ++p) { @@ -281,36 +281,40 @@ bool CardsPrintout::OnPrintPage(int page) { void CardsPrintout::drawCards(DC& dc, PrintJobP& job, int page) { FOR_EACH(card_layout, job->page_layouts[page - 1]) { drawCard(dc, card_layout); - } + } dc.SetDeviceOrigin(0, 0); } void CardsPrintout::drawCard(DC& dc, PrintJob::CardLayout& card_layout) { - // upscale to printer dpi - RealPoint scale(printer_px_per_mm.width * card_layout.size_mm.width / card_layout.size_px.width, - printer_px_per_mm.height * card_layout.size_mm.height / card_layout.size_px.height); - int bleed = lround(card_layout.bleed_size_px * scale.x); + // upscale to printer dpi + RealPoint scale(printer_px_per_mm.width * card_layout.size_mm.width / card_layout.size_px.width, + printer_px_per_mm.height * card_layout.size_mm.height / card_layout.size_px.height); + int bleed = lround(card_layout.bleed_size_px * scale.x); int width = lround(card_layout.size_px.width * scale.x), height = lround(card_layout.size_px.height * scale.y); // render card to its own dc wxBitmap buffer(width, height, 32); wxMemoryDC bufferDC; bufferDC.SelectObject(buffer); clearDC(bufferDC,*wxWHITE_BRUSH); - RotatedDC rdc(bufferDC, card_layout.rot, RealRect(0, 0, card_layout.size_px.width, card_layout.size_px.height), scale.x, QUALITY_AA, ROTATION_ATTACH_TOP_LEFT); + RotatedDC rdc(bufferDC, card_layout.rot, RealRect(0, 0, card_layout.size_px.width, card_layout.size_px.height), scale.x, QUALITY_AA, ROTATION_ATTACH_TOP_LEFT); if (is_rad90(card_layout.rot)) bufferDC.SetDeviceOrigin(bleed, height - width - 1 - bleed); // I don't understand why this is needed - else bufferDC.SetDeviceOrigin(bleed, bleed); + else bufferDC.SetDeviceOrigin(bleed, bleed); viewer.setCard(card_layout.card); - viewer.draw(rdc, *wxWHITE); + viewer.draw(rdc, *wxWHITE); bufferDC.SetDeviceOrigin(0,0); - /// add print bleed edge - if (bleed > 0) { - Image left_border = bufferDC.GetAsBitmap(&wxRect(bleed + 1, bleed, bleed, height - 2 * bleed)).ConvertToImage(); - bufferDC.DrawBitmap(left_border.Mirror(true), 0, bleed); - Image right_border = bufferDC.GetAsBitmap(&wxRect(width - 2 * bleed - 1, bleed, bleed, height - 2 * bleed)).ConvertToImage(); - bufferDC.DrawBitmap(right_border.Mirror(true), width - bleed - 1, bleed); - Image top_border = bufferDC.GetAsBitmap(&wxRect(0, bleed + 1, width, bleed)).ConvertToImage(); - bufferDC.DrawBitmap(top_border.Mirror(false), 0, 0); - Image bottom_border = bufferDC.GetAsBitmap(&wxRect(0, height - 2 * bleed - 1, width, bleed)).ConvertToImage(); - bufferDC.DrawBitmap(bottom_border.Mirror(false), 0, height - bleed - 1); + /// add print bleed edge + if (bleed > 0) { + auto left_rect = wxRect(bleed + 1, bleed, bleed, height - 2 * bleed); + Image left_border = bufferDC.GetAsBitmap(&left_rect).ConvertToImage(); + bufferDC.DrawBitmap(left_border.Mirror(true), 0, bleed); + auto right_rect = wxRect(width - 2 * bleed - 1, bleed, bleed, height - 2 * bleed); + Image right_border = bufferDC.GetAsBitmap(&right_rect).ConvertToImage(); + bufferDC.DrawBitmap(right_border.Mirror(true), width - bleed - 1, bleed); + auto top_rect = wxRect(0, bleed + 1, width, bleed); + Image top_border = bufferDC.GetAsBitmap(&top_rect).ConvertToImage(); + bufferDC.DrawBitmap(top_border.Mirror(false), 0, 0); + auto bottom_rect = wxRect(0, height - 2 * bleed - 1, width, bleed); + Image bottom_border = bufferDC.GetAsBitmap(&bottom_rect).ConvertToImage(); + bufferDC.DrawBitmap(bottom_border.Mirror(false), 0, height - bleed - 1); } // render card dc to page dc bufferDC.SelectObject(wxNullBitmap); @@ -322,11 +326,11 @@ void CardsPrintout::drawCutterLines(DC& dc, PrintJobP& job, int page) { const vector& page_layouts = job->page_layouts[page - 1]; const RealSize& page_margin = job->page_margins[page - 1]; int page_width, page_height; - GetPageSizeMM(&page_width, &page_height); + GetPageSizeMM(&page_width, &page_height); wxPen pen(wxColour(0, 0, 0), 2, wxPENSTYLE_SOLID); pen.SetQuality(wxPEN_QUALITY_HIGH); - dc.SetPen(pen); - // vertical + dc.SetPen(pen); + // vertical int v_bleed = printer_px_per_mm.width * settings.print_bleed; for (int i = 0; i < page_layouts.size(); ++i) { double left_line = page_layouts[i].pos.width; @@ -349,22 +353,22 @@ void CardsPrintout::drawCutterLines(DC& dc, PrintJobP& job, int page) { } } } - if (draw_left_line) { + if (draw_left_line) { int left = printer_px_per_mm.width * left_line; - dc.DrawLine(wxPoint(left + v_bleed, 0.0), + dc.DrawLine(wxPoint(left + v_bleed, 0.0), wxPoint(left + v_bleed, printer_px_per_mm.height * CUTTER_LINE_SIZE_MM)); - dc.DrawLine(wxPoint(left + v_bleed, printer_px_per_mm.height * page_height), + dc.DrawLine(wxPoint(left + v_bleed, printer_px_per_mm.height * page_height), wxPoint(left + v_bleed, printer_px_per_mm.height * (page_height - CUTTER_LINE_SIZE_MM))); } if (draw_right_line) { int right = printer_px_per_mm.width * right_line; - dc.DrawLine(wxPoint(right - v_bleed, 0.0), + dc.DrawLine(wxPoint(right - v_bleed, 0.0), wxPoint(right - v_bleed, printer_px_per_mm.height * CUTTER_LINE_SIZE_MM)); - dc.DrawLine(wxPoint(right - v_bleed, printer_px_per_mm.height * page_height), + dc.DrawLine(wxPoint(right - v_bleed, printer_px_per_mm.height * page_height), wxPoint(right - v_bleed, printer_px_per_mm.height * (page_height - CUTTER_LINE_SIZE_MM))); } } - // horizontal + // horizontal int h_bleed = printer_px_per_mm.height * settings.print_bleed; for (int i = 0; i < page_layouts.size(); ++i) { double top_line = page_layouts[i].pos.height; @@ -389,16 +393,16 @@ void CardsPrintout::drawCutterLines(DC& dc, PrintJobP& job, int page) { } if (draw_top_line) { int top = printer_px_per_mm.height * top_line; - dc.DrawLine(wxPoint(0.0, top + h_bleed), + dc.DrawLine(wxPoint(0.0, top + h_bleed), wxPoint(printer_px_per_mm.width * CUTTER_LINE_SIZE_MM, top + h_bleed)); - dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, top + h_bleed), + dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, top + h_bleed), wxPoint(printer_px_per_mm.width * (page_width - CUTTER_LINE_SIZE_MM), top + h_bleed)); } if (draw_bottom_line) { int bottom = printer_px_per_mm.height * bottom_line; - dc.DrawLine(wxPoint(0.0, bottom - h_bleed), + dc.DrawLine(wxPoint(0.0, bottom - h_bleed), wxPoint(printer_px_per_mm.width * CUTTER_LINE_SIZE_MM, bottom - h_bleed)); - dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, bottom - h_bleed), + dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, bottom - h_bleed), wxPoint(printer_px_per_mm.width * (page_width - CUTTER_LINE_SIZE_MM), bottom - h_bleed)); } } @@ -482,3 +486,4 @@ void print_preview(Window* parent, const SetP& set, const ExportCardSelectionCho void print_set(Window* parent, const SetP& set, const ExportCardSelectionChoices& choices) { print_set(parent, make_print_job(parent, set, choices)); } +