Skip to content

Commit

Permalink
TT↔PS conversion, fix #1
Browse files Browse the repository at this point in the history
  • Loading branch information
CyanoHao committed Mar 26, 2020
1 parent 737d8aa commit 89fc078
Show file tree
Hide file tree
Showing 13 changed files with 843 additions and 27 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018 Cyano Hao
Copyright (c) 2018–2020 Cyano Hao

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
15 changes: 2 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
* `WarFontMerger-TC-版本号.7z`:繁体中文大字库(覆盖中日韩各国字符,字形采用台湾标准,体积稍大)。
* `WarFontMerger-Classic-版本号.7z`:传统字形大字库(覆盖中日韩各国字符,字形采用传统印刷体风格,体积稍大)。

除了合并补全工具自带的字体库之外,[WMF 开源字体库](https://github.com/CyanoHao/WFM-Free-Font) 中的字体也经过验证可以用于该工具。

## 快速入门(Windows)

### 合并两个字体并补全
Expand Down Expand Up @@ -56,7 +54,6 @@ macOS 下的使用方法和 Windows 稍有不同。

## 限制

* 目前只支持 TrueType 曲线字体(TrueType 或 OpenType/TT,扩展名通常为 `.ttf`),暂不支持 PostScript 曲线字体(OpenType/CFF 或 OpenType/CID,扩展名通常为 `.otf`)。
* 不提供预编译的 32 位版本。WFM 不可避免地需要操纵汉字,而汉字是一个非常庞大的集合,读取并操作汉字需要巨大的内存,32 位程序极易因为超出内存上限而崩溃。

## 编译和运行
Expand Down Expand Up @@ -110,20 +107,12 @@ otfccbuild base.otd -O2 -o 合并之后的字体.ttf
rm *.otd
```

## 开发计划

### 支持对每个字体自定义变换矩阵

这样可以更好地匹配原有字体的风格。例如,修改倾斜角度、压缩字符宽度,甚至旋转字符。

### 支持 PostScript 曲线字体

许多高质量的字体采用了 PostScript 曲线,封装为 OpenType/CFF 或 OpenType/CID 字体。由于 OpenType/CFF 或 OpenType/CID 的字体格式与 OpenType/TT 差别很大,目前还没办法支持。

## 感谢

[Belleve Invis](https://github.com/be5invis)[李阿玲](https://github.com/clerkma)编写的 [otfcc](https://github.com/caryll/otfcc) 用于解析和生成 OpenType 字体文件。

[Niels Lohmann](https://github.com/nlohmann)[json](https://github.com/nlohmann/json) 库提供了非常漂亮的 C++ JSON 接口。本工具使用了修改版的 `json.hpp`,容许非标准编码的字符。

TrueType 和 PostScript 曲线相互转换的算法来自 [AFDKO](https://github.com/adobe-type-tools/afdko)[Fontello](https://github.com/fontello/cubic2quad)。这两个算法有[配合 otfcc 使用的独立版本](https://github.com/nowar-fonts/otfcc-quad2cubic),可用于 OpenType/TT 和 OpenType/CFF 字体的相互转换。

Google 提供了大量的开源字体,Adobe 提供了高质量的[思源黑体](https://github.com/adobe-fonts/source-han-sans)
3 changes: 1 addition & 2 deletions build-mac64.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ source ./version.bash

VERSION=$VERSION-mac64

clang++ src/merge-otd.cpp src/merge-name.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -o bin-mac64/merge-otd
strip bin-mac64/merge-otd
clang++ src/merge-otd.cpp src/merge-name.cpp src/ps2tt.cpp src/tt2ps.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -s -o bin-mac64/merge-otd

mkdir -p release
cd release
Expand Down
3 changes: 1 addition & 2 deletions build-win32.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ source ./version.bash

VERSION=$VERSION-win32

i686-w64-mingw32-g++ src/merge-otd.cpp src/merge-name.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -static -Wl,--large-address-aware -o bin-win32/merge-otd.exe
strip bin-win32/merge-otd.exe
i686-w64-mingw32-g++ src/merge-otd.cpp src/merge-name.cpp src/ps2tt.cpp src/tt2ps.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -static -s -Wl,--large-address-aware -o bin-win32/merge-otd.exe

mkdir -p release
cd release
Expand Down
3 changes: 1 addition & 2 deletions build-win64.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ source ./version.bash

VERSION=$VERSION-win64

x86_64-w64-mingw32-g++ src/merge-otd.cpp src/merge-name.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -static -o bin-win64/merge-otd.exe
strip bin-win64/merge-otd.exe
x86_64-w64-mingw32-g++ src/merge-otd.cpp src/merge-name.cpp src/ps2tt.cpp src/tt2ps.cpp src/iostream.cpp -Isrc/ -std=c++17 -O3 -static -s -o bin-win64/merge-otd.exe

mkdir -p release
cd release
Expand Down
2 changes: 1 addition & 1 deletion src/merge-name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ void RemoveRedundantTable(vector<json> &nametables) {
}

// Nowar Sans LCG + Nowar Sans CJK
if (nowarlcg != -1) {
if (nowarlcg != size_t(-1)) {
bool hascjk = false;
for (size_t i = 0; i < nametables.size(); i++) {
json &table = nametables[i];
Expand Down
13 changes: 8 additions & 5 deletions src/merge-otd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@

#include "invisible.hpp"
#include "merge-name.h"
#include "ps2tt.h"
#include "tt2ps.h"

const char *usage = reinterpret_cast<const char *>(u8"用法:\n\t%s 1.otd 2.otd [n.otd ...]\n");
const char *loadfilefail = reinterpret_cast<const char *>(u8"读取文件 %s 失败\n");
const char *mixedpostscript = reinterpret_cast<const char *>(u8"暂不支持混用 TrueType 和 PostScript 轮廓字体");

using json = nlohmann::json;

Expand Down Expand Up @@ -188,7 +189,7 @@ int main(int argc, char *u8argv[]) {
try {
auto s = LoadFile(u8argv[1]);
base = json::parse(s);
} catch (std::runtime_error) {
} catch (const std::runtime_error &) {
return EXIT_FAILURE;
}
basecff = IsPostScriptOutline(base);
Expand All @@ -203,9 +204,11 @@ int main(int argc, char *u8argv[]) {
} catch (std::runtime_error) {
return EXIT_FAILURE;
}
if (IsPostScriptOutline(ext) != basecff) {
nowide::cerr << mixedpostscript << std::endl;
return EXIT_FAILURE;
bool extcff = IsPostScriptOutline(ext);
if (basecff && !extcff) {
ext["glyf"] = Tt2Ps(ext["glyf"]);
} else if (!basecff && extcff) {
ext["glyf"] = Ps2Tt(ext["glyf"]);
}
RemoveBlankGlyph(ext);
nametables.push_back(ext["name"]);
Expand Down
75 changes: 75 additions & 0 deletions src/point.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#pragma once

#include <cmath>
#include <nlohmann/json.hpp>

struct Point
{
double x;
double y;

Point() : x(0), y(0)
{
}
Point(double x, double y) : x(x), y(y)
{
}
Point(const nlohmann::json &p) : x(p["x"]), y(p["y"])
{
}
nlohmann::json ToJson(bool on)
{
return {{"x", x}, {"y", y}, {"on", on}};
}
};

inline Point operator+(Point a, Point b)
{
return {a.x + b.x, a.y + b.y};
}

inline Point operator-(Point a, Point b)
{
return {a.x - b.x, a.y - b.y};
}

inline Point operator-(Point a)
{
return {-a.x, -a.y};
}

inline Point operator/(Point a, double b)
{
return {a.x / b, a.y / b};
}

inline Point operator*(Point a, double b)
{
return {a.x * b, a.y * b};
}

inline Point operator*(double a, Point b)
{
return {a * b.x, a * b.y};
}

// dot
inline double operator*(Point a, Point b)
{
return a.x * b.x + a.y * b.y;
}

inline double abs(Point a)
{
return sqrt(a * a);
}

inline void RoundInPlace(nlohmann::json &glyph)
{
for (auto &contour : glyph["contours"])
for (auto &point : contour)
{
point["x"] = int(round(double(point["x"])));
point["y"] = int(round(double(point["y"])));
}
}
Loading

0 comments on commit 89fc078

Please sign in to comment.