Beispiel #1
0
	def __init__(self, filename, size,
					charset='abcdefghijklmnopqrstuvwxyz' +\
							'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +\
							'1234567890;:,.!?%&"\' '):
		#filename = os.path.join('fonts', filename)
		self.filename = filename
		self.charset = charset
		self.charmap = {}
        
		font = pygame.font.Font(filename, size)
		self.descent = font.get_descent()
		self.w, self.h = font.size(self.charset)
		self.w += len(self.charset) * self.characterSpacing
		self.lineSize = self.h
		if self.w > self.maxTextureWidth:
			self.h = (self.w / self.maxTextureWidth + 1) * self.h
			self.w = self.maxTextureWidth
		self.tw, self.th = resource.pow2(self.w), resource.pow2(self.h)
		data = chr(0) * self.tw * self.th * 4
		surface = pygame.image.fromstring(data, (self.tw, self.th), 'RGBA')
		
		x, y = 0.0, 0.0
		for c in charset:
			render = font.render(c, True, (255, 255, 255))
			render = pygame.transform.flip(render,False,True)		# hack somehow my shit was upside down
		
			cw, ch = font.size(c)
			if x + cw >= self.tw:
				x = 0.0
				y += self.lineSize
			surface.blit(render, (x, y))
			
			self.charmap[c] = (x/self.tw, (self.th-y-self.lineSize)/self.th, 
								(x+cw)/self.tw, (self.th-y)/self.th), cw
			x += cw + self.characterSpacing
			
			
		self.tex = glGenTextures(1)
		glBindTexture(GL_TEXTURE_2D, self.tex)
		glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
		glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		glTexImage2D(GL_TEXTURE_2D, 0, 4, self.tw, self.th,
					0, GL_RGBA, GL_UNSIGNED_BYTE, 
					pygame.image.tostring(surface, 'RGBA', True))
Beispiel #2
0
    def __init__(self, filename, size,
                 charset='abcdefghijklmnopqrstuvwxyz' +\
                         'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +\
                         '1234567890;:,.!?%&"\' '):
        filename = os.path.join('fonts', filename)
        self.filename = filename
        self.charset = charset
        self.charmap = {}
        
        font = pygame.font.Font(filename, size)
        self.descent = font.get_descent()
        self.w, self.h = font.size(self.charset)
        self.w += len(self.charset) * self.characterSpacing
        self.lineSize = self.h
        if self.w > self.maxTextureWidth:
            self.h = (self.w / self.maxTextureWidth + 1) * self.h
            self.w = self.maxTextureWidth
        self.tw, self.th = res.pow2(self.w), res.pow2(self.h)
        data = chr(0) * self.tw * self.th * 4
        surface = pygame.image.fromstring(data, (self.tw, self.th), 'RGBA')

        x, y = 0.0, 0.0
        for c in charset:
            render = font.render(c, True, (255, 255, 255))
            cw, ch = font.size(c)
            if x + cw >= self.tw:
                x = 0.0
                y += self.lineSize
            surface.blit(render, (x, y))
            self.charmap[c] = (x/self.tw, (self.th-y-self.lineSize)/self.th, 
                               (x+cw)/self.tw, (self.th-y)/self.th), cw
            x += cw + self.characterSpacing
        self.tex = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.tex)
        glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, 4, self.tw, self.th,
                     0, GL_RGBA, GL_UNSIGNED_BYTE, 
                     pygame.image.tostring(surface, 'RGBA', True))
Beispiel #3
0
    def _layout(self):
        """Generate indices, uvs and verts for the text."""
        font = self.font_atlas.font

        descent = font.get_descent()
        n_chars = len(self._str) - self._str.count('\n')
        verts = np.ones((4 * n_chars, 3), dtype='f4')
        uvs = np.zeros((4 * n_chars, 2), dtype='f4')
        indices = np.zeros(n_chars * 6, dtype='u4')

        lines = self._str.split('\n')

        # We lay out based on 48px tex so line size is scaled later
        line_height = 48 * 1.3

        curchar = 0
        tex_ids = set()
        tex = None

        for lineno, line in enumerate(lines):
            if not line:
                continue
            # (min_x, max_x, min_y, max_y, horizontal_advance_x)
            metrics = np.array(font.metrics(line), dtype='f4')
            cx = np.cumsum(metrics[:, 4])
            xpos = metrics[:, 0:2] + cx[::, np.newaxis]

            layout_width = cx[-1] #+ metrics[-1, 4]
            align_offset = ALIGNMENTS[self._align] * layout_width
            yoff = lineno * line_height
            for idx, char in enumerate(line):
                texregion = self.font_atlas.get(char)
                # TODO: this could break if tex is reallocated (eg. because it
                # grows)
                tex = texregion.tex.tex
                glyph_uvs = texregion.texcoords
                glyph_verts = texregion.get_verts(texregion.width, texregion.height)
                tex_ids.add(tex.glo)

                # The kerning seems pretty bad on Pygame fonts...
    #            glyph_width = glyph_verts[1, 0] - glyph_verts[0, 0]
    #            metrics_width = xpos[idx, 1] - xpos[idx, 0]
    #            print(repr(char), glyph_width, metrics_width, metrics[idx, 4])

                x = xpos[idx, 0]

                quadnum = idx + curchar
                start = quadnum * 4
                glyph_slice = slice(start, start + 4)
                verts[glyph_slice] = glyph_verts + (x - align_offset, yoff - descent, 0)
                uvs[glyph_slice] = glyph_uvs
                indices[6 * quadnum:6 * quadnum + 6] = QUAD + 4 * quadnum

            curchar += len(line)

        # Scale coordinates
        resize = np.identity(3, dtype='f4')
        scale = self.fontsize / 48
        resize[0, 0] = scale
        resize[1, 1] = scale

        # TODO: handle use of multiple textures. We will be able to handle
        # this eventually by selecting texture unit within the shader, or by
        # making multiple draw calls
        assert len(tex_ids) < 2, "Label got allocated over multiple textures"
        self.tex = tex
        self._verts = verts @ resize
        self._uvs = uvs
        self._indices = indices

        # TODO: update self.lst, set dirty OR reallocate self.lst for new size
        if self.tex is None:
            if self.lst:
                self.lst.free()
                self.lst = None
                self.vao = None
        elif self.lst:
            self.lst.realloc(len(self._verts), len(indices))
            self.lst.indexbuf[:] = indices
            self.lst.indexbuf += self.lst.vertoff.start
            self.lst.vertbuf['in_uv'] = uvs
            self._update()
        elif self.tex and not self.vao:
            self._migrate(self.layer._text_vao(self.font_atlas))