Skip to content

Instantly share code, notes, and snippets.

@Earnestly
Last active March 23, 2020 18:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Earnestly/b2986fc5df7e7c66375968e386b670ca to your computer and use it in GitHub Desktop.
Save Earnestly/b2986fc5df7e7c66375968e386b670ca to your computer and use it in GitHub Desktop.
fc-glyph - display all fonts which contain specified glyphs
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include <wchar.h>
#include <locale.h>
#include <fontconfig/fontconfig.h>
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
static FcChar8 *fmt = (unsigned char*)"%{file} (%{family})\n";
int
main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
if(argc<2)
errx(1, "usage: fc-glyph [-f format] glyph [glyph...]");
int opt = 0;
while((opt = getopt(argc, argv, ":f:")) != -1){
switch(opt){
case 'f':
fmt = (FcChar8 *)optarg;
break;
case ':':
errx(1, "usage: fc-glyph [-f format] glyph [glyph...]");
}
}
FcPattern *pattern = FcPatternCreate();
FcFontSet *fontset = FcFontList(0, pattern, NULL);
FcPatternDestroy(pattern);
/*
* Provide a degree of room for the matching glyphs which are prefixed
* to the format string.
*/
int width = (argc-1) * 2;
int nfont = fontset->nfont;
for(int i = 0; i < nfont; ++i){
FcPattern *font = fontset->fonts[i];
FcCharSet *charset = 0;
if(FcPatternGetCharSet(font, FC_CHARSET, 0, &charset) != FcResultMatch)
continue;
/* Should be enough for most reasonable cases. */
wchar_t buf[64] = {0};
size_t off = 0;
for(int j = optind; j < argc; ++j){
FcChar32 ch;
FcUtf8ToUcs4((FcChar8 *)argv[j], &ch, strlen(argv[j]));
if(!FcCharSetHasChar(charset, ch))
continue;
if(off <= ARRAY_SIZE(buf))
off += swprintf(buf+off, sizeof(buf)-off, L"%s ", argv[j]);
else
err(111, "glyph count exceeded %ld", ARRAY_SIZE(buf));
}
if(*buf){
FcChar8 *format = FcPatternFormat(font, fmt);
if(format)
fwprintf(stdout, L"%-*ls %s", width, buf, format);
FcStrFree(format);
}
}
FcFontSetDestroy(fontset);
FcFini();
exit(0);
}
PREFIX ?= /usr/local
bindir ?= $(PREFIX)/bin
CFLAGS ?= -g -O2 -Wall -Wextra -Wpedantic
CPPFLAGS ?= -D_FORTIFY_SOURCE=2
override CFLAGS += $(shell pkg-config --cflags fontconfig)
override LDFLAGS += $(shell pkg-config --libs-only-L fontconfig)
LDLIBS := $(shell pkg-config --libs-only-l fontconfig)
all: fc-glyph
fc-glyph.o: fc-glyph.c
install:
install -Dm0755 fc-glyph $(DESTDIR)$(bindir)/fc-glyph
clean:
$(RM) fc-glyph fc-glyph.o
.PHONY: all install clean
# Blue Oak Model License
Version 1.0.0
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment