Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Font Lib Laravel Package

phenx/php-font-lib

Read and parse TrueType, OpenType (TT glyphs) and WOFF fonts in PHP. Extract basic/advanced metadata, metrics, glyph names and shapes, generate Adobe Font Metrics (AFM), and build font subsets. Used by dompdf for font handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require dompdf/php-font-lib
    

    Ensure ext-mbstring is enabled in your PHP environment.

  2. Basic Usage: Load a font file and extract metadata:

    use FontLib\Font;
    
    $font = Font::load(storage_path('fonts/your-font.ttf'));
    $font->parse();
    
    // Extract metadata
    $fontName = $font->getFontName();
    $weight = $font->getFontWeight();
    $postscriptName = $font->getFontPostscriptName();
    
    $font->close();
    
  3. First Use Case: Generate a PDF with DOMPDF using a subsetted font:

    use Dompdf\Dompdf;
    use FontLib\Font;
    
    $font = Font::load(storage_path('fonts/your-font.ttf'));
    $font->parse();
    $font->setSubset("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    $font->reduce();
    $font->save(storage_path('fonts/subset-font.ttf'));
    $font->close();
    
    // Use the subsetted font in DOMPDF
    $dompdf = new Dompdf();
    $dompdf->loadHtml('<h1>Hello World</h1>');
    $dompdf->setPaper('A4', 'portrait');
    $dompdf->setOption('isRemoteEnabled', true);
    $dompdf->setOption('isFontSubsettingEnabled', true);
    $dompdf->render();
    $dompdf->stream("document.pdf", ["Attachment" => true]);
    

Where to Look First

  • Documentation: Focus on the README.md for core functionality.
  • Examples: Study the usage examples in the README for font metadata extraction, subsetting, and AFM generation.
  • Tests: Explore the test directory for edge cases and best practices.

Implementation Patterns

Usage Patterns

  1. Font Metadata Extraction: Use the library to extract font properties for dynamic typography or validation:

    $font = Font::load($fontPath);
    $font->parse();
    
    $metadata = [
        'name' => $font->getFontName(),
        'family' => $font->getFontSubfamily(),
        'weight' => $font->getFontWeight(),
        'postscript' => $font->getFontPostscriptName(),
    ];
    
    $font->close();
    
  2. Font Subsetting for PDFs: Subset fonts to reduce file size and improve rendering performance:

    $font = Font::load($fontPath);
    $font->parse();
    $font->setSubset($requiredCharacters); // e.g., "abc123"
    $font->reduce();
    $subsetPath = $outputPath . '.subset.ttf';
    $font->save($subsetPath);
    $font->close();
    
  3. AFM/UFM Generation: Generate Adobe Font Metrics for legacy systems or compatibility:

    $font = Font::load($fontPath);
    $font->parse();
    $font->saveAdobeFontMetrics($outputPath . '.afm');
    $font->close();
    
  4. Font Re-encoding: Re-encode fonts for specific platforms or encodings:

    $font = Font::load($fontPath);
    $font->parse();
    $font->open($outputPath, FontLib\BinaryStream::modeReadWrite);
    $font->encode(['OS/2']); // Specify encoding tables
    $font->close();
    

Workflows

  1. PDF Generation Pipeline:

    • Use the library to subset fonts before generating PDFs with DOMPDF.
    • Cache subsetted fonts to avoid reprocessing.
    // app/Services/FontService.php
    class FontService {
        public function getSubsetFont($fontPath, $characters) {
            $cachePath = storage_path("fonts/{md5($fontPath)}{md5($characters)}.ttf");
            if (!file_exists($cachePath)) {
                $font = Font::load($fontPath);
                $font->parse();
                $font->setSubset($characters);
                $font->reduce();
                $font->save($cachePath);
                $font->close();
            }
            return $cachePath;
        }
    }
    
  2. Dynamic Typography:

    • Extract font metadata to dynamically adjust typography based on font properties.
    $font = Font::load($fontPath);
    $font->parse();
    
    $fontSize = $font->getFontWeight() > 500 ? 12 : 10; // Adjust size based on weight
    $font->close();
    
  3. Font Validation:

    • Validate fonts before processing to ensure compatibility.
    try {
        $font = Font::load($fontPath);
        $font->parse();
        if ($font->getFontWeight() === null) {
            throw new \Exception("Invalid font weight");
        }
        $font->close();
    } catch (\Exception $e) {
        Log::error("Font validation failed: " . $e->getMessage());
    }
    

Integration Tips

  1. Laravel Service Container: Bind the FontLib\Font class to the container for dependency injection:

    // config/app.php
    'bindings' => [
        FontLib\Font::class => function ($app) {
            return new FontLib\Font();
        },
    ];
    
  2. Artisan Commands: Create custom commands for font processing:

    // app/Console/Commands/SubsetFont.php
    class SubsetFont extends Command {
        protected $signature = 'font:subset {font} {characters} {--output=}';
        protected $description = 'Subset a font file';
    
        public function handle() {
            $fontPath = storage_path('fonts/' . $this->argument('font'));
            $outputPath = $this->option('output') ?: storage_path('fonts/subset-' . $this->argument('font'));
            $characters = $this->argument('characters');
    
            $font = Font::load($fontPath);
            $font->parse();
            $font->setSubset($characters);
            $font->reduce();
            $font->save($outputPath);
            $font->close();
    
            $this->info("Font subsetted successfully: {$outputPath}");
        }
    }
    
  3. Queue Jobs: Offload font processing to queues for performance:

    // app/Jobs/SubsetFontJob.php
    class SubsetFontJob implements ShouldQueue {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        public $fontPath;
        public $characters;
        public $outputPath;
    
        public function handle() {
            $font = Font::load($this->fontPath);
            $font->parse();
            $font->setSubset($this->characters);
            $font->reduce();
            $font->save($this->outputPath);
            $font->close();
        }
    }
    
  4. Storage Integration: Use Laravel’s filesystem to handle font files:

    use Illuminate\Support\Facades\Storage;
    
    $fontPath = Storage::disk('fonts')->path('your-font.ttf');
    $font = Font::load($fontPath);
    $font->parse();
    // Process font
    $font->close();
    

Gotchas and Tips

Pitfalls

  1. Font Parsing Errors:

    • Some fonts may throw exceptions due to malformed tables (e.g., glyf, cmap). Handle exceptions gracefully:
    try {
        $font = Font::load($fontPath);
        $font->parse();
        // Process font
    } catch (\Exception $e) {
        Log::error("Failed to parse font: " . $e->getMessage());
        throw new \RuntimeException("Invalid font file");
    }
    
  2. Memory Usage:

    • Processing large fonts (e.g., CJK) can consume significant memory. Use streaming where possible:
    $font = Font::load($fontPath, FontLib\BinaryStream::modeRead);
    $font->parse();
    // Process font
    $font->close();
    
  3. PHP Version Compatibility:

    • Ensure your PHP version (7.1+) matches the library’s requirements. Test with PHP 8.x for potential TypedArray issues.
  4. Subsetting Limitations:

    • Subsetting may not work perfectly for all fonts, especially those with complex glyphs or encodings. Test thoroughly with your target fonts.
  5. File Permissions:

    • Ensure the web server has write permissions for output directories when saving subsetted fonts or AFM files.

Debugging

  1. Logging Font Metadata:
    • Log detailed font metadata for debugging:
    $font = Font::load($fontPath);
    $font->parse();
    Log::debug('Font Metadata:', [
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity