nixp.ru v3.0

22 ноября 2024,
пятница,
06:14:10 MSK

5 июля 2011, 10:15

pdf.js — свободная реализация PDF-рендерера на JavaScript

4
Рендеринг в pdf.js 0.1 (сверху) и 0.2 (снизу)
Рендеринг в pdf.js 0.1 (сверху) и 0.2 (снизу)
Иллюстрация с сайта h-online.com

Программисты на JavaScript не останавливаются на достигнутом и продолжают приносить миру Web готовые Open Source-реализации привычных для десктопов приложений. Очередным шагом в этом направлении стал проект pdf.js.

Авторы pdf.js задались целью написать на скриптовом языке JavaScript рендерер популярного формата для документов PDF. Сам проект был анонсирован две недели назад, и с тех пор достигнуты значимые результаты: выполнена первая крупная задача — отличное отображение PDF-документа, посвященного движку Tracemonkey. Это произошло с выпуском pdf.js 0.2.

В этом же релизе (pdf.js 0.2) заявлены корректное отображение динамически загружаемых шрифтов в PDF, улучшения в рендеринге графиков и пользовательском интерфейсе, где появилась панель предварительного просмотра страниц. Следующая ключевая задача, которую поставили перед собой разработчики, — идеальное отображение документов в соответствии со спецификацией PDF 1.7.

Исходный код pdf.js распространяется под лицензией BSD, он доступен на GitHub. Посмотреть на pdf.js в действии можно здесь.

За pdf.js стоят участники проекта Mozilla, однако они говорят об отсутствии планов по интеграции pdf.js в Firefox — рассматривать такую возможность начнут только после того, как разработка станет достаточно зрелой. Пока же планируется сделать для Firefox дополнение в виде просмотрщика PDF-документов на базе pdf.js.

Постоянная ссылка к новости: http://www.nixp.ru/news/11287.html. Дмитрий Шурупов по материалам h-online.com.

fb twitter vk
yesint

Отображает пока ооочень криво (у меня колонки друн на друга налазят и шрифты глючат), но скорость работы на удивление неплохая. Загружается долго, но скролится очень резво. Будет отличная вещь когда допилят.

Дмитрий Шурупов

Да, у меня тоже отображает криво на FF5. Ну, это допилят — сомнений нет.

dfghm

Здорово. JS это не прожорливый Adobe )

yesint

Увы, эта хрень по потреблению памяти априорно будет в разы хуже даже адоба — все же интерпретируемый язык

defender

Ну, скажем так, JavaScript в принципе КОМПИЛИРУЕМЫЙ язык и есть куча компиляторов оного (как пример — компилятор ExtendedScript — скриптодвижок в Creative Suite —  по сути являющийся JavaScript-ом дополненным сокетами и обращениями к локальным файлам и еще кучка). И потребление памяти как-то мало зависит от того — интерпретируемый язык или нет… Зависит от того как часто прога выделяет память, хватает ли процессорного времени сборщику мусора чтобы реально освободить память и тд и тп. И в некотором смысле может быть даже и лучше кода на С/С++ и иже с ними. Меньше багов с утечкой памяти. Да и производительность интерпретаторов, включенных в браузеры,  вполне себе. Самое главное — ограничиться целочисленной арифметикой :D

Да есть вероятность нарваться на баг интерпретатора и засорить память — дык это к автору интерпретатора.

ЗЫ

вы не смотрите так — на самом деле я программирую 90% на С++ и SQL/PLPGSQL. :D. Да. Кстати. В научных кругах очень пользуется популярностью такая штука как интерпретатор С (clif). Со сборкой мусора. Производительность на уровне, а вот париться с памятью при процессинге сложных выражений (читай — очень больших :D, например, численный метод расчета интегралов) не надо. Но правда стоит заметить что clif — это С-подобный язык, хоть и до мелочей если так сказать :D.

yesint

Не соглашусь. Потребления памяти ой как зависит от того  интерпретируемый язык или нет. В динамическом языке априори надо выделять память в куче под любой объект, что медленно. Плюс каждый объект тянет с собой информацию о типе, что жрет память. Плюс сам интерпретатор отжирает под свою внутреннюю кухню.

defender

В компилируемых языках есть «аналоги» почти всех приведенных «минусов». Скажем так, редкий проект сейчас пишется без использования какого-нить фреймворка — типа QT, GTK, wxWidgets etc. Примерно 10% кода каждого такого фреймворка связано как раз с хранением мета-информации о типах. И непонятно что лучше — каждый свою систему подобную будет изобретать или такое поддерживает ядро языка. (да, кстати, rtti никто не отменял — правда говно и я не видел ни разу чтобы его использовали…).

> В динамическом языке априори надо выделять память в куче под любой объект

Мы говорим про количество занимаемой памяти или про быстродействие? Немного не связанные величины. Да, кстати. Рассматривая задачу рендеринга PDF (да рендеринга чего угодно) 99% объектов будет динамически создано… так что компилируемый язык тут практически ничем не поможет (как я уже говорил -— разве-что приемлемой производительностью операций с флоатами). Под вопросом конечно остается оптимизация с использованием специфичных расширений типовых процессоров… Но! Все это касается производительности.

