react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

non-latin font (Persian fonts) upside-down

Open hrkazemi opened this issue 3 years ago • 7 comments

I did try register Persian fonts, everything looks fine unless text gets larger than one line. this is my codes:

mock text:

export const data = {
    text_persian: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد.',
    text_english: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
};

and this is my template:

import React from 'react';
import { data } from './mock';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';

const styles = StyleSheet.create({
    page: { fontFamily: "iransans" },
    textRight: { textAlign: 'right' },
});

export function invoicePdfTemplate() {
    return (
        <Document>
            <Page size="A4" style={styles.page}>
                <View>
                    <Text>
                        {data.text_english}
                    </Text>
                    <Text style={styles.textRight}>
                        {data.text_persian}
                    </Text>
                </View>
            </Page>
        </Document>
    )
}

and this is the final result: image

the problem is in Persian font if the text gets larger than a line, it will be rendered upside-down

hrkazemi avatar Jul 30 '20 21:07 hrkazemi

I should mention that registering font, works fine (both URL and import).

import React from 'react';
import { PDFDownloadLink, Font } from '@react-pdf/renderer';
import { invoicePdfTemplate } from './pdfTemplate';
import font from './IRANSansWeb.ttf'

Font.register({
    family: "iransans",
    format: "truetype",
    // src: `${process.env.PUBLIC_URL}/static/fonts/IRANSansWeb.ttf`
    src: font
});

export class Gholi extends React.Component{
    render() {
        return <PDFDownloadLink document={invoicePdfTemplate()} fileName={`invoice-1.pdf`}>
            {({ blob, url, loading, error }) => {
                return <>{(loading ? 'Loading...' : 'Download now!')}</>;
            }}
        </PDFDownloadLink>
    }
}

the only problem is when the text gets larger than one line

hrkazemi avatar Jul 30 '20 21:07 hrkazemi

I think this is because Persian is a RTL language, which React-PDF doesn't support.

oowowaee avatar Aug 14 '20 23:08 oowowaee

This is my problem to.

mortezakarimi64 avatar Oct 04 '20 22:10 mortezakarimi64

I have some progress made on supporting RTL text using the style direction: rtl although it's not yet finished. I'm clos to, but need more time unfortunately, which I lack lately 😅 Will post updates as soon as I have them

diegomura avatar Jun 02 '21 03:06 diegomura

I have some progress made on supporting RTL text using the style direction: rtl although it's not yet finished. I'm clos to, but need more time unfortunately, which I lack lately 😅 Will post updates as soon as I have them

@diegomura Any luck with that? maybe we can help with it?

benshabatnoam avatar May 25 '22 20:05 benshabatnoam

Any updates? has anyone found a solution?

Hi, I found a way Test the code below, it might work for you too.

Store the list of words in the array

const [splitedText, setSplitedText] = useState([])
useEffect(()=>{
   const _splitedText = text.split(" ");
   setSplitedText(_splitedText)
},[])

now we need styles to show the all word correctly inside a <View> tag

const styles = StyleSheet.create({
  flexRowReverse: {
      flexDirection: "row-reverse"
  },
  flexWrap: {
      flexWrap: "wrap"
  },
  ml1: {
      marginLeft: "2pt"
  }
})

then map splitedText inside View tag

<View style={[styles.flexRowReverse, styles.flexWrap]}>
      {
          splitedText.map((word, idx) => {
              return (
                <Text style={styles.ml1} key={idx}>
                  {word}
                </Text>
              );
          })
      }
</View>

X3rom-S avatar Jun 29 '22 15:06 X3rom-S

X3rom-S there is no need for code changes once #1821 will get merged, we're all waiting for it

benshabatnoam avatar Jun 29 '22 17:06 benshabatnoam