Получить CGPDFDocumentRef название документа

Можно ли получить название документа из CGPDFDocumentRef

1 ответ

Решение

Под "названием документа" вы подразумеваете имя файла или название документа?

Если документ "title" включен в метаданные, его можно получить следующим образом:

    char *titleKey = "Title";
    CGPDFStringRef titleStringRef;

    CGPDFDictionaryRef info = CGPDFDocumentGetInfo(myDocumentRef);
    CGPDFDictionaryGetString(info, titleKey, &titleStringRef);
    const unsigned char *titleCstring = CGPDFStringGetBytePtr(titleStringRef);

    printf("title: %s", titleCstring);

Другие ключи перечислены в разделе 10.2 спецификации PDF 1.7: Справочные архивы Adobe PDF

Вот как это сделать в Swift 5:

extension CGPDFDocument {
    var title: String? {
        guard let infoDict = self.info else {
            return nil
        }
        let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!
        var titleStringRef: CGPDFStringRef?
        CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
        if let stringRef = titleStringRef,
           let cTitle = CGPDFStringGetBytePtr(stringRef) {
            let length = CGPDFStringGetLength(stringRef)
            let encoding = CFStringBuiltInEncodings.UTF8.rawValue
            let allocator = kCFAllocatorDefault
            let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)
            if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
                return title as String
            }
        }
        return nil
    }
}

И вот мое понимание того, как это работает:

Сначала мы проверяем, прикреплен ли к PDF-документу информационный словарь. Информационный словарь PDF может содержать метаданные, включая заголовок документа.*

        guard let infoDict = self.info else {
            return nil
        }

Если это так, мы пытаемся получить заголовок из этого словаря, используя CGPDFDictionaryAPI. Этот API принимает только типы C, поэтому нам нужно выполнить некоторые преобразования, чтобы получить Swift String ”Title” представлен в виде строки C.

        let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!

В CGPDFDictionaryGetString вызов принимает указатель на CGPDFStringRef?переменная в качестве третьего аргумента. Чтобы преобразовать ссылку Swift в указатель, мы добавляем к ней &. Результат поиска в словаре может быть нулевым, если заголовок не был указан при создании PDF.

        var titleStringRef: CGPDFStringRef?
        CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
        if let stringRef = titleStringRef,
           let cTitle = CGPDFStringGetBytePtr(stringRef) {

На данный момент мы знаем, что есть строка заголовка, но она еще не входит в используемую строку Swift. Чтобы прочитать строку C из памяти (с CFStringCreateWithBytes), нам нужно знать, где он начинается (указатель) и через сколько байтов следует прекратить чтение (длина). Кроме того, мы указываем, что строка должна читаться с использованием кодировки UTF-8 и использовать макет памяти по умолчанию. Последний элемент, который нам нужен, - это правильно напечатанная ссылка на строку C. Тип строки C - это указатель на char, который представлен как UInt8в памяти. Итак, мы получаем Optional<UnsafePointer<UInt8>>.

            let length = CGPDFStringGetLength(stringRef)
            let encoding = CFStringBuiltInEncodings.UTF8.rawValue
            let allocator = kCFAllocatorDefault
            let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)

Собрав эту информацию, пришло время получить Swift String из строки C. К счастью, CFString бесплатно подключена к Swift String, что означает, что мы можем использовать CFStringCreateWithBytes вызовите и просто приведите результат к String.

            if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
                return title as String
            }
        }
        return nil

* Ключи для значений в этом словаре можно найти в Справочнике Adobe PDF, ТАБЛИЦА 10.2 "Записи в информационном словаре документа" на странице 844.

Другие вопросы по тегам