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.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; 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> * <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. * enabled or use a prebuilt package with <code>fontconfig</code> inside to use this feature.
@ -408,10 +410,26 @@ public class FFmpegKitConfig {
* friendly names * friendly names
*/ */
public static void setFontDirectory(final Context context, final String fontDirectoryPath, final Map<String, String> fontNameMapping) { 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(); final File cacheDir = context.getCacheDir();
int validFontNameMappingCount = 0; int validFontNameMappingCount = 0;
final File tempConfigurationDirectory = new File(cacheDir, ".ffmpegkit"); final File tempConfigurationDirectory = new File(cacheDir, "fontconfig");
if (!tempConfigurationDirectory.exists()) { if (!tempConfigurationDirectory.exists()) {
boolean tempFontConfDirectoryCreated = tempConfigurationDirectory.mkdirs(); boolean tempFontConfDirectoryCreated = tempConfigurationDirectory.mkdirs();
android.util.Log.d(TAG, String.format("Created temporary font conf directory: %s.", tempFontConfDirectoryCreated)); 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" + final StringBuilder fontConfigBuilder = new StringBuilder();
"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n" + fontConfigBuilder.append("<?xml version=\"1.0\"?>\n");
"<fontconfig>\n" + fontConfigBuilder.append("<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n");
" <dir>.</dir>\n" + fontConfigBuilder.append("<fontconfig>\n");
" <dir>" + fontDirectoryPath + "</dir>\n" + fontConfigBuilder.append(" <dir prefix=\"cwd\">.</dir>\n");
fontNameMappingBlock + for (String fontDirectoryPath : fontDirectoryList) {
"</fontconfig>"; fontConfigBuilder.append(" <dir>");
fontConfigBuilder.append(fontDirectoryPath);
fontConfigBuilder.append("</dir>\n");
}
fontConfigBuilder.append(fontNameMappingBlock);
fontConfigBuilder.append("</fontconfig>");
final AtomicReference<FileOutputStream> reference = new AtomicReference<>(); final AtomicReference<FileOutputStream> reference = new AtomicReference<>();
try { try {
final FileOutputStream outputStream = new FileOutputStream(fontConfiguration); final FileOutputStream outputStream = new FileOutputStream(fontConfiguration);
reference.set(outputStream); reference.set(outputStream);
outputStream.write(fontConfig.getBytes()); outputStream.write(fontConfigBuilder.toString().getBytes());
outputStream.flush(); outputStream.flush();
android.util.Log.d(TAG, String.format("Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount)); android.util.Log.d(TAG, String.format("Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount));
setFontconfigConfigurationPath(tempConfigurationDirectory.getAbsolutePath()); 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) { } 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 { } finally {
if (reference.get() != null) { if (reference.get() != null) {
try { 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 * Note that you need to build FFmpegKit with fontconfig enabled or use a prebuilt package with
* enabled or use a prebuilt package with fontconfig inside to use this feature. * fontconfig inside to use this feature.
* *
* @param fontDirectoryPath directory which contains fonts (.ttf and .otf files) * @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 * @param fontNameMapping custom font name mappings, useful to access your fonts with more friendly names
*/ */
+ (void)setFontDirectory:(NSString*)fontDirectoryPath with:(NSDictionary*)fontNameMapping { + (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; NSError *error = nil;
BOOL isDirectory = YES; BOOL isDirectory = YES;
BOOL isFile = NO; BOOL isFile = NO;
int validFontNameMappingCount = 0; int validFontNameMappingCount = 0;
NSString *tempConfigurationDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@".ffmpegkit"]; NSString *tempConfigurationDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"fontconfig"];
NSString *fontConfigurationFile = [tempConfigurationDirectory stringByAppendingPathComponent:@"fonts.conf"]; NSString *fontConfigurationFile = [tempConfigurationDirectory stringByAppendingPathComponent:@"fonts.conf"];
int activeLogLevel = av_log_get_level();
if (![[NSFileManager defaultManager] fileExistsAtPath:tempConfigurationDirectory isDirectory:&isDirectory]) { if (![[NSFileManager defaultManager] fileExistsAtPath:tempConfigurationDirectory isDirectory:&isDirectory]) {
if (![[NSFileManager defaultManager] createDirectoryAtPath:tempConfigurationDirectory withIntermediateDirectories:YES attributes:nil error:&error]) { 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; return;
} }
NSLog(@"Created temporary font conf directory: TRUE.");
if ((activeLogLevel != AV_LOG_QUIET) && (AV_LOG_DEBUG <= activeLogLevel)) {
NSLog(@"Created temporary font conf directory: TRUE.");
}
} }
if ([[NSFileManager defaultManager] fileExistsAtPath:fontConfigurationFile isDirectory:&isFile]) { if ([[NSFileManager defaultManager] fileExistsAtPath:fontConfigurationFile isDirectory:&isFile]) {
BOOL fontConfigurationDeleted = [[NSFileManager defaultManager] removeItemAtPath:fontConfigurationFile error:NULL]; 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 */ /* 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\"?>", @"<?xml version=\"1.0\"?>",
@"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">", @"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">",
@"<fontconfig>", @"<fontconfig>",
@" <dir>.</dir>", @" <dir prefix=\"cwd\">.</dir>"];
@" <dir>", fontDirectoryPath, @"</dir>", for (int i=0; i < [fontDirectoryArray count]; i++) {
fontNameMappingBlock, NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
@"</fontconfig>"]; [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 (![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; 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]; [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); 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; int ret;
float t; 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 (!is_last_report) {
if (last_time == -1) { if (last_time == -1) {
last_time = cur_time; 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; 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; t = (cur_time-timer_start) / 1000000.0;