Создание документа в формате PDF, просмотр и преобразование

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

Кварц создает для всех приложений, высокочастотных документов в формате PDF, сохраняющих операции рисования приложения, как показано на рисунке 13-1. Получающийся PDF может быть оптимизирован для определенного использования (такого как определенный принтер, или для сети) другими частями системы, или сторонними продуктами. Документы в формате PDF, сгенерированные представлением Quartz правильно в Предварительном просмотре и Acrobat.

  Кварц рисунка 13-1 создает высококачественные документы в формате PDF
Quartz creates high-quality PDF documents

Кварц не только использует PDF в качестве своей “цифровой статьи”, но также и включает как часть его API много функций, которые можно использовать, чтобы вывести на экран и генерировать файлы PDF и выполнить много других СВЯЗАННЫХ С PDF задач.

Для получения дальнейшей информации о PDF, включая язык PDF и синтаксис, посмотрите Ссылку PDF, Четвертый Выпуск, Версию 1.5.

Открытие и просмотр PDF

Кварц обеспечивает тип данных CGPDFDocumentRef представлять документ в формате PDF. Вы создаете объект CGPDFDocument, использующий любого функция CGPDFDocumentCreateWithProvider или функция CGPDFDocumentCreateWithURL. После создания объекта CGPDFDocument можно нарисовать его к графическому контексту. Рисунок 13-2 показывает документ в формате PDF, выведенный на экран в окне.

Рисунок 13-2  документ в формате PDF
A PDF document displayed by the PDFViewer sample application

Перечисление 13-1 показывает, как создать CGPDFDocument, возражают и получают число страниц в документе. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление 13-1  , Создающее CGPDFDocument, возражает от файла PDF

CGPDFDocumentRef MyGetPDFDocumentRef (const char *filename)
{
    CFStringRef path;
    CFURLRef url;
    CGPDFDocumentRef document;
    size_t count;
 
    path = CFStringCreateWithCString (NULL, filename,
                         kCFStringEncodingUTF8);
    url = CFURLCreateWithFileSystemPath (NULL, path, // 1
                        kCFURLPOSIXPathStyle, 0);
    CFRelease (path);
    document = CGPDFDocumentCreateWithURL (url);// 2
    CFRelease(url);
    count = CGPDFDocumentGetNumberOfPages (document);// 3
    if (count == 0) {
        printf("`%s' needs at least one page!", filename);
        return NULL;
    }
    return document;
}

Вот то, что делает код:

  1. Вызывает Базовую функцию Основы для создания объекта CFURL из объекта CFString, представляющего имя файла файла PDF для отображения.

  2. Создает объект CGPDFDocument из объекта CFURL.

  3. Получает число страниц в PDF так, чтобы следующий оператор в коде мог гарантировать, что документ имеет по крайней мере одну страницу.

Вы видите, как нарисовать страницу PDF к графическому контексту путем рассмотрения кода в Перечислении 13-2. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление 13-2  , Получающее страницу PDF

void MyDisplayPDFPage (CGContextRef myContext,
                    size_t pageNumber,
                    const char *filename)
{
    CGPDFDocumentRef document;
    CGPDFPageRef page;
 
    document = MyGetPDFDocumentRef (filename);// 1
    page = CGPDFDocumentGetPage (document, pageNumber);// 2
    CGContextDrawPDFPage (myContext, page);// 3
    CGPDFDocumentRelease (document);// 4
}

Вот то, что делает код:

  1. Вызывает Вашу функцию (см. Перечисление 13-1) для создания объекта CGPDFDocument из имени файла, Вы предоставляете.

  2. Получает страницу для указанного номера страницы из документа в формате PDF.

  3. Рисует указанную страницу из файла PDF путем вызывания функции CGContextDrawPDFPage. Необходимо предоставить графический контекст и страницу для рисования.

  4. Выпускает объект CGPDFDocument.

Создание преобразования для страницы PDF

Кварц обеспечивает функцию —CGPDFPageGetDrawingTransform— это создает аффинное преобразование путем отображения поля на странице PDF к прямоугольнику, который Вы указываете. Прототип для этой функции:

CGAffineTransform CGPDFPageGetDrawingTransform (
        CGPPageRef page,
        CGPDFBox box,
        CGRect rect,
        int rotate,
        bool preserveAspectRatio
);

Функция возвращает аффинное преобразование с помощью того после алгоритма:

Можно использовать эту функцию, например, если Вы пишете приложение просмотра PDF, подобное показанному на рисунке 13-3. Если необходимо было обеспечить функцию Rotate Left/Rotate Right, Вы могли бы вызвать CGPDFPageGetDrawingTransform вычислить надлежащее преобразование для текущего размера окна и установки вращения.

  Страница A PDF рисунка 13-3 повернула 90 градусов вправо
A PDF page rotated 90 degrees to the right

Перечисление 13-3 показывает функцию, создающую аффинное преобразование для страницы PDF с помощью параметров, передал функции, применяет преобразование, и затем рисует страницу PDF. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление 13-3  , Создающее аффинное преобразование для страницы PDF

void MyDrawPDFPageInRect (CGContextRef context,
                    CGPDFPageRef page,
                    CGPDFBox box,
                    CGRect rect,
                    int rotation,
                    bool preserveAspectRatio)
{
    CGAffineTransform m;
 
    m = CGPDFPageGetDrawingTransform (page, box, rect, rotation,// 1
                                    preserveAspectRato);
    CGContextSaveGState (context);// 2
    CGContextConcatCTM (context, m);// 3
    CGContextClipToRect (context,CGPDFPageGetBoxRect (page, box));// 4
    CGContextDrawPDFPage (context, page);// 5
    CGContextRestoreGState (context);// 6
}

Вот то, что делает код:

  1. Создает аффинное преобразование из параметров, предоставленных функции.

  2. Сохраняет состояние графики.

  3. Связывает CTM с аффинным преобразованием.

  4. Отсекает графический контекст к прямоугольнику, указанному box параметр. Функция CGPDFPageGetBoxRect получает ограничительную рамку страницы (носители, обрезка, выход за край, обрезка и художественные поля) связанный с константой, которую Вы предоставляете —kCGPDFMediaBox, kCGPDFCropBox, kCGPDFBleedBox, kCGPDFTrimBox, или kCGPDFArtBox.

  5. Рисует страницу PDF к преобразованному и отсеченному контексту.

  6. Восстанавливает состояние графики.

Создание файла PDF

Столь же просто создать файл PDF с помощью Кварца, 2D, как это должно нарисовать к любому графическому контексту. Вы указываете расположение для файла PDF, устанавливаете контекст графики PDF и используете ту же подпрограмму получения, которую Вы использовали бы для любого графического контекста. Функция MyCreatePDFFile, показанный в Перечислении 13-4, показывает все задачи, которые Ваш код выполняет для создания файла PDF. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Обратите внимание на то, что код формирует рисунок страниц PDF путем вызывания функций CGPDFContextBeginPage и CGPDFContextEndPage. Можно передать объект CFDictionary указать свойства страницы включая носители, обрезку, выход за край, обрезку и художественные поля. Для списка ключевых констант словаря и более подробного описания каждого, см. Ссылку CGPDFContext.

Перечисление 13-4  , Создающее файл PDF

