/* ply-label.c - label control * * Copyright (C) 2008 Red Hat, Inc. * * 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, 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 details. * * 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. * * Written by: Ray Strode */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ply-pixel-buffer.h" #include "ply-pixel-display.h" #include "ply-utils.h" #include "ply-label-plugin.h" struct _ply_label_plugin_control { ply_event_loop_t *loop; ply_pixel_display_t *display; ply_rectangle_t area; char *text; float red; float green; float blue; float alpha; uint32_t is_hidden : 1; }; ply_label_plugin_control_t * create_control (void) { ply_label_plugin_control_t *label; label = calloc (1, sizeof (ply_label_plugin_control_t)); label->is_hidden = true; return label; } void destroy_control (ply_label_plugin_control_t *label) { if (label == NULL) return; free (label); } long get_width_of_control (ply_label_plugin_control_t *label) { return label->area.width; } long get_height_of_control (ply_label_plugin_control_t *label) { return label->area.height; } static cairo_t * get_cairo_context_for_pixel_buffer (ply_label_plugin_control_t *label, ply_pixel_buffer_t *pixel_buffer) { cairo_surface_t *cairo_surface; cairo_t *cairo_context; unsigned char *data; ply_rectangle_t size; data = (unsigned char *) ply_pixel_buffer_get_argb32_data (pixel_buffer); ply_pixel_buffer_get_size (pixel_buffer, &size); cairo_surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, size.width, size.height, size.width * 4); cairo_context = cairo_create (cairo_surface); cairo_surface_destroy (cairo_surface); return cairo_context; } static cairo_t * get_cairo_context_for_sizing (ply_label_plugin_control_t *label) { cairo_surface_t *cairo_surface; cairo_t *cairo_context; cairo_surface = cairo_image_surface_create_for_data (NULL, CAIRO_FORMAT_ARGB32, 0, 0, 0); cairo_context = cairo_create (cairo_surface); cairo_surface_destroy (cairo_surface); return cairo_context; } static void size_control (ply_label_plugin_control_t *label) { cairo_t *cairo_context; PangoLayout *pango_layout; PangoFontDescription *description; int text_width; int text_height; if (label->is_hidden) return; cairo_context = get_cairo_context_for_sizing (label); pango_layout = pango_cairo_create_layout (cairo_context); description = pango_font_description_from_string ("Sans 12"); pango_layout_set_font_description (pango_layout, description); pango_font_description_free (description); pango_layout_set_text (pango_layout, label->text, -1); pango_cairo_update_layout (cairo_context, pango_layout); pango_layout_get_size (pango_layout, &text_width, &text_height); label->area.width = (long) ((double) text_width / PANGO_SCALE); label->area.height = (long) ((double) text_height / PANGO_SCALE); g_object_unref (pango_layout); cairo_destroy (cairo_context); } void draw_control (ply_label_plugin_control_t *label, ply_pixel_buffer_t *pixel_buffer, long x, long y, unsigned long width, unsigned long height) { cairo_t *cairo_context; PangoLayout *pango_layout; PangoFontDescription *description; int text_width; int text_height; if (label->is_hidden) return; cairo_context = get_cairo_context_for_pixel_buffer (label, pixel_buffer); pango_layout = pango_cairo_create_layout (cairo_context); description = pango_font_description_from_string ("Sans 12"); pango_layout_set_font_description (pango_layout, description); pango_font_description_free (description); pango_layout_set_text (pango_layout, label->text, -1); pango_cairo_update_layout (cairo_context, pango_layout); pango_layout_get_size (pango_layout, &text_width, &text_height); label->area.width = (long) ((double) text_width / PANGO_SCALE); label->area.height = (long) ((double) text_height / PANGO_SCALE); cairo_rectangle (cairo_context, x, y, width, height); cairo_clip (cairo_context); cairo_move_to (cairo_context, label->area.x, label->area.y); cairo_set_source_rgba (cairo_context, label->red, label->green, label->blue, label->alpha); pango_cairo_show_layout (cairo_context, pango_layout); g_object_unref (pango_layout); cairo_destroy (cairo_context); } void set_text_for_control (ply_label_plugin_control_t *label, const char *text) { ply_rectangle_t dirty_area; if (label->text != text) { dirty_area = label->area; free (label->text); label->text = strdup (text); size_control (label); if (!label->is_hidden && label->display != NULL) ply_pixel_display_draw_area (label->display, dirty_area.x, dirty_area.y, dirty_area.width, dirty_area.height); } } void set_color_for_control (ply_label_plugin_control_t *label, float red, float green, float blue, float alpha) { label->red = red; label->green = green; label->blue = blue; label->alpha = alpha; if (!label->is_hidden && label->display != NULL) ply_pixel_display_draw_area (label->display, label->area.x, label->area.y, label->area.width, label->area.height); } bool show_control (ply_label_plugin_control_t *label, ply_pixel_display_t *display, long x, long y) { ply_rectangle_t dirty_area; dirty_area = label->area; label->display = display; label->area.x = x; label->area.y = y; label->is_hidden = false; size_control (label); if (!label->is_hidden && label->display != NULL) ply_pixel_display_draw_area (label->display, dirty_area.x, dirty_area.y, dirty_area.width, dirty_area.height); label->is_hidden = false; return true; } void hide_control (ply_label_plugin_control_t *label) { label->is_hidden = true; if (label->display != NULL) ply_pixel_display_draw_area (label->display, label->area.x, label->area.y, label->area.width, label->area.height); label->display = NULL; label->loop = NULL; } bool is_control_hidden (ply_label_plugin_control_t *label) { return label->is_hidden; } ply_label_plugin_interface_t * ply_label_plugin_get_interface (void) { static ply_label_plugin_interface_t plugin_interface = { .create_control = create_control, .destroy_control = destroy_control, .show_control = show_control, .hide_control = hide_control, .draw_control = draw_control, .is_control_hidden = is_control_hidden, .set_text_for_control = set_text_for_control, .set_color_for_control = set_color_for_control, .get_width_of_control = get_width_of_control, .get_height_of_control = get_height_of_control }; return &plugin_interface; } /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */