Menu

#1364 Platform interface changes for 5.0

Committed
closed
scintilla (287)
5
2021-06-02
2020-06-28
No

Scintilla 5.0 is most concerned with splitting out lexing functionality into the Lexilla project.

It is also an opportunity to make improvements that break compatibility.

The Platform.h file and the features it represents should be improved with use of newer C++17 features. Graphics methods should support scaled drawing and should support translucency in more cases.

This will lead to many change sets and an initial set is attached to this issue. Currently, the interface described in Platform.h is the main focus with incomplete and untested implementations.

The changes to Platform.h are in Platform3.h.patch and the full set of changes including implementations are in 3.patch.

2 Attachments

Related

Bugs: #2241
Feature Requests: #1398

Discussion

1 2 > >> (Page 1 of 2)
  • Neil Hodgson

    Neil Hodgson - 2020-06-28

    Here are some working notes on the changes.

    Split into Surface and Window definition files?

    Return std::unique_ptr instead of raw pointers.

    noexcept where reasonable. Anything that allocates should not be noexcept in case of memory or resource exhaustion.
    Surface::Release
    Platform::Assert (and other debug calls but not discovery functions which could allocate)
    Window::Destroy
    ListBox::Clear
    Menu::Destroy
    Change Platform to a namespace as there is no Platform object.

    UTF-8 forms of Surface text operations. This allows annotations and similar with any characters even when the main text is Latin-1.
    Surface::DrawText*
    Surface::MeasureWidths
    Surface::WidthText
    Virtual methods on Editor to convert between current encoding to UTF-8 and back. These need to be implemented on each platform's ScintillaBase subclass.
    virtual std::string UTF8FromEncoded(std::string_view encoded) const = 0;
    virtual std::string EncodedFromUTF8(std::string_view utf8) const = 0;

    Surface::Stadium to draw horizontal rectangles with rounded ends or one rounded end and one square end.
    enum class Ends { left, right, both };
    virtual void Stadium(PRectangle rc, ColourAlpha fill, ColourAlpha outline, Ends ends) = 0;

    Surface::FrameRectangle to draw unfilled rectangles.
    void FrameRectangle(PRectangle rc, ColourAlpha frame, float strokeWidth)=0;

    Surface initialiser that takes an extendable struct so that more fields can be added over time rather than requiring a new method that causes old implementations to break.

    Add strokeWidth parameters to various Surface drawing calls. Can be used to scale drawing for high DPI screens. May not be supported on all platforms or technologies or for all widths. For example, GDI can only support positive integer widths.

    Support alpha in more Surface drawing calls. Add variants that take ColourAlpha instead of ColourDesired.
    virtual void FillRectangle(PRectangle rc, ColourAlpha back)=0;
    While this is currently implemented with AlphaRectangle, that is a costly call creating a bitmap for the rectangle then drawing into the bitmap and copying to the destination.

    Add a way to determine capabilities: bool Surface::Supports(enum class capability).

    Templates for Point and Rectangle with current types based on templates: allows for Rectangle<int>.</int>

    More colour parameters to ListBox to allow sufficient customization for dark mode.

    Remove Window::SetFont as only used for ListBox.

    Use enum class instead of enum for Window::Cursor.

     
  • Zufu Liu

    Zufu Liu - 2020-06-28

    Another change is font locale [bugs:#2027]

    For stroke width, as it only depends on DPI and zoom level, I think it can be made as a member of surface implementation with a public getter. Maybe zoom level and print magnification can be changed to percentages to simplify the codes.

    Will Scintilla 5.0 be a new unstable/development branch?

     

    Related

    Bugs: #2027

  • Neil Hodgson

    Neil Hodgson - 2020-06-29

    Stroke width should be a choice for the application or user to suit their design. An element may be made more or less prominent by choosing a diferent stroke width and this may be traded off against colour intensity or translucency. People with visual impairments or presenting code at a meeting may choose different sizes to meet their needs.

    Stroke width APIs for markers and indicators could look like:

    # Set the stroke width of a marker in hundredths of a pixel.
    set void MarkerSetStrokeWidth=2750(int markerNumber, int widthHundredthPixels)
    
    # Set the stroke width of an indicator in hundredths of a pixel.
    set void IndicSetStrokeWidth=2752(int indicator, int widthHundredthPixels)
    

    Image with different stroke widths

    Unsure how this will be managed. I find multiple branches confusing so I may just stop working on other issues while an initial 5.0.0 is made, then some updates until a stable 5.1.0.

     

    Last edit: Neil Hodgson 2020-06-29
  • Zufu Liu

    Zufu Liu - 2020-06-29

    Then this will need stoke width APIs for most non-filled graphics, e.g. tab arrow, borders.

    The complicate of stroke width (assuming >=1), some constant 1 will need be replaced with stroke width, e.g. in drawing tab arrow, minus/plus inside box/circle.

     
    • Neil Hodgson

      Neil Hodgson - 2020-06-29

      Tab arrows are a feature that should be controlled specifically. Doubling the width makes them far too heavy until text is much larger than normal.

      In many fonts, arrows go wide much later than Roman character stems. For example, with Verdana and DirectWrite you start to see 2 pixel wide stems around 13 or 14 points (somewhat arbitrary as they are really fractional) but '→' doesn't go wide until 17 points. With Tahoma '→' goes wide much larger, at 23 points.

       
  • Neil Hodgson

    Neil Hodgson - 2020-07-22

    Nearly finished set of patches. This won't be applied like this as there are many reversions included. A simplified set of patches will be applied instead,

     
    • YX Hao

      YX Hao - 2021-03-15

      No indentation?
      I'm not sure if it's intentional. Maybe you have changed them already. Just in case.

       
      • YX Hao

        YX Hao - 2021-03-15

        False positive, it's namespace!

         
  • Zufu Liu

    Zufu Liu - 2020-07-28

    It seems some of 5.patch can be added into 4.4.5 (part of it already added/reverted in 4.4.4):
    1. most enum classes.
    2. change Platform to namespace (no caller side code changes).

     
    • Zufu Liu

      Zufu Liu - 2020-07-28

      P.S. dynamic_cast can be used in SurfaceGDI::Copy() and ScintillaWin::EnsureRenderTarget().

       
      • Neil Hodgson

        Neil Hodgson - 2020-07-28

        Changed SurfaceGDI::Copy with [73514a].

        EnsureRenderTarget appears to be referring to

        const HRESULT hr = static_cast<ID2D1DCRenderTarget*>(pRenderTarget)->BindDC(hdc, &rcWindow);
        

        Changing that to dynamic_cast fails. dynamic_cast depends on RTTI which may be implemented differently by different compilers or compilation modes. ID2D1RenderTarget is implemented in a system DLL which may be compiled with a different compiler than is being used to build Scintilla so dynamic_cast produces:

        Exception thrown at 0x00007FFC7B1698C5 (vcruntime140d.dll) in SciTE.exe: 0xC0000005: Access violation reading location 0x000001E9619118CC. occurred
        
            vcruntime140d.dll!FindCompleteObject(void * inptr) Line 318 C++
            vcruntime140d.dll!__RTDynamicCast(void * inptr, long VfDelta, void * srcVoid, void * targetVoid, int isReference) Line 223  C++
        >   SciTE.exe!ScintillaWin::EnsureRenderTarget(HDC__ * hdc) Line 672    C++
        
         

        Related

        Commit: [73514a]

    • Neil Hodgson

      Neil Hodgson - 2020-07-28

      The compatibility promise here (which is not absolute but 'strong effort') is to maintainers of out-of-tree platform layers. Changing more enum to enum class will break those platform layers. I tried changing several other instances (TickReason, inDragDrop, PasteShape, ...) but found significant changes needed to in-tree platform layers. While other projects could have decided to use some of the enums that have already been changed, its much more likely where these elements are known to be used in, say, ScintillaWin.cxx.

      More enum will become enum class when a compatibility break is declared. Its possible there will be a 4.x long-term-support branch starting soon if anyone wants to maintain it.

       
  • Zufu Liu

    Zufu Liu - 2020-09-25

    how about change Sci_PositionCR to Sci_Position in Scintilla 5:

    // For Sci_CharacterRange, previously defined as long to be compatible with Win32 CHARRANGE.
    // long is 32-bit on LLP64 system (e.g. 64-bit Windows), thus can not be used to access text beyond 2 GiB.
    // application should stop using legacy Win32 EM_* messages and related structures to interact with Scintilla.
    typedef Sci_Position Sci_PositionCR;
    
     

    Last edit: Zufu Liu 2020-09-26
  • Zufu Liu

    Zufu Liu - 2021-03-18

    How about add function to draw rectangle frame, something like:

    void RectangleFrame(PRectangle rc, ColourDesired fore) = 0;
    void RectangleFrame(PRectangle rc, ColourDesired fore, XYPOSITION strokeWidth, int alpha) = 0;
    

    first one can be used for SC_FOLDDISPLAYTEXT_BOXED, EOLANNOTATION_BOXED and INDIC_BOX (match current code with stroke width=1).

    second one can be used for DrawCaretLineFramed() (DrawFrame can be renamed to DrawFrameBorder to reduce confusing).

     
    • Neil Hodgson

      Neil Hodgson - 2021-03-18

      Why is that better than the API already in the patch set?

      void RectangleFrame(PRectangle rc, ColourAlpha stroke, XYPOSITION widthStroke) = 0;
      
       
      👍
      1

      Last edit: Neil Hodgson 2021-03-18
      • Zufu Liu

        Zufu Liu - 2021-03-19

        I'm sorry, forgot most things in the 21K lines patch. GDI RectangleFrame() may need updates to support stroke width larger than 1.

         
  • Neil Hodgson

    Neil Hodgson - 2021-03-31

    This has now been committed. From change set 8592 (tagged start-platform-changes) to 8668. Some changes mentioned in this issue did not work well or were refined further.

     
  • Neil Hodgson

    Neil Hodgson - 2021-03-31
    • Group: Initial --> Committed
     
  • Zufu Liu

    Zufu Liu - 2021-04-03
    1. How about change Surface method virtual void Init(SurfaceID sid, WindowID wid)=0; to virtual void Init(SurfaceID sid, WindowID wid, bool printing = false)=0; to avoid ::GetDeviceCaps(hdc, TECHNOLOGY) != DT_RASDISPLAY in SurfaceGDI::Init().
    2. API to change FontParameters.localeName is not committed.
    3. destructor for derived Font classes can be marked as noexcept override.
     
    • Zufu Liu

      Zufu Liu - 2021-04-04
      1. CallTip::PaintCT() seems has wrong condition for macOS, maybe the condition is #if defined(__APPLE__) && !PLAT_CURSES
       
      • Neil Hodgson

        Neil Hodgson - 2021-04-04

        Neither macOS nor curses want Scintilla's added 3D borders on calltips: macOS because its against mac style and curses since a border is relatively large when it requires a whole character on top and bottom.

         
        • Zufu Liu

          Zufu Liu - 2021-04-04

          You are right, the old code is #ifndef __APPLE__.

           
    • Neil Hodgson

      Neil Hodgson - 2021-04-06

      1) DT_RASDISPLAY seems to answer whether screen scaling is wanted. Its uncertain which APIs would always be printing. For example, FormatRange could be used for a screen HDC.
      2) There are many items in the pipeline and there needs to be a release. Not everything can make it into 5.0.1 which will be released in a few days.
      3) OK. [c951de]

       

      Related

      Commit: [c951de]

      • Zufu Liu

        Zufu Liu - 2021-04-06

        Yes, Editor::FormatRange() is the only API for printing,

         
  • Zufu Liu

    Zufu Liu - 2021-04-06

    In PlatWin.cxx, second parameter to TextWide used in ListBoxX::GetDesiredRect() and ListBoxX::Draw() need be SC_CP_UTF8 instead of unicodeMode.

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.