Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ios, android): support loading font dynamically #4067

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1ec89cd
feat(ios, android): support loading font dynamically
Cyunong Oct 15, 2024
91c0b2d
fix(ios, android): Some fixes for loading font dynamically
Cyunong Oct 20, 2024
42538c1
feat(demo): add demo for dynamically load font
Cyunong Oct 17, 2024
1ce1cb2
fix: fix the "given a font name rather than font family" condition
Cyunong Oct 21, 2024
455118c
feat(doc): add FontLoaderModule
Cyunong Oct 31, 2024
02cf5d6
fix(android): improve the implemention of loading font dynamically
Cyunong Oct 21, 2024
5490c79
fix(android, react, vue): add font load state, change resolve from vo…
Cyunong Oct 22, 2024
76546e9
fix(ios): remove IO operations from main thread and ensure thread safety
Cyunong Oct 22, 2024
48e684f
fix(ios): fix the "given a font name rather than font family" condition
Cyunong Oct 22, 2024
e5624b5
fead(ios, android): support load font from JSbundle
Cyunong Oct 24, 2024
074c238
feat(ios): add unitest for FontLoaderModule
Cyunong Oct 24, 2024
15e1fdf
fix(android, ios): improve dynamically load font according to code re…
Cyunong Oct 24, 2024
68f1af9
fix(doc): add docs for fontUrl in JSBundle path format
Cyunong Oct 25, 2024
ca9e7c4
fix(android): fix the use of weak reference in font loader
Cyunong Oct 31, 2024
c34cf0d
fix(ios, android): make the code more standardized for font loader
Cyunong Nov 12, 2024
5b38b3f
fix(ios): fix HippyFontLoaderTest using local file
Cyunong Nov 12, 2024
cd0a84a
Merge remote-tracking branch 'upstream/main'
Cyunong Nov 12, 2024
4b9c093
fix(ios): improve code after discussion
Cyunong Dec 11, 2024
af292a8
Merge remote-tracking branch 'upstream/main'
Cyunong Dec 11, 2024
e20859d
fix(ios): change vfs load function in fontLoader
Cyunong Dec 11, 2024
3a4b3c1
Merge branch 'main' into main
wwwcg Dec 16, 2024
6cabb60
fix(ios): update hippy.podspec due to code coverage failure
wwwcg Dec 16, 2024
f69ad77
Update HippyFontLoaderTest.m
wwwcg Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/api/hippy-react/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,22 @@ AsyncStorage 是一个简单的、异步的、持久化的 Key-Value 存储系

---

# FontLoaderModule

提供通过url动态下载远程字体或者动态加载JSBundle包中字体的能力,下载的远程字体将保存在应用Cache目录下,由Hippy统一管理,可能被终端系统删除。常用字体不推荐使用该模块动态远程下载。


## 方法

### FontLoaderModule.load

`(fontFamily: string, fontUrl: string) => Promise<string>` 通过fontUrl异步下载字体,下载完成后会刷新终端文本。

> - fontFamily - 下载字体的字体家族,用于保存文件和检索字体文件
> - fontUrl - 下载字体的地址,可以是http网络地址,也可以本地文件地址或者以“hpfile://./”为前缀的JSbundle包中的相对地址

---

# NetInfo

