]> git.vomp.tv Git - vompclient.git/blob - surfacevector.cc
Fix segfault in boxstack.cc
[vompclient.git] / surfacevector.cc
1 /*\r
2     Copyright 2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include "surfacevector.h"\r
22 #include "bitmap.h"\r
23 #include <wchar.h>\r
24 #include <stdlib.h>\r
25 \r
26 SurfaceVector::SurfaceVector(OsdVector* vosd)\r
27 {\r
28 \r
29         osd=vosd;\r
30 }\r
31 \r
32 SurfaceVector::~SurfaceVector()\r
33 {\r
34         osd->removeSurface(this);\r
35         list<SVGCommand>::iterator itty=commands.begin();\r
36         while (itty!=commands.end())\r
37         {\r
38                 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff\r
39                 ImageIndex ii=(*itty).getImageIndex();\r
40                 if (ii) osd->removeImageRef(ii);\r
41                 itty++;\r
42         }\r
43 }\r
44 \r
45 \r
46 int SurfaceVector::getFontHeight()\r
47 {\r
48         return osd->getFontHeight();\r
49 }\r
50 \r
51 float SurfaceVector::getCharWidth(wchar_t c)\r
52 {\r
53         return osd->getCharWidth(c);\r
54 }\r
55 \r
56 wchar_t SurfaceVector::getWChar(const char* str, unsigned int *length)\r
57 {\r
58         int mlength=0;\r
59         int max_length=4;\r
60         wchar_t tempo[1];\r
61         size_t num_bytes=1;\r
62         if (str[0]=='\0') {\r
63                 *length=1;\r
64                 return '\0';\r
65         } else if (str[1]=='\0'){\r
66                 max_length=2;\r
67         } else if (str[2]=='\0'){\r
68                 max_length=3;\r
69         }\r
70         mbstate_t state;\r
71         memset((void*)&state,0,sizeof(state));\r
72         num_bytes=mbrtowc(tempo, str, max_length, &state);\r
73         if (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2))\r
74         {\r
75                 *length=num_bytes;\r
76                 return *tempo;\r
77         }\r
78         *length=1;\r
79         return '?';\r
80 }\r
81 \r
82 \r
83 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){\r
84         return drawText(text, x, y, 0, c);\r
85 }\r
86 \r
87 int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)\r
88 {\r
89         float shift=0.;\r
90         const char *run=text;\r
91         mbstate_t state;\r
92         wchar_t tempo[1];\r
93         size_t num_bytes=1;\r
94         size_t length=strlen(text);\r
95         memset((void*)&state,0,sizeof(state));\r
96         command_mutex.Lock();\r
97         num_bytes=mbrtowc(tempo, run, length, &state);\r
98         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)\r
99         {\r
100                 unsigned int ref=osd->getStyleRef(c);\r
101                 commands.push_back(SVGCommand(x+shift,y,*tempo,ref));\r
102                 shift+=osd->getCharWidth(*tempo);\r
103                 length -= num_bytes;\r
104                 run += num_bytes;\r
105                 if (shift>width && width >0) {\r
106                         command_mutex.Unlock();\r
107                         return 1;\r
108                 }\r
109                 num_bytes=mbrtowc(tempo, run, length, &state);\r
110         }\r
111         command_mutex.Unlock();\r
112         return 1;\r
113 \r
114 }\r
115 int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)\r
116 {\r
117         float shift=0.;\r
118         const char *run=text;\r
119         mbstate_t state;\r
120         wchar_t tempo[1];\r
121         size_t num_bytes=1;\r
122         size_t length=strlen(text);\r
123         memset((void*)&state,0,sizeof(state));\r
124 \r
125         num_bytes=mbrtowc(tempo, run, length, &state);\r
126         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)\r
127         {\r
128                 shift+=osd->getCharWidth(*tempo);\r
129                 length -= num_bytes;\r
130                 run += num_bytes;\r
131                 num_bytes=mbrtowc(tempo, run, length, &state);\r
132         }\r
133         return drawText(text, x-shift,  y, c);\r
134 }\r
135 \r
136 int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)\r
137 {\r
138         float shift=0;\r
139         const char *run=text;\r
140         mbstate_t state;\r
141         wchar_t tempo[1];\r
142         size_t num_bytes=1;\r
143         size_t length=strlen(text);\r
144         memset((void*)&state,0,sizeof(state));\r
145 \r
146         num_bytes=mbrtowc(tempo, run, length, &state);\r
147         while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)\r
148         {\r
149                 shift+=osd->getCharWidth(*tempo);\r
150                 length -= num_bytes;\r
151                 run += num_bytes;\r
152                 num_bytes=mbrtowc(tempo, run, length, &state);\r
153         }\r
154         return drawText(text, x-shift/2.,  y, c);\r
155 }\r
156 \r
157 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)\r
158 {\r
159         command_mutex.Lock();\r
160         ImageIndex image=osd->getJpegRef(fileName,width,height);\r
161         commands.push_back(SVGCommand(x,y,*width,*height,image,0));\r
162         command_mutex.Unlock();\r
163 }\r
164 \r
165 int SurfaceVector::create(UINT width, UINT height)\r
166 {\r
167         sheight=height;\r
168         swidth=width;\r
169         return 1;\r
170 }\r
171 void SurfaceVector::display()\r
172 {\r
173         //nothing this is really mvp specific\r
174 }\r
175 \r
176 int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)\r
177 {\r
178         command_mutex.Lock();\r
179         removeCommands(x,y,width,height); // remove commands below the box\r
180         unsigned int ref=osd->getStyleRef(c);\r
181         commands.push_back(SVGCommand(x,y,width,height,Rectangle,ref));\r
182         command_mutex.Unlock();\r
183         return 1;\r
184 \r
185 }\r
186 void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)\r
187 {\r
188         command_mutex.Lock();\r
189         unsigned int ref=osd->getStyleRef(c);\r
190         commands.push_back(SVGCommand(x1,y,x2-x1,1,HorzLine,ref));\r
191         command_mutex.Unlock();\r
192 }\r
193 \r
194 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){\r
195         command_mutex.Lock();\r
196         unsigned int ref=osd->getStyleRef(c);\r
197         commands.push_back(SVGCommand(x,y1,1,y2-y1,VertLine,ref));\r
198         command_mutex.Unlock();\r
199 }\r
200 \r
201 void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)\r
202 {\r
203         //this is complicated\r
204         command_mutex.Lock();\r
205 /*\r
206         unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());\r
207         for (UINT j = 0; j < bm.getHeight(); ++j){\r
208            for (UINT i = 0; i < bm.getWidth(); ++i)\r
209            {\r
210                    data[i+j*bm.getHeight()]=bm.getColour(i,j);\r
211            }\r
212     }*/\r
213         ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),\r
214                         (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD\r
215         //free(data);\r
216         float tx=x+region.windowx;\r
217         float ty=y+region.windowy;\r
218         float th=bm.getHeight();\r
219         float tw=bm.getWidth();\r
220 \r
221         float scalex=720.f/((float) (region.framewidth+1));\r
222         float scaley=576.f/((float) (region.frameheight+1));\r
223         tx*=scalex;\r
224         ty*=scaley;\r
225         tw*=scalex;\r
226         th*=scaley;\r
227         SVGCommand temp=SVGCommand(tx,ty,tw,th,image,0);\r
228         commands.push_back(temp);\r
229         command_mutex.Unlock();\r
230 }\r
231 \r
232 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){\r
233         if (!fastdraw) command_mutex.Lock();\r
234         unsigned int ref=osd->getStyleRef(c);\r
235         commands.push_back(SVGCommand(x,y,1,1,Point,ref));\r
236         if (!fastdraw)  command_mutex.Unlock();\r
237 }\r
238 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, Colour& nextColour)\r
239 {\r
240         command_mutex.Lock();\r
241         ImageIndex image=osd->getMonoBitmapRef(base,width,height);\r
242         unsigned int ref=osd->getColorRef(nextColour);\r
243         commands.push_back(SVGCommand(dx,dy,height,width,image,ref));\r
244         command_mutex.Unlock();\r
245 }\r
246 \r
247 \r
248 int SurfaceVector::removeCommands(float x,float y,float width,float height)\r
249 {\r
250         // we iterate through all old commands in order to remove commands hidden by this rectangle\r
251         list<SVGCommand>::iterator itty=commands.begin();\r
252         while (itty!=commands.end())\r
253         {\r
254                 if ((*itty).Test(x,y,width,height) ) {\r
255                         osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff\r
256                         ImageIndex ii=(*itty).getImageIndex();\r
257                         if (ii) osd->removeImageRef(ii);\r
258                         itty=commands.erase(itty);\r
259                 } else {\r
260                         itty++;\r
261                 }\r
262         }\r
263         return 1;\r
264 \r
265 }\r
266 \r
267 int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)\r
268 {\r
269         // ok this method really works in a pixel oriented way\r
270         command_mutex.Lock();\r
271         osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands);\r
272         command_mutex.Unlock();\r
273         return 1;\r
274 }\r
275 \r
276 \r
277 /* This is for systems which need a locking of the drawing surface to speed up drawing */\r
278 void SurfaceVector::startFastDraw() {\r
279         command_mutex.Lock();\r
280 }\r
281 void SurfaceVector::endFastDraw() {\r
282         command_mutex.Unlock();\r
283 }\r
284 \r
285 \r
286 void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)\r
287 {\r
288         command_mutex.Lock();\r
289         list<SVGCommand>::iterator itty=commands.begin();\r
290         while (itty!=commands.end())\r
291         {\r
292                 if ((*itty).TTTest(ox,oy,x,y) ) {\r
293                         itty=commands.erase(itty);\r
294                         break;\r
295                 } else {\r
296                         itty++;\r
297                 }\r
298         }\r
299         commands.push_back(SVGCommand(ox,oy,x,y,c.getInternal()));\r
300         command_mutex.Unlock();\r
301 }\r