How to get an arbitrary text string Size (width and height) #2524
Replies: 3 comments 2 replies
-
You should really sure the paragraph API for this:
https://shopify.github.io/react-native-skia/docs/text/paragraph/
All these other APIs where made available because we weren't shipping the
paragraph API yet.
I hope this helps.
…On Mon, Jul 8, 2024 at 4:54 PM SaeedZhiany ***@***.***> wrote:
Hi,
I have just one usage from this library: calculating the width and height
of an arbitrary text with custom fontFamily and fontSize before rendering
it.
previously I was using react-native-text-size
<https://github.com/aMarCruz/react-native-text-size> tp calculating the
width of a string text. it takes the string and its font-related styles and
calculates the text's width async. due to the async nature of the library,
I can't use it in the components render function and always have to
calculate the width separately and then re-render the component by setting
the widths in the component's state.
Now, I'm upgrading my react-native project to the latest version (0.74.3)
and I found this library with similar functionality but runs synchronously.
I'm also have installed the newest version of react-native-skia in my
project.
I tracked the repository's git history and found three ways to calculate
the width:
1. getTextWidth -> deprecated
<#1870> in favor of
measureText, return 0 even when using it.
2. measureText -> deprecated
<#754> in favor of
getGlyphWidths, return 0 even when using it.
3. getGlyphWidths -> I didn't find any useful documentation about how
should I use it.
- Please note that my react-native project is all written using class
components and I have no functional components (and prefer not to have any)
- I don't want to draw any shapes within canvas. I will use the
React-Native Text component for rendering regular text.
- I'm also using a few custom fonts in my application for the text.
the fonts are registered in the project and React-Native knows them using I
use their name in the styles. (they are copied to Android assets/fonts
directory and submitted into iOS's project.pbxproj)
a simple usage would be like below:
// utils fileimport {matchFont} from ***@***.***/react-native-skia';
export function renderedTextSize(text: string, size: number = 14, fontFamily: string = 'myCustomFont1') {
if (!!text) {
const skFont = matchFont({fontFamily, fontSize: size});
const {width, height, x, y} = skFont.measureText(text);
return {
width,
height,
};
}
return {
width: 0,
height: 0,
};}
import {View, Text} from 'react-native';import {renderedTextSize} from 'path/to/utils';
class myComponent {
render() {
const {names = []} this.props;
let longestName = '';
let longestWidth = 0;
for (name : names) {
const width = renderedTextSize(name , 12, 'myCustomFont2').width;
if (longestWidth < width) {
longestWidth = width ;
longestName = name;
}
}
const finalWidth = // apply some other logics according to the longestWidth and the calculate the finalWidth
return (
<View style={{width: finalWidth}}>
<Text style={{fontFamily: 'myCustomFont2', fontSize: 12}}>{longestName}</Text>
</View>
);
}}
Can you please tell me how should I exactly use this library to get a text
width before rendering? (I want to rewrite the renderedTextSize's body)
Thanks
—
Reply to this email directly, view it on GitHub
<#2524>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACKXVXG6VTXARUNW7MVDHDZLKR3NAVCNFSM6AAAAABKRAMZUOVHI2DSMVQWIX3LMV43ERDJONRXK43TNFXW4OZWHEYTEMJWGU>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
you need to use layout() to access the layout information:
https://shopify.github.io/react-native-skia/docs/text/paragraph/#paragraph-bounding-box
…On Tue, Jul 9, 2024 at 6:07 AM SaeedZhiany ***@***.***> wrote:
Thanks for your response. I tried this code but still got zero for both width and height.
export function renderedTextSize(text: string, size: number = 14, fontFamily: string = 'myCustomFont1') {
if (!!text) {
const skParagraph = Skia.ParagraphBuilder.Make()
.addText(text)
.pushStyle({fontSize: size, fontFamilies: [fontFamily]})
.build();
console.log(text, skParagraph.getLongestLine(), skParagraph.getHeight());
return {
width: skParagraph.getLongestLine(),
height: skParagraph.getHeight(),
};
}
return {
width: 0,
height: 0,
};
}
should I register my fonts for Skia too? Is there any non-hook function for it? The hook useFonts is not possible to use for me.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
For anyone interested here is my solution: // utils.ts
import {SkData, Skia} from '@shopify/react-native-skia';
import {Platform} from '@shopify/react-native-skia/src/Platform';
const skTypefaceFontProvider = Skia.TypefaceFontProvider.Make();
function registerFontForSkia(data: SkData, fontFamily: string): void {
const skTypeface = Skia.Typeface.MakeFreeTypeFaceFromData(data);
if (!isNull(skTypeface)) {
skTypefaceFontProvider.registerFont(skTypeface, fontFamily);
}
}
Skia.Data.fromURI(Platform.resolveAsset(require('./path/to/myCustomFont1.ttf')))
.then(data => registerFontForSkia(data, 'myCustomFont1'))
.catch(promiseEmptyCallback);
// repeat the above code for registering all your other custom fonts
export function renderedTextSize(text: string, size: number = 14, fontFamily: string = 'myCustomFont1') {
if (!!text) {
const skParagraph = Skia.ParagraphBuilder.Make(undefined, skTypefaceFontProvider)
.pushStyle({fontSize: size, fontFamilies: [fontFamily]})
.addText(text)
.build();
skParagraph.layout(Dimensions.get('window').width); // or you can use Number.MAX_VALUE
return {
width: Math.ceil(skParagraph.getLongestLine()), // for the reason of using Math.ceil, see the below explanation
height: skParagraph.getHeight(),
};
}
return {
width: 0,
height: 0,
};
} width calculation comparison using both
@wcandillon As you can see react-native-skia calculates width less than react-native-text-size which results in inaccurate calculation, The longer the text, the more the calculation error of the library increases. react-native-text-size uses native implementation for both Android and iOS platforms and I'm pretty sure that its result is more accurate. as a workaround I used a |
Beta Was this translation helpful? Give feedback.
-
Hi,
I have just one usage from this library: calculating the width and height of an arbitrary text with custom
fontFamily
andfontSize
before rendering it.previously I was using react-native-text-size to calculating the width of a string text. it takes the string and its font-related styles and calculates the text's width async. due to the async nature of the library, I can't use it in the components
render
function and always have to calculate the width separately and then re-render the component by setting the widths in the component's state.Now, I'm upgrading my react-native project to the latest version (0.74.3) and I found this library with similar functionality, but runs synchronously and I hope it helps me avoiding the unnecessary re-renders. I'm also have installed the newest version of react-native-skia in my project.
I tracked the repository's git history and found three ways to calculate the width:
assets/fonts
directory and submitted into iOS'sproject.pbxproj
)a simple usage would be like below:
Can you please tell me how should I exactly use this library to get a text width before rendering? (I want to rewrite the renderedTextSize's body)
@wcandillon can you help me with this? according to the git histories, it seems you are the one who implemented the utilities for this library.
Thanks
Beta Was this translation helpful? Give feedback.
All reactions