// Scintilla source code edit control /** @file XPM.cxx ** Define a class that holds data in the X Pixmap (XPM) format, **/ // Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include #include #include "Platform.h" #include "XPM.h" static const char *NextField(const char *s) { while (*s && *s != ' ') { s++; } while (*s && *s == ' ') { s++; } return s; } // Data lines in XPM can be terminated either with NUL or " static size_t MeasureLength(const char *s) { size_t i = 0; while (s[i] && (s[i] != '\"')) i++; return i; } ColourAllocated XPM::ColourFromCode(int ch) { return colourCodeTable[ch]->allocated; #ifdef SLOW for (int i=0;iFillRectangle(rc, ColourFromCode(code)); } } XPM::XPM(const char *textForm) : data(0), codes(0), colours(0), lines(0) { Init(textForm); } XPM::XPM(const char * const *linesForm) : data(0), codes(0), colours(0), lines(0) { Init(linesForm); } XPM::~XPM() { Clear(); } void XPM::Init(const char *textForm) { Clear(); // Test done is two parts to avoid possibility of overstepping the memory // 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); Init(linesForm); delete []linesForm; } else { // It is really in line form Init(reinterpret_cast(textForm)); } } void XPM::Init(const char * const *linesForm) { Clear(); height = 1; width = 1; nColours = 1; data = NULL; codeTransparent = ' '; codes = NULL; colours = NULL; lines = NULL; if (!linesForm) return; const char *line0 = linesForm[0]; width = atoi(line0); line0 = NextField(line0); height = atoi(line0); line0 = NextField(line0); nColours = atoi(line0); codes = new char[nColours]; colours = new ColourPair[nColours]; int strings = 1+height+nColours; lines = new char *[strings]; int allocation = 0; for (int i=0; i(codes[c])] = &(colours[c]); } } void XPM::Clear() { delete []data; data = 0; delete []codes; codes = 0; delete []colours; colours = 0; delete []lines; lines = 0; } void XPM::RefreshColourPalette(Palette &pal, bool want) { if (!data || !codes || !colours || !lines) { return; } for (int i=0;iGetId() == id) { set[i]->Init(textForm); return; } } // No present, so add to end XPM *pxpm = new XPM(textForm); if (pxpm) { pxpm->SetId(id); pxpm->CopyDesiredColours(); if (len == maximum) { int lenNew = len + 100; XPM **setNew = new XPM *[lenNew]; for (int i=0; iGetId() == id) { return set[i]; } } return 0; } int XPMSet::GetHeight() { if (height < 0) { for (int i=0; iGetHeight()) { height = set[i]->GetHeight(); } } } return (height > 0) ? height : 0; } int XPMSet::GetWidth() { if (width < 0) { for (int i=0; iGetWidth()) { width = set[i]->GetWidth(); } } } return (width > 0) ? width : 0; }