diff options
-rw-r--r-- | fc-arch/fcarch.tmpl.h | 3 | ||||
-rw-r--r-- | fc-lang/fc-lang.c | 185 | ||||
-rw-r--r-- | fontconfig/fontconfig.h | 3 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/fccache.c | 581 | ||||
-rw-r--r-- | src/fccfg.c | 102 | ||||
-rw-r--r-- | src/fccharset.c | 493 | ||||
-rw-r--r-- | src/fcdbg.c | 43 | ||||
-rw-r--r-- | src/fcdefault.c | 64 | ||||
-rw-r--r-- | src/fcfs.c | 133 | ||||
-rw-r--r-- | src/fcint.h | 477 | ||||
-rw-r--r-- | src/fclang.c | 120 | ||||
-rw-r--r-- | src/fclist.c | 86 | ||||
-rw-r--r-- | src/fcmatch.c | 179 | ||||
-rw-r--r-- | src/fcname.c | 142 | ||||
-rw-r--r-- | src/fcpat.c | 1025 | ||||
-rw-r--r-- | src/fcstr.c | 1 | ||||
-rw-r--r-- | src/fcxml.c | 15 |
18 files changed, 1394 insertions, 2259 deletions
diff --git a/fc-arch/fcarch.tmpl.h b/fc-arch/fcarch.tmpl.h index 6e89ad9..4cf483f 100644 --- a/fc-arch/fcarch.tmpl.h +++ b/fc-arch/fcarch.tmpl.h @@ -31,4 +31,5 @@ @@@ name endian char char* int Pattern EltPtr Elt * Elt ObjPtr VLPtr Value Binding VL * CharSet Leaf** Char16 * Char16 Leaf Char32 Cache PageSize x86 78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000 x86-64 78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000 -ppc 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000 +ppc-4k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000 +ppc-64k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00010000 diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c index b72893b..631411d 100644 --- a/fc-lang/fc-lang.c +++ b/fc-lang/fc-lang.c @@ -37,10 +37,6 @@ * functions are also needed in slightly modified form */ -const FcChar16 langBankNumbers[1]; /* place holders so that externs resolve */ -const FcCharLeaf langBankLeaves[1]; -const int langBankLeafIdx[1]; - void FcMemAlloc (int kind, int size) { @@ -51,18 +47,6 @@ FcMemFree (int kind, int size) { } -int* _fcBankId = 0; -int* _fcBankIdx = 0; -FcValueList ** _fcValueLists = 0; -FcPatternElt ** _fcPatternElts = 0; -int FcDebugVal = 0; - -int -FcCacheBankToIndexMTF (int bank) -{ - return -1; -} - FcChar8 * FcConfigHome (void) { @@ -239,19 +223,18 @@ main (int argc, char **argv) static char *files[MAX_LANG]; static FcCharSet *sets[MAX_LANG]; static int duplicate[MAX_LANG]; - static int offsets[MAX_LANG]; static int country[MAX_LANG]; static char *names[MAX_LANG]; static char *langs[MAX_LANG]; + static int off[MAX_LANG]; FILE *f; - int offset = 0; int ncountry = 0; int i = 0; + int nsets = 0; int argi; FcCharLeaf **leaves; int total_leaves = 0; - int offset_count = 0; - int l, sl, tl; + int l, sl, tl, tn; static char line[1024]; static FcChar32 map[MAX_LANG_SET_MAP]; int num_lang_set_map; @@ -290,6 +273,7 @@ main (int argc, char **argv) i++; fclose (f); } + nsets = i; sets[i] = 0; leaves = malloc (total_leaves * sizeof (FcCharLeaf *)); tl = 0; @@ -301,10 +285,10 @@ main (int argc, char **argv) for (sl = 0; sl < sets[i]->num; sl++) { for (l = 0; l < tl; l++) - if (leaves[l] == FcCharSetGetLeaf(sets[i], sl)) + if (leaves[l] == FcCharSetLeaf(sets[i], sl)) break; if (l == tl) - leaves[tl++] = FcCharSetGetLeaf(sets[i], sl); + leaves[tl++] = FcCharSetLeaf(sets[i], sl); } } @@ -321,22 +305,6 @@ main (int argc, char **argv) printf ("/* total size: %d unique leaves: %d */\n\n", total_leaves, tl); - /* - * Dump leaves - */ - printf ("const FcCharLeaf langBankLeaves[%d] = {\n", tl); - for (l = 0; l < tl; l++) - { - printf (" { { /* %d */", l); - for (i = 0; i < 256/32; i++) - { - if (i % 4 == 0) - printf ("\n "); - printf (" 0x%08x,", leaves[l]->map[i]); - } - printf ("\n } },\n"); - } - printf ("};\n\n"); /* * Find duplicate charsets @@ -355,111 +323,121 @@ main (int argc, char **argv) } } + tn = 0; + for (i = 0; sets[i]; i++) { + if (duplicate[i] >= 0) + continue; + off[i] = tn; + tn += sets[i]->num; + } + + printf ("#define LEAF0 (%d * sizeof (FcLangCharSet))\n", nsets); + printf ("#define OFF0 (LEAF0 + %d * sizeof (FcCharLeaf))\n", tl); + printf ("#define NUM0 (OFF0 + %d * sizeof (intptr_t))\n", tn); + printf ("#define SET(n) (n * sizeof (FcLangCharSet) + offsetof (FcLangCharSet, charset))\n"); + printf ("#define OFF(s,o) (OFF0 + o * sizeof (intptr_t) - SET(s))\n"); + printf ("#define NUM(s,n) (NUM0 + n * sizeof (FcChar16) - SET(s))\n"); + printf ("#define LEAF(o,l) (LEAF0 + l * sizeof (FcCharLeaf) - (OFF0 + o * sizeof (intptr_t)))\n"); + printf ("#define fcLangCharSets (fcLangData.langCharSets)\n"); + printf ("\n"); + + printf ("static const struct {\n" + " FcLangCharSet langCharSets[%d];\n" + " FcCharLeaf leaves[%d];\n" + " intptr_t leaf_offsets[%d];\n" + " FcChar16 numbers[%d];\n" + "} fcLangData = {\n", + nsets, tl, tn, tn); + /* - * Find ranges for each letter for faster searching + * Dump sets */ - setRangeChar = 'a'; + + printf ("{\n"); for (i = 0; sets[i]; i++) { - char c = names[i][0]; - - while (setRangeChar <= c && c <= 'z') - setRangeStart[setRangeChar++ - 'a'] = i; + int j = duplicate[i]; + + if (j < 0) + j = i; + + printf (" { (FcChar8 *) \"%s\", " + " { FC_REF_CONSTANT, %d, OFF(%d,%d), NUM(%d,%d) } }, /* %d */\n", + langs[i], + sets[j]->num, i, off[j], i, off[j], i); } - for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++) - setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1; - setRangeEnd[setRangeChar - 'a'] = i - 1; + printf ("},\n"); /* - * Dump arrays + * Dump leaves */ - for (i = 0; sets[i]; i++) + printf ("{\n"); + for (l = 0; l < tl; l++) { - int n; - - if (duplicate[i] >= 0) - continue; - - for (n = 0; n < sets[i]->num; n++) + printf (" { { /* %d */", l); + for (i = 0; i < 256/32; i++) { - for (l = 0; l < tl; l++) - if (leaves[l] == FcCharSetGetLeaf(sets[i], n)) - break; - if (l == tl) - fatal (names[i], 0, "can't find leaf"); - offset_count++; + if (i % 4 == 0) + printf ("\n "); + printf (" 0x%08x,", leaves[l]->map[i]); } - offsets[i] = offset; - offset += sets[i]->num; + printf ("\n } },\n"); } + printf ("},\n"); - printf ("const int langBankLeafIdx[%d] = {\n", - offset_count); + /* + * Dump leaves + */ + printf ("{\n"); for (i = 0; sets[i]; i++) { int n; if (duplicate[i] >= 0) continue; + printf (" /* %s */\n", names[i]); for (n = 0; n < sets[i]->num; n++) { - if (n % 8 == 0) + if (n % 4 == 0) printf (" "); for (l = 0; l < tl; l++) - if (leaves[l] == FcCharSetGetLeaf(sets[i], n)) + if (leaves[l] == FcCharSetLeaf(sets[i], n)) break; if (l == tl) fatal (names[i], 0, "can't find leaf"); - printf (" %3d,", l); - if (n % 8 == 7) + printf (" LEAF(%3d,%3d),", off[i], l); + if (n % 4 == 3) printf ("\n"); } - if (n % 8 != 0) + if (n % 4 != 0) printf ("\n"); } - printf ("};\n\n"); - - printf ("const FcChar16 langBankNumbers[%d] = {\n", - offset_count); + printf ("},\n"); + + printf ("{\n"); for (i = 0; sets[i]; i++) { int n; - + if (duplicate[i] >= 0) continue; + printf (" /* %s */\n", names[i]); for (n = 0; n < sets[i]->num; n++) { if (n % 8 == 0) printf (" "); - printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]); + printf (" 0x%04x,", FcCharSetNumbers (sets[i])[n]); if (n % 8 == 7) printf ("\n"); } if (n % 8 != 0) printf ("\n"); } - printf ("};\n\n"); + printf ("}\n"); - /* - * Dump sets - */ - - printf ("const FcLangCharSet fcLangCharSets[] = {\n"); - for (i = 0; sets[i]; i++) - { - int j = duplicate[i]; - - if (j < 0) - j = i; - - printf (" { (FcChar8 *) \"%s\",\n" - " { FC_REF_CONSTANT, %d, FC_BANK_LANGS, " - "{ { %d, %d } } } }, /* %d */\n", - langs[i], - sets[j]->num, offsets[j], offsets[j], j); - } printf ("};\n\n"); + printf ("#define NUM_LANG_CHAR_SET %d\n", i); num_lang_set_map = (i + 31) / 32; printf ("#define NUM_LANG_SET_MAP %d\n", num_lang_set_map); @@ -507,6 +485,23 @@ main (int argc, char **argv) /* + * Find ranges for each letter for faster searching + */ + setRangeChar = 'a'; + memset(setRangeStart, '\0', sizeof (setRangeStart)); + memset(setRangeEnd, '\0', sizeof (setRangeEnd)); + for (i = 0; sets[i]; i++) + { + char c = names[i][0]; + + while (setRangeChar <= c && c <= 'z') + setRangeStart[setRangeChar++ - 'a'] = i; + } + for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++) + setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1; + setRangeEnd[setRangeChar - 'a'] = i - 1; + + /* * Dump sets start/finish for the fastpath */ printf ("static const FcLangCharSetRange fcLangCharSetRanges[] = {\n"); diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 8ef2f7c..410da1e 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -212,17 +212,14 @@ typedef struct _FcValue { FcType type; union { const FcChar8 *s; - int s_off; int i; FcBool b; double d; const FcMatrix *m; const FcCharSet *c; - int c_off; void *f; const FcPattern *p; const FcLangSet *l; - int l_off; /* this is a difference of char *s */ } u; } FcValue; diff --git a/src/Makefile.am b/src/Makefile.am index 5d144bc..586594c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,6 +95,7 @@ libfontconfig_la_SOURCES = \ fcmatrix.c \ fcname.c \ fcpat.c \ + fcserialize.c \ fcstr.c \ fcxml.c \ ftglue.h \ diff --git a/src/fccache.c b/src/fccache.c index a677253..c1c58fb 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -1,6 +1,4 @@ /* - * $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $ - * * Copyright © 2000 Keith Packard * Copyright © 2005 Patrick Lam * @@ -37,29 +35,12 @@ # include <windows.h> #endif -#define ENDIAN_TEST 0x12345678 -#define MACHINE_SIGNATURE_SIZE (9 + 5*20 + 1) -/* for when we don't have sysconf: */ -#define FC_HARDCODED_PAGESIZE 8192 - #ifndef O_BINARY #define O_BINARY 0 #endif -static FILE * -FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path); - -static void * -FcDirCacheProduce (FcFontSet *set, FcCache * metadata); - -static off_t -FcCacheNextOffset(off_t w); - -static FcBool -FcCacheHaveBank (int bank); - -static void -FcCacheAddBankDir (int bank, const char * dir); +static int +FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size); struct MD5Context { FcChar32 buf[4]; @@ -74,67 +55,17 @@ static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]); #define FC_DBG_CACHE_REF 1024 -static char * -FcCacheReadString (FILE *file, char *dest, int len) -{ - int c; - char *d = dest; - - if (len == 0) - return 0; - - while ((c = getc (file)) != EOF && len > 0) { - *d++ = c; - if (c == '\0') - return dest; - len--; - } - return 0; -} - -static FcBool -FcCacheWriteString (int fd, const char *chars) -{ - if (write (fd, chars, strlen(chars)+1) != strlen(chars)+1) - return FcFalse; - return FcTrue; -} - -/* - * Find the next presumably-mmapable offset after the supplied file - * position. - */ -static off_t -FcCacheNextOffset(off_t w) -{ - static long pagesize = -1; - - if (w == -1) - return w; - - if (pagesize == -1) -#if defined (HAVE_SYSCONF) - pagesize = sysconf(_SC_PAGESIZE); -#else - pagesize = FC_HARDCODED_PAGESIZE; -#endif - if (w % pagesize == 0) - return w; - else - return ((w / pagesize)+1)*pagesize; -} - /* Does not check that the cache has the appropriate arch section. */ FcBool FcDirCacheValid (const FcChar8 *dir, FcConfig *config) { - FILE *file; + int fd; - file = FcDirCacheOpen (config, dir, NULL); + fd = FcDirCacheOpen (config, dir, NULL); - if (file == NULL) + if (fd < 0) return FcFalse; - fclose (file); + close (fd); return FcTrue; } @@ -282,218 +213,281 @@ FcCacheRead (FcConfig *config) * This searches the list of cache dirs for the relevant cache file, * returning the first one found. */ -static FILE * -FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path) +static int +FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size) { - FILE *file = NULL; - FcChar8 *cache_hashed = NULL; + int fd = -1; FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir; struct stat file_stat, dir_stat; if (stat ((char *) dir, &dir_stat) < 0) - return NULL; + return -1; FcDirCacheBasename (dir, cache_base); list = FcStrListCreate (config->cacheDirs); if (!list) - return NULL; + return -1; while ((cache_dir = FcStrListNext (list))) { - cache_hashed = FcStrPlus (cache_dir, cache_base); + FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base); if (!cache_hashed) break; - file = fopen((char *) cache_hashed, "rb"); - if (file != NULL) { - if (fstat (fileno (file), &file_stat) >= 0 && + fd = open((char *) cache_hashed, O_RDONLY | O_BINARY); + FcStrFree (cache_hashed); + if (fd >= 0) { + if (fstat (fd, &file_stat) >= 0 && dir_stat.st_mtime <= file_stat.st_mtime) { + if (size) + *size = file_stat.st_size; break; } - fclose (file); - file = NULL; + close (fd); + fd = -1; } - FcStrFree (cache_hashed); - cache_hashed = NULL; } FcStrListDone (list); - - if (file == NULL) - return NULL; - if (cache_path) - *cache_path = cache_hashed; - else - FcStrFree (cache_hashed); + return fd; +} - return file; +#if 0 +static void +FcDirCacheUnmap (FcCache *cache) +{ + if (cache->magic == FC_CACHE_MAGIC_COPY) + { + free (cache); + return; + } +#if defined(HAVE_MMAP) || defined(__CYGWIN__) + munmap (cache, cache->size); +#elif defined(_WIN32) + UnmapViewOfFile (cache); +#endif } +#endif /* read serialized state from the cache file */ -FcBool -FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs, - const FcChar8 *dir, char *dirname) +static FcCache * +FcDirCacheMap (int fd, off_t size) { - FcCache metadata; - void *current_dir_block; - char subdir_name[FC_MAX_FILE_LEN + 1 + 12 + 1]; - int i; - - if (fread(&metadata, sizeof(FcCache), 1, file) != 1) - goto bail; - if (metadata.magic != FC_CACHE_MAGIC) - goto bail; - - /* skip directory name; it's just for fc-cat */ - if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name))) - goto bail; - - if (dirname) - strcpy (dirname, subdir_name); + FcCache *cache; + FcBool allocated = FcFalse; - for (i = 0; i < metadata.subdirs; i++) { - if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name))) - goto bail; - FcStrSetAdd (dirs, (FcChar8 *)subdir_name); - } - - if (metadata.count) - { - int fd = fileno (file); + if (size < sizeof (FcCache)) + return NULL; #if defined(HAVE_MMAP) || defined(__CYGWIN__) - current_dir_block = mmap (0, metadata.count, - PROT_READ, MAP_SHARED, fd, metadata.pos); - if (current_dir_block == MAP_FAILED) - goto bail; + cache = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0); #elif defined(_WIN32) - { - HANDLE hFileMap; - - hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL); - if (hFileMap == NULL) - goto bail; + { + HANDLE hFileMap; - current_dir_block = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, metadata.pos, metadata.count); - if (current_dir_block == NULL) - { - CloseHandle (hFileMap); - goto bail; - } + cache = NULL; + hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, + PAGE_READONLY, 0, 0, NULL); + if (hFileMap != NULL) + { + cache = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, size); + CloseHandle (hFileMap); } -#else - if (lseek (fd, metatdata.pos, SEEK_SET) == -1) - goto bail; - - current_dir_block = malloc (metadata.count); - if (!current_dir_block) - goto bail; + } +#endif + if (!cache) + { + cache = malloc (size); + if (!cache) + return NULL; - /* could also use CreateMappedViewOfFile under MinGW... */ - if (read (fd, current_dir_block, metadata.count) != metadata.count) + if (read (fd, cache, size) != size) { - free (current_dir_block); - goto bail; + free (cache); + return NULL; } + allocated = FcTrue; + } + if (cache->magic != FC_CACHE_MAGIC || + cache->size != size) + { + if (allocated) + free (cache); + else + { +#if defined(HAVE_MMAP) || defined(__CYGWIN__) + munmap (cache, size); +#elif defined(_WIN32) + UnmapViewOfFile (cache); #endif - FcCacheAddBankDir (metadata.bank, (char *) dir); - if (!FcFontSetUnserialize (&metadata, set, current_dir_block)) - goto bail; + } + return NULL; } - return FcTrue; - - bail: - return FcFalse; + /* Mark allocated caches so they're freed rather than unmapped */ + if (allocated) + cache->magic = FC_CACHE_MAGIC_COPY; + + return cache; } FcBool FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config) { - FILE *file; - - file = FcDirCacheOpen (config, dir, NULL); - if (file == NULL) - goto bail; + int fd; + FcCache *cache; + off_t size; + int i; + FcFontSet *cache_set; + intptr_t *cache_dirs; + FcPattern **cache_fonts; - if (!FcDirCacheConsume (file, set, dirs, dir, NULL)) - goto bail1; + fd = FcDirCacheOpen (config, dir, &size); + if (fd < 0) + return FcFalse; + cache = FcDirCacheMap (fd, size); + + if (!cache) + { + if (FcDebug() & FC_DBG_CACHE) + printf ("FcDirCacheRead failed to map cache for %s\n", dir); + close (fd); + return FcFalse; + } + + cache_set = FcCacheSet (cache); + cache_fonts = FcFontSetFonts(cache_set); + if (FcDebug() & FC_DBG_CACHE) + printf ("FcDirCacheRead mapped cache for %s (%d fonts %d subdirs)\n", + dir, cache_set->nfont, cache->dirs_count); + for (i = 0; i < cache_set->nfont; i++) + { + FcPattern *font = FcEncodedOffsetToPtr (cache_set, + cache_fonts[i], + FcPattern); + if (FcDebug() & FC_DBG_CACHEV) { + printf ("Mapped font %d\n", i); + FcPatternPrint (font); + } + FcFontSetAdd (set, font); + } + + cache_dirs = FcCacheDirs (cache); + for (i = 0; i < cache->dirs_count; i++) + FcStrSetAdd (dirs, FcOffsetToPtr (cache_dirs, + cache_dirs[i], + FcChar8)); + if (config) FcConfigAddFontDir (config, (FcChar8 *)dir); - fclose (file); + close (fd); return FcTrue; - -bail1: - fclose (file); -bail: - return FcFalse; } +/* + * Cache file is: + * + * FcCache + * dir name + * subdirs + * FcFontSet + */ -static void * -FcDirCacheProduce (FcFontSet *set, FcCache *metadata) +static FcCache * +FcDirCacheProduce (FcFontSet *set, const FcChar8 *dir, FcStrSet *dirs) { - void * current_dir_block, * final_dir_block; - static unsigned int rand_state = 0; - int bank, needed_bytes_no_align; - -#if defined (HAVE_RAND_R) - if (!rand_state) - rand_state = time(0L); - bank = rand_r(&rand_state); + FcSerialize *serialize = FcSerializeCreate (); + FcCache *cache; + int i; + intptr_t cache_offset; + intptr_t dirs_offset; + FcChar8 *dir_serialize; + intptr_t *dirs_serialize; + FcFontSet *set_serialize; + + if (!serialize) + return NULL; + /* + * Space for cache structure + */ + cache_offset = FcSerializeReserve (serialize, sizeof (FcCache)); + /* + * Directory name + */ + if (!FcStrSerializeAlloc (serialize, dir)) + goto bail1; + /* + * Subdirs + */ + dirs_offset = FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *)); + for (i = 0; i < dirs->num; i++) + if (!FcStrSerializeAlloc (serialize, dirs->strs[i])) + goto bail1; - while (FcCacheHaveBank(bank)) - bank = rand_r(&rand_state); -#else - if (!rand_state) - { - rand_state = 1; - srand (time (0L)); - } - bank = rand(); + /* + * Patterns + */ + if (!FcFontSetSerializeAlloc (serialize, set)) + goto bail1; + + /* Serialize layout complete. Now allocate space and fill it */ + cache = malloc (serialize->size); + if (!cache) + goto bail1; + /* shut up valgrind */ + memset (cache, 0, serialize->size); - while (FcCacheHaveBank(bank)) - bank = rand(); -#endif + serialize->linear = cache; - memset (metadata, 0, sizeof(FcCache)); - FcFontSetNewBank(); - needed_bytes_no_align = FcFontSetNeededBytes (set); - metadata->count = needed_bytes_no_align + - FcFontSetNeededBytesAlign (); - metadata->magic = FC_CACHE_MAGIC; - metadata->bank = bank; + cache->magic = FC_CACHE_MAGIC; + cache->size = serialize->size; - if (!needed_bytes_no_align) /* not a failure, no fonts to write */ + /* + * Serialize directory name + */ + dir_serialize = FcStrSerialize (serialize, dir); + if (!dir_serialize) + goto bail2; + cache->dir = FcPtrToOffset (cache, dir_serialize); + + /* + * Serialize sub dirs + */ + dirs_serialize = FcSerializePtr (serialize, dirs); + if (!dirs_serialize) + goto bail2; + cache->dirs = FcPtrToOffset (cache, dirs_serialize); + cache->dirs_count = dirs->num; + for (i = 0; i < dirs->num; i++) { - /* no, you don't really need to write any bytes at all. */ - metadata->count = 0; - return 0; + FcChar8 *d_serialize = FcStrSerialize (serialize, dirs->strs[i]); + if (!d_serialize) + goto bail2; + dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize); } + + /* + * Serialize font set + */ + set_serialize = FcFontSetSerialize (serialize, set); + if (!set_serialize) + goto bail2; + cache->set = FcPtrToOffset (cache, set_serialize); - current_dir_block = malloc (metadata->count); - if (!current_dir_block) - goto bail; - /* shut up valgrind */ - memset (current_dir_block, 0, metadata->count); - final_dir_block = FcFontSetDistributeBytes (metadata, current_dir_block); - - if ((void *)((char *)current_dir_block+metadata->count) < final_dir_block) - goto bail; - - if (!FcFontSetSerialize (bank, set)) - goto bail; - - return current_dir_block; + FcSerializeDestroy (serialize); + + return cache; - bail: - free (current_dir_block); - return 0; +bail2: + free (cache); +bail1: + FcSerializeDestroy (serialize); + return NULL; } static FcBool @@ -524,14 +518,12 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c { FcChar8 cache_base[CACHEBASE_LEN]; FcChar8 *cache_hashed; - int fd, i; + int fd; FcAtomic *atomic; - FcCache metadata; - void *current_dir_block = 0; + FcCache *cache; FcStrList *list; FcChar8 *cache_dir = NULL; FcChar8 *test_dir; - off_t header_len; /* * Write it to the first directory in the list which is writable @@ -563,14 +555,15 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c FcStrListDone (list); if (!cache_dir) return FcFalse; + FcDirCacheBasename (dir, cache_base); cache_hashed = FcStrPlus (cache_dir, cache_base); if (!cache_hashed) return FcFalse; - current_dir_block = FcDirCacheProduce (set, &metadata); + cache = FcDirCacheProduce (set, dir, dirs); - if (metadata.count && !current_dir_block) + if (!cache) goto bail1; if (FcDebug () & FC_DBG_CACHE) @@ -579,54 +572,24 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c atomic = FcAtomicCreate ((FcChar8 *)cache_hashed); if (!atomic) - goto bail1; + goto bail2; if (!FcAtomicLock (atomic)) - goto bail2; + goto bail3; fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); if (fd == -1) - goto bail3; - - /* - * Compute file header length -- the FcCache followed by the subdir names - */ - header_len = sizeof (FcCache); - header_len += strlen ((char *) dir) + 1; - for (i = 0; i < dirs->size; i++) - header_len += strlen ((char *)dirs->strs[i]) + 1; + goto bail4; - metadata.pos = FcCacheNextOffset (lseek (fd, 0, SEEK_CUR) + header_len); - metadata.subdirs = dirs->size; - - /* - * Write out the header - */ - if (write (fd, &metadata, sizeof(FcCache)) != sizeof(FcCache)) + if (write (fd, cache, cache->size) != cache->size) { - perror("write metadata"); + perror ("write cache"); goto bail5; } - - FcCacheWriteString (fd, (char *) dir); - - for (i = 0; i < dirs->size; i++) - FcCacheWriteString (fd, (char *)dirs->strs[i]); - - if (metadata.count) - { - if (lseek (fd, metadata.pos, SEEK_SET) != metadata.pos) - perror("lseek"); - else if (write (fd, current_dir_block, metadata.count) != - metadata.count) - perror("write current_dir_block"); - free (current_dir_block); - current_dir_block = 0; - } close(fd); if (!FcAtomicReplaceOrig(atomic)) - goto bail3; + goto bail4; FcStrFree ((FcChar8 *)cache_hashed); FcAtomicUnlock (atomic); FcAtomicDestroy (atomic); @@ -634,99 +597,17 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c bail5: close (fd); - bail3: + bail4: FcAtomicUnlock (atomic); - bail2: + bail3: FcAtomicDestroy (atomic); + bail2: + free (cache); bail1: FcStrFree ((FcChar8 *)cache_hashed); - if (current_dir_block) - free (current_dir_block); - return FcFalse; -} - -static int banks_ptr = 0, banks_alloc = 0; -int * _fcBankId = 0, * _fcBankIdx = 0; -static const char ** bankDirs = 0; - -static FcBool -FcCacheHaveBank (int bank) -{ - int i; - - if (bank < FC_BANK_FIRST) - return FcTrue; - - for (i = 0; i < banks_ptr; i++) - if (_fcBankId[i] == bank) - return FcTrue; - return FcFalse; } -int -FcCacheBankToIndexMTF (int bank) -{ - int i, j; - - for (i = 0; i < banks_ptr; i++) - if (_fcBankId[_fcBankIdx[i]] == bank) - { - int t = _fcBankIdx[i]; - - for (j = i; j > 0; j--) - _fcBankIdx[j] = _fcBankIdx[j-1]; - _fcBankIdx[0] = t; - return t; - } - - if (banks_ptr >= banks_alloc) - { - int * b, * bidx; - const char ** bds; - - b = realloc (_fcBankId, (banks_alloc + 4) * sizeof(int)); - if (!b) - return -1; - _fcBankId = b; - - bidx = realloc (_fcBankIdx, (banks_alloc + 4) * sizeof(int)); - if (!bidx) - return -1; - _fcBankIdx = bidx; - - bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *)); - if (!bds) - return -1; - bankDirs = bds; - - banks_alloc += 4; - } - - i = banks_ptr++; - _fcBankId[i] = bank; - _fcBankIdx[i] = i; - return i; -} - -static void -FcCacheAddBankDir (int bank, const char * dir) -{ - int bi = FcCacheBankToIndexMTF (bank); - - if (bi < 0) - return; - - bankDirs[bi] = (const char *)FcStrCopy ((FcChar8 *)dir); -} - -const char * -FcCacheFindBankDir (int bank) -{ - int bi = FcCacheBankToIndex (bank); - return bankDirs[bi]; -} - /* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was diff --git a/src/fccfg.c b/src/fccfg.c index 586c656..4377ce6 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -310,11 +310,12 @@ FcConfigBuildFonts (FcConfig *config) for (i = 0; i < cached_fonts->nfont; i++) { FcChar8 *cfn; - FcPatternGetString (cached_fonts->fonts[i], FC_FILE, 0, &cfn); + FcPattern *font = cached_fonts->fonts[i]; + FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &cfn); - if (FcConfigAcceptFont (config, cached_fonts->fonts[i]) && + if (FcConfigAcceptFont (config, font) && (cfn && FcConfigAcceptFilename (config, cfn))) - FcFontSetAdd (fonts, cached_fonts->fonts[i]); + FcFontSetAdd (fonts, font); cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */ } @@ -841,7 +842,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) v.u.b = e->u.bval; break; case FcOpField: - r = FcPatternGet (p, e->u.field, 0, &v); + r = FcPatternObjectGet (p, e->u.object, 0, &v); if (r != FcResultMatch) v.type = FcTypeVoid; v = FcValueSave (v); @@ -1093,7 +1094,7 @@ FcConfigMatchValueList (FcPattern *p, e = 0; } - for (v = values; v; v = FcValueListPtrU(v->next)) + for (v = values; v; v = FcValueListNext(v)) { /* Compare the pattern value to the match expression value */ if (FcConfigCompareValue (&v->value, t->op, &value)) @@ -1129,17 +1130,17 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) if (e->op == FcOpComma) { l->value = FcConfigEvaluate (p, e->u.tree.left); - l->next = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding)); + l->next = FcConfigValues (p, e->u.tree.right, binding); } else { l->value = FcConfigEvaluate (p, e); - l->next = FcValueListPtrCreateDynamic(0); + l->next = NULL; } l->binding = binding; if (l->value.type == FcTypeVoid) { - FcValueList *next = FcValueListPtrU(l->next); + FcValueList *next = FcValueListNext(l); FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free (l); @@ -1162,27 +1163,26 @@ FcConfigAdd (FcValueListPtr *head, sameBinding = position->binding; else sameBinding = FcValueBindingWeak; - for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v); - v = FcValueListPtrU(v)->next) - if (FcValueListPtrU(v)->binding == FcValueBindingSame) - FcValueListPtrU(v)->binding = sameBinding; + for (v = new; v != NULL; v = FcValueListNext(v)) + if (v->binding == FcValueBindingSame) + v->binding = sameBinding; if (append) { if (position) prev = &position->next; else - for (prev = head; FcValueListPtrU(*prev); - prev = &(FcValueListPtrU(*prev)->next)) + for (prev = head; *prev != NULL; + prev = &(*prev)->next) ; } else { if (position) { - for (prev = head; FcValueListPtrU(*prev); - prev = &(FcValueListPtrU(*prev)->next)) + for (prev = head; *prev != NULL; + prev = &(*prev)->next) { - if (FcValueListPtrU(*prev) == position) + if (*prev == position) break; } } @@ -1191,7 +1191,7 @@ FcConfigAdd (FcValueListPtr *head, if (FcDebug () & FC_DBG_EDIT) { - if (!FcValueListPtrU(*prev)) + if (*prev == NULL) printf ("position not on list\n"); } } @@ -1205,12 +1205,12 @@ FcConfigAdd (FcValueListPtr *head, if (new) { - last = FcValueListPtrCreateDynamic(new); - while (FcValueListPtrU(FcValueListPtrU(last)->next)) - last = FcValueListPtrU(last)->next; + last = new; + while (last->next != NULL) + last = last->next; - FcValueListPtrU(last)->next = *prev; - *prev = FcValueListPtrCreateDynamic(new); + last->next = *prev; + *prev = new; } if (FcDebug () & FC_DBG_EDIT) @@ -1229,14 +1229,13 @@ FcConfigDel (FcValueListPtr *head, { FcValueListPtr *prev; - for (prev = head; FcValueListPtrU(*prev); - prev = &(FcValueListPtrU(*prev)->next)) + for (prev = head; *prev != NULL; prev = &(*prev)->next) { - if (FcValueListPtrU(*prev) == position) + if (*prev == position) { *prev = position->next; - position->next = FcValueListPtrCreateDynamic(0); - FcValueListDestroy (FcValueListPtrCreateDynamic(position)); + position->next = NULL; + FcValueListDestroy (position); break; } } @@ -1244,13 +1243,13 @@ FcConfigDel (FcValueListPtr *head, static void FcConfigPatternAdd (FcPattern *p, - const char *object, + FcObject object, FcValueList *list, FcBool append) { if (list) { - FcPatternElt *e = FcPatternInsertElt (p, object); + FcPatternElt *e = FcPatternObjectInsertElt (p, object); if (!e) return; @@ -1263,24 +1262,24 @@ FcConfigPatternAdd (FcPattern *p, */ static void FcConfigPatternDel (FcPattern *p, - const char *object) + FcObject object) { - FcPatternElt *e = FcPatternFindElt (p, object); + FcPatternElt *e = FcPatternObjectFindElt (p, object); if (!e) return; - while (FcValueListPtrU(e->values)) - FcConfigDel (&e->values, FcValueListPtrU(e->values)); + while (e->values != NULL) + FcConfigDel (&e->values, e->values); } static void FcConfigPatternCanon (FcPattern *p, - const char *object) + FcObject object) { - FcPatternElt *e = FcPatternFindElt (p, object); + FcPatternElt *e = FcPatternObjectFindElt (p, object); if (!e) return; - if (!FcValueListPtrU(e->values)) - FcPatternDel (p, object); + if (e->values == NULL) + FcPatternObjectDel (p, object); } FcBool @@ -1337,7 +1336,7 @@ FcConfigSubstituteWithPat (FcConfig *config, else m = p; if (m) - st[i].elt = FcPatternFindElt (m, t->field); + st[i].elt = FcPatternObjectFindElt (m, t->object); else st[i].elt = 0; /* @@ -1358,12 +1357,12 @@ FcConfigSubstituteWithPat (FcConfig *config, * Check to see if there is a match, mark the location * to apply match-relative edits */ - st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values)); + st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values); if (!st[i].value) break; - if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values)) + if (t->qual == FcQualFirst && st[i].value != st[i].elt->values) break; - if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values)) + if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values) break; } if (t) @@ -1391,8 +1390,7 @@ FcConfigSubstituteWithPat (FcConfig *config, for (t = s->test, i = 0; t; t = t->next, i++) { if ((t->kind == FcMatchFont || kind == FcMatchPattern) && - !FcStrCmpIgnoreCase ((FcChar8 *) t->field, - (FcChar8 *) e->field)) + t->object == e->object) { /* * KLUDGE - the pattern may have been reallocated or @@ -1401,7 +1399,7 @@ FcConfigSubstituteWithPat (FcConfig *config, * the element again */ if (e != s->edit && st[i].elt) - st[i].elt = FcPatternFindElt (p, t->field); + st[i].elt = FcPatternObjectFindElt (p, t->object); if (!st[i].elt) t = 0; break; @@ -1416,7 +1414,7 @@ FcConfigSubstituteWithPat (FcConfig *config, if (t) { FcValueList *thisValue = st[i].value; - FcValueList *nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0; + FcValueList *nextValue = thisValue; /* * Append the new list of values after the current value @@ -1444,8 +1442,8 @@ FcConfigSubstituteWithPat (FcConfig *config, * Delete all of the values and insert * the new set */ - FcConfigPatternDel (p, e->field); - FcConfigPatternAdd (p, e->field, l, FcTrue); + FcConfigPatternDel (p, e->object); + FcConfigPatternAdd (p, e->object, l, FcTrue); /* * Adjust any pointers into the value list as they no * longer point to anything valid @@ -1468,7 +1466,7 @@ FcConfigSubstituteWithPat (FcConfig *config, } /* fall through ... */ case FcOpPrependFirst: - FcConfigPatternAdd (p, e->field, l, FcFalse); + FcConfigPatternAdd (p, e->object, l, FcFalse); break; case FcOpAppend: if (t) @@ -1478,10 +1476,10 @@ FcConfigSubstituteWithPat (FcConfig *config, } /* fall through ... */ case FcOpAppendLast: - FcConfigPatternAdd (p, e->field, l, FcTrue); + FcConfigPatternAdd (p, e->object, l, FcTrue); break; default: - FcValueListDestroy (FcValueListPtrCreateDynamic(l)); + FcValueListDestroy (l); break; } } @@ -1490,7 +1488,7 @@ FcConfigSubstituteWithPat (FcConfig *config, * any properties without data */ for (e = s->edit; e; e = e->next) - FcConfigPatternCanon (p, e->field); + FcConfigPatternCanon (p, e->object); if (FcDebug () & FC_DBG_EDIT) { diff --git a/src/fccharset.c b/src/fccharset.c index e0a0961..d55c611 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -29,33 +29,6 @@ /* #define CHATTY */ -static FcCharSet ** charsets = 0; -static FcChar16 ** numbers = 0; -static int charset_bank_count = 0, charset_ptr, charset_count; -static int charset_numbers_ptr, charset_numbers_count; -static FcCharLeaf ** leaves = 0; -static int charset_leaf_ptr, charset_leaf_count; -static int ** leaf_idx = 0; -static int charset_leaf_idx_ptr, charset_leaf_idx_count; - -extern const FcChar16 langBankNumbers[]; -extern const FcCharLeaf langBankLeaves[]; -extern const int langBankLeafIdx[]; - -static FcBool -FcCharSetEnsureBank (int bi); - -void -FcLangCharSetPopulate (void) -{ - int bi = FcCacheBankToIndexMTF (FC_BANK_LANGS); - FcCharSetEnsureBank (bi); - charsets[bi] = 0; - numbers[bi] = (FcChar16 *)langBankNumbers; - leaves[bi] = (FcCharLeaf *)langBankLeaves; - leaf_idx[bi] = (int *)langBankLeafIdx; -} - FcCharSet * FcCharSetCreate (void) { @@ -67,9 +40,8 @@ FcCharSetCreate (void) FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet)); fcs->ref = 1; fcs->num = 0; - fcs->bank = FC_BANK_DYNAMIC; - fcs->u.dyn.leaves = 0; - fcs->u.dyn.numbers = 0; + fcs->leaves_offset = FcPtrToOffset (fcs, NULL); + fcs->numbers_offset = FcPtrToOffset (fcs, NULL); return fcs; } @@ -86,27 +58,25 @@ void FcCharSetDestroy (FcCharSet *fcs) { int i; + if (fcs->ref == FC_REF_CONSTANT) return; if (--fcs->ref > 0) return; - if (fcs->bank == FC_BANK_DYNAMIC) + for (i = 0; i < fcs->num; i++) { - for (i = 0; i < fcs->num; i++) - { - FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); - free (fcs->u.dyn.leaves[i]); - } - if (fcs->u.dyn.leaves) - { - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *)); - free (fcs->u.dyn.leaves); - } - if (fcs->u.dyn.numbers) - { - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); - free (fcs->u.dyn.numbers); - } + FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); + free (FcCharSetLeaf (fcs, i)); + } + if (FcCharSetLeaves (fcs)) + { + FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t)); + free (FcCharSetLeaves (fcs)); + } + if (FcCharSetNumbers (fcs)) + { + FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); + free (FcCharSetNumbers (fcs)); } FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (fcs); @@ -121,7 +91,7 @@ FcCharSetDestroy (FcCharSet *fcs) static int FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4) { - FcChar16 *numbers = FcCharSetGetNumbers(fcs); + FcChar16 *numbers = FcCharSetNumbers(fcs); FcChar16 page; int low = 0; int high = fcs->num - 1; @@ -150,7 +120,7 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4) { int pos = FcCharSetFindLeafPos (fcs, ucs4); if (pos >= 0) - return FcCharSetGetLeaf(fcs, pos); + return FcCharSetLeaf(fcs, pos); return 0; } @@ -160,68 +130,55 @@ FcCharSetPutLeaf (FcCharSet *fcs, FcCharLeaf *leaf, int pos) { - FcCharLeaf **leaves; - FcChar16 *numbers; + intptr_t *leaves = FcCharSetLeaves (fcs); + FcChar16 *numbers = FcCharSetNumbers (fcs); ucs4 >>= 8; if (ucs4 >= 0x10000) return FcFalse; - if (fcs->bank != FC_BANK_DYNAMIC) + if (!leaves) + leaves = malloc (sizeof (*leaves)); + else { - /* convert to dynamic */ - int i; - - leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *)); - if (!leaves) - return FcFalse; - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *)); - numbers = malloc ((fcs->num + 1) * sizeof (FcChar16)); - if (!numbers) - { - free (leaves); - return FcFalse; - } - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16)); - - for (i = 0; i < fcs->num; i++) - leaves[i] = FcCharSetGetLeaf(fcs, i); - memcpy (numbers, FcCharSetGetNumbers(fcs), - fcs->num * sizeof (FcChar16)); + intptr_t *new_leaves = realloc (leaves, (fcs->num + 1) * + sizeof (*leaves)); + intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves; + + if (new_leaves && distance) + { + int i; - fcs->bank = FC_BANK_DYNAMIC; - fcs->u.dyn.leaves = leaves; - fcs->u.dyn.numbers = numbers; + for (i = 0; i < fcs->num; i++) + new_leaves[i] -= distance; + } + leaves = new_leaves; } + if (!leaves) + return FcFalse; + + if (fcs->num) + FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t)); + FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t)); + fcs->leaves_offset = FcPtrToOffset (fcs, leaves); + + if (!numbers) + numbers = malloc (sizeof (FcChar16)); else - { - if (!fcs->u.dyn.leaves) - leaves = malloc (sizeof (FcCharLeaf *)); - else - leaves = realloc (fcs->u.dyn.leaves, (fcs->num + 1) * sizeof (FcCharLeaf *)); - if (!leaves) - return FcFalse; - if (fcs->num) - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *)); - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *)); - fcs->u.dyn.leaves = leaves; - if (!fcs->u.dyn.numbers) - numbers = malloc (sizeof (FcChar16)); - else - numbers = realloc (fcs->u.dyn.numbers, (fcs->num + 1) * sizeof (FcChar16)); - if (!numbers) - return FcFalse; - if (fcs->num) - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16)); - fcs->u.dyn.numbers = numbers; - } + numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16)); + if (!numbers) + return FcFalse; + + if (fcs->num) + FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); + FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16)); + fcs->numbers_offset = FcPtrToOffset (fcs, numbers); - memmove (fcs->u.dyn.leaves + pos + 1, fcs->u.dyn.leaves + pos, - (fcs->num - pos) * sizeof (FcCharLeaf *)); - memmove (fcs->u.dyn.numbers + pos + 1, fcs->u.dyn.numbers + pos, - (fcs->num - pos) * sizeof (FcChar16)); - fcs->u.dyn.numbers[pos] = (FcChar16) ucs4; - fcs->u.dyn.leaves[pos] = leaf; + memmove (leaves + pos + 1, leaves + pos, + (fcs->num - pos) * sizeof (*leaves)); + memmove (numbers + pos + 1, numbers + pos, + (fcs->num - pos) * sizeof (*numbers)); + numbers[pos] = (FcChar16) ucs4; + leaves[pos] = FcPtrToOffset (leaves, leaf); fcs->num++; return FcTrue; } @@ -239,7 +196,7 @@ FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4) pos = FcCharSetFindLeafPos (fcs, ucs4); if (pos >= 0) - return FcCharSetGetLeaf(fcs, pos); + return FcCharSetLeaf(fcs, pos); leaf = calloc (1, sizeof (FcCharLeaf)); if (!leaf) @@ -264,16 +221,9 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf) if (pos >= 0) { FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); - if (fcs->bank == FC_BANK_DYNAMIC) - { - free (fcs->u.dyn.leaves[pos]); - fcs->u.dyn.leaves[pos] = leaf; - } - else - { - int bi = FcCacheBankToIndex(fcs->bank); - leaves[bi][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf; - } + free (FcCharSetLeaf (fcs, pos)); + FcCharSetLeaves(fcs)[pos] = FcPtrToOffset (FcCharSetLeaves(fcs), + leaf); return FcTrue; } pos = -pos - 1; @@ -324,9 +274,9 @@ FcCharSetIterSet (const FcCharSet *fcs, FcCharSetIter *iter) iter->leaf = 0; return; } - iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8; + iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8; } - iter->leaf = FcCharSetGetLeaf(fcs, pos); + iter->leaf = FcCharSetLeaf(fcs, pos); iter->pos = pos; #ifdef CHATTY printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf); @@ -344,8 +294,8 @@ FcCharSetIterNext (const FcCharSet *fcs, FcCharSetIter *iter) } else { - iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8; - iter->leaf = FcCharSetGetLeaf(fcs, pos); + iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8; + iter->leaf = FcCharSetLeaf(fcs, pos); iter->pos = pos; } } @@ -662,15 +612,15 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) ai = 0; while (ai < a->num && bi < b->num) { - an = FcCharSetGetNumbers(a)[ai]; - bn = FcCharSetGetNumbers(b)[bi]; + an = FcCharSetNumbers(a)[ai]; + bn = FcCharSetNumbers(b)[bi]; /* * Check matching pages */ if (an == bn) { - FcChar32 *am = FcCharSetGetLeaf(a, ai)->map; - FcChar32 *bm = FcCharSetGetLeaf(b, bi)->map; + FcChar32 *am = FcCharSetLeaf(a, ai)->map; + FcChar32 *bm = FcCharSetLeaf(b, bi)->map; if (am != bm) { @@ -701,7 +651,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) while (low <= high) { int mid = (low + high) >> 1; - bn = FcCharSetGetNumbers(b)[mid]; + bn = FcCharSetNumbers(b)[mid]; if (bn == an) { high = mid; @@ -713,7 +663,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) high = mid - 1; } bi = high; - while (bi < b->num && FcCharSetGetNumbers(b)[bi] < an) + while (bi < b->num && FcCharSetNumbers(b)[bi] < an) bi++; } } @@ -1021,10 +971,10 @@ FcCharSetHash (FcCharSet *fcs) /* hash in leaves */ for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++) - hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map); + hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetLeaf(fcs, i)->map); /* hash in numbers */ for (i = 0; i < fcs->num; i++) - hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetGetNumbers(fcs); + hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetNumbers(fcs); return hash; } @@ -1041,6 +991,7 @@ FcCharSetFreezeBase (FcCharSet *fcs) FcCharSetEnt **bucket = &FcCharSetHashTable[hash % FC_CHAR_SET_HASH_SIZE]; FcCharSetEnt *ent; int size; + int i; FcCharSetTotal++; FcCharSetTotalEnts += fcs->num; @@ -1048,15 +999,15 @@ FcCharSetFreezeBase (FcCharSet *fcs) { if (ent->hash == hash && ent->set.num == fcs->num && - !memcmp (FcCharSetGetNumbers(&ent->set), - FcCharSetGetNumbers(fcs), + !memcmp (FcCharSetNumbers(&ent->set), + FcCharSetNumbers(fcs), fcs->num * sizeof (FcChar16))) { FcBool ok = FcTrue; int i; for (i = 0; i < fcs->num; i++) - if (FcCharSetGetLeaf(&ent->set, i) != FcCharSetGetLeaf(fcs, i)) + if (FcCharSetLeaf(&ent->set, i) != FcCharSetLeaf(fcs, i)) ok = FcFalse; if (ok) return &ent->set; @@ -1075,26 +1026,26 @@ FcCharSetFreezeBase (FcCharSet *fcs) ent->set.ref = FC_REF_CONSTANT; ent->set.num = fcs->num; - ent->set.bank = fcs->bank; - if (fcs->bank == FC_BANK_DYNAMIC) + if (fcs->num) { - if (fcs->num) - { - ent->set.u.dyn.leaves = (FcCharLeaf **) (ent + 1); - ent->set.u.dyn.numbers = (FcChar16 *) (ent->set.u.dyn.leaves + fcs->num); - memcpy (ent->set.u.dyn.leaves, fcs->u.dyn.leaves, fcs->num * sizeof (FcCharLeaf *)); - memcpy (ent->set.u.dyn.numbers, fcs->u.dyn.numbers, fcs->num * sizeof (FcChar16)); - } - else - { - ent->set.u.dyn.leaves = 0; - ent->set.u.dyn.numbers = 0; - } + intptr_t *ent_leaves; + + ent->set.leaves_offset = sizeof (ent->set); + ent->set.numbers_offset = (ent->set.leaves_offset + + fcs->num * sizeof (intptr_t)); + + ent_leaves = FcCharSetLeaves (&ent->set); + for (i = 0; i < fcs->num; i++) + ent_leaves[i] = FcPtrToOffset (ent_leaves, + FcCharSetLeaf (fcs, i)); + memcpy (FcCharSetNumbers (&ent->set), + FcCharSetNumbers (fcs), + fcs->num * sizeof (FcChar16)); } else { - ent->set.u.stat.leafidx_offset = fcs->u.stat.leafidx_offset; - ent->set.u.stat.numbers_offset = fcs->u.stat.numbers_offset; + ent->set.leaves_offset = 0; + ent->set.numbers_offset = 0; } ent->hash = hash; @@ -1140,26 +1091,23 @@ FcCharSetFreeze (FcCharSet *fcs) goto bail0; for (i = 0; i < fcs->num; i++) { - l = FcCharSetFreezeLeaf (FcCharSetGetLeaf(fcs, i)); + l = FcCharSetFreezeLeaf (FcCharSetLeaf(fcs, i)); if (!l) goto bail1; - if (!FcCharSetInsertLeaf (b, FcCharSetGetNumbers(fcs)[i] << 8, l)) + if (!FcCharSetInsertLeaf (b, FcCharSetNumbers(fcs)[i] << 8, l)) goto bail1; } n = FcCharSetFreezeBase (b); bail1: - if (b->bank == FC_BANK_DYNAMIC) + if (FcCharSetLeaves (b)) { - if (b->u.dyn.leaves) - { - FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *)); - free (b->u.dyn.leaves); - } - if (b->u.dyn.numbers) - { - FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16)); - free (b->u.dyn.numbers); - } + FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *)); + free (FcCharSetLeaves (b)); + } + if (FcCharSetNumbers (b)) + { + FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16)); + free (FcCharSetNumbers (b)); } FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (b); @@ -1225,20 +1173,17 @@ FcNameParseCharSet (FcChar8 *string) #endif n = FcCharSetFreezeBase (c); bail1: - if (c->bank == FC_BANK_DYNAMIC) + if (FcCharSetLeaves (c)) { - if (c->u.dyn.leaves) - { - FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *)); - free (c->u.dyn.leaves); - } - if (c->u.dyn.numbers) - { - FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16)); - free (c->u.dyn.numbers); - } - FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); + FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *)); + free (FcCharSetLeaves (c)); + } + if (FcCharSetNumbers (c)) + { + FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16)); + free (FcCharSetNumbers (c)); } + FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (c); bail0: return n; @@ -1317,175 +1262,67 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c) return FcTrue; } -void -FcCharSetNewBank(void) -{ - charset_count = 0; - charset_numbers_count = 0; - charset_leaf_count = 0; - charset_leaf_idx_count = 0; -} - -int -FcCharSetNeededBytes (const FcCharSet *c) -{ - /* yes, there's redundancy */ - charset_count++; - charset_leaf_idx_count += c->num; - charset_leaf_count += c->num; - charset_numbers_count += c->num; - return sizeof (FcCharSet) + - sizeof (int) * c->num + /* leaf_idx */ - sizeof (FcCharLeaf) * c->num + /* leaf */ - sizeof (FcChar16) * c->num; /* number */ -} - -int -FcCharSetNeededBytesAlign (void) -{ - return fc_alignof (FcCharSet) + fc_alignof (int) + - fc_alignof (FcCharLeaf) + fc_alignof (FcChar16); -} - -static FcBool -FcCharSetEnsureBank (int bi) +FcBool +FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs) { - if (!charsets || charset_bank_count <= bi) - { - int new_count = charset_bank_count + 2; - FcCharSet ** cs; - FcChar16 ** n; - FcCharLeaf ** lvs; - int ** lvi; - int i; - - cs = realloc(charsets, sizeof(FcCharSet*) * new_count); - if (!cs) return 0; - n = realloc(numbers, sizeof(FcChar16*) * new_count); - if (!n) return 0; - lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count); - if (!lvs) return 0; - lvi = realloc(leaf_idx, sizeof(int*) * new_count); - if (!lvi) return 0; - - charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi; - for (i = charset_bank_count; i < new_count; i++) - { - charsets[i] = 0; - numbers[i] = 0; - leaves[i] = 0; - leaf_idx[i] = 0; - } - charset_bank_count = new_count; - } + intptr_t *leaves = FcCharSetLeaves (cs); + FcChar16 *numbers = FcCharSetNumbers (cs); + int i; + + if (!FcSerializeAlloc (serialize, cs, sizeof (FcCharSet))) + return FcFalse; + if (!FcSerializeAlloc (serialize, leaves, cs->num * sizeof (intptr_t))) + return FcFalse; + if (!FcSerializeAlloc (serialize, numbers, cs->num * sizeof (FcChar16))) + return FcFalse; + for (i = 0; i < cs->num; i++) + if (!FcSerializeAlloc (serialize, FcCharSetLeaf(cs, i), + sizeof (FcCharLeaf))) + return FcFalse; return FcTrue; } - -void * -FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr) + +FcCharSet * +FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) { - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcCharSetEnsureBank(bi)) - return 0; + FcCharSet *cs_serialized = FcSerializePtr (serialize, cs); + intptr_t *leaves, *leaves_serialized; + FcChar16 *numbers, *numbers_serialized; + FcCharLeaf *leaf, *leaf_serialized; + int i; - block_ptr = ALIGN (block_ptr, FcCharSet); - charsets[bi] = (FcCharSet *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcCharSet) * charset_count)); - block_ptr = ALIGN (block_ptr, FcChar16); - numbers[bi] = (FcChar16 *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(FcChar16) * charset_numbers_count)); - block_ptr = ALIGN (block_ptr, FcCharLeaf); - leaves[bi] = (FcCharLeaf *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(FcCharLeaf) * charset_leaf_count)); - block_ptr = ALIGN (block_ptr, int); - leaf_idx[bi] = (int *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(int) * charset_leaf_idx_count)); - - metadata->charset_count = charset_count; - metadata->charset_numbers_count = charset_numbers_count; - metadata->charset_leaf_count = charset_leaf_count; - metadata->charset_leaf_idx_count = charset_leaf_idx_count; - charset_ptr = 0; charset_leaf_ptr = 0; - charset_leaf_idx_ptr = 0; charset_numbers_ptr = 0; - return block_ptr; -} + if (!cs_serialized) + return NULL; + + cs_serialized->ref = FC_REF_CONSTANT; + cs_serialized->num = cs->num; -FcCharSet * -FcCharSetSerialize(int bank, FcCharSet *c) -{ - int i; - FcCharSet new; - int bi = FcCacheBankToIndex(bank), cp = charset_ptr; + leaves = FcCharSetLeaves (cs); + leaves_serialized = FcSerializePtr (serialize, leaves); + if (!leaves_serialized) + return NULL; - new.ref = FC_REF_CONSTANT; - new.bank = bank; - new.u.stat.leafidx_offset = charset_leaf_idx_ptr; - new.u.stat.numbers_offset = charset_numbers_ptr; - new.num = c->num; + cs_serialized->leaves_offset = FcPtrToOffset (cs_serialized, + leaves_serialized); + + numbers = FcCharSetNumbers (cs); + numbers_serialized = FcSerializePtr (serialize, numbers); + if (!numbers) + return NULL; - charsets[bi][charset_ptr++] = new; + cs_serialized->numbers_offset = FcPtrToOffset (cs_serialized, + numbers_serialized); - for (i = 0; i < c->num; i++) + for (i = 0; i < cs->num; i++) { - leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr; - memcpy (&leaves[bi][charset_leaf_ptr++], - c->u.dyn.leaves[i], sizeof(FcCharLeaf)); - numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i]; + leaf = FcCharSetLeaf (cs, i); + leaf_serialized = FcSerializePtr (serialize, leaf); + if (!leaf_serialized) + return NULL; + *leaf_serialized = *leaf; + leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf); + numbers_serialized[i] = numbers[i]; } - - return &charsets[bi][cp]; -} - -void * -FcCharSetUnserialize (FcCache *metadata, void *block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcCharSetEnsureBank(bi)) - return 0; - - block_ptr = ALIGN (block_ptr, FcCharSet); - charsets[bi] = (FcCharSet *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcCharSet) * metadata->charset_count)); - block_ptr = ALIGN (block_ptr, FcChar16); - numbers[bi] = (FcChar16 *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(FcChar16) * metadata->charset_numbers_count)); - block_ptr = ALIGN (block_ptr, FcCharLeaf); - leaves[bi] = (FcCharLeaf *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(FcCharLeaf) * metadata->charset_leaf_count)); - block_ptr = ALIGN (block_ptr, int); - leaf_idx[bi] = (int *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof(int) * metadata->charset_leaf_idx_count)); - - return block_ptr; -} - -FcCharLeaf * -FcCharSetGetLeaf(const FcCharSet *c, int i) -{ - int bi; - if (c->bank == FC_BANK_DYNAMIC) - return c->u.dyn.leaves[i]; - bi = FcCacheBankToIndex(c->bank); - - return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset+i]]; -} - -FcChar16 * -FcCharSetGetNumbers(const FcCharSet *c) -{ - int bi; - if (c->bank == FC_BANK_DYNAMIC) - return c->u.dyn.numbers; - bi = FcCacheBankToIndex(c->bank); - - return &numbers[bi][c->u.stat.numbers_offset]; + + return cs_serialized; } - diff --git a/src/fcdbg.c b/src/fcdbg.c index 9b7e8f7..16b6bfd 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -49,7 +49,8 @@ FcValuePrint (const FcValue v) printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); break; case FcTypeCharSet: /* XXX */ - printf (" set"); + printf (" "); + FcCharSetPrint (v.u.c); break; case FcTypeLangSet: printf (" "); @@ -64,10 +65,10 @@ FcValuePrint (const FcValue v) void FcValueListPrint (FcValueListPtr l) { - for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next) + for (; l != NULL; l = FcValueListNext(l)) { - FcValuePrint (FcValueCanonicalize(&FcValueListPtrU(l)->value)); - switch (FcValueListPtrU(l)->binding) { + FcValuePrint (FcValueCanonicalize(&l->value)); + switch (l->binding) { case FcValueBindingWeak: printf ("(w)"); break; @@ -96,6 +97,22 @@ FcLangSetPrint (const FcLangSet *ls) } void +FcCharSetPrint (const FcCharSet *c) +{ + int i, j; + + for (i = 0; i < c->num; i++) + { + FcCharLeaf *leaf = FcCharSetLeaf(c, i); + + printf ("%04x:", FcCharSetNumbers(c)[i]); + for (j = 0; j < 256/32; j++) + printf (" %08x", leaf->map[j]); + printf ("\n"); + } +} + +void FcPatternPrint (const FcPattern *p) { int i; @@ -109,15 +126,15 @@ FcPatternPrint (const FcPattern *p) printf ("Pattern has %d elts (size %d)\n", p->num, p->size); for (i = 0; i < p->num; i++) { - e = FcPatternEltU(p->elts) + i; - printf ("\t%s:", FcObjectPtrU(e->object)); + e = &FcPatternElts(p)[i]; + printf ("\t%s:", FcObjectName(e->object)); /* so that fc-match properly displays file: foo... */ - if (e->object == FcObjectToPtr(FC_FILE)) + if (e->object == FC_FILE_OBJECT) { FcChar8 * s; - FcPatternGetString (p, FC_FILE, 0, &s); + FcPatternObjectGetString (p, FC_FILE_OBJECT, 0, &s); printf (" \"%s\"", s); - switch (FcValueListPtrU(e->values)->binding) { + switch (FcPatternEltValues(e)->binding) { case FcValueBindingWeak: printf ("(w)"); break; @@ -130,7 +147,7 @@ FcPatternPrint (const FcPattern *p) } } else - FcValueListPrint (e->values); + FcValueListPrint (FcPatternEltValues(e)); printf ("\n"); } printf ("\n"); @@ -197,7 +214,7 @@ FcExprPrint (const FcExpr *expr) case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break; case FcOpCharSet: printf ("charset\n"); break; case FcOpNil: printf ("nil\n"); break; - case FcOpField: printf ("%s", expr->u.field); break; + case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break; case FcOpConst: printf ("%s", expr->u.constant); break; case FcOpQuest: FcExprPrint (expr->u.tree.left); @@ -307,7 +324,7 @@ FcTestPrint (const FcTest *test) printf ("not_first "); break; } - printf ("%s ", test->field); + printf ("%s ", FcObjectName (test->object)); FcOpPrint (test->op); printf (" "); FcExprPrint (test->expr); @@ -317,7 +334,7 @@ FcTestPrint (const FcTest *test) void FcEditPrint (const FcEdit *edit) { - printf ("Edit %s ", edit->field); + printf ("Edit %s ", FcObjectName (edit->object)); FcOpPrint (edit->op); printf (" "); FcExprPrint (edit->expr); diff --git a/src/fcdefault.c b/src/fcdefault.c index 4fd3ed8..b582310 100644 --- a/src/fcdefault.c +++ b/src/fcdefault.c @@ -26,14 +26,14 @@ #include <locale.h> static const struct { - const char *field; + FcObject field; FcBool value; } FcBoolDefaults[] = { - { FC_HINTING, FcTrue }, /* !FT_LOAD_NO_HINTING */ - { FC_VERTICAL_LAYOUT, FcFalse }, /* FC_LOAD_VERTICAL_LAYOUT */ - { FC_AUTOHINT, FcFalse }, /* FC_LOAD_FORCE_AUTOHINT */ - { FC_GLOBAL_ADVANCE, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ - { FC_EMBEDDED_BITMAP, FcTrue }, /* !FC_LOAD_NO_BITMAP */ + { FC_HINTING_OBJECT, FcTrue }, /* !FT_LOAD_NO_HINTING */ + { FC_VERTICAL_LAYOUT_OBJECT, FcFalse }, /* FC_LOAD_VERTICAL_LAYOUT */ + { FC_AUTOHINT_OBJECT, FcFalse }, /* FC_LOAD_FORCE_AUTOHINT */ + { FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ + { FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */ }; #define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0]) @@ -105,63 +105,63 @@ FcDefaultSubstitute (FcPattern *pattern) FcValue v; int i; - if (FcPatternGet (pattern, FC_STYLE, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_STYLE_OBJECT, 0, &v) == FcResultNoMatch) { - if (FcPatternGet (pattern, FC_WEIGHT, 0, &v) == FcResultNoMatch ) + if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch ) { - FcPatternAddInteger (pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM); + FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM); } - if (FcPatternGet (pattern, FC_SLANT, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch) { - FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN); + FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN); } } - if (FcPatternGet (pattern, FC_WIDTH, 0, &v) == FcResultNoMatch) - FcPatternAddInteger (pattern, FC_WIDTH, FC_WIDTH_NORMAL); + if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch) + FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL); for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++) - if (FcPatternGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch) - FcPatternAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value); + if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch) + FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value); - if (FcPatternGet (pattern, FC_PIXEL_SIZE, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch) { double dpi, size, scale; - if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) != FcResultMatch) + if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch) { size = 12.0; - (void) FcPatternDel (pattern, FC_SIZE); - FcPatternAddDouble (pattern, FC_SIZE, size); + (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT); + FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size); } - if (FcPatternGetDouble (pattern, FC_SCALE, 0, &scale) != FcResultMatch) + if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch) { scale = 1.0; - (void) FcPatternDel (pattern, FC_SCALE); - FcPatternAddDouble (pattern, FC_SCALE, scale); + (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT); + FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale); } size *= scale; - if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch) + if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch) { dpi = 75.0; - (void) FcPatternDel (pattern, FC_DPI); - FcPatternAddDouble (pattern, FC_DPI, dpi); + (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT); + FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi); } size *= dpi / 72.0; - FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size); + FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size); } - if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) == FcResultNoMatch) { - FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ()); + FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang ()); } - if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch) { - FcPatternAddInteger (pattern, FC_FONTVERSION, 0x7fffffff); + FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff); } - if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch) + if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch) { - FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL); + FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL); } } @@ -81,117 +81,52 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font) return FcTrue; } -static int * fcfs_pat_count; - -void -FcFontSetNewBank (void) -{ - FcPatternNewBank(); -} - -int -FcFontSetNeededBytes (FcFontSet *s) -{ - int i, c, cum = 0; - - for (i = 0; i < s->nfont; i++) - { - c = FcPatternNeededBytes(s->fonts[i]); - if (c < 0) - return c; - cum += c; - } - - if (cum > 0) - return cum + sizeof(int) + FcObjectNeededBytes(); - else - return 0; -} - -/* Returns an overestimate of the number of bytes that - * might later get eaten up by padding in the ALIGN macro. */ -int -FcFontSetNeededBytesAlign (void) -{ - return fc_alignof (int) + - FcPatternNeededBytesAlign () + FcObjectNeededBytesAlign (); -} - -void * -FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr) -{ - block_ptr = ALIGN (block_ptr, int); - fcfs_pat_count = (int *)block_ptr; - block_ptr = (int *)block_ptr + 1; - /* we don't consume any bytes for the fontset itself, */ - /* since we don't allocate it statically. */ - block_ptr = FcPatternDistributeBytes (metadata, block_ptr); - - /* for good measure, write out the object ids used for */ - /* this bank to the file. */ - return FcObjectDistributeBytes (metadata, block_ptr); -} - FcBool -FcFontSetSerialize (int bank, FcFontSet * s) +FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s) { int i; - FcPattern * p; - *fcfs_pat_count = s->nfont; - + + if (!FcSerializeAlloc (serialize, s, sizeof (FcFontSet))) + return FcFalse; + if (!FcSerializeAlloc (serialize, s->fonts, s->nfont * sizeof (FcPattern *))) + return FcFalse; for (i = 0; i < s->nfont; i++) { - p = FcPatternSerialize (bank, s->fonts[i]); - if (!p) return FcFalse; + if (!FcPatternSerializeAlloc (serialize, s->fonts[i])) + return FcFalse; } - FcObjectSerialize(); - return FcTrue; } -FcBool -FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr) +FcFontSet * +FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s) { - int nfont; - int i, n; - - block_ptr = ALIGN (block_ptr, int); - nfont = *(int *)block_ptr; - block_ptr = (int *)block_ptr + 1; + int i; + FcFontSet *s_serialize; + FcPattern **fonts_serialize; + FcPattern *p_serialize; + + s_serialize = FcSerializePtr (serialize, s); + if (!s_serialize) + return NULL; + *s_serialize = *s; + s_serialize->sfont = s_serialize->nfont; + + fonts_serialize = FcSerializePtr (serialize, s->fonts); + if (!fonts_serialize) + return NULL; + s_serialize->fonts = FcPtrToEncodedOffset (s_serialize, + fonts_serialize, FcPattern *); - /* comparing nfont and metadata.count is a bit like comparing - apples and oranges. Its just for rejecting totally insane - nfont values, and for that its good enough */ - if (nfont > 0 && nfont < metadata->count / sizeof(void*)) + for (i = 0; i < s->nfont; i++) { - FcPattern * p = (FcPattern *)block_ptr; - - if (s->sfont < s->nfont + nfont) - { - int sfont = s->nfont + nfont; - FcPattern ** pp; - pp = realloc (s->fonts, sfont * sizeof (FcPattern)); - if (!pp) - return FcFalse; - s->fonts = pp; - s->sfont = sfont; - } - n = s->nfont; - s->nfont += nfont; - - /* The following line is a bit counterintuitive. The usual - * convention is that FcPatternUnserialize is responsible for - * aligning the FcPattern. However, the FontSet also stores - * the FcPatterns in its own array, so we need to align here - * too. */ - p = ALIGN(p, FcPattern); - for (i = 0; i < nfont; i++) - s->fonts[n + i] = p+i; - - block_ptr = FcPatternUnserialize (metadata, block_ptr); - block_ptr = FcObjectUnserialize (metadata, block_ptr); - return block_ptr != 0; + p_serialize = FcPatternSerialize (serialize, s->fonts[i]); + if (!p_serialize) + return NULL; + fonts_serialize[i] = FcPtrToEncodedOffset (s_serialize, + p_serialize, + FcPattern); } - return FcFalse; + return s_serialize; } diff --git a/src/fcint.h b/src/fcint.h index fbbdf77..2f656cb 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -74,6 +74,7 @@ #define FC_DBG_SCANV 256 #define FC_DBG_MEMORY 512 #define FC_DBG_CONFIG 1024 +#define FC_DBG_LANGSET 2048 #define FC_MEM_CHARSET 0 #define FC_MEM_CHARLEAF 1 @@ -116,44 +117,94 @@ typedef enum _FcValueBinding { FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame } FcValueBinding; -typedef struct _FcValueListPtr { - int bank; - union { - int stat; - struct _FcValueList *dyn; - } u; -} FcValueListPtr; +/* + * Serialized data structures use only offsets instead of pointers + * A low bit of 1 indicates an offset. + */ + +/* Is the provided pointer actually an offset? */ +#define FcIsEncodedOffset(p) ((((intptr_t) (p)) & 1) != 0) -typedef struct _FcValueList { - FcValueListPtr next; +/* Encode offset in a pointer of type t */ +#define FcOffsetEncode(o,t) ((t *) ((o) | 1)) + +/* Decode a pointer into an offset */ +#define FcOffsetDecode(p) (((intptr_t) (p)) & ~1) + +/* Compute pointer offset */ +#define FcPtrToOffset(b,p) ((intptr_t) (p) - (intptr_t) (b)) + +/* Given base address, offset and type, return a pointer */ +#define FcOffsetToPtr(b,o,t) ((t *) ((intptr_t) (b) + (o))) + +/* Given base address, encoded offset and type, return a pointer */ +#define FcEncodedOffsetToPtr(b,p,t) FcOffsetToPtr(b,FcOffsetDecode(p),t) - FcValue value; - FcValueBinding binding; +/* Given base address, pointer and type, return an encoded offset */ +#define FcPtrToEncodedOffset(b,p,t) FcOffsetEncode(FcPtrToOffset(b,p),t) + +/* Given a structure, offset member and type, return pointer */ +#define FcOffsetMember(s,m,t) FcOffsetToPtr(s,(s)->m,t) + +/* Given a structure, encoded offset member and type, return pointer to member */ +#define FcEncodedOffsetMember(s,m,t) FcOffsetToPtr(s,FcOffsetDecode((s)->m), t) + +/* Given a structure, member and type, convert the member to a pointer */ +#define FcPointerMember(s,m,t) (FcIsEncodedOffset((s)->m) ? \ + FcEncodedOffsetMember (s,m,t) : \ + (s)->m) + +/* + * Serialized values may hold strings, charsets and langsets as pointers, + * unfortunately FcValue is an exposed type so we can't just always use + * offsets + */ +#define FcValueString(v) FcPointerMember(v,u.s,FcChar8) +#define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet) +#define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet) + +typedef struct _FcValueList *FcValueListPtr; + +typedef struct _FcValueList { + struct _FcValueList *next; + FcValue value; + FcValueBinding binding; } FcValueList; -typedef int FcObjectPtr; +#define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList) + +typedef int FcObject; -typedef struct _FcPatternEltPtr { - int bank; - union { - int stat; - struct _FcPatternElt *dyn; - } u; -} FcPatternEltPtr; +typedef struct _FcPatternElt *FcPatternEltPtr; +/* + * Pattern elts are stuck in a structure connected to the pattern, + * so they get moved around when the pattern is resized. Hence, the + * values field must be a pointer/offset instead of just an offset + */ typedef struct _FcPatternElt { - FcObjectPtr object; - FcValueListPtr values; + FcObject object; + FcValueList *values; } FcPatternElt; +#define FcPatternEltValues(pe) FcPointerMember(pe,values,FcValueList) + struct _FcPattern { int num; int size; - FcPatternEltPtr elts; + intptr_t elts_offset; int ref; - int bank; }; +#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt) + +#define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *) +/* +#define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \ + FcOffsetToPtr(FcFontSetFonts(fs), \ + FcFontSetFonts(fs)[i]) : \ + fs->fonts[i])*/ + typedef enum _FcOp { FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet, FcOpNil, @@ -178,7 +229,7 @@ typedef struct _FcExpr { FcMatrix *mval; FcBool bval; FcCharSet *cval; - char *field; + FcObject object; FcChar8 *constant; struct { struct _FcExpr *left, *right; @@ -196,14 +247,14 @@ typedef struct _FcTest { struct _FcTest *next; FcMatchKind kind; FcQual qual; - const char *field; + FcObject object; FcOp op; FcExpr *expr; } FcTest; typedef struct _FcEdit { struct _FcEdit *next; - const char *field; + FcObject object; FcOp op; FcExpr *expr; FcValueBinding binding; @@ -224,19 +275,16 @@ typedef struct _FcCharLeaf { struct _FcCharSet { int ref; /* reference count */ int num; /* size of leaves and numbers arrays */ - int bank; - union { - struct { - int leafidx_offset; - int numbers_offset; - } stat; - struct { - FcCharLeaf **leaves; - FcChar16 *numbers; - } dyn; - } u; + intptr_t leaves_offset; + intptr_t numbers_offset; }; +#define FcCharSetLeaves(c) FcOffsetMember(c,leaves_offset,intptr_t) +#define FcCharSetLeaf(c,i) (FcOffsetToPtr(FcCharSetLeaves(c), \ + FcCharSetLeaves(c)[i], \ + FcCharLeaf)) +#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) + struct _FcStrSet { int ref; /* reference count */ int num; @@ -258,22 +306,36 @@ typedef struct _FcStrBuf { } FcStrBuf; typedef struct _FcCache { - int magic; /* FC_CACHE_MAGIC */ - int subdirs; /* number of subdir strings */ - off_t pos; /* position of data block in file */ - off_t count; /* number of bytes of data in block */ - int bank; /* bank ID */ - int pattern_count; /* number of FcPatterns */ - int patternelt_count; /* number of FcPatternElts */ - int valuelist_count; /* number of FcValueLists */ - int str_count; /* size of strings appearing as FcValues */ - int langset_count; /* number of FcLangSets */ - int charset_count; /* number of FcCharSets */ - int charset_numbers_count; - int charset_leaf_count; - int charset_leaf_idx_count; + int magic; /* FC_CACHE_MAGIC */ + off_t size; /* size of file */ + intptr_t dir; /* offset to dir name */ + intptr_t dirs; /* offset to subdirs */ + int dirs_count; /* number of subdir strings */ + intptr_t set; /* offset to font set */ } FcCache; +#define FcCacheDir(c) FcOffsetMember(c,dir,FcChar8) +#define FcCacheDirs(c) FcOffsetMember(c,dirs,intptr_t) +#define FcCacheSet(c) FcOffsetMember(c,set,FcFontSet) + +/* + * Used while constructing a directory cache object + */ + +#define FC_SERIALIZE_HASH_SIZE 8191 + +typedef struct _FcSerializeBucket { + struct _FcSerializeBucket *next; + const void *object; + intptr_t offset; +} FcSerializeBucket; + +typedef struct _FcSerialize { + intptr_t size; + void *linear; + FcSerializeBucket *buckets[FC_SERIALIZE_HASH_SIZE]; +} FcSerialize; + /* * To map adobe glyph names to unicode values, a precomputed hash * table is used @@ -317,15 +379,17 @@ typedef struct _FcCaseFold { #define FC_MAX_FILE_LEN 4096 -#define FC_STORAGE_STATIC 0x80 -#define fc_value_string(v) (((v)->type & FC_STORAGE_STATIC) ? ((FcChar8 *) v) + (v)->u.s_off : (v) -> u.s) -#define fc_value_charset(v) (((v)->type & FC_STORAGE_STATIC) ? (const FcCharSet *)(((char *) v) + (v)->u.c_off) : (v) -> u.c) -#define fc_value_langset(v) (((v)->type & FC_STORAGE_STATIC) ? (const FcLangSet *)(((char *) v) + (v)->u.l_off) : (v) -> u.l) -#define fc_storage_type(v) ((v)->type & ~FC_STORAGE_STATIC) +/* XXX remove these when we're ready */ + +#define fc_value_string(v) FcValueString(v) +#define fc_value_charset(v) FcValueCharSet(v) +#define fc_value_langset(v) FcValueLangSet(v) +#define fc_storage_type(v) ((v)->type) #define fc_alignof(type) offsetof (struct { char c; type member; }, member) -#define FC_CACHE_MAGIC 0xFC02FC04 +#define FC_CACHE_MAGIC 0xFC02FC04 +#define FC_CACHE_MAGIC_COPY 0xFC02FC05 struct _FcAtomic { FcChar8 *file; /* original file name */ @@ -428,19 +492,6 @@ FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs, FcBool FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config); - -extern int *_fcBankId, *_fcBankIdx; -int -FcCacheBankToIndexMTF (int bank); - -static inline int -FcCacheBankToIndex (int bank) -{ - return (_fcBankId[*_fcBankIdx] == bank) ? *_fcBankIdx : FcCacheBankToIndexMTF(bank); -} - -const char * -FcCacheFindBankDir (int bank); /* fccfg.c */ @@ -512,6 +563,33 @@ FcConfigAcceptFont (FcConfig *config, FcFileTime FcConfigModifiedTime (FcConfig *config); +intptr_t +FcAlignSize (intptr_t size); + +FcSerialize * +FcSerializeCreate (void); + +void +FcSerializeDestroy (FcSerialize *serialize); + +FcBool +FcSerializeAlloc (FcSerialize *serialize, const void *object, int size); + +intptr_t +FcSerializeReserve (FcSerialize *serialize, int size); + +intptr_t +FcSerializeOffset (FcSerialize *serialize, const void *object); + +void * +FcSerializePtr (FcSerialize *serialize, const void *object); + +FcBool +FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l); + +FcLangSet * +FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l); + /* fccharset.c */ void FcLangCharSetPopulate (void); @@ -531,27 +609,11 @@ FcNameParseCharSet (FcChar8 *string); FcCharLeaf * FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4); -void -FcCharSetNewBank (void); - -int -FcCharSetNeededBytes (const FcCharSet *c); - -int -FcCharSetNeededBytesAlign (void); - -void * -FcCharSetDistributeBytes (FcCache * metadata, - void * block_ptr); +FcBool +FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs); FcCharSet * -FcCharSetSerialize(int bank, FcCharSet *c); - -void * -FcCharSetUnserialize (FcCache * metadata, void *block_ptr); - -FcCharLeaf * -FcCharSetGetLeaf(const FcCharSet *c, int i); +FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs); FcChar16 * FcCharSetGetNumbers(const FcCharSet *c); @@ -578,6 +640,9 @@ FcEditPrint (const FcEdit *edit); void FcSubstPrint (const FcSubst *subst); +void +FcCharSetPrint (const FcCharSet *c); + extern int FcDebugVal; static inline int @@ -633,24 +698,12 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding); /* fcfs.c */ -void -FcFontSetNewBank (void); - -int -FcFontSetNeededBytes (FcFontSet *s); - -int -FcFontSetNeededBytesAlign (void); - -void * -FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr); - -FcBool -FcFontSetSerialize (int bank, FcFontSet * s); - FcBool -FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr); +FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s); +FcFontSet * +FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s); + /* fcgram.y */ int FcConfigparse (void); @@ -731,25 +784,6 @@ FcNameParseLangSet (const FcChar8 *string); FcBool FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls); -void -FcLangSetNewBank (void); - -int -FcLangSetNeededBytes (const FcLangSet *l); - -int -FcLangSetNeededBytesAlign (void); - -void * -FcLangSetDistributeBytes (FcCache * metadata, - void * block_ptr); - -FcLangSet * -FcLangSetSerialize (int bank, FcLangSet *l); - -void * -FcLangSetUnserialize (FcCache * metadata, void *block_ptr); - /* fclist.c */ FcBool @@ -760,36 +794,64 @@ FcListPatternMatchAny (const FcPattern *p, /* fcname.c */ -FcBool -FcNameBool (const FcChar8 *v, FcBool *result); - -void * -FcObjectDistributeBytes (FcCache * metadata, - void * block_ptr); - -FcObjectPtr -FcObjectToPtr (const char * si); +/* + * NOTE -- this ordering is part of the cache file format. + * It must also match the ordering in fcname.c + */ -int -FcObjectNeededBytes (void); +#define FC_FAMILY_OBJECT 1 +#define FC_FAMILYLANG_OBJECT 2 +#define FC_STYLE_OBJECT 3 +#define FC_STYLELANG_OBJECT 4 +#define FC_FULLNAME_OBJECT 5 +#define FC_FULLNAMELANG_OBJECT 6 +#define FC_SLANT_OBJECT 7 +#define FC_WEIGHT_OBJECT 8 +#define FC_WIDTH_OBJECT 9 +#define FC_SIZE_OBJECT 10 +#define FC_ASPECT_OBJECT 11 +#define FC_PIXEL_SIZE_OBJECT 12 +#define FC_SPACING_OBJECT 13 +#define FC_FOUNDRY_OBJECT 14 +#define FC_ANTIALIAS_OBJECT 15 +#define FC_HINT_STYLE_OBJECT 16 +#define FC_HINTING_OBJECT 17 +#define FC_VERTICAL_LAYOUT_OBJECT 18 +#define FC_AUTOHINT_OBJECT 19 +#define FC_GLOBAL_ADVANCE_OBJECT 20 +#define FC_FILE_OBJECT 21 +#define FC_INDEX_OBJECT 22 +#define FC_RASTERIZER_OBJECT 23 +#define FC_OUTLINE_OBJECT 24 +#define FC_SCALABLE_OBJECT 25 +#define FC_DPI_OBJECT 26 +#define FC_RGBA_OBJECT 27 +#define FC_SCALE_OBJECT 28 +#define FC_MINSPACE_OBJECT 29 +#define FC_CHAR_WIDTH_OBJECT 30 +#define FC_CHAR_HEIGHT_OBJECT 31 +#define FC_MATRIX_OBJECT 32 +#define FC_CHARSET_OBJECT 33 +#define FC_LANG_OBJECT 34 +#define FC_FONTVERSION_OBJECT 35 +#define FC_CAPABILITY_OBJECT 36 +#define FC_FONTFORMAT_OBJECT 37 +#define FC_EMBOLDEN_OBJECT 38 +#define FC_EMBEDDED_BITMAP_OBJECT 39 -int -FcObjectNeededBytesAlign (void); +FcBool +FcNameBool (const FcChar8 *v, FcBool *result); -void * -FcObjectUnserialize (FcCache * metadata, void *block_ptr); +FcBool +FcObjectValidType (FcObject object, FcType type); -void -FcObjectSerialize (void); +FcObject +FcObjectFromName (const char * name); const char * -FcObjectPtrU (FcObjectPtr p); +FcObjectName (FcObject object); -static inline int -FcObjectPtrCompare (const FcObjectPtr a, const FcObjectPtr b) -{ - return a - b; -} +#define FcObjectCompare(a, b) ((int) a - (int) b) void FcObjectStaticNameFini (void); @@ -803,73 +865,98 @@ void FcValueListDestroy (FcValueListPtr l); FcPatternElt * -FcPatternFindElt (const FcPattern *p, const char *object); +FcPatternObjectFindElt (const FcPattern *p, FcObject object); FcPatternElt * -FcPatternInsertElt (FcPattern *p, const char *object); +FcPatternObjectInsertElt (FcPattern *p, FcObject object); FcBool -FcPatternAddWithBinding (FcPattern *p, - const char *object, - FcValue value, - FcValueBinding binding, - FcBool append); +FcPatternObjectAddWithBinding (FcPattern *p, + FcObject object, + FcValue value, + FcValueBinding binding, + FcBool append); -void -FcPatternFini (void); +FcBool +FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append); + +FcBool +FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append); + +FcResult +FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v); + +FcBool +FcPatternObjectDel (FcPattern *p, FcObject object); FcBool -FcPatternAppend (FcPattern *p, FcPattern *s); +FcPatternObjectRemove (FcPattern *p, FcObject object, int id); -const FcChar8 * -FcStrStaticName (const FcChar8 *name); +FcBool +FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i); -FcChar32 -FcStringHash (const FcChar8 *s); +FcBool +FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d); -void -FcPatternNewBank (void); +FcBool +FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s); -int -FcPatternNeededBytes (FcPattern *p); +FcBool +FcPatternObjectAddMatrix (FcPattern *p, FcObject object, const FcMatrix *s); -int -FcPatternNeededBytesAlign (void); +FcBool +FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c); -void * -FcPatternDistributeBytes (FcCache * metadata, void * block_ptr); +FcBool +FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b); -/* please don't access these outside of fcpat.c! only visible so that - * *PtrU can be inlined. */ -extern FcValueList ** _fcValueLists; -extern FcPatternElt ** _fcPatternElts; +FcBool +FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls); + +FcResult +FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i); + +FcResult +FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int n, double *d); -static inline FcValueList * -FcValueListPtrU (FcValueListPtr pi) -{ - if (pi.bank == FC_BANK_DYNAMIC) - return pi.u.dyn; +FcResult +FcPatternObjectGetString (const FcPattern *p, FcObject object, int n, FcChar8 ** s); - return &_fcValueLists[FcCacheBankToIndex(pi.bank)][pi.u.stat]; -} +FcResult +FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s); -static inline FcPatternElt * -FcPatternEltU (FcPatternEltPtr pei) -{ - if (pei.bank == FC_BANK_DYNAMIC) - return pei.u.dyn; +FcResult +FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); - return &_fcPatternElts[FcCacheBankToIndex(pei.bank)][pei.u.stat]; -} +FcResult +FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); -FcValueListPtr -FcValueListPtrCreateDynamic(FcValueList * p); +FcResult +FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); + +void +FcPatternFini (void); + +FcBool +FcPatternAppend (FcPattern *p, FcPattern *s); + +const FcChar8 * +FcStrStaticName (const FcChar8 *name); + +FcChar32 +FcStringHash (const FcChar8 *s); + +FcBool +FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat); FcPattern * -FcPatternSerialize (int bank, FcPattern * p); +FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat); -void * -FcPatternUnserialize (FcCache * metadata, void *block_ptr); +FcBool +FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); + +FcValueList * +FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); /* fcrender.c */ @@ -929,4 +1016,10 @@ FcStrHashIgnoreCase (const FcChar8 *s); FcChar8 * FcStrCanonFilename (const FcChar8 *s); +FcBool +FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str); + +FcChar8 * +FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); + #endif /* _FC_INT_H_ */ diff --git a/src/fclang.c b/src/fclang.c index 552253d..f8f6f0b 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -44,8 +44,6 @@ struct _FcLangSet { #define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f))) #define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1) -static FcBool langsets_populated = FcFalse; - FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang) @@ -55,19 +53,26 @@ FcFreeTypeLangSet (const FcCharSet *charset, const FcCharSet *exclusiveCharset = 0; FcLangSet *ls; - if (!langsets_populated) - { - FcLangCharSetPopulate (); - langsets_populated = FcTrue; - } - if (exclusiveLang) exclusiveCharset = FcCharSetForLang (exclusiveLang); ls = FcLangSetCreate (); if (!ls) return 0; + if (FcDebug() & FC_DBG_LANGSET) + { + printf ("font charset\n"); + FcCharSetPrint (charset); + printf ("\n"); + } for (i = 0; i < NUM_LANG_CHAR_SET; i++) { + if (FcDebug() & FC_DBG_LANGSET) + { + printf ("%s charset\n", fcLangCharSets[i].lang); + FcCharSetPrint (&fcLangCharSets[i].charset); + printf ("\n"); + } + /* * Check for Han charsets to make fonts * which advertise support for a single language @@ -80,8 +85,8 @@ FcFreeTypeLangSet (const FcCharSet *charset, continue; for (j = 0; j < fcLangCharSets[i].charset.num; j++) - if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) != - FcCharSetGetLeaf(exclusiveCharset, j)) + if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != + FcCharSetLeaf(exclusiveCharset, j)) continue; } missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset); @@ -196,12 +201,6 @@ FcCharSetForLang (const FcChar8 *lang) int i; int country = -1; - if (!langsets_populated) - { - FcLangCharSetPopulate (); - langsets_populated = FcTrue; - } - for (i = 0; i < NUM_LANG_CHAR_SET; i++) { switch (FcLangCompare (lang, fcLangCharSets[i].lang)) { @@ -710,90 +709,21 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb) return FcTrue; } -static FcLangSet ** langsets = 0; -static int langset_bank_count = 0, langset_ptr = 0, langset_count = 0; - -void -FcLangSetNewBank (void) -{ - langset_count = 0; -} - -/* ideally, should only write one copy of any particular FcLangSet */ -int -FcLangSetNeededBytes (const FcLangSet *l) -{ - langset_count++; - return sizeof (FcLangSet); -} - -int -FcLangSetNeededBytesAlign (void) -{ - return fc_alignof (FcLangSet); -} - -static FcBool -FcLangSetEnsureBank (int bi) +FcBool +FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l) { - if (!langsets || bi >= langset_bank_count) - { - int new_count = langset_bank_count + 2; - int i; - FcLangSet** tt; - tt = realloc(langsets, new_count * sizeof(FcLangSet *)); - if (!tt) - return FcFalse; - - langsets = tt; - for (i = langset_bank_count; i < new_count; i++) - langsets[i] = 0; - langset_bank_count = new_count; - } - + if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet))) + return FcFalse; return FcTrue; } -void * -FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcLangSetEnsureBank(bi)) - return 0; - - block_ptr = ALIGN(block_ptr, FcLangSet); - langsets[bi] = block_ptr; - block_ptr = (void *)((char *)block_ptr + - langset_count * sizeof(FcLangSet)); - langset_ptr = 0; - metadata->langset_count = langset_count; - return block_ptr; -} - FcLangSet * -FcLangSetSerialize(int bank, FcLangSet *l) -{ - int p = langset_ptr, bi = FcCacheBankToIndex(bank); - - if (!l) return 0; - - langsets[bi][langset_ptr] = *l; - langsets[bi][langset_ptr].extra = 0; - langset_ptr++; - return &langsets[bi][p]; -} - -void * -FcLangSetUnserialize (FcCache * metadata, void *block_ptr) +FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l) { - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcLangSetEnsureBank(bi)) - return 0; + FcLangSet *l_serialize = FcSerializePtr (serialize, l); - FcMemAlloc (FC_MEM_LANGSET, metadata->langset_count * sizeof(FcLangSet)); - block_ptr = ALIGN(block_ptr, FcLangSet); - langsets[bi] = (FcLangSet *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - metadata->langset_count * sizeof(FcLangSet)); - return block_ptr; + if (!l_serialize) + return NULL; + *l_serialize = *l; + return l_serialize; } diff --git a/src/fclist.c b/src/fclist.c index 9aef842..c0b7fb0 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -130,23 +130,21 @@ FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */ { FcValueListPtr pat, fnt; - for (pat = patOrig; FcValueListPtrU(pat); - pat = FcValueListPtrU(pat)->next) + for (pat = patOrig; pat != NULL; pat = FcValueListNext(pat)) { - for (fnt = fntOrig; FcValueListPtrU(fnt); - fnt = FcValueListPtrU(fnt)->next) + for (fnt = fntOrig; fnt != NULL; fnt = FcValueListNext(fnt)) { /* * make sure the font 'contains' the pattern. * (OpListing is OpContains except for strings * where it requires an exact match) */ - if (FcConfigCompareValue (&FcValueListPtrU(fnt)->value, + if (FcConfigCompareValue (&fnt->value, FcOpListing, - &FcValueListPtrU(pat)->value)) + &pat->value)) break; } - if (!FcValueListPtrU(fnt)) + if (fnt == NULL) return FcFalse; } return FcTrue; @@ -158,26 +156,22 @@ FcListValueListEqual (FcValueListPtr v1orig, { FcValueListPtr v1, v2; - for (v1 = v1orig; FcValueListPtrU(v1); - v1 = FcValueListPtrU(v1)->next) + for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1)) { - for (v2 = v2orig; FcValueListPtrU(v2); - v2 = FcValueListPtrU(v2)->next) - if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value), - FcValueCanonicalize(&FcValueListPtrU(v2)->value))) + for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2)) + if (FcValueEqual (FcValueCanonicalize(&(v1)->value), + FcValueCanonicalize(&(v2)->value))) break; - if (!FcValueListPtrU(v2)) + if (v2 == NULL) return FcFalse; } - for (v2 = v2orig; FcValueListPtrU(v2); - v2 = FcValueListPtrU(v2)->next) + for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2)) { - for (v1 = v1orig; FcValueListPtrU(v1); - v1 = FcValueListPtrU(v1)->next) - if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value), - FcValueCanonicalize(&FcValueListPtrU(v2)->value))) + for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1)) + if (FcValueEqual (FcValueCanonicalize(&v1->value), + FcValueCanonicalize(&v2->value))) break; - if (!FcValueListPtrU(v1)) + if (v1 == NULL) return FcFalse; } return FcTrue; @@ -193,13 +187,14 @@ FcListPatternEqual (FcPattern *p1, for (i = 0; i < os->nobject; i++) { - e1 = FcPatternFindElt (p1, os->objects[i]); - e2 = FcPatternFindElt (p2, os->objects[i]); + e1 = FcPatternObjectFindElt (p1, FcObjectFromName (os->objects[i])); + e2 = FcPatternObjectFindElt (p2, FcObjectFromName (os->objects[i])); if (!e1 && !e2) continue; if (!e1 || !e2) return FcFalse; - if (!FcListValueListEqual (e1->values, e2->values)) + if (!FcListValueListEqual (FcPatternEltValues(e1), + FcPatternEltValues(e2))) return FcFalse; } return FcTrue; @@ -214,16 +209,15 @@ FcListPatternMatchAny (const FcPattern *p, const FcPattern *font) { int i; - FcPatternElt *e; for (i = 0; i < p->num; i++) { - e = FcPatternFindElt (font, - FcObjectPtrU((FcPatternEltU(p->elts)+i)->object)); - if (!e) + FcPatternElt *pe = &FcPatternElts(p)[i]; + FcPatternElt *fe = FcPatternObjectFindElt (font, pe->object); + if (!fe) return FcFalse; - if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values, /* pat elts */ - e->values)) /* font elts */ + if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */ + FcPatternEltValues(fe))) /* font elts */ return FcFalse; } return FcTrue; @@ -272,10 +266,10 @@ FcListValueListHash (FcValueListPtr list) { FcChar32 h = 0; - while (FcValueListPtrU(list)) + while (list != NULL) { - h = h ^ FcListValueHash (&FcValueListPtrU(list)->value); - list = FcValueListPtrU(list)->next; + h = h ^ FcListValueHash (&list->value); + list = FcValueListNext(list); } return h; } @@ -290,9 +284,9 @@ FcListPatternHash (FcPattern *font, for (n = 0; n < os->nobject; n++) { - e = FcPatternFindElt (font, os->objects[n]); + e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n])); if (e) - h = h ^ FcListValueListHash (e->values); + h = h ^ FcListValueListHash (FcPatternEltValues(e)); } return h; } @@ -338,10 +332,10 @@ FcListHashTableCleanup (FcListHashTable *table) } static int -FcGetDefaultObjectLangIndex (FcPattern *font, const char *object) +FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object) { FcChar8 *lang = FcGetDefaultLang (); - FcPatternElt *e = FcPatternFindElt (font, object); + FcPatternElt *e = FcPatternObjectFindElt (font, object); FcValueListPtr v; FcValue value; int idx = -1; @@ -349,9 +343,9 @@ FcGetDefaultObjectLangIndex (FcPattern *font, const char *object) if (e) { - for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i) + for (v = FcPatternEltValues(e), i = 0; v; v = FcValueListNext(v), ++i) { - value = FcValueCanonicalize (&FcValueListPtrU (v)->value); + value = FcValueCanonicalize (&v->value); if (value.type == FcTypeString) { @@ -404,33 +398,33 @@ FcListAppend (FcListHashTable *table, if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG)) { if (familyidx < 0) - familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG); + familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT); defidx = familyidx; } else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG)) { if (fullnameidx < 0) - fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG); + fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT); defidx = fullnameidx; } else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG)) { if (styleidx < 0) - styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG); + styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT); defidx = styleidx; } else defidx = 0; - e = FcPatternFindElt (font, os->objects[o]); + e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o])); if (e) { - for (v = e->values, idx = 0; FcValueListPtrU(v); - v = FcValueListPtrU(v)->next, ++idx) + for (v = FcPatternEltValues(e), idx = 0; v; + v = FcValueListNext(v), ++idx) { if (!FcPatternAdd (bucket->pattern, os->objects[o], - FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx)) + FcValueCanonicalize(&v->value), defidx != idx)) goto bail2; } } diff --git a/src/fcmatch.c b/src/fcmatch.c index 739ef3e..7e3353b 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -173,8 +173,7 @@ FcCompareSize (FcValue *value1, FcValue *value2) } typedef struct _FcMatcher { - const char *object; - FcObjectPtr objectPtr; + FcObject object; double (*compare) (FcValue *value1, FcValue *value2); int strong, weak; } FcMatcher; @@ -185,156 +184,111 @@ typedef struct _FcMatcher { * later values */ static FcMatcher _FcMatchers [] = { - { FC_FOUNDRY, 0, FcCompareString, 0, 0 }, + { FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 }, #define MATCH_FOUNDRY 0 #define MATCH_FOUNDRY_INDEX 0 - { FC_CHARSET, 0, FcCompareCharSet, 1, 1 }, + { FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 }, #define MATCH_CHARSET 1 #define MATCH_CHARSET_INDEX 1 - { FC_FAMILY, 0, FcCompareFamily, 2, 4 }, + { FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 }, #define MATCH_FAMILY 2 #define MATCH_FAMILY_STRONG_INDEX 2 #define MATCH_FAMILY_WEAK_INDEX 4 - { FC_LANG, 0, FcCompareLang, 3, 3 }, + { FC_LANG_OBJECT, FcCompareLang, 3, 3 }, #define MATCH_LANG 3 #define MATCH_LANG_INDEX 3 - { FC_SPACING, 0, FcCompareNumber, 5, 5 }, + { FC_SPACING_OBJECT, FcCompareNumber, 5, 5 }, #define MATCH_SPACING 4 #define MATCH_SPACING_INDEX 5 - { FC_PIXEL_SIZE, 0, FcCompareSize, 6, 6 }, + { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 }, #define MATCH_PIXEL_SIZE 5 #define MATCH_PIXEL_SIZE_INDEX 6 - { FC_STYLE, 0, FcCompareString, 7, 7 }, + { FC_STYLE_OBJECT, FcCompareString, 7, 7 }, #define MATCH_STYLE 6 #define MATCH_STYLE_INDEX 7 - { FC_SLANT, 0, FcCompareNumber, 8, 8 }, + { FC_SLANT_OBJECT, FcCompareNumber, 8, 8 }, #define MATCH_SLANT 7 #define MATCH_SLANT_INDEX 8 - { FC_WEIGHT, 0, FcCompareNumber, 9, 9 }, + { FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 }, #define MATCH_WEIGHT 8 #define MATCH_WEIGHT_INDEX 9 - { FC_WIDTH, 0, FcCompareNumber, 10, 10 }, + { FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 }, #define MATCH_WIDTH 9 #define MATCH_WIDTH_INDEX 10 - { FC_ANTIALIAS, 0, FcCompareBool, 11, 11 }, + { FC_ANTIALIAS_OBJECT, FcCompareBool, 11, 11 }, #define MATCH_ANTIALIAS 10 #define MATCH_ANTIALIAS_INDEX 11 - { FC_RASTERIZER, 0, FcCompareString, 12, 12 }, + { FC_RASTERIZER_OBJECT, FcCompareString, 12, 12 }, #define MATCH_RASTERIZER 11 #define MATCH_RASTERIZER_INDEX 12 - { FC_OUTLINE, 0, FcCompareBool, 13, 13 }, + { FC_OUTLINE_OBJECT, FcCompareBool, 13, 13 }, #define MATCH_OUTLINE 12 #define MATCH_OUTLINE_INDEX 13 - { FC_FONTVERSION, 0, FcCompareNumber, 14, 14 }, + { FC_FONTVERSION_OBJECT, FcCompareNumber, 14, 14 }, #define MATCH_FONTVERSION 13 #define MATCH_FONTVERSION_INDEX 14 }; #define NUM_MATCH_VALUES 15 -static FcBool matchObjectPtrsInit = FcFalse; - -static void -FcMatchObjectPtrsInit (void) -{ - _FcMatchers[MATCH_FOUNDRY].objectPtr = FcObjectToPtr(FC_FOUNDRY); - _FcMatchers[MATCH_CHARSET].objectPtr = FcObjectToPtr(FC_CHARSET); - _FcMatchers[MATCH_FAMILY].objectPtr = FcObjectToPtr(FC_FAMILY); - _FcMatchers[MATCH_LANG].objectPtr = FcObjectToPtr(FC_LANG); - _FcMatchers[MATCH_SPACING].objectPtr = FcObjectToPtr(FC_SPACING); - _FcMatchers[MATCH_PIXEL_SIZE].objectPtr = FcObjectToPtr(FC_PIXEL_SIZE); - _FcMatchers[MATCH_STYLE].objectPtr = FcObjectToPtr(FC_STYLE); - _FcMatchers[MATCH_SLANT].objectPtr = FcObjectToPtr(FC_SLANT); - _FcMatchers[MATCH_WEIGHT].objectPtr = FcObjectToPtr(FC_WEIGHT); - _FcMatchers[MATCH_WIDTH].objectPtr = FcObjectToPtr(FC_WIDTH); - _FcMatchers[MATCH_ANTIALIAS].objectPtr = FcObjectToPtr(FC_ANTIALIAS); - _FcMatchers[MATCH_RASTERIZER].objectPtr = FcObjectToPtr(FC_RASTERIZER); - _FcMatchers[MATCH_OUTLINE].objectPtr = FcObjectToPtr(FC_OUTLINE); - _FcMatchers[MATCH_FONTVERSION].objectPtr = FcObjectToPtr(FC_FONTVERSION); - matchObjectPtrsInit = FcTrue; -} - static FcMatcher* -FcObjectPtrToMatcher (FcObjectPtr o) +FcObjectToMatcher (FcObject object) { int i; - const char *object = FcObjectPtrU(o); i = -1; - switch (object[0]) { - case 'f': - switch (object[1]) { - case 'o': - switch (object[2]) { - case 'u': - i = MATCH_FOUNDRY; break; - case 'n': - i = MATCH_FONTVERSION; break; - } - break; - case 'a': - i = MATCH_FAMILY; break; - } - break; - case 'c': + switch (object) { + case FC_FOUNDRY_OBJECT: + i = MATCH_FOUNDRY; break; + case FC_FONTVERSION_OBJECT: + i = MATCH_FONTVERSION; break; + case FC_FAMILY_OBJECT: + i = MATCH_FAMILY; break; + case FC_CHARSET_OBJECT: i = MATCH_CHARSET; break; - case 'a': + case FC_ANTIALIAS_OBJECT: i = MATCH_ANTIALIAS; break; - case 'l': + case FC_LANG_OBJECT: i = MATCH_LANG; break; - case 's': - switch (object[1]) { - case 'p': - i = MATCH_SPACING; break; - case 't': - i = MATCH_STYLE; break; - case 'l': - i = MATCH_SLANT; break; - } - break; - case 'p': + case FC_SPACING_OBJECT: + i = MATCH_SPACING; break; + case FC_STYLE_OBJECT: + i = MATCH_STYLE; break; + case FC_SLANT_OBJECT: + i = MATCH_SLANT; break; + case FC_PIXEL_SIZE_OBJECT: i = MATCH_PIXEL_SIZE; break; - case 'w': - switch (object[1]) { - case 'i': - i = MATCH_WIDTH; break; - case 'e': - i = MATCH_WEIGHT; break; - } - break; - case 'r': + case FC_WIDTH_OBJECT: + i = MATCH_WIDTH; break; + case FC_WEIGHT_OBJECT: + i = MATCH_WEIGHT; break; + case FC_RASTERIZER_OBJECT: i = MATCH_RASTERIZER; break; - case 'o': + case FC_OUTLINE_OBJECT: i = MATCH_OUTLINE; break; } if (i < 0) - return 0; - - if (!matchObjectPtrsInit) - FcMatchObjectPtrsInit(); - - if (o != _FcMatchers[i].objectPtr) - return 0; + return NULL; return _FcMatchers+i; } static FcBool -FcCompareValueList (FcObjectPtr o, +FcCompareValueList (FcObject object, FcValueListPtr v1orig, /* pattern */ FcValueListPtr v2orig, /* target */ FcValue *bestValue, @@ -342,16 +296,14 @@ FcCompareValueList (FcObjectPtr o, FcResult *result) { FcValueListPtr v1, v2; - FcValueList *v1_ptrU, *v2_ptrU; double v, best, bestStrong, bestWeak; int j; - const char *object = FcObjectPtrU(o); - FcMatcher *match = FcObjectPtrToMatcher(o); + FcMatcher *match = FcObjectToMatcher(object); if (!match) { if (bestValue) - *bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value); + *bestValue = FcValueCanonicalize(&v2orig->value); return FcTrue; } @@ -359,13 +311,11 @@ FcCompareValueList (FcObjectPtr o, bestStrong = 1e99; bestWeak = 1e99; j = 0; - for (v1 = v1orig, v1_ptrU = FcValueListPtrU(v1); v1_ptrU; - v1 = v1_ptrU->next, v1_ptrU = FcValueListPtrU(v1)) + for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) { - for (v2 = v2orig, v2_ptrU = FcValueListPtrU(v2); v2_ptrU; - v2 = v2_ptrU->next, v2_ptrU = FcValueListPtrU(v2)) + for (v2 = v1orig; v2; v2 = FcValueListNext(v2)) { - v = (match->compare) (&v1_ptrU->value, &v2_ptrU->value); + v = (match->compare) (&v1->value, &v2->value); if (v < 0) { *result = FcResultTypeMismatch; @@ -375,10 +325,10 @@ FcCompareValueList (FcObjectPtr o, if (v < best) { if (bestValue) - *bestValue = FcValueCanonicalize(&v2_ptrU->value); + *bestValue = FcValueCanonicalize(&v2->value); best = v; } - if (v1_ptrU->binding == FcValueBindingStrong) + if (v1->binding == FcValueBindingStrong) { if (v < bestStrong) bestStrong = v; @@ -393,7 +343,7 @@ FcCompareValueList (FcObjectPtr o, } if (FcDebug () & FC_DBG_MATCHV) { - printf (" %s: %g ", object, best); + printf (" %s: %g ", FcObjectName (object), best); FcValueListPrint (v1orig); printf (", "); FcValueListPrint (v2orig); @@ -434,10 +384,10 @@ FcCompare (FcPattern *pat, i2 = 0; while (i1 < pat->num && i2 < fnt->num) { - FcPatternElt *elt_i1 = FcPatternEltU(pat->elts)+i1; - FcPatternElt *elt_i2 = FcPatternEltU(fnt->elts)+i2; + FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1]; + FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2]; - i = FcObjectPtrCompare(elt_i1->object, elt_i2->object); + i = FcObjectCompare(elt_i1->object, elt_i2->object); if (i > 0) i2++; else if (i < 0) @@ -445,7 +395,8 @@ FcCompare (FcPattern *pat, else { if (!FcCompareValueList (elt_i1->object, - elt_i1->values, elt_i2->values, + FcPatternEltValues(elt_i1), + FcPatternEltValues(elt_i2), 0, value, result)) return FcFalse; i1++; @@ -471,28 +422,30 @@ FcFontRenderPrepare (FcConfig *config, return 0; for (i = 0; i < font->num; i++) { - fe = FcPatternEltU(font->elts)+i; - pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object)); + fe = &FcPatternElts(font)[i]; + pe = FcPatternObjectFindElt (pat, fe->object); if (pe) { - if (!FcCompareValueList (pe->object, pe->values, - fe->values, &v, 0, &result)) + if (!FcCompareValueList (pe->object, FcPatternEltValues(pe), + FcPatternEltValues(fe), &v, 0, &result)) { FcPatternDestroy (new); return 0; } } else - v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value); - FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse); + v = FcValueCanonicalize(&FcPatternEltValues (fe)->value); + FcPatternObjectAdd (new, fe->object, v, FcFalse); } for (i = 0; i < pat->num; i++) { - pe = FcPatternEltU(pat->elts)+i; - fe = FcPatternFindElt (font, FcObjectPtrU(pe->object)); + pe = &FcPatternElts(pat)[i]; + fe = FcPatternObjectFindElt (font, pe->object); if (!fe) - FcPatternAdd (new, FcObjectPtrU(pe->object), - FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue); + { + v = FcValueCanonicalize(&FcPatternEltValues(pe)->value); + FcPatternObjectAdd (new, pe->object, v, FcTrue); + } } FcConfigSubstituteWithPat (config, new, pat, FcMatchFont); diff --git a/src/fcname.c b/src/fcname.c index a5c8fee..96adc62 100644 --- a/src/fcname.c +++ b/src/fcname.c @@ -30,7 +30,7 @@ /* Please do not revoke any of these bindings. */ /* The __DUMMY__ object enables callers to distinguish the error return - * of FcObjectToPtrLookup from FC_FAMILY's FcObjectPtr, which would + * of FcObjectToPtrLookup from FC_FAMILY's FcObject, which would * otherwise be 0. */ static const FcObjectType _FcBaseObjectTypes[] = { { "__DUMMY__", FcTypeVoid, }, @@ -48,14 +48,12 @@ static const FcObjectType _FcBaseObjectTypes[] = { { FC_PIXEL_SIZE, FcTypeDouble, }, { FC_SPACING, FcTypeInteger, }, { FC_FOUNDRY, FcTypeString, }, -/* { FC_CORE, FcTypeBool, }, */ { FC_ANTIALIAS, FcTypeBool, }, { FC_HINT_STYLE, FcTypeInteger, }, { FC_HINTING, FcTypeBool, }, { FC_VERTICAL_LAYOUT, FcTypeBool, }, { FC_AUTOHINT, FcTypeBool, }, { FC_GLOBAL_ADVANCE, FcTypeBool, }, -/* { FC_XLFD, FcTypeString, }, */ { FC_FILE, FcTypeString, }, { FC_INDEX, FcTypeInteger, }, { FC_RASTERIZER, FcTypeString, }, @@ -65,7 +63,6 @@ static const FcObjectType _FcBaseObjectTypes[] = { { FC_RGBA, FcTypeInteger, }, { FC_SCALE, FcTypeDouble, }, { FC_MINSPACE, FcTypeBool, }, -/* { FC_RENDER, FcTypeBool, },*/ { FC_CHAR_WIDTH, FcTypeInteger }, { FC_CHAR_HEIGHT, FcTypeInteger }, { FC_MATRIX, FcTypeMatrix }, @@ -182,16 +179,13 @@ static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; /* Design constraint: biggest_known_ntypes must never change * after any call to FcNameRegisterObjectTypes. */ static const FcObjectType *biggest_known_types = _FcBaseObjectTypes; -static FcBool allocated_biggest_known_types; static int biggest_known_ntypes = NUM_OBJECT_TYPES; -static int biggest_known_count = 0; -static char * biggest_ptr; -static FcObjectPtr +static FcObject FcObjectToPtrLookup (const char * object) { - FcObjectPtr i = 0, n; + FcObject i = 0, n; const FcObjectTypeList *l; FcObjectType *t = _FcUserObjectNames; FcBool replace; @@ -251,8 +245,16 @@ FcObjectToPtrLookup (const char * object) return -n; } -FcObjectPtr -FcObjectToPtr (const char * name) +FcBool +FcObjectValidType (FcObject object, FcType type) +{ + if (object < NUM_OBJECT_TYPES && _FcBaseObjectTypes[object].type != type) + return FcFalse; + return FcTrue; +} + +FcObject +FcObjectFromName (const char * name) { FcChar32 hash = FcStringHash ((const FcChar8 *) name); struct objectBucket **p; @@ -299,112 +301,24 @@ FcObjectStaticNameFini (void) } const char * -FcObjectPtrU (FcObjectPtr si) +FcObjectName (FcObject object) { const FcObjectTypeList *l; int i, j; - if (si > 0) + if (object > 0) { - if (si < biggest_known_ntypes) - return biggest_known_types[si].object; + if (object < biggest_known_ntypes) + return biggest_known_types[object].object; j = 0; for (l = _FcObjectTypes; l; l = l->next) for (i = 0; i < l->ntypes; i++, j++) - if (j == si) + if (j == object) return l->types[i].object; } - return _FcUserObjectNames[-si].object; -} - -int -FcObjectNeededBytes () -{ - int num = 0, i; - for (i = 0; i < biggest_known_ntypes; i++) - { - const char * t = biggest_known_types[i].object; - num = num + strlen(t) + 1; - } - biggest_known_count = num; - return num + sizeof(int); -} - -int -FcObjectNeededBytesAlign (void) -{ - return fc_alignof (int) + fc_alignof (char); -} - -void * -FcObjectDistributeBytes (FcCache * metadata, void * block_ptr) -{ - block_ptr = ALIGN (block_ptr, int); - *(int *)block_ptr = biggest_known_ntypes; - block_ptr = (int *) block_ptr + 1; - block_ptr = ALIGN (block_ptr, char); - biggest_ptr = block_ptr; - block_ptr = (char *) block_ptr + biggest_known_count; - return block_ptr; -} - -void -FcObjectSerialize (void) -{ - int i; - for (i = 0; i < biggest_known_ntypes; i++) - { - const char * t = biggest_known_types[i].object; - strcpy (biggest_ptr, t); - biggest_ptr = biggest_ptr + strlen(t) + 1; - } -} - -void * -FcObjectUnserialize (FcCache * metadata, void *block_ptr) -{ - int new_biggest; - block_ptr = ALIGN (block_ptr, int); - new_biggest = *(int *)block_ptr; - block_ptr = (int *) block_ptr + 1; - if (biggest_known_ntypes < new_biggest) - { - int i; - char * bp = (char *)block_ptr; - FcObjectType * bn; - - bn = malloc (sizeof (const FcObjectType) * (new_biggest + 1)); - if (!bn) - return 0; - - for (i = 0; i < new_biggest; i++) - { - const FcObjectType * t = FcNameGetObjectType(bp); - if (t) - bn[i].type = t->type; - else - bn[i].type = FcTypeVoid; - bn[i].object = bp; - bp = bp + strlen(bp) + 1; - } - - FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse); - if (allocated_biggest_known_types) - { - free ((FcObjectTypeList *)biggest_known_types); - } - else - allocated_biggest_known_types = FcTrue; - - FcNameRegisterObjectTypes (bn, new_biggest); - biggest_known_ntypes = new_biggest; - biggest_known_types = (const FcObjectType *)bn; - } - block_ptr = ALIGN (block_ptr, char); - block_ptr = (char *) block_ptr + biggest_known_count; - return block_ptr; + return _FcUserObjectNames[-object].object; } static const FcConstant _FcBaseConstants[] = { @@ -803,11 +717,11 @@ FcNameUnparseValueList (FcStrBuf *buf, FcValueListPtr v, FcChar8 *escape) { - while (FcValueListPtrU(v)) + while (v) { - if (!FcNameUnparseValue (buf, &FcValueListPtrU(v)->value, escape)) + if (!FcNameUnparseValue (buf, &v->value, escape)) return FcFalse; - if (FcValueListPtrU(v = FcValueListPtrU(v)->next)) + if ((v = FcValueListNext(v)) != NULL) if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) return FcFalse; } @@ -834,18 +748,18 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) const FcObjectType *o; FcStrBufInit (&buf, buf_static, sizeof (buf_static)); - e = FcPatternFindElt (pat, FC_FAMILY); + e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); if (e) { - if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) + if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) goto bail0; } - e = FcPatternFindElt (pat, FC_SIZE); + e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); if (e) { if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) goto bail0; - if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) + if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) goto bail0; } for (l = _FcObjectTypes; l; l = l->next) @@ -858,7 +772,7 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) !strcmp (o->object, FC_FILE)) continue; - e = FcPatternFindElt (pat, o->object); + e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); if (e) { if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) @@ -867,7 +781,7 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) goto bail0; if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) goto bail0; - if (!FcNameUnparseValueList (&buf, e->values, escape ? + if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) goto bail0; } diff --git a/src/fcpat.c b/src/fcpat.c index da1d490..7432745 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -1,6 +1,4 @@ /* - * $RCSId: xc/lib/fontconfig/src/fcpat.c,v 1.18 2002/09/18 17:11:46 tsi Exp $ - * * Copyright © 2000 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -27,15 +25,6 @@ #include <string.h> #include <assert.h> -static FcPattern ** _fcPatterns = 0; -static int fcpattern_bank_count = 0, fcpattern_ptr, fcpattern_count; -FcPatternElt ** _fcPatternElts = 0; -static int fcpatternelt_ptr, fcpatternelt_count; -FcValueList ** _fcValueLists = 0; -static int fcvaluelist_bank_count = 0, fcvaluelist_ptr, fcvaluelist_count; - -static FcPatternEltPtr -FcPatternEltPtrCreateDynamic (FcPatternElt * e); static FcBool FcStrHashed (const FcChar8 *name); @@ -50,8 +39,7 @@ FcPatternCreate (void) FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern)); p->num = 0; p->size = 0; - p->elts = FcPatternEltPtrCreateDynamic(0); - p->bank = FC_BANK_DYNAMIC; + p->elts_offset = FcPtrToOffset (p, NULL); p->ref = 1; return p; } @@ -81,28 +69,27 @@ FcValueDestroy (FcValue v) FcValue FcValueCanonicalize (const FcValue *v) { - if (v->type & FC_STORAGE_STATIC) - { - FcValue new = *v; + FcValue new; - switch (v->type & ~FC_STORAGE_STATIC) - { - case FcTypeString: - new.u.s = fc_value_string(v); - new.type = FcTypeString; - break; - case FcTypeCharSet: - new.u.c = fc_value_charset(v); - new.type = FcTypeCharSet; - break; - case FcTypeLangSet: - new.u.l = fc_value_langset(v); - new.type = FcTypeLangSet; - break; - } - return new; + switch (v->type) + { + case FcTypeString: + new.u.s = fc_value_string(v); + new.type = FcTypeString; + break; + case FcTypeCharSet: + new.u.c = fc_value_charset(v); + new.type = FcTypeCharSet; + break; + case FcTypeLangSet: + new.u.l = fc_value_langset(v); + new.type = FcTypeLangSet; + break; + default: + new = *v; + break; } - return *v; + return new; } FcValue @@ -139,31 +126,30 @@ void FcValueListDestroy (FcValueListPtr l) { FcValueListPtr next; - for (; FcValueListPtrU(l); l = next) + for (; l; l = next) { - switch (FcValueListPtrU(l)->value.type) { + switch (l->value.type) { case FcTypeString: - if (!FcStrHashed ((FcChar8 *)FcValueListPtrU(l)->value.u.s)) - FcStrFree ((FcChar8 *)FcValueListPtrU(l)->value.u.s); + if (!FcStrHashed ((FcChar8 *)l->value.u.s)) + FcStrFree ((FcChar8 *)l->value.u.s); break; case FcTypeMatrix: - FcMatrixFree ((FcMatrix *)FcValueListPtrU(l)->value.u.m); + FcMatrixFree ((FcMatrix *)l->value.u.m); break; case FcTypeCharSet: FcCharSetDestroy - ((FcCharSet *) (FcValueListPtrU(l)->value.u.c)); + ((FcCharSet *) (l->value.u.c)); break; case FcTypeLangSet: FcLangSetDestroy - ((FcLangSet *) (FcValueListPtrU(l)->value.u.l)); + ((FcLangSet *) (l->value.u.l)); break; default: break; } - next = FcValueListPtrU(l)->next; + next = FcValueListNext(l); FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); - if (l.bank == FC_BANK_DYNAMIC) - free(l.u.dyn); + free(l); } } @@ -263,18 +249,17 @@ FcValueHash (const FcValue *v) static FcBool FcValueListEqual (FcValueListPtr la, FcValueListPtr lb) { - if (FcValueListPtrU(la) == FcValueListPtrU(lb)) + if (la == lb) return FcTrue; - while (FcValueListPtrU(la) && FcValueListPtrU(lb)) + while (la && lb) { - if (!FcValueEqual (FcValueListPtrU(la)->value, - FcValueListPtrU(lb)->value)) + if (!FcValueEqual (la->value, lb->value)) return FcFalse; - la = FcValueListPtrU(la)->next; - lb = FcValueListPtrU(lb)->next; + la = FcValueListNext(la); + lb = FcValueListNext(lb); } - if (FcValueListPtrU(la) || FcValueListPtrU(lb)) + if (la || lb) return FcFalse; return FcTrue; } @@ -283,12 +268,10 @@ static FcChar32 FcValueListHash (FcValueListPtr l) { FcChar32 hash = 0; - FcValueList *l_ptrU; - for (l_ptrU = FcValueListPtrU(l); l_ptrU; - l_ptrU = FcValueListPtrU(l_ptrU->next)) + for (; l; l = FcValueListNext(l)) { - hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l_ptrU->value); + hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value); } return hash; } @@ -297,32 +280,27 @@ void FcPatternDestroy (FcPattern *p) { int i; + FcPatternElt *elts; if (p->ref == FC_REF_CONSTANT || --p->ref > 0) return; + elts = FcPatternElts (p); for (i = 0; i < p->num; i++) - FcValueListDestroy ((FcPatternEltU(p->elts)+i)->values); + FcValueListDestroy (FcPatternEltValues(&elts[i])); - p->num = 0; - if (FcPatternEltU(p->elts) && p->elts.bank == FC_BANK_DYNAMIC) - { - FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt)); - free (FcPatternEltU(p->elts)); - p->elts = FcPatternEltPtrCreateDynamic(0); - } - p->size = 0; + FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt)); + free (elts); FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern)); free (p); } static int -FcPatternPosition (const FcPattern *p, const char *object) +FcPatternObjectPosition (const FcPattern *p, FcObject object) { int low, high, mid, c; - FcObjectPtr obj; + FcPatternElt *elts = FcPatternElts(p); - obj = FcObjectToPtr(object); low = 0; high = p->num - 1; c = 1; @@ -330,7 +308,7 @@ FcPatternPosition (const FcPattern *p, const char *object) while (low <= high) { mid = (low + high) >> 1; - c = FcObjectPtrCompare((FcPatternEltU(p->elts)+mid)->object, obj); + c = elts[mid].object - object; if (c == 0) return mid; if (c < 0) @@ -344,21 +322,21 @@ FcPatternPosition (const FcPattern *p, const char *object) } FcPatternElt * -FcPatternFindElt (const FcPattern *p, const char *object) +FcPatternObjectFindElt (const FcPattern *p, FcObject object) { - int i = FcPatternPosition (p, object); + int i = FcPatternObjectPosition (p, object); if (i < 0) return 0; - return FcPatternEltU(p->elts)+i; + return &FcPatternElts(p)[i]; } FcPatternElt * -FcPatternInsertElt (FcPattern *p, const char *object) +FcPatternObjectInsertElt (FcPattern *p, FcObject object) { int i; FcPatternElt *e; - i = FcPatternPosition (p, object); + i = FcPatternObjectPosition (p, object); if (i < 0) { i = -i - 1; @@ -367,9 +345,9 @@ FcPatternInsertElt (FcPattern *p, const char *object) if (p->num + 1 >= p->size) { int s = p->size + 16; - if (FcPatternEltU(p->elts)) + if (p->size) { - FcPatternElt *e0 = FcPatternEltU(p->elts); + FcPatternElt *e0 = FcPatternElts(p); e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt)); if (!e) /* maybe it was mmapped */ { @@ -382,52 +360,54 @@ FcPatternInsertElt (FcPattern *p, const char *object) e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt)); if (!e) return FcFalse; - p->elts = FcPatternEltPtrCreateDynamic(e); + p->elts_offset = FcPtrToOffset (p, e); if (p->size) FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt)); FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt)); while (p->size < s) { - (FcPatternEltU(p->elts)+p->size)->object = 0; - (FcPatternEltU(p->elts)+p->size)->values = - FcValueListPtrCreateDynamic(0); + e[p->size].object = 0; + e[p->size].values = NULL; p->size++; } } + e = FcPatternElts(p); /* move elts up */ - memmove (FcPatternEltU(p->elts) + i + 1, - FcPatternEltU(p->elts) + i, + memmove (e + i + 1, + e + i, sizeof (FcPatternElt) * (p->num - i)); /* bump count */ p->num++; - (FcPatternEltU(p->elts)+i)->object = FcObjectToPtr (object); - (FcPatternEltU(p->elts)+i)->values = FcValueListPtrCreateDynamic(0); + e[i].object = object; + e[i].values = NULL; } - return FcPatternEltU(p->elts)+i; + return FcPatternElts(p) + i; } FcBool FcPatternEqual (const FcPattern *pa, const FcPattern *pb) { int i; + FcPatternElt *pae, *pbe; if (pa == pb) return FcTrue; if (pa->num != pb->num) return FcFalse; + pae = FcPatternElts(pa); + pbe = FcPatternElts(pb); for (i = 0; i < pa->num; i++) { - if (FcObjectPtrCompare((FcPatternEltU(pa->elts)+i)->object, - (FcPatternEltU(pb->elts)+i)->object) != 0) + if (pae[i].object != pbe[i].object) return FcFalse; - if (!FcValueListEqual ((FcPatternEltU(pa->elts)+i)->values, - (FcPatternEltU(pb->elts)+i)->values)) + if (!FcValueListEqual (FcPatternEltValues(&pae[i]), + FcPatternEltValues(&pbe[i]))) return FcFalse; } return FcTrue; @@ -438,12 +418,13 @@ FcPatternHash (const FcPattern *p) { int i; FcChar32 h = 0; + FcPatternElt *pe = FcPatternElts(p); for (i = 0; i < p->num; i++) { h = (((h << 1) | (h >> 31)) ^ - FcStringHash ((FcChar8 *)FcObjectPtrU ((FcPatternEltU(p->elts)+i)->object)) ^ - FcValueListHash ((FcPatternEltU(p->elts)+i)->values)); + pe[i].object ^ + FcValueListHash (FcPatternEltValues(&pe[i]))); } return h; } @@ -456,13 +437,14 @@ FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObject for (i = 0; i < os->nobject; i++) { - ea = FcPatternFindElt (pai, os->objects[i]); - eb = FcPatternFindElt (pbi, os->objects[i]); + FcObject object = FcObjectFromName (os->objects[i]); + ea = FcPatternObjectFindElt (pai, object); + eb = FcPatternObjectFindElt (pbi, object); if (ea) { if (!eb) return FcFalse; - if (!FcValueListEqual (ea->values, eb->values)) + if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb))) return FcFalse; } else @@ -475,26 +457,23 @@ FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObject } FcBool -FcPatternAddWithBinding (FcPattern *p, - const char *object, - FcValue value, - FcValueBinding binding, - FcBool append) +FcPatternObjectAddWithBinding (FcPattern *p, + FcObject object, + FcValue value, + FcValueBinding binding, + FcBool append) { FcPatternElt *e; FcValueListPtr new, *prev; - FcValueList *newp; - FcObjectPtr objectPtr; if (p->ref == FC_REF_CONSTANT) goto bail0; - newp = malloc (sizeof (FcValueList)); - if (!newp) + new = malloc (sizeof (FcValueList)); + if (!new) goto bail0; - memset(newp, 0, sizeof (FcValueList)); - new = FcValueListPtrCreateDynamic(newp); + memset(new, 0, sizeof (FcValueList)); FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList)); /* dup string */ if (value.type == FcTypeString) @@ -508,88 +487,70 @@ FcPatternAddWithBinding (FcPattern *p, if (value.type == FcTypeVoid) goto bail1; - /* quick and dirty hack to enable FcCompareFamily/FcCompareString - * speedup: only allow strings to be added under the FC_FAMILY, - * FC_FOUNDRY, FC_STYLE, FC_RASTERIZER keys. - * and charsets under FC_CHARSET key. - * This is slightly semantically different from the old behaviour, - * but fonts shouldn't be getting non-strings here anyway. - * a better hack would use FcBaseObjectTypes to check all objects. */ - objectPtr = FcObjectToPtr(object); - if ((objectPtr == FcObjectToPtr(FC_FAMILY) - || objectPtr == FcObjectToPtr(FC_FOUNDRY) - || objectPtr == FcObjectToPtr(FC_STYLE) - || objectPtr == FcObjectToPtr(FC_RASTERIZER)) - && value.type != FcTypeString) - goto bail1; - if (objectPtr == FcObjectToPtr(FC_CHARSET) - && value.type != FcTypeCharSet) - goto bail1; - - FcValueListPtrU(new)->value = value; - FcValueListPtrU(new)->binding = binding; - FcValueListPtrU(new)->next = FcValueListPtrCreateDynamic(0); + /* + * Make sure the stored type is valid for built-in objects + */ + if (!FcObjectValidType (object, value.type)) + goto bail1; + + new->value = value; + new->binding = binding; + new->next = NULL; - e = FcPatternInsertElt (p, object); + e = FcPatternObjectInsertElt (p, object); if (!e) goto bail2; if (append) { - for (prev = &e->values; FcValueListPtrU(*prev); prev = &FcValueListPtrU(*prev)->next) + for (prev = &e->values; *prev; prev = &(*prev)->next) ; *prev = new; } else { - FcValueListPtrU(new)->next = e->values; + new->next = e->values; e->values = new; } return FcTrue; bail2: - switch (value.type) { - case FcTypeString: - FcStrFree ((FcChar8 *) value.u.s); - break; - case FcTypeMatrix: - FcMatrixFree ((FcMatrix *) value.u.m); - break; - case FcTypeCharSet: - FcCharSetDestroy ((FcCharSet *) value.u.c); - break; - case FcTypeLangSet: - FcLangSetDestroy ((FcLangSet *) value.u.l); - break; - default: - break; - } + FcValueDestroy (value); bail1: FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); - free (FcValueListPtrU(new)); + free (new); bail0: return FcFalse; } FcBool +FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append) +{ + return FcPatternObjectAddWithBinding (p, object, + value, FcValueBindingStrong, append); +} + +FcBool FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append) { - return FcPatternAddWithBinding (p, object, value, FcValueBindingStrong, append); + return FcPatternObjectAddWithBinding (p, FcObjectFromName (object), + value, FcValueBindingStrong, append); } FcBool FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append) { - return FcPatternAddWithBinding (p, object, value, FcValueBindingWeak, append); + return FcPatternObjectAddWithBinding (p, FcObjectFromName (object), + value, FcValueBindingWeak, append); } FcBool -FcPatternDel (FcPattern *p, const char *object) +FcPatternObjectDel (FcPattern *p, FcObject object) { FcPatternElt *e; - e = FcPatternFindElt (p, object); + e = FcPatternObjectFindElt (p, object); if (!e) return FcFalse; @@ -598,33 +559,38 @@ FcPatternDel (FcPattern *p, const char *object) /* shuffle existing ones down */ memmove (e, e+1, - (FcPatternEltU(p->elts) + p->num - (e + 1)) * + (FcPatternElts(p) + p->num - (e + 1)) * sizeof (FcPatternElt)); p->num--; - (FcPatternEltU(p->elts)+p->num)->object = 0; - (FcPatternEltU(p->elts)+p->num)->values = FcValueListPtrCreateDynamic(0); + e = FcPatternElts(p) + p->num; + e->object = 0; + e->values = NULL; return FcTrue; } FcBool +FcPatternDel (FcPattern *p, const char *object) +{ + return FcPatternObjectDel (p, FcObjectFromName (object)); +} + +FcBool FcPatternRemove (FcPattern *p, const char *object, int id) { FcPatternElt *e; FcValueListPtr *prev, l; - e = FcPatternFindElt (p, object); + e = FcPatternObjectFindElt (p, FcObjectFromName (object)); if (!e) return FcFalse; - for (prev = &e->values; - FcValueListPtrU(l = *prev); - prev = &FcValueListPtrU(l)->next) + for (prev = &e->values; (l = *prev); prev = &l->next) { if (!id) { - *prev = FcValueListPtrU(l)->next; - FcValueListPtrU(l)->next = FcValueListPtrCreateDynamic(0); + *prev = l->next; + l->next = NULL; FcValueListDestroy (l); - if (!FcValueListPtrU(e->values)) + if (!e->values) FcPatternDel (p, object); return FcTrue; } @@ -634,28 +600,40 @@ FcPatternRemove (FcPattern *p, const char *object, int id) } FcBool -FcPatternAddInteger (FcPattern *p, const char *object, int i) +FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i) { FcValue v; v.type = FcTypeInteger; v.u.i = i; - return FcPatternAdd (p, object, v, FcTrue); + return FcPatternObjectAdd (p, object, v, FcTrue); } FcBool -FcPatternAddDouble (FcPattern *p, const char *object, double d) +FcPatternAddInteger (FcPattern *p, const char *object, int i) +{ + return FcPatternObjectAddInteger (p, FcObjectFromName (object), i); +} + +FcBool +FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d) { FcValue v; v.type = FcTypeDouble; v.u.d = d; - return FcPatternAdd (p, object, v, FcTrue); + return FcPatternObjectAdd (p, object, v, FcTrue); } FcBool -FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s) +FcPatternAddDouble (FcPattern *p, const char *object, double d) +{ + return FcPatternObjectAddDouble (p, FcObjectFromName (object), d); +} + +FcBool +FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s) { FcValue v; @@ -663,12 +641,18 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s) { v.type = FcTypeVoid; v.u.s = 0; - return FcPatternAdd (p, object, v, FcTrue); + return FcPatternObjectAdd (p, object, v, FcTrue); } v.type = FcTypeString; v.u.s = FcStrStaticName(s); - return FcPatternAdd (p, object, v, FcTrue); + return FcPatternObjectAdd (p, object, v, FcTrue); +} + +FcBool +FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s) +{ + return FcPatternObjectAddString (p, FcObjectFromName (object), s); } FcBool @@ -683,13 +667,19 @@ FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s) FcBool -FcPatternAddBool (FcPattern *p, const char *object, FcBool b) +FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b) { FcValue v; v.type = FcTypeBool; v.u.b = b; - return FcPatternAdd (p, object, v, FcTrue); + return FcPatternObjectAdd (p, object, v, FcTrue); +} + +FcBool +FcPatternAddBool (FcPattern *p, const char *object, FcBool b) +{ + return FcPatternObjectAddBool (p, FcObjectFromName (object), b); } FcBool @@ -723,19 +713,19 @@ FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls) } FcResult -FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) +FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v) { FcPatternElt *e; FcValueListPtr l; - e = FcPatternFindElt (p, object); + e = FcPatternObjectFindElt (p, object); if (!e) return FcResultNoMatch; - for (l = e->values; FcValueListPtrU(l); l = FcValueListPtrU(l)->next) + for (l = FcPatternEltValues(e); l; l = FcValueListNext(l)) { if (!id) { - *v = FcValueCanonicalize(&FcValueListPtrU(l)->value); + *v = FcValueCanonicalize(&l->value); return FcResultMatch; } id--; @@ -744,12 +734,18 @@ FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) } FcResult -FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i) +FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) +{ + return FcPatternObjectGet (p, FcObjectFromName (object), id, v); +} + +FcResult +FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i) { FcValue v; FcResult r; - r = FcPatternGet (p, object, id, &v); + r = FcPatternObjectGet (p, object, id, &v); if (r != FcResultMatch) return r; switch (v.type) { @@ -766,12 +762,19 @@ FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i) } FcResult -FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d) +FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i) +{ + return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i); +} + + +FcResult +FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d) { FcValue v; FcResult r; - r = FcPatternGet (p, object, id, &v); + r = FcPatternObjectGet (p, object, id, &v); if (r != FcResultMatch) return r; switch (v.type) { @@ -788,12 +791,18 @@ FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d) } FcResult -FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s) +FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d) +{ + return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d); +} + +FcResult +FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s) { FcValue v; FcResult r; - r = FcPatternGet (p, object, id, &v); + r = FcPatternObjectGet (p, object, id, &v); if (r != FcResultMatch) return r; if (v.type != FcTypeString) @@ -804,6 +813,12 @@ FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s } FcResult +FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s) +{ + return FcPatternObjectGetString (p, FcObjectFromName (object), id, s); +} + +FcResult FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m) { FcValue v; @@ -891,16 +906,14 @@ FcPatternDuplicate (const FcPattern *orig) if (!new) goto bail0; - e = FcPatternEltU(orig->elts); + e = FcPatternElts(orig); for (i = 0; i < orig->num; i++) { - for (l = (e + i)->values; - FcValueListPtrU(l); - l = FcValueListPtrU(l)->next) - if (!FcPatternAdd (new, FcObjectPtrU((e + i)->object), - FcValueCanonicalize(&FcValueListPtrU(l)->value), - FcTrue)) + for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l)) + if (!FcPatternObjectAdd (new, e[i].object, + FcValueCanonicalize(&l->value), + FcTrue)) goto bail1; } @@ -951,13 +964,12 @@ FcPatternAppend (FcPattern *p, FcPattern *s) for (i = 0; i < s->num; i++) { - e = FcPatternEltU(s->elts)+i; - for (v = e->values; FcValueListPtrU(v); - v = FcValueListPtrU(v)->next) + e = FcPatternElts(s)+i; + for (v = FcPatternEltValues(e); v; v = FcValueListNext(v)) { - if (!FcPatternAddWithBinding (p, FcObjectPtrU(e->object), - FcValueCanonicalize(&FcValueListPtrU(v)->value), - FcValueListPtrU(v)->binding, FcTrue)) + if (!FcPatternObjectAddWithBinding (p, e->object, + FcValueCanonicalize(&v->value), + v->binding, FcTrue)) return FcFalse; } } @@ -1035,561 +1047,140 @@ FcPatternFini (void) FcObjectStaticNameFini (); } -static FcPatternEltPtr -FcPatternEltPtrCreateDynamic (FcPatternElt * e) -{ - FcPatternEltPtr new; - new.bank = FC_BANK_DYNAMIC; - new.u.dyn = e; - return new; -} - -static FcPatternEltPtr -FcPatternEltPtrCreateStatic (int bank, int i) -{ - FcPatternEltPtr new; - new.bank = bank; - new.u.stat = i; - return new; -} - -static void -FcStrNewBank (void); -static int -FcStrNeededBytes (const FcChar8 * s); -static int -FcStrNeededBytesAlign (void); -static void * -FcStrDistributeBytes (FcCache * metadata, void * block_ptr); -static const FcChar8 * -FcStrSerialize (int bank, const FcChar8 * s); -static void * -FcStrUnserialize (FcCache * metadata, void *block_ptr); - -static void -FcValueListNewBank (void); -static int -FcValueListNeededBytes (FcValueList * vl); -static int -FcValueListNeededBytesAlign (void); -static void * -FcValueListDistributeBytes (FcCache * metadata, void *block_ptr); -static FcValueListPtr -FcValueListSerialize(int bank, FcValueList *pi); -static void * -FcValueListUnserialize (FcCache * metadata, void *block_ptr); - - -void -FcPatternNewBank (void) -{ - fcpattern_count = 0; - fcpatternelt_count = 0; - - FcStrNewBank(); - FcValueListNewBank(); -} - -int -FcPatternNeededBytes (FcPattern * p) -{ - int i, cum = 0, c; - - fcpattern_count++; - fcpatternelt_count += p->num; - - for (i = 0; i < p->num; i++) - { - c = FcValueListNeededBytes (FcValueListPtrU - (((FcPatternEltU(p->elts)+i)->values))); - if (c < 0) - return c; - cum += c; - } - - return cum + sizeof (FcPattern) + sizeof(FcPatternElt)*p->num; -} - -int -FcPatternNeededBytesAlign (void) -{ - return fc_alignof (FcPattern) + fc_alignof (FcPatternElt) + - FcValueListNeededBytesAlign (); -} - -static FcBool -FcPatternEnsureBank (int bi) -{ - FcPattern **pp; - FcPatternElt **ep; - int i; - - if (!_fcPatterns || fcpattern_bank_count <= bi) - { - int new_count = bi + 4; - pp = realloc (_fcPatterns, sizeof (FcPattern *) * new_count); - if (!pp) - return 0; - - FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern *) * new_count); - _fcPatterns = pp; - - ep = realloc (_fcPatternElts, sizeof (FcPatternElt *) * new_count); - if (!ep) - return 0; - - FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt *) * new_count); - _fcPatternElts = ep; - - for (i = fcpattern_bank_count; i < new_count; i++) - { - _fcPatterns[i] = 0; - _fcPatternElts[i] = 0; - } - - fcpattern_bank_count = new_count; - } - - FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * fcpattern_count); - return FcTrue; -} - -void * -FcPatternDistributeBytes (FcCache * metadata, void * block_ptr) +FcBool +FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat) { - int bi = FcCacheBankToIndex(metadata->bank); - - if (!FcPatternEnsureBank(bi)) - return 0; - - fcpattern_ptr = 0; - block_ptr = ALIGN(block_ptr, FcPattern); - _fcPatterns[bi] = (FcPattern *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcPattern) * fcpattern_count)); + int i; + FcPatternElt *elts = FcPatternElts(pat); - FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt) * fcpatternelt_count); - fcpatternelt_ptr = 0; - block_ptr = ALIGN(block_ptr, FcPatternElt); - _fcPatternElts[bi] = (FcPatternElt *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcPatternElt) * fcpatternelt_count)); - - metadata->pattern_count = fcpattern_count; - metadata->patternelt_count = fcpatternelt_count; - - block_ptr = FcStrDistributeBytes (metadata, block_ptr); - block_ptr = FcValueListDistributeBytes (metadata, block_ptr); - return block_ptr; + if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern))) + return FcFalse; + if (!FcSerializeAlloc (serialize, elts, pat->num * sizeof (FcPatternElt))) + return FcFalse; + for (i = 0; i < pat->num; i++) + if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i))) + return FcFalse; + return FcTrue; } FcPattern * -FcPatternSerialize (int bank, FcPattern *old) +FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat) { - FcPattern *p; - FcPatternElt *e, *nep; - FcValueList * nv; - FcValueListPtr v, nv_head, nvp; - int i, elts, bi = FcCacheBankToIndex(bank); - - p = &_fcPatterns[bi][fcpattern_ptr++]; - p->bank = bank; - elts = fcpatternelt_ptr; - nep = &_fcPatternElts[bi][elts]; - if (!nep) - return FcFalse; + FcPattern *pat_serialized; + FcPatternElt *elts = FcPatternElts (pat); + FcPatternElt *elts_serialized; + FcValueList *values_serialized; + int i; - fcpatternelt_ptr += old->num; + pat_serialized = FcSerializePtr (serialize, pat); + if (!pat_serialized) + return NULL; + *pat_serialized = *pat; + pat_serialized->size = pat->num; + pat_serialized->ref = FC_REF_CONSTANT; + + elts_serialized = FcSerializePtr (serialize, elts); + if (!elts_serialized) + return NULL; + + pat_serialized->elts_offset = FcPtrToOffset (pat_serialized, + elts_serialized); - for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++) + for (i = 0; i < pat->num; i++) { - v = e->values; - nvp = nv_head = FcValueListSerialize(bank, FcValueListPtrU(v)); - if (!FcValueListPtrU(nv_head)) - return 0; - nv = FcValueListPtrU(nvp); - - for (; - FcValueListPtrU(v); - v = FcValueListPtrU(v)->next, - nv = FcValueListPtrU(nv->next)) - { - - if (FcValueListPtrU(FcValueListPtrU(v)->next)) - { - nvp = FcValueListSerialize - (bank, FcValueListPtrU(FcValueListPtrU(v)->next)); - nv->next = nvp; - } - } - - nep[i].values = nv_head; - nep[i].object = e->object; + values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i)); + if (!values_serialized) + return NULL; + elts_serialized[i].object = elts[i].object; + elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i], + values_serialized, + FcValueList); } - - p->elts = old->elts; - p->elts = FcPatternEltPtrCreateStatic(bank, elts); - p->size = old->num; - p->num = old->num; - p->ref = FC_REF_CONSTANT; - return p; -} - -void * -FcPatternUnserialize (FcCache * metadata, void *block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcPatternEnsureBank(bi)) - return FcFalse; - - FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * metadata->pattern_count); - block_ptr = ALIGN(block_ptr, FcPattern); - _fcPatterns[bi] = (FcPattern *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcPattern) * metadata->pattern_count)); - - FcMemAlloc (FC_MEM_PATELT, - sizeof (FcPatternElt) * metadata->patternelt_count); - block_ptr = ALIGN(block_ptr, FcPatternElt); - _fcPatternElts[bi] = (FcPatternElt *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcPatternElt) * metadata->patternelt_count)); - - block_ptr = FcStrUnserialize (metadata, block_ptr); - block_ptr = FcValueListUnserialize (metadata, block_ptr); - - return block_ptr; -} - -static void -FcValueListNewBank (void) -{ - fcvaluelist_count = 0; - - FcCharSetNewBank(); - FcLangSetNewBank(); + return pat_serialized; } -static int -FcValueListNeededBytes (FcValueList *p) +FcBool +FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl) { - FcValueList *vl; - int cum = 0; - - for (vl = p; - vl; - vl = FcValueListPtrU(vl->next)) + while (vl) { - /* unserialize just in case */ - FcValue v = FcValueCanonicalize(&vl->value); - - switch (v.type) - { + if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList))) + return FcFalse; + switch (vl->value.type) { + case FcTypeString: + if (!FcStrSerializeAlloc (serialize, vl->value.u.s)) + return FcFalse; + break; case FcTypeCharSet: - cum += FcCharSetNeededBytes(v.u.c); + if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c)) + return FcFalse; break; case FcTypeLangSet: - cum += FcLangSetNeededBytes(v.u.l); + if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l)) + return FcFalse; break; - case FcTypeString: - cum += FcStrNeededBytes(v.u.s); default: break; } - fcvaluelist_count++; - cum += sizeof (FcValueList); - } - - return cum; -} - -static int -FcValueListNeededBytesAlign (void) -{ - return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() + - FcStrNeededBytesAlign() + fc_alignof (FcValueList); -} - -static FcBool -FcValueListEnsureBank (int bi) -{ - FcValueList **pvl; - - if (!_fcValueLists || fcvaluelist_bank_count <= bi) - { - int new_count = bi + 2, i; - - pvl = realloc (_fcValueLists, sizeof (FcValueList *) * new_count); - if (!pvl) - return FcFalse; - - FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList *) * new_count); - - _fcValueLists = pvl; - for (i = fcvaluelist_bank_count; i < new_count; i++) - _fcValueLists[i] = 0; - - fcvaluelist_bank_count = new_count; + vl = vl->next; } return FcTrue; } -static void * -FcValueListDistributeBytes (FcCache * metadata, void *block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - - if (!FcValueListEnsureBank(bi)) - return 0; - - FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList) * fcvaluelist_count); - fcvaluelist_ptr = 0; - block_ptr = ALIGN(block_ptr, FcValueList); - _fcValueLists[bi] = (FcValueList *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcValueList) * fcvaluelist_count)); - metadata->valuelist_count = fcvaluelist_count; - - block_ptr = FcCharSetDistributeBytes(metadata, block_ptr); - block_ptr = FcLangSetDistributeBytes(metadata, block_ptr); - - return block_ptr; -} - -static FcValueListPtr -FcValueListSerialize(int bank, FcValueList *pi) -{ - FcValueListPtr new; - FcValue * v; - int bi = FcCacheBankToIndex(bank); - - if (!pi) - { - new.bank = FC_BANK_DYNAMIC; - new.u.dyn = 0; - return new; - } - - _fcValueLists[bi][fcvaluelist_ptr] = *pi; - new.bank = bank; - new.u.stat = fcvaluelist_ptr++; - _fcValueLists[bi][new.u.stat].value = FcValueCanonicalize (&pi->value); - v = &_fcValueLists[bi][new.u.stat].value; - switch (v->type) - { - case FcTypeString: - if (v->u.s) - { - const FcChar8 * s = FcStrSerialize(bank, v->u.s); - if (!s) - return FcValueListPtrCreateDynamic(pi); - v->u.s_off = s - (const FcChar8 *)v; - v->type |= FC_STORAGE_STATIC; - } - break; - case FcTypeMatrix: - break; - case FcTypeCharSet: - if (v->u.c) - { - FcCharSet * c = FcCharSetSerialize(bank, (FcCharSet *)v->u.c); - if (!c) - return FcValueListPtrCreateDynamic(pi); - v->u.c_off = (char *)c - (char *)v; - v->type |= FC_STORAGE_STATIC; - } - break; - case FcTypeLangSet: - if (v->u.l) - { - FcLangSet * l = FcLangSetSerialize(bank, (FcLangSet *)v->u.l); - if (!l) - return FcValueListPtrCreateDynamic(pi); - v->u.l_off = (char *)l - (char *)v; - v->type |= FC_STORAGE_STATIC; - } - break; - default: - break; - } - return new; -} - -static void * -FcValueListUnserialize (FcCache * metadata, void *block_ptr) +FcValueList * +FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) { - int bi = FcCacheBankToIndex(metadata->bank); - - if (!FcValueListEnsureBank(bi)) - return 0; - - FcMemAlloc (FC_MEM_VALLIST, - sizeof (FcValueList) * metadata->valuelist_count); - block_ptr = ALIGN(block_ptr, FcValueList); - _fcValueLists[bi] = (FcValueList *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (FcValueList) * metadata->valuelist_count)); - - block_ptr = FcCharSetUnserialize(metadata, block_ptr); - block_ptr = FcLangSetUnserialize(metadata, block_ptr); + FcValueList *vl_serialized; + FcChar8 *s_serialized; + FcCharSet *c_serialized; + FcLangSet *l_serialized; + FcValueList *head_serialized = NULL; + FcValueList *prev_serialized = NULL; - return block_ptr; -} - -FcValueListPtr -FcValueListPtrCreateDynamic(FcValueList * p) -{ - FcValueListPtr r; - - r.bank = FC_BANK_DYNAMIC; - r.u.dyn = p; - return r; -} - -static FcChar8 ** static_strs; -static int static_str_bank_count = 0, fcstr_ptr, fcstr_count; - -static struct objectBucket *FcStrBuckets[OBJECT_HASH_SIZE]; - -static void -FcStrNewBank (void) -{ - int i, size; - struct objectBucket *b, *next; - char *name; - - for (i = 0; i < OBJECT_HASH_SIZE; i++) + while (vl) { - for (b = FcStrBuckets[i]; b; b = next) - { - next = b->next; - name = (char *) (b + 1); - size = sizeof (struct objectBucket) + strlen (name) + 1; - FcMemFree (FC_MEM_STATICSTR, size); - free (b); + vl_serialized = FcSerializePtr (serialize, vl); + if (!vl_serialized) + return NULL; + + if (prev_serialized) + prev_serialized->next = FcPtrToEncodedOffset (prev_serialized, + vl_serialized, + FcValueList); + else + head_serialized = vl_serialized; + + vl_serialized->next = NULL; + vl_serialized->value = vl->value; + switch (vl->value.type) { + case FcTypeString: + s_serialized = FcStrSerialize (serialize, vl->value.u.s); + if (!s_serialized) + return NULL; + vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value, + s_serialized, + FcChar8); + break; + case FcTypeCharSet: + c_serialized = FcCharSetSerialize (serialize, vl->value.u.c); + if (!c_serialized) + return NULL; + vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value, + c_serialized, + FcCharSet); + break; + case FcTypeLangSet: + l_serialized = FcLangSetSerialize (serialize, vl->value.u.l); + if (!l_serialized) + return NULL; + vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value, + l_serialized, + FcLangSet); + break; + default: + break; } - FcStrBuckets[i] = 0; - } - - fcstr_count = 0; -} - -static int -FcStrNeededBytes (const FcChar8 * s) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) s); - struct objectBucket **p; - struct objectBucket *b; - int size; - FcChar8 *const null = 0; - - for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1))) - return 0; - size = sizeof (struct objectBucket) + strlen ((char *)s) + 1 + sizeof(char *); - b = malloc (size); - FcMemAlloc (FC_MEM_STATICSTR, size); - if (!b) - return -1; - b->next = 0; - b->hash = hash; - strcpy ((char *) (b + 1), (char *)s); - - /* Yes, the following line is convoluted. However, it is - * incorrect to replace the with a memset, because the C - * specification doesn't guarantee that the null pointer is - * the same as the zero bit pattern. */ - /* Misaligned pointers are not guaranteed to work, either! */ - memcpy (((char *) (b + 1) + strlen((char *)s) + 1), &null, sizeof (null)); - *p = b; - - fcstr_count += strlen((char *)s) + 1; - return strlen((char *)s) + 1; -} - -static int -FcStrNeededBytesAlign (void) -{ - return fc_alignof (char); -} - -static FcBool -FcStrEnsureBank (int bi) -{ - FcChar8 ** ss; - - if (!static_strs || static_str_bank_count <= bi) - { - int new_count = bi + 4, i; - ss = realloc (static_strs, sizeof (const char *) * new_count); - if (!ss) - return FcFalse; - - FcMemAlloc (FC_MEM_STRING, sizeof (const char *) * (new_count-static_str_bank_count)); - static_strs = ss; - - for (i = static_str_bank_count; i < new_count; i++) - static_strs[i] = 0; - static_str_bank_count = new_count; + vl = vl->next; } - return FcTrue; -} - -static void * -FcStrDistributeBytes (FcCache * metadata, void * block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcStrEnsureBank(bi)) - return 0; - - FcMemAlloc (FC_MEM_STRING, sizeof (char) * fcstr_count); - block_ptr = ALIGN (block_ptr, FcChar8); - static_strs[bi] = (FcChar8 *)block_ptr; - block_ptr = (void *)((char *)block_ptr + (sizeof (char) * fcstr_count)); - metadata->str_count = fcstr_count; - fcstr_ptr = 0; - - return block_ptr; -} - -static const FcChar8 * -FcStrSerialize (int bank, const FcChar8 * s) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) s); - struct objectBucket **p; - struct objectBucket *b; - int bi = FcCacheBankToIndex(bank); - - for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1))) - { - FcChar8 * t; - memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *)); - if (!t) - { - strcpy((char *)(static_strs[bi] + fcstr_ptr), (char *)s); - t = static_strs[bi] + fcstr_ptr; - memcpy ((FcChar8 *) (b + 1) + strlen((char *)s) + 1, &t, sizeof (FcChar8 *)); - fcstr_ptr += strlen((char *)s) + 1; - memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *)); - } - return t; - } - return 0; -} - -static void * -FcStrUnserialize (FcCache * metadata, void *block_ptr) -{ - int bi = FcCacheBankToIndex(metadata->bank); - if (!FcStrEnsureBank(bi)) - return 0; - - FcMemAlloc (FC_MEM_STRING, sizeof (char) * metadata->str_count); - block_ptr = ALIGN (block_ptr, FcChar8); - static_strs[bi] = (FcChar8 *)block_ptr; - block_ptr = (void *)((char *)block_ptr + - (sizeof (char) * metadata->str_count)); - - return block_ptr; + return head_serialized; } diff --git a/src/fcstr.c b/src/fcstr.c index 37bad6b..b83a709 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -1052,3 +1052,4 @@ FcStrListDone (FcStrList *list) FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList)); free (list); } + diff --git a/src/fcxml.c b/src/fcxml.c index c5c9065..608f834 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -65,7 +65,6 @@ FcTestDestroy (FcTest *test) if (test->next) FcTestDestroy (test->next); FcExprDestroy (test->expr); - FcStrFree ((FcChar8 *) test->field); FcMemFree (FC_MEM_TEST, sizeof (FcTest)); free (test); } @@ -162,7 +161,7 @@ FcExprCreateField (const char *field) { FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpField; - e->u.field = (char *) FcStrCopy ((FcChar8 *) field); + e->u.object = FcObjectFromName (field); } return e; } @@ -218,7 +217,6 @@ FcExprDestroy (FcExpr *e) case FcOpBool: break; case FcOpField: - FcStrFree ((FcChar8 *) e->u.field); break; case FcOpConst: FcStrFree (e->u.constant); @@ -269,7 +267,6 @@ FcEditDestroy (FcEdit *e) { if (e->next) FcEditDestroy (e->next); - FcStrFree ((FcChar8 *) e->field); if (e->expr) FcExprDestroy (e->expr); free (e); @@ -579,7 +576,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) case FcOpNil: break; case FcOpField: - o = FcNameGetObjectType (expr->u.field); + o = FcNameGetObjectType (FcObjectName (expr->u.object)); if (o) FcTypecheckValue (parse, o->type, type); break; @@ -659,10 +656,10 @@ FcTestCreate (FcConfigParse *parse, test->next = 0; test->kind = kind; test->qual = qual; - test->field = (char *) FcStrCopy (field); + test->object = FcObjectFromName ((const char *) field); test->op = compare; test->expr = expr; - o = FcNameGetObjectType (test->field); + o = FcNameGetObjectType (FcObjectName (test->object)); if (o) FcTypecheckExpr (parse, expr, o->type); } @@ -683,11 +680,11 @@ FcEditCreate (FcConfigParse *parse, const FcObjectType *o; e->next = 0; - e->field = field; /* already saved in grammar */ + e->object = FcObjectFromName (field); e->op = op; e->expr = expr; e->binding = binding; - o = FcNameGetObjectType (e->field); + o = FcNameGetObjectType (FcObjectName (e->object)); if (o) FcTypecheckExpr (parse, expr, o->type); } |