/** * Convert an absolute CSS length to points. * * \param length Length to convert * \param unit Corresponding unit * \return length in points */ css_fixed nscss_len2pt(css_fixed length, css_unit unit) { /* Length must not be relative */ assert(unit != CSS_UNIT_EM && unit != CSS_UNIT_EX); switch (unit) { /* We assume the screen and any other output has the same dpi */ /* 1in = DPIpx => 1px = (72/DPI)pt */ case CSS_UNIT_PX: return FDIV(FMUL(length, F_72), nscss_screen_dpi); /* 1in = 72pt */ case CSS_UNIT_IN: return FMUL(length, F_72); /* 1in = 2.54cm => 1cm = (72/2.54)pt */ case CSS_UNIT_CM: return FMUL(length, FDIV(F_72, FLTTOFIX(2.54))); /* 1in = 25.4mm => 1mm = (72/25.4)pt */ case CSS_UNIT_MM: return FMUL(length, FDIV(F_72, FLTTOFIX(25.4))); case CSS_UNIT_PT: return length; /* 1pc = 12pt */ case CSS_UNIT_PC: return FMUL(length, INTTOFIX(12)); default: break; } return 0; }
css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size) { static css_hint_length sizes[] = { { FLTTOFIX(6.75), CSS_UNIT_PT }, { FLTTOFIX(7.50), CSS_UNIT_PT }, { FLTTOFIX(9.75), CSS_UNIT_PT }, { FLTTOFIX(12.0), CSS_UNIT_PT }, { FLTTOFIX(13.5), CSS_UNIT_PT }, { FLTTOFIX(18.0), CSS_UNIT_PT }, { FLTTOFIX(24.0), CSS_UNIT_PT } }; const css_hint_length *parent_size; UNUSED(pw); /* Grab parent size, defaulting to medium if none */ if (parent == NULL) { parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1]; } else { assert(parent->status == CSS_FONT_SIZE_DIMENSION); assert(parent->data.length.unit != CSS_UNIT_EM); assert(parent->data.length.unit != CSS_UNIT_EX); parent_size = &parent->data.length; } assert(size->status != CSS_FONT_SIZE_INHERIT); if (size->status < CSS_FONT_SIZE_LARGER) { /* Keyword -- simple */ size->data.length = sizes[size->status - 1]; } else if (size->status == CSS_FONT_SIZE_LARGER) { /** \todo Step within table, if appropriate */ size->data.length.value = FMUL(parent_size->value, FLTTOFIX(1.2)); size->data.length.unit = parent_size->unit; } else if (size->status == CSS_FONT_SIZE_SMALLER) { /** \todo Step within table, if appropriate */ size->data.length.value = FMUL(parent_size->value, FLTTOFIX(1.2)); size->data.length.unit = parent_size->unit; } else if (size->data.length.unit == CSS_UNIT_EM || size->data.length.unit == CSS_UNIT_EX) { size->data.length.value = FMUL(size->data.length.value, parent_size->value); if (size->data.length.unit == CSS_UNIT_EX) { size->data.length.value = FMUL(size->data.length.value, FLTTOFIX(0.6)); } size->data.length.unit = parent_size->unit; } else if (size->data.length.unit == CSS_UNIT_PCT) { size->data.length.value = FDIV(FMUL(size->data.length.value, parent_size->value), FLTTOFIX(100)); size->data.length.unit = parent_size->unit; } size->status = CSS_FONT_SIZE_DIMENSION; return CSS_OK; }
/** * Convert a CSS length to pixels. * * \param length Length to convert * \param unit Corresponding unit * \param style Computed style applying to length. May be NULL if unit is * neither em nor ex * \return length in pixels */ css_fixed nscss_len2px(css_fixed length, css_unit unit, const css_computed_style *style) { /* We assume the screen and ay other output has the same dpi */ css_fixed px_per_unit; assert(style != NULL || (unit != CSS_UNIT_EM && unit != CSS_UNIT_EX)); switch (unit) { case CSS_UNIT_EM: case CSS_UNIT_EX: { css_fixed font_size = 0; css_unit font_unit = CSS_UNIT_PT; css_computed_font_size(style, &font_size, &font_unit); /* Convert to points */ font_size = nscss_len2pt(font_size, font_unit); /* Clamp to configured minimum */ if (font_size < FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)) { font_size = FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10); } /* Convert to pixels (manually, to maximise precision) * 1in = 72pt => 1pt = (DPI/72)px */ px_per_unit = FDIV(FMUL(font_size, nscss_screen_dpi), F_72); /* Scale ex units: we use a fixed ratio of 1ex = 0.6em */ if (unit == CSS_UNIT_EX) px_per_unit = FMUL(px_per_unit, FLTTOFIX(0.6)); } break; case CSS_UNIT_PX: px_per_unit = F_1; break; /* 1in = DPIpx */ case CSS_UNIT_IN: px_per_unit = nscss_screen_dpi; break; /* 1in = 2.54cm => 1cm = (DPI/2.54)px */ case CSS_UNIT_CM: px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(2.54)); break; /* 1in = 25.4mm => 1mm = (DPI/25.4)px */ case CSS_UNIT_MM: px_per_unit = FDIV(nscss_screen_dpi, FLTTOFIX(25.4)); break; /* 1in = 72pt => 1pt = (DPI/72)px */ case CSS_UNIT_PT: px_per_unit = FDIV(nscss_screen_dpi, F_72); break; /* 1pc = 12pt => 1in = 6pc => 1pc = (DPI/6)px */ case CSS_UNIT_PC: px_per_unit = FDIV(nscss_screen_dpi, INTTOFIX(6)); break; default: px_per_unit = 0; break; } /* Ensure we round px_per_unit to the nearest whole number of pixels: * the use of FIXTOINT() below will truncate. */ px_per_unit += F_0_5; /* Calculate total number of pixels */ return FMUL(length, TRUNCATEFIX(px_per_unit)); }
/** * Initialize GTK interface. */ static void gui_init(int argc, char** argv, char **respath) { char buf[PATH_MAX]; const char *addr = NETSURF_HOMEPAGE; char *resource_filename; /* check user options */ check_options(respath); /* find the languages file */ languages_file_location = filepath_find(respath, "languages"); if ((languages_file_location == NULL) || (strlen(languages_file_location) < 10)) { die("Unable to find resources.\n"); } /* Obtain resources path location. * * Uses the directory the languages file was found in, * @todo find and slaughter all references to this! */ res_dir_location = calloc(1, strlen(languages_file_location) - 8); memcpy(res_dir_location, languages_file_location, strlen(languages_file_location) - 9); LOG(("Using '%s' for resource path", res_dir_location)); /* initialise the glade templates */ nsgtk_init_glade(respath); /* set default icon if its available */ resource_filename = filepath_find(respath, "netsurf.xpm"); if (resource_filename != NULL) { gtk_window_set_default_icon_from_file(resource_filename, NULL); free(resource_filename); } /* Search engine sources */ search_engines_file_location = filepath_find(respath, "SearchEngines"); LOG(("Using '%s' as Search Engines file", search_engines_file_location)); /* Default Icon */ search_default_ico_location = filepath_find(respath, "default.ico"); LOG(("Using '%s' as default search ico", search_default_ico_location)); /* Default favicon */ resource_filename = filepath_find(respath, "favicon.png"); if (resource_filename != NULL) { favicon_pixbuf = gdk_pixbuf_new_from_file(resource_filename, NULL); free(resource_filename); if (favicon_pixbuf == NULL) { favicon_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 16,16); } } /* Toolbar inicies file */ toolbar_indices_file_location = filepath_find(respath, "toolbarIndices"); LOG(("Using '%s' as custom toolbar settings file", toolbar_indices_file_location)); /* load throbber images */ if (nsgtk_throbber_init(respath, THROBBER_FRAMES) == false) die("Unable to load throbber image.\n"); /* Initialise completions - cannot fail */ nsgtk_completion_init(); filepath_sfinddef(respath, buf, "mime.types", "/etc/"); gtk_fetch_filetype_init(buf); urldb_load(nsoption_charp(url_file)); urldb_load_cookies(nsoption_charp(cookie_file)); /* The tree view system needs to know the screen's DPI, so we * find that out here, rather than when we create a first browser * window. */ nscss_screen_dpi = FLTTOFIX(gdk_screen_get_resolution( gdk_screen_get_default())); LOG(("Set CSS DPI to %f", FIXTOFLT(nscss_screen_dpi))); if (nsgtk_history_init(glade_file_location->history) == false) die("Unable to initialise history window.\n"); if (nsgtk_download_init(glade_file_location->downloads) == false) die("Unable to initialise download window.\n"); if (nsgtk_cookies_init(glade_file_location->cookies) == false) die("Unable to initialise cookies window.\n"); if (nsgtk_hotlist_init(glade_file_location->hotlist) == false) die("Unable to initialise hotlist window.\n"); sslcert_init(tree_content_icon_name); if (nsoption_charp(homepage_url) != NULL) { addr = nsoption_charp(homepage_url); } if (2 <= argc) addr = argv[1]; /* Last step of initialization. Opens the main browser window. */ browser_window_create(addr, 0, 0, true, false); }
/** * Font size computation callback for libcss * * \param pw Computation context * \param parent Parent font size (absolute) * \param size Font size to compute * \return CSS_OK on success * * \post \a size will be an absolute font size */ css_error nscss_compute_font_size(void *pw, const css_hint *parent, css_hint *size) { /** * Table of font-size keyword scale factors * * These are multiplied by the configured default font size * to produce an absolute size for the relevant keyword */ static const css_fixed factors[] = { FLTTOFIX(0.5625), /* xx-small */ FLTTOFIX(0.6250), /* x-small */ FLTTOFIX(0.8125), /* small */ FLTTOFIX(1.0000), /* medium */ FLTTOFIX(1.1250), /* large */ FLTTOFIX(1.5000), /* x-large */ FLTTOFIX(2.0000) /* xx-large */ }; css_hint_length parent_size; /* Grab parent size, defaulting to medium if none */ if (parent == NULL) { parent_size.value = FDIV(FMUL(factors[CSS_FONT_SIZE_MEDIUM - 1], INTTOFIX(nsoption_int(font_size))), INTTOFIX(10)); parent_size.unit = CSS_UNIT_PT; } else { assert(parent->status == CSS_FONT_SIZE_DIMENSION); assert(parent->data.length.unit != CSS_UNIT_EM); assert(parent->data.length.unit != CSS_UNIT_EX); assert(parent->data.length.unit != CSS_UNIT_PCT); parent_size = parent->data.length; } assert(size->status != CSS_FONT_SIZE_INHERIT); if (size->status < CSS_FONT_SIZE_LARGER) { /* Keyword -- simple */ size->data.length.value = FDIV(FMUL(factors[size->status - 1], INTTOFIX(nsoption_int(font_size))), F_10); size->data.length.unit = CSS_UNIT_PT; } else if (size->status == CSS_FONT_SIZE_LARGER) { /** \todo Step within table, if appropriate */ size->data.length.value = FMUL(parent_size.value, FLTTOFIX(1.2)); size->data.length.unit = parent_size.unit; } else if (size->status == CSS_FONT_SIZE_SMALLER) { /** \todo Step within table, if appropriate */ size->data.length.value = FDIV(parent_size.value, FLTTOFIX(1.2)); size->data.length.unit = parent_size.unit; } else if (size->data.length.unit == CSS_UNIT_EM || size->data.length.unit == CSS_UNIT_EX || size->data.length.unit == CSS_UNIT_CAP || size->data.length.unit == CSS_UNIT_CH || size->data.length.unit == CSS_UNIT_IC) { size->data.length.value = FMUL(size->data.length.value, parent_size.value); switch (size->data.length.unit) { case CSS_UNIT_EX: /* 1ex = 0.6em in NetSurf */ size->data.length.value = FMUL(size->data.length.value, FLTTOFIX(0.6)); break; case CSS_UNIT_CAP: /* Height of captals. 1cap = 0.9em in NetSurf. */ size->data.length.value = FMUL(size->data.length.value, FLTTOFIX(0.9)); break; case CSS_UNIT_CH: /* Width of '0'. 1ch = 0.4em in NetSurf. */ size->data.length.value = FMUL(size->data.length.value, FLTTOFIX(0.4)); break; case CSS_UNIT_IC: /* Width of U+6C43. 1ic = 1.1em in NetSurf. */ size->data.length.value = FMUL(size->data.length.value, FLTTOFIX(1.1)); break; default: /* No scaling required for EM. */ break; } size->data.length.unit = parent_size.unit; } else if (size->data.length.unit == CSS_UNIT_PCT) { size->data.length.value = FDIV(FMUL(size->data.length.value, parent_size.value), INTTOFIX(100)); size->data.length.unit = parent_size.unit; } else if (size->data.length.unit == CSS_UNIT_REM) { nscss_select_ctx *ctx = pw; if (parent == NULL) { size->data.length.value = parent_size.value; size->data.length.unit = parent_size.unit; } else { css_computed_font_size(ctx->root_style, &parent_size.value, &size->data.length.unit); size->data.length.value = FMUL( size->data.length.value, parent_size.value); } } else if (size->data.length.unit == CSS_UNIT_RLH) { /** TODO: Convert root element line-height to absolute value. */ size->data.length.value = FMUL(size->data.length.value, FDIV( INTTOFIX(nsoption_int(font_size)), INTTOFIX(10))); size->data.length.unit = CSS_UNIT_PT; } size->status = CSS_FONT_SIZE_DIMENSION; return CSS_OK; }