diff options
author | nyamatongwe <unknown> | 2002-10-02 03:26:47 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2002-10-02 03:26:47 +0000 |
commit | 3ce653c5dca296d9280a1a6f60a5d53423ac5fe2 (patch) | |
tree | 07a566b2912ab1d77d3e859687a05f806651c87a /src | |
parent | c0da3d705622cbea4033e1226e2e37502c2977d2 (diff) | |
download | scintilla-mirror-3ce653c5dca296d9280a1a6f60a5d53423ac5fe2.tar.gz |
PixMap marker support.
Diffstat (limited to 'src')
-rw-r--r-- | src/Editor.cxx | 23 | ||||
-rw-r--r-- | src/LineMarker.cxx | 227 | ||||
-rw-r--r-- | src/LineMarker.h | 29 | ||||
-rw-r--r-- | src/ViewStyle.cxx | 5 |
4 files changed, 253 insertions, 31 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 62a035613..425847852 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -5142,6 +5142,19 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_MARKERDEFINE: if (wParam <= MARKER_MAX) vs.markers[wParam].markType = lParam; + { + static char *stop_xpm = "\ + static char *stop_xpm[] = {\ +\"4 4 3 1\",\ +\" c None\",\ +\". c #0000FF\",\ +\"+ c #FFFF00\",\ +\" .. \",\ +\".++.\",\ +\".++.\",\ +\" .. \"};"; + vs.markers[wParam].SetXPM(stop_xpm); + }; InvalidateStyleData(); RedrawSelMargin(); break; @@ -5190,7 +5203,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } return -1; - case SCI_SETMARGINTYPEN: + case SCI_MARKERDEFINEPIXMAP: + if (wParam <= MARKER_MAX) { + vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); + }; + InvalidateStyleData(); + RedrawSelMargin(); + break; + + case SCI_SETMARGINTYPEN: if (ValidMargin(wParam)) { vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL); InvalidateStyleRedraw(); diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx index 009ea4ea5..b2a49991d 100644 --- a/src/LineMarker.cxx +++ b/src/LineMarker.cxx @@ -5,11 +5,180 @@ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. +#include <stdlib.h> + #include "Platform.h" #include "Scintilla.h" #include "LineMarker.h" +static const char *NextField(const char *s) { + while (*s && *s != ' ') { + s++; + } + while (*s && *s == ' ') { + s++; + } + return s; +} + +static int IntFromHexDigit(const char ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else + return 0; +} + +static ColourDesired ColourFromString(const char *val) { + int r = IntFromHexDigit(val[1]) * 16 + IntFromHexDigit(val[2]); + int g = IntFromHexDigit(val[3]) * 16 + IntFromHexDigit(val[4]); + int b = IntFromHexDigit(val[5]) * 16 + IntFromHexDigit(val[6]); + return ColourDesired(r, g, b); +} + +void XPM::Init(const char * const *linesForm) { + height = 1; + width = 1; + nColours = 1; + data = NULL; + codeTransparent = ' '; + codes = NULL; + colours = NULL; + if (!linesForm) + return; + + const char *line0 = linesForm[0]; + width = atoi(line0); + line0 = NextField(line0); + height = atoi(line0); + line0 = NextField(line0); + nColours = atoi(line0); + data = new char[height * width]; + codes = new char[nColours]; + colours = new ColourPair[nColours]; + + for (int c=0; c<nColours; c++) { + const char *colourDef = linesForm[c+1]; + codes[c] = colourDef[0]; + colourDef += 4; + if (*colourDef == '#') { + colourDef++; + colours[c].desired = ColourFromString(colourDef); + } else { + colours[c].desired = ColourDesired(0xff, 0xff, 0xff); + codeTransparent = codes[c]; + } + } + int datapos = 0; + for (int l=0; l<height; l++) { + for (int x=0; x<width; x++) { + data[datapos++] = linesForm[1+nColours+l][x]; + } + } +} + +ColourAllocated XPM::ColourFromCode(char ch) { + for (int i=0;i<nColours;i++) { + if (codes[i] == ch) { + return colours[i].allocated; + } + } + return colours[0].allocated; +} + +void XPM::FillRun(Surface *surface, char code, int startX, int y, int x) { + if (code != codeTransparent) { + PRectangle rc(startX, y, x, y+1); + surface->FillRectangle(rc, ColourFromCode(code)); + } +} + +XPM::XPM(const char *textForm) { + int countQuotes = 0; + for (int i=0; textForm[i]; i++) { + if (textForm[i] == '\"') { + countQuotes++; + } + } + const char **linesForm = new const char *[countQuotes/2]; + countQuotes = 0; + if (linesForm) { + for (int j=0; textForm[j]; j++) { + if (textForm[j] == '\"') { + if ((countQuotes & 1) == 0) { + linesForm[countQuotes / 2] = textForm + j + 1; + } + countQuotes++; + } + } + } + Init(linesForm); + delete []linesForm; +} + +XPM::XPM(const char * const *linesForm) { + Init(linesForm); +} + +XPM::~XPM() { + delete []data; + delete []codes; + delete []colours; +} + +void XPM::RefreshColourPalette(Palette &pal, bool want) { + if (!data || !codes || !colours) { + return; + } + for (int i=0;i<nColours;i++) { + pal.WantFind(colours[i], want); + } +} + +void XPM::Draw(Surface *surface, PRectangle &rc) { + if (!data || !codes || !colours) { + return; + } + // Centre the pixmap + int startY = rc.top + (rc.Height() - height) / 2; + int startX = rc.left + (rc.Width() - width) / 2; + for (int y=0;y<height;y++) { + char prevCode = 0; + int xStartRun = 0; + for (int x=0; x<width; x++) { + int code = data[y*width + x]; + if (code != prevCode) { + FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x); + xStartRun = x; + prevCode = code; + } + } + FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width); + } +} + +void LineMarker::RefreshColourPalette(Palette &pal, bool want) { + pal.WantFind(fore, want); + pal.WantFind(back, want); + if (pxpm) { + pxpm->RefreshColourPalette(pal, want); + } +} + +void LineMarker::SetXPM(const char *textForm) { + delete pxpm; + pxpm = new XPM(textForm); +} + +void LineMarker::SetXPM(const char * const *linesForm) { + delete pxpm; + pxpm = new XPM(linesForm); +} + static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) { PRectangle rc; rc.left = centreX - armSize; @@ -41,6 +210,10 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C } void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) { + if (pxpm) { + pxpm->Draw(surface, rcWhole); + return; + } // Restrict most shapes a bit PRectangle rc = rcWhole; rc.top++; @@ -122,121 +295,121 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac rcSmall.right = rc.right - 1; rcSmall.bottom = rc.bottom - 2; surface->RectangleDraw(rcSmall, fore.allocated, back.allocated); - + } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) { // An invisible marker so don't draw anything - + } else if (markType == SC_MARK_VLINE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_LCORNER) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); - + } else if (markType == SC_MARK_TCORNER) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); surface->MoveTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); - + } else if (markType == SC_MARK_LCORNERCURVE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); - + } else if (markType == SC_MARK_TCORNERCURVE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); - + } else if (markType == SC_MARK_BOXPLUS) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + } else if (markType == SC_MARK_BOXPLUSCONNECTED) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_BOXMINUS) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_BOXMINUSCONNECTED) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_CIRCLEPLUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_CIRCLEMINUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType >= SC_MARK_CHARACTER) { char character[1]; character[0] = static_cast<char>(markType - SC_MARK_CHARACTER); int width = surface->WidthText(fontForCharacter, character, 1); rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; - surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, + surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, character, 1, fore.allocated, back.allocated); } else if (markType == SC_MARK_DOTDOTDOT) { diff --git a/src/LineMarker.h b/src/LineMarker.h index 7897aa775..50194d65c 100644 --- a/src/LineMarker.h +++ b/src/LineMarker.h @@ -8,6 +8,27 @@ #ifndef LINEMARKER_H #define LINEMARKER_H +class XPM { + int height; + int width; + int nColours; + char *data; + char codeTransparent; + char *codes; + ColourPair *colours; + void Init(const char * const *linesForm); + ColourAllocated ColourFromCode(char ch); + void FillRun(Surface *surface, char code, int startX, int y, int x); +public: + XPM(const char *textForm); + XPM(const char * const *linesForm); + ~XPM(); + // Similar to same named method in ViewStyle: + void RefreshColourPalette(Palette &pal, bool want); + // Decompose image into runs and use FillRectangle for each run: + void Draw(Surface *surface, PRectangle &rc); +}; + /** */ class LineMarker { @@ -15,11 +36,19 @@ public: int markType; ColourPair fore; ColourPair back; + XPM *pxpm; LineMarker() { markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); back = ColourDesired(0xff,0xff,0xff); + pxpm = NULL; + } + ~LineMarker() { + delete pxpm; } + void RefreshColourPalette(Palette &pal, bool want); + void SetXPM(const char *textForm); + void SetXPM(const char * const *linesForm); void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter); }; diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 12e1406aa..e28e11ed8 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -178,8 +178,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(indicators[i].fore, want); } for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) { - pal.WantFind(markers[i].fore, want); - pal.WantFind(markers[i].back, want); + markers[i].RefreshColourPalette(pal, want); } pal.WantFind(selforeground, want); pal.WantFind(selbackground, want); @@ -225,7 +224,7 @@ void ViewStyle::Refresh(Surface &surface) { } void ViewStyle::ResetDefaultStyle() { - styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), + styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), ColourDesired(0xff,0xff,0xff), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, |