Часто при разработке в 1С возникает задача отобразить PDF-документ прямо на форме, не прибегая к использованию сторонних программ-просмотрщиков, установленных на компьютере пользователя. Одним из популярных решений является использование поля HTML-документа и популярной JavaScript-библиотеки PDF.js. Однако разработчики сталкиваются с неприятной проблемой: при рендеринге документа смазываются шрифты, а масштаб отображения не соответствует исходному файлу. Давайте разберем по шагам, почему это происходит и как мы можем это исправить.
Главная причина нечеткого отображения и "мыльных" шрифтов заключается в механизме работы самой библиотеки PDF.js. Для вывода страницы документа библиотека использует HTML-элемент canvas (холст). По умолчанию размер этого холста в пикселях строго совпадает с его физическим размером на экране.
Проблема проявляется, если у пользователя в операционной системе Windows установлен масштаб экрана больше 100% (например, 125% или 150%), либо используется современный монитор с высокой плотностью пикселей (High-DPI или Retina). В таких случаях браузерный движок внутри 1С искусственно растягивает изображение на холсте, из-за чего оно теряет четкость и масштабируется некорректно. Выясним, как мы можем адаптировать наш код под такие экраны.
Прежде чем погружаться в дебри JavaScript, рассмотрим самый правильный и надежный путь. Начиная с версии платформы 1С Предприятие 8.3.21, разработчикам доступен встроенный объект ДокументPDF. Если конфигурация и сервер позволяют обновиться, настоятельно рекомендуем использовать именно его.
Этот объект предназначен для полноценной работы с PDF-документами прямо из встроенного языка: чтение, запись, извлечение страниц, проверка и добавление подписей, а также вывод на печать и отображение пользователю с помощью метода Показать. Использование нативного объекта полностью избавляет от проблем с масштабированием, зависимостей от внешних скриптов и версий движков HTML внутри платформы.
Если обновление платформы пока невозможно (например, используется версия 8.3.17), проанализируем ситуацию и исправим код рендеринга. Чтобы шрифты были четкими на любых мониторах, нам необходимо отрисовать холст в увеличенном (внутреннем) разрешении, а затем сжать его до нужных визуальных размеров с помощью CSS-стилей.
Для этого в JavaScript существует специальный параметр window.devicePixelRatio, который возвращает коэффициент масштабирования экрана. Посмотрим на пример модифицированной функции рендеринга страницы:
function handlePages(page) {
var scale = 1;
var viewport = page.getViewport({scale: scale});
var canvas = document.createElement("canvas");
var context = canvas.getContext('2d');
// Получаем коэффициент масштабирования экрана пользователя
var outputScale = window.devicePixelRatio || 1;
// Увеличиваем физическое разрешение холста на этот коэффициент
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
// Визуальный размер холста оставляем оригинальным, задавая его через CSS
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
canvas.style.display = "block";
// Передаем матрицу трансформации в контекст рендеринга PDF.js
var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
var renderContext = {
canvasContext: context,
transform: transform,
viewport: viewport
};
var renderTask = page.render(renderContext);
document.body.appendChild(canvas);
currPage++;
if (thePDF !== null && currPage <= numPages) {
thePDF.getPage(currPage).then(handlePages);
}
}
В этом коде мы умножаем ширину и высоту элемента canvas на коэффициент масштабирования экрана, но визуальный размер в браузере (через стили) оставляем прежним. В результате библиотека отрисовывает больше пикселей, и текст выглядит идеально резко.
Если первый способ по каким-то причинам (например, из-за специфики старых движков) не дает нужного результата, рассмотрим "грубый", но рабочий метод. Мы можем принудительно заставить PDF.js рендерить страницу в двойном или тройном масштабе.
Для этого переменную scale изначально задаем больше единицы (например, var scale = 2;). Библиотека отрендерит страницу в очень высоком качестве. А чтобы эта огромная картинка поместилась в экран Поля HTML документа, мы задаем холсту жесткие ограничения в CSS:
var scale = 2; // Принудительно увеличиваем качество
var viewport = page.getViewport({scale: scale});
var canvas = document.createElement("canvas");
canvas.width = viewport.width;
canvas.height = viewport.height;
// Заставляем браузер сжать качественную картинку до ширины экрана
canvas.style.width = "100%";
Браузер сам сожмет изображение высокого разрешения, и текст останется отлично читаемым, а проблема со смазыванием исчезнет.
Разберем еще несколько важных архитектурных моментов при работе с Полем HTML-документа в 1С.
Применяя данные подходы, мы можем гарантировать стабильное и качественное отображение PDF-документов в формах 1С, независимо от масштаба экрана пользователя и настроек его операционной системы.