定制 ls-a/font-finder 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ls-a/font-finder

Composer 安装命令:

composer require ls-a/font-finder

包简介

Find every font registered on server Operating System. Inspiration found in Apache FOP FontFileFinder

README 文档

README

Build Woff2 Decompress utility Test and bench

This documentation is also available in these languages:

This library is an universal font finder: with almost every operating system, containing almost every font format, returns an array of standardized information. It aims to be (very) quick and retrieves minimal but sufficient information on fonts.

If you like this package and want to show you support, star this project: it means a lot to us!

Quick example

$fonts = FontFileFinder::init()
    // Load system fonts (OS-dependent)
    ->addSystemFonts()
    // Load some directory
    ->addDirectoryRecursive(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'tests', 'samples']))
    ->get();

In previous example, $fonts is an array of Font objects, aggregated by font name, with these properties:

  • filename: where the font lies
  • name: family name
  • bold: bold flag (boolean)
  • italic: italic flag (boolean)
  • weight: CSS style weight, from 100 to 900

Find more in documentation below.

Installation

This library is available on Composer. Install it with:

composer require ls-a/font-finder

Operating system support

This library is currently tested on:

  • Windows x64
  • Windows i386
  • Windows ARM
  • macOS amd64
  • macOS arm64
  • Linux amd64
  • Linux arm64
  • Linux armv7
  • FreeBSD amd64
  • FreeBSD arm64
  • OpenBSD amd64
  • OpenBSD arm64
  • Solaris amd64

For more information, feel free to check test-and-bench action.

Font format support

This library currently retrieves font information in these formats:

  • AdobeFontMetrics (*.afm, in conjuction with PFA/PFB/T1/PS)
  • BitstreamSpeedo (*.spd)
  • BsdVgaFont (*.fnt, but BSD ones, not Microsoft)
  • CompactFontFormat (*.cff, both PostScript and binary)
  • DataForkTrueTypeFont (*.dfont)
  • EmbeddedOpenType (*.eot)
  • GlyphBitmapDistributionFormat (*.bdf)
  • JimHersheyFont (*.jhf)
  • OpenTypeBitmap (*.otb)
  • OpenTypeCollection (*.otc)
  • OpenTypeFont (*.otf)
  • PcScreenFont (*.psf)
  • PcScreenFontUnicodeCompressed (*.psfu.gz, usually found with *.psf.fz extension)
  • PcScreenFontCompressed (*.psf.gz)
  • PcScreenFontUnicode (*.psfu)
  • PortableCompiledFormat (*.pcf)
  • PortableCompiledFormatCompressed (*.pcf.gz)
  • PostScript (*.ps)
  • PrinterFontAscii (*.pfa)
  • PrinterFontBinary (*.pfb)
  • PrinterFontMetrics (*.pfm, in conjuction with PFA/PFB/T1/PS)
  • ScalableVectorGraphics (*.svg)
  • ScalableVectorGraphicsCompressed (*.svgz)
  • Type1 (*.t1)
  • TrueTypeCollection (*.ttc)
  • TrueTypeFont (*.ttf)
  • WebOpenFontFormat (*.woff)
  • WebOpenFontFormat2 (*.woff2)
  • WindowsBitmapFontCollection (*.fon)

Why?

A rabbit hole, really. We needed to check some configuration option for our next package about XSL-FO, especially the <auto-detect/> option in Apache FOP configuration file. This option allows to retrieve all fonts registered in current OS.

First, we wanted to validate some values against this option. Then, we found old fonts on some operating systems does not publicize their name in the filename. And after some search on Composer, it seems no package does that. Phenx PHP Font Lib handles TrueType, OpenType and WOFF but that's all. And it is very slow with hundreds of fonts.

After some time and digging through history of fonts, this package became more and more a tribute to evolution of fonts. And it's a pleasure to discover so many ways to embed characters and typography.

If you can read French or can use a translator, find more about how we did it here.
If you wish to browse through samples collection used in this package, see their provenance and our thanks, you may go here.

Performance

