

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>font &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/font/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Fri, 19 May 2023 01:50:50 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>font &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>苦累蛙圓體修正錯字示範</title>
		<link>https://stackoverflow.max-everyday.com/2021/07/correct-font-glyph-error/</link>
					<comments>https://stackoverflow.max-everyday.com/2021/07/correct-font-glyph-error/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 02 Jul 2021 10:16:39 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[FontForge]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=3821</guid>

					<description><![CDATA[這篇文章示範字體檔案的某一個單字的修改，透過自動...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="773" height="469" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/correct-font-glyph-error-cover.jpg" alt="" class="wp-image-3824" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/correct-font-glyph-error-cover.jpg?v=1625220678 773w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/correct-font-glyph-error-cover-600x364.jpg?v=1625220678 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2021/07/correct-font-glyph-error-cover-768x466.jpg?v=1625220678 768w" sizes="(max-width: 773px) 100vw, 773px" /></figure>



<p>這篇文章示範字體檔案的某一個單字的修改，透過自動化的方式，簡化手動去操作FontForge，可以提升更多的效率。影片示範重點為：</p>



<ol class="wp-block-list">
<li><strong>取出字體檔特定的文字</strong><br>copy selected glyph out, ex command:<br><code>copy_selected_out.py --input KurewaGothicCjkTc-Regular.sfdir --output new.sfdir --string 揄</code></li>



<li><strong>修改好的點陣圖轉成向量圖格式</strong><br>bmp to svg, ex command:<br><code>potrace -b svg -u 50 orig/U_25540.bmp -o orig/U_25540.bmp.svg</code></li>



<li><strong>svg 匯入字體檔案</strong><br>import svg to font, ex command:<br><code>fontforge ~/Documents/sh/import_svg.py --input new.sfdir --svg_path orig --filename_pattern="U_%s.bmp.svg" --filename_source=unicode_int</code></li>
</ol>



<hr class="wp-block-separator has-css-opacity"/>



<p>Youtube 影片：苦累蛙圓體修正錯字示範<br><a href="https://youtu.be/26ENvQD50cA">https://youtu.be/26ENvQD50cA</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="苦累蛙圓體修正錯字示範" width="640" height="480" src="https://www.youtube.com/embed/26ENvQD50cA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<hr class="wp-block-separator has-css-opacity"/>



<h2 class="wp-block-heading">相關文章</h2>



<p>Max學習字體的筆記<br><a href="https://codereview.max-everyday.com/font-readme/">https://codereview.max-everyday.com/font-readme/</a></p>



<p>字型轉圖片 font to image<br><a href="https://codereview.max-everyday.com/font-to-image/">https://codereview.max-everyday.com/font-to-image/</a></p>



<p>dumping SVG outlines into a FontForge file<br><a href="https://stackoverflow.max-everyday.com/2021/06/dumping-svg-outlines-into-a-fontforge-file/">https://stackoverflow.max-everyday.com/2021/06/dumping-svg-outlines-into-a-fontforge-file/</a></p>



<p>苦累蛙圓體 Kurewa Gothic<br><a href="https://max-everyday.com/2021/06/kurewa-gothic/">https://max-everyday.com/2021/06/kurewa-gothic/</a></p>



<p>苦累蛙圓體下載點<br><a href="https://github.com/max32002/kurewa-gothic">https://github.com/max32002/kurewa-gothic</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2021/07/correct-font-glyph-error/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>點陣圖片轉成向量的字型檔</title>
		<link>https://stackoverflow.max-everyday.com/2020/12/bmp-2-ttf/</link>
					<comments>https://stackoverflow.max-everyday.com/2020/12/bmp-2-ttf/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 30 Dec 2020 19:28:43 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[FontForge]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=3667</guid>

					<description><![CDATA[這篇文章的目的是把點陣圖片(.bmp 或 .pn...]]></description>
										<content:encoded><![CDATA[
<p>這篇文章的目的是把點陣圖片(.bmp 或 .png) 產生成一個字型檔，原來滿簡單的，網路上有很多驗證過且完整的解法。</p>



<p>相關網頁：</p>



<ul class="wp-block-list"><li>妄想者造字记<br><a href="https://zhuanlan.zhihu.com/p/23607678">https://zhuanlan.zhihu.com/p/23607678</a></li><li>中文像素字体制作<br><a href="https://indienova.com/u/hata/blogread/26923">https://indienova.com/u/hata/blogread/26923</a></li><li>Converting rasters to SVG, and creating a rudimentary font with font-forge &#8211; Part 4 of an XKCD font saga<br><a href="https://pelson.github.io/2017/xkcd_font_raster_to_vector_and_basic_font_creation/">https://pelson.github.io/2017/xkcd_font_raster_to_vector_and_basic_font_creation/</a></li><li>字体生成小记<br><a href="http://www.shushilvshe.com/data/font-build.html">http://www.shushilvshe.com/data/font-build.html</a></li><li>幫字型檔補缺字<br><a href="https://max-everyday.com/2020/02/how-to-add-new-glyph-to-font/">https://max-everyday.com/2020/02/how-to-add-new-glyph-to-font/</a></li></ul>



<hr class="wp-block-separator"/>



<p>最後成功後的執行畫面：</p>



<figure class="wp-block-image size-large"><img decoding="async" width="644" height="469" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-31-at-00.13.33.png" alt="" class="wp-image-3669" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-31-at-00.13.33.png?v=1609351666 644w, https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-31-at-00.13.33-600x437.png?v=1609351666 600w" sizes="(max-width: 644px) 100vw, 644px" /></figure>



<p>上面圖片裡的「桌」是前一篇文章的產物，參考看看：<br>Python 在圖像上輸出文字<br><a href="https://stackoverflow.max-everyday.com/2020/12/python-draw-text/">https://stackoverflow.max-everyday.com/2020/12/python-draw-text/</a></p>



<p>有了 bmp 檔案後，要怎麼變成字型檔案呢？常見的解法是先用 potrace,Inkscape,autotrace 自動描邊的軟體把圖片轉成向量格式，手動的指令可以參考看看：</p>



<p>Looking at the&nbsp;<code>potrace</code>&nbsp;website you can apparently go directly from BMP to SVG.</p>



<pre class="wp-block-code"><code>$ potrace -s input.bmp -o output.svg
</code></pre>



<h3 class="wp-block-heading">autotrace</h3>



<p>Another option to&nbsp;<code>potrace</code>&nbsp;is&nbsp;<a href="http://autotrace.sourceforge.net/"><code>autotrace</code></a>.</p>



<pre class="wp-block-code"><code>$ autotrace -output-file ouput.svg -output-format svg --color-count 4 input.bmp
</code></pre>



<p>You&#8217;ll likely have to play with the&nbsp;<code>--color-count</code>&nbsp;to get an image that suites your needs.</p>



<hr class="wp-block-separator"/>



<p>有了 .svg 檔案，可以手動在 fontforge 裡做匯入(import)，當然最理想的作法是寫python腳本程式來自動匯入，才會比較有效率和省時間。</p>



<p>直接使用空的字型檔案，或直接匯入 .svg 都會讓圖片產生偏移，奇怪的是坐標內容是正確的，執行結果：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="773" height="321" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-30-at-19.12.50.png" alt="" class="wp-image-3670" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-30-at-19.12.50.png?v=1609352172 773w, https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-30-at-19.12.50-600x249.png?v=1609352172 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2020/12/Screen-Shot-2020-12-30-at-19.12.50-768x319.png?v=1609352172 768w" sizes="auto, (max-width: 773px) 100vw, 773px" /></figure>



<p>解決這個問題滿簡單的，不要使用空的字型檔，而是去更新一個要修改的字(.glyph) 就可以解決了，max 的 sample code:<br><a href="https://github.com/max32002/MaxFontScripts/blob/master/bmp2ttf.py">https://github.com/max32002/MaxFontScripts/blob/master/bmp2ttf.py</a></p>



<hr class="wp-block-separator"/>



<pre class="wp-block-preformatted"><code>import os

BMP_PATH = './bmp/'
SVG_PATH = './svg/'
FONT_PROJECT= './myfont.sfdir'
FONT_PATH= './myfont.ttf'

import fontforge
# new font.
#font = fontforge.font()
# open exist font.
print("Open font:", FONT_PROJECT)
font=fontforge.open(FONT_PROJECT)

# prepare environment
if not os.path.exists(BMP_PATH):
    # make dir.
    print('mkdir bmp folder')
    os.system('mkdir -p ' + BMP_PATH)

if not os.path.exists(SVG_PATH):
    # make dir.
    print('mkdir svg folder')
    os.system('mkdir -p ' + SVG_PATH)

print('bmp transform to svg...')

for filename in os.listdir(BMP_PATH):
    bmp_filepath = os.path.join(BMP_PATH, filename)
    svg_filename = filename.replace('.bmp','.svg')
    svg_filepath = os.path.join(SVG_PATH, svg_filename)
    command='potrace -s ' + bmp_filepath + ' -o ' + svg_filepath

    try:
        os.system(command)
    except Exception as e:
        print(e)

print('bmp transform to svg finished, move svg image to svg folder.')


print('generate fonts...')

for filename in os.listdir(SVG_PATH):
    svg = os.path.join(SVG_PATH, filename)
    try:
        #image filename example: "U_001234.svg"
        glyph = font.createChar(int('0x'+filename.split('.')[0][-4:], 16) ,filename.split('.')[0]) 
        
        # force overwrite, must clear before import.
        glyph.clear()
        # if .clear() clean too many infomation, use below code instead.
        #glyph.layers[0] = fontforge.layer()
        #glyph.layers[1] = fontforge.layer()

        glyph.importOutlines(svg)

        #glyph.correctDirection()
        glyph.simplify()
        glyph.round()

    except Exception as e:
        print(e)
    except Error as err:
        print(err)

# not necessary to save, save only for debug purpose.
#font.save(FONT_PROJECT)

font.generate(FONT_PATH)
font.close()

print('generate fonts finished.^_^y')

</code</pre>



<hr class="wp-block-separator"/>



<p>一開始以為 glyph.clear() 會把異體字對應的table清除，實際測試額外的 AltUni2 還有被保留，還沒有去測試 Substitution2 的資料會不會因為 glyph.clear() 造成遺失。</p>



<p>fontforge scripting 官方說明：<br><a href="https://fontforge.org/docs/scripting/python/fontforge.htm">https://fontforge.org/docs/scripting/python/fontforge.htm</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2020/12/bmp-2-ttf/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Python 字型相關工具</title>
		<link>https://stackoverflow.max-everyday.com/2020/02/python-font/</link>
					<comments>https://stackoverflow.max-everyday.com/2020/02/python-font/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 10 Feb 2020 21:39:26 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=3216</guid>

					<description><![CDATA[Max 分享一些關於處理Python中的字體相關...]]></description>
										<content:encoded><![CDATA[
<p>Max 分享一些關於處理Python中的字體相關工具。</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">轉換系統</h2>



<p><strong>ufo2ft</strong><br><a href="https://github.com/googlefonts/ufo2ft">https://github.com/googlefonts/ufo2ft</a><br>可以通過UFO to OTF/TTF</p>



<pre class="wp-block-preformatted">from defcon import Font
from ufo2ft import compileOTF
ufo = Font('MyFont-Regular.ufo')
otf = compileOTF(ufo)
otf.save('MyFont-Regular.otf')</pre>



<p><strong>ufo2fdk</strong><br><a href="https://github.com/robotools/ufo2fdk">https://github.com/robotools/ufo2fdk</a><br>從UFO to AFDKO的轉換</p>



<p><strong>UFO Extractor</strong><br><a href="https://github.com/robotools/extractor">https://github.com/robotools/extractor</a><br>otf/ttf to UFO</p>



<pre class="wp-block-preformatted">&gt;&gt;&gt; import extractor
&gt;&gt;&gt; import defcon
&gt;&gt;&gt; ufo = defcon.Font()
&gt;&gt;&gt; extractor.extractUFO("/path/to/MyFont.ttf", ufo)
&gt;&gt;&gt; ufo.save("/path/to/MyFont.ufo")</pre>



<p><strong>fontmake</strong><br><a href="https://github.com/googlefonts/fontmake">https://github.com/googlefonts/fontmake</a><br>UFO to otf/ttf</p>



<p>Max 實際測試，這不是一般的折騰！遇到問題時，完全無解，參考看看：<br><a href="https://stackoverflow.max-everyday.com/2020/02/ufo2ft-filtersrunning-removeoverlapsfilter/">https://stackoverflow.max-everyday.com/2020/02/ufo2ft-filtersrunning-removeoverlapsfilter/</a></p>



<p><strong>AFDKO</strong><br><a href="https://github.com/adobe-type-tools/afdko">https://github.com/adobe-type-tools/afdko</a><br>Adobe Font Development Kit for OpenType</p>



<p><strong>Font Merger</strong><br><a href="https://github.com/iij/fontmerger">https://github.com/iij/fontmerger</a><br>合併字型檔案<br>You can merge some fonts which are regular fonts and symbol fonts(<a href="https://powerline.readthedocs.io/en/latest/">Powerline</a>,&nbsp;<a href="http://fontawesome.io/">Font Awesome</a>) and others.</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">編輯器</h2>



<p><strong>fontParts</strong><br><a href="https://github.com/robotools/fontParts">https://github.com/robotools/fontParts</a><br>An API for interacting with the parts of fonts during the font development process. FontParts is the replacement for&nbsp;<a href="http://robofab.com/">RoboFab</a>.<br>The documentation is at&nbsp;<a href="http://fontparts.readthedocs.io/en/latest/">fontparts.readthedocs.io</a>.</p>



<p><strong>defcon</strong><br><a href="https://github.com/robotools/defcon">https://github.com/robotools/defcon</a><br>A set of UFO based objects for use in font editing applications.</p>



<p><strong>fonttools</strong><br><a href="https://github.com/fonttools/fonttools">https://github.com/fonttools/fonttools</a><br>A library to manipulate font files from Python.</p>



<p>The package is listed in the Python Package Index (PyPI), so you can install it with&nbsp;<a href="https://pip.pypa.io/">pip</a>:</p>



<pre class="wp-block-preformatted">pip install fonttools</pre>



<p><strong>glyphsLib</strong><br><a href="https://github.com/googlefonts/glyphsLib">https://github.com/googlefonts/glyphsLib</a><br>A bridge from Glyphs source files (.glyphs) to UFOs</p>



<p><strong>ufoLib2</strong><br><a href="https://github.com/fonttools/ufoLib2">https://github.com/fonttools/ufoLib2</a><br>ufoLib2 is a UFO font library.</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">其他</h2>



<p>ttfautohint-py<br><a href="https://github.com/fonttools/ttfautohint-py">https://github.com/fonttools/ttfautohint-py</a><br>Python wrapper for ttfautohint, a free auto-hinter for TrueType fonts </p>



<p>fontbakery<br><a href="https://github.com/googlefonts/fontbakery">https://github.com/googlefonts/fontbakery</a><br>Font quality assurance tool written in Python 3.</p>



<p>kernDump<br><a href="https://github.com/adobe-type-tools/kern-dump">https://github.com/adobe-type-tools/kern-dump</a><br>Scripts for working with and analyzing kerning information</p>



<hr class="wp-block-separator"/>



<p>Max 比較建議使用的工具是 FontForge<br><a href="https://github.com/fontforge/fontforge/releases">https://github.com/fontforge/fontforge/releases</a></p>



<p>還有：Glyphr Studio Desktop</p>



<p><a href="https://github.com/glyphr-studio/Glyphr-Studio-Desktop">https://github.com/glyphr-studio/Glyphr-Studio-Desktop</a></p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">相關文章：</h2>



<p>Font­Tools 安裝與使用簡明指南<br><a href="https://stackoverflow.max-everyday.com/2020/02/fonttools/">https://stackoverflow.max-everyday.com/2020/02/fonttools/</a></p>



<p>Awesome Typography<br><a href="https://github.com/Jolg42/awesome-typography">https://github.com/Jolg42/awesome-typography</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2020/02/python-font/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Font­Tools 安裝與使用簡明指南</title>
		<link>https://stackoverflow.max-everyday.com/2020/02/fonttools/</link>
					<comments>https://stackoverflow.max-everyday.com/2020/02/fonttools/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 10 Feb 2020 21:14:19 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[font]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=3213</guid>

					<description><![CDATA[Max 最近在協助其他的好心人開發免費的字型，順...]]></description>
										<content:encoded><![CDATA[
<p>Max 最近在協助其他的好心人開發免費的字型，順便學一下關於字型的相關技術。</p>



<p>Font­Tools 是一套以 ttx 為核心的工具集，用於處理與字體編輯有關的各種問題，程序用 Python 編寫完成，代碼開源，具有良好的跨平台性。</p>



<p>FontForeg正式版和開發中的版本下載：<br><a href="https://fontforge.org/en-US/downloads/">https://fontforge.org/en-US/downloads/</a></p>



<p>官網網站：<br><a href="https://github.com/fonttools/fonttools">https://github.com/fonttools/fonttools</a></p>



<p>Font­Tools 由以下 4 個程序組成：</p>



<ul class="wp-block-list"><li>ttx 可將字體文件與 xml 文件進行雙向轉換</li><li>pyft­merge 可將數個字體文件合併成為一個字體文件</li><li>pyft­sub­set 可產生一個由字體的指定字符組成的子集</li><li>pyftin­spect 可顯示字體文件的二進制組成信息</li></ul>



<h2 class="wp-block-heading">安裝 Font­Tools</h2>



<p>詳細介紹：<br><a href="https://pypi.org/project/fonttools/">https://pypi.org/project/fonttools/</a></p>



<p>指令：</p>



<pre class="wp-block-preformatted">pip install fonttools</pre>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">字體基本知識</h2>



<p>一個字體由數個表（ta­ble）構成，字體的信息儲存在表中。一個最基本的字體文件一定會包含以下的表：</p>



<ul class="wp-block-list"><li>cmap: Char­ac­ter to glyph map­ping</li><li>head: Font header</li><li>hhea: Hor­i­zon­tal header</li><li>hmtx: Hor­i­zon­tal met­rics</li><li>maxp: Max­i­mum pro­file</li><li>name: Nam­ing ta­ble</li><li>OS/2: OS/2 and Win­dows spe­cific met­rics</li><li>post: Post­Script in­for­ma­tion: </li></ul>



<p>以上都不知道，也沒差，有個印象就好了。</p>



<hr class="wp-block-separator"/>



<p>使用 True­Type 曲線繪制的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>cvt: Con­trol Value Table</li><li>fpgm: Font pro­gram</li><li>glyf: Glyph data</li><li>loca: In­dex to lo­ca­tion</li><li>prep: CVT Pro­gram</li><li>gasp: Grid-fit­ting/Scan-con­ver­sion (op­tional ta­ble) </li></ul>



<p>以上都不知道，也沒差，有個印象就好了。</p>



<hr class="wp-block-separator"/>



<p>使用 Post­Script 曲線繪制的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>CFF: Post­Script font pro­gram (com­pact font for­mat)</li><li>VORG: Ver­ti­cal Ori­gin (op­tional ta­ble)</li></ul>



<hr class="wp-block-separator"/>



<p>使用 SVG 曲線繪制的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>SVG: The SVG (Scal­able Vec­tor Graph­ics) ta­ble</li></ul>



<hr class="wp-block-separator"/>



<p>使用 Bitmap 圖形構成的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>EBDT: Em­bed­ded bitmap data</li><li>EBLC: Em­bed­ded bitmap lo­ca­tion data</li><li>EBSC: Em­bed­ded bitmap scal­ing data</li><li>CBDT: Color bitmap data</li><li>CBLC: Color bitmap lo­ca­tion data</li></ul>



<hr class="wp-block-separator"/>



<p>包含高級書法特性的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>BASE: Base­line data</li><li>GDEF: Glyph de­f­i­n­i­tion data</li><li>GPOS: Glyph po­si­tion­ing data</li><li>GSUB: Glyph sub­sti­tu­tion data</li><li>JSTF: Jus­ti­fi­ca­tion data</li><li>MATH: Math lay­out data</li></ul>



<hr class="wp-block-separator"/>



<p>包含其他特性的字體會包含如下的表：</p>



<ul class="wp-block-list"><li>DSIG: Dig­i­tal sig­na­ture</li><li>hdmx: Hor­i­zon­tal de­vice met­rics</li><li>kern: Kern­ing</li><li>LTSH: Lin­ear thresh­old data</li><li>PCLT: PCL 5 data</li><li>VDMX: Ver­ti­cal de­vice met­rics</li><li>vhea: Ver­ti­cal Met­rics header</li><li>vmtx: Ver­ti­cal Met­rics</li><li>COLR: Color ta­ble</li><li>CPAL: Color palette ta­ble </li></ul>



<p>對字體的修改基本上是圍繞著最上方的基本表進行的，如果要修改字符形態等才需要用到之後的表。</p>



<p>以上都不知道，也沒差，有個印象就好了。</p>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">ttx 指令使用說明</h2>



<p>ttx 是 Font­Tools 的核心工具，用於將字體轉換為 xml 文件，或者將 xml 文件轉換回字體。ttx 所產生的 xml 文件的後綴名是 ttx，可以用各種文檔編輯器打開進行編輯。</p>



<p>將字體全部的表轉換為 ttx 文件：</p>



<pre class="wp-block-preformatted">$ ttx font.ttf</pre>



<p>將 ttx 文件轉換回字體文件。</p>



<pre class="wp-block-preformatted">$ ttx font.ttx</pre>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">pyft­merge 使用說明</h2>



<p>合併字體：</p>



<pre class="wp-block-preformatted">$ pyft­merge font1.otf font2.otf</pre>



<p>實測結果：</p>



<p class="has-text-color has-vivid-red-color">合併失敗</p>



<pre class="wp-block-preformatted">➜  ttf pyftmerge temp.ttf temp2.ttf       
 WARNING: Dropped cmap subtable from font [0]: format  0, platformID  1, platEncID  0
 WARNING: Dropped cmap subtable from font [1]: format  0, platformID  1, platEncID  0
 Traceback (most recent call last):
   File "/usr/local/bin/pyftmerge", line 8, in &lt;module&gt;
     sys.exit(main())
   File "/usr/local/lib/python2.7/site-packages/fontTools/misc/loggingTools.py", line 375, in wrapper
     return func(*args, **kwds)
   File "/usr/local/lib/python2.7/site-packages/fontTools/merge.py", line 1157, in main
     font = merger.merge(args)
   File "/usr/local/lib/python2.7/site-packages/fontTools/merge.py", line 997, in merge
     table = clazz(tag).merge(self, tables)
   File "/usr/local/lib/python2.7/site-packages/fontTools/merge.py", line 160, in merge
     return m.mergeObjects(self, self.mergeMap, tables)
   File "/usr/local/lib/python2.7/site-packages/fontTools/merge.py", line 1043, in mergeObjects
     value = mergeLogic(getattr(table, key, NotImplemented) for table in tables)
   File "/usr/local/lib/python2.7/site-packages/fontTools/merge.py", line 49, in equal
     assert all(item == first for item in t), "Expected all items to be equal: %s" % lst
 AssertionError: Expected all items to be equal: [1024, 1000]</pre>



<hr class="wp-block-separator"/>



<h2 class="wp-block-heading">pyft­sub­set 使用說明</h2>



<p>pyft­sub­set 可提取一個字體的部分字符，產生一個只由它們組成的新字體。通過這一子集化技術，可有效縮小字體文件的體積，便於網絡傳輸。</p>



<p>用法：</p>



<pre class="wp-block-preformatted">$ pyft­sub­set font.otf --text="漢字"</pre>



<ul class="wp-block-list"><li>&#8211;text 選項用於指定需要保留的字符</li><li>&#8211;text-file 選項用於指定一個包含需要保留的字符的 txt 文檔</li><li>&#8211;out­put-file 選項用於指定輸出文件的保存位置</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2020/02/fonttools/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ufo2ft.filters:Running RemoveOverlapsFilter</title>
		<link>https://stackoverflow.max-everyday.com/2020/02/ufo2ft-filtersrunning-removeoverlapsfilter/</link>
					<comments>https://stackoverflow.max-everyday.com/2020/02/ufo2ft-filtersrunning-removeoverlapsfilter/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 10 Feb 2020 19:42:38 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://stackoverflow.max-everyday.com/?p=3210</guid>

					<description><![CDATA[在使用 fontmake 把 UFO 打包成 t...]]></description>
										<content:encoded><![CDATA[
<p>在使用 fontmake 把 UFO 打包成  ttf 時遇到錯誤，完整錯誤訊息：</p>



<pre class="wp-block-preformatted">INFO:fontmake.font_project:Building TTF for JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft:Pre-processing glyphs
 INFO:ufo2ft.filters:Running DecomposeComponentsFilter on JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft.filters:Running RemoveOverlapsFilter on JasonHandwriting2-JasonHandwriting2
 Traceback (most recent call last):
   File "/usr/local/bin/fontmake", line 8, in &lt;module>
     sys.exit(main())
   File "/usr/local/lib/python2.7/site-packages/fontmake/<strong>main</strong>.py", line 422, in main
     ufo_paths, is_instance=args.pop("masters_as_instances"), **args
   File "/usr/local/lib/python2.7/site-packages/fontmake/font_project.py", line 1026, in run_from_ufos
     self.build_ttfs(ufos, **kwargs)
   File "/usr/local/lib/python2.7/site-packages/fontmake/font_project.py", line 311, in build_ttfs
     self.save_otfs(ufos, ttf=True, *<em>kwargs)   File "/usr/local/lib/python2.7/site-packages/fontTools/misc/loggingTools.py", line 375, in wrapper     return func(</em>args, **kwds)
   File "/usr/local/lib/python2.7/site-packages/fontmake/font_project.py", line 578, in save_otfs
     for font, ufo in zip(fonts, ufos):
   File "/usr/local/lib/python2.7/site-packages/fontmake/font_project.py", line 441, in <em>iter_compile     yield compile_func(ufo, **options)   File "/usr/local/lib/python2.7/site-packages/ufo2ft/<strong>init</strong>.py", line 198, in compileTTF     glyphSet = preProcessor.process()   File "/usr/local/lib/python2.7/site-packages/ufo2ft/preProcessor.py", line 49, in process     func(ufo, glyphSet)   File "/usr/local/lib/python2.7/site-packages/ufo2ft/filters/<strong>init</strong>.py", line 219, in <strong>call</strong>     if include(glyph) and filter</em>(glyph):
   File "/usr/local/lib/python2.7/site-packages/ufo2ft/filters/removeOverlaps.py", line 50, in filter
     self.union(contours, pen)
   File "/usr/local/lib/python2.7/site-packages/booleanOperations/booleanOperationManager.py", line 101, in union
     return _performOperation("union", contours, [], outPen)
   File "/usr/local/lib/python2.7/site-packages/booleanOperations/booleanOperationManager.py", line 70, in _performOperation
     subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]
   File "/usr/local/lib/python2.7/site-packages/booleanOperations/flatten.py", line 69, in <strong>init</strong>
     self.segments = _convertPointsToSegments(points)
   File "/usr/local/lib/python2.7/site-packages/booleanOperations/flatten.py", line 441, in _convertPointsToSegments
     willBeReversed=willBeReversed
   File "/usr/local/lib/python2.7/site-packages/booleanOperations/flatten.py", line 171, in <strong>init</strong>
     for pt1, pt2 in decomposeQuadraticSegment(pointCoordinates[1:]):
   File "/usr/local/lib/python2.7/site-packages/fontTools/pens/basePen.py", line 360, in decomposeQuadraticSegment
     assert n > 0
 AssertionError</pre>



<hr class="wp-block-separator"/>



<p>解法：先使用 fontmake -h 查看沒有可以使用的參數，找到關於 overlaps</p>



<pre class="wp-block-preformatted">Handling of contours:
   --keep-overlaps       Do not remove any overlap.
   --overlaps-backend BACKEND
                         Select library to remove overlaps. Choose between:
                         booleanOperations, pathops (default:
                         booleanOperations)</pre>



<hr class="wp-block-separator"/>



<p>由於 pathops 在 python2 已無法使用，python3 的安裝方法：</p>



<pre class="wp-block-preformatted">pip3 install --upgrade skia-pathops</pre>



<p>由於直接執行 fontmake 會使用 python2 來執行，所以指令改成：</p>



<pre class="wp-block-preformatted">python3 -m fontmake</pre>



<hr class="wp-block-separator"/>



<p>在 python3 使用 booleanOperations </p>



<p>錯誤訊息：</p>



<pre class="wp-block-preformatted">INFO:fontmake.font_project:Building TTF for JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft:Pre-processing glyphs
 INFO:ufo2ft.filters:Running DecomposeComponentsFilter on JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft.filters:Running RemoveOverlapsFilter on JasonHandwriting2-JasonHandwriting2
 ERROR:ufo2ft.filters.removeOverlaps:Failed to remove overlaps for glyph00004
 Traceback (most recent call last):
   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in <em>run_module_as_main     "<strong>main</strong>", mod_spec)   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code     exec(code, run_globals)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 471, in &lt;module>     sys.exit(main())   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 460, in main     ufo_paths, is_instance=args.pop("masters_as_instances"), **args   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 1019, in run_from_ufos     self.build_ttfs(ufos, **kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 208, in build_ttfs     self.save_otfs(ufos, ttf=True, *kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontTools/misc/loggingTools.py", line 367, in wrapper     return func(args, **kwds)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 480, in save_otfs
     for font, ufo in zip(fonts, ufos):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 345, in _iter_compile
     yield compile_func(ufo, debugFeatureFile=debugFeatureFile, **options)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/<strong>init</strong>.py", line 198, in compileTTF
     glyphSet = preProcessor.process()
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/preProcessor.py", line 49, in process
     func(ufo, glyphSet)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/<strong>init</strong>.py", line 219, in <strong>call</strong>
     if include(glyph) and filter</em>(glyph):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/removeOverlaps.py", line 50, in filter
     self.union(contours, pen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 100, in union
     return _performOperation("union", contours, [], outPen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 69, in _performOperation
     subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 69, in &lt;listcomp>
     subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/flatten.py", line 68, in <strong>init</strong>
     self.segments = _convertPointsToSegments(points)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/flatten.py", line 448, in _convertPointsToSegments
     point.segmentType
 booleanOperations.exceptions.UnsupportedContourError: ('Trying to perform operation on unsupported segment type.', 'qcurve')</pre>



<hr class="wp-block-separator"/>



<p>改用 pathops，一樣有錯誤：</p>



<pre class="wp-block-preformatted">INFO:fontmake.font_project:Building TTF for JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft:Pre-processing glyphs
 INFO:ufo2ft.filters:Running DecomposeComponentsFilter on JasonHandwriting2-JasonHandwriting2
 INFO:ufo2ft.filters:Running RemoveOverlapsFilter on JasonHandwriting2-JasonHandwriting2
 ERROR:ufo2ft.filters.removeOverlaps:Failed to remove overlaps for glyph00004
 Traceback (most recent call last):
   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in <em>run_module_as_main     "<strong>main</strong>", mod_spec)   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code     exec(code, run_globals)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 471, in &lt;module>     sys.exit(main())   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 460, in main     ufo_paths, is_instance=args.pop("masters_as_instances"), **args   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 1019, in run_from_ufos     self.build_ttfs(ufos, **kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 208, in build_ttfs     self.save_otfs(ufos, ttf=True, *kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontTools/misc/loggingTools.py", line 367, in wrapper     return func(args, **kwds)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 480, in save_otfs
     for font, ufo in zip(fonts, ufos):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 345, in _iter_compile
     yield compile_func(ufo, debugFeatureFile=debugFeatureFile, **options)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/<strong>init</strong>.py", line 198, in compileTTF
     glyphSet = preProcessor.process()
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/preProcessor.py", line 49, in process
     func(ufo, glyphSet)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/<strong>init</strong>.py", line 219, in <strong>call</strong>
     if include(glyph) and filter</em>(glyph):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/removeOverlaps.py", line 50, in filter
     self.union(contours, pen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 100, in union
     return <em>performOperation("union", contours, [], outPen)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 69, in _performOperation     subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/booleanOperationManager.py", line 69, in &lt;listcomp>     subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/flatten.py", line 68, in <strong>init</strong>     self.segments = _convertPointsToSegments(points)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/booleanOperations/flatten.py", line 448, in _convertPointsToSegments     point.segmentType booleanOperations.exceptions.UnsupportedContourError: ('Trying to perform operation on unsupported segment type.', 'qcurve') ➜  ttf ./build_jason_font2.sh INFO:fontmake.font_project:Building TTF for JasonHandwriting2-JasonHandwriting2 INFO:ufo2ft:Pre-processing glyphs INFO:ufo2ft.filters:Running DecomposeComponentsFilter on JasonHandwriting2-JasonHandwriting2 INFO:ufo2ft.filters:Running RemoveOverlapsFilter on JasonHandwriting2-JasonHandwriting2 Traceback (most recent call last):   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main     "<strong>main</strong>", mod_spec)   File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code     exec(code, run_globals)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 471, in &lt;module>     sys.exit(main())   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/<strong>main</strong>.py", line 460, in main     ufo_paths, is_instance=args.pop("masters_as_instances"), **args   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 1019, in run_from_ufos     self.build_ttfs(ufos, **kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 208, in build_ttfs     self.save_otfs(ufos, ttf=True, *kwargs)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontTools/misc/loggingTools.py", line 367, in wrapper     return func(args, **kwds)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 480, in save_otfs
     for font, ufo in zip(fonts, ufos):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontmake/font_project.py", line 345, in _iter_compile
     yield compile_func(ufo, debugFeatureFile=debugFeatureFile, *options)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/<strong>init</strong>.py", line 198, in compileTTF     glyphSet = preProcessor.process()   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/preProcessor.py", line 49, in process     func(ufo, glyphSet)   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/<strong>init</strong>.py", line 219, in <strong>call</strong>     if include(glyph) and filter(glyph):
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufo2ft/filters/removeOverlaps.py", line 50, in filter
     self.union(contours, pen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/pathops/operations.py", line 10, in union
     contour.draw(pen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufoLib2/objects/contour.py", line 54, in draw
     self.drawPoints(pointPen)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/ufoLib2/objects/contour.py", line 78, in drawPoints
     pointPen.endPath()
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontTools/pens/pointPen.py", line 140, in endPath
     self._flushContour(segments)
   File "/Users/chunyuyao/Library/Python/3.7/lib/python/site-packages/fontTools/pens/pointPen.py", line 211, in _flushContour
     pen.qCurveTo(</em>points)
   File "src/python/pathops/_pathops.pyx", line 700, in pathops._pathops.PathPen.qCurveTo
   File "src/python/pathops/_pathops.pyx", line 703, in pathops._pathops.PathPen._qCurveToOne
 TypeError: 'NoneType' object is not subscriptable</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2020/02/ufo2ft-filtersrunning-removeoverlapsfilter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
