📄 gseisviewaxisz.c
字号:
/* * GTKSEISVIEWGL - Library for rendering of 2D seismic data * * Copyright (C) 2006 Vladimir Bashkardin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more av. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Vladimir Bashkardin <vovizmus@users.sourceforge.net> */#include <math.h>#include <GL/gl.h>#include <gtk/gtkgl.h>#include "gseisviewaxisz.h"#include "gtkseisviewgl.h"G_DEFINE_TYPE (GSeisViewAxisZ, g_seis_view_axis_z, G_SEIS_TYPE_VIEW_AXIS)#define G_SEIS_VIEW_AXIS_Z_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_SEIS_TYPE_VIEW_AXIS_Z, GSeisViewAxisZPrivate))typedef struct _GSeisViewAxisZPrivate GSeisViewAxisZPrivate;struct _GSeisViewAxisZPrivate { GSeisViewAxisZFormat format; PangoFontDescription *font_desc; gchar *font_name; guint text_width_screen; guint text_height_screen; GSeisColor fg_color; GSeisColor bg_color; GLuint font_list_base; GLuint font_list_start; GLuint font_list_end; gchar gformat[G_ASCII_DTOSTR_BUF_SIZE]; gint16 label_max_strlen; guint8 precision; gdouble min_value; gdouble max_value; gdouble values_step; guint32 values_num; GLuint display_list_base; gboolean redisplay; gboolean rebuild_font; gboolean is_threaded; GMutex *rendering_mutex;};static void g_seis_view_axis_z_delete_render_list (GSeisViewAxisZ *self, GtkWidget *seis_view_gl, gboolean context_started) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (self); GdkGLContext *gl_context; GdkGLDrawable *gl_drawable; if (private->display_list_base != 0) { if (FALSE == context_started) { if (GTK_WIDGET_REALIZED (seis_view_gl)) { if (private->is_threaded) gdk_threads_enter (); gl_context = gtk_widget_get_gl_context (seis_view_gl); gl_drawable = gtk_widget_get_gl_drawable (seis_view_gl); if (gdk_gl_drawable_gl_begin (gl_drawable, gl_context)) { glDeleteLists (private->display_list_base, 1); gdk_gl_drawable_gl_end (gl_drawable); } if (private->is_threaded) gdk_threads_leave (); } } else glDeleteLists (private->display_list_base, 1); private->display_list_base = 0; private->redisplay = TRUE; }}static void g_seis_view_axis_z_delete_font_list (GSeisViewAxisZ *self, GtkWidget *seis_view_gl, gboolean context_started) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (self); GdkGLContext *gl_context; GdkGLDrawable *gl_drawable; if (private->font_list_base != 0) { if (FALSE == context_started) { if (GTK_WIDGET_REALIZED (seis_view_gl)) { if (private->is_threaded) gdk_threads_enter (); gl_context = gtk_widget_get_gl_context (seis_view_gl); gl_drawable = gtk_widget_get_gl_drawable (seis_view_gl); if (gdk_gl_drawable_gl_begin (gl_drawable, gl_context)) { glDeleteLists (private->font_list_base, private->font_list_end + 1); gdk_gl_drawable_gl_end (gl_drawable); } if (private->is_threaded) gdk_threads_leave (); } } else glDeleteLists (private->font_list_base, private->font_list_end + 1); private->font_list_base = 0; private->rebuild_font = TRUE; }}static void g_seis_view_axis_z_create_font_list (GSeisViewAxisZ *self, GtkWidget *seis_view_gl) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (self); private->font_list_base = glGenLists (private->font_list_end + 1); gdk_gl_font_use_pango_font (private->font_desc, private->font_list_start, private->font_list_end, private->font_list_base + private->font_list_start); private->rebuild_font = FALSE; private->redisplay = TRUE;}static void g_seis_view_axis_z_attach_notify (GSeisViewAxis *self, GtkWidget *seis_view_gl, GSeisViewDataVisibility *data_visibility) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (G_SEIS_VIEW_AXIS_Z (self)); private->rebuild_font = TRUE; private->redisplay = TRUE; private->is_threaded = gtk_seis_view_gl_is_threaded (GTK_SEIS_VIEW_GL (seis_view_gl)); if (private->is_threaded && NULL == private->rendering_mutex) private->rendering_mutex = g_mutex_new ();}static void g_seis_view_axis_z_detach_notify (GSeisViewAxis *self, GtkWidget *seis_view_gl, GSeisViewDataVisibility *data_visibility) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (G_SEIS_VIEW_AXIS_Z (self)); private->is_threaded = gtk_seis_view_gl_is_threaded (GTK_SEIS_VIEW_GL (seis_view_gl)); g_seis_view_axis_z_delete_render_list (G_SEIS_VIEW_AXIS_Z (self), seis_view_gl, FALSE); g_seis_view_axis_z_delete_font_list (G_SEIS_VIEW_AXIS_Z (self), seis_view_gl, FALSE);}static void g_seis_view_axis_z_data_viewport_change (GSeisViewAxis *self, GtkWidget *seis_view_gl, GSeisViewDataVisibility *data_visibility) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (G_SEIS_VIEW_AXIS_Z (self)); private->redisplay = TRUE;}static void g_seis_view_axis_z_redraw_event (GSeisViewAxis *self, GtkWidget *seis_view_gl, GSeisViewDataVisibility *data_visibility) { GSeisViewAxisZPrivate *private = G_SEIS_VIEW_AXIS_Z_GET_PRIVATE (G_SEIS_VIEW_AXIS_Z (self)); gdouble slow_pixel_to_object_scale; gdouble fast_pixel_to_object_scale; gchar gbuffer[G_ASCII_DTOSTR_BUF_SIZE]; gdouble text_width_object, text_height_object; /* Label dimensions in the object space */ gdouble first_value, last_value; /* Visible values of the data */ gdouble start_label, end_label, labels_step; /* Visible labels parameters */ gdouble start_label_object, labels_step_object; /* Labels parameters in the object space */ gdouble slow_start_object; /* Actual starting position of the axis - depends on the type */ gdouble fast_start_data, fast_size_data; /* Actual starting position of the data */ gdouble tick_size_object, margin_object; guint32 labels_num, i; gint16 power_of_ten, label_strlen; gdouble ten_powered, ten_factor; gdouble labels_residue; guint8 labels_precision; gdouble value_to_object_scale; /* No bottom or top positions */ if (self->type < G_SEIS_VIEW_AXIS_LEFT) return; if (private->rebuild_font && private->font_desc) { if (private->rendering_mutex) g_mutex_lock (private->rendering_mutex); g_seis_view_axis_z_delete_font_list (G_SEIS_VIEW_AXIS_Z (self), seis_view_gl, TRUE); g_seis_view_axis_z_create_font_list (G_SEIS_VIEW_AXIS_Z (self), seis_view_gl); if (private->rendering_mutex) g_mutex_unlock (private->rendering_mutex); } glColor3f (private->bg_color.red / (gfloat)G_MAXUINT16, private->bg_color.green / (gfloat)G_MAXUINT16, private->bg_color.blue / (gfloat)G_MAXUINT16); if (G_SEIS_VIEW_AXIS_LEFT == self->type) { glBegin (GL_QUADS); glVertex2f (0, data_visibility->fast_start_object); glVertex2f (data_visibility->slow_start_object, data_visibility->fast_start_object); glVertex2f (data_visibility->slow_start_object, data_visibility->fast_start_object + data_visibility->fast_size_object); glVertex2f (0, data_visibility->fast_start_object + data_visibility->fast_size_object); glEnd (); } else { glBegin (GL_QUADS); glVertex2f (data_visibility->slow_start_object + data_visibility->slow_size_object, data_visibility->fast_start_object); glVertex2f (data_visibility->slow_full_size_object, data_visibility->fast_start_object); glVertex2f (data_visibility->slow_full_size_object, data_visibility->fast_start_object + data_visibility->fast_size_object); glVertex2f (data_visibility->slow_start_object + data_visibility->slow_size_object, data_visibility->fast_start_object + data_visibility->fast_size_object); glEnd (); } glColor3f (private->fg_color.red / (gfloat)G_MAXUINT16, private->fg_color.green / (gfloat)G_MAXUINT16, private->fg_color.blue / (gfloat)G_MAXUINT16); if (private->redisplay) { if (private->rendering_mutex) g_mutex_lock (private->rendering_mutex); if (private->display_list_base) glDeleteLists (private->display_list_base, 1); slow_pixel_to_object_scale = data_visibility->slow_size_object / (gdouble)data_visibility->slow_size_screen; fast_pixel_to_object_scale = data_visibility->fast_size_object / (gdouble)data_visibility->fast_size_screen; fast_start_data = data_visibility->fast_start_data - 0.5 / (gdouble)(private->values_num); fast_size_data = data_visibility->fast_size_data; /* Dimensions in the object space */ text_width_object = private->text_width_screen * slow_pixel_to_object_scale; text_height_object = private->text_height_screen * fast_pixel_to_object_scale; /* Variables defining positions of the labels */ if (self->type == G_SEIS_VIEW_AXIS_RIGHT) { slow_start_object = data_visibility->slow_start_object + data_visibility->slow_size_object; tick_size_object = -(gint)(private->text_height_screen * 0.4) * fast_pixel_to_object_scale; margin_object = text_width_object * 0.13125; } else { slow_start_object = data_visibility->slow_start_object; tick_size_object = (gint)(private->text_height_screen * 0.4) * fast_pixel_to_object_scale; margin_object = text_width_object * 0.13125; } first_value = private->min_value + (private->max_value - private->min_value + private->values_step) * fast_start_data; last_value = private->min_value + (private->max_value - private->min_value + private->values_step) * (fast_start_data + fast_size_data); value_to_object_scale = data_visibility->fast_size_object / (last_value - first_value); labels_step = 0; labels_step_object = 0; /* Calculate appropriate distance between labels */ power_of_ten = log10 (private->values_step); ten_powered = pow (10, power_of_ten); ten_factor = 1.0; while (labels_step_object < text_height_object * 1.5 || labels_num > private->values_num || labels_step < (private->values_step - private->values_step / 1000.0)) { labels_step = ten_powered * ten_factor; start_label = ((gint)(first_value / labels_step)) * labels_step; while (start_label < first_value)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -