最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java全面解析ttf字體的信息

 更新時間:2025年01月14日 15:05:00   作者:念九_ysl  
文章介紹了Java如何解析TTF字體文件,提取字體的基本信息、版本信息、版權(quán)和許可證、字符映射以及各種表格信息,通過代碼解析,可以獲取字體的詳細描述和度量數(shù)據(jù)

Java解析ttf字體的信息

TTF(TrueType Font)文件格式復(fù)雜,包含了多個表格,每個表格存儲了不同的字體信息。

前提是ttf要包含這些表格信息。

通過代碼解析 TTF 文件,你可以獲取以下內(nèi)容:

public static final int COPYRIGHT = 0; // 版權(quán)信息
public static final int FAMILY_NAME = 1; // 字體家族名稱
public static final int FONT_SUBFAMILY_NAME = 2; // 字體子家族名稱(例如:粗體、斜體等)
public static final int UNIQUE_FONT_IDENTIFIER = 3; // 唯一字體標(biāo)識符
public static final int FULL_FONT_NAME = 4; // 完整字體名稱
public static final int VERSION = 5; // 字體版本信息
public static final int POSTSCRIPT_NAME = 6; // PostScript名稱
public static final int TRADEMARK = 7; // 商標(biāo)信息
public static final int MANUFACTURER = 8; // 制造商信息
public static final int DESIGNER = 9; // 設(shè)計師信息
public static final int DESCRIPTION = 10; // 字體描述
public static final int URL_VENDOR = 11; // 制造商的URL
public static final int URL_DESIGNER = 12; // 設(shè)計師的URL
public static final int LICENSE_DESCRIPTION = 13; // 授權(quán)描述
public static final int LICENSE_INFO_URL = 14; // 授權(quán)信息的URL  

以下是數(shù)據(jù)示例:

