ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
Revision: 1.24
Committed: Wed Apr 12 21:01:45 2006 UTC (18 years, 1 month ago) by root
Branch: MAIN
Changes since 1.23: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.5 #include <string.h>
6    
7 root 1.2 #include <SDL.h>
8 root 1.23 #include <SDL_image.h>
9 root 1.3 #include <SDL_opengl.h>
10 root 1.5
11     #include <pango/pango.h>
12 root 1.10 #include <pango/pangofc-fontmap.h>
13 root 1.5 #include <pango/pangoft2.h>
14    
15 root 1.22 #include <sys/time.h>
16     #include <sys/types.h>
17     #include <unistd.h>
18    
19 root 1.10 #include <sys/types.h>
20     #include <sys/socket.h>
21     #include <netinet/in.h>
22     #include <netinet/tcp.h>
23    
24 root 1.5 static PangoContext *context;
25     static PangoFontMap *fontmap;
26 root 1.2
27 root 1.14 typedef struct cf_layout {
28     PangoLayout *pl;
29     int base_height;
30 root 1.15 } *CFClient__Layout;
31 root 1.14
32     static void
33 root 1.19 substitute_func (FcPattern *pattern, gpointer data)
34     {
35 root 1.20 FcPatternAddBool (pattern, FC_HINTING , 1);
36     FcPatternAddBool (pattern, FC_AUTOHINT, 1);
37 root 1.19 }
38    
39     static void
40 root 1.17 layout_update (CFClient__Layout self)
41     {
42 root 1.19 /* use a random scale factor to account for unknown descenders, 0.8 works
43     * reasonably well with bitstream vera
44     */
45 root 1.17 PangoFontDescription *font = pango_context_get_font_description (context);
46 root 1.19 pango_font_description_set_absolute_size (font, self->base_height * (PANGO_SCALE * 8 / 10));
47 root 1.17 }
48    
49     static void
50 root 1.15 layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
51 root 1.14 {
52 root 1.19 layout_update (self);
53 root 1.16
54 root 1.14 pango_layout_get_pixel_size (self->pl, w, h);
55    
56     *w = (*w + 3) & ~3;
57     if (!*w) *w = 1;
58     if (!*h) *h = 1;
59     }
60    
61 root 1.15 MODULE = CFClient PACKAGE = CFClient
62 root 1.1
63 root 1.11 PROTOTYPES: ENABLE
64    
65 root 1.5 BOOT:
66     {
67     fontmap = pango_ft2_font_map_new ();
68 root 1.19 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0);
69 root 1.8 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap);
70 root 1.5 }
71    
72 root 1.10 void
73     lowdelay (int fd, int val = 1)
74     CODE:
75     setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
76    
77 root 1.3 char *
78 root 1.4 gl_version ()
79     CODE:
80 root 1.5 RETVAL = (char *)glGetString (GL_VERSION);
81 root 1.4 OUTPUT:
82     RETVAL
83    
84     char *
85 root 1.3 gl_extensions ()
86     CODE:
87 root 1.5 RETVAL = (char *)glGetString (GL_EXTENSIONS);
88 root 1.3 OUTPUT:
89     RETVAL
90    
91 root 1.5 void
92 root 1.13 add_font (char *file)
93     CODE:
94     FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
95    
96     void
97 root 1.9 set_font (char *file)
98 root 1.8 CODE:
99     {
100 root 1.9 int count;
101     FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
102 root 1.10 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
103 root 1.9 FcPatternDestroy (pattern);
104 root 1.8 pango_context_set_font_description (context, font);
105     }
106    
107 root 1.23 void
108     load_image_inline (SV *image_)
109     ALIAS:
110     load_image_file = 1
111     PPCODE:
112     {
113     STRLEN image_len;
114     char *image = (char *)SvPVbyte (image_, image_len);
115     SDL_Surface *surface, *surface2;
116     SDL_PixelFormat fmt;
117     SDL_RWops *rw = ix
118     ? SDL_RWFromFile (image, "r")
119     : SDL_RWFromConstMem (image, image_len);
120    
121     if (!rw)
122     croak ("load_image: unable to open file");
123    
124     surface = IMG_Load_RW (rw, 1);
125     if (!surface)
126     croak ("load_image: unable to read file");
127    
128     fmt.palette = NULL;
129     fmt.BitsPerPixel = 32;
130     fmt.BytesPerPixel = 4;
131     fmt.Rmask = 0x000000ff;
132     fmt.Gmask = 0x0000ff00;
133     fmt.Bmask = 0x00ff0000;
134     fmt.Amask = 0xff000000;
135     fmt.Rloss = 0;
136     fmt.Gloss = 0;
137     fmt.Bloss = 0;
138     fmt.Aloss = 0;
139     fmt.Rshift = 0;
140     fmt.Gshift = 8;
141     fmt.Bshift = 16;
142     fmt.Ashift = 24;
143     fmt.colorkey = 0;
144     fmt.alpha = 0;
145    
146     surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
147    
148     EXTEND (SP, 5);
149     PUSHs (sv_2mortal (newSViv (surface2->w)));
150     PUSHs (sv_2mortal (newSViv (surface2->h)));
151     SDL_LockSurface (surface2);
152     PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
153     SDL_UnlockSurface (surface2);
154 root 1.24 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
155 root 1.23 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
156     PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_INT_8_8_8_8_REV)));
157    
158     SDL_FreeSurface (surface);
159     SDL_FreeSurface (surface2);
160     }
161    
162 root 1.15 MODULE = CFClient PACKAGE = CFClient::Layout
163 root 1.14
164 root 1.15 CFClient::Layout
165 root 1.14 new (SV *class, int base_height = 10)
166     CODE:
167     New (0, RETVAL, 1, struct cf_layout);
168     RETVAL->base_height = base_height;
169     RETVAL->pl = pango_layout_new (context);
170     pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
171     OUTPUT:
172     RETVAL
173    
174     void
175 root 1.15 DESTROY (CFClient::Layout self)
176 root 1.14 CODE:
177     g_object_unref (self->pl);
178     Safefree (self);
179 root 1.13
180 root 1.8 void
181 root 1.15 set_markup (CFClient::Layout self, SV *text_)
182 root 1.14 CODE:
183 root 1.5 {
184     STRLEN textlen;
185     char *text = SvPVutf8 (text_, textlen);
186 root 1.14
187     pango_layout_set_markup (self->pl, text, textlen);
188     }
189    
190     void
191 root 1.16 set_height (CFClient::Layout self, int base_height)
192     CODE:
193     self->base_height = base_height;
194    
195     void
196 root 1.15 set_width (CFClient::Layout self, int max_width = -1)
197 root 1.14 CODE:
198     pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
199    
200     void
201 root 1.15 size (CFClient::Layout self)
202 root 1.14 PPCODE:
203     {
204     int w, h;
205    
206 root 1.17 layout_update (self);
207 root 1.14 layout_get_pixel_size (self, &w, &h);
208    
209     EXTEND (SP, 2);
210     PUSHs (sv_2mortal (newSViv (w)));
211     PUSHs (sv_2mortal (newSViv (h)));
212     }
213    
214 root 1.17 int
215     xy_to_index (CFClient::Layout self, int x, int y)
216     CODE:
217     {
218     int index, trailing;
219    
220     layout_update (self);
221     pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
222    
223     RETVAL = index;
224     }
225     OUTPUT:
226     RETVAL
227    
228     void
229     cursor_pos (CFClient::Layout self, int index)
230     PPCODE:
231     {
232     PangoRectangle strong_pos;
233     layout_update (self);
234     pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
235     EXTEND (SP, 3);
236     PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
237     PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
238     PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
239     }
240    
241 root 1.14 void
242 root 1.15 render (CFClient::Layout self)
243 root 1.14 PPCODE:
244     {
245 root 1.5 SV *retval;
246     int w, h;
247     FT_Bitmap bitmap;
248    
249 root 1.17 layout_update (self);
250 root 1.14 layout_get_pixel_size (self, &w, &h);
251 root 1.5
252     retval = newSV (w * h);
253     SvPOK_only (retval);
254     SvCUR_set (retval, w * h);
255    
256     bitmap.rows = h;
257     bitmap.width = w;
258     bitmap.pitch = w;
259     bitmap.buffer = (unsigned char*)SvPVX (retval);
260     bitmap.num_grays = 256;
261     bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
262    
263     memset (bitmap.buffer, 0, w * h);
264    
265 root 1.14 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
266 root 1.1
267 root 1.5 EXTEND (SP, 3);
268     PUSHs (sv_2mortal (newSViv (w)));
269     PUSHs (sv_2mortal (newSViv (h)));
270     PUSHs (sv_2mortal (retval));
271     }
272 root 1.11
273 root 1.15 MODULE = CFClient PACKAGE = CFClient::Texture
274 root 1.11
275     void
276 root 1.12 draw_quad (SV *self, double x, double y, double w = 0, double h = 0)
277     PROTOTYPE: $$$;$$
278 root 1.11 CODE:
279     {
280 root 1.12 HV *hv = (HV *)SvRV (self);
281     double s = SvNV (*hv_fetch (hv, "s", 1, 1));
282     double t = SvNV (*hv_fetch (hv, "t", 1, 1));
283     int name = SvIV (*hv_fetch (hv, "name", 4, 1));
284    
285     if (items < 5)
286     {
287 root 1.18 w = SvNV (*hv_fetch (hv, "w", 1, 1));
288     h = SvNV (*hv_fetch (hv, "h", 1, 1));
289 root 1.12 }
290    
291     glBindTexture (GL_TEXTURE_2D, name);
292     glBegin (GL_QUADS);
293     glTexCoord2d (0, 0); glVertex2d (x , y );
294     glTexCoord2d (0, t); glVertex2d (x , y + h);
295     glTexCoord2d (s, t); glVertex2d (x + w, y + h);
296     glTexCoord2d (s, 0); glVertex2d (x + w, y );
297     glEnd ();
298 root 1.11 }