aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2013-05-02 17:40:29 +1000
committernyamatongwe <devnull@localhost>2013-05-02 17:40:29 +1000
commit42ef5cfc1cae639a17da2eaea805e71bf851d063 (patch)
tree045d4e93978fe837ea311fcde7cbae9cda45205d /src
parentcb22e6da376c129ce45153b24fbb6a0ff9777a79 (diff)
downloadscintilla-mirror-42ef5cfc1cae639a17da2eaea805e71bf851d063.tar.gz
Simplifying XPM code and avoiding bare allocations.
Diffstat (limited to 'src')
-rw-r--r--src/XPM.cxx96
-rw-r--r--src/XPM.h19
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;
}
diff --git a/src/XPM.h b/src/XPM.h
index 5deeffa48..c19025d1a 100644
--- a/src/XPM.h
+++ b/src/XPM.h
@@ -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