I tried to solve some problems when using iText to handle Asian font.
My suggested solution is listed as below. There are some tiny
modifications on original iText source code, and I have to distribute
the modified editon to my clients. Please let me know if there is
anything wrong for violating the license of iText.
( Modified source code can be downloaded from here:
http://fengdh.googlepages.com/iTextenhancementsource.zip
which are used only to show my solution, licence declaration and
comments are still missed. BTW, i'm using iText-1.4.5 release.)
[Problem 1]
Description:
CHOOSE embedment for TrueTypeFontUnicode or not
When BaseFont.createFont(...) creates a TrueTypeFontUnicode object,
it always sets "embedded=true" for the object.
TrueTypeFontUnicode#writeFont(...) always assumes "embedded=true" and
embedded font data in all cases, too.
But when devlopping an application for users inside a local
company, whose PCs are surely pre-installed with TrueType fonts of
local language, why should we embedded those true type fonts?
especially considering extra file size for embedded font data.
My Solution
Here is the what I modified for TrueTypeFontUnicode:
void writeFont(PdfWriter writer, PdfIndirectReference ref, Object
params[]) throws DocumentException, IOException {
HashMap longTag = (HashMap)params[0];
// <<< BEGIN: added by FeNG Dihai([EMAIL PROTECTED]), Oct. 12, 2006
if (embedded) addRangeUni(longTag, true, subset);
// >>> End
Object metrics[] = longTag.values().toArray();
Arrays.sort(metrics, this);
PdfIndirectReference ind_font = null;
PdfObject pobj = null;
PdfIndirectObject obj = null;
// sivan: cff
// <<< BEGIN: added by FeNG Dihai([EMAIL PROTECTED]), Sep. 28, 2006
if (embedded){
// >>> END ::: should indent following if-block
if (cff) {
// nothing changed inside if-block
... ...
}
// <<< BEGIN: added by FeNG Dihai([EMAIL PROTECTED]), Sep. 28, 2006
}
// >>> END
String subsetPrefix = "";
... ...
}
I didnot touch BaseFont, but use Java Reflection API to change
value of TrueTypeFontUnicode#embeded field.
[Problem 2]
Description:
PROCESS external characters ( or EUDC font transparently)
This problem is also discussed in mailing list archive before, see
http://www.mail-archive.com/[email protected]/msg05984.html
http://article.gmane.org/gmane.comp.java.lib.itext.general/26496
My Solution:
First, I append one classe and one interface to handle dirty work.
IEudcFontRegistry: Mapping normal BaseFont to an EUDC BaseFont,
define it in your own way
EnhancedPdfWriter: Holding an IEudcFontRegistry implemented
object. When called from PdfContentByte#showText(String text) ,
#processEudc(PdfContentByte contentByte, String text,
PdfContentByte.GraphicState state) will split text into several parts
if containing EUDC characters (\uE000-\uF8FF) , then render each parts
using correct font.
Next, a little change of PdfContentByte and TrueTypeFontUnicode.
*** PdfContentByte ***
public void showText(String text) {
// <<< BEGIN: modified by FeNG dihai([EMAIL PROTECTED]), Nov. 1, 2006
// If writer can handle external font, let it do
if (writer instanceof EnhancedPdfWriter){
if (((EnhancedPdfWriter)writer).isSupportEUDC()){
if (((EnhancedPdfWriter)writer).processEudc(this, text, state)){
return;
}
}
}
// Otherwise process as normaly
showTextSimple(text);
// >>> END
}
// <<< BEGIN: added by FeNG dihai([EMAIL PROTECTED]), Nov. 1, 2006
void showTextSimple(String text) {
showText2(text);
content.append("Tj").append_i(separator);
}
// >>> END
*** TrueTypeFontUnicode ***
int getRawWidth(int c, String name) {
// <<< BEGIN: added by Feng Dihai([EMAIL PROTECTED]), Nov. 1, 2006
if (c<0xE000){
// >>> END
HashMap map = null;
if (name == null || cmap31 == null)
map = cmap10;
else
map = cmap31;
if (map == null)
return 0;
int metric[] = (int[])map.get(new Integer(c));
if (metric == null)
return 0;
return metric[1];
// <<< BEGIN: added by Feng Dihai([EMAIL PROTECTED]), Nov. 1, 2006
} else {
return 1000;
}
// >>> END
}
Just call like below, EUDC font will be handled transparently.
Document document = new Document();
EnhancedPdfWriter writer =
EnhancedPdfWriter.getInstance(document, output, new
MyEudcFontRegistry());
Conclusion:
Text output through PdfContentByte#showText(String) is ok, but i
don't know how to improve PdfContentByte#showText(PdfTextArray). In
my case, it's not a problem.
Another problem, bold style of EUDC character maybe not handled
well (italic is ok).
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions