renderer_preferences_util.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/renderer_preferences_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/renderer_preferences.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_ANDROID)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font_render_params_linux.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_theme_service.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h"
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/linux_ui/linux_ui.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace renderer_preferences_util {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_ANDROID)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::RendererPreferencesHintingEnum GetRendererPreferencesHintingEnum(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::FontRenderParams::Hinting hinting) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (hinting) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::HINTING_NONE:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_HINTING_NONE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::HINTING_SLIGHT:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_HINTING_SLIGHT;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::HINTING_MEDIUM:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_HINTING_MEDIUM;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::HINTING_FULL:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_HINTING_FULL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unhandled hinting style " << hinting;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_HINTING_SYSTEM_DEFAULT;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::RendererPreferencesSubpixelRenderingEnum
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetRendererPreferencesSubpixelRenderingEnum(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::FontRenderParams::SubpixelRendering subpixel_rendering) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (subpixel_rendering) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_NONE;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_RGB;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_BGR;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VRGB;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VBGR;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unhandled subpixel rendering style "
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << subpixel_rendering;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return content::RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_LINUX) || defined(OS_ANDROID)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateFromSystemSettings(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RendererPreferences* prefs, Profile* profile) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefService* pref_service = profile->GetPrefs();
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  prefs->accept_languages = pref_service->GetString(prefs::kAcceptLanguages);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->enable_referrers = pref_service->GetBoolean(prefs::kEnableReferrers);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->enable_do_not_track =
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref_service->GetBoolean(prefs::kEnableDoNotTrack);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->default_zoom_level = pref_service->GetDouble(prefs::kDefaultZoomLevel);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkThemeService* theme_service = GtkThemeService::GetFrom(profile);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->focus_ring_color = theme_service->get_focus_ring_color();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->thumb_active_color = theme_service->get_thumb_active_color();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->thumb_inactive_color = theme_service->get_thumb_inactive_color();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->track_color = theme_service->get_track_color();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->active_selection_bg_color =
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      theme_service->get_active_selection_bg_color();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->active_selection_fg_color =
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      theme_service->get_active_selection_fg_color();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->inactive_selection_bg_color =
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      theme_service->get_inactive_selection_bg_color();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->inactive_selection_fg_color =
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      theme_service->get_inactive_selection_fg_color();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Dividing GTK's cursor blink cycle time (in milliseconds) by this value
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // yields an appropriate value for RendererPreferences::caret_blink_interval.
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // This matches the logic in the WebKit GTK port.
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const double kGtkCursorBlinkCycleFactor = 2000.0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta cursor_blink_time = gfx::GetCursorBlinkCycle();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->caret_blink_interval =
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cursor_blink_time.InMilliseconds() ?
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cursor_blink_time.InMilliseconds() / kGtkCursorBlinkCycleFactor :
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(USE_DEFAULT_RENDER_THEME)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->focus_ring_color = SkColorSetRGB(0x4D, 0x90, 0xFE);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if !defined(OS_WIN)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This color is 0x544d90fe modulated with 0xffffff.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->active_selection_bg_color = SkColorSetRGB(0xCB, 0xE4, 0xFA);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->active_selection_fg_color = SK_ColorBLACK;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->inactive_selection_bg_color = SkColorSetRGB(0xEA, 0xEA, 0xEA);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->inactive_selection_fg_color = SK_ColorBLACK;
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchpad_fling_profile[0] =
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchpadAlpha);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchpad_fling_profile[1] =
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchpadBeta);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchpad_fling_profile[2] =
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchpadGamma);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchscreen_fling_profile[0] =
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchscreenAlpha);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchscreen_fling_profile[1] =
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchscreenBeta);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->touchscreen_fling_profile[2] =
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service->GetDouble(prefs::kFlingCurveTouchscreenGamma);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  prefs->caret_blink_interval = views::Textfield::GetCaretBlinkMs() / 1000.0;
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  views::LinuxUI* linux_ui = views::LinuxUI::instance();
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (linux_ui) {
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (ThemeServiceFactory::GetForProfile(profile)->UsingNativeTheme()) {
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->focus_ring_color = linux_ui->GetFocusRingColor();
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->thumb_active_color = linux_ui->GetThumbActiveColor();
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->thumb_inactive_color = linux_ui->GetThumbInactiveColor();
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->track_color = linux_ui->GetTrackColor();
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->active_selection_bg_color = linux_ui->GetActiveSelectionBgColor();
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->active_selection_fg_color = linux_ui->GetActiveSelectionFgColor();
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->inactive_selection_bg_color =
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        linux_ui->GetInactiveSelectionBgColor();
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      prefs->inactive_selection_fg_color =
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        linux_ui->GetInactiveSelectionFgColor();
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // If we have a linux_ui object, set the caret blink interval regardless of
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // whether we're in native theme mode.
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    prefs->caret_blink_interval = linux_ui->GetCursorBlinkInterval();
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_ANDROID)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::FontRenderParams& params = gfx::GetDefaultWebKitFontRenderParams();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->should_antialias_text = params.antialiasing;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->use_subpixel_positioning = params.subpixel_positioning;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->hinting = GetRendererPreferencesHintingEnum(params.hinting);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->use_autohinter = params.autohinter;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->use_bitmaps = params.use_bitmaps;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->subpixel_rendering =
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetRendererPreferencesSubpixelRenderingEnum(params.subpixel_rendering);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if !defined(OS_MACOSX)
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  prefs->plugin_fullscreen_allowed =
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pref_service->GetBoolean(prefs::kFullscreenAllowed);
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace renderer_preferences_util
180