Performance is checked with GitHub runners, in test-and-bench action.
Data displayed below are extracted from a single run, with following architectures:

  • Windows: Windows amd64
  • MacOS: MacOS amd64
  • Linux: Linux amd64
  • FreeBSD: Virtual machine amd64 inside Linux container
  • OpenBSD: Virtual machine amd64 inside Linux container
  • Solaris: Virtual machine amd64 inside Linux container

Note: Obviously, you should get better results in *BSD and Solaris with bare metal environment.

Time displayed is meant to be per file: it's an average of every font available in samples + current operating system.

Filetype Windows Mac Linux FreeBSD OpenBSD Solaris
bdf 3ms 48µs 85µs 81µs 104µs 81µs
cff 37µs 17µs 103µs 32µs 39µs 19µs
cff (ps) 2ms 621µs 9ms 1ms 2ms 1ms
dfont 129µs 49µs 405µs 114µs 141µs 91µs
eot 123µs 46µs 401µs 96µs 118µs 79µs
fnt (BSD) 5µs 2µs 7µs 3µs 4µs 3µs
fon (win) 19µs 5µs 27µs 7µs 10µs 7µs
jhf 4µs 2µs 5µs 2µs 3µs 2µs
pcf 75µs 31µs 246µs 57µs 70µs 50µs
pcf.gz 80µs 43µs 230µs 68µs 80µs 57µs
pfa 60µs 36µs 41µs 24µs 75µs 58µs
pfb 122µs 83µs 96µs 40µs 88µs 81µs
psf 4µs 2µs 5µs 2µs 3µs 2µs
psf.gz 7µs 5µs 9µs 6µs 7µs 6µs
psfu 3µs 1µs 5µs 2µs 3µs 3µs
psfu.gz 9µs 6µs 11µs 7µs 8µs 7µs
spd 4µs 2µs 7µs 2µs 3µs 3µs
svg 12µs 11µs 13µs 8µs 10µs 9µs
svgz 129µs 132µs 102µs 117µs 121µs 105µs
ttc 372µs 287µs 2ms 483µs 549µs 397µs
ttf 189µs 145µs 1ms 272µs 327µs 214µs
woff 5ms 3ms 7ms 5ms 5ms 5ms
woff2 210ms 21ms 22ms 30ms 70ms 27ms

You may check metrics in the specific run used for these metrics.

If you like PHPBench and would prefer PHPBench metrics because you also care about memory peak, here you go:

Windows amd64

benchmark subject set revs its mem_peak mode rstdev
SamplesPerformanceTest benchSamples 100 5 1.946mb 7.184ms ±0.61%
SystemPerformanceTest benchSystem 100 5 1.946mb 5.251μs ±3.50%

Linux amd64

benchmark subject set revs its mem_peak mode rstdev
SystemPerformanceTest benchSystem 100 5 2.189mb 5.843μs ±1.82%
SamplesPerformanceTest benchSamples 100 5 2.189mb 1.645ms ±0.29%

MacOS amd64

benchmark subject set revs its mem_peak mode rstdev
SamplesPerformanceTest benchSamples 100 5 1.950mb 1.064ms ±4.56%
SystemPerformanceTest benchSystem 100 5 1.950mb 3.099μs ±9.82%

FreeBSD amd64 (VM)

benchmark subject set revs its mem_peak mode rstdev
SamplesPerformanceTest benchSamples 100 5 1.955mb 346.581μs ±1.02%
SystemPerformanceTest benchSystem 100 5 1.955mb 3.367μs ±9.12%

OpenBSD amd64 (VM)

benchmark subject set revs its mem_peak mode rstdev
SamplesPerformanceTest benchSamples 100 5 1.943mb 3.870ms ±1.69%
SystemPerformanceTest benchSystem 100 5 1.943mb 4.224μs ±6.37%

Solaris amd64 (VM)

benchmark subject set revs its mem_peak mode rstdev
SamplesPerformanceTest benchSamples 100 5 1.948mb 1.463ms ±1.63%
SystemPerformanceTest benchSystem 100 5 1.948mb 3.821μs ±3.65%

Documentation

Every call to this library should be done on FontFileFinder class.

Usage

Create an instance: inst()

// Returns a FontFileFinder instance
$instance = FontFileFinder::inst();

No operation will be done until you call the get() method: it only creates an objet.

Include system fonts: addSystemFonts()

