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

Reply via email to