summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Rumney <jasonr@gnu.org>2008-07-25 21:53:21 +0000
committerJason Rumney <jasonr@gnu.org>2008-07-25 21:53:21 +0000
commit964035f2d9778edb5f33f9b310ba9481c90a310e (patch)
tree2229a3450efeae908e93b2631d34db7ff7833445 /src
parentd2593d6f8aa4649bd1cd57ab875a4a9ca4eccf92 (diff)
downloademacs-964035f2d9778edb5f33f9b310ba9481c90a310e.tar.gz
(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 8c28c635357..1fdc31edcc4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-25 Jason Rumney <jasonr@gnu.org>
+
+ * w32uniscribe.c (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.
+
+ * w32font.c (w32font_has_char): Handle the case where we can't
+ determine the script for a character.
+
2008-07-25 Chong Yidong <cyd@stupidchicken.com>
* 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)
/* Initialize the cache for this font. */
uniscribe_font->cache = NULL;
+
/* Mark the format as opentype */
uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype;
uniscribe_font->w32_font.font.driver = &uniscribe_font_driver;
@@ -150,7 +151,7 @@ uniscribe_close (f, font)
= (struct uniscribe_font_info *) font;
if (uniscribe_font->cache)
- ScriptFreeCache (&uniscribe_font->cache);
+ ScriptFreeCache (&(uniscribe_font->cache));
w32font_close (f, font);
}
@@ -206,12 +207,10 @@ uniscribe_shape (lgstring)
wchar_t *chars;
WORD *glyphs, *clusters;
SCRIPT_ITEM *items;
- SCRIPT_CONTROL control;
SCRIPT_VISATTR *attributes;
int *advances;
GOFFSET *offsets;
ABC overall_metrics;
- MAT2 transform;
HDC context;
HFONT old_font;
HRESULT result;
@@ -239,9 +238,8 @@ uniscribe_shape (lgstring)
can be treated together. First try a single run. */
max_items = 2;
items = (SCRIPT_ITEM *) xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1);
- bzero (&control, sizeof (control));
- while ((result = ScriptItemize (chars, nchars, max_items, &control, NULL,
+ while ((result = ScriptItemize (chars, nchars, max_items, NULL, NULL,
items, &nitems)) == E_OUTOFMEMORY)
{
/* If that wasn't enough, keep trying with one more run. */
@@ -250,8 +248,7 @@ uniscribe_shape (lgstring)
sizeof (SCRIPT_ITEM) * max_items + 1);
}
- /* 0 = success in Microsoft's backwards world. */
- if (result)
+ if (!SUCCEEDED (result))
{
xfree (items);
return Qnil;
@@ -269,9 +266,6 @@ uniscribe_shape (lgstring)
attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
advances = alloca (max_glyphs * sizeof (int));
offsets = alloca (max_glyphs * sizeof (GOFFSET));
- bzero (&transform, sizeof (transform));
- transform.eM11.value = 1;
- transform.eM22.value = 1;
for (i = 0; i < nitems; i++)
{
@@ -304,7 +298,7 @@ uniscribe_shape (lgstring)
result = ScriptPlace (context, &(uniscribe_font->cache),
glyphs, nglyphs, attributes, &(items[i].a),
advances, offsets, &overall_metrics);
- if (result == 0) /* Success. */
+ if (SUCCEEDED (result))
{
int j, nclusters, from, to;
@@ -364,7 +358,7 @@ uniscribe_shape (lgstring)
&(uniscribe_font->cache),
glyphs[j], &char_metric);
- if (result == 0) /* Success. */
+ if (SUCCEEDED (result))
{
LGLYPH_SET_LBEARING (lglyph, char_metric.abcA);
LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA
@@ -411,45 +405,68 @@ uniscribe_encode_char (font, c)
struct font *font;
int c;
{
- wchar_t chars[2];
- int len;
- WORD indices[1];
HDC context;
struct frame *f;
HFONT old_font;
- DWORD retval;
+ unsigned code = FONT_INVALID_CODE;
+
+ /* Use selected frame until API is updated to pass the frame. */
+ f = XFRAME (selected_frame);
+ context = get_frame_dc (f);
+ old_font = SelectObject (context, FONT_HANDLE(font));
- if (c > 0xFFFF)
+ /* There are a number of ways to get glyph indices for BMP characters.
+ The GetGlyphIndices GDI function seems to work best for detecting
+ non-existing glyphs. */
+ if (c < 0x10000)
+ {
+ wchar_t ch = (wchar_t) c;
+ WORD index;
+ DWORD retval = GetGlyphIndicesW (context, &ch, 1, &index,
+ GGI_MARK_NONEXISTING_GLYPHS);
+ if (retval == 1 && index != 0xFFFF)
+ code = index;
+ }
+
+ /* Non BMP characters must be handled by the uniscribe shaping
+ engine as GDI functions (except blindly displaying lines of
+ unicode text) and the promising looking ScriptGetCMap do not
+ convert surrogate pairs to glyph indexes correctly. */
+ else
{
+ wchar_t ch[2];
+ SCRIPT_ITEM* items;
+ int nitems;
+ struct uniscribe_font_info *uniscribe_font
+ = (struct uniscribe_font_info *)font;
DWORD surrogate = c - 0x10000;
/* High surrogate: U+D800 - U+DBFF. */
- chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
+ ch[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
/* Low surrogate: U+DC00 - U+DFFF. */
- chars[1] = 0xDC00 + (surrogate & 0x03FF);
- len = 2;
+ ch[1] = 0xDC00 + (surrogate & 0x03FF);
+
+ items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1);
+ if (SUCCEEDED (ScriptItemize (ch, 2, 2, NULL, NULL, items, &nitems)))
+ {
+ WORD glyphs[2], clusters[2];
+ SCRIPT_VISATTR attrs[2];
+ int nglyphs;
+
+ if (SUCCEEDED (ScriptShape (context, &(uniscribe_font->cache),
+ ch, 2, 2, &(items[0].a),
+ glyphs, clusters, attrs, &nglyphs))
+ && nglyphs == 1)
+ {
+ code = glyphs[0];
+ }
+ }
}
- else
- {
- chars[0] = (wchar_t) c;
- len = 1;
- }
-
- /* Use selected frame until API is updated to pass the frame. */
- f = XFRAME (selected_frame);
- context = get_frame_dc (f);
- old_font = SelectObject (context, FONT_HANDLE(font));
-
- retval = GetGlyphIndicesW (context, chars, len, indices,
- GGI_MARK_NONEXISTING_GLYPHS);
SelectObject (context, old_font);
release_frame_dc (f, context);
- if (retval == 1)
- return indices[0] == 0xFFFF ? FONT_INVALID_CODE : indices[0];
- else
- return FONT_INVALID_CODE;
+ return code;
}
/*