1
- import {
2
- htmlProperty ,
3
- LabelBase ,
4
- lineBreakProperty ,
5
- maxLinesProperty
6
- } from './label-common' ;
1
+ import { htmlProperty , LabelBase , lineBreakProperty , maxLinesProperty } from './label-common' ;
7
2
// import { backgroundColorProperty } from 'tns-core-modules/ui/page/page';
8
- import {
9
- TextTransform ,
10
- WhiteSpace ,
11
- whiteSpaceProperty
12
- } from 'tns-core-modules/ui/text-base/text-base' ;
3
+ import { TextTransform , WhiteSpace , whiteSpaceProperty } from 'tns-core-modules/ui/text-base/text-base' ;
13
4
import { Font } from 'tns-core-modules/ui/styling/font' ;
5
+ Font . prototype . getAndroidTypeface = function ( ) {
6
+ if ( ! this . _typeface ) {
7
+ this . _typeface = createTypeface ( this ) ;
8
+ }
9
+ return this . _typeface ;
10
+ } ;
14
11
// import { Span } from 'tns-core-modules/text/span';
15
12
16
13
export * from './label-common' ;
17
14
15
+ let _useAndroidX ;
16
+ function useAndroidX ( ) {
17
+ if ( _useAndroidX === undefined ) {
18
+ _useAndroidX = ! ! ( global as any ) . androidx && ! ! ( global as any ) . androidx . appcompat ;
19
+ }
20
+ return _useAndroidX ;
21
+ }
22
+ let _ContentPackageName : typeof android . support . v4 . content ;
23
+ function ContentPackageName ( ) {
24
+ if ( _ContentPackageName === undefined ) {
25
+ _ContentPackageName = useAndroidX ( ) ? ( global as any ) . androidx . core . content : android . support . v4 . content ;
26
+ }
27
+ return _ContentPackageName ;
28
+ }
29
+ import * as application from 'tns-core-modules/application' ;
30
+ import * as fs from 'tns-core-modules/file-system' ;
31
+ import { categories as traceCategories , isEnabled as traceEnabled , messageType as traceMessageType , write as traceWrite } from 'tns-core-modules/trace' ;
32
+ import { Font as FontBase , FontWeight , genericFontFamilies , parseFontFamily } from 'tns-core-modules/ui/styling/font-common' ;
33
+ let appAssets : android . content . res . AssetManager ;
34
+ const typefaceCache = new Map < string , android . graphics . Typeface > ( ) ;
35
+ const FONTS_BASE_PATH = '/fonts/' ;
36
+ function loadFontFromFile ( fontFamily : string ) : android . graphics . Typeface {
37
+ if ( fontFamily . startsWith ( 'res/' ) ) {
38
+ let result = typefaceCache . get ( fontFamily ) ;
39
+ if ( ! result ) {
40
+ const context = application . android . context ;
41
+ const fontID = context . getResources ( ) . getIdentifier ( fontFamily . slice ( 4 ) , 'font' , context . getPackageName ( ) ) ;
42
+ result = ContentPackageName ( ) . res . ResourcesCompat . getFont ( context , fontID ) ;
43
+ if ( result ) {
44
+ typefaceCache . set ( fontFamily , result ) ;
45
+ }
46
+ return result ;
47
+ }
48
+ }
49
+ appAssets = appAssets || application . android . context . getAssets ( ) ;
50
+ if ( ! appAssets ) {
51
+ return null ;
52
+ }
53
+
54
+ let result = typefaceCache . get ( fontFamily ) ;
55
+ // Check for undefined explicitly as null mean we tried to load the font, but failed.
56
+ if ( result === undefined ) {
57
+ result = null ;
58
+
59
+ let fontAssetPath : string ;
60
+ const basePath = fs . path . join ( fs . knownFolders . currentApp ( ) . path , 'fonts' , fontFamily ) ;
61
+ if ( fs . File . exists ( basePath + '.ttf' ) ) {
62
+ fontAssetPath = FONTS_BASE_PATH + fontFamily + '.ttf' ;
63
+ } else if ( fs . File . exists ( basePath + '.otf' ) ) {
64
+ fontAssetPath = FONTS_BASE_PATH + fontFamily + '.otf' ;
65
+ } else {
66
+ if ( traceEnabled ( ) ) {
67
+ traceWrite ( 'Could not find font file for ' + fontFamily , traceCategories . Error , traceMessageType . error ) ;
68
+ }
69
+ }
70
+
71
+ if ( fontAssetPath ) {
72
+ try {
73
+ fontAssetPath = fs . path . join ( fs . knownFolders . currentApp ( ) . path , fontAssetPath ) ;
74
+ result = android . graphics . Typeface . createFromFile ( fontAssetPath ) ;
75
+ } catch ( e ) {
76
+ if ( traceEnabled ( ) ) {
77
+ traceWrite ( 'Error loading font asset: ' + fontAssetPath , traceCategories . Error , traceMessageType . error ) ;
78
+ }
79
+ }
80
+ }
81
+ typefaceCache . set ( fontFamily , result ) ;
82
+ }
83
+
84
+ return result ;
85
+ }
86
+
87
+ function createTypeface ( font : Font ) : android . graphics . Typeface {
88
+ let fontStyle = 0 ;
89
+ if ( font . isBold ) {
90
+ fontStyle |= android . graphics . Typeface . BOLD ;
91
+ }
92
+ if ( font . isItalic ) {
93
+ fontStyle |= android . graphics . Typeface . ITALIC ;
94
+ }
95
+
96
+ // http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
97
+ const fonts = parseFontFamily ( font . fontFamily ) ;
98
+ let result = null ;
99
+ for ( let i = 0 ; i < fonts . length ; i ++ ) {
100
+ switch ( fonts [ i ] . toLowerCase ( ) ) {
101
+ case genericFontFamilies . serif :
102
+ result = android . graphics . Typeface . create ( 'serif' + getFontWeightSuffix ( font . fontWeight ) , fontStyle ) ;
103
+ break ;
104
+
105
+ case genericFontFamilies . sansSerif :
106
+ case genericFontFamilies . system :
107
+ result = android . graphics . Typeface . create ( 'sans-serif' + getFontWeightSuffix ( font . fontWeight ) , fontStyle ) ;
108
+ break ;
109
+
110
+ case genericFontFamilies . monospace :
111
+ result = android . graphics . Typeface . create ( 'monospace' + getFontWeightSuffix ( font . fontWeight ) , fontStyle ) ;
112
+ break ;
113
+
114
+ default :
115
+ result = loadFontFromFile ( fonts [ i ] ) ;
116
+ if ( result && fontStyle ) {
117
+ result = android . graphics . Typeface . create ( result , fontStyle ) ;
118
+ }
119
+ break ;
120
+ }
121
+
122
+ if ( result ) {
123
+ // Found the font!
124
+ break ;
125
+ }
126
+ }
127
+
128
+ if ( ! result ) {
129
+ result = android . graphics . Typeface . create ( 'sans-serif' + getFontWeightSuffix ( font . fontWeight ) , fontStyle ) ;
130
+ }
131
+
132
+ return result ;
133
+ }
134
+
135
+ function getFontWeightSuffix ( fontWeight : FontWeight ) : string {
136
+ switch ( fontWeight ) {
137
+ case FontWeight . THIN :
138
+ return android . os . Build . VERSION . SDK_INT >= 16 ? '-thin' : '' ;
139
+ case FontWeight . EXTRA_LIGHT :
140
+ case FontWeight . LIGHT :
141
+ return android . os . Build . VERSION . SDK_INT >= 16 ? '-light' : '' ;
142
+ case FontWeight . NORMAL :
143
+ case '400' :
144
+ case undefined :
145
+ case null :
146
+ return '' ;
147
+ case FontWeight . MEDIUM :
148
+ case FontWeight . SEMI_BOLD :
149
+ return android . os . Build . VERSION . SDK_INT >= 21 ? '-medium' : '' ;
150
+ case FontWeight . BOLD :
151
+ case '700' :
152
+ case FontWeight . EXTRA_BOLD :
153
+ return '' ;
154
+ case FontWeight . BLACK :
155
+ return android . os . Build . VERSION . SDK_INT >= 21 ? '-black' : '' ;
156
+ default :
157
+ throw new Error ( `Invalid font weight: "${ fontWeight } "` ) ;
158
+ }
159
+ }
160
+
18
161
export class Label extends LabelBase {
19
162
nativeViewProtected : android . widget . TextView ;
20
163
@@ -28,9 +171,7 @@ export class Label extends LabelBase {
28
171
29
172
// This makes the html <a href...> work
30
173
nativeView . setLinksClickable ( false ) ;
31
- nativeView . setMovementMethod (
32
- android . text . method . LinkMovementMethod . getInstance ( )
33
- ) ;
174
+ nativeView . setMovementMethod ( android . text . method . LinkMovementMethod . getInstance ( ) ) ;
34
175
}
35
176
36
177
public resetNativeView ( ) : void {
@@ -51,9 +192,7 @@ export class Label extends LabelBase {
51
192
}
52
193
const nativeView = this . nativeViewProtected ;
53
194
nativeView . setAutoLinkMask ( mask ) ;
54
- const spannableStringBuilder = createSpannableStringBuilder (
55
- android . text . Html . fromHtml ( value )
56
- ) ;
195
+ const spannableStringBuilder = createSpannableStringBuilder ( android . text . Html . fromHtml ( value ) ) ;
57
196
nativeView . setText ( spannableStringBuilder as any ) ;
58
197
59
198
// textProperty.nativeValueChange(this, value === null || value === undefined ? '' : value.toString());
@@ -79,27 +218,13 @@ export class Label extends LabelBase {
79
218
nativeView . setEllipsize ( android . text . TextUtils . TruncateAt . START ) ;
80
219
break ;
81
220
case 'middle' :
82
- nativeView . setEllipsize (
83
- android . text . TextUtils . TruncateAt . MIDDLE
84
- ) ;
221
+ nativeView . setEllipsize ( android . text . TextUtils . TruncateAt . MIDDLE ) ;
85
222
break ;
86
223
case 'none' :
87
224
nativeView . setEllipsize ( null ) ;
88
225
break ;
89
226
}
90
227
}
91
- [ whiteSpaceProperty . setNative ] ( value : WhiteSpace ) {
92
- const nativeView = this . nativeTextViewProtected ;
93
- switch ( value ) {
94
- case 'initial' :
95
- case 'normal' :
96
- nativeView . setEllipsize ( null ) ;
97
- break ;
98
- case 'nowrap' :
99
- nativeView . setEllipsize ( android . text . TextUtils . TruncateAt . END ) ;
100
- break ;
101
- }
102
- }
103
228
}
104
229
105
230
// function isBold(fontWeight: FontWeight): boolean {
@@ -117,10 +242,7 @@ function getCapitalizedString(str: string): string {
117
242
return newWords . join ( ' ' ) ;
118
243
}
119
244
120
- export function getTransformedText (
121
- text : string ,
122
- textTransform : TextTransform
123
- ) : string {
245
+ export function getTransformedText ( text : string , textTransform : TextTransform ) : string {
124
246
switch ( textTransform ) {
125
247
case 'uppercase' :
126
248
return text . toUpperCase ( ) ;
@@ -134,47 +256,22 @@ export function getTransformedText(
134
256
}
135
257
}
136
258
137
- function createSpannableStringBuilder (
138
- spannedString : android . text . Spanned
139
- ) : android . text . SpannableStringBuilder {
259
+ function createSpannableStringBuilder ( spannedString : android . text . Spanned ) : android . text . SpannableStringBuilder {
140
260
if ( ! spannedString ) {
141
261
return null ;
142
262
}
143
- const builder = new android . text . SpannableStringBuilder (
144
- spannedString as any
145
- ) ;
146
- const spans : native . Array <
147
- android . text . style . TypefaceSpan
148
- > = builder . getSpans (
149
- 0 ,
150
- builder . length ( ) ,
151
- android . text . style . TypefaceSpan . class
152
- ) ;
263
+ const builder = new android . text . SpannableStringBuilder ( spannedString as any ) ;
264
+ const spans : native . Array < android . text . style . TypefaceSpan > = builder . getSpans ( 0 , builder . length ( ) , android . text . style . TypefaceSpan . class ) ;
153
265
for ( let index = 0 ; index < spans . length ; index ++ ) {
154
266
const span = spans [ index ] ;
155
267
const start = builder . getSpanStart ( span ) ;
156
268
const end = builder . getSpanEnd ( span ) ;
157
269
const fontFamily = span . getFamily ( ) ;
158
270
const style = fontFamily . split ( '-' ) [ 1 ] || builder . removeSpan ( span ) ;
159
- const font = new Font (
160
- fontFamily ,
161
- 0 ,
162
- style === 'italic' ? 'italic' : 'normal' ,
163
- style === 'bold' ? 'bold' : 'normal'
164
- ) ;
165
- const typeface =
166
- font . getAndroidTypeface ( ) ||
167
- android . graphics . Typeface . create ( fontFamily , 0 ) ;
168
- const typefaceSpan : android . text . style . TypefaceSpan = new org . nativescript . widgets . CustomTypefaceSpan (
169
- fontFamily ,
170
- typeface
171
- ) ;
172
- builder . setSpan (
173
- typefaceSpan ,
174
- start ,
175
- end ,
176
- android . text . Spanned . SPAN_EXCLUSIVE_EXCLUSIVE
177
- ) ;
271
+ const font = new Font ( fontFamily , 0 , style === 'italic' ? 'italic' : 'normal' , style === 'bold' ? 'bold' : 'normal' ) ;
272
+ const typeface = font . getAndroidTypeface ( ) || android . graphics . Typeface . create ( fontFamily , 0 ) ;
273
+ const typefaceSpan : android . text . style . TypefaceSpan = new org . nativescript . widgets . CustomTypefaceSpan ( fontFamily , typeface ) ;
274
+ builder . setSpan ( typefaceSpan , start , end , android . text . Spanned . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
178
275
}
179
276
180
277
// const ssb = new android.text.SpannableStringBuilder();
0 commit comments