From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/printproc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 84d7539b963..d4c6d95b003 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -1008,12 +1008,12 @@ static BOOL is_path_record(int type) }
static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, - const ENHMETARECORD *rec, int n, LPARAM arg) + const ENHMETARECORD *rec, int handle_count, LPARAM arg) { struct pp_data *data = (struct pp_data *)arg;
if (data->path && is_path_record(rec->iType)) - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count);
switch (rec->iType) { @@ -1113,9 +1113,9 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_RESTOREDC: { HDC hdc = data->pdev->dev.hdc; - int ret = PlayEnhMetaFileRecord(hdc, htable, rec, n); + int ret = PlayEnhMetaFileRecord(hdc, htable, rec, handle_count);
- select_hbrush(data, htable, n, GetCurrentObject(hdc, OBJ_BRUSH)); + select_hbrush(data, htable, handle_count, GetCurrentObject(hdc, OBJ_BRUSH)); /* TODO: reselect font */ PSDRV_SelectPen(&data->pdev->dev, GetCurrentObject(hdc, OBJ_PEN), NULL); PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc)); @@ -1145,7 +1145,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, const EMRDELETEOBJECT *p = (const EMRDELETEOBJECT *)rec;
memset(&data->patterns[p->ihObject], 0, sizeof(*data->patterns)); - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); } case EMR_ANGLEARC: { @@ -1169,7 +1169,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, arcto.ptlEnd.y = GDI_ROUND(p->ptlCenter.y - sin((p->eStartAngle + p->eSweepAngle) * M_PI / 180) * p->nRadius);
- ret = hmf_proc(hdc, htable, (ENHMETARECORD *)&arcto, n, arg); + ret = hmf_proc(hdc, htable, (ENHMETARECORD *)&arcto, handle_count, arg); SetArcDirection(data->pdev->dev.hdc, arc_dir); return ret; } @@ -1266,12 +1266,12 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_BEGINPATH: { data->path = TRUE; - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); } case EMR_ENDPATH: { data->path = FALSE; - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); } case EMR_FILLPATH: return PSDRV_FillPath(&data->pdev->dev); @@ -1282,7 +1282,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_ABORTPATH: { data->path = FALSE; - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); } case EMR_FILLRGN: { @@ -1291,7 +1291,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, int ret;
rgn = ExtCreateRegion(NULL, p->cbRgnData, (const RGNDATA *)p->RgnData); - ret = fill_rgn(data, htable, n, p->ihBrush, rgn); + ret = fill_rgn(data, htable, handle_count, p->ihBrush, rgn); DeleteObject(rgn); return ret; } @@ -1315,7 +1315,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, OffsetRgn(rgn, 0, -p->szlStroke.cy); CombineRgn(frame, rgn, frame, RGN_DIFF);
- ret = fill_rgn(data, htable, n, p->ihBrush, frame); + ret = fill_rgn(data, htable, handle_count, p->ihBrush, frame); DeleteObject(rgn); DeleteObject(frame); return ret; @@ -1328,7 +1328,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
rgn = ExtCreateRegion(NULL, p->cbRgnData, (const RGNDATA *)p->RgnData); old_rop = SetROP2(data->pdev->dev.hdc, R2_NOT); - ret = fill_rgn(data, htable, n, 0x80000000 | BLACK_BRUSH, rgn); + ret = fill_rgn(data, htable, handle_count, 0x80000000 | BLACK_BRUSH, rgn); SetROP2(data->pdev->dev.hdc, old_rop); DeleteObject(rgn); return ret; @@ -1541,7 +1541,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, { const EMRCREATEMONOBRUSH *p = (const EMRCREATEMONOBRUSH *)rec;
- if (!PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n)) + if (!PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count)) return 0; data->patterns[p->ihBrush].usage = p->iUsage; data->patterns[p->ihBrush].info = (BITMAPINFO *)((BYTE *)p + p->offBmi); @@ -1552,7 +1552,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, { const EMRCREATEDIBPATTERNBRUSHPT *p = (const EMRCREATEDIBPATTERNBRUSHPT *)rec;
- if (!PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n)) + if (!PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count)) return 0; data->patterns[p->ihBrush].usage = p->iUsage; data->patterns[p->ihBrush].info = (BITMAPINFO *)((BYTE *)p + p->offBmi); @@ -1615,7 +1615,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_EXTSELECTCLIPRGN: case EMR_SETLAYOUT: case EMR_SETTEXTJUSTIFICATION: - return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, n); + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); default: FIXME("unsupported record: %ld\n", rec->iType); }
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/printproc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index d4c6d95b003..8c32808dcdd 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -1748,6 +1748,9 @@ HANDLE WINAPI OpenPrintProcessor(WCHAR *port, PRINTPROCESSOROPENDATA *open_data) return NULL; } data->pdev->dev.hdc = hdc; + + PSDRV_SetTextColor(&data->pdev->dev, GetTextColor(hdc)); + PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc)); return (HANDLE)data; }
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/printproc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 8c32808dcdd..71dd28239e1 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -1613,6 +1613,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_WIDENPATH: case EMR_SELECTCLIPPATH: case EMR_EXTSELECTCLIPRGN: + case EMR_EXTCREATEFONTINDIRECTW: case EMR_SETLAYOUT: case EMR_SETTEXTJUSTIFICATION: return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/Makefile.in | 2 +- dlls/wineps.drv/printproc.c | 67 ++++++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in index 52eb27923d9..aa8d15759b4 100644 --- a/dlls/wineps.drv/Makefile.in +++ b/dlls/wineps.drv/Makefile.in @@ -1,5 +1,5 @@ MODULE = wineps.drv -IMPORTS = user32 gdi32 winspool advapi32 +IMPORTS = user32 gdi32 winspool advapi32 win32u
C_SRCS = \ afm.c \ diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 71dd28239e1..449748c8b22 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -22,6 +22,7 @@ #include <stdlib.h>
#include <windows.h> +#include <ntgdi.h> #include <winspool.h> #include <ddk/winsplp.h>
@@ -40,7 +41,10 @@ struct pp_data HANDLE hport; WCHAR *doc_name; WCHAR *out_file; + PSDRV_PDEVICE *pdev; + struct gdi_physdev font_dev; + struct brush_pattern *patterns; BOOL path; }; @@ -133,6 +137,50 @@ static struct pp_data* get_handle_data(HANDLE pp) return ret; }
+static BOOL CDECL font_EnumFonts(PHYSDEV dev, LOGFONTW *lf, FONTENUMPROCW proc, LPARAM lp) +{ + return EnumFontFamiliesExW(dev->hdc, lf, proc, lp, 0); +} + +static BOOL CDECL font_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) +{ + XFORM old, xform = { .eM11 = 1.0f }; + BOOL ret; + + GetWorldTransform(dev->hdc, &old); + SetWorldTransform(dev->hdc, &xform); + ret = NtGdiGetCharWidthW(dev->hdc, first, count, (WCHAR *)chars, NTGDI_GETCHARWIDTH_INT, buffer); + SetWorldTransform(dev->hdc, &old); + return ret; +} + +static BOOL CDECL font_GetTextExtentExPoint(PHYSDEV dev, const WCHAR *str, INT count, INT *dxs) +{ + SIZE size; + return GetTextExtentExPointW(dev->hdc, str, count, -1, NULL, dxs, &size); +} + +static BOOL CDECL font_GetTextMetrics(PHYSDEV dev, TEXTMETRICW *metrics) +{ + return GetTextMetricsW(dev->hdc, metrics); +} + +static HFONT CDECL font_SelectFont(PHYSDEV dev, HFONT hfont, UINT *aa_flags) +{ + *aa_flags = GGO_BITMAP; + return SelectObject(dev->hdc, hfont) ? hfont : 0; +} + +static const struct gdi_dc_funcs font_funcs = +{ + .pEnumFonts = font_EnumFonts, + .pGetCharWidth = font_GetCharWidth, + .pGetTextExtentExPoint = font_GetTextExtentExPoint, + .pGetTextMetrics = font_GetTextMetrics, + .pSelectFont = font_SelectFont, + .priority = GDI_PRIORITY_FONT_DRV +}; + static inline INT GDI_ROUND(double val) { return (int)floor(val + 0.5); @@ -1114,18 +1162,23 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, { HDC hdc = data->pdev->dev.hdc; int ret = PlayEnhMetaFileRecord(hdc, htable, rec, handle_count); + UINT aa_flags;
- select_hbrush(data, htable, handle_count, GetCurrentObject(hdc, OBJ_BRUSH)); - /* TODO: reselect font */ - PSDRV_SelectPen(&data->pdev->dev, GetCurrentObject(hdc, OBJ_PEN), NULL); - PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc)); - PSDRV_SetTextColor(&data->pdev->dev, GetTextColor(hdc)); + if (ret) + { + select_hbrush(data, htable, handle_count, GetCurrentObject(hdc, OBJ_BRUSH)); + PSDRV_SelectFont(&data->pdev->dev, GetCurrentObject(hdc, OBJ_FONT), &aa_flags); + PSDRV_SelectPen(&data->pdev->dev, GetCurrentObject(hdc, OBJ_PEN), NULL); + PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc)); + PSDRV_SetTextColor(&data->pdev->dev, GetTextColor(hdc)); + } return ret; } case EMR_SELECTOBJECT: { const EMRSELECTOBJECT *so = (const EMRSELECTOBJECT *)rec; struct brush_pattern *pattern; + UINT aa_flags; HGDIOBJ obj;
obj = get_object_handle(data, htable, so->ihObject, &pattern); @@ -1135,6 +1188,7 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, { case OBJ_PEN: return PSDRV_SelectPen(&data->pdev->dev, obj, NULL) != NULL; case OBJ_BRUSH: return PSDRV_SelectBrush(&data->pdev->dev, obj, pattern) != NULL; + case OBJ_FONT: return PSDRV_SelectFont(&data->pdev->dev, obj, &aa_flags) != NULL; default: FIXME("unhandled object type %ld\n", GetObjectType(obj)); return 1; @@ -1749,6 +1803,9 @@ HANDLE WINAPI OpenPrintProcessor(WCHAR *port, PRINTPROCESSOROPENDATA *open_data) return NULL; } data->pdev->dev.hdc = hdc; + data->pdev->dev.next = &data->font_dev; + data->font_dev.funcs = &font_funcs; + data->font_dev.hdc = hdc;
PSDRV_SetTextColor(&data->pdev->dev, GetTextColor(hdc)); PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc));
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/printproc.c | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 449748c8b22..0452e19845a 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -47,6 +47,16 @@ struct pp_data
struct brush_pattern *patterns; BOOL path; + INT break_extra; + INT break_rem; + + INT saved_dc_size; + INT saved_dc_top; + struct + { + INT break_extra; + INT break_rem; + } *saved_dc; };
typedef enum @@ -88,6 +98,13 @@ typedef struct unsigned int cjSize; } record_hdr;
+typedef struct +{ + EMR emr; + INT break_extra; + INT break_count; +} EMRSETTEXTJUSTIFICATION; + BOOL WINAPI SeekPrinter(HANDLE, LARGE_INTEGER, LARGE_INTEGER*, DWORD, BOOL);
static const WCHAR emf_1003[] = L"NT EMF 1.003"; @@ -1158,8 +1175,37 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, PSDRV_SetBkColor(&data->pdev->dev, p->crColor); return 1; } + case EMR_SAVEDC: + { + int ret = PlayEnhMetaFileRecord(hdc, htable, rec, handle_count); + + if (!data->saved_dc_size) + { + data->saved_dc = malloc(8 * sizeof(*data->saved_dc)); + if (data->saved_dc) + data->saved_dc_size = 8; + } + else if (data->saved_dc_size == data->saved_dc_top) + { + void *alloc = realloc(data->saved_dc, data->saved_dc_size * 2); + + if (alloc) + { + data->saved_dc = alloc; + data->saved_dc_size *= 2; + } + } + if (data->saved_dc_size == data->saved_dc_top) + return 0; + + data->saved_dc[data->saved_dc_top].break_extra = data->break_extra; + data->saved_dc[data->saved_dc_top].break_rem = data->break_rem; + data->saved_dc_top++; + return ret; + } case EMR_RESTOREDC: { + const EMRRESTOREDC *p = (const EMRRESTOREDC *)rec; HDC hdc = data->pdev->dev.hdc; int ret = PlayEnhMetaFileRecord(hdc, htable, rec, handle_count); UINT aa_flags; @@ -1171,6 +1217,12 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, PSDRV_SelectPen(&data->pdev->dev, GetCurrentObject(hdc, OBJ_PEN), NULL); PSDRV_SetBkColor(&data->pdev->dev, GetBkColor(hdc)); PSDRV_SetTextColor(&data->pdev->dev, GetTextColor(hdc)); + + if (p->iRelative >= 0 || data->saved_dc_top + p->iRelative < 0) + return 0; + data->saved_dc_top += p->iRelative; + data->break_extra = data->saved_dc[data->saved_dc_top].break_extra; + data->break_rem = data->saved_dc[data->saved_dc_top].break_rem; } return ret; } @@ -1633,6 +1685,14 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, return gradient_fill(&data->pdev->dev, p->Ver, p->nVer, p->Ver + p->nVer, p->nTri, p->ulMode); } + case EMR_SETTEXTJUSTIFICATION: + { + const EMRSETTEXTJUSTIFICATION *p = (const EMRSETTEXTJUSTIFICATION *)rec; + + data->break_extra = p->break_extra / p->break_count; + data->break_rem = p->break_extra - data->break_extra * p->break_count; + return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); + }
case EMR_EXTFLOODFILL: case EMR_ALPHABLEND: @@ -1656,7 +1716,6 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_INTERSECTCLIPRECT: case EMR_SCALEVIEWPORTEXTEX: case EMR_SCALEWINDOWEXTEX: - case EMR_SAVEDC: case EMR_SETWORLDTRANSFORM: case EMR_MODIFYWORLDTRANSFORM: case EMR_CREATEPEN: @@ -1669,7 +1728,6 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable, case EMR_EXTSELECTCLIPRGN: case EMR_EXTCREATEFONTINDIRECTW: case EMR_SETLAYOUT: - case EMR_SETTEXTJUSTIFICATION: return PlayEnhMetaFileRecord(data->pdev->dev.hdc, htable, rec, handle_count); default: FIXME("unsupported record: %ld\n", rec->iType); @@ -1719,6 +1777,10 @@ static BOOL print_metafile(struct pp_data *data, HANDLE hdata) DeleteEnhMetaFile(hmf); free(data->patterns); data->patterns = NULL; + data->path = FALSE; + data->break_extra = 0; + data->break_rem = 0; + data->saved_dc_top = 0; return ret; }
@@ -1959,6 +2021,7 @@ BOOL WINAPI ClosePrintProcessor(HANDLE pp) DeleteDC(data->pdev->dev.hdc); HeapFree(GetProcessHeap(), 0, data->pdev->Devmode); HeapFree(GetProcessHeap(), 0, data->pdev); + free(data->saved_dc);
memset(data, 0, sizeof(*data)); LocalFree(data);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/printproc.c | 515 ++++++++++++++++++++++++++++++++++++ 1 file changed, 515 insertions(+)
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 0452e19845a..858a118b41b 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -1020,6 +1020,493 @@ static BOOL select_hbrush(struct pp_data *data, HANDLETABLE *htable, int handle_ return PSDRV_SelectBrush(&data->pdev->dev, brush, pattern) != NULL; }
+/* Performs a device to world transformation on the specified width (which + * is in integer format). + */ +static inline INT INTERNAL_XDSTOWS(HDC hdc, INT width) +{ + double floatWidth; + XFORM xform; + + GetWorldTransform(hdc, &xform); + + /* Perform operation with floating point */ + floatWidth = (double)width * xform.eM11; + /* Round to integers */ + return GDI_ROUND(floatWidth); +} + +/* Performs a device to world transformation on the specified size (which + * is in integer format). + */ +static inline INT INTERNAL_YDSTOWS(HDC hdc, INT height) +{ + double floatHeight; + XFORM xform; + + GetWorldTransform(hdc, &xform); + + /* Perform operation with floating point */ + floatHeight = (double)height * xform.eM22; + /* Round to integers */ + return GDI_ROUND(floatHeight); +} + +static inline INT INTERNAL_YWSTODS(HDC hdc, INT height) +{ + POINT pt[2]; + pt[0].x = pt[0].y = 0; + pt[1].x = 0; + pt[1].y = height; + LPtoDP(hdc, pt, 2); + return pt[1].y - pt[0].y; +} + +/* compute positions for text rendering, in device coords */ +static BOOL get_char_positions(struct pp_data *data, const WCHAR *str, + INT count, INT *dx, SIZE *size) +{ + TEXTMETRICW tm; + + size->cx = size->cy = 0; + if (!count) return TRUE; + + PSDRV_GetTextMetrics(&data->pdev->dev, &tm); + if (!PSDRV_GetTextExtentExPoint(&data->pdev->dev, str, count, dx)) return FALSE; + + if (data->break_extra || data->break_rem) + { + int i, space = 0, rem = data->break_rem; + + for (i = 0; i < count; i++) + { + if (str[i] == tm.tmBreakChar) + { + space += data->break_extra; + if (rem > 0) + { + space++; + rem--; + } + } + dx[i] += space; + } + } + size->cx = dx[count - 1]; + size->cy = tm.tmHeight; + return TRUE; +} + +static BOOL get_text_extent(struct pp_data *data, const WCHAR *str, INT count, + INT max_ext, INT *nfit, INT *dxs, SIZE *size, UINT flags) +{ + INT buffer[256], *pos = dxs; + int i, char_extra; + BOOL ret; + + if (flags) + return GetTextExtentExPointI(data->pdev->dev.hdc, str, count, max_ext, nfit, dxs, size); + else if (data->pdev->font.fontloc == Download) + return GetTextExtentExPointW(data->pdev->dev.hdc, str, count, max_ext, nfit, dxs, size); + + if (!dxs) + { + pos = buffer; + if (count > 256 && !(pos = malloc(count * sizeof(*pos)))) + return FALSE; + } + + if ((ret = get_char_positions(data, str, count, pos, size))) + { + char_extra = GetTextCharacterExtra(data->pdev->dev.hdc); + if (dxs || nfit) + { + for (i = 0; i < count; i++) + { + unsigned int dx = abs(INTERNAL_XDSTOWS(data->pdev->dev.hdc, pos[i])) + + (i + 1) * char_extra; + if (nfit && dx > (unsigned int)max_ext) break; + if (dxs) dxs[i] = dx; + } + if (nfit) *nfit = i; + } + + size->cx = abs(INTERNAL_XDSTOWS(data->pdev->dev.hdc, size->cx)) + + count * char_extra; + size->cy = abs(INTERNAL_YDSTOWS(data->pdev->dev.hdc, size->cy)); + } + + if (pos != buffer && pos != dxs) free(pos); + + TRACE("(%s, %d) returning %dx%d\n", debugstr_wn(str,count), + max_ext, (int)size->cx, (int)size->cy); + return ret; +} + +static inline BOOL intersect_rect(RECT *dst, const RECT *src1, const RECT *src2) +{ + dst->left = max(src1->left, src2->left); + dst->top = max(src1->top, src2->top); + dst->right = min(src1->right, src2->right); + dst->bottom = min(src1->bottom, src2->bottom); + return !IsRectEmpty(dst); +} + +/*********************************************************************** + * get_line_width + * + * Scale the underline / strikeout line width. + */ +static inline int get_line_width(HDC hdc, int metric_size) +{ + int width = abs(INTERNAL_YWSTODS(hdc, metric_size)); + if (width == 0) width = 1; + if (metric_size < 0) width = -width; + return width; +} + +static BOOL ext_text_out(struct pp_data *data, HANDLETABLE *htable, + int handle_count, INT x, INT y, UINT flags, const RECT *rect, + const WCHAR *str, UINT count, const INT *dx) +{ + HDC hdc = data->pdev->dev.hdc; + BOOL ret = FALSE; + UINT align; + DWORD layout; + POINT pt; + TEXTMETRICW tm; + LOGFONTW lf; + double cosEsc, sinEsc; + INT char_extra; + SIZE sz; + RECT rc; + POINT *deltas = NULL, width = {0, 0}; + INT breakRem; + XFORM xform; + + /* TODO: Add BiDi support */ + + align = GetTextAlign(hdc); + breakRem = data->break_rem; + layout = GetLayout(hdc); + + if (flags & ETO_RTLREADING) align |= TA_RTLREADING; + if (layout & LAYOUT_RTL) + { + if ((align & TA_CENTER) != TA_CENTER) align ^= TA_RIGHT; + align ^= TA_RTLREADING; + } + + TRACE("%d, %d, %08x, %s, %s, %d, %p)\n", x, y, flags, + wine_dbgstr_rect(rect), debugstr_wn(str, count), count, dx); + TRACE("align = %x bkmode = %x mapmode = %x\n", align, GetBkMode(hdc), + GetMapMode(hdc)); + + if(align & TA_UPDATECP) + { + GetCurrentPositionEx(hdc, &pt); + x = pt.x; + y = pt.y; + } + + PSDRV_GetTextMetrics(&data->pdev->dev, &tm); + GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf); + + if(!(tm.tmPitchAndFamily & TMPF_VECTOR)) /* Non-scalable fonts shouldn't be rotated */ + lf.lfEscapement = 0; + + GetWorldTransform(hdc, &xform); + if (GetGraphicsMode(hdc) == GM_COMPATIBLE && + xform.eM11 * xform.eM22 < 0) + { + lf.lfEscapement = -lf.lfEscapement; + } + + if(lf.lfEscapement != 0) + { + cosEsc = cos(lf.lfEscapement * M_PI / 1800); + sinEsc = sin(lf.lfEscapement * M_PI / 1800); + } + else + { + cosEsc = 1; + sinEsc = 0; + } + + if (rect && (flags & (ETO_OPAQUE | ETO_CLIPPED))) + { + rc = *rect; + LPtoDP(hdc, (POINT*)&rc, 2); + order_rect(&rc); + if (flags & ETO_OPAQUE) + PSDRV_ExtTextOut(&data->pdev->dev, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL); + } + else flags &= ~ETO_CLIPPED; + + if(count == 0) + { + ret = TRUE; + goto done; + } + + pt.x = x; + pt.y = y; + LPtoDP(hdc, &pt, 1); + x = pt.x; + y = pt.y; + + char_extra = GetTextCharacterExtra(hdc); + if (char_extra && dx) + char_extra = 0; /* Printer drivers don't add char_extra if dx is supplied */ + + if(char_extra || data->break_extra || breakRem || dx || lf.lfEscapement != 0) + { + UINT i; + POINT total = {0, 0}, desired[2]; + + deltas = malloc(count * sizeof(*deltas)); + if (dx) + { + if (flags & ETO_PDY) + { + for (i = 0; i < count; i++) + { + deltas[i].x = dx[i * 2] + char_extra; + deltas[i].y = -dx[i * 2 + 1]; + } + } + else + { + for (i = 0; i < count; i++) + { + deltas[i].x = dx[i] + char_extra; + deltas[i].y = 0; + } + } + } + else + { + INT *dx = malloc(count * sizeof(*dx)); + + get_text_extent(data, str, count, -1, NULL, dx, &sz, !!(flags & ETO_GLYPH_INDEX)); + + deltas[0].x = dx[0]; + deltas[0].y = 0; + for (i = 1; i < count; i++) + { + deltas[i].x = dx[i] - dx[i - 1]; + deltas[i].y = 0; + } + free(dx); + } + + for(i = 0; i < count; i++) + { + total.x += deltas[i].x; + total.y += deltas[i].y; + + desired[0].x = desired[0].y = 0; + + desired[1].x = cosEsc * total.x + sinEsc * total.y; + desired[1].y = -sinEsc * total.x + cosEsc * total.y; + + LPtoDP(hdc, desired, 2); + desired[1].x -= desired[0].x; + desired[1].y -= desired[0].y; + + if (GetGraphicsMode(hdc) == GM_COMPATIBLE) + { + if (xform.eM11 < 0) + desired[1].x = -desired[1].x; + if (xform.eM22 < 0) + desired[1].y = -desired[1].y; + } + + deltas[i].x = desired[1].x - width.x; + deltas[i].y = desired[1].y - width.y; + + width = desired[1]; + } + flags |= ETO_PDY; + } + else + { + POINT desired[2]; + + get_text_extent(data, str, count, 0, NULL, NULL, &sz, !!(flags & ETO_GLYPH_INDEX)); + desired[0].x = desired[0].y = 0; + desired[1].x = sz.cx; + desired[1].y = 0; + LPtoDP(hdc, desired, 2); + desired[1].x -= desired[0].x; + desired[1].y -= desired[0].y; + + if (GetGraphicsMode(hdc) == GM_COMPATIBLE) + { + if (xform.eM11 < 0) + desired[1].x = -desired[1].x; + if (xform.eM22 < 0) + desired[1].y = -desired[1].y; + } + width = desired[1]; + } + + tm.tmAscent = abs(INTERNAL_YWSTODS(hdc, tm.tmAscent)); + tm.tmDescent = abs(INTERNAL_YWSTODS(hdc, tm.tmDescent)); + switch(align & (TA_LEFT | TA_RIGHT | TA_CENTER)) + { + case TA_LEFT: + if (align & TA_UPDATECP) + { + pt.x = x + width.x; + pt.y = y + width.y; + DPtoLP(hdc, &pt, 1); + MoveToEx(hdc, pt.x, pt.y, NULL); + } + break; + + case TA_CENTER: + x -= width.x / 2; + y -= width.y / 2; + break; + + case TA_RIGHT: + x -= width.x; + y -= width.y; + if (align & TA_UPDATECP) + { + pt.x = x; + pt.y = y; + DPtoLP(hdc, &pt, 1); + MoveToEx(hdc, pt.x, pt.y, NULL); + } + break; + } + + switch(align & (TA_TOP | TA_BOTTOM | TA_BASELINE)) + { + case TA_TOP: + y += tm.tmAscent * cosEsc; + x += tm.tmAscent * sinEsc; + break; + + case TA_BOTTOM: + y -= tm.tmDescent * cosEsc; + x -= tm.tmDescent * sinEsc; + break; + + case TA_BASELINE: + break; + } + + if (GetBkMode(hdc) != TRANSPARENT) + { + if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) + { + if(!(flags & ETO_OPAQUE) || !rect || + x < rc.left || x + width.x >= rc.right || + y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom) + { + RECT text_box; + text_box.left = x; + text_box.right = x + width.x; + text_box.top = y - tm.tmAscent; + text_box.bottom = y + tm.tmDescent; + + if (flags & ETO_CLIPPED) intersect_rect(&text_box, &text_box, &rc); + if (!IsRectEmpty(&text_box)) + PSDRV_ExtTextOut(&data->pdev->dev, 0, 0, ETO_OPAQUE, &text_box, NULL, 0, NULL); + } + } + } + + ret = PSDRV_ExtTextOut(&data->pdev->dev, x, y, (flags & ~ETO_OPAQUE), &rc, + str, count, (INT*)deltas); + +done: + free(deltas); + + if (ret && (lf.lfUnderline || lf.lfStrikeOut)) + { + int underlinePos, strikeoutPos; + int underlineWidth, strikeoutWidth; + UINT size = NtGdiGetOutlineTextMetricsInternalW(hdc, 0, NULL, 0); + OUTLINETEXTMETRICW* otm = NULL; + POINT pts[5]; + HBRUSH hbrush = CreateSolidBrush(GetTextColor(hdc)); + HPEN hpen = GetStockObject(NULL_PEN); + + PSDRV_SelectPen(&data->pdev->dev, hpen, NULL); + hpen = SelectObject(hdc, hpen); + + PSDRV_SelectBrush(&data->pdev->dev, hbrush, NULL); + hbrush = SelectObject(hdc, hbrush); + + if(!size) + { + underlinePos = 0; + underlineWidth = tm.tmAscent / 20 + 1; + strikeoutPos = tm.tmAscent / 2; + strikeoutWidth = underlineWidth; + } + else + { + otm = malloc(size); + NtGdiGetOutlineTextMetricsInternalW(hdc, size, otm, 0); + underlinePos = abs(INTERNAL_YWSTODS(hdc, otm->otmsUnderscorePosition)); + if (otm->otmsUnderscorePosition < 0) underlinePos = -underlinePos; + underlineWidth = get_line_width(hdc, otm->otmsUnderscoreSize); + strikeoutPos = abs(INTERNAL_YWSTODS(hdc, otm->otmsStrikeoutPosition)); + if (otm->otmsStrikeoutPosition < 0) strikeoutPos = -strikeoutPos; + strikeoutWidth = get_line_width(hdc, otm->otmsStrikeoutSize); + free(otm); + } + + + if (lf.lfUnderline) + { + const INT cnt = 5; + pts[0].x = x - (underlinePos + underlineWidth / 2) * sinEsc; + pts[0].y = y - (underlinePos + underlineWidth / 2) * cosEsc; + pts[1].x = x + width.x - (underlinePos + underlineWidth / 2) * sinEsc; + pts[1].y = y + width.y - (underlinePos + underlineWidth / 2) * cosEsc; + pts[2].x = pts[1].x + underlineWidth * sinEsc; + pts[2].y = pts[1].y + underlineWidth * cosEsc; + pts[3].x = pts[0].x + underlineWidth * sinEsc; + pts[3].y = pts[0].y + underlineWidth * cosEsc; + pts[4].x = pts[0].x; + pts[4].y = pts[0].y; + DPtoLP(hdc, pts, 5); + PSDRV_PolyPolygon(&data->pdev->dev, pts, &cnt, 1); + } + + if (lf.lfStrikeOut) + { + const INT cnt = 5; + pts[0].x = x - (strikeoutPos + strikeoutWidth / 2) * sinEsc; + pts[0].y = y - (strikeoutPos + strikeoutWidth / 2) * cosEsc; + pts[1].x = x + width.x - (strikeoutPos + strikeoutWidth / 2) * sinEsc; + pts[1].y = y + width.y - (strikeoutPos + strikeoutWidth / 2) * cosEsc; + pts[2].x = pts[1].x + strikeoutWidth * sinEsc; + pts[2].y = pts[1].y + strikeoutWidth * cosEsc; + pts[3].x = pts[0].x + strikeoutWidth * sinEsc; + pts[3].y = pts[0].y + strikeoutWidth * cosEsc; + pts[4].x = pts[0].x; + pts[4].y = pts[0].y; + DPtoLP(hdc, pts, 5); + PSDRV_PolyPolygon(&data->pdev->dev, pts, &cnt, 1); + } + + PSDRV_SelectPen(&data->pdev->dev, hpen, NULL); + SelectObject(hdc, hpen); + select_hbrush(data, htable, handle_count, hbrush); + SelectObject(hdc, hbrush); + DeleteObject(hbrush); + } + + return ret; +} + static BOOL fill_rgn(struct pp_data *data, HANDLETABLE *htable, int handle_count, DWORD brush, HRGN rgn) { struct brush_pattern *pattern; @@ -1501,6 +1988,34 @@ static int WINAPI hmf_proc(HDC hdc, HANDLETABLE *htable,
return plg_blt(&data->pdev->dev, p); } + case EMR_EXTTEXTOUTW: + { + const EMREXTTEXTOUTW *p = (const EMREXTTEXTOUTW *)rec; + HDC hdc = data->pdev->dev.hdc; + const INT *dx = NULL; + int old_mode, ret; + RECT rect; + + rect.left = p->emrtext.rcl.left; + rect.top = p->emrtext.rcl.top; + rect.right = p->emrtext.rcl.right; + rect.bottom = p->emrtext.rcl.bottom; + + old_mode = SetGraphicsMode(hdc, p->iGraphicsMode); + /* Reselect the font back into the dc so that the transformation + gets updated. */ + SelectObject(hdc, GetCurrentObject(hdc, OBJ_FONT)); + + if (p->emrtext.offDx) + dx = (const INT *)((const BYTE *)rec + p->emrtext.offDx); + + ret = ext_text_out(data, htable, handle_count, p->emrtext.ptlReference.x, + p->emrtext.ptlReference.y, p->emrtext.fOptions, &rect, + (LPCWSTR)((const BYTE *)rec + p->emrtext.offString), p->emrtext.nChars, dx); + + SetGraphicsMode(hdc, old_mode); + return ret; + } case EMR_POLYBEZIER16: { const EMRPOLYBEZIER16 *p = (const EMRPOLYBEZIER16 *)rec;
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/Makefile.in | 1 + dlls/wineps.drv/direction.c | 717 ++++++++++++++++++++++++++++++++++++ dlls/wineps.drv/printproc.c | 602 +++++++++++++++++++++++++++++- tools/make_unicode | 1 + 4 files changed, 1320 insertions(+), 1 deletion(-) create mode 100644 dlls/wineps.drv/direction.c
diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in index aa8d15759b4..9fe0497c2b2 100644 --- a/dlls/wineps.drv/Makefile.in +++ b/dlls/wineps.drv/Makefile.in @@ -45,6 +45,7 @@ C_SRCS = \ data/ZapfChancery_MediumItalic.c \ data/ZapfDingbats.c \ data/agl.c \ + direction.c \ download.c \ driver.c \ encode.c \ diff --git a/dlls/wineps.drv/direction.c b/dlls/wineps.drv/direction.c new file mode 100644 index 00000000000..721ffbe6281 --- /dev/null +++ b/dlls/wineps.drv/direction.c @@ -0,0 +1,717 @@ +/* Unicode BiDi direction table */ +/* Automatically generated; DO NOT EDIT!! */ + +#include "windef.h" + +const unsigned short DECLSPEC_HIDDEN bidi_direction_table[5631] = +{ + /* level 1 offsets */ + 0x0110, 0x0120, 0x0130, 0x0140, 0x0144, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x015e, 0x0152, 0x0152, 0x0152, 0x0152, 0x016a, + 0x017a, 0x018a, 0x0152, 0x019a, 0x0152, 0x0152, 0x01a0, 0x0152, + 0x0152, 0x0152, 0x0152, 0x01b0, 0x01bd, 0x01cd, 0x01dd, 0x01ed, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x01fd, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, + /* level 2 offsets */ + 0x020d, 0x021d, 0x0222, 0x0232, 0x0242, 0x024b, 0x025b, 0x026b, + 0x027b, 0x028b, 0x029b, 0x02ab, 0x02bb, 0x02cb, 0x02d9, 0x02e8, + 0x02f6, 0x021d, 0x021d, 0x0301, 0x0311, 0x021d, 0x0319, 0x0328, + 0x0338, 0x0346, 0x0356, 0x0366, 0x0376, 0x0386, 0x021d, 0x0396, + 0x03a6, 0x03b6, 0x03c5, 0x03d2, 0x03e0, 0x03ef, 0x03f5, 0x03ef, + 0x021d, 0x03ef, 0x03ef, 0x0400, 0x0410, 0x0420, 0x0430, 0x0440, + 0x0450, 0x0460, 0x046f, 0x047c, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x048c, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x049c, 0x021d, 0x04ac, 0x04bc, 0x04cc, 0x04dc, + 0x04eb, 0x04fb, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x050a, 0x0518, 0x0525, + 0x0535, 0x0545, 0x021d, 0x0555, 0x0565, 0x0575, 0x021d, 0x021d, + 0x021d, 0x021d, 0x0585, 0x0595, 0x05a5, 0x05b5, 0x05c5, 0x05d5, + 0x05df, 0x05ef, 0x05ff, 0x060f, 0x061d, 0x062d, 0x063a, 0x0647, + 0x0655, 0x0664, 0x0672, 0x067f, 0x068f, 0x021d, 0x069c, 0x06a9, + 0x06b3, 0x06c3, 0x021d, 0x021d, 0x021d, 0x021d, 0x06d3, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x06d9, 0x06e9, 0x021d, 0x021d, 0x021d, 0x06f5, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x0704, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x0714, 0x021d, 0x071e, 0x072e, + 0x073e, 0x021d, 0x021d, 0x0744, 0x0753, 0x021d, 0x021d, 0x0763, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x0773, 0x06e9, 0x077c, + 0x021d, 0x078c, 0x021d, 0x021d, 0x021d, 0x079c, 0x07ac, 0x021d, + 0x021d, 0x07b5, 0x07c5, 0x07d5, 0x021d, 0x07e5, 0x07f5, 0x0800, + 0x03ef, 0x03ef, 0x03ef, 0x0810, 0x0820, 0x0830, 0x03ef, 0x0840, + 0x0850, 0x021d, 0x021d, 0x021d, 0x021d, 0x0860, 0x0870, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + 0x021d, 0x021d, 0x021d, 0x021d, 0x021d, + /* level 3 offsets */ + 0x0880, 0x088e, 0x089e, 0x08ae, 0x08bd, 0x08c2, 0x08bd, 0x08d2, + 0x08e1, 0x08e7, 0x08f7, 0x0907, 0x0917, 0x0920, 0x0917, 0x0920, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0928, 0x0936, 0x0936, 0x0946, 0x0955, 0x0965, 0x0965, 0x0965, + 0x0965, 0x0965, 0x0965, 0x0965, 0x0975, 0x0984, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0921, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0991, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x099b, 0x09ab, + 0x0965, 0x09ad, 0x09bb, 0x09cb, 0x09d0, 0x09df, 0x09ef, 0x09ff, + 0x0a0a, 0x0a0a, 0x0a0f, 0x0965, 0x0a1f, 0x0a09, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x0a2c, 0x0a3b, 0x0a4b, 0x0a55, 0x0a64, + 0x0a0a, 0x0965, 0x0a74, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a6e, 0x0a84, 0x09cb, 0x09cb, 0x0a94, 0x0aa0, 0x09cb, 0x0aae, + 0x0aba, 0x09cc, 0x09cb, 0x0aca, 0x0ada, 0x0a0a, 0x0aea, 0x0afa, + 0x0a0a, 0x0a0a, 0x0a6a, 0x0965, 0x0b08, 0x0965, 0x0b15, 0x0917, + 0x0917, 0x0b1b, 0x0b2a, 0x0993, 0x0b38, 0x0917, 0x0b47, 0x0917, + 0x0917, 0x0b3c, 0x0b56, 0x0917, 0x0b38, 0x0b64, 0x0b73, 0x0917, + 0x0917, 0x0b3c, 0x0b82, 0x0b47, 0x0917, 0x0b8e, 0x0b73, 0x0917, + 0x0917, 0x0b3c, 0x0b9d, 0x0917, 0x0b38, 0x0bac, 0x0b47, 0x0917, + 0x0917, 0x0bbc, 0x0b56, 0x0bcc, 0x0b38, 0x0917, 0x0b46, 0x0917, + 0x0917, 0x0917, 0x0b3b, 0x0917, 0x0917, 0x0bd9, 0x0be9, 0x0917, + 0x0917, 0x0bee, 0x0bfd, 0x0bcc, 0x0b38, 0x0c0b, 0x0b47, 0x0917, + 0x0917, 0x0b3c, 0x0b77, 0x0917, 0x0b38, 0x0917, 0x0c1b, 0x0917, + 0x0917, 0x0b78, 0x0b56, 0x0917, 0x0b38, 0x0917, 0x0b47, 0x0917, + 0x0917, 0x0917, 0x0b3e, 0x0c29, 0x0917, 0x0917, 0x0917, 0x0c38, + 0x0c48, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0c57, + 0x098c, 0x0917, 0x0917, 0x0917, 0x0c64, 0x0917, 0x0c6f, 0x0917, + 0x0917, 0x0917, 0x0c7e, 0x0c88, 0x0c95, 0x0965, 0x0968, 0x0b42, + 0x0917, 0x0917, 0x0917, 0x0b4a, 0x0ca4, 0x0917, 0x0b7b, 0x0cb2, + 0x0cc1, 0x0ccf, 0x0cdd, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0b4a, 0x0917, 0x0917, 0x0917, 0x0ced, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x08bd, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0cfd, 0x0d02, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0d10, 0x0917, 0x0b38, 0x0917, + 0x0b38, 0x0917, 0x0b38, 0x0917, 0x0917, 0x0917, 0x0d1c, 0x0c33, + 0x0d26, 0x0917, 0x0ced, 0x0d36, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0bcc, 0x0917, 0x0b3f, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0d45, 0x0d53, 0x0d63, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x08bf, 0x0955, + 0x0955, 0x0917, 0x0d6c, 0x0917, 0x0917, 0x0917, 0x0d78, 0x0d86, + 0x0d93, 0x0917, 0x0917, 0x0917, 0x0965, 0x0966, 0x0917, 0x0917, + 0x0917, 0x0b14, 0x0917, 0x0917, 0x0da3, 0x0b46, 0x0917, 0x0db0, + 0x0b14, 0x0c1b, 0x0917, 0x0dc0, 0x0917, 0x0917, 0x0917, 0x0dce, + 0x0c1b, 0x0917, 0x0917, 0x0b4b, 0x0ddd, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0ded, 0x0dfc, + 0x0e05, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0965, 0x0965, 0x0965, + 0x0965, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0e0f, 0x08d0, 0x08c0, 0x08c0, + 0x0d00, 0x0e1f, 0x0955, 0x0e2f, 0x0e3f, 0x0e4b, 0x0e50, 0x0e60, + 0x0e70, 0x0e80, 0x0917, 0x0e90, 0x0e90, 0x0e9f, 0x0965, 0x0965, + 0x0cb2, 0x0eaf, 0x0ebb, 0x0ec9, 0x0ed8, 0x0ee8, 0x0955, 0x0917, + 0x0917, 0x0ef6, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0f06, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0f10, 0x0917, 0x0917, 0x0917, 0x08c2, 0x0955, 0x094f, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0f0f, 0x0917, 0x093b, + 0x0917, 0x0955, 0x0955, 0x0f20, 0x0f28, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0f16, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0f38, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0f45, 0x0955, 0x094e, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0f55, 0x0f64, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0cb3, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0965, 0x0965, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0938, 0x0917, 0x0917, 0x0955, 0x0f6d, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x08ba, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0f10, 0x0917, 0x093a, 0x0f7d, 0x0955, 0x0f8c, 0x0f9c, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0fac, 0x08bd, 0x0917, 0x0917, + 0x0917, 0x0917, 0x091c, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0955, + 0x0955, 0x08ba, 0x0917, 0x0d00, 0x0917, 0x0917, 0x0917, 0x0955, + 0x0917, 0x0fb9, 0x0917, 0x0917, 0x0917, 0x0954, 0x08c1, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0fc8, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x08bf, 0x0917, 0x08be, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0955, 0x0955, 0x0955, 0x0f0f, 0x0917, 0x0917, 0x0917, 0x08c0, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0cb3, 0x0fd8, 0x0917, + 0x0b49, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0c1b, 0x0955, + 0x0955, 0x08bc, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x091f, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0fe8, + 0x0917, 0x0ff4, 0x1001, 0x0917, 0x0917, 0x0917, 0x0eee, 0x0917, + 0x0917, 0x0917, 0x0917, 0x100d, 0x0917, 0x0965, 0x0b16, 0x0917, + 0x0917, 0x1017, 0x0917, 0x1025, 0x0c1b, 0x0917, 0x0917, 0x0b15, + 0x0917, 0x0917, 0x1035, 0x0917, 0x0917, 0x0b43, 0x0917, 0x0917, + 0x1043, 0x0cac, 0x1052, 0x0917, 0x0917, 0x0b3c, 0x0917, 0x0917, + 0x0917, 0x1062, 0x0b47, 0x0917, 0x0b77, 0x0b42, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0ed8, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x1072, 0x0917, 0x1080, 0x108f, + 0x1099, 0x10a9, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x10b9, 0x0ae7, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0a0a, 0x0a0a, 0x10c9, 0x0955, 0x0a0a, 0x0a0a, 0x0a0a, + 0x0a0a, 0x0ae8, 0x0a0a, 0x0a0a, 0x10d9, 0x0917, 0x0917, 0x10e9, + 0x0965, 0x0ced, 0x0965, 0x0955, 0x0955, 0x10f9, 0x1109, 0x1119, + 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x0a0a, 0x111f, + 0x112f, 0x08ae, 0x08bd, 0x08c2, 0x08bd, 0x08c2, 0x0f10, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x113f, 0x08c4, + 0x114e, 0x0917, 0x0917, 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0939, 0x0939, 0x08bd, 0x0917, 0x0917, 0x0917, 0x0917, 0x0cdd, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x115e, 0x0f28, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x116e, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x117e, 0x09cb, 0x09cb, 0x1188, 0x09cb, 0x1197, 0x09cb, 0x09cb, + 0x09cb, 0x09cc, 0x09c4, 0x0917, 0x0917, 0x0917, 0x09cb, 0x11a4, + 0x09cb, 0x11af, 0x09cb, 0x11bf, 0x0917, 0x0917, 0x0917, 0x0917, + 0x09cb, 0x09cb, 0x09cb, 0x09d3, 0x09cb, 0x09c9, 0x09cb, 0x09cb, + 0x11ce, 0x11de, 0x09cb, 0x11e8, 0x11f8, 0x11f8, 0x09cb, 0x09cb, + 0x09cb, 0x09cb, 0x0917, 0x0917, 0x09cb, 0x09cb, 0x1208, 0x1213, + 0x09cb, 0x09cb, 0x09cb, 0x1223, 0x09cb, 0x1233, 0x09cb, 0x1240, + 0x09cb, 0x124e, 0x0a8b, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x09cb, 0x09cb, 0x09cb, 0x09cb, 0x11f8, 0x0917, 0x0917, 0x0917, + 0x09cb, 0x09cb, 0x09cb, 0x1258, 0x09cb, 0x09cb, 0x09cb, 0x1268, + 0x0a0a, 0x0a0a, 0x1278, 0x1288, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x1298, 0x1299, 0x09cb, 0x09cb, 0x12a9, 0x12b9, 0x0917, 0x0917, + 0x0917, 0x0b4a, 0x09cb, 0x09cb, 0x12c9, 0x0a0a, 0x0a6e, 0x12d9, + 0x0917, 0x09cb, 0x12e9, 0x0917, 0x0917, 0x09cb, 0x09cf, 0x0917, + 0x09cb, 0x1213, 0x0b47, 0x0917, 0x0917, 0x1015, 0x0994, 0x0936, + 0x0f10, 0x12f9, 0x0c1b, 0x0917, 0x0917, 0x1305, 0x0b46, 0x0917, + 0x0917, 0x0917, 0x0b15, 0x0917, 0x1310, 0x0b13, 0x0917, 0x0917, + 0x0917, 0x0b45, 0x0c1b, 0x0917, 0x0917, 0x1026, 0x12ff, 0x0917, + 0x0917, 0x0917, 0x0cb3, 0x131e, 0x0b47, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0cb3, 0x101a, 0x0917, + 0x0c1b, 0x0917, 0x0917, 0x0b78, 0x0cb2, 0x0917, 0x098e, 0x0b13, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x1015, 0x0c29, 0x132d, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x133c, 0x0b72, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x1349, 0x0cb2, 0x0b77, + 0x0917, 0x0917, 0x0917, 0x1359, 0x0cb2, 0x0917, 0x0939, 0x0917, + 0x0917, 0x0917, 0x0b1a, 0x1368, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0b4a, 0x1376, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0cb3, + 0x0c85, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x1382, 0x0b45, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x1304, + 0x0cb2, 0x0917, 0x1391, 0x0917, 0x0917, 0x139e, 0x0b41, 0x13ad, + 0x0917, 0x0917, 0x1013, 0x13bd, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x13cd, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0c7d, 0x13dd, 0x13ec, 0x0917, 0x0917, 0x0917, 0x0917, 0x13fb, + 0x1368, 0x0917, 0x0917, 0x0917, 0x0917, 0x140a, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0e0a, 0x0c1b, 0x0917, + 0x0917, 0x116e, 0x140f, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x141a, 0x1429, 0x08bc, 0x0917, 0x0917, + 0x0917, 0x0917, 0x1439, 0x0995, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0b13, 0x0917, 0x0917, 0x0917, 0x0994, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0cb3, 0x0917, 0x0917, 0x0917, + 0x0cb3, 0x0b15, 0x0917, 0x0917, 0x0917, 0x0917, 0x1449, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0b76, 0x1459, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0965, + 0x0965, 0x0967, 0x0965, 0x0994, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x1462, + 0x146f, 0x147c, 0x0917, 0x0b4d, 0x0917, 0x0917, 0x0917, 0x0928, + 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, 0x148c, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0f0f, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x091c, 0x0917, 0x0917, 0x1497, + 0x0917, 0x0917, 0x08be, 0x0917, 0x0917, 0x0917, 0x091e, 0x0917, + 0x0917, 0x0917, 0x1499, 0x14a7, 0x14a7, 0x14a7, 0x0965, 0x0965, + 0x0965, 0x14b7, 0x0965, 0x0965, 0x0968, 0x0b43, 0x0b44, 0x0db0, + 0x09ab, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x14c2, 0x14ca, + 0x14d8, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0cb3, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x132d, 0x0917, 0x0917, 0x0917, 0x0b4b, 0x14e3, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0b4b, 0x0917, 0x09cb, + 0x09cb, 0x09cb, 0x09cb, 0x09cb, 0x09cb, 0x09cb, 0x09cb, 0x09cb, + 0x09cb, 0x09cb, 0x09cb, 0x14f3, 0x0994, 0x0917, 0x0917, 0x09cb, + 0x09cb, 0x09cb, 0x09cb, 0x14ff, 0x09d1, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0ae9, + 0x0a0a, 0x0a0a, 0x0a0a, 0x150f, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0ae9, 0x0a0a, 0x0a0a, 0x151f, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x111a, 0x0a0a, 0x152e, 0x153b, 0x1549, 0x1559, 0x1567, 0x156f, + 0x157f, 0x158a, 0x1599, 0x158a, 0x0917, 0x0917, 0x0917, 0x08bc, + 0x0955, 0x0955, 0x093a, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x08ba, 0x15a9, 0x0954, 0x0954, 0x0954, 0x0955, 0x0f10, + 0x15b9, 0x0917, 0x08be, 0x0917, 0x0917, 0x0917, 0x0f16, 0x0917, + 0x0917, 0x0917, 0x091a, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0f10, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x15c4, 0x0939, 0x0939, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x15c5, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0ced, 0x093a, 0x08bd, 0x093a, 0x0955, 0x0955, 0x0955, 0x0f0e, + 0x0ced, 0x0955, 0x0955, 0x0f0e, 0x0955, 0x0938, 0x08bc, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x08ba, 0x0938, 0x0939, 0x0f0d, 0x0955, 0x0955, 0x15d0, 0x15df, + 0x093a, 0x0f0d, 0x0f0d, 0x0955, 0x0955, 0x0955, 0x0955, 0x0955, + 0x0955, 0x0955, 0x0955, 0x0955, 0x0951, 0x0955, 0x0955, 0x093b, + 0x0917, 0x0917, 0x1164, 0x15ef, 0x0917, 0x08e7, 0x08e7, 0x08e7, + 0x08e7, 0x08e7, 0x08e7, 0x0917, 0x0917, 0x0917, 0x0917, 0x0917, + 0x0917, 0x0917, 0x0917, 0x0965, 0x0965, 0x0965, 0x0965, 0x0965, + 0x0965, 0x0965, 0x0965, 0x0965, 0x0965, 0x0965, 0x0965, 0x0965, + 0x0965, 0x0965, 0x0917, + /* values */ + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000b, 0x000d, 0x000b, 0x000c, 0x000d, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000d, 0x000d, 0x000d, 0x000b, 0x000c, 0x0000, + 0x0000, 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0008, 0x0007, 0x0008, 0x0007, 0x0007, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0007, + 0x0000, 0x0009, 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0000, 0x0000, 0x000a, 0x0000, 0x0000, 0x0009, + 0x0009, 0x0004, 0x0004, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0004, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0009, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0002, 0x0006, 0x0006, 0x0002, 0x0006, + 0x0006, 0x0002, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, 0x0005, + 0x0009, 0x0009, 0x0005, 0x0007, 0x0005, 0x0000, 0x0000, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0009, 0x0003, 0x0003, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0003, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0005, 0x0005, 0x0006, 0x0006, 0x0000, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0005, 0x0005, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, 0x0006, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0005, 0x0005, 0x0005, 0x0006, 0x0005, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0002, 0x0002, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0002, 0x0001, 0x0001, 0x0006, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0002, 0x0006, + 0x0006, 0x0006, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0002, 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0001, 0x0003, 0x0003, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0003, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0009, 0x0009, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0009, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0009, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0009, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0009, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0001, + 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x000c, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0009, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0006, 0x0006, 0x0006, 0x000a, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0000, 0x000c, + 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, + 0x000c, 0x000c, 0x000a, 0x000a, 0x000a, 0x0001, 0x0002, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, + 0x000d, 0x0011, 0x000f, 0x0012, 0x0010, 0x000e, 0x0007, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0001, 0x0013, 0x0014, + 0x0015, 0x0016, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x0004, 0x0001, 0x0001, 0x0001, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, + 0x0000, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0009, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0009, 0x0009, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0008, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0002, + 0x0001, 0x0002, 0x0002, 0x0001, 0x0002, 0x0002, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0000, + 0x0000, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0000, 0x0000, + 0x0000, 0x0007, 0x0000, 0x0007, 0x0001, 0x0000, 0x0007, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0009, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0000, 0x0009, 0x0009, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x000a, 0x0001, + 0x0000, 0x0000, 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0008, 0x0007, 0x0008, 0x0007, 0x0007, 0x0009, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0009, 0x0009, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0002, 0x0001, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0001, 0x0002, 0x0002, 0x0002, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0006, 0x0006, 0x0002, 0x0001, + 0x0001, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, + 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, + 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, 0x0001, 0x0006, + 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0009, + 0x0009, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0001, 0x0001, 0x0000, 0x0001, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x000a, 0x000a, 0x000a, 0x000a, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0006, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, 0x0001, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0009, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0001, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, 0x0005, + 0x0005, 0x0001, 0x0005, 0x0001, 0x0001, 0x0005, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, 0x0005, + 0x0005, 0x0001, 0x0005, 0x0005, 0x0001, 0x0005, 0x0001, 0x0001, + 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, 0x0001, + 0x0005, 0x0005, 0x0001, 0x0005, 0x0001, 0x0001, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, 0x0001, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, 0x0005, + 0x0005, 0x0005, 0x0005, 0x0001, 0x0005, 0x0005, 0x0005, 0x0005, + 0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, + 0x000a, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 +}; diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 858a118b41b..b40f7a7962c 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -25,6 +25,7 @@ #include <ntgdi.h> #include <winspool.h> #include <ddk/winsplp.h> +#include <usp10.h>
#include "psdrv.h"
@@ -1143,6 +1144,585 @@ static BOOL get_text_extent(struct pp_data *data, const WCHAR *str, INT count, return ret; }
+extern const unsigned short bidi_direction_table[] DECLSPEC_HIDDEN; + +/*------------------------------------------------------------------------ + Bidirectional Character Types + + as defined by the Unicode Bidirectional Algorithm Table 3-7. + + Note: + + The list of bidirectional character types here is not grouped the + same way as the table 3-7, since the numeric values for the types + are chosen to keep the state and action tables compact. +------------------------------------------------------------------------*/ +enum directions +{ + /* input types */ + /* ON MUST be zero, code relies on ON = N = 0 */ + ON = 0, /* Other Neutral */ + L, /* Left Letter */ + R, /* Right Letter */ + AN, /* Arabic Number */ + EN, /* European Number */ + AL, /* Arabic Letter (Right-to-left) */ + NSM, /* Non-spacing Mark */ + CS, /* Common Separator */ + ES, /* European Separator */ + ET, /* European Terminator (post/prefix e.g. $ and %) */ + + /* resolved types */ + BN, /* Boundary neutral (type of RLE etc after explicit levels) */ + + /* input types, */ + S, /* Segment Separator (TAB) // used only in L1 */ + WS, /* White space // used only in L1 */ + B, /* Paragraph Separator (aka as PS) */ + + /* types for explicit controls */ + RLO, /* these are used only in X1-X9 */ + RLE, + LRO, + LRE, + PDF, + + LRI, /* Isolate formatting characters new with 6.3 */ + RLI, + FSI, + PDI, + + /* resolved types, also resolved directions */ + NI = ON, /* alias, where ON, WS and S are treated the same */ +}; + +static inline unsigned short get_table_entry_32(const unsigned short *table, UINT ch) +{ + return table[table[table[table[ch >> 12] + ((ch >> 8) & 0x0f)] + ((ch >> 4) & 0x0f)] + (ch & 0xf)]; +} + +/* Convert the libwine information to the direction enum */ +static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount) +{ + unsigned i; + + for (i = 0; i < uCount; ++i) + chartype[i] = get_table_entry_32(bidi_direction_table, lpString[i]); +} + +/* Set a run of cval values at locations all prior to, but not including */ +/* iStart, to the new value nval. */ +static void SetDeferredRun(BYTE *pval, int cval, int iStart, int nval) +{ + int i = iStart - 1; + for (; i >= iStart - cval; i--) + { + pval[i] = nval; + } +} + +/* THE PARAGRAPH LEVEL */ + +/*------------------------------------------------------------------------ + Function: resolveParagraphs + + Resolves the input strings into blocks over which the algorithm + is then applied. + + Implements Rule P1 of the Unicode Bidi Algorithm + + Input: Text string + Character count + + Output: revised character count + + Note: This is a very simplistic function. In effect it restricts + the action of the algorithm to the first paragraph in the input + where a paragraph ends at the end of the first block separator + or at the end of the input text. + +------------------------------------------------------------------------*/ + +static int resolveParagraphs(WORD *types, int cch) +{ + /* skip characters not of type B */ + int ich = 0; + for(; ich < cch && types[ich] != B; ich++); + /* stop after first B, make it a BN for use in the next steps */ + if (ich < cch && types[ich] == B) + types[ich++] = BN; + return ich; +} + +/* REORDER */ +/*------------------------------------------------------------------------ + Function: resolveLines + + Breaks a paragraph into lines + + Input: Array of line break flags + Character count + In/Out: Array of characters + + Returns the count of characters on the first line + + Note: This function only breaks lines at hard line breaks. Other + line breaks can be passed in. If pbrk[n] is TRUE, then a break + occurs after the character in pszInput[n]. Breaks before the first + character are not allowed. +------------------------------------------------------------------------*/ +static int resolveLines(LPCWSTR pszInput, const BOOL * pbrk, int cch) +{ + /* skip characters not of type LS */ + int ich = 0; + for(; ich < cch; ich++) + { + if (pszInput[ich] == (WCHAR)'\n' || (pbrk && pbrk[ich])) + { + ich++; + break; + } + } + + return ich; +} + +/*------------------------------------------------------------------------ + Function: resolveWhiteSpace + + Resolves levels for WS and S + Implements rule L1 of the Unicode bidi Algorithm. + + Input: Base embedding level + Character count + Array of direction classes (for one line of text) + + In/Out: Array of embedding levels (for one line of text) + + Note: this should be applied a line at a time. The default driver + code supplied in this file assumes a single line of text; for + a real implementation, cch and the initial pointer values + would have to be adjusted. +------------------------------------------------------------------------*/ +static void resolveWhitespace(int baselevel, const WORD *pcls, BYTE *plevel, int cch) +{ + int cchrun = 0; + BYTE oldlevel = baselevel; + + int ich = 0; + for (; ich < cch; ich++) + { + switch(pcls[ich]) + { + default: + cchrun = 0; /* any other character breaks the run */ + break; + case WS: + cchrun++; + break; + + case RLE: + case LRE: + case LRO: + case RLO: + case PDF: + case LRI: + case RLI: + case FSI: + case PDI: + case BN: + plevel[ich] = oldlevel; + cchrun++; + break; + + case S: + case B: + /* reset levels for WS before eot */ + SetDeferredRun(plevel, cchrun, ich, baselevel); + cchrun = 0; + plevel[ich] = baselevel; + break; + } + oldlevel = plevel[ich]; + } + /* reset level before eot */ + SetDeferredRun(plevel, cchrun, ich, baselevel); +} + +/*------------------------------------------------------------------------ + Function: BidiLines + + Implements the Line-by-Line phases of the Unicode Bidi Algorithm + + Input: Count of characters + Array of character directions + + Inp/Out: Input text + Array of levels + +------------------------------------------------------------------------*/ +static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, const WORD * pclsLine, + BYTE * plevelLine, int cchPara, const BOOL * pbrk) +{ + int cchLine = 0; + int done = 0; + int *run; + + run = HeapAlloc(GetProcessHeap(), 0, cchPara * sizeof(int)); + if (!run) + { + WARN("Out of memory\n"); + return; + } + + do + { + /* break lines at LS */ + cchLine = resolveLines(pszLine, pbrk, cchPara); + + /* resolve whitespace */ + resolveWhitespace(baselevel, pclsLine, plevelLine, cchLine); + + if (pszOutLine) + { + int i; + /* reorder each line in place */ + ScriptLayout(cchLine, plevelLine, NULL, run); + for (i = 0; i < cchLine; i++) + pszOutLine[done+run[i]] = pszLine[i]; + } + + pszLine += cchLine; + plevelLine += cchLine; + pbrk += pbrk ? cchLine : 0; + pclsLine += cchLine; + cchPara -= cchLine; + done += cchLine; + + } while (cchPara); + + HeapFree(GetProcessHeap(), 0, run); +} + +#define WINE_GCPW_FORCE_LTR 0 +#define WINE_GCPW_FORCE_RTL 1 +#define WINE_GCPW_DIR_MASK 3 + +static BOOL BIDI_Reorder(HDC hDC, /* [in] Display DC */ + LPCWSTR lpString, /* [in] The string for which information is to be returned */ + INT uCount, /* [in] Number of WCHARs in string. */ + DWORD dwFlags, /* [in] GetCharacterPlacement compatible flags */ + DWORD dwWineGCP_Flags, /* [in] Wine internal flags - Force paragraph direction */ + LPWSTR lpOutString, /* [out] Reordered string */ + INT uCountOut, /* [in] Size of output buffer */ + UINT *lpOrder, /* [out] Logical -> Visual order map */ + WORD **lpGlyphs, /* [out] reordered, mirrored, shaped glyphs to display */ + INT *cGlyphs) /* [out] number of glyphs generated */ +{ + WORD *chartype = NULL; + BYTE *levels = NULL; + INT i, done; + unsigned glyph_i; + BOOL is_complex, ret = FALSE; + + int maxItems; + int nItems; + SCRIPT_CONTROL Control; + SCRIPT_STATE State; + SCRIPT_ITEM *pItems = NULL; + HRESULT res; + SCRIPT_CACHE psc = NULL; + WORD *run_glyphs = NULL; + WORD *pwLogClust = NULL; + SCRIPT_VISATTR *psva = NULL; + DWORD cMaxGlyphs = 0; + BOOL doGlyphs = TRUE; + + TRACE("%s, %d, 0x%08lx lpOutString=%p, lpOrder=%p\n", + debugstr_wn(lpString, uCount), uCount, dwFlags, + lpOutString, lpOrder); + + memset(&Control, 0, sizeof(Control)); + memset(&State, 0, sizeof(State)); + if (lpGlyphs) + *lpGlyphs = NULL; + + if (!(dwFlags & GCP_REORDER)) + { + FIXME("Asked to reorder without reorder flag set\n"); + return FALSE; + } + + if (lpOutString && uCountOut < uCount) + { + FIXME("lpOutString too small\n"); + return FALSE; + } + + chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)); + if (!chartype) + { + WARN("Out of memory\n"); + return FALSE; + } + + if (lpOutString) + memcpy(lpOutString, lpString, uCount * sizeof(WCHAR)); + + is_complex = FALSE; + for (i = 0; i < uCount && !is_complex; i++) + { + if ((lpString[i] >= 0x900 && lpString[i] <= 0xfff) || + (lpString[i] >= 0x1cd0 && lpString[i] <= 0x1cff) || + (lpString[i] >= 0xa840 && lpString[i] <= 0xa8ff)) + is_complex = TRUE; + } + + /* Verify reordering will be required */ + if (WINE_GCPW_FORCE_RTL == (dwWineGCP_Flags & WINE_GCPW_DIR_MASK)) + State.uBidiLevel = 1; + else if (!is_complex) + { + done = 1; + classify(lpString, chartype, uCount); + for (i = 0; i < uCount; i++) + switch (chartype[i]) + { + case R: + case AL: + case RLE: + case RLO: + done = 0; + break; + } + if (done) + { + HeapFree(GetProcessHeap(), 0, chartype); + if (lpOrder) + { + for (i = 0; i < uCount; i++) + lpOrder[i] = i; + } + return TRUE; + } + } + + levels = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(BYTE)); + if (!levels) + { + WARN("Out of memory\n"); + goto cleanup; + } + + maxItems = 5; + pItems = HeapAlloc(GetProcessHeap(),0, maxItems * sizeof(SCRIPT_ITEM)); + if (!pItems) + { + WARN("Out of memory\n"); + goto cleanup; + } + + if (lpGlyphs) + { + cMaxGlyphs = 1.5 * uCount + 16; + run_glyphs = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * cMaxGlyphs); + if (!run_glyphs) + { + WARN("Out of memory\n"); + goto cleanup; + } + pwLogClust = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * uCount); + if (!pwLogClust) + { + WARN("Out of memory\n"); + goto cleanup; + } + psva = HeapAlloc(GetProcessHeap(),0,sizeof(SCRIPT_VISATTR) * cMaxGlyphs); + if (!psva) + { + WARN("Out of memory\n"); + goto cleanup; + } + } + + done = 0; + glyph_i = 0; + while (done < uCount) + { + INT j; + classify(lpString + done, chartype, uCount - done); + /* limit text to first block */ + i = resolveParagraphs(chartype, uCount - done); + for (j = 0; j < i; ++j) + switch(chartype[j]) + { + case B: + case S: + case WS: + case ON: chartype[j] = NI; + default: continue; + } + + res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems); + while (res == E_OUTOFMEMORY) + { + SCRIPT_ITEM *new_pItems = HeapReAlloc(GetProcessHeap(), 0, pItems, sizeof(*pItems) * maxItems * 2); + if (!new_pItems) + { + WARN("Out of memory\n"); + goto cleanup; + } + pItems = new_pItems; + maxItems *= 2; + res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems); + } + + if (lpOutString || lpOrder) + for (j = 0; j < nItems; j++) + { + int k; + for (k = pItems[j].iCharPos; k < pItems[j+1].iCharPos; k++) + levels[k] = pItems[j].a.s.uBidiLevel; + } + + if (lpOutString) + { + /* assign directional types again, but for WS, S this time */ + classify(lpString + done, chartype, i); + + BidiLines(State.uBidiLevel, lpOutString + done, lpString + done, + chartype, levels, i, 0); + } + + if (lpOrder) + { + int k, lastgood; + for (j = lastgood = 0; j < i; ++j) + if (levels[j] != levels[lastgood]) + { + --j; + if (levels[lastgood] & 1) + for (k = j; k >= lastgood; --k) + lpOrder[done + k] = done + j - k; + else + for (k = lastgood; k <= j; ++k) + lpOrder[done + k] = done + k; + lastgood = ++j; + } + if (levels[lastgood] & 1) + for (k = j - 1; k >= lastgood; --k) + lpOrder[done + k] = done + j - 1 - k; + else + for (k = lastgood; k < j; ++k) + lpOrder[done + k] = done + k; + } + + if (lpGlyphs && doGlyphs) + { + BYTE *runOrder; + int *visOrder; + SCRIPT_ITEM *curItem; + + runOrder = HeapAlloc(GetProcessHeap(), 0, maxItems * sizeof(*runOrder)); + visOrder = HeapAlloc(GetProcessHeap(), 0, maxItems * sizeof(*visOrder)); + if (!runOrder || !visOrder) + { + WARN("Out of memory\n"); + HeapFree(GetProcessHeap(), 0, runOrder); + HeapFree(GetProcessHeap(), 0, visOrder); + goto cleanup; + } + + for (j = 0; j < nItems; j++) + runOrder[j] = pItems[j].a.s.uBidiLevel; + + ScriptLayout(nItems, runOrder, visOrder, NULL); + + for (j = 0; j < nItems; j++) + { + int k; + int cChars,cOutGlyphs; + curItem = &pItems[visOrder[j]]; + + cChars = pItems[visOrder[j]+1].iCharPos - curItem->iCharPos; + + res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs); + while (res == E_OUTOFMEMORY) + { + WORD *new_run_glyphs = HeapReAlloc(GetProcessHeap(), 0, run_glyphs, sizeof(*run_glyphs) * cMaxGlyphs * 2); + SCRIPT_VISATTR *new_psva = HeapReAlloc(GetProcessHeap(), 0, psva, sizeof(*psva) * cMaxGlyphs * 2); + if (!new_run_glyphs || !new_psva) + { + WARN("Out of memory\n"); + HeapFree(GetProcessHeap(), 0, runOrder); + HeapFree(GetProcessHeap(), 0, visOrder); + HeapFree(GetProcessHeap(), 0, *lpGlyphs); + *lpGlyphs = NULL; + if (new_run_glyphs) + run_glyphs = new_run_glyphs; + if (new_psva) + psva = new_psva; + goto cleanup; + } + run_glyphs = new_run_glyphs; + psva = new_psva; + cMaxGlyphs *= 2; + res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs); + } + if (res) + { + if (res == USP_E_SCRIPT_NOT_IN_FONT) + TRACE("Unable to shape with currently selected font\n"); + else + FIXME("Unable to shape string (%lx)\n",res); + j = nItems; + doGlyphs = FALSE; + HeapFree(GetProcessHeap(), 0, *lpGlyphs); + *lpGlyphs = NULL; + } + else + { + WORD *new_glyphs; + if (*lpGlyphs) + new_glyphs = HeapReAlloc(GetProcessHeap(), 0, *lpGlyphs, sizeof(**lpGlyphs) * (glyph_i + cOutGlyphs)); + else + new_glyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(**lpGlyphs) * (glyph_i + cOutGlyphs)); + if (!new_glyphs) + { + WARN("Out of memory\n"); + HeapFree(GetProcessHeap(), 0, runOrder); + HeapFree(GetProcessHeap(), 0, visOrder); + HeapFree(GetProcessHeap(), 0, *lpGlyphs); + *lpGlyphs = NULL; + goto cleanup; + } + *lpGlyphs = new_glyphs; + for (k = 0; k < cOutGlyphs; k++) + (*lpGlyphs)[glyph_i+k] = run_glyphs[k]; + glyph_i += cOutGlyphs; + } + } + HeapFree(GetProcessHeap(), 0, runOrder); + HeapFree(GetProcessHeap(), 0, visOrder); + } + + done += i; + } + if (cGlyphs) + *cGlyphs = glyph_i; + + ret = TRUE; +cleanup: + HeapFree(GetProcessHeap(), 0, chartype); + HeapFree(GetProcessHeap(), 0, levels); + HeapFree(GetProcessHeap(), 0, pItems); + HeapFree(GetProcessHeap(), 0, run_glyphs); + HeapFree(GetProcessHeap(), 0, pwLogClust); + HeapFree(GetProcessHeap(), 0, psva); + ScriptFreeCache(&psc); + return ret; +} + static inline BOOL intersect_rect(RECT *dst, const RECT *src1, const RECT *src2) { dst->left = max(src1->left, src2->left); @@ -1182,9 +1762,28 @@ static BOOL ext_text_out(struct pp_data *data, HANDLETABLE *htable, RECT rc; POINT *deltas = NULL, width = {0, 0}; INT breakRem; + WORD *glyphs = NULL; XFORM xform;
- /* TODO: Add BiDi support */ + if (!(flags & (ETO_GLYPH_INDEX | ETO_IGNORELANGUAGE)) && count > 0) + { + int glyphs_count = 0; + UINT bidi_flags; + + bidi_flags = (GetTextAlign(hdc) & TA_RTLREADING) || (flags & ETO_RTLREADING) + ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR; + + BIDI_Reorder(hdc, str, count, GCP_REORDER, bidi_flags, + NULL, 0, NULL, &glyphs, &glyphs_count); + + flags |= ETO_IGNORELANGUAGE; + if (glyphs) + { + flags |= ETO_GLYPH_INDEX; + count = glyphs_count; + str = glyphs; + } + }
align = GetTextAlign(hdc); breakRem = data->break_rem; @@ -1504,6 +2103,7 @@ done: DeleteObject(hbrush); }
+ HeapFree(GetProcessHeap(), 0, glyphs); return ret; }
diff --git a/tools/make_unicode b/tools/make_unicode index 2d1a90fafbc..d0e3afc4294 100755 --- a/tools/make_unicode +++ b/tools/make_unicode @@ -5807,6 +5807,7 @@ chdir ".." if -f "./make_unicode"; load_data(); dump_bidi_dir_table( "dlls/gdi32/uniscribe/direction.c" ); dump_bidi_dir_table( "dlls/dwrite/direction.c" ); +dump_bidi_dir_table( "dlls/wineps.drv/direction.c" ); dump_mirroring( "dlls/gdi32/uniscribe/mirror.c" ); dump_mirroring( "dlls/dwrite/mirror.c" ); dump_bracket( "dlls/gdi32/uniscribe/bracket.c" );
Huw Davies (@huw) commented about dlls/wineps.drv/printproc.c:
return NULL; } data->pdev->dev.hdc = hdc;
- data->pdev->dev.next = &data->font_dev;
- data->font_dev.funcs = &font_funcs;
- data->font_dev.hdc = hdc;
What's the plan with this - how does this work when we switch the driver interface to the unix-side?
On Wed Apr 19 08:23:37 2023 +0000, Huw Davies wrote:
What's the plan with this - how does this work when we switch the driver interface to the unix-side?
This is temporary, it's needed so e.g. following code can work while we still use wine_get_gdi_driver: ```c dev = GET_NEXT_PHYSDEV( dev, pGetTextMetrics ); return dev->funcs->pGetTextMetrics( dev, metrics ); ``` After `wine_get_gdi_driver` path is removed, the code will be changed to: ```c return GetTextMetricsW(dev->hdc, metrics); ``` (and `font_GetTextMetrics` will be removed, note that dev->hdc points to memory DC in this case).
The alternative is to change the callers to something like: ```c if (dev.next) //we can mark what path is used in PSDRV_DEVICE to make it more explicit { dev = GET_NEXT_PHYSDEV( dev, pGetTextMetrics ); return dev->funcs->pGetTextMetrics( dev, metrics ); } else { return GetTextMetricsW(dev->hdc, metrics); } ``` I'm not sure if it answers your question. I was thinking that the plan is to implement small parts of user-mode DDI so the driver interface is not on the unix side. I was already doing some tests regarding how it's done for GetDeviceCaps call (and it's basically a matter of copying the caps to structure supplied by GDI). I guess it will be harder for device font related functions. If we end with some other solution this part may need to be changed.
On Wed Apr 19 09:30:43 2023 +0000, Piotr Caban wrote:
This is temporary, it's needed so e.g. following code can work while we still use wine_get_gdi_driver:
dev = GET_NEXT_PHYSDEV( dev, pGetTextMetrics ); return dev->funcs->pGetTextMetrics( dev, metrics );
After `wine_get_gdi_driver` path is removed, the code will be changed to:
return GetTextMetricsW(dev->hdc, metrics);
(and `font_GetTextMetrics` will be removed, note that dev->hdc points to memory DC in this case). The alternative is to change the callers to something like:
if (dev.next) //we can mark what path is used in PSDRV_DEVICE to make it more explicit { dev = GET_NEXT_PHYSDEV( dev, pGetTextMetrics ); return dev->funcs->pGetTextMetrics( dev, metrics ); } else { return GetTextMetricsW(dev->hdc, metrics); }
I'm not sure if it answers your question. I was thinking that the plan is to implement small parts of user-mode DDI so the driver interface is not on the unix side. I was already doing some tests regarding how it's done for GetDeviceCaps call (and it's basically a matter of copying the caps to structure supplied by GDI). I guess it will be harder for device font related functions. If we end with some other solution this part may need to be changed.
Ok, if it's temporary that's of course fine.
I was hoping we could eliminate the `GetTextMetrics()` / `GetTextExtentPointW()` calls at some point, since we always have the offset array in the EMF and we could likely do something on the gdi side to deal with the vertical case.
On Wed Apr 19 09:40:46 2023 +0000, Huw Davies wrote:
Ok, if it's temporary that's of course fine. I was hoping we could eliminate the `GetTextMetrics()` / `GetTextExtentPointW()` calls at some point, since we always have the offset array in the EMF and we could likely do something on the gdi side to deal with the vertical case.
It's not really important since we don't create such records but there's EMR_SMALLTEXTOUT record that is similar to EMR_EXTTEXTOUT but doesn't contain the offsets.
On Wed Apr 19 09:59:50 2023 +0000, Piotr Caban wrote:
It's not really important since we don't create such records but there's EMR_SMALLTEXTOUT record that is similar to EMR_EXTTEXTOUT but doesn't contain the offsets.
Yeah, I think we can ignore that (for now at least) since, as you say, we don't create it.
This merge request was approved by Huw Davies.