Skip to content

Commit

Permalink
feat: implement for Android and iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
unindented committed Sep 6, 2023
1 parent 2c859ba commit df5756e
Show file tree
Hide file tree
Showing 19 changed files with 320 additions and 147 deletions.
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BasedOnStyle: Chromium
ColumnLimit: 100
3 changes: 3 additions & 0 deletions .stylua.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
column_width = 100
indent_type = "Spaces"
indent_width = 2
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Defold
Copyright (c) 2023 Myopic Design

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
# Native extension template
This template contains the basic setup for creation of a Defold native extension.
# Defold FontScale

You can learn more about native extensions in the [official manual](https://www.defold.com/manuals/extensions/).
Defold [native extension](https://www.defold.com/manuals/extensions/) that returns the preferred font scaling factor on the device.

- On Android, users can set the font scaling factor via **Settings > Display > Display size & text**.
- On iOS, users can set the font scaling factor via **Settings > Display and Brightness > Text Size**, or via **Settings > Accessibility > Display & Text Size > Larger Text**.

| Android | iOS |
| :----------------------------------------------------------------: | :--------------------------------------------------------: |
| ![Setting the font scaling factor on Android](docs/android@2x.png) | ![Setting the font scaling factor on iOS](docs/ios@2x.png) |

## Platform support

Defold FontScale currently supports Android and iOS. On all other platforms, it'll return `1.0`.

Contributions are welcome!

## Installation

You can use Defold FontScale by adding it as a [library dependency](https://defold.com/manuals/libraries/#setting-up-library-dependencies) in your project:

- Use a specific version for development and release to avoid breaking changes: https://github.com/myopic-design/defold-fontscale/releases
- Use the latest version only while evaluating and testing the asset: https://github.com/myopic-design/defold-fontscale/archive/master.zip.

## Usage

Get the font scaling factor with `fontscale.get()`, and then apply it to whatever nodes you want:

```lua
if fontscale then
local scale = fontscale.get()
go.set("#label", "scale", vmath.vector3(scale, scale, 0))
end
```
Binary file added docs/android@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ios@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions example/example.collection
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,56 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"label\"\n"
" type: \"label\"\n"
" data: \"size {\\n"
" x: 256.0\\n"
" y: 64.0\\n"
" z: 0.0\\n"
" w: 0.0\\n"
"}\\n"
"color {\\n"
" x: 1.0\\n"
" y: 1.0\\n"
" z: 1.0\\n"
" w: 1.0\\n"
"}\\n"
"outline {\\n"
" x: 0.0\\n"
" y: 0.0\\n"
" z: 0.0\\n"
" w: 1.0\\n"
"}\\n"
"shadow {\\n"
" x: 0.0\\n"
" y: 0.0\\n"
" z: 0.0\\n"
" w: 1.0\\n"
"}\\n"
"leading: 1.0\\n"
"tracking: 0.0\\n"
"pivot: PIVOT_W\\n"
"blend_mode: BLEND_MODE_ALPHA\\n"
"line_break: false\\n"
"text: \\\"Font scale: 1\\\"\\n"
"font: \\\"/example/example.font\\\"\\n"
"material: \\\"/builtins/fonts/label-df.material\\\"\\n"
"\"\n"
" position {\n"
" x: 50.0\n"
" y: 100.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
Expand Down
17 changes: 17 additions & 0 deletions example/example.font
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
font: "/builtins/fonts/vera_mo_bd.ttf"
material: "/builtins/fonts/font-df.material"
size: 18
antialias: 1
alpha: 1.0
outline_alpha: 0.0
outline_width: 0.0
shadow_alpha: 0.0
shadow_blur: 0
shadow_x: 0.0
shadow_y: 0.0
extra_characters: ""
output_format: TYPE_BITMAP
all_chars: false
cache_width: 0
cache_height: 0
render_mode: MODE_SINGLE_LAYER
33 changes: 6 additions & 27 deletions example/example.script
Original file line number Diff line number Diff line change
@@ -1,30 +1,9 @@
function init(self)
local s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
local reverse_s = myextension.reverse(s)
print(reverse_s) --> ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
end

function final(self)
-- Add finalization code here
-- Remove this function if not needed
end

function update(self, dt)
-- Add update code here
-- Remove this function if not needed
end

function on_message(self, message_id, message, sender)
-- Add message-handling code here
-- Remove this function if not needed
end

function on_input(self, action_id, action)
-- Add input-handling code here
-- Remove this function if not needed
end
msg.post("@render:", "use_fixed_fit_projection")

function on_reload(self)
-- Add reload-handling code here
-- Remove this function if not needed
timer.delay(1, true, function()
local scale = fontscale.get()
label.set_text("#label", "Font scale: " .. tostring(scale))
go.set("#label", "scale", vmath.vector3(scale, scale, 0))
end)
end
2 changes: 1 addition & 1 deletion myextension/ext.manifest → fontscale/ext.manifest
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# C++ symbol in your extension
name: "MyExtension"
name: "FontScale"
56 changes: 56 additions & 0 deletions fontscale/src/fontscale.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#define EXTENSION_NAME FontScale
#define LIB_NAME "FontScale"
#define MODULE_NAME "fontscale"

#include <dmsdk/sdk.h>
#include "fontscale_private.h"

static int GetFontScale(lua_State* L) {
DM_LUA_STACK_CHECK(L, 1);

lua_Number fontScale = ext_fontscale::getFontScale();

lua_pushnumber(L, fontScale);
return 1;
}

static const luaL_reg Module_methods[] = {{"get", GetFontScale}, {0, 0}};

static void LuaInit(lua_State* L) {
int top = lua_gettop(L);

luaL_register(L, MODULE_NAME, Module_methods);

lua_pop(L, 1);
assert(top == lua_gettop(L));
}

static dmExtension::Result AppInitializeFontScale(dmExtension::AppParams* params) {
return dmExtension::RESULT_OK;
}

static dmExtension::Result InitializeFontScale(dmExtension::Params* params) {
LuaInit(params->m_L);
return dmExtension::RESULT_OK;
}

static dmExtension::Result AppFinalizeFontScale(dmExtension::AppParams* params) {
return dmExtension::RESULT_OK;
}

static dmExtension::Result FinalizeFontScale(dmExtension::Params* params) {
return dmExtension::RESULT_OK;
}

static dmExtension::Result OnUpdateFontScale(dmExtension::Params* params) {
return dmExtension::RESULT_OK;
}

DM_DECLARE_EXTENSION(EXTENSION_NAME,
LIB_NAME,
AppInitializeFontScale,
AppFinalizeFontScale,
InitializeFontScale,
OnUpdateFontScale,
0,
FinalizeFontScale)
22 changes: 22 additions & 0 deletions fontscale/src/fontscale_android.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#if defined(DM_PLATFORM_ANDROID)

#include "fontscale_private.h"
#include "fontscale_jni.h"

namespace ext_fontscale {

float getFontScale() {
ThreadAttacher attacher;
JNIEnv* env = attacher.env;

jclass cls = ClassLoader(env).load("com.defold.fontscale.FontScale");
jmethodID method = env->GetStaticMethodID(cls, "getFontScale", "(Landroid/content/Context;)F");

jfloat return_value =
(jfloat)env->CallStaticFloatMethod(cls, method, dmGraphics::GetNativeAndroidActivity());
return return_value;
}

} // namespace ext_fontscale

#endif
9 changes: 9 additions & 0 deletions fontscale/src/fontscale_android.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.defold.fontscale;

import android.content.Context;

class FontScale {
public static float getFontScale(Context context) {
return context.getResources().getConfiguration().fontScale;
}
}
44 changes: 44 additions & 0 deletions fontscale/src/fontscale_ios.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#if defined(DM_PLATFORM_IOS)

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#include "fontscale_private.h"

namespace ext_fontscale {

float getFontScale() {
UIContentSizeCategory fontCategory =
[[UIApplication sharedApplication] preferredContentSizeCategory];
if ([fontCategory isEqualToString:UIContentSizeCategoryExtraSmall]) {
return 0.823;
} else if ([fontCategory isEqualToString:UIContentSizeCategorySmall]) {
return 0.882;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryMedium]) {
return 0.941;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryLarge]) {
return 1.0;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryExtraLarge]) {
return 1.118;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) {
return 1.235;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) {
return 1.353;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryAccessibilityMedium]) {
return 1.786;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryAccessibilityLarge]) {
return 2.143;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraLarge]) {
return 2.643;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraLarge]) {
return 3.143;
} else if ([fontCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraExtraLarge]) {
return 3.571;
} else {
return 1.0;
}
}

} // namespace ext_fontscale

