{ this is not complete but it may help someone - code for 256 colour DIBs I've nearly finished a little DIB demo that I'll upload to DSP soon John B =================================== } unit DIB_surface_object; interface uses { Borland } Windows,Sysutils,Graphics,Classes, { Mine } Palunit; type Pshape = ^shape; shape = array[0..0] of Tpoint; type DIBsurfaceobject = Class(TObject) DIBheader : TMyBitmapInfo; DIBPalette : TMyLogPalette; DIBhpalette : hPalette; DIBpalsize : integer; DIBbits : Pointer; DIBhandle : THandle; DIBDC : hDC; Original_BMP : hBitmap; Original_PAL : hPalette; DIBWidth : integer; DIBHeight : integer; DIBWidth_b : integer; DIBSize : integer; constructor Create(palette:TMyLogPalette; newsize:TPoint); destructor destroy; override; procedure change_size(newsize:TPoint; force:boolean); procedure change_palette(newpal:shortstring); procedure draw_horizontal_line(x1,x2,y:integer; b:byte); procedure set_pixel(x,y:integer; b:byte); procedure safe_set_pixel(x,y:integer; b:byte); procedure fill_polygon(n:integer; poly:Pshape; fillcol:byte); procedure copy_surface_to_screen(destDC:hDC); procedure copy_screen_to_surface(sourceDC:hDC); procedure clear_surface; end; implementation { ------------------------------------------------------------------------ } { DIB surface object } { ------------------------------------------------------------------------ } constructor DIBsurfaceobject.Create(palette:TMyLogPalette; newsize:TPoint); var lp1 : integer; begin inherited Create; DIBbits := nil; DIBhandle := 0; DIBPalette := palette; DIBhpalette := CreatePalette(PLogPalette(@palette)^); DIBDC := CreateCompatibleDC(0); Original_PAL := SelectPalette(DIBDC,DIBhpalette,false); with DIBheader do begin with bmiHeader do begin biSize := sizeof(TBITMAPINFOHEADER); biWidth := newsize.x; biHeight := newsize.y; biPlanes := 1; biBitCount := 8; biCompression := BI_RGB; biSizeImage := 0; biXPelsPerMeter := 0; biYPelsPerMeter := 0; biClrUsed := 0; biClrImportant := 0; end; for lp1:=0 to 255 do BMIcolors[lp1] := (lp1+0) and 255; { Pal_indices - no offset } end; Original_BMP := 0; DIBWidth := 0; DIBHeight := 0; change_size(newsize,false); end; destructor DIBsurfaceobject.destroy; begin if Original_BMP<>0 then SelectObject(DIBDC,Original_BMP); if Original_PAL<>0 then SelectPalette(DIBDC,Original_PAL,false); if DIBhandle<>0 then DeleteObject(DIBhandle); if DIBhpalette<>0 then DeleteObject(DIBhpalette); DeleteDC(DIBDC); inherited destroy; end; procedure DIBsurfaceobject.change_size(newsize:TPoint; force:boolean); begin if (not force) and (newsize.x=DIBWidth) and (newsize.y=DIBHeight) then exit; DIBWidth := newsize.x; DIBHeight := newsize.y; DIBWidth_b := ((DIBWidth+3)shr 2)shl 2; DIBSize := DIBWidth_b*DIBHeight; if Original_BMP<>0 then SelectObject(DIBDC,Original_BMP); if DIBhandle<>0 then DeleteObject(DIBhandle); DIBheader.BMIheader.biWidth := DIBWidth; DIBheader.BMIheader.biHeight :=-DIBHeight; { Top down for me please...} DIBhandle := CreateDIBSection(DIBDC,pBitmapInfo(@DIBheader)^,DIB_PAL_COLORS,DIBbits,nil,0); Original_BMP := SelectObject(DIBDC,DIBhandle); end; procedure DIBsurfaceobject.change_palette(newpal:shortstring); begin SelectPalette(DIBDC,Original_PAL,false); create_256_identity_palette_from_file(DIBpalette,DIBhpalette,newpal); Original_PAL := SelectPalette(DIBDC,DIBhpalette,false); change_size(Point(DIBwidth,DIBheight),true); end; procedure DIBsurfaceobject.draw_horizontal_line(x1,x2,y:integer; b:byte); var lp1,offset : integer; begin offset:=integer(DIBbits)+ y*DIBWidth_b; for lp1:=x1 to x2 do Pbyte( offset+lp1 )^ := b; end; procedure DIBsurfaceobject.set_pixel(x,y:integer; b:byte); begin Pbyte( integer(DIBbits) + y*DIBWidth_b + x )^ := b; end; procedure DIBsurfaceobject.safe_set_pixel(x,y:integer; b:byte); begin if (x=0) then begin if (y=0) then begin Pbyte( integer(DIBbits) + y*DIBWidth_b + x )^ := b; end; end; end; procedure DIBsurfaceobject.fill_polygon(n:integer; poly:Pshape; fillcol:byte); var loop1 : integer; yval,ymax,ymin : integer; yval0,yval1,yval2,yval3 : integer; ydifl,ydifr : integer; xval0,xval1,xval2,xval3 : integer; xleft,xright : integer; mu : integer; minvertex : integer; vert0,vert1,vert2,vert3 : integer; begin ymax:=-99999; ymin:=99999; { get top & bottom scan lines to work with } for loop1:=0 to n-1 do begin yval:=poly^[loop1].y; if yval>ymax then ymax:=yval; if yvalydifl then begin vert0:=vert1; vert1:=(vert1+1) mod n-1; yval0 := poly^[vert0].y; yval1 := poly^[vert1].y; xval0 := poly^[vert0].x; xval1 := poly^[vert1].x; ydifl := yval1-yval0; mu:=(loop1-yval0) end; if ydifl<>0 then xleft:=xval0 - (mu*integer(xval0-xval1) div ydifl) else xleft:=xval0; {intersection on right hand side } if ydifr<>0 then mu:=(loop1-yval2) else mu:=ydifr; if mu>ydifr then begin vert2:=vert3; vert3:=(vert3-1) mod n-1; yval2 := poly^[vert2].y; yval3 := poly^[vert3].y; xval2 := poly^[vert2].x; xval3 := poly^[vert3].x; ydifr := yval3-yval2; if ydifr<>0 then mu:=(loop1-yval2) else mu:=ydifr; end; if ydifr<>0 then xright:=xval2 + (mu*integer(xval3-xval2) div ydifr) else xright:=xval2; draw_horizontal_line(xleft,xright,loop1,fillcol); end; end; procedure DIBsurfaceobject.copy_surface_to_screen(destDC:hDC); begin SelectPalette(destDC,DIBhpalette,false); BitBlt(destDC,0,0,DIBWidth,DIBHeight,DIBDC,0,0,SRCCOPY); end; procedure DIBsurfaceobject.copy_screen_to_surface(sourceDC:hDC); begin BitBlt(DIBDC,0,0,DIBWidth,DIBHeight,sourceDC,0,0,SRCCOPY); end; procedure DIBsurfaceobject.clear_surface; var DWORDptr : Plongint; lp1 : integer; begin for lp1:=0 to DIBheight-1 do draw_horizontal_line(0,DIBwidth,lp1,lp1); exit; DWORDptr:=DIBbits; for lp1:=0 to (DIBsize div 4)-1 do begin Plongint(DWORDptr)^:=$00000000; inc(DWORDptr); end; end; initialization end.