Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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