/* * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a * aplicativos mainframe. Registro no INPI sob o nome G3270. * * Copyright (C) <2008> * * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela * Free Software Foundation. * * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para * obter mais detalhes. * * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110-1301 USA * * Este programa está nomeado como - e possui - linhas de código. * * Contatos: * * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) * */ #include #include #include #include #define VIEW_HEIGTH_FROM_FONT(font_height) (( ((unsigned int) font_height) * (rows+1)) + OIA_TOP_MARGIN + 2) #define VIEW_WIDTH_FROM_FONT(max_x_advance) ( ((unsigned int) max_x_advance) * cols) /*--[ Globals ]--------------------------------------------------------------------------------------*/ #ifdef _WIN32 const gchar * v3270_default_font = "Lucida Console"; #else const gchar * v3270_default_font = "monospace"; #endif // _WIN32 /*--[ Implement ]------------------------------------------------------------------------------------*/ const gchar * v3270_get_default_font_name() { return v3270_default_font; } /** * @brief Update font metrics based on view sizes. * * @param terminal v3270 terminal widget. * @param cr Cairo context. * @param width View width in pixels. * @param height View height in pixels. * */ void v3270_update_font_metrics(v3270 *terminal, cairo_t *cr, unsigned int width, unsigned int height) { // update font metrics unsigned int rows, cols, hFont, size; cairo_font_extents_t extents; lib3270_get_screen_size(terminal->host,&rows,&cols); debug( "Screen_size: %ux%u Scalled=%s view_rows=%d", rows, cols, terminal->font.scaled ? "Yes" : "No", (rows+OIA_TOP_MARGIN+3) ); terminal->font.weight = lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_BOLD) ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL; if(terminal->font.face) { cairo_font_face_destroy(terminal->font.face); } terminal->font.face = cairo_toy_font_face_create(terminal->font.family, CAIRO_FONT_SLANT_NORMAL, terminal->font.weight); cairo_set_font_face(cr,terminal->font.face); // cairo_select_font_face(cr,terminal->font.family, CAIRO_FONT_SLANT_NORMAL,terminal->font.weight); if(terminal->font.scaled) { // double w = ((double) width) / ((double)cols); // double h = ((double) height) / ((double) ((rows + OIA_TOP_MARGIN + 3))); // double s = (w < h) ? w : h; double s = 0; double selected = 0; do { selected = s; s += 0.5; cairo_set_font_size(cr,s); cairo_font_extents(cr,&extents); debug("font_size=%lf x_advance=%lf y_advance=%lf font_extents=%u+%u font_height=%u view_height=%u view_width=%u", s, extents.max_x_advance, extents.max_y_advance, (unsigned int) extents.height, (unsigned int) extents.descent, VIEW_HEIGTH_FROM_FONT( (unsigned int) (extents.height + extents.descent) ), height, VIEW_WIDTH_FROM_FONT(extents.max_x_advance) ); } while( (VIEW_HEIGTH_FROM_FONT( (extents.height+extents.descent) ) < height) && (VIEW_WIDTH_FROM_FONT(extents.max_x_advance) < width) ); debug("Selected size=%lf",selected); cairo_set_font_size(cr,selected); cairo_font_extents(cr,&extents); /* cairo_set_font_size(cr,s); cairo_font_extents(cr,&extents); while( (VIEW_HEIGTH_FROM_FONT( (extents.height+extents.descent) ) < height) && (VIEW_WIDTH_FROM_FONT(extents.max_x_advance) < width) ) { s += 0.5; cairo_set_font_size(cr,s); cairo_font_extents(cr,&extents); debug("font_size=%lf x_advance=%lf y_advance=%lf font_extents=%u+%u font_height=%u view_height=%u view_width=%u", s, extents.max_x_advance, extents.max_y_advance, (unsigned int) extents.height, (unsigned int) extents.descent, VIEW_HEIGTH_FROM_FONT( (unsigned int) (extents.height + extents.descent) ), height, VIEW_WIDTH_FROM_FONT(extents.max_x_advance) ); } s -= 0.5; */ } else { static const unsigned int font_size[] = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28, 32, 36, 40, 48, 56, 64, 72 }; size_t f; size = font_size[0]; for(f=0;f < G_N_ELEMENTS(font_size);f++) { cairo_set_font_size(cr,font_size[f]); cairo_font_extents(cr,&extents); if(f == 0) { terminal->minimum_width = (cols * extents.max_x_advance); terminal->minimum_height = ((rows+1) * (extents.height + extents.descent)) + (OIA_TOP_MARGIN+2); } debug("font_size=%d x_advance=%lf y_advance=%lf font_extents=%u+%u font_height=%u view_height=%u view_width=%u", font_size[f], extents.max_x_advance, extents.max_y_advance, (unsigned int) extents.height, (unsigned int) extents.descent, VIEW_HEIGTH_FROM_FONT( (unsigned int) (extents.height + extents.descent) ), height, VIEW_WIDTH_FROM_FONT(extents.max_x_advance) ); if( VIEW_HEIGTH_FROM_FONT((extents.height + extents.descent)) < height && VIEW_WIDTH_FROM_FONT(extents.max_x_advance) < width) size = font_size[f]; } debug("font_size=%d",size); cairo_set_font_size(cr,size); #if !GTK_CHECK_VERSION(3,0,0) gtk_widget_set_size_request(GTK_WIDGET(terminal),terminal->minimum_width,terminal->minimum_height); #endif // !GTK(3,0,0) } cairo_font_extents(cr,&extents); // Save scaled font for use on next drawings if(terminal->font.scaled) cairo_scaled_font_destroy(terminal->font.scaled); terminal->font.scaled = cairo_get_scaled_font(cr); cairo_scaled_font_reference(terminal->font.scaled); cairo_scaled_font_extents(terminal->font.scaled,&extents); terminal->font.width = (int) extents.max_x_advance; terminal->font.height = (int) extents.height; terminal->font.ascent = (int) extents.ascent; terminal->font.descent = (int) extents.descent; hFont = (unsigned int) (terminal->font.height + terminal->font.descent); // Create new cursor surface if(terminal->cursor.surface) cairo_surface_destroy(terminal->cursor.surface); terminal->cursor.surface = gdk_window_create_similar_surface(gtk_widget_get_window(GTK_WIDGET(terminal)),CAIRO_CONTENT_COLOR,terminal->font.width,hFont); // Center image size = VIEW_WIDTH_FROM_FONT(terminal->font.width); if(width >= size) { terminal->font.left = ((width - size) / 2); } else { terminal->font.left = 0; } // terminal->font.left = (width >> 1) - ((size) >> 1); debug("Width=%u size=%u left=%d",height, size, terminal->font.left); /* terminal->font.spacing = height / (rows+1); if((int) terminal->font.spacing < hFont) terminal->font.spacing = hFont; */ terminal->font.spacing = hFont; size = VIEW_HEIGTH_FROM_FONT(terminal->font.spacing); if(height >= size) { terminal->font.top = ((height - size) /2); } else { terminal->font.top = 0; } //terminal->font.top = (height >> 1) - (size >> 1); debug("screen_height=%u content_height=%u top=%d",height, size, terminal->font.top); } LIB3270_EXPORT void v3270_set_font_family(GtkWidget *widget, const gchar *name) { v3270 * terminal; g_return_if_fail(GTK_IS_V3270(widget)); terminal = GTK_V3270(widget); if(!name) { name = v3270_default_font; } if(g_ascii_strcasecmp(terminal->font.family,name)) { // Font has changed, update it g_free(terminal->font.family); terminal->font.family = g_strdup(name); terminal->font.weight = lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_BOLD) ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL; g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_UPDATE_CONFIG], 0, "font-family", name); g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.font_family); v3270_reload(widget); gtk_widget_queue_draw(widget); } } LIB3270_EXPORT const gchar * v3270_get_font_family(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_V3270(widget),NULL); return GTK_V3270(widget)->font.family; } LIB3270_EXPORT void v3270_set_scaled_fonts(GtkWidget *widget, gboolean on) { g_return_if_fail(GTK_IS_V3270(widget)); GTK_V3270(widget)->scaled_fonts = on ? 1 : 0; }