]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/XPM.cxx
   1 // Scintilla source code edit control 
   3  ** Define a class that holds data in the X Pixmap (XPM) format, 
   5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> 
   6 // The License.txt file describes the conditions under which this software may be distributed. 
  15 static const char *NextField(const char *s
) { 
  16         while (*s 
&& *s 
!= ' ') { 
  19         while (*s 
&& *s 
== ' ') { 
  25 // Data lines in XPM can be terminated either with NUL or " 
  26 static size_t MeasureLength(const char *s
) { 
  28         while (s
[i
] && (s
[i
] != '\"')) 
  33 ColourAllocated 
XPM::ColourFromCode(int ch
) { 
  34         return colourCodeTable
[ch
]->allocated
; 
  36         for (int i
=0;i
<nColours
;i
++) { 
  38                         return colours
[i
].allocated
; 
  41         return colours
[0].allocated
; 
  45 void XPM::FillRun(Surface 
*surface
, int code
, int startX
, int y
, int x
) { 
  46         if ((code 
!= codeTransparent
) && (startX 
!= x
)) { 
  47                 PRectangle 
rc(startX
, y
, x
, y
+1); 
  48                 surface
->FillRectangle(rc
, ColourFromCode(code
)); 
  52 XPM::XPM(const char *textForm
) :  
  53         data(0),        codes(0), colours(0), lines(0) { 
  57 XPM::XPM(const char * const *linesForm
) : 
  58         data(0),        codes(0), colours(0), lines(0) { 
  66 void XPM::Init(const char *textForm
) { 
  68         // Test done is two parts to avoid possibility of overstepping the memory 
  69         // if memcmp implemented strangely. Must be 4 bytes at least at destination. 
  70         if ((0 == memcmp(textForm
, "/* X", 4)) && (0 == memcmp(textForm
, "/* XPM */", 9))) { 
  71                 // Build the lines form out of the text form 
  72                 const char **linesForm 
= LinesFormFromTextForm(textForm
); 
  76                 // It is really in line form 
  77                 Init(reinterpret_cast<const char * const *>(textForm
)); 
  81 void XPM::Init(const char * const *linesForm
) { 
  87         codeTransparent 
= ' '; 
  94         const char *line0 
= linesForm
[0]; 
  96         line0 
= NextField(line0
); 
  98         line0 
= NextField(line0
); 
  99         nColours 
= atoi(line0
); 
 100         codes 
= new char[nColours
]; 
 101         colours 
= new ColourPair
[nColours
]; 
 103         int strings 
= 1+height
+nColours
; 
 104         lines 
= new char *[strings
]; 
 105         size_t allocation 
= 0; 
 106         for (int i
=0; i
<strings
; i
++) { 
 107                 allocation 
+= MeasureLength(linesForm
[i
]) + 1; 
 109         data 
= new char[allocation
]; 
 110         char *nextBit 
= data
; 
 111         for (int j
=0; j
<strings
; j
++) { 
 113                 size_t len 
= MeasureLength(linesForm
[j
]); 
 114                 memcpy(nextBit
, linesForm
[j
], len
); 
 119         for (int code
=0;code
<256; code
++) { 
 120                 colourCodeTable
[code
] = 0; 
 123         for (int c
=0; c
<nColours
; c
++) { 
 124                 const char *colourDef 
= linesForm
[c
+1]; 
 125                 codes
[c
] = colourDef
[0]; 
 127                 if (*colourDef 
== '#') { 
 128                         colours
[c
].desired
.Set(colourDef
); 
 130                         colours
[c
].desired 
= ColourDesired(0xff, 0xff, 0xff); 
 131                         codeTransparent 
= codes
[c
]; 
 133                 colourCodeTable
[static_cast<unsigned char>(codes
[c
])] = &(colours
[c
]); 
 148 void XPM::RefreshColourPalette(Palette 
&pal
, bool want
) { 
 149         if (!data 
|| !codes 
|| !colours 
|| !lines
) { 
 152         for (int i
=0;i
<nColours
;i
++) { 
 153                 pal
.WantFind(colours
[i
], want
); 
 157 void XPM::CopyDesiredColours() { 
 158         if (!data 
|| !codes 
|| !colours 
|| !lines
) { 
 161         for (int i
=0;i
<nColours
;i
++) { 
 166 void XPM::Draw(Surface 
*surface
, PRectangle 
&rc
) { 
 167         if (!data 
|| !codes 
|| !colours 
|| !lines
) { 
 171         int startY 
= rc
.top 
+ (rc
.Height() - height
) / 2; 
 172         int startX 
= rc
.left 
+ (rc
.Width() - width
) / 2; 
 173         for (int y
=0;y
<height
;y
++) { 
 176                 for (int x
=0; x
<width
; x
++) { 
 177                         int code 
= lines
[y
+nColours
+1][x
]; 
 178                         if (code 
!= prevCode
) { 
 179                                 FillRun(surface
, prevCode
, startX 
+ xStartRun
, startY 
+ y
, startX 
+ x
); 
 184                 FillRun(surface
, prevCode
, startX 
+ xStartRun
, startY 
+ y
, startX 
+ width
); 
 188 const char **XPM::LinesFormFromTextForm(const char *textForm
) { 
 189         // Build the lines form out of the text form 
 190         const char **linesForm 
= 0; 
 193         for (int j
=0; countQuotes 
< (2*strings
); j
++) { 
 194                 if (textForm
[j
] == '\"') { 
 195                         if (countQuotes 
== 0) { 
 196                                 const char *line0 
= textForm 
+ j 
+ 1; 
 198                                 line0 
= NextField(line0
); 
 199                                 // Add 1 line for each pixel of height 
 200                                 strings 
+= atoi(line0
); 
 201                                 line0 
= NextField(line0
); 
 202                                 // Add 1 line for each colour 
 203                                 strings 
+= atoi(line0
); 
 204                                 linesForm 
= new const char *[strings
]; 
 206                         if (linesForm 
&& ((countQuotes 
& 1) == 0)) { 
 207                                 linesForm
[countQuotes 
/ 2] = textForm 
+ j 
+ 1; 
 215 // In future, may want to minimize search time by sorting and using a binary search. 
 217 XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) { 
 224 void XPMSet::Clear() { 
 225         for (int i
=0;i
<maximum
;i
++) { 
 236 void XPMSet::Add(int id
, const char *textForm
) { 
 237         // Invalidate cached dimensions 
 241         // Replace if this id already present 
 242         for (int i
=0;i
<maximum
;i
++) { 
 243                 if (set
[i
]->GetId() == id
) { 
 244                         set
[i
]->Init(textForm
); 
 249         // No present, so add to end 
 250         XPM 
*pxpm 
= new XPM(textForm
); 
 253                 pxpm
->CopyDesiredColours(); 
 254                 if (len 
== maximum
) { 
 255                         int lenNew 
= len 
+ 100; 
 256                         XPM 
**setNew 
= new XPM 
*[lenNew
]; 
 257                         for (int i
=0; i
<maximum
; i
++) { 
 268 XPM 
*XPMSet::Get(int id
) { 
 269         for (int i
=0;i
<maximum
;i
++) { 
 270                 if (set
[i
]->GetId() == id
) { 
 277 int XPMSet::GetHeight() { 
 279                 for (int i
=0; i
<maximum
; i
++) { 
 280                         if (height 
< set
[i
]->GetHeight()) { 
 281                                 height 
= set
[i
]->GetHeight(); 
 285         return (height 
> 0) ? height 
: 0; 
 288 int XPMSet::GetWidth() { 
 290                 for (int i
=0; i
<maximum
; i
++) { 
 291                         if (width 
< set
[i
]->GetWidth()) { 
 292                                 width 
= set
[i
]->GetWidth(); 
 296         return (width 
> 0) ? width 
: 0;