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 |