Big rework of image.c and the image cache system.
[dana/openbox.git] / obrender / render.h
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    render.h for the Openbox window manager
4    Copyright (c) 2006        Mikael Magnusson
5    Copyright (c) 2003-2007   Dana Jansens
6    Copyright (c) 2003        Derek Foreman
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    See the COPYING file for a copy of the GNU General Public License.
19 */
20
21 #ifndef __render_h
22 #define __render_h
23
24 #include <X11/Xlib.h> /* some platforms dont include this as needed for Xft */
25 #include <pango/pangoxft.h>
26 #include <glib.h>
27
28 G_BEGIN_DECLS
29
30 #include "obrender/geom.h"
31 #include "obrender/version.h"
32
33 typedef union  _RrTextureData      RrTextureData;
34 typedef struct _RrAppearance       RrAppearance;
35 typedef struct _RrSurface          RrSurface;
36 typedef struct _RrFont             RrFont;
37 typedef struct _RrTexture          RrTexture;
38 typedef struct _RrTextureMask      RrTextureMask;
39 typedef struct _RrTextureRGBA      RrTextureRGBA;
40 typedef struct _RrTextureImage     RrTextureImage;
41 typedef struct _RrTextureText      RrTextureText;
42 typedef struct _RrTextureLineArt   RrTextureLineArt;
43 typedef struct _RrPixmapMask       RrPixmapMask;
44 typedef struct _RrInstance         RrInstance;
45 typedef struct _RrColor            RrColor;
46 typedef struct _RrImage            RrImage;
47 typedef struct _RrImageSet         RrImageSet;
48 typedef struct _RrImagePic         RrImagePic;
49 typedef struct _RrImageCache       RrImageCache;
50
51 typedef guint32 RrPixel32;  /* RGBA format */
52 typedef guint16 RrPixel16;
53 typedef guchar  RrPixel8;
54
55 typedef enum {
56     RR_RELIEF_FLAT,
57     RR_RELIEF_RAISED,
58     RR_RELIEF_SUNKEN,
59     RR_RELIEF_NUM_TYPES
60 } RrReliefType;
61
62 typedef enum {
63     RR_BEVEL_1,
64     RR_BEVEL_2,
65     RR_BEVEL_NUM_TYPES
66 } RrBevelType;
67
68 typedef enum {
69     RR_SURFACE_NONE,
70     RR_SURFACE_PARENTREL,
71     RR_SURFACE_SOLID,
72     RR_SURFACE_SPLIT_VERTICAL,
73     RR_SURFACE_HORIZONTAL,
74     RR_SURFACE_VERTICAL,
75     RR_SURFACE_DIAGONAL,
76     RR_SURFACE_CROSS_DIAGONAL,
77     RR_SURFACE_PYRAMID,
78     RR_SURFACE_MIRROR_HORIZONTAL,
79     RR_SURFACE_NUM_TYPES
80 } RrSurfaceColorType;
81
82 typedef enum {
83     RR_TEXTURE_NONE,
84     RR_TEXTURE_MASK,
85     RR_TEXTURE_TEXT,
86     RR_TEXTURE_LINE_ART,
87     RR_TEXTURE_RGBA,
88     RR_TEXTURE_IMAGE,
89     RR_TEXTURE_NUM_TYPES
90 } RrTextureType;
91
92 typedef enum {
93     RR_JUSTIFY_LEFT,
94     RR_JUSTIFY_CENTER,
95     RR_JUSTIFY_RIGHT,
96     RR_JUSTIFY_NUM_TYPES
97 } RrJustify;
98
99 /* Put middle first so it's the default */
100 typedef enum {
101     RR_ELLIPSIZE_MIDDLE,
102     RR_ELLIPSIZE_NONE,
103     RR_ELLIPSIZE_START,
104     RR_ELLIPSIZE_END,
105     RR_ELLIPSIZE_NUM_TYPES
106 } RrEllipsizeMode;
107
108 typedef enum {
109     RR_FONTWEIGHT_LIGHT,
110     RR_FONTWEIGHT_NORMAL,
111     RR_FONTWEIGHT_SEMIBOLD,
112     RR_FONTWEIGHT_BOLD,
113     RR_FONTWEIGHT_ULTRABOLD,
114     RR_FONTWEIGHT_NUM_TYPES
115 } RrFontWeight;
116
117 typedef enum {
118     RR_FONTSLANT_NORMAL,
119     RR_FONTSLANT_ITALIC,
120     RR_FONTSLANT_OBLIQUE,
121     RR_FONTSLANT_NUM_TYPES
122 } RrFontSlant;
123
124 struct _RrSurface {
125     RrSurfaceColorType grad;
126     RrReliefType relief;
127     RrBevelType bevel;
128     RrColor *primary;
129     RrColor *secondary;
130     RrColor *border_color;
131     RrColor *bevel_dark;
132     RrColor *bevel_light;
133     RrColor *interlace_color;
134     gboolean interlaced;
135     gboolean border;
136     RrAppearance *parent;
137     gint parentx;
138     gint parenty;
139     RrPixel32 *pixel_data;
140     gint bevel_dark_adjust;  /* 0-255, default is 64 */
141     gint bevel_light_adjust; /* 0-255, default is 128 */
142     RrColor *split_primary;
143     RrColor *split_secondary;
144 };
145
146 struct _RrTextureText {
147     RrFont *font;
148     RrJustify justify;
149     RrColor *color;
150     const gchar *string;
151     gint shadow_offset_x;
152     gint shadow_offset_y;
153     RrColor *shadow_color;
154     gboolean shortcut; /*!< Underline a character */
155     guint shortcut_pos; /*!< Position in bytes of the character to underline */
156     RrEllipsizeMode ellipsize;
157     gboolean flow; /* allow multiple lines.  must set maxwidth below */
158     gint maxwidth;
159     guchar shadow_alpha; /* at the bottom to improve alignment */
160 };
161
162 struct _RrPixmapMask {
163     const RrInstance *inst;
164     Pixmap mask;
165     gint width;
166     gint height;
167     gchar *data;
168 };
169
170 struct _RrTextureMask {
171     RrColor *color;
172     RrPixmapMask *mask;
173 };
174
175 struct _RrTextureRGBA {
176     gint width;
177     gint height;
178     gint alpha;
179     RrPixel32 *data;
180     /* size and position to draw at (if these are zero, then it will be
181        drawn to fill the entire texture */
182     gint tx;
183     gint ty;
184     gint twidth;
185     gint theight;
186 };
187
188 struct _RrTextureImage {
189     RrImage *image;
190     gint alpha;
191     /* size and position to draw at (if these are zero, then it will be
192        drawn to fill the entire texture */
193     gint tx;
194     gint ty;
195     gint twidth;
196     gint theight;
197 };
198
199 struct _RrTextureLineArt {
200     RrColor *color;
201     gint x1;
202     gint y1;
203     gint x2;
204     gint y2;
205 };
206
207 union _RrTextureData {
208     RrTextureRGBA rgba;
209     RrTextureImage image;
210     RrTextureText text;
211     RrTextureMask mask;
212     RrTextureLineArt lineart;
213 };
214
215 struct _RrTexture {
216     /* If changing the type of a texture, you should DEFINITELY call
217        RrAppearanceClearTextures() first! */
218     RrTextureType type;
219     RrTextureData data;
220 };
221
222 struct _RrAppearance {
223     const RrInstance *inst;
224
225     RrSurface surface;
226     gint textures;
227     RrTexture *texture;
228     Pixmap pixmap;
229     XftDraw *xftdraw;
230
231     /* cached for internal use */
232     gint w, h;
233 };
234
235 /*! Holds a RGBA image picture */
236 struct _RrImagePic {
237     gint width, height;
238     RrPixel32 *data;
239     /* The sum of all the pixels.  This is used to compare pictures if their
240        hashes match. */
241     gint sum;
242 };
243
244 typedef void (*RrImageDestroyFunc)(RrImage *image, gpointer data);
245
246 /*! An RrImage refers to a RrImageSet.  If multiple RrImageSets end up
247   holding the same image data, they will be marged and the RrImages that
248   point to them would be updated. */
249 struct _RrImage {
250     gint ref;
251     RrImageSet *set;
252
253     /* This function (if not NULL) will be called just before destroying
254       RrImage. */
255     RrImageDestroyFunc destroy_func;
256     gpointer           destroy_data;
257 };
258
259 /*! An RrImage is a sort of meta-image.  It can contain multiple versions
260   of an image at different sizes, which may or may not be completely different
261   pictures */
262 struct _RrImageSet
263 {
264     RrImageCache *cache;
265
266     /*! If a picture is loaded by a name, then it has a name attached to it.
267       This contains a list of strings, containing all names that have ever
268       been associated with the RrImageSet. A name in the RrImageCache can
269       only be associated with a single RrImageSet. */
270     GSList *names;
271
272     /*! RrImages that point at this RrImageSet. If this is empty, then there
273       are no images using the set and it can be freed. */
274     GSList *images;
275
276     /*! An array of "originals", that is of RrPictures that have been added
277       to the image in various sizes, and that have not been resized.  These
278       are explicitly added to the RrImageSet. */
279     RrImagePic **original;
280     gint n_original;
281     /*! An array of "resized" pictures.  When an "original" RrPicture
282       needs to be resized for drawing, it is saved in here so that it doesn't
283       need to be resized again.  These are automatically added to the
284       RrImage. */
285     RrImagePic **resized;
286     gint n_resized;
287 };
288
289 /* these are the same on all endian machines because it seems to be dependant
290    on the endianness of the gfx card, not the cpu. */
291 #define RrDefaultAlphaOffset 24
292 #define RrDefaultRedOffset 16
293 #define RrDefaultGreenOffset 8
294 #define RrDefaultBlueOffset 0
295
296 #define RrDefaultFontFamily       "arial,sans"
297 #define RrDefaultFontSize         8
298 #define RrDefaultFontWeight       RR_FONTWEIGHT_NORMAL
299 #define RrDefaultFontSlant        RR_FONTSLANT_NORMAL
300
301 RrInstance* RrInstanceNew (Display *display, gint screen);
302 void        RrInstanceFree (RrInstance *inst);
303
304 Display* RrDisplay      (const RrInstance *inst);
305 gint     RrScreen       (const RrInstance *inst);
306 Window   RrRootWindow   (const RrInstance *inst);
307 Visual*  RrVisual       (const RrInstance *inst);
308 gint     RrDepth        (const RrInstance *inst);
309 Colormap RrColormap     (const RrInstance *inst);
310 gint     RrRedOffset    (const RrInstance *inst);
311 gint     RrGreenOffset  (const RrInstance *inst);
312 gint     RrBlueOffset   (const RrInstance *inst);
313 gint     RrRedShift     (const RrInstance *inst);
314 gint     RrGreenShift   (const RrInstance *inst);
315 gint     RrBlueShift    (const RrInstance *inst);
316 gint     RrRedMask      (const RrInstance *inst);
317 gint     RrGreenMask    (const RrInstance *inst);
318 gint     RrBlueMask     (const RrInstance *inst);
319
320 RrColor *RrColorNew   (const RrInstance *inst, gint r, gint g, gint b);
321 RrColor *RrColorParse (const RrInstance *inst, gchar *colorname);
322 void     RrColorFree  (RrColor *in);
323
324 gint     RrColorRed   (const RrColor *c);
325 gint     RrColorGreen (const RrColor *c);
326 gint     RrColorBlue  (const RrColor *c);
327 gulong   RrColorPixel (const RrColor *c);
328 GC       RrColorGC    (RrColor *c);
329
330 RrAppearance *RrAppearanceNew  (const RrInstance *inst, gint numtex);
331 RrAppearance *RrAppearanceCopy (RrAppearance *a);
332 void          RrAppearanceFree (RrAppearance *a);
333 void          RrAppearanceRemoveTextures(RrAppearance *a);
334 void          RrAppearanceAddTextures(RrAppearance *a, gint numtex);
335 /*! Always call this when changing the type of a texture in an appearance */
336 void          RrAppearanceClearTextures(RrAppearance *a);
337
338 RrFont *RrFontOpen          (const RrInstance *inst, const gchar *name,
339                              gint size, RrFontWeight weight, RrFontSlant slant);
340 RrFont *RrFontOpenDefault   (const RrInstance *inst);
341 void    RrFontClose         (RrFont *f);
342 /*! Returns an RrSize, that was allocated with g_slice_new().  Use g_slice_free() to
343   free it. */
344 RrSize *RrFontMeasureString (const RrFont *f, const gchar *str,
345                              gint shadow_offset_x, gint shadow_offset_y,
346                              gboolean flow, gint maxwidth);
347 gint    RrFontHeight        (const RrFont *f, gint shadow_offset_y);
348 gint    RrFontMaxCharWidth  (const RrFont *f);
349
350 /* Paint into the appearance. The old pixmap is returned (if there was one). It
351    is the responsibility of the caller to call XFreePixmap on the return when
352    it is non-null. */
353 Pixmap RrPaintPixmap (RrAppearance *a, gint w, gint h);
354 void   RrPaint       (RrAppearance *a, Window win, gint w, gint h);
355 void   RrMinSize     (RrAppearance *a, gint *w, gint *h);
356 gint   RrMinWidth    (RrAppearance *a);
357 /* For text textures, if flow is TRUE, then the string must be set before
358    calling this, otherwise it doesn't need to be */
359 gint   RrMinHeight   (RrAppearance *a);
360 void   RrMargins     (RrAppearance *a, gint *l, gint *t, gint *r, gint *b);
361
362 gboolean RrPixmapToRGBA(const RrInstance *inst,
363                         Pixmap pmap, Pixmap mask,
364                         gint *w, gint *h, RrPixel32 **data);
365
366 /*! Create a new image cache for RrImages.
367   @param max_resized_saved The number of resized copies of an image to save
368 */
369 RrImageCache* RrImageCacheNew(gint max_resized_saved);
370 void          RrImageCacheRef(RrImageCache *self);
371 void          RrImageCacheUnref(RrImageCache *self);
372
373 /*! Create a new image, or return one from the cache that matches.
374   @param cache The image cache.
375   @param old The current RrImage, which the new image should be added to.
376     Use this if loading a different sized version of the same image.
377     The returned RrImage should replace the one passed in as old.
378     Pass NULL here if adding an image which is (or may be) entirely new.
379   @param name The name of the icon to be loaded off disk, or used in the cache
380   @return Returns NULL if unable to load an image by the name and it is not in
381     the cache already
382 */
383 RrImage* RrImageNewFromName(RrImageCache *cache, const gchar *name);
384
385 /*! Create a new image, or return one from the cache that matches.
386   @param cache The image cache.
387   @param data The image data in RGBA32 format.  There should be @w * @h many
388     values in the data array.
389   @param w The width of the image data.
390   @param h The height of the image data.
391   @return Returns NULL if unable to load an image by the name and it is not in
392     the cache already
393 */
394 RrImage* RrImageNewFromData(RrImageCache *cache, RrPixel32 *data,
395                             gint w, gint h);
396
397 /*! Add a new size of a picture to an image.
398   If a picture has multiple versions of different sizes (example 16x16, 32x32
399   and so on), they should all be under the same RrImage.  This adds a new
400   size to an existing RrImage, associating the newly sized picture with the
401   others in the RrImage - classifying them as being the same logical image at a
402   different dimention.
403 */
404 void RrImageAddFromData(RrImage *image, RrPixel32 *data, gint w, gint h);
405
406 void RrImageRef(RrImage *im);
407 void RrImageUnref(RrImage *im);
408
409 G_END_DECLS
410
411 #endif /*__render_h*/