整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          中文像素字體制作

          段時間想做一款像素風的游戲,中文像素字體就是一個繞不過去的問題。這里記錄下我制作 12 像素字體的過程。

          使用的軟件是 fontforge:https://fontforge.org/en-US/

          自己一個字一個字的做是不可能自己做的,所以在網上找到了兩個開源的字體庫

          1. M+ BITMAP FONTS

          https://mplus-fonts.osdn.jp/mplus-bitmap-fonts/download/index.html

          這是來自日本的完全免費字體,看著還蠻好看,有一部分的中文部分。

          2. HZK-12

          https://github.com/aguegu/BitmapFont

          覆蓋 GB2312 的中文 12 像素字體

          制作思路

          靈感來自 ipix 中文像素字體的制作 我在原作的基礎上進行了一些修改。原作是將字模導出為 png 然后 Potrace 轉化成 svg 圖片, 最后再把 SVG 圖片導入 FontForge 中就制作。

          我是直接調用了命令行的 fontforge, 使用 python 腳本讀取字模信息,然后調用 fontforge 的矩形繪制函數,把每個像素點繪制成一個 100x100的正方形。省去了一些中間步驟,所以效率提升了很多,制作過程只用了幾分鐘就完成了。當然摸索這個方法的時間也用了三個晚上,好在以后重新制作的時間縮短到了幾分鐘。這里記錄下詳細的制作步驟,以及分享下源碼。

          1. 安裝 fontforge 并添加支持庫 bdflib

          bdf 支持庫是為了解析 M+ BITMAP FONTS ,hzk12 不需要額外插件。

          fontforge 安裝步驟省略,fontforge 會默認安裝上 python 運行環境到軟件目錄下面 。

          下載 bdflib 的 whl 文件解壓到

          FontForgeBuilds\lib\python3.8\site-packages

          目錄下就安裝好了。

          2. 利用 Hzk12 生成 fontforge 工程

          新建一個文件夾使用 vscode 打開, 新建 python 腳本命名為 hzk_to_sfd.py,安裝 python 插件,設置 python 目錄為 fontforge 下的 python 環境 如圖所示:

          源碼部分:

           import fontforge
          import binascii

          KEYS = [0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01]

          sdf_path = "HZK12.sfd"
          hzk_path = "C:/Users/lo/Downloads/HZK/HZK12"
          gb2312_path = "C:/Users/lo/Downloads/HZK/gb2312.txt"


          defDraw(font, ch, rect_list):

          gb2312 = ch.encode('gb2312')
          hex_str = binascii.b2a_hex(gb2312)
          result = str(hex_str, encoding='utf-8')
          area = eval('0x' + result[:2]) -0x80
          index = eval('0x' + result[2:]) -0x80

          ioj = (area <<8) + index
          # print(ch, gb2312, hex_str, result, ioj)

          glyph = font.createMappedChar(ioj)
          pen = glyph.glyphPen

          y =11
          max_x =0
          for row in rect_list:
          y = y -1
          x = -1
          for i in row:
          x = x +1
          if i:
          pen.moveTo((100* x ,100* y ))
          pen.lineTo((100* x ,100* y +100))
          pen.lineTo((100* x +100,100* y +100))
          pen.lineTo((100* x +100,100* y ))
          pen.closePath
          max_x = max(max_x,x)
          # print("#")
          # else:
          # print(" ")
          # print("\n")

          pen = None
          glyph.removeOverlap
          glyph.width = max_x*100+200

          def draw_glyph(ch):
          rect_list = *12
          for i in range(12):
          rect_list.append([] *16)

          # 獲取中文的 gb2312 編碼,一個漢字是由 2 個字節編碼組成
          gb2312 = ch.encode('gb2312')
          # 將二進制編碼數據轉化為十六進制數據
          hex_str = binascii.b2a_hex(gb2312)
          # 將數據按 unicode 轉化為字符串
          result = str(hex_str, encoding='utf-8')
          # 前兩位對應漢字的第一個字節:區碼,每一區記錄 94 個字符
          area = eval('0x' + result[:2]) -0xA0
          # 后兩位對應漢字的第二個字節:位碼,是漢字在其區的位置
          index = eval('0x' + result[2:]) -0xA0
          # 漢字在 HZK16 中的絕對偏移位置,最后乘 24 是因為字庫中的每個漢字字模都需要 24 字節
          offset = (94* (area-1) + (index-1)) *24
          font_rect = None
          # 讀取 HZK16 漢字庫文件
          with open(hzk_path, "rb") as f:
          # 找到目標漢字的偏移位置
          f.seek(offset)
          # 從該字模數據中讀取 24 字節數據
          font_rect = f.read(24)

          # font_rect 的長度是 24,此處相當于 for k in range(16)
          for k in range(len(font_rect) // 2):
          # 每行數據
          row_list = rect_list[k]
          for j in range(2):
          for i in range(8):
          asc = font_rect[k *2+ j]
          # 此處&為 Python 中的按位與運算符
          flag = asc & KEYS[i]
          # 數據規則獲取字模中數據添加到 16 行每行中 16 個位置處每個位置
          row_list.append(flag)

          return rect_list

          defOpenGBK:
          f = open(gb2312_path, 'r', encoding='UTF-8')
          line = f.readline

          for index, ch in enumerate(line):
          if ch == "\n":
          continue

          print(index, end=' ')
          print(ch)

          f.close


          defStart:

          font = fontforge.font # Open a font
          font.encoding = "gb2312"
          font.ascent =1200

          f = open(gb2312_path, 'r', encoding='UTF-8')

          line = f.readline

          while line:
          for index, ch in enumerate(line):
          if ch == "\n":
          continue
          print(ch)
          rect = draw_glyph(ch)
          Draw(font, ch, rect)
          line = f.readline

          font.save(sdf_path)
          f.close

          Start

          這里依賴兩個文件 HZK12 和 gb2312.txt ,可以在 源碼中下載,在 Vscode 中運行腳本,或者在終端輸入:

          "c:/Program Files (x86)/FontForgeBuilds/bin/ffpython.exe" c:/Users/lo/Downloads/HZK/hzk_to_sfd.py
          #當然這里的 ffpython.exe 文件和 python 文件的路徑需要修改。

          就能生成一個 hzk12.sfd的文件,雙擊使用 fontforge 打開。看看效果。

          還行 文字沒有錯位(hzk12 沒有前面的英文字模,所以看效果需要向下多翻一點)下面就來添加英文字模進來

          3. 利用 M+ BITMAP FONTS 生成 fontforge 工程

          我這里選擇的是 mplus_jf12r.bdf文件作為字模,也可以使用其他的。

          與第二步相同新建一個名為 bdf_to_sdf.py的文件,這里依賴了第一步中安裝的bdflib插件。

           from bdflib import reader
          from bdflib import writer
          import fontforge

          defOpenBDF(path):
          with open(path, "rb") as handle:
          return reader.read_bdf(handle)

          defStart:

          bdf_font =OpenBDF("C:/Users/lo/Downloads/HZK/mplus_jf12r.bdf")
          sdf_font = fontforge.font
          sdf_font.encoding = "jis208"
          sdf_font.ascent =1200

          for bdf_glyph in bdf_font.glyphs:
          # bdf_glyph = bdf_font[12321]
          x = -1
          y =10

          print(bdf_glyph.codepoint)
          glyph = sdf_font.createMappedChar(bdf_glyph.codepoint)
          pen = glyph.glyphPen

          for ch in bdf_glyph.__str__:
          if ch == '\n':
          y = y -1
          x = -1
          print("")

          if ch == '#' :
          pen.moveTo((100* x ,100* y ))
          pen.lineTo((100* x ,100* y +100))
          pen.lineTo((100* x +100,100* y +100))
          pen.lineTo((100* x +100,100* y ))
          pen.closePath
          print("#",end=" ")
          else:
          print(" ",end=" ")
          x = x +1

          pen = None
          glyph.removeOverlap

          # break

          # sdf_font.autoWidth
          sdf_font.save("mplus_jf12r.sfd")

          Start

          這里使用的文件同 mplus_jf12r.bdf 樣放在了源碼中。和第二步一樣的運行方式,運行后得到一個 mplus_jf12r.sfd 的 fontforge 工程。

          也沒有錯位,太棒了。第 4 步就是把這兩個字體合并一下了。

          4. 合并字體

          hzk12 和 mplus bitmap 中有很多重合的字,所以有兩種合并方式,一個是重合的部分使用 hzk12 的字模,一個是使用 mplus 的。我選擇保留 mplus 的重合部分。

          由于兩者編碼格式不同所以先統一下編碼格式,一個是 gb2312 一個是 jis208,所以我這全都設置成 Unicode Full 的格式。(fontforge 下的菜單 Encoding->reencode->ISO 10646-1 ( Unicode, Full ))。然后在打開 Mplus-jf12r 的 fontforge 的窗口中 選擇菜單Element->Merge Fonts然后選擇hzk12.sfd文件,然后會彈出一個對話框詢問 是否用導入的 graph 替換本工程的同位置 graph,這里選擇NO,就是使用 mplus 的重合部分。

          選擇英文和符號部分 調整下 Graph 的寬度 ,推薦 菜單 Metrics->Auto Width

          推薦按下

          下一步生成 ttf 字體文件。生成之前可以先編輯下字體信息, 菜單 Element->font info,這里不介紹了。

          5. 生成 ttf 文件

          菜單 File->Generate Fonts

          設置下 TrueType 就可以點擊 Generate了。這里會有對話框提示:“有重合的點或者面”, 我還沒有找到比較好的辦法消除,但是并不影響使用,所以就沒有再多處理。依然點擊Generate生成。

          好了現在打開字體看下效果。

          還行吧 就是符號的部分不是很好看,也可以重新找點好看的字模用上面的方法替換下,我覺得也能用就沒換了,有需要可以自己動手了,接著看下在 Unity 中的效果怎么樣吧。

          效果不錯 沒有錯位。

          結束。

          源碼及參考

          源碼以及 TTF 文件: https://github.com/Luckeee/mplus_hzk_12

          參考:

          • ipix 中文像素字體的制作https://indienova.com/u/purestudio/blogread/20097

          • 如何將點陣漢字矢量化https://indienova.com/indie-game-development/vectorize-chinese-bitmap-font/

          • Python 解析 HZK16https://zhuanlan.zhihu.com/p/54931969

          、標簽的分類:雙標簽和單標簽

          雙標簽:就是成對出現的,類似于這種 <html> </html>

          單標簽:就是可以單個使用的,類似于 <br> 換行標簽 或 <hr>水平線標簽。

          二、標簽屬性的作用:

          標簽的屬性是用來定義文字或字符的 顏色、寬高、粗細、大小、等,這個是標簽屬性的作用。


          三、標簽屬性的特性:

          1、每一個標簽都有自己的屬性,單標簽和雙標簽都有。

          2、一個標簽可以有多個屬性。

          3、每個屬性都有對應的值,值要用單或雙引號引起來。

          4、多個屬性之間使用空格隔開。

          5、屬性沒有順序之分。

          6、字體屬性值,必須是系統可以識別的字體,一般為系統自帶字體。

          7、HTML5 中 font 屬性已經棄用。

          源代碼:↓

          <!DOCTYPE html>

          <html lang="en">

          <head>

          <meta charset="UTF-8">

          <!--網頁抬頭-->

          <title>中央氣象局</title>

          </head>

          <body>

          <!--水平線的寬度是500像素,這個width就是標簽屬性-->

          <hr width="500">

          <!--下面這個是多個標簽屬性,多個屬性之間用空格隔開-->

          <font color="red" face="黑體" size="7">標簽屬性</font>

          </body>

          </html>

          字是網頁展示的重要內容之一,所以對文字的修飾也是CSS重點關注的一部分, CSS提供了以下常用的樣式屬性來修飾文字。

          color 屬性

          color 用來設置文字顏色。

          設置方式支持以下幾種格式

          • 英語顏色單詞形式,如: red(紅)、black(黑)、orange(橙色)等。
          <style>
            .box {
              color: red;
            }
          </style>
          
          
          <div class="box">文字顏色</div>
          • 十六進制表示法, 設計軟件中通用的表示方法。
          • 例如:ff00000; ff 即為十進制255;每種顏色分為 0~255的數字。
          • 如果表示顏色值重復 例如:#ffaabb 可以簡寫為#fab.。
          • 黑色為 #000 ,白色為 #fff。
          • 以#ff0000為例,兩兩分組,分別表示三原色:紅、綠、藍。


          <style>
            .box {
              color: #ff0000;
            }
            .box1 {
              color: #f00;
            }
          </style>
          
          
          <div class="box">文字顏色</div>
          <div class="box1">簡寫形式</div>
          • RGB 表示法
          • 例如: color: rgb(255,0,0); rgb 內部的三個值,依次代表三原色 紅、綠、藍。
          • 其中 rgb(0,0,0) 代表黑色, rgb(255,255,255) 表示白色。


          <style>
            .box {
              color: rgb(255, 0, 0);
            }
          </style>
          <div class="box">文字顏色</div>
          • RGBA 表示法, 在RGB的表示方法的基礎上增加了透明度(最后一個參數代表透明度)。0-表示透明 1-表示實心。透明度是介于[0,1]之間的值。
          • RGBA 從 IE9開始兼容。
          <style>
          .box {
            color: rgba(255, 0, 0, 0.5);
          }
          </style>
          
          
          
          
          <div class="box">文字顏色</div>


          font-size 屬性

          font-size 屬性用來設置字體大小,單位通常為px 也可以為em,rem

          單位的解釋

          • px:像素
          • em: 相對元素字體的倍數
          • rem:相對html字體的倍數, 例如:html標簽 設置為font-size為100px , div 設置font-size為1.5 rem 實際表現為:150px。
          <style>
            .box {
              font-size: 30px;
            }
          </style>
          
          
          <div class="box">文字大小</div>


          font-weight 屬性

          設置字體的粗細程度,常用的屬性有 normal 和 bold 兩個值。

          可以用以下值表示,也可以用數字表示。

          意義

          normal

          正常粗細,和400值相等

          bold

          加粗,與700數值相等

          lighter

          比 正常粗細還細, 不常用

          bolder

          比 加粗還粗,不常用

          100 200 300 400 500 600 700 800 900

          使用數字定義字體粗細

          inherit

          從父元素繼承字體粗細


          <style>
          .box_normal {
            font-weight: normal;
          }
          .box_bold {
            font-weight: bold;
          }
          
          
          .box_lighter {
            font-weight: lighter;
          }
          
          
          .box_bolder {
            font-weight: bolder;
          }
          
          
          .box_number {
            font-weight: 600;
          }
          </style>
          
          
          <body>
            <div class="box_normal">font-weight演示:正常粗細</div>
            <div class="box_bold">font-weight演示,加粗</div>
            <div class="box_lighter">font-weight演示,更細</div>
            <div class="box_bolder">font-weight演示, 更粗</div>
            <div class="box_number">font-weight演示, 數字</div>
          </body>


          font-style 屬性

          設置字體的傾斜程度

          意義

          normal

          正常字體, 不帶傾斜效果

          italic

          傾斜字體(常用,使用傾斜字體)

          oblique

          傾斜字體(用常規字體模擬傾斜,不常用)


          <style>
            .box1 {
              font-style: normal;
            }
            .box2 {
              font-style: italic;
            }
            .box3 {
              font-style: oblique;
            }
          </style>
          <body>
            <div class="box1">正常字體</div>
            <div class="box2">傾斜字體</div>
            <div class="box3">傾斜字體2</div>
          </body>


          text-decoration 屬性

          設置文本的修飾線的樣式

          示例

          意義

          none

          無線(a標簽去除下劃線會用到)

          underline;

          下劃線

          line-through;

          刪除線

          …等等

          還有很多,可自行百度


          <style>
            .decoration-none {
              text-decoration: none;
            }
            .decoration-underline {
              text-decoration: underline;
            }
            .decoration-line-through {
              text-decoration: line-through;
            }
          </style>
          <body>
            <div class="decoration-none">無線修飾</div>
            <div class="decoration-underline">下劃線</div>
            <div class="decoration-line-through">刪除線</div>
          </body>


          font-family 屬性

          指定使用的字體族,操作系統一般自帶很多字體;

          例如:window操作系統中的 ‘微軟雅黑’ ,黑體等。

          字體文件的格式有很多,比如 eot,woff2,woff,ttf,svg等。

          font-family 可以一次指定多個字體, 后面的字體屬于后備字體,只有前面的字體沒有找到,才會使用后面的字體。


          <style>
            div {
                font-family: serif, "Time New Roman", "微軟雅黑"
            }
          </style>
          <body>
            <div>字體</div>
          </body>


          自定義字體

          某些時候,我們的字體比較個性化,或者我們的字體是一個圖標字體(一種用符號表示圖片的方式)。那么此時,需要我們使用 @font-face 自定義字體

          自定義的字體一般是隨著網頁發布在服務器端,操作系統中并沒有。

          推薦一個比較好用的字體庫網站:https://www.iconfont.cn/(具體使用方式請自行百度)。


          主站蜘蛛池模板: 亚洲国产精品一区第二页| 99精品国产一区二区三区2021 | 精品一区二区三区在线观看l| 国产精品美女一区二区| 国产熟女一区二区三区四区五区 | 亚洲人成人一区二区三区| 国产在线观看91精品一区| 亚洲欧美日韩一区二区三区 | 91video国产一区| 久久国产精品一区免费下载 | 精品日韩一区二区| 精品亚洲av无码一区二区柚蜜| 亚洲国产精品一区| 亚洲一区二区三区夜色| 国产一在线精品一区在线观看| 免费视频精品一区二区| 日本免费一区尤物| 国产伦精品一区二区三区无广告| 蜜桃AV抽搐高潮一区二区| 亚洲色一区二区三区四区| 亚洲日韩AV一区二区三区四区 | 国产成人综合一区精品| 亚洲电影唐人社一区二区| 亚洲av无码一区二区三区天堂古代 | 亚洲av无码一区二区三区四区 | 美女AV一区二区三区| 国产人妖视频一区二区破除| 成人精品一区二区激情| 乱码人妻一区二区三区| 国产精品无码一区二区在线观| 日韩高清一区二区三区不卡| 国产精品一区二区久久乐下载| 国产一区二区三区不卡在线看| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久精品无码一区二区三区免费| 亚洲欧美日韩国产精品一区| 国产成人精品无码一区二区老年人| 精品免费国产一区二区| 日韩精品一区二区三区不卡| 91一区二区三区| 亚洲综合在线成人一区|