Attempted to clean up the Uniscribe stuff.
This commit is contained in:
parent
9dbc8a1ba2
commit
e79066fd9d
|
@ -38,6 +38,22 @@ void uiDrawFreeFont(uiDrawFont *df)
|
||||||
- http://www.microsoft.com/msj/1198/multilang/multilang.aspx
|
- http://www.microsoft.com/msj/1198/multilang/multilang.aspx
|
||||||
Even with all this we're on our own with actual paragraph layout; see the last link for example code (which we don't use here). */
|
Even with all this we're on our own with actual paragraph layout; see the last link for example code (which we don't use here). */
|
||||||
|
|
||||||
|
struct uniitem {
|
||||||
|
SCRIPT_ITEM item;
|
||||||
|
|
||||||
|
int nGlyphs;
|
||||||
|
WORD *glyphs;
|
||||||
|
SCRIPT_VISATTR *visattrs;
|
||||||
|
int *advances;
|
||||||
|
GOFFSET *goffsets;
|
||||||
|
|
||||||
|
WCHAR *pwcChars;
|
||||||
|
int nChars;
|
||||||
|
WORD *clusters;
|
||||||
|
|
||||||
|
ABC abc;
|
||||||
|
};
|
||||||
|
|
||||||
struct uniscribe {
|
struct uniscribe {
|
||||||
WCHAR *text;
|
WCHAR *text;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -46,26 +62,22 @@ struct uniscribe {
|
||||||
SCRIPT_CONTROL control;
|
SCRIPT_CONTROL control;
|
||||||
SCRIPT_STATE state;
|
SCRIPT_STATE state;
|
||||||
|
|
||||||
SCRIPT_ITEM *items;
|
struct uniitem *items;
|
||||||
int nItems;
|
int nItems;
|
||||||
|
|
||||||
SCRIPT_CACHE cache;
|
SCRIPT_CACHE cache;
|
||||||
WORD **glyphs;
|
|
||||||
WORD **clusters;
|
|
||||||
SCRIPT_VISATTR **visattrs;
|
|
||||||
int *nGlyphs;
|
|
||||||
|
|
||||||
int **advances;
|
|
||||||
GOFFSET **gOffsets;
|
|
||||||
ABC *abcs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// the step numbers in this function are according to the "Lay Out Text Using Uniscribe" section of https://msdn.microsoft.com/en-us/library/windows/desktop/dd317792%28v=vs.85%29.aspx
|
// the step numbers in this function are according to the "Lay Out Text Using Uniscribe" section of https://msdn.microsoft.com/en-us/library/windows/desktop/dd317792%28v=vs.85%29.aspx
|
||||||
void initUniscribe(struct uniscribe *s, WCHAR *text, HDC dc)
|
|
||||||
|
// this does step 4
|
||||||
|
// steps 1 through 3 are irrelevent here
|
||||||
|
static void initUniscribe(struct uniscribe *s, WCHAR *text, HDC dc)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
SCRIPT_ITEM *items;
|
||||||
int nAlloc;
|
int nAlloc;
|
||||||
int i;
|
int i;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
ZeroMemory(s, sizeof (struct uniscribe));
|
ZeroMemory(s, sizeof (struct uniscribe));
|
||||||
|
|
||||||
|
@ -73,17 +85,15 @@ void initUniscribe(struct uniscribe *s, WCHAR *text, HDC dc)
|
||||||
s->len = wcslen(s->text);
|
s->len = wcslen(s->text);
|
||||||
s->dc = dc;
|
s->dc = dc;
|
||||||
|
|
||||||
// steps 1 through 3 are irrelevent here
|
items = NULL;
|
||||||
|
|
||||||
// step 4
|
|
||||||
nAlloc = 32;
|
nAlloc = 32;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// TODO use uiRealloc
|
// TODO use uiRealloc
|
||||||
s->items = realloc(s->items, nAlloc * sizeof (SCRIPT_ITEM));
|
items = realloc(items, nAlloc * sizeof (SCRIPT_ITEM));
|
||||||
hr = ScriptItemize(s->text, s->len,
|
hr = ScriptItemize(s->text, s->len,
|
||||||
nAlloc,
|
nAlloc,
|
||||||
&(s->control), &(s->state),
|
&(s->control), &(s->state),
|
||||||
s->items, &(s->nItems));
|
items, &(s->nItems));
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
break;
|
break;
|
||||||
if (hr == E_OUTOFMEMORY) {
|
if (hr == E_OUTOFMEMORY) {
|
||||||
|
@ -93,40 +103,67 @@ void initUniscribe(struct uniscribe *s, WCHAR *text, HDC dc)
|
||||||
logHRESULT("error itemizing string in initUniscribe()", hr);
|
logHRESULT("error itemizing string in initUniscribe()", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this does part of step 6
|
||||||
|
s->items = malloc(s->nItems * sizeof (struct uniitem));
|
||||||
|
ZeroMemory(s->items, s->nItems * sizeof (struct uniitem));//TODO remove when switching to uiAlloc
|
||||||
|
for (i = 0; i < s->nItems; i++) {
|
||||||
|
s->items[i].pwcChars = s->text + items[i].iCharPos;
|
||||||
|
s->items[i].nChars = items[i + 1].iCharPos - items[i].iCharPos;
|
||||||
|
s->items[i].item = items[i];
|
||||||
|
}
|
||||||
|
free(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetItem(struct uniitem *item)
|
||||||
|
{
|
||||||
|
if (item->nGlyphs == 0)
|
||||||
|
return;
|
||||||
|
item->nGlyphs = 0;
|
||||||
|
// TODO switch to uiFree
|
||||||
|
free(item->glyphs);
|
||||||
|
item->glyphs = NULL;
|
||||||
|
free(item->visattrs);
|
||||||
|
item->visattrs = NULL;
|
||||||
|
free(item->advances);
|
||||||
|
item->advances = NULL;
|
||||||
|
free(item->goffsets);
|
||||||
|
item->goffsets = NULL;
|
||||||
|
free(item->clusters);
|
||||||
|
item->clusters = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// step 5
|
// step 5
|
||||||
// we're not using multiple fonts; we have no lists to merge
|
// we're not using multiple fonts; we have no lists to merge
|
||||||
|
|
||||||
// step 6
|
// step 6
|
||||||
s->glyphs = malloc(s->nItems * sizeof (WORD *));
|
static void shapeItem(struct uniscribe *s, int n)
|
||||||
s->clusters = malloc(s->nItems * sizeof (WORD *));
|
{
|
||||||
s->visattrs = malloc(s->nItems * sizeof (SCRIPT_VISATTR *));
|
struct uniitem *item;
|
||||||
s->nGlyphs = malloc(s->nItems * sizeof (int));
|
int nAlloc;
|
||||||
for (i = 0; i < s->nItems; i++) {
|
HRESULT hr;
|
||||||
WCHAR *pwcChars;
|
|
||||||
int nChars;
|
|
||||||
|
|
||||||
pwcChars = s->text + s->items[i].iCharPos;
|
item = &(s->items[n]);
|
||||||
nChars = s->items[i + 1].iCharPos - s->items[i].iCharPos;
|
resetItem(item);
|
||||||
nAlloc = 1.5 * nChars + 16;
|
item->clusters = malloc(nChars * sizeof (WORD));
|
||||||
s->glyphs[i] = NULL;//TODO remove when switched to uiAlloc
|
|
||||||
s->visattrs[i] = NULL;
|
// TODO move to uiAlloc
|
||||||
s->clusters[i] = malloc(nChars * sizeof (WORD));
|
nAlloc = 1.5 * item->nChars + 16;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
s->glyphs[i] = realloc(s->glyphs[i], nAlloc * sizeof (WORD));
|
item->glyphs = realloc(item->glyphs, nAlloc * sizeof (WORD));
|
||||||
s->visattrs[i] = realloc(s->visattrs[i], nAlloc * sizeof (SCRIPT_VISATTR));
|
item->visattrs = realloc(item->visattrs, nAlloc * sizeof (SCRIPT_VISATTR));
|
||||||
hr = ScriptShape(s->dc, &(s->cache),
|
hr = ScriptShape(s->dc, &(s->cache),
|
||||||
pwcChars, nChars,
|
item->pwcChars, item->nChars,
|
||||||
nAlloc,
|
nAlloc,
|
||||||
&(s->items[i].a),
|
&(item->item.a),
|
||||||
s->glyphs[i], s->clusters[i],
|
item->glyphs, item->clusters,
|
||||||
s->visattrs[i], &(s->nGlyphs[i]));
|
item->visattrs, &(item->nGlyphs));
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
break;
|
break;
|
||||||
if (hr == E_OUTOFMEMORY) {
|
if (hr == E_OUTOFMEMORY) {
|
||||||
nAlloc *= 2;
|
nAlloc *= 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logHRESULT("error shaping glyphs in initUniscribe()", hr);
|
logHRESULT("error shaping glyphs in shapeItem()", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,55 +171,35 @@ s->visattrs[i] = NULL;
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// step 8
|
// step 8
|
||||||
s->advances = malloc(s->nItems * sizeof (int *));
|
static void placeItem(struct uniscribe *s, int n)
|
||||||
s->goffsets = malloc(s->nItems * sizeof (GOFFSET *));
|
{
|
||||||
s->abcs = malloc(s->nItems * sizeof (ABC));
|
struct uniitem *item;
|
||||||
for (i = 0; i < s->nItems; i++) {
|
HRESULT hr;
|
||||||
s->advances[i] = malloc(s->nGlyphs[i] * sizeof (int));
|
|
||||||
s->goffsets[i] = malloc(s->nGlyphs[i] * sizeof (GOFFSET));
|
item = &(s->items[n]);
|
||||||
|
|
||||||
|
item->advances = malloc(item->nGlyphs * sizeof (int));
|
||||||
|
item->goffsets = malloc(item->nGlyphs * sizeof (GOFFSET));
|
||||||
hr = ScriptPlace(s->dc, &(s->cache),
|
hr = ScriptPlace(s->dc, &(s->cache),
|
||||||
s->glyphs[i], s->nGlyphs[i], s->visattrs[i],
|
item->glyphs, item->nGlyphs, item->visattrs,
|
||||||
&(s->items[i].a),
|
&(item->item.a),
|
||||||
s->advances[i], s->goffsets[i], &(s->abcs[i]));
|
item->advances, item->goffsets, &(item->abc));
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT("error placing glyphs in initUniscribe()", hr);
|
logHRESULT("error placing glyphs in placeItem()", hr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitUniscribe(struct uniscribe *s)
|
static void uninitUniscribe(struct uniscribe *s)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// TODO use uiFree
|
// TODO use uiFree
|
||||||
|
|
||||||
free(s->abcs);
|
|
||||||
|
|
||||||
for (i = 0; i < s->goffsets; i++)
|
|
||||||
free(s->goffsets[i]);
|
|
||||||
free(s->goffsets);
|
|
||||||
|
|
||||||
for (i = 0; i < s->nItems; i++)
|
for (i = 0; i < s->nItems; i++)
|
||||||
free(s->advances[i]);
|
resetItem(&(s->items[i]));
|
||||||
free(s->advances);
|
free(s->items);
|
||||||
|
|
||||||
free(s->nGlyphs);
|
|
||||||
|
|
||||||
for (i = 0; i < s->nItems; i++)
|
|
||||||
free(s->visattrs[i]);
|
|
||||||
free(s->visattrs);
|
|
||||||
|
|
||||||
for (i = 0; i < s->nItems; i++)
|
|
||||||
free(s->clusters[i]);
|
|
||||||
free(s->clusters);
|
|
||||||
|
|
||||||
for (i = 0; i < s->nItems; i++)
|
|
||||||
free(s->glyphs[i]);
|
|
||||||
free(s->glyphs);
|
|
||||||
|
|
||||||
hr = ScriptCacheFree(&(s->cache));
|
hr = ScriptCacheFree(&(s->cache));
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT("error freeing Uniscribe cache in uninitUniscribe()");
|
logHRESULT("error freeing Uniscribe cache in uninitUniscribe()");
|
||||||
|
|
||||||
free(s->items);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue