java 解析ttf字体文件

要了解ttf字体文件的原理更方便对代码的理解
package com.maoyan.movie.ttf.encode;

public class PostTableHeader {
	
	public long format; 
	public long italicAngle;
	public int  underlinePosition;
	public int  underlineThichness;
	public long  isFixedPitch;
	public long  minMemType42;
	public long  maxMemType42;
	public long  minMemType1;
	public long  maxMemType1;

}



package com.maoyan.movie.ttf.encode;

public class TableDirectory {
    
    public String name; //table name

     public  int checkSum; //Check sum

     public int offset; //Offset from beginning of file

     public int length; //length of the table in bytes
}



package com.maoyan.movie.ttf.encode;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 作者 :朱海川 [email protected]
 * @version 创建时间:2016年10月26日 下午10:29:55 类说明
 */
public class TTFCodeParse {

    public TTFCodeParse() {
        // TODO Auto-generated constructor stub
    }

    public static int COPYRIGHT = 0;

    public static int FAMILY_NAME = 1;

    public static int FONT_SUBFAMILY_NAME = 2;

    public static int UNIQUE_FONT_IDENTIFIER = 3;

    public static int FULL_FONT_NAME = 4;

    public static int VERSION = 5;

    public static int POSTSCRIPT_NAME = 6;

    public static int TRADEMARK = 7;

    public static int MANUFACTURER = 8;

    public static int DESIGNER = 9;

    public static int DESCRIPTION = 10;

    public static int URL_VENDOR = 11;

    public static int URL_DESIGNER = 12;

    public static int LICENSE_DESCRIPTION = 13;

    public static int LICENSE_INFO_URL = 14;

    public String uni = "";

    private Map fontProperties = new HashMap();

    public String getFontName() {

        if (fontProperties.containsKey(FULL_FONT_NAME)) {

            return fontProperties.get(FULL_FONT_NAME);

        } else if (fontProperties.containsKey(FAMILY_NAME)) {

            return fontProperties.get(FAMILY_NAME);

        } else {

            return null;

        }

    }

    public String getFontPropertie(int nameID) {

        if (fontProperties.containsKey(nameID)) {

            return fontProperties.get(nameID);

        } else {
            
            return null;
        }

    }

    public Map getFontProperties() {
        
        return fontProperties;
        
    }

    public String parseInner(String fileName) throws IOException {

        RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "r");

        ArrayList arrayList = new ArrayList();

        // Attribute attribute = new Attribute();

        int majorVersion = randomAccessFile.readShort();

        int minorVersion = randomAccessFile.readShort();

        int numOfTables = randomAccessFile.readShort();

        // if (majorVersion != 1 || minorVersion != 0) {
        // return ;
        // }

        // jump to TableDirectory struct

        randomAccessFile.seek(12);

        boolean found = false;

        byte[] buff = new byte[4];

        TableDirectory tableDirectory = new TableDirectory();

        for (int i = 0; i < numOfTables; i++) {

            randomAccessFile.read(buff);

            tableDirectory.name = new String(buff);

            tableDirectory.checkSum = randomAccessFile.readInt();

            tableDirectory.offset = randomAccessFile.readInt();

            tableDirectory.length = randomAccessFile.readInt();

            // System.out.println("*******************" + tableDirectory.name);

            if ("post".equalsIgnoreCase(tableDirectory.name)) {

                found = true;
                // System.out.println("talbe: post found!");
                // break;

            } else if (tableDirectory.name == null || tableDirectory.name.length() == 0) {

                break;

            }

        }

        // not found table of name
        //
        // if (!found) {
        // return;
        // }

        randomAccessFile.seek(tableDirectory.offset);

