1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chrome_page_zoom.h" 6 7 #include <algorithm> 8 #include <cmath> 9 10 #include "base/prefs/pref_service.h" 11 #include "chrome/browser/chrome_page_zoom_constants.h" 12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/common/pref_names.h" 14 #include "content/public/browser/render_view_host.h" 15 #include "content/public/browser/user_metrics.h" 16 #include "content/public/browser/web_contents.h" 17 #include "content/public/common/page_zoom.h" 18 #include "content/public/common/renderer_preferences.h" 19 20 using content::UserMetricsAction; 21 22 namespace chrome_page_zoom { 23 24 enum PageZoomValueType { 25 PAGE_ZOOM_VALUE_TYPE_FACTOR, 26 PAGE_ZOOM_VALUE_TYPE_LEVEL, 27 }; 28 29 std::vector<double> PresetZoomValues(PageZoomValueType value_type, 30 double custom_value) { 31 // Generate a vector of zoom values from an array of known preset 32 // factors. The values in content::kPresetZoomFactors will already be in 33 // sorted order. 34 std::vector<double> zoom_values; 35 bool found_custom = false; 36 for (size_t i = 0; i < kPresetZoomFactorsSize; i++) { 37 double zoom_value = kPresetZoomFactors[i]; 38 if (value_type == PAGE_ZOOM_VALUE_TYPE_LEVEL) 39 zoom_value = content::ZoomFactorToZoomLevel(zoom_value); 40 if (content::ZoomValuesEqual(zoom_value, custom_value)) 41 found_custom = true; 42 zoom_values.push_back(zoom_value); 43 } 44 // If the preset array did not contain the custom value, append it to the 45 // vector and then sort. 46 double min = value_type == PAGE_ZOOM_VALUE_TYPE_LEVEL ? 47 content::ZoomFactorToZoomLevel(content::kMinimumZoomFactor) : 48 content::kMinimumZoomFactor; 49 double max = value_type == PAGE_ZOOM_VALUE_TYPE_LEVEL ? 50 content::ZoomFactorToZoomLevel(content::kMaximumZoomFactor) : 51 content::kMaximumZoomFactor; 52 if (!found_custom && custom_value > min && custom_value < max) { 53 zoom_values.push_back(custom_value); 54 std::sort(zoom_values.begin(), zoom_values.end()); 55 } 56 return zoom_values; 57 } 58 59 std::vector<double> PresetZoomFactors(double custom_factor) { 60 return PresetZoomValues(PAGE_ZOOM_VALUE_TYPE_FACTOR, custom_factor); 61 } 62 63 std::vector<double> PresetZoomLevels(double custom_level) { 64 return PresetZoomValues(PAGE_ZOOM_VALUE_TYPE_LEVEL, custom_level); 65 } 66 67 void Zoom(content::WebContents* web_contents, content::PageZoom zoom) { 68 content::RenderViewHost* host = web_contents->GetRenderViewHost(); 69 double current_zoom_level = web_contents->GetZoomLevel(); 70 double default_zoom_level = 71 Profile::FromBrowserContext(web_contents->GetBrowserContext())-> 72 GetPrefs()->GetDouble(prefs::kDefaultZoomLevel); 73 74 if (zoom == content::PAGE_ZOOM_RESET) { 75 host->SetZoomLevel(default_zoom_level); 76 content::RecordAction(UserMetricsAction("ZoomNormal")); 77 return; 78 } 79 80 // Generate a vector of zoom levels from an array of known presets along with 81 // the default level added if necessary. 82 std::vector<double> zoom_levels = PresetZoomLevels(default_zoom_level); 83 84 if (zoom == content::PAGE_ZOOM_OUT) { 85 // Iterate through the zoom levels in reverse order to find the next 86 // lower level based on the current zoom level for this page. 87 for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin(); 88 i != zoom_levels.rend(); ++i) { 89 double zoom_level = *i; 90 if (content::ZoomValuesEqual(zoom_level, current_zoom_level)) 91 continue; 92 if (zoom_level < current_zoom_level) { 93 host->SetZoomLevel(zoom_level); 94 content::RecordAction(UserMetricsAction("ZoomMinus")); 95 return; 96 } 97 content::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum")); 98 } 99 } else { 100 // Iterate through the zoom levels in normal order to find the next 101 // higher level based on the current zoom level for this page. 102 for (std::vector<double>::const_iterator i = zoom_levels.begin(); 103 i != zoom_levels.end(); ++i) { 104 double zoom_level = *i; 105 if (content::ZoomValuesEqual(zoom_level, current_zoom_level)) 106 continue; 107 if (zoom_level > current_zoom_level) { 108 host->SetZoomLevel(zoom_level); 109 content::RecordAction(UserMetricsAction("ZoomPlus")); 110 return; 111 } 112 } 113 content::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum")); 114 } 115 } 116 117 } // namespace chrome_page_zoom 118