]> www.fi.muni.cz Git - evince.git/blob - dvi/painter.cc
a1bb7587992abcf0b6cc7c0d3187f569ce298adc
[evince.git] / dvi / painter.cc
1 #include "painter.hh"
2 #include "dl-dvi-fontdefinition.hh"
3
4 using DviLib::DviFontdefinition;
5 using DviLib::AbstractCharacter;
6
7 // paint a bitmap
8 void
9 DviPainter::paint_bitmap (const unsigned char *data,
10                           uint width, uint height, 
11                           int hoffset, int voffset)
12 {
13     GdkPixbuf *pixbuf = 
14         gdk_pixbuf_new_from_data (data,
15                                   GDK_COLORSPACE_RGB, 
16                                   TRUE,        // has_alpha,
17                                   8,
18                                   width,
19                                   height,
20                                   width * 4,  // rowstride
21                                   NULL,     // destroy_fn
22                                   NULL);    // destroy_fn_data
23     
24     uint x = dvi_to_pixels (current_frame->h);
25     uint y = dvi_to_pixels (current_frame->v);
26     
27     gdk_pixbuf_render_to_drawable (pixbuf,
28                                    pixmap,
29                                    gc,
30                                    0, 0,
31                                    x-hoffset,
32                                    y-voffset,
33                                    //y+(height - voffset),
34                                    width,
35                                    height,
36                                    GDK_RGB_DITHER_NONE,
37                                    0, 0);
38 }
39
40 // typeset ch, move w
41 void 
42 DviPainter::set_char (int ch)
43 {
44     g_assert (current_font);
45     
46     AbstractCharacter *character = current_font->get_char (ch);
47     character->paint (* this);
48     
49     int tfm_width = character->get_tfm_width ();
50     int at_size = current_font->get_at_size ();
51     int dvi_width = tfm_to_dvi (tfm_width, at_size);
52     
53     current_frame->h += dvi_width;
54 }
55
56 // typeset ch, don't move
57 void 
58 DviPainter::put_char (int ch)
59 {
60     AbstractCharacter *character = current_font->get_char (ch);
61     character->paint (* this);
62 }
63
64 void 
65 // rule, move (height, width)
66 DviPainter::set_rule (int height, 
67                       int width)
68 {
69     int width_p = dvi_to_pixels_no_offset (width);
70     int height_p = dvi_to_pixels_no_offset (height);
71     int x = dvi_to_pixels (current_frame->h);
72     int y = dvi_to_pixels (current_frame->v);
73     
74     cout << "BIRNAN\n" << endl;
75     
76     gdk_draw_rectangle (pixmap, gc, TRUE, 
77                         x, y, 
78                         width_p + 1, height_p + 1);
79     
80     current_frame->h += width;
81 }
82
83 // rule, don't move
84 void 
85 DviPainter::put_rule (int height, 
86                       int width)
87 {
88     cout << "w h " << width << " " << height << " " << endl;
89     
90     int width_p = dvi_to_pixels_no_offset (width);
91     int height_p = dvi_to_pixels_no_offset (height);
92     int x = dvi_to_pixels (current_frame->h);
93     int y = dvi_to_pixels (current_frame->v);
94     
95     cout << "EMFLE\n" << endl;
96     
97     cout << "x y h w " << x << " " << y << " " << height_p << " " 
98          << width_p << endl;
99     
100     gdk_draw_rectangle (pixmap, gc, TRUE, 
101                         x, y, 
102                         width_p + 1, height_p + 1);
103 }
104
105 // push current context
106 DviFrame *
107 DviFrame::copy (void)
108 {
109     DviFrame *frame = new DviFrame ();
110
111     frame->h = this->h;
112     frame->v = this->v;
113     frame->w = this->w;
114     frame->x = this->x;
115     frame->y = this->y;
116     frame->z = this->z;
117
118     return frame;
119 }
120
121 void 
122 DviPainter::push (void)
123 {
124     DviFrame *new_frame = current_frame->copy();
125     new_frame->next = current_frame;
126     current_frame = new_frame;
127 }
128
129 // pop ccontext
130 void 
131 DviPainter::pop (void)
132 {
133     DviFrame *old_frame = current_frame;
134
135     current_frame = current_frame->next;
136
137     old_frame->unref();
138 }
139
140 // move right len
141 void 
142 DviPainter::right (int len)
143 {
144     current_frame->h += len;
145 }
146
147 // move right len, set w = len
148 void 
149 DviPainter::w (int len)
150 {
151     right (len);
152     current_frame->w = len;
153 }
154
155 // move right w
156 void 
157 DviPainter::w_rep ()
158 {
159     right (current_frame->w);
160 }
161
162 // move right len, set x = len
163 void 
164 DviPainter::x (int len)
165 {
166     right (len);
167     current_frame->x = len;
168 }
169
170 // move right x
171 void 
172 DviPainter::x_rep ()
173 {
174     right (current_frame->x);
175 }
176
177 // move down len
178 void 
179 DviPainter::down (int len)
180 {
181     current_frame->v += len;
182 }
183
184 // move down len, set y = len
185 void 
186 DviPainter::y (int len)
187 {
188     down (len);
189     current_frame->y = len;
190 }
191
192 // move down y
193 void 
194 DviPainter::y_rep ()
195 {
196     down (current_frame->y);
197 }
198
199 // move down len, set z = len
200 void 
201 DviPainter::z (int len)
202 {
203     down (len);
204     current_frame->z = len;
205 }
206
207 // move down z
208 void 
209 DviPainter::z_rep ()
210 {
211     down (current_frame->z);
212 }
213
214 // f = font_num 
215 void 
216 DviPainter::font_num (int font_num)
217 {
218     cout << "get fno " << font_num << endl;
219     DviFontdefinition *fd = dvi_file->get_fontdefinition (font_num);
220     
221     g_assert (fd);
222     if (fd)
223     {
224         // gtkdvi:
225         int dpi = (int)floor( 0.5 + 1.0 * base_dpi * 
226                               dvi_file->get_magnification() * fd->at_size /
227                               ( 1000.0 * fd->design_size));
228         cout << "fno: " << fd->fontnum << endl;
229         cout << fd->name << endl;
230         current_font = 
231             font_factory->create_font (fd->name, dpi, fd->at_size);
232     }
233 }
234
235 // do something special
236 void 
237 DviPainter::special (string spc)
238 {
239     cout << "warning: special " << spc << " " << "not handled" << endl;
240 }
241
242 int 
243 DviPainter::tfm_to_dvi (uint tfm, int at_size)
244 {
245     // this is from gtkdvi:
246     int alpha, z, beta, b0, b1, b2, b3, r;
247     
248     alpha = 16;
249     z = at_size;
250     while (z >= (1<<23))
251     {
252         z >>= 1;
253         alpha <<= 1;
254     }
255     beta = 256/alpha;
256     alpha *= z;
257     
258 #if 0
259     b0 = tfm & (0xFF << 24);
260     b1 = tfm & (0xFF << 16);
261     b2 = tfm & (0xFF << 8);
262     b3 = tfm & (0xFF << 0);
263 #endif
264     
265     b0 = tfm >> 24;  
266     b1 = (tfm >> 16) & 255;
267     b2 = (tfm >> 8) & 255;
268     b3 = tfm & 255;
269     
270 #if 0
271     r = (((((b3 * z) / 256) + (b2 * z)) / 256) + (b1 * z))/beta;
272 #endif
273     
274     b1 *= z;
275     b2 *= z;
276     b3 *= z;
277     
278     r = (((b3 / 256 + b2) / 256) + b1) / beta;
279     
280     if (b0 > 0)
281     {
282         if ((b0 > 0) != (tfm > 0))
283             cout << "b0: " << b0 << "tfm: " << tfm << endl;
284         r -= alpha;
285     }
286     
287     return r;
288 }
289
290 DviPainter::DviPainter (GdkPixmap              *pixmap_arg,
291                          GdkGC                 *gc_arg,
292                          DviLib::DviFile       *dvi_file_arg,
293                          uint                   base_dpi_arg,
294                          AbstractFontFactory   *font_factory_arg)
295 {
296     pixmap              = (GdkPixmap *)g_object_ref (pixmap_arg);
297     gc                  = (GdkGC *)g_object_ref (gc_arg);
298     dvi_file            = dvi_file_arg;
299     base_dpi            = base_dpi_arg;
300     font_factory        = font_factory_arg;
301
302     dvi_file->ref();
303     font_factory->ref();
304     
305     current_font = 0;
306     
307     current_frame = new DviFrame;
308     current_frame->h = 0;
309     current_frame->v = 0;
310     current_frame->w = 0;
311     current_frame->x = 0;
312     current_frame->y = 0;
313     current_frame->z = 0;
314     
315     // from gtkdvi:
316     scale =  dvi_file->get_numerator() / 254000.0;
317     scale *= 1.0 * base_dpi / dvi_file->get_denominator ();
318     scale *= dvi_file->get_magnification () / 1000.0;
319 }
320
321 DviPainter::~DviPainter ()
322 {
323     g_object_unref (pixmap);
324     g_object_unref (gc);
325     dvi_file->unref();
326     font_factory->unref();
327     while (current_frame)
328         pop();
329 }
330
331 void
332 DviPainter::push_fontmap (std::map<int, DviFontdefinition *> fontmap)
333 {
334 }