Change FcCharSet datastructure, add FcFontSort API
This commit is contained in:
parent
bc9469baad
commit
20ac65ab00
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $XFree86: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.11 2002/05/24 05:20:02 keithp Exp $
|
* $XFree86: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.12 2002/05/29 08:21:33 keithp Exp $
|
||||||
*
|
*
|
||||||
* Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
|
* Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
|
||||||
*
|
*
|
||||||
|
@ -516,6 +516,13 @@ FcFontSetSort (FcConfig *config,
|
||||||
FcCharSet **csp,
|
FcCharSet **csp,
|
||||||
FcResult *result);
|
FcResult *result);
|
||||||
|
|
||||||
|
FcFontSet *
|
||||||
|
FcFontSort (FcConfig *config,
|
||||||
|
FcPattern *p,
|
||||||
|
FcBool trim,
|
||||||
|
FcCharSet **csp,
|
||||||
|
FcResult *result);
|
||||||
|
|
||||||
void
|
void
|
||||||
FcFontSetSortDestroy (FcFontSet *fs);
|
FcFontSetSortDestroy (FcFontSet *fs);
|
||||||
|
|
||||||
|
|
780
src/fccharset.c
780
src/fccharset.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.8 2002/05/29 08:21:33 keithp Exp $
|
* $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.9 2002/05/29 22:07:33 keithp Exp $
|
||||||
*
|
*
|
||||||
* Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
|
* Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
|
||||||
*
|
*
|
||||||
|
@ -27,53 +27,7 @@
|
||||||
|
|
||||||
/* #define CHECK */
|
/* #define CHECK */
|
||||||
|
|
||||||
static int
|
/* #define CHATTY */
|
||||||
FcCharSetLevels (FcChar32 ucs4)
|
|
||||||
{
|
|
||||||
if (ucs4 <= 0xff)
|
|
||||||
return 1;
|
|
||||||
if (ucs4 <= 0xffff)
|
|
||||||
return 2;
|
|
||||||
if (ucs4 <= 0xffffff)
|
|
||||||
return 3;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FcBool
|
|
||||||
FcCharSetCheckLevel (FcCharSet *fcs, FcChar32 ucs4)
|
|
||||||
{
|
|
||||||
int level = FcCharSetLevels (ucs4);
|
|
||||||
|
|
||||||
if (level <= fcs->levels)
|
|
||||||
return FcTrue;
|
|
||||||
while (fcs->levels < level)
|
|
||||||
{
|
|
||||||
if (fcs->levels == 0)
|
|
||||||
{
|
|
||||||
FcCharLeaf *leaf;
|
|
||||||
|
|
||||||
leaf = (FcCharLeaf *) calloc (1, sizeof (FcCharLeaf));
|
|
||||||
if (!leaf)
|
|
||||||
return FcFalse;
|
|
||||||
FcMemAlloc (FC_MEM_CHARNODE, sizeof (FcCharLeaf));
|
|
||||||
fcs->node.leaf = leaf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FcCharBranch *branch;
|
|
||||||
|
|
||||||
branch = (FcCharBranch *) calloc (1, sizeof (FcCharBranch));
|
|
||||||
if (!branch)
|
|
||||||
return FcFalse;
|
|
||||||
FcMemAlloc (FC_MEM_CHARNODE, sizeof (FcCharBranch));
|
|
||||||
branch->nodes[0] = fcs->node;
|
|
||||||
/* next pointers are all zero */
|
|
||||||
fcs->node.branch = branch;
|
|
||||||
}
|
|
||||||
++fcs->levels;
|
|
||||||
}
|
|
||||||
return FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcCharSetCreate (void)
|
FcCharSetCreate (void)
|
||||||
|
@ -85,8 +39,9 @@ FcCharSetCreate (void)
|
||||||
return 0;
|
return 0;
|
||||||
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
fcs->ref = 1;
|
fcs->ref = 1;
|
||||||
fcs->levels = 0;
|
fcs->num = 0;
|
||||||
fcs->node.leaf = 0;
|
fcs->leaves = 0;
|
||||||
|
fcs->numbers = 0;
|
||||||
fcs->constant = FcFalse;
|
fcs->constant = FcFalse;
|
||||||
return fcs;
|
return fcs;
|
||||||
}
|
}
|
||||||
|
@ -100,64 +55,111 @@ FcCharSetNew (void)
|
||||||
return FcCharSetCreate ();
|
return FcCharSetCreate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
FcCharNodeDestroy (FcCharNode node, int level)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
FcMemFree (FC_MEM_CHARNODE, sizeof (FcCharLeaf));
|
|
||||||
free (node.leaf);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
if (node.branch->nodes[i].branch)
|
|
||||||
FcCharNodeDestroy (node.branch->nodes[i], level - 1);
|
|
||||||
FcMemFree (FC_MEM_CHARNODE, sizeof (FcCharBranch));
|
|
||||||
free (node.branch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcCharSetDestroy (FcCharSet *fcs)
|
FcCharSetDestroy (FcCharSet *fcs)
|
||||||
{
|
{
|
||||||
if (fcs->constant)
|
if (!fcs->constant && --fcs->ref <= 0)
|
||||||
return;
|
|
||||||
if (--fcs->ref <= 0)
|
|
||||||
{
|
{
|
||||||
FcCharNodeDestroy (fcs->node, fcs->levels);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < fcs->num; i++)
|
||||||
|
{
|
||||||
|
FcMemFree (FC_MEM_CHARNODE, sizeof (FcCharLeaf));
|
||||||
|
free (fcs->leaves[i]);
|
||||||
|
}
|
||||||
|
if (fcs->leaves)
|
||||||
|
{
|
||||||
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
|
||||||
|
free (fcs->leaves);
|
||||||
|
}
|
||||||
|
if (fcs->numbers)
|
||||||
|
{
|
||||||
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||||
|
free (fcs->numbers);
|
||||||
|
}
|
||||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
free (fcs);
|
free (fcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locate the leaf containing the specified char, returning
|
* Locate the leaf containing the specified char, return
|
||||||
* null if it doesn't exist
|
* its index if it exists, otherwise return negative of
|
||||||
|
* the (position + 1) where it should be inserted
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
|
{
|
||||||
|
FcChar16 *numbers = fcs->numbers;
|
||||||
|
FcChar16 page;
|
||||||
|
int low = 0;
|
||||||
|
int high = fcs->num - 1;
|
||||||
|
|
||||||
|
if (!numbers)
|
||||||
|
return -1;
|
||||||
|
ucs4 >>= 8;
|
||||||
|
while (low <= high)
|
||||||
|
{
|
||||||
|
int mid = (low + high) >> 1;
|
||||||
|
page = numbers[mid];
|
||||||
|
if (page == ucs4)
|
||||||
|
return mid;
|
||||||
|
if (page < ucs4)
|
||||||
|
low = mid + 1;
|
||||||
|
else
|
||||||
|
high = mid - 1;
|
||||||
|
}
|
||||||
|
if (numbers[high] < ucs4)
|
||||||
|
high++;
|
||||||
|
return -(high + 1);
|
||||||
|
}
|
||||||
|
|
||||||
static FcCharLeaf *
|
static FcCharLeaf *
|
||||||
FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
{
|
{
|
||||||
int l;
|
int pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||||
const FcCharNode *prev;
|
if (pos >= 0)
|
||||||
FcCharNode node;
|
return fcs->leaves[pos];
|
||||||
FcChar32 i;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
prev = &fcs->node;
|
static FcBool
|
||||||
l = fcs->levels;
|
FcCharSetPutLeaf (FcCharSet *fcs,
|
||||||
while (--l > 0)
|
FcChar32 ucs4,
|
||||||
{
|
FcCharLeaf *leaf,
|
||||||
node = *prev;
|
int pos)
|
||||||
if (!node.branch)
|
{
|
||||||
return 0;
|
FcCharLeaf **leaves;
|
||||||
i = (ucs4 >> (l << 3)) & 0xff;
|
FcChar16 *numbers;
|
||||||
prev = &node.branch->nodes[i];
|
|
||||||
}
|
ucs4 >>= 8;
|
||||||
return prev->leaf;
|
if (ucs4 >= 0x10000)
|
||||||
|
return FcFalse;
|
||||||
|
if (!fcs->leaves)
|
||||||
|
leaves = malloc (sizeof (FcCharLeaf *));
|
||||||
|
else
|
||||||
|
leaves = realloc (fcs->leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
||||||
|
if (!leaves)
|
||||||
|
return FcFalse;
|
||||||
|
fcs->leaves = leaves;
|
||||||
|
if (!fcs->numbers)
|
||||||
|
numbers = malloc (sizeof (FcChar16));
|
||||||
|
else
|
||||||
|
numbers = realloc (fcs->numbers, (fcs->num + 1) * sizeof (FcChar16));
|
||||||
|
if (!numbers)
|
||||||
|
return FcFalse;
|
||||||
|
fcs->numbers = numbers;
|
||||||
|
|
||||||
|
memmove (fcs->leaves + pos + 1, fcs->leaves + pos,
|
||||||
|
(fcs->num - pos) * sizeof (FcCharLeaf *));
|
||||||
|
memmove (fcs->numbers + pos + 1, fcs->numbers + pos,
|
||||||
|
(fcs->num - pos) * sizeof (FcChar16));
|
||||||
|
fcs->numbers[pos] = (FcChar16) ucs4;
|
||||||
|
fcs->leaves[pos] = leaf;
|
||||||
|
fcs->num++;
|
||||||
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,54 +170,41 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
static FcCharLeaf *
|
static FcCharLeaf *
|
||||||
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4)
|
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4)
|
||||||
{
|
{
|
||||||
int l;
|
int pos;
|
||||||
FcCharNode *prev, node;
|
FcCharLeaf *leaf;
|
||||||
FcChar32 i = 0;
|
|
||||||
int j;
|
|
||||||
FcChar8 *next = 0, old;
|
|
||||||
|
|
||||||
if (!FcCharSetCheckLevel (fcs, ucs4))
|
pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||||
return FcFalse;
|
if (pos >= 0)
|
||||||
prev = &fcs->node;
|
return fcs->leaves[pos];
|
||||||
l = fcs->levels;
|
|
||||||
while (--l > 0)
|
leaf = calloc (1, sizeof (FcCharLeaf));
|
||||||
|
if (!leaf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pos = -pos - 1;
|
||||||
|
if (!FcCharSetPutLeaf (fcs, ucs4, leaf, pos))
|
||||||
{
|
{
|
||||||
node = *prev;
|
free (leaf);
|
||||||
if (!node.branch)
|
return 0;
|
||||||
{
|
|
||||||
node.branch = calloc (1, sizeof (FcCharBranch));
|
|
||||||
if (!node.branch)
|
|
||||||
return 0;
|
|
||||||
FcMemAlloc (FC_MEM_CHARNODE, sizeof (FcCharBranch));
|
|
||||||
*prev = node;
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
old = next[i];
|
|
||||||
for (j = (int) i - 1; j >= 0 && next[j] == old; j--)
|
|
||||||
next[j] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = (ucs4 >> (l << 3)) & 0xff;
|
|
||||||
prev = &node.branch->nodes[i];
|
|
||||||
next = &node.branch->next[0];
|
|
||||||
}
|
}
|
||||||
node = *prev;
|
return leaf;
|
||||||
if (!node.leaf)
|
}
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||||
|
if (pos >= 0)
|
||||||
{
|
{
|
||||||
node.leaf = calloc (1, sizeof (FcCharLeaf));
|
|
||||||
if (!node.leaf)
|
|
||||||
return 0;
|
|
||||||
FcMemAlloc (FC_MEM_CHARNODE, sizeof (FcCharLeaf));
|
FcMemAlloc (FC_MEM_CHARNODE, sizeof (FcCharLeaf));
|
||||||
*prev = node;
|
free (fcs->leaves[pos]);
|
||||||
ucs4 = ucs4 & ~0xff;
|
fcs->leaves[pos] = leaf;
|
||||||
if (next)
|
return FcTrue;
|
||||||
{
|
|
||||||
old = next[i];
|
|
||||||
for (j = i - 1; j >= 0 && next[j] == old; j--)
|
|
||||||
next[j] = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return node.leaf;
|
pos = -pos - 1;
|
||||||
|
return FcCharSetPutLeaf (fcs, ucs4, leaf, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -241,179 +230,66 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4)
|
||||||
typedef struct _fcCharSetIter {
|
typedef struct _fcCharSetIter {
|
||||||
FcCharLeaf *leaf;
|
FcCharLeaf *leaf;
|
||||||
FcChar32 ucs4;
|
FcChar32 ucs4;
|
||||||
FcCharBranch *branch_stack[5];
|
int pos;
|
||||||
int branch_stackp;
|
|
||||||
} FcCharSetIter;
|
} FcCharSetIter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the nearest leaf at or beyond *ucs4, return 0 if no leaf
|
* Set iter->leaf to the leaf containing iter->ucs4 or higher
|
||||||
* exists
|
|
||||||
*/
|
*/
|
||||||
static FcCharLeaf *
|
|
||||||
FcCharSetIterLeaf (FcCharNode node, int level, FcChar32 *ucs4)
|
|
||||||
{
|
|
||||||
if (level <= 1)
|
|
||||||
return node.leaf;
|
|
||||||
else if (!node.branch)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int shift = ((level - 1) << 3);
|
|
||||||
FcChar32 inc = 1 << shift;
|
|
||||||
FcChar32 mask = ~(inc - 1);
|
|
||||||
FcChar32 byte = (*ucs4 >> shift) & 0xff;
|
|
||||||
FcCharLeaf *leaf;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
leaf = FcCharSetIterLeaf (node.branch->nodes[byte],
|
|
||||||
level - 1,
|
|
||||||
ucs4);
|
|
||||||
if (leaf)
|
|
||||||
break;
|
|
||||||
/* step to next branch, resetting lower indices */
|
|
||||||
*ucs4 = (*ucs4 & mask) + inc;
|
|
||||||
byte = (byte + 1) & 0xff;
|
|
||||||
if (byte == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return leaf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcCharSetIterSet (const FcCharSet *fcs, FcCharSetIter *iter)
|
FcCharSetIterSet (const FcCharSet *fcs, FcCharSetIter *iter)
|
||||||
{
|
{
|
||||||
int level = fcs->levels;
|
int pos = FcCharSetFindLeafPos (fcs, iter->ucs4);
|
||||||
FcChar32 ucs4 = iter->ucs4;
|
|
||||||
FcCharNode node = fcs->node;
|
|
||||||
|
|
||||||
iter->branch_stackp = 0;
|
if (pos < 0)
|
||||||
if (ucs4 >= 1 << (level << 3))
|
|
||||||
{
|
{
|
||||||
iter->leaf = 0;
|
pos = -pos - 1;
|
||||||
iter->ucs4 = ~0;
|
if (pos == fcs->num)
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (level > 1)
|
|
||||||
{
|
|
||||||
level--;
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
FcCharBranch *branch = node.branch;
|
iter->ucs4 = ~0;
|
||||||
FcChar32 byte;
|
iter->leaf = 0;
|
||||||
|
return;
|
||||||
byte = (ucs4 >> (level << 3)) & 0xff;
|
|
||||||
|
|
||||||
node = branch->nodes[byte];
|
|
||||||
if (!node.leaf)
|
|
||||||
{
|
|
||||||
while (!(byte = branch->next[byte]))
|
|
||||||
{
|
|
||||||
if (iter->branch_stackp == 0)
|
|
||||||
{
|
|
||||||
iter->leaf = 0;
|
|
||||||
iter->ucs4 = ~0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
branch = node.branch = iter->branch_stack[--iter->branch_stackp];
|
|
||||||
level++;
|
|
||||||
ucs4 += 1 << (level << 3);
|
|
||||||
byte = (ucs4 >> (level << 3)) & 0xff;
|
|
||||||
}
|
|
||||||
ucs4 = (ucs4 & ~ ((1 << ((level + 1) << 3)) - 1)) |
|
|
||||||
(byte << (level << 3));
|
|
||||||
node = branch->nodes[byte];
|
|
||||||
}
|
|
||||||
iter->branch_stack[iter->branch_stackp++] = branch;
|
|
||||||
if (--level == 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
|
||||||
}
|
}
|
||||||
if (!(iter->leaf = node.leaf))
|
iter->leaf = fcs->leaves[pos];
|
||||||
ucs4 = ~0;
|
iter->pos = pos;
|
||||||
iter->ucs4 = ucs4;
|
#ifdef CHATTY
|
||||||
#if 0
|
printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
|
||||||
printf ("set %08x: %08x\n", ucs4, node.leaf);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcCharSetIterNext (const FcCharSet *fcs, FcCharSetIter *iter)
|
FcCharSetIterNext (const FcCharSet *fcs, FcCharSetIter *iter)
|
||||||
{
|
{
|
||||||
FcCharNode node;
|
int pos = iter->pos + 1;
|
||||||
FcCharBranch *branch;
|
if (pos >= fcs->num)
|
||||||
FcChar32 ucs4;
|
|
||||||
int level;
|
|
||||||
|
|
||||||
if (!iter->branch_stackp)
|
|
||||||
{
|
{
|
||||||
iter->ucs4 = ~0;
|
iter->ucs4 = ~0;
|
||||||
iter->leaf = 0;
|
iter->leaf = 0;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
level = 1;
|
|
||||||
node.branch = iter->branch_stack[--iter->branch_stackp];
|
|
||||||
ucs4 = iter->ucs4;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FcChar32 byte;
|
|
||||||
|
|
||||||
branch = node.branch;
|
|
||||||
while (!(byte = branch->next[(ucs4 >> (level << 3)) & 0xff]))
|
|
||||||
{
|
|
||||||
if (iter->branch_stackp == 0)
|
|
||||||
{
|
|
||||||
iter->leaf = 0;
|
|
||||||
iter->ucs4 = ~0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
branch = node.branch = iter->branch_stack[--iter->branch_stackp];
|
|
||||||
level++;
|
|
||||||
ucs4 += 1 << (level << 3);
|
|
||||||
}
|
|
||||||
ucs4 = (ucs4 & ~ ((1 << ((level + 1) << 3)) - 1)) |
|
|
||||||
(byte << (level << 3));
|
|
||||||
node = branch->nodes[byte];
|
|
||||||
iter->branch_stack[iter->branch_stackp++] = branch;
|
|
||||||
if (--level == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
iter->ucs4 = ucs4;
|
|
||||||
iter->leaf = node.leaf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
|
||||||
FcCharSetDump (FcCharNode node, int level, FcChar32 ucs4, int indent)
|
|
||||||
{
|
|
||||||
if (level)
|
|
||||||
{
|
|
||||||
if (node.branch)
|
|
||||||
{
|
|
||||||
FcChar32 inc = (1 << (level << 3));
|
|
||||||
int i;
|
|
||||||
FcCharBranch *branch = node.branch;
|
|
||||||
|
|
||||||
for (i = 0; i < indent; i++)
|
|
||||||
printf (" ");
|
|
||||||
printf ("%08x: %08x\n", ucs4, branch);
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
FcCharSetDump (branch->nodes[i], level - 1, ucs4, indent+1);
|
|
||||||
ucs4 += inc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (node.leaf)
|
iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
|
||||||
{
|
iter->leaf = fcs->leaves[pos];
|
||||||
while (indent--)
|
iter->pos = pos;
|
||||||
printf (" ");
|
}
|
||||||
printf ("%08x: %08x\n", ucs4, node.leaf);
|
}
|
||||||
}
|
|
||||||
|
#ifdef CHATTY
|
||||||
|
static void
|
||||||
|
FcCharSetDump (const FcCharSet *fcs)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
printf ("fcs %08x:\n", (FcChar32) fcs);
|
||||||
|
for (pos = 0; pos < fcs->num; pos++)
|
||||||
|
{
|
||||||
|
FcCharLeaf *leaf = fcs->leaves[pos];
|
||||||
|
FcChar32 ucs4 = (FcChar32) fcs->numbers[pos] << 8;
|
||||||
|
|
||||||
|
printf (" %08x: %08x\n", ucs4, (FcChar32) leaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -421,8 +297,8 @@ FcCharSetDump (FcCharNode node, int level, FcChar32 ucs4, int indent)
|
||||||
static void
|
static void
|
||||||
FcCharSetIterStart (const FcCharSet *fcs, FcCharSetIter *iter)
|
FcCharSetIterStart (const FcCharSet *fcs, FcCharSetIter *iter)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef CHATTY
|
||||||
FcCharSetDump (fcs->node, fcs->levels - 1, 0, 0);
|
FcCharSetDump (fcs);
|
||||||
#endif
|
#endif
|
||||||
iter->ucs4 = 0;
|
iter->ucs4 = 0;
|
||||||
FcCharSetIterSet (fcs, iter);
|
FcCharSetIterSet (fcs, iter);
|
||||||
|
@ -697,93 +573,61 @@ FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FcCharBranch *ab, *bb;
|
|
||||||
FcChar32 byte;
|
|
||||||
} FcCharSetPairStack;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return FcTrue iff a is a subset of b
|
* return FcTrue iff a is a subset of b
|
||||||
*/
|
*/
|
||||||
FcBool
|
FcBool
|
||||||
FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
||||||
{
|
{
|
||||||
FcCharSetPairStack stack[5], *stackp;
|
int ai, bi;
|
||||||
FcChar32 byte;
|
FcChar16 an, bn;
|
||||||
FcCharBranch *ab, *bb;
|
|
||||||
int level;
|
if (a == b) return FcTrue;
|
||||||
FcCharNode an, bn;
|
bi = 0;
|
||||||
|
ai = 0;
|
||||||
if (a->levels > b->levels)
|
while (ai < a->num && bi < b->num)
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
level = b->levels;
|
|
||||||
an = a->node;
|
|
||||||
bn = b->node;
|
|
||||||
while (level != a->levels)
|
|
||||||
{
|
{
|
||||||
bn = bn.branch->nodes[0];
|
an = a->numbers[ai];
|
||||||
level--;
|
bn = b->numbers[bi];
|
||||||
}
|
if (an == bn)
|
||||||
|
|
||||||
if (level == 0)
|
|
||||||
;
|
|
||||||
if (level == 1)
|
|
||||||
{
|
|
||||||
FcChar32 *am = an.leaf->map;
|
|
||||||
FcChar32 *bm = bn.leaf->map;
|
|
||||||
int i = 256/32;
|
|
||||||
|
|
||||||
while (i--)
|
|
||||||
if (*am++ & ~*bm++)
|
|
||||||
return FcFalse;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
byte = 0;
|
|
||||||
stackp = stack;
|
|
||||||
ab = an.branch;
|
|
||||||
bb = bn.branch;
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
an = ab->nodes[byte];
|
FcChar32 *am = a->leaves[ai]->map;
|
||||||
if (an.branch)
|
FcChar32 *bm = b->leaves[bi]->map;
|
||||||
|
|
||||||
|
if (am != bm)
|
||||||
{
|
{
|
||||||
bn = bb->nodes[byte];
|
int i = 256/32;
|
||||||
if (!bn.branch)
|
while (i--)
|
||||||
return FcFalse;
|
if (*am++ & ~*bm++)
|
||||||
if (level == 2)
|
return FcFalse;
|
||||||
{
|
}
|
||||||
FcChar32 *am = an.leaf->map;
|
ai++;
|
||||||
FcChar32 *bm = bn.leaf->map;
|
bi++;
|
||||||
int i = 256/32;
|
}
|
||||||
|
else if (an < bn)
|
||||||
|
return FcFalse;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int low = bi + 1;
|
||||||
|
int high = b->num - 1;
|
||||||
|
|
||||||
while (i--)
|
while (low <= high)
|
||||||
if (*am++ & ~*bm++)
|
|
||||||
return FcFalse;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
level--;
|
|
||||||
stackp->ab = ab;
|
|
||||||
stackp->bb = bb;
|
|
||||||
stackp->byte = byte;
|
|
||||||
stackp++;
|
|
||||||
byte = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
byte = ab->next[byte];
|
|
||||||
if (!byte)
|
|
||||||
{
|
{
|
||||||
if (stackp == stack)
|
int mid = (low + high) >> 1;
|
||||||
|
bn = b->numbers[mid];
|
||||||
|
if (bn == an)
|
||||||
|
{
|
||||||
|
high = mid;
|
||||||
break;
|
break;
|
||||||
level++;
|
}
|
||||||
--stackp;
|
if (bn < an)
|
||||||
ab = stackp->ab;
|
low = mid + 1;
|
||||||
bb = stackp->bb;
|
else
|
||||||
byte = stackp->byte;
|
high = mid - 1;
|
||||||
}
|
}
|
||||||
|
bi = high;
|
||||||
|
while (bi < b->num && b->numbers[bi] < an)
|
||||||
|
bi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
@ -830,6 +674,33 @@ FcCharSetFirstPage (const FcCharSet *a,
|
||||||
return FcCharSetNextPage (a, map, next);
|
return FcCharSetNextPage (a, map, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* old coverage API, rather hard to use correctly
|
||||||
|
*/
|
||||||
|
FcChar32
|
||||||
|
FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
|
||||||
|
|
||||||
|
FcChar32
|
||||||
|
FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result)
|
||||||
|
{
|
||||||
|
FcCharSetIter ai;
|
||||||
|
|
||||||
|
ai.ucs4 = page;
|
||||||
|
FcCharSetIterSet (a, &ai);
|
||||||
|
if (!ai.leaf)
|
||||||
|
{
|
||||||
|
memset (result, '\0', 256 / 8);
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy (result, ai.leaf->map, sizeof (ai.leaf->map));
|
||||||
|
FcCharSetIterNext (a, &ai);
|
||||||
|
page = ai.ucs4;
|
||||||
|
}
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ASCII representation of charsets.
|
* ASCII representation of charsets.
|
||||||
*
|
*
|
||||||
|
@ -943,12 +814,159 @@ FcCharSetUnparseValue (FcStrBuf *buf, FcChar32 value)
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _FcCharLeafEnt FcCharLeafEnt;
|
||||||
|
|
||||||
|
struct _FcCharLeafEnt {
|
||||||
|
FcCharLeafEnt *next;
|
||||||
|
FcChar32 hash;
|
||||||
|
FcCharLeaf leaf;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FC_CHAR_LEAF_BLOCK (4096 / sizeof (FcCharLeafEnt))
|
||||||
|
|
||||||
|
static FcCharLeafEnt *
|
||||||
|
FcCharLeafEntCreate (void)
|
||||||
|
{
|
||||||
|
static FcCharLeafEnt *block;
|
||||||
|
static int remain;
|
||||||
|
|
||||||
|
if (!remain)
|
||||||
|
{
|
||||||
|
block = malloc (FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt));
|
||||||
|
if (!block)
|
||||||
|
return 0;
|
||||||
|
remain = FC_CHAR_LEAF_BLOCK;
|
||||||
|
}
|
||||||
|
remain--;
|
||||||
|
return block++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FC_CHAR_LEAF_HASH_SIZE 257
|
||||||
|
|
||||||
|
static FcChar32
|
||||||
|
FcCharLeafHash (FcCharLeaf *leaf)
|
||||||
|
{
|
||||||
|
FcChar32 hash = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 256/32; i++)
|
||||||
|
hash = ((hash << 1) | (hash >> 31)) ^ leaf->map[i];
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FcCharLeafTotal;
|
||||||
|
static int FcCharLeafUsed;
|
||||||
|
|
||||||
|
static FcCharLeaf *
|
||||||
|
FcNameParseBuildLeaf (FcCharLeaf *leaf)
|
||||||
|
{
|
||||||
|
static FcCharLeafEnt *hashTable[FC_CHAR_LEAF_HASH_SIZE];
|
||||||
|
FcChar32 hash = FcCharLeafHash (leaf);
|
||||||
|
FcCharLeafEnt **bucket = &hashTable[hash % FC_CHAR_LEAF_HASH_SIZE];
|
||||||
|
FcCharLeafEnt *ent;
|
||||||
|
|
||||||
|
FcCharLeafTotal++;
|
||||||
|
for (ent = *bucket; ent; ent = ent->next)
|
||||||
|
{
|
||||||
|
if (ent->hash == hash && !memcmp (&ent->leaf, leaf, sizeof (FcCharLeaf)))
|
||||||
|
return &ent->leaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ent = FcCharLeafEntCreate();
|
||||||
|
if (!ent)
|
||||||
|
return 0;
|
||||||
|
FcCharLeafUsed++;
|
||||||
|
ent->leaf = *leaf;
|
||||||
|
ent->hash = hash;
|
||||||
|
ent->next = *bucket;
|
||||||
|
*bucket = ent;
|
||||||
|
return &ent->leaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _FcCharSetEnt FcCharSetEnt;
|
||||||
|
|
||||||
|
struct _FcCharSetEnt {
|
||||||
|
FcCharSetEnt *next;
|
||||||
|
FcChar32 hash;
|
||||||
|
FcCharSet set;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FC_CHAR_SET_HASH_SIZE 67
|
||||||
|
|
||||||
|
static FcChar32
|
||||||
|
FcCharSetHash (FcCharSet *fcs)
|
||||||
|
{
|
||||||
|
FcChar32 hash = 0;
|
||||||
|
FcChar32 *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* hash in leaves */
|
||||||
|
p = (FcChar32 *) fcs->leaves;
|
||||||
|
for (i = 0; i < fcs->num * sizeof (FcCharLeaf *) / sizeof (FcChar32); i++)
|
||||||
|
hash = ((hash << 1) | (hash >> 31)) ^ *p++;
|
||||||
|
/* hash in numbers */
|
||||||
|
for (i = 0; i < fcs->num; i++)
|
||||||
|
hash = ((hash << 1) | (hash >> 31)) ^ fcs->numbers[i];
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FcCharSetTotal;
|
||||||
|
static int FcCharSetUsed;
|
||||||
|
static int FcCharSetTotalEnts, FcCharSetUsedEnts;
|
||||||
|
|
||||||
|
static FcCharSet *
|
||||||
|
FcNameParseBuildSet (FcCharSet *fcs)
|
||||||
|
{
|
||||||
|
static FcCharSetEnt *hashTable[FC_CHAR_SET_HASH_SIZE];
|
||||||
|
FcChar32 hash = FcCharSetHash (fcs);
|
||||||
|
FcCharSetEnt **bucket = &hashTable[hash % FC_CHAR_SET_HASH_SIZE];
|
||||||
|
FcCharSetEnt *ent;
|
||||||
|
|
||||||
|
FcCharSetTotal++;
|
||||||
|
FcCharSetTotalEnts += fcs->num;
|
||||||
|
for (ent = *bucket; ent; ent = ent->next)
|
||||||
|
{
|
||||||
|
if (ent->hash == hash &&
|
||||||
|
ent->set.num == fcs->num &&
|
||||||
|
!memcmp (ent->set.leaves, fcs->leaves,
|
||||||
|
fcs->num * sizeof (FcCharLeaf *)) &&
|
||||||
|
!memcmp (ent->set.numbers, fcs->numbers,
|
||||||
|
fcs->num * sizeof (FcChar16)))
|
||||||
|
{
|
||||||
|
return &ent->set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ent = malloc (sizeof (FcCharSetEnt) +
|
||||||
|
fcs->num * sizeof (FcCharLeaf *) +
|
||||||
|
fcs->num * sizeof (FcChar16));
|
||||||
|
if (!ent)
|
||||||
|
return 0;
|
||||||
|
FcCharSetUsed++;
|
||||||
|
FcCharSetUsedEnts += fcs->num;
|
||||||
|
|
||||||
|
ent->set.ref = 0;
|
||||||
|
ent->set.constant = FcTrue;
|
||||||
|
ent->set.num = fcs->num;
|
||||||
|
ent->set.leaves = (FcCharLeaf **) (ent + 1);
|
||||||
|
ent->set.numbers = (FcChar16 *) (ent->set.leaves + fcs->num);
|
||||||
|
memcpy (ent->set.leaves, fcs->leaves, fcs->num * sizeof (FcCharLeaf *));
|
||||||
|
memcpy (ent->set.numbers, fcs->numbers, fcs->num * sizeof (FcChar16));
|
||||||
|
|
||||||
|
ent->hash = hash;
|
||||||
|
ent->next = *bucket;
|
||||||
|
*bucket = ent;
|
||||||
|
return &ent->set;
|
||||||
|
}
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcNameParseCharSet (FcChar8 *string)
|
FcNameParseCharSet (FcChar8 *string)
|
||||||
{
|
{
|
||||||
FcCharSet *c;
|
FcCharSet *c, *n = 0;
|
||||||
FcChar32 ucs4;
|
FcChar32 ucs4;
|
||||||
FcCharLeaf *leaf;
|
FcCharLeaf *leaf;
|
||||||
|
FcCharLeaf temp;
|
||||||
|
FcChar32 bits;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
c = FcCharSetCreate ();
|
c = FcCharSetCreate ();
|
||||||
|
@ -959,21 +977,53 @@ FcNameParseCharSet (FcChar8 *string)
|
||||||
string = FcCharSetParseValue (string, &ucs4);
|
string = FcCharSetParseValue (string, &ucs4);
|
||||||
if (!string)
|
if (!string)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
leaf = FcCharSetFindLeafCreate (c, ucs4);
|
bits = 0;
|
||||||
if (!leaf)
|
|
||||||
goto bail1;
|
|
||||||
for (i = 0; i < 256/32; i++)
|
for (i = 0; i < 256/32; i++)
|
||||||
{
|
{
|
||||||
string = FcCharSetParseValue (string, &leaf->map[i]);
|
string = FcCharSetParseValue (string, &temp.map[i]);
|
||||||
if (!string)
|
if (!string)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
bits |= temp.map[i];
|
||||||
|
}
|
||||||
|
if (bits)
|
||||||
|
{
|
||||||
|
leaf = FcNameParseBuildLeaf (&temp);
|
||||||
|
if (!leaf)
|
||||||
|
goto bail1;
|
||||||
|
if (!FcCharSetInsertLeaf (c, ucs4, leaf))
|
||||||
|
goto bail1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c;
|
#ifdef CHATTY
|
||||||
|
printf (" %8s %8s %8s %8s\n", "total", "totalmem", "new", "newmem");
|
||||||
|
printf ("Leaves: %8d %8d %8d %8d\n",
|
||||||
|
FcCharLeafTotal, sizeof (FcCharLeaf) * FcCharLeafTotal,
|
||||||
|
FcCharLeafUsed, sizeof (FcCharLeaf) * FcCharLeafUsed);
|
||||||
|
printf ("Charsets: %8d %8d %8d %8d\n",
|
||||||
|
FcCharSetTotal, sizeof (FcCharSet) * FcCharSetTotal,
|
||||||
|
FcCharSetUsed, sizeof (FcCharSet) * FcCharSetUsed);
|
||||||
|
printf ("Tables: %8d %8d %8d %8d\n",
|
||||||
|
FcCharSetTotalEnts, FcCharSetTotalEnts * (sizeof (FcCharLeaf *) + sizeof (FcChar16)),
|
||||||
|
FcCharSetUsedEnts, FcCharSetUsedEnts * (sizeof (FcCharLeaf *) + sizeof (FcChar16)));
|
||||||
|
printf ("Total: %8s %8d %8s %8d\n",
|
||||||
|
"",
|
||||||
|
sizeof (FcCharLeaf) * FcCharLeafTotal +
|
||||||
|
sizeof (FcCharSet) * FcCharSetTotal +
|
||||||
|
FcCharSetTotalEnts * (sizeof (FcCharLeaf *) + sizeof (FcChar16)),
|
||||||
|
"",
|
||||||
|
sizeof (FcCharLeaf) * FcCharLeafUsed +
|
||||||
|
sizeof (FcCharSet) * FcCharSetUsed +
|
||||||
|
FcCharSetUsedEnts * (sizeof (FcCharLeaf *) + sizeof (FcChar16)));
|
||||||
|
#endif
|
||||||
|
n = FcNameParseBuildSet (c);
|
||||||
bail1:
|
bail1:
|
||||||
FcCharSetDestroy (c);
|
if (c->leaves)
|
||||||
|
free (c->leaves);
|
||||||
|
if (c->numbers)
|
||||||
|
free (c->numbers);
|
||||||
|
free (c);
|
||||||
bail0:
|
bail0:
|
||||||
return 0;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
|
27
src/fcint.h
27
src/fcint.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $XFree86: xc/lib/fontconfig/src/fcint.h,v 1.8 2002/05/21 17:06:22 keithp Exp $
|
* $XFree86: xc/lib/fontconfig/src/fcint.h,v 1.10 2002/05/29 22:07:33 keithp Exp $
|
||||||
*
|
*
|
||||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||||
*
|
*
|
||||||
|
@ -157,29 +157,16 @@ typedef struct _FcSubst {
|
||||||
FcEdit *edit;
|
FcEdit *edit;
|
||||||
} FcSubst;
|
} FcSubst;
|
||||||
|
|
||||||
typedef struct _FcCharLeaf FcCharLeaf;
|
typedef struct _FcCharLeaf {
|
||||||
typedef struct _FcCharBranch FcCharBranch;
|
|
||||||
typedef union _FcCharNode FcCharNode;
|
|
||||||
|
|
||||||
struct _FcCharLeaf {
|
|
||||||
FcChar32 map[256/32];
|
FcChar32 map[256/32];
|
||||||
};
|
} FcCharLeaf;
|
||||||
|
|
||||||
union _FcCharNode {
|
|
||||||
FcCharBranch *branch;
|
|
||||||
FcCharLeaf *leaf;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _FcCharBranch {
|
|
||||||
FcCharNode nodes[256];
|
|
||||||
FcChar8 next[256];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _FcCharSet {
|
struct _FcCharSet {
|
||||||
int levels;
|
|
||||||
int ref; /* reference count */
|
int ref; /* reference count */
|
||||||
FcBool constant; /* shared constant */
|
FcBool constant; /* in hash table constant */
|
||||||
FcCharNode node;
|
int num; /* size of leaves and numbers arrays */
|
||||||
|
FcCharLeaf **leaves;
|
||||||
|
FcChar16 *numbers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FcStrSet {
|
struct _FcStrSet {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.6 2002/05/29 08:21:33 keithp Exp $
|
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.7 2002/05/29 22:07:33 keithp Exp $
|
||||||
*
|
*
|
||||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||||
*
|
*
|
||||||
|
@ -613,3 +613,27 @@ bail1:
|
||||||
bail0:
|
bail0:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcFontSet *
|
||||||
|
FcFontSort (FcConfig *config,
|
||||||
|
FcPattern *p,
|
||||||
|
FcBool trim,
|
||||||
|
FcCharSet **csp,
|
||||||
|
FcResult *result)
|
||||||
|
{
|
||||||
|
FcFontSet *sets[2];
|
||||||
|
int nsets;
|
||||||
|
|
||||||
|
if (!config)
|
||||||
|
{
|
||||||
|
config = FcConfigGetCurrent ();
|
||||||
|
if (!config)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nsets = 0;
|
||||||
|
if (config->fonts[FcSetSystem])
|
||||||
|
sets[nsets++] = config->fonts[FcSetSystem];
|
||||||
|
if (config->fonts[FcSetApplication])
|
||||||
|
sets[nsets++] = config->fonts[FcSetApplication];
|
||||||
|
return FcFontSetSort (config, sets, nsets, p, trim, csp, result);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue