1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-02-05 20:43:08 +00:00

(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.
This commit is contained in:
Jason Rumney 2008-07-25 21:53:21 +00:00
parent 6a8082b5d4
commit 11856d4d74
2 changed files with 66 additions and 38 deletions

View File

@ -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,

View File

@ -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;
if (c > 0xFFFF)
{
DWORD surrogate = c - 0x10000;
/* High surrogate: U+D800 - U+DBFF. */
chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
/* Low surrogate: U+DC00 - U+DFFF. */
chars[1] = 0xDC00 + (surrogate & 0x03FF);
len = 2;
}
else
{
chars[0] = (wchar_t) c;
len = 1;
}
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));
retval = GetGlyphIndicesW (context, chars, len, indices,
GGI_MARK_NONEXISTING_GLYPHS);
/* 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. */
ch[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
/* Low surrogate: U+DC00 - U+DFFF. */
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];
}
}
}
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;
}
/*