Started writing the Uniscribe gunk. This is a mess...
This commit is contained in:
parent
0db611abd8
commit
9dbc8a1ba2
|
@ -0,0 +1,188 @@
|
|||
// 14 september 2015
|
||||
#include "area.h"
|
||||
|
||||
struct uiDrawFont {
|
||||
HFONT font;
|
||||
};
|
||||
|
||||
uiDrawFont *uiDrawPrepareFont(uiDrawFontSpec *spec)
|
||||
{
|
||||
uiDrawFont *df;
|
||||
LOGFONTW lf;
|
||||
|
||||
// TODO use uiNew
|
||||
df = malloc(sizeof (uiDrawFont));
|
||||
ZeroMemory(&lf, sizeof (LOGFONTW));
|
||||
// TODO
|
||||
df->font = xxxxxxxx(&lf);
|
||||
if (df->font == NULL)
|
||||
logLastError("error creating font in uiDrawPrepareFont()");
|
||||
return df;
|
||||
}
|
||||
|
||||
void uiDrawFreeFont(uiDrawFont *df)
|
||||
{
|
||||
if (DeleteObject(df->font) == 0)
|
||||
logLastError("error deleting font in uiDrawFreeFont()");
|
||||
// TODO use uiFree
|
||||
free(df);
|
||||
}
|
||||
|
||||
/* uniscribe notes:
|
||||
- https://msdn.microsoft.com/en-us/library/windows/desktop/dd317792%28v=vs.85%29.aspx
|
||||
- https://maxradi.us/documents/uniscribe/
|
||||
- http://www.catch22.net/tuts/introduction-uniscribe
|
||||
- http://www.catch22.net/tuts/uniscribe-mysteries
|
||||
- http://www.catch22.net/tuts/more-uniscribe-mysteries
|
||||
- http://www.catch22.net/tuts/drawing-styled-text-uniscribe
|
||||
- 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). */
|
||||
|
||||
struct uniscribe {
|
||||
WCHAR *text;
|
||||
size_t len;
|
||||
HDC dc;
|
||||
|
||||
SCRIPT_CONTROL control;
|
||||
SCRIPT_STATE state;
|
||||
|
||||
SCRIPT_ITEM *items;
|
||||
int nItems;
|
||||
|
||||
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
|
||||
void initUniscribe(struct uniscribe *s, WCHAR *text, HDC dc)
|
||||
{
|
||||
HRESULT hr;
|
||||
int nAlloc;
|
||||
int i;
|
||||
|
||||
ZeroMemory(s, sizeof (struct uniscribe));
|
||||
|
||||
s->text = text;
|
||||
s->len = wcslen(s->text);
|
||||
s->dc = dc;
|
||||
|
||||
// steps 1 through 3 are irrelevent here
|
||||
|
||||
// step 4
|
||||
nAlloc = 32;
|
||||
for (;;) {
|
||||
// TODO use uiRealloc
|
||||
s->items = realloc(s->items, nAlloc * sizeof (SCRIPT_ITEM));
|
||||
hr = ScriptItemize(s->text, s->len,
|
||||
nAlloc,
|
||||
&(s->control), &(s->state),
|
||||
s->items, &(s->nItems));
|
||||
if (hr == S_OK)
|
||||
break;
|
||||
if (hr == E_OUTOFMEMORY) {
|
||||
nAlloc *= 2;
|
||||
continue;
|
||||
}
|
||||
logHRESULT("error itemizing string in initUniscribe()", hr);
|
||||
}
|
||||
|
||||
// step 5
|
||||
// we're not using multiple fonts; we have no lists to merge
|
||||
|
||||
// step 6
|
||||
s->glyphs = malloc(s->nItems * sizeof (WORD *));
|
||||
s->clusters = malloc(s->nItems * sizeof (WORD *));
|
||||
s->visattrs = malloc(s->nItems * sizeof (SCRIPT_VISATTR *));
|
||||
s->nGlyphs = malloc(s->nItems * sizeof (int));
|
||||
for (i = 0; i < s->nItems; i++) {
|
||||
WCHAR *pwcChars;
|
||||
int nChars;
|
||||
|
||||
pwcChars = s->text + s->items[i].iCharPos;
|
||||
nChars = s->items[i + 1].iCharPos - s->items[i].iCharPos;
|
||||
nAlloc = 1.5 * nChars + 16;
|
||||
s->glyphs[i] = NULL;//TODO remove when switched to uiAlloc
|
||||
s->visattrs[i] = NULL;
|
||||
s->clusters[i] = malloc(nChars * sizeof (WORD));
|
||||
for (;;) {
|
||||
s->glyphs[i] = realloc(s->glyphs[i], nAlloc * sizeof (WORD));
|
||||
s->visattrs[i] = realloc(s->visattrs[i], nAlloc * sizeof (SCRIPT_VISATTR));
|
||||
hr = ScriptShape(s->dc, &(s->cache),
|
||||
pwcChars, nChars,
|
||||
nAlloc,
|
||||
&(s->items[i].a),
|
||||
s->glyphs[i], s->clusters[i],
|
||||
s->visattrs[i], &(s->nGlyphs[i]));
|
||||
if (hr == S_OK)
|
||||
break;
|
||||
if (hr == E_OUTOFMEMORY) {
|
||||
nAlloc *= 2;
|
||||
continue;
|
||||
}
|
||||
logHRESULT("error shaping glyphs in initUniscribe()", hr);
|
||||
}
|
||||
}
|
||||
|
||||
// step 7
|
||||
// TODO
|
||||
|
||||
// step 8
|
||||
s->advances = malloc(s->nItems * sizeof (int *));
|
||||
s->goffsets = malloc(s->nItems * sizeof (GOFFSET *));
|
||||
s->abcs = malloc(s->nItems * sizeof (ABC));
|
||||
for (i = 0; i < s->nItems; i++) {
|
||||
s->advances[i] = malloc(s->nGlyphs[i] * sizeof (int));
|
||||
s->goffsets[i] = malloc(s->nGlyphs[i] * sizeof (GOFFSET));
|
||||
hr = ScriptPlace(s->dc, &(s->cache),
|
||||
s->glyphs[i], s->nGlyphs[i], s->visattrs[i],
|
||||
&(s->items[i].a),
|
||||
s->advances[i], s->goffsets[i], &(s->abcs[i]));
|
||||
if (hr != S_OK)
|
||||
logHRESULT("error placing glyphs in initUniscribe()", hr);
|
||||
}
|
||||
}
|
||||
|
||||
void uninitUniscribe(struct uniscribe *s)
|
||||
{
|
||||
HRESULT hr;
|
||||
int i;
|
||||
|
||||
// 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++)
|
||||
free(s->advances[i]);
|
||||
free(s->advances);
|
||||
|
||||
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));
|
||||
if (hr != S_OK)
|
||||
logHRESULT("error freeing Uniscribe cache in uninitUniscribe()");
|
||||
|
||||
free(s->items);
|
||||
}
|
|
@ -28,3 +28,4 @@
|
|||
#include <stdio.h>
|
||||
#include <shobjidl.h>
|
||||
#include <math.h>
|
||||
#include <usp10.h>
|
||||
|
|
Loading…
Reference in New Issue