// Returns a FontFileFinder instance
$instance = FontFileFinder::inst()
    ->addSystemFonts();

Based on current operating system, will add system font directories.

Include a specific directory: addDirectory()

// Returns a FontFileFinder instance
$instance = FontFileFinder::inst()
    // Tip: use absolute path
    ->addDirectory(implode(DIRECTORY_SEPARATOR, [
        __DIR__,
        'samples'
    ]));

This method will add any file found in this directory. Note that it is not recursive.

Include a specific directory, recursively: addDirectoryRecursive()

// Returns a FontFileFinder instance
$instance = FontFileFinder::inst()
    // Tip: use absolute path
    ->addDirectoryRecursive(implode(DIRECTORY_SEPARATOR, [
        __DIR__,
        'samples'
    ]));

This method will add any file found in this directory, recursively.

Exclude patterns: except()

$instance = FontFileFinder::inst()
    // Exclude .git* files
    ->except('/\.git.*$/')
    // You may use a list
    ->except([
        '/myfolder\/*/',
        '/\.php$/'
    ]) ;

Except method accepts regular expressions and is tested against an absolute path.
If you prefer to exclude based on strings, check exceptExact.

Exclude file names: exceptExact()

$instance = FontFileFinder::inst()
    // Exclude .gitignore files
    ->exceptExact('.gitignore')
    // You may use a list
    ->exceptExact([
        '.DS_Store',
        '.gitkeep'
    ]);

This method checks your strings against an absolute path with str_ends_with, meaning you can exclude extensions without relying on regular expressions.

Get fonts

// Get fonts
$fonts = FontFileFinder::init()
    // Load system fonts (OS-dependent)
    ->addSystemFonts()
    // Load some directory
    ->addDirectoryRecursive(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'tests', 'samples']))
    ->get();

You may want to retrieve other information, such as font count or errors. get() method allows to define what you want to get:

[$errors, $count, $fonts] = FontFileFinder::init()
    ->addSystemFonts()
    ->get('errors', 'count', 'fonts');

Currently, only errors, count and fonts are defined. You may define them in any order:

[$count, $errors] = FontFileFinder::init()
    ->addSystemFonts()
    ->get('count', 'errors');

Configuration

Silence errors

You may want to silence errors: by default, errors are printed to standard error output (stderr).

$instance = FontFileFinder::inst()
    ->silent();

Enable performance metrics

Because sometimes, you wish to see performance metrics.

$instance = FontFileFinder::inst()
    ->enableMetrics();

You can disable them later with disableMetrics.

Advanced

Use a configuration array

$fonts = FontFileFinder::load([
     'directories' => [
         [
             'recursive' => true,
             'path' => '/usr/local/...'
         ],
         '/home/user/...'
     ]
]);

Method load accepts autoDetect (boolean) or directories. It is not possible to get errors and count this way, but maybe in a next release!

Check system fonts

If you want a quick peek on system fonts, simply write:

$fonts = FontFileFinder::getSystemFonts();

You won't have access to any of FontFileFinder configuration, but sometimes it's just what you want.

Override FontDecoder

FontFileFinder relies on a class called FontDecoder, which:

  • Run through all decoders to find a match for the current file
  • Actually does the performance check

If this class is not sufficient for your needs, you may define another subclass (that you have to write) and declare it this way:

$instance = FontFileFinder::inst()
    ->setDecoderClass(MyAwesomeClass::class);

Changelog

Please refer to the CHANGELOG file to see the latest changes.

Support

We put our heart into delivering high-quality products that are accessible to everyone. If you like our work, don’t hesitate to reach out to us for your next project!

Contributing

Contributions are governed by the CONTRIBUTING file.

Security

If you’ve found a bug or vulnerability, please contact us by email at contact@ls-a.fr instead of opening an issue, in order to protect the security of other users.

Credits

  • Renaud Berthier

License

The MIT License (MIT). Please see License File for more information.

ls-a/font-finder 适用场景与选型建议

ls-a/font-finder 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「linux」 「windows」 「font」 「unix」 「os」 「finder」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 ls-a/font-finder 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ls-a/font-finder 我们能提供哪些服务?
定制开发 / 二次开发

基于 ls-a/font-finder 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 39
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-18