create fontconfig configuration under the fontconfig folder and allow registration of multiple font directories

This commit is contained in:
Taner Sener 2021-01-24 20:14:28 +00:00
parent 2af487818a
commit 457b0fb1b1
3 changed files with 78 additions and 46 deletions

View File

@ -34,6 +34,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@ -397,7 +398,8 @@ public class FFmpegKitConfig {
}
/**
* <p>Registers fonts inside the given path, so they become available to use in FFmpeg filters.
* <p>Registers the fonts inside the given path, so they become available to use in FFmpeg
* filters.
*
* <p>Note that you need to build <code>FFmpegKit</code> with <code>fontconfig</code>
* enabled or use a prebuilt package with <code>fontconfig</code> inside to use this feature.
@ -408,10 +410,26 @@ public class FFmpegKitConfig {
* friendly names
*/
public static void setFontDirectory(final Context context, final String fontDirectoryPath, final Map<String, String> fontNameMapping) {
setFontDirectoryList(context, Collections.singletonList(fontDirectoryPath), fontNameMapping);
}
/**
* <p>Registers the fonts inside the given list of font directories, so they become available
* to use in FFmpeg filters.
*
* <p>Note that you need to build <code>FFmpegKit</code> with <code>fontconfig</code>
* enabled or use a prebuilt package with <code>fontconfig</code> inside to use this feature.
*
* @param context application context to access application data
* @param fontDirectoryList list of directories which contain fonts (.ttf and .otf files)
* @param fontNameMapping custom font name mappings, useful to access your fonts with more
* friendly names
*/
public static void setFontDirectoryList(final Context context, final List<String> fontDirectoryList, final Map<String, String> fontNameMapping) {
final File cacheDir = context.getCacheDir();
int validFontNameMappingCount = 0;
final File tempConfigurationDirectory = new File(cacheDir, ".ffmpegkit");
final File tempConfigurationDirectory = new File(cacheDir, "fontconfig");
if (!tempConfigurationDirectory.exists()) {
boolean tempFontConfDirectoryCreated = tempConfigurationDirectory.mkdirs();
android.util.Log.d(TAG, String.format("Created temporary font conf directory: %s.", tempFontConfDirectoryCreated));
@ -446,30 +464,37 @@ public class FFmpegKitConfig {
}
}
final String fontConfig = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n" +
"<fontconfig>\n" +
" <dir>.</dir>\n" +
" <dir>" + fontDirectoryPath + "</dir>\n" +
fontNameMappingBlock +
"</fontconfig>";
final StringBuilder fontConfigBuilder = new StringBuilder();
fontConfigBuilder.append("<?xml version=\"1.0\"?>\n");
fontConfigBuilder.append("<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n");
fontConfigBuilder.append("<fontconfig>\n");
fontConfigBuilder.append(" <dir prefix=\"cwd\">.</dir>\n");
for (String fontDirectoryPath : fontDirectoryList) {
fontConfigBuilder.append(" <dir>");
fontConfigBuilder.append(fontDirectoryPath);
fontConfigBuilder.append("</dir>\n");
}
fontConfigBuilder.append(fontNameMappingBlock);
fontConfigBuilder.append("</fontconfig>");
final AtomicReference<FileOutputStream> reference = new AtomicReference<>();
try {
final FileOutputStream outputStream = new FileOutputStream(fontConfiguration);
reference.set(outputStream);
outputStream.write(fontConfig.getBytes());
outputStream.write(fontConfigBuilder.toString().getBytes());
outputStream.flush();
android.util.Log.d(TAG, String.format("Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount));
setFontconfigConfigurationPath(tempConfigurationDirectory.getAbsolutePath());
android.util.Log.d(TAG, String.format("Font directory %s registered successfully.", fontDirectoryPath));
for (String fontDirectoryPath : fontDirectoryList) {
android.util.Log.d(TAG, String.format("Font directory %s registered successfully.", fontDirectoryPath));
}
} catch (final IOException e) {
android.util.Log.e(TAG, String.format("Failed to set font directory: %s.%s", fontDirectoryPath, Exceptions.getStackTraceString(e)));
android.util.Log.e(TAG, String.format("Failed to set font directory: %s.%s", Arrays.toString(fontDirectoryList.toArray()), Exceptions.getStackTraceString(e)));
} finally {
if (reference.get() != null) {
try {

View File

@ -607,42 +607,47 @@ void callbackBlockFunction() {
}
/**
* Registers fonts inside the given path, so they are available in FFmpeg filters.
* Registers the fonts inside the given path, so they become available to use in FFmpeg filters.
*
* Note that you need to build FFmpegKit with fontconfig
* enabled or use a prebuilt package with fontconfig inside to use this feature.
* Note that you need to build FFmpegKit with fontconfig enabled or use a prebuilt package with
* fontconfig inside to use this feature.
*
* @param fontDirectoryPath directory which contains fonts (.ttf and .otf files)
* @param fontNameMapping custom font name mappings, useful to access your fonts with more friendly names
*/
+ (void)setFontDirectory:(NSString*)fontDirectoryPath with:(NSDictionary*)fontNameMapping {
[FFmpegKitConfig setFontDirectoryList:[NSArray arrayWithObject:fontDirectoryPath] with:fontNameMapping];
}
/**
* Registers the fonts inside the given array of font directories, so they become available to use
* in FFmpeg filters.
*
* Note that you need to build FFmpegKit with fontconfig enabled or use a prebuilt package with
* fontconfig inside to use this feature.
*
* @param fontDirectoryArray array of directories which contain fonts (.ttf and .otf files)
* @param fontNameMapping custom font name mappings, useful to access your fonts with more friendly names
*/
+ (void)setFontDirectoryList:(NSArray*)fontDirectoryArray with:(NSDictionary*)fontNameMapping {
NSError *error = nil;
BOOL isDirectory = YES;
BOOL isFile = NO;
int validFontNameMappingCount = 0;
NSString *tempConfigurationDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@".ffmpegkit"];
NSString *tempConfigurationDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"fontconfig"];
NSString *fontConfigurationFile = [tempConfigurationDirectory stringByAppendingPathComponent:@"fonts.conf"];
int activeLogLevel = av_log_get_level();
if (![[NSFileManager defaultManager] fileExistsAtPath:tempConfigurationDirectory isDirectory:&isDirectory]) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:tempConfigurationDirectory withIntermediateDirectories:YES attributes:nil error:&error]) {
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_WARNING <= activeLogLevel)) {
NSLog(@"Failed to set font directory. Error received while creating temp conf directory: %@.", error);
}
NSLog(@"Failed to set font directory. Error received while creating temp conf directory: %@.", error);
return;
}
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_DEBUG <= activeLogLevel)) {
NSLog(@"Created temporary font conf directory: TRUE.");
}
NSLog(@"Created temporary font conf directory: TRUE.");
}
if ([[NSFileManager defaultManager] fileExistsAtPath:fontConfigurationFile isDirectory:&isFile]) {
BOOL fontConfigurationDeleted = [[NSFileManager defaultManager] removeItemAtPath:fontConfigurationFile error:NULL];
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_DEBUG <= activeLogLevel)) {
NSLog(@"Deleted old temporary font configuration: %s.", fontConfigurationDeleted?"TRUE":"FALSE");
}
NSLog(@"Deleted old temporary font configuration: %s.", fontConfigurationDeleted?"TRUE":"FALSE");
}
/* PROCESS MAPPINGS FIRST */
@ -666,28 +671,31 @@ void callbackBlockFunction() {
}
}
NSString *fontConfiguration = [NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@%@%@\n%@\n%@\n",
NSMutableString *fontConfiguration = [NSMutableString stringWithFormat:@"%@\n%@\n%@\n%@\n",
@"<?xml version=\"1.0\"?>",
@"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">",
@"<fontconfig>",
@" <dir>.</dir>",
@" <dir>", fontDirectoryPath, @"</dir>",
fontNameMappingBlock,
@"</fontconfig>"];
@" <dir prefix=\"cwd\">.</dir>"];
for (int i=0; i < [fontDirectoryArray count]; i++) {
NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
[fontConfiguration appendString: @" <dir>"];
[fontConfiguration appendString: fontDirectoryPath];
[fontConfiguration appendString: @"</dir>"];
}
[fontConfiguration appendString:fontNameMappingBlock];
[fontConfiguration appendString:@"</fontconfig>"];
if (![fontConfiguration writeToFile:fontConfigurationFile atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_WARNING <= activeLogLevel)) {
NSLog(@"Failed to set font directory. Error received while saving font configuration: %@.", error);
}
NSLog(@"Failed to set font directory. Error received while saving font configuration: %@.", error);
return;
}
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_DEBUG <= activeLogLevel)) {
NSLog(@"Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount);
}
NSLog(@"Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount);
[FFmpegKitConfig setFontconfigConfigurationPath:tempConfigurationDirectory];
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_DEBUG <= activeLogLevel)) {
for (int i=0; i < [fontDirectoryArray count]; i++) {
NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
NSLog(@"Font directory %@ registered successfully.", fontDirectoryPath);
}
}

View File

@ -1843,12 +1843,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
int ret;
float t;
// FORWARD IT BEFORE PROCESSING
forward_report(is_last_report, timer_start, cur_time);
if (!print_stats && !is_last_report && !progress_avio)
return;
if (!is_last_report) {
if (last_time == -1) {
last_time = cur_time;
@ -1859,6 +1853,11 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
last_time = cur_time;
}
forward_report(is_last_report, timer_start, cur_time);
if (!print_stats && !is_last_report && !progress_avio)
return;
t = (cur_time-timer_start) / 1000000.0;