开发者

Unable to draw Unicode characters with Python's PyCDC.DrawText()

开发者 https://www.devze.com 2023-03-31 02:10 出处:网络
I\'m trying to draw Unicode characters using PyCDC.DrawText(), but it seems to draw two ASCII characters instead. For example, when trying to draw \'Я\' (\\u042F), I get: http://i.stack.imgur.com/hh9

I'm trying to draw Unicode characters using PyCDC.DrawText(), but it seems to draw two ASCII characters instead. For example, when trying to draw 'Я' (\u042F), I get: http://i.stack.imgur.com/hh9RJ.png

My string is defined as a Unicode string:

text = u'Я'
开发者_如何学JAVA

And the file starts with:

# -*- coding:utf-8 -*-

I also tried printing the string (to the console) and it comes out fine, so the problem is probably lying within the implementation of DrawText().

Thanks!


To output Unicode text on Windows you need to encode it in UTF-16 and call the wide character version of the DrawText() or TextOut() Win32 functions. In case you aren't familiar, the Windows API is natively UTF-16 and has parallel 8 bit ANSI versions for legacy support.

I know nothing of the Win32 wrapper you are using but rather suspect that PyCDC.DrawText() is calling the ANSI version of whichever one of these Win32 functions is doing the work. Your solution will likely involve finding a way to invoke DrawTextW() or TextOutW(). You could do it with ctypes, and these functions must surely be available through PyWin32 also.

However, I would probably opt for something higher level, like PyQt.


David: 'these functions must surely be available through PyWin32 ' actually, they are not.

After dozens of hours of searching, trying to figure out where within win32ui, win32gui, etc. there might be a hidden TextOutW, writing my own C extension that had other flaws so couldn't use it, writing an external prog. called from within python only to find out that HDC handles cannot be transfered to other processes, I have finally stumbled upon this single-line elegant pre-programmed solution, based on ctypes as suggested above:

  1. you need the TextOutW or similar function as you were used to from windows gdi c. Although there is a function called win32gdi.DrawTextW which works exactly like the windows counterpart, yet sometimes you need to specifically use e.g. TextOut, ExtTextOut etc., which are not available in the unicode W-suffixed versions in pywin32's win32gdi
  2. to achieve this, instead of using the limited win32gui functions, use windll.gdi32.TextOutW available from ctypes:

    from ctypes import *
    import win32gdi
    
    # init HDC
    # set hdc to something like 
    hdc = win32gdi.CreateDC(print_processor, printername, devmode)
    
    # here comes the ctypes function that does your deal
    text = u'Working! \u4e00\u4e01'
    windll.gdi32.TextOutW(hdc, x, y, text, len(text))
    
    # ... continue your prog ...
    

Have fun with this

0

精彩评论

暂无评论...
验证码 换一张
取 消