]> git.vomp.tv Git - vompclient.git/blob - surfacevector.cc
Reverting changes in mutex
[vompclient.git] / surfacevector.cc
1 /*
2     Copyright 2012 Marten Richter
3
4     This file is part of VOMP.
5
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.
10
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.
15
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.
19 */
20
21 #include "surfacevector.h"
22 #include "bitmap.h"
23 #include "staticartwork.h"
24 #include <wchar.h>
25 #include <stdlib.h>
26 #include <math.h>
27
28 SurfaceVector::SurfaceVector(OsdVector* vosd)
29 {
30
31         osd=vosd;
32         commands.reserve(2048);
33 }
34
35 SurfaceVector::~SurfaceVector()
36 {
37         osd->removeSurface(this);
38         vector<SVGCommand>::iterator itty=commands.begin();
39         while (itty!=commands.end())
40         {
41                 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
42                 ImageIndex ii=(*itty).getImageIndex();
43                 if (ii) {
44                         osd->removeImageRef(ii);
45                 }
46                 LoadIndex li=(*itty).getLoadIndex();
47                 if (li) osd->removeLoadIndexRef(li);
48                 itty++;
49         }
50 }
51
52
53 int SurfaceVector::getFontHeight()
54 {
55         return osd->getFontHeight();
56 }
57
58 float SurfaceVector::getCharWidth(wchar_t c)
59 {
60         return osd->getCharWidth(c);
61 }
62
63
64 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){
65         return drawText(text, x, y, 0, c);
66 }
67
68 int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
69 {
70         float shift=0.;
71         const char *run=text;
72         mbstate_t state;
73         wchar_t tempo;
74         size_t num_bytes=1;
75         size_t length=strlen(text);
76         memset((void*)&state,0,sizeof(state));
77
78         command_mutex.Lock();
79         num_bytes=mbrtowc(&tempo, run, length, &state);
80         unsigned int ref=osd->getStyleRef(c);
81         float *charwidtharray=osd->getCharWidthArray();
82
83         int commands_size=commands.size();
84         int chars=0;
85         commands.resize(commands_size+strlen(text));
86
87         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
88         {
89                 SVGCommand::PaintGlyph(commands[commands_size+chars],x+shift,y,tempo,ref);
90                 chars++;
91
92                 float cur_shift=charwidtharray[tempo & 0xFF];
93                 if (tempo && 0xFFFFFF00) cur_shift=osd->getCharWidth(tempo);
94                 shift+=cur_shift;
95                 length -= num_bytes;
96                 run += num_bytes;
97                 if (shift>width && width >0) {
98                         command_mutex.Unlock();
99                         return 1;
100                 }
101                 num_bytes=mbrtowc(&tempo, run, length, &state);
102         }
103         commands.resize(commands_size+chars);
104         command_mutex.Unlock();
105         return 1;
106
107 }
108 int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
109 {
110         float shift=0.;
111         const char *run=text;
112         mbstate_t state;
113         wchar_t tempo[1];
114         size_t num_bytes=1;
115         size_t length=strlen(text);
116         memset((void*)&state,0,sizeof(state));
117
118         num_bytes=mbrtowc(tempo, run, length, &state);
119         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
120         {
121                 shift+=osd->getCharWidth(*tempo);
122                 length -= num_bytes;
123                 run += num_bytes;
124                 num_bytes=mbrtowc(tempo, run, length, &state);
125         }
126         return drawText(text, x-shift,  y, c);
127 }
128
129 int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
130 {
131         float shift=0;
132         const char *run=text;
133         mbstate_t state;
134         wchar_t tempo[1];
135         size_t num_bytes=1;
136         size_t length=strlen(text);
137         memset((void*)&state,0,sizeof(state));
138
139         num_bytes=mbrtowc(tempo, run, length, &state);
140         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
141         {
142                 shift+=osd->getCharWidth(*tempo);
143                 length -= num_bytes;
144                 run += num_bytes;
145                 num_bytes=mbrtowc(tempo, run, length, &state);
146         }
147         return drawText(text, x-shift/2.,  y, c);
148 }
149
150 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
151 {
152         StaticArtwork index=sa_MAX; // This is for compatibility only
153         if (strcmp(fileName,"/vdr.jpg")==0) {
154                 index=sa_vdrlogo;
155                 *height=100; // this is faked so that the system does use the old coordinate system
156                 *width=ceil(190.f*osd->getPixelAspect());
157         } else if (strcmp(fileName,"/wallpaperPAL.jpg")==0) {
158                 index=sa_wallpaper;
159                 *width=720; // this is faked so that the system does use the old coordinate system
160                 *height=576;
161         }
162         if (index!=sa_MAX) {
163                 TVMediaInfo info;
164                 info.setStaticArtwork(index);
165                 drawTVMedia(info,x,y,*width,*height,TopLeft);
166         }
167 }
168
169 /*
170 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
171 {
172         command_mutex.Lock();
173         ImageIndex image=osd->getJpegRef(fileName,width,height);
174         commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
175         command_mutex.Unlock();
176 }
177 */
178
179 void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  width, float height, Corner corner)
180 {
181         command_mutex.Lock();
182         ImageIndex image=0;
183         LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
184         if (width!=0 && height!=0) {
185                 removeCommands(x,y,width,height);
186         }
187         if (image) {
188                 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
189                 commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
190         } else {
191
192                 commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
193                 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
194         }
195         command_mutex.Unlock();
196 }
197
198 void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
199 {
200         command_mutex.Lock();
201         commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
202         command_mutex.Unlock();
203 }
204
205 int SurfaceVector::create(UINT width, UINT height)
206 {
207         sheight=height;
208         swidth=width;
209         return 1;
210 }
211 void SurfaceVector::display()
212 {
213         //nothing this is really mvp specific
214 }
215
216 int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)
217 {
218         command_mutex.Lock();
219         removeCommands(x,y,width,height); // remove commands below the box
220         unsigned int ref=osd->getStyleRef(c);
221         commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref));
222         command_mutex.Unlock();
223         return 1;
224
225 }
226 void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
227 {
228         command_mutex.Lock();
229         unsigned int ref=osd->getStyleRef(c);
230         commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref));
231         command_mutex.Unlock();
232 }
233
234 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
235         command_mutex.Lock();
236         unsigned int ref=osd->getStyleRef(c);
237         commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref));
238         command_mutex.Unlock();
239 }
240
241 void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)
242 {
243         //this is complicated
244         command_mutex.Lock();
245 /*
246         unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
247         for (UINT j = 0; j < bm.getHeight(); ++j){
248            for (UINT i = 0; i < bm.getWidth(); ++i)
249            {
250                    data[i+j*bm.getHeight()]=bm.getColour(i,j);
251            }
252     }*/
253         ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),
254                         (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
255         //free(data);
256         float tx=x+region.windowx;
257         float ty=y+region.windowy;
258         float th=bm.getHeight();
259         float tw=bm.getWidth();
260
261         float scalex=720.f/((float) (region.framewidth+1));
262         float scaley=576.f/((float) (region.frameheight+1));
263         tx*=scalex;
264         ty*=scaley;
265         tw*=scalex;
266         th*=scaley;
267         SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
268         removeCommands(tx,ty,tw,th);
269         commands.push_back(temp);
270         command_mutex.Unlock();
271 }
272
273 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
274         if (!fastdraw) command_mutex.Lock();
275         unsigned int ref=osd->getStyleRef(c);
276         commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref));
277         if (!fastdraw)  command_mutex.Unlock();
278 }
279 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
280 {
281         command_mutex.Lock();
282         ImageIndex image=osd->getMonoBitmapRef(base,width,height);
283         unsigned int ref=osd->getStyleRef(nextColour);
284         removeCommands(dx,dy,width,height);
285         commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
286         command_mutex.Unlock();
287 }
288
289
290 int SurfaceVector::removeCommands(float x,float y,float width,float height)
291 {
292         // we iterate through all old commands in order to remove commands hidden by this rectangle
293         vector<SVGCommand>::iterator itty=commands.begin();
294         vector<SVGCommand>::iterator remstart;
295         bool remove=false;
296         while (itty!=commands.end())
297         {
298                 if ((*itty).Test(x,y,width,height)  && (*itty).instr != DrawClipping) {
299                         //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
300                         //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
301                         osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
302                         ImageIndex ii=(*itty).getImageIndex();
303                         if (ii) osd->removeImageRef(ii);
304                         LoadIndex li=(*itty).getLoadIndex();
305                         if (li) osd->removeLoadIndexRef(li);
306                         if (!remove)  {
307                                 remstart=itty;
308                                 remove=true;
309                         }
310                 } else {
311                         if (remove) {
312                                 itty=commands.erase(remstart,itty);
313                                 remove=false;
314                         }
315                 }
316                 itty++;
317         }
318         if (remove) {
319                 itty=commands.erase(remstart,itty);
320         }
321         return 1;
322
323 }
324
325 int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)
326 {
327         // ok this method really works in a pixel oriented way
328         command_mutex.Lock();
329         osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands);
330         command_mutex.Unlock();
331         return 1;
332 }
333
334
335 /* This is for systems which need a locking of the drawing surface to speed up drawing */
336 void SurfaceVector::startFastDraw() {
337         command_mutex.Lock();
338 }
339 void SurfaceVector::endFastDraw() {
340         command_mutex.Unlock();
341 }
342
343
344 void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
345 {
346         command_mutex.Lock();
347         vector<SVGCommand>::iterator itty=commands.begin();
348         while (itty!=commands.end())
349         {
350                 if ((*itty).TTTest(ox,oy,x,y) ) {
351                         itty=commands.erase(itty);
352                         break;
353                 } else {
354                         itty++;
355                 }
356         }
357         commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
358         command_mutex.Unlock();
359 }