*shower* :-)
[lectures/dfb-slides.git] / render.c
1 /* DirectFB presentation app
2  *
3  * Copyright (C) 2001  convergence integrated media
4  * Authors: Sven Neumann <sven@convergence.de>
5  *
6  * This program 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  * This program 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 this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include <directfb.h>
26
27 #include <glib-object.h>
28
29 #include "apptypes.h"
30
31 #include "action.h"
32 #include "context.h"
33 #include "header.h"
34 #include "image.h"
35 #include "listitem.h"
36 #include "render.h"
37 #include "resources.h"
38 #include "slides.h"
39 #include "slide.h"
40 #include "text.h"
41 #include "video.h"
42
43
44 static void render_bullet (Context *context,
45                            gint    *offx,
46                            gint     offy);
47
48 void
49 render_bg (Context *context)
50 {
51   guchar *color;
52   
53   color = context_get_bgcolor (context);
54   context->surface->SetColor (context->surface, 
55                               color[0], color[1], color[2], color[3]);
56   context->surface->FillRectangle (context->surface, 
57                                    0, 0, context->w, context->h);
58 }
59
60 void
61 render_bgimage (Context *context)
62 {
63   gchar *image;
64
65   image = context_get_bgimage (context);
66   if (image)
67     {
68       IDirectFBSurface *src;
69       gint w, h;
70
71       src = resources_get_surface (image);
72       if (!src)
73         return;
74
75       src->GetSize (src, &w, &h);
76           
77       if (w == context->w && h == context->h)
78         {
79           context->surface->Blit (context->surface, src, NULL, 0, 0);
80         }     
81       else
82         {
83           DFBRectangle rect = { 0, 0, context->w, context->h };
84           
85           context->surface->StretchBlit (context->surface, 
86                                          src, NULL, &rect);
87         }
88       
89       resources_release_surface (image);
90     }
91 }
92
93 void
94 render_image (Context *context,
95               Image   *image)
96 {
97   Item                  *item;
98   IDirectFBSurface      *src; 
99   DFBRectangle           rect;
100   DFBSurfacePixelFormat  format;
101   gint w, h, ratio;
102
103   if (IS_VIDEO (image))
104     {
105       Video *video;
106
107       video = (Video *) image;
108       video->dest_surface = context->surface;
109
110       return;
111     }
112
113   src = resources_get_surface (ITEM (image)->value);
114
115   if (!src)
116     return;
117
118   src->GetSize (src, &w, &h);
119   src->GetPixelFormat (src, &format);
120
121   if (format == DSPF_ARGB)
122     context->surface->SetBlittingFlags (context->surface, 
123                                         DSBLIT_BLEND_ALPHACHANNEL);
124
125   ratio = (w * 1024) / h;
126   item = (Item *) image;
127   
128   rect.w = item->flags & WIDTH ? 
129     item->width : (item->flags & HEIGHT ? (item->height * ratio) / 1024 : w);
130   rect.h = item->flags & HEIGHT ? 
131     item->height : (item->flags & WIDTH ? (item->width * 1024) / ratio : h);
132
133   rect.x = item->flags & XOFFSET ? item->x : 0;
134   rect.y = item->flags & YOFFSET ? item->y : 0;
135   
136   if (format == DSPF_ARGB)
137     context->surface->SetBlittingFlags (context->surface, 
138                                         DSBLIT_BLEND_ALPHACHANNEL);
139
140   if (w == rect.w || h == rect.h)
141     context->surface->Blit (context->surface, src, NULL, rect.x, rect.y);
142   else
143     context->surface->StretchBlit (context->surface, src, NULL, &rect);
144
145   context->surface->SetBlittingFlags (context->surface, DSBLIT_NOFX);
146
147   resources_release_surface (ITEM (image)->value);
148 }
149
150 void
151 render_text (Context *context,
152              Text    *text,
153              gint    *offy)
154 {
155   guchar        *color;
156   gchar         *face;
157   gint           size;
158   gint           offx;
159   IDirectFBFont *font;
160
161   context_push (context, (Item *) text);
162
163   color = context_get_fgcolor (context);
164   context->surface->SetColor (context->surface, 
165                               color[0], color[1], color[2], color[3]);
166
167   face = context_get_face (context);
168   size = context_get_size (context);
169
170   g_return_if_fail (face != NULL);
171   g_return_if_fail (size > 0);
172
173   offx = 10;
174
175   if (IS_HEADER (text))
176     size = (size * 64) / 52;
177   else if (IS_LISTITEM (text))
178     size = (size * 48) / 64;
179   else
180     offx+=40;
181
182   font = resources_get_font (face, size);
183   
184   if (IS_LISTITEM (text))
185     {
186       gint asc;
187
188       font->GetAscender (font, &asc);
189       render_bullet (context, &offx, *offy + asc);
190     }
191
192   context->surface->SetFont (context->surface, font);
193   context->surface->DrawString (context->surface, 
194                                 ITEM (text)->value, -1,
195                                 offx, *offy, DSTF_TOPLEFT);
196
197   *offy += (size * 64) / 48;
198
199   context_pop (context, (Item *) text);
200 }
201
202 static void
203 render_bullet (Context *context,
204                gint    *offx,
205                gint     offy)
206 {
207   IDirectFBSurface *src;
208   gchar            *image;
209   gint              w, h;
210
211   image = context_get_bullet (context);
212   if (image)
213     {
214       src = resources_get_surface (image);
215       if (!src)
216         return;
217
218       src->GetSize (src, &w, &h);
219
220       context->surface->SetBlittingFlags (context->surface, 
221                                           DSBLIT_BLEND_ALPHACHANNEL);
222       context->surface->Blit (context->surface, 
223                               src, NULL, *offx + 20, offy - h);
224       context->surface->SetBlittingFlags (context->surface, DSBLIT_NOFX);
225
226       resources_release_surface (image);
227
228       *offx += w + 24;
229     }
230 }