root/branches/clutter-experiments/page.hh

Revision 59, 4.3 KB (checked in by mirko, 3 years ago)

Keybindings core.

Line 
1// TODO: move implementation in .cc file
2// TODO: refine api, it's somewhat ugly right now
3// TODO: should we render in a thread?
4#ifndef __PDFCUBE__PAGE_HH__
5#define __PDFCUBE__PAGE_HH__
6
7#include <glib.h>
8#include <poppler.h>
9#include <gdk-pixbuf/gdk-pixbuf.h>
10
11namespace pdfcube
12{
13
14  /**
15   * @brief The pdfcube::page class is the link between a PopplerPage
16   * and ClutterActor GObjects.
17   *
18   * This class is used to render low and hi res version of a
19   * PopplerPage as GdkPixbufs
20   *
21   * Usually, on start, all the pages will be rendered in a low res
22   * version, while higher res versions will be rendered on demand by
23   * the animations.
24   *
25   * While displaying one page the following page is rendered in high
26   * resolution. No forward animation is possible until the rendering
27   * finishes.
28   *
29   */
30  class page 
31  {
32  public:
33    /**
34     * @brief Ctor.
35     *
36     * This is used internally by pdfcube::document. (FIXME: make
37     * protected and friend of document?)
38     *
39     * @param poppler_page a PopplerPage*
40     *
41     */
42    page(PopplerPage* poppler_page) 
43      : poppler_page_m(poppler_page),
44        low_res_m(NULL),
45        hi_res_m(NULL)
46    { }
47   
48    double
49    aspect_ratio()
50    {
51      double w, h;
52      poppler_page_get_size(poppler_page_m, &w, &h);
53      return w/h;
54    }
55
56    std::pair<double, double>
57    size()
58    {
59      double w, h;
60      poppler_page_get_size(poppler_page_m, &w, &h);
61      return std::make_pair(w,h);
62    }
63   
64    enum rendering_mode { LOW_RES, HI_RES };
65   
66    /**
67     * @brief Renders the PopplerPage on the desired pixbuf.
68     */
69    void
70    render(rendering_mode mode)
71    { 
72      switch(mode)
73        {
74        case LOW_RES:
75          {
76            int w,h;
77            // we assume 4/3 aspect monitor can do better
78            double box_w = 320;
79            double box_h = 240;
80            double aspect = aspect_ratio();
81            // Check if our slot ratio is less or more than owr own
82            if(box_h > box_w/aspect)
83              {
84                w = box_w;
85                h = w/aspect;
86              }
87            else 
88              {
89                h = box_h;
90                w = h*aspect;
91              }
92
93            if(!low_res_m)
94              low_res_m = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
95            poppler_page_render_to_pixbuf(poppler_page_m, 
96                                          0,
97                                          0, 
98                                          w, 
99                                          h, 
100                                          ((double)h)/size().second, 
101                                          0, 
102                                          low_res_m);
103            break;
104          }
105        case HI_RES:
106          {
107            int w, h;
108            // FIXME: we assume 4/3 aspect monitor.
109            double box_w = 1600;
110            double box_h = 1200;
111            double aspect = aspect_ratio();
112            // Check if our slot ratio is less or more than owr own
113            if(box_h > box_w/aspect)
114              {
115                w = box_w;
116                h = w/aspect;
117              }
118            else 
119              {
120                h = box_h;
121                w = h*aspect;
122              }
123            if(!hi_res_m)
124              hi_res_m = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
125            poppler_page_render_to_pixbuf(poppler_page_m, 
126                                          0,
127                                          0, 
128                                          w, 
129                                          h, 
130                                          ((double)h)/size().second, 
131                                          0, 
132                                          hi_res_m);
133            break;
134          }
135        }
136    };
137
138    /**
139     * @brief Frees an unneeded actor.
140     */
141    void
142    free(rendering_mode mode)
143    { 
144      switch(mode)
145        {
146        case LOW_RES:
147          g_object_unref(low_res_m);
148          low_res_m = NULL;
149          break;
150        case HI_RES:
151          g_object_unref(hi_res_m);
152          hi_res_m = NULL;
153          break;
154        }
155    };
156
157    /**
158     * @brief Tells if the desired version is available.
159     */
160    bool
161    has(rendering_mode mode)
162    { 
163      switch(mode)
164        {
165        case LOW_RES:
166          return low_res_m != NULL;
167        case HI_RES:
168          return hi_res_m != NULL;
169        }
170      return false;
171    };
172
173    /**
174     * @brief Returns the desired actor (on NULL if not present).
175     */
176    GdkPixbuf* 
177    pixbuf(rendering_mode mode)
178    {
179      switch(mode)
180        {
181        case LOW_RES:
182          return low_res_m;
183        case HI_RES:
184          return hi_res_m;
185        }
186      return NULL;
187    }
188
189    PopplerPageTransitionType transition_type()
190    {
191      PopplerPageTransition* ppt = poppler_page_get_transition(poppler_page_m);
192      if(ppt) return ppt->type;
193      else return POPPLER_PAGE_TRANSITION_REPLACE;
194    }
195
196  protected:
197
198    /*
199     * GList PopplerLinkMapping enumerating function
200     */
201    void link_function(gpointer data, gpointer user_data)
202    {
203      PopplerLinkMapping* link = (PopplerLinkMapping*)data;
204      g_print("Link area (%f,%f)x(%f,%f)\n", 
205              link->area.x1, 
206              link->area.y1, 
207              link->area.x2, 
208              link->area.y2); 
209    }
210
211    PopplerPage* poppler_page_m;
212    GdkPixbuf* low_res_m;
213    GdkPixbuf* hi_res_m;
214  };
215
216}
217
218#endif
Note: See TracBrowser for help on using the browser.