Changeset 538


Ignore:
Timestamp:
Apr 16, 2024, 10:57:39 AM (2 weeks ago)
Author:
chronos
Message:
  • Fixed: Map drawing in case of fractional scaling.
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LocalPlayer/IsoEngine.pas

    r537 r538  
    5252    DefHealth: Integer;
    5353    FAdviceLoc: Integer;
    54     DataCanvas: TCanvas;
    55     MaskCanvas: TCanvas;
    5654    LandPatch: TBitmap;
    5755    OceanPatch: TBitmap;
     
    329327    raise Exception.Create(FileName + ' not found.');
    330328
     329
    331330  FileName := Format('Cities%dx%d.png', [xxt * 2, yyt * 2]);
    332331  IsoMapCache[ATileSize].HGrCities := LoadGraphicSet(FileName);
     
    584583begin
    585584  FOutput.Canvas.Font.Color := Color;
    586   FOutput.Canvas.TextRect(Rect(FLeft, FTop, FRight, FBottom), X, Y, S)
     585  FOutput.Canvas.TextRect(Rect(FLeft, FTop, FRight, FBottom), X, Y, S);
    587586end;
    588587
     
    593592  begin
    594593    Width := Width - (FLeft - X);
    595     xSrc := xSrc + (FLeft - X);
     594    XSrc := XSrc + (FLeft - X);
    596595    X := FLeft;
    597596  end;
     
    599598  begin
    600599    Height := Height - (FTop - Y);
    601     ySrc := ySrc + (FTop - Y);
     600    YSrc := YSrc + (FTop - Y);
    602601    Y := FTop;
    603602  end;
     
    609608    Exit;
    610609
     610  {$IFDEF DPI}
    611611  BitBltBitmap(FOutput, X, Y, Width, Height, Src, xSrc, ySrc, Rop);
     612  {$ELSE}
     613  BitBltCanvas(FOutput.Canvas, X, Y, Width, Height, Src.Canvas, xSrc, ySrc, Rop);
     614  {$ENDIF}
    612615end;
    613616
     
    649652    Exit;
    650653
    651   BitBltCanvas(FOutput.Canvas, xDst, yDst, Width, Height, MaskCanvas, xSrc, ySrc, SRCAND);
     654  BitBltBitmap(FOutput, xDst, yDst, Width, Height, HGrTerrain.Mask, xSrc, ySrc, SRCAND);
    652655  if not PureBlack then
    653     BitBltCanvas(FOutput.Canvas, xDst, yDst, Width, Height, DataCanvas, xSrc, ySrc, SRCPAINT);
     656    BitBltBitmap(FOutput, xDst, yDst, Width, Height, HGrTerrain.Data, xSrc, ySrc, SRCPAINT);
    654657end;
    655658
     
    707710      if Flags and unFortified <> 0 then
    708711      begin
    709         { DataCanvas := HGrTerrain.Data.Canvas;
    710           MaskCanvas := HGrTerrain.Mask.Canvas;
    711           TerrainSprite(X, Y + 16, 12 * 9 + 7);  }
     712        { TerrainSprite(X, Y + 16, 12 * 9 + 7);  }
    712713        Sprite(HGrStdUnits, X, Y, xxu * 2, yyu * 2, 1 + 6 * (xxu * 2 + 1), 1);
    713714      end;
     
    11521153  end; { square not discovered }
    11531154
    1154   if not(FoW and (Tile and fObserved = 0)) then
     1155  if not (FoW and (Tile and fObserved = 0)) then
    11551156    PaintBorder;
    11561157
     
    15691570                end;
    15701571              BitBltBitmapOutput(OceanPatch, X + dx * xxt, Y + dy * yyt, xxt, yyt,
    1571                 Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY)
    1572             end
     1572                Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY);
     1573            end;
    15731574          end
    15741575          else
     
    16251626            else
    16261627              BitBltBitmapOutput(LandPatch, X + dx * xxt, Y + dy * yyt, xxt, yyt,
    1627                 Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY)
     1628                Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY);
    16281629          end;
    16291630      end;
    16301631
    1631   DataCanvas := HGrTerrain.Data.Canvas;
    1632   MaskCanvas := HGrTerrain.Mask.Canvas;
    16331632  for dy := -2 to ny + 1 do
    16341633    for dx := -1 to nx do
     
    16401639        PaintTileExtraTerrain(X + xxt * dx, Y + yyt + yyt * dy,
    16411640          dLoc(Loc, dx, dy));
     1641
    16421642  if CityOwner >= 0 then
    16431643  begin
  • trunk/Packages/CevoComponents/ScreenTools.pas

    r536 r538  
    549549            DataPixel.PixelB := 0;
    550550          end else begin
    551             MaskPixel.PixelR := $00;
    552             MaskPixel.PixelG := $00;
    553             MaskPixel.PixelB := $00;
     551            MaskPixel.PixelR := 0;
     552            MaskPixel.PixelG := 0;
     553            MaskPixel.PixelB := 0;
    554554          end;
    555555          DataPixel.NextPixel;
  • trunk/Packages/DpiControls/Dpi.Common.pas

    r523 r538  
    1111
    1212function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc,
    13     YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
     13  YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
    1414function BitBltCanvas(Dest: TCanvas; X, Y, Width, Height: Integer; Src: TCanvas;
    15     XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
     15  XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
     16function BitBltBitmap(Dest: TBitmap; X, Y, Width, Height: Integer; Src: TBitmap;
     17  XSrc, YSrc: Integer; Rop: DWORD = SRCCOPY): Boolean;
    1618function CreateRectRgn(X1, Y1, X2, Y2: Integer): HRGN;
    1719{$IFDEF WINDOWS}
     
    3941resourcestring
    4042  SNotImplemented = 'Not implemented';
     43  SUnsupportedPaintOperationType = 'Unsupported paint operation type';
    4144
    4245
    4346implementation
     47
     48uses
     49  NativePixelPointer;
    4450
    4551function BitBltCanvas(Dest: TCanvas; X, Y, Width, Height: Integer;
     
    4753begin
    4854  Result := BitBlt(Dest.Handle, X, Y, Width, Height, Src.Handle, XSrc, YSrc, Rop);
     55end;
     56
     57function BitBltBitmap(Dest: TBitmap; X, Y, Width, Height: Integer;
     58  Src: TBitmap; XSrc, YSrc: Integer; Rop: DWORD): Boolean;
     59var
     60  SrcPixel: TPixelPointer;
     61  DstPixel: TPixelPointer;
     62  DstWidth, DstHeight: Integer;
     63  SrcWidth, SrcHeight: Integer;
     64  XX, YY: Integer;
     65  DstPixelX, DstPixelY: Integer;
     66  XNative, YNative: Integer;
     67  DstPixelWidth, DstPixelHeight: Integer;
     68begin
     69  if Frac(ScreenInfo.Dpi / 96) = 0 then
     70  begin
     71    // Use faster non-fractional scaling
     72    Result := BitBlt(Dest.Canvas.Handle, X, Y, Width, Height, Src.Canvas.Handle, XSrc, YSrc, Rop);
     73    Exit;
     74  end;
     75
     76  if X < 0 then begin
     77    Width := Width + X;
     78    XSrc := XSrc - X;
     79    X := 0;
     80  end;
     81  if Y < 0 then begin
     82    Height := Height + Y;
     83    YSrc := YSrc - Y;
     84    Y := 0;
     85  end;
     86  if (X + Width) > Dest.Width then begin
     87    Width := Dest.Width - X;
     88  end;
     89  if (Y + Height) > Dest.Height then begin
     90    Height := Dest.Height - Y;
     91  end;
     92
     93  DstWidth := ScaleToNativeDist(X, Width);
     94  DstHeight := ScaleToNativeDist(Y, Height);
     95  SrcWidth := ScaleToNativeDist(XSrc, Width);
     96  SrcHeight := ScaleToNativeDist(YSrc, Height);
     97  XNative := ScaleToNative(X);
     98  YNative := ScaleToNative(Y);
     99
     100  Dest.BeginUpdate;
     101  SrcPixel := TPixelPointer.Create(Src.NativeBitmap);
     102  DstPixel := TPixelPointer.Create(Dest.NativeBitmap);
     103  for YY := 0 to Height - 1 do begin
     104    DstPixelHeight := ScaleToNative(Y + YY + 1) - ScaleToNative(Y + YY);
     105    for DstPixelY := 0 to DstPixelHeight - 1 do begin
     106      for XX := 0 to Width - 1 do begin
     107        SrcPixel.SetXY(ScaleToNative(XSrc + XX), ScaleToNative(YSrc + YY));
     108        DstPixel.SetXY(ScaleToNative(X + XX), ScaleToNative(Y + YY) + DstPixelY);
     109        DstPixelWidth := ScaleToNative(X + XX + 1) - ScaleToNative(X + XX);
     110        for DstPixelX := 0 to DstPixelWidth - 1 do begin
     111{$IFDEF DEBUG}
     112          if SrcPixel.PosValid and DstPixel.PosValid then
     113{$ENDIF}
     114            if Rop = SRCCOPY then begin
     115              DstPixel.PixelB := SrcPixel.PixelB;
     116              DstPixel.PixelG := SrcPixel.PixelG;
     117              DstPixel.PixelR := SrcPixel.PixelR;
     118            end else
     119            if Rop = SRCPAINT then begin
     120              DstPixel.PixelB := SrcPixel.PixelB or DstPixel.PixelB;
     121              DstPixel.PixelG := SrcPixel.PixelG or DstPixel.PixelG;
     122              DstPixel.PixelR := SrcPixel.PixelR or DstPixel.PixelR;
     123            end else
     124            if Rop = SRCAND then begin
     125              DstPixel.PixelB := SrcPixel.PixelB and DstPixel.PixelB;
     126              DstPixel.PixelG := SrcPixel.PixelG and DstPixel.PixelG;
     127              DstPixel.PixelR := SrcPixel.PixelR and DstPixel.PixelR;
     128            end else
     129            if Rop = DSTINVERT then begin
     130              DstPixel.PixelB := not DstPixel.PixelB;
     131              DstPixel.PixelG := not DstPixel.PixelG;
     132              DstPixel.PixelR := not DstPixel.PixelR;
     133            end else begin
     134              raise Exception.Create(SUnsupportedPaintOperationType);
     135            end;
     136          DstPixel.NextPixel;
     137        end;
     138      end;
     139      //DstPixel.NextLine;
     140    end;
     141  end;
     142  Dest.EndUpdate;
     143  Result := True;
    49144end;
    50145
     
    95190function ScaleToNative(Value: Integer): Integer;
    96191begin
    97   Result := Round(Value * ScreenInfo.Dpi / 96);
     192  Result := Ceil(Value * ScreenInfo.Dpi / 96);
    98193end;
    99194
  • trunk/Packages/DpiControls/Dpi.Graphics.pas

    r506 r538  
    692692  SrcPtr: TPixelPointer;
    693693  DstPtr: TPixelPointer;
    694   xx, yy: Integer;
    695   SrcX, SrcY: Integer;
    696   DstX, DstY: Integer;
    697   DstWidth, DstHeight: Integer;
    698 begin
    699   //Dst.Canvas.StretchDraw(Rect(0, 0, ScaleToNative(Dst.Width), ScaleToNative(Dst.Height)), Src);
    700   //Exit;
     694  XX, YY: Integer;
     695  DstPixelX, DstPixelY: Integer;
     696  DstPixelWidth, DstPixelHeight: Integer;
     697begin
    701698  Dst.BeginUpdate;
    702699  SrcPtr := TPixelPointer.Create(Src, 0, 0);
    703700  DstPtr := TPixelPointer.Create(Dst, 0, 0);
    704   {for yy := 0 to Dst.Height - 1 do begin
    705     for xx := 0 to Dst.Width - 1 do begin
    706       SrcPtr.SetXY(Min(ScaleFromNative(xx), Src.Width - 1),
    707         Min(ScaleFromNative(yy), Src.Height - 1));
    708       DstPtr.PixelB := SrcPtr.PixelB;
    709       DstPtr.PixelG := SrcPtr.PixelG;
    710       DstPtr.PixelR := SrcPtr.PixelR;
    711       DstPtr.NextPixel;
    712     end;
    713     DstPtr.NextLine;
    714   end;
    715   }
    716   for SrcY := 0 to Src.Height - 1 do begin
    717     DstHeight := ScaleToNative(SrcY + 1) - ScaleToNative(SrcY);
    718     for DstY := 0 to DstHeight - 1 do begin
    719       for SrcX := 0 to Src.Width - 1 do begin
    720         DstWidth := ScaleToNative(SrcX + 1) - ScaleToNative(SrcX);
    721         for DstX := 0 to DstWidth - 1 do begin
     701  for YY := 0 to Src.Height - 1 do begin
     702    DstPixelHeight := ScaleToNative(YY + 1) - ScaleToNative(YY);
     703    for DstPixelY := 0 to DstPixelHeight - 1 do begin
     704      for XX := 0 to Src.Width - 1 do begin
     705        DstPixelWidth := ScaleToNative(XX + 1) - ScaleToNative(XX);
     706        for DstPixelX := 0 to DstPixelWidth - 1 do begin
    722707          DstPtr.PixelB := SrcPtr.PixelB;
    723708          DstPtr.PixelG := SrcPtr.PixelG;
  • trunk/Packages/DpiControls/Dpi.PixelPointer.pas

    r507 r538  
    9393
    9494resourcestring
    95   SOutOfRange = 'Pixel pointer out of range [X: %d. Y: %d]';
     95  SOutOfRange = 'Pixel pointer out of range [X: %d, Y: %d, Width: %d, Height: %d]';
    9696  SWrongBitmapSize = 'Wrong bitmap size [width: %d, height: %d]';
    9797
     
    160160    X := B - Y * BytesPerLine;
    161161    X := Floor(X / BytesPerPixel);
    162     raise Exception.Create(Format(SOutOfRange, [X, Y]));
     162    raise Exception.Create(Format(SOutOfRange, [X, Y, Width, Height]));
    163163  end;
    164164  {$ENDIF}
  • trunk/Packages/DpiControls/NativePixelPointer.pas

    r506 r538  
    6363    procedure SetX(X: Integer); inline; // Set horizontal pixel position relative to base
    6464    procedure CheckRange; inline; // Check if current pixel position is not out of range
     65    function PosValid: Boolean;
    6566    class function Create(Bitmap: TRasterImage; BaseX: Integer = 0; BaseY: Integer = 0): TPixelPointer; static;
    6667    property PixelARGB: TColor32 read GetPixelARGB write SetPixelARGB;
     
    9394
    9495resourcestring
    95   SOutOfRange = 'Pixel pointer out of range [X: %d. Y: %d]';
     96  SOutOfRange = 'Pixel pointer out of range [X: %d, Y: %d, Width: %d, Height: %d]';
    9697  SWrongBitmapSize = 'Wrong bitmap size [width: %d, height: %d]';
    9798
     
    159160    X := X - Y * BytesPerLine;
    160161    X := Floor(X / BytesPerPixel);
    161     raise Exception.Create(Format(SOutOfRange, [X, Y]));
     162    raise Exception.Create(Format(SOutOfRange, [X, Y, Width, Height]));
    162163  end;
    163164  {$ENDIF}
     165end;
     166
     167function TPixelPointer.PosValid: Boolean;
     168begin
     169  Result := not ((PByte(Pixel) < PByte(Data)) or
     170    (PByte(Pixel) >= PByte(Data) + Height * BytesPerLine));
    164171end;
    165172
Note: See TracChangeset for help on using the changeset viewer.