Fix debugscript, some quadtree stuff and don't intersect vertical/horz lines when...
[ipdf/code.git] / src / debugscript.cpp
1 #include "debugscript.h"
2
3 #include <string>
4
5 using namespace IPDF;
6 using namespace std;
7
8 void DebugScript::ParseAction(View * view, Screen * scr)
9 {
10         *m_input >> std::ws;
11         if (m_input == NULL || !m_input->good())
12                 return;
13         istream & inp = *m_input;
14         Debug("Get action type...");
15         std::string actionType;
16         inp >> actionType;
17         Debug("Action type: %s", actionType.c_str());
18         // Skip comments
19         while (actionType[0] == '#')
20         {
21                 std::string tmp;
22                 std::getline(inp, tmp);
23                 inp >> std::ws >> actionType;
24         }
25         if (actionType == "loop")
26         {
27                 inp >> currentAction.loops >> actionType;
28         }
29         else
30         {
31                 currentAction.loops = 1;
32         }
33
34         if (actionType == "wait")
35         {
36                 currentAction.type = AT_WaitFrame;
37                 return;
38         }
39         else if (actionType == "translate")
40         {
41                 std::string _x, _y;
42                 inp >> _x >> _y;
43                 currentAction.type = AT_Translate;
44                 currentAction.x = RealFromStr(_x.c_str());
45                 currentAction.y = RealFromStr(_y.c_str());
46                 return;
47         }
48         else if (actionType == "zoom")
49         {
50                 std::string _x, _y, _z;
51                 inp >> _x >> _y >> _z;
52                 currentAction.type = AT_Zoom;
53                 currentAction.x = RealFromStr(_x.c_str());
54                 currentAction.y = RealFromStr(_y.c_str());
55                 currentAction.z = RealFromStr(_z.c_str());
56         }
57         else if (actionType == "pxtranslate")
58         {
59                 inp >> currentAction.ix >> currentAction.iy;
60                 currentAction.type = AT_TranslatePx;
61         }
62         else if (actionType == "pxzoom")
63         {
64                 inp >> currentAction.ix >> currentAction.iy >> currentAction.iz;
65                 currentAction.type = AT_ZoomPx;
66         }
67         else if (actionType == "gpu")
68         {
69                 currentAction.type = AT_SetGPURendering;
70         }
71         else if (actionType == "cpu")
72         {
73                 currentAction.type = AT_SetCPURendering;
74         }
75         else if (actionType == "lazy")
76         {
77                 currentAction.type = AT_EnableLazyRendering;
78         }
79         else if (actionType == "nolazy")
80         {
81                 currentAction.type = AT_DisableLazyRendering;
82         }
83         else if (actionType == "quit")
84         {
85                 currentAction.type = AT_Quit;
86         }
87         else if (actionType == "loadsvg")
88         {
89                 currentAction.type = AT_LoadSVG;
90                 inp >> currentAction.textargs;
91         }
92         else if (actionType == "label")
93         {
94                 currentAction.type = AT_Label;
95                 inp >> currentAction.textargs;
96         }
97         else if (actionType == "goto")
98         {
99                 currentAction.type = AT_Goto;
100                 inp >> currentAction.textargs;
101         }
102         else if (actionType == "debug")
103         {
104                 currentAction.type = AT_Debug;
105                 getline(inp,currentAction.textargs);
106         }
107         else if (actionType == "clear")
108         {
109                 currentAction.type = AT_ClearDocument;
110         }
111         else if (actionType == "clearperf")
112         {
113                 currentAction.type = AT_ClearPerformance;
114         }
115         else if (actionType == "printperf")
116         {
117                 currentAction.type = AT_PrintPerformance;
118         }
119         else if (actionType == "recordperf")
120         {
121                 currentAction.type = AT_RecordPerformance;
122         }
123         else if (actionType == "debugfont")
124         {
125                 currentAction.type = AT_DebugFont;
126                 inp >> currentAction.textargs;
127         }
128         else if (actionType == "approachz") // approach zenoistically
129         {
130                 currentAction.type = AT_ApproachBoundsZeno;
131                 std::string _x, _y, _w, _h, _z;
132                 inp >> _x >> _y >> _w >> _h >> _z;
133                 currentAction.x = RealFromStr(_x.c_str());
134                 currentAction.y = RealFromStr(_y.c_str());
135                 currentAction.w = RealFromStr(_w.c_str());
136                 currentAction.h = RealFromStr(_h.c_str());
137                 currentAction.z = RealFromStr(_z.c_str());
138         }
139         else if (actionType == "approachl") // approach linearly
140         {
141                 currentAction.type = AT_ApproachBoundsLinear;
142                 std::string _x, _y, _w, _h, _z;
143                 inp >> _x >> _y >> _w >> _h >> _z;
144                 currentAction.x = RealFromStr(_x.c_str());
145                 currentAction.y = RealFromStr(_y.c_str());
146                 currentAction.w = RealFromStr(_w.c_str());
147                 currentAction.h = RealFromStr(_h.c_str());
148                 currentAction.z = RealFromStr(_z.c_str());
149                 currentAction.x = (currentAction.x - view->GetBounds().x)/currentAction.z;
150                 currentAction.y = (currentAction.y - view->GetBounds().y)/currentAction.z;
151                 currentAction.w = (currentAction.w - view->GetBounds().w)/currentAction.z;
152                 currentAction.h = (currentAction.h - view->GetBounds().h)/currentAction.z;
153         }
154         else if (actionType == "setbounds")
155         {
156                 currentAction.type = AT_SetBounds;
157                 std::string _x, _y, _w, _h;
158                 inp >> _x >> _y >> _w >> _h;
159                 currentAction.x = RealFromStr(_x.c_str());
160                 currentAction.y = RealFromStr(_y.c_str());
161                 currentAction.w = RealFromStr(_w.c_str());
162                 currentAction.h = RealFromStr(_h.c_str());
163         }
164         else if (actionType == "querygpubounds")
165         {
166                 currentAction.type = AT_QueryGPUBounds;
167                 inp >> currentAction.textargs;
168                 currentAction.loops = 1;
169         }
170         else if (actionType == "screenshot")
171         {
172                 currentAction.type = AT_ScreenShot;
173                 inp >> currentAction.textargs;  
174         }
175         else
176                 Fatal("Unknown action %s", actionType.c_str());
177
178 }
179
180 bool DebugScript::Execute(View *view, Screen *scr)
181 {
182         if (currentAction.loops <= 0)
183         {
184                 if (m_index >= m_actions.size())
185                 {
186                         ParseAction(view, scr);
187                         if (m_labels.size() > 0)
188                         {
189                                 m_actions.push_back(currentAction);
190                                 m_index++;
191                         }
192                                 
193                 }
194                 else
195                         currentAction = m_actions[m_index++];
196         }
197
198         switch(currentAction.type)
199         {
200         case AT_Quit:
201                 return true;
202         case AT_WaitFrame:
203                 break;
204         case AT_Translate:
205                 view->Translate(currentAction.x, currentAction.y);
206                 break;
207         case AT_TranslatePx:
208                 view->Translate(Real(currentAction.ix)/Real(scr->ViewportWidth()), Real(currentAction.iy)/Real(scr->ViewportHeight()));
209                 break;
210         case AT_Zoom:
211                 view->ScaleAroundPoint(currentAction.x, currentAction.y, currentAction.z);
212                 break;
213         case AT_ZoomPx:
214                 view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), Real(expf(-currentAction.iz/20.f)));
215                 break;
216         case AT_SetGPURendering:
217                 view->SetGPURendering(true);
218                 break;
219         case AT_SetCPURendering:
220                 view->SetGPURendering(false);
221                 break;
222         case AT_EnableLazyRendering:
223                 view->SetLazyRendering(true);
224                 break;
225         case AT_DisableLazyRendering:
226                 view->SetLazyRendering(false);
227                 break;
228         case AT_LoadSVG:
229         {
230                 #ifdef TRANSFORM_OBJECTS_NOT_VIEW
231                         view->Doc().LoadSVG(currentAction.textargs, Rect(Real(1)/Real(2),Real(1)/Real(2),Real(1)/Real(800),Real(1)/Real(600))); 
232                 #else
233                         const Rect & bounds = view->GetBounds();
234                         view->Doc().LoadSVG(currentAction.textargs, Rect(bounds.x+bounds.w/Real(2),bounds.y+bounds.h/Real(2),bounds.w/Real(800),bounds.h/Real(600)));
235                 #endif
236                 currentAction.type = AT_WaitFrame;
237                 view->ForceRenderDirty();
238                 view->ForceBufferDirty();
239                 view->ForceBoundsDirty();
240                 currentAction.loops = 1;
241                 break;
242         }
243         case AT_Label:
244                 m_labels[currentAction.textargs] = m_index;
245                 currentAction.type = AT_WaitFrame;
246                 currentAction.loops = 1;
247                 break;
248         case AT_Goto:
249                 m_index = m_labels[currentAction.textargs];
250                 currentAction.loops = 1;
251                 break;
252         case AT_Debug:
253                 Debug("View bounds: %s", view->GetBounds().Str().c_str());
254                 if (currentAction.textargs.size() > 0)
255                         Debug("%s", currentAction.textargs.c_str());
256                 break;
257         case AT_ClearDocument:
258                 view->Doc().ClearObjects();
259                 currentAction.loops = 1;
260                 break;
261         case AT_ClearPerformance:
262                 ClearPerformance(view, scr);
263                 currentAction.loops = 1;
264                 break;
265         case AT_PrintPerformance:
266                 PrintPerformance(view, scr);
267                 currentAction.loops = 1;        
268                 break;
269         case AT_RecordPerformance:
270                 PrintPerformance(view, scr);
271                 break;
272         case AT_DebugFont:
273                 scr->ShowDebugFont(currentAction.textargs == "1" || currentAction.textargs == "on");
274                 currentAction.loops = 1;
275                 break;
276                 
277         case AT_ApproachBoundsZeno:
278         {       
279                 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
280                 if (currentAction.z != VReal(1))
281                 {
282                         target.x = view->GetBounds().x + (target.x-view->GetBounds().x)/VReal(currentAction.z);
283                         target.y = view->GetBounds().y + (target.y-view->GetBounds().y)/VReal(currentAction.z);
284                         target.w = view->GetBounds().w + (target.w-view->GetBounds().w)/VReal(currentAction.z);
285                         target.h = view->GetBounds().h + (target.h-view->GetBounds().h)/VReal(currentAction.z);
286                 }
287                 
288
289                 VReal s = target.w/(view->GetBounds().w);
290                 if (Real(s) != 1)
291                 {
292                         VReal x0;
293                         VReal y0;
294                         x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
295                         y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
296                         view->ScaleAroundPoint(x0, y0, s);
297                         currentAction.loops++;
298                 }
299                 else
300                 {
301                         Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
302                         currentAction.type = AT_WaitFrame;
303                 }
304                 break;
305         }
306         case AT_ApproachBoundsLinear:
307         {
308                 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
309                 target.x += view->GetBounds().x;
310                 target.y += view->GetBounds().y;
311                 target.w += view->GetBounds().w;
312                 target.h += view->GetBounds().h;
313                 VReal s = target.w/(view->GetBounds().w);
314                 if (Real(s) != 1)
315                 {
316                         VReal x0;
317                         VReal y0;
318                         x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
319                         y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
320                         view->ScaleAroundPoint(x0, y0, s);
321                         currentAction.loops++;
322                 }
323                 else
324                 {
325                         Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
326                         currentAction.type = AT_WaitFrame;
327                 }
328                 break;
329         }
330         case AT_SetBounds:
331         {
332                 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
333                 view->SetBounds(target);
334                 break;
335         }
336         
337         case AT_QueryGPUBounds:
338         {
339                 view->QueryGPUBounds(currentAction.textargs.c_str(), "w");
340                 currentAction.loops = 1;
341                 break;
342         }
343         case AT_ScreenShot:
344         {
345                 view->SaveBMP(currentAction.textargs.c_str());
346                 currentAction.loops = 1;
347                 break;
348         }
349         default:
350                 Fatal("Unknown script command in queue.");
351         }
352         currentAction.loops--;
353         return false;
354 }
355
356 void DebugScript::ClearPerformance(View * view, Screen * scr)
357 {
358         m_perf_start.clock = clock();
359         m_perf_start.object_count = view->Doc().ObjectCount();
360         m_perf_start.view_bounds = view->GetBounds();
361         m_perf_last = m_perf_start;
362 }
363
364 void DebugScript::PrintPerformance(View * view, Screen * scr)
365 {
366         DebugScript::PerformanceData now;
367         now.clock = clock();
368         now.object_count = view->Doc().ObjectCount();
369         now.view_bounds = view->GetBounds();
370
371         // object_count  clock  delta_clock  x  Log10(x)  y  Log10(y)  w  Log10(w)  Size(w)
372         #ifdef QUADTREE_DISABLED
373         printf("%d\t%llu\t%llu\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n",
374                 now.object_count, (long long unsigned)now.clock,
375                 (long long unsigned)(now.clock - m_perf_last.clock),
376                 Str(now.view_bounds.x).c_str(), Str(Log10(Abs(now.view_bounds.x))).c_str(),
377                 Str(now.view_bounds.y).c_str(), Str(Log10(Abs(now.view_bounds.y))).c_str(),
378                 Str(now.view_bounds.w).c_str(), Str(Log10(now.view_bounds.w)).c_str(),
379                 (unsigned)Size(now.view_bounds.w));
380         #endif
381         m_perf_last = now;
382 }

UCC git Repository :: git.ucc.asn.au