1. 程式人生 > >java 解析ttf字型檔案

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<Integer, String> fontProperties = new HashMap<Integer, String>(); 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<Integer, String> getFontProperties() { return fontProperties; } public String parseInner(String fileName) throws IOException { RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "r"); ArrayList<String> arrayList = new ArrayList<String>(); // 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 解析ttf字型檔案

要了解ttf字型檔案的原理更方便對程式碼的理解 package com.maoyan.movie.ttf.encode; public class PostTableHeader { public long format; public long italicA

Java隨機生成圖片驗證碼工具類/** * ttf字型檔案 * @author dsna * */ public class ImgFontByte { public Font g

/** * ttf字型檔案 * @author dsna * */ public class ImgFontByte { public Font getFont(int fontHeight){ try { Font baseFont = Font.createFo

TTF字型檔案裁剪(支援簡體中文,繁體中文TTF字型裁剪)

Google開源的字型提取神器——sfntly sfnttool,官網地址是:https://code.google.com/p/sfntly/ 可用於編輯、建立和使用字型檔案,主要針對OpenType,TrueType字型。 我在專案中,主要用於對漢字字型庫的裁剪(tt

三步教你iOS匯入.ttf字型檔案

1.首先info.plist中加入屬性Fonts provided by application,在item 0 處填寫匯入的ttf檔名 2.查出你匯入字型的font name     NSArray * fontArrays = [[NSArray alloc]

C++解析IconFont向量字型檔案ttf,以及無鋸齒顯示向量字型

一、下載向量字型檔案TTF 1、可以使用整合好的向量字型,如FontAwesome、openwebicons、IcoMoon-Free、typicons…… 只要去搜索關鍵字,找到對應的官網即可下載到,其中FontAwesome使用最為廣泛。 2、國內最大的IconFont

easypoi解析前端multipart檔案Java物件註解類

導包: <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>3.

java解析json檔案(省,市,區)

[{"code":"11","name":"北京市"},{"code":"12","name":"天津市"},{"code":"13","name":"河北省"},{"code":"14","name":"山西省"},{"code":"15","name":"內蒙古自治區"},{"code":"21","na

Java解析xml檔案的方式

import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; impo

手把手教你利用前端字型檔案(.ttf)混淆數字來阻止爬蟲爬取網站資料

先上一張效果圖 假如 正確的數字是321456 這時候使用者看到的就是對的 而爬蟲在抓取資料的時候 抓到得是123456 混淆了數字 怎麼實現呢? 工具: 1、FontCreator (中文漢化破解版) 當然英語好或者土豪的可以無視 2、做好的字型圖片 步

java解析Excel,使用InputStream讀取檔案

一、需要匯入的jar包 <dependency>             <groupId>org.apache.poi</groupId>             <artifactId>poi</ar

java 解析Dicom 檔案

專案使用中需要解析下載過來的Dicom檔案,然後根據固定的層級結構給檔案分目錄。以下是程式碼: /**  * <p>  * Title: GetDicomTag  * </p>  *   * <p>  * Description:解析DI

Java解析XML檔案的常用方法介紹

1 import java.io.IOException; 2 3 import javax.xml.parsers.DocumentBuilder; 4 import javax.xml.parsers.DocumentBuilderFactory; 5 import javax.x

Java解析xml檔案遇到“unknown protocol: c Nested exception: unknown protocol: c”問題的解決辦法

在寫畢設的時候在解析XML檔案的時候遇到的一個棘手的問題“unknown protocol: c Nested exception: unknown protocol: c”,翻閱了資料說是tomcat的安裝路徑不能有空格,要麼重新安裝tomcat,要麼以檔案的形式進行解析,

Java 解析CSV檔案

十一匆匆的就過去了,OneCoder過的也是有點恍惚。不知道都做了什麼,心卻有點散。做一篇翻譯,權當收收心,找找感覺吧。 在之前釋出的博文裡我提到,我最近正在把一些neo4j資料載入的程式碼從Ruby遷移到Java,因此作為這個過程中

Java眼中的XML---檔案讀取(二)SAX解析XML檔案

目錄 (一)SAX解析是什麼? (二)SAX解析和DOM解析的區別? (三)SAX方法解析XML的步驟 (四)SAX解析Java程式碼實現 (一)SAX解析是什麼? SAX(simple API for XML)是一種XML解析的

Java眼中的XML---檔案讀取(一)DOM解析XML檔案

目錄 (一)什麼是XML? (二)XML的作用 (三)DOM解析XML檔案的準備工作 (四)使用DOM解析XML檔案的屬性名和屬性值 (五)使用DOM解析XML檔案的節點名和節點值 (一)什麼是XML? XML 指可

Java解析yml檔案

程式碼 public class YmlUtil { /** * key:檔名索引 * value:配置檔案內容 */ private stat

Java解析魔獸爭霸3錄影W3G檔案(一):Header

魔獸爭霸3是一款非常著名的即時戰略遊戲。相信很多人都聽過sky、moon、grubby這些名字,還有塔魔infi、中國的鬼王ted、剛猛的fly、飄逸的th000等選手。遺憾的是WCG2013是魔獸爭霸3的最後一屆,我自己也去現場觀看了魔獸的總決賽。此外,還有DOTA、真三

Java引用外部字型即自定義字型檔案

      有時候我們在程式中,會使用到Java字型,但不是所有的字體系統中都會有,我們就可能會使用外部自定義字型,這樣在程式遷移部署中就會少些工作,最近在一個專案中使用到了自定義字型檔案,理順了,記之。 package cy.util; import java.awt.F

java解析由String型別拼接的XML檔案

首先要解析string型別的xml必須先要將其轉化成dom格式,然後再進行解析取值,如下是解析程式碼示例: package com.company; import org.dom4j.Document