diff options
| author | YAMAMOTO Mitsuharu | 2005-09-06 08:07:32 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2005-09-06 08:07:32 +0000 |
| commit | 468213f1f3be48436558f3ddb07cff3bc196f1cb (patch) | |
| tree | 49532842c34c424df4df07589abedd67cd77b114 /src | |
| parent | 2a6bc1f7cae62b2ddfdf574ba4686fdecb92bfc7 (diff) | |
| download | emacs-468213f1f3be48436558f3ddb07cff3bc196f1cb.tar.gz emacs-468213f1f3be48436558f3ddb07cff3bc196f1cb.zip | |
(struct xlfdpat_block, struct xlfdpat): New structs.
(xlfdpat_destroy, xlfdpat_create, xlfdpat_exact_p)
(xlfdpat_block_match_1, xlfdpat_match): New functions.
(xlfdpat_block_match): New macro.
(mac_to_x_fontname): Don't use tolower for non-ASCII characters.
(x_font_name_to_mac_font_name): Set coding.dst_multibyte to 0.
(add_font_name_table_entry): Increase font_name_table_size more
rapidly.
(mac_c_string_match): Remove function.
(mac_do_list_fonts): Use XLFD pattern match instead of regular
expression match.
Diffstat (limited to 'src')
| -rw-r--r-- | src/macterm.c | 445 |
1 files changed, 357 insertions, 88 deletions
diff --git a/src/macterm.c b/src/macterm.c index 3c7af5f1cef..362da7f77c7 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -6084,6 +6084,335 @@ x_wm_set_icon_position (f, icon_x, icon_y) | |||
| 6084 | 6084 | ||
| 6085 | 6085 | ||
| 6086 | /*********************************************************************** | 6086 | /*********************************************************************** |
| 6087 | XLFD Pattern Match | ||
| 6088 | ***********************************************************************/ | ||
| 6089 | |||
| 6090 | /* An XLFD pattern is divided into blocks delimited by '*'. This | ||
| 6091 | structure holds information for each block. */ | ||
| 6092 | struct xlfdpat_block | ||
| 6093 | { | ||
| 6094 | /* Length of the pattern string in this block. Non-zero except for | ||
| 6095 | the first and the last blocks. */ | ||
| 6096 | int len; | ||
| 6097 | |||
| 6098 | /* Pattern string except the last character in this block. The last | ||
| 6099 | character is replaced with NUL in order to use it as a | ||
| 6100 | sentinel. */ | ||
| 6101 | unsigned char *pattern; | ||
| 6102 | |||
| 6103 | /* Last character of the pattern string. Must not be '?'. */ | ||
| 6104 | unsigned char last_char; | ||
| 6105 | |||
| 6106 | /* One of the tables for the Boyer-Moore string search. It | ||
| 6107 | specifies the number of positions to proceed for each character | ||
| 6108 | with which the match fails. */ | ||
| 6109 | int skip[256]; | ||
| 6110 | |||
| 6111 | /* The skip value for the last character in the above `skip' is | ||
| 6112 | assigned to `infinity' in order to simplify a loop condition. | ||
| 6113 | The original value is saved here. */ | ||
| 6114 | int last_char_skip; | ||
| 6115 | }; | ||
| 6116 | |||
| 6117 | struct xlfdpat | ||
| 6118 | { | ||
| 6119 | /* Normalized pattern string. "Normalized" means that capital | ||
| 6120 | letters are lowered, blocks are not empty except the first and | ||
| 6121 | the last ones, and trailing '?'s in a block that is not the last | ||
| 6122 | one are moved to the next one. The last character in each block | ||
| 6123 | is replaced with NUL. */ | ||
| 6124 | unsigned char *buf; | ||
| 6125 | |||
| 6126 | /* Number of characters except '*'s and trailing '?'s in the | ||
| 6127 | normalized pattern string. */ | ||
| 6128 | int nchars; | ||
| 6129 | |||
| 6130 | /* Number of trailing '?'s in the normalized pattern string. */ | ||
| 6131 | int trailing_anychars; | ||
| 6132 | |||
| 6133 | /* Number of blocks and information for each block. The latter is | ||
| 6134 | NULL if the pattern is exact (no '*' or '?' in it). */ | ||
| 6135 | int nblocks; | ||
| 6136 | struct xlfdpat_block *blocks; | ||
| 6137 | }; | ||
| 6138 | |||
| 6139 | static void | ||
| 6140 | xlfdpat_destroy (pat) | ||
| 6141 | struct xlfdpat *pat; | ||
| 6142 | { | ||
| 6143 | if (pat) | ||
| 6144 | { | ||
| 6145 | if (pat->buf) | ||
| 6146 | { | ||
| 6147 | if (pat->blocks) | ||
| 6148 | xfree (pat->blocks); | ||
| 6149 | xfree (pat->buf); | ||
| 6150 | } | ||
| 6151 | xfree (pat); | ||
| 6152 | } | ||
| 6153 | } | ||
| 6154 | |||
| 6155 | static struct xlfdpat * | ||
| 6156 | xlfdpat_create (pattern) | ||
| 6157 | char *pattern; | ||
| 6158 | { | ||
| 6159 | struct xlfdpat *pat; | ||
| 6160 | int nblocks, i, skip; | ||
| 6161 | unsigned char last_char, *p, *q, *anychar_head; | ||
| 6162 | struct xlfdpat_block *blk; | ||
| 6163 | |||
| 6164 | pat = xmalloc (sizeof (struct xlfdpat)); | ||
| 6165 | if (pat == NULL) | ||
| 6166 | goto error; | ||
| 6167 | |||
| 6168 | pat->buf = xmalloc (strlen (pattern) + 1); | ||
| 6169 | if (pat->buf == NULL) | ||
| 6170 | goto error; | ||
| 6171 | |||
| 6172 | /* Normalize the pattern string and store it to `pat->buf'. */ | ||
| 6173 | nblocks = 0; | ||
| 6174 | anychar_head = NULL; | ||
| 6175 | q = pat->buf; | ||
| 6176 | last_char = '\0'; | ||
| 6177 | for (p = pattern; *p; p++) | ||
| 6178 | { | ||
| 6179 | unsigned char c = *p; | ||
| 6180 | |||
| 6181 | if (c == '*') | ||
| 6182 | if (last_char == '*') | ||
| 6183 | /* ...a** -> ...a* */ | ||
| 6184 | continue; | ||
| 6185 | else | ||
| 6186 | { | ||
| 6187 | if (last_char == '?') | ||
| 6188 | if (anychar_head > pat->buf && *(anychar_head - 1) == '*') | ||
| 6189 | /* ...*??* -> ...*?? */ | ||
| 6190 | continue; | ||
| 6191 | else | ||
| 6192 | /* ...a??* -> ...a*?? */ | ||
| 6193 | { | ||
| 6194 | *anychar_head++ = '*'; | ||
| 6195 | c = '?'; | ||
| 6196 | } | ||
| 6197 | nblocks++; | ||
| 6198 | } | ||
| 6199 | else if (c == '?') | ||
| 6200 | { | ||
| 6201 | if (last_char != '?') | ||
| 6202 | anychar_head = q; | ||
| 6203 | } | ||
| 6204 | else | ||
| 6205 | /* On Mac OS X 10.3, tolower also converts non-ASCII | ||
| 6206 | characters for some locales. */ | ||
| 6207 | if (isascii (c)) | ||
| 6208 | c = tolower (c); | ||
| 6209 | |||
| 6210 | *q++ = last_char = c; | ||
| 6211 | } | ||
| 6212 | *q = '\0'; | ||
| 6213 | nblocks++; | ||
| 6214 | pat->nblocks = nblocks; | ||
| 6215 | if (last_char != '?') | ||
| 6216 | pat->trailing_anychars = 0; | ||
| 6217 | else | ||
| 6218 | { | ||
| 6219 | pat->trailing_anychars = q - anychar_head; | ||
| 6220 | q = anychar_head; | ||
| 6221 | } | ||
| 6222 | pat->nchars = q - pat->buf - (nblocks - 1); | ||
| 6223 | |||
| 6224 | if (anychar_head == NULL && nblocks == 1) | ||
| 6225 | { | ||
| 6226 | /* The pattern is exact. */ | ||
| 6227 | pat->blocks = NULL; | ||
| 6228 | return pat; | ||
| 6229 | } | ||
| 6230 | |||
| 6231 | pat->blocks = xmalloc (sizeof (struct xlfdpat_block) * nblocks); | ||
| 6232 | if (pat->blocks == NULL) | ||
| 6233 | goto error; | ||
| 6234 | |||
| 6235 | /* Divide the normalized pattern into blocks. */ | ||
| 6236 | p = pat->buf; | ||
| 6237 | for (blk = pat->blocks; blk < pat->blocks + nblocks - 1; blk++) | ||
| 6238 | { | ||
| 6239 | blk->pattern = p; | ||
| 6240 | while (*p != '*') | ||
| 6241 | p++; | ||
| 6242 | blk->len = p - blk->pattern; | ||
| 6243 | p++; | ||
| 6244 | } | ||
| 6245 | blk->pattern = p; | ||
| 6246 | blk->len = q - blk->pattern; | ||
| 6247 | |||
| 6248 | /* Setup a table for the Boyer-Moore string search. */ | ||
| 6249 | for (blk = pat->blocks; blk < pat->blocks + nblocks; blk++) | ||
| 6250 | if (blk->len != 0) | ||
| 6251 | { | ||
| 6252 | blk->last_char = blk->pattern[blk->len - 1]; | ||
| 6253 | blk->pattern[blk->len - 1] = '\0'; | ||
| 6254 | |||
| 6255 | for (skip = 1; skip < blk->len; skip++) | ||
| 6256 | if (blk->pattern[blk->len - skip - 1] == '?') | ||
| 6257 | break; | ||
| 6258 | |||
| 6259 | for (i = 0; i < 256; i++) | ||
| 6260 | blk->skip[i] = skip; | ||
| 6261 | |||
| 6262 | p = blk->pattern + (blk->len - skip); | ||
| 6263 | while (--skip > 0) | ||
| 6264 | blk->skip[*p++] = skip; | ||
| 6265 | |||
| 6266 | blk->last_char_skip = blk->skip[blk->last_char]; | ||
| 6267 | } | ||
| 6268 | |||
| 6269 | return pat; | ||
| 6270 | |||
| 6271 | error: | ||
| 6272 | xlfdpat_destroy (pat); | ||
| 6273 | return NULL; | ||
| 6274 | } | ||
| 6275 | |||
| 6276 | static INLINE int | ||
| 6277 | xlfdpat_exact_p (pat) | ||
| 6278 | struct xlfdpat *pat; | ||
| 6279 | { | ||
| 6280 | return (pat)->blocks == NULL; | ||
| 6281 | } | ||
| 6282 | |||
| 6283 | /* Return the first string in STRING + 0, ..., STRING + START_MAX such | ||
| 6284 | that the pattern in *BLK matches with its prefix. Return NULL | ||
| 6285 | there is no such strings. STRING must be lowered in advance. */ | ||
| 6286 | |||
| 6287 | static char * | ||
| 6288 | xlfdpat_block_match_1 (blk, string, start_max) | ||
| 6289 | struct xlfdpat_block *blk; | ||
| 6290 | unsigned char *string; | ||
| 6291 | int start_max; | ||
| 6292 | { | ||
| 6293 | int start, infinity; | ||
| 6294 | unsigned char *p, *s; | ||
| 6295 | |||
| 6296 | xassert (blk->len > 0); | ||
| 6297 | xassert (start_max + blk->len <= strlen (string)); | ||
| 6298 | xassert (blk->pattern[blk->len - 1] != '?'); | ||
| 6299 | |||
| 6300 | /* See the comments in the function `boyer_moore' (search.c) for the | ||
| 6301 | use of `infinity'. */ | ||
| 6302 | infinity = start_max + blk->len + 1; | ||
| 6303 | blk->skip[blk->last_char] = infinity; | ||
| 6304 | |||
| 6305 | start = 0; | ||
| 6306 | do | ||
| 6307 | { | ||
| 6308 | /* Check the last character of the pattern. */ | ||
| 6309 | s = string + blk->len - 1; | ||
| 6310 | do | ||
| 6311 | { | ||
| 6312 | start += blk->skip[*(s + start)]; | ||
| 6313 | } | ||
| 6314 | while (start <= start_max); | ||
| 6315 | |||
| 6316 | if (start < infinity) | ||
| 6317 | /* Couldn't find the last character. */ | ||
| 6318 | return NULL; | ||
| 6319 | |||
| 6320 | /* No less than `infinity' means we could find the last | ||
| 6321 | character at `s[start - infinity]'. */ | ||
| 6322 | start -= infinity; | ||
| 6323 | |||
| 6324 | /* Check the remaining characters. We prefer making no-'?' | ||
| 6325 | cases faster because the use of '?' is really rare. */ | ||
| 6326 | p = blk->pattern; | ||
| 6327 | s = string + start; | ||
| 6328 | do | ||
| 6329 | { | ||
| 6330 | while (*p++ == *s++) | ||
| 6331 | ; | ||
| 6332 | } | ||
| 6333 | while (*(p - 1) == '?'); | ||
| 6334 | |||
| 6335 | if (*(p - 1) == '\0') | ||
| 6336 | /* Matched. */ | ||
| 6337 | return string + start; | ||
| 6338 | |||
| 6339 | /* Didn't match. */ | ||
| 6340 | start += blk->last_char_skip; | ||
| 6341 | } | ||
| 6342 | while (start <= start_max); | ||
| 6343 | |||
| 6344 | return NULL; | ||
| 6345 | } | ||
| 6346 | |||
| 6347 | #define xlfdpat_block_match(b, s, m) \ | ||
| 6348 | ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \ | ||
| 6349 | : xlfdpat_block_match_1 (b, s, m)) | ||
| 6350 | |||
| 6351 | /* Check if XLFD pattern PAT, which is generated by `xfldpat_create', | ||
| 6352 | matches with STRING. STRING must be lowered in advance. */ | ||
| 6353 | |||
| 6354 | static int | ||
| 6355 | xlfdpat_match (pat, string) | ||
| 6356 | struct xlfdpat *pat; | ||
| 6357 | unsigned char *string; | ||
| 6358 | { | ||
| 6359 | int str_len, nblocks, i, start_max; | ||
| 6360 | struct xlfdpat_block *blk; | ||
| 6361 | unsigned char *s; | ||
| 6362 | |||
| 6363 | xassert (pat->nblocks > 0); | ||
| 6364 | |||
| 6365 | if (xlfdpat_exact_p (pat)) | ||
| 6366 | return strcmp (pat->buf, string) == 0; | ||
| 6367 | |||
| 6368 | /* The number of the characters in the string must not be smaller | ||
| 6369 | than that in the pattern. */ | ||
| 6370 | str_len = strlen (string); | ||
| 6371 | if (str_len < pat->nchars + pat->trailing_anychars) | ||
| 6372 | return 0; | ||
| 6373 | |||
| 6374 | /* Chop off the trailing '?'s. */ | ||
| 6375 | str_len -= pat->trailing_anychars; | ||
| 6376 | |||
| 6377 | /* The last block. When it is non-empty, it must match at the end | ||
| 6378 | of the string. */ | ||
| 6379 | nblocks = pat->nblocks; | ||
| 6380 | blk = pat->blocks + (nblocks - 1); | ||
| 6381 | if (nblocks == 1) | ||
| 6382 | /* The last block is also the first one. */ | ||
| 6383 | return (str_len == blk->len | ||
| 6384 | && (blk->len == 0 || xlfdpat_block_match (blk, string, 0))); | ||
| 6385 | else if (blk->len != 0) | ||
| 6386 | if (!xlfdpat_block_match (blk, string + (str_len - blk->len), 0)) | ||
| 6387 | return 0; | ||
| 6388 | |||
| 6389 | /* The first block. When it is non-empty, it must match at the | ||
| 6390 | beginning of the string. */ | ||
| 6391 | blk = pat->blocks; | ||
| 6392 | if (blk->len != 0) | ||
| 6393 | { | ||
| 6394 | s = xlfdpat_block_match (blk, string, 0); | ||
| 6395 | if (s == NULL) | ||
| 6396 | return 0; | ||
| 6397 | string = s + blk->len; | ||
| 6398 | } | ||
| 6399 | |||
| 6400 | /* The rest of the blocks. */ | ||
| 6401 | start_max = str_len - pat->nchars; | ||
| 6402 | for (i = 1, blk++; i < nblocks - 1; i++, blk++) | ||
| 6403 | { | ||
| 6404 | s = xlfdpat_block_match (blk, string, start_max); | ||
| 6405 | if (s == NULL) | ||
| 6406 | return 0; | ||
| 6407 | start_max -= s - string; | ||
| 6408 | string = s + blk->len; | ||
| 6409 | } | ||
| 6410 | |||
| 6411 | return 1; | ||
| 6412 | } | ||
| 6413 | |||
| 6414 | |||
| 6415 | /*********************************************************************** | ||
| 6087 | Fonts | 6416 | Fonts |
| 6088 | ***********************************************************************/ | 6417 | ***********************************************************************/ |
| 6089 | 6418 | ||
| @@ -6178,7 +6507,8 @@ mac_to_x_fontname (name, size, style, charset) | |||
| 6178 | { | 6507 | { |
| 6179 | Str31 foundry, cs; | 6508 | Str31 foundry, cs; |
| 6180 | Str255 family; | 6509 | Str255 family; |
| 6181 | char xf[256], *result, *p; | 6510 | char xf[256], *result; |
| 6511 | unsigned char *p; | ||
| 6182 | 6512 | ||
| 6183 | if (sscanf (name, "%31[^-]-%255[^-]-%31s", foundry, family, cs) == 3) | 6513 | if (sscanf (name, "%31[^-]-%255[^-]-%31s", foundry, family, cs) == 3) |
| 6184 | charset = cs; | 6514 | charset = cs; |
| @@ -6195,7 +6525,10 @@ mac_to_x_fontname (name, size, style, charset) | |||
| 6195 | result = xmalloc (strlen (foundry) + strlen (family) + strlen (xf) + 3 + 1); | 6525 | result = xmalloc (strlen (foundry) + strlen (family) + strlen (xf) + 3 + 1); |
| 6196 | sprintf (result, "-%s-%s-%s", foundry, family, xf); | 6526 | sprintf (result, "-%s-%s-%s", foundry, family, xf); |
| 6197 | for (p = result; *p; p++) | 6527 | for (p = result; *p; p++) |
| 6198 | *p = tolower(*p); | 6528 | /* On Mac OS X 10.3, tolower also converts non-ASCII characters |
| 6529 | for some locales. */ | ||
| 6530 | if (isascii (*p)) | ||
| 6531 | *p = tolower (*p); | ||
| 6199 | return result; | 6532 | return result; |
| 6200 | } | 6533 | } |
| 6201 | 6534 | ||
| @@ -6253,7 +6586,7 @@ x_font_name_to_mac_font_name (xf, mf, mf_decoded, style, cs) | |||
| 6253 | { | 6586 | { |
| 6254 | setup_coding_system (coding_system, &coding); | 6587 | setup_coding_system (coding_system, &coding); |
| 6255 | coding.src_multibyte = 1; | 6588 | coding.src_multibyte = 1; |
| 6256 | coding.dst_multibyte = 1; | 6589 | coding.dst_multibyte = 0; |
| 6257 | coding.mode |= CODING_MODE_LAST_BLOCK; | 6590 | coding.mode |= CODING_MODE_LAST_BLOCK; |
| 6258 | encode_coding (&coding, mf_decoded, mf, | 6591 | encode_coding (&coding, mf_decoded, mf, |
| 6259 | strlen (mf_decoded), sizeof (Str255) - 1); | 6592 | strlen (mf_decoded), sizeof (Str255) - 1); |
| @@ -6267,13 +6600,13 @@ add_font_name_table_entry (char *font_name) | |||
| 6267 | { | 6600 | { |
| 6268 | if (font_name_table_size == 0) | 6601 | if (font_name_table_size == 0) |
| 6269 | { | 6602 | { |
| 6270 | font_name_table_size = 16; | 6603 | font_name_table_size = 256; |
| 6271 | font_name_table = (char **) | 6604 | font_name_table = (char **) |
| 6272 | xmalloc (font_name_table_size * sizeof (char *)); | 6605 | xmalloc (font_name_table_size * sizeof (char *)); |
| 6273 | } | 6606 | } |
| 6274 | else if (font_name_count + 1 >= font_name_table_size) | 6607 | else if (font_name_count + 1 >= font_name_table_size) |
| 6275 | { | 6608 | { |
| 6276 | font_name_table_size += 16; | 6609 | font_name_table_size *= 2; |
| 6277 | font_name_table = (char **) | 6610 | font_name_table = (char **) |
| 6278 | xrealloc (font_name_table, | 6611 | xrealloc (font_name_table, |
| 6279 | font_name_table_size * sizeof (char *)); | 6612 | font_name_table_size * sizeof (char *)); |
| @@ -6498,39 +6831,16 @@ static int xlfd_scalable_fields[] = | |||
| 6498 | }; | 6831 | }; |
| 6499 | 6832 | ||
| 6500 | static Lisp_Object | 6833 | static Lisp_Object |
| 6501 | mac_c_string_match (regexp, string, nonspecial, exact) | ||
| 6502 | Lisp_Object regexp; | ||
| 6503 | const char *string, *nonspecial; | ||
| 6504 | int exact; | ||
| 6505 | { | ||
| 6506 | if (exact) | ||
| 6507 | { | ||
| 6508 | if (strcmp (string, nonspecial) == 0) | ||
| 6509 | return build_string (string); | ||
| 6510 | } | ||
| 6511 | else if (strstr (string, nonspecial)) | ||
| 6512 | { | ||
| 6513 | Lisp_Object str = build_string (string); | ||
| 6514 | |||
| 6515 | if (fast_string_match (regexp, str) >= 0) | ||
| 6516 | return str; | ||
| 6517 | } | ||
| 6518 | |||
| 6519 | return Qnil; | ||
| 6520 | } | ||
| 6521 | |||
| 6522 | static Lisp_Object | ||
| 6523 | mac_do_list_fonts (pattern, maxnames) | 6834 | mac_do_list_fonts (pattern, maxnames) |
| 6524 | char *pattern; | 6835 | char *pattern; |
| 6525 | int maxnames; | 6836 | int maxnames; |
| 6526 | { | 6837 | { |
| 6527 | int i, n_fonts = 0; | 6838 | int i, n_fonts = 0; |
| 6528 | Lisp_Object font_list = Qnil, pattern_regex, fontname; | 6839 | Lisp_Object font_list = Qnil; |
| 6529 | char *regex = (char *) alloca (strlen (pattern) * 2 + 3); | 6840 | struct xlfdpat *pat; |
| 6530 | char *scaled, *ptr; | 6841 | char *scaled, *ptr; |
| 6531 | int scl_val[XLFD_SCL_LAST], *field, *val; | 6842 | int scl_val[XLFD_SCL_LAST], *field, *val; |
| 6532 | char *longest_start, *cur_start, *nonspecial; | 6843 | int exact; |
| 6533 | int longest_len, exact; | ||
| 6534 | 6844 | ||
| 6535 | if (font_name_table == NULL) /* Initialize when first used. */ | 6845 | if (font_name_table == NULL) /* Initialize when first used. */ |
| 6536 | init_font_name_table (); | 6846 | init_font_name_table (); |
| @@ -6588,61 +6898,17 @@ mac_do_list_fonts (pattern, maxnames) | |||
| 6588 | else | 6898 | else |
| 6589 | scl_val[XLFD_SCL_PIXEL_SIZE] = -1; | 6899 | scl_val[XLFD_SCL_PIXEL_SIZE] = -1; |
| 6590 | 6900 | ||
| 6591 | ptr = regex; | 6901 | pat = xlfdpat_create (pattern); |
| 6592 | *ptr++ = '^'; | 6902 | if (pat == NULL) |
| 6593 | 6903 | return Qnil; | |
| 6594 | longest_start = cur_start = ptr; | ||
| 6595 | longest_len = 0; | ||
| 6596 | exact = 1; | ||
| 6597 | |||
| 6598 | /* Turn pattern into a regexp and do a regexp match. Also find the | ||
| 6599 | longest substring containing no special characters. */ | ||
| 6600 | for (; *pattern; pattern++) | ||
| 6601 | { | ||
| 6602 | if (*pattern == '?' || *pattern == '*') | ||
| 6603 | { | ||
| 6604 | if (ptr - cur_start > longest_len) | ||
| 6605 | { | ||
| 6606 | longest_start = cur_start; | ||
| 6607 | longest_len = ptr - cur_start; | ||
| 6608 | } | ||
| 6609 | exact = 0; | ||
| 6610 | |||
| 6611 | if (*pattern == '?') | ||
| 6612 | *ptr++ = '.'; | ||
| 6613 | else /* if (*pattern == '*') */ | ||
| 6614 | { | ||
| 6615 | *ptr++ = '.'; | ||
| 6616 | *ptr++ = '*'; | ||
| 6617 | } | ||
| 6618 | cur_start = ptr; | ||
| 6619 | } | ||
| 6620 | else | ||
| 6621 | *ptr++ = tolower (*pattern); | ||
| 6622 | } | ||
| 6623 | |||
| 6624 | if (ptr - cur_start > longest_len) | ||
| 6625 | { | ||
| 6626 | longest_start = cur_start; | ||
| 6627 | longest_len = ptr - cur_start; | ||
| 6628 | } | ||
| 6629 | |||
| 6630 | *ptr = '$'; | ||
| 6631 | *(ptr + 1) = '\0'; | ||
| 6632 | |||
| 6633 | nonspecial = xmalloc (longest_len + 1); | ||
| 6634 | strncpy (nonspecial, longest_start, longest_len); | ||
| 6635 | nonspecial[longest_len] = '\0'; | ||
| 6636 | 6904 | ||
| 6637 | pattern_regex = build_string (regex); | 6905 | exact = xlfdpat_exact_p (pat); |
| 6638 | 6906 | ||
| 6639 | for (i = 0; i < font_name_count; i++) | 6907 | for (i = 0; i < font_name_count; i++) |
| 6640 | { | 6908 | { |
| 6641 | fontname = mac_c_string_match (pattern_regex, font_name_table[i], | 6909 | if (xlfdpat_match (pat, font_name_table[i])) |
| 6642 | nonspecial, exact); | ||
| 6643 | if (!NILP (fontname)) | ||
| 6644 | { | 6910 | { |
| 6645 | font_list = Fcons (fontname, font_list); | 6911 | font_list = Fcons (build_string (font_name_table[i]), font_list); |
| 6646 | if (exact || maxnames > 0 && ++n_fonts >= maxnames) | 6912 | if (exact || maxnames > 0 && ++n_fonts >= maxnames) |
| 6647 | break; | 6913 | break; |
| 6648 | } | 6914 | } |
| @@ -6652,6 +6918,8 @@ mac_do_list_fonts (pattern, maxnames) | |||
| 6652 | int former_len = ptr - font_name_table[i]; | 6918 | int former_len = ptr - font_name_table[i]; |
| 6653 | 6919 | ||
| 6654 | scaled = xmalloc (strlen (font_name_table[i]) + 20 + 1); | 6920 | scaled = xmalloc (strlen (font_name_table[i]) + 20 + 1); |
| 6921 | if (scaled == NULL) | ||
| 6922 | continue; | ||
| 6655 | memcpy (scaled, font_name_table[i], former_len); | 6923 | memcpy (scaled, font_name_table[i], former_len); |
| 6656 | sprintf (scaled + former_len, | 6924 | sprintf (scaled + former_len, |
| 6657 | "-%d-%d-75-75-m-%d-%s", | 6925 | "-%d-%d-75-75-m-%d-%s", |
| @@ -6659,19 +6927,20 @@ mac_do_list_fonts (pattern, maxnames) | |||
| 6659 | scl_val[XLFD_SCL_POINT_SIZE], | 6927 | scl_val[XLFD_SCL_POINT_SIZE], |
| 6660 | scl_val[XLFD_SCL_AVGWIDTH], | 6928 | scl_val[XLFD_SCL_AVGWIDTH], |
| 6661 | ptr + sizeof ("-0-0-0-0-m-0-") - 1); | 6929 | ptr + sizeof ("-0-0-0-0-m-0-") - 1); |
| 6662 | fontname = mac_c_string_match (pattern_regex, scaled, | 6930 | |
| 6663 | nonspecial, exact); | 6931 | if (xlfdpat_match (pat, scaled)) |
| 6664 | xfree (scaled); | ||
| 6665 | if (!NILP (fontname)) | ||
| 6666 | { | 6932 | { |
| 6667 | font_list = Fcons (fontname, font_list); | 6933 | font_list = Fcons (build_string (scaled), font_list); |
| 6934 | xfree (scaled); | ||
| 6668 | if (exact || maxnames > 0 && ++n_fonts >= maxnames) | 6935 | if (exact || maxnames > 0 && ++n_fonts >= maxnames) |
| 6669 | break; | 6936 | break; |
| 6670 | } | 6937 | } |
| 6938 | else | ||
| 6939 | xfree (scaled); | ||
| 6671 | } | 6940 | } |
| 6672 | } | 6941 | } |
| 6673 | 6942 | ||
| 6674 | xfree (nonspecial); | 6943 | xlfdpat_destroy (pat); |
| 6675 | 6944 | ||
| 6676 | return font_list; | 6945 | return font_list; |
| 6677 | } | 6946 | } |