        if (found) {
            
            PostTableHeader postTableHeader = new PostTableHeader();
            postTableHeader.format = ttfGetFixed(randomAccessFile);
            postTableHeader.italicAngle = ttfGetFixed(randomAccessFile);

            postTableHeader.underlinePosition = ttfGetSHORT(randomAccessFile);
            postTableHeader.underlineThichness = ttfGetSHORT(randomAccessFile);

            postTableHeader.isFixedPitch = ttfGetLONG(randomAccessFile);
            postTableHeader.minMemType42 = ttfGetLONG(randomAccessFile);
            postTableHeader.maxMemType42 = ttfGetLONG(randomAccessFile);
            postTableHeader.minMemType1 = ttfGetLONG(randomAccessFile);
            postTableHeader.maxMemType1 = ttfGetLONG(randomAccessFile);

            if (postTableHeader.format == 0x00020000) {

                int numGlyphs = ttfGetSHORT(randomAccessFile);
                
                int[] glyphNameIndex = new int[numGlyphs];

                for (int i = 0; i < numGlyphs; i++) {
                    
                    glyphNameIndex[i] = ttfGetSHORT(randomAccessFile);
                    
                }

                // long pos = randomAccessFile.getFilePointer();
                // randomAccessFile.seek(pos + 1);
                
                randomAccessFile.skipBytes(1);
                
                for (int i = 0; i < numGlyphs; i++) {
                    
                    if (glyphNameIndex[i] <= 257) {
                        
                        /* do nothing for standard Mac glyf name */
                    } else if (glyphNameIndex[i] <= 32767) {
                        /*
                         * non-standard glyf name is stored as a Pascal string
                         * in the file i.e. the first byte is the length of the
                         * string but the string is not ended with a null
                         * character
                         */

                        int len = ttfGetCHAR(randomAccessFile);
                        byte[] bf = new byte[len];
                        
                        if (len > 0)
                            randomAccessFile.read(bf);

                        String uniCoding = new String(bf, Charset.forName("utf-8"));
                        
                        arrayList.add(uniCoding);

                    }

                }

            }

        }
        // arrayList.toString().substring(4, 92).replaceAll(" ", "");
        // System.out.println(arrayList.toString().substring(4, 92).replaceAll("
        // ", ""));
        
        String maoyanencode = arrayList.toString().substring(4, 92).replaceAll(" ", "").
                replaceAll("uni", "")
                .toLowerCase();
        
        return maoyanencode;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return fontProperties.toString();
    }

    public static int ttfGetCHAR(RandomAccessFile file) {

        int cc = 0;

        try {
            
            cc = file.readUnsignedByte();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return cc;
    }

    public static int ttfGetSHORT(RandomAccessFile file) {

        int cc = 0;
        
        try {
            cc = file.readUnsignedByte() << 8;
            cc |= file.readUnsignedByte();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return (int) cc;
    }

    public static long ttfGetLONG(RandomAccessFile file) {

        int cc = 0;
        
        try {
            cc = file.readUnsignedByte() << 24;
            cc |= file.readUnsignedByte() << 16;
            cc |= file.readUnsignedByte() << 8;
            cc |= file.readUnsignedByte();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return (long) cc;
    }

    public static long ttfGetFixed(RandomAccessFile file) {

        return (long) ttfGetLONG(file);
    }

    public void FixedSplit(long f, long b[]) {

        b[0] = f & 0xff00;
        b[1] = f >> 16;
    }


}



package com.maoyan.movie.ttf.encode;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

/**
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2016年11月10日 下午11:01:39 类说明 :
 */
public class DownParseTTF {

    //解析ttf字体文件
    public String parseTTF(String htmlsource) {

        TTFCodeParse ttfCodeParse = new TTFCodeParse();
        
        //解析电影的源码html文件
        Document document = Jsoup.parse(htmlsource);

        Elements headStyle = document.select("head style");

        Document headStyleDocu = Jsoup.parse(headStyle.html());
        String ttfFigureCode = "";
        
        if (!headStyleDocu.body().text().contains(".ttf")) {
            return "没有ttf文件解析";
        }
        else {
            //获取ttf字体文件下载链接
            String ttfURL = "http://" + headStyleDocu.body().text().substring(244, 310);

            //获取ttf字体文件的名称
            String ttfName = ttfURL.substring(33, ttfURL.length());

            //本地存放地址
            String savePath = "F:\\ttf\\";

            

            try {
                URL url = new URL(ttfURL);

                // 获取url链接反应
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                // 设置超时间为10秒
                conn.setConnectTimeout(10 * 1000);

                // 防止屏蔽程序抓取而返回403错误
                conn.setRequestProperty("User-Agent",
                        "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0");

                // 得到输入流
                InputStream inputStream = conn.getInputStream();

                // 获取自己数组
                byte[] getData = readInputStream(inputStream);

                // 文件保存位置
                File saveDir = new File(savePath);

                if (!saveDir.exists()) {
                    saveDir.mkdir();
                }

                File file = new File(saveDir + File.separator + ttfName);
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(getData);

                //得到ttf字的编码,猫眼电影中的ttf文件是对0到9的解析编码,找到其一一对应的顺序
                ttfFigureCode = ttfCodeParse.parseInner(file.toString());

                if (fos != null) {
                    fos.close();
                }

                if (inputStream != null) {
                    inputStream.close();
                }

                // return code;
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return ttfFigureCode;
        }

//        return ttfFigureCode;
    }
    
    
    public static byte[] readInputStream(InputStream inputStream) throws IOException {

        byte[] buffer = new byte[1024];

        int len = 0;

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        while ((len = inputStream.read(buffer)) != -1) {

            bos.write(buffer, 0, len);

        }

        bos.close();

        return bos.toByteArray();
    }

}





 



你可能感兴趣的:(java爬虫)