Xlenco

Xlenco

github
zhihu
email

Front-end font compression solution

Fontmin#

Fontmin is a pure JS font subsetting solution. With Fontmin, you can extract the characters needed from a TTF font file and convert them into a TTF file output, achieving a "compression" effect.
Official website: ecomfe.github.io/fontmin/

Installing Fontmin#

npm install --save fontmin

Create a font.js file

The name can be arbitrary, mainly for running later

var Fontmin = require("fontmin")

var fontmin = new Fontmin()
  .src("./src/assets/font/example.ttf")
  .dest("./src/assets/fontmin/")
  .use(
    Fontmin.glyph({
      text: "The text you want to compress goes here"
    })
  )

fontmin.run(function(err, files) {
  if (err) {
    throw err
  }
})

This is the usage from the fontmin documentation. You can also check the documentation on GitHub for other usages: fontmin
Then run the following command using node:

node .\font.js

Advanced#

The above solution can be cumbersome when faced with a large amount of text compression requirements. In actual projects, it is not possible for us to manually write all the text and put it in ${text}. Next, let's work on reading files to extract all the characters they contain.

const fs = require("fs")

fs.readFile("./idenx.html", (err, data) => {
  if (err) {
    console.log(err)
  }
  const mySet = new Set(data.toString()) // The purpose of deduplication
  console.log(Array.from(mySet).join(""))
})

Complete Code#

The following source code is from: zhuanlan.zhihu.com/p/48318293

const fs = require("fs")
const Fontmin = require("fontmin") // Requires the use of the fontmin plugin
let set = new Set()

//get all possible characters
const scanFolder = (dir, done) => {
  let results = []
  fs.readdir(dir, (err, list) => {
    if (err) {
      return done(err)
    }
    let i = 0
    ;(function iter() {
      // The immediate function here triggers a closure, keeping the value of results constant
      let file = list[i++]
      if (!file) {
        // iterator traversal, file does not exist means completion of execution
        return done(null, results)
      }
      file = dir + "/" + file
      fs.stat(file, (err, stat) => {
        if (stat && stat.isDirectory()) {
          scanFolder(file, (err, res) => {
            // Call the method again to get the directory structure under the subdirectory
            results = results.concat(res)
            iter()
          })
        } else {
          results.push(file)
          iter() // Execute the next step
        }
      })
    })()
  })
}

//get all possible characters
const generateFinalHTML = finalString => {
  const fontmin = new Fontmin()
    .src("./src/assets/font/SourceHanSansCN-Regular.ttf") // Path to the source font file
    .dest("./src/assets/font/fontmin/") // Path to store the compressed file, this is the file that will be used in the end
    .use(
      Fontmin.glyph({
        text: finalString, // You can also directly specify the character set to be generated
        hinting: false
      })
    )

  fontmin.run(err => {
    if (err) {
      throw err
    }
  })
}

//get all possible characters
// Specify the scan path, note that different paths will result in different numbers of characters scanned in the end
scanFolder("src/views", (n, results) => {
  results.forEach(file => {
    const result = fs.readFileSync(file, "utf8")
    const currentSet = new Set(result)
    // Get the characters in each file and store them in the set
    set = new Set([...set, ...currentSet])
  })
  generateFinalHTML(Array.from(set).join(""))
  console.log("Generated a total of: " + Array.from(set).length + " characters")
})

Conclusion#

If your requirements are not large, you can also use the client
app.png
Client download:
Cloud storage: https://www.123pan.com/s/IlX7jv-GSJk3.html
Official website (Github): https://github.com/ecomfe/fontmin-app/releases/download/v0.2.0/Fontmin-v0.2.0-win64.zip

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.