diff options
| author | nyamatongwe <devnull@localhost> | 2013-05-02 17:40:29 +1000 | 
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2013-05-02 17:40:29 +1000 | 
| commit | 42ef5cfc1cae639a17da2eaea805e71bf851d063 (patch) | |
| tree | 045d4e93978fe837ea311fcde7cbae9cda45205d /src | |
| parent | cb22e6da376c129ce45153b24fbb6a0ff9777a79 (diff) | |
| download | scintilla-mirror-42ef5cfc1cae639a17da2eaea805e71bf851d063.tar.gz | |
Simplifying XPM code and avoiding bare allocations.
Diffstat (limited to 'src')
| -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 | 