{0=Digitized data copyright ? 2007, Google Corporation., 1=Droid Sans
Mono, 2=Regular, 3=Ascender - Droid Sans Mono, 4=Droid Sans Mono,
5=Version 1.00 build 113, 6=DroidSansMono, 7=Droid is a trademark of
Google and may be registered in certain jurisdictions., 8=Ascender
Corporation, 10=Droid Sans is a humanist sans serif typeface
designed for user interfaces and electronic communication.,
11=http://www.ascendercorp.com/,
12=http://www.ascendercorp.com/typedesigners.html, 13=Licensed under
the Apache License, Version 2.0,
14=http://www.apache.org/licenses/LICENSE-2.0, 18=?潩搠卡湳?潮?}

{0=Copyright 上海字魂網(wǎng)絡(luò)科技有限公司, 1=字魂再見怪獸體(商用需授權(quán)), 2=Regular, 3=ZHZJGST_T,
4=字魂再見怪獸體(商用需授權(quán)), 5=Version 2.00, 6=ZHZJGST_T, 7=字魂 ?,
8=上海字魂網(wǎng)絡(luò)科技有限公司, 9=字魂網(wǎng), 10=字魂聯(lián)名系列, 11=https://izihun.com/,
12=https://izihun.com/, 13=商用需購買授權(quán),請訪問: https://izihun.com/,
16=字魂再見怪獸體(商用需授權(quán)), 17=常規(guī)體} {0=Digitized data copyright ? 2007,
Google Corporation., 1=Droid Sans Mono, 2=Regular, 3=Ascender -
Droid Sans Mono, 4=Droid Sans Mono, 5=Version 1.00 build 113,
6=DroidSansMono, 7=Droid is a trademark of Google and may be
registered in certain jurisdictions., 8=Ascender Corporation,
10=Droid Sans is a humanist sans serif typeface designed for user
interfaces and electronic communication.,
11=http://www.ascendercorp.com/,
12=http://www.ascendercorp.com/typedesigners.html, 13=Licensed under
the Apache License, Version 2.0,
14=http://www.apache.org/licenses/LICENSE-2.0, 18=?潩搠卡湳?潮?}

1.基本信息:

  • 字體名稱:包括全名、家族名、子家族名等。
  • 版本信息:字體的版本號。
  • 版權(quán)和許可證:版權(quán)聲明、許可描述等信息。

2.字符映射:

  • 字形表(glyf):包含了每個字符的實際輪廓(即矢量數(shù)據(jù))。
  • 字形數(shù)據(jù):定義了每個字符的圖形表示方式。

3.表格信息:

  • 表目錄(table directory):包含所有表格的名稱、偏移量和長度。
  • 字體頭(head):字體的基本信息,如字體的最小和最大字形的邊界框。

4.度量信息:

  • 水平度量表(hmtx):包含每個字形的水平度量數(shù)據(jù)。
  • 垂直度量表(vmtx):包含每個字形的垂直度量數(shù)據(jù)。

5.表格詳情:

  • 名稱表(name):存儲字體的各種名稱信息,如字體的全名、家族名、子家族名等。
  • 字符映射表(cmap):定義了字符代碼與字形索引之間的映射關(guān)系。
  • 頭表(head):提供了字體的一些基本信息,如字體的版本、創(chuàng)建時間等。
  • 控制點表(loca):提供字形輪廓數(shù)據(jù)的偏移量。

6.額外的表格:

  • 垂直和水平指標(biāo)表(hhea 和 vhea):包含了字體的水平和垂直基線指標(biāo)。
  • 輪廓圖像表(glyf):存儲了每個字形的實際輪廓。

代碼解析示例

1.建立工具類

package com.example.psd.font;

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

/**
 * TTF 字體文件解析器
 */
public class TTFParser {

    public static final int COPYRIGHT = 0;
    public static final int FAMILY_NAME = 1;
    public static final int FONT_SUBFAMILY_NAME = 2;
    public static final int UNIQUE_FONT_IDENTIFIER = 3;
    public static final int FULL_FONT_NAME = 4;
    public static final int VERSION = 5;
    public static final int POSTSCRIPT_NAME = 6;
    public static final int TRADEMARK = 7;
    public static final int MANUFACTURER = 8;
    public static final int DESIGNER = 9;
    public static final int DESCRIPTION = 10;
    public static final int URL_VENDOR = 11;
    public static final int URL_DESIGNER = 12;
    public static final int LICENSE_DESCRIPTION = 13;
    public static final int LICENSE_INFO_URL = 14;

    private final Map<Integer, String> fontProperties = new HashMap<>();

    /**
     * 獲取全字體名稱,如果不可用則獲取字體家族名稱。
     *
     * @return 字體名稱
     */
    public String getFontName() {
        return fontProperties.getOrDefault(FULL_FONT_NAME, fontProperties.get(FAMILY_NAME));
    }

    /**
     * 獲取特定的字體屬性。
     *
     * @param nameID 屬性 ID
     * @return 屬性值
     */
    public String getFontProperty(int nameID) {
        return fontProperties.get(nameID);
    }

    /**
     * 獲取所有字體屬性。
     *
     * @return 字體屬性映射
     */
    public Map<Integer, String> getFontProperties() {
        return fontProperties;
    }

    /**
     * 解析 TTF 文件并提取字體屬性。
     *
     * @param fileName TTF 文件路徑
     * @throws IOException 如果發(fā)生 I/O 錯誤
     */
    public void parse(String fileName) throws IOException {
        fontProperties.clear();
        try (RandomAccessFile raf = new RandomAccessFile(fileName, "r")) {
            parseInner(raf);
        }
    }

    private void parseInner(RandomAccessFile raf) throws IOException {
        int majorVersion = raf.readUnsignedShort();
        int minorVersion = raf.readUnsignedShort();
        int numOfTables = raf.readUnsignedShort();

        if (majorVersion != 1 || minorVersion != 0) {
            return; // 不支持的版本
        }

        // 跳到表目錄
        raf.seek(12); // 跳過版本信息和表數(shù)

        boolean found = false;
        TableDirectory tableDirectory = new TableDirectory();

        for (int i = 0; i < numOfTables; i++) {
            byte[] nameBytes = new byte[4];
            raf.readFully(nameBytes);
            tableDirectory.name = new String(nameBytes, StandardCharsets.ISO_8859_1);
            tableDirectory.checkSum = raf.readInt();
            tableDirectory.offset = raf.readInt();
            tableDirectory.length = raf.readInt();

            if ("name".equalsIgnoreCase(tableDirectory.name)) {
                found = true;
                break;
            }
        }

        if (!found) {
            return; // 未找到 'name' 表
        }

        raf.seek(tableDirectory.offset);
        NameTableHeader nameTableHeader = new NameTableHeader();
        nameTableHeader.fSelector = raf.readUnsignedShort();
        nameTableHeader.nRCount = raf.readUnsignedShort();
        nameTableHeader.storageOffset = raf.readUnsignedShort();

        for (int i = 0; i < nameTableHeader.nRCount; i++) {
            NameRecord nameRecord = new NameRecord();
            nameRecord.platformID = raf.readUnsignedShort();
            nameRecord.encodingID = raf.readUnsignedShort();
            nameRecord.languageID = raf.readUnsignedShort();
            nameRecord.nameID = raf.readUnsignedShort();
            nameRecord.stringLength = raf.readUnsignedShort();
            nameRecord.stringOffset = raf.readUnsignedShort();

            long pos = raf.getFilePointer();
            raf.seek(tableDirectory.offset + nameRecord.stringOffset + nameTableHeader.storageOffset);
            byte[] bf = new byte[nameRecord.stringLength];
            raf.readFully(bf);
            String value = new String(bf, StandardCharsets.UTF_16);
            fontProperties.put(nameRecord.nameID, value);
            // 打印出可能的授權(quán)信息
            if (nameRecord.nameID == TTFParser.COPYRIGHT || nameRecord.nameID == TTFParser.LICENSE_DESCRIPTION) {
                System.out.println("Found information: " + value);
                System.out.println();
            }
            raf.seek(pos);
        }
    }

    /**
     * 檢查字體文件中是否包含版權(quán)聲明。
     *
     * @return 如果找到版權(quán)聲明,返回 true;否則返回 false
     */
    public boolean hasCopyrightInfo() {
        return fontProperties.containsKey(COPYRIGHT);
    }

    /**
     * 檢查字體文件中是否包含商用授權(quán)信息。
     *
     * @return 返回一個包含兩個布爾值的數(shù)組,第一個表示是否允許商用,第二個表示是否需要授權(quán)。
     */
    public boolean[] checkCommercialUseAndAuthorization() {
        boolean isCommercialUseAllowed = false;
        boolean isAuthorizationRequired = false;

        String licenseDescription = fontProperties.get(LICENSE_DESCRIPTION);
        if (licenseDescription != null) {
            // 解析 licenseDescription 中的關(guān)鍵詞來判斷
            String descriptionLower = licenseDescription.toLowerCase();
            if (descriptionLower.contains("commercial use allowed")) {
                isCommercialUseAllowed = true;
            }
            if (descriptionLower.contains("authorization required")) {
                isAuthorizationRequired = true;
            }
        }

        String licenseInfoURL = fontProperties.get(LICENSE_INFO_URL);
        System.out.println("============111111" + fontProperties);
        if (licenseInfoURL != null) {
            // 可以通過訪問此URL來確認授權(quán)信息
            System.out.println("檢查授權(quán)信息,請訪問: " + licenseInfoURL);
            // 假設(shè)如果有 URL 說明需要進一步確認授權(quán)
            isAuthorizationRequired = true;
        }

        return new boolean[]{isCommercialUseAllowed, isAuthorizationRequired};
    }

    @Override
    public String toString() {
        return fontProperties.toString();
    }

    private static class TableDirectory {
        String name;
        int checkSum;
        int offset;
        int length;
    }

    private static class NameTableHeader {
        int fSelector;
        int nRCount;
        int storageOffset;
    }

    private static class NameRecord {
        int platformID;
        int encodingID;
        int languageID;
        int nameID;
        int stringLength;
        int stringOffset;
    }
}

2.demo

package com.example.psd.font;

import com.example.psd.font.TTFParser;

import java.io.File;
import java.io.FilenameFilter;

public class TTFParserExample {

    public static void main(String[] args) {
        // 指定 TTF 文件所在目錄
        File fontDir = new File("D:\\測試");

        // 列出目錄中的所有 TTF 文件
        File[] files = fontDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".ttf");
            }
        });

        // 處理每個 TTF 文件
        if (files != null) {
            for (File file : files) {
                TTFParser parser = new TTFParser();
                try {
                    parser.parse(file.getAbsolutePath());
                    // 獲取并打印字體名稱
                    String fontName = parser.getFontName();
                    System.out.println("Font name: " + fontName);

                    // 如果需要獲取其他屬性,可以使用類似的方式
                    String familyName = parser.getFontProperty(TTFParser.FAMILY_NAME);
                    System.out.println("Family name: " + familyName);
                } catch (Exception e) {
                    System.err.println("Error parsing font file: " + file.getAbsolutePath());
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("No TTF files found in the specified directory.");
        }
    }
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談springboot項目中定時任務(wù)如何優(yōu)雅退出

    淺談springboot項目中定時任務(wù)如何優(yōu)雅退出

    這篇文章主要介紹了淺談springboot項目中定時任務(wù)如何優(yōu)雅退出?具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • java代理 jdk動態(tài)代理應(yīng)用案列

    java代理 jdk動態(tài)代理應(yīng)用案列

    java代理有jdk動態(tài)代理、cglib代理,這里只說下jdk動態(tài)代理,jdk動態(tài)代理主要使用的是java反射機制,需要了解的朋友可以參考下
    2012-11-11
  • Java項目如何防止SQL注入(多種方案匯總)

    Java項目如何防止SQL注入(多種方案匯總)

    SQL注入即是指web應(yīng)用程序?qū)τ脩糨斎霐?shù)據(jù)的合法性沒有判斷或過濾不嚴,攻擊者可以在web應(yīng)用程序中事先定義好的查詢語句的結(jié)尾上添加額外的SQL語句,這篇文章主要介紹了?Java項目防止SQL注入的四種方案,需要的朋友可以參考下
    2023-12-12
  • Java ProcessBuilder執(zhí)行多次CMD命令的使用

    Java ProcessBuilder執(zhí)行多次CMD命令的使用

    本文介紹了Java的ProcessBuilder類,該類用于執(zhí)行外部命令,通過ProcessBuilder,我們可以在Java程序中靈活地執(zhí)行多次CMD命令,并控制輸入輸出流以及工作目錄等,感興趣的可以了解一下
    2024-11-11
  • java內(nèi)存分布實現(xiàn)代碼

    java內(nèi)存分布實現(xiàn)代碼

    這篇文章主要介紹了淺談Java內(nèi)存區(qū)域劃分和內(nèi)存分配策略,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段

    Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段

    這篇文章主要介紹了Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 總結(jié)一下關(guān)于在Java8中使用stream流踩過的一些坑

    總結(jié)一下關(guān)于在Java8中使用stream流踩過的一些坑

    java8新增了stream流式處理,對于list的各種操作處理提供了好多方法 ,用過的都知道,方便極了.比如篩選、排序、合并、類型轉(zhuǎn)換等等.以下是我實際工作中踩過的坑,記錄下避免大家踩坑,需要的朋友可以參考下
    2021-06-06
  • Spring boot多線程配置方法

    Spring boot多線程配置方法

    這篇文章主要為大家詳細介紹了Spring boot多線程配置方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java中Set集合轉(zhuǎn)為List集合常見的兩種方式

    Java中Set集合轉(zhuǎn)為List集合常見的兩種方式

    List是Java中比較常用的集合類,指一系列存儲數(shù)據(jù)的接口和類,可以解決復(fù)雜的數(shù)據(jù)存儲問題,這篇文章主要給大家介紹了關(guān)于Java中Set集合轉(zhuǎn)為List集合常見的兩種方式,需要的朋友可以參考下
    2023-12-12
  • 一文掌握IDEA中的Maven集成與創(chuàng)建

    一文掌握IDEA中的Maven集成與創(chuàng)建

    maven是用來幫助我們快速搭建項目結(jié)構(gòu)與開發(fā)環(huán)境的好工具,這篇文章主要介紹了一文掌握IDEA中的Maven集成與創(chuàng)建,需要的朋友可以參考下
    2023-02-02

最新評論

新郑市| 酒泉市| 黑河市| 沿河| 盘锦市| 青岛市| 息烽县| 团风县| 西昌市| 卫辉市| 丹巴县| 泾阳县| 安徽省| 迁安市| 土默特右旗| 登封市| 天门市| 宜兰县| 庄浪县| 靖江市| 宁强县| 普宁市| 泽库县| 卢氏县| 鹿邑县| 陵水| 万盛区| 从江县| 柳江县| 浙江省| 陕西省| 巩留县| 南昌县| 炎陵县| 枣阳市| 凤翔县| 阿鲁科尔沁旗| 江安县| 新津县| 德清县| 土默特右旗|