Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4364 Rev 5043
1
/*
1
/*
2
 * Copyright 2004 James Bursa 
2
 * Copyright 2004 James Bursa 
3
 * Copyright 2009 John-Mark Bell 
3
 * Copyright 2009 John-Mark Bell 
4
 *
4
 *
5
 * This file is part of NetSurf, http://www.netsurf-browser.org/
5
 * This file is part of NetSurf, http://www.netsurf-browser.org/
6
 *
6
 *
7
 * NetSurf is free software; you can redistribute it and/or modify
7
 * NetSurf is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; version 2 of the License.
9
 * the Free Software Foundation; version 2 of the License.
10
 *
10
 *
11
 * NetSurf is distributed in the hope that it will be useful,
11
 * NetSurf is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
14
 * GNU General Public License for more details.
15
 *
15
 *
16
 * You should have received a copy of the GNU General Public License
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see .
17
 * along with this program.  If not, see .
18
 */
18
 */
19
 
19
 
20
#include 
20
#include 
21
 
21
 
22
#include "css/utils.h"
22
#include "css/utils.h"
23
 
23
 
24
#include "desktop/options.h"
24
#include "desktop/options.h"
25
#include "utils/log.h"
25
#include "utils/log.h"
26
 
26
 
27
/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
27
/** Screen DPI in fixed point units: defaults to 90, which RISC OS uses */
28
css_fixed nscss_screen_dpi = F_90;
28
css_fixed nscss_screen_dpi = F_90;
29
 
29
 
30
/**
30
/**
31
 * Convert an absolute CSS length to points.
31
 * Convert an absolute CSS length to points.
32
 *
32
 *
33
 * \param  length  Length to convert
33
 * \param  length  Length to convert
34
 * \param  unit    Corresponding unit
34
 * \param  unit    Corresponding unit
35
 * \return	   length in points
35
 * \return	   length in points
36
 */
36
 */
37
css_fixed nscss_len2pt(css_fixed length, css_unit unit)
37
css_fixed nscss_len2pt(css_fixed length, css_unit unit)
38
{
38
{
39
	/* Length must not be relative */
39
	/* Length must not be relative */
40
	assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX);
40
	assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX);
41
 
41
 
42
	switch (unit) {
42
	switch (unit) {
43
	/* We assume the screen and any other output has the same dpi */
43
	/* We assume the screen and any other output has the same dpi */
44
	/* 1in = DPIpx => 1px = (72/DPI)pt */
44
	/* 1in = DPIpx => 1px = (72/DPI)pt */
45
	case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi);
45
	case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi);
46
	/* 1in = 72pt */
46
	/* 1in = 72pt */
47
	case CSS_UNIT_IN: return FMUL(length, F_72);
47
	case CSS_UNIT_IN: return FMUL(length, F_72);
48
	/* 1in = 2.54cm => 1cm = (72/2.54)pt */
48
	/* 1in = 2.54cm => 1cm = (72/2.54)pt */
49
	case CSS_UNIT_CM: return FMUL(length, 
49
	case CSS_UNIT_CM: return FMUL(length, 
50
				FDIV(F_72, FLTTOFIX(2.54)));
50
				FDIV(F_72, FLTTOFIX(2.54)));
51
	/* 1in = 25.4mm => 1mm = (72/25.4)pt */
51
	/* 1in = 25.4mm => 1mm = (72/25.4)pt */
52
	case CSS_UNIT_MM: return FMUL(length, 
52
	case CSS_UNIT_MM: return FMUL(length, 
53
				      FDIV(F_72, FLTTOFIX(25.4)));
53
				      FDIV(F_72, FLTTOFIX(25.4)));
54
	case CSS_UNIT_PT: return length;
54
	case CSS_UNIT_PT: return length;
55
	/* 1pc = 12pt */
55
	/* 1pc = 12pt */
56
	case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
56
	case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12));
57
	default: break;
57
	default: break;
58
	}
58
	}
59
 
59
 
60
	return 0;
60
	return 0;
61
}
61
}
62
 
62
 
63
 
63
 
64
/**
64
/**
65
 * Convert a CSS length to pixels.
65
 * Convert a CSS length to pixels.
66
 *
66
 *
67
 * \param  length  Length to convert
67
 * \param  length  Length to convert
68
 * \param  unit    Corresponding unit
68
 * \param  unit    Corresponding unit
69
 * \param  style   Computed style applying to length. May be NULL if unit is 
69
 * \param  style   Computed style applying to length. May be NULL if unit is 
70
 *                 neither em nor ex
70
 *                 neither em nor ex
71
 * \return	   length in pixels
71
 * \return	   length in pixels
72
 */
72
 */
