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