comparison gtk/dw.c @ 1168:4e8f00c31c91

Added basic printing support for GTK 2.10 and above... Drawing except bitblt is currently supported.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 16 Sep 2011 22:28:14 +0000
parents 924c8087a755
children 8be8607301c8
comparison
equal deleted inserted replaced
1167:5668d269beb3 1168:4e8f00c31c91
7732 */ 7732 */
7733 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) 7733 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
7734 { 7734 {
7735 int _locked_by_me = FALSE; 7735 int _locked_by_me = FALSE;
7736 GdkGC *gc = NULL; 7736 GdkGC *gc = NULL;
7737 #if GTK_CHECK_VERSION(2,10,0)
7738 cairo_t *cr = NULL;
7739 #endif
7737 7740
7738 DW_MUTEX_LOCK; 7741 DW_MUTEX_LOCK;
7739 if(handle) 7742 if(handle)
7740 gc = _set_colors(handle->window); 7743 gc = _set_colors(handle->window);
7741 else if(pixmap) 7744 else if(pixmap && pixmap->pixmap)
7742 gc = _set_colors(pixmap->pixmap); 7745 gc = _set_colors(pixmap->pixmap);
7746 #if GTK_CHECK_VERSION(2,10,0)
7747 else if(pixmap && pixmap->image)
7748 cr = cairo_create(pixmap->image);
7749 if(cr)
7750 {
7751 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
7752
7753 gdk_cairo_set_source_color (cr, foreground);
7754 cairo_set_line_width(cr, 1);
7755 cairo_move_to(cr, x, y);
7756 cairo_stroke(cr);
7757 cairo_destroy(cr);
7758 }
7759 #endif
7743 if(gc) 7760 if(gc)
7744 { 7761 {
7745 gdk_draw_point(handle ? handle->window : pixmap->pixmap, gc, x, y); 7762 gdk_draw_point(handle ? handle->window : pixmap->pixmap, gc, x, y);
7746 gdk_gc_unref(gc); 7763 gdk_gc_unref(gc);
7747 } 7764 }
7759 */ 7776 */
7760 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) 7777 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
7761 { 7778 {
7762 int _locked_by_me = FALSE; 7779 int _locked_by_me = FALSE;
7763 GdkGC *gc = NULL; 7780 GdkGC *gc = NULL;
7781 #if GTK_CHECK_VERSION(2,10,0)
7782 cairo_t *cr = NULL;
7783 #endif
7764 7784
7765 DW_MUTEX_LOCK; 7785 DW_MUTEX_LOCK;
7766 if(handle) 7786 if(handle)
7767 gc = _set_colors(handle->window); 7787 gc = _set_colors(handle->window);
7768 else if(pixmap) 7788 else if(pixmap && pixmap->pixmap)
7769 gc = _set_colors(pixmap->pixmap); 7789 gc = _set_colors(pixmap->pixmap);
7790 #if GTK_CHECK_VERSION(2,10,0)
7791 else if(pixmap && pixmap->image)
7792 cr = cairo_create(pixmap->image);
7793 if(cr)
7794 {
7795 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
7796
7797 gdk_cairo_set_source_color (cr, foreground);
7798 cairo_set_line_width(cr, 1);
7799 cairo_move_to(cr, x1, y1);
7800 cairo_line_to(cr, x2, y2);
7801 cairo_stroke(cr);
7802 cairo_destroy(cr);
7803 }
7804 #endif
7770 if(gc) 7805 if(gc)
7771 { 7806 {
7772 gdk_draw_line(handle ? handle->window : pixmap->pixmap, gc, x1, y1, x2, y2); 7807 gdk_draw_line(handle ? handle->window : pixmap->pixmap, gc, x1, y1, x2, y2);
7773 gdk_gc_unref(gc); 7808 gdk_gc_unref(gc);
7774 } 7809 }
7788 { 7823 {
7789 int _locked_by_me = FALSE; 7824 int _locked_by_me = FALSE;
7790 int i; 7825 int i;
7791 GdkGC *gc = NULL; 7826 GdkGC *gc = NULL;
7792 GdkPoint *points = NULL; 7827 GdkPoint *points = NULL;
7793 7828 #if GTK_CHECK_VERSION(2,10,0)
7794 DW_MUTEX_LOCK; 7829 cairo_t *cr = NULL;
7795 if ( handle ) 7830 #endif
7796 gc = _set_colors( handle->window ); 7831
7797 else if ( pixmap ) 7832 DW_MUTEX_LOCK;
7798 gc = _set_colors( pixmap->pixmap ); 7833 if(handle)
7799 if ( npoints ) 7834 gc = _set_colors(handle->window);
7800 { 7835 else if(pixmap && pixmap->pixmap)
7801 points = alloca( npoints * sizeof(GdkPoint) ); 7836 gc = _set_colors(pixmap->pixmap);
7837 #if GTK_CHECK_VERSION(2,10,0)
7838 else if(pixmap && pixmap->image)
7839 cr = cairo_create(pixmap->image);
7840 if(cr)
7841 {
7842 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
7843
7844 gdk_cairo_set_source_color (cr, foreground);
7845 cairo_set_line_width(cr, 1);
7846 cairo_move_to(cr, x[0], y[0]);
7847 for(i=1;i<npoints;i++)
7848 {
7849 cairo_line_to(cr, x[i], y[i]);
7850 }
7851 if(fill)
7852 cairo_fill(cr);
7853 cairo_stroke(cr);
7854 cairo_destroy(cr);
7855 }
7856 #endif
7857 if(gc && npoints)
7858 {
7859 points = alloca(npoints * sizeof(GdkPoint));
7802 /* 7860 /*
7803 * should check for NULL pointer return! 7861 * should check for NULL pointer return!
7804 */ 7862 */
7805 for ( i = 0 ; i < npoints ; i++ ) 7863 for(i = 0; i < npoints; i++)
7806 { 7864 {
7807 points[i].x = x[i]; 7865 points[i].x = x[i];
7808 points[i].y = y[i]; 7866 points[i].y = y[i];
7809 } 7867 }
7810 } 7868
7811 if ( gc )
7812 {
7813 gdk_draw_polygon(handle ? handle->window : pixmap->pixmap, gc, fill, points, npoints ); 7869 gdk_draw_polygon(handle ? handle->window : pixmap->pixmap, gc, fill, points, npoints );
7814 gdk_gc_unref( gc ); 7870 gdk_gc_unref(gc);
7815 } 7871 }
7816 DW_MUTEX_UNLOCK; 7872 DW_MUTEX_UNLOCK;
7817 } 7873 }
7818 7874
7819 /* Draw a rectangle on a window (preferably a render window). 7875 /* Draw a rectangle on a window (preferably a render window).
7828 */ 7884 */
7829 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) 7885 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
7830 { 7886 {
7831 int _locked_by_me = FALSE; 7887 int _locked_by_me = FALSE;
7832 GdkGC *gc = NULL; 7888 GdkGC *gc = NULL;
7889 #if GTK_CHECK_VERSION(2,10,0)
7890 cairo_t *cr = NULL;
7891 #endif
7833 7892
7834 DW_MUTEX_LOCK; 7893 DW_MUTEX_LOCK;
7835 if(handle) 7894 if(handle)
7836 gc = _set_colors(handle->window); 7895 gc = _set_colors(handle->window);
7837 else if(pixmap) 7896 else if(pixmap && pixmap->pixmap)
7838 gc = _set_colors(pixmap->pixmap); 7897 gc = _set_colors(pixmap->pixmap);
7898 #if GTK_CHECK_VERSION(2,10,0)
7899 else if(pixmap && pixmap->image)
7900 cr = cairo_create(pixmap->image);
7901 if(cr)
7902 {
7903 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
7904
7905 gdk_cairo_set_source_color (cr, foreground);
7906 cairo_set_line_width(cr, 1);
7907 cairo_move_to(cr, x, y);
7908 cairo_line_to(cr, x, y + height);
7909 cairo_line_to(cr, x + width, y + height);
7910 cairo_line_to(cr, x + width, y);
7911 if(fill)
7912 cairo_fill(cr);
7913 cairo_stroke(cr);
7914 cairo_destroy(cr);
7915 }
7916 #endif
7839 if(gc) 7917 if(gc)
7840 { 7918 {
7841 gdk_draw_rectangle(handle ? handle->window : pixmap->pixmap, gc, fill, x, y, width, height); 7919 gdk_draw_rectangle(handle ? handle->window : pixmap->pixmap, gc, fill, x, y, width, height);
7842 gdk_gc_unref(gc); 7920 gdk_gc_unref(gc);
7843 } 7921 }
7860 PangoFontDescription *font; 7938 PangoFontDescription *font;
7861 #else 7939 #else
7862 GdkFont *font; 7940 GdkFont *font;
7863 #endif 7941 #endif
7864 char *tmpname, *fontname = "fixed"; 7942 char *tmpname, *fontname = "fixed";
7943 #if GTK_CHECK_VERSION(2,10,0)
7944 cairo_t *cr = NULL;
7945 #endif
7865 7946
7866 if(!text) 7947 if(!text)
7867 return; 7948 return;
7868 7949
7869 DW_MUTEX_LOCK; 7950 DW_MUTEX_LOCK;
7871 { 7952 {
7872 if((tmpname = (char *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_fontname"))) 7953 if((tmpname = (char *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_fontname")))
7873 fontname = tmpname; 7954 fontname = tmpname;
7874 gc = _set_colors(handle->window); 7955 gc = _set_colors(handle->window);
7875 } 7956 }
7876 else if(pixmap) 7957 else if(pixmap && pixmap->pixmap)
7877 { 7958 {
7878 if(pixmap->font) 7959 if(pixmap->font)
7879 fontname = pixmap->font; 7960 fontname = pixmap->font;
7880 else if((tmpname = (char *)gtk_object_get_data(GTK_OBJECT(pixmap->handle), "_dw_fontname"))) 7961 else if((tmpname = (char *)gtk_object_get_data(GTK_OBJECT(pixmap->handle), "_dw_fontname")))
7881 fontname = tmpname; 7962 fontname = tmpname;
7882 gc = _set_colors(pixmap->pixmap); 7963 gc = _set_colors(pixmap->pixmap);
7883 } 7964 }
7965 #if GTK_CHECK_VERSION(2,10,0)
7966 else if(pixmap && pixmap->image)
7967 {
7968 if(pixmap->font)
7969 fontname = pixmap->font;
7970 else if(pixmap->handle && (tmpname = (char *)g_object_get_data(G_OBJECT(pixmap->handle), "_dw_fontname")))
7971 fontname = tmpname;
7972 cr = cairo_create(pixmap->image);
7973 }
7974 if(cr)
7975 {
7976 font = pango_font_description_from_string(fontname);
7977 if(font)
7978 {
7979 PangoContext *context = pango_cairo_create_context(cr);
7980
7981 if(context)
7982 {
7983 PangoLayout *layout = pango_layout_new(context);
7984
7985 if(layout)
7986 {
7987 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
7988 GdkColor *background = pthread_getspecific(_dw_bg_color_key);
7989
7990 pango_layout_set_font_description(layout, font);
7991 pango_layout_set_text(layout, text, strlen(text));
7992
7993 gdk_cairo_set_source_color (cr, foreground);
7994 /* Create a background color attribute if required */
7995 if(background)
7996 {
7997 PangoAttrList *list = pango_layout_get_attributes(layout);
7998 PangoAttribute *attr = pango_attr_background_new(background->red,
7999 background->green,
8000 background->blue);
8001 if(!list)
8002 {
8003 list = pango_attr_list_new();
8004 }
8005 pango_attr_list_change(list, attr);
8006 pango_layout_set_attributes(layout, list);
8007 }
8008 /* Do the drawing */
8009 cairo_move_to(cr, x, y);
8010 pango_cairo_show_layout (cr, layout);
8011
8012 g_object_unref(layout);
8013 }
8014 g_object_unref(context);
8015 }
8016 pango_font_description_free(font);
8017 }
8018 cairo_destroy(cr);
8019 }
8020 #endif
7884 if(gc) 8021 if(gc)
7885 { 8022 {
7886 #if GTK_MAJOR_VERSION > 1 8023 #if GTK_MAJOR_VERSION > 1
7887 font = pango_font_description_from_string(fontname); 8024 font = pango_font_description_from_string(fontname);
7888 if(font) 8025 if(font)
11723 gtk_clipboard_set_text( clipboard_object, str, len ); 11860 gtk_clipboard_set_text( clipboard_object, str, len );
11724 } 11861 }
11725 DW_MUTEX_UNLOCK; 11862 DW_MUTEX_UNLOCK;
11726 } 11863 }
11727 11864
11865 #if GTK_CHECK_VERSION(2,10,0)
11866 /* Internal function to create the drawable pixmap and call the function */
11867 static void _dw_draw_page(GtkPrintOperation *operation, GtkPrintContext *context, int page_nr)
11868 {
11869 cairo_t *cr = gtk_print_context_get_cairo_context(context);
11870 void *drawdata = g_object_get_data(G_OBJECT(operation), "_dw_drawdata");
11871 int (*drawfunc)(HPRINT, HPIXMAP, int, void *) = g_object_get_data(G_OBJECT(operation), "_dw_drawfunc");
11872 int result = 0;
11873 HPIXMAP pixmap;
11874
11875 if(cr && drawfunc && (pixmap = calloc(1,sizeof(struct _hpixmap))))
11876 {
11877 pixmap->image = cairo_get_group_target(cr);
11878 pixmap->handle = (HWND)operation;
11879 pixmap->width = gtk_print_context_get_width(context);
11880 pixmap->height = gtk_print_context_get_height(context);
11881 result = drawfunc((HPRINT)operation, pixmap, page_nr, drawdata);
11882 if(result)
11883 gtk_print_operation_draw_page_finish(operation);
11884 free(pixmap);
11885 }
11886 }
11887 #endif
11888
11728 /* 11889 /*
11729 * Creates a new print object. 11890 * Creates a new print object.
11730 * Parameters: 11891 * Parameters:
11731 * jobname: Name of the print job to show in the queue. 11892 * jobname: Name of the print job to show in the queue.
11732 * flags: Flags to initially configure the print object. 11893 * flags: Flags to initially configure the print object.
11736 * Returns: 11897 * Returns:
11737 * A handle to the print object or NULL on failure. 11898 * A handle to the print object or NULL on failure.
11738 */ 11899 */
11739 HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata) 11900 HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata)
11740 { 11901 {
11902 #if GTK_CHECK_VERSION(2,10,0)
11903 GtkPrintOperation *op;
11904 int _locked_by_me = FALSE;
11905
11906 if(!drawfunc)
11907 return NULL;
11908
11909 DW_MUTEX_LOCK;
11910 if((op = gtk_print_operation_new()))
11911 {
11912 gtk_print_operation_set_n_pages(op, pages);
11913 gtk_print_operation_set_job_name(op, jobname ? jobname : "Dynamic Windows Print Job");
11914 g_object_set_data(G_OBJECT(op), "_dw_drawfunc", drawfunc);
11915 g_object_set_data(G_OBJECT(op), "_dw_drawdata", drawdata);
11916 g_signal_connect(op, "draw_page", G_CALLBACK(_dw_draw_page), NULL);
11917 }
11918 DW_MUTEX_UNLOCK;
11919 return (HPRINT)op;
11920 #else
11741 return NULL; 11921 return NULL;
11922 #endif
11742 } 11923 }
11743 11924
11744 /* 11925 /*
11745 * Runs the print job, causing the draw page callbacks to fire. 11926 * Runs the print job, causing the draw page callbacks to fire.
11746 * Parameters: 11927 * Parameters:
11749 * Returns: 11930 * Returns:
11750 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success. 11931 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success.
11751 */ 11932 */
11752 int API dw_print_run(HPRINT print, unsigned long flags) 11933 int API dw_print_run(HPRINT print, unsigned long flags)
11753 { 11934 {
11935 #if GTK_CHECK_VERSION(2,10,0)
11936 GtkPrintOperationResult res;
11937 GtkPrintOperation *op = (GtkPrintOperation *)print;
11938 int _locked_by_me = FALSE;
11939
11940 DW_MUTEX_LOCK;
11941 res = gtk_print_operation_run(op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, NULL);
11942 DW_MUTEX_UNLOCK;
11943 return (res == GTK_PRINT_OPERATION_RESULT_ERROR ? DW_ERROR_UNKNOWN : DW_ERROR_NONE);
11944 #else
11754 return DW_ERROR_UNKNOWN; 11945 return DW_ERROR_UNKNOWN;
11946 #endif
11755 } 11947 }
11756 11948
11757 /* 11949 /*
11758 * Cancels the print job, typically called from a draw page callback. 11950 * Cancels the print job, typically called from a draw page callback.
11759 * Parameters: 11951 * Parameters:
11760 * print: Handle to the print object returned by dw_print_new(). 11952 * print: Handle to the print object returned by dw_print_new().
11761 */ 11953 */
11762 void API dw_print_cancel(HPRINT print) 11954 void API dw_print_cancel(HPRINT print)
11763 { 11955 {
11956 #if GTK_CHECK_VERSION(2,10,0)
11957 int _locked_by_me = FALSE;
11958 GtkPrintOperation *op = (GtkPrintOperation *)print;
11959
11960 DW_MUTEX_LOCK;
11961 gtk_print_operation_cancel(op);
11962 DW_MUTEX_UNLOCK;
11963 #endif
11764 } 11964 }
11765 11965
11766 /* 11966 /*
11767 * Returns a pointer to a static buffer which containes the 11967 * Returns a pointer to a static buffer which containes the
11768 * current user directory. Or the root directory (C:\ on 11968 * current user directory. Or the root directory (C:\ on