#endif
57 changes: 57 additions & 0 deletions fontscale/src/fontscale_jni.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#if defined(DM_PLATFORM_ANDROID)
#include <dmsdk/sdk.h>

namespace ext_fontscale {

struct ThreadAttacher {
JNIEnv* env;
bool has_attached;
ThreadAttacher() : env(NULL), has_attached(false) {
if (dmGraphics::GetNativeAndroidJavaVM()->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
dmGraphics::GetNativeAndroidJavaVM()->AttachCurrentThread(&env, NULL);
has_attached = true;
}
}
~ThreadAttacher() {
if (has_attached) {
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
env->ExceptionClear();
dmGraphics::GetNativeAndroidJavaVM()->DetachCurrentThread();
}
}
};

struct ClassLoader {
private:
JNIEnv* env;
jobject class_loader_object;
jmethodID find_class;

public:
ClassLoader(JNIEnv* env) : env(env) {
jclass activity_class = env->FindClass("android/app/NativeActivity");
jmethodID get_class_loader =
env->GetMethodID(activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
class_loader_object =
env->CallObjectMethod(dmGraphics::GetNativeAndroidActivity(), get_class_loader);
jclass class_loader = env->FindClass("java/lang/ClassLoader");
find_class =
env->GetMethodID(class_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
env->DeleteLocalRef(activity_class);
env->DeleteLocalRef(class_loader);
}
~ClassLoader() { env->DeleteLocalRef(class_loader_object); }
jclass load(const char* class_name) {
jstring str_class_name = env->NewStringUTF(class_name);
jclass loaded_class =
(jclass)env->CallObjectMethod(class_loader_object, find_class, str_class_name);
env->DeleteLocalRef(str_class_name);
return loaded_class;
}
};

} // namespace ext_fontscale

#endif
11 changes: 11 additions & 0 deletions fontscale/src/fontscale_null.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#if !defined(DM_PLATFORM_ANDROID) && !defined(DM_PLATFORM_IOS)

namespace ext_fontscale {

float getFontScale() {
return 1;
}

} // namespace ext_fontscale

#endif
5 changes: 5 additions & 0 deletions fontscale/src/fontscale_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace ext_fontscale {

float getFontScale();

} // namespace ext_fontscale
6 changes: 3 additions & 3 deletions game.project
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ main_collection = /example/example.collectionc
shared_state = 1

[display]
width = 960
height = 640
width = 640
height = 1136

[project]
title = defold-fontscale

[library]
include_dirs = myextension
include_dirs = fontscale

0 comments on commit df5756e

Please sign in to comment.