>  Плюс сам интерпретатор отжирает под свою внутреннюю кухню.

Инстанс  для отдельной странички много не кушает. Когда запущен браузер память под ядро JavaScript уже занято — половина функционала браузера (ну загнул конечно, но не особо) выполнена на JavaScript.

yesint

Ок, флудить так флудить :)

По поводу памяти. Объект JavaScript «толще» аналогичного объекта на С++ просто из-за реализации. В JavaScript это просто ассоциативный массив с кучей метаинформации а в С++ компилятор очень многое оптимизирует. Вообще сама интерпретируемость требует тянуть за собой постоянно много информации в текстовом виде (имя класса, имена всех методов и переменных например) и памяти это жрет немало, а в С++ все это не нужно.

По быстродействию. Про флоаты вы сами сказали. А все остальное тормозит просто из-за того, что интерпретатор на ходу постоянно бегает по дереву синтаксиса в памяти и тратит уйму циклов процессора на то чтобы решить какую функцию низкого уровня в данный момент вызвать. Это не лечится поскольку indirection by design. Любой алгоритм на JavaScript будет тем быстрее чем более он «крупноблочный» — вызвали библиотечную функцию написанную на С и ждем от нее результата. Это один indirection на всю функцию. А если логику этой функции переписать на самом JavaScript, то будет indirection на каждый оператор! Поэтому писать сложные алгоритмы на JavaScript это, имхо, забивание гвоздей микроскопом — сделать можно, но зачем?

А по поводу рендеринга чего угодно — вы видели хоть один нормальный рейтрейсер написанный на скриптовом языке? ПДФки это не настолько «тяжелая» работа, скорее просто преобразование форматов и генерация текстового эквивалента бинарных данных как ниже написано, так что скрипт вполне справляется.

Вообще, имхо, если бы был нормальный и широко используемый компилируемый язык без прибабахов С++, то скриптовые были бы куда как менее популярны. Языки такие есть (тот-же D), но они на маргинальном положении, поэтому и пишут что-попало на JavaScript :)

defender

Все это справедливо для «сферических интерпретаторов в вакууме». Повторюсь — JavaScript язык компилируемый, весь его сабсет (ну конечно стоит вспомнить eval…). так что избавиться от многих проблем интерпретатора для JavaScript _можно_.

yesint

Что в вашем понимании «компилируемый»? Компилируемый это тот, который создает нативный выполняемый машинный код. Любой современный скриптовый язык создает АST и даже преобразует его в поток инструкций для внутренней виртуальной машины, но он не генерит нативные инструкции. Компиляция в байт-код не есть истинная компиляция.

defender

Компилируемый — значит его можно странслировать в нативный код процессора. 

>  для внутренней виртуальной машины

Большинство современных компиляторов так делают. Например, есть такая вещь как LLVM (Low level virtual machine). Набор компиляторов GCC компилит сначала в код этой машины а потом только в нативный процессора. Сделано это дабы для каждого языка не писать много-много повторяющегося кода и выполнить продвинутую оптимизацию (например, LLVM может использовать СТАТИСТИКУ выполнения и код, результат работы которого статичен, тупо заменить на константу, но тут речь не идет об обычной компиляции). Ну и еще много всякой вкуснятины с пом. такого подхода можно сделать.

JavaScript и похожие языки сейчас не интерпретируются «всухую». Используются так называемые Just-in-time компилеры и оптимизирующий компилятор.  время запуска немного больше, а скорость работы — почти не отличается от компилируемого кода. И что самое главное, при использовании архитектуры, подобной LLVM возможно использование всяко разных расширений процессора (SSE2,SSE3,…)

Eleidan

2yesint

Посмею вставить свои 5 копеек, хоть и далеко не ас в этих вещах.

Я слышал о движке V8 от гугля. А вы?

Выдержка из вики:

Ларс Бак считал, что краеугольными камнями V8 являются:

  • Компиляция исходного кода JavaScript непосредственно в собственный машинный код, минуя стадию промежуточного байт-кода.
dfghm

Время покажет. Сейчас же исходный документ содержит 14 страниц.

у меня на Linux 3.0-3-generic #4-Ubuntu SMP x86_64 получилось вот что.

Google Chrome 12.0.742.112

Пустая вкладка            Открытый пример

18 364 K                       111 568 K

Mozilla Firefox 5.0

Пустая вкладка            Открытый пример

54 784 K                       191 708 K

В итоге памяти только в 2 раза больше, чем эта открыта страница.

Весь документ — это динамически свёрстана html5 страница с canvas элементами в виде списка страниц и iframe как контейнер для png рисунков, закодированных в base64. То есть в виде строки, коротая, примерно, на треть больше оригинала. Терпимо, если учесть, что я не так часто использую PDF, что бы устанавливать дополнительные бинарные файлы.

Надеюсь, в скором будущем сделают редактор изображений с поддержкой слоев (альтернативу PSD или PSB) на JavaScript (с использованием xhtml или html5, css3 и рисунки в формате WebP) и внедрят это как открытый стандарт (будут использовать в ChromeOS, например).

