We'll use the function "drawstringw", that is just an adapted version from the original xfcgraphics.drawstring function.
It accepts the same parameters and overloads from the original function - the sole difference is the first parameter that was introduced - the graphics object.
Another helper function - "hextounicode" was introduced. It converts a string containing hex values separated by a space into the unicode needed by gdiplus.dll to draw the string.
Just run the script and you'll obtain a result similar to the one below:
Prerequisites
Visual FoxPro 9 and the GdiPlusX library from VfpX
DO LOCFILE("System.app") LOCAL N, x, Y, lnColor LOCAL loBmp AS xfcbitmap, loGfx AS xfcGraphics, loFont AS xfcFont LOCAL loBrush AS xfcsolidBrush LOCAL laWords(9,2) * greek laWords(1,1) = "greek" laWords(1,2) = "03b5 03b9 03c1 03ae 03bd 03b7" * korean laWords(2,1) = "korean" laWords(2,2) = "d3c9 d654" * hebrew laWords(3,1) = "hebrew" laWords(3,2) = "05e9 05dc 05d5 05dd" * bulgarian laWords(4,1) = "bulgarian" laWords(4,2) = "043c 0438 0440" * arabic laWords(5,1) = "arabic" laWords(5,2) = "0633 0644 0627 0645" * simplified chinese laWords(6,1) = "chinese" laWords(6,2) = "548c 5e73" * thai laWords(7,1) = "thai" laWords(7,2) = "0e04 0e27 0e32 0e21 0e2a 0e07 0e1a" * russian laWords(8,1) = "russian" laWords(8,2) = "043c 0438 0440" * japanese laWords(9,1) = "japanese" laWords(9,2) = "5e73 548c" WITH _SCREEN.SYSTEM.Drawing loFont = .Font.New("tahoma", 18) loBmp = .BITMAP.New(350,370) loGfx = .Graphics.fromImage(loBmp) loGfx.CLEAR(.COLOR.White) loGfx.DrawString("gdi+x Drawing Unicodes", loFont, .Brushes.black, 10,5) FOR N = 1 TO 9 Y = N * 35 x = 160 lnColor = RGB(RAND() * 255, RAND() * 255, RAND() * 255) * create a solidBrush with randomic color loBrush = .solidBrush.New(.COLOR.fromrgb(lnColor)) * Draw the language Name loGfx.DrawString(laWords(N,1), .Font.New("tahoma", 10), .Brushes.black, 65, Y + 5) * Draw the text in Unicodes =DrawStringw(loGfx, hextoUnicode(laWords(N,2)), loFont,; loBrush, x, Y) ENDFOR loBmp.SAVE("testUnicodes.png", .imaging.ImageFormat.png) ENDWITH FUNCTION DrawStringw(togfx, ; tcString, toFont AS xfcFont, toBrush AS xfcBrush, tnX, tnY ; , toFormat AS xfcStringFormat) *********** tcString, toFont AS xfcFont, toBrush AS xfcBrush, toPoint AS xfcPointf ; , toFormat AS xfcStringFormat *********** tcString, toFont AS xfcFont, toBrush AS xfcBrush, toRectangle AS xfcRectanglef ; , toFormat AS xfcStringFormat LOCAL lqlayoutRect LOCAL lnWidth, lnHeight, loPoint AS xfcPointf, loRect AS xfcRectanglef LOCAL lhFormat STORE 0 TO lnWidth, lnHeight STORE NULL TO loPoint, loRect m.lqlayoutRect = 0h00 ** handle overload parameters DO CASE CASE VARTYPE(tnX) = "N" CASE VARTYPE(tnX) = "O" AND INLIST(tnX.baseName,"Point","Pointf") m.loPoint = m.tnX m.toFormat = m.tnY m.loPoint.getextent(@tnX, @tnY) CASE VARTYPE(tnX) = "O" AND INLIST(tnX.baseName,"Rectangle","Rectanglef") m.loRect = m.tnX m.toFormat = m.tnY m.loRect.getextent(@tnX, @tnY, @lnWidth, @lnHeight) ENDCASE ** optional parameter ** the c++ classes show this parameter as null if not specified IF VARTYPE(m.toFormat) = "O" m.lhFormat = m.toFormat.handle ELSE m.lhFormat = 0 ENDIF m.lqlayoutRect = BINTOC(m.tnX,"F")+BINTOC(m.tnY,"F")+; BINTOC(m.lnWidth,"F")+BINTOC(m.lnHeight,"F") =xfcgdipDrawString(togfx.handle, m.tcString+0h00, LENC(tcString)/2, ; m.toFont.handle, @lqlayoutRect, m.lhFormat, m.toBrush.handle) ENDFUNC FUNCTION HexToUnicode(tcHex) LOCAL N, lcHex, lcUnicode lcUnicode = SPACE(0) FOR N = 1 TO GETWORDCOUNT(tchex, SPACE(1)) lcHex = EVALUATE("0x" + GETWORDNUM(tcHex, N, SPACE(1))) lcUnicode = lcUnicode + BINTOC(lcHex, "4RS") ENDFOR RETURN lcUnicode ENDFUNC