aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Editor.cxx17
-rw-r--r--src/Editor.h1
-rw-r--r--src/LineMarker.cxx13
-rw-r--r--src/LineMarker.h7
-rw-r--r--src/PositionCache.cxx1
-rw-r--r--src/ScintillaBase.cxx5
-rw-r--r--src/ViewStyle.cxx3
-rw-r--r--src/XPM.cxx135
-rw-r--r--src/XPM.h49
9 files changed, 224 insertions, 7 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 26c260101..ff9872e58 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include <map>
#include <algorithm>
#include <memory>
@@ -8020,6 +8021,22 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
RedrawSelMargin();
break;
+ case SCI_RGBAIMAGESETWIDTH:
+ sizeRGBAImage.x = wParam;
+ break;
+
+ case SCI_RGBAIMAGESETHEIGHT:
+ sizeRGBAImage.y = wParam;
+ break;
+
+ case SCI_MARKERDEFINERGBAIMAGE:
+ if (wParam <= MARKER_MAX) {
+ vs.markers[wParam].SetRGBAImage(sizeRGBAImage, reinterpret_cast<unsigned char *>(lParam));
+ };
+ InvalidateStyleData();
+ RedrawSelMargin();
+ break;
+
case SCI_SETMARGINTYPEN:
if (ValidMargin(wParam)) {
vs.ms[wParam].style = lParam;
diff --git a/src/Editor.h b/src/Editor.h
index 74f0eff86..f1a500b74 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -131,6 +131,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
* When a style attribute is changed, this cache is flushed. */
bool stylesValid;
ViewStyle vs;
+ Point sizeRGBAImage;
Palette palette;
int printMagnification;
diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx
index 747c5ff12..1415c609b 100644
--- a/src/LineMarker.cxx
+++ b/src/LineMarker.cxx
@@ -7,6 +7,9 @@
#include <string.h>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
@@ -38,6 +41,12 @@ void LineMarker::SetXPM(const char *const *linesForm) {
markType = SC_MARK_PIXMAP;
}
+void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
+ delete image;
+ image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
+ markType = SC_MARK_RGBAIMAGE;
+}
+
static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
PRectangle rc;
rc.left = centreX - armSize;
@@ -96,6 +105,10 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
pxpm->Draw(surface, rcWhole);
return;
}
+ if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
+ surface->DrawRGBAImage(rcWhole, image->GetWidth(), image->GetHeight(), image->Pixels());
+ return;
+ }
// Restrict most shapes a bit
PRectangle rc = rcWhole;
rc.top++;
diff --git a/src/LineMarker.h b/src/LineMarker.h
index 39c38fa41..722c44b62 100644
--- a/src/LineMarker.h
+++ b/src/LineMarker.h
@@ -25,6 +25,7 @@ public:
ColourPair backSelected;
int alpha;
XPM *pxpm;
+ RGBAImage *image;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
@@ -32,6 +33,7 @@ public:
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
+ image = NULL;
}
LineMarker(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real copy constructor
@@ -41,9 +43,11 @@ public:
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
+ image = NULL;
}
~LineMarker() {
delete pxpm;
+ delete image;
}
LineMarker &operator=(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real assignment operator
@@ -54,11 +58,14 @@ public:
alpha = SC_ALPHA_NOALPHA;
delete pxpm;
pxpm = NULL;
+ delete image;
+ image = NULL;
return *this;
}
void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
+ void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
};
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index e59c12630..5f3ce81b3 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include <map>
#include "Platform.h"
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 3de4a4583..380ed2424 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include <map>
#include "Platform.h"
@@ -760,6 +761,10 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
+ case SCI_REGISTERRGBAIMAGE:
+ ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam));
+ break;
+
case SCI_CLEARREGISTEREDIMAGES:
ac.lb->ClearRegisteredImages();
break;
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index 03a2fb42f..9ba69b1ce 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -7,6 +7,9 @@
#include <string.h>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
diff --git a/src/XPM.cxx b/src/XPM.cxx
index d1389efa0..6c615dd94 100644
--- a/src/XPM.cxx
+++ b/src/XPM.cxx
@@ -8,6 +8,13 @@
#include <string.h>
#include <stdlib.h>
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "XPM.h"
@@ -38,6 +45,10 @@ static size_t MeasureLength(const char *s) {
return i;
}
+ColourDesired XPM::ColourDesiredFromCode(int ch) const {
+ return colourCodeTable[ch]->desired;
+}
+
ColourAllocated XPM::ColourFromCode(int ch) const {
return colourCodeTable[ch]->allocated;
#ifdef SLOW
@@ -200,6 +211,21 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
}
}
+void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const {
+ if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) {
+ colour = 0;
+ transparent = true;
+ return;
+ }
+ int code = lines[y+nColours+1][x];
+ transparent = code == codeTransparent;
+ if (transparent) {
+ colour = 0;
+ } else {
+ colour = ColourDesiredFromCode(code).AsLong();
+ }
+}
+
const char **XPM::LinesFormFromTextForm(const char *textForm) {
// Build the lines form out of the text form
const char **linesForm = 0;
@@ -261,14 +287,14 @@ void XPMSet::Clear() {
width = -1;
}
-void XPMSet::Add(int id, const char *textForm) {
+void XPMSet::Add(int ident, const char *textForm) {
// Invalidate cached dimensions
height = -1;
width = -1;
// Replace if this id already present
for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == id) {
+ if (set[i]->GetId() == ident) {
set[i]->Init(textForm);
set[i]->CopyDesiredColours();
return;
@@ -278,7 +304,7 @@ void XPMSet::Add(int id, const char *textForm) {
// Not present, so add to end
XPM *pxpm = new XPM(textForm);
if (pxpm) {
- pxpm->SetId(id);
+ pxpm->SetId(ident);
pxpm->CopyDesiredColours();
if (len == maximum) {
maximum += 64;
@@ -294,9 +320,9 @@ void XPMSet::Add(int id, const char *textForm) {
}
}
-XPM *XPMSet::Get(int id) {
+XPM *XPMSet::Get(int ident) {
for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == id) {
+ if (set[i]->GetId() == ident) {
return set[i];
}
}
@@ -324,3 +350,102 @@ int XPMSet::GetWidth() {
}
return (width > 0) ? width : 0;
}
+
+RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
+ height(height_), width(width_) {
+ pixelBytes.assign(pixels_, pixels_ + CountBytes());
+}
+
+RGBAImage::RGBAImage(const XPM &xpm) {
+ height = xpm.GetHeight();
+ width = xpm.GetWidth();
+ pixelBytes.resize(CountBytes());
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ ColourDesired colour;
+ bool transparent = false;
+ xpm.PixelAt(x, y, colour, transparent);
+ unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
+ // RGBA
+ pixel[0] = colour.GetRed();
+ pixel[1] = colour.GetGreen();
+ pixel[2] = colour.GetBlue();
+ pixel[3] = transparent ? 0 : 255;
+ }
+ }
+}
+
+RGBAImage::~RGBAImage() {
+}
+
+int RGBAImage::CountBytes() const {
+ return width * height * 4;
+}
+
+const unsigned char *RGBAImage::Pixels() const {
+ return &pixelBytes[0];
+}
+
+RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
+}
+
+RGBAImageSet::~RGBAImageSet() {
+ Clear();
+}
+
+/// Remove all images.
+void RGBAImageSet::Clear() {
+ for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) {
+ delete it->second;
+ it->second = 0;
+ }
+ images.clear();
+ height = -1;
+ width = -1;
+}
+
+/// Add an image.
+void RGBAImageSet::Add(int ident, RGBAImage *image) {
+ ImageMap::iterator it=images.find(ident);
+ if (it == images.end()) {
+ images[ident] = image;
+ } else {
+ delete it->second;
+ it->second = image;
+ }
+ height = -1;
+ width = -1;
+}
+
+/// Get image by id.
+RGBAImage *RGBAImageSet::Get(int ident) {
+ ImageMap::iterator it = images.find(ident);
+ if (it != images.end()) {
+ return it->second;
+ }
+ return NULL;
+}
+
+/// Give the largest height of the set.
+int RGBAImageSet::GetHeight() const {
+ if (height < 0) {
+ for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
+ if (height < it->second->GetHeight()) {
+ height = it->second->GetHeight();
+ }
+ }
+ }
+ return (height > 0) ? height : 0;
+}
+
+/// Give the largest width of the set.
+int RGBAImageSet::GetWidth() const {
+ if (width < 0) {
+ for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
+ if (width < it->second->GetWidth()) {
+ width = it->second->GetWidth();
+ }
+ }
+ }
+ return (width > 0) ? width : 0;
+}
diff --git a/src/XPM.h b/src/XPM.h
index cb05aae3e..8b72ef08d 100644
--- a/src/XPM.h
+++ b/src/XPM.h
@@ -24,6 +24,7 @@ class XPM {
char codeTransparent;
char *codes;
ColourPair *colours;
+ ColourDesired ColourDesiredFromCode(int ch) const;
ColourAllocated ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines;
@@ -46,6 +47,7 @@ public:
int GetId() const { return pid; }
int GetHeight() const { return height; }
int GetWidth() const { return width; }
+ void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const;
static const char **LinesFormFromTextForm(const char *textForm);
};
@@ -64,15 +66,58 @@ public:
/// Remove all XPMs.
void Clear();
/// Add a XPM.
- void Add(int id, const char *textForm);
+ void Add(int ident, const char *textForm);
/// Get XPM by id.
- XPM *Get(int id);
+ XPM *Get(int ident);
/// Give the largest height of the set.
int GetHeight();
/// Give the largest width of the set.
int GetWidth();
};
+/**
+ * An translucent image stoed as a sequence of RGBA bytes.
+ */
+class RGBAImage {
+ // Private so RGBAImage objects can not be copied
+ RGBAImage(const RGBAImage &);
+ RGBAImage &operator=(const RGBAImage &);
+ int height;
+ int width;
+ std::vector<unsigned char> pixelBytes;
+public:
+ RGBAImage(int width_, int height_, const unsigned char *pixels_);
+ RGBAImage(const XPM &xpm);
+ virtual ~RGBAImage();
+ int GetHeight() const { return height; }
+ int GetWidth() const { return width; }
+ int CountBytes() const;
+ const unsigned char *Pixels() const;
+};
+
+/**
+ * A collection of RGBAImage pixmaps indexed by integer id.
+ */
+class RGBAImageSet {
+ typedef std::map<int, RGBAImage*> ImageMap;
+ ImageMap images;
+ mutable int height; ///< Memorize largest height of the set.
+ mutable int width; ///< Memorize largest width of the set.
+public:
+ RGBAImageSet();
+ ~RGBAImageSet();
+ /// Remove all images.
+ void Clear();
+ /// Add an image.
+ void Add(int ident, RGBAImage *image);
+ /// Get image by id.
+ RGBAImage *Get(int ident);
+ /// Give the largest height of the set.
+ int GetHeight() const;
+ /// Give the largest width of the set.
+ int GetWidth() const;
+};
+
#ifdef SCI_NAMESPACE
}
#endif