

<?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>MaxCodeReview &#8211; Max的每一天</title>
	<atom:link href="https://max-everyday.com/tag/maxcodereview/feed/" rel="self" type="application/rss+xml" />
	<link>https://max-everyday.com</link>
	<description>認真過每一天、快樂過每一天</description>
	<lastBuildDate>Tue, 23 Aug 2022 04:35:35 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://max-everyday.com/wp-content/uploads/2020/02/ic_launcher_round_2020-003.png</url>
	<title>MaxCodeReview &#8211; Max的每一天</title>
	<link>https://max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>程式效能調整：以異體字比對為例</title>
		<link>https://max-everyday.com/2020/04/alternate-form-compare/</link>
					<comments>https://max-everyday.com/2020/04/alternate-form-compare/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Sat, 11 Apr 2020 20:11:15 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=11089</guid>

					<description><![CDATA[沒想到「異體字」離我們的生活這麼近，冰淇淋的「淋」和姓氏「林」都有異體字。 前陣子隨手修改了一下Google和Adobe分享的字型檔案，因為Max完全不懂字體相關的知識， [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>沒想到「異體字」離我們的生活這麼近，冰淇淋的「淋」和姓氏「林」都有異體字。</p>



<p>前陣子隨手修改了一下Google和Adobe分享的字型檔案，因為Max完全不懂字體相關的知識，把字型檔案解開後，打包不回去。Google查了半天，也看不懂，亂給設定值也失敗，山不轉路轉，那就用其他替代解法吧。</p>



<p>首先，要取得異體字的對應表，需要到別人的網站上去偷資料庫內容，偷完的結果分享如下：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>查「部首」、「筆畫」、「異體字」、「同義字」和「文字組件」的字典<br><a href="https://max-everyday.com/2020/04/chinese-dictionary-radical/">https://max-everyday.com/2020/04/chinese-dictionary-radical/</a></p></blockquote>



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



<p>有了對應表後，要把字型檔裡的字都翻一遍出來檢查對應，第一個版本寫的程式跑了15分鐘，居然一個字都沒有比對完成。@_@；只好重新思考解法。</p>



<p>新的解法和Code Review 影片：<br><a href="https://youtu.be/JX6FnCPtRyw">https://youtu.be/JX6FnCPtRyw</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio wp-embed-aspect-16-9"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe title="[MaxCodeReview] 程式效能調整：以異體字比對為例" width="885" height="498" src="https://www.youtube.com/embed/JX6FnCPtRyw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>程式架構：</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="734" src="https://max-everyday.com/wp-content/uploads/2020/04/alternate_compare-1024x734.jpg?v=1586635841" alt="" class="wp-image-11091" srcset="https://max-everyday.com/wp-content/uploads/2020/04/alternate_compare-1024x734.jpg?v=1586635841 1024w, https://max-everyday.com/wp-content/uploads/2020/04/alternate_compare-500x358.jpg?v=1586635841 500w, https://max-everyday.com/wp-content/uploads/2020/04/alternate_compare.jpg?v=1586635841 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>寫出來的python 副程式：</p>



<pre class="wp-block-preformatted">def compare_dictionary(source_ff, unicode_field, full_dict):
    target_unicode_set, target_dict = load_files_to_set_dict(source_ff, unicode_field)
    alternate_set = set()
    alternate_dict = {}
    for char_key in full_dict:
        char_dict = full_dict[char_key]
        for alternate in char_dict['alternate']:
            unicode_int = ord(alternate)
            alternate_set.add(unicode_int)
            alternate_dict[unicode_int] = ord(char_key)
    diff_set_common =  target_unicode_set &amp; alternate_set
    copy_count = 0
    for item in diff_set_common:
        if not alternate_dict[item] in target_unicode_set:
            target_filename = "uni%s.glyph" % str(hex(alternate_dict[item]))[2:].upper()
            source_path = join(source_ff,target_dict[item])
            target_path = join(source_ff,target_filename)
            shutil.copy(source_path,target_path)
            overwrite_config_encoding(target_path, alternate_dict[item], unicode_field)
            copy_count += 1
</pre>



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



<p>後記：由於資料庫不是很完整，上面的方法後來沒有再使用了，改用直接修改 glyph 檔案，直接比對 unicode code 編碼，符合的話，就增加 &#8220;AltUni2: &#8221; 欄位，使用的字典檔：<br><a href="https://max-everyday.com/2020/04/chinese-dictionary-radical/">https://max-everyday.com/2020/04/chinese-dictionary-radical/</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/04/alternate-form-compare/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>筆畫交叉的判斷</title>
		<link>https://max-everyday.com/2020/04/stroke-join-check/</link>
					<comments>https://max-everyday.com/2020/04/stroke-join-check/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Fri, 03 Apr 2020 19:08:43 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10983</guid>

					<description><![CDATA[「筆畫」是指漢字書寫時，不間斷地一次連續寫成的一條線條。筆畫是漢字的最小構成單位。 Max 要來挑戰的是判斷某一個交叉點，是二筆畫，還是同一筆畫。同一筆和不同筆，在之後文 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>「筆畫」是指漢字書寫時，不間斷地一次連續寫成的一條線條。筆畫是漢字的最小構成單位。</p>



<p>Max 要來挑戰的是判斷某一個交叉點，是二筆畫，還是同一筆畫。同一筆和不同筆，在之後文字效果的處理會不同，同一筆畫會變形，與第二筆畫的交叉不應該變形。</p>



<p>這次寫完的程式，過二天再回來看，就像完全沒看過的程式一樣陌生，完全不知道當初在寫什麼！數學的世界，常常讓人無法理解，太難了。Q_Q；</p>



<p>程式碼的Code Review 參考下面的 YouTube 影片：<br><a href="https://youtu.be/TXNyNkWpde0">https://youtu.be/TXNyNkWpde0</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe title="[MaxCodeReview] 筆畫交叉的判斷" width="885" height="498" src="https://www.youtube.com/embed/TXNyNkWpde0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



<p>舉例：判斷「丸」的「十」交叉不是同一筆畫，右上角長出來的尾巴是同一筆畫。</p>



<p>在判斷筆畫時還是第二筆。水平線和垂直線的判斷相對容易很多，比較難的是「乂」叉叉系列的判斷，例如：「女」，的轉角是同一筆畫。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="975" height="889" src="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-04-at-00.53.32.png" alt="" class="wp-image-10984" srcset="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-04-at-00.53.32.png?v=1585933220 975w, https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-04-at-00.53.32-500x456.png?v=1585933220 500w" sizes="(max-width: 975px) 100vw, 975px" /></figure>



<p>產出的副程式：</p>



<pre class="wp-block-preformatted">def join_line_check(self,x0,y0,x1,y1,x2,y2):
    inside_stroke_flag = False
    previous_extend_x,previous_extend_y = spline_util.two_point_extend(x0,y0,x1,y1, self.config.STROKE_WIDTH_AVERAGE)
    previous_extend_x_offset = x1-previous_extend_x
    previous_extend_y_offset = y1-previous_extend_y
    previous_left_x,previous_left_y = spline_util.two_point_extend(x0,y0,x1,y1, int(2.0 *self.config.STROKE_WIDTH_AVERAGE))
    tmp_next_extend_x,tmp_next_extend_y=spline_util.two_point_extend(x2,y2,x1,y1, self.config.STROKE_WIDTH_AVERAGE)
    next_extend_x = tmp_next_extend_x - previous_extend_x_offset
    next_extend_y = tmp_next_extend_y - previous_extend_y_offset
    next_left_x = next_extend_x - previous_extend_x_offset
    next_left_y = tmp_next_extend_y - previous_extend_y_offset -previous_extend_y_offset
    bmp_x1, bmp_y1, bmp_x2, bmp_y2, bmp_x3, bmp_y3, bmp_x4, bmp_y4 = previous_extend_x, previous_extend_y, previous_left_x, previous_left_y, next_left_x, next_left_y, next_extend_x, next_extend_y
    inside_stroke_flag = self.is_inside_stroke(bmp_x1, bmp_y1, bmp_x2, bmp_y2, bmp_x3, bmp_y3, bmp_x4, bmp_y4)
    return inside_stroke_flag
</pre>



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



<p>前一篇文章：<br>二點之間內縮後坐標<br><a href="https://max-everyday.com/2020/04/two-point-extend/">https://max-everyday.com/2020/04/two-point-extend/</a></p>



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



<p>上面的方法，似乎太容易誤判，改良為下面作法：</p>



<pre class="wp-block-preformatted">def join_line_check(self,x0,y0,x1,y1,x2,y2):
    inside_stroke_flag = False
    stroke_width = self.get_stroke_width(x0,y0,x1,y1)
    previous_extend_x,previous_extend_y = spline_util.two_point_extend(x0,y0,x1,y1, int(stroke_width * 1.2))
    next_extend_x,next_extend_y=spline_util.two_point_extend(x2,y2,x1,y1, int(stroke_width/2))
    next_extend_x_offset = x1-next_extend_x
    next_extend_y_offset = y1-next_extend_y
    test_x = previous_extend_x - next_extend_x_offset
    test_y = previous_extend_y - next_extend_y_offset
    bmp_x = self.ff_x_to_bmp_x(test_x)
    bmp_y = self.ff_y_to_bmp_y(test_y)
    data=self.bmp_image.getpixel((bmp_x, bmp_y))
    if data &lt;=128:
        inside_stroke_flag = True
    return inside_stroke_flag
</pre>



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



<p>上面共用筆寬的作做，還是踩到雷了，在下面的情況會誤判，應該不做事情，實際結果卻是加了圓角：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="975" height="889" src="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-06-at-23.28.56.png" alt="" class="wp-image-10992" srcset="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-06-at-23.28.56.png?v=1586187039 975w, https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-06-at-23.28.56-500x456.png?v=1586187039 500w" sizes="(max-width: 975px) 100vw, 975px" /></figure>



<p>解法很簡單，先取得上方的筆寬（實際值是41單位），再取得左邊筆寬（實際值是74單位，跨過左邊紫色區塊後，檢查左上角有無黑線。</p>



<p>輪出的除錯訊息如下：</p>



<pre class="wp-block-preformatted">test coordinate: 731 456 - 535 456 - 535 408
stroke_width_lower: 74
stroke_width_upper: 41
test_x,y: 461 480
test_x,y: 460 480
test_x,y: 459 480
test_x,y: 458 480
test_x,y: 457 480
test_x,y: 456 480
test_x,y: 455 480
test_x,y: 454 480
test_x,y: 453 480
test_x,y: 452 480
test_x,y: 451 480
test_x,y: 450 480
test_x,y: 449 480
test_x,y: 448 480</pre>



<p>說明：要檢查 [731,456] , [535,456] , [535,408] 這個角，是交叉線還是角落。依序取得線條寬度後，在左上角做測試。測試結果：是交叉線。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/04/stroke-join-check/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>二點之間內縮後坐標</title>
		<link>https://max-everyday.com/2020/04/two-point-extend/</link>
					<comments>https://max-everyday.com/2020/04/two-point-extend/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Fri, 03 Apr 2020 06:37:16 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10973</guid>

					<description><![CDATA[最近這幾天，Max都在 X軸和Y軸的世界裡打滾，滿有趣的。坐標相關的數學，在離開學校後，幾乎在生活上都沒到過，重新回來應用數學，覺得「數學很神奇」。 為什麼要寫下這篇文章 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>最近這幾天，Max都在 X軸和Y軸的世界裡打滾，滿有趣的。坐標相關的數學，在離開學校後，幾乎在生活上都沒到過，重新回來應用數學，覺得「數學很神奇」。</p>



<p>為什麼要寫下這篇文章？因為不寫下來，我隔2天就會忘了，寫過的程式碼都像全新沒看過的。</p>



<p>影片說明：<br><a href="https://youtu.be/R0sPFHd2yis">https://youtu.be/R0sPFHd2yis</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] 二點之間內縮後坐標" width="885" height="498" src="https://www.youtube.com/embed/R0sPFHd2yis?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>視覺化舉例：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="975" height="889" src="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-03-at-13.36.35.png" alt="" class="wp-image-10974" srcset="https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-03-at-13.36.35.png?v=1585895756 975w, https://max-everyday.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-03-at-13.36.35-500x456.png?v=1585895756 500w" sizes="(max-width: 975px) 100vw, 975px" /></figure>



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



<p>使用到的 Python 程式碼：</p>



<pre class="wp-block-preformatted"># distance between two points
from math import hypot

def two_point_extend(x1,y1,x2,y2,distance_offset):
    distance = get_distance(x1,y1,x2,y2)
    distance_percent = (distance_offset / distance)

    x_offset = int((x2-x1) * distance_percent)
    y_offset = int((y2-y1) * distance_percent)
    
    # 斜線上的「內縮」的新坐標。
    new_x=x2+x_offset
    new_y=y2+y_offset

    return new_x,new_y</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/04/two-point-extend/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>幫字型加字重</title>
		<link>https://max-everyday.com/2020/02/change-weight-for-font/</link>
					<comments>https://max-everyday.com/2020/02/change-weight-for-font/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Mon, 24 Feb 2020 10:43:17 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10434</guid>

					<description><![CDATA[文字和字型，一直是門藝術，是很美的東西，很高興Max可以替「中華民國美學」盡分心力。 有一天遇到好心人（游清松）在分享他製作的免費授權字型，真的是大好人一枚，花這麼多時間 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>文字和字型，一直是門藝術，是很美的東西，很高興Max可以替「中華民國美學」盡分心力。</p>



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



<p>有一天遇到好心人（游清松）在分享他製作的免費授權字型，真的是大好人一枚，花這麼多時間，在做照福大眾的事情，Max在用過字型後，發現還滿好看的，於是想幫他做一個網站來推廣：<br><a href="https://jasonfonts.max-everyday.com/">https://jasonfonts.max-everyday.com/</a></p>



<p>網站隨手點一點就完成了，大約花了一個晚上的時間就完成了上列的網站，但創作字型的作者目前沒打算使用，暫時算是做白工。</p>



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



<p>在使用某些字型時發現字太細，長像太斯文，希望可以有粗一點的版本，Max示範如何幫字型加字重。參考實際操用影片：<br><a href="https://youtu.be/rQ56_CHcBs0">https://youtu.be/rQ56_CHcBs0</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] 幫字型加字重" width="885" height="498" src="https://www.youtube.com/embed/rQ56_CHcBs0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<h2 class="wp-block-heading">Step 1：先取得要處理的字型</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="828" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-10.00.15-1024x828.jpg?v=1582539470" alt="" class="wp-image-10526" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-10.00.15-1024x828.jpg?v=1582539470 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-10.00.15-500x404.jpg?v=1582539470 500w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-10.00.15.jpg?v=1582539470 1098w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Step 2：使用FontForge 開啟並另存新檔</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="406" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.19.40.jpg" alt="" class="wp-image-10527" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.19.40.jpg?v=1582540207 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.19.40-500x198.jpg?v=1582540207 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Step 3：執行調整字重的script</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="732" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.39.15.jpg" alt="" class="wp-image-10530" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.39.15.jpg?v=1582541240 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-18.39.15-500x357.jpg?v=1582541240 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>當然，也可以不要使用script（腳本）而是用滑鼠去點，用滑鼠很花時間，而且操作的步驟又很多，使用script（腳本）來操作重覆性高的事情，相對輕鬆一點。</p>



<p>如果是手動點，不是透過script 請先「全選」所有字型後，按右鍵選「Expand Stroke&#8230;」即可取得調整字重後的字型。 </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="491" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-25-at-11.37.41.jpg" alt="" class="wp-image-10561" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-25-at-11.37.41.jpg?v=1582602015 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-25-at-11.37.41-500x240.jpg?v=1582602015 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>FontForge script 官方的教學網址：</p>



<ul class="wp-block-list"><li>Scripting FontForge</li><li><a href="https://fontforge.org/docs/scripting/scripting-alpha.html">https://fontforge.org/docs/scripting/scripting-alpha.html</a></li></ul>



<p>附上完整script：</p>



<pre class="wp-block-preformatted">!/usr/local/bin/fontforge
 Print("===================================")
 Open("JasonHandwriting2-Regular.sfdir")
 SetFontNames("JasonHandwriting2-Regular","JasonHandwriting2","JasonHandwriting2-Regular","Regular")
 Generate("JasonHandwriting2-Regular.ttf")
 Save("JasonHandwriting2-Light.sfdir")
 Save("JasonHandwriting2-SemiBold.sfdir")
 Save("JasonHandwriting2-Bold.sfdir")
 Save("JasonHandwriting2-Heavy.sfdir")
 Close()
 Print("===================================")
 Print("Open JasonHandwriting2 Light")
 Open("JasonHandwriting2-Light.sfdir")
 SetFontNames("JasonHandwriting2-Light","JasonHandwriting2","JasonHandwriting2-Light","Light")
 SelectAll()
 Print("ExpandStroke…")
 ExpandStroke(15,45,15,15,0,2)
 Save("JasonHandwriting2-Light.sfdir")
 Print("Generate ttf…")
 Generate("JasonHandwriting2-Light.ttf")
 Close()
 Print("Close JasonHandwriting2 Light")
 Print("===================================")
 Print("Open JasonHandwriting2 Medium")
 Open("JasonHandwriting2-Medium.sfdir")
 SetFontNames("JasonHandwriting2-Medium","JasonHandwriting2","JasonHandwriting2-Medium","Medium")
 SetMacStyle(-1)
 SetMacStyle(0x01)
 Print("ExpandStroke…")
 SelectAll()
 ExpandStroke(12,45,12,12,0,1)
 Save("JasonHandwriting2-Medium.sfdir")
 Print("Generate ttf…")
 Generate("JasonHandwriting2-Medium.ttf")
 Close()
 Print("Close JasonHandwriting2 Medium")
 Print("===================================")
 Print("Open JasonHandwriting2 SemiBold")
 Open("JasonHandwriting2-SemiBold.sfdir")
 SetFontNames("JasonHandwriting2-SemiBold","JasonHandwriting2","JasonHandwriting2-SemiBold","SemiBold")
 SetMacStyle(-1)
 SetMacStyle(0x01)
 Print("ExpandStroke…")
 SelectAll()
 ExpandStroke(24,45,24,24,0,1)
 Save("JasonHandwriting2-SemiBold.sfdir")
 Print("Generate ttf…")
 Generate("JasonHandwriting2-SemiBold.ttf")
 Close()
 Print("Close JasonHandwriting2 SemiBold")
 Print("===================================")
 Print("Open JasonHandwriting2 Bold")
 Open("JasonHandwriting2-Bold.sfdir")
 SetFontNames("JasonHandwriting2-Bold","JasonHandwriting2","JasonHandwriting2-Bold","Bold")
 SetMacStyle(-1)
 SetMacStyle(0x01)
 Print("ExpandStroke…")
 SelectAll()
 ExpandStroke(34,45,34,34,0,1)
 Save("JasonHandwriting2-Bold.sfdir")
 Print("Generate ttf…")
 Generate("JasonHandwriting2-Bold.ttf")
 Close()
 Print("Close JasonHandwriting2 Bold")</pre>



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



<h2 class="wp-block-heading">FontForge 的說明：</h2>



<p><a href="https://fontforge.org/elementmenu.html#Expand">ExpandStroke</a>(width)<br>ExpandStroke(width,line cap, line join)<br>ExpandStroke(width,line cap, line join,0,removeinternal /external flag)<br>ExpandStroke(width,calligraphic-angle,height-numerator,height-denom)<br><strong>ExpandStroke(width,calligraphic-angle,height-numerator,height-denom, 0, remove internal/external flag)</strong></p>



<p>In the first format a line cap of &#8220;butt&#8221; and line join of &#8220;round&#8221; are implied.<br>A value of 1 for remove internal/external will remove the internal contour, a value of 2 will remove the external contour.<br>The first three calls simulate the PostScript &#8220;stroke&#8221; command, the two final simulate a caligraphic pen.</p>



<ul class="wp-block-list"><li><strong>Width</strong><br>In the PostScript &#8220;stroke&#8221; command the width is the distance between the two generated curves. To be more precise, at ever point on the original curve, a point will be added to each of the new curves at width/2 units as measured on a vector normal to the direction of the original curve at that point.<br>In a caligraphic pen, the width is the width of the pen used to draw the curve.</li><li><strong>Line-cap</strong><br>Can have one of three values: <br>0=&gt; butt, <br>1=&gt;round, <br>2=&gt;square</li><li><strong>Line-join</strong><br>Can have one of three values: <br>0=&gt;miter, <br>1=&gt;round, <br>2=&gt;bevel</li><li><strong>caligraphic-angle</strong><br>the (fixed) angle at which the pen is held.</li><li><strong>height-numerator/denominator</strong><br>These two values specify a ratio between the height and the width<br>height = numerator * width / denominator<br>(the scripting language only deals in integers, so when fractions are needed this kludge is used)</li><li><strong>remove internal/external contour flags</strong><br>1 =&gt; remove internal contour<br>2=&gt; remove external contour<br>(you may not remove both contours)<br>4 =&gt; run remove overlap on result (buggy)</li></ul>



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



<p>實際測試，使用參數愈少的，問題愈多！建議使用最後一組，參數很多的，我幫大家把參數加粗。</p>



<p>使用最後一組的缺點是，Line Join 會使用 Bevel <strong>很醜！</strong>不能接受 Bevel 請改用<br>ExpandStroke(width,line cap, line join,0,removeinternal /external flag)</p>



<p>範例：</p>



<pre class="wp-block-preformatted">ExpandStroke(15,1,0,0,1)</pre>



<p>大多的情況都是很難二全其美，在使用 line join=0 可以讓文字在變細時，比較銳利，問題是也可能變成這樣子，「微」字就開叉了：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="216" height="209" src="https://max-everyday.com/wp-content/uploads/2020/03/76655072-77ad2080-65a7-11ea-9210-720631d3faf8.jpeg" alt="" class="wp-image-10850"/></figure>



<p>折衷的方案是使用 join join=1 ，讓筆畫間有渲染的感覺，會略醜，但問題較少 T_T。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="830" height="273" src="https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-15-at-07.11.03-down.jpg" alt="" class="wp-image-10856" srcset="https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-15-at-07.11.03-down.jpg?v=1584229324 830w, https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-15-at-07.11.03-down-500x164.jpg?v=1584229324 500w" sizes="(max-width: 830px) 100vw, 830px" /></figure>



<p>最佳解法是使用 Join Limit as Legnth</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="641" src="https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-17-at-08.59.09.jpg" alt="" class="wp-image-10892" srcset="https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-17-at-08.59.09.jpg?v=1584407090 1024w, https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-17-at-08.59.09-500x313.jpg?v=1584407090 500w, https://max-everyday.com/wp-content/uploads/2020/03/Screen-Shot-2020-03-17-at-08.59.09-200x125.jpg?v=1584407090 200w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>更多的 stroke() 範例：<br><a href="https://github.com/fontforge/fontforge/blob/1cd85a0e621352f81aca07bf9eb42467ee078f38/tests/test1003.py">https://github.com/fontforge/fontforge/blob/1cd85a0e621352f81aca07bf9eb42467ee078f38/tests/test1003.py</a></p>



<p>附註：上面的範例，要使用新的版本才能使用。Max 用的 stroke 是：</p>



<pre class="wp-block-preformatted">glyph.stroke("circular",54,cap="round",join="miter",angle=math.radians(45),removeexternal=True,simplify=True,joinlimit=6)</pre>



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



<p>針對使用上面會掛掉的字，改用下面這組就 OK 了：</p>



<pre class="wp-block-preformatted">glyph.stroke("circular",54,cap="round",join="miter",removeexternal=True,simplify=True)</pre>



<p>主要差在，angle=math.radians(45)，有些字可以使用，有些字不行。</p>



<p>完整的程式碼，放在這一個網頁裡：<br>FontForge script debug<br><a href="http://stackoverflow.max-everyday.com/2020/03/fontforge-script-debug/">http://stackoverflow.max-everyday.com/2020/03/fontforge-script-debug/</a></p>



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



<p>建議使用「較新」版本的FontForge 執行檔來處理，可能錯誤會較少。如果是使用macOS 可以試看看在 .pe 檔案裡，最上面使用這一行：</p>



<pre class="wp-block-preformatted">#!/Applications/FontForge.app/Contents/Resources/opt/local/bin/fontforge</pre>



<p>開發者的版本(<a href="https://fontforge.org/en-US/downloads/mac-dl/#collapseDev">Development builds</a>)：<br><a href="http://dl.bintray.com/fontforge/fontforge/">http://dl.bintray.com/fontforge/fontforge/</a></p>



<p>開發者的版本，不是萬能的，雖然解決掉一些字在 expand stroke 時會亂掉的問題，但相對不太隱定，有較高的機率程式會卡住，卡住有可能是(1)程式完全沒回應，也可能是(2)顯示有錯就關閉掉程式（閃退）。</p>



<p class="has-text-color has-vivid-red-color">「<strong>Correct Direction</strong>」 有可能會造成字型檔被改壞掉，使用「全選」來做這一個功能，可能會有不具名的字會改壞掉。<br><br>但是！有些字型裡，還沒有去使用「Correct Direction」功能，產生出來的方向就已經出問題了，又不可能一個一個字去檢查，到底修改字重後，會放大還是縮小。結論：用與不用，都很難選。</p>



<p class="has-text-color has-vivid-red-color">最後Max還是決定都使用，因為這樣比較方便用來做其他字體樣式的處理，透過使用Correct Direction，大多的「點」會被重新排序，方便做處理。</p>



<p>如果遇到在 Expand stroke 時，方向錯誤的區塊，就是預期應該變細，但是卻變粗了的情況，請使用一下 Correct Direction，如果還是無法解決，最佳解法是使用匯出(export)功能匯出該字為 svg 格式，再把 fontforge 裡的線條都清空，透過匯入(import)功能匯入該字的 svg 檔案，通常就不會有問題。</p>



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



<p>為什麼會講到開發者版本，參考看看：</p>



<p>莫大毛筆字體的調整 ver 1.30<br><a href="https://max-everyday.com/2020/03/bakudaifont-ver-1-30/">https://max-everyday.com/2020/03/bakudaifont-ver-1-30/</a></p>



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



<p>除了透過 FontForge script 來改字重，也可以透過 python script , 可以操控的變數更多，功能也更多。<br><a href="https://fontforge.org/docs/scripting/python/fontforge.html#module-functions">https://fontforge.org/docs/scripting/python/fontforge.html#module-functions</a></p>



<p><code>glyph.</code><code>stroke</code>(<em>&#8220;circular&#8221;</em>,&nbsp;<em>width</em>[,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>FLAGS</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;elliptical&#8221;</em>,&nbsp;<em>width</em>,&nbsp;<em>minor_width</em>,&nbsp;<em>ANGLE</em>[,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>FLAGS</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;calligraphic&#8221;</em>,&nbsp;<em>width</em>,&nbsp;<em>height</em>,&nbsp;<em>angle</em>[,&nbsp;<em>FLAGS</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;polygon&#8221;</em>,&nbsp;<em>contour</em>[,&nbsp;<em>FLAGS</em>])<code>(Legacy interface)</code><code>glyph.</code><code>stroke</code>(<em>&#8220;circular&#8221;</em>,&nbsp;<em>width</em>[,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>ANGLE</em>,&nbsp;<em>KEYWORD</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;elliptical&#8221;</em>,&nbsp;<em>width</em>,&nbsp;<em>minor_width</em>[,&nbsp;<em>ANGLE</em>,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>KEYWORD</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;calligraphic&#8221;</em>,&nbsp;<em>width</em>,&nbsp;<em>height</em>[,&nbsp;<em>ANGLE</em>,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>KEYWORD</em>])<code>glyph.</code><code>stroke</code>(<em>&#8220;convex&#8221;</em>,&nbsp;<em>contour</em>[,&nbsp;<em>ANGLE</em>,&nbsp;<em>CAP</em>,&nbsp;<em>JOIN</em>,&nbsp;<em>KEYWORD</em>])<code>(Current interface)</code></p>



<p>Strokes the contours of the glyph according to the supplied parameters. See the&nbsp;<a href="https://fontforge.org/docs/techref/stroke.html">stroke</a>&nbsp;documentation for a more complete description of the facility and its parameters.</p>



<p>A&nbsp;<code>"circular"</code>&nbsp;nib just has a&nbsp;<code>width</code>&nbsp;(the diameter), while an&nbsp;<code>"elliptical"</code>&nbsp;nib has a&nbsp;<code>width</code>&nbsp;(major axis) and a&nbsp;<code>minor_width</code>&nbsp;(minor axis). A&nbsp;<code>"calligraphic"</code>&nbsp;or&nbsp;<code>"rectangular"</code>&nbsp;nib is similar in that it has a&nbsp;<code>width</code>&nbsp;and a&nbsp;<code>height</code>. Finally a&nbsp;<code>"convex"</code>&nbsp;nib is one supplied by the user as a&nbsp;<a href="https://fontforge.org/docs/scripting/python/fontforge.html#fontforge.contour"><code>fontforge.contour</code></a>&nbsp;or&nbsp;<a href="https://fontforge.org/docs/scripting/python/fontforge.html#fontforge.layer"><code>fontforge.layer</code></a>. It must be&nbsp;<em>convex</em>&nbsp;as defined in the main stroke facility documentation.</p>



<p><code>ANGLE</code>&nbsp;is optional. It can be specified either positionally or with&nbsp;<code>angle=float</code>. It must be a floating point number in units of radians and defaults to zero. The nib is rotated by this angle before stroking the path.</p>



<p><code>CAP</code>&nbsp;is optional. It can be specified either positionally or with&nbsp;<code>cap=string</code>. It must be one of the strings “nib” (the default), “butt”, “round”, and “bevel”.</p>



<p><code>JOIN</code>&nbsp;is optional. It can be specified either positionally or with&nbsp;<code>join=string</code>. It must be one of the strings “nib” (the default), “bevel”, “miter”, and “miterclip”, “round”, and “arcs”.</p>



<p><code>KEYWORD</code>&nbsp;Parameters:<code>removeinternal (boolean, default=False)</code></p>



<p>When a contour is closed and clockwise, only the smaller “inside” contour is retained. When a contour is closed and counter-clockwise only the larger “outside” contour is retained.<code>removeexternal (boolean, default=False)</code></p>



<p>When a contour is closed and clockwise, only the larger “outside” contour is retained. When a contour is closed and counter-clockwise only the smaller “inside” contour is retained.<code>extrema (boolean, default=True)</code></p>



<p>When true, any missing extrema on the stroked paths are added.<code>simplify (boolean, default=True)</code></p>



<p>When true, simplify is called on the path before it is returned. The&nbsp;<code>error-bound</code>&nbsp;is set to the&nbsp;<code>accuracy</code>&nbsp;value.<code>removeoverlap (string, default="layer")</code></p>



<p>Specifies whether, and on what basis, remove-overlap should be run. “layer” corresponds to running remove-overlap on the&nbsp;<a href="https://fontforge.org/docs/scripting/python/fontforge.html#fontforge.layer"><code>layer</code></a>&nbsp;as a whole. “contour” corresponds to running remove-overlap on individual contours. “none” corresponds to not running remove-overlap. Note that because the stroke facility relies on remove-overlap to eliminate cusps and other artifacts, “none” is an unusual choice and available primarily for debugging purposes.<code>accuracy (float, default=0.25)</code></p>



<p>This is a target (but not a guarantee) for the allowed error, in em-units, of the output relative to the input path and nib geometries. Higher values allow more error will typically yield contours with fewer points.<code>jlrelative (boolean, default=True)</code></p>



<p>See below.<code>joinlimit (float, default=20)</code></p>



<p>Specifies the maximum length of a “miter”, “miterclip”, or “arcs” join. For “miter” joins that would be longer will fall back to “bevel”. With “miterclip” and “arcs” a longer join will be trimmed to the specified length. Note, however, that no join is trimmed past the “bevel line” and therefore lower values do not guarantee a given length.</p>



<p>When&nbsp;<code>jlrelative</code>&nbsp;is false the value is interpreted as a length in em-units. Otherwise the value is interpreted as a multiple of “stroke-widths”: the average of the spans of the nib at the incoming and outgoing join angles.<code>ecrelative (boolean, default=True)</code></p>



<p>See below.<code>extendcap (float, default=0)</code></p>



<p>When the contour being stroked is open and the&nbsp;<code>cap</code>&nbsp;style is “butt” or “round”, this parameter adds area between the end of that contour and the cap. The length of that area will never be less than the specified value but may be more, depending on the geometry of the nib and the join. (However, it will always be exact for circular nibs.)</p>



<p>When&nbsp;<code>ecrelative</code>&nbsp;is false the value is interpreted as a length in em-units. Otherwise the value is interpreted as a multiple of “stroke-widths”: the span of the stroked path at the angle at the cap.<code>arcsclip (string, default="auto")</code></p>



<p>When using the “arcs” join style this parameter influences the algorithm used to clip joins that exceed the&nbsp;<code>joinlimit</code>. The value “svg2” specifies the standard SVG algorithm while the value “ratio” specifies an alternative algorithm that works better for longer and thinner nibs at shorter limits. The default value “auto” chooses the “ratio” algorithm for oblong elliptical and calligraphic nibs and&nbsp;<code>jlrelative&nbsp;joinlimit</code>&nbsp;&lt; 4 and the “svg2” algorithm otherwise.</p>



<p>In the legacy interface,&nbsp;<code>FLAGS</code>&nbsp;is an optional tuple containing zero or more of the strings “removeinternal”, “removeexternal”, and “cleanup”. The last is interpreted as&nbsp;<code>simplify=True</code>, with a default of&nbsp;<code>False</code>&nbsp;when a FLAGS tuple is present.</p>



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



<p></p>



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



<h2 class="wp-block-heading">補充說明：</h2>



<ul class="wp-block-list"><li>上面的例子，可以在Windows/macOS/Linux平台上使用。</li><li>非開源的字型檔，自行編修沒有辦法被得知，但公開發佈也許會有法律上的問題。</li><li>不是所有的字型都可以使用。</li><li>透過程式調整筆劃可能會失敗，字可能會被改壞掉。</li><li>有些字型需要先使用Select All，再用 Correct Direction 調整方向，才不會造成調整的結論是：有些字變粗，有些字變細。</li><li>透過程式調整筆劃，只能調整粗細無法調整間距，所以有些字會因為調粗而變的太擠，或跟下一個字會相連在一起。</li><li>沒有任何一個字型編輯軟體能確保重新儲存的字型檔跟原始檔一模一樣。編修後的字型檔，很有可能會有kerning數值跑掉、直排字符異常或各種問題。</li><li>有空多看些英文的網站也滿好的，練習一下英文。</li></ul>



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



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



<p>幫字型檔補缺字<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></p>



<p>免費商用字體整理<br><a href="https://max-everyday.com/2020/02/free-commercial-fonts/">https://max-everyday.com/2020/02/free-commercial-fonts/</a></p>



<p>比較不同字形檔之間的缺字差異：<br><a href="https://max-everyday.com/2020/02/font-glyph-set-compare/">https://max-everyday.com/2020/02/font-glyph-set-compare/</a></p>



<p>FontForge 調整字型在 Windows 的安裝顯示名稱<br><a href="https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/">https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/02/change-weight-for-font/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>幫字型檔補缺字</title>
		<link>https://max-everyday.com/2020/02/how-to-add-new-glyph-to-font/</link>
					<comments>https://max-everyday.com/2020/02/how-to-add-new-glyph-to-font/#comments</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Tue, 11 Feb 2020 01:36:35 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[krita]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10392</guid>

					<description><![CDATA[這篇文章在解決字型的缺字問題。Max示範如何透過 FontForge 幫有漏字的字型補缺字，如果你的電腦是Windows / macOS 或 Linux 也都可以使用，因 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>這篇文章在解決字型的缺字問題。Max示範如何透過 FontForge 幫有漏字的字型補缺字，如果你的電腦是Windows / macOS 或 Linux 也都可以使用，因為用到的工具都跨平台。</p>



<p>Max影片教學：<br><a href="https://youtu.be/LPAshVmfF6s">https://youtu.be/LPAshVmfF6s</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] 如何幫字型檔補缺字" width="885" height="498" src="https://www.youtube.com/embed/LPAshVmfF6s?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>[MaxCodeReview] FontForge 補缺字：㧳<br><a href="https://youtu.be/ugrR1Oh0LSw">https://youtu.be/ugrR1Oh0LSw</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] FontForge 補缺字：㧳 (內海字體)" width="885" height="498" src="https://www.youtube.com/embed/ugrR1Oh0LSw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>[MaxCodeReview] FontForge 補缺字：霉<br><a href="https://youtu.be/QjZNT8uBwMg">https://youtu.be/QjZNT8uBwMg</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] FontForge 補缺字：霉 (內海字體)" width="885" height="498" src="https://www.youtube.com/embed/QjZNT8uBwMg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>[MaxCodeReview] FontForge 補缺字：齜<br><a href="https://youtu.be/X4X-m-vthw8">https://youtu.be/X4X-m-vthw8</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] FontForge 補缺字：齜 (內海字體)" width="885" height="498" src="https://www.youtube.com/embed/X4X-m-vthw8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>[MaxCodeReview] FontForge 補缺字：鼴<br><a href="https://youtu.be/N4hCLq-Db9A">https://youtu.be/N4hCLq-Db9A</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] FontForge 補缺字：鼴 (內海字體)" width="885" height="498" src="https://www.youtube.com/embed/N4hCLq-Db9A?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>前置準備，下載和安裝：</p>



<ul class="wp-block-list"><li>FontForge<br><a href="https://github.com/fontforge/fontforge/releases">https://github.com/fontforge/fontforge/releases</a></li><li>(選用，非必要) ImageMagick<br><a href="https://imagemagick.org/script/download.php">https://imagemagick.org/script/download.php</a></li><li>(選用，非必要) potrace<br><a href="http://potrace.sourceforge.net/#downloading">http://potrace.sourceforge.net/#downloading</a></li></ul>



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



<p>FontForge 的執行在 Windows 和 Linux 因為檔案的安全性設計，執行上比較沒問題，在 macOS 雖然在「安全性」裡設定了「Full Disk Access」但還是會出現「Unauthorized Operation not permitted」的Error。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="899" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-09-at-17.26.02.jpg" alt="" class="wp-image-10394" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-09-at-17.26.02.jpg?v=1581380379 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-09-at-17.26.02-500x439.jpg?v=1581380379 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>解法很簡單，在App 按右鍵選「Show Package Contents」，再進去 Contents/MacOS 目錄下點2下 FontForge 執行檔。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="548" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m13s869-1024x548.jpg?v=1581384378" alt="" class="wp-image-10400" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m13s869-1024x548.jpg?v=1581384378 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m13s869-500x267.jpg?v=1581384378 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m13s869.jpg?v=1581384378 1221w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>或是透過 Terminal 執行：</p>



<pre class="wp-block-preformatted">/Applications/FontForge.app/Contents/MacOS/FontForge</pre>



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



<p>在 macOS 裡要安裝 imageMagicK 可以執行：</p>



<pre class="wp-block-preformatted">brew install imagemagick</pre>



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



<p>在 macOS 裡要安裝 potrace ，把檔案解壓縮後，把將：</p>



<ul class="wp-block-list"><li>potrace</li><li>potrace.1</li><li>mkbitmap</li><li>mkbitmap.1</li></ul>



<p>這4個檔案複製到目錄 /usr/local/bin 即可。</p>



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



<p>執行 FontForge 後 &#8220;File&#8221; &#8211; &#8220;Open&#8221; 開啟我們有缺字的字型檔。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="347" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m36s821-1024x347.jpg?v=1581384429" alt="" class="wp-image-10401" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m36s821-1024x347.jpg?v=1581384429 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m36s821-500x170.jpg?v=1581384429 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m36s821-1536x521.jpg?v=1581384429 1536w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h17m36s821.jpg?v=1581384429 1662w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>使用熱鍵 <strong>Command + Shift + &gt;</strong> 這3個鍵，出發到編輯畫面，也可以點選單 &#8220;View&#8221; &#8211; &#8220;Goto&#8221;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="349" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m06s897-1024x349.jpg?v=1581384475" alt="" class="wp-image-10402" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m06s897-1024x349.jpg?v=1581384475 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m06s897-500x170.jpg?v=1581384475 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m06s897-1536x523.jpg?v=1581384475 1536w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m06s897.jpg?v=1581384475 1663w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>因為在FontForge 裡無法使用輸入法，所以請在其他文字編輯器裡copy 缺字，到 FontForge 裡 paste 貼上：</p>



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



<p>透過繪圖軟體製作我們的字型圖片，大小設定 1024 x 1024 px：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="880" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m33s978-1024x880.jpg?v=1581384539" alt="" class="wp-image-10403" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m33s978-1024x880.jpg?v=1581384539 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m33s978-500x430.jpg?v=1581384539 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h18m33s978.jpg?v=1581384539 1030w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>把畫好的影像檔，透過 magick 指令轉成 svg 格式：</p>



<pre class="wp-block-preformatted">magick image.png image.svg</pre>



<p>附說：除了potrace 可以轉換為 svg 格式之外，還有很多程式也支援，但對曲線的判斷，potrace 效果好一點點。但 potrace 1.8 版會在直線中間多插入一個多的點，覺得占空間。</p>



<ul class="wp-block-list"><li>說明1：除了在 krita 裡匯出 png 格式，也可以使用 bmp 格式，最後都可以使用 magick 指令轉換成 SVG 格式。如果是匯出成 bmp 就不需要安裝 imagemagicK，只需要 potrace，執行範例：</li></ul>



<pre class="wp-block-preformatted">potrace -s inputfile.bmp</pre>



<p>上面的指令會把bmp 檔轉成 svg 檔案。</p>



<ul class="wp-block-list"><li>說明2：請連白色的背景一起放進匯出的PNG或BMP格式檔案裡，不然magick 匯出會失敗。</li></ul>



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



<p>在 FontForge 裡 import svg ：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h19m49s150-1024x576.jpg?v=1581384670" alt="" class="wp-image-10404" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h19m49s150-1024x576.jpg?v=1581384670 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h19m49s150-500x281.jpg?v=1581384670 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h19m49s150-1536x864.jpg?v=1581384670 1536w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h19m49s150.jpg?v=1581384670 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>除了在繪圖軟體裡畫字，也可以透過 FontForge 的編輯界面來設計字型，但相對對畫筆的筆觸的控制就沒有那麼方便。</p>



<p>在 FontForget 裡編輯的好處是，有些新字路徑可以從其他已建立的字裡只複製部份，併裝組合成新字。</p>



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



<p>最後在 &#8220;File&#8221; &#8211; &#8220;Generate Fonts&#8221;，就可以取得修改後的字型：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h20m27s127-1024x807.jpg?v=1581384750" alt="" class="wp-image-10405" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h20m27s127-1024x807.jpg?v=1581384750 1024w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h20m27s127-500x394.jpg?v=1581384750 500w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-09h20m27s127.jpg?v=1581384750 1027w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<h2 class="wp-block-heading">如何在FontForge 裡組合出需要的缺字：</h2>



<p>如果我們要組合出「洩 」(6D29)。</p>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 1：</strong><br><strong>先分別使用Pointer(箭頭)的選取工具，選取出需要組合的字，例如：曳</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="643" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.01.55.jpg" alt="" class="wp-image-10536" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.01.55.jpg?v=1582550441 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.01.55-500x314.jpg?v=1582550441 500w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.01.55-200x125.jpg?v=1582550441 200w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 2：</strong><br><strong>找到組合字的另一邊，例如：「洪」的三點水，選取好後複制到其他缺字的格子裡，暫時借放，之後記得按Clear 把做一半的字清掉。</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="556" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.15.35.jpg" alt="" class="wp-image-10537" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.15.35.jpg?v=1582550455 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.15.35-500x271.jpg?v=1582550455 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 3：</strong><br><strong>透過Transform (Command + \ ) 工具，可以進行X,Y軸的移動（Move）或縮放（Scale）。<br>（其他的做法是：使用其他的圖片編輯軟體來編修改，再存成SVG格式，最後在FontForge裡匯入）</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="563" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.21.jpg" alt="" class="wp-image-10538" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.21.jpg?v=1582550470 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.21-500x275.jpg?v=1582550470 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 4：</strong><br><strong>把要被組合的字，複製並貼回我們的目的地，我們的字就完成了。</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="561" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.58.jpg" alt="" class="wp-image-10539" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.58.jpg?v=1582550483 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-24-at-19.23.58-500x274.jpg?v=1582550483 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>自己組合的字，有點不協調感，但總比缺字好看多了。要讓字的協調感較佳，可以試看看下面這篇文章的作法：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>AI造字經驗分享<br><a href="https://max-everyday.com/2021/07/zi2zi-ai-font/">https://max-everyday.com/2021/07/zi2zi-ai-font/</a></p></blockquote>



<p>也可以把組合好的字的ttf 檔，再分享回來給原作者，如果原作者有空也許會調整一下，再發佈到新的版本裡。</p>



<p>要匯出某一個字，可以先進入編輯該字，再點「Export」，匯出的格式，建議使用 ttf 或 otf格式會比較少問題。</p>



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



<h2 class="wp-block-heading">透過繪圖軟體 Krtia 補缺字</h2>



<p>以補 setofont （瀨戶字體）的缺字「鄉」(9109)為例：</p>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 1：</strong><br><strong>在FontForge 先把缺字需要的原料匯出。</strong></p>



<p>例如：匯出相似的2個字unicode 9115 和 unicode 90F7 ，匯出為SVG , bmp 或 png 格式可以。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="500" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-26-at-23.57.40.jpg" alt="" class="wp-image-10604" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-26-at-23.57.40.jpg?v=1582801531 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-26-at-23.57.40-500x244.jpg?v=1582801531 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 2：</strong><br><strong>在Krtia 分別開啟匯出的SVG檔，並把 9115 上方的點，複製起來，到90F7 貼上，並移動到想要的位置。</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="827" height="1024" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-00.02.39-down-827x1024.jpg?v=1582793163" alt="" class="wp-image-10590" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-00.02.39-down-827x1024.jpg?v=1582793163 827w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-00.02.39-down-404x500.jpg?v=1582793163 404w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-00.02.39-down-1241x1536.jpg?v=1582793163 1241w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-00.02.39-down.jpg?v=1582793163 1290w" sizes="(max-width: 827px) 100vw, 827px" /></figure>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 3：</strong><br><strong>影像處理完成後，匯出為bmp格式。</strong></p>



<p>附註：背景白色，請一起匯出。</p>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 4：</strong><br><strong>在指令模式裡，轉換BMP格式為SVG格式：</strong></p>



<p>使用 potrace 指令：</p>



<pre class="wp-block-preformatted">potrace -b svg -u 50 90F7.bmp -o 9109.svg</pre>



<p>附註：如果你的繪圖工具高級一點，也許可以直接匯出為 SVG 格式，如果不想安裝 potrace 也可以使用很多免費的網上網站，有提線上轉檔的服務。</p>



<p class="has-luminous-vivid-amber-background-color has-background"><strong>Step 5：</strong><br><strong>在FontForge裡匯入完成的 SVG：</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="565" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-02.29.32-1024x565.jpg?v=1582793635" alt="" class="wp-image-10591" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-02.29.32-1024x565.jpg?v=1582793635 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-02.29.32-500x276.jpg?v=1582793635 500w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-02.29.32.jpg?v=1582793635 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>如果沒有要調整字重，補缺字到這裡就可以結束了。如果希望生出來的新字，可以有其他的字重，需要再有一些微調。</p>



<p>FontForge 匯出的SVG 只有 1.3KB，但potrace 轉檔出來的預設是 3.9KB，長大了 3倍，potrace 預設 -u 是 10px ，在使用FontForge 的  Expand Stroke&#8230; 時，會造成像腫瘤般的奇怪小圈圈，如圖所示：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="476" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-16.05.38-1024x476.jpg?v=1582795756" alt="" class="wp-image-10592" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-16.05.38-1024x476.jpg?v=1582795756 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-16.05.38-500x232.jpg?v=1582795756 500w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-16.05.38.jpg?v=1582795756 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>解法：是 potrace 指令，設定 quantize（量化）參數 -u 為 50px，這時候匯出的檔案會再略大一點，長大到 4.5KB，即可是解決在FontForge 裡 Expand Stroke 造成的筆畫的誤判。上面的範例已修改為 -u 50.</p>



<p>做到這裡，其實就沒有問題了，只是字型檔比較胖一點，如果你想讓新長出來的字型檔更完美一點，就看接下來優化的部份。</p>



<p>附註：如果你也是使用 potrace 1.8 版，上面的 -u 50 參數應該是不用加了，因為效果差不多。</p>



<p>匯入的SVG檔裡有很多的「點」，是因為點陣圖（BMP）轉換到到向量圖（SVG）時多出來的，請在 FontForge 裡使用左上角第一個選取工具（Pointer，熱鍵V）去點擊多餘的點，使用Merge(Command + M）進行點的合併。</p>



<p>有時候合併的結果會讓直線變成曲線，這時候請先使用還原（Command＋Z）功能，再使用 Merge to Line （Command + Shift + M）讓消失的點，變成一直線，或是放棄合併這一個點。</p>



<p>有時候會需要拉進（Zoom in）請使用熱鍵 Z ；拉遠（Zoom out）熱鍵 X 來調整。</p>



<p>重要：由於是囫圇吞棗，在完全不懂的情況下亂改字型檔，所以最後存檔（Save）前，請執行一次選單裡 Element 裡的 Correct Direction（Command + Shift + D）來修正方向錯誤。</p>



<p>為確定Expand Stroke 不會出錯，請用熱鍵 Command＋Shift＋E 先試看看無誤。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="970" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-17.20.41-1024x970.jpg?v=1582796372" alt="" class="wp-image-10593" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-17.20.41-1024x970.jpg?v=1582796372 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-17.20.41-500x474.jpg?v=1582796372 500w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-27-at-17.20.41.jpg?v=1582796372 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>良裡有二個口，上面的口有經過 merge 功能來消除多餘的點，下面的口還未經處理，Merge 過簡化的字型，在檔案大小會略小一點，在Expand Stroke 時，可能比較不會誤判。</p>



<ul class="wp-block-list"><li>結論1：字體的開發，是非常的花時間！</li><li>結論2：幫字型檔補上差強人意的缺字還滿簡單的。</li><li>結論3：FontForge用一陣子後，發現還滿簡單的，補字不需要使到其他的影像編輯軟體。大多數的情況下，使用預設的選取工具（Pointer），就可以完成編輯和移動，如果情況需要縮放的話，使用 Transform(Command+\) 。</li></ul>



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



<h2 class="wp-block-heading">附註：</h2>



<ul class="wp-block-list"><li>上面的例子，可以在Windows/macOS/Linux平台上使用。</li><li>非開源的字型檔，自行編修沒有辦法被得知，但公開發佈也許會有法律上的問題。</li><li>沒有任何一個字型編輯軟體能確保重新儲存的字型檔跟原始檔一模一樣。編修後的字型檔，很有可能會有kerning數值跑掉、直排字符異常或各種問題。</li></ul>



<p>針對 Warning 的處理：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="843" height="199" src="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-21h49m51s983.jpg" alt="" class="wp-image-10424" srcset="https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-21h49m51s983.jpg?v=1581429771 843w, https://max-everyday.com/wp-content/uploads/2020/02/vlcsnap-2020-02-11-21h49m51s983-500x118.jpg?v=1581429771 500w" sizes="(max-width: 843px) 100vw, 843px" /></figure>



<p>建議開啟ttf檔案後，請存成資料夾格式的FontForge&#8217;s SFD 格式，每個字都會變成獨立的檔案，可以透過其他文字編輯器去調整或置換掉glyph檔案。</p>



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



<p>最後，強力推薦一個網站，對於補字的工作很有幫助：</p>



<p>中國哲學書電子化計劃 &#8211; 字典<br><a href="https://ctext.org/dictionary.pl?if=gb">https://ctext.org/dictionary.pl?if=gb</a></p>



<p>這個網站很神奇，比如我想補「唬」，想知道字的組成元件有「虎」的字有那些，可以在這個網站看到有「虓」，有些字型還真的有這一個字可以拿來組合。</p>



<p>也可以使用「漢文博士」<br><a href="https://www.cnblogs.com/hanbox/">https://www.cnblogs.com/hanbox/</a></p>



<p>査詢漢字的構字資料，快速尋找有沒有可以借用的字元。</p>



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



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



<p>Python 字型相關工具<br><a href="https://stackoverflow.max-everyday.com/2020/02/python-font/">https://stackoverflow.max-everyday.com/2020/02/python-font/</a></p>



<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>幫字型加字重<br><a href="https://max-everyday.com/2020/02/change-weight-for-font/">https://max-everyday.com/2020/02/change-weight-for-font/</a></p>



<p>比較不同字形檔之間的缺字差異：<br><a href="https://max-everyday.com/2020/02/font-glyph-set-compare/">https://max-everyday.com/2020/02/font-glyph-set-compare/</a></p>



<p>FontForge 調整字型在 Windows 的安裝顯示名稱<br><a href="https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/">https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/</a></p>



<p>免費中文字體 NotoSans 思源黑體<br><a href="https://max-everyday.com/2018/03/noto-font/">https://max-everyday.com/2018/03/noto-font/</a></p>



<p>免費商用字體整理<br><a href="https://max-everyday.com/2020/02/free-commercial-fonts/">https://max-everyday.com/2020/02/free-commercial-fonts/</a></p>



<p>「粉圓字型 」<br><a href="https://blog.justfont.com/2020/02/huninn-preview/">https://blog.justfont.com/2020/02/huninn-preview/</a></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>真的是很漂亮的圓體，也有被「找腳」的是這一個圓體：「源泉圓體」：<br><a href="https://github.com/ButTaiwan/gensen-font">https://github.com/ButTaiwan/gensen-font</a><br>把印刷字的怪角給拔掉，好神奇，但也聽到很多「災情」，像是「關」這個字的中間下面的腳被誤判為多出來的角而被拔掉，也不是所有字重都有問題，反而是較重的字才有被拔的情況。</p></blockquote>



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



<h2 class="wp-block-heading">相關影片：</h2>



<p>【央視走基層】中華美學無所不在 街訪國人同胞對「美」的忍受度｜眼球中央電視台<br><a href="https://www.youtube.com/watch?v=1jQnbXKF_jY">https://www.youtube.com/watch?v=1jQnbXKF_jY</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="【央視走基層】中華美學無所不在 街訪國人同胞對「美」的忍受度｜眼球中央電視台" width="885" height="498" src="https://www.youtube.com/embed/1jQnbXKF_jY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



<p>可以看到 justfont 公司裡面的情況，及字型設計師如何去設計字型。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/02/how-to-add-new-glyph-to-font/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>比較不同字形檔之間的缺字差異</title>
		<link>https://max-everyday.com/2020/02/font-glyph-set-compare/</link>
					<comments>https://max-everyday.com/2020/02/font-glyph-set-compare/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Mon, 10 Feb 2020 22:29:30 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10375</guid>

					<description><![CDATA[看完這篇文章（或影片）你會學到： 增加電腦字形一點點知識 如何轉換ttf 為 ufo / ufo 轉為 ttf 如何比對2個字型檔的缺字情況 顯示文字對應到的unicod [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>看完這篇文章（或影片）你會學到：</p>



<ul class="wp-block-list"><li>增加電腦字形一點點知識</li><li>如何轉換ttf 為 ufo / ufo 轉為 ttf</li><li>如何比對2個字型檔的缺字情況</li><li>顯示文字對應到的unicode字碼</li></ul>



<p>MaxCodeReview：<br><a href="https://youtu.be/HSxRJ7_MyJQ">https://youtu.be/HSxRJ7_MyJQ</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio wp-embed-aspect-16-9"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="[MaxCodeReview] 比較不同字形檔之間的缺字差異" width="885" height="498" src="https://www.youtube.com/embed/HSxRJ7_MyJQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



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



<p>Max發現有一個好心人（游清松），花了很多時間去寫手寫字，並把字變成字型檔開放免費下載，我在過年期間隨手幫他弄了一個網頁：<br><a href="https://jasonfonts.max-everyday.com/">https://jasonfonts.max-everyday.com/</a></p>



<p>原作者說，暫時他還沒有打算架網頁，如果未來有需要再找來請教我。</p>



<p>我發現有人在社團裡提出增字的要求：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="828" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-10-at-03.33.05.jpg" alt="" class="wp-image-10383" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-10-at-03.33.05.jpg?v=1581373172 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-10-at-03.33.05-500x404.jpg?v=1581373172 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>Max 使用的Python程式碼轉換 ttf 為 ufo：</p>



<pre class="wp-block-preformatted"> import extractor
 import defcon
 ufo = defcon.Font()
 extractor.extractUFO("JasonFonts1.ttf", ufo)
 ufo.save("JasonFonts1.ufo", removeUnreferencedImages=True)
 ufo = defcon.Font()
 extractor.extractUFO("JasonFonts2.ttf", ufo)
 ufo.save("JasonFonts2.ufo", removeUnreferencedImages=True)
 ufo = defcon.Font()</pre>



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



<p>Max 使用的Python程式碼比對缺字，並輸出比較結果到文字檔：</p>



<pre class="wp-block-preformatted"> def output_to_file(myfile, myfont_set):
     for item in myfont_set:
         output_string = "%s(%s)" % (chr(item),str(hex(item))[2:])
         myfile.write(output_string)
 import defcon
 ufo_font1 = defcon.Font(path="JasonFonts1.ufo")
 set_font1 = set()
 for glyph in ufo_font1:
     set_font1.add(glyph.unicode)
 ufo_font2 = defcon.Font(path="JasonFonts2.ufo")
 set_font2 = set()
 for glyph in ufo_font2:
     set_font2.add(glyph.unicode)
 print("start to compare…")
 print("1 have 2 without")
 filename_output = "diff_1_sub_2.txt"
 outfile = open(filename_output, 'w')
 diff_1_sub_2 = set_font1 - set_font2
 sorted_set=sorted(diff_1_sub_2)
 output_to_file(outfile,sorted_set)
 outfile.close()</pre>



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



<p>最後貼上比較的結果：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="665" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-11-at-06.24.18.jpg" alt="" class="wp-image-10384" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-11-at-06.24.18.jpg?v=1581373502 1024w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-11-at-06.24.18-500x325.jpg?v=1581373502 500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p>轉成 ufo 格式有點麻煩，Max 後來是直接使用 FontForge 的資料夾格式去進行缺字的比對，使用的程式碼如下：</p>



<pre class="wp-block-preformatted">from os import listdir, remove
from os.path import join, exists

import shutil

def output_to_file(myfile, myfont_set):
    for item in myfont_set:
        try:
            output_string = "%s(%s)" % (chr(item),str(hex(item))[2:])
        except Exception as exc:
            print("error item:%d" %(item))
            print("error item(hex):%s" %(str(hex(item))))
            raise
        myfile.write(output_string)

def load_unicode_from_file(filename_input):
    mycode = 0
    myfile = open(filename_input, 'r')
    left_part = 'Encoding: '
    left_part_length = len(left_part)
    for x_line in myfile:
        #print(x_line)
        if left_part == x_line[:left_part_length]:
            right_part = x_line[left_part_length:]
            if ' ' in right_part:
                mychar_array = right_part.split(' ')
                if len(mychar_array) &gt; 0:
                    mycode = int(mychar_array[0])
                    #print("bingo")
                    break
        
    myfile.close()
    return mycode

def load_files_to_set_dict(ff_folder):
    my_set = set()
    my_dict = {}

    files = listdir(ff_folder)

    for f in files:
        if '.glyph' in f:
            unicode_info = load_unicode_from_file(join(ff_folder,f))
            if unicode_info &gt; 0 and unicode_info &lt; 0x110000:
                #print('code:', unicode_info)
                my_set.add(unicode_info)
                my_dict[unicode_info] = f
                #break
    return my_set, my_dict

source_ff = 'JasonHandwriting1-Regular.sfdir'
target_ff = 'JasonHandwriting2-Regular.sfdir'

source_unicode_set, source_dict = load_files_to_set_dict(source_ff)
target_unicode_set, target_dict = load_files_to_set_dict(target_ff)

print("length source:", len(source_unicode_set))
print("length target:", len(target_unicode_set))
diff_set_more =  target_unicode_set - source_unicode_set
diff_set_lost =  source_unicode_set - target_unicode_set
diff_set_common =  source_unicode_set &amp; target_unicode_set
print("length more:", len(diff_set_more))
print("length lost:", len(diff_set_lost))
print("length common:", len(diff_set_common))

print("output compare result to file...")

filename_output = "diff_base_sub_%s.txt" % (target_ff)
outfile = open(filename_output, 'w')
sorted_set=sorted(diff_set_more)
output_to_file(outfile,sorted_set)
outfile.close()</pre>



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



<p>如果是想合併 2個字型檔，也可以服用下面的 code:</p>



<pre class="wp-block-preformatted"> conflic_count = 0
 copy_count = 0
 for item in diff_set_more:
     target_path = join(target_ff,target_dict[item])
     source_path = join(source_ff,target_dict[item])
     if exists(source_path):
         print("conflic:", source_path)
         conflic_count += 1
     else:
         shutil.copy(target_path, source_path)
         copy_count += 1</pre>



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



<p>如果是想刪除2個字型檔裡，共用的部分，只留下差異的文字，請服用下面的code：</p>



<pre class="wp-block-preformatted"> remove_count = 0
 for item in diff_set_common:
     target_path = join(target_ff,target_dict[item])
     remove(target_path)
     remove_count += 1</pre>



<p>與其使用 ufo 格式，不用直接使用 FontForge 的檔案，方便很多，也更容易產生成新的字型檔案，在編輯字型上也很方便。</p>



<p>要刪字或增字，只要直接去存取FontForge資料夾下的 .glyph 的檔案就完成了。</p>



<p>上面的Python程式碼，可以在Windows/macOS/Linux平台上使用。</p>



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



<p>如果是想比對特定文章裡的字串，在字型檔裡有沒有缺字，可以使用下面文章裡的程式：</p>



<p>常見的「台灣方言字」整理<br><a href="https://max-everyday.com/2020/03/taiwanese-common-word-700/">https://max-everyday.com/2020/03/taiwanese-common-word-700/</a></p>



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



<h2 class="wp-block-heading">附註（非商用）：</h2>



<ul class="wp-block-list"><li>「教育部 4808 個常用字」係指民國 71 年 9 月 1 日教育部公告的「常用國字標準字體表」所收錄之常用字。</li><li>教育部標準楷書字形檔(Version 4.00)，目前收錄國字數為 13,076 字。<br><a href="https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/edukai-4.0.zip">https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/edukai-4.0.zip</a></li><li>教育部隸書字形檔(Version 3.00)，目前收錄國字數為4,808字。<br><a href="https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/MoeLI-3.0.zip">https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/MoeLI-3.0.zip</a></li><li>教育部標準宋體字形檔 ：<br><a href="https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/eduSong_Unicode.zip">https://language.moe.gov.tw/001/Upload/Files/site_content/M0001/eduSong_Unicode.zip</a></li></ul>



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



<h2 class="wp-block-heading">附註（可商用）：</h2>



<ul class="wp-block-list"><li>マメロン Regular<br><a href="https://moji-waku.com/mamelon/">https://moji-waku.com/mamelon/</a></li><li>花園明朝：<br><a href="http://osdn.jp/projects/hanazono-font/releases/">http://osdn.jp/projects/hanazono-font/releases/</a><br>日本花園明朝體(HanaMin)是一款非常漂亮的藝術字體，包含近十萬字，所以不必擔心缺字，有分割成HanaMinA、HanaMinB兩個字體檔，安裝A就好了，在macOS 裡 HanaMinB 會有問題，會跳回去PingFang 並變粗體字。</li><li>王漢宗自由字型：(193MB)<br><a href="https://drive.google.com/file/d/1eM7bpKCdcZc1i7QGIhXiUquS2TFCbXUf/view">https://drive.google.com/file/d/1eM7bpKCdcZc1i7QGIhXiUquS2TFCbXUf/view</a></li><li>M+ FONTS PROJECT<br><a href="http://mplus-fonts.osdn.jp/about.html">http://mplus-fonts.osdn.jp/about.html</a></li><li>Fandol字体（4款）仿宋 黑体 楷体 宋体<br><a href="https://ctan.org/pkg/fandol">https://ctan.org/pkg/fandol</a><br>Fandol系列字体来自一家已经破产的字体公司，现在已经开源了。</li><li>瀨戶字體<br><a href="https://zh-tw.osdn.net/projects/setofont/">https://zh-tw.osdn.net/projects/setofont/</a><br>瀨戶字體是一個由日本人開發的線上免費字體，支援繁體中文、簡體中文、日文、英文和其他特殊符號，總共支援3萬多個漢字。</li><li>楊任東竹石體<br><a href="http://www.fonts.net.cn/author-6289251609-1.html">http://www.fonts.net.cn/author-6289251609-1.html</a><br>上面的這個版本，字型檔案好像有點問題，有些字會出錯。改下載這個版本即可解決：<br><a href="https://m.fontke.com/font/28225026/">https://m.fontke.com/font/28225026/</a><br>出錯的原因是在版本號，第一個連結是 1.2 版，後面的是 1.5版，1.5版才有支援繁體字，可是 1.5 版的字重被調重了，相當於1.2版的 Medium。<br><br>“杨任东字体”微信公众号<br><a href="https://www.weibo.com/p/1005053026020863/info?mod=pedit_more">https://www.weibo.com/p/1005053026020863/info?mod=pedit_more</a><br>好年輕的人哦，生日：1993年12月30日。</li><li>TanukiMagic 麥克筆手繪 POP 日文字型：<br><a href="http://tanukifont.com/tanuki-permanent-marker/">http://tanukifont.com/tanuki-permanent-marker/</a></li><li>日系851原子筆手寫風格字型，可商用免費下載<br><a href="https://pm85122.onamae.jp/851fontpage.html">https://pm85122.onamae.jp/851fontpage.html</a></li></ul>



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



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



<p>Python 字型相關工具<br><a href="https://stackoverflow.max-everyday.com/2020/02/python-font/">https://stackoverflow.max-everyday.com/2020/02/python-font/</a></p>



<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>FontForge<br><a href="https://github.com/fontforge/fontforge/releases">https://github.com/fontforge/fontforge/releases</a></p>



<p>Awesome Typography<br><a href="https://github.com/Jolg42/awesome-typography">https://github.com/Jolg42/awesome-typography</a></p>



<p>免費中文字體 NotoSans 思源黑體<br><a href="https://max-everyday.com/2018/03/noto-font/">https://max-everyday.com/2018/03/noto-font/</a></p>



<p>free and carefree: 可以免費商用的中文或漢字字型<br><a href="https://tips.justfont.com/post/113397509827/freeandcarefreefonts">https://tips.justfont.com/post/113397509827/freeandcarefreefonts</a></p>



<p>免費商用字體整理<br><a href="https://max-everyday.com/2020/02/free-commercial-fonts/">https://max-everyday.com/2020/02/free-commercial-fonts/</a></p>



<p>FontForge 調整字型在 Windows 的安裝顯示名稱<br><a href="https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/">https://stackoverflow.max-everyday.com/2020/02/fontforge-chinese/</a></p>



<p>內海字體 (NaikaiFont)<br><a href="https://max-everyday.com/2020/03/naikaifont/">https://max-everyday.com/2020/03/naikaifont/</a></p>



<p>幫字型檔補缺字<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></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/02/font-glyph-set-compare/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>css如何實作網頁右上角選單效果</title>
		<link>https://max-everyday.com/2020/02/css-auto-show-hide-menu-icon/</link>
					<comments>https://max-everyday.com/2020/02/css-auto-show-hide-menu-icon/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Fri, 07 Feb 2020 21:36:20 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[MaxCodeReview]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=10365</guid>

					<description><![CDATA[Max的網站，最近換了一個新的主題，發現在 chrome 瀏覽器裡主選單沒有被顯示出來。 發生的原因：css 裡 em 和 px 的轉換不一致所造成，Google一下 e [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Max的網站，最近換了一個新的主題，發現在 chrome 瀏覽器裡主選單沒有被顯示出來。</p>



<p>發生的原因：css 裡 em 和 px 的轉換不一致所造成，Google一下 em 轉 px 應該是 1em=16px，但實際測試在 macOS 裡的 chrome 居然是 1em=20px。</p>



<p>影片說明：<br><a href="https://youtu.be/CJ_YEo3Uv3g">https://youtu.be/CJ_YEo3Uv3g</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="css如何實作網頁右上角選單效果" width="885" height="498" src="https://www.youtube.com/embed/CJ_YEo3Uv3g?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



<p>瀏覽器的實測結果：</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1034" height="1360" src="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-08-at-04.53.07-down.jpg?v=1581109063" alt="" class="wp-image-10368" srcset="https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-08-at-04.53.07-down.jpg?v=1581109063 1034w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-08-at-04.53.07-down-380x500.jpg?v=1581109063 380w, https://max-everyday.com/wp-content/uploads/2020/02/Screen-Shot-2020-02-08-at-04.53.07-down-779x1024.jpg?v=1581109063 779w" sizes="(max-width: 1034px) 100vw, 1034px" /></figure>



<p>解法：把 64em 改用 1024px 。</p>



<p>會去用em 應該是有原因的，但目前不同瀏覽器對em的定義似乎不太一致，所以做出來的網頁在不同瀏覽器的效果會有所差別。</p>



<p>沒想到會來研究css，多學一點也滿好的，可以自己幫自己解決問題。</p>



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



<p>附上測試用的網頁：</p>



<pre class="wp-block-preformatted">&lt;html&gt;
 &lt;body&gt;
 &lt;div style="box-sizing: border-box;
     width: <strong>64em</strong>;    background: #fff3d4;
     border-color: #f6b73c;"&gt;hello 64em&lt;/div&gt;
 &lt;hr/&gt;
 &lt;div style="box-sizing: border-box;
     width: <strong>1024px</strong>;    background: #fff3d4;
     border-color: #f6b73c;"&gt;hello 1024px&lt;/div&gt;
 &lt;hr/&gt;
 &lt;div style="box-sizing: border-box;
     width: <strong>51.2em</strong>;    background: #fff3d4;
     border-color: #f6b73c;"&gt;hello 51.2em&lt;/div&gt;
 &lt;/body&gt;
 &lt;/html&gt;</pre>



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



<p>css如何實作網頁右上角選單效果：</p>



<pre class="wp-block-preformatted">@media print, screen and (min-width: 1024px) {
   .hide-for-large {
     display: none !important; } }
</pre>



<p>程式碼說明：</p>



<p>當符合最小寬度1024px（等於：螢幕寬度為 1024px 以上）執行括號內的設定值。</p>



<p>倒過來的範例：</p>



<pre class="wp-block-preformatted">@media screen and (max-width: 1024px) {
   .show-for-large {
     display: none !important; } }</pre>



<p>程式碼說明：</p>



<p>當符合最大寬度1024px（等於：螢幕寬度為 1024px 以下）執行括號內的設定值。</p>



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



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



<p>Day22：小事之 Media Query<br><a href="https://ithelp.ithome.com.tw/articles/10196578">https://ithelp.ithome.com.tw/articles/10196578</a></p>



<p>CSS Media Queries 詳細介紹<br><a href="https://www.oxxostudio.tw/articles/201810/css-media-queries.html">https://www.oxxostudio.tw/articles/201810/css-media-queries.html</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2020/02/css-auto-show-hide-menu-icon/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
