CGPDFScannerPopString возвращает странный результат
Я наконец получил какой-то сканер PDF для работы. Он без проблем считывает функции обратного вызова, но когда я пытаюсь NSLog получить результат из CGPDFScannerPopString, я получаю такой результат:
ˆ ˛˝ # ˜˜˜ #˜' ˜˜˜ "˜ '˜˜ " ' ˜˜
Здесь нет ни одной строки...
Есть идеи, что это может быть? Это моя функция обратного вызова:
static void op_Tj (CGPDFScannerRef s, void *info)
{
CGPDFStringRef string;
if (!CGPDFScannerPopString(s, &string))
return;
NSLog(@"string: %@", (__bridge NSString *)CGPDFStringCopyTextString(string));
}
Уже спасибо!
Редактировать: пример PDF
1 ответ
Вы должны знать, что CGPDFStringRef не является строкой ASCII или чем-то похожим вообще. Ср http://developer.apple.com/library/mac/documentation/graphicsimaging/Reference/CGPDFString/Reference/reference.html --- это "серия байтов - целочисленные значения без знака в диапазоне от 0 до 255", которые имеют интерпретироваться в соответствии с последней ссылкой в формате PDF.
Ссылка на PDF, в свою очередь, скажет вам, что интерпретация байтов зависит от используемого шрифта, и хотя ASCII-подобные интерпретации распространены в европейских языках, они не являются обязательными, а в случае азиатских языков, где встраивание подмножества шрифтов является очень часто интерпретация может выглядеть случайной.
CGPDFStringCopyTextString пытается интерпретировать эти байты соответствующим образом, но не должно быть разумной интерпретации как обычной строки.
РЕДАКТИРОВАНИЕ ОБРАЗЦА образца PDF, предоставленного Роном, показало, что в случае этого образца действительно кодировка шрифта в объекте 3 0 (который является доминирующим на большинстве страниц документа) не является стандартной кодировкой, а вместо этого:
<</Type/Encoding
/Differences[0/.notdef/C/O/V/E/R/space/slash/H/L/F/underscore/W/B/five/eight/four
/zero/two/six/D/one/period/three/Z/I/N/G/U/S/T/colon/seven/A/M/P/Y
/plus/nine/X/hyphen/i/s/p/a/t/c/h/n/f/o/K/greater/equal/l/m/y/J/Q
/parenleft/parenright/comma/dollar/ampersand/d/r/v/b/e/u/w/k/g/x/bar
/quotesingle/asterisk/q/question/percent]
>>
Глядя на верхнюю часть первой страницы документа
COVER / HLF_CWEB_58408485 / 58408485 / 26DEC12 10.30.22Z
BRIEFING INCLUDES FOLLOWING FLIGHTS:
26DEC12 OR0337 EHAM0630 MUVR1710 PHOYE VSM+2/8 179
NEXT FLIGHTS OF AIRCRAFT:
26DEC12 OR0338 MUVR1830 MMUN1940 PHOYE VSM+2/8 213
26DEC12 OR0338 MMUN2105 EHAM0655 PHOYE GPT+2/7 263
27DEC12 OR0365 EHAM0900 TNCB1930 PHOYE BAH+1/8 272
27DEC12 OR0366 TNCB2030 TNCC2110 PHOYE BAH+1/8 250
27DEC12 OR0366 TNCC2250 EHAM0835 PHOYE ASD+1/8 199
эта кодировка, кажется, была создана путем раздачи следующего числа, начинающегося с единицы, для следующего требуемого глифа. Это, очевидно, приводит к очень индивидуалистической кодировке...
При этом объект шрифта включает в себя как запись /Encoding, так и запись /ToUnicode. Таким образом, если бы метод CGPDFStringCopyTextString получил здесь ссылку на шрифт и действительно попытался, он легко сможет правильно перевести эти байты в соответствующий текст. То, что он не достигает ничего приличного, кажется, указывает на то, что у него просто нет информации, для какого шрифта интерпретировать байты - я не думаю, что он не пытается...
Поэтому для точного извлечения текста вы должны интерпретировать байты в CGPDFStringRef самостоятельно, используя информацию о шрифте в потоке контента. Если вы не хотите делать это с нуля, вас может заинтересовать PDFKitten, платформа для извлечения данных из PDF-файлов в iOS. Хотя он еще не идеален (некоторые структуры шрифтов могут сбить его с толку), это хорошая отправная точка.