2014-10-14 12 views
1

Я использую следующие настройки для создания PDF-документов с использованием IText (коммерческая лицензия, IText Версия: 5.4.5):Как использовать шрифты CJK в iText с XMLWorker на Android?

  • HTML Шаблоны создаются с jmustache, во время этого шага интернационализация выполняется, то есть документы могут содержат европейские языки, но также японский и китайский (также сочетание обоих, так как некоторые части текста могут остаться на английском языке)

  • окончательный HTML визуализируется с использованием XMLWorker так:

    final float marginPt = 28.35f;//1cm == 28.35pt 
    final Document document = new Document(PageSize.A4, marginPt, marginPt, marginPt, 0); 
    final PdfWriter writer = PdfWriter.getInstance(document, output); 
    //we write multiple documents to a ZipOutputStream, so we close the output stream later 
    writer.setCloseStream(false); 
    document.open(); 
    
    final HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 
    
    htmlContext.setImageProvider(new DynamicImageProvider(privateStorageFolder)); 
    
    final CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true); 
    
    final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, 
         new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer))); 
    final XMLWorker worker = new XMLWorker(pipeline, true); 
    final XMLParser p = new XMLParser(worker); 
    p.parse(new StringReader(input)); 
    
    document.close(); 
    

Все работает отлично для европейских символов (латинские буквы, умлауты, акценты и т. Д.). Однако для символов CJK (например, японский) итоговый текст в PDF не отображается, также нет сообщений, в которых мне предлагается установить дополнительные шрифты.

Я попытался добавить itext-asian.jar из extrajars-2.3.zip в андроид-библиотеки (http://sourceforge.net/projects/itext/files/extrajars/), но это не помогло.

Я ищу решение, чтобы правильно добавить CJK текст в результате PDF либо:

1.) Использование функции PDF CJK (т.е. конечный пользователь должен Читателя с CJK шрифтов, установленных)

2.) Вставьте шрифт в PDF, содержащий как латинские & CJK chars.

Решение 1 было бы предпочтительнее, но исправление с использованием подхода 2 также было бы высоко оценено.

Решение 1 должен работать с IText-asian.jar, но это не в моей установке (это, что не работает на версии Android IText по какой-то причине?)

Для решения 2 я должен был бы найти способ добавить несколько шрифтов XMLWorker в Android, так как большинство шрифтов, поддерживающих несколько сценариев расщепляются в разных файлах TTF (например, Google Noto шрифты https://www.google.com/get/noto/)

ответ

4

После того, как много проб и ошибок я пришел со следующим решением, которое работает для Android и настольных ПК:

1.) Добавьте соответствующий itext-asian.jar для IText версии на ваш путь к классам

2.) Реализовать обычай FontFactory так:

public class MyFontFactory extends FontFactoryImp { 
@Override 
public Font getFont(final String fontname, final String encoding, final boolean embedded, final float size, final int style, final BaseColor color, final boolean cached) { 
    if ("CJK".equals(fontname)){ 
     //these parameters were found out via trial-and-error, it is the asian font that looked best for our needs 
     //look into the itext-asian.jar for alternatives 
     return FontFactory.getFont("HeiseiKakuGo-W5","UniJIS-UCS2-H", BaseFont.NOT_EMBEDDED, size, style, color, cached);   
    } else { 
     return super.getFont(fontname, encoding, embedded, size, style, color, cached); 
    } 
} 

3.) Добавить фабрику шрифта в вашей XMLWorker цепи, как это:

final MyFontFactory fontFactory = new MyFontFactory(); 
//this sets the custom font factory for everything *but* the XMLWorker 
//(now that's amazing API design -.-) 
FontFactory.setFontImp(fontFactory); 
//this is the trick to get our fontFactory into the XmlWorker: 
//build the processing pipeline manually and inject the factory along the way 
final HtmlPipelineContext htmlContext = new HtmlPipelineContext(new CssAppliersImpl(fontFactory)); 
final CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true); 
final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer))); 
final XMLWorker worker = new XMLWorker(pipeline, true); 
final XMLParser p = new XMLParser(worker); 
p.parse(new StringReader(input)); 

Теперь вы можете использовать псевдо-шрифт «CJK» в вашем HTML/CSS, и вы получите азиатские символы без вложения всего шрифта:

* { 
    font-family:CJK; 
    font-size: 8pt; 
} 

Если вы хотите встроить шрифт, просто создайте шрифты по-разному в своем FontFactory, т. Е.как так:

return FontFactory.getFont("/system/fonts/DroidSans.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, style, color, cached); 

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

Смежные вопросы