2 Copyright 2012 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "osdvector.h"
22 #include "surfacevector.h"
24 OsdVector::OsdVector()
26 setlocale(LC_CTYPE,"C.UTF-8");
29 OsdVector::~OsdVector()
35 int OsdVector::getFD()
40 void OsdVector::screenShot(const char* fileName)
45 Surface * OsdVector::createNewSurface()
47 return new SurfaceVector(this);
50 void OsdVector::BeginPainting()
52 surfaces_mutex.Lock();
54 void OsdVector::EndPainting()
56 surfaces_mutex.Unlock();
59 void OsdVector::Blank()
61 // do nothing? remove this one?
64 int OsdVector::restore()
66 // First clear the contents of all registered surfaces
67 surfaces_mutex.Lock();
69 //Now go through all surfaces and draw them
70 list<SurfaceCommands>::iterator curdraw=scommands.begin();
71 while (curdraw!=scommands.end()) {
72 (*curdraw).commands.clear();
75 //also clear all handles, they are now invalid, no need to release them
82 surfaces_mutex.Unlock();
86 void OsdVector::drawSurfaces()
88 surfaces_mutex.Lock();
89 list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
90 list<SurfaceCommands>::iterator itty1=scommands.begin();
91 while (itty1!=scommands.end()) {
92 list<SurfaceCommands>::iterator itty2=itty1;
95 while (itty2!=scommands.end()) {
96 SurfaceCommands & ref1=*itty1;
97 SurfaceCommands & ref2=*itty2;
98 if (ref1.x>=ref2.x && ref1.y>=ref2.y
99 && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
100 && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
106 if (!hidden) { // we are not hidden, perfect
107 todraw.push_back(&(*itty1));
111 //Now go through all surfaces and draw them
112 list<SurfaceCommands*>::iterator curdraw=todraw.begin();
113 while (curdraw!=todraw.end()) {
114 drawSetTrans(*(*curdraw));
115 list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
116 list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
117 while (commands!=end) {
118 executeDrawCommand(*commands);
124 surfaces_mutex.Unlock();
128 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
129 list<SVGCommand>& commands)
131 surfaces_mutex.Lock();
132 //First determine it is already in our system
133 list<SurfaceCommands>::iterator itty=scommands.begin();
134 while (itty!=scommands.end()) {
135 if ((*itty).surf==surf) {
136 //decrease the references
137 dereferenceSVGCommand((*itty).commands);
143 if (itty==scommands.end()) {
144 SurfaceCommands new_sc;
150 itty=scommands.insert(itty,new_sc);
152 // then clear and copy
153 (*itty).commands.clear();
154 (*itty).commands=commands;
155 //increase the references
156 list<SVGCommand>::iterator sitty=(*itty).commands.begin();
157 while (sitty!=(*itty).commands.end())
159 incStyleRef((*sitty).getRef());
160 ImageIndex ii=(*sitty).getImageIndex();
161 if (ii) incImageRef(ii);
164 cleanupOrphanedRefs();
166 surfaces_mutex.Unlock();
169 void OsdVector::removeSurface(const SurfaceVector *surf)
171 surfaces_mutex.Lock();
172 //First determine it is already in our system
173 list<SurfaceCommands>::iterator itty=scommands.begin();
174 while (itty!=scommands.end()) {
175 if ((*itty).surf==surf) {
176 dereferenceSVGCommand((*itty).commands);
177 (*itty).commands.clear();
178 scommands.erase(itty);
183 surfaces_mutex.Unlock();
187 void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
190 list<SVGCommand>::iterator sitty = commands.begin();
191 while (sitty != commands.end()) {
192 removeStyleRef((*sitty).getRef());
193 ImageIndex ii = (*sitty).getImageIndex();
194 if (ii) removeImageRef(ii);
199 void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )
201 list<SVGCommand>::iterator sitty=commands.begin();
202 while (sitty!=commands.end())
204 incStyleRef((*sitty).getRef());
205 ImageIndex ii=(*sitty).getImageIndex();
206 if (ii) incImageRef(ii);
211 void OsdVector::incImageRef(ImageIndex index)
213 if (images_ref.find(index)==images_ref.end()) {
220 void OsdVector::removeImageRef(const ImageIndex ref)
225 void OsdVector::cleanupOrphanedRefs()
226 { // Do some garbage collection
228 map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
229 while (mitty!=monobitmaps.end()) {
230 map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*mitty).second);
231 int count=(*curitty).second;
233 ImageIndex ref=(*curitty).first;
234 monobitmaps.erase(mitty++);
235 images_ref.erase(curitty++);
236 destroyImageRef(ref);
240 map<string,ImageIndex>::iterator jitty=jpegs.begin();
241 while (jitty!=jpegs.end()) {
242 map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*jitty).second);
243 int count=(*curitty).second;
245 ImageIndex ref=(*curitty).first;
246 jpegs.erase(jitty++);
247 images_ref.erase(curitty++);
248 destroyImageRef(ref);
253 map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
254 while (sitty!=styles.end()) {
255 map<unsigned int,unsigned int>::iterator curitty=styles_ref.find((*sitty).second);
256 int count=(*curitty).second;
258 unsigned int ref=(*curitty).first;
259 styles.erase(sitty++);
260 styles_ref.erase(curitty++);
261 destroyStyleRef(ref);
269 unsigned int OsdVector::getImageRef(ImageIndex index)
271 if (images_ref.find(index)==images_ref.end()) {
274 return images_ref[index];
278 void OsdVector::incStyleRef(unsigned int index)
280 if (styles_ref.find(index)==styles_ref.end()) {
287 void OsdVector::removeStyleRef(unsigned int index)
292 unsigned int OsdVector::getStyleRef(const DrawStyle &c)
294 unsigned int style_handle=0;
295 if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
297 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
299 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
300 //Now check if the handle is valid
301 if (styles_ref.find(style_handle)==styles_ref.end()) {
302 //invalid handle recreate
303 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
306 incStyleRef(style_handle);
310 unsigned int OsdVector::getColorRef(const Colour &c)
312 unsigned int style_handle=0;
313 if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
315 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
317 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
318 if (styles_ref.find(style_handle)==styles_ref.end()) {
319 //invalid handle recreate
320 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
323 incStyleRef(style_handle);
327 unsigned int OsdVector::getStyleRef(unsigned int index)
329 if (styles_ref.find(index)==styles_ref.end()) {
332 return styles_ref[index];
336 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
338 ImageIndex image_handle=0;
339 if (jpegs.find(fileName)==jpegs.end())
341 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
343 image_handle=jpegs[fileName];
346 if (images_ref.find(image_handle)==images_ref.end()) {
347 //invalid handle recreate
348 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
351 incImageRef(image_handle);
355 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
357 ImageIndex image_handle;
358 if (monobitmaps.find(base)==monobitmaps.end())
360 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
362 image_handle=monobitmaps[base];
363 if (images_ref.find(image_handle)==images_ref.end()) {
364 //invalid handle recreate
365 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
368 incImageRef(image_handle);
372 ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
374 ImageIndex image_handle;
375 image_handle=createImagePalette(width,height,image_data,palette_data);
376 incImageRef(image_handle);