This commit is contained in:
parent
9f89ce2e00
commit
3a849267fc
1 changed files with 94 additions and 2 deletions
|
|
@ -195,6 +195,77 @@ fail:
|
|||
return ttf;
|
||||
}
|
||||
|
||||
static UINT32 *str_to_codepoints(const char *str, UINT codePage, UINT32 *pCount)
|
||||
{
|
||||
int wideLen;
|
||||
WCHAR *wideBuf;
|
||||
UINT32 *codePoints;
|
||||
UINT32 count;
|
||||
int i;
|
||||
|
||||
if (pCount != NULL) {
|
||||
*pCount = 0;
|
||||
}
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Size query; result includes the terminating null. */
|
||||
wideLen = MultiByteToWideChar(codePage, 0, str, -1, NULL, 0);
|
||||
if (wideLen <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wideBuf = (WCHAR *)malloc((size_t)wideLen * sizeof(WCHAR));
|
||||
if (wideBuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (MultiByteToWideChar(codePage, 0, str, -1, wideBuf, wideLen) == 0) {
|
||||
free(wideBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* One code point per UTF-16 unit is the worst case (no surrogate
|
||||
pairs), so wideLen is always a safe upper bound for the output. */
|
||||
codePoints = (UINT32 *)malloc((size_t)wideLen * sizeof(UINT32));
|
||||
if (codePoints == NULL) {
|
||||
free(wideBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
i = 0;
|
||||
while (wideBuf[i] != 0) {
|
||||
WCHAR unit = wideBuf[i];
|
||||
|
||||
if (unit >= 0xD800 && unit <= 0xDBFF &&
|
||||
wideBuf[i + 1] >= 0xDC00 && wideBuf[i + 1] <= 0xDFFF) {
|
||||
/* High + low surrogate -> one supplementary-plane code point. */
|
||||
UINT32 hi = (UINT32)(unit - 0xD800);
|
||||
UINT32 lo = (UINT32)(wideBuf[i + 1] - 0xDC00);
|
||||
|
||||
codePoints[count] = 0x10000u + (hi << 10) + lo;
|
||||
count++;
|
||||
i += 2;
|
||||
} else {
|
||||
/* Ordinary BMP character (or a lone/invalid surrogate, passed
|
||||
through as-is -- GetGlyphIndices will just report .notdef
|
||||
for it). */
|
||||
codePoints[count] = (UINT32)unit;
|
||||
count++;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
free(wideBuf);
|
||||
|
||||
if (pCount != NULL) {
|
||||
*pCount = count;
|
||||
}
|
||||
return codePoints;
|
||||
}
|
||||
|
||||
static int dw_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) {
|
||||
IDWriteBitmapRenderTarget *target;
|
||||
RECT rc;
|
||||
|
|
@ -202,18 +273,39 @@ static int dw_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const ch
|
|||
DWRITE_GLYPH_RUN glyphRun;
|
||||
DWRITE_FONT_METRICS metrics;
|
||||
LONG width, height;
|
||||
IDWriteRenderingParams * rendering_params;
|
||||
UINT32 codepoint_len;
|
||||
UINT32* codepoints;
|
||||
UINT16 *index;
|
||||
|
||||
codepoints = str_to_codepoints(text, CP_UTF8, &codepoint_len);
|
||||
index = malloc(sizeof(UINT16) * codepoint_len);
|
||||
|
||||
IDWriteFontFace_GetMetrics(ttf->font_face, &metrics);
|
||||
|
||||
GetClientRect(handle->lowlevel->gdi.hWnd, &rc);
|
||||
MapWindowPoints(handle->lowlevel->gdi.hWnd, GetParent(handle->lowlevel->gdi.hWnd), (LPPOINT)&rc, 2);
|
||||
|
||||
IDWriteFactory_CreateRenderingParams(ttf->write_factory, &rendering_params);
|
||||
|
||||
IDWriteFontFace_GetGlyphIndices(ttf->font_face, codepoints, codepoint_len, index);
|
||||
|
||||
glyphRun.fontFace = ttf->font_face;
|
||||
glyphRun.fontEmSize = (ttf->px*96.f)/72.f;
|
||||
glyphRun.glyphCount = codepoint_len;
|
||||
glyphRun.glyphIndices = index;
|
||||
|
||||
width = rc.right - rc.left;
|
||||
height = MwTextHeight(handle, ttf, text);
|
||||
height = rc.bottom - rc.top;
|
||||
|
||||
IDWriteGdiInterop_CreateBitmapRenderTarget(ttf->gdiInterop, handle->lowlevel->gdi.hDC, width, height, &target);
|
||||
|
||||
IDWriteBitmapRenderTarget_DrawGlyphRun(target, point->x, point->y, DWRITE_MEASURING_MODE_GDI_NATURAL, &glyphRun, rendering_params, RGB(color->common.red, color->common.green, color->common.blue), NULL);
|
||||
|
||||
|
||||
memoryHDC = IDWriteBitmapRenderTarget_GetMemoryDC(target);
|
||||
|
||||
BitBlt(handle->lowlevel->gdi.hDC, point->x , point->y, width, height, memoryHDC, 0, 0, SRCCOPY | NOMIRRORBITMAP);
|
||||
BitBlt(handle->lowlevel->gdi.hDC, 0,0, width, height, memoryHDC, 0, 0, SRCCOPY | NOMIRRORBITMAP);
|
||||
|
||||
IDWriteBitmapRenderTarget_Release(target);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue