Skip to content

Commit

Permalink
Android: Add opt-in high-dpi support
Browse files Browse the repository at this point in the history
Opt-in by setting android.app.auto_screen_scale_factor
to true in AndroidManifest.xml. This will enable
devicePixelRatio scaling in QtGui using a scale
factor provided by Android DisplayMetrics.

Note that the Android style is not currently supported:
it already accounts for different display densities
which results in incorrect visual sizes when enabling
devicePixelRatio scaling.

Implementation: Bring DisplayMetrics::density through
to setDisplayMetrics in androidjnimain.cpp, similar
to what is done for "scaledDensity". Override
QPlatformScreen::pixelDensity(), which forwards the
scale factor to QtGui.

[The difference between "density" and "scaledDensity"
is that the former is a physical display density factor
which corresponds closely to devicePixelRatio in Qt,
while the latter also includes the Android global font
scale factor.]

Scale the global font pixel size in qandroidplatformtheme.cpp
to keep the visual font size constant.

Based on an initial patch from Daiwei Li <daiweili@suitabletech.com>

Task-number: QTBUG-46615
Change-Id: Ia51f99bf6dda485a57413949246c7b32cb47e8dd
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
  • Loading branch information
msorvig committed Oct 26, 2015
1 parent 45bb9c2 commit b2d24dc
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels, w, h,
metrics.xdpi, metrics.ydpi, metrics.scaledDensity, metrics.density);
if (m_startApplicationRunnable != null) {
m_startApplicationRunnable.run();
m_startApplicationRunnable = null;
Expand Down
14 changes: 10 additions & 4 deletions src/android/jar/src/org/qtproject/qt5/android/QtNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class QtNative
private static double m_displayMetricsXDpi = .0;
private static double m_displayMetricsYDpi = .0;
private static double m_displayMetricsScaledDensity = 1.0;
private static double m_displayMetricsDensity = 1.0;
private static int m_oldx, m_oldy;
private static final int m_moveThreshold = 0;
private static ClipboardManager m_clipboardManager = null;
Expand Down Expand Up @@ -229,7 +230,8 @@ public static boolean startApplication(String params,
m_displayMetricsDesktopHeightPixels,
m_displayMetricsXDpi,
m_displayMetricsYDpi,
m_displayMetricsScaledDensity);
m_displayMetricsScaledDensity,
m_displayMetricsDensity);
if (params.length() > 0 && !params.startsWith("\t"))
params = "\t" + params;
startQtApplication(f.getAbsolutePath() + params, environment);
Expand All @@ -244,7 +246,8 @@ public static void setApplicationDisplayMetrics(int screenWidthPixels,
int desktopHeightPixels,
double XDpi,
double YDpi,
double scaledDensity)
double scaledDensity,
double density)
{
/* Fix buggy dpi report */
if (XDpi < android.util.DisplayMetrics.DENSITY_LOW)
Expand All @@ -260,7 +263,8 @@ public static void setApplicationDisplayMetrics(int screenWidthPixels,
desktopHeightPixels,
XDpi,
YDpi,
scaledDensity);
scaledDensity,
density);
} else {
m_displayMetricsScreenWidthPixels = screenWidthPixels;
m_displayMetricsScreenHeightPixels = screenHeightPixels;
Expand All @@ -269,6 +273,7 @@ public static void setApplicationDisplayMetrics(int screenWidthPixels,
m_displayMetricsXDpi = XDpi;
m_displayMetricsYDpi = YDpi;
m_displayMetricsScaledDensity = scaledDensity;
m_displayMetricsDensity = density;
}
}
}
Expand Down Expand Up @@ -621,7 +626,8 @@ public static native void setDisplayMetrics(int screenWidthPixels,
int desktopHeightPixels,
double XDpi,
double YDpi,
double scaledDensity);
double scaledDensity,
double density);
public static native void handleOrientationChanged(int newRotation, int nativeOrientation);
// screen methods

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,12 @@ public void onCreate(Bundle savedInstanceState)
} else {
ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t";
}

