From c11582320d2f814cce96d071fb85849775720259 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Wed, 24 Jun 2020 17:23:28 -0500 Subject: [PATCH 01/13] Fix location of stc autocomp popup with images The stc autocomp popup is supposed to report the location at which text is drawn with the wxSTCListBox::CaretFromEdge function. To return the correct value, the popup needs to compute the largest width of any bitmap used for icons in the popup since text is drawn to the right of the popup's images. Previously the wxSTCListBox tried to compute this largest width when the listbox items were set. However, Scintilla actually calls CaretFromEdge before setting the listbox items. Consequently the CaretFromEdge was returning a value that assumed zero width for the list's images since images had not been set yet. Instead, keep a running tally of the widest image width when images are registered. This means that this variable must be moved to the wxSTCListBoxVisualData class since that is where image registration is handled. Also track the largest image height since that is also needed. --- src/stc/PlatWX.cpp | 98 +++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index ce4e7e2bff..9434f167fa 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2330,6 +2330,8 @@ public: // Image data const wxBitmap* GetImage(int i) const; + int GetImageAreaWidth() const; + int GetImageAreaHeight() const; // Colour data void ComputeColours(); @@ -2358,6 +2360,8 @@ private: int m_desiredVisibleRows; ImgList m_imgList; + int m_imageAreaWidth; + int m_imageAreaHeight; wxColour m_borderColour; wxColour m_bgColour; @@ -2381,6 +2385,7 @@ private: }; wxSTCListBoxVisualData::wxSTCListBoxVisualData(int d):m_desiredVisibleRows(d), + m_imageAreaWidth(0), m_imageAreaHeight(0), m_useDefaultBgColour(true), m_useDefaultTextColour(true), m_useDefaultHighlightBgColour(true), @@ -2414,10 +2419,40 @@ void wxSTCListBoxVisualData::RegisterImage(int type, const wxBitmap& bmp) return; ImgList::iterator it=m_imgList.find(type); + bool preExisting = false; if ( it != m_imgList.end() ) + { m_imgList.erase(it); + preExisting = true; + } m_imgList[type] = bmp; + + if ( preExisting ) + { + m_imageAreaWidth = 0; + m_imageAreaHeight = 0; + + for ( ImgList::iterator it = m_imgList.begin() ; it != m_imgList.end() ; ++it ) + { + wxBitmap bmp = it->second; + + if ( bmp.GetWidth() > m_imageAreaWidth ) + { + m_imageAreaWidth = bmp.GetWidth(); + } + + if ( bmp.GetHeight() > m_imageAreaHeight ) + { + m_imageAreaHeight = bmp.GetHeight(); + } + } + } + else + { + m_imageAreaWidth = wxMax(m_imageAreaWidth, bmp.GetWidth()); + m_imageAreaHeight = wxMax(m_imageAreaHeight, bmp.GetHeight()); + } } void wxSTCListBoxVisualData::RegisterImage(int type, const char *xpm_data) @@ -2451,6 +2486,8 @@ void wxSTCListBoxVisualData::RegisterRGBAImage(int type, int width, int height, void wxSTCListBoxVisualData::ClearRegisteredImages() { m_imgList.clear(); + m_imageAreaWidth = 0; + m_imageAreaHeight = 0; } const wxBitmap* wxSTCListBoxVisualData::GetImage(int i) const @@ -2463,6 +2500,16 @@ const wxBitmap* wxSTCListBoxVisualData::GetImage(int i) const return NULL; } +int wxSTCListBoxVisualData::GetImageAreaWidth() const +{ + return m_imageAreaWidth; +} + +int wxSTCListBoxVisualData::GetImageAreaHeight() const +{ + return m_imageAreaHeight; +} + void wxSTCListBoxVisualData::ComputeColours() { // wxSYS_COLOUR_BTNSHADOW seems to be the closest match with most themes. @@ -2640,7 +2687,6 @@ protected: // Helpers void AppendHelper(const wxString& text, int type); void SelectHelper(int i); - void AccountForBitmap(int type, bool recalculateItemHeight); void RecalculateItemHeight(); int TextBoxFromClientEdge() const; @@ -2658,8 +2704,6 @@ protected: virtual void OnDrawBackground(wxDC&, const wxRect&,size_t) const wxOVERRIDE; private: - WX_DECLARE_HASH_SET(int, wxIntegerHash, wxIntegerEqual, SetOfInts); - wxSTCListBoxVisualData* m_visualData; wxVector m_labels; wxVector m_imageNos; @@ -2675,8 +2719,6 @@ private: int m_textHeight; int m_itemHeight; int m_textTopGap; - int m_imageAreaWidth; - int m_imageAreaHeight; // These drawing parameters are set internally and can be changed if needed // to better match the appearance of a list box on a specific platform. @@ -2690,7 +2732,7 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) m_visualData(v), m_maxStrWidth(0), m_currentRow(wxNOT_FOUND), m_doubleClickAction(NULL), m_doubleClickActionData(NULL), m_aveCharWidth(8), m_textHeight(ht), m_itemHeight(ht), - m_textTopGap(0), m_imageAreaWidth(0), m_imageAreaHeight(0) + m_textTopGap(0) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, "AutoCompListBox"); @@ -2796,8 +2838,6 @@ int wxSTCListBox::CaretFromEdge() const void wxSTCListBox::Clear() { - m_imageAreaWidth = 0; - m_imageAreaHeight = 0; m_labels.clear(); m_imageNos.clear(); } @@ -2805,7 +2845,7 @@ void wxSTCListBox::Clear() void wxSTCListBox::Append(char *s, int type) { AppendHelper(stc2wx(s), type); - AccountForBitmap(type, true); + RecalculateItemHeight(); } int wxSTCListBox::Length() const @@ -2835,7 +2875,6 @@ void wxSTCListBox::SetList(const char* list, char separator, char typesep) { wxWindowUpdateLocker noUpdates(this); Clear(); - SetOfInts bitmapNos; wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator); while ( tkzr.HasMoreTokens() ) { wxString token = tkzr.GetNextToken(); @@ -2846,14 +2885,9 @@ void wxSTCListBox::SetList(const char* list, char separator, char typesep) token.Truncate(pos); } AppendHelper(token, (int)type); - bitmapNos.insert(static_cast(type)); } - for ( SetOfInts::iterator it=bitmapNos.begin(); it!=bitmapNos.end(); ++it ) - AccountForBitmap(*it, false); - - if ( m_imageAreaHeight > 0 ) - RecalculateItemHeight(); + RecalculateItemHeight(); } void wxSTCListBox::AppendHelper(const wxString& text, int type) @@ -2895,34 +2929,17 @@ void wxSTCListBox::SelectHelper(int i) } } -void wxSTCListBox::AccountForBitmap(int type, bool recalculateItemHeight) -{ - const int oldHeight = m_imageAreaHeight; - const wxBitmap* bmp = m_visualData->GetImage(type); - - if ( bmp ) - { - if ( bmp->GetWidth() > m_imageAreaWidth ) - m_imageAreaWidth = bmp->GetWidth(); - - if ( bmp->GetHeight() > m_imageAreaHeight ) - m_imageAreaHeight = bmp->GetHeight(); - } - - if ( recalculateItemHeight && m_imageAreaHeight != oldHeight ) - RecalculateItemHeight(); -} - void wxSTCListBox::RecalculateItemHeight() { m_itemHeight = wxMax(m_textHeight + 2 * m_textExtraVerticalPadding, - m_imageAreaHeight + 2 * m_imagePadding); + m_visualData->GetImageAreaHeight() + 2 * m_imagePadding); m_textTopGap = (m_itemHeight - m_textHeight)/2; } int wxSTCListBox::TextBoxFromClientEdge() const { - return (m_imageAreaWidth == 0 ? 0 : m_imageAreaWidth + 2 * m_imagePadding); + const int width = m_visualData->GetImageAreaWidth(); + return (width == 0 ? 0 : width + 2 * m_imagePadding); } void wxSTCListBox::OnSelection(wxCommandEvent& event) @@ -2993,7 +3010,7 @@ wxCoord wxSTCListBox::OnMeasureItem(size_t WXUNUSED(n)) const // // +++++++++++++++++++++++++ =====ITEM TEXT================ // | | | | -// | m_imageAreaWidth | | +// | imageAreaWidth | | // | | | // m_imagePadding | m_textBoxToTextGap // | @@ -3002,8 +3019,8 @@ wxCoord wxSTCListBox::OnMeasureItem(size_t WXUNUSED(n)) const // // m_imagePadding : Used to give a little extra space between the // client edge and an item's bitmap. -// m_imageAreaWidth : Computed as the width of the largest registered -// bitmap. +// imageAreaWidth : Computed as the width of the largest registered +// bitmap (part of wxSTCListBoxVisualData). // m_textBoxToTextGap : Used so that item text does not begin immediately // at the edge of the highlight box. // @@ -3042,8 +3059,9 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const const wxBitmap* b = m_visualData->GetImage(imageNo); if ( b ) { + const int width = m_visualData->GetImageAreaWidth(); topGap = (m_itemHeight - b->GetHeight())/2; - leftGap = m_imagePadding + (m_imageAreaWidth - b->GetWidth())/2; + leftGap = m_imagePadding + (width - b->GetWidth())/2; dc.DrawBitmap(*b, rect.GetLeft()+leftGap, rect.GetTop()+topGap, true); } } From 4e3e26422812ce0f1df77a9f5d13beed8d403497 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Wed, 24 Jun 2020 17:24:43 -0500 Subject: [PATCH 02/13] Fix size of stc autocomp popup with Direct2D Due to a confusion between DIPs and Pts, the stc autocomp window was a little larger than it should have been when Direct2D was used. Instead use the methods defined in SurfaceD2D so the popup will be measured and drawn the same way the main editor window is. --- src/stc/PlatWX.cpp | 144 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 19 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 9434f167fa..53b79e84be 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2661,7 +2661,8 @@ int wxSTCListBoxVisualData::GetStartLen() const class wxSTCListBox : public wxSystemThemedControl { public: - wxSTCListBox(wxWindow*, wxSTCListBoxVisualData*, int); + wxSTCListBox(wxWindow*, wxSTCListBoxVisualData*, int, int); + ~wxSTCListBox(); // wxWindow overrides virtual bool AcceptsFocus() const wxOVERRIDE; @@ -2725,14 +2726,19 @@ private: int m_imagePadding; int m_textBoxToTextGap; int m_textExtraVerticalPadding; + + // These are needed when Direct2D is used for drawing. + int m_technology; + void* m_surfaceFontData; }; -wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) +wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, + int ht, int technology) :wxSystemThemedControl(), m_visualData(v), m_maxStrWidth(0), m_currentRow(wxNOT_FOUND), m_doubleClickAction(NULL), m_doubleClickActionData(NULL), m_aveCharWidth(8), m_textHeight(ht), m_itemHeight(ht), - m_textTopGap(0) + m_textTopGap(0), m_technology(technology), m_surfaceFontData(NULL) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, "AutoCompListBox"); @@ -2763,6 +2769,18 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) } } +wxSTCListBox::~wxSTCListBox() +{ +#ifdef HAVE_DIRECTWRITE_TECHNOLOGY + if ( m_surfaceFontData ) + { + SurfaceFontDataD2D* fontData = + reinterpret_cast(m_surfaceFontData); + delete fontData; + } +#endif +} + bool wxSTCListBox::AcceptsFocus() const { return false; @@ -2780,9 +2798,36 @@ void wxSTCListBox::SetContainerBorderSize(int s) void wxSTCListBox::SetListBoxFont(Font &font) { - SetFont(*((wxFont*)font.GetID())); - int w; - GetTextExtent(EXTENT_TEST, &w, &m_textHeight); + if ( m_technology == wxSTC_TECHNOLOGY_DEFAULT ) + { + SetFont(*((wxFont*)font.GetID())); + int w; + GetTextExtent(EXTENT_TEST, &w, &m_textHeight); + } + else + { + #ifdef HAVE_DIRECTWRITE_TECHNOLOGY + wxFontWithAscent* fwa = wxFontWithAscent::FromFID(font.GetID()); + + SurfaceData* data = fwa->GetSurfaceFontData(); + SurfaceFontDataD2D* d2dft = static_cast(data); + m_surfaceFontData = new SurfaceFontDataD2D(*d2dft); + + wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); + SurfaceFontDataD2D* newSurfaceData = new SurfaceFontDataD2D(*d2dft); + fontCopy->SetSurfaceFontData(newSurfaceData); + Font tempFont; + tempFont.SetID(fontCopy); + + SurfaceD2D surface; + wxClientDC dc(this); + surface.Init(&dc,GetGrandParent()); + m_textHeight = surface.Height(tempFont); + tempFont.Release(); + surface.Release(); + #endif + } + RecalculateItemHeight(); } @@ -3043,18 +3088,79 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const int topGap = m_textTopGap; int leftGap = TextBoxFromClientEdge() + m_textBoxToTextGap; - wxDCTextColourChanger tcc(dc); + wxColour textCol; if ( IsSelected(n) ) - tcc.Set(m_visualData->GetHighlightTextColour()); + textCol = m_visualData->GetHighlightTextColour(); else if ( static_cast(n) == m_currentRow ) - tcc.Set(m_visualData->GetCurrentTextColour()); + textCol = m_visualData->GetCurrentTextColour(); else - tcc.Set(m_visualData->GetTextColour()); + textCol = m_visualData->GetTextColour(); - label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, - rect.GetWidth() - leftGap); - dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); + if ( m_technology == wxSTC_TECHNOLOGY_DEFAULT ) + { + wxDCTextColourChanger tcc(dc, textCol); + + label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, + rect.GetWidth() - leftGap); + dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); + } + else + { + #ifdef HAVE_DIRECTWRITE_TECHNOLOGY + SurfaceD2D surface; + surface.Init(&dc, GetGrandParent()); + + wxString ellipsizedLabel = label; + + SurfaceFontDataD2D* fontData = + reinterpret_cast(m_surfaceFontData); + wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); + SurfaceFontDataD2D* newSurfaceData = new SurfaceFontDataD2D(*fontData); + fontCopy->SetSurfaceFontData(newSurfaceData); + Font tempFont; + tempFont.SetID(fontCopy); + + wxCharBuffer buffer = wx2stc(label); + int curWidth = surface.WidthText(tempFont, buffer.data(), + wx2stclen(wxString(),buffer)); + + int maxWidth = rect.GetWidth() - leftGap; + + if ( curWidth > maxWidth ) + { + int len = label.Length(); + + for ( int i = len ; i >= 0 ; --i) + { + ellipsizedLabel = label.Left(i); + ellipsizedLabel << "..."; + + buffer = wx2stc(ellipsizedLabel); + curWidth = surface.WidthText(tempFont, buffer.data(), + wx2stclen(wxString(),buffer)); + + if ( curWidth <= maxWidth ) + { + break; + } + } + } + + wxRect rect2(rect.GetLeft() + leftGap, rect.GetTop() + topGap, + rect.GetWidth() - leftGap, m_textHeight); + + PRectangle prect = PRectangleFromwxRect(rect2); + ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); + + XYPOSITION ybase = rect2.GetTop() + fontData->GetAscent(); + + surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), + wx2stclen(wxString(),buffer), fore); + tempFont.Release(); + surface.Release(); + #endif // HAVE_DIRECTWRITE_TECHNOLOGY + } const wxBitmap* b = m_visualData->GetImage(imageNo); if ( b ) @@ -3126,7 +3232,8 @@ void wxSTCListBox::OnDrawBackground(wxDC &dc, const wxRect &rect,size_t n) const class wxSTCListBoxWin : public wxSTCPopupWindow { public: - wxSTCListBoxWin(wxWindow*, wxSTCListBox**, wxSTCListBoxVisualData*, int); + wxSTCListBoxWin(wxWindow*, wxSTCListBox**, wxSTCListBoxVisualData*, + int, int); protected: void OnPaint(wxPaintEvent&); @@ -3136,10 +3243,10 @@ private: }; wxSTCListBoxWin::wxSTCListBoxWin(wxWindow* parent, wxSTCListBox** lb, - wxSTCListBoxVisualData* v, int h) + wxSTCListBoxVisualData* v, int h, int tech) :wxSTCPopupWindow(parent) { - *lb = new wxSTCListBox(this, v, h); + *lb = new wxSTCListBox(this, v, h, tech); // Use the background of this window to form a frame around the listbox // except on macos where the native Scintilla popup has no frame. @@ -3189,10 +3296,9 @@ void ListBoxImpl::SetFont(Font &font) { void ListBoxImpl::Create(Window &parent, int WXUNUSED(ctrlID), Point WXUNUSED(location_), int lineHeight_, - bool WXUNUSED(unicodeMode_), - int WXUNUSED(technology_)) { + bool WXUNUSED(unicodeMode_), int technology_) { wid = new wxSTCListBoxWin(GETWIN(parent.GetID()), &m_listBox, m_visualData, - lineHeight_); + lineHeight_, technology_); } From b912dc380abbb4f576f3a58b51c542d6c184cb2c Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Mon, 22 Jun 2020 21:35:12 +0200 Subject: [PATCH 03/13] Fix the DPI in wxSTC IME window This same modification was made to the Scintilla/SciTE source. --- src/stc/ScintillaWX.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 7b7a7ef033..23c5453fd5 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -1510,13 +1510,8 @@ void ScintillaWX::ImeStartComposition() { int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel * SC_FONT_SIZE_MULTIPLIER; if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; - AutoSurface surface(this); - int deviceHeight = sizeZoomed; - if (surface) { - deviceHeight = (sizeZoomed * surface->LogPixelsY()) / 72; - } // The negative is to allow for leading - lf.lfHeight = -(std::abs(deviceHeight / SC_FONT_SIZE_MULTIPLIER)); + lf.lfHeight = -::MulDiv(sizeZoomed, stc->GetDPI().y, 72 * SC_FONT_SIZE_MULTIPLIER); lf.lfWeight = vs.styles[styleHere].weight; lf.lfItalic = static_cast(vs.styles[styleHere].italic ? 1 : 0); lf.lfCharSet = DEFAULT_CHARSET; From 24fad36d0ca541c6347186823bc11b96f2f1280b Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 25 Jun 2020 17:15:24 -0500 Subject: [PATCH 04/13] Add changes requested in comments for PR 1906 --- src/stc/PlatWX.cpp | 106 ++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 60 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 53b79e84be..6f6dc9d429 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2360,8 +2360,7 @@ private: int m_desiredVisibleRows; ImgList m_imgList; - int m_imageAreaWidth; - int m_imageAreaHeight; + wxSize m_imgAreaSize; wxColour m_borderColour; wxColour m_bgColour; @@ -2385,8 +2384,7 @@ private: }; wxSTCListBoxVisualData::wxSTCListBoxVisualData(int d):m_desiredVisibleRows(d), - m_imageAreaWidth(0), m_imageAreaHeight(0), - m_useDefaultBgColour(true), + m_imgAreaSize(0,0), m_useDefaultBgColour(true), m_useDefaultTextColour(true), m_useDefaultHighlightBgColour(true), m_useDefaultHighlightTextColour(true), @@ -2419,39 +2417,32 @@ void wxSTCListBoxVisualData::RegisterImage(int type, const wxBitmap& bmp) return; ImgList::iterator it=m_imgList.find(type); - bool preExisting = false; + bool preExistingWithDifferentSize = false; if ( it != m_imgList.end() ) { + if ( it->second.GetSize() != bmp.GetSize() ) + { + preExistingWithDifferentSize = true; + } + m_imgList.erase(it); - preExisting = true; } m_imgList[type] = bmp; - if ( preExisting ) + if ( preExistingWithDifferentSize ) { - m_imageAreaWidth = 0; - m_imageAreaHeight = 0; + m_imgAreaSize.Set(0,0); - for ( ImgList::iterator it = m_imgList.begin() ; it != m_imgList.end() ; ++it ) + for ( ImgList::iterator imgIt = m_imgList.begin() ; + imgIt != m_imgList.end() ; ++imgIt ) { - wxBitmap bmp = it->second; - - if ( bmp.GetWidth() > m_imageAreaWidth ) - { - m_imageAreaWidth = bmp.GetWidth(); - } - - if ( bmp.GetHeight() > m_imageAreaHeight ) - { - m_imageAreaHeight = bmp.GetHeight(); - } + m_imgAreaSize.IncTo(it->second.GetSize()); } } else { - m_imageAreaWidth = wxMax(m_imageAreaWidth, bmp.GetWidth()); - m_imageAreaHeight = wxMax(m_imageAreaHeight, bmp.GetHeight()); + m_imgAreaSize.IncTo(bmp.GetSize()); } } @@ -2486,8 +2477,7 @@ void wxSTCListBoxVisualData::RegisterRGBAImage(int type, int width, int height, void wxSTCListBoxVisualData::ClearRegisteredImages() { m_imgList.clear(); - m_imageAreaWidth = 0; - m_imageAreaHeight = 0; + m_imgAreaSize.Set(0,0); } const wxBitmap* wxSTCListBoxVisualData::GetImage(int i) const @@ -2502,12 +2492,12 @@ const wxBitmap* wxSTCListBoxVisualData::GetImage(int i) const int wxSTCListBoxVisualData::GetImageAreaWidth() const { - return m_imageAreaWidth; + return m_imgAreaSize.GetWidth(); } int wxSTCListBoxVisualData::GetImageAreaHeight() const { - return m_imageAreaHeight; + return m_imgAreaSize.GetHeight(); } void wxSTCListBoxVisualData::ComputeColours() @@ -2729,7 +2719,9 @@ private: // These are needed when Direct2D is used for drawing. int m_technology; - void* m_surfaceFontData; +#ifdef HAVE_DIRECTWRITE_TECHNOLOGY + SurfaceFontDataD2D* m_surfaceFontData; +#endif }; wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, @@ -2738,7 +2730,7 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, m_visualData(v), m_maxStrWidth(0), m_currentRow(wxNOT_FOUND), m_doubleClickAction(NULL), m_doubleClickActionData(NULL), m_aveCharWidth(8), m_textHeight(ht), m_itemHeight(ht), - m_textTopGap(0), m_technology(technology), m_surfaceFontData(NULL) + m_textTopGap(0), m_technology(technology) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, "AutoCompListBox"); @@ -2767,6 +2759,10 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, parent->SetOwnBackgroundColour(m_visualData->GetBgColour()); #endif } + + #ifdef HAVE_DIRECTWRITE_TECHNOLOGY + m_surfaceFontData = NULL; + #endif } wxSTCListBox::~wxSTCListBox() @@ -2774,9 +2770,7 @@ wxSTCListBox::~wxSTCListBox() #ifdef HAVE_DIRECTWRITE_TECHNOLOGY if ( m_surfaceFontData ) { - SurfaceFontDataD2D* fontData = - reinterpret_cast(m_surfaceFontData); - delete fontData; + delete m_surfaceFontData; } #endif } @@ -2798,13 +2792,7 @@ void wxSTCListBox::SetContainerBorderSize(int s) void wxSTCListBox::SetListBoxFont(Font &font) { - if ( m_technology == wxSTC_TECHNOLOGY_DEFAULT ) - { - SetFont(*((wxFont*)font.GetID())); - int w; - GetTextExtent(EXTENT_TEST, &w, &m_textHeight); - } - else + if ( m_technology == wxSTC_TECHNOLOGY_DIRECTWRITE ) { #ifdef HAVE_DIRECTWRITE_TECHNOLOGY wxFontWithAscent* fwa = wxFontWithAscent::FromFID(font.GetID()); @@ -2813,20 +2801,19 @@ void wxSTCListBox::SetListBoxFont(Font &font) SurfaceFontDataD2D* d2dft = static_cast(data); m_surfaceFontData = new SurfaceFontDataD2D(*d2dft); - wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); - SurfaceFontDataD2D* newSurfaceData = new SurfaceFontDataD2D(*d2dft); - fontCopy->SetSurfaceFontData(newSurfaceData); - Font tempFont; - tempFont.SetID(fontCopy); - SurfaceD2D surface; wxClientDC dc(this); surface.Init(&dc,GetGrandParent()); - m_textHeight = surface.Height(tempFont); - tempFont.Release(); + m_textHeight = surface.Height(font); surface.Release(); #endif } + else + { + SetFont(*((wxFont*)font.GetID())); + int w; + GetTextExtent(EXTENT_TEST, &w, &m_textHeight); + } RecalculateItemHeight(); } @@ -3097,15 +3084,7 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const else textCol = m_visualData->GetTextColour(); - if ( m_technology == wxSTC_TECHNOLOGY_DEFAULT ) - { - wxDCTextColourChanger tcc(dc, textCol); - - label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, - rect.GetWidth() - leftGap); - dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); - } - else + if ( m_technology == wxSTC_TECHNOLOGY_DIRECTWRITE ) { #ifdef HAVE_DIRECTWRITE_TECHNOLOGY SurfaceD2D surface; @@ -3113,10 +3092,9 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const wxString ellipsizedLabel = label; - SurfaceFontDataD2D* fontData = - reinterpret_cast(m_surfaceFontData); wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); - SurfaceFontDataD2D* newSurfaceData = new SurfaceFontDataD2D(*fontData); + SurfaceFontDataD2D* newSurfaceData = + new SurfaceFontDataD2D(*m_surfaceFontData); fontCopy->SetSurfaceFontData(newSurfaceData); Font tempFont; tempFont.SetID(fontCopy); @@ -3153,7 +3131,7 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const PRectangle prect = PRectangleFromwxRect(rect2); ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); - XYPOSITION ybase = rect2.GetTop() + fontData->GetAscent(); + XYPOSITION ybase = rect2.GetTop() + m_surfaceFontData->GetAscent(); surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), wx2stclen(wxString(),buffer), fore); @@ -3161,6 +3139,14 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const surface.Release(); #endif // HAVE_DIRECTWRITE_TECHNOLOGY } + else + { + wxDCTextColourChanger tcc(dc, textCol); + + label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, + rect.GetWidth() - leftGap); + dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); + } const wxBitmap* b = m_visualData->GetImage(imageNo); if ( b ) From f49f899856cd106a273d6f38f9c42463b6ac3b94 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Fri, 26 Jun 2020 02:13:40 +0200 Subject: [PATCH 05/13] Move wxSTC DirectDraw specific code to derived class --- src/stc/PlatWX.cpp | 258 +++++++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 113 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 6f6dc9d429..6c5f1f1576 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2651,8 +2651,7 @@ int wxSTCListBoxVisualData::GetStartLen() const class wxSTCListBox : public wxSystemThemedControl { public: - wxSTCListBox(wxWindow*, wxSTCListBoxVisualData*, int, int); - ~wxSTCListBox(); + wxSTCListBox(wxWindow*, wxSTCListBoxVisualData*, int); // wxWindow overrides virtual bool AcceptsFocus() const wxOVERRIDE; @@ -2662,7 +2661,7 @@ public: void SetContainerBorderSize(int); // ListBoxImpl implementation - void SetListBoxFont(Font &font); + virtual void SetListBoxFont(Font &font); void SetAverageCharWidth(int width); PRectangle GetDesiredRect() const; int CaretFromEdge() const; @@ -2694,7 +2693,6 @@ protected: virtual void OnDrawItem(wxDC& , const wxRect &, size_t) const wxOVERRIDE; virtual void OnDrawBackground(wxDC&, const wxRect&,size_t) const wxOVERRIDE; -private: wxSTCListBoxVisualData* m_visualData; wxVector m_labels; wxVector m_imageNos; @@ -2716,21 +2714,14 @@ private: int m_imagePadding; int m_textBoxToTextGap; int m_textExtraVerticalPadding; - - // These are needed when Direct2D is used for drawing. - int m_technology; -#ifdef HAVE_DIRECTWRITE_TECHNOLOGY - SurfaceFontDataD2D* m_surfaceFontData; -#endif }; -wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, - int ht, int technology) +wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) :wxSystemThemedControl(), m_visualData(v), m_maxStrWidth(0), m_currentRow(wxNOT_FOUND), m_doubleClickAction(NULL), m_doubleClickActionData(NULL), m_aveCharWidth(8), m_textHeight(ht), m_itemHeight(ht), - m_textTopGap(0), m_technology(technology) + m_textTopGap(0) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, "AutoCompListBox"); @@ -2759,20 +2750,6 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, parent->SetOwnBackgroundColour(m_visualData->GetBgColour()); #endif } - - #ifdef HAVE_DIRECTWRITE_TECHNOLOGY - m_surfaceFontData = NULL; - #endif -} - -wxSTCListBox::~wxSTCListBox() -{ -#ifdef HAVE_DIRECTWRITE_TECHNOLOGY - if ( m_surfaceFontData ) - { - delete m_surfaceFontData; - } -#endif } bool wxSTCListBox::AcceptsFocus() const @@ -2792,29 +2769,9 @@ void wxSTCListBox::SetContainerBorderSize(int s) void wxSTCListBox::SetListBoxFont(Font &font) { - if ( m_technology == wxSTC_TECHNOLOGY_DIRECTWRITE ) - { - #ifdef HAVE_DIRECTWRITE_TECHNOLOGY - wxFontWithAscent* fwa = wxFontWithAscent::FromFID(font.GetID()); - - SurfaceData* data = fwa->GetSurfaceFontData(); - SurfaceFontDataD2D* d2dft = static_cast(data); - m_surfaceFontData = new SurfaceFontDataD2D(*d2dft); - - SurfaceD2D surface; - wxClientDC dc(this); - surface.Init(&dc,GetGrandParent()); - m_textHeight = surface.Height(font); - surface.Release(); - #endif - } - else - { - SetFont(*((wxFont*)font.GetID())); - int w; - GetTextExtent(EXTENT_TEST, &w, &m_textHeight); - } - + SetFont(*((wxFont*)font.GetID())); + int w; + GetTextExtent(EXTENT_TEST, &w, &m_textHeight); RecalculateItemHeight(); } @@ -3084,69 +3041,11 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const else textCol = m_visualData->GetTextColour(); - if ( m_technology == wxSTC_TECHNOLOGY_DIRECTWRITE ) - { - #ifdef HAVE_DIRECTWRITE_TECHNOLOGY - SurfaceD2D surface; - surface.Init(&dc, GetGrandParent()); + wxDCTextColourChanger tcc(dc, textCol); - wxString ellipsizedLabel = label; - - wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); - SurfaceFontDataD2D* newSurfaceData = - new SurfaceFontDataD2D(*m_surfaceFontData); - fontCopy->SetSurfaceFontData(newSurfaceData); - Font tempFont; - tempFont.SetID(fontCopy); - - wxCharBuffer buffer = wx2stc(label); - int curWidth = surface.WidthText(tempFont, buffer.data(), - wx2stclen(wxString(),buffer)); - - int maxWidth = rect.GetWidth() - leftGap; - - if ( curWidth > maxWidth ) - { - int len = label.Length(); - - for ( int i = len ; i >= 0 ; --i) - { - ellipsizedLabel = label.Left(i); - ellipsizedLabel << "..."; - - buffer = wx2stc(ellipsizedLabel); - curWidth = surface.WidthText(tempFont, buffer.data(), - wx2stclen(wxString(),buffer)); - - if ( curWidth <= maxWidth ) - { - break; - } - } - } - - wxRect rect2(rect.GetLeft() + leftGap, rect.GetTop() + topGap, - rect.GetWidth() - leftGap, m_textHeight); - - PRectangle prect = PRectangleFromwxRect(rect2); - ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); - - XYPOSITION ybase = rect2.GetTop() + m_surfaceFontData->GetAscent(); - - surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), - wx2stclen(wxString(),buffer), fore); - tempFont.Release(); - surface.Release(); - #endif // HAVE_DIRECTWRITE_TECHNOLOGY - } - else - { - wxDCTextColourChanger tcc(dc, textCol); - - label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, - rect.GetWidth() - leftGap); - dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); - } + label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, + rect.GetWidth() - leftGap); + dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); const wxBitmap* b = m_visualData->GetImage(imageNo); if ( b ) @@ -3214,6 +3113,130 @@ void wxSTCListBox::OnDrawBackground(wxDC &dc, const wxRect &rect,size_t n) const } +#ifdef HAVE_DIRECTWRITE_TECHNOLOGY +class wxSTCListBoxD2D : public wxSTCListBox +{ +public: + wxSTCListBoxD2D(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) + : wxSTCListBox(parent, v, ht) + , m_surfaceFontData(NULL) + { + } + + ~wxSTCListBoxD2D() + { + if ( m_surfaceFontData ) + { + delete m_surfaceFontData; + } + } + + void SetListBoxFont(Font& font) wxOVERRIDE + { + wxFontWithAscent* fwa = wxFontWithAscent::FromFID(font.GetID()); + + SurfaceData* data = fwa->GetSurfaceFontData(); + SurfaceFontDataD2D* d2dft = static_cast(data); + m_surfaceFontData = new SurfaceFontDataD2D(*d2dft); + + SurfaceD2D surface; + wxClientDC dc(this); + surface.Init(&dc, GetGrandParent()); + m_textHeight = surface.Height(font); + surface.Release(); + + RecalculateItemHeight(); + } + + void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const wxOVERRIDE + { + wxString label; + int imageNo = -1; + if ( n < m_labels.size() ) + { + label = m_labels[n]; + imageNo = m_imageNos[n]; + } + + int topGap = m_textTopGap; + int leftGap = TextBoxFromClientEdge() + m_textBoxToTextGap; + + wxColour textCol; + + if ( IsSelected(n) ) + textCol = m_visualData->GetHighlightTextColour(); + else if ( static_cast(n) == m_currentRow ) + textCol = m_visualData->GetCurrentTextColour(); + else + textCol = m_visualData->GetTextColour(); + + SurfaceD2D surface; + surface.Init(&dc, GetGrandParent()); + + wxString ellipsizedLabel = label; + + wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); + SurfaceFontDataD2D* newSurfaceData = + new SurfaceFontDataD2D(*m_surfaceFontData); + fontCopy->SetSurfaceFontData(newSurfaceData); + Font tempFont; + tempFont.SetID(fontCopy); + + wxCharBuffer buffer = wx2stc(label); + int curWidth = surface.WidthText(tempFont, buffer.data(), + wx2stclen(wxString(), buffer)); + + int maxWidth = rect.GetWidth() - leftGap; + + if ( curWidth > maxWidth ) + { + int len = label.Length(); + + for ( int i = len; i >= 0; --i ) + { + ellipsizedLabel = label.Left(i); + ellipsizedLabel << "..."; + + buffer = wx2stc(ellipsizedLabel); + curWidth = surface.WidthText(tempFont, buffer.data(), + wx2stclen(wxString(), buffer)); + + if ( curWidth <= maxWidth ) + { + break; + } + } + } + + wxRect rect2(rect.GetLeft() + leftGap, rect.GetTop() + topGap, + rect.GetWidth() - leftGap, m_textHeight); + + PRectangle prect = PRectangleFromwxRect(rect2); + ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); + + XYPOSITION ybase = rect2.GetTop() + m_surfaceFontData->GetAscent(); + + surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), + wx2stclen(wxString(), buffer), fore); + tempFont.Release(); + surface.Release(); + + const wxBitmap* b = m_visualData->GetImage(imageNo); + if ( b ) + { + const int width = m_visualData->GetImageAreaWidth(); + topGap = (m_itemHeight - b->GetHeight()) / 2; + leftGap = m_imagePadding + (width - b->GetWidth()) / 2; + dc.DrawBitmap(*b, rect.GetLeft() + leftGap, rect.GetTop() + topGap, true); + } + } + +private: + SurfaceFontDataD2D* m_surfaceFontData; +}; +#endif + + // A popup window to place the wxSTCListBox upon class wxSTCListBoxWin : public wxSTCPopupWindow { @@ -3232,7 +3255,16 @@ wxSTCListBoxWin::wxSTCListBoxWin(wxWindow* parent, wxSTCListBox** lb, wxSTCListBoxVisualData* v, int h, int tech) :wxSTCPopupWindow(parent) { - *lb = new wxSTCListBox(this, v, h, tech); +#ifdef HAVE_DIRECTWRITE_TECHNOLOGY + if ( tech == wxSTC_TECHNOLOGY_DIRECTWRITE ) + { + *lb = new wxSTCListBoxD2D(this, v, h); + } + else +#endif + { + *lb = new wxSTCListBox(this, v, h); + } // Use the background of this window to form a frame around the listbox // except on macos where the native Scintilla popup has no frame. From 0a6eea9bb53f2c88fd051e44ee7884bed0e97a51 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 25 Jun 2020 20:49:50 -0500 Subject: [PATCH 06/13] Remove duplicate code in wxSTCListBox::OnDrawItem To remove code duplication in the OnDrawItem in wxSTCListBox and wxSTCListBoxD2D, move the code for drawing just the text to a new virtual method named OnDrawItemText. Then have the OnDrawItem method call the new function. --- src/stc/PlatWX.cpp | 78 +++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 6c5f1f1576..6b728a952f 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2679,6 +2679,8 @@ protected: void SelectHelper(int i); void RecalculateItemHeight(); int TextBoxFromClientEdge() const; + virtual void OnDrawItemText(wxDC&, const wxRect&, + const wxString&, const wxColour&) const; // Event handlers void OnSelection(wxCommandEvent&); @@ -3019,6 +3021,17 @@ wxCoord wxSTCListBox::OnMeasureItem(size_t WXUNUSED(n)) const // x = m_imagePadding + m_imageAreaWidth + m_imagePadding. // Text is drawn at x + m_textBoxToTextGap and centered vertically. +void wxSTCListBox::OnDrawItemText(wxDC& dc, const wxRect& rect, + const wxString& label, + const wxColour& textCol) const +{ + wxDCTextColourChanger tcc(dc, textCol); + + wxString ellipsizedlabel = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, + rect.GetWidth()); + dc.DrawText(ellipsizedlabel, rect.GetLeft(), rect.GetTop()); +} + void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const { wxString label; @@ -3041,11 +3054,10 @@ void wxSTCListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const else textCol = m_visualData->GetTextColour(); - wxDCTextColourChanger tcc(dc, textCol); + wxRect rect2(rect.GetLeft() + leftGap, rect.GetTop() + topGap, + rect.GetWidth() - leftGap, m_textHeight); - label = wxControl::Ellipsize(label, dc, wxELLIPSIZE_END, - rect.GetWidth() - leftGap); - dc.DrawText(label, rect.GetLeft() + leftGap, rect.GetTop() + topGap); + OnDrawItemText(dc, rect2, label, textCol); const wxBitmap* b = m_visualData->GetImage(imageNo); if ( b ) @@ -3148,47 +3160,25 @@ public: RecalculateItemHeight(); } - void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const wxOVERRIDE + void OnDrawItemText(wxDC& dc, const wxRect& rect, const wxString& label, + const wxColour& textCol) const wxOVERRIDE { - wxString label; - int imageNo = -1; - if ( n < m_labels.size() ) - { - label = m_labels[n]; - imageNo = m_imageNos[n]; - } - - int topGap = m_textTopGap; - int leftGap = TextBoxFromClientEdge() + m_textBoxToTextGap; - - wxColour textCol; - - if ( IsSelected(n) ) - textCol = m_visualData->GetHighlightTextColour(); - else if ( static_cast(n) == m_currentRow ) - textCol = m_visualData->GetCurrentTextColour(); - else - textCol = m_visualData->GetTextColour(); + wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); + SurfaceFontDataD2D* sfd = new SurfaceFontDataD2D(*m_surfaceFontData); + fontCopy->SetSurfaceFontData(sfd); + Font tempFont; + tempFont.SetID(fontCopy); SurfaceD2D surface; surface.Init(&dc, GetGrandParent()); wxString ellipsizedLabel = label; - wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); - SurfaceFontDataD2D* newSurfaceData = - new SurfaceFontDataD2D(*m_surfaceFontData); - fontCopy->SetSurfaceFontData(newSurfaceData); - Font tempFont; - tempFont.SetID(fontCopy); - - wxCharBuffer buffer = wx2stc(label); + wxCharBuffer buffer = wx2stc(ellipsizedLabel); int curWidth = surface.WidthText(tempFont, buffer.data(), wx2stclen(wxString(), buffer)); - int maxWidth = rect.GetWidth() - leftGap; - - if ( curWidth > maxWidth ) + if ( curWidth > rect.GetWidth() ) { int len = label.Length(); @@ -3201,34 +3191,22 @@ public: curWidth = surface.WidthText(tempFont, buffer.data(), wx2stclen(wxString(), buffer)); - if ( curWidth <= maxWidth ) + if ( curWidth <= rect.GetWidth() ) { break; } } } - wxRect rect2(rect.GetLeft() + leftGap, rect.GetTop() + topGap, - rect.GetWidth() - leftGap, m_textHeight); - - PRectangle prect = PRectangleFromwxRect(rect2); + PRectangle prect = PRectangleFromwxRect(rect); ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); - XYPOSITION ybase = rect2.GetTop() + m_surfaceFontData->GetAscent(); + XYPOSITION ybase = rect.GetTop() + m_surfaceFontData->GetAscent(); surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), wx2stclen(wxString(), buffer), fore); tempFont.Release(); surface.Release(); - - const wxBitmap* b = m_visualData->GetImage(imageNo); - if ( b ) - { - const int width = m_visualData->GetImageAreaWidth(); - topGap = (m_itemHeight - b->GetHeight()) / 2; - leftGap = m_imagePadding + (width - b->GetWidth()) / 2; - dc.DrawBitmap(*b, rect.GetLeft() + leftGap, rect.GetTop() + topGap, true); - } } private: From a3a6938673555580c1d7e0b2e4a2ad7ebd726738 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 25 Jun 2020 21:41:33 -0500 Subject: [PATCH 07/13] Add other changes requested in comments for PR 1906 --- src/stc/PlatWX.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 6b728a952f..1280b65595 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2384,7 +2384,7 @@ private: }; wxSTCListBoxVisualData::wxSTCListBoxVisualData(int d):m_desiredVisibleRows(d), - m_imgAreaSize(0,0), m_useDefaultBgColour(true), + m_useDefaultBgColour(true), m_useDefaultTextColour(true), m_useDefaultHighlightBgColour(true), m_useDefaultHighlightTextColour(true), @@ -3178,24 +3178,14 @@ public: int curWidth = surface.WidthText(tempFont, buffer.data(), wx2stclen(wxString(), buffer)); - if ( curWidth > rect.GetWidth() ) + for ( int i = label.length(); curWidth > rect.GetWidth() && i; --i ) { - int len = label.Length(); + ellipsizedLabel = label.Left(i); + ellipsizedLabel << "..."; - for ( int i = len; i >= 0; --i ) - { - ellipsizedLabel = label.Left(i); - ellipsizedLabel << "..."; - - buffer = wx2stc(ellipsizedLabel); - curWidth = surface.WidthText(tempFont, buffer.data(), - wx2stclen(wxString(), buffer)); - - if ( curWidth <= rect.GetWidth() ) - { - break; - } - } + buffer = wx2stc(ellipsizedLabel); + curWidth = surface.WidthText(tempFont, buffer.data(), + wx2stclen(wxString(), buffer)); } PRectangle prect = PRectangleFromwxRect(rect); From 01b3bf7eefce7d7e40cd175f11eb48e175c5bea4 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 25 Jun 2020 21:45:04 -0500 Subject: [PATCH 08/13] Remove double strlen call in wxSTCListBoxD2D The length of a string in wxSTCListBoxD2D::OnDrawItemText was being calculated twice - first when measured and again when drawn. Instead store the length the first time it is calculated. Also, pass a copy of the string in wx2stclen to allow the calculation to work in ASCII builds. --- src/stc/PlatWX.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 1280b65595..40b78b5102 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3175,8 +3175,8 @@ public: wxString ellipsizedLabel = label; wxCharBuffer buffer = wx2stc(ellipsizedLabel); - int curWidth = surface.WidthText(tempFont, buffer.data(), - wx2stclen(wxString(), buffer)); + int ellipsizedLen = wx2stclen(ellipsizedLabel, buffer); + int curWidth = surface.WidthText(tempFont, buffer.data(),ellipsizedLen); for ( int i = label.length(); curWidth > rect.GetWidth() && i; --i ) { @@ -3184,8 +3184,8 @@ public: ellipsizedLabel << "..."; buffer = wx2stc(ellipsizedLabel); - curWidth = surface.WidthText(tempFont, buffer.data(), - wx2stclen(wxString(), buffer)); + ellipsizedLen = wx2stclen(ellipsizedLabel, buffer); + curWidth = surface.WidthText(tempFont, buffer.data(),ellipsizedLen); } PRectangle prect = PRectangleFromwxRect(rect); @@ -3194,7 +3194,7 @@ public: XYPOSITION ybase = rect.GetTop() + m_surfaceFontData->GetAscent(); surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), - wx2stclen(wxString(), buffer), fore); + ellipsizedLen, fore); tempFont.Release(); surface.Release(); } From 71fdad5f6df0b9130e38de415a1546eea6b44287 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Fri, 26 Jun 2020 14:06:32 -0500 Subject: [PATCH 09/13] Prevent warning in wxSTCListBoxWin ctr Currently 1 argument for the constructor is only used in an #ifdef block, and so some compilers give an unused parameter warning. Instead use the parameter with a switch statement to avoid the warning. --- src/stc/PlatWX.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 40b78b5102..34f6356279 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3223,15 +3223,17 @@ wxSTCListBoxWin::wxSTCListBoxWin(wxWindow* parent, wxSTCListBox** lb, wxSTCListBoxVisualData* v, int h, int tech) :wxSTCPopupWindow(parent) { + switch ( tech ) + { #ifdef HAVE_DIRECTWRITE_TECHNOLOGY - if ( tech == wxSTC_TECHNOLOGY_DIRECTWRITE ) - { - *lb = new wxSTCListBoxD2D(this, v, h); - } - else + case wxSTC_TECHNOLOGY_DIRECTWRITE: + *lb = new wxSTCListBoxD2D(this, v, h); + break; #endif - { - *lb = new wxSTCListBox(this, v, h); + case wxSTC_TECHNOLOGY_DEFAULT: + wxFALLTHROUGH; + default: + *lb = new wxSTCListBox(this, v, h); } // Use the background of this window to form a frame around the listbox From 7f78e97021a9e7611ee95b71b3340cdc092cfbb5 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Fri, 26 Jun 2020 14:11:39 -0500 Subject: [PATCH 10/13] Use ellipsis char not 3 periods to shorten label --- src/stc/PlatWX.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 34f6356279..b8377f205c 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3181,7 +3181,12 @@ public: for ( int i = label.length(); curWidth > rect.GetWidth() && i; --i ) { ellipsizedLabel = label.Left(i); - ellipsizedLabel << "..."; + #if wxUSE_UNICODE + // Add the "Horizontal Ellipsis" character (U+2026). + ellipsizedLabel << wxUniChar(0x2026); + #else + ellipsizedLabel << "..."; + #endif buffer = wx2stc(ellipsizedLabel); ellipsizedLen = wx2stclen(ellipsizedLabel, buffer); From 74332e913271c0983dace93bdff7f5aa7cbf3c7b Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Fri, 26 Jun 2020 14:40:17 -0500 Subject: [PATCH 11/13] Add comments for wxSTCListBoxD2D and its methods --- src/stc/PlatWX.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index b8377f205c..1d06fd7b8f 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3126,6 +3126,11 @@ void wxSTCListBox::OnDrawBackground(wxDC &dc, const wxRect &rect,size_t n) const #ifdef HAVE_DIRECTWRITE_TECHNOLOGY + +// This class will use SurfaceD2D methods to measure and draw items in the popup +// listbox. This is needed to ensure that the text in the listbox matches the +// text in the editor window as closely as possible. + class wxSTCListBoxD2D : public wxSTCListBox { public: @@ -3145,12 +3150,14 @@ public: void SetListBoxFont(Font& font) wxOVERRIDE { + // Retrieve the SurfaceFontDataD2D from font and store a copy of it. wxFontWithAscent* fwa = wxFontWithAscent::FromFID(font.GetID()); SurfaceData* data = fwa->GetSurfaceFontData(); SurfaceFontDataD2D* d2dft = static_cast(data); m_surfaceFontData = new SurfaceFontDataD2D(*d2dft); + // Create a SurfaceD2D object to measure text height for the font. SurfaceD2D surface; wxClientDC dc(this); surface.Init(&dc, GetGrandParent()); @@ -3163,6 +3170,7 @@ public: void OnDrawItemText(wxDC& dc, const wxRect& rect, const wxString& label, const wxColour& textCol) const wxOVERRIDE { + // Create a font and a surface object. wxFontWithAscent* fontCopy = new wxFontWithAscent(wxFont()); SurfaceFontDataD2D* sfd = new SurfaceFontDataD2D(*m_surfaceFontData); fontCopy->SetSurfaceFontData(sfd); @@ -3172,6 +3180,8 @@ public: SurfaceD2D surface; surface.Init(&dc, GetGrandParent()); + // Ellipsize the label if necessary. This is done by manually removing + // characters from the end of the label until it's short enough. wxString ellipsizedLabel = label; wxCharBuffer buffer = wx2stc(ellipsizedLabel); @@ -3193,6 +3203,7 @@ public: curWidth = surface.WidthText(tempFont, buffer.data(),ellipsizedLen); } + // Construct the necessary Scintilla objects and then draw the label. PRectangle prect = PRectangleFromwxRect(rect); ColourDesired fore(textCol.Red(), textCol.Green(), textCol.Blue()); @@ -3200,6 +3211,8 @@ public: surface.DrawTextTransparent(prect, tempFont, ybase, buffer.data(), ellipsizedLen, fore); + + // Clean up. tempFont.Release(); surface.Release(); } From 8129b38ee426c897d0bb85309ee5be7f59e71142 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 27 Jun 2020 13:50:07 +0200 Subject: [PATCH 12/13] Remove unnecessary pointer check before deleting it No real changes. --- src/stc/PlatWX.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 1d06fd7b8f..e92fc22285 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3142,10 +3142,7 @@ public: ~wxSTCListBoxD2D() { - if ( m_surfaceFontData ) - { - delete m_surfaceFontData; - } + delete m_surfaceFontData; } void SetListBoxFont(Font& font) wxOVERRIDE From 3bd832b2f3664fa3122c320e75622935ff965ccd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 27 Jun 2020 13:51:01 +0200 Subject: [PATCH 13/13] Add comment after closing "#endif" for clarify No real changes. --- src/stc/PlatWX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index e92fc22285..5bc0f60436 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -3217,7 +3217,7 @@ public: private: SurfaceFontDataD2D* m_surfaceFontData; }; -#endif +#endif // HAVE_DIRECTWRITE_TECHNOLOGY // A popup window to place the wxSTCListBox upon