diff options
| author | Jason Rumney | 2008-07-25 11:25:43 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-07-25 11:25:43 +0000 |
| commit | f31cf550ca95e76bbff474487c68bb36992f96c3 (patch) | |
| tree | 05a8e5b42151bc213d212609a3ce603fe6924dd8 | |
| parent | 6f79c90b19ef0fa073a07e515db7639a2a81fb03 (diff) | |
| download | emacs-f31cf550ca95e76bbff474487c68bb36992f96c3.tar.gz emacs-f31cf550ca95e76bbff474487c68bb36992f96c3.zip | |
* w32font.c (w32font_encode_char): Encode characters outside BMP as
surrogates before looking up glyph index.
(w32font_text_extents): Encode as surrogates if falling back to
functions that need UTF-16 wide chars.
* w32uniscribe.c (uniscribe_encode_char): Encode characters outside
BMP as surrogates before looking up glyph index.
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/w32font.c | 45 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 21 |
3 files changed, 55 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d0daa9412ac..d8583efd915 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2008-07-25 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32font.c (w32font_encode_char): Encode characters outside BMP as | ||
| 4 | surrogates before looking up glyph index. | ||
| 5 | (w32font_text_extents): Encode as surrogates if falling back to | ||
| 6 | functions that need UTF-16 wide chars. | ||
| 7 | |||
| 8 | * w32uniscribe.c (uniscribe_encode_char): Encode characters outside | ||
| 9 | BMP as surrogates before looking up glyph index. | ||
| 10 | |||
| 1 | 2008-07-25 Chong Yidong <cyd@stupidchicken.com> | 11 | 2008-07-25 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 12 | ||
| 3 | * image.c (svg_load_image): Check for failure in return value of | 13 | * image.c (svg_load_image): Check for failure in return value of |
diff --git a/src/w32font.c b/src/w32font.c index 4a4c7625787..380bead2e74 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -327,8 +327,13 @@ w32font_encode_char (font, c) | |||
| 327 | 327 | ||
| 328 | if (c > 0xFFFF) | 328 | if (c > 0xFFFF) |
| 329 | { | 329 | { |
| 330 | /* TODO: Encode as surrogate pair and lookup the glyph. */ | 330 | DWORD surrogate = c - 0x10000; |
| 331 | return FONT_INVALID_CODE; | 331 | |
| 332 | /* High surrogate: U+D800 - U+DBFF. */ | ||
| 333 | in[0] = 0xD800 + ((surrogate >> 10) & 0x03FF); | ||
| 334 | /* Low surrogate: U+DC00 - U+DFFF. */ | ||
| 335 | in[1] = 0xDC00 + (surrogate & 0x03FF); | ||
| 336 | len = 2; | ||
| 332 | } | 337 | } |
| 333 | else | 338 | else |
| 334 | { | 339 | { |
| @@ -394,7 +399,7 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 394 | HDC dc = NULL; | 399 | HDC dc = NULL; |
| 395 | struct frame * f; | 400 | struct frame * f; |
| 396 | int total_width = 0; | 401 | int total_width = 0; |
| 397 | WORD *wcode = NULL; | 402 | WORD *wcode; |
| 398 | SIZE size; | 403 | SIZE size; |
| 399 | 404 | ||
| 400 | struct w32font_info *w32_font = (struct w32font_info *) font; | 405 | struct w32font_info *w32_font = (struct w32font_info *) font; |
| @@ -484,19 +489,27 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 484 | /* For non-truetype fonts, GetGlyphOutlineW is not supported, so | 489 | /* For non-truetype fonts, GetGlyphOutlineW is not supported, so |
| 485 | fallback on other methods that will at least give some of the metric | 490 | fallback on other methods that will at least give some of the metric |
| 486 | information. */ | 491 | information. */ |
| 487 | if (!wcode) { | 492 | |
| 488 | wcode = alloca (nglyphs * sizeof (WORD)); | 493 | /* Make array big enough to hold surrogates. */ |
| 489 | for (i = 0; i < nglyphs; i++) | 494 | wcode = alloca (nglyphs * sizeof (WORD) * 2); |
| 490 | { | 495 | for (i = 0; i < nglyphs; i++) |
| 491 | if (code[i] < 0x10000) | 496 | { |
| 492 | wcode[i] = code[i]; | 497 | if (code[i] < 0x10000) |
| 493 | else | 498 | wcode[i] = code[i]; |
| 494 | { | 499 | else |
| 495 | /* TODO: Convert to surrogate, reallocating array if needed */ | 500 | { |
| 496 | wcode[i] = 0xffff; | 501 | DWORD surrogate = code[i] - 0x10000; |
| 497 | } | 502 | |
| 498 | } | 503 | /* High surrogate: U+D800 - U+DBFF. */ |
| 499 | } | 504 | wcode[i++] = 0xD800 + ((surrogate >> 10) & 0x03FF); |
| 505 | /* Low surrogate: U+DC00 - U+DFFF. */ | ||
| 506 | wcode[i] = 0xDC00 + (surrogate & 0x03FF); | ||
| 507 | /* An extra glyph. wcode is already double the size of code to | ||
| 508 | cope with this. */ | ||
| 509 | nglyphs++; | ||
| 510 | } | ||
| 511 | } | ||
| 512 | |||
| 500 | if (dc == NULL) | 513 | if (dc == NULL) |
| 501 | { | 514 | { |
| 502 | /* TODO: Frames can come and go, and their fonts outlive | 515 | /* TODO: Frames can come and go, and their fonts outlive |
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index 0e0a4e8d143..fc9f48b3a17 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c | |||
| @@ -411,25 +411,36 @@ uniscribe_encode_char (font, c) | |||
| 411 | struct font *font; | 411 | struct font *font; |
| 412 | int c; | 412 | int c; |
| 413 | { | 413 | { |
| 414 | wchar_t chars[1]; | 414 | wchar_t chars[2]; |
| 415 | int len; | ||
| 415 | WORD indices[1]; | 416 | WORD indices[1]; |
| 416 | HDC context; | 417 | HDC context; |
| 417 | struct frame *f; | 418 | struct frame *f; |
| 418 | HFONT old_font; | 419 | HFONT old_font; |
| 419 | DWORD retval; | 420 | DWORD retval; |
| 420 | 421 | ||
| 421 | /* TODO: surrogates. */ | ||
| 422 | if (c > 0xFFFF) | 422 | if (c > 0xFFFF) |
| 423 | return FONT_INVALID_CODE; | 423 | { |
| 424 | DWORD surrogate = c - 0x10000; | ||
| 424 | 425 | ||
| 425 | chars[0] = (wchar_t) c; | 426 | /* High surrogate: U+D800 - U+DBFF. */ |
| 427 | chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF); | ||
| 428 | /* Low surrogate: U+DC00 - U+DFFF. */ | ||
| 429 | chars[1] = 0xDC00 + (surrogate & 0x03FF); | ||
| 430 | len = 2; | ||
| 431 | } | ||
| 432 | else | ||
| 433 | { | ||
| 434 | chars[0] = (wchar_t) c; | ||
| 435 | len = 1; | ||
| 436 | } | ||
| 426 | 437 | ||
| 427 | /* Use selected frame until API is updated to pass the frame. */ | 438 | /* Use selected frame until API is updated to pass the frame. */ |
| 428 | f = XFRAME (selected_frame); | 439 | f = XFRAME (selected_frame); |
| 429 | context = get_frame_dc (f); | 440 | context = get_frame_dc (f); |
| 430 | old_font = SelectObject (context, FONT_HANDLE(font)); | 441 | old_font = SelectObject (context, FONT_HANDLE(font)); |
| 431 | 442 | ||
| 432 | retval = GetGlyphIndicesW (context, chars, 1, indices, | 443 | retval = GetGlyphIndicesW (context, chars, len, indices, |
| 433 | GGI_MARK_NONEXISTING_GLYPHS); | 444 | GGI_MARK_NONEXISTING_GLYPHS); |
| 434 | 445 | ||
| 435 | SelectObject (context, old_font); | 446 | SelectObject (context, old_font); |