add bleed margin in print menu

This commit is contained in:
GenevensiS
2025-12-30 03:21:10 +01:00
parent 436c437189
commit 6a1d23efc7
21 changed files with 163 additions and 102 deletions
+2
View File
@@ -728,6 +728,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2
View File
@@ -726,6 +726,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2
View File
@@ -744,6 +744,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+3 -2
View File
@@ -694,6 +694,7 @@ label:
# print dialog # print dialog
put space between cards: Soll zwischen den Karten ein Leerzeichen eingefügt werden? put space between cards: Soll zwischen den Karten ein Leerzeichen eingefügt werden?
spacing print: Kartenabstand in Millimetern spacing print: Kartenabstand in Millimetern
bleed print: Beschnittzugabe in Millimetern
cutter lines print: Schnittlinien hinzufügen? cutter lines print: Schnittlinien hinzufügen?
cutter lines all: Alle cutter lines all: Alle
cutter lines no intersect: Wenn sie keine Karte schneiden cutter lines no intersect: Wenn sie keine Karte schneiden
@@ -747,8 +748,8 @@ button:
Viewer-Rotationseinstellung Viewer-Rotationseinstellung
beim Exportieren verwenden beim Exportieren verwenden
bleed export: bleed export:
Fügen Sie einen einfachen Grobe Beschnittzugabe
Druckbeschnittrand hinzu. hinzufügen
notes export: notes export:
Kartennotizen in Kartennotizen in
Bildmetadaten exportieren Bildmetadaten exportieren
+1
View File
@@ -696,6 +696,7 @@ label:
# print dialog # print dialog
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2
View File
@@ -729,6 +729,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2 -1
View File
@@ -694,7 +694,8 @@ label:
# print dialog # print dialog
put space between cards: Ajouter un espace entre les cartes? put space between cards: Ajouter un espace entre les cartes?
spacing print: Espace entre les cartes en millimetres spacing print: Espace entre les cartes en millimètres
bleed print: Marge de fond perdu en millimètres
cutter lines print: Ajouter des lignes de découpe? cutter lines print: Ajouter des lignes de découpe?
cutter lines all: Toutes cutter lines all: Toutes
cutter lines no intersect: Si elles n'intersectent pas de carte cutter lines no intersect: Si elles n'intersectent pas de carte
+2 -1
View File
@@ -695,6 +695,7 @@ label:
# print dialog # print dialog
put space between cards: Inserire uno spazio tra le carte? put space between cards: Inserire uno spazio tra le carte?
spacing print: Spaziatura tra le carte in millimetri spacing print: Spaziatura tra le carte in millimetri
bleed print: Margine di abbondanza in millimetri
cutter lines print: Aggiungere linee di taglio? cutter lines print: Aggiungere linee di taglio?
cutter lines all: Tutte cutter lines all: Tutte
cutter lines no intersect: Se non intersecano una carta cutter lines no intersect: Se non intersecano una carta
@@ -749,7 +750,7 @@ button:
visualizzatore durante l'esportazione visualizzatore durante l'esportazione
bleed export: bleed export:
Aggiungere un margine Aggiungere un margine
grezzo di stampa di abbondanza grezzo
notes export: notes export:
Esporta note della carta all'interno Esporta note della carta all'interno
dei metadati dell'immagine dei metadati dell'immagine
+2
View File
@@ -728,6 +728,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2
View File
@@ -734,6 +734,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+2
View File
@@ -778,6 +778,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+1
View File
@@ -696,6 +696,7 @@ label:
# print dialog # print dialog
put space between cards: Colocar um espaço entre os Cards? put space between cards: Colocar um espaço entre os Cards?
spacing print: Espaçamento entre Cards em milímetros spacing print: Espaçamento entre Cards em milímetros
bleed print: Margem de sangria de impressão em milímetros
cutter lines print: Adicionar linhas de corte? cutter lines print: Adicionar linhas de corte?
cutter lines all: Todas cutter lines all: Todas
cutter lines no intersect: Se não cruzarem um cartão cutter lines no intersect: Se não cruzarem um cartão
+2
View File
@@ -768,6 +768,8 @@ label:
#TODO: Localize section #TODO: Localize section
put space between cards: Put space between cards? put space between cards: Put space between cards?
spacing print: Spacing between cards in millimeters spacing print: Spacing between cards in millimeters
#TODO: Localize
bleed print: Print bleed margin in millimeters
cutter lines print: Add cutter guide lines? cutter lines print: Add cutter guide lines?
cutter lines all: All cutter lines all: All
cutter lines no intersect: If they don't intersect a card cutter lines no intersect: If they don't intersect a card
+3 -2
View File
@@ -55,9 +55,10 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
/// rotate /// rotate
img = rotate_image(img, angle_radians); img = rotate_image(img, angle_radians);
int width = img.GetWidth(), height = img.GetHeight();
/// add print bleed edge /// add print bleed edge
int width = img.GetWidth(), height = img.GetHeight();
bleed = max(0, min(width-1, min(height-1, bleed)));
if (size.width < bleed + 2 || size.height < bleed + 2) { if (size.width < bleed + 2 || size.height < bleed + 2) {
queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge")); queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge"));
} }
@@ -200,7 +201,7 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
Byte* pixels = global_img.GetData(); Byte* pixels = global_img.GetData();
Byte* alpha = global_img.GetAlpha(); Byte* alpha = global_img.GetAlpha();
// fill with transparent // fill with transparent
for (UInt i = 0; i < global_width*global_height; ++i) { for (int i = 0; i < global_width*global_height; ++i) {
pixels[3 * i + 0] = 0; pixels[3 * i + 0] = 0;
pixels[3 * i + 1] = 0; pixels[3 * i + 1] = 0;
pixels[3 * i + 2] = 0; pixels[3 * i + 2] = 0;
+2
View File
@@ -197,6 +197,7 @@ Settings::Settings()
, symbol_grid (true) , symbol_grid (true)
, symbol_grid_snap (false) , symbol_grid_snap (false)
, print_spacing (0.33) , print_spacing (0.33)
, print_bleed (0.0)
, print_cutter_lines (CUTTER_ALL) , print_cutter_lines (CUTTER_ALL)
, dark_mode_type (DARKMODE_SYSTEM) , dark_mode_type (DARKMODE_SYSTEM)
, import_scale_selection (0) , import_scale_selection (0)
@@ -334,6 +335,7 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(Settings) {
REFLECT(symbol_grid_snap); REFLECT(symbol_grid_snap);
REFLECT(default_game); REFLECT(default_game);
REFLECT(print_spacing); REFLECT(print_spacing);
REFLECT(print_bleed);
REFLECT(print_cutter_lines); REFLECT(print_cutter_lines);
REFLECT(dark_mode_type); REFLECT(dark_mode_type);
REFLECT(apprentice_location); REFLECT(apprentice_location);
+1
View File
@@ -209,6 +209,7 @@ public:
// --------------------------------------------------- : Printing // --------------------------------------------------- : Printing
double print_spacing; double print_spacing;
double print_bleed;
CutterLinesType print_cutter_lines; CutterLinesType print_cutter_lines;
// --------------------------------------------------- : Dark Mode // --------------------------------------------------- : Dark Mode
+4 -2
View File
@@ -326,13 +326,15 @@ Image BleedEdgedImage::generate(const Options& opt) {
// create enlarged image // create enlarged image
Image base_img = base_image->generate(opt); Image base_img = base_image->generate(opt);
int w = base_img.GetWidth(), h = base_img.GetHeight(); int w = base_img.GetWidth(), h = base_img.GetHeight();
if (w <= 4 || h <= 4) { if (w <= 3 || h <= 3) {
queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge")); queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge"));
return base_img; return base_img;
} }
bool is_landscape = w > h; bool is_landscape = w > h;
int dw = int(w * (horizontal_size > 0.0 ? horizontal_size : is_landscape ? 0.037 : 0.048)); int dw = int(w * (horizontal_size > 0.0 ? horizontal_size : is_landscape ? 0.037 : 0.048));
int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037)); int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037));
dw = min(w-1, max(0, dw));
dh = min(h-1, max(0, dh));
if (dw <= 0 && dh <= 0) { if (dw <= 0 && dh <= 0) {
return base_img; return base_img;
} }
+1 -1
View File
@@ -301,7 +301,7 @@ TransfersPreferencesPage::TransfersPreferencesPage(Window* parent) : Preferences
export_scale->Append(String::Format(_("%d%%"), i)); export_scale->Append(String::Format(_("%d%%"), i));
} }
int default_export_scale = settings.default_stylesheet_settings.export_scale_selection(); int default_export_scale = settings.default_stylesheet_settings.export_scale_selection();
if (default_export_scale < 0 || default_export_scale > export_scale->GetCount() - 1) default_export_scale = 0; if (default_export_scale < 0 || default_export_scale > (int)export_scale->GetCount() - 1) default_export_scale = 0;
export_scale->SetSelection(default_export_scale); export_scale->SetSelection(default_export_scale);
internal_image_extension->SetValue(settings.internal_image_extension); internal_image_extension->SetValue(settings.internal_image_extension);
+117 -84
View File
@@ -50,19 +50,28 @@ void PrintJob::measure_cards() {
std::sort(sorted_layouts.begin(), sorted_layouts.end()); std::sort(sorted_layouts.begin(), sorted_layouts.end());
} }
PrintJob::CardLayout PrintJob::measure_card(const CardP& card) { PrintJob::CardLayout PrintJob::measure_card(const CardP& card) {
// initial measure
const StyleSheet& stylesheet = set->stylesheetFor(card); 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_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); RealSize size_px(stylesheet.card_width, stylesheet.card_height);
// check if we need to rotate to align best to default card height
Radians rotation = 0.0; Radians rotation = 0.0;
bool rotated = abs(size_mm.width - default_size_mm.height) < abs(size_mm.height - default_size_mm.height); // try to align best to default card height if (abs(size_mm.width - default_size_mm.height) < abs(size_mm.height - default_size_mm.height)) {
if (rotated) {
swap(size_mm.width, size_mm.height); swap(size_mm.width, size_mm.height);
swap(size_px.width, size_px.height); swap(size_px.width, size_px.height);
rotation = rad90; rotation = rad90;
} }
if (abs(size_mm.width - default_size_mm.width) < threshold_size.width) size_mm.width = default_size_mm.width; // snap to default_size_mm if we are close // 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; if (abs(size_mm.height - default_size_mm.height) < threshold_size.height) size_mm.height = default_size_mm.height;
return CardLayout(card, size_mm, size_px, rotation); // 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_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() { void PrintJob::layout_cards() {
@@ -223,6 +232,7 @@ private:
/// Draw cutter lines in the page margins, corresponding to the edges of cards /// Draw cutter lines in the page margins, corresponding to the edges of cards
void drawCutterLines(DC& dc, PrintJobP& job, int page); void drawCutterLines(DC& dc, PrintJobP& job, int page);
static constexpr double CUTTER_LINE_SIZE_MM = 8.0;
/// Draw cards according to their CardLayout info /// Draw cards according to their CardLayout info
void drawCards (DC& dc, PrintJobP& job, int page); void drawCards (DC& dc, PrintJobP& job, int page);
void drawCard (DC& dc, PrintJob::CardLayout& card_layout); void drawCard (DC& dc, PrintJob::CardLayout& card_layout);
@@ -263,8 +273,8 @@ bool CardsPrintout::OnPrintPage(int page) {
// scale factor (pixels per mm) // scale factor (pixels per mm)
printer_px_per_mm = RealSize((double)page_width_px / page_width_mm, (double)page_height_px / page_height_mm); printer_px_per_mm = RealSize((double)page_width_px / page_width_mm, (double)page_height_px / page_height_mm);
// print the cards that belong on this page // print the cards that belong on this page
drawCards(dc, job, page);
if (settings.print_cutter_lines != CUTTER_NONE) drawCutterLines(dc, job, page); if (settings.print_cutter_lines != CUTTER_NONE) drawCutterLines(dc, job, page);
drawCards(dc, job, page);
return true; return true;
} }
@@ -273,22 +283,37 @@ void CardsPrintout::drawCards(DC& dc, PrintJobP& job, int page) {
drawCard(dc, card_layout); drawCard(dc, card_layout);
} }
dc.SetDeviceOrigin(0, 0); dc.SetDeviceOrigin(0, 0);
//dc.SetUserScale(printer_px_per_mm.width, printer_px_per_mm.height);
} }
void CardsPrintout::drawCard(DC& dc, PrintJob::CardLayout& card_layout) { void CardsPrintout::drawCard(DC& dc, PrintJob::CardLayout& card_layout) {
// upscale to printer dpi // upscale to printer dpi
double card_px_per_mm_width = card_layout.size_px.width / card_layout.size_mm.width; RealPoint scale(printer_px_per_mm.width * card_layout.size_mm.width / card_layout.size_px.width,
double scale = printer_px_per_mm.width / card_px_per_mm_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 // render card to its own dc
wxBitmap buffer(card_layout.size_px.width * scale, card_layout.size_px.height * scale, 32); wxBitmap buffer(width, height, 32);
wxMemoryDC bufferDC; wxMemoryDC bufferDC;
bufferDC.SelectObject(buffer); bufferDC.SelectObject(buffer);
clearDC(bufferDC,*wxWHITE_BRUSH); clearDC(bufferDC,*wxWHITE_BRUSH);
RotatedDC rdc(bufferDC, card_layout.rot, RealRect(0, 0, card_layout.size_px.width, card_layout.size_px.height), scale, 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);
viewer.setCard(card_layout.card); viewer.setCard(card_layout.card);
viewer.draw(rdc, *wxWHITE); viewer.draw(rdc, *wxWHITE);
bufferDC.SelectObject(wxNullBitmap); 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);
}
// render card dc to page dc // render card dc to page dc
bufferDC.SelectObject(wxNullBitmap);
dc.SetDeviceOrigin(int(printer_px_per_mm.width * card_layout.pos.width), int(printer_px_per_mm.height * card_layout.pos.height)); dc.SetDeviceOrigin(int(printer_px_per_mm.width * card_layout.pos.width), int(printer_px_per_mm.height * card_layout.pos.height));
dc.DrawBitmap(buffer, 0, 0); dc.DrawBitmap(buffer, 0, 0);
} }
@@ -298,81 +323,84 @@ void CardsPrintout::drawCutterLines(DC& dc, PrintJobP& job, int page) {
const RealSize& page_margin = job->page_margins[page - 1]; const RealSize& page_margin = job->page_margins[page - 1];
int page_width, page_height; int page_width, page_height;
GetPageSizeMM(&page_width, &page_height); GetPageSizeMM(&page_width, &page_height);
wxPen pen(wxColour(0, 0, 0), 2, wxPENSTYLE_SOLID);
double vertical_line_size = min(10.0, page_margin.height - 3.0); pen.SetQuality(wxPEN_QUALITY_HIGH);
if (vertical_line_size > 0.0) { dc.SetPen(pen);
for (int i = 0; i < page_layouts.size(); ++i) { // vertical
double left_line = page_layouts[i].pos.width; int v_bleed = printer_px_per_mm.width * settings.print_bleed;
double right_line = left_line + page_layouts[i].size_mm.width; for (int i = 0; i < page_layouts.size(); ++i) {
bool draw_left_line = true; double left_line = page_layouts[i].pos.width;
bool draw_right_line = true; double right_line = left_line + page_layouts[i].size_mm.width;
if (settings.print_cutter_lines == CUTTER_NO_INTERSECTION) { bool draw_left_line = true;
// check if another card is in the way of this cutter line bool draw_right_line = true;
for (int j = 0; j < page_layouts.size(); ++j) { if (settings.print_cutter_lines == CUTTER_NO_INTERSECTION) {
if (i == j) continue; // check if another card is in the way of this cutter line
double other_left_line = page_layouts[j].pos.width; for (int j = 0; j < page_layouts.size(); ++j) {
double other_right_line = other_left_line + page_layouts[j].size_mm.width; if (i == j) continue;
if (draw_left_line && left_line - other_left_line > job->threshold_bottom && other_right_line - left_line > job->threshold_bottom) { double other_left_line = page_layouts[j].pos.width;
draw_left_line = false; double other_right_line = other_left_line + page_layouts[j].size_mm.width;
if (!draw_right_line) break; if (draw_left_line && left_line - other_left_line > job->threshold_bottom && other_right_line - left_line > job->threshold_bottom) {
} draw_left_line = false;
if (draw_right_line && right_line - other_left_line > job->threshold_bottom && other_right_line - right_line > job->threshold_bottom) { if (!draw_right_line) break;
draw_right_line = false; }
if (!draw_left_line) break; if (draw_right_line && right_line - other_left_line > job->threshold_bottom && other_right_line - right_line > job->threshold_bottom) {
} draw_right_line = false;
if (!draw_left_line) break;
} }
} }
if (draw_left_line) {
int left = printer_px_per_mm.width * left_line;
dc.DrawLine(wxPoint(left, 0.0), wxPoint(left, printer_px_per_mm.height * vertical_line_size));
dc.DrawLine(wxPoint(left, printer_px_per_mm.height * page_height), wxPoint(left, printer_px_per_mm.height * (page_height - vertical_line_size)));
}
if (draw_right_line) {
int right = printer_px_per_mm.width * right_line;
dc.DrawLine(wxPoint(right, 0.0), wxPoint(right, printer_px_per_mm.height * vertical_line_size));
dc.DrawLine(wxPoint(right, printer_px_per_mm.height * page_height), wxPoint(right, printer_px_per_mm.height * (page_height - vertical_line_size)));
}
} }
} else { if (draw_left_line) {
queue_message(MESSAGE_WARNING, _ERROR_("v margin too small for cutter")); int left = printer_px_per_mm.width * left_line;
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),
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),
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),
wxPoint(right - v_bleed, printer_px_per_mm.height * (page_height - CUTTER_LINE_SIZE_MM)));
}
} }
// horizontal
double horizontal_line_size = min(10.0, page_margin.width - 3.0); int h_bleed = printer_px_per_mm.height * settings.print_bleed;
if (horizontal_line_size > 0.0) { for (int i = 0; i < page_layouts.size(); ++i) {
for (int i = 0; i < page_layouts.size(); ++i) { double top_line = page_layouts[i].pos.height;
double top_line = page_layouts[i].pos.height; double bottom_line = top_line + page_layouts[i].size_mm.height;
double bottom_line = top_line + page_layouts[i].size_mm.height; bool draw_top_line = true;
bool draw_top_line = true; bool draw_bottom_line = true;
bool draw_bottom_line = true; if (settings.print_cutter_lines == CUTTER_NO_INTERSECTION) {
if (settings.print_cutter_lines == CUTTER_NO_INTERSECTION) { // check if another card is in the way of this cutter line
// check if another card is in the way of this cutter line for (int j = 0; j < page_layouts.size(); ++j) {
for (int j = 0; j < page_layouts.size(); ++j) { if (i == j) continue;
if (i == j) continue; double other_top_line = page_layouts[j].pos.height;
double other_top_line = page_layouts[j].pos.height; double other_bottom_line = other_top_line + page_layouts[j].size_mm.height;
double other_bottom_line = other_top_line + page_layouts[j].size_mm.height; if (draw_top_line && top_line - other_top_line > job->threshold_bottom && other_bottom_line - top_line > job->threshold_bottom) {
if (draw_top_line && top_line - other_top_line > job->threshold_bottom && other_bottom_line - top_line > job->threshold_bottom) { draw_top_line = false;
draw_top_line = false; if (!draw_bottom_line) break;
if (!draw_bottom_line) break; }
} if (draw_bottom_line && bottom_line - other_top_line > job->threshold_bottom && other_bottom_line - bottom_line > job->threshold_bottom) {
if (draw_bottom_line && bottom_line - other_top_line > job->threshold_bottom && other_bottom_line - bottom_line > job->threshold_bottom) { draw_bottom_line = false;
draw_bottom_line = false; if (!draw_top_line) break;
if (!draw_top_line) break;
}
} }
} }
if (draw_top_line) {
int top = printer_px_per_mm.height * top_line;
dc.DrawLine(wxPoint(0.0, top), wxPoint(printer_px_per_mm.width * horizontal_line_size, top));
dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, top), wxPoint(printer_px_per_mm.width * (page_width - horizontal_line_size), top));
}
if (draw_bottom_line) {
int bottom = printer_px_per_mm.height * bottom_line;
dc.DrawLine(wxPoint(0.0, bottom), wxPoint(printer_px_per_mm.width * horizontal_line_size, bottom));
dc.DrawLine(wxPoint(printer_px_per_mm.width * page_width, bottom), wxPoint(printer_px_per_mm.width * (page_width - horizontal_line_size), bottom));
}
} }
} else { if (draw_top_line) {
queue_message(MESSAGE_WARNING, _ERROR_("h margin too small for cutter")); int top = printer_px_per_mm.height * top_line;
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),
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),
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),
wxPoint(printer_px_per_mm.width * (page_width - CUTTER_LINE_SIZE_MM), bottom - h_bleed));
}
} }
} }
@@ -382,11 +410,11 @@ PrintJobP make_print_job(Window* parent, const SetP& set, const ExportCardSelect
// Let the user choose cards and spacing // Let the user choose cards and spacing
// controls // controls
ExportWindowBase wnd(parent, _TITLE_("select cards print"), set, choices); ExportWindowBase wnd(parent, _TITLE_("select cards print"), set, choices);
wxFloatingPointValidator<float> validator(2, NULL, wxNUM_VAL_ZERO_AS_BLANK); wxFloatingPointValidator<double> validator(2, NULL);
validator.SetRange(0, 100); validator.SetRange(0.0, 10.0);
wxTextCtrl* space = new wxTextCtrl(&wnd, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0L, validator); wxTextCtrl* space = new wxTextCtrl(&wnd, wxID_ANY, wxString::Format(wxT("%.2f"), settings.print_spacing), wxDefaultPosition, wxDefaultSize, 0L, validator);
space->SetValue(wxString::Format(wxT("%lf"), settings.print_spacing)); wxTextCtrl* bleed = new wxTextCtrl(&wnd, wxID_ANY, wxString::Format(wxT("%.2f"), settings.print_bleed), wxDefaultPosition, wxDefaultSize, 0L, validator);
wxChoice* cutter = new wxChoice(&wnd, wxID_ANY); wxChoice* cutter = new wxChoice(&wnd, wxID_ANY);
cutter->Clear(); cutter->Clear();
cutter->Append(_LABEL_("cutter lines all")); cutter->Append(_LABEL_("cutter lines all"));
cutter->Append(_LABEL_("cutter lines no intersect")); cutter->Append(_LABEL_("cutter lines no intersect"));
@@ -400,6 +428,8 @@ PrintJobP make_print_job(Window* parent, const SetP& set, const ExportCardSelect
wxSizer* s4 = new wxStaticBoxSizer(wxVERTICAL, &wnd, _TITLE_("settings")); wxSizer* s4 = new wxStaticBoxSizer(wxVERTICAL, &wnd, _TITLE_("settings"));
s4->Add(new wxStaticText(&wnd, -1, _LABEL_("spacing print")), 0, wxALL, 8); s4->Add(new wxStaticText(&wnd, -1, _LABEL_("spacing print")), 0, wxALL, 8);
s4->Add(space, 0, wxALL & ~wxTOP, 8); s4->Add(space, 0, wxALL & ~wxTOP, 8);
s4->Add(new wxStaticText(&wnd, -1, _LABEL_("bleed print")), 0, wxALL, 8);
s4->Add(bleed, 0, wxALL & ~wxTOP, 8);
s4->Add(new wxStaticText(&wnd, -1, _LABEL_("cutter lines print")), 0, wxALL, 8); s4->Add(new wxStaticText(&wnd, -1, _LABEL_("cutter lines print")), 0, wxALL, 8);
s4->Add(cutter, 0, wxALL & ~wxTOP, 8); s4->Add(cutter, 0, wxALL & ~wxTOP, 8);
s2->Add(s4, 1, wxEXPAND | (wxALL & ~wxLEFT), 8); s2->Add(s4, 1, wxEXPAND | (wxALL & ~wxLEFT), 8);
@@ -416,6 +446,9 @@ PrintJobP make_print_job(Window* parent, const SetP& set, const ExportCardSelect
String spacing = space->GetValue(); String spacing = space->GetValue();
if (spacing.empty()) spacing = _("0"); if (spacing.empty()) spacing = _("0");
spacing.ToDouble(&settings.print_spacing); spacing.ToDouble(&settings.print_spacing);
String bleeding = bleed->GetValue();
if (bleeding.empty()) bleeding = _("0");
bleeding.ToDouble(&settings.print_bleed);
settings.print_cutter_lines = (CutterLinesType)cutter->GetSelection(); settings.print_cutter_lines = (CutterLinesType)cutter->GetSelection();
PrintJobP job = make_intrusive<PrintJob>(set, wnd.getSelection()); PrintJobP job = make_intrusive<PrintJob>(set, wnd.getSelection());
return job; return job;
+5 -4
View File
@@ -29,12 +29,12 @@ public:
threshold_top = 0.75 * default_size_mm.width; threshold_top = 0.75 * default_size_mm.width;
threshold_bottom = 0.1; threshold_bottom = 0.1;
threshold_size = RealSize(0.05 * default_size_mm.width, 0.05 * default_size_mm.height); threshold_size = RealSize(0.03 * default_size_mm.width, 0.03 * default_size_mm.height);
} }
SetP set; SetP set;
vector<CardP> cards; ///< Cards selected by the user for print vector<CardP> cards; ///< Cards selected by the user for print
RealSize default_size_mm; ///< Size of a card with the default stylesheet in millimetres RealSize default_size_mm; ///< Size of a card with the default stylesheet in millimetres, without bleed
// align cards that are at most this far appart in millimeters // align cards that are at most this far appart in millimeters
double threshold_top; double threshold_top;
@@ -44,8 +44,8 @@ public:
RealSize threshold_size; RealSize threshold_size;
struct CardLayout { struct CardLayout {
CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, const Radians& rotation) CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, double bleed_size_px, Radians rotation)
: card(card), size_mm(size_mm), size_px(size_px), rot(rotation), other_face(-1) {} : card(card), size_mm(size_mm), size_px(size_px), bleed_size_px(bleed_size_px), rot(rotation), other_face(-1) {}
bool operator<(const CardLayout& that) const { bool operator<(const CardLayout& that) const {
return size_mm.width > that.size_mm.width; // put the widest cards first return size_mm.width > that.size_mm.width; // put the widest cards first
@@ -54,6 +54,7 @@ public:
CardP card; CardP card;
RealSize size_mm; RealSize size_mm;
RealSize size_px; RealSize size_px;
double bleed_size_px;
Radians rot; Radians rot;
RealSize pos; RealSize pos;
int other_face; int other_face;
+1 -1
View File
@@ -32,7 +32,7 @@ public:
/** with the given rectangle of external coordinates and a given rotation angle and zoom factor. /** with the given rectangle of external coordinates and a given rotation angle and zoom factor.
* if is_internal then the rect gives the internal coordinates, its origin should be (0,0) * if is_internal then the rect gives the internal coordinates, its origin should be (0,0)
*/ */
Rotation(Radians angle = 0, const RealRect& rect = RealRect(0,0,0,0), double zoom = 1.0, double strectch = 1.0, RotationFlags flags = ROTATION_NORMAL); Rotation(Radians angle = 0, const RealRect& rect = RealRect(0,0,0,0), double zoom = 1.0, double stretch = 1.0, RotationFlags flags = ROTATION_NORMAL);
/// Change the zoom factor /// Change the zoom factor
inline void setZoom(double z) { zoomX = zoomY = z; } inline void setZoom(double z) { zoomX = zoomY = z; }