File: adjust.c

package info (click to toggle)
wily 0.13.33-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,500 kB
  • ctags: 1,720
  • sloc: ansic: 12,830; sh: 245; makefile: 188
file content (124 lines) | stat: -rw-r--r-- 3,008 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "tile.h"

/*****************************************************************
	Collection of functions to reduce the size of a tile.
	Each reduces the tile's size, and return the amount of savings.
	They appear in order of severity.
*****************************************************************/

/* If t's body contains any blank lines, get rid of them */
static int
stripwhitespace(Tile *t, int excess) {
	int	saving,size;

	if (!t->body )
		return 0;
	
	size = TILESIZE(t);

	/* Possibly we've already mangled this tile, so it can no longer
	 * properly contain its body and tag
	 */
	if(size < view_height(t->body) + view_height(t->tag))
		return 0;

	if((saving = view_stripwhitespace(t->body))) {
		assert(saving < size);
		saving = MIN(saving, excess);
		t->max -= saving;
		assert(TILESIZE(t) >= t->base);
	}
	return saving;
}

/* Have the amount by which t's size exceeds t->base */
static int
halve(Tile*t, int excess) {
	int	saving,size = TILESIZE(t);
	int	extra = size - t->base;

	if(extra > 0) {
		saving = MIN(extra/2, excess);
		t->max -= saving;
		return size - TILESIZE(t);
	}
	return 0;
}

/* Shrink 't' down to t->base */
static int
shrink(Tile *t, int excess) {
	int	saving = MIN(TILESIZE(t) - t->base, excess);
	t->max -= saving;
	return saving;
}

/* Hide 't':  => size = 0 */
static int
hide(Tile *t, int excess) {
	assert(TILESIZE(t) == t->base);	/* we've already done 'shrink' */
	t->ishidden = true;
	return t->base;
}

typedef int (*SizeAdjust)(Tile*, int);
SizeAdjust method []  = { 
	stripwhitespace, halve, shrink, hide, 0
};
/*****************************************************************
	End of Collection of functions to reduce the size of a tile.
*****************************************************************/

/*
 * Adjust the sizes of the tiles in [start,end) so that they add to
 * <= 'available'.
 * Return the total size.
*/
int
adjust_sizes_in_range(Tile*start, Tile*end, int available)
{
	Tile *t;
	int size,saving,excess;
	int	now;
	int	j;
	SizeAdjust	m;	/* method to adjust the size of a tile */

	assert(available >= 0);

	size = list_size(start,end);

	for(j=0; (m=method[j]); j++) {
		FOR_EACH_VISIBLE(start,end){
			assert(size == (now = list_size(start, end)));	
			excess = MAX(size - available, 0);
			saving = (*m)(t, excess);
			assert(t->ishidden || (TILESIZE(t) >= t->base));
			size -= saving;
			
			/* check our math */
			assert(size == (now = list_size(start, end)));	

			if (size <= available) {
				/* C doesn't have labelled break.  So sue me. */
				goto out;	
			}
		}
	}
out:
	/* check our math */
	assert(size == (now = list_size(start, end)));	

	assert (size <= available);	/* Even if we had to hide everything */

	/* If we've taken too much, return some size to the last visible tile */
	if(size<available && (t = last_visible(start,end))) {
		t->max += available - size;
		size = available;
		now = list_size(start,end);
		assert( size == now);
	}

	assert( size <= available);
	assert (size >= 0);
	return size;
}