Jump to content

pyscripter

Members
  • Content Count

    974
  • Joined

  • Last visited

  • Days Won

    61

Posts posted by pyscripter


  1. LIBSUFFIX AUTO has been a much requested feature for ages.  The Delphi 10.4.1 announcement said:

     

    Quote

    Package AUTO libsuffix: packages can now have an automatic version suffix, instead of manually updating and specifying the right version suffix with each new release. (The compiler quietly supported this in 10.4, but full support for the feature in the IDE and package project settings is introduced in 10.4.1.)

    Sounded interesting so I decided to try that.  I first searched the documentation and found the following:

    Quote

    Note: In RAD Studio Sydney 10.4, the $LIBSUFFIX directive allows the use of an AUTO option. This option makes the compiler use the current release number for packages, it also allows to upgrade a package to a new release, with no need to update the libsuffix value.

     

    So I added {$LIBSUFFIX AUTO} to a package of mine say xyz.dpk  and the bpl file generated was indeed xyz270.bpl.   However I got an error message saying:

     

    Quote

    [Fatal Error] Can't load package xyzAUTO.bpl.
    The system cannot find the file specified 

    This much for "full support" for this feature.  :classic_angry:   Am I missing something??

    • Sad 1

  2. 57 minutes ago, Anders Melander said:

    If you care about speed use a SAX parser instead

    ... of TXMLDocument:classic_biggrin:.  Fully agree.

     

    MSXML contains a SAX reader/writer.  Delphi implementation examples at http://www.craigmurphy.com/bug/.

     

    XMLLite is a good alternative to SAX on Windows.  See the note about push and pull parsers.  Similar speed and much easier to program with.  And there is a Delphi wrapper (just a single unit to add to  your project).


  3. 18 hours ago, Javier Tarí said:

    If you are interested in performance, http://kluug.net (Ondřej Pokorný) has two excellent libraries; the freeware OmniXML and the commercial OXml. I'm user and customer of OXml

    OmniXML is included in Delphi, but I am not sure how it compares to the standalone one.

     

    If you look at the benchmarks of OXml you will see that if you access the library through Delphi XML and the OXml vendor  you would consume almost 10 times more memory and  5.7 times more CPU time compared to raw access.  The navigation time increases 32 times!! Which is exactly the point I was trying to make.

     

    image.thumb.png.b16fa4fd3de742a43be6cbd3b03603f5.png


  4. 2 hours ago, Andrea Raimondi said:

    This is why I don't necessarily agree with what you're saying. 

    Where exactly do we disagree?  I started by saying the features are great.  But if xml processing is a performance bottleneck you can improve performance drastically (see below) by accessing the underlying implementation directly with minimal changes to your code, since implementations follow the standard DOM interfaces.


  5. XML used to be considered the universal data format.  Now is a bit passé with JSON, YAML etc being "in".   I got involved in XML parsing, since SVG files are in XML format.

     

    XML Delphi support

    At the surface the XML support in Delphi is very good:

    • You have TXMLDocument/IXMLDocument offering high-level support (Xml.xmldoc)
    • Support for the standard DOM interfaces (Xml.XmlDom)
    • Multiple implementations including (MSXML, OmniXML, OpenXML and more)
    • Ability to plug in your own implementation
    • Multiple platform support.

    The most common way of accessing XML is through TXMLDocument/IXMLDocument.   However there is a big catch: PERFORMANCE.  Say you want to use MSXML and you specify 'MSXML' as your DefaultDomVendor.  (or you simply include the implementation unit Xml.Win.msxmldom in your uses clause).  Your create an XML document and you access the top node:

    var Doc: IXMLDocument = TXMLDocument.Create(nil);
    var Node: IXMLNode := Doc.DocumentElement;

    Node is an IXMLInterface implemented by TXMLNode (TInterfacedObject defined in Xml.XmlDoc).

    TXMLNode wraps an IDOMNode stored in a private field FDOMNode.  IDOMNode is defined in Xml.Xmldom.

    The IDOMNode is implemented by the used vendor in this case Xml.Win.msxmldom by a class TMSDOMNode

    TMSDOMNode (also a TInterfacedObject) wraps IXMLDOMNode stored in a private field FMSNode.  IXMLDOMNode is defined in Winapi.msxml.

     

    As a result when you create any IXMLNode, a TXMLNode is created and this creates a TMSDOMNode which points to an IXMLDOMNode.   Any call/property access to IXMLNode translates in a call of IDOMNode which then calls IXMLDOMNode.  The created TInterfaced objects also need to be destroyed when you release your XML Node. The same two-level indirection applies to all XML objects (attributes, Children) and cause a huge degradation of performance.

     

    Conclusion

    If you care about speed forget about TXMLDocument.  You can access the Vendor implementation or even better in the case of MSXML the Microsoft ActiveX objects directly:

    uses WinAPI.msxml
    var  XML: IXMLDOMDocument3 := CoDOMDocument60.Create;
    XML.loadXML(XMLString);
    var   DocNode: IXMLDOMNode := XML.documentElement;

    In SVG parsing and processing accessing directly the ActiveX objects reduced processing time by more than 50%.

     

    Additional tip

    A common performance pitfall with MSXML is explained in http://www.gerixsoft.com/blog/delphi/msxml.   The fastest way to iterate through ChildNodes is via getFirstChild/nextSibling and Attributes via nextNode.

     

     

     

     

     

    • Like 4

  6. 3 hours ago, Ondrej Kelle said:

    If you wanted to avoid the requirement of having the fonts installed globally in Windows you could write a design package with the fonts linked in as resources. The package, when loaded by the IDE, could load the fonts from the resources (using the code shown by @Attila Kovacs) and call Screen.ResetFonts to signal the IDE to reinitialize its font list . After that the fonts would be available to the IDE.

    Indeed:

    From https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontmemresourceex

    Quote

     

    This function allows an application to get a font that is embedded in a document or a webpage. A font that is added by AddFontMemResourceEx is always private to the process that made the call and is not enumerable.

    A memory image can contain more than one font. When this function succeeds, pcFonts is a pointer to a DWORD whose value is the number of fonts added to the system as a result of this call. For example, this number could be 2 for the vertical and horizontal faces of an Asian font.

    When the function succeeds, the caller of this function can free the memory pointed to by pbFont because the system has made its own copy of the memory. To remove the fonts that were installed, call RemoveFontMemResourceEx. However, when the process goes away, the system will unload the fonts even if the process did not call RemoveFontMemResource.

     

     


  7.  dic.Items['aaa']:=l2;

    dic.Items['aaa'] already contains l2 and l2 is freed before it is readded, since you set 

    doOwnsValues

    Also an issue would occur if you do

    dic.Items['bbb']:=l2;

     

    When the dictionary is destroyed the list will be freed twice.


  8. In an earlier thread I presented an Interface-based access to native Windows (Direct2D) SVG support for Delphi applications.  This has now been integrated into the SVGIconImageList components by @Carlo Barazzetta.  Carlo is a kind of master of ImageLists (among other things).  Have a look at his IconFontsImageList for instance. His SVGIconImageList component was based on the work of Martin Walter who must be a great programmer.  His SVG component covered almost every SVG element and was well structured and cleanly written.  There were numerous bugs and issues though, which, to a large extent, were fixed over the last few weeks and the code was refactored and optimized.  Finally, @Vincent Parrett contributed a virtual version of the Image List, mirroring Delphi's VirtualImageList.

     

    So in its current form the component features:

    • An SVGImageCollection component that inherits from Delphi's CustomImageCollection and thus is compatible with VirtualImageList
    • A choice of SVG engines:  the pascal one based on Martin's work which is using GDI+ and the native Windows one which is using Direct2D.
    • Other SVG engines can be plugged-in with minimum effort.
    • Excellent design support with a nice and effective SVGImageCollection editor developed by Carlo and the built-in VirtualImageList editor.
    • Support for changing the opacity and color of the SVGs including using GrayScale.  If you adopt  Material Design for example and you use VCL styles, you can adjust the icon color to the style.
    • Compatibility with older Delphi versions going back to XE6.
    • It is free and open-source

     

    Svgs are vastly superior to bitmaps because they are typically tiny text files and scale perfectly.  So, you do not need to ship with your application multiple resolutions of your images to match the DPI of the monitors.  And there is a vast number of free SVGs to cover most needs.  IMHO the combination of SVGImageCollection with Delphi's VirtualImageList is the best available solution (commercial ones included) for building DPI-aware Windows applications.  Give it a try.

    • Like 12
    • Thanks 6

  9. PyScripter, an Open Source, freely available Python IDE written in Delphi, has reached 1 million downloads from Sourceforge.  This is in addition to many millions of downloads from its earlier home at the now defunct Google Code and an unknown number of downloads from other distribution channels.

     

    Historic note:

     

    The initial motivation was to build a good scripting solution for Delphi applications.   About 20 years ago Microsoft was still promoting ActiveX scripting and Windows Script Engines (such as vbScript and jScript) as the way of building scripting solutions for Windows applications (one of many Microsoft technologies that was all but abandoned).  At that time Python was relatively unknown, but it so happened that it was available as a Windows Script Engine and I looked into it.  I loved the clean syntax, the expressiveness and conciseness of the language.  Other things I liked were duck typing, batteries included, strong object orientation (everything is an object) etc..   The first iteration was an IDE (editor/debugger) for ActiveX Script Engines.   But there were many bugs and limitations of Active Scripting both on the Microsoft/Windows side and the Python side.

     

    I then came across Python4Delphi which at the time was maintained by a Canadian developer Morgan Martinet.    I started contributing to that project and later become its main maintainer, when Morgan's interested shifted to other things.  I also developed a simple Python IDE which was named PyScripter and was originally distributed alongside Python4Delphi.  There was very few Python IDEs available at the time and somehow the project became known in the Python community and instantly popular.   For me, developing PyScripter was just a hobby, but I received a lot of encouragement and kept on improving it.  I was also making some income from donations and Google AdSense.  Both PyScripter and Python4Delphi were later moved to Google Code.  Python popularity was steadily increasing and at the peak of PyScripter's popularity around 2010, there were hundreds of thousands of downloads the days following each new release.

     

    More recently as we all know Python became one of the most popular programming languages, but at the same time there was strong competition to PyScripter from freely available commercial grade IDE's such as Jetbrains PyCharm and Microsoft's Visual Studio and Visual Studio Code.  PyScripter was almost abandoned when Google Code closed down due to my frustration,  but after a couple of years of inactivity the project was moved to Github and development resumed.  Downloads are available through Sourceforge, since 2016.  Through the years PyScripter has kept a large and loyal group of followers.   I get many comments along the lines "I have tried VSCode, I have tried PyCharm, but I keep going back to PyScripter".   PyScripter is also quite widely used in many Universities for introducing Python to students. 

     

    And almost 20 years after its first release, PyScripter is still going strong...

    • Like 29
    • Thanks 3

  10. 14 hours ago, Rollo62 said:

    Maybe you could clarify what that "Python" note really means ?

    It refers to the intention to promote Python4Delphi as a means of bringing Python and Delphi closer together:

     

    Python for Delphi (P4D) is a set of free components that wrap up the Python dll into Delphi and Lazarus (FPC). They let you easily execute Python scripts, create new Python modules and new Python types. You can create Python extensions as dlls and much more. P4D provides different levels of functionality:

    • Low-level access to the python API
    • High-level bi-directional interaction with Python
    • Access to Python objects using Delphi custom variants (VarPyth.pas)
    • Wrapping of Delphi objects for use in python scripts using RTTI (WrapDelphi.pas)
    • Creating python extension modules with Delphi classes and functions

    P4D makes it very easy to use python as a scripting language for Delphi applications. It comes with an extensive range of demos and tutorials.

     

    • Like 6
    • Thanks 1

  11. @Attila KovacsThanks.

     

    Just replace D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT with $00000004.

    And of course both LPCWSTR and LPWSTR are cast to PWideChar.  But you are right!

     

    I would like to add that the purpose of Winapi.D2DMissing is not to provide for the missing D2D API, but to include just enough to serve the purpose of handling svg files.   Warning: there are many translation errors in the the parts not used in this project.

     

    "TOSVersion.Build returns 0 on my system".

    Any idea why?  Is this a Delphi bug?  

     

    A more reliable way would be:

    if Supports(RenderTarget, ID2D1DeviceContext5) then
      //Supported

    But that would involve creating the Factory and the Render Target.

     

    Any other suggestions?

     


  12. 1 hour ago, Gustav Schubert said:

    Works for me! Except for two minor observations:

     

    a) in Winapi.D2DMissing there are references to some enum values (const) which are not available in my Rio installation, but those can be looked up on the Internet.

    
      const 
        D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR    = 0; //D2D1_INTERPOLATION_MODE_DEFINITION_NEAREST_NEIGHBOR;
        ...

    b) GrayScale can be set only once, thereafter it fails with EOSError, Code 87, Wrong Parameter?

    The attached fixes both issues.

     

    Svg.zip

    • Thanks 1

  13. In the attachment you can find a high-level interface-based encapsulation of the Direct2D SVG functionality.  It allows you to parse SVG files and draw them to a GDI/GDI+ DC.  Requires Windows 10 with Creators Update or later.

     

    Main form code  to display SVG files:

    { TForm1 }
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      fSVG := GetD2DSVGHandler.NewSvg;
      fSVG.LoadFromFile('..\..\browser.svg');
      //fSVG.FixedColor := TAlphaColorRec.Red;
      //fSVG.Opacity := 0.5;
      fSVG.GrayScale := True;
    end;
    
    procedure TForm1.Paint;
    begin
      inherited;
      fSvg.PaintTo(Canvas.Handle, TRectF.Create(ClientRect), True);
    end;
    
    procedure TForm1.Resize;
    begin
      inherited;
      Invalidate;
    end;

    Features:

    • Scale to any size
    • Keep aspect ratio (optionally)
    • Control opacity
    • Recolor to any color
    • Draw in gray scale

     

    Samples:

    image.thumb.png.d599fed793f9dc6ac1cd12c09f4b4827.png

     

    The above in grayscale:

    image.thumb.png.6b4ea11cb573e3f1b90e5d9ecee3f9f4.png

     

    Svg.zip

     

    image.png

    • Like 17
×