Package org.jpedal.fonts.tt.conversion

Source Code of org.jpedal.fonts.tt.conversion.PS2OTFFontWriter

/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info:  http://www.jpedal.org
*
* (C) Copyright 2011, IDRsolutions and Contributors.
*
*   This file is part of JPedal
*
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


  *
  * ---------------

  * TTFontWriter.java
  * ---------------
  * (C) Copyright 2011, by IDRsolutions and Contributors.
  *
  *
  * --------------------------
*/
package org.jpedal.fonts.tt.conversion;

import org.jpedal.fonts.PdfFont;
import org.jpedal.fonts.TrueType;
import org.jpedal.fonts.Type1C;
import org.jpedal.fonts.glyph.PdfGlyph;
import org.jpedal.fonts.glyph.PdfJavaGlyphs;
import org.jpedal.fonts.glyph.T1Glyphs;
import org.jpedal.fonts.tt.TTGlyphs;

import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class PS2OTFFontWriter extends FontWriter{

    byte[] cff;

    byte[] cmap=null;

    PdfFont pdfFont,orginalFont;
    PdfJavaGlyphs glyphs;

    int minCharCode;
    int maxCharCode;

    //Glyph Metrics
    private int xAvgCharWidth=0;
    private double xMaxExtent= Double.MIN_VALUE;
    private double minRightSideBearing = Double.MAX_VALUE;
    private double minLeftSideBearing = Double.MAX_VALUE;
    private double advanceWidthMax = Double.MIN_VALUE;
    private double lowestDescender = -1;
    private double highestAscender = 1;
    private float[] fontBBox = new float[4];
    private int[] advanceWidths;
    private HashMap<String,Integer> widthMap;


    public PS2OTFFontWriter(PdfFont orginalFont,byte[] rawFontData, String fileType, HashMap<String,Integer> widths) throws Exception {

        boolean is1C=fileType.equals("cff");

        name=orginalFont.getBaseFontName();

        this.widthMap = widths;

        //adjust for TT or Postscript
        String typeSpecificTable="CFF ";

        if(fileType.equals("ttf")){

            //read the data into our T1/t1c object so we can then parse
            glyphs=new TTGlyphs();
            pdfFont=new TrueType(rawFontData,glyphs);

            typeSpecificTable="glyf";
        }else{
            /**
             * for the moment we reread with diff paramters to extract other data
             */
            //read the data into our T1/t1c object so we can then parse
            glyphs=new T1Glyphs(false,is1C);

            pdfFont=new Type1C(rawFontData,glyphs,is1C);

        }

        glyphCount=glyphs.getGlyphCount();

        this.orginalFont=orginalFont;
        this.cff=rawFontData;

        /**
         * required fonts (CMAP must be before OS2 ans it does a precalculation for it)
         */
        final String[] tablesUsed=new String[]{typeSpecificTable,
//                "FFTM",
//                "GDEF",
                "OS/2",
                "cmap",
                "head",
                "hhea",
                "hmtx",
                "maxp",
                "name",
                "post"
        };
     
        tableList=new ArrayList();

        numTables=tablesUsed.length;

        int floor = 1;
        while (floor*2 <= numTables)
            floor *= 2;

        searchRange = floor * 16;

        entrySelector = 0;
        while (Math.pow(2,entrySelector) < floor)
            entrySelector++;

        rangeShift = (numTables*16) - searchRange;

        tableList.addAll(Arrays.asList(tablesUsed).subList(0, numTables));

        //location of tables
        checksums=new int[tableCount][1];
        tables=new int[tableCount][1];
        tableLength =new int[tableCount][1];


        type=OPENTYPE;
       
       
        //@sam - used to hack in font
//        if(name.contains("KTBBOD+HermesFB-Bold")){
////        if(name.contains("ZapfEchos")){
//
//            try{
//                File file=new File("C:/Users/Sam/Downloads/HermesFB-Regular.otf");
////                File file=new File("C:/Users/Sam/Downloads/zapfechosWorks.otf");
//                int len=(int)file.length();
//                byte[] data=new byte[len];
//                FileInputStream fis=new FileInputStream(file);
//                fis.read(data);
//                fis.close();
//                FontFile2 f=new FontFile2(data,false);
//
//
//                for(int l=0;l<numTables;l++){
//
//                    String tag= (String) tableList.get(l);
//
//                    //read table value (including for head which is done differently at end)
//                    int id= getTableID(tag);
//
//                    if(id!=-1){
//                        this.tables[id][currentFontID]=f.getTableStart(id);
//                    }
//                }
//
//            }catch(Exception e){
//                e.printStackTrace();
//            }
//        }
    }

    void readTables() {

        //Fetch advance widths
        int totalWidth=0;
        advanceWidths = new int[glyphCount];
        if (widthMap != null) {
            for (int i=0; i < glyphCount; i++) {
                Integer w = widthMap.get(glyphs.getIndexForCharString(i+1));
                if (w != null)
                    advanceWidths[i] = w;
                else {
                    w = widthMap.get("JPedalDefaultWidth");
                    if (w != null)
                        advanceWidths[i] = w;
                }
                advanceWidthMax = advanceWidthMax > advanceWidths[i] ? advanceWidthMax : advanceWidths[i];
                totalWidth += advanceWidths[i];
            }
        }

        //Store average width
        if(glyphCount>0)
            xAvgCharWidth= (int) ((double)totalWidth/(double)glyphCount);

        //Collect glyph metrics
        double maxX = Double.MIN_VALUE;
        for (int i=0; i<glyphCount && i<256; i++) {
            PdfGlyph glyph = glyphs.getEmbeddedGlyph(new org.jpedal.fonts.glyph.T1GlyphFactory(),
                                                     pdfFont.getMappedChar(i, false),
                                                     new float[][]{{1,0},{0,1}},
                                                     i,
                                                     pdfFont.getGlyphValue(i),
                                                     pdfFont.getWidth(i),
                                                     pdfFont.getMappedChar(i, false));

            if (glyph != null && glyph.getShape() != null) {

                Rectangle2D area = glyph.getShape().getBounds2D();

                double lsb = area.getMinX();
                double rsb = advanceWidths[i]-area.getMaxX();
                double extent = area.getMinX() + area.getWidth();

                minLeftSideBearing = minLeftSideBearing < lsb ? minLeftSideBearing : lsb;
                minRightSideBearing = minRightSideBearing < rsb ? minRightSideBearing : rsb;
                xMaxExtent = xMaxExtent > extent ? xMaxExtent : extent;
                lowestDescender = lowestDescender < area.getMinY() ? lowestDescender : area.getMinY();
                highestAscender = highestAscender > area.getMaxY() ? highestAscender : area.getMaxY();
                maxX = maxX > area.getMaxX() ? maxX : area.getMaxX();
            }
        }

        fontBBox = pdfFont.FontBBox;

        minLeftSideBearing = minLeftSideBearing < fontBBox[0] ? minLeftSideBearing : fontBBox[0];
        lowestDescender = lowestDescender < fontBBox[1] ? lowestDescender : fontBBox[1];
        maxX = maxX > fontBBox[2] ? maxX : fontBBox[2];
        highestAscender = highestAscender > fontBBox[3] ? highestAscender : fontBBox[3];

        fontBBox = new float[]{(float)minLeftSideBearing, (float)lowestDescender, (float)maxX, (float)highestAscender};
    }

    public byte[] getTableBytes(int tableID){

        byte[] fontData=new byte[0];

        FontTableWriter tableWriter=null;

        switch(tableID){

            case CFF:
                if (pdfFont.is1C()) {
                    //fix bad commands in CFF data
                    fontData = (new CFFFixer(cff)).getBytes();
                } else {
                    //convert type 1 to 1c
                    tableWriter=new CFFWriter(glyphs, name);

//                    try {
//                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//                        BufferedReader reader = new BufferedReader(new FileReader(new File("C:\\Users\\Sam\\Desktop\\FontForgeAmerican.txt")));
//
//                        while (reader.ready()) {
//                            String line = reader.readLine();
//                            String first = line.split("\t")[0];
//                            first = first.replaceAll("[^01]", "");
//                            if (first.length() == 8) {
//                                int mag = 128;
//                                byte val = 0;
//                                for (int i=0; i<8; i++) {
//                                    boolean is1 = first.charAt(i) == '1';
//                                    if (is1)
//                                        val += mag;
//
//                                    mag = mag / 2;
//                                }
//
//                                bos.write(val);
//                                fontData = bos.toByteArray();
//                            }
//                        }
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
                }
                break;

            case HEAD:
                tableWriter=new HeadWriter(fontBBox);
                break;

            case CMAP :
//                if(name.contains("BKJFHK+HermesFB-Regular")){
                tableWriter=new CMAPWriter(pdfFont,glyphs);
                minCharCode=tableWriter.getIntValue(FontTableWriter.MIN_CHAR_CODE);
                maxCharCode=tableWriter.getIntValue(FontTableWriter.MAX_CHAR_CODE);
//                }
                break;

            case HHEA:
                tableWriter=new HheaWriter(glyphs, xMaxExtent, minRightSideBearing, minLeftSideBearing, advanceWidthMax, lowestDescender, highestAscender);
                break;

            case HMTX:
                tableWriter=new HmtxWriter(pdfFont,glyphs,advanceWidths);
                break;

            case OS2 :
                tableWriter=new OS2Writer(glyphs, xAvgCharWidth, minCharCode,  maxCharCode, fontBBox);

                break;

            case MAXP :
                tableWriter=new MAXPWriter(glyphs);
                break;

            case NAME:
                tableWriter=new NameWriter(pdfFont, glyphs, name);
                break;

            case POST:
                tableWriter=new PostWriter();
                break;

            default:

//                //@sam - code to hack table from manulaly converted
//                // font (setup fro Zapf)
//                if(name.contains("BKJFHK+HermesFB-Regular")){
////                if(name.contains("apf")){
//
//                        try {
//                File file=new File("C:/Users/Sam/Downloads/BKJFHK+HermesFB-Regular.otf");
////                File file=new File("C:/Users/Sam/Downloads/zapfechosWorks.otf");
//                        int len=(int)file.length();
//                        byte[] data=new byte[len];
//                        FileInputStream fis=new FileInputStream(file);
//                        fis.read(data);
//                        fis.close();
//                        FontFile2 f=new FontFile2(data,false);
//                        f.selectTable(tableID);
//                        fontData=f.getTableBytes(tableID);
//                    }catch(Exception e){
//                        e.printStackTrace();
//                    }
//                }

                break;
        }

        if(tableWriter!=null){
            try {
                fontData=tableWriter.writeTable();  
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //@sam - code to print out bytes in either hacked table or our version
//        if(tableID==CFF && name.contains("AmericanTypewriter")){
////        if(tableID==POST && name.contains("apf")){
//            System.out.println("--name--"+name);
//            for(int aa=0;aa<fontData.length;aa++) {
//                //Old printout
////                System.out.println(aa+" "+fontData[aa]);
//                String bin = Integer.toBinaryString(fontData[aa]);
//                int addZeros = 8 - bin.length();
//                for (int i=0; i<addZeros; i++)
//                    System.out.print("0");
//                if (addZeros < 0)
//                    bin = bin.substring(-addZeros);
//                int val = fontData[aa];
//                if (val < 0)
//                    val += 256;
//                System.out.println(bin+"\t"+val);
//            }
//
//        }

        return fontData;
    }
}
TOP

Related Classes of org.jpedal.fonts.tt.conversion.PS2OTFFontWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.