From 664e37abfe5c796c1279b8295fb030f126b0a7d8 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 30 Nov 2011 11:36:13 -0600 Subject: Initial import of qscintilla from 2007 --- src/XPM.cpp | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 src/XPM.cpp (limited to 'src/XPM.cpp') diff --git a/src/XPM.cpp b/src/XPM.cpp new file mode 100644 index 0000000..b8e27f4 --- /dev/null +++ b/src/XPM.cpp @@ -0,0 +1,348 @@ +// 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" + +#if defined(PLAT_QT) + +XPM::XPM(const char *textForm) +{ + qpm = *reinterpret_cast(textForm); +} + +XPM::XPM(const char * const *linesForm) +{ + qpm = *reinterpret_cast(linesForm); +} + +void XPM::RefreshColourPalette(Palette &pal, bool want) +{ + // Nothing to do. +} + +void XPM::Draw(Surface *surface, PRectangle &rc) +{ + surface -> DrawXPM(rc,this); +} + +#else + +static const char *NextField(const char *s) { + // In case there are leading spaces in the string + while (*s && *s == ' ') { + 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); + if (linesForm != 0) { + 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); + line0 = NextField(line0); + if (atoi(line0) != 1) { + // Only one char per pixel is supported + return; + } + codes = new char[nColours]; + colours = new ColourPair[nColours]; + + int strings = 1+height+nColours; + lines = new char *[strings]; + size_t 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; i= strings) { + break; // Bad height or number of colors! + } + if ((countQuotes & 1) == 0) { + linesForm[countQuotes / 2] = 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; + } + 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 id, 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() == id) { + set[i]->Init(textForm); + set[i]->CopyDesiredColours(); + return; + } + } + + // Not present, so add to end + XPM *pxpm = new XPM(textForm); + if (pxpm) { + pxpm->SetId(id); + pxpm->CopyDesiredColours(); + 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 id) { + for (int i = 0; i < len; i++) { + if (set[i]->GetId() == id) { + 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; +} + +#endif -- cgit v1.2.3