73
css_fixed nscss_len2px(css_fixed length, css_unit unit, 
73
css_fixed nscss_len2px(css_fixed length, css_unit unit, 
74
		const css_computed_style *style)
74
		const css_computed_style *style)
75
{
75
{
76
	/* We assume the screen and any other output has the same dpi */
76
	/* We assume the screen and ay other output has the same dpi */
77
	css_fixed px_per_unit;
77
	css_fixed px_per_unit;
78
 
78
 
79
	assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX));
79
	assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX));
80
 
80
 
81
	switch (unit) {
81
	switch (unit) {
82
	case CSS_UNIT_EM:
82
	case CSS_UNIT_EM:
83
	case CSS_UNIT_EX:
83
	case CSS_UNIT_EX:
84
	{
84
	{
85
		css_fixed font_size = 0;
85
		css_fixed font_size = 0;
86
		css_unit font_unit = CSS_UNIT_PT;
86
		css_unit font_unit = CSS_UNIT_PT;
87
 
87
 
88
		css_computed_font_size(style, &font_size, &font_unit);
88
		css_computed_font_size(style, &font_size, &font_unit);
89
 
89
 
90
		/* Convert to points */
90
		/* Convert to points */
91
		font_size = nscss_len2pt(font_size, font_unit);
91
		font_size = nscss_len2pt(font_size, font_unit);
92
 
92
 
93
		/* Clamp to configured minimum */
93
		/* Clamp to configured minimum */
94
		if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) {
94
		if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) {
95
		  font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10);
95
		  font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10);
96
		}
96
		}
97
 
97
 
98
		/* Convert to pixels (manually, to maximise precision) 
98
		/* Convert to pixels (manually, to maximise precision) 
99
		 * 1in = 72pt => 1pt = (DPI/72)px */
99
		 * 1in = 72pt => 1pt = (DPI/72)px */
100
		px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
100
		px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72);
101
 
101
 
102
		/* Scale ex units: we use a fixed ratio of 1ex = 0.6em */
102
		/* Scale ex units: we use a fixed ratio of 1ex = 0.6em */
103
		if (unit == CSS_UNIT_EX)
103
		if (unit == CSS_UNIT_EX)
104
			px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
104
			px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6));
105
	}
105
	}
106
		break;
106
		break;
107
	case CSS_UNIT_PX: 
107
	case CSS_UNIT_PX: 
108
		px_per_unit = F_1;
108
		px_per_unit = F_1;
109
		break;
109
		break;
110
	/* 1in = DPIpx */
110
	/* 1in = DPIpx */
111
	case CSS_UNIT_IN: 
111
	case CSS_UNIT_IN: 
112
		px_per_unit = nscss_screen_dpi;
112
		px_per_unit = nscss_screen_dpi;
113
		break;
113
		break;
114
	/* 1in = 2.54cm => 1cm = (DPI/2.54)px */
114
	/* 1in = 2.54cm => 1cm = (DPI/2.54)px */
115
	case CSS_UNIT_CM: 
115
	case CSS_UNIT_CM: 
116
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54));
116
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54));
117
		break;
117
		break;
118
	/* 1in = 25.4mm => 1mm = (DPI/25.4)px */
118
	/* 1in = 25.4mm => 1mm = (DPI/25.4)px */
119
	case CSS_UNIT_MM: 
119
	case CSS_UNIT_MM: 
120
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4));
120
		px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4));
121
		break;
121
		break;
122
	/* 1in = 72pt => 1pt = (DPI/72)px */
122
	/* 1in = 72pt => 1pt = (DPI/72)px */
123
	case CSS_UNIT_PT: 
123
	case CSS_UNIT_PT: 
124
		px_per_unit = FDIV(nscss_screen_dpi, F_72);
124
		px_per_unit = FDIV(nscss_screen_dpi, F_72);
125
		break;
125
		break;
126
	/* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */
126
	/* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */
127
	case CSS_UNIT_PC: 
127
	case CSS_UNIT_PC: 
128
		px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6));
128
		px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6));
129
		break;
129
		break;
130
	default:
130
	default:
131
		px_per_unit = 0;
131
		px_per_unit = 0;
132
		break;
132
		break;
133
	}
133
	}
134
 
134
 
135
	/* Ensure we round px_per_unit to the nearest whole number of pixels:
135
	/* Ensure we round px_per_unit to the nearest whole number of pixels:
136
	 * the use of FIXTOINT() below will truncate. */
136
	 * the use of FIXTOINT() below will truncate. */
137
	px_per_unit += F_0_5;
137
	px_per_unit += F_0_5;
138
 
138
 
139
	/* Calculate total number of pixels */
139
	/* Calculate total number of pixels */
140
	return FMUL(length, TRUNCATEFIX(px_per_unit));
140
	return FMUL(length, TRUNCATEFIX(px_per_unit));
141
}
141
}