freetype-py
http://code.google.com/p/freetype-py/
pythonのfreetypeラッパ。ctypesで実装されているので別途freetypeのバイナリが必要となる。Windowsの場合、
http://gnuwin32.sourceforge.net/packages/freetype.htm
からバイナリを入手して、中の
bin/freetype6.dll
をPATHの通ったところにfreetype.dllという名前でコピーする。
examplesを動かすには
http://ja.fonts2u.com/download/bitstream-vera-sans.%E3%83%95%E3%82%A1%E3%83%9F%E3%83%AA%E3%83%BC
をダウンロードしてカレントディレクトリに展開する。
C:/Pytnon27/freetype.dllを使いたかったので・・・
freetype/__init__.pyに以下を追加した。
if not FT_Library_filename: try: __dll__ = ctypes.CDLL('libfreetype.so.6') except OSError: __dll__ = None # 追加 # if not FT_Library_filename: try: __dll__ = ctypes.CDLL('freetype') except OSError: __dll__ = None # 追加おわり #
ctypes.util.find_library('freetype')だとPATHの通ったところしか探してくれないらしい。
日本語フォントでテクスチャを作るメモ
examples/opengl.pyは、1枚のテクスチャにアスキー文字を全部出力してからUVを変えて1文字ずつ出力する例。
それを改造してunicodeを1文字ずつ出力するようにした。
# coding: utf-8 import numpy from freetype import * from OpenGL.GL import * from OpenGL.GLUT import * class MultibyteFont(object): def __init__(self, fontfile, size, text): assert(isinstance(text, unicode)) # Load font and check it is monotype face = Face(fontfile) face.set_char_size( size*64 ) # Determine largest glyph size width, height, ascender, descender = 0, 0, 0, 0 for c in text: face.load_char(c, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT ) bitmap = face.glyph.bitmap width = max( width, bitmap.width ) ascender = max( ascender, face.glyph.bitmap_top ) descender = max( descender, bitmap.rows-face.glyph.bitmap_top ) height = ascender+descender # size lines=1 cols=len(text)+1 self.texture_width=width*cols self.texture_height=height*lines # Generate texture data Z = numpy.zeros((self.texture_height, self.texture_width), dtype=numpy.ubyte) j=0 for i, c in enumerate(text): face.load_char(c, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT ) bitmap = face.glyph.bitmap x = i*width + face.glyph.bitmap_left y = j*height + ascender - face.glyph.bitmap_top print y, y+bitmap.rows, x, x+bitmap.width Z[y:y+bitmap.rows,x:x+bitmap.width].flat = bitmap.buffer print Z # Bound texture self.texid = glGenTextures(1) glBindTexture( GL_TEXTURE_2D, self.texid ) glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, Z.shape[1], Z.shape[0], 0, GL_ALPHA, GL_UNSIGNED_BYTE, Z ) def draw(self): glPushMatrix() glBindTexture(GL_TEXTURE_2D, self.texid) glColor(1,1,1,1) glEnable( GL_TEXTURE_2D ) glBegin( GL_QUADS ) glTexCoord2f( 0, -1 ), glVertex( 0, self.texture_height ) glTexCoord2f( 0, 0 ), glVertex( 0, 0 ) glTexCoord2f( 1, 0 ), glVertex( self.texture_width, 0 ) glTexCoord2f( 1, -1 ), glVertex( self.texture_width, self.texture_height ) glEnd( ) glPopMatrix() class Controller(object): def __init__(self): self.is_initialized=False def onResize(self, w, h): glViewport(0, 0, w, h) glMatrixMode( GL_PROJECTION ) glLoadIdentity( ) glOrtho( 0, w, 0, h, -1, 1 ) glMatrixMode( GL_MODELVIEW ) glLoadIdentity( ) def onLeftDown(self, x, y): print 'onLeftDown', x, y def onLeftUp(self, x, y): print 'onLeftUp', x, y def onMiddleDown(self, x, y): print 'onMiddleDown', x, y def onMiddleUp(self, x, y): print 'onMiddleUp', x, y def onRightDown(self, x, y): print 'onRightDown', x, y def onRightUp(self, x, y): print 'onRightUp', x, y def onMotion(self, x, y): print 'onMotion', x, y def onWheel(self, d): print 'onWheel', d def onKeyDown(self, keycode): print 'onKeyDown', keycode def onUpdate(self, d): print 'onUpdate', d def onInitialize(self): glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) glEnable( GL_DEPTH_TEST ) glEnable( GL_BLEND ) glEnable( GL_COLOR_MATERIAL ) glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) self.mb=MultibyteFont('C:/Windows/fonts/msgothic.ttc', 32, u'日本語フォント') self.is_initialized=True def draw(self): if not self.is_initialized: self.onInitialize() glClearColor(0.9, 0.5, 0.0, 0.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self.mb.draw() glFlush() if __name__=="__main__": controller=Controller() import glglue.glut glglue.glut.mainloop(controller, 400, 60, b"Freetype OpenGL")