aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <unknown>2002-10-02 03:26:47 +0000
committernyamatongwe <unknown>2002-10-02 03:26:47 +0000
commit3ce653c5dca296d9280a1a6f60a5d53423ac5fe2 (patch)
tree07a566b2912ab1d77d3e859687a05f806651c87a /src
parentc0da3d705622cbea4033e1226e2e37502c2977d2 (diff)
downloadscintilla-mirror-3ce653c5dca296d9280a1a6f60a5d53423ac5fe2.tar.gz
PixMap marker support.
Diffstat (limited to 'src')
-rw-r--r--src/Editor.cxx23
-rw-r--r--src/LineMarker.cxx227
-rw-r--r--src/LineMarker.h29
-rw-r--r--src/ViewStyle.cxx5
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,