On Tue, 29 Nov 2016 16:30:35 +0900, Akira TAGOH wrote: > Can you attach the example that can reproduce your issue? > > FcNameParse() should generates the same FcPattern with the strings > generated by FcNameUnparse(). OK, I have narrowed it down. Attached is the simplest C program I could come up with to demonstrate the issue. Pass it a pattern string on the command line, e.g. fc_pattern_2 sans-serif and it will print out some information about what it found. Having found a matching pattern, it calls FcNameUnparse to convert that to a pattern string, followed by FcNameParse to convert the string back to a pattern. If the pattern includes the “charset” property, the FcNameParse call fails, possibly even segfaults. Removing this property causes the parse (and the subsequent match) to succeed. I helpfully put the call “FcPatternDel(found_pat, FC_CHARSET);” inside an “if (true)” block, so you can try changing it to “if (false)” to observe the effect. I have libconfig 2.11.0 installed from the repo package on Debian Unstable.
/* Try to investigate oddity with parsing/unparsing of Fontconfig patterns. Build command: gcc -o fc_pattern_2 -lfontconfig fc_pattern_2.c Usage: fc_pattern_2 «pat-string» */ #include <stdbool.h> #include <iso646.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <fontconfig/fontconfig.h> static char * progname; static int exit_status = 0; int main ( int argc, char ** argv ) { FcPattern * find_pat = 0; FcPattern * found_pat = 0; char * pat_str = 0; FcPattern * parsed_pat = 0; FcPattern * found_pat_2 = 0; FcResult fc_result; progname = argv[0]; do /*once*/ { if (argc != 2) { fprintf(stderr, "Usage:\n\t%s «pat-string»\n", progname); exit_status = 1; break; } /*if*/ find_pat = FcNameParse(argv[1]); if (find_pat == 0) { fprintf(stderr, "%s: initial FcNameParse failed\n", progname); exit_status = 3; break; } /*if*/ if (not FcConfigSubstitute(0, find_pat, FcMatchPattern)) { fprintf(stderr, "%s: FcConfigSubstitute failed\n", progname); exit_status = 3; break; } /*if*/ FcDefaultSubstitute(find_pat); found_pat = FcFontMatch(0, find_pat, &fc_result); if (found_pat == 0) { fprintf(stderr, "%s: first FcFontMatch failed with status %d\n", progname, fc_result); exit_status = 3; break; } /*if*/ { char * namestr; FcPatternGetString(found_pat, FC_FAMILY, 0, (FcChar8 **)&namestr); fprintf(stderr, "found font with family name â??%sâ??\n", namestr); } if (true) { /* if this is disabled, the following FcNameParse call will fail */ FcPatternDel(found_pat, FC_CHARSET); } /*if*/ pat_str = FcNameUnparse(found_pat); if (pat_str == 0) { fprintf(stderr, "%s: FcNameUnparse failed\n", progname); exit_status = 3; break; } /*if*/ fprintf(stdout, "Found pat (%d): %s\n", fc_result, pat_str); parsed_pat = FcNameParse(pat_str); if (parsed_pat == 0) { fprintf(stderr, "%s: second FcNameParse failed\n", progname); exit_status = 3; break; } /*if*/ found_pat_2 = FcFontMatch(0, find_pat, &fc_result); if (found_pat_2 == 0) { fprintf(stderr, "%s: second FcFontMatch failed with status %d\n", progname, fc_result); exit_status = 3; break; } /*if*/ { char * namestr; FcPatternGetString(found_pat_2, FC_FAMILY, 0, (FcChar8 **)&namestr); fprintf(stderr, "found second font with family name â??%sâ??\n", namestr); } } while (false); FcPatternDestroy(found_pat_2); FcPatternDestroy(parsed_pat); free(pat_str); FcPatternDestroy(found_pat); FcPatternDestroy(find_pat); return exit_status; } /*main*/
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/fontconfig