Техническая статья

Цветопроба CMYK с наложением и устройства отрисовки в HotPDF

HotPDF выводит загруженную страницу PDF через одну точку входа — RenderLoadedPageToDevice, — и переданное устройство решает, чем станет результат: растровым изображением, отрисовкой на внешнем контексте устройства вроде холста принтера или векторным расширенным метафайлом. Установите RenderOverprintPreview в True, и тот же вызов имитирует CMYK-наложение триадных красок, поэтому оператор видит на экране то взаимодействие красок, которое иначе проявилось бы лишь на печатном оттиске

Эти две возможности решают разные задачи, которые случайно встречаются на одном пути кода. Абстракция устройства устраняет ветвление, где предпросмотр, печать и экспорт имели каждый свой вызов отрисовки со своим дрейфом. Цветопроба с наложением устраняет класс производственных ошибок, где документ выглядит корректно в любом просмотрщике и сходит с машины неправильно

Почему страница печатается иначе, чем предпросматривается?

Потому что наложение (overprint) — это инструкция устройству воспроизведения, а не операция закраски. Когда страница устанавливает /OP или /op в истине в графическом состоянии, она указывает RIP не выбивать краски под собой — голубой объект, нарисованный поверх жёлтого, оставляет жёлтый на месте, и оттиск показывает зелёный. Просмотрщик, игнорирующий наложение, выбивает нормально и показывает голубой. Ни тот, ни другой не ошибаются на своих условиях, и в этом-то и проблема: экран и печатная машина расходятся, и никто не узнаёт об этом, пока не вернутся пробы

RenderOverprintPreview заставляет HotPDF принять инструкцию всерьёз для красок DeviceCMYK, управляемых /OP, /op и /OPM 1. Результат — цветопробный предпросмотр, а не предпросмотр просмотрщика: чёрный, накладываемый поверх оттенка, остаётся насыщенным перекрытием, а не пробивает дыру, а случайное наложение дизайнера на белом тексте становится видимым как исчезающий текст, каким он и окажется

var
  Pdf: THotPDF;
  Device: THPDFBitmapRenderDevice;
  Proof: TBitmap;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.LoadFromFile('cover-cmyk.pdf');
    Pdf.RenderOverprintPreview := True;    // proof, not plain preview
    Device := THPDFBitmapRenderDevice.Create;
    try
      if Pdf.RenderLoadedPageToDevice(0, 150, Device) then
      begin
        Proof := Device.TakeBitmap;        // ownership moves to the caller
        try
          Image1.Picture.Assign(Proof);
        finally
          Proof.Free;
        end;
      end;
    finally
      Device.Free;
    end;
  finally
    Pdf.Free;
  end;
end;

Эта настройка участвует в идентичности кэша отрисовки — и в памяти, и на диске, поэтому обычный предпросмотр и цветопробный предпросмотр никогда не разделяют один растр. Переключение свойства не требует вручную инвалидировать что-либо — кэш, вернувший не тот из двух вариантов, был бы хуже, чем отсутствие кэша

Три устройства, один вызов отрисовки

THPDFRenderDevice — абстрактный класс с двумя значимыми членами: Kind, сообщающим цель как rdkBitmap, rdkDeviceContext или rdkEnhancedMetafile, и Execute, вызываемым библиотекой. Три конкретных устройства поставляются с HotPDF, и каждое владеет своим выводом по-разному

THPDFBitmapRenderDevice владеет TBitmap, пока TakeBitmap не передаст владение вам. THPDFDeviceContextRenderDevice принимает существующий HDC плюс ширину и высоту и рисует прямо в него — так вы отрисовываете на холст принтера без растрового прохода туда-обратно. THPDFMetafileRenderDevice владеет TMetafile, пока TakeMetafile не передаст его, что сохраняет векторное содержимое как векторы для потребителей, которым это нужно

var
  Device: THPDFDeviceContextRenderDevice;
begin
  Printer.BeginDoc;
  try
    Device := THPDFDeviceContextRenderDevice.Create(
      Printer.Canvas.Handle, Printer.PageWidth, Printer.PageHeight);
    try
      Pdf.RenderLoadedPageToDevice(PageIndex, 300, Device);
    finally
      Device.Free;
    end;
  finally
    Printer.EndDoc;
  end;
end;

Чтение Kind вместо проверки класса во время выполнения намеренно. Код приложения, диспетчеризующий по типу устройства, продолжает работать, когда устройство обёрнуто, декорировано или заменено, а код, проверяющий is THPDFBitmapRenderDevice, — нет

Что передача владения значит на деле

До TakeBitmap или TakeMetafile устройство владеет объектом и освобождает его в своём деструкторе. После вызова им владеете вы, а устройство — больше нет. Оба шаблона законны: используйте свойство Bitmap или Metafile, когда объект должен пережить лишь вызов отрисовки, и заберите владение, когда объект переживает устройство

Режим отказа — обычный для Delphi. Возьмите растр, освободите устройство, забудьте освободить растр — и у вас утечка, растущая с числом страниц: невидимая на пятистраничном тесте и очевидная на пакете в пятьсот страниц. Оборачивайте оба объекта в их собственные try/finally, а не в общий, и вопрос владения отпадёт сам собой

Цветопроба наложения и прозрачность на одной странице

Выбивание группы прозрачности остаётся активным, когда включён предпросмотр наложения, и оба композируются на одном пути ограниченного снимка закраски. Это важно, потому что реальные предпечатные файлы постоянно смешивают оба: группа прозрачности с графикой лежит на фоне, чей чёрный установлен в наложение, а имитация одного без другого даёт пробу, ошибающуюся по-новому, а не правильную

Помните и об ограничениях. Предпросмотр наложения имитирует поведение триадных красок для красок DeviceCMYK под перечисленными выше органами управления наложением. Это проба взаимодействия красок, а не цветоуправляемая контрактная цветопроба: она не заменяет ICC-рабочий процесс и не сообщает, что даст конкретная печатная машина и бумага. Относитесь к ней так же, как предпечатный оператор относится к предпросмотру наложения в профессиональном просмотрщике — как к проверке, ловящей ошибки, которые никто не ловит, глядя на обычный предпросмотр

Куда цветопроба встаёт в шаг предпечатной подготовки

Полезное место для неё — рядом с проверками, которые вы уже прогоняете. Проход предпечатной подготовки сообщает, что чёрный текст установлен в наложение; цветопробный показ показывает оператору, что это значит на странице; и оба попадают в один отчёт. Для плашечных цветов, часто сопровождающих наложение в упаковочной работе, разбор отрисовки плашечных цветов Separation и DeviceN описывает красочную сторону той же страницы, тогда как заметки об отрисовке страницы PDF в растр и о печати загруженного PDF через TPrinter описывают две целевые устройства в их обычной, не-цветопробной форме

HotPDF выводит, цветопробует и печатает загруженные страницы PDF из нативного VCL-кода для Delphi и C++Builder, без внешней DLL отрисовки, поставляемой рядом с приложением — на странице компонента HotPDF есть список возможностей отрисовки и пробная сборка