diff options
Diffstat (limited to 'scintilla/src/XPM.cxx')
-rw-r--r-- | scintilla/src/XPM.cxx | 179 |
1 files changed, 30 insertions, 149 deletions
diff --git a/scintilla/src/XPM.cxx b/scintilla/src/XPM.cxx index 02b2f32..59fa2c2 100644 --- a/scintilla/src/XPM.cxx +++ b/scintilla/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,111 +183,23 @@ 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;
}
-// In future, may want to minimize search time by sorting and using a binary search.
-
-XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
-}
-
-XPMSet::~XPMSet() {
- Clear();
-}
-
-void XPMSet::Clear() {
- for (int i = 0; i < len; i++) {
- delete set[i];
- }
- delete []set;
- set = 0;
- len = 0;
- maximum = 0;
- height = -1;
- width = -1;
-}
-
-void XPMSet::Add(int ident, const char *textForm) {
- // Invalidate cached dimensions
- height = -1;
- width = -1;
-
- // Replace if this id already present
- for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == ident) {
- set[i]->Init(textForm);
- return;
- }
- }
-
- // Not present, so add to end
- XPM *pxpm = new XPM(textForm);
- if (pxpm) {
- pxpm->SetId(ident);
- if (len == maximum) {
- maximum += 64;
- XPM **setNew = new XPM *[maximum];
- for (int i = 0; i < len; i++) {
- setNew[i] = set[i];
- }
- delete []set;
- set = setNew;
- }
- set[len] = pxpm;
- len++;
- }
-}
-
-XPM *XPMSet::Get(int ident) {
- for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == ident) {
- return set[i];
- }
- }
- return 0;
-}
-
-int XPMSet::GetHeight() {
- if (height < 0) {
- for (int i = 0; i < len; i++) {
- if (height < set[i]->GetHeight()) {
- height = set[i]->GetHeight();
- }
- }
- }
- return (height > 0) ? height : 0;
-}
-
-int XPMSet::GetWidth() {
- if (width < 0) {
- for (int i = 0; i < len; i++) {
- if (width < set[i]->GetWidth()) {
- width = set[i]->GetWidth();
- }
- }
- }
- return (width > 0) ? width : 0;
-}
-
RGBAImage::RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_) :
height(height_), width(width_), scale(scale_) {
if (pixels_) {
|