huangkun
2 months 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