Jump to content

Steve Maughan

Members
  • Content Count

    135
  • Joined

  • Last visited

Posts posted by Steve Maughan


  1. In my mapping application I need to merge different layers together to create the map. 

     

    Question: how do I merge a bitmap with anti-aliased text with a bitmap showing a multi-colored image? Is there a way to draw the anti-aliased text on a bitmap with the alpha channel enabled and then have the transparency preserved / respected when it is combined with the other bitmap?

     

    Here's a simple example that shows the problem (code attached to this message):

    procedure TForm2.FormPaint(Sender: TObject);
    var
      f: TBitmap;
      b: TBitmap;
      x, y: integer;
      xText: string;
      xWidth, xHeight: integer;
    begin
    
      //-- Size of image
      xWidth := Form2.Width;
      xHeight := Form2.Height;
    
      //-- Create the background bitmap
      f := TBitmap.Create;
      f.PixelFormat := pf32bit;
      f.SetSize(xWidth, xHeight);
      f.Canvas.Brush.Color := clFuchsia;
      f.Canvas.FillRect(f.Canvas.ClipRect);
    
      //-- Create the bitmap with the text
      b := TBitmap.Create;
      b.PixelFormat := pf32bit;
      b.Canvas.Brush.Color := clWhite;
      b.SetSize(xWidth, xHeight);
    
      b.Canvas.Font.Size := 32;
      b.Canvas.Font.Color := clBlack;
      b.Canvas.Font.Quality := TFontQuality.fqDefault;
    
      //-- Draw the text
      xText := 'Delphi 25th';
      x := (b.Width - b.Canvas.TextWidth(xText)) div 2;
      y := (b.Height - b.Canvas.TextHeight(xText)) div 2;
      b.Canvas.TextOut(x, y, xText);
    
      //-- Transfer the text layer to the background
      TransparentBlt(f.Canvas.Handle, 0, 0, xWidth, xHeight, b.Canvas.Handle, 0, 0, xWidth, xHeight, clWhite);
    
      //-- Transfer to the form's canvas
      Form2.Canvas.CopyRect(Form2.Canvas.ClipRect, f.Canvas, f.Canvas.ClipRect);
    
      b.Free;
      f.Free;
    end;

    This results in the following screen (also attached to this message):

     

    https://ibb.co/GVWRZ6Y

     

    You can see the ugly white around the text due to the anti-aliasing. Currently I use non anti-aliased text, but that also looks blocky and ugly too.

     

    Thanks and Happy Delphi 25th!

     

    Steve

     

    2020-02-14_9-02-57.png

    Anti-Aliased-Text.zip


  2. I finally got to the bottom of this error. It's a bug in the Parallel Programming Library that ships with 10.3.2 and 10.3.3.

     

    Here's what happened...

     

    After I downgraded to 10.2.3 I was just pleased that the freezing stopped. I was also concerned that I'd be stuck using 10.2.3 for ever. So this week I upgraded again; this time to 10.3.3 in the hope the bug didn't show up in this version (the bug had initially appeared in 10.3.2). Unfortunately it showed up—I was gutted! I tried replacing the memory manager - that didn't work. I tried checking for resource leaks; there weren't any. I then switched the main rendering routine to use OmniThread instead of the PPL and that corrected the bug. It seems that after being under load, and then left for a while, the PPL's can suspend some threads for a period of up to 1 minute. If the suspended thread is in a "for" loop the program freezes. Eventually the application comes back to life but it happens repeatedly. The bug wasn't present in 10.2.3 but was present in 10.3.2.

     

    I'm elated that the bug is gone!

     

    Steve

    • Like 1

  3. I have quite a large list of 3000 objects stored in a TList<T>. I need to delete about half of them in a time-critical manner i.e. as fast as possible. I don't need to free the objects, just delete them from the list.

     

    Two possible approaches come to mind. I could simply iterate through the list and repeatedly call List.Delete(index) for each item I'd like to remove. Another alternative would be to set the item to nil and then call List.Pack at the end. Is there any advantage in the second approach? Any other insights appreciated.

     

    Steve  


  4. 1 hour ago, Anders Melander said:

    If you can reproduce the problem then simply run the application in the debugger, break when the problem occurs and examine the callstacks.

     

    ...however; My usual advice when people experience this kind of progressive or periodic slowdown/lockup is to uninstall the various cloud storage services they have running (ITunes, Google Drive, OneDrive, etc.). Solves the problem in 9 out of 10 cases.

    Hi Anders,

     

    I took your advice. There was nothing on the call stack, even in debug mode:

     

     

    Interestingly, after the freeze I started Loom and SnagIt to record the video. Both wouldn't start until AlignMix was unfrozen. To me this implies it's something to do with Windows 10.

     

    Thanks,

     

    Steve


  5. My mapping program is a VCL app that makes extensive use of GDI drawing to draw the map. I've recently upgraded from Delphi 10.2.3 to 10.3.2. The version compiled with Rio will often lock up after being used for 20 minutes. The app becomes unresponsive for about 15 seconds. In that time the CPU utilization is close to zero and the memory usage doesn't change. After the lock-up it will sometimes become fully responsive or in some case will only be responsive for a moment. There are no error message during or after a lockup. The application is compiled as 64 bit and uses about 1.6 Gb of memory while the test machine has 32 Gb i.e. it's not short of memory.

     

    What could cause the lockup? 

     

    My first thoughts is it's something to do with GDI. Has anything changed with GDI in Delphi Rio compared to Delphi Tokyo?

     

    Or maybe it's a virus scanner. I use Panda Dome. I'll switch it for something else to see if that's the problem.

     

    Or could it be Windows 10 messing with the memory allocation? I've just updated to Windows 1909.

     

    I know it's a long shot but any suggestions are welcome.

     

    Steve


  6. 12 minutes ago, David Heffernan said:

    Doesn't sound very much like dvcs is what you need. Sounds more like a central database is what you need. 

    What's your thinking?

     

    Potentially a company will want distributed people working on their part of the alignment. They may experiment locally themselves with different alignments before committing to the main alignment. They'd also like to be able to rollback changes to see what the alignment looked like at a specific date. To me this seems akin to software development.

     

    What am I missing that a central database would provide?

     

    Thanks - Steve


  7. My application manages sales territory alignments e.g. zip code "32779" is assigned to territory "T164". Typically many people want to access and make changes to these assignments. For example, the manager on the west coast may want to dissolve a territory, and a manager on the east coast may want to expand a territory. It seems to me this is akin to version control. This being the case I've been thinking that Git could be used to manage the alignment version control. For this to happen I'd need my application to be able to access all the functionality of Git: commit, pull etc.

     

    Has anyone done this before? Are there any Delphi Git components or tutorials? Would I need to distribute a copy of git - I assume I will?

     

    Steve


  8. Back when Rio was initially launched I remember Marco mentioning it now supports Windows Pen / Ink. This would enable apps to use the Surface Pen.  I can't find anything in the documentation. Does anyone know of a demo of how to use the Surface Pen with Delphi 10.3?

     

    Thanks,

     

    Steve


  9. No LLVM optimization is really disappointing. 

     

    If you wind the clock back to 1995, many of the early developers coming from VB3 were exited about a compiled executable that ran at the same speed as "C" programs. They wanted and valued fast executables. Borland / Codegear / Embarcadero have each ignored this value their developers place on fast code and haven't improved the code optimization for 20 years. It seems they take a, "it's good enough" view. I'd encourage them to invest some time and include all the optimizations that LLVM offers (even if it slows down compilation speed for the Release Build). I think they'd be surprised at how well this would be received by the Delphi community.

     

    Steve

    • Like 3

  10. Is the new release (10.3.2) component compatible with 10.3.1?

     

    I'm seeing some component vendors (e.g. DevExpress) say their latest release supports 10.3 (i.e. no mention of the ".1" or ".2"). This implies it will install components into 10.3.1 and 10.3.2. even thought this version of their components was released before 10.3.2

     

    Can anyone confirm?

     

    Thanks - Steve


  11. 7 hours ago, David Heffernan said:

    Why would you expect it to be faster?

    Why would you expect it to be significantly faster? 

    What sort of code do you expect to be faster? 

    Hi David,

     

    I'm certainly not an expert in this field. Over the years I've seen various speed benchmarks that suggest Delphi's Windows compiler produces executables that are significantly slower than those produced by the top C++ compilers (e.g. Intel). In the chess world (where I am an expert) the rule of thumb is a Delphi version of a chess engine will run about 30% slower than the C++ equivalent code bases (Critter is the engine that was developed in two parallel code bases).

     

    Let's face it, there doesn't seem to have been any work done on optimizing the code created by the Delphi compiler in the last 20 years. I'm just hoping the new backend will be better.

     

    Thanks,

     

    Steve

    • Like 1
    • Sad 1

  12. 19 hours ago, Remy Lebeau said:

    In VCL, the TBitmap.Canvas must be locked while using the TBitmap in a worker thread.  The RTL keeps track of all GDI resources it allocates, and the main UI thread runs a routine periodically that frees GDI resources that are not locked.  Which is very bad for TBitmap used in a worker thread.  The alternative is to not use TBitmap at all, just use the Win32 API directly for all GDI operations in a worker thread.

    Are you sure?

     

    As I said above, in AlignMix I render a TBitmap.Canvas for each layer of a map using one worker thread per layer. It's rock solid, no crashes or resource issues when rendering.

     

    Steve

×