aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2008-07-25 21:53:21 +0000
committerJason Rumney2008-07-25 21:53:21 +0000
commit11856d4d74e6670f2b60c277fab8a323588461a1 (patch)
treebb2145c1bdd347970253e21898790add80aa78cf /src
parent6a8082b5d4574f44a40c6c03c56d023f17a8ab3a (diff)
downloademacs-11856d4d74e6670f2b60c277fab8a323588461a1.tar.gz
emacs-11856d4d74e6670f2b60c277fab8a323588461a1.zip
(uniscribe_shape): Pass NULL for control arg to ScriptItemize. Clean
up return value checking. Remove unused variables. (uniscribe_encode_char): Encode non-BMP characters with uniscribe shaping engine.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/w32uniscribe.c91
2 files changed, 65 insertions, 37 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 32129795587..c23aadee7d8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12008-07-25 Jason Rumney <jasonr@gnu.org>
2
3 * w32uniscribe.c (uniscribe_shape): Pass NULL for control arg to
4 ScriptItemize. Clean up return value checking. Remove unused
5 variables.
6 (uniscribe_encode_char): Encode non-BMP characters with uniscribe
7 shaping engine.
8
9 * w32font.c (w32font_has_char): Handle the case where we can't
10 determine the script for a character.
11
12008-07-25 Chong Yidong <cyd@stupidchicken.com> 122008-07-25 Chong Yidong <cyd@stupidchicken.com>
2 13
3 * term.c (syms_of_term): Initialize default_orig_pair, 14 * term.c (syms_of_term): Initialize default_orig_pair,
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index fc9f48b3a17..8315f8814ad 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -134,6 +134,7 @@ uniscribe_open (f, font_entity, pixel_size)
134 134
135 /* Initialize the cache for this font. */ 135 /* Initialize the cache for this font. */
136 uniscribe_font->cache = NULL; 136 uniscribe_font->cache = NULL;
137
137 /* Mark the format as opentype */ 138 /* Mark the format as opentype */
138 uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype; 139 uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype;
139 uniscribe_font->w32_font.font.driver = &uniscribe_font_driver; 140 uniscribe_font->w32_font.font.driver = &uniscribe_font_driver;
@@ -150,7 +151,7 @@ uniscribe_close (f, font)
150 = (struct uniscribe_font_info *) font; 151 = (struct uniscribe_font_info *) font;
151 152
152 if (uniscribe_font->cache) 153 if (uniscribe_font->cache)
153 ScriptFreeCache (&uniscribe_font->cache); 154 ScriptFreeCache (&(uniscribe_font->cache));
154 155
155 w32font_close (f, font); 156 w32font_close (f, font);
156} 157}
@@ -206,12 +207,10 @@ uniscribe_shape (lgstring)
206 wchar_t *chars; 207 wchar_t *chars;
207 WORD *glyphs, *clusters; 208 WORD *glyphs, *clusters;
208 SCRIPT_ITEM *items; 209 SCRIPT_ITEM *items;
209 SCRIPT_CONTROL control;
210 SCRIPT_VISATTR *attributes; 210 SCRIPT_VISATTR *attributes;
211 int *advances; 211 int *advances;
212 GOFFSET *offsets; 212 GOFFSET *offsets;
213 ABC overall_metrics; 213 ABC overall_metrics;
214 MAT2 transform;
215 HDC context; 214 HDC context;
216 HFONT old_font; 215 HFONT old_font;
217 HRESULT result; 216 HRESULT result;
@@ -239,9 +238,8 @@ uniscribe_shape (lgstring)
239 can be treated together. First try a single run. */ 238 can be treated together. First try a single run. */
240 max_items = 2; 239 max_items = 2;
241 items = (SCRIPT_ITEM *) xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1); 240 items = (SCRIPT_ITEM *) xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1);
242 bzero (&control, sizeof (control));
243 241
244 while ((result = ScriptItemize (chars, nchars, max_items, &control, NULL, 242 while ((result = ScriptItemize (chars, nchars, max_items, NULL, NULL,
245 items, &nitems)) == E_OUTOFMEMORY) 243 items, &nitems)) == E_OUTOFMEMORY)
246 { 244 {
247 /* If that wasn't enough, keep trying with one more run. */ 245 /* If that wasn't enough, keep trying with one more run. */
@@ -250,8 +248,7 @@ uniscribe_shape (lgstring)
250 sizeof (SCRIPT_ITEM) * max_items + 1); 248 sizeof (SCRIPT_ITEM) * max_items + 1);
251 } 249 }
252 250
253 /* 0 = success in Microsoft's backwards world. */ 251 if (!SUCCEEDED (result))
254 if (result)
255 { 252 {
256 xfree (items); 253 xfree (items);
257 return Qnil; 254 return Qnil;
@@ -269,9 +266,6 @@ uniscribe_shape (lgstring)
269 attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR)); 266 attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
270 advances = alloca (max_glyphs * sizeof (int)); 267 advances = alloca (max_glyphs * sizeof (int));
271 offsets = alloca (max_glyphs * sizeof (GOFFSET)); 268 offsets = alloca (max_glyphs * sizeof (GOFFSET));
272 bzero (&transform, sizeof (transform));
273 transform.eM11.value = 1;
274 transform.eM22.value = 1;
275 269
276 for (i = 0; i < nitems; i++) 270 for (i = 0; i < nitems; i++)
277 { 271 {
@@ -304,7 +298,7 @@ uniscribe_shape (lgstring)
304 result = ScriptPlace (context, &(uniscribe_font->cache), 298 result = ScriptPlace (context, &(uniscribe_font->cache),
305 glyphs, nglyphs, attributes, &(items[i].a), 299 glyphs, nglyphs, attributes, &(items[i].a),
306 advances, offsets, &overall_metrics); 300 advances, offsets, &overall_metrics);
307 if (result == 0) /* Success. */ 301 if (SUCCEEDED (result))
308 { 302 {
309 int j, nclusters, from, to; 303 int j, nclusters, from, to;
310 304
@@ -364,7 +358,7 @@ uniscribe_shape (lgstring)
364 &(uniscribe_font->cache), 358 &(uniscribe_font->cache),
365 glyphs[j], &char_metric); 359 glyphs[j], &char_metric);
366 360
367 if (result == 0) /* Success. */ 361 if (SUCCEEDED (result))
368 { 362 {
369 LGLYPH_SET_LBEARING (lglyph, char_metric.abcA); 363 LGLYPH_SET_LBEARING (lglyph, char_metric.abcA);
370 LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA 364 LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA
@@ -411,45 +405,68 @@ uniscribe_encode_char (font, c)
411 struct font *font; 405 struct font *font;
412 int c; 406 int c;
413{ 407{
414 wchar_t chars[2];
415 int len;
416 WORD indices[1];
417 HDC context; 408 HDC context;
418 struct frame *f; 409 struct frame *f;
419 HFONT old_font; 410 HFONT old_font;
420 DWORD retval; 411 unsigned code = FONT_INVALID_CODE;
412
413 /* Use selected frame until API is updated to pass the frame. */
414 f = XFRAME (selected_frame);
415 context = get_frame_dc (f);
416 old_font = SelectObject (context, FONT_HANDLE(font));
421 417
422 if (c > 0xFFFF) 418 /* There are a number of ways to get glyph indices for BMP characters.
419 The GetGlyphIndices GDI function seems to work best for detecting
420 non-existing glyphs. */
421 if (c < 0x10000)
422 {
423 wchar_t ch = (wchar_t) c;
424 WORD index;
425 DWORD retval = GetGlyphIndicesW (context, &ch, 1, &index,
426 GGI_MARK_NONEXISTING_GLYPHS);
427 if (retval == 1 && index != 0xFFFF)
428 code = index;
429 }
430
431 /* Non BMP characters must be handled by the uniscribe shaping
432 engine as GDI functions (except blindly displaying lines of
433 unicode text) and the promising looking ScriptGetCMap do not
434 convert surrogate pairs to glyph indexes correctly. */
435 else
423 { 436 {
437 wchar_t ch[2];
438 SCRIPT_ITEM* items;
439 int nitems;
440 struct uniscribe_font_info *uniscribe_font
441 = (struct uniscribe_font_info *)font;
424 DWORD surrogate = c - 0x10000; 442 DWORD surrogate = c - 0x10000;
425 443
426 /* High surrogate: U+D800 - U+DBFF. */ 444 /* High surrogate: U+D800 - U+DBFF. */
427 chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF); 445 ch[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
428 /* Low surrogate: U+DC00 - U+DFFF. */ 446 /* Low surrogate: U+DC00 - U+DFFF. */
429 chars[1] = 0xDC00 + (surrogate & 0x03FF); 447 ch[1] = 0xDC00 + (surrogate & 0x03FF);
430 len = 2; 448
449 items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1);
450 if (SUCCEEDED (ScriptItemize (ch, 2, 2, NULL, NULL, items, &nitems)))
451 {
452 WORD glyphs[2], clusters[2];
453 SCRIPT_VISATTR attrs[2];
454 int nglyphs;
455
456 if (SUCCEEDED (ScriptShape (context, &(uniscribe_font->cache),
457 ch, 2, 2, &(items[0].a),
458 glyphs, clusters, attrs, &nglyphs))
459 && nglyphs == 1)
460 {
461 code = glyphs[0];
462 }
463 }
431 } 464 }
432 else
433 {
434 chars[0] = (wchar_t) c;
435 len = 1;
436 }
437
438 /* Use selected frame until API is updated to pass the frame. */
439 f = XFRAME (selected_frame);
440 context = get_frame_dc (f);
441 old_font = SelectObject (context, FONT_HANDLE(font));
442
443 retval = GetGlyphIndicesW (context, chars, len, indices,
444 GGI_MARK_NONEXISTING_GLYPHS);
445 465
446 SelectObject (context, old_font); 466 SelectObject (context, old_font);
447 release_frame_dc (f, context); 467 release_frame_dc (f, context);
448 468
449 if (retval == 1) 469 return code;
450 return indices[0] == 0xFFFF ? FONT_INVALID_CODE : indices[0];
451 else
452 return FONT_INVALID_CODE;
453} 470}
454 471
455/* 472/*