mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-21 13:10:19 +00:00
- Converted text background loading to build Cairo surfaces directly from pixbufs for renderer use.
- Updated the xtext renderer to accept Cairo background surfaces and dropped the GtkStyle attach during realize to keep rendering Cairo/Pango-focused. - Switched background surface ownership and cleanup to use cairo_surface_t across the shared state and settings update path.
This commit is contained in:
@@ -58,7 +58,7 @@
|
|||||||
#include <canberra.h>
|
#include <canberra.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GdkPixmap *channelwin_pix;
|
cairo_surface_t *channelwin_pix;
|
||||||
|
|
||||||
#ifdef USE_LIBCANBERRA
|
#ifdef USE_LIBCANBERRA
|
||||||
static ca_context *ca_con;
|
static ca_context *ca_con;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
#ifdef HAVE_GTK_MAC
|
#ifdef HAVE_GTK_MAC
|
||||||
#include <gtkosxapplication.h>
|
#include <gtkosxapplication.h>
|
||||||
@@ -178,8 +179,8 @@ typedef struct session_gui
|
|||||||
|
|
||||||
} session_gui;
|
} session_gui;
|
||||||
|
|
||||||
extern GdkPixmap *channelwin_pix;
|
extern cairo_surface_t *channelwin_pix;
|
||||||
extern GdkPixmap *dialogwin_pix;
|
extern cairo_surface_t *dialogwin_pix;
|
||||||
|
|
||||||
#define SPELL_ENTRY_GET_TEXT(e) ((char *)(gtk_entry_get_text (GTK_ENTRY(e))))
|
#define SPELL_ENTRY_GET_TEXT(e) ((char *)(gtk_entry_get_text (GTK_ENTRY(e))))
|
||||||
#define SPELL_ENTRY_SET_TEXT(e,txt) gtk_entry_set_text(GTK_ENTRY(e),txt)
|
#define SPELL_ENTRY_SET_TEXT(e,txt) gtk_entry_set_text(GTK_ENTRY(e),txt)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
GdkPixbuf *pix_ulist_voice;
|
GdkPixbuf *pix_ulist_voice;
|
||||||
GdkPixbuf *pix_ulist_halfop;
|
GdkPixbuf *pix_ulist_halfop;
|
||||||
@@ -49,26 +50,89 @@ GdkPixbuf *pix_tree_util;
|
|||||||
GdkPixbuf *pix_book;
|
GdkPixbuf *pix_book;
|
||||||
GdkPixbuf *pix_zoitechat;
|
GdkPixbuf *pix_zoitechat;
|
||||||
|
|
||||||
static GdkPixmap *
|
static cairo_surface_t *
|
||||||
|
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
gboolean has_alpha;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int src_stride;
|
||||||
|
int dest_stride;
|
||||||
|
int n_channels;
|
||||||
|
const guchar *src_pixels;
|
||||||
|
unsigned char *dest_pixels;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||||
|
|
||||||
|
width = gdk_pixbuf_get_width (pixbuf);
|
||||||
|
height = gdk_pixbuf_get_height (pixbuf);
|
||||||
|
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||||
|
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
|
||||||
|
|
||||||
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||||
|
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||||
|
src_pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||||
|
dest_stride = cairo_image_surface_get_stride (surface);
|
||||||
|
dest_pixels = cairo_image_surface_get_data (surface);
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
const guchar *src_row = src_pixels + (y * src_stride);
|
||||||
|
guint32 *dest_row = (guint32 *)(dest_pixels + (y * dest_stride));
|
||||||
|
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
const guchar *src = src_row + (x * n_channels);
|
||||||
|
guchar alpha = has_alpha ? src[3] : 0xff;
|
||||||
|
guchar red = src[0];
|
||||||
|
guchar green = src[1];
|
||||||
|
guchar blue = src[2];
|
||||||
|
guchar premul_red = (guchar)((red * alpha + 127) / 255);
|
||||||
|
guchar premul_green = (guchar)((green * alpha + 127) / 255);
|
||||||
|
guchar premul_blue = (guchar)((blue * alpha + 127) / 255);
|
||||||
|
|
||||||
|
dest_row[x] = ((guint32)alpha << 24) |
|
||||||
|
((guint32)premul_red << 16) |
|
||||||
|
((guint32)premul_green << 8) |
|
||||||
|
((guint32)premul_blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_mark_dirty (surface);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
pixmap_load_from_file_real (char *file)
|
pixmap_load_from_file_real (char *file)
|
||||||
{
|
{
|
||||||
GdkPixbuf *img;
|
GdkPixbuf *img;
|
||||||
GdkPixmap *pixmap;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
img = gdk_pixbuf_new_from_file (file, 0);
|
img = gdk_pixbuf_new_from_file (file, 0);
|
||||||
if (!img)
|
if (!img)
|
||||||
return NULL;
|
return NULL;
|
||||||
gdk_pixbuf_render_pixmap_and_mask (img, &pixmap, NULL, 128);
|
|
||||||
|
surface = pixbuf_to_cairo_surface (img);
|
||||||
g_object_unref (img);
|
g_object_unref (img);
|
||||||
|
|
||||||
return pixmap;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkPixmap *
|
cairo_surface_t *
|
||||||
pixmap_load_from_file (char *filename)
|
pixmap_load_from_file (char *filename)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
GdkPixmap *pix;
|
cairo_surface_t *pix;
|
||||||
|
|
||||||
if (filename[0] == '\0')
|
if (filename[0] == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#ifndef HEXCHAT_PIXMAPS_H
|
#ifndef HEXCHAT_PIXMAPS_H
|
||||||
#define HEXCHAT_PIXMAPS_H
|
#define HEXCHAT_PIXMAPS_H
|
||||||
|
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
extern GdkPixbuf *pix_ulist_voice;
|
extern GdkPixbuf *pix_ulist_voice;
|
||||||
extern GdkPixbuf *pix_ulist_halfop;
|
extern GdkPixbuf *pix_ulist_halfop;
|
||||||
extern GdkPixbuf *pix_ulist_op;
|
extern GdkPixbuf *pix_ulist_op;
|
||||||
@@ -40,7 +42,7 @@ extern GdkPixbuf *pix_tree_util;
|
|||||||
extern GdkPixbuf *pix_book;
|
extern GdkPixbuf *pix_book;
|
||||||
extern GdkPixbuf *pix_zoitechat;
|
extern GdkPixbuf *pix_zoitechat;
|
||||||
|
|
||||||
extern GdkPixmap *pixmap_load_from_file (char *file);
|
extern cairo_surface_t *pixmap_load_from_file (char *file);
|
||||||
extern void pixmaps_init (void);
|
extern void pixmaps_init (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2449,7 +2449,7 @@ setup_apply_real (int new_pix, int do_ulist, int do_layout, int do_identd)
|
|||||||
if (new_pix)
|
if (new_pix)
|
||||||
{
|
{
|
||||||
if (channelwin_pix)
|
if (channelwin_pix)
|
||||||
g_object_unref (channelwin_pix);
|
cairo_surface_destroy (channelwin_pix);
|
||||||
channelwin_pix = pixmap_load_from_file (prefs.hex_text_background);
|
channelwin_pix = pixmap_load_from_file (prefs.hex_text_background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -780,7 +780,6 @@ gtk_xtext_realize (GtkWidget * widget)
|
|||||||
xtext->resize_cursor = gdk_cursor_new_for_display (gdk_window_get_display (widget->window), GDK_LEFT_SIDE);
|
xtext->resize_cursor = gdk_cursor_new_for_display (gdk_window_get_display (widget->window), GDK_LEFT_SIDE);
|
||||||
|
|
||||||
gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
|
gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
|
||||||
widget->style = gtk_style_attach (widget->style, widget->window);
|
|
||||||
|
|
||||||
backend_init (xtext);
|
backend_init (xtext);
|
||||||
}
|
}
|
||||||
@@ -3571,7 +3570,7 @@ gtk_xtext_set_font (GtkXText *xtext, char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap)
|
gtk_xtext_set_background (GtkXText * xtext, cairo_surface_t *surface)
|
||||||
{
|
{
|
||||||
if (xtext->background_surface)
|
if (xtext->background_surface)
|
||||||
{
|
{
|
||||||
@@ -3580,14 +3579,12 @@ gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dontscroll (xtext->buffer);
|
dontscroll (xtext->buffer);
|
||||||
if (pixmap != 0)
|
if (surface)
|
||||||
{
|
{
|
||||||
cairo_t *cr = gdk_cairo_create (pixmap);
|
xtext->background_surface = cairo_surface_reference (surface);
|
||||||
xtext->background_surface = cairo_surface_reference (cairo_get_target (cr));
|
|
||||||
cairo_destroy (cr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmap != 0 && gtk_widget_get_realized (GTK_WIDGET(xtext)))
|
if (surface && gtk_widget_get_realized (GTK_WIDGET(xtext)))
|
||||||
{
|
{
|
||||||
xtext->ts_x = xtext->ts_y = 0;
|
xtext->ts_x = xtext->ts_y = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define HEXCHAT_XTEXT_H
|
#define HEXCHAT_XTEXT_H
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
#define GTK_TYPE_XTEXT (gtk_xtext_get_type ())
|
#define GTK_TYPE_XTEXT (gtk_xtext_get_type ())
|
||||||
#define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText))
|
#define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText))
|
||||||
@@ -268,7 +269,7 @@ void gtk_xtext_append_indent (xtext_buffer *buf,
|
|||||||
unsigned char *right_text, int right_len,
|
unsigned char *right_text, int right_len,
|
||||||
time_t stamp);
|
time_t stamp);
|
||||||
int gtk_xtext_set_font (GtkXText *xtext, char *name);
|
int gtk_xtext_set_font (GtkXText *xtext, char *name);
|
||||||
void gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap);
|
void gtk_xtext_set_background (GtkXText * xtext, cairo_surface_t *surface);
|
||||||
void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]);
|
void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]);
|
||||||
void gtk_xtext_clear (xtext_buffer *buf, int lines);
|
void gtk_xtext_clear (xtext_buffer *buf, int lines);
|
||||||
void gtk_xtext_save (GtkXText * xtext, int fh);
|
void gtk_xtext_save (GtkXText * xtext, int fh);
|
||||||
|
|||||||
Reference in New Issue
Block a user