diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Editor.cxx | 17 | ||||
| -rw-r--r-- | src/Editor.h | 1 | ||||
| -rw-r--r-- | src/LineMarker.cxx | 13 | ||||
| -rw-r--r-- | src/LineMarker.h | 7 | ||||
| -rw-r--r-- | src/PositionCache.cxx | 1 | ||||
| -rw-r--r-- | src/ScintillaBase.cxx | 5 | ||||
| -rw-r--r-- | src/ViewStyle.cxx | 3 | ||||
| -rw-r--r-- | src/XPM.cxx | 135 | ||||
| -rw-r--r-- | src/XPM.h | 49 | 
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; +} @@ -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 | 
