From: Santino Mazza smazza@codeweavers.com
--- dlls/gdiplus/graphics.c | 66 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 65b33cdc960..5315da89d49 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -30,6 +30,7 @@ #include "ocidl.h" #include "olectl.h" #include "ole2.h" +#include "mlang.h"
#include "winreg.h" #include "shlwapi.h" @@ -5641,13 +5642,71 @@ static GpStatus draw_string_callback(HDC hdc, struct draw_string_args *args = user_data; PointF position; GpStatus stat; + IMLangFontLink2 *iMLFL2; + DWORD codepages, font_codepages; + INT current_index, current_length; + LONG processed; + HFONT new_font, old_font, hfont; + GpFont *new_gpfont; + LOGFONTW lfw; + HRESULT hr;
position.X = args->x + bounds->X / args->rel_width; position.Y = args->y + bounds->Y / args->rel_height + args->ascent;
- stat = draw_driver_string(args->graphics, &string[index], length, font, format, - args->brush, &position, - DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL); + if (FAILED(hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_ALL, &IID_IMLangFontLink2, (void**)&iMLFL2))) + { + ERR("Failed to create font linking interface %lx\n", hr); + return hr; + }; + + get_font_hfont(args->graphics, font, format, &hfont, &lfw, NULL); + IMLangFontLink2_GetFontCodePages(iMLFL2, hdc, hfont, &font_codepages); + + current_index = index; + current_length = length; + do + { + IMLangFontLink2_GetStrCodePages(iMLFL2, &string[current_index], current_length, 0, &codepages, &processed); + if (font_codepages & codepages) /* if the font supports the required codepages don't do anything. */ + stat = draw_driver_string(args->graphics, &string[current_index], processed, font, format, + args->brush, &position, + DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL); + else + { + old_font = SelectObject(hdc, hfont); + hr = IMLangFontLink2_MapFont(iMLFL2, hdc, codepages, 0, &new_font); + if (FAILED(hr)) + { + SelectObject(hdc, old_font); + break; + } + SelectObject(hdc, new_font); + stat = GdipCreateFontFromDC(hdc, &new_gpfont); + if (stat != Ok) + { + SelectObject(hdc, old_font); + IMLangFontLink2_ReleaseFont(iMLFL2, new_font); + break; + } + SelectObject(hdc, old_font); + stat = draw_driver_string(args->graphics, &string[current_index], processed, new_gpfont, format, + args->brush, &position, + DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL); + IMLangFontLink2_ReleaseFont(iMLFL2, new_font); + } + + current_index += processed; + current_length -= processed; + } + while (current_length > 0); + + if (stat != Ok || FAILED(hr)) /* If font linking failed, draw the rest without it. */ + { + stat = draw_driver_string(args->graphics, &string[current_index], current_length, font, format, + args->brush, &position, + DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL); + }
if (stat == Ok && underlined_index_count) { @@ -5676,6 +5735,7 @@ static GpStatus draw_string_callback(HDC hdc, } }
+ IMLangFontLink2_Release(iMLFL2); return stat; }