void MyCreatePDFFile (CGRect pageRect, const char *filename)// 1
{
    CGContextRef pdfContext;
    CFStringRef path;
    CFURLRef url;
    CFDataRef boxData = NULL;
    CFMutableDictionaryRef myDictionary = NULL;
    CFMutableDictionaryRef pageDictionary = NULL;
 
    path = CFStringCreateWithCString (NULL, filename, // 2
                                kCFStringEncodingUTF8);
    url = CFURLCreateWithFileSystemPath (NULL, path, // 3
                     kCFURLPOSIXPathStyle, 0);
    CFRelease (path);
    myDictionary = CFDictionaryCreateMutable(NULL, 0,
                        &kCFTypeDictionaryKeyCallBacks,
                        &kCFTypeDictionaryValueCallBacks); // 4
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File"));
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name"));
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary); // 5
    CFRelease(myDictionary);
    CFRelease(url);
    pageDictionary = CFDictionaryCreateMutable(NULL, 0,
                        &kCFTypeDictionaryKeyCallBacks,
                        &kCFTypeDictionaryValueCallBacks); // 6
    boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof (CGRect));
    CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);
    CGPDFContextBeginPage (pdfContext, pageDictionary); // 7
    myDrawContent (pdfContext);// 8
    CGPDFContextEndPage (pdfContext);// 9
    CGContextRelease (pdfContext);// 10
    CFRelease(pageDictionary); // 11
    CFRelease(boxData);
}

Вот то, что делает код:

  1. Берет в качестве параметров прямоугольник, указывающий размер страницы PDF и строки, указывающей имя файла.

  2. Создает объект CFString из имени файла, переданного функции MyCreatePDFFile.

  3. Создает объект CFURL из объекта CFString.

  4. Создает пустой объект CFDictionary содержать метаданные. Следующие две строки добавляют заголовок и создателя. Можно добавить столько пар ключ/значение, сколько требуется использовать функцию CFDictionarySetValue. Для получения дополнительной информации о создании словарей см. Ссылку CFDictionary.

  5. Создает контекст графики PDF, передавая три параметра:

    • Объект CFURL, указывающий расположение для данных PDF.

    • Указатель на прямоугольник, определяющий размер по умолчанию и расположение страницы PDF. Источник прямоугольника обычно (0, 0). Кварц использует этот прямоугольник в качестве границ по умолчанию поля носителей страницы. Если Вы передаете NULL, Кварц использует размер страницы по умолчанию 8,5 на 11 дюймов (612 792 точками).

    • Объект CFDictionary, содержащий метаданные PDF. Передача NULL если у Вас нет метаданных для добавления.

      Можно использовать объект CFDictionary указать выходные опции намерения — поглощенный подтип, условие, идентификатор условия, имя реестра, целевой выходной профиль и человекочитаемая текстовая строка, содержащая дополнительную информацию или комментарии о намеченном целевом устройстве или производственном условии. Для получения дополнительной информации о выходных опциях намерения, см. Ссылку CGPDFContext.

  6. Создает объект CFDictionary содержать поля страницы для страницы PDF. Этот пример устанавливает поле носителей.

  7. Сигнализирует запуск страницы. Когда Вы используете графический контекст, поддерживающий многократные страницы (такие как PDF), Вы вызываете функцию CGPDFContextBeginPage вместе с CGPDFContextEndPage формировать рисунок границ страницы в выводе. Каждая страница должна быть заключена в скобки вызовами к CGPDFContextBeginPage и CGPDFContextEndPage. Кварц игнорирует все операции рисования, выполняемые вне границы страницы в основанном на странице контексте.

  8. Вызывает определенную с помощью приложения функцию для рисования содержания к контексту PDF. Вы предоставляете свою подпрограмму получения здесь.

  9. Сигнализирует конец страницы в основанном на странице графическом контексте.

  10. Выпускает контекст PDF.

  11. Выпускает словарь страницы.

Добавление ссылок

Можно добавить ссылки и привязки к контексту PDF, который Вы создаете. Кварц обеспечивает три функции, каждая из которых берет контекст графики PDF в качестве параметра, вместе с информацией о ссылках:

Защита содержания PDF

Для защиты содержания PDF существует много параметров безопасности, которые можно указать во вспомогательном словаре, который Вы передаете функции CGPDFContextCreate. Можно установить пароль владельца, пароль пользователя, и может ли PDF быть распечатан или скопирован включением следующих ключей во вспомогательном словаре:

Перечисление 14-4 (в следующей главе) показывает код, что документ в формате PDF проверок, чтобы видеть, заблокировано ли это и если это, пытается открыть документ с паролем.