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