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.
This commit is contained in:
New Pagodi
2019-02-14 22:25:57 -06:00
parent 8c180ee7b5
commit f50b18000a
7 changed files with 53 additions and 18 deletions

View File

@@ -33,6 +33,8 @@
#include "wx/dataobj.h" #include "wx/dataobj.h"
#include "wx/clipbrd.h" #include "wx/clipbrd.h"
#include "wx/dnd.h" #include "wx/dnd.h"
#include "wx/image.h"
#include "wx/scopedarray.h"
#if !wxUSE_STD_CONTAINERS && !wxUSE_STD_IOSTREAM && !wxUSE_STD_STRING #if !wxUSE_STD_CONTAINERS && !wxUSE_STD_IOSTREAM && !wxUSE_STD_STRING
#include "wx/beforestd.h" #include "wx/beforestd.h"
@@ -1336,6 +1338,33 @@ bool ScintillaWX::GetUseAntiAliasing() {
return vs.extraFontFlag != 0; 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<unsigned char> 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( sptr_t ScintillaWX::DirectFunction(
ScintillaWX* swx, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaWX* swx, unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return swx->WndProc(iMessage, wParam, lParam); return swx->WndProc(iMessage, wParam, lParam);

View File

@@ -199,6 +199,7 @@ public:
bool GetUseAntiAliasing(); bool GetUseAntiAliasing();
SurfaceData* GetSurfaceData() const {return m_surfaceData;} SurfaceData* GetSurfaceData() const {return m_surfaceData;}
void SetPaintAbandoned(){paintState = paintAbandoned;} void SetPaintAbandoned(){paintState = paintAbandoned;}
void DoMarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
private: private:
bool capturedMouse; bool capturedMouse;

View File

@@ -40,7 +40,8 @@ categoriesList = [
('OtherSettings' ,'Other settings', 0), ('OtherSettings' ,'Other settings', 0),
('BraceHighlighting' ,'Brace highlighting', 0), ('BraceHighlighting' ,'Brace highlighting', 0),
('TabsAndIndentationGuides' ,'Tabs and Indentation Guides', 0), ('TabsAndIndentationGuides' ,'Tabs and Indentation Guides', 0),
('Markers' ,'Markers', 0), ('Markers' ,'Markers',
('@see MarkerDefineBitmap',)),
('Indicators' ,'Indicators', 0), ('Indicators' ,'Indicators', 0),
('Autocompletion' ,'Autocompletion', 0), ('Autocompletion' ,'Autocompletion', 0),
('UserLists' ,'User lists', 0), ('UserLists' ,'User lists', 0),
@@ -1406,7 +1407,9 @@ sinceAnnotations= {
'SetMouseWheelCaptures':'3.1.1', 'SetMouseWheelCaptures':'3.1.1',
'SetTabDrawMode':'3.1.1', 'SetTabDrawMode':'3.1.1',
'TargetWholeDocument':'3.1.1', 'TargetWholeDocument':'3.1.1',
'ToggleFoldShowText':'3.1.1' 'ToggleFoldShowText':'3.1.1',
'MarkerDefinePixmap':'3.1.3'
} }

View File

@@ -213,22 +213,11 @@ methodOverrideMap = {
), ),
'MarkerDefinePixmap' : 'MarkerDefinePixmap' :
('MarkerDefineBitmap', (0,
'''void %s(int markerNumber, const wxBitmap& bmp);''', '''void %s(int markerNumber, const char* const* xpmData);''',
'''void %s(int markerNumber, const wxBitmap& bmp) { '''void %s(int markerNumber, const char* const* xpmData) {
// convert bmp to a xpm in a string SendMsg(%s, markerNumber, (sptr_t)xpmData);'''
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;'''
), ),
'GetMargins' : ('GetMarginCount', 0, 0), 'GetMargins' : ('GetMarginCount', 0, 0),

View File

@@ -563,6 +563,11 @@ void wxStyledTextCtrl::AnnotationClearLine(int line) {
SendMsg(SCI_ANNOTATIONSETTEXT, line, (sptr_t)NULL); SendMsg(SCI_ANNOTATIONSETTEXT, line, (sptr_t)NULL);
} }
void wxStyledTextCtrl::MarkerDefineBitmap(int markerNumber,
const wxBitmap& bmp) {
m_swx->DoMarkerDefineBitmap(markerNumber, bmp);
}

View File

@@ -298,6 +298,9 @@ public:
// Clear annotations from the given line. // Clear annotations from the given line.
void AnnotationClearLine(int 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 // The following methods are nearly equivalent to their similarly named

View File

@@ -353,6 +353,11 @@ public:
*/ */
void AnnotationClearLine(int line); void AnnotationClearLine(int line);
/**
Define a marker with a wxBitmap.
*/
void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
//@} //@}