r4fterman/pdf.forms

View on GitHub
src/main/java/org/pdf/forms/fonts/FontHandler.java

Summary

Maintainability
A
0 mins
Test Coverage
C
70%
package org.pdf.forms.fonts;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

import org.pdf.forms.model.properties.Font;
import org.pdf.forms.readers.properties.DesignerPropertiesFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class FontHandler {

    private final Logger logger = LoggerFactory.getLogger(FontHandler.class);
    private final List<Font> fonts = new ArrayList<>();
    private final DesignerPropertiesFile designerPropertiesFile;

    public FontHandler(
            final DesignerPropertiesFile designerPropertiesFile,
            final FontDirectories fontDirectories) {
        this.designerPropertiesFile = designerPropertiesFile;
        fontDirectories.getDirectories().forEach(this::registerDirectory);

        updateFonts();
    }

    public void updateFonts() {
        //todo: need to check if file has moved, and if so offer user chance to browse
        designerPropertiesFile.getCustomFonts().forEach(font -> registerFont(new File(font.getPath())));
    }

    private void registerDirectory(final File fontDirectory) {
        try {
            if (!fontDirectory.exists() || !fontDirectory.isDirectory()) {
                return;
            }

            final File[] fontFiles = fontDirectory.listFiles((directory, fileName) -> fileName.toLowerCase()
                    .endsWith(".ttf"));
            if (fontFiles == null) {
                return;
            }

            Arrays.stream(fontFiles).forEach(this::registerFont);
        } catch (final Exception e) {
            logger.info("Error registering directory. {}", e.getMessage());
        }
    }

    Optional<String> registerFont(final File fontFile) {
        try {
            final java.awt.Font font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile);
            final String fontName = font.getFontName();

            this.fonts.add(new Font(fontName, fontFile.getPath()));

            return Optional.of(fontName);
        } catch (FontFormatException | IOException e) {
            logger.warn("Unable reading font in FontHandler. {}", e.getMessage());
        }

        return Optional.empty();
    }

    public java.awt.Font getDefaultFont() {
        if (!getFonts().isEmpty()) {
            final Font font = getFonts().get(0);
            final Optional<java.awt.Font> javaFont = font.convertToJavaFont();
            if (javaFont.isPresent()) {
                return javaFont.get();
            }
        }
        return new java.awt.Font("Arial", java.awt.Font.PLAIN, 11);
    }

    public List<Font> getFonts() {
        fonts.sort(Comparator.comparing(Font::getName));
        return List.copyOf(fonts);
    }

    public Optional<String> getFontDirectory(final java.awt.Font font) {
        return getAbsoluteFontPath(font)
                .map(fontPath -> {
                    final String fileName = new File(fontPath).getName();
                    return fontPath.substring(0, fontPath.length() - fileName.length());
                });
    }

    public Optional<String> getAbsoluteFontPath(final java.awt.Font font) {
        final String fontName = font.getName();

        return fonts.stream()
                .filter(f -> f.getName().equals(fontName))
                .findFirst()
                .map(Font::getPath);
    }

    public java.awt.Font getFontFromName(final String fontName) {
        return fonts.stream()
                .filter(font -> font.getName().equals(fontName))
                .findFirst()
                .flatMap(Font::convertToJavaFont)
                .orElseGet(this::getDefaultFont);
    }

    public String[] getFontFamilies() {
        return fonts.stream()
                .map(Font::getName)
                .toArray(String[]::new);
    }

}