Skip to content
Snippets Groups Projects
Commit fbf176b0 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

optionaly use CAIRO to get nice font on linux (no texture cache => quite

slow, disabled by default)
parent a8446cbe
No related branches found
No related tags found
No related merge requests found
...@@ -38,6 +38,7 @@ option(ENABLE_BUILD_ANDROID "Build Gmsh library for Android NDK" OFF) ...@@ -38,6 +38,7 @@ option(ENABLE_BUILD_ANDROID "Build Gmsh library for Android NDK" OFF)
option(ENABLE_BUILD_IOS "Build Gmsh library for iOS (ARM)" OFF) option(ENABLE_BUILD_IOS "Build Gmsh library for iOS (ARM)" OFF)
option(ENABLE_BUILD_IOS_EMULATOR "Build Gmsh library for iOS emulator (x86)" OFF) option(ENABLE_BUILD_IOS_EMULATOR "Build Gmsh library for iOS emulator (x86)" OFF)
option(ENABLE_CGNS "Enable CGNS mesh export" OFF) option(ENABLE_CGNS "Enable CGNS mesh export" OFF)
option(ENABLE_CAIRO "Enable cairo to render fonts" OFF)
option(ENABLE_CHACO "Enable Chaco mesh partitioner" ${DEFAULT}) option(ENABLE_CHACO "Enable Chaco mesh partitioner" ${DEFAULT})
option(ENABLE_DINTEGRATION "Enable discrete integration and levelsets" ${DEFAULT}) option(ENABLE_DINTEGRATION "Enable discrete integration and levelsets" ${DEFAULT})
option(ENABLE_FLTK "Build FLTK GUI" ${DEFAULT}) option(ENABLE_FLTK "Build FLTK GUI" ${DEFAULT})
...@@ -567,6 +568,16 @@ if(ENABLE_BFGS) ...@@ -567,6 +568,16 @@ if(ENABLE_BFGS)
set_config_option(HAVE_BFGS "Bfgs") set_config_option(HAVE_BFGS "Bfgs")
endif(ENABLE_BFGS) endif(ENABLE_BFGS)
if(ENABLE_CAIRO)
find_library(CAIRO_LIB cairo)
find_path(CAIRO_INC "cairo/cairo.h" PATH_SUFFIXES include)
if(CAIRO_INC AND CAIRO_LIB)
set_config_option(HAVE_CAIRO "cairo")
list(APPEND EXTERNAL_LIBRARIES ${CAIRO_LIB})
list(APPEND EXTERNAL_INCLUDES ${CAIRO_INC})
endif(CAIRO_LIB AND CAIRO_INC)
endif(ENABLE_CAIRO)
if(ENABLE_DINTEGRATION) if(ENABLE_DINTEGRATION)
add_subdirectory(contrib/DiscreteIntegration) add_subdirectory(contrib/DiscreteIntegration)
include_directories(contrib/DiscreteIntegration) include_directories(contrib/DiscreteIntegration)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#cmakedefine HAVE_BFGS #cmakedefine HAVE_BFGS
#cmakedefine HAVE_BLAS #cmakedefine HAVE_BLAS
#cmakedefine HAVE_BLOSSOM #cmakedefine HAVE_BLOSSOM
#cmakedefine HAVE_CAIRO
#cmakedefine HAVE_CHACO #cmakedefine HAVE_CHACO
#cmakedefine HAVE_DLOPEN #cmakedefine HAVE_DLOPEN
#cmakedefine HAVE_DINTEGRATION #cmakedefine HAVE_DINTEGRATION
......
...@@ -9,6 +9,7 @@ set(SRC ...@@ -9,6 +9,7 @@ set(SRC
openglWindow.cpp openglWindow.cpp
optionWindow.cpp optionWindow.cpp
colorbarWindow.cpp colorbarWindow.cpp
drawContextFltkCairo.cpp
gamepadWindow.cpp gamepadWindow.cpp
fieldWindow.cpp fieldWindow.cpp
pluginWindow.cpp pluginWindow.cpp
......
...@@ -18,6 +18,7 @@ typedef unsigned long intptr_t; ...@@ -18,6 +18,7 @@ typedef unsigned long intptr_t;
#include <FL/fl_draw.H> #include <FL/fl_draw.H>
#include "FlGui.h" #include "FlGui.h"
#include "drawContextFltk.h" #include "drawContextFltk.h"
#include "drawContextFltkCairo.h"
#include "graphicWindow.h" #include "graphicWindow.h"
#include "optionWindow.h" #include "optionWindow.h"
#include "fieldWindow.h" #include "fieldWindow.h"
...@@ -239,7 +240,11 @@ FlGui::FlGui(int argc, char **argv) ...@@ -239,7 +240,11 @@ FlGui::FlGui(int argc, char **argv)
Fl::add_handler(globalShortcut); Fl::add_handler(globalShortcut);
// set global fltk-dependent drawing functions // set global fltk-dependent drawing functions
#if defined(HAVE_CAIRO)
drawContext::setGlobal(new drawContextFltkCairo);
#else
drawContext::setGlobal(new drawContextFltk); drawContext::setGlobal(new drawContextFltk);
#endif
// set default font size // set default font size
FL_NORMAL_SIZE = drawContext::global()->getFontSize(); FL_NORMAL_SIZE = drawContext::global()->getFontSize();
......
#include "drawContextFltkCairo.h"
#if defined(HAVE_CAIRO)
#include <cairo/cairo.h>
#include "GL/gl.h"
//mostly borrowed from fltk function gl_texture_fifo::display_texture
static void _data2gl (int width, int height, unsigned char *data, int Lx, int Ly, unsigned int _textureId) {
//setup matrices
GLint matrixMode;
glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
glMatrixMode (GL_PROJECTION);
glPushMatrix();
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glLoadIdentity ();
float winw = Fl_Window::current()->w();
float winh = Fl_Window::current()->h();
glScalef (2.0f / winw, 2.0f / winh, 1.0f);
glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f);
//write the texture on screen
GLfloat pos[4];
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, _textureId);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SRC0_ALPHA);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTranslatef(pos[0] /*+ rect->x_bearing*/, pos[1] /*+ rect->y_bearing*/, pos[2]);
glBegin (GL_QUADS);
glTexCoord2f (0, 0);
glVertex2f (0.0f, Ly);
glTexCoord2f (Lx, 0);
glVertex2f (Lx, Ly);
glTexCoord2f (Lx, Ly);
glVertex2f (Lx, 0.0f);
glTexCoord2f (0, Ly);
glVertex2f (0.0f, 0.0f);
glEnd ();
glPopAttrib();
// reset original matrices
glPopMatrix(); // GL_MODELVIEW
glMatrixMode (GL_PROJECTION);
glPopMatrix();
glMatrixMode (matrixMode);
}
double drawContextFltkCairo::getStringWidth(const char *str) {
cairo_text_extents_t e;
cairo_text_extents(_cr, str, &e);
return e.width;
}
void drawContextFltkCairo::draw()
{
drawContextFltk::draw();
}
//ensure the surface is large enough
void drawContextFltkCairo::_resizeSurface(int w, int h)
{
if (w > cairo_image_surface_get_width(_surface) || h > cairo_image_surface_get_height(_surface)) {
cairo_font_face_t *face = cairo_get_font_face(_cr);
cairo_matrix_t matrix;
cairo_get_font_matrix(_cr, &matrix);
cairo_destroy(_cr);
cairo_surface_destroy(_surface);
_surface = cairo_image_surface_create(CAIRO_FORMAT_A8, w, h);
_cr = cairo_create(_surface);
cairo_set_font_face(_cr, face);
cairo_set_font_matrix(_cr, &matrix);
}
}
void drawContextFltkCairo::drawString(const char *str)
{
cairo_text_extents_t extent;
cairo_text_extents(_cr, str, &extent);
_resizeSurface(extent.width + 2, extent.height + 2);
cairo_surface_t *surface = _surface;
cairo_t *cr = _cr;
cairo_set_source_rgba (cr, 0., 0., 0., 0);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
extent.width +=1;
extent.height +=1;
cairo_move_to(cr, 1-extent.x_bearing, 1-extent.y_bearing);
cairo_set_source_rgba(cr, 1, 1, 1, 1);
cairo_show_text(cr, str);
_data2gl(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface), cairo_image_surface_get_data(surface), extent.width + 1, extent.height + 1, _textureId);
// fltk version (fl_read_image is too slow)
/*Fl_Offscreen offscreen = fl_create_offscreen(100, 100);
fl_begin_offscreen(offscreen);
fl_color(0, 0, 0);
fl_rectf(0, 0, 100, 100);
fl_color(255, 255, 255);
fl_draw(str, 10, 90);
fl_read_image(data, 0, 0, 100, 100);
CGContextRef src = (CGContextRef)fl_gc; // get bitmap context
uchar *base = (uchar *)CGBitmapContextGetData(src); // get data
for (int i = 0; i < 100 * 100; ++i) {
data[i] = data[i * 3];
}
fl_end_offscreen();
fl_delete_offscreen(offscreen);
*/
}
drawContextFltkCairo::~drawContextFltkCairo()
{
cairo_destroy(_cr);
cairo_surface_destroy(_surface);
glDeleteTextures(1, &_textureId);
}
drawContextFltkCairo::drawContextFltkCairo()
{
_surface = cairo_image_surface_create(CAIRO_FORMAT_A8, 100, 100);
_cr = cairo_create(_surface);
glGenTextures (1, &_textureId);
_currentFontId = -1;
}
void drawContextFltkCairo::setFont(int fontid, int fontsize) {
if (_currentFontId != fontid) {
switch (fontid) {
case FL_HELVETICA :
case FL_HELVETICA_BOLD :
case FL_HELVETICA_BOLD_ITALIC :
case FL_HELVETICA_ITALIC :
cairo_select_font_face(_cr, "sans",
fontid & FL_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
fontid & FL_BOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
break;
case FL_COURIER :
case FL_COURIER_BOLD :
case FL_COURIER_BOLD_ITALIC :
case FL_COURIER_ITALIC :
cairo_select_font_face(_cr, "courier",
fontid & FL_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
fontid & FL_BOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
break;
case FL_TIMES :
case FL_TIMES_BOLD :
case FL_TIMES_BOLD_ITALIC :
case FL_TIMES_ITALIC :
cairo_select_font_face(_cr, "serif",
fontid & FL_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
fontid & FL_BOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
break;
default :
cairo_select_font_face(_cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
}
_currentFontId = fontid;
}
cairo_set_font_size(_cr, fontsize);
}
#endif
#ifndef _DRAW_CONTEXT_FLTK_CAIRO_H_
#define _DRAW_CONTEXT_FLTK_CAIRO_H_
#include "GmshConfig.h"
#if defined(HAVE_CAIRO)
#include "drawContextFltk.h"
typedef struct _cairo_surface cairo_surface_t;
typedef struct _cairo cairo_t;
class drawContextFltkCairo : public drawContextFltk {
cairo_surface_t *_surface;
cairo_t *_cr;
unsigned int _textureId;
int _currentFontId;
int _currentFontSize;
void _resizeSurface(int w, int h);
public:
void draw();
drawContextFltkCairo();
~drawContextFltkCairo();
double getStringWidth(const char *str);
//int getStringHeight();
//int getStringDescent();
void drawString(const char *str);
void setFont(int fontid, int fontsize);
};
#endif
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment