예제 #1
0
파일: font.hpp 프로젝트: duzy/ds.ge
 view_t view()
 {
   FT_BitmapGlyph bmg = bitmap_glyph();
   return boost::gil::interleaved_view
     ( bmg->bitmap.width, bmg->bitmap.rows,
       (pixel_t*)bmg->bitmap.buffer,
       sizeof(pixel_t) * bmg->bitmap.width );
 }
예제 #2
0
void gep::Font::buildChar(void* pFace, wchar_t c, size_t num){
    FT_Face face = (FT_Face)pFace;
    // Load the glyph
    if(FT_Load_Glyph( face, FT_Get_Char_Index( face, c ), FT_LOAD_DEFAULT ) != 0)
    {
        std::ostringstream msg;
        msg << "Error loading character " << (uint32)c;
        throw Exception(msg.str());
    }

    FT_Glyph glyph;
    FT_Get_Glyph( face->glyph, &glyph);

    // Convert it to a bitmap
    FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, nullptr, 1 );
    FT_BitmapGlyph bitmap_glyph((FT_BitmapGlyph)glyph);
    FT_Bitmap* bitmap = &bitmap_glyph->bitmap;

    // Allocate the bitmap
    ImageData2D::image_data_t buffer;
    if(bitmap->width > 0 || bitmap->rows > 0) {
        buffer = GEP_NEW_ARRAY(g_stdAllocator, ImageData2D::mipmap_data_t, 1);
        buffer[0] = GEP_NEW_ARRAY(g_stdAllocator, ImageData2D::channel_data_t, bitmap->rows * bitmap->width);
        auto& mipmap = buffer[0];
        for(int i=0; i<bitmap->rows * bitmap->width; i++){
            mipmap[i] = bitmap->buffer[i];
        }
    }

    auto& g = m_glyphs[num];
    if(bitmap->width > 0 || bitmap->rows > 0) {
        g.m_data = GEP_NEW(g_stdAllocator, ImageData2D);
        g.m_data->setData(&g_stdAllocator, buffer, bitmap->width, bitmap->rows, ImageFormat::R8, ImageCompression::NONE);
    }
    else
    {
        g.m_data = nullptr;
    }
    g.m_width = bitmap->width;
    g.m_height = bitmap->rows;
    g.m_top = bitmap_glyph->top;
    g.m_left = bitmap_glyph->left;
    g.m_right = (face->glyph->advance.x >> 6) - bitmap_glyph->left - bitmap->width;
}
예제 #3
0
	void font_data::createGlyph(CharacterCode charCode) const
	{
		if (FT_Load_Glyph(_face, FT_Get_Char_Index(_face, charCode), FT_LOAD_DEFAULT))
		{
			LogError << "FT_Load_Glyph failed" << std::endl;
			throw std::runtime_error("FT_Load_Glyph failed");
		}

		FT_Glyph glyph;
		if (FT_Get_Glyph(_face->glyph, &glyph))
		{
			LogError << "FT_Get_Glyph failed" << std::endl;
			throw std::runtime_error("FT_Get_Glyph failed");
		}

		FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
		FT_BitmapGlyph bitmap_glyph(reinterpret_cast<FT_BitmapGlyph>(glyph));

		const FT_Bitmap& bitmap = bitmap_glyph->bitmap;

		const int width(next_p2(bitmap.width + 1));
		const int height(next_p2(bitmap.rows + 1));

		const size_t expanded_size(width * height * 2);
		GLubyte* expanded_data = new GLubyte[expanded_size];
		memset(expanded_data, 0, expanded_size);

		for (int j(0); j < height; ++j)
		{
			for (int i(0); i < width; ++i)
			{
				expanded_data[2 * (i + j * width)] = expanded_data[2 * (i + j * width) + 1] =
					(i >= bitmap.width || j >= bitmap.rows) ?
					0 : static_cast<GLubyte>(std::min(static_cast<float>(bitmap.buffer[i + bitmap.width * j]) * 1.5f, 255.0f));
			}
		}

		GlyphData glyphData;
		glyphData._width = _face->glyph->advance.x >> 6;

		glyphData._texture = new OpenGL::Texture();
		glyphData._texture->bind();

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);

		delete[] expanded_data;
		expanded_data = NULL;

		glyphData._callList = new OpenGL::CallList();
		glyphData._callList->startRecording();

		glyphData._texture->bind();

		const float xl((const float)bitmap_glyph->left);
		const float xh(xl + width);
		const float yl((const float)h - bitmap_glyph->top);
		const float yh(yl + height);

		glBegin(GL_TRIANGLE_STRIP);
		glTexCoord2f(0.0f, 0.0f);
		glVertex2f(xl, yl);
		glTexCoord2f(0.0f, 1.0f);
		glVertex2f(xl, yh);
		glTexCoord2f(1.0f, 0.0f);
		glVertex2f(xh, yl);
		glTexCoord2f(1.0f, 1.0f);
		glVertex2f(xh, yh);
		glEnd();

		glTranslatef(static_cast<float>(glyphData._width), 0.0f, 0.0f);

		glyphData._callList->endRecording();

		_cachedGlyphs[charCode] = glyphData;
	}