FontPixelBuffer FontEngine_Freetype::get_font_glyph_subpixel(int glyph) { FontPixelBuffer font_buffer; FT_GlyphSlot slot = face->glyph; FT_UInt glyph_index; // Get glyph index glyph_index = FT_Get_Char_Index(face, glyph); FT_Error error; error = FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD ); if (error) return font_buffer; error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD); font_buffer.glyph = glyph; // Set Increment pen position font_buffer.increment.x = (slot->advance.x+32) >> 6; font_buffer.increment.y = (slot->advance.y+32) >> 6; if (error || slot->bitmap.rows == 0 || slot->bitmap.width == 0) return font_buffer; // Set destination offset font_buffer.offset.x = slot->bitmap_left; font_buffer.offset.y = -slot->bitmap_top; int src_width = slot->bitmap.width; int src_height = slot->bitmap.rows; int src_pitch = slot->bitmap.pitch; // Convert the bitmap PixelBuffer pixelbuffer(src_width/3, src_height, tf_rgba8); font_buffer.buffer = pixelbuffer; font_buffer.buffer_rect = pixelbuffer.get_size(); font_buffer.empty_buffer = false; unsigned char *src_data = slot->bitmap.buffer; unsigned char *pixel_data = (unsigned char *) font_buffer.buffer.get_data(); int dest_pitch = font_buffer.buffer.get_pitch(); // For 8bit bitmaps for (int ycnt = 0; ycnt < src_height; ycnt++) { unsigned char *dest_data = pixel_data; for (int xcnt = 0; xcnt < src_width/3; xcnt++) { *(dest_data++)= src_data[xcnt*3+2]; *(dest_data++)= src_data[xcnt*3+1]; *(dest_data++)= src_data[xcnt*3+0]; *(dest_data++)= 0; } pixel_data += dest_pitch; src_data += src_pitch; } return font_buffer; }
bool CL_OpenGLWindowProvider_GLX::on_clicked(XButtonEvent &event) { if (event.button != 1) // Left mouse button return true; int height = get_viewport().get_height(); glDrawBuffer(GL_BACK); glReadBuffer(GL_FRONT); CL_Rect rect = CL_Rect(event.x,event.y, CL_Size(1,1)); CL_PixelBuffer pixelbuffer(rect.get_width(), rect.get_height(), cl_rgba8); glReadPixels( rect.left, height - rect.bottom, rect.right - rect.left, rect.bottom - rect.top, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixelbuffer.get_data()); const cl_ubyte32 *xptr = (const cl_ubyte32 *) (pixelbuffer.get_data()); if (((*xptr) & 0xFF) < 10) { XLowerWindow(x11_window.get_display(), x11_window.get_window()); return false; } return true; }
FontPixelBuffer FontEngine_Win32::get_font_glyph_gray8(int glyph) { DataBuffer glyph_bitmap; GLYPHMETRICS glyph_metrics = { 0 }; MAT2 matrix = { 0 }; matrix.eM11.value = 1; matrix.eM22.value = 1; if (try_load_glyph_bitmap(glyph, GGO_GRAY8_BITMAP, matrix, glyph_bitmap, glyph_metrics)) { PixelBuffer pixelbuffer(glyph_metrics.gmBlackBoxX, glyph_metrics.gmBlackBoxY, tf_rgba8); DWORD s_pitch = (glyph_metrics.gmBlackBoxX + 3) / 4 * 4; unsigned char *s = (unsigned char *) glyph_bitmap.get_data(); DWORD d_width = glyph_metrics.gmBlackBoxX; Vec4ub *d = pixelbuffer.get_data<Vec4ub>(); for (DWORD py = 0; py < glyph_metrics.gmBlackBoxY; py++) { for (DWORD px = 0; px < glyph_metrics.gmBlackBoxX; px++) { DWORD gray = s[px + py*s_pitch]; d[px + py*d_width] = Vec4ub(255, 255, 255, (gray * 255 + 32) / 64); } } FontPixelBuffer font_buffer; font_buffer.glyph = glyph; font_buffer.buffer = pixelbuffer; font_buffer.buffer_rect = pixelbuffer.get_size(); font_buffer.offset.x = glyph_metrics.gmptGlyphOrigin.x; font_buffer.offset.y = -glyph_metrics.gmptGlyphOrigin.y; font_buffer.empty_buffer = false; font_buffer.metrics.advance.width = glyph_metrics.gmCellIncX; font_buffer.metrics.advance.height = glyph_metrics.gmCellIncY; font_buffer.metrics.bbox_offset.x = glyph_metrics.gmptGlyphOrigin.x; font_buffer.metrics.bbox_offset.y = -glyph_metrics.gmptGlyphOrigin.y; font_buffer.metrics.bbox_size.width = glyph_metrics.gmBlackBoxX; font_buffer.metrics.bbox_size.height = glyph_metrics.gmBlackBoxY; return font_buffer; } else { return get_empty_font_glyph(glyph); } }
FontPixelBuffer FontEngine_Freetype::get_font_glyph_standard(int glyph, bool anti_alias) { FontPixelBuffer font_buffer; FT_GlyphSlot slot = face->glyph; FT_UInt glyph_index; // Get glyph index glyph_index = FT_Get_Char_Index(face, glyph); FT_Error error; // Use FT_RENDER_MODE_NORMAL for 8bit anti-aliased bitmaps. Use FT_RENDER_MODE_MONO for 1-bit bitmaps if (anti_alias) { error = FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LIGHT ); if (error) return font_buffer; error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL); } else { error = FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_MONO); if (error) return font_buffer; error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_MONO); } font_buffer.glyph = glyph; // Set Increment pen position font_buffer.increment.x = (slot->advance.x+32) >> 6; font_buffer.increment.y = (slot->advance.y+32) >> 6; if (error || slot->bitmap.rows == 0 || slot->bitmap.width == 0) return font_buffer; // Set destination offset font_buffer.offset.x = slot->bitmap_left; font_buffer.offset.y = -slot->bitmap_top; int src_width = slot->bitmap.width; int src_height = slot->bitmap.rows; int src_pitch = slot->bitmap.pitch; PixelBuffer pixelbuffer(src_width, src_height, tf_rgba8); font_buffer.buffer = pixelbuffer; font_buffer.buffer_rect = pixelbuffer.get_size(); font_buffer.empty_buffer = false; unsigned char *src_data = slot->bitmap.buffer; unsigned char *pixel_data = (unsigned char *) font_buffer.buffer.get_data(); unsigned char *dest_data; int dest_pitch = font_buffer.buffer.get_pitch(); // Convert the bitmap if (anti_alias) { // For 8bit bitmaps for (int ycnt = 0; ycnt < src_height; ycnt++) { dest_data = pixel_data; for (int xcnt = 0; xcnt < src_width; xcnt++) { *(dest_data++)= 255; *(dest_data++)= 255; *(dest_data++)= 255; *(dest_data++)= src_data[xcnt]; } pixel_data += dest_pitch; src_data += src_pitch; } } else { int src_byte; unsigned char *src_work_ptr; // For 1bit bitmaps for (int ycnt = 0; ycnt < src_height; ycnt++) { dest_data = pixel_data; src_work_ptr = src_data; for (int xcnt = 0; xcnt < src_width; xcnt++) { *(dest_data++)= 255; *(dest_data++)= 255; *(dest_data++)= 255; if (!(xcnt&7)) { src_byte = *(src_work_ptr++); // Extract the pixel } if (src_byte & 0x80) // Bit set { *(dest_data++) = 255; } else { *(dest_data++) = 0; } src_byte = src_byte << 1; } pixel_data += dest_pitch; src_data += src_pitch; } } return font_buffer; }
void OpenGLWindowProvider::flip(int interval) { OpenGL::set_active(get_gc()); glFlush(); if (shadow_window) { int width = get_viewport().get_width(); int height = get_viewport().get_height(); if (using_gl3) { if (double_buffered) { glDrawBuffer(GL_BACK); glReadBuffer(GL_FRONT); } PixelBuffer pixelbuffer(width, height, tf_bgra8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); } else { GLint old_viewport[4], old_matrix_mode; GLfloat old_matrix_projection[16], old_matrix_modelview[16]; glGetIntegerv(GL_VIEWPORT, old_viewport); glGetIntegerv(GL_MATRIX_MODE, &old_matrix_mode); glGetFloatv(GL_PROJECTION_MATRIX, old_matrix_projection); glGetFloatv(GL_MODELVIEW_MATRIX, old_matrix_modelview); GLboolean blending = glIsEnabled(GL_BLEND); glDisable(GL_BLEND); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMultMatrixf(Mat4f::ortho_2d(0.0f, (float)width, 0.0f, (float)height, handed_right, clip_negative_positive_w)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (double_buffered) { glReadBuffer(GL_BACK); } glRasterPos2i(0, 0); glPixelZoom(1.0f, 1.0f); PixelBuffer pixelbuffer(width, height, tf_rgba8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); if (blending) glEnable(GL_BLEND); glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]); glMatrixMode(GL_PROJECTION); glLoadMatrixf(old_matrix_projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(old_matrix_modelview); glMatrixMode(old_matrix_mode); } } else { if (interval != -1 && interval != swap_interval) { swap_interval = interval; if (wglSwapIntervalEXT) wglSwapIntervalEXT(swap_interval); } BOOL retval = SwapBuffers(get_device_context()); if (dwm_layered) { int width = get_viewport().get_width(); int height = get_viewport().get_height(); glReadBuffer(GL_FRONT); PixelBuffer pixelbuffer(width, height, tf_r8); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, pixelbuffer.get_pitch() / pixelbuffer.get_bytes_per_pixel()); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadPixels( 0, 0, width, height, GL_ALPHA, GL_BYTE, // use GL_BITMAP here for even less transfer? pixelbuffer.get_data()); win32_window.update_layered(pixelbuffer); } } OpenGL::check_error(); }