Subversion Repositories Kolibri OS

Rev

Rev 4364 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2004 James Bursa <james@netsurf-browser.org>
  3.  * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
  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 <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. #include <assert.h>
  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. {
  76.         /* We assume the screen and ay other output has the same dpi */
  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.  
  143.