From b6593d0a09c5db5b926fdf8f17ec65a44bd566f5 Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 5 Jan 2004 01:18:16 +0000 Subject: [PATCH] implemented Double Buffering for synedit and deactivated multi buffering in TGTKObject.ExtTextOut git-svn-id: trunk@5015 - --- components/synedit/synedit.pp | 70 +++++++-- lcl/graphics.pp | 9 +- lcl/include/canvas.inc | 22 +-- lcl/interfaces/gtk/gtkproc.inc | 13 ++ lcl/interfaces/gtk/gtkproc.pp | 24 ++- lcl/interfaces/gtk/gtkwinapi.inc | 260 ++++++++++++++++--------------- 6 files changed, 232 insertions(+), 166 deletions(-) diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index a5c4e54355..f0e135719a 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -62,7 +62,7 @@ interface uses {$IFDEF SYN_LAZARUS} - FPCAdds, LCLIntf, LCLType, LMessages, + FPCAdds, LCLIntf, LCLType, LMessages, LCLProc, {$ELSE} Windows, {$ENDIF} @@ -531,6 +531,10 @@ type procedure PaintGutter(AClip: TRect; FirstLine, LastLine: integer); virtual; procedure PaintTextLines(AClip: TRect; FirstLine, LastLine, FirstCol, LastCol: integer); virtual; + {$IFDEF SYN_LAZARUS} + procedure StartPaintBuffer(const ClipRect: TRect); + procedure EndPaintBuffer(const ClipRect: TRect); + {$ENDIF} procedure RecalcCharExtent; procedure RedoItem; //sbs 2000-11-19 procedure SetCaretXY(Value: TPoint); virtual; @@ -547,6 +551,10 @@ type protected fGutterWidth: Integer; fInternalImage: TSynInternalImage; + {$IFNDEF DisableDoubleBuf} + BufferBitmap: TBitmap; // the double buffer + SavedCanvas: TCanvas; // the normal TCustomControl canvas during paint + {$ENDIF} procedure DoOnClearBookmark(var Mark: TSynEditMark); virtual; // djlp - 2000-08-29 procedure DoOnCommandProcessed(Command: TSynEditorCommand; AChar: char; Data: pointer); virtual; @@ -618,7 +626,7 @@ type function PrevWordPos: TPoint; virtual; function PixelsToRowColumn(Pixels: TPoint): TPoint; {$IFDEF SYN_LAZARUS} - function PixelsToLogicalPos(Pixels: TPoint): TPoint; + function PixelsToLogicalPos(const Pixels: TPoint): TPoint; {$ENDIF} procedure Redo; procedure RegisterCommandHandler(AHandlerProc: THookedCommandEvent; @@ -750,12 +758,12 @@ type published // inherited properties property Align; +{$IFDEF SYN_LAZARUS} + property BlockIndent; +{$ENDIF} {$IFDEF SYN_COMPILER_4_UP} property Anchors; -{$IFNDEF SYN_LAZARUS} -// ToDo Constraints property Constraints; -{$ENDIF} {$ENDIF} property Color; property Ctl3D; @@ -784,10 +792,8 @@ type property OnDragDrop; property OnDragOver; {$IFDEF SYN_COMPILER_4_UP} -{$IFNDEF SYN_LAZARUS} // ToDo Docking property OnEndDock; -{$ENDIF} {$ENDIF} property OnEndDrag; property OnEnter; @@ -799,16 +805,11 @@ type property OnMouseMove; property OnMouseUp; {$IFDEF SYN_COMPILER_4_UP} -{$IFNDEF SYN_LAZARUS} // ToDo Docking property OnStartDock; -{$ENDIF} {$ENDIF} property OnStartDrag; // TCustomSynEdit properties - {$IFDEF SYN_LAZARUS} - property BlockIndent; - {$ENDIF} property BookMarkOptions; property BorderStyle; property ExtraLineSpacing; @@ -961,7 +962,7 @@ begin end; {$IFDEF SYN_LAZARUS} -function TCustomSynEdit.PixelsToLogicalPos(Pixels: TPoint): TPoint; +function TCustomSynEdit.PixelsToLogicalPos(const Pixels: TPoint): TPoint; begin Result:=PhysicalToLogicalPos(PixelsToRowColumn(Pixels)); end; @@ -2175,6 +2176,7 @@ begin // Get the invalidated rect. Compute the invalid area in lines / columns. {$IFDEF SYN_LAZARUS} rcClip:=Rect(0,0,Width,Height); + StartPaintBuffer(rcClip); Include(fStateFlags,sfPainting); {$ELSE} rcClip := Canvas.ClipRect; @@ -2208,6 +2210,9 @@ begin // If there is a custom paint handler call it. DoOnPaint; finally + {$IFDEF SYN_LAZARUS} + EndPaintBuffer(rcClip); + {$ENDIF} UpdateCaret; {$IFDEF SYN_LAZARUS} Exclude(fStateFlags,sfPainting); @@ -3146,6 +3151,7 @@ begin end; // Do everything else with API calls. This (maybe) realizes the new pen color. dc := Canvas.Handle; + // If anything of the two pixel space before the text area is visible, then // fill it with the component background color. if (AClip.Left < fGutterWidth + 2) then begin @@ -3200,6 +3206,38 @@ begin {$ENDIF} end; +{$IFDEF SYN_LAZARUS} +procedure TCustomSynEdit.StartPaintBuffer(const ClipRect: TRect); +begin + if (SavedCanvas<>nil) then RaiseGDBException(''); + {$IFNDEF DisableDoubleBuf} + if BufferBitmap=nil then + BufferBitmap:=TBitmap.Create; + if BufferBitmap.Width [TCanvas.CopyRect] ', [])); - if Canvas <> nil - then begin - Canvas.RequiredState([csHandleValid, csBrushValid]); + if SrcCanvas<> nil then begin + SrcCanvas.RequiredState([csHandleValid, csBrushValid]); RequiredState([csHandleValid, csBrushValid]); SH := Source.Bottom - Source.Top; @@ -80,11 +79,11 @@ Begin DH := Dest.Bottom - Dest.Top; DW := Dest.Right - Dest.Left; if (Dh=0) and (DW=0) then exit; - //writeln('TCanvas.CopyRect ',ClassName,' Canvas=',Canvas.ClassName,' ', + //writeln('TCanvas.CopyRect ',ClassName,' SRcCanvas=',SrcCanvas.ClassName,' ', // ' Src=',Source.Left,',',Source.Top,',',SW,',',SH, // ' Dest=',Dest.Left,',',Dest.Top,',',DW,',',DH); StretchBlt(FHandle, Dest.Left, Dest.Top, DW, DH, - Canvas.FHandle, Source.Left, Source.Top, SW, SH, CopyMode); + SrcCanvas.FHandle, Source.Left, Source.Top, SW, SH, CopyMode); end; Assert(False, Format('Trace:<== [TCanvas.CopyRect] ', [])); @@ -94,7 +93,7 @@ end; {-----------------------------------------------} Function TCanvas.GetPixel(X,Y : Integer) : TColor; var -Msg : TLMSetGetPixel; + Msg : TLMSetGetPixel; {TLMSetGetPixel = record X,Y : Integer; PixColor : TColor; @@ -1254,6 +1253,9 @@ end; { ============================================================================= $Log$ + Revision 1.61 2004/01/05 01:18:15 mattias + implemented Double Buffering for synedit and deactivated multi buffering in TGTKObject.ExtTextOut + Revision 1.60 2004/01/03 23:14:59 mattias default font can now change height and fixed gtk crash diff --git a/lcl/interfaces/gtk/gtkproc.inc b/lcl/interfaces/gtk/gtkproc.inc index a6a87e0615..9e20121392 100644 --- a/lcl/interfaces/gtk/gtkproc.inc +++ b/lcl/interfaces/gtk/gtkproc.inc @@ -5644,6 +5644,16 @@ begin {$ENDIF GTK2} end; +function GetTextHeight(DCTextMetric: TDevContextTextMetric): integer; +// IMPORTANT: Before this call: UpdateDCTextMetric(TDeviceContext(DC)); +begin + {$IfDef Win32} + Result := DCTextMetric.TextMetric.tmHeight div 2; + {$Else} + Result := DCTextMetric.TextMetric.tmAscent; + {$EndIf} +end; + {$IFDEF ASSERT_IS_ON} {$UNDEF ASSERT_IS_ON} {$C-} @@ -5654,6 +5664,9 @@ end; { ============================================================================= $Log$ + Revision 1.239 2004/01/05 01:18:15 mattias + implemented Double Buffering for synedit and deactivated multi buffering in TGTKObject.ExtTextOut + Revision 1.238 2004/01/04 16:44:33 mattias updated gtk2 package diff --git a/lcl/interfaces/gtk/gtkproc.pp b/lcl/interfaces/gtk/gtkproc.pp index 19060ee416..0bb0821813 100644 --- a/lcl/interfaces/gtk/gtkproc.pp +++ b/lcl/interfaces/gtk/gtkproc.pp @@ -451,14 +451,6 @@ Function DeleteAmpersands(var Str : String) : Longint; function Ampersands2Underscore(Src: PChar) : PChar; function RemoveAmpersands(Src: PChar; LineLength : Longint) : PChar; -{$Ifdef GTK2} -Procedure GetTextExtentIgnoringAmpersands(FontDesc : PPangoFontDescription; Str : PChar; - LineLength : Longint; lbearing, rbearing, width, ascent, descent : Pgint); -{$Else} -Procedure GetTextExtentIgnoringAmpersands(Font : PGDKFont; Str : PChar; - LineLength : Longint; lbearing, rbearing, width, ascent, descent : Pgint); -{$EndIf} - function GetAccelGroup(const Widget: PGtkWidget; CreateIfNotExists: boolean): PGTKAccelGroup; procedure SetAccelGroup(const Widget: PGtkWidget; @@ -510,20 +502,26 @@ Function GetStyleWidget(const WName : String) : PGTKWidget; Procedure StyleFillRectangle(drawable : PGDKDrawable; GC : PGDKGC; Color : TColorRef; x, y, width, height : gint); Function StyleForegroundColor(Color : TColorRef; DefaultColor : PGDKColor): PGDKColor; +// fonts {$Ifdef GTK2} function LoadDefaultFontDesc: PPangoFontDescription; -{$Else} +Procedure GetTextExtentIgnoringAmpersands(FontDesc : PPangoFontDescription; Str : PChar; + LineLength : Longint; lbearing, rbearing, width, ascent, descent : Pgint); +{$ENDIF} +{$IFDEF GTK1} +function FontIsDoubleByteCharsFont(TheFont: PGdkFont): boolean; function LoadDefaultFont: PGDKFont; +Procedure GetTextExtentIgnoringAmpersands(Font : PGDKFont; Str : PChar; + LineLength : Longint; lbearing, rbearing, width, ascent, descent : Pgint); {$EndIf} function GetDefaultFontName: string; +Procedure FillScreenFonts(ScreenFonts : TStrings); +function GetTextHeight(DCTextMetric: TDevContextTextMetric): integer; procedure RealizeGDKColor(ColorMap: PGdkColormap; Color: PGDKColor); procedure RealizeGtkStyleColor(Style: PGTKStyle; Color: PGDKColor); Function GetSysGCValues(Color: TColorRef; ThemeWidget: PGtkWidget): TGDKGCValues; -{$Ifdef GTK1} -function FontIsDoubleByteCharsFont(TheFont: PGdkFont): boolean; -{$EndIf} Function GDKPixel2GDIRGB(Pixel : Longint; Visual : PGDKVisual; Colormap : PGDKColormap) : TGDIRGB; @@ -531,8 +529,6 @@ Function GDKPixel2GDIRGB(Pixel : Longint; Visual : PGDKVisual; Function GetWindowDecorations(AForm : TCustomForm) : Longint; Function GetWindowFunction(AForm : TCustomForm) : Longint; -Procedure FillScreenFonts(ScreenFonts : TStrings); - function GetGDKMouseCursor(Cursor: TCursor): PGdkCursor; Procedure FreeGDKCursors; diff --git a/lcl/interfaces/gtk/gtkwinapi.inc b/lcl/interfaces/gtk/gtkwinapi.inc index f43c51fbe0..72e26d568e 100644 --- a/lcl/interfaces/gtk/gtkwinapi.inc +++ b/lcl/interfaces/gtk/gtkwinapi.inc @@ -72,12 +72,12 @@ begin DCOrigin:=GetDCOffset(TDeviceContext(DC)); inc(X,DCOrigin.X); inc(Y,DCOrigin.Y); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} gdk_draw_arc(Drawable, GC, 0, X, Y, Width, Height, Angle1 shl 2, Angle2 shl 2); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} end else @@ -755,7 +755,7 @@ begin //write('TgtkObject.CreateBitmap->'); GdiObject := NewGDIObject(gdiBitmap); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} @@ -792,7 +792,7 @@ begin end; GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, GdkTrue); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} @@ -972,7 +972,7 @@ begin sError := ''; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} @@ -1048,7 +1048,7 @@ begin , [lbStyle]); end; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} @@ -1120,7 +1120,7 @@ begin Depth := -1; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} if (IsValidDC(DC) and (TDeviceContext(DC).Drawable <> nil)) then begin @@ -1136,7 +1136,7 @@ begin then begin Result := 0; WriteLn(Format('ERROR: [TgtkObject.CreateCompatibleBitmap] Illegal depth %d', [Depth])); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} Exit; @@ -1164,7 +1164,7 @@ begin GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, GdkTrue); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} @@ -1592,7 +1592,7 @@ begin PaletteVisual := nil; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} @@ -1603,7 +1603,7 @@ begin end; PaletteColormap := GDK_Colormap_new(PaletteVisual, GdkTrue); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} @@ -1671,7 +1671,7 @@ begin p:=nil; // automatically create transparency mask Window:=nil; // use the X root window for colormap - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} @@ -1708,7 +1708,7 @@ begin DisposeGDIObject(GdiObject); GdiObject:=nil; end; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} end; @@ -3003,7 +3003,7 @@ var CharsWritten, CurX, i: integer; LinePos: PChar; begin - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} with TDeviceContext(DC) do begin @@ -3035,7 +3035,7 @@ var gdk_draw_line(Buffer, GC, TxtPt.X, Y, TxtPt.X+UnderLineLen, Y); end; end; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} end; @@ -3104,10 +3104,9 @@ begin Height := Rect^.Bottom - Rect^.Top; SelectedColors := dcscCustom; EnsureGCColor(DC, dccCurrentBackColor, True, False); - {$IFNDEF DisableDoubleBuf} + {$IFDEF EnableDoubleBuf} buffered := True; buffer := gdk_pixmap_new(Drawable, Width, Height, -1); - BeginGDKErrorTrap; {$ENDIF} if buffered then begin Left:=0; @@ -3116,7 +3115,7 @@ begin Left:=Rect^.Left+DCOrigin.X; Top:=Rect^.Top+DCOrigin.Y; end; - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} if IsBackgroundColor(TColor(CurrentBackColor.ColorRef)) then @@ -3124,7 +3123,7 @@ begin Left, Top, Width, Height) else gdk_draw_rectangle(buffer, GC, 1, Left, Top, Width, Height); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} end; @@ -3132,11 +3131,7 @@ begin if UseFont<>nil then begin LineLen := FindChar(#10,Str,Count); UpdateDCTextMetric(TDeviceContext(DC)); - {$IfDef Win32} - LineHeight := DCTextMetric.TextMetric.tmHeight div 2; - {$Else} - LineHeight := DCTextMetric.TextMetric.tmAscent; - {$EndIf} + LineHeight:=GetTextHeight(DCTextMetric); if Buffered then begin TxtPt.X := 0; TxtPt.Y := LineHeight; @@ -3168,11 +3163,11 @@ begin end; end; If UnRef then begin - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} BeginGDKErrorTrap; {$ENDIF} GDK_Font_UnRef(UseFont); - {$IFNDEF DisableDoubleBuf} + {$IFDEF DebugGDKTraps} EndGDKErrorTrap; {$ENDIF} end; @@ -8250,69 +8245,66 @@ var temp_color : TGDKColor; Region: PGdiObject; RGNType : Longint; - //DCOrigin: TPoint; OffsetXY: TPoint; begin // activate clipping region of destination SelectGDIRegion(DestDC); temp_mask := nil; - if ((ClipMergeMask <> NIL) {and (ClipMergeMask^.UseMask)} - and (ClipMergeMask^.GDIBitmapMaskObject <> nil)) then + if ((ClipMergeMask = NIL) + or (ClipMergeMask^.GDIBitmapMaskObject = nil)) then exit; + + BeginGDKErrorTrap; + // create temporary mask with the size of the destination rectangle + temp_mask := PGdkBitmap(gdk_pixmap_new(NIL, width, height, 1)); + // create temporary GC for mask with no clipping + temp_gc := gdk_gc_new(temp_mask); + gdk_gc_set_clip_region(temp_gc, nil); + gdk_gc_set_clip_rectangle(temp_gc, nil); + + // clear mask + temp_color.pixel := 0; + gdk_gc_set_foreground(temp_gc, @temp_color); + + gdk_draw_rectangle(temp_mask, temp_gc, 1, 0, 0, width, height); + gdk_draw_rectangle(temp_mask, temp_gc, 0, 0, 0, width, height); + + // copy the destination clipping mask into the temporary mask + with TDeviceContext(DestDC) do begin - BeginGDKErrorTrap; - // create temporary mask with the size of the destination rectangle - temp_mask := PGdkBitmap(gdk_pixmap_new(NIL, width, height, 1)); - // create temporary GC for mask with no clipping - temp_gc := gdk_gc_new(temp_mask); - gdk_gc_set_clip_region(temp_gc, nil); - gdk_gc_set_clip_rectangle(temp_gc, nil); - - // clear mask - temp_color.pixel := 0; - gdk_gc_set_foreground(temp_gc, @temp_color); - - gdk_draw_rectangle(temp_mask, temp_gc, 1, 0, 0, width, height); - gdk_draw_rectangle(temp_mask, temp_gc, 0, 0, 0, width, height); - - // copy the destination clipping mask into the temporary mask - with TDeviceContext(DestDC) do - begin - If (ClipRegion <> 0) then begin - Region:=PGDIObject(ClipRegion); - RGNType := RegionType(Region^.GDIRegionObject); - If (RGNType <> ERROR) and (RGNType <> NULLREGION) then begin - // destination has a clipping mask - // -> copy the destination clipping mask to the temporary mask - // The X,Y coordinate in the destination relates to - // 0,0 in the temporary mask. - // The clip region of dest is always at 0,0 in dest - //DCOrigin:=GetDCOffset(TDeviceContext(DestDC)); - OffsetXY:=Point(-X,-Y); - // 1. Move the region - gdk_region_offset(Region^.GDIRegionObject,OffsetXY.X,OffsetXY.Y); - // 2. Apply region to temporary mask - gdk_gc_set_clip_region(temp_gc, Region^.GDIRegionObject); - // 3. Undo moving the region - gdk_region_offset(Region^.GDIRegionObject,-OffsetXY.X,-OffsetXY.Y); - end; + If (ClipRegion <> 0) then begin + Region:=PGDIObject(ClipRegion); + RGNType := RegionType(Region^.GDIRegionObject); + If (RGNType <> ERROR) and (RGNType <> NULLREGION) then begin + // destination has a clipping mask + // -> copy the destination clipping mask to the temporary mask + // The X,Y coordinate in the destination relates to + // 0,0 in the temporary mask. + // The clip region of dest is always at 0,0 in dest + OffsetXY:=Point(-X,-Y); + // 1. Move the region + gdk_region_offset(Region^.GDIRegionObject,OffsetXY.X,OffsetXY.Y); + // 2. Apply region to temporary mask + gdk_gc_set_clip_region(temp_gc, Region^.GDIRegionObject); + // 3. Undo moving the region + gdk_region_offset(Region^.GDIRegionObject,-OffsetXY.X,-OffsetXY.Y); end; end; - - // merge the source clipping mask into the temporary mask - gdk_draw_pixmap(temp_mask, temp_gc, ClipMergeMask^.GDIBitmapMaskObject, - 0, 0, 0, 0, width, height); - - // free the temporary GC - gdk_gc_destroy(temp_gc); - - // apply the new mask to the destination GC - // The new mask has only the size of the destination rectangle, not of - // the whole destination. Apply it to destination and move it to the right - // position - gdk_gc_set_clip_mask(DestGC, temp_mask); - gdk_gc_set_clip_origin(DestGC, x, y); - EndGDKErrorTrap; end; + + // merge the source clipping mask into the temporary mask + gdk_draw_pixmap(temp_mask, temp_gc, ClipMergeMask^.GDIBitmapMaskObject, + 0, 0, 0, 0, width, height); + + // free the temporary GC + gdk_gc_destroy(temp_gc); + + // apply the new mask to the destination GC + // The new mask has only the size of the destination rectangle, not of + // the whole destination. Apply it to destination and move it to the right + // position + gdk_gc_set_clip_mask(DestGC, temp_mask); + gdk_gc_set_clip_origin(DestGC, x, y); + EndGDKErrorTrap; end; Procedure ResetClipping(DestGC : PGDKGC); @@ -8408,9 +8400,9 @@ var end; Function ScaleAndROP(DestGC: PGDKGC; - SRC: PGDKDrawable; SRCBitmap: PGDIObject): Boolean; + Src: PGDKDrawable; SrcBitmap: PGDIObject): Boolean; var - SRCClip : PGDKPixmap; + SrcClip : PGDKPixmap; begin Result := False; @@ -8421,11 +8413,11 @@ var end; // get source mask for clipping - If (SRCBitmap <> nil) - and (SRCBitmap^.GDIBitmapMaskObject <> nil) then - SRCClip := SRCBitmap^.GDIBitmapMaskObject + If (SrcBitmap <> nil) + and (SrcBitmap^.GDIBitmapMaskObject <> nil) then + SrcClip := SrcBitmap^.GDIBitmapMaskObject else - SRCClip := nil; + SrcClip := nil; // create a temporary buffer for raster operations and scaling Case ROP of @@ -8435,18 +8427,18 @@ var begin ScaleBMP := CreateCompatibleBitmap(0, Width, Height); Scale := PGdiObject(ScaleBMP); - Scale^.GDIBitmapMaskObject := SRCClip; + Scale^.GDIBitmapMaskObject := SrcClip; SetRasterOperation(DestGC); Result := True; exit; //skip scaling end; - else begin - // create a temporary compatible bitmap with the size - // of the source and the source mask - ScaleBMP := CreateCompatibleBitmap(0, SRCWidth, SRCHeight); - Scale := PGdiObject(ScaleBMP); - Scale^.GDIBitmapMaskObject := SRCClip; - end; + else begin + // create a temporary compatible bitmap with the size + // of the source and the source mask + ScaleBMP := CreateCompatibleBitmap(0, SrcWidth, SrcHeight); + Scale := PGdiObject(ScaleBMP); + Scale^.GDIBitmapMaskObject := SrcClip; + end; end; // set raster operation for SrcCopy or NotSrcCopy @@ -8459,13 +8451,13 @@ var GDK_GC_COPY(fGC, DestGC); // clear any previous clipping in the temporary GC (fGC) - gdk_gc_set_clip_region(fGC, nil); - gdk_gc_set_clip_rectangle (fGC, nil); + gdk_gc_set_clip_region(fGC,nil); + gdk_gc_set_clip_rectangle(fGC,nil); // copy source into scale buffer BeginGDKErrorTrap; gdk_window_copy_area(Scale^.GDIPixmapObject, fGC, 0, 0, - SRC, XSRC, YSRC, SRCWidth, SRCHeight); + Src, XSrc, YSrc, SrcWidth, SrcHeight); EndGDKErrorTrap; // restore the raster operation back to SRCCOPY in the destination GC @@ -8516,6 +8508,22 @@ var SrcDevContext:=TDeviceContext(SrcDC); DestDevContext:=TDeviceContext(DestDC); SrcGDIBitmap:=SrcDevContext.CurrentBitmap; + + if (SrcGDIBitmap=nil) then exit; + if (SrcGDIBitmap^.GDIBitmapMaskObject=nil) + and (Width=SrcWidth) and (Height=SrcHeight) + and (ROP=SRCCOPY) + then begin + // simply copy the area + //writeln('DrawableToDrawable Simple copy'); + BeginGDKErrorTrap; + gdk_window_copy_area(DestDevContext.Drawable, DestDevContext.GC, X, Y, + SrcGDIBitmap^.GDIPixmapObject, XSrc, YSrc, Width, Height); + EndGDKErrorTrap; + + exit; + end; + // create a temporary graphic context for the scale and raster operations fGC := GDK_GC_New(DestDevContext.Drawable); @@ -8722,38 +8730,37 @@ var DCOrigin: TPoint; begin Assert(True, Format('trace:> [TgtkObject.StretchBlt] DestDC:0x%x; X:%d, Y:%d, Width:%d, Height:%d; SrcDC:0x%x; XSrc:%d, YSrc:%d, SrcWidth:%d, SrcHeight:%d; Rop:0x%x', [DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, SrcWidth, SrcHeight, Rop])); Result := IsValidDC(DestDC) and IsValidDC(SrcDC); + if not Result then exit; if (Width=0) and (Height=0) then exit; if (SrcWidth=0) and (SrcHeight=0) then exit; - if Result - then begin - with TDeviceContext(DestDC) do begin - DCOrigin:=GetDCOffset(TDeviceContext(DestDC)); - Inc(X,DCOrigin.X); - Inc(Y,DCOrigin.Y); - end; - with TDeviceContext(SrcDC) do begin - DCOrigin:=GetDCOffset(TDeviceContext(SrcDC)); - Inc(XSrc,DCOrigin.X); - Inc(YSrc,DCOrigin.Y); - end; - //writeln('TgtkObject.StretchBlt X=',X,' Y=',Y,' Width=',Width,' Height=',Height, - // ' XSrc=',XSrc,' YSrc=',YSrc,' SrcWidth=',SrcWidth,' SrcHeight=',SrcHeight, - // ' SrcDrawable=',HexStr(Cardinal(TDeviceContext(SrcDC).Drawable),8), - // ' DestDrawable=',HexStr(Cardinal(TDeviceContext(DestDC).Drawable),8)); + with TDeviceContext(DestDC) do begin + DCOrigin:=GetDCOffset(TDeviceContext(DestDC)); + Inc(X,DCOrigin.X); + Inc(Y,DCOrigin.Y); + end; + with TDeviceContext(SrcDC) do begin + DCOrigin:=GetDCOffset(TDeviceContext(SrcDC)); + Inc(XSrc,DCOrigin.X); + Inc(YSrc,DCOrigin.Y); + end; - If TDeviceContext(SrcDC).Drawable = nil then begin - If TDeviceContext(DestDC).Drawable = nil then - Result := NoDrawableToNoDrawable - else - Result := NoDrawableToDrawable; - end - else begin - If TDeviceContext(DestDC).Drawable = nil then - Result := DrawableToNoDrawable - else - Result := DrawableToDrawable; - end; + {writeln('TgtkObject.StretchBlt X=',X,' Y=',Y,' Width=',Width,' Height=',Height, + ' XSrc=',XSrc,' YSrc=',YSrc,' SrcWidth=',SrcWidth,' SrcHeight=',SrcHeight, + ' SrcDrawable=',HexStr(Cardinal(TDeviceContext(SrcDC).Drawable),8), + ' DestDrawable=',HexStr(Cardinal(TDeviceContext(DestDC).Drawable),8));} + + If TDeviceContext(SrcDC).Drawable = nil then begin + If TDeviceContext(DestDC).Drawable = nil then + Result := NoDrawableToNoDrawable + else + Result := NoDrawableToDrawable; + end + else begin + If TDeviceContext(DestDC).Drawable = nil then + Result := DrawableToNoDrawable + else + Result := DrawableToDrawable; end; Assert(True, Format('trace:< [TgtkObject.StretchBlt] DestDC:0x%x --> %s', [DestDC, BOOL_TEXT[Result]])); end; @@ -9092,6 +9099,9 @@ end; { ============================================================================= $Log$ + Revision 1.310 2004/01/05 01:18:16 mattias + implemented Double Buffering for synedit and deactivated multi buffering in TGTKObject.ExtTextOut + Revision 1.309 2004/01/03 23:15:00 mattias default font can now change height and fixed gtk crash