@@ -702,30 +702,52 @@ static inline MCRectangle MCGRectangleToMCRectangle(const MCGRectangle &p_rect)
702702
703703// //////////////////////////////////////////////////////////////////////////////
704704
705+ void MCX11PutImage (Display *p_dpy, Drawable d, Region p_clip_region, XImage *source, int2 sx, int2 sy,
706+ int2 dx, int2 dy, uint2 w, uint2 h)
707+ {
708+ if (d == nil)
709+ return ;
710+
711+ GC t_gc;
712+
713+ t_gc = XCreateGC (p_dpy, d, 0 , NULL );
714+
715+ XRectangle t_rect;
716+ t_rect.x = t_rect.y = t_rect.width = t_rect.height = 0 ;
717+ XClipBox (p_clip_region, &t_rect);
718+
719+ XSetRegion (p_dpy, t_gc, p_clip_region);
720+ XPutImage (p_dpy, d, t_gc , source, sx, sy, dx, dy, w, h);
721+ XFreeGC (p_dpy, t_gc);
722+ }
723+
724+ bool MCLinuxMCGRegionToRegion (MCGRegionRef p_region, Region &r_region);
725+ void MCLinuxRegionDestroy (Region p_region);
726+
727+ // ////////
728+
705729class MCLinuxStackSurface : public MCStackSurface
706730{
707731 MCStack *m_stack;
708- MCRegionRef m_region;
732+ MCGRegionRef m_region;
709733
710734 bool m_locked;
711735 MCGContextRef m_locked_context;
712- MCRectangle m_locked_area;
736+ MCGIntegerRectangle m_locked_area;
713737
714- MCRegionRef m_redraw_region;
715738 MCBitmap *m_bitmap;
716739 MCGRaster m_raster;
717- MCRectangle m_area;
740+ MCGIntegerRectangle m_area;
718741
719742public:
720- MCLinuxStackSurface (MCStack *p_stack, MCRegionRef p_region)
743+ MCLinuxStackSurface (MCStack *p_stack, MCGRegionRef p_region)
721744 {
722745 m_stack = p_stack;
723746 m_region = p_region;
724747
725748 m_locked = false ;
726749 m_locked_context = nil;
727750
728- m_redraw_region = nil;
729751 m_bitmap = nil;
730752 }
731753
@@ -734,35 +756,29 @@ class MCLinuxStackSurface: public MCStackSurface
734756 if (m_bitmap != nil)
735757 return false ;
736758
737- MCRectangle t_actual_area;
738- t_actual_area = MCRegionGetBoundingBox (m_region);
739- if (MCU_empty_rect (t_actual_area))
759+ MCGIntegerRectangle t_actual_area;
760+ t_actual_area = MCGRegionGetBounds (m_region);
761+ if (MCGIntegerRectangleIsEmpty (t_actual_area))
740762 return false ;
741763
742764 bool t_success = true ;
743765
744766 if (t_success)
745- t_success = MCRegionCreate (m_redraw_region);
746-
747- if (t_success)
748- t_success = nil != (m_bitmap = ((MCScreenDC*)MCscreen)->createimage (32 , t_actual_area.width , t_actual_area.height , False, 0x0 , False, False));
767+ t_success = nil != (m_bitmap = ((MCScreenDC*)MCscreen)->createimage (32 , t_actual_area.size .width , t_actual_area.size .height , False, 0x0 , False, False));
749768
750769 if (t_success)
751770 {
752- m_raster . format = kMCGRasterFormat_ARGB ;
753- m_raster . width = t_actual_area . width;
754- m_raster . height = t_actual_area . height;
755- m_raster . stride = t_actual_area . width * sizeof (uint32_t );
771+ m_raster . format = kMCGRasterFormat_xRGB ;
772+ m_raster . width = t_actual_area. size . width ;
773+ m_raster . height = t_actual_area. size . height ;
774+ m_raster . stride = t_actual_area. size . width * sizeof (uint32_t );
756775 m_raster . pixels = m_bitmap->data ;
757776
758777 m_area = t_actual_area;
759778
760779 return true ;
761780 }
762781
763- MCRegionDestroy (m_redraw_region);
764- m_redraw_region = nil;
765-
766782 if (m_bitmap != nil)
767783 ((MCScreenDC*)MCscreen)->destroyimage (m_bitmap);
768784 m_bitmap = nil;
@@ -786,42 +802,50 @@ class MCLinuxStackSurface: public MCStackSurface
786802 t_mask = m_stack -> getwindowshape ();
787803 if (t_mask != nil && !t_mask -> is_sharp)
788804 {
789- if (m_area.x + m_area.width > t_mask->width )
790- MCBitmapClearRegion (m_bitmap, t_mask->width , 0 , m_area.x + m_area.width - t_mask->width , m_area.height );
791- if (m_area.y + m_area.height > t_mask->height )
792- MCBitmapClearRegion (m_bitmap, 0 , t_mask->height , m_area.width , m_area.y + m_area.height - t_mask->height );
805+ if (m_area.origin . x + m_area. size .width > t_mask->width )
806+ MCBitmapClearRegion (m_bitmap, t_mask->width , 0 , m_area.origin . x + m_area.size . width - t_mask->width , m_area. size .height );
807+ if (m_area.origin . y + m_area. size .height > t_mask->height )
808+ MCBitmapClearRegion (m_bitmap, 0 , t_mask->height , m_area.size . width , m_area.origin . y + m_area. size .height - t_mask->height );
793809
794810 uint32_t t_width = 0 ;
795811 uint32_t t_height = 0 ;
796- if (t_mask->width > m_area.x )
797- t_width = MCMin (t_mask->width - m_area.x , m_area.width );
798- if (t_mask->height > m_area.y )
799- t_height = MCMin (t_mask->height - m_area.y , m_area.height );
812+ if (t_mask->width > m_area.origin . x )
813+ t_width = MCMin (( uint32_t )( t_mask->width - m_area.origin . x ) , m_area. size .width );
814+ if (t_mask->height > m_area.origin . y )
815+ t_height = MCMin (( uint32_t )( t_mask->height - m_area.origin . y ) , m_area. size .height );
800816
801817 void *t_src_ptr;
802- t_src_ptr = t_mask -> data + m_area . y * t_mask -> stride + m_area . x;
818+ t_src_ptr = t_mask -> data + m_area. origin . y * t_mask -> stride + m_area. origin . x ;
803819 surface_merge_with_alpha (m_raster.pixels , m_raster.stride , t_src_ptr, t_mask -> stride, t_width, t_height);
804820 }
805821
822+ Region t_region;
823+ t_region = nil;
806824
807- ((MCScreenDC*)MCscreen)->putimage (m_stack->getwindow (), m_bitmap, 0 , 0 , m_area.x , m_area.y , m_area.width , m_area.height );
825+ /* UNCHECKED */ MCLinuxMCGRegionToRegion (m_region, t_region);
826+
827+ MCX11PutImage (((MCScreenDC*)MCscreen)->getDisplay (), m_stack->getwindow (), t_region, (XImage*)m_bitmap, 0 , 0 , m_area.origin .x , m_area.origin .y , m_area.size .width , m_area.size .height );
828+
829+ MCLinuxRegionDestroy (t_region);
808830 }
809831
810832 ((MCScreenDC*)MCscreen)->destroyimage (m_bitmap);
811833 m_bitmap = nil;
812834 }
813835
814- bool LockGraphics (MCRegionRef p_area, MCGContextRef& r_context)
836+ bool LockGraphics (MCGRegionRef p_area, MCGContextRef& r_context)
815837 {
816838 MCGRaster t_raster;
817- if (LockPixels (p_area, t_raster))
839+ if (LockPixels (MCGRegionGetBounds ( p_area) , t_raster))
818840 {
819841 if (MCGContextCreateWithRaster (t_raster, m_locked_context))
820842 {
821843 // Set origin
822- MCGContextTranslateCTM (m_locked_context, -m_locked_area.x , -m_locked_area.y );
844+ MCGContextTranslateCTM (m_locked_context, -m_locked_area.origin .x , -m_locked_area.origin .y );
845+
823846 // Set clipping rect
824- MCGContextClipToRect (m_locked_context, MCRectangleToMCGRectangle (m_locked_area));
847+ MCGContextClipToRegion (m_locked_context, p_area);
848+ MCGContextClipToRect (m_locked_context, MCGIntegerRectangleToMCGRectangle (m_locked_area));
825849
826850 r_context = m_locked_context;
827851
@@ -845,26 +869,24 @@ class MCLinuxStackSurface: public MCStackSurface
845869 UnlockPixels ();
846870 }
847871
848- bool LockPixels (MCRegionRef p_area, MCGRaster &r_raster)
872+ bool LockPixels (MCGIntegerRectangle p_area, MCGRaster &r_raster)
849873 {
850874 if (m_bitmap == nil || m_locked)
851875 return false ;
852876
853- MCRectangle t_bounds = MCRegionGetBoundingBox (m_region);
854- MCRectangle t_actual_area;
855- t_actual_area = MCU_intersect_rect ( MCRegionGetBoundingBox ( p_area) , t_bounds);
856- if (MCU_empty_rect (t_actual_area))
877+ MCGIntegerRectangle t_bounds = MCGRegionGetBounds (m_region);
878+ MCGIntegerRectangle t_actual_area;
879+ t_actual_area = MCGIntegerRectangleIntersection ( p_area, t_bounds);
880+ if (MCGIntegerRectangleIsEmpty (t_actual_area))
857881 return false ;
858882
859- /* UNCHECKED */ MCRegionIncludeRect (m_redraw_region, t_actual_area);
860-
861- uint8_t *t_bits = (uint8_t *)m_raster.pixels + (t_actual_area.y - t_bounds.y ) * m_raster.stride + (t_actual_area.x - t_bounds.x ) * sizeof (uint32_t );
883+ uint8_t *t_bits = (uint8_t *)m_raster.pixels + (t_actual_area.origin .y - t_bounds.origin .y ) * m_raster.stride + (t_actual_area.origin .x - t_bounds.origin .x ) * sizeof (uint32_t );
862884
863885 m_locked_area = t_actual_area;
864886
865- r_raster . format = kMCGRasterFormat_ARGB ;
866- r_raster . width = t_actual_area . width;
867- r_raster . height = t_actual_area . height;
887+ r_raster . format = kMCGRasterFormat_xRGB ;
888+ r_raster . width = t_actual_area. size . width ;
889+ r_raster . height = t_actual_area. size . height ;
868890 r_raster . stride = m_raster.stride ;
869891 r_raster . pixels = t_bits;
870892
@@ -892,12 +914,12 @@ class MCLinuxStackSurface: public MCStackSurface
892914 bool t_success = true ;
893915
894916 MCGContextRef t_context = nil;
895- MCRegionRef t_region = nil;
917+ MCGRegionRef t_region = nil;
896918
897- t_success = MCRegionCreate (t_region);
919+ t_success = MCGRegionCreate (t_region);
898920
899921 if (t_success)
900- t_success = MCRegionSetRect (t_region, MCGRectangleToMCRectangle (p_dst_rect));
922+ t_success = MCGRegionSetRect (t_region, MCGRectangleGetBounds (p_dst_rect));
901923
902924 if (t_success)
903925 t_success = LockGraphics (t_region, t_context);
@@ -913,7 +935,7 @@ class MCLinuxStackSurface: public MCStackSurface
913935
914936 UnlockGraphics ();
915937
916- MCRegionDestroy (t_region);
938+ MCGRegionDestroy (t_region);
917939
918940 return t_success;
919941 }
@@ -943,7 +965,7 @@ void MCStack::view_device_updatewindow(MCRegionRef p_region)
943965 }
944966
945967 if (t_update_region != nil)
946- MCRegionUnion (t_update_region, t_update_region, p_region);
968+ MCRegionAddRegion ( t_update_region, p_region);
947969 else
948970 t_update_region = p_region;
949971
@@ -964,11 +986,11 @@ void MCStack::view_platform_updatewindowwithcallback(MCRegionRef p_region, MCSta
964986
965987void MCStack::onexpose (MCRegionRef p_region)
966988{
967- MCLinuxStackSurface t_surface (this , p_region);
989+ MCLinuxStackSurface t_surface (this , (MCGRegionRef) p_region);
968990 if (t_surface.Lock ())
969991 {
970992 if (s_update_callback == nil)
971- view_surface_redrawwindow (&t_surface, p_region);
993+ view_surface_redrawwindow (&t_surface, (MCGRegionRef) p_region);
972994 else
973995 s_update_callback (&t_surface, p_region, s_update_context);
974996
0 commit comments