Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/common/cups_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,12 +547,36 @@ void dt_print_file(const dt_imgid_t imgid,

cupsFreeDests(num_dests, dests);

// if we have a profile, disable cm on CUPS, this is important as dt does the cm
// When a printer ICC profile is selected, tell CUPS to skip its
// own color management — darktable already did the conversion
// via LittleCMS, and the ICC profile is embedded in the PDF.
//
// Linux: cm-calibration=true causes pdftoraster to set cm_disabled=1,
// skipping its own color management.
//
// macOS: cgpdftoraster ignores cm-calibration. Instead we send
// AP_ColorMatchingMode=AP_ApplicationColorMatching which
// tells both cgpdftoraster and the printer driver that the
// application already handled color matching.

num_options = cupsAddOption("cm-calibration",
*pinfo->printer.profile ? "true" : "false",
num_options, &options);

#ifdef __APPLE__
if(*pinfo->printer.profile)
{
// dot-notation variant appears to be legacy but is observed in
// print jobs from other macOS applications
num_options = cupsAddOption("AP.ColorMatchingMode",
"AP_ApplicationColorMatching",
num_options, &options);
num_options = cupsAddOption("AP_ColorMatchingMode",
"AP_ApplicationColorMatching",
num_options, &options);
}
#endif

// media to print on

num_options = cupsAddOption("media", pinfo->paper.name, num_options, &options);
Expand Down
27 changes: 21 additions & 6 deletions src/libs/print_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static void _create_pdf(dt_job_t *job,

const float page_width = dt_pdf_mm_to_point(width);
const float page_height = dt_pdf_mm_to_point(height);
const int icc_id = 0;
int icc_id = 0;

dt_pdf_image_t *pdf_image[MAX_IMAGE_PER_PAGE];

Expand All @@ -454,11 +454,19 @@ static void _create_pdf(dt_job_t *job,
params->prt.printer.resolution,
DT_PDF_STREAM_ENCODER_FLATE);

/*
// ??? should a profile be embedded here?
if(*printer_profile)
icc_id = dt_pdf_add_icc(pdf, printer_profile);
*/
#ifdef __APPLE__
// On macOS, embed the printer ICC profile in the PDF so the
// already-converted pixel data is correctly tagged with its actual
// color space. Without this, cgpdftoraster assumes DeviceRGB = sRGB
// and misinterprets the data.
//
// On Linux this must NOT be done — Poppler (inside pdftoraster) would
// see the ICCBased color space and convert the data back to sRGB,
// undoing the LittleCMS conversion. Linux uses cm-calibration instead.
if(params->p_icc_profile && *params->p_icc_profile)
icc_id = dt_pdf_add_icc(pdf, params->p_icc_profile);
Comment thread
TurboGit marked this conversation as resolved.
#endif

int32_t count = 0;

for(int k=0; k<imgs.count; k++)
Expand Down Expand Up @@ -779,6 +787,13 @@ static void _print_button_clicked(GtkWidget *widget, dt_lib_module_t *self)
params->p_icc_intent = ps->v_pintent;
params->black_point_compensation = ps->v_black_point_compensation;

// Propagate the printer profile selection so dt_print_file() can
// tell CUPS to skip color management when dt already did the
// ICC conversion. See cups_print.c for platform-specific details.
if(ps->v_piccprofile && *ps->v_piccprofile)
Comment thread
TurboGit marked this conversation as resolved.
g_strlcpy(params->prt.printer.profile, ps->v_piccprofile,
sizeof(params->prt.printer.profile));

dt_control_add_job(DT_JOB_QUEUE_USER_EXPORT, job);
}

Expand Down
Loading