Add dpi support for WebView.
In the "viewport" meta tag, you can specify "target-densityDpi".
If it is not specified, it uses the default, 160dpi as of today.
Then the 1.0 scale factor specified in the viewport tag means 100%
on G1 and 150% on Sholes. If you set "target-densityDpi" to
"device-dpi", then the 1.0 scale factor means 100% on both G1 and Sholes.
Implemented Safari's window.devicePixelRatio and css media query
device-pixel-ratio.
So if you use "device-dpi" and modify the css for font-size and image
src depending on window.devicePixelRatio, you can get a better page on
Sholes/Passion.
Here is a list of options for "target-densityDpi".
device-dpi: Use the device's native dpi as target dpi.
low-dpi: 120dpi
medium-dpi: 160dpi, which is also the default as of today
high-dpi: 240dpi
<number>: We take any number between 70 and 400 as a valid target dpi.
Fix http://b/issue?id=2071943
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index a8d2368..9692707 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -412,9 +412,10 @@
m_viewport_minimum_scale = 0;
m_viewport_maximum_scale = 0;
m_viewport_user_scalable = true;
- m_format_detection_telephone = true;
- m_format_detection_address = true;
- m_format_detection_email = true;
+ m_viewport_target_densitydpi = -1;
+ m_format_detection_telephone = true;
+ m_format_detection_address = true;
+ m_format_detection_email = true;
}
void Settings::setMetadataSettings(const String& key, const String& value)
@@ -465,7 +466,22 @@
// some sites, e.g. gomoviesapp.com, use "false".
if (value == "no" || value == "0" || value == "false") {
m_viewport_user_scalable = false;
- }
+ }
+ } else if (key == "target-densitydpi") {
+ if (value == "device-dpi") {
+ m_viewport_target_densitydpi = 0;
+ } else if (value == "low-dpi") {
+ m_viewport_target_densitydpi = 120;
+ } else if (value == "medium-dpi") {
+ m_viewport_target_densitydpi = 160;
+ } else if (value == "high-dpi") {
+ m_viewport_target_densitydpi = 240;
+ } else {
+ int dpi = value.toInt();
+ if (dpi >= 70 && dpi <= 400) {
+ m_viewport_target_densitydpi = dpi;
+ }
+ }
} else if (key == "telephone") {
if (value == "no") {
m_format_detection_telephone = false;
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 574fed7..162b21d 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -223,12 +223,13 @@
void resetMetadataSettings();
void setMetadataSettings(const String& key, const String& value);
- int viewportWidth() const { return m_viewport_width; }
+ int viewportWidth() const { return m_viewport_width; }
int viewportHeight() const { return m_viewport_height; }
int viewportInitialScale() const { return m_viewport_initial_scale; }
int viewportMinimumScale() const { return m_viewport_minimum_scale; }
int viewportMaximumScale() const { return m_viewport_maximum_scale; }
bool viewportUserScalable() const { return m_viewport_user_scalable; }
+ int viewportTargetDensityDpi() const { return m_viewport_target_densitydpi; }
bool formatDetectionAddress() const { return m_format_detection_address; }
bool formatDetectionEmail() const { return m_format_detection_email; }
bool formatDetectionTelephone() const { return m_format_detection_telephone; }
@@ -331,6 +332,9 @@
int m_viewport_maximum_scale;
// default is yes
bool m_viewport_user_scalable : 1;
+ // range is from 70 to 400. 0 is a special value means device-dpi
+ // default is -1, which means undefined.
+ int m_viewport_target_densitydpi;
// default is yes
bool m_format_detection_telephone : 1;
// default is yes
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 6dc7faf..93869c3 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -81,8 +81,8 @@
float ChromeClientAndroid::scaleFactor()
{
- // only seems to be used for dashboard regions, so just return 1
- return 1;
+ ASSERT(m_webFrame);
+ return m_webFrame->density();
}
void ChromeClientAndroid::focus() {
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index f366479..f768fd0 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -145,6 +145,7 @@
jmethodID mDecidePolicyForFormResubmission;
jmethodID mRequestFocus;
jmethodID mGetRawResFilename;
+ jmethodID mDensity;
AutoJObject frame(JNIEnv* env) {
return getRealObject(env, mObj);
}
@@ -200,6 +201,7 @@
"()V");
mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename",
"(I)Ljava/lang/String;");
+ mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
@@ -218,6 +220,7 @@
LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission");
LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus");
LOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename");
+ LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
mUserAgent = WebCore::String();
mUserInitiatedClick = false;
@@ -715,6 +718,15 @@
return to_string(env, ret);
}
+float
+WebFrame::density() const
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity);
+ checkException(env);
+ return dpi;
+}
+
// ----------------------------------------------------------------------------
static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
{
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 353545e..609aecc 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -109,6 +109,8 @@
WebCore::String getRawResourceFilename(RAW_RES_ID) const;
+ float density() const;
+
/**
* When the user initiates a click (via trackball, enter-press, or touch),
* we set mUserInitiatedClick to true. If a load happens due to this click,
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index dc51a8f..07e7633 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -148,6 +148,7 @@
jfieldID m_viewportMinimumScale;
jfieldID m_viewportMaximumScale;
jfieldID m_viewportUserScalable;
+ jfieldID m_viewportDensityDpi;
jfieldID m_webView;
} gWebViewCoreFields;
@@ -2557,6 +2558,7 @@
env->SetIntField(obj, gWebViewCoreFields.m_viewportMinimumScale, s->viewportMinimumScale());
env->SetIntField(obj, gWebViewCoreFields.m_viewportMaximumScale, s->viewportMaximumScale());
env->SetBooleanField(obj, gWebViewCoreFields.m_viewportUserScalable, s->viewportUserScalable());
+ env->SetIntField(obj, gWebViewCoreFields.m_viewportDensityDpi, s->viewportTargetDensityDpi());
#endif
}
@@ -2841,6 +2843,10 @@
"mViewportUserScalable", "Z");
LOG_ASSERT(gWebViewCoreFields.m_viewportUserScalable,
"Unable to find android/webkit/WebViewCore.mViewportUserScalable");
+ gWebViewCoreFields.m_viewportDensityDpi = env->GetFieldID(widget,
+ "mViewportDensityDpi", "I");
+ LOG_ASSERT(gWebViewCoreFields.m_viewportDensityDpi,
+ "Unable to find android/webkit/WebViewCore.mViewportDensityDpi");
gWebViewCoreFields.m_webView = env->GetFieldID(widget,
"mWebView", "Landroid/webkit/WebView;");
LOG_ASSERT(gWebViewCoreFields.m_webView,