forked from AuroraMiddleware/gtk
Private function to tell if we have RENDER extension.
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com> * gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h (_gdk_x11_have_render): Private function to tell if we have RENDER extension. * gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return None if we don't have RENDER extension. * gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't use Xft unless we have render extension. * gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture): Handle missing render extension. * gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c gdk/gdkinternals.h: Add a private copy_to_image() virtual function to the GdkDrawable vtable that extends get_image() to allow copying onto existing images. Make the default implementation of get_image() use this so that backends don't have to implement both. Add private wrapper _gdk_drawable_copy_to_image(). * gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement copy_to_image() semantics, speed up by using ShmPixmaps and XCopyArea when possible, XFlush() after ungrabbing the server, generally redo the logic once again. * gdk/gdkinternals.h gdk/x11/gdkimage-x11.c _gdk_windowing_bits_per_depth(): Function to convert from depth to bits-per-pixel. (We assume only one bpp per depth - X requires this.) * gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB scratch image code into a generic _gdk_image_get_scratch() chunk of code that we can use other places we need scratch images. * gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h: Add _gdk_image_new_for_depth() as the backend to _gdk_image_new() to allowing creating images with a depth and no visual. * gdk/gdkpixbuf-drawable.c: Fix so that getting parts of images not at 0,0 actually works. * gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c: - Add a new GdkDrawableClass vfunc _draw_pixbuf, and _gdk_draw_pixbuf() [ will be made public later ], to allow backends to accelerate drawing pixbufs. - Move the implementation of gdk_pixbuf_render_to_drawable_alpha() to be the default implementation. - Update docs for gdk_pixbuf_render_to_drawable_alpha(). - Optimize the default implementation by using _gdk_image_copy_to_pixmap() and scratch shared images, and special casing the compositing. * gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf() with alpha using the RENDER extension. * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Optimize by _gdk_image_copy_to_pixmap() and scratch images. * tests/testrgb.c: Add test for speed of alpha composition, reduce the number of iterations since alpha composition can be a bit slow. * gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap): Private function to get a ShmPixmap for an image, if possible.
This commit is contained in:
parent
a755adc58d
commit
d12c9702a4
70
ChangeLog
70
ChangeLog
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
@ -1,3 +1,73 @@
|
||||
Thu Jan 3 22:18:15 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c gdk/x11/gdkprivate-x11.h
|
||||
(_gdk_x11_have_render): Private function to tell if we have RENDER
|
||||
extension.
|
||||
|
||||
* gdk/x11/gdkgc-x11.c (_gdk_x11_gc_get_fg_picture): Return
|
||||
None if we don't have RENDER extension.
|
||||
|
||||
* gdk/x11/gdkpango-x11.c (gdk_pango_context_get): Don't
|
||||
use Xft unless we have render extension.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
|
||||
Handle missing render extension.
|
||||
|
||||
* gdk/gdkdraw.c gdk/gdkdrawable.h gdk/gdkpixmap.c gdk/gdkwindow.c
|
||||
gdk/gdkinternals.h: Add a private copy_to_image() virtual function
|
||||
to the GdkDrawable vtable that extends get_image() to allow
|
||||
copying onto existing images. Make the default implementation of
|
||||
get_image() use this so that backends don't have to implement
|
||||
both. Add private wrapper _gdk_drawable_copy_to_image().
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/x11/gdkprivate-x11.c
|
||||
gdk/x11/gdkdrawable-x11.c (_gdk_x11_copy_to_image): Implement
|
||||
copy_to_image() semantics, speed up by using ShmPixmaps and
|
||||
XCopyArea when possible, XFlush() after ungrabbing the server,
|
||||
generally redo the logic once again.
|
||||
|
||||
* gdk/gdkinternals.h gdk/x11/gdkimage-x11.c
|
||||
_gdk_windowing_bits_per_depth(): Function to convert from depth to
|
||||
bits-per-pixel. (We assume only one bpp per depth - X requires
|
||||
this.)
|
||||
|
||||
* gdk/gdkinternals.h gdk/gdkrgb.c gdk/gdkimage.c: Move the GdkRGB
|
||||
scratch image code into a generic _gdk_image_get_scratch() chunk
|
||||
of code that we can use other places we need scratch images.
|
||||
|
||||
* gdk/gdkimage.c gdk/x11/gdkimage.c gdk/gdkinternals.h:
|
||||
Add _gdk_image_new_for_depth() as the backend
|
||||
to _gdk_image_new() to allowing creating images with
|
||||
a depth and no visual.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c: Fix so that getting
|
||||
parts of images not at 0,0 actually works.
|
||||
|
||||
* gdk/gdkdrawable.h gdk/gdkinternals.h gdk/gdkdraw.c
|
||||
gdk/gdkwindow.c gdk/gdkpixmap.c gdk/gdkpixbuf-render.c:
|
||||
- Add a new GdkDrawableClass vfunc _draw_pixbuf, and
|
||||
_gdk_draw_pixbuf() [ will be made public later ], to allow
|
||||
backends to accelerate drawing pixbufs.
|
||||
- Move the implementation of gdk_pixbuf_render_to_drawable_alpha()
|
||||
to be the default implementation.
|
||||
- Update docs for gdk_pixbuf_render_to_drawable_alpha().
|
||||
- Optimize the default implementation by using
|
||||
_gdk_image_copy_to_pixmap() and scratch shared images, and
|
||||
special casing the compositing.
|
||||
|
||||
* gdk/x11/gdkdrawable-x11.c: Accelerate _gdk_draw_pixbuf()
|
||||
with alpha using the RENDER extension.
|
||||
|
||||
* gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable):
|
||||
Optimize by _gdk_image_copy_to_pixmap() and scratch images.
|
||||
|
||||
* tests/testrgb.c: Add test for speed of alpha composition,
|
||||
reduce the number of iterations since alpha composition
|
||||
can be a bit slow.
|
||||
|
||||
* gdk/x11/gdkimage-x11.c gdk/gdkprivate-x11.h (_gdk_x11_image_get_shm_pixmap):
|
||||
Private function to get a ShmPixmap for an image, if possible.
|
||||
|
||||
2002-01-04 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* tests/testtreesort.c: Add my cool list of integers.
|
||||
|
555
gdk/gdkdraw.c
555
gdk/gdkdraw.c
@ -27,15 +27,34 @@
|
||||
#include "gdkdrawable.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkwindow.h"
|
||||
#include "gdk-pixbuf-private.h"
|
||||
#include "gdkpixbuf.h"
|
||||
|
||||
static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
static GdkRegion * gdk_drawable_real_get_visible_region (GdkDrawable *drawable);
|
||||
static GdkImage* gdk_drawable_real_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
static GdkRegion * gdk_drawable_real_get_visible_region (GdkDrawable *drawable);
|
||||
static void gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
static void gdk_drawable_class_init (GdkDrawableClass *klass);
|
||||
|
||||
@ -70,10 +89,12 @@ gdk_drawable_get_type (void)
|
||||
static void
|
||||
gdk_drawable_class_init (GdkDrawableClass *klass)
|
||||
{
|
||||
klass->get_image = gdk_drawable_real_get_image;
|
||||
klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
|
||||
/* Default implementation for clip and visible region is the same */
|
||||
klass->get_clip_region = gdk_drawable_real_get_visible_region;
|
||||
klass->get_visible_region = gdk_drawable_real_get_visible_region;
|
||||
klass->_draw_pixbuf = gdk_drawable_real_draw_pixbuf;
|
||||
}
|
||||
|
||||
/* Manipulation of drawables
|
||||
@ -529,6 +550,57 @@ gdk_draw_image (GdkDrawable *drawable,
|
||||
xdest, ydest, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_draw_pixbuf:
|
||||
* @drawable: Destination drawable.
|
||||
* @gc: a #GdkGC, used for clipping, or %NULL
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
* @src_x: Source X coordinate within pixbuf.
|
||||
* @src_y: Source Y coordinates within pixbuf.
|
||||
* @dest_x: Destination X coordinate within drawable.
|
||||
* @dest_y: Destination Y coordinate within drawable.
|
||||
* @width: Width of region to render, in pixels, or -1 to use pixbuf width.
|
||||
* @height: Height of region to render, in pixels, or -1 to use pixbuf height.
|
||||
* @dither: Dithering mode for GdkRGB.
|
||||
* @x_dither: X offset for dither.
|
||||
* @y_dither: Y offset for dither.
|
||||
*
|
||||
* Renders a rectangular portion of a pixbuf to a drawable. The destination
|
||||
* drawable must have a colormap. All windows have a colormap, however, pixmaps
|
||||
* only have colormap by default if they were created with a non-NULL window argument.
|
||||
* Otherwise a colormap must be set on them with gdk_drawable_set_colormap.
|
||||
*
|
||||
* On older X servers, rendering pixbufs with an alpha channel involves round trips
|
||||
* to the X server, and may be somewhat slow.
|
||||
**/
|
||||
void
|
||||
_gdk_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||||
g_return_if_fail (gc == NULL || GDK_IS_GC (gc));
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
if (width == -1)
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
if (height == -1)
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
GDK_DRAWABLE_GET_CLASS (drawable)->_draw_pixbuf (drawable, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y, width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_draw_points (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
@ -617,6 +689,80 @@ gdk_draw_glyphs (GdkDrawable *drawable,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _gdk_drawable_copy_to_image:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @image: a #GdkDrawable, or %NULL if a new @image should be created.
|
||||
* @src_x: x coordinate on @drawable
|
||||
* @src_y: y coordinate on @drawable
|
||||
* @dest_x: x coordinate within @image. Must be 0 if @image is %NULL
|
||||
* @dest_y: y coordinate within @image. Must be 0 if @image is %NULL
|
||||
* @width: width of region to get
|
||||
* @height: height or region to get
|
||||
*
|
||||
* Copies a portion of @drawable into the client side image structure
|
||||
* @image. If @image is %NULL, creates a new image of size @width x @height
|
||||
* and copies into that. See gdk_drawable_get_image() for further details.
|
||||
*
|
||||
* Return value: @image, or a new a #GdkImage containing the contents
|
||||
of @drawable
|
||||
**/
|
||||
GdkImage*
|
||||
_gdk_drawable_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkDrawable *composite;
|
||||
gint composite_x_offset = 0;
|
||||
gint composite_y_offset = 0;
|
||||
GdkImage *retval;
|
||||
GdkColormap *cmap;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
|
||||
g_return_val_if_fail (src_x >= 0, NULL);
|
||||
g_return_val_if_fail (src_y >= 0, NULL);
|
||||
|
||||
/* FIXME? Note race condition since we get the size then
|
||||
* get the image, and the size may have changed.
|
||||
*/
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
gdk_drawable_get_size (drawable,
|
||||
width < 0 ? &width : NULL,
|
||||
height < 0 ? &height : NULL);
|
||||
|
||||
composite =
|
||||
GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
&composite_x_offset,
|
||||
&composite_y_offset);
|
||||
|
||||
retval = GDK_DRAWABLE_GET_CLASS (composite)->_copy_to_image (composite,
|
||||
image,
|
||||
src_x - composite_x_offset,
|
||||
src_y - composite_y_offset,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
g_object_unref (G_OBJECT (composite));
|
||||
|
||||
if (!image && retval)
|
||||
{
|
||||
cmap = gdk_drawable_get_colormap (drawable);
|
||||
|
||||
if (cmap)
|
||||
gdk_image_set_colormap (retval, cmap);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drawable_get_image:
|
||||
* @drawable: a #GdkDrawable
|
||||
@ -705,6 +851,16 @@ gdk_drawable_get_image (GdkDrawable *drawable,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static GdkImage*
|
||||
gdk_drawable_real_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
return _gdk_drawable_copy_to_image (drawable, NULL, x, y, 0, 0, width, height);
|
||||
}
|
||||
|
||||
static GdkDrawable*
|
||||
gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
|
||||
gint x,
|
||||
@ -776,3 +932,386 @@ gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
|
||||
|
||||
return gdk_region_rectangle (&rect);
|
||||
}
|
||||
|
||||
static void
|
||||
composite (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guchar a = p[3];
|
||||
guint t;
|
||||
|
||||
t = a * p[0] + (255 - a) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[1] + (255 - a) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[2] + (255 - a) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
|
||||
p += 4;
|
||||
q += 3;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
composite_0888 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
if (dest_byte_order == GDK_LSB_FIRST)
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
|
||||
q[3] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
composite_565 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
gushort *q = (gushort *)dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guchar a = p[3];
|
||||
guint tr, tg, tb;
|
||||
guint tr1, tg1, tb1;
|
||||
guint tmp = *q;
|
||||
|
||||
#if 1
|
||||
/* This is fast, and corresponds to what composite() above does
|
||||
* if we converted to 8-bit first.
|
||||
*/
|
||||
tr = (tmp & 0xf800);
|
||||
tr1 = a * p[0] + (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
|
||||
tg = (tmp & 0x07e0);
|
||||
tg1 = a * p[1] + (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
|
||||
tb = (tmp & 0x001f);
|
||||
tb1 = a * p[2] + (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
|
||||
|
||||
*q = (((tr1 + (tr1 >> 8)) & 0xf800) |
|
||||
(((tg1 + (tg1 >> 8)) & 0xfc00) >> 5) |
|
||||
((tb1 + (tb1 >> 8)) >> 11));
|
||||
#else
|
||||
/* This version correspond to the result we get with XRENDER -
|
||||
* a bit of precision is lost since we convert to 8 bit after premultiplying
|
||||
* instead of at the end
|
||||
*/
|
||||
guint tr2, tg2, tb2;
|
||||
guint tr3, tg3, tb3;
|
||||
|
||||
tr = (tmp & 0xf800);
|
||||
tr1 = (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
|
||||
tr2 = a * p[0] + 0x80;
|
||||
tr3 = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8);
|
||||
|
||||
tg = (tmp & 0x07e0);
|
||||
tg1 = (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
|
||||
tg2 = a * p[0] + 0x80;
|
||||
tg3 = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8);
|
||||
|
||||
tb = (tmp & 0x001f);
|
||||
tb1 = (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
|
||||
tb2 = a * p[0] + 0x80;
|
||||
tb3 = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
|
||||
|
||||
*q = (((tr3 & 0xf8) << 8) |
|
||||
((tg3 & 0xfc) << 3) |
|
||||
((tb3 >> 3)));
|
||||
#endif
|
||||
|
||||
p += 4;
|
||||
q++;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
gboolean free_gc = FALSE;
|
||||
GdkPixbuf *composited = NULL;
|
||||
gint dwidth, dheight;
|
||||
GdkRegion *clip;
|
||||
GdkRegion *drect;
|
||||
GdkRectangle tmp_rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
|
||||
g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
|
||||
g_return_if_fail (pixbuf->bits_per_sample == 8);
|
||||
|
||||
g_return_if_fail (drawable != NULL);
|
||||
|
||||
if (width == -1)
|
||||
width = pixbuf->width;
|
||||
if (height == -1)
|
||||
height = pixbuf->height;
|
||||
|
||||
g_return_if_fail (width >= 0 && height >= 0);
|
||||
g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
|
||||
g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
|
||||
|
||||
/* Clip to the drawable; this is required for get_from_drawable() so
|
||||
* can't be done implicitly
|
||||
*/
|
||||
|
||||
if (dest_x < 0)
|
||||
{
|
||||
src_x -= dest_x;
|
||||
width += dest_x;
|
||||
dest_x = 0;
|
||||
}
|
||||
|
||||
if (dest_y < 0)
|
||||
{
|
||||
src_y -= dest_y;
|
||||
height += dest_y;
|
||||
dest_y = 0;
|
||||
}
|
||||
|
||||
gdk_drawable_get_size (drawable, &dwidth, &dheight);
|
||||
|
||||
if ((dest_x + width) > dwidth)
|
||||
width = dwidth - dest_x;
|
||||
|
||||
if ((dest_y + height) > dheight)
|
||||
height = dheight - dest_y;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
/* Clip to the clip region; this avoids getting more
|
||||
* image data from the server than we need to.
|
||||
*/
|
||||
|
||||
tmp_rect.x = dest_x;
|
||||
tmp_rect.y = dest_y;
|
||||
tmp_rect.width = width;
|
||||
tmp_rect.height = height;
|
||||
|
||||
drect = gdk_region_rectangle (&tmp_rect);
|
||||
clip = gdk_drawable_get_clip_region (drawable);
|
||||
|
||||
gdk_region_intersect (drect, clip);
|
||||
|
||||
gdk_region_get_clipbox (drect, &tmp_rect);
|
||||
|
||||
gdk_region_destroy (drect);
|
||||
gdk_region_destroy (clip);
|
||||
|
||||
if (tmp_rect.width == 0 ||
|
||||
tmp_rect.height == 0)
|
||||
return;
|
||||
|
||||
/* Actually draw */
|
||||
|
||||
if (!gc)
|
||||
{
|
||||
gc = gdk_gc_new (drawable);
|
||||
free_gc = TRUE;
|
||||
}
|
||||
|
||||
if (pixbuf->has_alpha)
|
||||
{
|
||||
GdkVisual *visual = gdk_drawable_get_visual (drawable);
|
||||
void (*composite_func) (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height) = NULL;
|
||||
|
||||
/* First we see if we have a visual-specific composition function that can composite
|
||||
* the pixbuf data directly onto the image
|
||||
*/
|
||||
if (visual)
|
||||
{
|
||||
gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (visual->depth);
|
||||
|
||||
if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
|
||||
visual->depth == 16 &&
|
||||
visual->red_mask == 0xf800 &&
|
||||
visual->green_mask == 0x07e0 &&
|
||||
visual->blue_mask == 0x001f)
|
||||
composite_func = composite_565;
|
||||
else if (visual->depth == 24 && bits_per_pixel == 32 &&
|
||||
visual->red_mask == 0xff0000 &&
|
||||
visual->green_mask == 0x00ff00 &&
|
||||
visual->blue_mask == 0x0000ff)
|
||||
composite_func = composite_0888;
|
||||
}
|
||||
|
||||
/* We can't use our composite func if we are required to dither
|
||||
*/
|
||||
if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
|
||||
{
|
||||
gint x0, y0;
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
GdkImage *image = _gdk_image_get_scratch (width1, height1, gdk_drawable_get_depth (drawable), &xs0, &ys0);
|
||||
|
||||
_gdk_drawable_copy_to_image (drawable, image,
|
||||
dest_x + x0, dest_y + y0,
|
||||
xs0, ys0,
|
||||
width1, height1);
|
||||
(*composite_func) (pixbuf->pixels + (src_y + y0) * pixbuf->rowstride + (src_x + x0) * 4,
|
||||
pixbuf->rowstride,
|
||||
image->mem + ys0 * image->bpl + xs0 * image->bpp,
|
||||
image->bpl,
|
||||
visual->byte_order,
|
||||
width1, height1);
|
||||
gdk_draw_image (drawable, gc, image,
|
||||
xs0, ys0,
|
||||
dest_x + x0, dest_y + y0,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No special composition func, convert dest to 24 bit RGB data, composite against
|
||||
* that, and convert back.
|
||||
*/
|
||||
composited = gdk_pixbuf_get_from_drawable (NULL,
|
||||
drawable,
|
||||
NULL,
|
||||
dest_x, dest_y,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
if (composited)
|
||||
composite (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
|
||||
pixbuf->rowstride,
|
||||
composited->pixels,
|
||||
composited->rowstride,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (composited)
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (composited,
|
||||
drawable, gc,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable, gc,
|
||||
src_x, src_y,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
|
||||
out:
|
||||
if (composited)
|
||||
g_object_unref (G_OBJECT (composited));
|
||||
|
||||
if (free_gc)
|
||||
gdk_gc_unref (gc);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkgc.h>
|
||||
#include <gdk/gdkrgb.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -130,7 +132,28 @@ struct _GdkDrawableClass
|
||||
gint height,
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
|
||||
|
||||
void (*_draw_pixbuf) (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
GdkImage* (*_copy_to_image) (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*_gdk_reserved1) (void);
|
||||
void (*_gdk_reserved2) (void);
|
||||
void (*_gdk_reserved3) (void);
|
||||
|
263
gdk/gdkimage.c
263
gdk/gdkimage.c
@ -27,8 +27,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "gdk.h" /* For gdk_flush() */
|
||||
#include "gdkimage.h"
|
||||
#include "gdkprivate.h"
|
||||
#include "gdkinternals.h" /* For scratch_image code */
|
||||
|
||||
/**
|
||||
* gdk_image_ref:
|
||||
@ -137,3 +139,264 @@ gdk_image_get_colormap (GdkImage *image)
|
||||
|
||||
return image->colormap;
|
||||
}
|
||||
|
||||
/* We have N_REGION GDK_SCRATCH_IMAGE_WIDTH x GDK_SCRATCH_IMAGE_HEIGHT regions divided
|
||||
* up between n_images different images. possible_n_images gives
|
||||
* various divisors of N_REGIONS. The reason for allowing this
|
||||
* flexibility is that we want to create as few images as possible,
|
||||
* but we want to deal with the abberant systems that have a SHMMAX
|
||||
* limit less than
|
||||
*
|
||||
* GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT * N_REGIONS * 4 (384k)
|
||||
*
|
||||
* (Are there any such?)
|
||||
*/
|
||||
#define N_REGIONS 6
|
||||
static const int possible_n_images[] = { 1, 2, 3, 6 };
|
||||
|
||||
/* We allocate one GdkScratchImageInfo structure for each
|
||||
* depth where we are allocating scratch images. (Future: one
|
||||
* per depth, per display)
|
||||
*/
|
||||
typedef struct _GdkScratchImageInfo GdkScratchImageInfo;
|
||||
|
||||
struct _GdkScratchImageInfo {
|
||||
gint depth;
|
||||
|
||||
gint n_images;
|
||||
GdkImage *static_image[N_REGIONS];
|
||||
gint static_image_idx;
|
||||
|
||||
/* In order to optimize filling fractions, we simultaneously fill in up
|
||||
* to three regions of size GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT: one
|
||||
* for images that are taller than GDK_SCRATCH_IMAGE_HEIGHT / 2, and must
|
||||
* be tiled horizontally. One for images that are wider than
|
||||
* GDK_SCRATCH_IMAGE_WIDTH / 2 and must be tiled vertically, and a third
|
||||
* for images smaller than GDK_SCRATCH_IMAGE_HEIGHT / 2 x GDK_SCRATCH_IMAGE_WIDTH x 2
|
||||
* that we tile in horizontal rows.
|
||||
*/
|
||||
gint horiz_idx;
|
||||
gint horiz_y;
|
||||
gint vert_idx;
|
||||
gint vert_x;
|
||||
|
||||
/* tile_y1 and tile_y2 define the horizontal band into
|
||||
* which we are tiling images. tile_x is the x extent to
|
||||
* which that is filled
|
||||
*/
|
||||
gint tile_idx;
|
||||
gint tile_x;
|
||||
gint tile_y1;
|
||||
gint tile_y2;
|
||||
};
|
||||
|
||||
static GSList *scratch_image_infos = NULL;
|
||||
|
||||
static gboolean
|
||||
allocate_scratch_images (GdkScratchImageInfo *info,
|
||||
gint n_images,
|
||||
gboolean shared)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_images; i++)
|
||||
{
|
||||
info->static_image[i] = _gdk_image_new_for_depth (shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
|
||||
NULL,
|
||||
GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), GDK_SCRATCH_IMAGE_HEIGHT,
|
||||
info->depth);
|
||||
|
||||
if (!info->static_image[i])
|
||||
{
|
||||
gint j;
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
gdk_image_unref (info->static_image[i]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GdkScratchImageInfo *
|
||||
scratch_image_info_for_depth (gint depth)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
GdkScratchImageInfo *image_info;
|
||||
gint i;
|
||||
|
||||
tmp_list = scratch_image_infos;
|
||||
while (tmp_list)
|
||||
{
|
||||
image_info = tmp_list->data;
|
||||
if (image_info->depth == depth)
|
||||
return image_info;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
image_info = g_new (GdkScratchImageInfo, 1);
|
||||
|
||||
image_info->depth = depth;
|
||||
|
||||
/* Try to allocate as few possible shared images */
|
||||
for (i=0; i < G_N_ELEMENTS (possible_n_images); i++)
|
||||
{
|
||||
if (allocate_scratch_images (image_info, possible_n_images[i], TRUE))
|
||||
{
|
||||
image_info->n_images = possible_n_images[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If that fails, just allocate N_REGIONS normal images */
|
||||
if (i == G_N_ELEMENTS (possible_n_images))
|
||||
{
|
||||
allocate_scratch_images (image_info, N_REGIONS, FALSE);
|
||||
image_info->n_images = N_REGIONS;
|
||||
}
|
||||
|
||||
image_info->static_image_idx = 0;
|
||||
|
||||
image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT;
|
||||
image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH;
|
||||
image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH;
|
||||
image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT;
|
||||
|
||||
scratch_image_infos = g_slist_prepend (scratch_image_infos, image_info);
|
||||
|
||||
return image_info;
|
||||
}
|
||||
|
||||
/* Defining NO_FLUSH can cause inconsistent screen updates, but is useful
|
||||
for performance evaluation. */
|
||||
|
||||
#undef NO_FLUSH
|
||||
|
||||
#ifdef VERBOSE
|
||||
static gint sincelast;
|
||||
#endif
|
||||
|
||||
static gint
|
||||
alloc_scratch_image (GdkScratchImageInfo *image_info)
|
||||
{
|
||||
if (image_info->static_image_idx == N_REGIONS)
|
||||
{
|
||||
#ifndef NO_FLUSH
|
||||
gdk_flush ();
|
||||
#endif
|
||||
#ifdef VERBOSE
|
||||
g_print ("flush, %d puts since last flush\n", sincelast);
|
||||
sincelast = 0;
|
||||
#endif
|
||||
image_info->static_image_idx = 0;
|
||||
|
||||
/* Mark all regions that we might be filling in as completely
|
||||
* full, to force new tiles to be allocated for subsequent
|
||||
* images
|
||||
*/
|
||||
image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT;
|
||||
image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH;
|
||||
image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH;
|
||||
image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT;
|
||||
}
|
||||
return image_info->static_image_idx++;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_image_get_scratch:
|
||||
* @width: desired width
|
||||
* @height: desired height
|
||||
* @depth: depth of image
|
||||
* @x: X location within returned image of scratch image
|
||||
* @y: Y location within returned image of scratch image
|
||||
*
|
||||
* Allocates an image of size width/height, up to a maximum
|
||||
* of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT
|
||||
*
|
||||
* Return value: a scratch image. This must be used by a
|
||||
* call to gdk_image_put() before any other calls to
|
||||
* _gdk_image_get_scratch()
|
||||
**/
|
||||
GdkImage *
|
||||
_gdk_image_get_scratch (gint width,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
GdkScratchImageInfo *image_info;
|
||||
GdkImage *image;
|
||||
gint idx;
|
||||
|
||||
image_info = scratch_image_info_for_depth (depth);
|
||||
|
||||
if (width >= (GDK_SCRATCH_IMAGE_WIDTH >> 1))
|
||||
{
|
||||
if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1))
|
||||
{
|
||||
idx = alloc_scratch_image (image_info);
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (height + image_info->horiz_y > GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
image_info->horiz_idx = alloc_scratch_image (image_info);
|
||||
image_info->horiz_y = 0;
|
||||
}
|
||||
idx = image_info->horiz_idx;
|
||||
*x = 0;
|
||||
*y = image_info->horiz_y;
|
||||
image_info->horiz_y += height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1))
|
||||
{
|
||||
if (width + image_info->vert_x > GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
image_info->vert_idx = alloc_scratch_image (image_info);
|
||||
image_info->vert_x = 0;
|
||||
}
|
||||
idx = image_info->vert_idx;
|
||||
*x = image_info->vert_x;
|
||||
*y = 0;
|
||||
/* using 3 and -4 would be slightly more efficient on 32-bit machines
|
||||
with > 1bpp displays */
|
||||
image_info->vert_x += (width + 7) & -8;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (width + image_info->tile_x > GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
image_info->tile_y1 = image_info->tile_y2;
|
||||
image_info->tile_x = 0;
|
||||
}
|
||||
if (height + image_info->tile_y1 > GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
image_info->tile_idx = alloc_scratch_image (image_info);
|
||||
image_info->tile_x = 0;
|
||||
image_info->tile_y1 = 0;
|
||||
image_info->tile_y2 = 0;
|
||||
}
|
||||
if (height + image_info->tile_y1 > image_info->tile_y2)
|
||||
image_info->tile_y2 = height + image_info->tile_y1;
|
||||
idx = image_info->tile_idx;
|
||||
*x = image_info->tile_x;
|
||||
*y = image_info->tile_y1;
|
||||
image_info->tile_x += (width + 7) & -8;
|
||||
}
|
||||
}
|
||||
image = image_info->static_image[idx * image_info->n_images / N_REGIONS];
|
||||
*x += GDK_SCRATCH_IMAGE_WIDTH * (idx % (N_REGIONS / image_info->n_images));
|
||||
#ifdef VERBOSE
|
||||
g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x, *y, width, height);
|
||||
sincelast++;
|
||||
#endif
|
||||
return image;
|
||||
}
|
||||
|
@ -158,6 +158,43 @@ void _gdk_event_queue_append (GdkEvent *event);
|
||||
|
||||
void _gdk_event_button_generate (GdkEvent *event);
|
||||
|
||||
#define GDK_SCRATCH_IMAGE_WIDTH 256
|
||||
#define GDK_SCRATCH_IMAGE_HEIGHT 64
|
||||
|
||||
GdkImage* _gdk_image_new_for_depth (GdkImageType type,
|
||||
GdkVisual *visual,
|
||||
gint width,
|
||||
gint height,
|
||||
gint depth);
|
||||
GdkImage *_gdk_image_get_scratch (gint width,
|
||||
gint height,
|
||||
gint depth,
|
||||
gint *x,
|
||||
gint *y);
|
||||
|
||||
/* Will most likely be exported in the future
|
||||
*/
|
||||
void _gdk_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
GdkImage *_gdk_drawable_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
/*************************************
|
||||
* Interfaces used by windowing code *
|
||||
*************************************/
|
||||
@ -204,6 +241,11 @@ GdkWindow* _gdk_windowing_window_get_pointer (GdkWindow *window,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
|
||||
/* Return the number of bits-per-pixel for images of the specified depth.
|
||||
* (Future: needs to be GdkDiplay specific.)
|
||||
*/
|
||||
gint _gdk_windowing_get_bits_for_depth (gint depth);
|
||||
|
||||
#define GDK_WINDOW_IS_MAPPED(window) ((((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
|
||||
|
||||
/* Called before processing updates for a window. This gives the windowing
|
||||
|
@ -72,7 +72,7 @@ bitmap1 (GdkImage *image,
|
||||
int bpl;
|
||||
register guint8 data;
|
||||
guint8 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl, *orow = pixels;
|
||||
|
||||
d (printf ("bitmap, no alpha\n"));
|
||||
|
||||
@ -128,7 +128,7 @@ bitmap1a (GdkImage *image,
|
||||
int bpl;
|
||||
register guint8 data;
|
||||
guint8 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl, *orow = pixels;
|
||||
|
||||
d (printf ("bitmap, with alpha\n"));
|
||||
|
||||
@ -183,7 +183,7 @@ rgb1 (GdkImage *image,
|
||||
int bpl;
|
||||
register guint8 data;
|
||||
guint8 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl, *orow = pixels;
|
||||
|
||||
d (printf ("1 bits/pixel\n"));
|
||||
|
||||
@ -231,7 +231,7 @@ rgb1a (GdkImage *image,
|
||||
int bpl;
|
||||
register guint8 data;
|
||||
guint8 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl, *orow = pixels;
|
||||
|
||||
d (printf ("1 bits/pixel\n"));
|
||||
|
||||
@ -279,7 +279,7 @@ rgb8 (GdkImage *image,
|
||||
int bpl;
|
||||
guint32 mask;
|
||||
register guint32 data;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
register guint8 *s;
|
||||
register guint8 *o;
|
||||
|
||||
@ -326,7 +326,7 @@ rgb8a (GdkImage *image,
|
||||
guint32 remap[256];
|
||||
register guint8 *s; /* read 2 pixels at once */
|
||||
register guint32 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -387,7 +387,7 @@ rgb565lsb (GdkImage *image,
|
||||
register guint8 *s; /* read 2 pixels at once */
|
||||
#endif
|
||||
register guint16 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -490,7 +490,7 @@ rgb565msb (GdkImage *image,
|
||||
register guint32 *s; /* read 2 pixels at once */
|
||||
#endif
|
||||
register guint16 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -596,7 +596,7 @@ rgb565alsb (GdkImage *image,
|
||||
#endif
|
||||
register guint32 *o;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -659,7 +659,7 @@ rgb565amsb (GdkImage *image,
|
||||
#endif
|
||||
register guint32 *o;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -717,7 +717,7 @@ rgb555lsb (GdkImage *image,
|
||||
register guint8 *s; /* read 2 pixels at once */
|
||||
#endif
|
||||
register guint16 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -821,7 +821,7 @@ rgb555msb (GdkImage *image,
|
||||
register guint32 *s; /* read 2 pixels at once */
|
||||
#endif
|
||||
register guint16 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -922,7 +922,7 @@ rgb555alsb (GdkImage *image,
|
||||
#endif
|
||||
register guint32 *o;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -985,7 +985,7 @@ rgb555amsb (GdkImage *image,
|
||||
#endif
|
||||
register guint32 *o;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -1039,7 +1039,7 @@ rgb888alsb (GdkImage *image,
|
||||
|
||||
guint8 *s; /* for byte order swapping */
|
||||
guint8 *o;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
|
||||
bpl = image->bpl;
|
||||
|
||||
@ -1076,7 +1076,7 @@ rgb888lsb (GdkImage *image,
|
||||
int xx, yy;
|
||||
int bpl;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
guint8 *o, *s;
|
||||
|
||||
bpl = image->bpl;
|
||||
@ -1112,7 +1112,7 @@ rgb888amsb (GdkImage *image,
|
||||
int xx, yy;
|
||||
int bpl;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
#ifdef LITTLE
|
||||
guint32 *o;
|
||||
guint32 *s;
|
||||
@ -1166,7 +1166,7 @@ rgb888msb (GdkImage *image,
|
||||
int xx, yy;
|
||||
int bpl;
|
||||
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *srow = image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels;
|
||||
guint8 *s;
|
||||
guint8 *o;
|
||||
|
||||
@ -1207,8 +1207,7 @@ convert_real_slow (GdkImage *image,
|
||||
{
|
||||
int xx, yy;
|
||||
int bpl;
|
||||
guint8 *srow = image->mem, *orow = pixels;
|
||||
guint8 *s;
|
||||
guint8 *orow = pixels;
|
||||
guint8 *o;
|
||||
guint32 pixel;
|
||||
GdkVisual *v;
|
||||
@ -1225,7 +1224,6 @@ convert_real_slow (GdkImage *image,
|
||||
|
||||
for (yy = y1; yy < y2; yy++)
|
||||
{
|
||||
s = srow;
|
||||
o = orow;
|
||||
for (xx = x1; xx < x2; xx++)
|
||||
{
|
||||
@ -1268,7 +1266,6 @@ convert_real_slow (GdkImage *image,
|
||||
if (alpha)
|
||||
*o++ = 0xff;
|
||||
}
|
||||
srow += bpl;
|
||||
orow += rowstride;
|
||||
}
|
||||
}
|
||||
@ -1481,6 +1478,7 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
|
||||
int src_width, src_height;
|
||||
GdkImage *image;
|
||||
int depth;
|
||||
int x0, y0;
|
||||
|
||||
/* General sanity checks */
|
||||
|
||||
@ -1503,6 +1501,14 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
|
||||
g_return_val_if_fail (dest->bits_per_sample == 8, NULL);
|
||||
}
|
||||
|
||||
/* Create the pixbuf if needed */
|
||||
if (!dest)
|
||||
{
|
||||
dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
|
||||
if (dest == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cmap == NULL)
|
||||
cmap = gdk_drawable_get_colormap (src);
|
||||
|
||||
@ -1536,19 +1542,28 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
|
||||
g_return_val_if_fail (dest_x + width <= dest->width, NULL);
|
||||
g_return_val_if_fail (dest_y + height <= dest->height, NULL);
|
||||
}
|
||||
|
||||
/* Get Image in ZPixmap format (packed bits). */
|
||||
image = gdk_image_get (src, src_x, src_y, width, height);
|
||||
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
|
||||
dest = gdk_pixbuf_get_from_image (dest, image, cmap,
|
||||
0, 0, dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
gdk_image_destroy (image);
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
image = _gdk_image_get_scratch (width1, height1, depth, &xs0, &ys0);
|
||||
|
||||
_gdk_drawable_copy_to_image (src, image,
|
||||
src_x + x0, src_y + y0,
|
||||
xs0, ys0, width1, height1);
|
||||
|
||||
gdk_pixbuf_get_from_image (dest, image, cmap,
|
||||
xs0, ys0, dest_x + x0, dest_y + y0,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
@ -1638,8 +1653,8 @@ gdk_pixbuf_get_from_image (GdkPixbuf *dest,
|
||||
rowstride,
|
||||
alpha,
|
||||
src_x, src_y,
|
||||
src_x + width,
|
||||
src_y + height,
|
||||
width,
|
||||
height,
|
||||
cmap);
|
||||
|
||||
return dest;
|
||||
|
@ -237,30 +237,19 @@ gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf,
|
||||
* @dest_y: Destination Y coordinate within drawable.
|
||||
* @width: Width of region to render, in pixels, or -1 to use pixbuf width.
|
||||
* @height: Height of region to render, in pixels, or -1 to use pixbuf height.
|
||||
* @alpha_mode: If the image does not have opacity information, this is ignored.
|
||||
* Otherwise, specifies how to handle transparency when rendering.
|
||||
* @alpha_threshold: If the image does have opacity information and @alpha_mode
|
||||
* is GDK_PIXBUF_ALPHA_BILEVEL, specifies the threshold value for opacity
|
||||
* values.
|
||||
* @alpha_mode: Ignored. Present for backwards compatibility.
|
||||
* @alpha_threshold: Ignored. Present for backwards compatibility
|
||||
* @dither: Dithering mode for GdkRGB.
|
||||
* @x_dither: X offset for dither.
|
||||
* @y_dither: Y offset for dither.
|
||||
*
|
||||
* Renders a rectangular portion of a pixbuf to a drawable. This is done using
|
||||
* GdkRGB, so the specified drawable must have the GdkRGB visual and colormap.
|
||||
* Renders a rectangular portion of a pixbuf to a drawable. The destination
|
||||
* drawable must have a colormap. All windows have a colormap, however, pixmaps
|
||||
* only have colormap by default if they were created with a non-NULL window argument.
|
||||
* Otherwise a colormap must be set on them with gdk_drawable_set_colormap.
|
||||
*
|
||||
* When used with #GDK_PIXBUF_ALPHA_BILEVEL, this function has to create a bitmap
|
||||
* out of the thresholded alpha channel of the image and, it has to set this
|
||||
* bitmap as the clipping mask for the GC used for drawing. This can be a
|
||||
* significant performance penalty depending on the size and the complexity of
|
||||
* the alpha channel of the image. If performance is crucial, consider handling
|
||||
* the alpha channel yourself (possibly by caching it in your application) and
|
||||
* using gdk_pixbuf_render_to_drawable() or GdkRGB directly instead.
|
||||
*
|
||||
* The #GDK_PIXBUF_ALPHA_FULL mode involves round trips to the X
|
||||
* server, and may also be somewhat slow in its current implementation
|
||||
* (though in the future it could be made significantly faster, in
|
||||
* principle).
|
||||
* On older X servers, rendering pixbufs with an alpha channel involves round trips
|
||||
* to the X server, and may be somewhat slow.
|
||||
**/
|
||||
void
|
||||
gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf,
|
||||
@ -273,165 +262,9 @@ gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf,
|
||||
GdkRgbDither dither,
|
||||
int x_dither, int y_dither)
|
||||
{
|
||||
GdkBitmap *bitmap = NULL;
|
||||
GdkGC *gc;
|
||||
GdkPixbuf *composited = NULL;
|
||||
gint dwidth, dheight;
|
||||
GdkRegion *clip;
|
||||
GdkRegion *drect;
|
||||
GdkRectangle tmp_rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
|
||||
g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
|
||||
g_return_if_fail (pixbuf->bits_per_sample == 8);
|
||||
|
||||
g_return_if_fail (drawable != NULL);
|
||||
|
||||
if (width == -1)
|
||||
width = pixbuf->width;
|
||||
if (height == -1)
|
||||
height = pixbuf->height;
|
||||
|
||||
g_return_if_fail (width >= 0 && height >= 0);
|
||||
g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
|
||||
g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
|
||||
|
||||
/* Clip to the drawable; this is required for get_from_drawable() so
|
||||
* can't be done implicitly
|
||||
*/
|
||||
|
||||
if (dest_x < 0)
|
||||
{
|
||||
src_x -= dest_x;
|
||||
width += dest_x;
|
||||
dest_x = 0;
|
||||
}
|
||||
|
||||
if (dest_y < 0)
|
||||
{
|
||||
src_y -= dest_y;
|
||||
height += dest_y;
|
||||
dest_y = 0;
|
||||
}
|
||||
|
||||
gdk_drawable_get_size (drawable, &dwidth, &dheight);
|
||||
|
||||
if ((dest_x + width) > dwidth)
|
||||
width = dwidth - dest_x;
|
||||
|
||||
if ((dest_y + height) > dheight)
|
||||
height = dheight - dest_y;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
/* Clip to the clip region; this avoids getting more
|
||||
* image data from the server than we need to.
|
||||
*/
|
||||
|
||||
tmp_rect.x = dest_x;
|
||||
tmp_rect.y = dest_y;
|
||||
tmp_rect.width = width;
|
||||
tmp_rect.height = height;
|
||||
|
||||
drect = gdk_region_rectangle (&tmp_rect);
|
||||
clip = gdk_drawable_get_clip_region (drawable);
|
||||
|
||||
gdk_region_intersect (drect, clip);
|
||||
|
||||
gdk_region_get_clipbox (drect, &tmp_rect);
|
||||
|
||||
gdk_region_destroy (drect);
|
||||
gdk_region_destroy (clip);
|
||||
|
||||
if (tmp_rect.width == 0 ||
|
||||
tmp_rect.height == 0)
|
||||
return;
|
||||
|
||||
/* Actually draw */
|
||||
|
||||
gc = gdk_gc_new (drawable);
|
||||
|
||||
if (pixbuf->has_alpha)
|
||||
{
|
||||
if (alpha_mode == GDK_PIXBUF_ALPHA_FULL)
|
||||
{
|
||||
GdkPixbuf *sub = NULL;
|
||||
|
||||
composited = gdk_pixbuf_get_from_drawable (NULL,
|
||||
drawable,
|
||||
NULL,
|
||||
dest_x, dest_y,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
if (composited)
|
||||
{
|
||||
if (src_x != 0 || src_y != 0)
|
||||
{
|
||||
sub = gdk_pixbuf_new_subpixbuf (pixbuf, src_x, src_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
gdk_pixbuf_composite (sub ? sub : pixbuf,
|
||||
composited,
|
||||
0, 0,
|
||||
width, height,
|
||||
0, 0,
|
||||
1.0, 1.0,
|
||||
GDK_INTERP_BILINEAR,
|
||||
255);
|
||||
|
||||
if (sub)
|
||||
g_object_unref (G_OBJECT (sub));
|
||||
}
|
||||
else
|
||||
alpha_mode = GDK_PIXBUF_ALPHA_BILEVEL; /* fall back */
|
||||
}
|
||||
|
||||
if (alpha_mode == GDK_PIXBUF_ALPHA_BILEVEL)
|
||||
{
|
||||
bitmap = gdk_pixmap_new (NULL, width, height, 1);
|
||||
gdk_pixbuf_render_threshold_alpha (pixbuf, bitmap,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
width, height,
|
||||
alpha_threshold);
|
||||
|
||||
gdk_gc_set_clip_mask (gc, bitmap);
|
||||
gdk_gc_set_clip_origin (gc, dest_x, dest_y);
|
||||
}
|
||||
}
|
||||
|
||||
if (composited)
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (composited,
|
||||
drawable, gc,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable, gc,
|
||||
src_x, src_y,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
|
||||
if (bitmap)
|
||||
gdk_bitmap_unref (bitmap);
|
||||
|
||||
if (composited)
|
||||
g_object_unref (G_OBJECT (composited));
|
||||
|
||||
gdk_gc_unref (gc);
|
||||
_gdk_draw_pixbuf (drawable, NULL, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y, width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -531,5 +364,3 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
|
||||
*mask_return = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,16 +102,32 @@ static void gdk_pixmap_draw_image (GdkDrawable *drawable,
|
||||
gint ydest,
|
||||
gint width,
|
||||
gint height);
|
||||
static void gdk_pixmap_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
|
||||
static void gdk_pixmap_real_get_size (GdkDrawable *drawable,
|
||||
gint *width,
|
||||
gint *height);
|
||||
|
||||
static GdkImage* gdk_pixmap_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable);
|
||||
static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable);
|
||||
@ -182,12 +198,13 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
|
||||
drawable_class->draw_lines = gdk_pixmap_draw_lines;
|
||||
drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs;
|
||||
drawable_class->draw_image = gdk_pixmap_draw_image;
|
||||
drawable_class->_draw_pixbuf = gdk_pixmap_draw_pixbuf;
|
||||
drawable_class->get_depth = gdk_pixmap_real_get_depth;
|
||||
drawable_class->get_size = gdk_pixmap_real_get_size;
|
||||
drawable_class->set_colormap = gdk_pixmap_real_set_colormap;
|
||||
drawable_class->get_colormap = gdk_pixmap_real_get_colormap;
|
||||
drawable_class->get_visual = gdk_pixmap_real_get_visual;
|
||||
drawable_class->get_image = gdk_pixmap_get_image;
|
||||
drawable_class->_copy_to_image = gdk_pixmap_copy_to_image;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -366,6 +383,27 @@ gdk_pixmap_draw_image (GdkDrawable *drawable,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixmap_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkPixmapObject *private = (GdkPixmapObject *)drawable;
|
||||
|
||||
_gdk_draw_pixbuf (private->impl, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y, width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixmap_real_get_size (GdkDrawable *drawable,
|
||||
gint *width,
|
||||
@ -418,16 +456,21 @@ gdk_pixmap_real_get_colormap (GdkDrawable *drawable)
|
||||
}
|
||||
|
||||
static GdkImage*
|
||||
gdk_pixmap_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_pixmap_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL);
|
||||
|
||||
return gdk_drawable_get_image (((GdkPixmapObject*)drawable)->impl,
|
||||
x, y, width, height);
|
||||
return _gdk_drawable_copy_to_image (((GdkPixmapObject*)drawable)->impl,
|
||||
image,
|
||||
src_x, src_y, dest_x, dest_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static GdkBitmap *
|
||||
|
259
gdk/gdkrgb.c
259
gdk/gdkrgb.c
@ -46,22 +46,10 @@
|
||||
|
||||
#define ENABLE_GRAYSCALE
|
||||
|
||||
#ifdef GDK_RGB_STANDALONE
|
||||
|
||||
/* Compiling as a standalone module (i.e. with Gtk 1.0) */
|
||||
/* gtk/gtk.h is already included in gdkrgbstub.c */
|
||||
#include "config.h"
|
||||
#include <gdk/gdkprivate.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Compiling as a part of Gtk 1.1 or later */
|
||||
#include "config.h"
|
||||
#include "gdkprivate.h"
|
||||
#include "gdkinternals.h" /* _gdk_windowing_get_bits_for_depth() */
|
||||
|
||||
#endif
|
||||
|
||||
#include "gdk.h" /* For gdk_flush() */
|
||||
#include "gdkrgb.h"
|
||||
|
||||
typedef struct _GdkRgbInfo GdkRgbInfo;
|
||||
@ -84,30 +72,10 @@ static const gchar* visual_names[] =
|
||||
"direct color",
|
||||
};
|
||||
|
||||
#define REGION_WIDTH 256
|
||||
#define STAGE_ROWSTRIDE (REGION_WIDTH * 3)
|
||||
#define REGION_HEIGHT 64
|
||||
#define STAGE_ROWSTRIDE (GDK_SCRATCH_IMAGE_WIDTH * 3)
|
||||
|
||||
/* We have N_REGION REGION_WIDTH x REGION_HEIGHT regions divided
|
||||
* up between n_images different images. possible_n_images gives
|
||||
* various divisors of N_REGIONS. The reason for allowing this
|
||||
* flexibility is that we want to create as few images as possible,
|
||||
* but we want to deal with the abberant systems that have a SHMMAX
|
||||
* limit less than
|
||||
*
|
||||
* REGION_WIDTH * REGION_HEIGHT * N_REGIONS * 4 (384k)
|
||||
*
|
||||
* (Are there any such?)
|
||||
/* Some of these fields should go, as they're not being used at all. (?)
|
||||
*/
|
||||
#define N_REGIONS 6
|
||||
static const int possible_n_images[] = { 1, 2, 3, 6 };
|
||||
|
||||
/* Some of these fields should go, as they're not being used at all.
|
||||
Globals should generally migrate into here - it's very likely that
|
||||
we'll want to run more than one GdkRgbInfo context at the same time
|
||||
(i.e. some but not all windows have privately installed
|
||||
colormaps). */
|
||||
|
||||
struct _GdkRgbInfo
|
||||
{
|
||||
GdkVisual *visual;
|
||||
@ -147,32 +115,6 @@ struct _GdkRgbInfo
|
||||
GdkRgbConvFunc conv_indexed;
|
||||
GdkRgbConvFunc conv_indexed_d;
|
||||
|
||||
gint n_images;
|
||||
GdkImage *static_image[N_REGIONS];
|
||||
gint static_image_idx;
|
||||
|
||||
/* In order to optimize filling fractions, we simultaneously fill in up
|
||||
* to three regions of size REGION_WIDTH * REGION_HEIGHT: one
|
||||
* for images that are taller than REGION_HEIGHT / 2, and must
|
||||
* be tiled horizontally. One for images that are wider than
|
||||
* REGION_WIDTH / 2 and must be tiled vertically, and a third
|
||||
* for images smaller than REGION_HEIGHT / 2 x REGION_WIDTH x 2
|
||||
* that we tile in horizontal rows.
|
||||
*/
|
||||
gint horiz_idx;
|
||||
gint horiz_y;
|
||||
gint vert_idx;
|
||||
gint vert_x;
|
||||
|
||||
/* tile_y1 and tile_y2 define the horizontal band into
|
||||
* which we are tiling images. tile_x is the x extent to
|
||||
* which that is filled
|
||||
*/
|
||||
gint tile_idx;
|
||||
gint tile_x;
|
||||
gint tile_y1;
|
||||
gint tile_y2;
|
||||
|
||||
guchar *colorcube;
|
||||
guchar *colorcube_d;
|
||||
|
||||
@ -562,7 +504,7 @@ gdk_rgb_choose_visual (void)
|
||||
return best_visual;
|
||||
}
|
||||
|
||||
static void gdk_rgb_select_conv (GdkRgbInfo *image_info, GdkImage *image);
|
||||
static void gdk_rgb_select_conv (GdkRgbInfo *image_info);
|
||||
|
||||
static void
|
||||
gdk_rgb_set_gray_cmap (GdkRgbInfo *image_info,
|
||||
@ -606,39 +548,10 @@ gdk_rgb_set_gray_cmap (GdkRgbInfo *image_info,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_rgb_allocate_images (GdkRgbInfo *image_info,
|
||||
gint n_images,
|
||||
gboolean shared)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_images; i++)
|
||||
{
|
||||
image_info->static_image[i] = gdk_image_new (shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
|
||||
image_info->visual,
|
||||
REGION_WIDTH * (N_REGIONS / n_images), REGION_HEIGHT);
|
||||
|
||||
if (!image_info->static_image[i])
|
||||
{
|
||||
gint j;
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
gdk_image_unref (image_info->static_image[i]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_rgb_free_info (GdkRgbInfo *image_info)
|
||||
{
|
||||
gint i;
|
||||
GSList *tmp_list;
|
||||
|
||||
|
||||
if (image_info->stage_buf)
|
||||
g_free (image_info->stage_buf);
|
||||
@ -649,9 +562,6 @@ gdk_rgb_free_info (GdkRgbInfo *image_info)
|
||||
if (image_info->own_gc)
|
||||
gdk_gc_unref (image_info->own_gc);
|
||||
|
||||
for (i = 0; i < image_info->n_images; i++)
|
||||
gdk_image_unref (image_info->static_image[i]);
|
||||
|
||||
if (image_info->colorcube)
|
||||
g_free (image_info->colorcube);
|
||||
|
||||
@ -679,7 +589,6 @@ static GdkRgbInfo *
|
||||
gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
|
||||
{
|
||||
GdkRgbInfo *image_info;
|
||||
gint i;
|
||||
|
||||
image_info = g_new0 (GdkRgbInfo, 1);
|
||||
|
||||
@ -765,33 +674,9 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
|
||||
|
||||
image_info->bitmap = (image_info->visual->depth == 1);
|
||||
|
||||
/* Try to allocate as few possible shared images */
|
||||
for (i=0; i < G_N_ELEMENTS (possible_n_images); i++)
|
||||
{
|
||||
if (gdk_rgb_allocate_images (image_info, possible_n_images[i], TRUE))
|
||||
{
|
||||
image_info->n_images = possible_n_images[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
image_info->bpp = (_gdk_windowing_get_bits_for_depth (image_info->visual->depth) + 7) / 8;
|
||||
|
||||
/* If that fails, just allocate N_REGIONS normal images */
|
||||
if (i == G_N_ELEMENTS (possible_n_images))
|
||||
{
|
||||
gdk_rgb_allocate_images (image_info, N_REGIONS, FALSE);
|
||||
image_info->n_images = N_REGIONS;
|
||||
}
|
||||
|
||||
image_info->bpp = image_info->static_image[0]->bpp;
|
||||
|
||||
image_info->static_image_idx = 0;
|
||||
|
||||
image_info->horiz_y = REGION_HEIGHT;
|
||||
image_info->vert_x = REGION_WIDTH;
|
||||
image_info->tile_x = REGION_WIDTH;
|
||||
image_info->tile_y1 = image_info->tile_y2 = REGION_HEIGHT;
|
||||
|
||||
gdk_rgb_select_conv (image_info, image_info->static_image[0]);
|
||||
gdk_rgb_select_conv (image_info);
|
||||
|
||||
if (!gdk_rgb_quark)
|
||||
gdk_rgb_quark = g_quark_from_static_string (gdk_rgb_key);
|
||||
@ -1415,7 +1300,7 @@ gdk_rgb_convert_gray8_gray (GdkRgbInfo *image_info, GdkImage *image,
|
||||
#ifdef HAIRY_CONVERT_565
|
||||
/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
|
||||
This assumes native byte ordering - what should really be done is to
|
||||
check whether static_image->byte_order is consistent with the _ENDIAN
|
||||
check whether the the image byte_order is consistent with the _ENDIAN
|
||||
config flag, and if not, use a different function.
|
||||
|
||||
This one is even faster than the one below - its inner loop loads 3
|
||||
@ -1499,7 +1384,7 @@ gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image,
|
||||
#else
|
||||
/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
|
||||
This assumes native byte ordering - what should really be done is to
|
||||
check whether static_image->byte_order is consistent with the _ENDIAN
|
||||
check whether the image byte_order is consistent with the _ENDIAN
|
||||
config flag, and if not, use a different function.
|
||||
|
||||
This routine is faster than the one included with Gtk 1.0 for a number
|
||||
@ -2670,7 +2555,7 @@ static guchar *
|
||||
gdk_rgb_ensure_stage (GdkRgbInfo *image_info)
|
||||
{
|
||||
if (image_info->stage_buf == NULL)
|
||||
image_info->stage_buf = g_malloc (REGION_HEIGHT * STAGE_ROWSTRIDE);
|
||||
image_info->stage_buf = g_malloc (GDK_SCRATCH_IMAGE_HEIGHT * STAGE_ROWSTRIDE);
|
||||
return image_info->stage_buf;
|
||||
}
|
||||
|
||||
@ -2873,7 +2758,7 @@ gdk_rgb_convert_indexed_generic_d (GdkRgbInfo *image_info, GdkImage *image,
|
||||
/* Select a conversion function based on the visual and a
|
||||
representative image. */
|
||||
static void
|
||||
gdk_rgb_select_conv (GdkRgbInfo *image_info, GdkImage *image)
|
||||
gdk_rgb_select_conv (GdkRgbInfo *image_info)
|
||||
{
|
||||
GdkByteOrder byte_order;
|
||||
gint depth, bpp, byterev;
|
||||
@ -2887,9 +2772,9 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info, GdkImage *image)
|
||||
|
||||
depth = image_info->visual->depth;
|
||||
|
||||
bpp = image->bits_per_pixel;
|
||||
bpp = _gdk_windowing_get_bits_for_depth (image_info->visual->depth);
|
||||
|
||||
byte_order = image->byte_order;
|
||||
byte_order = image_info->visual->byte_order;
|
||||
if (gdk_rgb_verbose)
|
||||
g_print ("Chose visual type=%s depth=%d, image bpp=%d, %s first\n",
|
||||
visual_names[image_info->visual->type], image_info->visual->depth,
|
||||
@ -3066,116 +2951,6 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info, GdkImage *image)
|
||||
image_info->conv_indexed_d = conv_indexed_d;
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
static gint sincelast;
|
||||
#endif
|
||||
|
||||
/* Defining NO_FLUSH can cause inconsistent screen updates, but is useful
|
||||
for performance evaluation. */
|
||||
|
||||
#undef NO_FLUSH
|
||||
|
||||
static gint
|
||||
gdk_rgb_alloc_scratch_image (GdkRgbInfo *image_info)
|
||||
{
|
||||
if (image_info->static_image_idx == N_REGIONS)
|
||||
{
|
||||
#ifndef NO_FLUSH
|
||||
gdk_flush ();
|
||||
#endif
|
||||
#ifdef VERBOSE
|
||||
g_print ("flush, %d puts since last flush\n", sincelast);
|
||||
sincelast = 0;
|
||||
#endif
|
||||
image_info->static_image_idx = 0;
|
||||
|
||||
/* Mark all regions that we might be filling in as completely
|
||||
* full, to force new tiles to be allocated for subsequent
|
||||
* images
|
||||
*/
|
||||
image_info->horiz_y = REGION_HEIGHT;
|
||||
image_info->vert_x = REGION_WIDTH;
|
||||
image_info->tile_x = REGION_WIDTH;
|
||||
image_info->tile_y1 = image_info->tile_y2 = REGION_HEIGHT;
|
||||
}
|
||||
return image_info->static_image_idx++;
|
||||
}
|
||||
|
||||
static GdkImage *
|
||||
gdk_rgb_alloc_scratch (GdkRgbInfo *image_info,
|
||||
gint width, gint height, gint *x0, gint *y0)
|
||||
{
|
||||
GdkImage *image;
|
||||
gint idx;
|
||||
|
||||
if (width >= (REGION_WIDTH >> 1))
|
||||
{
|
||||
if (height >= (REGION_HEIGHT >> 1))
|
||||
{
|
||||
idx = gdk_rgb_alloc_scratch_image (image_info);
|
||||
*x0 = 0;
|
||||
*y0 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (height + image_info->horiz_y > REGION_HEIGHT)
|
||||
{
|
||||
image_info->horiz_idx = gdk_rgb_alloc_scratch_image (image_info);
|
||||
image_info->horiz_y = 0;
|
||||
}
|
||||
idx = image_info->horiz_idx;
|
||||
*x0 = 0;
|
||||
*y0 = image_info->horiz_y;
|
||||
image_info->horiz_y += height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (height >= (REGION_HEIGHT >> 1))
|
||||
{
|
||||
if (width + image_info->vert_x > REGION_WIDTH)
|
||||
{
|
||||
image_info->vert_idx = gdk_rgb_alloc_scratch_image (image_info);
|
||||
image_info->vert_x = 0;
|
||||
}
|
||||
idx = image_info->vert_idx;
|
||||
*x0 = image_info->vert_x;
|
||||
*y0 = 0;
|
||||
/* using 3 and -4 would be slightly more efficient on 32-bit machines
|
||||
with > 1bpp displays */
|
||||
image_info->vert_x += (width + 7) & -8;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (width + image_info->tile_x > REGION_WIDTH)
|
||||
{
|
||||
image_info->tile_y1 = image_info->tile_y2;
|
||||
image_info->tile_x = 0;
|
||||
}
|
||||
if (height + image_info->tile_y1 > REGION_HEIGHT)
|
||||
{
|
||||
image_info->tile_idx = gdk_rgb_alloc_scratch_image (image_info);
|
||||
image_info->tile_x = 0;
|
||||
image_info->tile_y1 = 0;
|
||||
image_info->tile_y2 = 0;
|
||||
}
|
||||
if (height + image_info->tile_y1 > image_info->tile_y2)
|
||||
image_info->tile_y2 = height + image_info->tile_y1;
|
||||
idx = image_info->tile_idx;
|
||||
*x0 = image_info->tile_x;
|
||||
*y0 = image_info->tile_y1;
|
||||
image_info->tile_x += (width + 7) & -8;
|
||||
}
|
||||
}
|
||||
image = image_info->static_image[idx * image_info->n_images / N_REGIONS];
|
||||
*x0 += REGION_WIDTH * (idx % (N_REGIONS / image_info->n_images));
|
||||
#ifdef VERBOSE
|
||||
g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x0, *y0, width, height);
|
||||
sincelast++;
|
||||
#endif
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_rgb_image_core (GdkRgbInfo *image_info,
|
||||
GdkDrawable *drawable,
|
||||
@ -3212,15 +2987,15 @@ gdk_draw_rgb_image_core (GdkRgbInfo *image_info,
|
||||
}
|
||||
gc = image_info->own_gc;
|
||||
}
|
||||
for (y0 = 0; y0 < height; y0 += REGION_HEIGHT)
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
height1 = MIN (height - y0, REGION_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += REGION_WIDTH)
|
||||
height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
width1 = MIN (width - x0, REGION_WIDTH);
|
||||
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
buf_ptr = buf + y0 * rowstride + x0 * pixstride;
|
||||
|
||||
image = gdk_rgb_alloc_scratch (image_info, width1, height1, &xs0, &ys0);
|
||||
image = _gdk_image_get_scratch (width1, height1, image_info->visual->depth, &xs0, &ys0);
|
||||
|
||||
conv (image_info, image, xs0, ys0, width1, height1, buf_ptr, rowstride,
|
||||
x + x0 + xdith, y + y0 + ydith, cmap);
|
||||
|
110
gdk/gdkwindow.c
110
gdk/gdkwindow.c
@ -126,12 +126,27 @@ static void gdk_window_draw_image (GdkDrawable *drawable,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static GdkImage* gdk_window_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
static void gdk_window_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static void gdk_window_real_get_size (GdkDrawable *drawable,
|
||||
gint *width,
|
||||
@ -223,12 +238,13 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
||||
drawable_class->draw_lines = gdk_window_draw_lines;
|
||||
drawable_class->draw_glyphs = gdk_window_draw_glyphs;
|
||||
drawable_class->draw_image = gdk_window_draw_image;
|
||||
drawable_class->_draw_pixbuf = gdk_window_draw_pixbuf;
|
||||
drawable_class->get_depth = gdk_window_real_get_depth;
|
||||
drawable_class->get_size = gdk_window_real_get_size;
|
||||
drawable_class->set_colormap = gdk_window_real_set_colormap;
|
||||
drawable_class->get_colormap = gdk_window_real_get_colormap;
|
||||
drawable_class->get_visual = gdk_window_real_get_visual;
|
||||
drawable_class->get_image = gdk_window_get_image;
|
||||
drawable_class->_copy_to_image = gdk_window_copy_to_image;
|
||||
drawable_class->get_clip_region = gdk_window_get_clip_region;
|
||||
drawable_class->get_visible_region = gdk_window_get_visible_region;
|
||||
drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
|
||||
@ -1862,6 +1878,65 @@ gdk_window_draw_image (GdkDrawable *drawable,
|
||||
RESTORE_GC (gc);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)drawable;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (drawable))
|
||||
return;
|
||||
|
||||
if (gc)
|
||||
{
|
||||
OFFSET_GC (gc);
|
||||
|
||||
if (private->paint_stack)
|
||||
{
|
||||
GdkWindowPaint *paint = private->paint_stack->data;
|
||||
_gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither - x_offset, y_dither - y_offset);
|
||||
}
|
||||
else
|
||||
_gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
|
||||
RESTORE_GC (gc);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint x_offset, y_offset;
|
||||
gdk_window_get_offsets (drawable, &x_offset, &y_offset);
|
||||
|
||||
if (private->paint_stack)
|
||||
{
|
||||
GdkWindowPaint *paint = private->paint_stack->data;
|
||||
_gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither - x_offset, y_dither - y_offset);
|
||||
}
|
||||
else
|
||||
_gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_real_get_size (GdkDrawable *drawable,
|
||||
@ -1927,11 +2002,14 @@ gdk_window_real_get_colormap (GdkDrawable *drawable)
|
||||
}
|
||||
|
||||
static GdkImage*
|
||||
gdk_window_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_window_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gint x_offset, y_offset;
|
||||
|
||||
@ -1946,10 +2024,12 @@ gdk_window_get_image (GdkDrawable *drawable,
|
||||
|
||||
_gdk_windowing_window_get_offsets (drawable, &x_offset, &y_offset);
|
||||
|
||||
return gdk_drawable_get_image (((GdkWindowObject*)drawable)->impl,
|
||||
x - x_offset,
|
||||
y - y_offset,
|
||||
width, height);
|
||||
return _gdk_drawable_copy_to_image (((GdkWindowObject*)drawable)->impl,
|
||||
image,
|
||||
src_x - x_offset,
|
||||
src_y - y_offset,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
/* Code for dirty-region queueing
|
||||
|
@ -35,6 +35,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
#if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
|
||||
#define USE_SHM
|
||||
@ -119,6 +120,20 @@ static void gdk_x11_draw_image (GdkDrawable *drawable,
|
||||
gint ydest,
|
||||
gint width,
|
||||
gint height);
|
||||
#ifdef HAVE_XFT
|
||||
static void gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
#endif /* HAVE_XFT */
|
||||
|
||||
static void gdk_x11_set_colormap (GdkDrawable *drawable,
|
||||
GdkColormap *colormap);
|
||||
@ -185,6 +200,9 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
|
||||
drawable_class->draw_lines = gdk_x11_draw_lines;
|
||||
drawable_class->draw_glyphs = gdk_x11_draw_glyphs;
|
||||
drawable_class->draw_image = gdk_x11_draw_image;
|
||||
#ifdef HAVE_XFT
|
||||
drawable_class->_draw_pixbuf = gdk_x11_draw_pixbuf;
|
||||
#endif /* HAVE_XFT */
|
||||
|
||||
drawable_class->set_colormap = gdk_x11_set_colormap;
|
||||
drawable_class->get_colormap = gdk_x11_get_colormap;
|
||||
@ -192,7 +210,7 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
|
||||
drawable_class->get_depth = gdk_x11_get_depth;
|
||||
drawable_class->get_visual = gdk_x11_get_visual;
|
||||
|
||||
drawable_class->get_image = _gdk_x11_get_image;
|
||||
drawable_class->_copy_to_image = _gdk_x11_copy_to_image;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -204,6 +222,17 @@ gdk_drawable_impl_x11_finalize (GObject *object)
|
||||
}
|
||||
|
||||
#ifdef HAVE_XFT
|
||||
gboolean
|
||||
_gdk_x11_have_render (void)
|
||||
{
|
||||
/* This check is cheap, but if we have to do version checks, we will
|
||||
* need to cache the result since version checks are round-trip
|
||||
*/
|
||||
int event_base, error_base;
|
||||
|
||||
return XRenderQueryExtension (gdk_display, &event_base, &error_base);
|
||||
}
|
||||
|
||||
static Picture
|
||||
gdk_x11_drawable_get_picture (GdkDrawable *drawable)
|
||||
{
|
||||
@ -225,7 +254,8 @@ gdk_x11_drawable_get_picture (GdkDrawable *drawable)
|
||||
}
|
||||
|
||||
format = XRenderFindVisualFormat (impl->xdisplay, GDK_VISUAL_XVISUAL (visual));
|
||||
impl->picture = XRenderCreatePicture (impl->xdisplay, impl->xid, format, 0, NULL);
|
||||
if (format)
|
||||
impl->picture = XRenderCreatePicture (impl->xdisplay, impl->xid, format, 0, NULL);
|
||||
}
|
||||
|
||||
return impl->picture;
|
||||
@ -752,3 +782,536 @@ gdk_x11_drawable_get_xid (GdkDrawable *drawable)
|
||||
|
||||
return ((GdkDrawableImplX11 *)impl)->xid;
|
||||
}
|
||||
|
||||
/* Code for accelerated alpha compositing using the RENDER extension.
|
||||
* It's a bit long because there are lots of possibilities for
|
||||
* what's the fastest depending on the available picture formats,
|
||||
* whether we can used shared pixmaps, etc.
|
||||
*/
|
||||
#ifdef HAVE_XFT
|
||||
typedef enum {
|
||||
FORMAT_NONE,
|
||||
FORMAT_EXACT_MASK,
|
||||
FORMAT_ARGB_MASK,
|
||||
FORMAT_ARGB
|
||||
} FormatType;
|
||||
|
||||
static FormatType
|
||||
select_format (Display *xdisplay,
|
||||
XRenderPictFormat **format,
|
||||
XRenderPictFormat **mask)
|
||||
{
|
||||
XRenderPictFormat pf;
|
||||
|
||||
|
||||
/* Look for a 32-bit xRGB and Axxx formats that exactly match the
|
||||
* in memory data format. We can use them as pixmap and mask
|
||||
* to deal with non-premultiplied data.
|
||||
*/
|
||||
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.redMask = 0xff;
|
||||
pf.direct.greenMask = 0xff;
|
||||
pf.direct.blueMask = 0xff;
|
||||
|
||||
pf.direct.alphaMask = 0;
|
||||
if (ImageByteOrder (xdisplay) == LSBFirst)
|
||||
{
|
||||
/* ABGR */
|
||||
pf.direct.red = 0;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RGBA */
|
||||
pf.direct.red = 24;
|
||||
pf.direct.green = 16;
|
||||
pf.direct.blue = 8;
|
||||
}
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
pf.direct.alphaMask = 0xff;
|
||||
if (ImageByteOrder (xdisplay) == LSBFirst)
|
||||
{
|
||||
/* ABGR */
|
||||
pf.direct.alpha = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
pf.direct.alpha = 0;
|
||||
}
|
||||
|
||||
*mask = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return FORMAT_EXACT_MASK;
|
||||
|
||||
/* OK, that failed, now look for xRGB and Axxx formats in
|
||||
* RENDER's preferred order
|
||||
*/
|
||||
pf.direct.alphaMask = 0;
|
||||
/* ARGB */
|
||||
pf.direct.red = 16;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 0;
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
pf.direct.alphaMask = 0xff;
|
||||
pf.direct.alpha = 24;
|
||||
|
||||
*mask = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return FORMAT_ARGB_MASK;
|
||||
|
||||
/* Finally, if neither of the above worked, fall back to
|
||||
* looking for combined ARGB -- we'll premultiply ourselves.
|
||||
*/
|
||||
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.red = 16;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 0;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
pf.direct.alpha = 24;
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
*mask = NULL;
|
||||
|
||||
if (*format)
|
||||
return FORMAT_ARGB;
|
||||
|
||||
return FORMAT_NONE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
list_formats (XRenderPictFormat *pf)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i=0 ;; i++)
|
||||
{
|
||||
XRenderPictFormat *pf = XRenderFindFormat (impl->xdisplay, 0, NULL, i);
|
||||
if (pf)
|
||||
{
|
||||
g_print ("%2d R-%#06x/%#06x G-%#06x/%#06x B-%#06x/%#06x A-%#06x/%#06x\n",
|
||||
pf->depth,
|
||||
pf->direct.red,
|
||||
pf->direct.redMask,
|
||||
pf->direct.green,
|
||||
pf->direct.greenMask,
|
||||
pf->direct.blue,
|
||||
pf->direct.blueMask,
|
||||
pf->direct.alpha,
|
||||
pf->direct.alphaMask);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
convert_to_format (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
FormatType dest_format,
|
||||
GdkByteOrder dest_byteorder,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (dest_format == FORMAT_EXACT_MASK &&
|
||||
src_rowstride == dest_rowstride)
|
||||
{
|
||||
memcpy (dest_buf, src_buf, height * src_rowstride);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < height; i++)
|
||||
{
|
||||
switch (dest_format)
|
||||
{
|
||||
case FORMAT_EXACT_MASK:
|
||||
{
|
||||
memcpy (dest_buf + i * dest_rowstride,
|
||||
src_buf + i * src_rowstride,
|
||||
width * 4);
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARGB_MASK:
|
||||
{
|
||||
guint *p = (guint *)(src_buf + i * src_rowstride);
|
||||
guint *q = (guint *)(dest_buf + i * dest_rowstride);
|
||||
guint *end = p + width;
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
if (dest_byteorder == GDK_LSB_FIRST)
|
||||
{
|
||||
/* ABGR => ARGB */
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
*q = ( (*p & 0xff00ff00) |
|
||||
((*p & 0x000000ff) << 16) |
|
||||
((*p & 0x00ff0000) >> 16));
|
||||
q++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ABGR => BGRA */
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
*q = (((*p & 0xff000000) >> 24) |
|
||||
((*p & 0x00ffffff) << 8));
|
||||
q++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#else /* G_BYTE_ORDER == G_BIG_ENDIAN */
|
||||
if (dest_byteorder == GDK_LSB_FIRST)
|
||||
{
|
||||
/* RGBA => BGRA */
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
*q = ( (*p & 0x00ff00ff) |
|
||||
((*p & 0x0000ff00) << 16) |
|
||||
((*p & 0xff000000) >> 16));
|
||||
q++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RGBA => ARGB */
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
*q = (((*p & 0xff000000) >> 24) |
|
||||
((*p & 0x00ffffff) << 8));
|
||||
q++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif /* G_BYTE_ORDER*/
|
||||
break;
|
||||
}
|
||||
case FORMAT_ARGB:
|
||||
{
|
||||
guchar *p = (src_buf + i * src_rowstride);
|
||||
guchar *q = (dest_buf + i * dest_rowstride);
|
||||
guchar *end = p + 4 * width;
|
||||
guchar a;
|
||||
guint t;
|
||||
|
||||
#define MULT(d,c,a) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END
|
||||
|
||||
if (dest_byteorder == GDK_LSB_FIRST)
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
a = p[3];
|
||||
MULT(q[0], p[2], a);
|
||||
MULT(q[1], p[1], a);
|
||||
MULT(q[2], p[0], a);
|
||||
q[3] = a;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (p < end)
|
||||
{
|
||||
a = p[3];
|
||||
q[0] = a;
|
||||
MULT(q[1], p[0], a);
|
||||
MULT(q[2], p[1], a);
|
||||
MULT(q[3], p[2], a);
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
#undef MULT
|
||||
break;
|
||||
}
|
||||
case FORMAT_NONE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_with_images (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
gint src_rowstride,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
|
||||
GdkImage *image;
|
||||
GdkPixmap *pix;
|
||||
GdkGC *pix_gc;
|
||||
Picture pict;
|
||||
Picture dest_pict;
|
||||
Picture mask = None;
|
||||
gint x0, y0;
|
||||
|
||||
pix = gdk_pixmap_new (NULL, width, height, 32);
|
||||
pict = XRenderCreatePicture (xdisplay,
|
||||
GDK_PIXMAP_XID (pix),
|
||||
format, 0, NULL);
|
||||
if (mask_format)
|
||||
mask = XRenderCreatePicture (xdisplay,
|
||||
GDK_PIXMAP_XID (pix),
|
||||
mask_format, 0, NULL);
|
||||
|
||||
dest_pict = gdk_x11_drawable_get_picture (drawable);
|
||||
|
||||
pix_gc = gdk_gc_new (pix);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0);
|
||||
|
||||
convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
image->mem + ys0 * image->bpl + 4 * xs0, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
gdk_draw_image (pix, pix_gc,
|
||||
image, xs0, ys0, x0, y0, width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict,
|
||||
0, 0, 0, 0, dest_x, dest_y, width, height);
|
||||
|
||||
XRenderFreePicture (xdisplay, pict);
|
||||
if (mask)
|
||||
XRenderFreePicture (xdisplay, mask);
|
||||
|
||||
g_object_unref (pix);
|
||||
g_object_unref (pix_gc);
|
||||
}
|
||||
|
||||
typedef struct _ShmPixmapInfo ShmPixmapInfo;
|
||||
|
||||
struct _ShmPixmapInfo
|
||||
{
|
||||
GdkImage *image;
|
||||
Pixmap pix;
|
||||
Picture pict;
|
||||
Picture mask;
|
||||
};
|
||||
|
||||
/* Returns FALSE if we can't get a shm pixmap */
|
||||
static gboolean
|
||||
get_shm_pixmap_for_image (Display *xdisplay,
|
||||
GdkImage *image,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
Pixmap *pix,
|
||||
Picture *pict,
|
||||
Picture *mask)
|
||||
{
|
||||
ShmPixmapInfo *info;
|
||||
|
||||
if (image->type != GDK_IMAGE_SHARED)
|
||||
return FALSE;
|
||||
|
||||
info = g_object_get_data (G_OBJECT (image), "gdk-x11-shm-pixmap");
|
||||
if (!info)
|
||||
{
|
||||
*pix = _gdk_x11_image_get_shm_pixmap (image);
|
||||
|
||||
if (!*pix)
|
||||
return FALSE;
|
||||
|
||||
info = g_new (ShmPixmapInfo, 1);
|
||||
info->pix = *pix;
|
||||
|
||||
info->pict = XRenderCreatePicture (xdisplay, info->pix,
|
||||
format, 0, NULL);
|
||||
if (mask_format)
|
||||
info->mask = XRenderCreatePicture (xdisplay, info->pix,
|
||||
mask_format, 0, NULL);
|
||||
else
|
||||
info->mask = None;
|
||||
|
||||
g_object_set_data (G_OBJECT (image), "gdk-x11-shm-pixmap", info);
|
||||
}
|
||||
|
||||
*pix = info->pix;
|
||||
*pict = info->pict;
|
||||
*mask = info->mask;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_SHM
|
||||
/* Returns FALSE if drawing with ShmPixmaps is not possible */
|
||||
static gboolean
|
||||
draw_with_pixmaps (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
gint src_rowstride,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
|
||||
GdkImage *image;
|
||||
Pixmap pix;
|
||||
Picture pict;
|
||||
Picture dest_pict;
|
||||
Picture mask = None;
|
||||
gint x0, y0;
|
||||
|
||||
dest_pict = gdk_x11_drawable_get_picture (drawable);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0);
|
||||
if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask))
|
||||
return FALSE;
|
||||
|
||||
convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
image->mem + ys0 * image->bpl + 4 * xs0, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict,
|
||||
xs0, ys0, xs0, ys0, x0 + dest_x, y0 + dest_y,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
|
||||
FormatType format_type;
|
||||
XRenderPictFormat *format, *mask_format;
|
||||
gint rowstride;
|
||||
#ifdef USE_SHM
|
||||
gboolean use_pixmaps = TRUE;
|
||||
#endif /* USE_SHM */
|
||||
|
||||
format_type = select_format (xdisplay, &format, &mask_format);
|
||||
|
||||
if (format_type == FORMAT_NONE ||
|
||||
!gdk_pixbuf_get_has_alpha (pixbuf) ||
|
||||
(dither == GDK_RGB_DITHER_MAX && gdk_drawable_get_depth (drawable) != 24))
|
||||
{
|
||||
GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
|
||||
GDK_DRAWABLE_CLASS (parent_class)->_draw_pixbuf (wrapper, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
return;
|
||||
}
|
||||
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
#ifdef USE_SHM
|
||||
if (use_pixmaps)
|
||||
{
|
||||
if (!draw_with_pixmaps (drawable, gc,
|
||||
format_type, format, mask_format,
|
||||
gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
|
||||
rowstride,
|
||||
dest_x, dest_y, width, height))
|
||||
use_pixmaps = FALSE;
|
||||
}
|
||||
|
||||
if (!use_pixmaps)
|
||||
#endif /* USE_SHM */
|
||||
draw_with_images (drawable, gc,
|
||||
format_type, format, mask_format,
|
||||
gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
|
||||
rowstride,
|
||||
dest_x, dest_y, width, height);
|
||||
}
|
||||
#endif /* HAVE_XFT */
|
||||
|
@ -810,9 +810,13 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat *pix_format = foreground_format (gc);
|
||||
Pixmap pix;
|
||||
|
||||
Pixmap pix = XCreatePixmap (x11_gc->xdisplay, _gdk_root_window,
|
||||
1, 1, pix_format->depth);
|
||||
if (!pix_format)
|
||||
return None;
|
||||
|
||||
pix = XCreatePixmap (x11_gc->xdisplay, _gdk_root_window,
|
||||
1, 1, pix_format->depth);
|
||||
pa.repeat = True;
|
||||
x11_gc->fg_picture = XRenderCreatePicture (x11_gc->xdisplay,
|
||||
pix,
|
||||
|
@ -59,10 +59,12 @@ struct _GdkImagePrivateX11
|
||||
XImage *ximage;
|
||||
Display *xdisplay;
|
||||
gpointer x_shm_info;
|
||||
Pixmap shm_pixmap;
|
||||
};
|
||||
|
||||
static GList *image_list = NULL;
|
||||
static gpointer parent_class = NULL;
|
||||
static gboolean have_shm_pixmaps;
|
||||
|
||||
static void gdk_x11_image_destroy (GdkImage *image);
|
||||
static void gdk_image_init (GdkImage *image);
|
||||
@ -198,33 +200,42 @@ _gdk_windowing_image_init (void)
|
||||
{
|
||||
if (_gdk_use_xshm)
|
||||
{
|
||||
if (!gdk_image_check_xshm (gdk_display))
|
||||
{
|
||||
_gdk_use_xshm = False;
|
||||
}
|
||||
gint res = gdk_image_check_xshm (gdk_display);
|
||||
|
||||
if (!res)
|
||||
_gdk_use_xshm = FALSE;
|
||||
else
|
||||
have_shm_pixmaps = (res == 2);
|
||||
}
|
||||
}
|
||||
|
||||
GdkImage*
|
||||
gdk_image_new (GdkImageType type,
|
||||
GdkVisual *visual,
|
||||
gint width,
|
||||
gint height)
|
||||
_gdk_image_new_for_depth (GdkImageType type,
|
||||
GdkVisual *visual,
|
||||
gint width,
|
||||
gint height,
|
||||
gint depth)
|
||||
{
|
||||
GdkImage *image;
|
||||
GdkImagePrivateX11 *private;
|
||||
#ifdef USE_SHM
|
||||
XShmSegmentInfo *x_shm_info;
|
||||
#endif /* USE_SHM */
|
||||
Visual *xvisual;
|
||||
Visual *xvisual = NULL;
|
||||
|
||||
g_return_val_if_fail (!visual || GDK_IS_VISUAL (visual), NULL);
|
||||
g_return_val_if_fail (visual || depth != -1, NULL);
|
||||
|
||||
if (visual)
|
||||
depth = visual->depth;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GDK_IMAGE_FASTEST:
|
||||
image = gdk_image_new (GDK_IMAGE_SHARED, visual, width, height);
|
||||
image = _gdk_image_new_for_depth (GDK_IMAGE_SHARED, visual, width, height, depth);
|
||||
|
||||
if (!image)
|
||||
image = gdk_image_new (GDK_IMAGE_NORMAL, visual, width, height);
|
||||
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height, depth);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -238,9 +249,10 @@ gdk_image_new (GdkImageType type,
|
||||
image->visual = visual;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->depth = visual->depth;
|
||||
image->depth = depth;
|
||||
|
||||
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
|
||||
if (visual)
|
||||
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -253,7 +265,7 @@ gdk_image_new (GdkImageType type,
|
||||
x_shm_info->shmid = -1;
|
||||
x_shm_info->shmaddr = (char*) -1;
|
||||
|
||||
private->ximage = XShmCreateImage (private->xdisplay, xvisual, visual->depth,
|
||||
private->ximage = XShmCreateImage (private->xdisplay, xvisual, depth,
|
||||
ZPixmap, NULL, x_shm_info, width, height);
|
||||
if (private->ximage == NULL)
|
||||
{
|
||||
@ -326,7 +338,7 @@ gdk_image_new (GdkImageType type,
|
||||
goto error;
|
||||
break;
|
||||
case GDK_IMAGE_NORMAL:
|
||||
private->ximage = XCreateImage (private->xdisplay, xvisual, visual->depth,
|
||||
private->ximage = XCreateImage (private->xdisplay, xvisual, depth,
|
||||
ZPixmap, 0, 0, width, height, 32, 0);
|
||||
|
||||
/* Use malloc, not g_malloc here, because X will call free()
|
||||
@ -344,7 +356,7 @@ gdk_image_new (GdkImageType type,
|
||||
|
||||
if (image)
|
||||
{
|
||||
image->byte_order = private->ximage->byte_order;
|
||||
image->byte_order = (private->ximage->byte_order == LSBFirst) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
|
||||
image->mem = private->ximage->data;
|
||||
image->bpl = private->ximage->bytes_per_line;
|
||||
image->bpp = (private->ximage->bits_per_pixel + 7) / 8;
|
||||
@ -379,39 +391,144 @@ gdk_image_new (GdkImageType type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Pixmap
|
||||
_gdk_x11_image_get_shm_pixmap (GdkImage *image)
|
||||
{
|
||||
GdkImagePrivateX11 *private = PRIVATE_DATA (image);
|
||||
|
||||
#ifdef USE_SHM
|
||||
/* Future: do we need one of these per-screen per-image? ShmPixmaps
|
||||
* are the same for every screen, but can they be shared?
|
||||
*/
|
||||
if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED && have_shm_pixmaps)
|
||||
private->shm_pixmap = XShmCreatePixmap (private->xdisplay, _gdk_root_window,
|
||||
image->mem, private->x_shm_info,
|
||||
image->width, image->height, image->depth);
|
||||
|
||||
return private->shm_pixmap;
|
||||
#else
|
||||
return None;
|
||||
#endif
|
||||
}
|
||||
|
||||
GdkImage*
|
||||
_gdk_x11_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gdk_image_new (GdkImageType type,
|
||||
GdkVisual *visual,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
return _gdk_image_new_for_depth (type, visual, width, height, -1);
|
||||
}
|
||||
|
||||
GdkImage*
|
||||
get_full_image (GdkDrawable *drawable,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkImage *image;
|
||||
GdkImagePrivateX11 *private;
|
||||
GdkDrawableImplX11 *impl;
|
||||
XImage *ximage;
|
||||
|
||||
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
|
||||
|
||||
ximage = XGetImage (impl->xdisplay,
|
||||
impl->xid,
|
||||
src_x, src_y, width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
if (!ximage)
|
||||
return NULL;
|
||||
|
||||
image = g_object_new (gdk_image_get_type (), NULL);
|
||||
|
||||
private = PRIVATE_DATA (image);
|
||||
|
||||
private->xdisplay = gdk_display;
|
||||
private->ximage = ximage;
|
||||
|
||||
image->type = GDK_IMAGE_NORMAL;
|
||||
image->visual = gdk_drawable_get_visual (drawable); /* could be NULL */
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->depth = gdk_drawable_get_depth (drawable);
|
||||
|
||||
image->mem = private->ximage->data;
|
||||
image->bpl = private->ximage->bytes_per_line;
|
||||
image->bits_per_pixel = private->ximage->bits_per_pixel;
|
||||
image->bpp = (private->ximage->bits_per_pixel + 7) / 8;
|
||||
image->byte_order = (private->ximage->byte_order == LSBFirst) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
GdkImage*
|
||||
_gdk_x11_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkImagePrivateX11 *private;
|
||||
GdkDrawableImplX11 *impl;
|
||||
GdkVisual *visual;
|
||||
gboolean have_grab;
|
||||
GdkRectangle req;
|
||||
GdkRectangle window_rect;
|
||||
XImage *ximage;
|
||||
Pixmap shm_pixmap = None;
|
||||
gboolean success = TRUE;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_X11 (drawable), NULL);
|
||||
g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
|
||||
|
||||
visual = gdk_drawable_get_visual (drawable);
|
||||
|
||||
g_assert (visual || !GDK_IS_WINDOW_IMPL_X11 (drawable));
|
||||
|
||||
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
|
||||
|
||||
have_grab = FALSE;
|
||||
|
||||
#define UNGRAB() G_STMT_START { \
|
||||
if (have_grab) { \
|
||||
gdk_x11_ungrab_server (); \
|
||||
XFlush (impl->xdisplay); \
|
||||
have_grab = FALSE; } \
|
||||
} G_STMT_END
|
||||
|
||||
if (!image && !GDK_IS_WINDOW_IMPL_X11 (drawable))
|
||||
return get_full_image (drawable, src_x, src_y, width, height);
|
||||
|
||||
if (image && image->type == GDK_IMAGE_SHARED)
|
||||
{
|
||||
shm_pixmap = _gdk_x11_image_get_shm_pixmap (image);
|
||||
if (shm_pixmap)
|
||||
{
|
||||
/* Again easy, we can just XCopyArea, and don't have to worry about clipping
|
||||
*/
|
||||
GC xgc = XCreateGC (impl->xdisplay, impl->xid, 0, NULL);
|
||||
|
||||
XCopyArea (impl->xdisplay, impl->xid, shm_pixmap, xgc,
|
||||
src_x, src_y, width, height, dest_x, dest_y);
|
||||
XSync (impl->xdisplay, FALSE);
|
||||
|
||||
XFreeGC (impl->xdisplay, xgc);
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now the general case - we may have to worry about clipping to the screen
|
||||
* bounds, in which case we'll have to grab the server and only get a piece
|
||||
* of the window.
|
||||
*/
|
||||
if (GDK_IS_WINDOW_IMPL_X11 (drawable))
|
||||
{
|
||||
GdkRectangle screen_rect;
|
||||
Window child;
|
||||
|
||||
g_assert (visual);
|
||||
|
||||
have_grab = TRUE;
|
||||
gdk_x11_grab_server ();
|
||||
|
||||
@ -443,13 +560,7 @@ _gdk_x11_get_image (GdkDrawable *drawable,
|
||||
if (gdk_error_trap_pop () ||
|
||||
!gdk_rectangle_intersect (&window_rect, &screen_rect,
|
||||
&window_rect))
|
||||
{
|
||||
if (have_grab)
|
||||
gdk_x11_ungrab_server ();
|
||||
return image = gdk_image_new (GDK_IMAGE_FASTEST,
|
||||
visual,
|
||||
width, height);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -460,8 +571,8 @@ _gdk_x11_get_image (GdkDrawable *drawable,
|
||||
&window_rect.height);
|
||||
}
|
||||
|
||||
req.x = x;
|
||||
req.y = y;
|
||||
req.x = src_x;
|
||||
req.y = src_y;
|
||||
req.width = width;
|
||||
req.height = height;
|
||||
|
||||
@ -470,97 +581,66 @@ _gdk_x11_get_image (GdkDrawable *drawable,
|
||||
* For pixmaps this is all of the pixmap, for windows it is just
|
||||
* the onscreen part.
|
||||
*/
|
||||
if (!gdk_rectangle_intersect (&req, &window_rect, &req) && visual)
|
||||
{
|
||||
if (have_grab)
|
||||
gdk_x11_ungrab_server ();
|
||||
return image = gdk_image_new (GDK_IMAGE_FASTEST,
|
||||
visual,
|
||||
width, height);
|
||||
}
|
||||
if (!gdk_rectangle_intersect (&req, &window_rect, &req))
|
||||
goto out;
|
||||
|
||||
if (req.x != x || req.y != y)
|
||||
private = PRIVATE_DATA (image);
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
if (!image &&
|
||||
req.x == src_x && req.y == src_y && req.width == width && req.height == height)
|
||||
{
|
||||
g_assert (GDK_IS_WINDOW (drawable));
|
||||
g_assert (visual);
|
||||
|
||||
image = gdk_image_new (GDK_IMAGE_FASTEST,
|
||||
visual,
|
||||
width, height);
|
||||
if (image == NULL)
|
||||
{
|
||||
if (have_grab)
|
||||
gdk_x11_ungrab_server ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private = PRIVATE_DATA (image);
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
ximage = XGetSubImage (impl->xdisplay,
|
||||
impl->xid,
|
||||
req.x, req.y, req.width, req.height,
|
||||
AllPlanes, ZPixmap,
|
||||
private->ximage,
|
||||
req.x - x, req.y - y);
|
||||
|
||||
if (have_grab)
|
||||
{
|
||||
gdk_x11_ungrab_server ();
|
||||
have_grab = FALSE;
|
||||
}
|
||||
|
||||
if (gdk_error_trap_pop () || ximage == NULL)
|
||||
{
|
||||
g_object_unref (G_OBJECT (image));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_assert (ximage == private->ximage);
|
||||
image = get_full_image (drawable, src_x, src_y, width, height);
|
||||
if (!image)
|
||||
success = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Here we ignore the req.width, req.height -
|
||||
* XGetImage() will do the right thing without
|
||||
* them.
|
||||
gboolean created_image = FALSE;
|
||||
|
||||
if (!image)
|
||||
{
|
||||
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height,
|
||||
gdk_drawable_get_depth (drawable));
|
||||
created_image = TRUE;
|
||||
}
|
||||
|
||||
/* In the ShmImage but no ShmPixmap case, we could use XShmGetImage when
|
||||
* we are getting the entire image.
|
||||
*/
|
||||
ximage = XGetImage (impl->xdisplay,
|
||||
impl->xid,
|
||||
x, y, width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
if (have_grab)
|
||||
{
|
||||
gdk_x11_ungrab_server ();
|
||||
have_grab = FALSE;
|
||||
}
|
||||
|
||||
if (!ximage)
|
||||
return NULL;
|
||||
|
||||
image = g_object_new (gdk_image_get_type (), NULL);
|
||||
|
||||
private = PRIVATE_DATA (image);
|
||||
|
||||
private->xdisplay = gdk_display;
|
||||
private->ximage = ximage;
|
||||
|
||||
image->type = GDK_IMAGE_NORMAL;
|
||||
image->visual = visual; /* May be NULL */
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->depth = gdk_drawable_get_depth (drawable);
|
||||
|
||||
image->mem = private->ximage->data;
|
||||
image->bpl = private->ximage->bytes_per_line;
|
||||
image->bits_per_pixel = private->ximage->bits_per_pixel;
|
||||
image->bpp = (private->ximage->bits_per_pixel + 7) / 8;
|
||||
image->byte_order = private->ximage->byte_order;
|
||||
if (XGetSubImage (impl->xdisplay,
|
||||
impl->xid,
|
||||
req.x, req.y, req.width, req.height,
|
||||
AllPlanes, ZPixmap,
|
||||
private->ximage,
|
||||
dest_x + req.x - src_x, dest_y + req.y - src_y) == None)
|
||||
{
|
||||
if (created_image)
|
||||
g_object_unref (image);
|
||||
image = NULL;
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (!have_grab);
|
||||
out:
|
||||
|
||||
if (have_grab)
|
||||
{
|
||||
gdk_x11_ungrab_server ();
|
||||
XFlush (impl->xdisplay);
|
||||
have_grab = FALSE;
|
||||
}
|
||||
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
if (success && !image)
|
||||
{
|
||||
/* We "succeeded", but could get no content for the image so return junk */
|
||||
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height,
|
||||
gdk_drawable_get_depth (drawable));
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -625,7 +705,11 @@ gdk_x11_image_destroy (GdkImage *image)
|
||||
case GDK_IMAGE_SHARED:
|
||||
#ifdef USE_SHM
|
||||
gdk_flush();
|
||||
|
||||
|
||||
if (private->shm_pixmap)
|
||||
XFreePixmap (private->xdisplay, private->shm_pixmap);
|
||||
|
||||
image_list = g_list_remove (image_list, image);
|
||||
XShmDetach (private->xdisplay, private->x_shm_info);
|
||||
XDestroyImage (private->ximage);
|
||||
|
||||
@ -634,8 +718,7 @@ gdk_x11_image_destroy (GdkImage *image)
|
||||
|
||||
g_free (private->x_shm_info);
|
||||
private->x_shm_info = NULL;
|
||||
|
||||
image_list = g_list_remove (image_list, image);
|
||||
|
||||
#else /* USE_SHM */
|
||||
g_error ("trying to destroy shared memory image when gdk was compiled without shared memory support");
|
||||
#endif /* USE_SHM */
|
||||
@ -673,3 +756,23 @@ gdk_x11_image_get_ximage (GdkImage *image)
|
||||
|
||||
return private->ximage;
|
||||
}
|
||||
|
||||
gint
|
||||
_gdk_windowing_get_bits_for_depth (gint depth)
|
||||
{
|
||||
XPixmapFormatValues *formats;
|
||||
gint count, i;
|
||||
|
||||
formats = XListPixmapFormats (gdk_display, &count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (formats[i].depth == depth)
|
||||
{
|
||||
gint result = formats[i].bits_per_pixel;
|
||||
XFree (formats);
|
||||
return result;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return -1;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ gdk_pango_context_get (void)
|
||||
{
|
||||
const char *val = g_getenv ("GDK_USE_XFT");
|
||||
|
||||
use_xft = val && (atoi (val) != 0);
|
||||
use_xft = val && (atoi (val) != 0) && _gdk_x11_have_render ();
|
||||
}
|
||||
|
||||
if (use_xft)
|
||||
|
@ -100,7 +100,8 @@ gint gdk_send_xevent (Window window,
|
||||
GType _gdk_gc_x11_get_type (void);
|
||||
|
||||
#ifdef HAVE_XFT
|
||||
Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
|
||||
gboolean _gdk_x11_have_render (void);
|
||||
Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
|
||||
#endif /* HAVE_XFT */
|
||||
|
||||
GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable,
|
||||
@ -112,11 +113,15 @@ GdkVisual * gdk_visual_lookup (Visual *xvisual);
|
||||
|
||||
void gdk_window_add_colormap_windows (GdkWindow *window);
|
||||
|
||||
GdkImage* _gdk_x11_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
GdkImage *_gdk_x11_copy_to_image (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height);
|
||||
Pixmap _gdk_x11_image_get_shm_pixmap (GdkImage *image);
|
||||
|
||||
/* Please see gdkwindow.c for comments on how to use */
|
||||
Window gdk_window_xid_at (Window base,
|
||||
|
@ -48,7 +48,7 @@ quit_func (GtkWidget *widget, gpointer dummy)
|
||||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 400
|
||||
#define NUM_ITERS 100
|
||||
#define NUM_ITERS 50
|
||||
|
||||
static void
|
||||
testrgb_rgb_test (GtkWidget *drawing_area)
|
||||
@ -62,11 +62,13 @@ testrgb_rgb_test (GtkWidget *drawing_area)
|
||||
gboolean dither;
|
||||
int dith_max;
|
||||
GTimer *timer;
|
||||
|
||||
buf = g_malloc (WIDTH * HEIGHT * 6);
|
||||
GdkPixbuf *pixbuf;
|
||||
gboolean to_pixmap;
|
||||
|
||||
buf = g_malloc (WIDTH * HEIGHT * 8);
|
||||
|
||||
val = 0;
|
||||
for (j = 0; j < WIDTH * HEIGHT * 6; j++)
|
||||
for (j = 0; j < WIDTH * HEIGHT * 8; j++)
|
||||
{
|
||||
val = (val + ((val + (rand () & 0xff)) >> 1)) >> 1;
|
||||
buf[j] = val;
|
||||
@ -103,6 +105,7 @@ testrgb_rgb_test (GtkWidget *drawing_area)
|
||||
GDK_RGB_DITHER_NONE,
|
||||
buf + offset, WIDTH * 3);
|
||||
}
|
||||
gdk_flush ();
|
||||
total_time = g_timer_elapsed (timer, NULL) - start_time;
|
||||
g_print ("Color test%s time elapsed: %.2fs, %.1f fps, %.2f megapixels/s\n",
|
||||
dither ? " (dithered)" : "",
|
||||
@ -124,6 +127,7 @@ testrgb_rgb_test (GtkWidget *drawing_area)
|
||||
GDK_RGB_DITHER_NONE,
|
||||
buf + offset, WIDTH);
|
||||
}
|
||||
gdk_flush ();
|
||||
total_time = g_timer_elapsed (timer, NULL) - start_time;
|
||||
g_print ("Grayscale test%s time elapsed: %.2fs, %.1f fps, %.2f megapixels/s\n",
|
||||
dither ? " (dithered)" : "",
|
||||
@ -132,6 +136,42 @@ testrgb_rgb_test (GtkWidget *drawing_area)
|
||||
NUM_ITERS * (WIDTH * HEIGHT * 1e-6) / total_time);
|
||||
}
|
||||
|
||||
for (to_pixmap = FALSE; to_pixmap <= TRUE; to_pixmap++)
|
||||
{
|
||||
if (to_pixmap)
|
||||
{
|
||||
GdkRectangle rect = { 0, 0, WIDTH, HEIGHT };
|
||||
gdk_window_begin_paint_rect (drawing_area->window, &rect);
|
||||
}
|
||||
|
||||
start_time = g_timer_elapsed (timer, NULL);
|
||||
for (i = 0; i < NUM_ITERS; i++)
|
||||
{
|
||||
offset = (rand () % (WIDTH * HEIGHT * 4)) & -4;
|
||||
pixbuf = gdk_pixbuf_new_from_data (buf + offset, GDK_COLORSPACE_RGB, TRUE,
|
||||
8, WIDTH, HEIGHT, WIDTH * 4,
|
||||
NULL, NULL);
|
||||
gdk_pixbuf_render_to_drawable_alpha (pixbuf, drawing_area->window,
|
||||
0, 0, 0, 0, WIDTH, HEIGHT,
|
||||
GDK_PIXBUF_ALPHA_FULL, /* ignored */
|
||||
0x80, /* ignored */
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
}
|
||||
gdk_flush ();
|
||||
total_time = g_timer_elapsed (timer, NULL) - start_time;
|
||||
|
||||
if (to_pixmap)
|
||||
gdk_window_end_paint (drawing_area->window);
|
||||
|
||||
g_print ("Alpha test%s time elapsed: %.2fs, %.1f fps, %.2f megapixels/s\n",
|
||||
to_pixmap ? " (to pixmap)" : "",
|
||||
total_time,
|
||||
NUM_ITERS / total_time,
|
||||
NUM_ITERS * (WIDTH * HEIGHT * 1e-6) / total_time);
|
||||
}
|
||||
|
||||
g_print ("Please submit these results to http://www.levien.com/gdkrgb/survey.html\n");
|
||||
|
||||
#if 1
|
||||
|
Loading…
Reference in New Issue
Block a user