[[NetInfo 范例]](//github.com/Tencent/Hippy/tree/master/examples/hippy-react-demo/src/modules/NetInfo)
Expand Down
15 changes: 15 additions & 0 deletions docs/api/hippy-vue/vue-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,21 @@ console.log(Vue.Native.getElemCss(this.demon1Point)) // => { height: 80, left: 0

---

# FontLoaderModule

提供通过url动态下载远程字体或者动态加载JSBundle包中字体的能力,下载的远程字体将保存在应用Cache目录下,由Hippy统一管理,可能被终端系统删除。常用字体不推荐使用该模块动态远程下载。

## 方法

### FontLoader.load

`(fontFamily: string, fontUrl: string) => Promise<string>` 通过fontUrl异步下载字体,下载完成后会刷新终端文本。

> * fontFamily - 下载字体的字体家族,用于保存文件和检索字体文件
> * fontUrl - 下载字体的地址,可以是http网络地址,也可以本地文件地址或者以“hpfile://./”为前缀的JSbundle包中的相对地址

---

# ImageLoader

通过该模块可以对远程图片进行相应操作
Expand Down
8 changes: 8 additions & 0 deletions docs/api/style/appearance.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@
| ------------------------ | ---- | ------------ |
| enum('normal', 'italic') | 否 | Android、iOS |

# fontUrl

动态加载字体的url,会在渲染时异步动态加载,可以是远程字体地址或者是使用JSBundle包中字体路径的相对地址。

| 类型 | 必需 | 支持平台 |
| ------------------------ | ---- | ------------ |
| string | 否 | Android、iOS |

# fontWeight

字体粗细
Expand Down
141 changes: 141 additions & 0 deletions driver/js/examples/hippy-react-demo/src/modules/FontLoader/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import React from 'react';
import {
View,
ScrollView,
StyleSheet,
Text,
TextInput,
FontLoaderModule,
} from '@hippy/react';

const styles = StyleSheet.create({
itemTitle: {
alignItems: 'flex-start',
justifyContent: 'center',
height: 40,
borderWidth: 1,
borderStyle: 'solid',
borderColor: '#e0e0e0',
borderRadius: 2,
backgroundColor: '#fafafa',
padding: 10,
marginTop: 10,
},
wrapper: {
borderColor: '#eee',
borderWidth: 1,
borderStyle: 'solid',
paddingHorizontal: 10,
paddingVertical: 5,
marginVertical: 10,
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
},
infoContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
marginTop: 5,
marginBottom: 5,
flexWrap: 'wrap',
},
text_style: {
fontSize: 16,
},
input_url_style: {
height: 60,
marginVertical: 10,
fontSize: 16,
color: '#242424',
},
input_font_style: {
height: 30,
marginVertical: 10,
fontSize: 16,
color: '#242424',
},
});

