huangkun
1 week ago
51 changed files with 3742 additions and 23 deletions
@ -0,0 +1,4 @@ |
|||
**/CMakeFiles |
|||
**/Makefile |
|||
**/cmake_install.cmake |
|||
**/main |
@ -0,0 +1,376 @@ |
|||
# This is the CMakeCache file. |
|||
# For build in directory: /home/kun1h/git/blog/cpp/fonts |
|||
# It was generated by CMake: /usr/bin/cmake |
|||
# You can edit this file to change values found and used by cmake. |
|||
# If you do not want to change any of the values, simply exit the editor. |
|||
# If you do want to change a value, simply edit, save, and exit the editor. |
|||
# The syntax for the file is as follows: |
|||
# KEY:TYPE=VALUE |
|||
# KEY is the name of a variable in the cache. |
|||
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. |
|||
# VALUE is the current value for the KEY. |
|||
|
|||
######################## |
|||
# EXTERNAL cache entries |
|||
######################## |
|||
|
|||
//Path to a program. |
|||
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line |
|||
|
|||
//Path to a program. |
|||
CMAKE_AR:FILEPATH=/usr/bin/ar |
|||
|
|||
//Choose the type of build, options are: None Debug Release RelWithDebInfo |
|||
// MinSizeRel ... |
|||
CMAKE_BUILD_TYPE:STRING= |
|||
|
|||
//Enable/Disable color output during build. |
|||
CMAKE_COLOR_MAKEFILE:BOOL=ON |
|||
|
|||
//CXX compiler |
|||
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ |
|||
|
|||
//A wrapper around 'ar' adding the appropriate '--plugin' option |
|||
// for the GCC compiler |
|||
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar |
|||
|
|||
//A wrapper around 'ranlib' adding the appropriate '--plugin' option |
|||
// for the GCC compiler |
|||
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib |
|||
|
|||
//Flags used by the CXX compiler during all build types. |
|||
CMAKE_CXX_FLAGS:STRING= |
|||
|
|||
//Flags used by the CXX compiler during DEBUG builds. |
|||
CMAKE_CXX_FLAGS_DEBUG:STRING=-g |
|||
|
|||
//Flags used by the CXX compiler during MINSIZEREL builds. |
|||
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG |
|||
|
|||
//Flags used by the CXX compiler during RELEASE builds. |
|||
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG |
|||
|
|||
//Flags used by the CXX compiler during RELWITHDEBINFO builds. |
|||
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG |
|||
|
|||
//C compiler |
|||
CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc |
|||
|
|||
//A wrapper around 'ar' adding the appropriate '--plugin' option |
|||
// for the GCC compiler |
|||
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar |
|||
|
|||
//A wrapper around 'ranlib' adding the appropriate '--plugin' option |
|||
// for the GCC compiler |
|||
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib |
|||
|
|||
//Flags used by the C compiler during all build types. |
|||
CMAKE_C_FLAGS:STRING= |
|||
|
|||
//Flags used by the C compiler during DEBUG builds. |
|||
CMAKE_C_FLAGS_DEBUG:STRING=-g |
|||
|
|||
//Flags used by the C compiler during MINSIZEREL builds. |
|||
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG |
|||
|
|||
//Flags used by the C compiler during RELEASE builds. |
|||
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG |
|||
|
|||
//Flags used by the C compiler during RELWITHDEBINFO builds. |
|||
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG |
|||
|
|||
//Path to a program. |
|||
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND |
|||
|
|||
//Flags used by the linker during all build types. |
|||
CMAKE_EXE_LINKER_FLAGS:STRING= |
|||
|
|||
//Flags used by the linker during DEBUG builds. |
|||
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= |
|||
|
|||
//Flags used by the linker during MINSIZEREL builds. |
|||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= |
|||
|
|||
//Flags used by the linker during RELEASE builds. |
|||
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= |
|||
|
|||
//Flags used by the linker during RELWITHDEBINFO builds. |
|||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= |
|||
|
|||
//Enable/Disable output of compile commands during generation. |
|||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL= |
|||
|
|||
//Value Computed by CMake. |
|||
CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=/home/kun1h/git/blog/cpp/fonts/CMakeFiles/pkgRedirects |
|||
|
|||
//Install path prefix, prepended onto install directories. |
|||
CMAKE_INSTALL_PREFIX:PATH=/usr/local |
|||
|
|||
//Path to a program. |
|||
CMAKE_LINKER:FILEPATH=/usr/bin/ld |
|||
|
|||
//Path to a program. |
|||
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/gmake |
|||
|
|||
//Flags used by the linker during the creation of modules during |
|||
// all build types. |
|||
CMAKE_MODULE_LINKER_FLAGS:STRING= |
|||
|
|||
//Flags used by the linker during the creation of modules during |
|||
// DEBUG builds. |
|||
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= |
|||
|
|||
//Flags used by the linker during the creation of modules during |
|||
// MINSIZEREL builds. |
|||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= |
|||
|
|||
//Flags used by the linker during the creation of modules during |
|||
// RELEASE builds. |
|||
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= |
|||
|
|||
//Flags used by the linker during the creation of modules during |
|||
// RELWITHDEBINFO builds. |
|||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= |
|||
|
|||
//Path to a program. |
|||
CMAKE_NM:FILEPATH=/usr/bin/nm |
|||
|
|||
//Path to a program. |
|||
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy |
|||
|
|||
//Path to a program. |
|||
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump |
|||
|
|||
//Value Computed by CMake |
|||
CMAKE_PROJECT_DESCRIPTION:STATIC= |
|||
|
|||
//Value Computed by CMake |
|||
CMAKE_PROJECT_HOMEPAGE_URL:STATIC= |
|||
|
|||
//Value Computed by CMake |
|||
CMAKE_PROJECT_NAME:STATIC=fonts |
|||
|
|||
//Path to a program. |
|||
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib |
|||
|
|||
//Path to a program. |
|||
CMAKE_READELF:FILEPATH=/usr/bin/readelf |
|||
|
|||
//Flags used by the linker during the creation of shared libraries |
|||
// during all build types. |
|||
CMAKE_SHARED_LINKER_FLAGS:STRING= |
|||
|
|||
//Flags used by the linker during the creation of shared libraries |
|||
// during DEBUG builds. |
|||
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= |
|||
|
|||
//Flags used by the linker during the creation of shared libraries |
|||
// during MINSIZEREL builds. |
|||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= |
|||
|
|||
//Flags used by the linker during the creation of shared libraries |
|||
// during RELEASE builds. |
|||
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= |
|||
|
|||
//Flags used by the linker during the creation of shared libraries |
|||
// during RELWITHDEBINFO builds. |
|||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= |
|||
|
|||
//If set, runtime paths are not added when installing shared libraries, |
|||
// but are added when building. |
|||
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO |
|||
|
|||
//If set, runtime paths are not added when using shared libraries. |
|||
CMAKE_SKIP_RPATH:BOOL=NO |
|||
|
|||
//Flags used by the linker during the creation of static libraries |
|||
// during all build types. |
|||
CMAKE_STATIC_LINKER_FLAGS:STRING= |
|||
|
|||
//Flags used by the linker during the creation of static libraries |
|||
// during DEBUG builds. |
|||
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING= |
|||
|
|||
//Flags used by the linker during the creation of static libraries |
|||
// during MINSIZEREL builds. |
|||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING= |
|||
|
|||
//Flags used by the linker during the creation of static libraries |
|||
// during RELEASE builds. |
|||
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= |
|||
|
|||
//Flags used by the linker during the creation of static libraries |
|||
// during RELWITHDEBINFO builds. |
|||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= |
|||
|
|||
//Path to a program. |
|||
CMAKE_STRIP:FILEPATH=/usr/bin/strip |
|||
|
|||
//If this value is on, makefiles will be generated without the |
|||
// .SILENT directive, and all commands will be echoed to the console |
|||
// during the make. This is useful for debugging only. With Visual |
|||
// Studio IDE projects all commands are done without /nologo. |
|||
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE |
|||
|
|||
//Value Computed by CMake |
|||
fonts_BINARY_DIR:STATIC=/home/kun1h/git/blog/cpp/fonts/reader |
|||
|
|||
//Value Computed by CMake |
|||
fonts_IS_TOP_LEVEL:STATIC=OFF |
|||
|
|||
//Value Computed by CMake |
|||
fonts_SOURCE_DIR:STATIC=/home/kun1h/git/blog/cpp/fonts/reader |
|||
|
|||
|
|||
######################## |
|||
# INTERNAL cache entries |
|||
######################## |
|||
|
|||
//ADVANCED property for variable: CMAKE_ADDR2LINE |
|||
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_AR |
|||
CMAKE_AR-ADVANCED:INTERNAL=1 |
|||
//This is the directory where this CMakeCache.txt was created |
|||
CMAKE_CACHEFILE_DIR:INTERNAL=/home/kun1h/git/blog/cpp/fonts |
|||
//Major version of cmake used to create the current loaded cache |
|||
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 |
|||
//Minor version of cmake used to create the current loaded cache |
|||
CMAKE_CACHE_MINOR_VERSION:INTERNAL=26 |
|||
//Patch version of cmake used to create the current loaded cache |
|||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=5 |
|||
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE |
|||
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 |
|||
//Path to CMake executable. |
|||
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake |
|||
//Path to cpack program executable. |
|||
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack |
|||
//Path to ctest program executable. |
|||
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest |
|||
//ADVANCED property for variable: CMAKE_CXX_COMPILER |
|||
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR |
|||
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB |
|||
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_FLAGS |
|||
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG |
|||
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL |
|||
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE |
|||
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO |
|||
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_COMPILER |
|||
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_COMPILER_AR |
|||
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB |
|||
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_FLAGS |
|||
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG |
|||
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL |
|||
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE |
|||
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO |
|||
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_DLLTOOL |
|||
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1 |
|||
//Path to cache edit program executable. |
|||
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake |
|||
//Executable file format |
|||
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF |
|||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS |
|||
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG |
|||
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL |
|||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE |
|||
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO |
|||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS |
|||
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 |
|||
//Name of external makefile project generator. |
|||
CMAKE_EXTRA_GENERATOR:INTERNAL= |
|||
//Name of generator. |
|||
CMAKE_GENERATOR:INTERNAL=Unix Makefiles |
|||
//Generator instance identifier. |
|||
CMAKE_GENERATOR_INSTANCE:INTERNAL= |
|||
//Name of generator platform. |
|||
CMAKE_GENERATOR_PLATFORM:INTERNAL= |
|||
//Name of generator toolset. |
|||
CMAKE_GENERATOR_TOOLSET:INTERNAL= |
|||
//Source directory with the top level CMakeLists.txt file for this |
|||
// project |
|||
CMAKE_HOME_DIRECTORY:INTERNAL=/home/kun1h/git/blog/cpp/fonts |
|||
//Install .so files without execute permission. |
|||
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0 |
|||
//ADVANCED property for variable: CMAKE_LINKER |
|||
CMAKE_LINKER-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM |
|||
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS |
|||
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG |
|||
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL |
|||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE |
|||
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO |
|||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_NM |
|||
CMAKE_NM-ADVANCED:INTERNAL=1 |
|||
//number of local generators |
|||
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=3 |
|||
//ADVANCED property for variable: CMAKE_OBJCOPY |
|||
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_OBJDUMP |
|||
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 |
|||
//Platform information initialized |
|||
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_RANLIB |
|||
CMAKE_RANLIB-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_READELF |
|||
CMAKE_READELF-ADVANCED:INTERNAL=1 |
|||
//Path to CMake installation. |
|||
CMAKE_ROOT:INTERNAL=/usr/share/cmake |
|||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS |
|||
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG |
|||
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL |
|||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE |
|||
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO |
|||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH |
|||
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_SKIP_RPATH |
|||
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS |
|||
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG |
|||
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL |
|||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE |
|||
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO |
|||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 |
|||
//ADVANCED property for variable: CMAKE_STRIP |
|||
CMAKE_STRIP-ADVANCED:INTERNAL=1 |
|||
//uname command |
|||
CMAKE_UNAME:INTERNAL=/usr/bin/uname |
|||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE |
|||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 |
|||
//linker supports push/pop state |
|||
_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED:INTERNAL=TRUE |
|||
|
@ -0,0 +1,6 @@ |
|||
cmake_minimum_required(VERSION 3.10) |
|||
project(fonts) |
|||
add_subdirectory(core) |
|||
add_subdirectory(reader) |
|||
add_executable(main main.cpp) |
|||
target_link_libraries(main core reader) |
@ -0,0 +1,29 @@ |
|||
include_directories(../) |
|||
include_directories(./) |
|||
include_directories(./tables) |
|||
include_directories(./tables/name) |
|||
set(SOURCE |
|||
tables/name/name_id.h |
|||
tables/name/name.h |
|||
tables/name/name.cpp |
|||
tables/name/platform_id.h |
|||
tables/name/name_head.h |
|||
tables/name/name_head.cpp |
|||
tables/table.h |
|||
tables/table.cpp |
|||
tables/table_name.h |
|||
font.cpp |
|||
font.h |
|||
head.cpp |
|||
head.h |
|||
tables/cmap/cmap.h |
|||
tables/cmap/cmap.cpp |
|||
tables/cmap/encoding_record.h |
|||
tables/cmap/encoding_record.cpp |
|||
tables/cmap/header.cpp |
|||
tables/cmap/header.h |
|||
tables/cmap/platform.h |
|||
tables/cmap/tables.h |
|||
) |
|||
project(fonts) |
|||
add_library(core SHARED ${SOURCE}) |
@ -0,0 +1,24 @@ |
|||
#include "font.h" |
|||
#include "tables/table_name.h" |
|||
#include "reader/buffer.h" |
|||
#include <iostream> |
|||
#include "../reader/file.h" |
|||
font::font(const char* fontFile){ |
|||
file rd(fontFile); |
|||
path = rd.getPath(); |
|||
read(&rd); |
|||
} |
|||
|
|||
void font::read(reader* rd){ |
|||
//读取字体头
|
|||
head.read(rd); |
|||
//读取表信息
|
|||
table.read(rd, head.getTableCount()); |
|||
|
|||
} |
|||
|
|||
void font::display(){ |
|||
std::cout<<"font file"<<path<<" readed."<<std::endl; |
|||
head.display(); |
|||
table.display(); |
|||
} |
@ -0,0 +1,21 @@ |
|||
#ifndef __FONT_H__ |
|||
#define __FONT_H__ |
|||
#include "tables/table.h" |
|||
#include "head.h" |
|||
#include <string> |
|||
|
|||
class font |
|||
{ |
|||
private: |
|||
FontTable table; |
|||
fontHead head; |
|||
std::string path; |
|||
public: |
|||
font(){}; |
|||
font(const char*); |
|||
~font(){}; |
|||
void read(reader*); |
|||
void display(); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,25 @@ |
|||
#include "head.h" |
|||
#include <iostream> |
|||
void fontHead::read(reader* rd){ |
|||
//先读4字节,看是ttf还是ttc
|
|||
auto ft = rd->readString(4); |
|||
if(ft == "ttcf"){ |
|||
throw "not support ttc"; |
|||
} |
|||
rd->seek(0); |
|||
verMain = rd->readUint16(); |
|||
verSub = rd->readUint16(); |
|||
tableCount = rd->readUint16(); |
|||
auto arg1 = rd->readUint16(); |
|||
args.push_back(arg1); |
|||
auto arg2 = rd->readUint16(); |
|||
args.push_back(arg2); |
|||
auto arg3 = rd->readUint16(); |
|||
args.push_back(arg3); |
|||
} |
|||
|
|||
void fontHead::display(){ |
|||
std::cout<<"this is header"<<std::endl; |
|||
std::cout<<"version: "<<verMain<<"."<<verSub<<"\ttableCount: "<<tableCount<<std::endl; |
|||
} |
|||
|
@ -0,0 +1,26 @@ |
|||
#ifndef __HEAD_H__ |
|||
#define __HEAD_H__ |
|||
#include "../reader/reader.h" |
|||
#include <list> |
|||
|
|||
class fontHead |
|||
{ |
|||
private: |
|||
uint16_t verMain; |
|||
uint16_t verSub; |
|||
uint16_t tableCount; |
|||
std::list<uint16_t> args; |
|||
public: |
|||
fontHead(/* args */){ |
|||
verMain = 0; |
|||
verSub = 0; |
|||
tableCount = 0; |
|||
args = {}; |
|||
}; |
|||
~fontHead(){}; |
|||
void read(reader*); |
|||
void display(); |
|||
uint16_t getTableCount(){return tableCount;}; |
|||
std::list<uint16_t> getArgs(){return args;}; |
|||
}; |
|||
#endif |
@ -0,0 +1,285 @@ |
|||
#ifndef __TABLE_BASE_HEADER_H__ |
|||
#define __TABLE_BASE_HEADER_H__ |
|||
#include "../../../reader/reader.h" |
|||
class BaseHeader1 |
|||
{ |
|||
private: |
|||
uint16_t _majorVersion; |
|||
uint16_t _minorVersion; |
|||
Offset16 _horizAxisOffset; |
|||
Offset16 _vertAxisOffset; |
|||
public: |
|||
BaseHeader1():_majorVersion(1),_minorVersion(0),_horizAxisOffset(0),_vertAxisOffset(0){}; |
|||
~BaseHeader1(){}; |
|||
BaseHeader1(reader* rd){read(rd);}; |
|||
void read(reader *rd){ |
|||
if(_majorVersion!=1||_minorVersion!=0)return; |
|||
_majorVersion = rd->readUint16(); |
|||
_minorVersion = rd->readUint16(); |
|||
_horizAxisOffset = rd->readUint16(); |
|||
_vertAxisOffset = rd->readUint16(); |
|||
}; |
|||
uint16_t majorVersion()const{return _majorVersion;}; |
|||
uint16_t minorVersion()const{return _minorVersion;}; |
|||
uint16_t horizAxisOffset()const{return _horizAxisOffset;}; |
|||
uint16_t vertAxisOffset()const{return _vertAxisOffset;}; |
|||
}; |
|||
|
|||
//
|
|||
class BaseHeader1_1: public BaseHeader1 |
|||
{ |
|||
private: |
|||
uint32_t _itemVarStoreOffset; |
|||
public: |
|||
BaseHeader1_1():_itemVarStoreOffset(0){}; |
|||
~BaseHeader1_1(){}; |
|||
BaseHeader1_1(reader* rd):BaseHeader1(rd){read(rd);}; |
|||
void read(reader* rd){ |
|||
_itemVarStoreOffset = rd->readUint32(); |
|||
} |
|||
uint32_t itemVarStoreOffset()const{return _itemVarStoreOffset;}; |
|||
}; |
|||
|
|||
//
|
|||
class AxisTable |
|||
{ |
|||
private: |
|||
uint16_t _baseTagListOffset; |
|||
uint16_t _baseScriptListOffset; |
|||
public: |
|||
AxisTable():_baseScriptListOffset(0),_baseTagListOffset(0){}; |
|||
~AxisTable(){}; |
|||
AxisTable(reader* rd){read(rd);}; |
|||
void read(reader* rd){ |
|||
_baseTagListOffset = rd->readUint16(); |
|||
_baseScriptListOffset = rd->readUint16(); |
|||
} |
|||
uint16_t baseTagListOffset()const{return _baseTagListOffset;}; |
|||
uint16_t baseScriptListOffset()const{return _baseScriptListOffset;}; |
|||
}; |
|||
|
|||
class BaseTagList |
|||
{ |
|||
private: |
|||
uint16_t _baseTagCount; |
|||
std::vector<Tag> _baselineTags; |
|||
public: |
|||
BaseTagList():_baseTagCount(0){}; |
|||
~BaseTagList(){}; |
|||
BaseTagList(reader*rd){read(rd);}; |
|||
void read(reader *rd){ |
|||
_baseTagCount = rd->readUint16(); |
|||
for(auto i=0;i<_baseTagCount;i++){ |
|||
Tag t = rd->readTag(); |
|||
_baselineTags.push_back(t); |
|||
} |
|||
} |
|||
uint16 baseTagCount(){return _baseTagCount;}; |
|||
std::vector<Tag> baselineTags(){return _baselineTags;}; |
|||
}; |
|||
|
|||
class BaseScriptRecord |
|||
{ |
|||
private: |
|||
Tag _baseScriptTag; |
|||
Offset16 _baseScriptOffset; |
|||
public: |
|||
BaseScriptRecord():_baseScriptOffset(0){}; |
|||
~BaseScriptRecord(){}; |
|||
BaseScriptRecord(reader*rd){read(rd);}; |
|||
void read(reader* rd){ |
|||
_baseScriptTag = rd->readTag(); |
|||
_baseScriptOffset = rd->readOffset16(); |
|||
}; |
|||
}; |
|||
|
|||
class BaseScriptList |
|||
{ |
|||
private: |
|||
uint16 _baseScriptCount; |
|||
std::vector<BaseScriptRecord> _baseScriptRecords; |
|||
public: |
|||
BaseScriptList():_baseScriptCount(0){}; |
|||
~BaseScriptList(){}; |
|||
BaseScriptList(reader *rd){read(rd);}; |
|||
void read(reader *rd){ |
|||
_baseScriptCount = rd->readUint16(); |
|||
for(auto i = 0; i<_baseScriptCount; i++){ |
|||
BaseScriptRecord bs(rd); |
|||
_baseScriptRecords.push_back(rd); |
|||
} |
|||
} |
|||
uint16 baseScriptCount(){return _baseScriptCount;}; |
|||
std::vector<BaseScriptRecord> baseScriptRecords(){return _baseScriptRecords;}; |
|||
}; |
|||
|
|||
class BaseValues |
|||
{ |
|||
private: |
|||
uint16 _defaultBaselineIndex; |
|||
uint16 _baseCoordCount; |
|||
std::vector<Offset16> _baseCoordOffset; |
|||
public: |
|||
BaseValues():_defaultBaselineIndex(0),_baseCoordCount(0){}; |
|||
~BaseValues(){}; |
|||
BaseValues(reader*rd){read(rd);}; |
|||
void read(reader*rd){ |
|||
_defaultBaselineIndex = rd->readUint16(); |
|||
_baseCoordCount = rd->readUint16(); |
|||
for(auto i=0;i<_baseCoordCount; i++){ |
|||
Offset16 f = rd->readOffset16(); |
|||
_baseCoordOffset.push_back(f); |
|||
} |
|||
} |
|||
uint16 defaultBaselineIndex(){return _defaultBaselineIndex;}; |
|||
uint16 baseCoordCount(){return _baseCoordCount;}; |
|||
std::vector<Offset16> baseCoordOffset(){return _baseCoordOffset;}; |
|||
}; |
|||
|
|||
class BaseLangSys |
|||
{ |
|||
private: |
|||
Tag _baseLangSysTag; |
|||
Offset16 _minMaxOffset; |
|||
public: |
|||
BaseLangSys():_minMaxOffset(0){}; |
|||
~BaseLangSys(){}; |
|||
BaseLangSys(reader* rd){read(rd);}; |
|||
void read(reader*rd){ |
|||
_baseLangSysTag = rd->readTag(); |
|||
_minMaxOffset = rd->readOffset16(); |
|||
} |
|||
Tag baseLangSysTag(){return _baseLangSysTag;}; |
|||
Offset16 minMaxOffset(){return _minMaxOffset;}; |
|||
}; |
|||
|
|||
|
|||
class BaseScript |
|||
{ |
|||
private: |
|||
Offset16 _baseValuesOffset; |
|||
Offset16 _defaultMinMaxOffset; |
|||
uint16 _baseLangSysCount; |
|||
std::vector<BaseLangSys> _baseLangSysRecords; |
|||
public: |
|||
BaseScript():_baseLangSysCount(0),_defaultMinMaxOffset(0),_baseValuesOffset(0){}; |
|||
~BaseScript(){}; |
|||
BaseScript(reader* rd){read(rd);}; |
|||
void read(reader* rd){ |
|||
_baseValuesOffset = rd->readOffset16(); |
|||
_defaultMinMaxOffset = rd->readOffset16(); |
|||
_baseLangSysCount = rd->readUint16(); |
|||
for(auto i = 0; i<_baseLangSysCount;i++){ |
|||
BaseLangSys bls(rd); |
|||
_baseLangSysRecords.push_back(bls); |
|||
} |
|||
} |
|||
Offset16 baseValueOffset(){return _baseValuesOffset;}; |
|||
Offset16 defaultMinMaxOffset(){return _defaultMinMaxOffset;}; |
|||
uint16 baseLangSysCount(){return _baseLangSysCount;}; |
|||
std::vector<BaseLangSys> baseLangSysRecords(){return _baseLangSysRecords;}; |
|||
}; |
|||
|
|||
class MinMax |
|||
{ |
|||
private: |
|||
Offset16 _minCoordOffset; |
|||
Offset16 _maxCoordOffset; |
|||
uint16 _featMinMaxCount; |
|||
std::vector<FeatMinMax> _featMinMaxRecords; |
|||
public: |
|||
MinMax():_minCoordOffset(0),_maxCoordOffset(0),_featMinMaxCount(0){}; |
|||
~MinMax(){}; |
|||
MinMax(reader *rd){read(rd);}; |
|||
void read(reader *rd){ |
|||
_minCoordOffset = rd->readOffset16(); |
|||
_maxCoordOffset = rd->readOffset16(); |
|||
_featMinMaxCount = rd->readUint16(); |
|||
for(auto i=0; i<_featMinMaxCount;i++){ |
|||
FeatMinMax fmm(rd); |
|||
_featMinMaxRecords.push_back(fmm); |
|||
} |
|||
} |
|||
Offset16 minCoordOffset(){return _minCoordOffset;}; |
|||
Offset16 maxCoordOffset(){return _maxCoordOffset;}; |
|||
uint16 featMinMaxCount(){return _featMinMaxCount;}; |
|||
std::vector<FeatMinMax> featMinMaxRecords(){return _featMinMaxRecords;}; |
|||
}; |
|||
|
|||
class FeatMinMax |
|||
{ |
|||
private: |
|||
Tag _featureTag; |
|||
Offset16 _minCoordOffset; |
|||
Offset16 _maxCoordOffset; |
|||
public: |
|||
FeatMinMax():_minCoordOffset(0), _maxCoordOffset(0){}; |
|||
~FeatMinMax(){}; |
|||
FeatMinMax(reader*rd){read(rd);}; |
|||
void read(reader*rd){ |
|||
_featureTag = rd->readTag(); |
|||
_minCoordOffset =rd->readOffset16(); |
|||
_maxCoordOffset = rd->readOffset16(); |
|||
} |
|||
Tag featureTag(){return _featureTag;}; |
|||
Offset16 minCoordOffset(){return _minCoordOffset;} |
|||
Offset16 maxCoordOffset(){return _maxCoordOffset;} |
|||
}; |
|||
|
|||
class BaseCoord1 |
|||
{ |
|||
private: |
|||
uint16 _format; |
|||
int16 _coordinate; |
|||
public: |
|||
BaseCoord1():_format(0),_coordinate(0){}; |
|||
~BaseCoord1(){}; |
|||
BaseCoord1(reader*rd){read(rd);}; |
|||
void read(reader*rd){ |
|||
_format = rd->readUint16(); |
|||
_coordinate = rd->readInt16(); |
|||
} |
|||
uint16 format(){return _format;} |
|||
int16 cordinate(){return _coordinate;} |
|||
}; |
|||
|
|||
class BaseCoord2: public BaseCoord1 |
|||
{ |
|||
private: |
|||
uint16 _referenceGlyph; |
|||
uint16 _baseCoordPoint; |
|||
public: |
|||
BaseCoord2():_referenceGlyph(0),_baseCoordPoint(0){}; |
|||
~BaseCoord2(){}; |
|||
BaseCoord2(reader*rd):BaseCoord1(rd){read(rd);}; |
|||
void read(reader* rd){ |
|||
_referenceGlyph = rd->readUint16(); |
|||
_baseCoordPoint = rd->readUint16(); |
|||
} |
|||
uint16 referenceGlyph(){return _referenceGlyph;} |
|||
uint16 baseCoordPoint(){return _baseCoordPoint;} |
|||
}; |
|||
|
|||
class BaseCoord3 : public BaseCoord1 |
|||
{ |
|||
private: |
|||
Offset16 _deviceOffset; |
|||
public: |
|||
BaseCoord3():_deviceOffset(0){}; |
|||
~BaseCoord3(){}; |
|||
BaseCoord3(reader *rd):BaseCoord1(rd){read(rd);}; |
|||
void read(reader *rd){ |
|||
_deviceOffset = rd->readOffset16(); |
|||
} |
|||
Offset16 deviceOffset(){return _deviceOffset;} |
|||
}; |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
#endif |
@ -0,0 +1,70 @@ |
|||
#include "cmap.h" |
|||
|
|||
void cmap::read(reader *rd) |
|||
{ |
|||
_header = CmapHeader(rd); |
|||
auto curr = rd->curr(); |
|||
_tableFormat = rd->readUint16(); |
|||
rd->seek(curr); |
|||
switch (_tableFormat) |
|||
{ |
|||
case 0: |
|||
{ |
|||
CmapTable0 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 2: |
|||
{ |
|||
CmapTable2 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
|
|||
case 4: |
|||
{ |
|||
CmapTable4 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 6: |
|||
{ |
|||
CmapTable6 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 8: |
|||
{ |
|||
CmapTable8 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 10: |
|||
{ |
|||
CmapTable10 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 12: |
|||
{ |
|||
CmapTable12 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 13: |
|||
{ |
|||
CmapTable13 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
case 14: |
|||
{ |
|||
CmapTable14 t(rd); |
|||
_table = &t; |
|||
} |
|||
break; |
|||
default: |
|||
_table = nullptr; |
|||
break; |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
#ifndef __TABLE_CMAP_H__ |
|||
#define __TABLE_CMAP_H__ |
|||
#include "../../../reader/reader.h" |
|||
#include "tables.h" |
|||
#include "header.h" |
|||
class CmapTable |
|||
{ |
|||
private: |
|||
CmapHeader _header; |
|||
uint16_t _tableFormat; |
|||
CmapTableBase *_table; |
|||
|
|||
public: |
|||
CmapTable():_tableFormat(0),_table(nullptr){}; |
|||
~CmapTable(){}; |
|||
CmapTable(reader* rd){read(rd);}; |
|||
void read(reader*); |
|||
uint16_t tableFormat()const{return _tableFormat;} |
|||
CmapTableBase* table()const{return _table;} |
|||
CmapHeader header()const{return _header;} |
|||
}; |
|||
|
|||
|
|||
|
|||
#endif |
@ -0,0 +1,11 @@ |
|||
#include "encoding_record.h" |
|||
|
|||
void CmapEncodingRecord::read(reader* rd){ |
|||
_platformId = rd->readUint16(); |
|||
_encodingId = rd->readUint16(); |
|||
_tableOffset = rd->readUint32(); |
|||
} |
|||
|
|||
CmapEncodingRecord::CmapEncodingRecord(reader* rd){ |
|||
read(rd); |
|||
} |
@ -0,0 +1,22 @@ |
|||
#ifndef __ENCODING_RECORD_H__ |
|||
#define __ENCODING_RECORD_H__ |
|||
#include <cstdint> |
|||
#include "../../../reader/reader.h" |
|||
class CmapEncodingRecord |
|||
{ |
|||
private: |
|||
uint16_t _platformId; |
|||
uint16_t _encodingId; |
|||
uint32_t _tableOffset; |
|||
public: |
|||
CmapEncodingRecord():_platformId(0),_encodingId(0),_tableOffset(0){}; |
|||
~CmapEncodingRecord(){}; |
|||
CmapEncodingRecord(reader*); |
|||
void read(reader*); |
|||
uint16_t platformId(){return _platformId;}; |
|||
uint16_t encodingId(){return _encodingId;}; |
|||
uint32_t tableOffset(){return _tableOffset;}; |
|||
}; |
|||
|
|||
|
|||
#endif |
@ -0,0 +1,14 @@ |
|||
#include "header.h" |
|||
|
|||
void CmapHeader::read(reader* rd){ |
|||
_version = rd->readUint16(); |
|||
_numTables = rd->readUint16(); |
|||
for(auto i = 0; i<_numTables; i++){ |
|||
CmapEncodingRecord cer(rd); |
|||
_recordTables.push_back(cer); |
|||
} |
|||
} |
|||
|
|||
CmapHeader::CmapHeader(reader* rd){ |
|||
read(rd); |
|||
} |
@ -0,0 +1,24 @@ |
|||
#ifndef __CMAP_HEADER_H__ |
|||
#define __CMAP_HEADER_H__ |
|||
#include <cstdint> |
|||
#include "encoding_record.h" |
|||
#include <list> |
|||
class CmapHeader |
|||
{ |
|||
private: |
|||
uint16_t _version; |
|||
uint16_t _numTables; |
|||
std::list<CmapEncodingRecord> _recordTables; |
|||
public: |
|||
CmapHeader():_version(0),_numTables(0), _recordTables(){}; |
|||
CmapHeader(reader*); |
|||
~CmapHeader(){}; |
|||
void read(reader*); |
|||
uint16_t version(){return _version;}; |
|||
uint16_t numberTables(){return _numTables;}; |
|||
std::list<CmapEncodingRecord> recordTables(){return _recordTables;}; |
|||
}; |
|||
|
|||
|
|||
|
|||
#endif |
@ -0,0 +1,54 @@ |
|||
#ifndef __CMAP_PLATFORM_H__ |
|||
#define __CMAP_PLATFORM_H__ |
|||
enum platformIds |
|||
{ |
|||
Unicode, |
|||
Macintosh, |
|||
ISO, // deprecated
|
|||
Windows, |
|||
Custom |
|||
}; |
|||
enum EncodingPlatformUnicode |
|||
{ |
|||
Unicode1_0, // deprecated
|
|||
Unicode1_1, // deprecated
|
|||
ISO_10646, // deprecated
|
|||
Unicode2_0_BMP, |
|||
Unicode2_0_Full, |
|||
Unicode_Variation_Sequences, // for table 14
|
|||
Unicode_Full, // for table 13
|
|||
}; |
|||
|
|||
enum EncodingMacintosh |
|||
{ |
|||
|
|||
}; |
|||
|
|||
enum EncodingISO |
|||
{ |
|||
ASCII_7Bit, |
|||
ISO_10646, |
|||
ISO_8859_1, |
|||
}; |
|||
|
|||
enum EncodingWindows |
|||
{ |
|||
Symbol, |
|||
Unicode_BMP, |
|||
ShiftJIS, |
|||
PRC, |
|||
Big5, |
|||
Wansung, |
|||
Johab, |
|||
Reserved, |
|||
Reserved, |
|||
Reserved, |
|||
Unicode_Full, |
|||
}; |
|||
|
|||
enum EncodingCustom |
|||
{ |
|||
|
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,502 @@ |
|||
#ifndef __CMAP_TABLES_H__ |
|||
#define __CMAP_TABLES_H__ |
|||
#include <cstdint> |
|||
#include "../../../reader/reader.h" |
|||
#include <vector> |
|||
#include <math.h> |
|||
#include "../../../types/types.h" |
|||
|
|||
#define list_uint16 std::vector<uint16_t> |
|||
#define list_uint8 std::vector<uint8_t> |
|||
#define list_int16 std::vector<int16_t> |
|||
class CmapTableBase |
|||
{ |
|||
private: |
|||
uint16_t _format; |
|||
uint16_t _length; |
|||
uint16_t _language; |
|||
uint16_t _reserved; |
|||
|
|||
public: |
|||
CmapTableBase() : _format(0), _length(0), _language(0), _reserved(0) {}; |
|||
~CmapTableBase() {}; |
|||
CmapTableBase(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_format = rd->readUint16(); |
|||
_reserved = 0; |
|||
if (_format == 8 || _format == 10 || _format == 12 || _format == 13) |
|||
_reserved = rd->readUint16(); |
|||
_length = rd->readUint16(); |
|||
if (_format == 14) |
|||
{ |
|||
return; |
|||
} |
|||
_language = rd->readUint16(); |
|||
}; |
|||
uint16_t format() const { return _format; }; |
|||
uint16_t length() const { return _length; }; |
|||
uint16_t language() const { return _language; }; |
|||
virtual uint16 Format() = 0; |
|||
}; |
|||
|
|||
class CmapTable0 : public CmapTableBase |
|||
{ |
|||
private: |
|||
list_uint8 _glyphldArray; |
|||
uint16_t _glyphldCount; |
|||
|
|||
public: |
|||
CmapTable0() : CmapTableBase(), _glyphldCount(256) {}; |
|||
~CmapTable0() {}; |
|||
CmapTable0(reader *rd) : CmapTableBase(rd), _glyphldCount(256) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 0) |
|||
return; |
|||
for (auto i = 0; i < _glyphldCount; i++) |
|||
{ |
|||
uint8_t glyph = rd->readUint8(); |
|||
_glyphldArray.push_back(glyph); |
|||
} |
|||
}; |
|||
list_uint8 glyphldArray() const { return _glyphldArray; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
class CmapTable2SubHeader |
|||
{ |
|||
private: |
|||
uint16_t _firstCode; |
|||
uint16_t _entryCount; |
|||
uint16_t _idDelta; |
|||
uint16_t _idRangeOffset; |
|||
|
|||
public: |
|||
CmapTable2SubHeader() : _firstCode(0), _entryCount(0), _idDelta(0), _idRangeOffset(0) {}; |
|||
~CmapTable2SubHeader() {}; |
|||
CmapTable2SubHeader(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_firstCode = rd->readUint16(); |
|||
_entryCount = rd->readUint16(); |
|||
_idDelta = rd->readUint16(); |
|||
_idRangeOffset = rd->readUint16(); |
|||
}; |
|||
uint16_t firstCode() const { return _firstCode; }; |
|||
uint16_t entryCount() const { return _entryCount; }; |
|||
uint16_t idDelta() const { return _idDelta; }; |
|||
uint16_t idRangeOffset() const { return _idRangeOffset; }; |
|||
}; |
|||
// 不常用
|
|||
class CmapTable2 : public CmapTableBase |
|||
{ |
|||
private: |
|||
list_uint16 _subHeaderKey; |
|||
std::vector<CmapTable2SubHeader> _subHeader; |
|||
list_uint16 _glyphldArray; |
|||
uint16_t _searchHeaderKeyCount; |
|||
|
|||
public: |
|||
CmapTable2() : _searchHeaderKeyCount(256) {}; |
|||
~CmapTable2() {}; |
|||
CmapTable2(reader *rd) : CmapTableBase(rd), _searchHeaderKeyCount(256) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 2) |
|||
return; |
|||
}; // 计算很复杂
|
|||
list_uint16 subHeaderKey() const { return _subHeaderKey; }; |
|||
std::vector<CmapTable2SubHeader> subHeader() { return _subHeader; }; |
|||
list_uint16 glyphldArray() const { return _glyphldArray; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
class CmapTable4 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint16_t _segCountX2; |
|||
uint16_t _segCount; |
|||
uint16_t _searchRange; |
|||
uint16_t _entrySelector; |
|||
uint16_t _rangeShift; |
|||
list_uint16 _endCode; |
|||
uint16_t _reservedPad; |
|||
list_uint16 _startCode; |
|||
list_int16 _idDelta; |
|||
list_uint16 _idRangeOffset; |
|||
list_uint16 _glyphldArray; |
|||
void _calculate() |
|||
{ |
|||
_segCount = _segCountX2 / 2; |
|||
_entrySelector = _segCount < 0 ? 0 : static_cast<uint16_t>(std::floor(std::log2(_segCount))); |
|||
_searchRange = static_cast<uint16_t>(std::pow(2, _entrySelector + 1)); |
|||
_rangeShift = _segCountX2 - _searchRange; |
|||
return; |
|||
}; |
|||
|
|||
public: |
|||
CmapTable4() : _segCountX2(0), _searchRange(0), _entrySelector(0), _rangeShift(0), _reservedPad(0) {}; |
|||
~CmapTable4() {}; |
|||
CmapTable4(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 4) |
|||
return; |
|||
_segCountX2 = rd->readUint16(); |
|||
_searchRange = rd->readUint16(); |
|||
_entrySelector = rd->readUint16(); |
|||
_rangeShift = rd->readUint16(); |
|||
_calculate(); // 计算代替读取
|
|||
for (auto i = 0; i < _segCount; i++) |
|||
{ |
|||
uint16_t code = rd->readUint16(); |
|||
_endCode.push_back(code); |
|||
} |
|||
_reservedPad = rd->readUint16(); |
|||
for (auto i = 0; i < _segCount; i++) |
|||
{ |
|||
uint16_t code = rd->readUint16(); |
|||
_startCode.push_back(code); |
|||
} |
|||
for (auto i = 0; i < _segCount; i++) |
|||
{ |
|||
int16_t code = rd->readUint16(); |
|||
_idDelta.push_back(code); |
|||
} |
|||
for (auto i = 0; i < _segCount; i++) |
|||
{ |
|||
uint16_t code = rd->readUint16(); |
|||
_idRangeOffset.push_back(code); |
|||
} |
|||
while (rd->curr() < rd->getLength()) |
|||
{ |
|||
uint16_t glyph = rd->readUint16(); |
|||
_glyphldArray.push_back(glyph); |
|||
} |
|||
}; |
|||
uint16_t segCountX2() const { return _segCountX2; }; |
|||
uint16_t segCount() const { return _segCount; }; |
|||
uint16_t searchRange() const { return _searchRange; }; |
|||
uint16_t entrySelector() const { return _entrySelector; }; |
|||
uint16_t rangeShift() const { return _rangeShift; }; |
|||
list_uint16 startCode() const { return _startCode; }; |
|||
list_uint16 endCode() const { return _endCode; }; |
|||
uint16_t reservePad() const { return _reservedPad; }; |
|||
list_int16 idDelta() const { return _idDelta; }; |
|||
list_uint16 idRangeOffset() const { return _idRangeOffset; }; |
|||
list_uint16 glyphldArray() const { return _glyphldArray; }; |
|||
uint16_t glyphId(uint16_t c, int i) const { return *(_idRangeOffset[i] / 2 + (c - _startCode[i]) + &_idRangeOffset[i]); }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
class CmapTable6 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint16_t _firstCode; |
|||
uint16_t _entryCount; |
|||
list_uint16 _glyphldArray; |
|||
|
|||
public: |
|||
CmapTable6() : _firstCode(0), _entryCount(0) {}; |
|||
~CmapTable6() {}; |
|||
CmapTable6(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 6) |
|||
return; |
|||
_firstCode = rd->readUint16(); |
|||
_entryCount = rd->readUint16(); |
|||
for (auto i = 0; i < _entryCount; i++) |
|||
{ |
|||
uint16_t glyph = rd->readUint16(); |
|||
_glyphldArray.push_back(glyph); |
|||
} |
|||
}; |
|||
uint16_t firstCode() const { return _firstCode; }; |
|||
uint16_t entryCount() const { return _entryCount; }; |
|||
list_uint16 glyphldArray() const { return _glyphldArray; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
//
|
|||
class MapGroup |
|||
{ |
|||
private: |
|||
uint32_t _startCharCode; |
|||
uint32_t _endCharCode; |
|||
uint32_t _startGlyphId; |
|||
|
|||
public: |
|||
MapGroup() : _startCharCode(0), _endCharCode(0), _startGlyphId(0) {}; |
|||
~MapGroup() {}; |
|||
MapGroup(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_startCharCode = rd->readUint32(); |
|||
_endCharCode = rd->readUint32(); |
|||
_startGlyphId = rd->readUint32(); |
|||
}; |
|||
uint32_t startCharCode() const { return _startCharCode; }; |
|||
uint32_t endCharCode() const { return _endCharCode; }; |
|||
uint32_t startGlyphId() const { return _startGlyphId; }; |
|||
}; |
|||
|
|||
class CmapTable8 : public CmapTableBase |
|||
{ |
|||
private: |
|||
list_uint8 _is32; |
|||
uint16_t _is32Count; |
|||
uint32_t _numGroups; |
|||
std::vector<MapGroup> _groups; |
|||
|
|||
public: |
|||
CmapTable8() : _is32Count(8192), _numGroups(0) {}; |
|||
~CmapTable8() {}; |
|||
CmapTable8(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 8) |
|||
return; |
|||
for (auto i = 0; i < _is32Count; i++) |
|||
{ |
|||
uint8_t u = rd->readUint8(); |
|||
_is32.push_back(u); |
|||
} |
|||
_numGroups = rd->readUint32(); |
|||
for (auto i = 0; i < _numGroups; i++) |
|||
{ |
|||
MapGroup mg(rd); |
|||
_groups.push_back(mg); |
|||
} |
|||
}; |
|||
list_uint8 is32() const { return _is32; }; |
|||
uint16_t numGroups() const { return _numGroups; }; |
|||
std::vector<MapGroup> groups() const { return _groups; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
//
|
|||
|
|||
class CmapTable10 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint32_t _startCharCode; |
|||
uint32_t _numChars; |
|||
list_uint16 _glyphldArray; |
|||
|
|||
public: |
|||
CmapTable10() : _startCharCode(0), _numChars(0) {}; |
|||
~CmapTable10() {}; |
|||
CmapTable10(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 10) |
|||
return; |
|||
_startCharCode = rd->readUint32(); |
|||
_numChars = rd->readUint32(); |
|||
while (rd->curr() < rd->getLength()) |
|||
{ |
|||
uint16_t glyph = rd->readUint16(); |
|||
_glyphldArray.push_back(glyph); |
|||
} |
|||
}; |
|||
uint32_t startCharCode() const { return _startCharCode; }; |
|||
uint32_t numChars() const { return _numChars; }; |
|||
list_uint16 glyphldArray() const { return _glyphldArray; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
//
|
|||
|
|||
class CmapTable12 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint32_t _numGroups; |
|||
std::vector<MapGroup> _groups; |
|||
|
|||
public: |
|||
CmapTable12() : _numGroups(0) {}; |
|||
~CmapTable12() {}; |
|||
CmapTable12(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 12) |
|||
return; |
|||
_numGroups = rd->readUint32(); |
|||
for (auto i = 0; i < _numGroups; i++) |
|||
{ |
|||
MapGroup mg(rd); |
|||
_groups.push_back(mg); |
|||
} |
|||
}; |
|||
uint16_t numGroups() const { return _numGroups; }; |
|||
std::vector<MapGroup> groups() const { return _groups; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
//
|
|||
class CmapTable13 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint32_t _numGroups; |
|||
std::vector<MapGroup> _groups; |
|||
|
|||
public: |
|||
CmapTable13() : _numGroups(0) {}; |
|||
~CmapTable13() {}; |
|||
CmapTable13(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 13) |
|||
return; |
|||
_numGroups = rd->readUint32(); |
|||
for (auto i = 0; i < _numGroups; i++) |
|||
{ |
|||
MapGroup mg(rd); |
|||
_groups.push_back(mg); |
|||
} |
|||
}; |
|||
uint16_t numGroups() const { return _numGroups; }; |
|||
std::vector<MapGroup> groups() const { return _groups; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
//
|
|||
|
|||
class VariationSelector |
|||
{ |
|||
private: |
|||
uint24 _varSelector; // read 24 bit
|
|||
uint16_t _defualtUVSOffset; |
|||
uint16_t _nonDefaultUVSOffset; |
|||
|
|||
public: |
|||
VariationSelector() : _varSelector(0), _defualtUVSOffset(0), _nonDefaultUVSOffset(0) {}; |
|||
~VariationSelector() {}; |
|||
VariationSelector(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_varSelector = rd->readUint24(); |
|||
_defualtUVSOffset = rd->readUint16(); |
|||
_nonDefaultUVSOffset = rd->readUint16(); |
|||
}; |
|||
uint32_t varSelector() const { return _varSelector; }; |
|||
uint16_t defaultUVSOffset() const { return _defualtUVSOffset; }; |
|||
uint16_t nonDefaultUVSOffset() const { return _nonDefaultUVSOffset; }; |
|||
}; |
|||
|
|||
//
|
|||
class CmapTable14 : public CmapTableBase |
|||
{ |
|||
private: |
|||
uint32_t _numVarSelectorRecords; |
|||
std::vector<VariationSelector> _varSelector; |
|||
|
|||
public: |
|||
CmapTable14() : _numVarSelectorRecords(0) {}; |
|||
~CmapTable14() {}; |
|||
CmapTable14(reader *rd) : CmapTableBase(rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
if (format() != 14) |
|||
return; |
|||
_numVarSelectorRecords = rd->readUint32(); |
|||
for (auto i = 0; i < _numVarSelectorRecords; i++) |
|||
{ |
|||
VariationSelector vs(rd); |
|||
_varSelector.push_back(vs); |
|||
} |
|||
}; |
|||
uint32_t numVarSelectorRecords() const { return _numVarSelectorRecords; }; |
|||
std::vector<VariationSelector> varSelector() const { return _varSelector; }; |
|||
uint16 Format()override{return format();} |
|||
}; |
|||
|
|||
// default uvs table
|
|||
class UnicodeRange |
|||
{ |
|||
private: |
|||
uint24 _startUnicodeValue; |
|||
uint8_t _additionalCount; |
|||
|
|||
public: |
|||
UnicodeRange() : _startUnicodeValue(0), _additionalCount(0) {}; |
|||
~UnicodeRange() {}; |
|||
UnicodeRange(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_startUnicodeValue = rd->readUint24(); |
|||
_additionalCount = rd->readUint8(); |
|||
}; |
|||
uint32_t startUnicodeValue() const { return _startUnicodeValue; }; |
|||
uint8_t additionalCount() const { return _additionalCount; }; |
|||
}; |
|||
|
|||
class DefaultUVS |
|||
{ |
|||
private: |
|||
uint32_t _numUnicodeValueRanges; |
|||
std::vector<UnicodeRange> _ranges; |
|||
|
|||
public: |
|||
DefaultUVS() : _numUnicodeValueRanges(0) {}; |
|||
~DefaultUVS() {}; |
|||
DefaultUVS(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_numUnicodeValueRanges = rd->readInt32(); |
|||
for (auto i = 0; i < _numUnicodeValueRanges; i++) |
|||
{ |
|||
UnicodeRange ur(rd); |
|||
_ranges.push_back(ur); |
|||
} |
|||
}; |
|||
uint32_t numUnicodeValueRanges() const { return _numUnicodeValueRanges; }; |
|||
std::vector<UnicodeRange> range() const { return _ranges; }; |
|||
}; |
|||
|
|||
// non-default uvs table
|
|||
class UVSMapping |
|||
{ |
|||
private: |
|||
uint24 _unicodeValue; |
|||
uint16_t _glyphId; |
|||
|
|||
public: |
|||
UVSMapping() : _unicodeValue(0), _glyphId(0) {}; |
|||
~UVSMapping() {}; |
|||
UVSMapping(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_unicodeValue = rd->readUint24(); |
|||
_glyphId = rd->readUint16(); |
|||
}; |
|||
uint32_t unicodeValue() const { return _unicodeValue; }; |
|||
uint16_t glyphId() const { return _glyphId; }; |
|||
}; |
|||
|
|||
class NonDefaultUVS |
|||
{ |
|||
private: |
|||
uint32_t _numUVSMappings; |
|||
std::vector<UVSMapping> _uvsMappings; |
|||
|
|||
public: |
|||
NonDefaultUVS() : _numUVSMappings(0) {}; |
|||
~NonDefaultUVS() {}; |
|||
NonDefaultUVS(reader *rd) { read(rd); }; |
|||
void read(reader *rd) |
|||
{ |
|||
_numUVSMappings = rd->readUint32(); |
|||
for (auto i = 0; i < _numUVSMappings; i++) |
|||
{ |
|||
UVSMapping um(rd); |
|||
_uvsMappings.push_back(um); |
|||
} |
|||
}; |
|||
uint32_t numUVSMappings() const { return _numUVSMappings; }; |
|||
std::vector<UVSMapping> uvsMappings() const { return _uvsMappings; }; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,85 @@ |
|||
#ifndef __GLYF_H__ |
|||
#define __GLYF_H__ |
|||
#include "../../../reader/reader.h" |
|||
#define ON_CURVE_POINT 0x01 |
|||
#define X_SHORT_VECTOR 0x02 |
|||
#define Y_SHORT_VECTOR 0x04 |
|||
#define REPEAT_FLAG 0x08 |
|||
#define X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR 0x10 |
|||
#define Y_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR 0x20 |
|||
#define OVERLAP_SIMPLE 0x40 |
|||
#define FLAG_Reserved 0x80 |
|||
#define list_uint8 std::vector<uint8_t> |
|||
#define list_uint16 std::vector<uint16_t> |
|||
/*
|
|||
header 其实是字形的边界框 |
|||
*/ |
|||
class GlyfTableHeader |
|||
{ |
|||
private: |
|||
int16_t _numberOfContours; //非负数表示简单字形,负数表示复合字形
|
|||
int16_t _xMin; |
|||
int16_t _yMin; |
|||
int16_t _xMax; |
|||
int16_t _yMax; |
|||
|
|||
public: |
|||
GlyfTableHeader():_numberOfContours(0),_xMax(0),_yMax(0),_xMin(0),_yMin(0){}; |
|||
~GlyfTableHeader(){}; |
|||
GlyfTableHeader(reader* rd){read(rd);}; |
|||
void read(reader*rd){ |
|||
_numberOfContours = rd->readInt16(); |
|||
_xMin = rd->readInt16(); |
|||
_yMin = rd->readInt16(); |
|||
_xMax = rd->readInt16(); |
|||
_yMax = rd->readInt16(); |
|||
} |
|||
int16_t numberOfContours(){return _numberOfContours;}; |
|||
int16_t xMin(){return _xMin;}; |
|||
int16_t yMin()const{return _yMin;}; |
|||
int16_t xMax()const{return _xMax;}; |
|||
int16_t yMax()const{return _yMax;}; |
|||
}; |
|||
//
|
|||
class SimpleGlyfTable |
|||
{ |
|||
private: |
|||
uint16_t _numOfContours; |
|||
list_uint16 _endPtsOfContours; |
|||
uint16_t _instructionLength; |
|||
list_uint8 _instructions; |
|||
list_uint8 _flags; |
|||
list_uint16 _xCoordinates; |
|||
list_uint16 _yCoordinates; |
|||
|
|||
public: |
|||
SimpleGlyfTable() : _instructionLength(0), _numOfContours(0) {}; |
|||
~SimpleGlyfTable() {}; |
|||
SimpleGlyfTable(uint16_t numOfContours, reader *rd) |
|||
{ |
|||
_numOfContours = numOfContours; |
|||
read(rd); |
|||
}; |
|||
void read(reader *rd) |
|||
{ |
|||
for (auto i = 0; i < _numOfContours; i++) |
|||
{ |
|||
uint16_t n = rd->readUint16(); |
|||
_endPtsOfContours.push_back(n); |
|||
} |
|||
_instructionLength = rd->readUint16(); |
|||
for (auto i = 0; i < _instructionLength; i++) |
|||
{ |
|||
uint8_t n = rd->readUint8(); |
|||
_instructions.push_back(n); |
|||
} |
|||
}; |
|||
list_uint16 endPtsOfContours() { return _endPtsOfContours; }; |
|||
uint16_t instructionLength() { return _instructionLength; }; |
|||
list_uint8 instructions() { return _instructions; }; |
|||
list_uint8 flags() { return _flags; }; |
|||
list_uint16 xCoordinates() { return _xCoordinates; }; |
|||
list_uint16 yCoordinates() { return _yCoordinates; }; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,90 @@ |
|||
#ifndef __TABLE_HEAD_H__ |
|||
#define __TABLE_HEAD_H__ |
|||
#include "../../../reader/reader.h" |
|||
|
|||
class HeadTable |
|||
{ |
|||
private: |
|||
uint16 _majorVersion; |
|||
uint16 _minorVersion; |
|||
Fixed _fontRevision; |
|||
uint32 _checksumAdjustment; |
|||
uint32 _magicNumber; |
|||
uint16 _flags; |
|||
uint16 _unitsPerEm; |
|||
LONGDATETIME _created; |
|||
LONGDATETIME _modified; |
|||
int16 _xMin; |
|||
int16 _yMin; |
|||
int16 _xMax; |
|||
int16 _yMax; |
|||
uint16 _maxStyle; |
|||
uint16 _lowestRecPPEM; |
|||
int16 _fontDirectHint; |
|||
int16 _indexToLocFormat; |
|||
int16 _glyphDataFormat; |
|||
|
|||
public: |
|||
HeadTable() : _majorVersion(0), |
|||
_minorVersion(0), |
|||
_fontRevision(), |
|||
_checksumAdjustment(0), |
|||
_magicNumber(0), |
|||
_flags(0), |
|||
_unitsPerEm(0), |
|||
_created(0), |
|||
_modified(0), |
|||
_xMin(0), |
|||
_yMin(0), |
|||
_xMax(0), |
|||
_yMax(0), |
|||
_maxStyle(0), |
|||
_lowestRecPPEM(0), |
|||
_fontDirectHint(0), |
|||
_indexToLocFormat(0), |
|||
_glyphDataFormat(0) {}; |
|||
~HeadTable() {}; |
|||
HeadTable(reader *rd) { read(rd); } |
|||
void read(reader *rd) |
|||
{ |
|||
_majorVersion = rd->readUint16(); |
|||
_minorVersion = rd->readUint16(); |
|||
_fontRevision = rd->readFixed(); |
|||
_checksumAdjustment = rd->readUint32(); |
|||
_magicNumber = rd->readUint32(); |
|||
_flags = rd->readUint16(); |
|||
_unitsPerEm = rd->readUint16(); |
|||
_created = rd->readUint64(); |
|||
_modified = rd->readUint64(); |
|||
_xMin = rd->readInt16(); |
|||
_yMin = rd->readInt16(); |
|||
_xMax = rd->readInt16(); |
|||
_yMax = rd->readInt16(); |
|||
_maxStyle = rd->readUint16(); |
|||
_lowestRecPPEM = rd->readUint16(); |
|||
_fontDirectHint = rd->readInt16(); |
|||
_indexToLocFormat = rd->readInt16(); |
|||
_glyphDataFormat = rd->readInt16(); |
|||
} |
|||
|
|||
uint16 majorVersion() { return _majorVersion; } |
|||
uint16 minorVersion() { return _minorVersion; } |
|||
Fixed fontRevision() { return _fontRevision; } |
|||
uint32 checksumAdjustment() { return _checksumAdjustment; } |
|||
uint32 magicNumber() { return _magicNumber; } |
|||
uint16 flags() { return _flags; } |
|||
uint16 unitsPerEm() { return _unitsPerEm; } |
|||
LONGDATETIME created() { return _created; } |
|||
LONGDATETIME modified() { return _modified; } |
|||
int16 xMin() { return _xMin; } |
|||
int16 yMin() { return _yMin; } |
|||
int16 xMax() { return _xMax; } |
|||
int16 yMax() { return _yMax; } |
|||
uint16 maxStyle() { return _maxStyle; } |
|||
uint16 lowestRecPPEM() { return _lowestRecPPEM; } |
|||
int16 fontDirectHint() { return _fontDirectHint; } |
|||
int16 indexToLocFormat() { return _indexToLocFormat; } |
|||
int16 glyphDataFormat() { return _glyphDataFormat; } |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,60 @@ |
|||
#ifndef __TABLE_LOCA_H__ |
|||
#define __TABLE_LOCA_H__ |
|||
#include "../../../reader/reader.h" |
|||
#define LocaShortFormat 0 |
|||
#define LocaLongFormat 1 |
|||
class LocaTable |
|||
{ |
|||
private: |
|||
uint16 _numGlyphs; |
|||
public: |
|||
LocaTable():_numGlyphs(0){}; |
|||
~LocaTable(){}; |
|||
LocaTable(uint16 i):_numGlyphs(i){} |
|||
uint16 numGlyphs(){return _numGlyphs;} |
|||
}; |
|||
|
|||
class LocaTableShort: public LocaTable |
|||
{ |
|||
private: |
|||
uint16 _indexToLocFormat; |
|||
std::vector<Offset16> _offsets; |
|||
public: |
|||
LocaTableShort():_indexToLocFormat(LocaShortFormat){}; |
|||
~LocaTableShort(){}; |
|||
LocaTableShort(uint16 num):LocaTable(num),_indexToLocFormat(LocaShortFormat){} |
|||
LocaTableShort(uint16 num, reader *rd):LocaTable(num),_indexToLocFormat(LocaShortFormat){read(rd);} |
|||
void read(reader *rd){ |
|||
for(auto i=0;i<numGlyphs();i++){ |
|||
Offset16 o = rd->readOffset16(); |
|||
_offsets.push_back(o); |
|||
} |
|||
} |
|||
uint16 format(){return _indexToLocFormat;} |
|||
std::vector<Offset16> offsets(){return _offsets;} |
|||
}; |
|||
|
|||
|
|||
class LocaTableLong: public LocaTable |
|||
{ |
|||
private: |
|||
uint16 _indexToLocFormat; |
|||
std::vector<Offset32> _offsets; |
|||
public: |
|||
LocaTableLong():_indexToLocFormat(LocaLongFormat){}; |
|||
~LocaTableLong(){}; |
|||
LocaTableLong(uint16 num):LocaTable(num),_indexToLocFormat(LocaLongFormat){} |
|||
LocaTableLong(uint16 num, reader *rd):LocaTable(num),_indexToLocFormat(LocaLongFormat){read(rd);} |
|||
void read(reader *rd){ |
|||
for(auto i=0;i<numGlyphs();i++){ |
|||
Offset32 o = rd->readOffset32(); |
|||
_offsets.push_back(o); |
|||
} |
|||
} |
|||
uint16 format(){return _indexToLocFormat;} |
|||
std::vector<Offset32> offsets(){return _offsets;} |
|||
}; |
|||
|
|||
|
|||
|
|||
#endif |
@ -0,0 +1,84 @@ |
|||
#ifndef __TABLE_MAXP_H__ |
|||
#define __TABLE_MAXP_H__ |
|||
#include "../../../reader/reader.h" |
|||
|
|||
class MaxpTable |
|||
{ |
|||
private: |
|||
Version16Dot16 _version; |
|||
uint16 _numGlyphs; |
|||
|
|||
public: |
|||
MaxpTable() : _version(0x00005000), _numGlyphs(0) {}; |
|||
~MaxpTable() {}; |
|||
MaxpTable(uint32 n) : _version(n), _numGlyphs(0) {}; |
|||
MaxpTable(reader *rd) { read(rd); } |
|||
void read(reader *rd) |
|||
{ |
|||
_version = rd->readVersion16Dot16(); |
|||
_numGlyphs = rd->readUint16(); |
|||
} |
|||
Version16Dot16 version() { return _version; } |
|||
uint16 numGlyphs() { return _numGlyphs; } |
|||
}; |
|||
|
|||
|
|||
#define MaxpTable0Dot5 MaxpTable |
|||
|
|||
class MaxpTable1Dot0 : public MaxpTable |
|||
{ |
|||
private: |
|||
uint16 _maxPoints; |
|||
uint16 _maxContours; |
|||
uint16 _maxCompositePoints; |
|||
uint16 _maxCompositeContours; |
|||
uint16 _maxZones; |
|||
uint16 _maxTwilightPoints; |
|||
uint16 _maxStorage; |
|||
uint16 _maxFunctionDefs; |
|||
uint16 _maxInstructionDefs; |
|||
uint16 _maxStackElements; |
|||
uint16 _maxSizeOfInstructions; |
|||
uint16 _maxComponentElemets; |
|||
uint16 _maxComponentDepth; |
|||
|
|||
public: |
|||
MaxpTable1Dot0() : MaxpTable(0x00010000), _maxComponentDepth(0), _maxComponentElemets(0), _maxCompositeContours(0), |
|||
_maxCompositePoints(0), _maxContours(0), _maxFunctionDefs(0), _maxInstructionDefs(0), |
|||
_maxPoints(0), _maxSizeOfInstructions(0), _maxStackElements(0), _maxStorage(0), |
|||
_maxTwilightPoints(0), _maxZones(0) {}; |
|||
~MaxpTable1Dot0() {}; |
|||
MaxpTable1Dot0(reader *rd) { read(rd); } |
|||
void read(reader *rd) |
|||
{ |
|||
MaxpTable::read(rd); |
|||
_maxPoints = rd->readUint16(); |
|||
_maxContours = rd->readUint16(); |
|||
_maxCompositePoints = rd->readUint16(); |
|||
_maxCompositeContours = rd->readUint16(); |
|||
_maxZones = rd->readUint16(); |
|||
_maxTwilightPoints = rd->readUint16(); |
|||
_maxStorage = rd->readUint16(); |
|||
_maxFunctionDefs = rd->readUint16(); |
|||
_maxInstructionDefs = rd->readUint16(); |
|||
_maxStackElements = rd->readUint16(); |
|||
_maxSizeOfInstructions = rd->readUint16(); |
|||
_maxComponentElemets = rd->readUint16(); |
|||
_maxComponentDepth = rd->readUint16(); |
|||
} |
|||
uint16 maxPoints() { return _maxPoints; } |
|||
uint16 maxContours() { return _maxContours; } |
|||
uint16 maxCompositePoints() { return _maxCompositePoints; } |
|||
uint16 maxCompositeContours() { return _maxCompositeContours; } |
|||
uint16 maxZones() { return _maxZones; } |
|||
uint16 maxTwilightPoints() { return _maxTwilightPoints; } |
|||
uint16 maxStorage() { return _maxStorage; } |
|||
uint16 maxFunctionDefs() { return _maxFunctionDefs; } |
|||
uint16 maxInstructionDefs() { return _maxInstructionDefs; } |
|||
uint16 maxStackElements() { return _maxStackElements; } |
|||
uint16 maxSizeOfInstructions() { return _maxSizeOfInstructions; } |
|||
uint16 maxComponentElemets() { return _maxComponentElemets; } |
|||
uint16 maxComponentDepth() { return _maxComponentDepth; } |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,58 @@ |
|||
#include "name.h" |
|||
#include "../reader/buffer.h" |
|||
#include <iostream> |
|||
|
|||
NameTable::NameTable(reader *rd, uint16_t length){ |
|||
read(rd, length); |
|||
} |
|||
|
|||
void NameTable::readHeader(reader* rd){ |
|||
header.read(rd); |
|||
} |
|||
|
|||
void NameTable::read(reader* rd, uint16_t length){ |
|||
header.read(rd); //read header
|
|||
|
|||
for(auto i = 0; i<header.getRecordCount(); i++){ |
|||
readRecord(rd); |
|||
} |
|||
if(!rd->seek(header.getStorageOffset())){ |
|||
throw "file len too low"; |
|||
} |
|||
auto len = length - header.getStorageOffset(); |
|||
auto data = rd->readString(len); |
|||
buffer storageReader(data); |
|||
for(auto it : header.getNameRecords()){ |
|||
readName(&storageReader, it); |
|||
} |
|||
} |
|||
|
|||
|
|||
void NameTable::readRecord(reader* rd){ |
|||
nameRecord nr; |
|||
nr.platformId = rd->readUint16(); |
|||
nr.encodingId = rd->readUint16(); |
|||
nr.languageId = rd->readUint16(); |
|||
nr.nameId = rd->readUint16(); |
|||
nr.length = rd->readUint16(); |
|||
nr.offset = rd->readUint16(); |
|||
nr.display(); |
|||
header.addNameRecord(nr); |
|||
} |
|||
|
|||
void NameTable::readName(reader* rd, nameRecord nr){ |
|||
if(!rd->seek(nr.offset)){ |
|||
return; |
|||
} |
|||
|
|||
std::string s = rd->readString(nr.length); |
|||
names[nr.nameId] = s; |
|||
} |
|||
|
|||
void NameTable::display(){ |
|||
std::cout<<"this is the name infomation of the font:"<<std::endl; |
|||
header.display(); |
|||
for(auto it: names){ |
|||
std::cout<<"id:"<<it.first<<"\tvalue:"<<it.second<<std::endl; |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
#ifndef __NAME_H__ |
|||
#define __NAME_H__ |
|||
#include <cstdint> |
|||
#include <list> |
|||
#include <string> |
|||
#include <map> |
|||
#include "../../../reader/reader.h" |
|||
#include "name_head.h" |
|||
|
|||
|
|||
|
|||
class NameTable |
|||
{ |
|||
private: |
|||
uint16_t offset; |
|||
uint16_t len; |
|||
nameTableHeader header; |
|||
std::map<int, std::string> names; |
|||
|
|||
public: |
|||
NameTable():offset(0),len(0),header(),names({}){}; |
|||
~NameTable() {}; |
|||
NameTable(reader *, uint16_t); |
|||
void readHeader(reader*); |
|||
void read(reader *, uint16_t); |
|||
void readRecord(reader *); |
|||
void display(); |
|||
void readName(reader*, nameRecord); |
|||
}; |
|||
#endif |
@ -0,0 +1,40 @@ |
|||
#include "name_head.h" |
|||
#include <iostream> |
|||
void nameTableHeader::display() |
|||
{ |
|||
std::cout << "the header of name table:" << std::endl; |
|||
std::cout << "version:" << version << "\trecordsCount:" << recordsCount << "\tstorageOffset:" << storageOffset << std::endl; |
|||
std::cout<<"langTags: "<<langTagCount<<std::endl; |
|||
// for(auto it : nameRecords){
|
|||
// it.display();
|
|||
// }
|
|||
} |
|||
|
|||
void nameTableHeader::read(reader *rd) |
|||
{ |
|||
version = rd->readUint16(); |
|||
recordsCount = rd->readUint16(); |
|||
storageOffset = rd->readUint16(); |
|||
// read language tag
|
|||
if (version == 1) |
|||
{ |
|||
langTagCount = rd->readUint16(); |
|||
for (auto i = 0; i < langTagCount; i++) |
|||
{ |
|||
//
|
|||
readLangTag(rd); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void nameTableHeader::readLangTag(reader *rd) |
|||
{ |
|||
langTagRecord lt; |
|||
lt.length = rd->readUint16(); |
|||
lt.offset = rd->readUint16(); |
|||
langTagRecords.push_back(lt); |
|||
} |
|||
|
|||
void nameTableHeader::addNameRecord(nameRecord nr){ |
|||
nameRecords.push_back(nr); |
|||
} |
@ -0,0 +1,52 @@ |
|||
#ifndef __NAME_HEAD_H__ |
|||
#define __NAME_HEAD_H__ |
|||
// 表格式, apple only support ver 0
|
|||
#include <cstdint> |
|||
#include <list> |
|||
#include "../../../reader/reader.h" |
|||
#include <iostream> |
|||
// 名称记录
|
|||
class nameRecord |
|||
{ |
|||
public: |
|||
uint16_t platformId; |
|||
uint16_t encodingId; |
|||
uint16_t languageId; |
|||
uint16_t nameId; |
|||
uint16_t length; |
|||
uint16_t offset; |
|||
void display() |
|||
{ |
|||
std::cout << "nameRecord: " << nameId <<" language: "<<languageId<< " len:" << length << " offset: " << offset << std::endl; |
|||
} |
|||
}; |
|||
//
|
|||
struct langTagRecord |
|||
{ |
|||
uint16_t length; |
|||
uint16_t offset; |
|||
}; |
|||
|
|||
class nameTableHeader |
|||
{ |
|||
private: |
|||
uint16_t version; |
|||
uint16_t recordsCount; |
|||
uint16_t storageOffset; |
|||
std::list<nameRecord> nameRecords; |
|||
uint16_t langTagCount; // only ver 1, apple not support
|
|||
std::list<langTagRecord> langTagRecords; // only ver 1, apple not support
|
|||
public: |
|||
nameTableHeader() : version(0), recordsCount(0), storageOffset(0), nameRecords(), langTagCount(0), langTagRecords() {}; |
|||
~nameTableHeader() {}; |
|||
void display(); |
|||
uint16_t getVersion() { return version; }; |
|||
uint16_t getRecordCount() { return recordsCount; }; |
|||
uint16_t getStorageOffset() { return storageOffset; }; |
|||
std::list<nameRecord> getNameRecords() { return nameRecords; }; |
|||
void read(reader *); |
|||
void readLangTag(reader *rd); |
|||
void addNameRecord(nameRecord); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,28 @@ |
|||
enum NameID { |
|||
Copyright, |
|||
FontFamily, |
|||
FontSubFamily, |
|||
UniqueFontID, |
|||
FullFontName, |
|||
Version, |
|||
PostScriptName, |
|||
Trademark, |
|||
ManufacturerName, |
|||
Designer, |
|||
Description, |
|||
VendorURL, |
|||
DesignerURL, |
|||
LicenseDescription, |
|||
LicenseInfoURL, |
|||
Reserved, |
|||
TypographicFamily, |
|||
TypographicSubFamily, |
|||
CompatibleFullName, //only macintosh
|
|||
SampleText, |
|||
PostscriptCID, |
|||
WWSFamily, |
|||
WWSSubFamily, |
|||
LightBackgroundPallete, |
|||
DarkBackgroundPallete, |
|||
VariationScriptNamePrefix, |
|||
}; |
@ -0,0 +1,49 @@ |
|||
enum PlatformID { |
|||
Unicode, |
|||
Macintosh, |
|||
Reserved, |
|||
Microsoft, |
|||
}; |
|||
|
|||
enum UnicodePlatformSpecificID { |
|||
Version1dot0, |
|||
Version1dot1, |
|||
ISO10646, |
|||
Unicode2OnlyBMP, |
|||
Unicode2NoBMP |
|||
}; |
|||
|
|||
enum MacintoshPlatformSpecificID { |
|||
Roman, |
|||
Japanese, |
|||
TraditionalChinese, |
|||
Korean, |
|||
Arabic, |
|||
Hebrew, |
|||
Greek, |
|||
Russian, |
|||
RSymbol, |
|||
Devanagari, |
|||
Gurmukhi, |
|||
Gujarati, |
|||
Oriya, |
|||
Bengali, |
|||
Tamil, |
|||
Telugu, |
|||
Kannada, |
|||
Malayalam, |
|||
Sinhalese, |
|||
Burmese, |
|||
Thai, |
|||
Laotian, |
|||
Georgian, |
|||
Armenian, |
|||
SimplifiedChinese, |
|||
Tibetan, |
|||
Mongolian, |
|||
Geez, |
|||
Slavic, |
|||
Vietnamese, |
|||
Sindhi, |
|||
Uniterpreted, |
|||
}; |
@ -0,0 +1,90 @@ |
|||
#include "table.h" |
|||
#include "table_name.h" |
|||
#include "../reader/buffer.h" |
|||
#include <iostream> |
|||
void FontTable::display() |
|||
{ |
|||
std::cout<<"table lists:"<<std::endl; |
|||
for(auto it : _tables){ |
|||
std::cout<<"table "<<it.name<<" length:"<<it.length<<"\toffset:"<<it.offset<<"\tsum:"<<it.sum<<std::endl; |
|||
auto iter = tableNameMap.find(it.name); |
|||
if (iter == tableNameMap.end()) |
|||
{ |
|||
continue; |
|||
} |
|||
auto id = (*iter).second; |
|||
switch (id) |
|||
{ |
|||
case name: |
|||
_name->display(); |
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void FontTable::read(reader *rd, uint16_t count) |
|||
{ |
|||
for (auto i = 0; i < count; i++) |
|||
{ |
|||
table t; |
|||
t.name = rd->readString(4); |
|||
t.sum = rd->readUint32(); |
|||
t.offset = rd->readUint32(); |
|||
t.length = rd->readUint32(); |
|||
_tables.push_back(t); |
|||
} |
|||
//读取表详情
|
|||
for (auto it: _tables) |
|||
{ |
|||
auto iter = tableNameMap.find(it.name); |
|||
if (iter == tableNameMap.end()) |
|||
{ |
|||
continue; |
|||
} |
|||
auto id = (*iter).second; |
|||
switch (id) |
|||
{ |
|||
case tableName::name: |
|||
{ |
|||
if(!rd->seek(it.offset)){ |
|||
throw "seek file failed"; |
|||
}; |
|||
auto data = rd->readString(it.length); |
|||
buffer nameReader(data); |
|||
_name = new NameTable(); |
|||
_name->read(&nameReader, it.length); |
|||
} |
|||
break; |
|||
case tableName::cmap: |
|||
{ |
|||
|
|||
break; |
|||
} |
|||
case tableName::BASE: |
|||
{ |
|||
break; |
|||
} |
|||
case tableName::head: |
|||
{ |
|||
break; |
|||
} |
|||
case tableName::maxp: |
|||
{ |
|||
break; |
|||
} |
|||
case tableName::glyf: |
|||
{ |
|||
break; |
|||
} |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
std::vector<table> FontTable::tables(){ |
|||
return _tables; |
|||
} |
@ -0,0 +1,65 @@ |
|||
#ifndef __TABLE_H__ |
|||
#define __TABLE_H__ |
|||
#include "name/name.h" |
|||
#include "../../reader/reader.h" |
|||
#include <string> |
|||
#include "cmap/cmap.h" |
|||
#include "base/base.h" |
|||
#include "glyf/glyf.h" |
|||
#include "head/head.h" |
|||
#include "name/name.h" |
|||
#include "loca/loca.h" |
|||
#include "maxp/maxp.h" |
|||
struct table |
|||
{ |
|||
std::string name; |
|||
uint32_t sum; |
|||
uint32_t offset; |
|||
uint32_t length; |
|||
}; |
|||
|
|||
|
|||
class FontTable |
|||
{ |
|||
private: |
|||
std::vector<table> _tables; |
|||
HeadTable* _head; |
|||
NameTable* _name; |
|||
BaseHeader1* _base; |
|||
CmapTable* _cmap; |
|||
MaxpTable* _maxp; |
|||
LocaTable* _loca; |
|||
|
|||
public: |
|||
FontTable(){}; |
|||
~FontTable(){ |
|||
if(_head!=nullptr){ |
|||
delete _head; |
|||
} |
|||
if(_name != nullptr){ |
|||
delete _name; |
|||
} |
|||
if(_base != nullptr){ |
|||
delete _base; |
|||
} |
|||
if(_cmap!= nullptr){ |
|||
delete _cmap; |
|||
} |
|||
if(_maxp!=nullptr){ |
|||
delete _maxp; |
|||
} |
|||
if(_loca!=nullptr){ |
|||
delete _loca; |
|||
} |
|||
}; |
|||
void display(); |
|||
void read(reader*, uint16_t); |
|||
std::vector<table> tables(); |
|||
}; |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
#endif |
@ -0,0 +1,164 @@ |
|||
#ifndef __TABLE_NAME_H__ |
|||
#define __TABLE_NAME_H__ |
|||
#include <map> |
|||
#include <string> |
|||
|
|||
|
|||
#define TABLE_NAME_OS2 = "OS/2" |
|||
#define TABLE_NAME_NAME = "name" |
|||
#define TABLE_NAME_AVAR = "avar" |
|||
#define TABLE_NAME_BASE = "BASE" |
|||
#define TABLE_NAME_CBDT = "CBDT" |
|||
#define TABLE_NAME_CBLC = "CBLC" |
|||
#define TABLE_NAME_CFF = "CFF" |
|||
#define TABLE_NAME_CFF2 = "CFF2" |
|||
#define TABLE_NAME_CMAP = "cmap" |
|||
#define TABLE_NAME_COLR = "COLR" |
|||
#define TABLE_NAME_CPAL = "CPAL" |
|||
#define TABLE_NAME_CVAR = "cvar" |
|||
#define TABLE_NAME_CVT = "cvt" |
|||
#define TABLE_NAME_DSIG = "DSIG" |
|||
#define TABLE_NAME_EBDT = "EBDT" |
|||
#define TABLE_NAME_EBLC = "EBLC" |
|||
#define TABLE_NAME_EBSC = "EBSC" |
|||
#define TABLE_NAME_FPGM = "fpgm" |
|||
#define TABLE_NAME_FVAR = "fvar" |
|||
#define TABLE_NAME_GASP = "gasp" |
|||
#define TABLE_NAME_GDEF = "GDEF" |
|||
#define TABLE_NAME_GLYF = "glyf" |
|||
#define TABLE_NAME_GPOS = "GPOS" |
|||
#define TABLE_NAME_GSUB = "GSUB" |
|||
#define TABLE_NAME_GVAR = "gvar" |
|||
#define TABLE_NAME_HDMX = "hdmx" |
|||
#define TABLE_NAME_HEAD = "head" |
|||
#define TABLE_NAME_HHEA = "hhea" |
|||
#define TABLE_NAME_HMTX = "hmtx" |
|||
#define TABLE_NAME_HVAR = "HVAR" |
|||
#define TABLE_NAME_JSTF = "JSTF" |
|||
#define TABLE_NAME_KERN = "kern" |
|||
#define TABLE_NAME_LOCA = "loca" |
|||
#define TABLE_NAME_LTSH = "LTSH" |
|||
#define TABLE_NAME_MATH = "MATH" |
|||
#define TABLE_NAME_MAXP = "maxp" |
|||
#define TABLE_NAME_MERG = "MERG" |
|||
#define TABLE_NAME_META = "meta" |
|||
#define TABLE_NAME_MVAR = "MVAR" |
|||
#define TABLE_NAME_PCLT = "PCLT" |
|||
#define TABLE_NAME_POST = "post" |
|||
#define TABLE_NAME_PREP = "prep" |
|||
#define TABLE_NAME_SBIX = "sbix" |
|||
#define TABLE_NAME_STAT = "STAT" |
|||
#define TABLE_NAME_SVG = "SVG" |
|||
#define TABLE_NAME_VDMX = "VDMX" |
|||
#define TABLE_NAME_VHEA = "vhea" |
|||
#define TABLE_NAME_VMTX = "vmtx" |
|||
#define TABLE_NAME_VORG = "VORG" |
|||
#define TABLE_NAME_VVAR = "VVAR" |
|||
|
|||
enum tableName |
|||
{ |
|||
os2, |
|||
name, |
|||
avar, |
|||
BASE, |
|||
CBDT, |
|||
CBLC, |
|||
CFF, |
|||
CFF2, |
|||
cmap, |
|||
COLR, |
|||
CPAL, |
|||
cvar, |
|||
cvt, |
|||
DSIG, |
|||
EBDT, |
|||
EBLC, |
|||
EBSC, |
|||
fpgm, |
|||
fvar, |
|||
gasp, |
|||
GDEF, |
|||
glyf, |
|||
GPOS, |
|||
GSUB, |
|||
gvar, |
|||
hdmx, |
|||
head, |
|||
hhea, |
|||
hmtx, |
|||
HVAR, |
|||
JSTF, |
|||
kern, |
|||
loca, |
|||
LTSH, |
|||
MATH, |
|||
maxp, |
|||
MERG, |
|||
meta, |
|||
MVAR, |
|||
PCLT, |
|||
post, |
|||
prep, |
|||
sbix, |
|||
STAT, |
|||
SVG, |
|||
VDMX, |
|||
vhea, |
|||
vmtx, |
|||
VORG, |
|||
VVAR, |
|||
}; |
|||
|
|||
const static std::map<std::string, tableName> tableNameMap = { |
|||
{"OS/2", os2}, |
|||
{"name", name}, |
|||
{"avar", avar}, |
|||
{"BASE", BASE}, |
|||
{"CBDT", CBDT}, |
|||
{"CBLC", CBLC}, |
|||
{"CFF", CFF}, |
|||
{"CFF2", CFF2}, |
|||
{"cmap", cmap}, |
|||
{"COLR", COLR}, |
|||
{"CPAL", CPAL}, |
|||
{"cvar", cvar}, |
|||
{"cvt", cvt}, |
|||
{"DSIG", DSIG}, |
|||
{"EBDT", EBDT}, |
|||
{"EBLC", EBLC}, |
|||
{"EBSC", EBSC}, |
|||
{"fpgm", fpgm}, |
|||
{"fvar", fvar}, |
|||
{"gasp", gasp}, |
|||
{"GDEF", GDEF}, |
|||
{"glyf", glyf}, |
|||
{"GPOS", GPOS}, |
|||
{"GSUB", GSUB}, |
|||
{"gvar", gvar}, |
|||
{"hdmx", hdmx}, |
|||
{"head", head}, |
|||
{"hhea", hhea}, |
|||
{"hmtx", hmtx}, |
|||
{"HVAR", HVAR}, |
|||
{"JSTF", JSTF}, |
|||
{"kern", kern}, |
|||
{"loca", loca}, |
|||
{"LTSH", LTSH}, |
|||
{"MATH", MATH}, |
|||
{"maxp", maxp}, |
|||
{"MERG", MERG}, |
|||
{"meta", meta}, |
|||
{"MVAR", MVAR}, |
|||
{"PCLT", PCLT}, |
|||
{"post", post}, |
|||
{"prep", prep}, |
|||
{"sbix", sbix}, |
|||
{"STAT", STAT}, |
|||
{"SVG", SVG}, |
|||
{"VDMX", VDMX}, |
|||
{"vhea", vhea}, |
|||
{"vmtx", vmtx}, |
|||
{"VORG", VORG}, |
|||
{"VVAR", VVAR}, |
|||
}; |
|||
#endif |
@ -0,0 +1,173 @@ |
|||
#ifndef __FONT_TYPES_H__ |
|||
#define __FONT_TYPES_H__ |
|||
#include <cstdint> |
|||
#include <list> |
|||
#include <vector> |
|||
#include <map> |
|||
#include <iostream> |
|||
#define uint8 uint8_t |
|||
#define uint16 uint16_t |
|||
#define uint32 uint32_t |
|||
#define int8 int8_t |
|||
#define int16 int16_t |
|||
#define int32 int32_t |
|||
#define FWORD int16_t |
|||
#define UFWORD uint16_t |
|||
#define LONGDATETIME uint64_t |
|||
#define Offset8 uint8_t |
|||
#define Offset16 uint16_t |
|||
#define Offset24 uint24_t |
|||
#define Offset32 uint32_t |
|||
#define uint24 uint24_t |
|||
#define int24 int24_t |
|||
|
|||
class uint24_t |
|||
{ |
|||
private: |
|||
uint32 _value; |
|||
|
|||
public: |
|||
uint24_t() : _value(0) {}; |
|||
~uint24_t() {}; |
|||
explicit uint24_t(uint32 i) : _value(i & 0xFFFFFF) {}; |
|||
operator uint32_t() const { return _value; }; |
|||
|
|||
public: |
|||
friend std::ostream &operator<<(std::ostream &os, const uint24_t &u) |
|||
{ |
|||
return os << u._value; |
|||
}; |
|||
friend std::istream &operator>>(std::istream &in, uint24_t &u) |
|||
{ |
|||
uint8_t bytes[3]; |
|||
in.read(reinterpret_cast<char *>(bytes), 3); |
|||
uint32_t ret = (static_cast<uint32_t>(bytes[2]) << 16) | (static_cast<uint32_t>(bytes[1]) << 8) | static_cast<uint32_t>(bytes[0]); |
|||
u._value = ret & 0xFFFFFF; |
|||
return in; |
|||
}; |
|||
|
|||
uint24_t operator+(const uint24_t &o) const |
|||
{ |
|||
return uint24_t(_value + o._value); |
|||
} |
|||
uint24_t operator-(const uint24_t &o) const |
|||
{ |
|||
return uint24_t(_value - o._value); |
|||
} |
|||
}; |
|||
|
|||
class int24_t |
|||
{ |
|||
private: |
|||
int32 _value; |
|||
|
|||
public: |
|||
int24_t() : _value(0) {}; |
|||
~int24_t() {}; |
|||
explicit int24_t(uint32 i) : _value(i & 0xFFFFFF) {}; |
|||
operator int32_t() const { return _value; }; |
|||
|
|||
public: |
|||
friend std::ostream &operator<<(std::ostream &os, const int24_t &u) |
|||
{ |
|||
return os << u._value; |
|||
}; |
|||
friend std::istream &operator>>(std::istream &in, int24_t &u) |
|||
{ |
|||
int8_t bytes[3]; |
|||
in.read(reinterpret_cast<char *>(bytes), 3); |
|||
int32_t ret = (static_cast<int32_t>(bytes[2]) << 16) | (static_cast<int32_t>(bytes[1]) << 8) | static_cast<int32_t>(bytes[0]); |
|||
u._value = ret & 0xFFFFFF; |
|||
return in; |
|||
}; |
|||
|
|||
int24_t operator+(const int24_t &o) const |
|||
{ |
|||
return int24_t(_value + o._value); |
|||
} |
|||
int24_t operator-(const int24_t &o) const |
|||
{ |
|||
return int24_t(_value - o._value); |
|||
} |
|||
}; |
|||
|
|||
|
|||
class Fixed |
|||
{ |
|||
private: |
|||
int16 _num1; |
|||
int16 _num2; |
|||
|
|||
public: |
|||
Fixed():_num1(0),_num2(0){}; |
|||
~Fixed(){}; |
|||
friend std::ostream &operator<<(std::ostream& out, const Fixed& f){ |
|||
return out<<f._num1<<"."<<f._num2; |
|||
} |
|||
friend std::istream &operator>>(std::istream& in, Fixed& f){ |
|||
return in>>f._num1>>f._num2; |
|||
} |
|||
}; |
|||
|
|||
// 16-bit signed fixed number with the low 14 bits of fraction (2.14).
|
|||
class F2DOT14 |
|||
{ |
|||
private: |
|||
uint16 _value; |
|||
uint8 _integer; |
|||
uint16 _fraction; |
|||
|
|||
public: |
|||
F2DOT14():_value(0){}; |
|||
~F2DOT14(){}; |
|||
friend std::ostream &operator<<(std::ostream& out, const F2DOT14& f){ |
|||
return out<<f._integer<<"."<<f._fraction; |
|||
} |
|||
friend std::istream &operator>>(std::istream& in, F2DOT14& f){ |
|||
in>>f._value; |
|||
f._integer = f._value >>14 ; |
|||
f._fraction = f._value<<2 ; |
|||
return in; |
|||
} |
|||
}; |
|||
|
|||
class Tag |
|||
{ |
|||
private: |
|||
uint8 _byte1; |
|||
uint8 _byte2; |
|||
uint8 _byte3; |
|||
uint8 _byte4; |
|||
|
|||
public: |
|||
Tag():_byte1(0),_byte2(0),_byte3(0), _byte4(0){}; |
|||
~Tag(){}; |
|||
friend std::ostream &operator<<(std::ostream& out, const Tag& t){ |
|||
return out<<t._byte1<<t._byte2<<t._byte3<<t._byte4; |
|||
} |
|||
friend std::istream &operator>>(std::istream& in, Tag& t){ |
|||
in>>t._byte1>>t._byte2>>t._byte3>>t._byte4; |
|||
return in; |
|||
} |
|||
}; |
|||
|
|||
class Version16Dot16 |
|||
{ |
|||
private: |
|||
uint16 _majorVersion; |
|||
uint16 _minorVersion; |
|||
public: |
|||
Version16Dot16():_majorVersion(0),_minorVersion(0){}; |
|||
Version16Dot16(uint32 n):_majorVersion(n>>16 & 0xFFFF),_minorVersion(n<<16>>16 &0xFFFF){}; |
|||
~Version16Dot16(){}; |
|||
friend std::ostream &operator<<(std::ostream& out, const Version16Dot16& f){ |
|||
return out<<f._majorVersion<<"."<<f._minorVersion; |
|||
} |
|||
friend std::istream &operator>>(std::istream& in, Version16Dot16& f){ |
|||
in>>f._majorVersion>>f._minorVersion; |
|||
return in; |
|||
} |
|||
|
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,14 @@ |
|||
#ifndef __FONT_MATH_H__ |
|||
#define __FONT_MATH_H__ |
|||
#include <cstdint> |
|||
uint16_t highestBitValue(uint16_t x) { |
|||
if (x == 0) return 0; |
|||
uint16_t n = 0; |
|||
while (x > 1) { |
|||
x >>= 1; |
|||
n++; |
|||
} |
|||
return 1U << n; |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,13 @@ |
|||
#include "reader/file.h" |
|||
#include "core/font.h" |
|||
|
|||
int main(int argc, char const *argv[]) |
|||
{ |
|||
/* code */ |
|||
const char* fontFile = "/home/kun1h/fonts/fzmw.ttf"; |
|||
file rd(fontFile); |
|||
font font; |
|||
font.read(&rd); |
|||
font.display(); |
|||
return 0; |
|||
} |
@ -0,0 +1,10 @@ |
|||
set (SOURCE |
|||
reader.h |
|||
file.h |
|||
file.cpp |
|||
buffer.h |
|||
buffer.cpp |
|||
) |
|||
|
|||
project(fonts) |
|||
add_library(reader SHARED ${SOURCE}) |
@ -0,0 +1,146 @@ |
|||
#include "buffer.h" |
|||
#include <cstring> |
|||
#include <sstream> |
|||
#include "endian.h" |
|||
|
|||
|
|||
buffer::buffer(std::string data) |
|||
{ |
|||
fp = std::stringstream(data); |
|||
length = data.length(); |
|||
}; |
|||
|
|||
std::streamsize buffer::read(char *bytes, uint16_t l) |
|||
{ |
|||
fp.read(reinterpret_cast<char *>(bytes), l); |
|||
std::streamsize bytesRead = fp.gcount(); |
|||
return bytesRead; |
|||
}; |
|||
int8_t buffer::readInt8() |
|||
{ |
|||
int8_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
int16_t buffer::readInt16() |
|||
{ |
|||
int16_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
}; |
|||
|
|||
int32_t buffer::readInt32() |
|||
{ |
|||
int32_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
int64_t buffer::readInt64() |
|||
{ |
|||
uint64_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
uint8_t buffer::readUint8() |
|||
{ |
|||
uint8_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return ret; |
|||
} |
|||
|
|||
uint16_t buffer::readUint16() |
|||
{ |
|||
uint16_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
}; |
|||
|
|||
uint24_t buffer::readUint24(){ |
|||
uint24_t ret(0); |
|||
fp>>ret; |
|||
return ret; |
|||
} |
|||
|
|||
uint32_t buffer::readUint32() |
|||
{ |
|||
uint32_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe32(ret); |
|||
} |
|||
|
|||
uint64_t buffer::readUint64() |
|||
{ |
|||
uint64_t ret = 0; |
|||
fp.read(reinterpret_cast<char*>(&ret), sizeof(ret)); |
|||
return htobe64(ret); |
|||
} |
|||
|
|||
std::string buffer::readString(int l) |
|||
{ |
|||
char *data = new char[l]; |
|||
fp.read(data, l); |
|||
std::streamsize bytesRead = fp.gcount(); |
|||
auto ret = std::string(data, bytesRead); |
|||
delete[] data; |
|||
return ret; |
|||
} |
|||
FWORD buffer::readFWord(){ |
|||
return readInt16(); |
|||
} |
|||
UFWORD buffer::readUFWord(){ |
|||
return readUint16(); |
|||
} |
|||
Offset8 buffer::readOffset8(){ |
|||
return readUint8(); |
|||
} |
|||
Offset16 buffer::readOffset16(){ |
|||
return readUint16(); |
|||
} |
|||
Offset24 buffer::readOffset24(){ |
|||
return readUint24(); |
|||
} |
|||
Offset32 buffer::readOffset32(){ |
|||
return readUint32(); |
|||
} |
|||
int24_t buffer::readInt24(){ |
|||
int24_t i; |
|||
fp>>i; |
|||
return i; |
|||
} |
|||
Fixed buffer::readFixed(){ |
|||
Fixed f; |
|||
fp>>f; |
|||
return f; |
|||
} |
|||
F2DOT14 buffer::readF2Dot14(){ |
|||
F2DOT14 f; |
|||
fp>>f; |
|||
return f; |
|||
} |
|||
Version16Dot16 buffer::readVersion16Dot16(){ |
|||
Version16Dot16 v; |
|||
fp>>v; |
|||
return v; |
|||
} |
|||
Tag buffer::readTag(){ |
|||
Tag t; |
|||
fp>>t; |
|||
return t; |
|||
} |
|||
bool buffer::seek(int64_t i) |
|||
{ |
|||
if (i > length) |
|||
{ |
|||
return false; |
|||
} |
|||
fp.seekg(i); |
|||
return true; |
|||
} |
|||
|
|||
std::streampos buffer::curr() |
|||
{ |
|||
return fp.tellg(); |
|||
} |
@ -0,0 +1,44 @@ |
|||
#ifndef __READER_BUFFER_H__ |
|||
#define __READER_BUFFER_H__ |
|||
#include "reader.h" |
|||
#include <sstream> |
|||
|
|||
class buffer : public reader |
|||
{ |
|||
private: |
|||
std::stringstream fp; |
|||
std::streampos length; |
|||
|
|||
public: |
|||
buffer(/* args */) : length(0) {}; |
|||
~buffer() {}; |
|||
buffer(std::string data); |
|||
std::streamsize read(char *, uint16_t) override; |
|||
int8_t readInt8() override; |
|||
int16_t readInt16() override; |
|||
int32_t readInt32() override; |
|||
int64_t readInt64() override; |
|||
uint8_t readUint8() override; |
|||
uint16_t readUint16() override; |
|||
uint32_t readUint32() override; |
|||
uint64_t readUint64() override; |
|||
std::string readString(int) override; |
|||
bool seek(int64_t) override; |
|||
std::streampos curr() override; |
|||
std::string getPath() override { return ""; }; |
|||
std::streampos getLength() override { return length; }; |
|||
uint24_t readUint24() override; |
|||
FWORD readFWord() override; |
|||
UFWORD readUFWord() override; |
|||
Offset8 readOffset8() override; |
|||
Offset16 readOffset16() override; |
|||
Offset24 readOffset24() override; |
|||
Offset32 readOffset32() override; |
|||
int24_t readInt24() override; |
|||
Fixed readFixed() override; |
|||
F2DOT14 readF2Dot14() override; |
|||
Version16Dot16 readVersion16Dot16() override; |
|||
Tag readTag() override; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,174 @@ |
|||
#include "file.h" |
|||
#include <cstring> |
|||
#include <sstream> |
|||
#include <endian.h> |
|||
|
|||
file::file(const char *filePath) : reader() |
|||
{ |
|||
fp.open(filePath, std::ios::binary); |
|||
if (!fp.is_open()) |
|||
{ |
|||
throw "file now open"; |
|||
} |
|||
path = new char[std::strlen(filePath)]; |
|||
std::memcpy(path, filePath, std::strlen(filePath)); |
|||
fp.seekg(0, fp.end); |
|||
length = fp.tellg(); |
|||
fp.seekg(0, fp.beg); |
|||
}; |
|||
|
|||
std::streamsize file::read(char *bytes, uint16_t l) |
|||
{ |
|||
fp.read(bytes, l); |
|||
std::streamsize bytesRead = fp.gcount(); |
|||
return bytesRead; |
|||
}; |
|||
|
|||
int8_t file::readInt8() |
|||
{ |
|||
int8_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
int16_t file::readInt16() |
|||
{ |
|||
int16_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
}; |
|||
|
|||
int32_t file::readInt32() |
|||
{ |
|||
int32_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
int64_t file::readInt64() |
|||
{ |
|||
uint64_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
} |
|||
|
|||
uint8_t file::readUint8() |
|||
{ |
|||
uint8_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return ret; |
|||
} |
|||
|
|||
uint16_t file::readUint16() |
|||
{ |
|||
uint16_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe16(ret); |
|||
}; |
|||
|
|||
uint24_t file::readUint24() |
|||
{ |
|||
uint24_t ret(0); |
|||
fp >> ret; |
|||
return ret; |
|||
} |
|||
|
|||
uint32_t file::readUint32() |
|||
{ |
|||
uint32_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe32(ret); |
|||
} |
|||
|
|||
uint64_t file::readUint64() |
|||
{ |
|||
uint64_t ret = 0; |
|||
fp.read(reinterpret_cast<char *>(&ret), sizeof(ret)); |
|||
return htobe64(ret); |
|||
} |
|||
|
|||
std::string file::readString(int l) |
|||
{ |
|||
char *data = new char[l]; |
|||
fp.read(data, l); |
|||
std::streamsize bytesRead = fp.gcount(); |
|||
auto ret = std::string(data, bytesRead); |
|||
delete[] data; |
|||
return ret; |
|||
} |
|||
|
|||
FWORD file::readFWord(){ |
|||
return readInt16(); |
|||
} |
|||
UFWORD file::readUFWord(){ |
|||
return readUint16(); |
|||
} |
|||
Offset8 file::readOffset8(){ |
|||
return readUint8(); |
|||
} |
|||
Offset16 file::readOffset16(){ |
|||
return readUint16(); |
|||
} |
|||
Offset24 file::readOffset24(){ |
|||
return readUint24(); |
|||
} |
|||
Offset32 file::readOffset32(){ |
|||
return readUint32(); |
|||
} |
|||
int24_t file::readInt24(){ |
|||
int24_t i; |
|||
fp>>i; |
|||
return i; |
|||
} |
|||
Fixed file::readFixed(){ |
|||
Fixed f; |
|||
fp>>f; |
|||
return f; |
|||
} |
|||
F2DOT14 file::readF2Dot14(){ |
|||
F2DOT14 f; |
|||
fp>>f; |
|||
return f; |
|||
} |
|||
Version16Dot16 file::readVersion16Dot16(){ |
|||
Version16Dot16 v; |
|||
fp>>v; |
|||
return v; |
|||
} |
|||
Tag file::readTag(){ |
|||
Tag t; |
|||
fp>>t; |
|||
return t; |
|||
} |
|||
|
|||
bool file::seek(int64_t i) |
|||
{ |
|||
if (i > length) |
|||
{ |
|||
return false; |
|||
} |
|||
fp.seekg(i); |
|||
return true; |
|||
} |
|||
|
|||
std::streampos file::curr() |
|||
{ |
|||
return fp.tellg(); |
|||
} |
|||
|
|||
std::string file::getPath() |
|||
{ |
|||
return path; |
|||
} |
|||
|
|||
file::~file() |
|||
{ |
|||
if (fp.is_open()) |
|||
{ |
|||
fp.close(); |
|||
} |
|||
if (path != nullptr) |
|||
{ |
|||
delete path; |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
#ifndef __READER_FILE_H__ |
|||
#define __READER_FILE_H__ |
|||
#include "reader.h" |
|||
#include <fstream> |
|||
|
|||
class file : public reader |
|||
{ |
|||
private: |
|||
std::ifstream fp; |
|||
char *path; |
|||
std::streampos length; |
|||
|
|||
public: |
|||
file() : path(nullptr), length(0), fp() {}; |
|||
~file(); |
|||
file(const char *filePath); |
|||
std::streamsize read(char *, uint16_t) override; |
|||
int8_t readInt8() override; |
|||
int16_t readInt16() override; |
|||
int32_t readInt32() override; |
|||
int64_t readInt64() override; |
|||
uint8_t readUint8() override; |
|||
uint16_t readUint16() override; |
|||
uint32_t readUint32() override; |
|||
uint64_t readUint64() override; |
|||
std::string readString(int) override; |
|||
bool seek(int64_t) override; |
|||
std::streampos curr() override; |
|||
std::string getPath() override; |
|||
std::streampos getLength() override { return length; }; |
|||
uint24_t readUint24() override; |
|||
FWORD readFWord() override; |
|||
UFWORD readUFWord() override; |
|||
Offset8 readOffset8() override; |
|||
Offset16 readOffset16() override; |
|||
Offset24 readOffset24() override; |
|||
Offset32 readOffset32() override; |
|||
int24_t readInt24() override; |
|||
Fixed readFixed() override; |
|||
F2DOT14 readF2Dot14() override; |
|||
Version16Dot16 readVersion16Dot16() override; |
|||
Tag readTag() override; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,41 @@ |
|||
#ifndef __READER_H__ |
|||
#define __READER_H__ |
|||
|
|||
#include <fstream> |
|||
#include <string> |
|||
#include "../types/types.h" |
|||
class reader |
|||
{ |
|||
private: |
|||
public: |
|||
reader(/* args */) {}; |
|||
virtual ~reader() {}; |
|||
virtual std::streamsize read(char *, uint16_t) = 0; |
|||
virtual int8_t readInt8() = 0; |
|||
virtual int16_t readInt16() = 0; |
|||
virtual int32_t readInt32() = 0; |
|||
virtual int64_t readInt64() = 0; |
|||
virtual uint8_t readUint8() = 0; |
|||
virtual uint16_t readUint16() = 0; |
|||
virtual uint32_t readUint32() = 0; |
|||
virtual uint64_t readUint64() = 0; |
|||
virtual std::string readString(int) = 0; |
|||
virtual bool seek(int64_t) = 0; |
|||
virtual std::streampos curr() = 0; |
|||
virtual std::string getPath() = 0; |
|||
virtual std::streampos getLength() = 0; |
|||
virtual uint24_t readUint24() = 0; |
|||
virtual Tag readTag() = 0; |
|||
virtual FWORD readFWord() = 0; |
|||
virtual UFWORD readUFWord() = 0; |
|||
virtual Offset8 readOffset8() = 0; |
|||
virtual Offset16 readOffset16() = 0; |
|||
virtual Offset24 readOffset24() = 0; |
|||
virtual Offset32 readOffset32() = 0; |
|||
virtual int24_t readInt24() = 0; |
|||
virtual Fixed readFixed() = 0; |
|||
virtual F2DOT14 readF2Dot14() = 0; |
|||
virtual Version16Dot16 readVersion16Dot16() = 0; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,7 @@ |
|||
package font |
|||
|
|||
|
|||
|
|||
type Font struct{ |
|||
Head Head `json:"head"` |
|||
} |
@ -0,0 +1,10 @@ |
|||
package font |
|||
|
|||
type Head struct { |
|||
Version string `json:"version"` |
|||
TableCount uint16 `json:"tableCount"` |
|||
Tables []Table `json:"tables"` |
|||
SearchRange uint16 `json:"searchRange"` |
|||
EntrySelector uint16 `json:"entrySelector"` |
|||
RangeShift uint16 `json:"rangeShift"` |
|||
} |
@ -0,0 +1,170 @@ |
|||
package font |
|||
|
|||
import ( |
|||
"bytes" |
|||
"encoding/binary" |
|||
"io" |
|||
"os" |
|||
) |
|||
|
|||
type Reader interface { |
|||
Read([]byte) (int, error) |
|||
Close() error |
|||
ReadInt8() (int8, error) |
|||
ReadInt16() (int16, error) |
|||
ReadInt32() (int32, error) |
|||
ReadInt64() (int64, error) |
|||
ReadUint8() (uint8, error) |
|||
ReadUint16() (uint16, error) |
|||
ReadUint32() (uint32, error) |
|||
ReadUint64() (uint64, error) |
|||
ReadString(int) (string, error) |
|||
ReadBytes(int) ([]byte, error) |
|||
Seek(int64, int) (int64, error) |
|||
Size() (int64, error) |
|||
} |
|||
|
|||
type reader struct { |
|||
path string |
|||
fp *os.File |
|||
} |
|||
|
|||
func NewReader(file string) (Reader, error) { |
|||
fp, err := os.OpenFile(file, os.O_RDONLY, os.ModePerm) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
r := &reader{ |
|||
fp: fp, |
|||
path: file, |
|||
} |
|||
return r, nil |
|||
} |
|||
|
|||
func (r *reader) Read(p []byte) (int, error) { |
|||
if r.fp == nil { |
|||
return 0, nil |
|||
} |
|||
return r.fp.Read(p) |
|||
} |
|||
|
|||
func (r *reader) Close() error { |
|||
if r.fp != nil { |
|||
return r.fp.Close() |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func (r *reader) ReadCloser() io.ReadCloser { |
|||
return r |
|||
} |
|||
|
|||
func (r *reader) ReadInt8() (int8, error) { |
|||
buff := make([]byte, 1) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int8(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func (r *reader) ReadInt16() (int16, error) { |
|||
buff := make([]byte, 2) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int16(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func (r *reader) ReadInt32() (int32, error) { |
|||
buff := make([]byte, 4) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int32(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func (r *reader) ReadInt64() (int64, error) { |
|||
buff := make([]byte, 8) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int64(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func (r *reader) ReadUint8() (uint8, error) { |
|||
buff := make([]byte, 1) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return uint8(buff[0]), nil |
|||
} |
|||
|
|||
func (r *reader) ReadUint16() (uint16, error) { |
|||
buff := make([]byte, 2) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint16(buff), nil |
|||
} |
|||
|
|||
func (r *reader) ReadUint32() (uint32, error) { |
|||
buff := make([]byte, 4) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint32(buff), nil |
|||
} |
|||
|
|||
func (r *reader) ReadUint64() (uint64, error) { |
|||
buff := make([]byte, 8) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint64(buff), nil |
|||
} |
|||
|
|||
func (r *reader) ReadString(len int) (string, error) { |
|||
buff := make([]byte, len) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return "", err |
|||
} |
|||
return string(buff), nil |
|||
} |
|||
|
|||
func (r *reader) ReadBytes(len int) ([]byte, error) { |
|||
buff := make([]byte, len) |
|||
_, err := r.fp.Read(buff) |
|||
if err != nil { |
|||
return []byte{}, err |
|||
} |
|||
return buff, nil |
|||
} |
|||
|
|||
func (r *reader) Seek(offset int64, whence int) (int64, error) { |
|||
return r.fp.Seek(offset, whence) |
|||
} |
|||
|
|||
func (r *reader) Size() (int64, error) { |
|||
fi, err := r.fp.Stat() |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return fi.Size(), nil |
|||
} |
@ -0,0 +1,8 @@ |
|||
package font |
|||
|
|||
type Table struct { |
|||
Name string `json:"name"` |
|||
Sum uint32 `json:"sum"` |
|||
Offset uint32 `json:"offset"` |
|||
Length uint32 `json:"length"` |
|||
} |
@ -0,0 +1,111 @@ |
|||
package font |
|||
|
|||
const ( |
|||
PlatformIDUnicode = iota |
|||
PlatformIDMacintosh |
|||
PlatformIDReserved |
|||
PlatformIDMicrosoft |
|||
) |
|||
|
|||
const ( |
|||
UnicodePlatformSpecificIDVer1dot0 = iota |
|||
UnicodePlatformSpecificIDVer1dot1 |
|||
UnicodePlatformSpecificIDISO10646 |
|||
UnicodePlatformSpecificIDUnicode2OnlyBMP |
|||
UnicodePlatformSpecificIDUnicode2NoBMP |
|||
) |
|||
|
|||
const ( |
|||
MacintoshPlatformSpecificIDRoman = iota |
|||
MacintoshPlatformSpecificIDJapanese |
|||
MacintoshPlatformSpecificIDTraditionalChinese |
|||
MacintoshPlatformSpecificIDKorean |
|||
MacintoshPlatformSpecificIDArabic |
|||
MacintoshPlatformSpecificIDHebrew |
|||
MacintoshPlatformSpecificIDGreek |
|||
MacintoshPlatformSpecificIDRussian |
|||
MacintoshPlatformSpecificIDRSymbol |
|||
MacintoshPlatformSpecificIDDevanagari |
|||
MacintoshPlatformSpecificIDGurmukhi |
|||
MacintoshPlatformSpecificIDGujarati |
|||
MacintoshPlatformSpecificIDOriya |
|||
MacintoshPlatformSpecificIDBengali |
|||
MacintoshPlatformSpecificIDTamil |
|||
MacintoshPlatformSpecificIDTelugu |
|||
MacintoshPlatformSpecificIDKannada |
|||
MacintoshPlatformSpecificIDMalayalam |
|||
MacintoshPlatformSpecificIDSinhalese |
|||
MacintoshPlatformSpecificIDBurmese |
|||
MacintoshPlatformSpecificIDThai |
|||
MacintoshPlatformSpecificIDLaotian |
|||
MacintoshPlatformSpecificIDGeorgian |
|||
MacintoshPlatformSpecificIDArmenian |
|||
MacintoshPlatformSpecificIDSimplifiedChinese |
|||
MacintoshPlatformSpecificIDTibetan |
|||
MacintoshPlatformSpecificIDMongolian |
|||
MacintoshPlatformSpecificIDGeez |
|||
MacintoshPlatformSpecificIDSlavic |
|||
MacintoshPlatformSpecificIDVietnamese |
|||
MacintoshPlatformSpecificIDSindhi |
|||
MacintoshPlatformSpecificIDUniterpreted |
|||
) |
|||
|
|||
const ( |
|||
NameIDCopyright = iota |
|||
NameIDFontFamily |
|||
NameIDFontSubFamily |
|||
NameIDUniqueFontID |
|||
NameIDFullFontName |
|||
NameIDVersion |
|||
NameIDPostScriptName |
|||
NameIDTrademark |
|||
NameIDManufacturerName |
|||
NameIDDesigner |
|||
NameIDDescription |
|||
NameIDVendorURL |
|||
NameIDDesignerURL |
|||
NameIDLicenseDescription |
|||
NameIDLicenseInfoURL |
|||
NameIDReserved |
|||
NameIDTypographicFamily |
|||
NameIDTypographicSubFamily |
|||
NameIDCompatibleFullName //only mac
|
|||
NameIDSampleText |
|||
NameIDPostscriptCID |
|||
NameIDWWSFamily |
|||
NameIDWWSSubFamily |
|||
NameIDLightBackgroundPallete |
|||
NameIDDarkBackgroundPallete |
|||
NameIDVariationScriptNamePrefix |
|||
) |
|||
|
|||
type NameTable struct { |
|||
Name string `json:"name"` |
|||
CopyRight string `json:"copyRight"` |
|||
Family string `json:"family"` |
|||
Style string `json:"style"` |
|||
} |
|||
|
|||
|
|||
type NameRecord struct{ |
|||
Platform uint16 |
|||
PlatformSpecific uint16 |
|||
Language uint16 |
|||
Name uint16 |
|||
Length uint16 |
|||
Offset uint16 |
|||
} |
|||
|
|||
type LangTagRecord struct{ |
|||
Length uint16 |
|||
Offset uint16 |
|||
} |
|||
|
|||
type NameTableFormat struct{ |
|||
Format uint16 |
|||
RecordsCount uint16 |
|||
StringOffset uint16 |
|||
NameRecords []NameRecord |
|||
LangTagCount uint16 //only ver 1, apple not support
|
|||
LangTagRecords []LangTagRecord //only ver 1, apple not support
|
|||
} |
@ -0,0 +1,217 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"bytes" |
|||
"encoding/binary" |
|||
"fmt" |
|||
"os" |
|||
) |
|||
|
|||
func readInt8(fp *os.File)(int8, error){ |
|||
buff := make([]byte, 1) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int8(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func readInt16(fp *os.File)(int16, error){ |
|||
buff := make([]byte, 2) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int16(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func readInt32(fp *os.File)(int32, error){ |
|||
buff := make([]byte, 4) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int32(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func readInt64(fp *os.File)(int64, error){ |
|||
buff := make([]byte, 8) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
reader := bytes.NewReader(buff) |
|||
n := int64(0) |
|||
return n, binary.Read(reader, binary.LittleEndian, &n) |
|||
} |
|||
|
|||
func readUint8(fp *os.File)(uint8, error){ |
|||
buff := make([]byte, 1) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return uint8(buff[0]), nil |
|||
} |
|||
|
|||
func readUint16(fp *os.File)(uint16, error){ |
|||
buff := make([]byte, 2) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint16(buff), nil |
|||
} |
|||
|
|||
func readUint32(fp *os.File)(uint32, error){ |
|||
buff := make([]byte, 4) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint32(buff), nil |
|||
} |
|||
|
|||
func readUint64(fp *os.File)(uint64, error){ |
|||
buff := make([]byte, 8) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return 0, err |
|||
} |
|||
return binary.BigEndian.Uint64(buff), nil |
|||
} |
|||
|
|||
func readString(fp *os.File, len int)(string, error){ |
|||
buff := make([]byte, len) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return "", err |
|||
} |
|||
return string(buff), nil |
|||
} |
|||
|
|||
func readBytes(fp *os.File, len int)([]byte, error){ |
|||
buff := make([]byte, len) |
|||
_, err := fp.Read(buff) |
|||
if err != nil { |
|||
return []byte{}, err |
|||
} |
|||
return buff, nil |
|||
} |
|||
|
|||
func readFontSearchArgs(fp *os.File)([]uint16, error){ |
|||
ret := []uint16{} |
|||
arg1, err := readUint16(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
ret = append(ret, arg1) |
|||
arg1, err = readUint16(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
ret = append(ret, arg1) |
|||
arg1, err = readUint16(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
ret = append(ret, arg1) |
|||
return ret, nil |
|||
} |
|||
|
|||
type ftable struct{ |
|||
Name string |
|||
Sum uint32 |
|||
Offset uint32 |
|||
Length uint32 |
|||
} |
|||
|
|||
func readFontTables(fp *os.File, tables uint16)([]ftable, error){ |
|||
ret := []ftable{} |
|||
for i := 0; i < int(tables); i++ { |
|||
t :=ftable{} |
|||
name, err := readString(fp, 4) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
t.Name = name |
|||
sum, err := readUint32(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
t.Sum = sum |
|||
addr, err := readUint32(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
t.Offset = addr |
|||
length, err := readUint32(fp) |
|||
if err != nil { |
|||
return ret, err |
|||
} |
|||
t.Length = length |
|||
ret = append(ret, t) |
|||
} |
|||
return ret, nil |
|||
} |
|||
|
|||
func readNameTable(fp *os.File, offset uint32, length uint32)([]byte, error){ |
|||
fp.Seek(int64(offset), 0) |
|||
return readBytes(fp, int(length)) |
|||
} |
|||
|
|||
func readFont(file string)error{ |
|||
fp, err := os.OpenFile(file, os.O_RDONLY, os.ModePerm) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer fp.Close() |
|||
verB, err := readUint16(fp) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
verL, err := readInt16(fp) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
fmt.Println("font head version is", fmt.Sprintf("%d.%d", verB, verL)) |
|||
tableCount, err := readUint16(fp) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
fmt.Println("font table count is", tableCount) |
|||
args, err := readFontSearchArgs(fp) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
fmt.Println("font search args is", args) |
|||
tables, err := readFontTables(fp, tableCount) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
nameBuff := []byte{} |
|||
for n, table := range tables { |
|||
fmt.Println("font table", n+1, ": name: ", table.Name, " sum: ", table.Sum, " offset: ", table.Offset, " length: ", table.Length) |
|||
if table.Name == "name" { |
|||
nameBuff, err = readNameTable(fp, table.Offset, table.Length) |
|||
} |
|||
} |
|||
if err != nil { |
|||
return err |
|||
} |
|||
fmt.Println("name table: ", string(nameBuff)) |
|||
return nil |
|||
} |
|||
|
|||
func main(){ |
|||
err := readFont("文鼎中黑.ttf") |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package test |
|||
|
|||
type Cmd interface{ |
|||
Result()bool |
|||
Output()string |
|||
} |
|||
|
|||
type cmd struct{ |
|||
r bool |
|||
o string |
|||
} |
|||
|
|||
func (c *cmd)exec(s string, args ...string){ |
|||
//....
|
|||
// c.r = ...
|
|||
//c.o = ...
|
|||
} |
|||
|
|||
func (c *cmd)Result()bool{ |
|||
return c.r |
|||
} |
|||
|
|||
func (c *cmd)Output()string{ |
|||
return c.o |
|||
} |
|||
|
|||
func Exec(s string, args ...string)Cmd{ |
|||
c := &cmd{} |
|||
c.exec(s, args...) |
|||
return c |
|||
} |
Loading…
Reference in new issue