From f50b18000af921c595d4bc3353f15e49a5141027 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Thu, 14 Feb 2019 22:25:57 -0600 Subject: [PATCH] Change wxSTC mapping for SCI_MARKERDEFINEPIXMAP Currently the Scintilla message SCI_MARKERDEFINEPIXMAP is mapped to the wxStyledTextCtrl::MarkerDefineBitmap method. This has two drawbacks. First this requires the XPM image handler be loaded before this method can be called. Second, any alpha data except for opaque and transparent is lost in the conversion to XPM format. Instead have MarkerDefineBitmap be a manually declared method but reimplemented it in a way similar to how the SCI_MARKERDEFINERGBAIMAGE message works. The new implementation preserves alpha data if it exists. To backfill the message map, the SCI_MARKERDEFINEPIXMAP is now mapped to a new method MarkerDefinePixmap(int, const char* const*). The new method accepts XPM data instead of a wxBitmap. --- src/stc/ScintillaWX.cpp | 29 +++++++++++++++++++++++++++++ src/stc/ScintillaWX.h | 1 + src/stc/gen_docs.py | 7 +++++-- src/stc/gen_iface.py | 21 +++++---------------- src/stc/stc.cpp.in | 5 +++++ src/stc/stc.h.in | 3 +++ src/stc/stc.interface.h.in | 5 +++++ 7 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index e9ddba686d..5ead9fc363 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -33,6 +33,8 @@ #include "wx/dataobj.h" #include "wx/clipbrd.h" #include "wx/dnd.h" +#include "wx/image.h" +#include "wx/scopedarray.h" #if !wxUSE_STD_CONTAINERS && !wxUSE_STD_IOSTREAM && !wxUSE_STD_STRING #include "wx/beforestd.h" @@ -1336,6 +1338,33 @@ bool ScintillaWX::GetUseAntiAliasing() { return vs.extraFontFlag != 0; } +void ScintillaWX::DoMarkerDefineBitmap(int markerNumber, const wxBitmap& bmp) { + if ( 0 <= markerNumber && markerNumber <= MARKER_MAX) { + // Build an RGBA buffer from bmp. + const int totalPixels = bmp.GetWidth() * bmp.GetHeight(); + wxScopedArray rgba(4*bmp.GetWidth()*bmp.GetHeight()); + wxImage img = bmp.ConvertToImage(); + int curRGBALoc = 0, curDataLoc = 0, curAlphaLoc = 0; + + for ( int i = 0; i < totalPixels; ++i ) { + rgba[curRGBALoc++] = img.GetData()[curDataLoc++]; + rgba[curRGBALoc++] = img.GetData()[curDataLoc++]; + rgba[curRGBALoc++] = img.GetData()[curDataLoc++]; + rgba[curRGBALoc++] = + img.HasAlpha()?img.GetAlpha()[curAlphaLoc++]:255; + } + + // Now follow the same procedure used for handling the + // SCI_MARKERDEFINERGBAIMAGE message, except use the bitmap's width and + // height instead of the values stored in sizeRGBAImage. + Point bitmapSize = Point::FromInts(bmp.GetWidth(), bmp.GetHeight()); + vs.markers[markerNumber].SetRGBAImage(bitmapSize, 1.0f, rgba.get()); + vs.CalcLargestMarkerHeight(); + } + InvalidateStyleData(); + RedrawSelMargin(); +} + sptr_t ScintillaWX::DirectFunction( ScintillaWX* swx, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return swx->WndProc(iMessage, wParam, lParam); diff --git a/src/stc/ScintillaWX.h b/src/stc/ScintillaWX.h index d4d03f9c0e..b858809b0f 100644 --- a/src/stc/ScintillaWX.h +++ b/src/stc/ScintillaWX.h @@ -199,6 +199,7 @@ public: bool GetUseAntiAliasing(); SurfaceData* GetSurfaceData() const {return m_surfaceData;} void SetPaintAbandoned(){paintState = paintAbandoned;} + void DoMarkerDefineBitmap(int markerNumber, const wxBitmap& bmp); private: bool capturedMouse; diff --git a/src/stc/gen_docs.py b/src/stc/gen_docs.py index a4de040ab7..cb9b1774dd 100644 --- a/src/stc/gen_docs.py +++ b/src/stc/gen_docs.py @@ -40,7 +40,8 @@ categoriesList = [ ('OtherSettings' ,'Other settings', 0), ('BraceHighlighting' ,'Brace highlighting', 0), ('TabsAndIndentationGuides' ,'Tabs and Indentation Guides', 0), - ('Markers' ,'Markers', 0), + ('Markers' ,'Markers', + ('@see MarkerDefineBitmap',)), ('Indicators' ,'Indicators', 0), ('Autocompletion' ,'Autocompletion', 0), ('UserLists' ,'User lists', 0), @@ -1406,7 +1407,9 @@ sinceAnnotations= { 'SetMouseWheelCaptures':'3.1.1', 'SetTabDrawMode':'3.1.1', 'TargetWholeDocument':'3.1.1', - 'ToggleFoldShowText':'3.1.1' + 'ToggleFoldShowText':'3.1.1', + + 'MarkerDefinePixmap':'3.1.3' } diff --git a/src/stc/gen_iface.py b/src/stc/gen_iface.py index 2de2832169..4cfdd2c854 100755 --- a/src/stc/gen_iface.py +++ b/src/stc/gen_iface.py @@ -213,22 +213,11 @@ methodOverrideMap = { ), - 'MarkerDefinePixmap' : - ('MarkerDefineBitmap', - '''void %s(int markerNumber, const wxBitmap& bmp);''', - '''void %s(int markerNumber, const wxBitmap& bmp) { - // convert bmp to a xpm in a string - wxMemoryOutputStream strm; - wxImage img = bmp.ConvertToImage(); - if (img.HasAlpha()) - img.ConvertAlphaToMask(); - img.SaveFile(strm, wxBITMAP_TYPE_XPM); - size_t len = strm.GetSize(); - char* buff = new char[len+1]; - strm.CopyTo(buff, len); - buff[len] = 0; - SendMsg(%s, markerNumber, (sptr_t)buff); - delete [] buff;''' + 'MarkerDefinePixmap' : + (0, + '''void %s(int markerNumber, const char* const* xpmData);''', + '''void %s(int markerNumber, const char* const* xpmData) { + SendMsg(%s, markerNumber, (sptr_t)xpmData);''' ), 'GetMargins' : ('GetMarginCount', 0, 0), diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 827633364d..d082ffd27c 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -563,6 +563,11 @@ void wxStyledTextCtrl::AnnotationClearLine(int line) { SendMsg(SCI_ANNOTATIONSETTEXT, line, (sptr_t)NULL); } +void wxStyledTextCtrl::MarkerDefineBitmap(int markerNumber, + const wxBitmap& bmp) { + m_swx->DoMarkerDefineBitmap(markerNumber, bmp); +} + diff --git a/src/stc/stc.h.in b/src/stc/stc.h.in index 8413084a7c..c21e8bf061 100644 --- a/src/stc/stc.h.in +++ b/src/stc/stc.h.in @@ -298,6 +298,9 @@ public: // Clear annotations from the given line. void AnnotationClearLine(int line); + // Define a marker from a bitmap. + void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp); + // The following methods are nearly equivalent to their similarly named diff --git a/src/stc/stc.interface.h.in b/src/stc/stc.interface.h.in index ec7885b0dd..19559197ad 100644 --- a/src/stc/stc.interface.h.in +++ b/src/stc/stc.interface.h.in @@ -353,6 +353,11 @@ public: */ void AnnotationClearLine(int line); + /** + Define a marker with a wxBitmap. + */ + void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp); + //@}