export default class LoadFontExample extends React.Component {
constructor(props) {
super(props);
this.state = {
fontFamily: '',
inputFontFamily: '',
fontUrl: '',
loadState: '',
};
}

fillExample() {
this.setState({ inputFontFamily: 'TencentSans W7' });
this.setState({ fontUrl: 'https://infra-packages.openhippy.com/test/resources/TencentSans_W7.ttf' });
// this.setState({ fontUrl: 'hpfile://./assets/hanyihuaxianzijianti.ttf' }
}

async loadFont() {
this.setState({ fontFamily: this.state.inputFontFamily });
await FontLoaderModule.load(this.state.fontFamily, this.state.fontUrl)
.then((result) => {
this.setState({ loadState: result });
})
.catch((error) => {
this.setState({ loadState: error });
});
}

render() {
return (
<ScrollView style={{ paddingHorizontal: 10 }}>
<View style={styles.itemTitle}>
<Text>通过组件fontUrl属性动态下载并使用字体</Text>
</View>
<Text style={styles.text_style}
fontFamily='TencentSans W3'
fontUrl='https://infra-packages.openhippy.com/test/resources/TencentSans_W3.otf'>
This sentence will use font 'TencentSans W3' downloaded dynamically according to 'fontUrl' property.
</Text>
<Text style={styles.text_style}
fontFamily='TencentSans W3'>
这句话将使用通过fontUrl属性下载的'TencentSans W3'字体.
</Text>
<View style={styles.itemTitle}>
<Text>下载并使用字体</Text>
</View>
<Text style={styles.text_style} fontFamily={this.state.fontFamily}>
This sentence will be set the specific font after download.
</Text>
<Text style={styles.text_style} fontFamily={this.state.fontFamily}>
这句话将用指定的下载字体显示。
</Text>
<TextInput
style={styles.input_font_style}
fontFamily={this.state.fontFamily}
placeholder="Input font family"
value={this.state.inputFontFamily}
onChangeText={(text) => this.setState({inputFontFamily: text})}
/>
<TextInput
style={styles.input_url_style}
placeholder="Input font url"
value={this.state.fontUrl}
onChangeText={(text) => this.setState({fontUrl: text})}
/>
<View style={[styles.wrapper]}
>
<View style={[styles.infoContainer]}>
<View style={{ backgroundColor: 'grey', padding: 10, borderRadius: 10, marginRight: 10 }} onClick={() => this.fillExample()}>
<Text style={{ color: 'white' }}>填充示例</Text>
</View>
<View style={{ backgroundColor: 'grey', padding: 10, borderRadius: 10, marginRight: 10 }} onClick={() => this.loadFont()}>
<Text style={{ color: 'white' }}>下载字体</Text>
</View>
</View>
</View>
<Text>load state: {this.state.loadState}</Text>
</ScrollView>
);
}
}
1 change: 1 addition & 0 deletions driver/js/examples/hippy-react-demo/src/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export { default as AsyncStorage } from './AsyncStorage';
export { default as NetInfo } from './NetInfo';
export { default as WebSocket } from './WebSocket';
export { default as UIManagerModule } from './UIManagerModule';
export { default as FontLoader } from './FontLoader';
8 changes: 8 additions & 0 deletions driver/js/examples/hippy-react-demo/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ export default [
type: Type.MODULE,
},
},
{
path: '/FontLoader',
name: 'FontLoader 模块',
component: PAGE_LIST.FontLoader,
meta: {
type: Type.MODULE,
},
},
{
path: '/Others',
name: 'Others',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,48 @@
</div>
</div>

<!-- FontLoader使用 -->
<div
v-if="Vue.Native.FontLoader"
class="native-block"
>
<label class="vue-native-title">FontLoader 使用</label>
<span :fontFamily="fontFamily">
This sentence will be set the specific font after download.
</span>
<span :fontFamily="fontFamily">
这句话将用指定的下载字体显示。
</span>
<input
:fontFamily="fontFamily"
v-model="inputFontFaimly"
placeholder="Input font family"
placeholder-text-color="#40b883"
:editable="true"
>
<input
v-model="fontUrl"
placeholder="Input font url"
placeholder-text-color="#40b883"
:editable="true"
>
<div class="item-wrapper">
<button
class="item-button"
@click="fillExample"
>
<span>填写示例</span>
</button>
<button
class="item-button"
@click="load"
>
<span>下载字体</span>
</button>
</div>
<span>load state: {{ loadState }}</span>
</div>

<!-- Fetch使用 -->
<div
class="native-block"
Expand Down Expand Up @@ -323,6 +365,10 @@ export default {
cookieString: 'ready to set',
cookiesValue: '',
hasLayout: false,
inputFontFaimly: '',
fontUrl: '',
fontFamily: '',
loadState: '',
};
},
async created() {
Expand All @@ -334,7 +380,7 @@ export default {
this.netInfoListener = Vue.Native.NetInfo.addEventListener('change', (info) => {
this.netInfoText = `收到通知: ${info.network_info}`;
});
fetch('https://hippyjs.org', {
fetch('https://openhippy.com/', {
mode: 'no-cors', // 2.14.0 or above supports other options(not only method/headers/url/body)
}).then((responseJson) => {
this.fetchText = `成功状态: ${responseJson.status}`;
Expand Down Expand Up @@ -402,12 +448,29 @@ export default {
console.log('ImageLoader getSize', result);
this.imageSize = `${result.width}x${result.height}`;
},
async load() {
this.fontFamily = this.inputFontFaimly;
console.log('fontFamily:', this.fontFamily)
console.log('fontUrl:', this.fontUrl)
let result;
try {
result = await Vue.Native.FontLoader.load(this.fontFamily, this.fontUrl);
} catch (error) {
result = error.message;
}
this.loadState = result;
},
fillExample() {
this.inputFontFaimly = 'HYHuaXianZi J';
this.fontUrl = 'https://zf.sc.chinaz.com/Files/DownLoad/upload/2024/1009/hanyihuaxianzijianti.ttf';
},

setCookie() {
Vue.Native.Cookie.set('https://hippyjs.org', 'name=hippy;network=mobile');
Vue.Native.Cookie.set('https://openhippy.com/', 'name=hippy;network=mobile');
this.cookieString = '\'name=hippy;network=mobile\' is set';
},
getCookie() {
Vue.Native.Cookie.getAll('https://hippyjs.org').then((cookies) => {
Vue.Native.Cookie.getAll('https://openhippy.com/').then((cookies) => {
this.cookiesValue = cookies;
});
},
Expand Down
Loading
Loading