2 * Copyright (C) 2007-2010 Openismus GmbH
5 * Mathias Hasselmann <mathias@openismus.com>
6 * Tristan Van Berkom <tristan.van.berkom@gmail.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library 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 GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
24 #include "gtksizerequestcacheprivate.h"
29 _gtk_size_request_cache_init (SizeRequestCache *cache)
31 memset (cache, 0, sizeof (SizeRequestCache));
35 free_sizes (SizeRequest **sizes)
39 for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
40 g_slice_free (SizeRequest, sizes[i]);
42 g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
46 _gtk_size_request_cache_free (SizeRequestCache *cache)
50 for (i = 0; i < 2; i++)
52 if (cache->requests[i])
53 free_sizes (cache->requests[i]);
58 _gtk_size_request_cache_clear (SizeRequestCache *cache)
61 _gtk_size_request_cache_free (cache);
62 _gtk_size_request_cache_init (cache);
66 _gtk_size_request_cache_commit (SizeRequestCache *cache,
67 GtkOrientation orientation,
72 SizeRequest **cached_sizes;
73 SizeRequest *cached_size;
76 /* First handle caching of the base requests */
79 cache->cached_size[orientation].minimum_size = minimum_size;
80 cache->cached_size[orientation].natural_size = natural_size;
81 cache->flags[orientation].cached_size_valid = TRUE;
85 /* Check if the minimum_size and natural_size is already
86 * in the cache and if this result can be used to extend
89 cached_sizes = cache->requests[orientation];
90 n_sizes = cache->flags[orientation].n_cached_requests;
92 for (i = 0; i < n_sizes; i++)
94 if (cached_sizes[i]->cached_size.minimum_size == minimum_size &&
95 cached_sizes[i]->cached_size.natural_size == natural_size)
97 cached_sizes[i]->lower_for_size = MIN (cached_sizes[i]->lower_for_size, for_size);
98 cached_sizes[i]->upper_for_size = MAX (cached_sizes[i]->upper_for_size, for_size);
103 /* If not found, pull a new size from the cache, the returned size cache
104 * will immediately be used to cache the new computed size so we go ahead
105 * and increment the last_cached_request right away */
106 if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
108 cache->flags[orientation].n_cached_requests++;
109 cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
113 if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
114 cache->flags[orientation].last_cached_request = 0;
117 if (cache->requests[orientation] == NULL)
118 cache->requests[orientation] = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
120 if (cache->requests[orientation][cache->flags[orientation].last_cached_request] == NULL)
121 cache->requests[orientation][cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequest);
123 cached_size = cache->requests[orientation][cache->flags[orientation].last_cached_request];
124 cached_size->lower_for_size = for_size;
125 cached_size->upper_for_size = for_size;
126 cached_size->cached_size.minimum_size = minimum_size;
127 cached_size->cached_size.natural_size = natural_size;
130 /* looks for a cached size request for this for_size.
132 * Note that this caching code was originally derived from
133 * the Clutter toolkit but has evolved for other GTK+ requirements.
136 _gtk_size_request_cache_lookup (SizeRequestCache *cache,
137 GtkOrientation orientation,
142 CachedSize *result = NULL;
146 if (cache->flags[orientation].cached_size_valid)
147 result = &cache->cached_size[orientation];
153 /* Search for an already cached size */
154 for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
156 SizeRequest *cur = cache->requests[orientation][i];
158 if (cur->lower_for_size <= for_size &&
159 cur->upper_for_size >= for_size)
161 result = &cur->cached_size;
169 *minimum = result->minimum_size;
170 *natural = result->natural_size;