if (m_activityInfo.metaData.containsKey("android.app.auto_screen_scale_factor")
&& m_activityInfo.metaData.getBoolean("android.app.auto_screen_scale_factor")) {
ENVIRONMENT_VARIABLES += "QT_AUTO_SCREEN_SCALE_FACTOR=1\t";
}

startApp(true);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/android/templates/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running -->

<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor -->
</activity>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
Expand Down
13 changes: 11 additions & 2 deletions src/plugins/platforms/android/androidjnimain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>

#include <qpa/qwindowsysteminterface.h>

Expand Down Expand Up @@ -109,6 +110,7 @@ static QAndroidPlatformIntegration *m_androidPlatformIntegration = nullptr;
static int m_desktopWidthPixels = 0;
static int m_desktopHeightPixels = 0;
static double m_scaledDensity = 0;
static double m_density = 1.0;

static volatile bool m_pauseApplication;

Expand Down Expand Up @@ -157,6 +159,11 @@ namespace QtAndroid
return m_scaledDensity;
}

double pixelDensity()
{
return m_density;
}

JavaVM *javaVM()
{
return m_javaVM;
Expand Down Expand Up @@ -547,7 +554,8 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
jint widthPixels, jint heightPixels,
jint desktopWidthPixels, jint desktopHeightPixels,
jdouble xdpi, jdouble ydpi, jdouble scaledDensity)
jdouble xdpi, jdouble ydpi,
jdouble scaledDensity, jdouble density)
{
// Android does not give us the correct screen size for immersive mode, but
// the surface does have the right size
Expand All @@ -558,6 +566,7 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
m_desktopWidthPixels = desktopWidthPixels;
m_desktopHeightPixels = desktopHeightPixels;
m_scaledDensity = scaledDensity;
m_density = density;

if (!m_androidPlatformIntegration) {
QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,
Expand Down Expand Up @@ -683,7 +692,7 @@ static JNINativeMethod methods[] = {
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
{"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
{"terminateQt", "()V", (void *)terminateQt},
{"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics},
{"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics},
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/android/androidjnimain.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ namespace QtAndroid
int desktopWidthPixels();
int desktopHeightPixels();
double scaledDensity();
double pixelDensity();
JavaVM *javaVM();
AAssetManager *assetManager();
jclass applicationClass();
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/platforms/android/qandroidplatformscreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ QDpi QAndroidPlatformScreen::logicalDpi() const
return QDpi(lDpi, lDpi);
}

qreal QAndroidPlatformScreen::pixelDensity() const
{
return QtAndroid::pixelDensity();
}

Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
{
return QAndroidPlatformIntegration::m_orientation;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/android/qandroidplatformscreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public slots:

private:
QDpi logicalDpi() const;
qreal pixelDensity() const;
Qt::ScreenOrientation orientation() const;
Qt::ScreenOrientation nativeOrientation() const;
void surfaceChanged(JNIEnv *env, jobject surface, int w, int h);
Expand Down
4 changes: 3 additions & 1 deletion src/plugins/platforms/android/qandroidplatformtheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
**
****************************************************************************/

#include "androidjnimain.h"
#include "androidjnimenu.h"
#include "qandroidplatformtheme.h"
#include "qandroidplatformmenubar.h"
Expand Down Expand Up @@ -216,6 +217,7 @@ QJsonObject AndroidStyle::loadStyleData()

static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
{
double pixelDensity = qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") ? QtAndroid::pixelDensity() : 1.0;
std::shared_ptr<AndroidStyle> style(new AndroidStyle);
style->m_styleData = AndroidStyle::loadStyleData();
if (style->m_styleData.isEmpty())
Expand Down Expand Up @@ -245,7 +247,7 @@ static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
// Font size (in pixels)
attributeIterator = item.find(QLatin1String("TextAppearance_textSize"));
if (attributeIterator != item.constEnd())
font.setPixelSize(int(attributeIterator.value().toDouble()));
font.setPixelSize(int(attributeIterator.value().toDouble() / pixelDensity));

// Font style
attributeIterator = item.find(QLatin1String("TextAppearance_textStyle"));
Expand Down

0 comments on commit b2d24dc

Please sign in to comment.