org.apache.poi.xslf.util.PDFFontMapper Maven / Gradle / Ivy
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.apache.poi.xslf.util;
import java.awt.Font;
import java.awt.FontFormatException;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import de.rototor.pdfbox.graphics2d.PdfBoxGraphics2DFontTextDrawer;
import org.apache.pdfbox.pdmodel.font.PDFont;
public class PDFFontMapper extends PdfBoxGraphics2DFontTextDrawer {
private static final String DEFAULT_TTF_PATTERN = ".*\\.tt[fc]";
private static final String FONTDIRS_MAC =
"$HOME/Library/Fonts;" +
"/Library/Fonts;" +
"/Network/Library/Fonts;" +
"/System/Library/Fonts;" +
"/System Folder/Fonts";
private static final String FONTDIRS_WIN =
"C:\\Windows\\Fonts";
private static final String FONTDIRS_UNX =
"/usr/share/fonts;" +
"/usr/local/share/fonts;" +
"$HOME/.fonts";
private final Map fonts = new HashMap<>();
private final Set registered = new HashSet<>();
public PDFFontMapper(String fontDir, String fontTtf) {
registerFonts(fontDir, fontTtf);
}
private void registerFonts(String fontDir, String fontTtf) {
if (fontDir == null) {
String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ROOT);
if (OS.contains("mac") || OS.contains("darwin")) {
fontDir = FONTDIRS_MAC;
} else if (OS.contains("win")) {
fontDir = FONTDIRS_WIN;
} else {
fontDir = FONTDIRS_UNX;
}
}
String fd = fontDir.replace("$HOME", System.getProperty("user.home"));
final LinkedList dirs = new LinkedList<>();
Stream.of(fd.split(";")).map(File::new).filter(File::isDirectory).forEach(dirs::add);
Pattern p = Pattern.compile(fontTtf == null ? DEFAULT_TTF_PATTERN : fontTtf);
while (!dirs.isEmpty()) {
File[] ttfs = dirs.removeFirst().listFiles((f, n) -> {
File f2 = new File(f, n);
if (f2.isDirectory()) {
dirs.add(f2);
return false;
} else {
return p.matcher(n).matches();
}
});
if (ttfs == null) {
continue;
}
for (File f : ttfs) {
try {
Font font = Font.createFont(Font.TRUETYPE_FONT, f);
fonts.put(font.getFontName(Locale.ROOT), f);
} catch (IOException|FontFormatException ignored) {
}
}
}
}
@Override
protected PDFont mapFont(Font font, IFontTextDrawerEnv env) throws IOException, FontFormatException {
String name = font.getFontName(Locale.ROOT);
if (!registered.contains(name)) {
registered.add(name);
File f = fonts.get(name);
if (f != null) {
super.registerFont(name, f);
}
}
return super.mapFont(font, env);
}
}