yesint

Я попробовал открыть свой большой пдф с кучей картинок и разной лабуды. Что отображает неправильно фиг с ним, но браузер повесился минут на пять намертво. Нехорошо.

dfghm

Приведите время открытия этого файла браузером (Google Chrome) и Adobe Reader пожалуйста.

rgo
yesint

Увы, эта хрень по потреблению памяти априорно будет в разы хуже даже адоба — все же интерпретируемый язык

У адоба всё интерпретируемое. Правда, если я правильно знаю, интерпретируется оно из байт-кода, но хрен редьки не слаще.

yesint

Не знал кстати. А на чем же тогда адоб ридер написан?

rgo

Я имел в виду всякие-там Flash и ActionScript. Про ридер не знаю, но предполагаю, что либо на Java, либо на C++: таких тормозных монстров на других языках не пишут.

sashakrasnoyarsk.ru

Когда вышел 2000 MS SQL, написанный на ActiveX компонентах, я смеялся, что скоро всё начнут писать на Visual Basic-е :( Пипец, кошмары начинаются сбываться…

rgo

Ура-ура! Наконец-то заметен прогресс в сторону просматра pdf’ок без выполнения ритуала скачал-открыл. Теперь дело за ps и производными от него ps.gz и pz.bz2.

Дмитрий Шурупов

> в сторону просматра pdf’ок без выполнения ритуала скачал-открыл

Современные браузеры давно это позволяют без всякого JS. Да, немного костыльно (у Firefox, например, открывается внешний PDF-просмотрщик внутри окна браузер), но я уже привык и даже рад этому.

rgo

Ничего не знаю. Я пользуюсь параллельно файрфоксом и хромом, ни тот ни другой даже не пытаются открывать. Тупо сохраняют на диск. Хром при этом ещё матерится о том, что pdf может содержать вредоносные java и javascript программы.

А с какой версии ff научился открывать pdf? Может дело в том, что у меня 3.6?

[upd]А-а-а… «внешний просмотрщик»… Не обратил внимания на фразу. Ну дык это действительно костыль. Мне без разницы где этот просмотрщик открывается — в окне фф, или рядом.

defender

Хром версии с 10-й открывает у мну во вкладке во встроенном въювере PDF…

rgo

Погуглил… Действительно умеет. Надо оказывается плугин ставить. Ещё и оверлеи какие-то на портажи натягивать… Но хром не заслуживает того, чтобы я ему ещё и плугины ставил. Я уж молчу про оверлеи. Ради фф, я бы ещё подумал. А хром пускай идёт лесом.

Count Raven Amiant

Простите, но чем Вам так не угодил Google Chrome?

rgo

Своею «конфигурабельностью». Тем что он до сих пор весь наскозь пропитан запахом греческой буквы β. Своею принадлежностью к империи зла Google.

А если серьёзно, то подключать оверлей из-за какой-то одной программы, по-моему перебор. Одно дело подключать, скажем, multilib, чтобы иметь возможность собрать систему, которая свободно гоняет и 32-х, и 64-х разрядные приложения. Одно дело подключать оверлей lisp, чтобы иметь в портажах кучу lisp’овых пакетов. Но подключать какой-то там оверлей неизвестного мне автора из-за поддержки pdf где бы там ни было — это уже перебор.

Count Raven Amiant

Ясненько. В данном вопросе соглашусь.

rgo

Смешнее было бы, если бы вы не согласились. ;)

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

Count Raven Amiant

У меня, как у web-разработчика стоят IE7 (wine), Safari 5 (wine), Google Chrome 12, Firefox 4 (5-ку не ставил еще), Arora, Midori — так просто стоят, Opera 11. Это все для тестирования JS и верстки.

Обычно я в Chrome, раньше всегда был в FF.

FF мне нравится обилием плагинов и их настройкой, но Chrome быстрее грузится и меньше тупит. Сейчас открыто 27 вкладок. Полет нормальный и при 50-ти будет нормальный. А в FF при открытии более 30-и вкладок (конечно зависит от того, что там собственно открыто — много flash, js и т.д. или просто мелкие странички) начинаются тормоза и пожирание процессора. Поэтому блуждаю в сети я из Chrome.

Firefox использую периодически — есть любимые плагины, которые иногда нужны.

Что касается остальных — не знаю, Opera я так и не полюбил. IE и Safari через wine — изврат, просто нужно иногда тестить кое-какие моменты именно на них. Ну а Midori и Arora собственно вообще нахрен, оба webkit, оба ничего особенного, лучше тогда Chrome.

Дмитрий Шурупов

Как это без разницы? В техническом задании («без выполнения ритуала скачал-открыл») такого не было ;-)

Дмитрий Шурупов

Поясню, что внешний просмотрщик находится _внутри _ окна браузера, вместо HTML-страницы. Самому не надо ничего скачивать и запускать.

Аналогично, к слову, в FF уже довольно давно открываются документы для OpenOffice.org / LibreOffice.