%PDF- %PDF-
| Direktori : /usr/share/doc/python3-freetype/examples/ |
| Current File : //usr/share/doc/python3-freetype/examples/subpixel-positioning.py |
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
#
# FreeType high-level python API - Copyright 2011-2015 Nicolas P. Rougier
# Distributed under the terms of the new BSD license.
#
# -----------------------------------------------------------------------------
'''
Subpixel rendering AND positioning using OpenGL and shaders.
'''
import numpy as np
import OpenGL.GL as gl
import OpenGL.GLUT as glut
from texture_font import TextureFont, TextureAtlas
from shader import Shader
vert='''
uniform sampler2D texture;
uniform vec2 pixel;
attribute float modulo;
varying float m;
void main() {
gl_FrontColor = gl_Color;
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
m = modulo;
}
'''
frag='''
uniform sampler2D texture;
uniform vec2 pixel;
varying float m;
void main() {
float gamma = 1.0;
vec2 uv = gl_TexCoord[0].xy;
vec4 current = texture2D(texture, uv);
vec4 previous= texture2D(texture, uv+vec2(-1,0)*pixel);
current = pow(current, vec4(1.0/gamma));
previous = pow(previous, vec4(1.0/gamma));
float r = current.r;
float g = current.g;
float b = current.b;
float a = current.a;
if( m <= 0.333 )
{
float z = m/0.333;
r = mix(current.r, previous.b, z);
g = mix(current.g, current.r, z);
b = mix(current.b, current.g, z);
}
else if( m <= 0.666 )
{
float z = (m-0.33)/0.333;
r = mix(previous.b, previous.g, z);
g = mix(current.r, previous.b, z);
b = mix(current.g, current.r, z);
}
else if( m < 1.0 )
{
float z = (m-0.66)/0.334;
r = mix(previous.g, previous.r, z);
g = mix(previous.b, previous.g, z);
b = mix(current.r, previous.b, z);
}
float t = max(max(r,g),b);
vec4 color = vec4(0.,0.,0., (r+g+b)/2.);
color = t*color + (1.-t)*vec4(r,g,b, min(min(r,g),b));
gl_FragColor = vec4( color.rgb, color.a);
}
'''
class Label:
def __init__(self, text, font, color=(1.0, 1.0, 1.0, 0.0), x=0, y=0,
width=None, height=None, anchor_x='left', anchor_y='baseline'):
self.text = text
self.vertices = np.zeros((len(text)*4,3), dtype=np.float32)
self.indices = np.zeros((len(text)*6, ), dtype=np.uint)
self.colors = np.zeros((len(text)*4,4), dtype=np.float32)
self.texcoords= np.zeros((len(text)*4,2), dtype=np.float32)
self.attrib = np.zeros((len(text)*4,1), dtype=np.float32)
pen = [x,y]
prev = None
for i,charcode in enumerate(text):
glyph = font[charcode]
kerning = glyph.get_kerning(prev)
x0 = pen[0] + glyph.offset[0] + kerning
dx = x0-int(x0)
x0 = int(x0)
y0 = pen[1] + glyph.offset[1]
x1 = x0 + glyph.size[0]
y1 = y0 - glyph.size[1]
u0 = glyph.texcoords[0]
v0 = glyph.texcoords[1]
u1 = glyph.texcoords[2]
v1 = glyph.texcoords[3]
index = i*4
indices = [index, index+1, index+2, index, index+2, index+3]
vertices = [[x0,y0,1],[x0,y1,1],[x1,y1,1], [x1,y0,1]]
texcoords = [[u0,v0],[u0,v1],[u1,v1], [u1,v0]]
colors = [color,]*4
self.vertices[i*4:i*4+4] = vertices
self.indices[i*6:i*6+6] = indices
self.texcoords[i*4:i*4+4] = texcoords
self.colors[i*4:i*4+4] = colors
self.attrib[i*4:i*4+4] = dx
pen[0] = pen[0]+glyph.advance[0]/64.0 + kerning
pen[1] = pen[1]+glyph.advance[1]/64.0
prev = charcode
width = pen[0]-glyph.advance[0]/64.0+glyph.size[0]
if anchor_y == 'top':
dy = -round(font.ascender)
elif anchor_y == 'center':
dy = +round(-font.height/2-font.descender)
elif anchor_y == 'bottom':
dy = -round(font.descender)
else:
dy = 0
if anchor_x == 'right':
dx = -width/1.0
elif anchor_x == 'center':
dx = -width/2.0
else:
dx = 0
self.vertices += (round(dx), round(dy), 0)
def draw(self):
gl.glEnable( gl.GL_TEXTURE_2D )
gl.glDisable( gl.GL_DEPTH_TEST )
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertices)
gl.glColorPointer(4, gl.GL_FLOAT, 0, self.colors)
gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, self.texcoords)
r,g,b = 0,0,0
gl.glColor( 1, 1, 1, 1 )
gl.glEnable( gl.GL_BLEND )
#gl.glBlendFunc( gl.GL_CONSTANT_COLOR_EXT, gl.GL_ONE_MINUS_SRC_COLOR )
#gl.glBlendColor(r,g,b,1)
gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )
gl.glBlendColor( 1, 1, 1, 1 )
gl.glEnableVertexAttribArray( 1 );
gl.glVertexAttribPointer( 1, 1, gl.GL_FLOAT, gl.GL_FALSE, 0, self.attrib)
shader.bind()
shader.uniformi('texture', 0)
shader.uniformf('pixel', 1.0/512, 1.0/512)
gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices),
gl.GL_UNSIGNED_INT, self.indices)
shader.unbind()
gl.glDisableVertexAttribArray( 1 );
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
gl.glDisable( gl.GL_TEXTURE_2D )
gl.glDisable( gl.GL_BLEND )
if __name__ == '__main__':
import sys
atlas = TextureAtlas(512,512,3)
def on_display( ):
#gl.glClearColor(0,0,0,1)
gl.glClearColor(1,1,1,1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glBindTexture( gl.GL_TEXTURE_2D, atlas.texid )
for label in labels:
label.draw()
gl.glColor(0,0,0,1)
gl.glBegin(gl.GL_LINES)
gl.glVertex2i(15,0)
gl.glVertex2i(15, 330)
gl.glVertex2i(225, 0)
gl.glVertex2i(225, 330)
gl.glEnd()
glut.glutSwapBuffers( )
def on_reshape( width, height ):
gl.glViewport( 0, 0, width, height )
gl.glMatrixMode( gl.GL_PROJECTION )
gl.glLoadIdentity( )
gl.glOrtho( 0, width, 0, height, -1, 1 )
gl.glMatrixMode( gl.GL_MODELVIEW )
gl.glLoadIdentity( )
def on_keyboard( key, x, y ):
if key == '\033':
sys.exit( )
glut.glutInit( sys.argv )
glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH )
glut.glutCreateWindow( "Freetype OpenGL" )
glut.glutReshapeWindow( 240, 330 )
glut.glutDisplayFunc( on_display )
glut.glutReshapeFunc( on_reshape )
glut.glutKeyboardFunc( on_keyboard )
font = TextureFont(atlas, './Vera.ttf', 9)
text = "|... A Quick Brown Fox Jumps Over The Lazy Dog"
labels = []
x,y = 20,310
for i in range(30):
labels.append(Label(text=text, font=font, x=x, y=y))
x += 0.1000000000001
y -= 10
atlas.upload()
shader = Shader(vert,frag)
glut.glutMainLoop( )