diff options
-rw-r--r-- | src/XPM.cxx | 96 | ||||
-rw-r--r-- | src/XPM.h | 19 |
2 files changed, 36 insertions, 79 deletions
diff --git a/src/XPM.cxx b/src/XPM.cxx index 4dcf439f5..d6397afa7 100644 --- a/src/XPM.cxx +++ b/src/XPM.cxx @@ -41,12 +41,8 @@ static size_t MeasureLength(const char *s) { return i; } -ColourDesired XPM::ColourDesiredFromCode(int ch) const { - return *colourCodeTable[ch]; -} - ColourDesired XPM::ColourFromCode(int ch) const { - return *colourCodeTable[ch]; + return colourCodeTable[ch]; } void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) { @@ -56,13 +52,11 @@ void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) { } } -XPM::XPM(const char *textForm) : - data(0), codes(0), colours(0), lines(0) { +XPM::XPM(const char *textForm) { Init(textForm); } -XPM::XPM(const char *const *linesForm) : - data(0), codes(0), colours(0), lines(0) { +XPM::XPM(const char *const *linesForm) { Init(linesForm); } @@ -76,10 +70,9 @@ void XPM::Init(const char *textForm) { // if memcmp implemented strangely. Must be 4 bytes at least at destination. if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { // Build the lines form out of the text form - const char **linesForm = LinesFormFromTextForm(textForm); - if (linesForm != 0) { - Init(linesForm); - delete []linesForm; + std::vector<const char *> linesForm = LinesFormFromTextForm(textForm); + if (!linesForm.empty()) { + Init(&linesForm[0]); } } else { // It is really in line form @@ -92,18 +85,17 @@ void XPM::Init(const char *const *linesForm) { height = 1; width = 1; nColours = 1; - data = NULL; + pixels.clear(); codeTransparent = ' '; - codes = NULL; - colours = NULL; - lines = NULL; if (!linesForm) return; + std::fill(colourCodeTable, colourCodeTable+256, 0); const char *line0 = linesForm[0]; width = atoi(line0); line0 = NextField(line0); height = atoi(line0); + pixels.resize(width*height); line0 = NextField(line0); nColours = atoi(line0); line0 = NextField(line0); @@ -111,56 +103,33 @@ void XPM::Init(const char *const *linesForm) { // Only one char per pixel is supported return; } - codes = new char[nColours]; - colours = new ColourDesired[nColours]; - - int strings = 1+height+nColours; - lines = new char *[strings]; - size_t allocation = 0; - for (int i=0; i<strings; i++) { - allocation += MeasureLength(linesForm[i]) + 1; - } - data = new char[allocation]; - char *nextBit = data; - for (int j=0; j<strings; j++) { - lines[j] = nextBit; - size_t len = MeasureLength(linesForm[j]); - memcpy(nextBit, linesForm[j], len); - nextBit += len; - *nextBit++ = '\0'; - } - - for (int code=0; code<256; code++) { - colourCodeTable[code] = 0; - } for (int c=0; c<nColours; c++) { const char *colourDef = linesForm[c+1]; - codes[c] = colourDef[0]; + int code = static_cast<unsigned char>(colourDef[0]); colourDef += 4; + ColourDesired colour(0xff, 0xff, 0xff); if (*colourDef == '#') { - colours[c].Set(colourDef); + colour.Set(colourDef); } else { - colours[c] = ColourDesired(0xff, 0xff, 0xff); - codeTransparent = codes[c]; + codeTransparent = code; } - colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]); + colourCodeTable[code] = colour; + } + + for (int y=0; y<height; y++) { + const char *lform = linesForm[y+nColours+1]; + size_t len = MeasureLength(lform); + for (size_t x = 0; x<len; x++) + pixels[y * width + x] = static_cast<unsigned char>(lform[x]); } } void XPM::Clear() { - delete []data; - data = 0; - delete []codes; - codes = 0; - delete []colours; - colours = 0; - delete []lines; - lines = 0; } void XPM::Draw(Surface *surface, PRectangle &rc) { - if (!data || !codes || !colours || !lines) { + if (pixels.empty()) { return; } // Centre the pixmap @@ -170,7 +139,7 @@ void XPM::Draw(Surface *surface, PRectangle &rc) { int prevCode = 0; int xStartRun = 0; for (int x=0; x<width; x++) { - int code = lines[y+nColours+1][x]; + int code = pixels[y * width + x]; if (code != prevCode) { FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x); xStartRun = x; @@ -182,23 +151,23 @@ 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)) { + if (pixels.empty() || (x<0) || (x >= width) || (y<0) || (y >= height)) { colour = 0; transparent = true; return; } - int code = lines[y+nColours+1][x]; + int code = pixels[y * width + x]; transparent = code == codeTransparent; if (transparent) { colour = 0; } else { - colour = ColourDesiredFromCode(code).AsLong(); + colour = ColourFromCode(code).AsLong(); } } -const char **XPM::LinesFormFromTextForm(const char *textForm) { +std::vector<const char *> XPM::LinesFormFromTextForm(const char *textForm) { // Build the lines form out of the text form - const char **linesForm = 0; + std::vector<const char *> linesForm; int countQuotes = 0; int strings=1; int j=0; @@ -214,24 +183,19 @@ const char **XPM::LinesFormFromTextForm(const char *textForm) { line0 = NextField(line0); // Add 1 line for each colour strings += atoi(line0); - linesForm = new const char *[strings]; - if (linesForm == 0) { - break; // Memory error! - } } if (countQuotes / 2 >= strings) { break; // Bad height or number of colors! } if ((countQuotes & 1) == 0) { - linesForm[countQuotes / 2] = textForm + j + 1; + linesForm.push_back(textForm + j + 1); } countQuotes++; } } if (textForm[j] == '\0' || countQuotes / 2 > strings) { // Malformed XPM! Height + number of colors too high or too low - delete []linesForm; - linesForm = 0; + linesForm.clear(); } return linesForm; } @@ -1,6 +1,6 @@ // Scintilla source code edit control /** @file XPM.h - ** Define a class that holds data in the X Pixmap (XPM) format. + ** Define a classes to hold image data in the X Pixmap (XPM) and RGBA formats. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. @@ -16,19 +16,14 @@ namespace Scintilla { * Hold a pixmap in XPM format. */ class XPM { - int pid; // Assigned by container int height; int width; int nColours; - char *data; + std::vector<unsigned char> pixels; + ColourDesired colourCodeTable[256]; char codeTransparent; - char *codes; - ColourDesired *colours; - ColourDesired ColourDesiredFromCode(int ch) const; ColourDesired ColourFromCode(int ch) const; void FillRun(Surface *surface, int code, int startX, int y, int x); - char **lines; - ColourDesired *colourCodeTable[256]; public: XPM(const char *textForm); XPM(const char *const *linesForm); @@ -38,17 +33,15 @@ public: void Clear(); /// Decompose image into runs and use FillRectangle for each run void Draw(Surface *surface, PRectangle &rc); - char **InLinesForm() { return lines; } - void SetId(int pid_) { pid = pid_; } - 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); +private: + static std::vector<const char *>LinesFormFromTextForm(const char *textForm); }; /** - * An translucent image stoed as a sequence of RGBA bytes. + * A translucent image stored as a sequence of RGBA bytes. */ class RGBAImage { // Private so RGBAImage objects can not be copied |