-
Notifications
You must be signed in to change notification settings - Fork 170
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
RTL support #56
Comments
Hi, The following defines a method to compute how bidirectional text should be written if looking from a regular computerized left-to-write writing (which is how writeText expects things to be) bidi = require('icu-bidi');
function computeTextForItem(inText,inDirection)
{
var p = bidi.Paragraph(inText,{paraLevel: inDirection == 'rtl' ? bidi.RTL:bidi.LTR});
return p.writeReordered(bidi.Reordered.KEEP_BASE_COMBINING);
} The text to pass to writeText should now be If you want multiline support, then i suggest you look into the hummusrenderer relevant code, and we can discuss it if you want. |
Yes, I used bidi as you suggested above and that worked in reversing the direction, but i still have an issue with the characters not joining as they should for arabic text (like they would for cursive fonts). so if i want to write the text حمّص , in the PDF i get it as ح مّ ص this happens in hummusrenderer as well. you can notice it if you try the following object
|
yes. i kinda figured this would come next. but i'm not sure i know what to do about this. At this point writeText only knows to translate unicode characters to their matching glyphs in the font. With Arabic characters there are several choices, but the simplistic selection code just picks the same one, which would create the not-connecting effect. To overcome this something needs to be changed in hummus to choose the right glyph according to position, or that you can provide the glyph ids directly. If you already know the correct glyphs, than i can assist you with knowing which hummus commands to use to place those glyphs, otherwise this needs some changes in hummus, which i'd be glad if you can add...otherwise it'll have to wait till i get to it...and its a lower priority now. So i'm sorry here. Gal. |
@galkahana i'm interested to patch this, can you show me where to change? Also is it ok to add a dependency? I think the best way to go here is to create a sort of "glyph resolver" library and make Hummus depend on it to pick the correct glyph. |
@amrnablus That would be lovely! Here is how it works: writeText is simply an abstraction over lower level text placement commands. This example shows how to use them [ill explain below:]: This is how to place text using the lower level commands: var page = pdfWriter.createPage(0,0,595,842);
var font = pdfWriter.getFontForFile(__dirname + '/TestMaterials/fonts/BrushScriptStd.otf');
var fontK = pdfWriter.getFontForFile(__dirname + '/TestMaterials/fonts/KozGoPro-Regular.otf');
pdfWriter.startPageContentContext(page)
.BT()
.k(0,0,0,1)
.Tf(font,1)
.Tm(30,0,0,30,78.4252,662.8997)
.Tj('abcd')
.ET()
pdfWriter.writePage(page).end(); Instead of calling -- In regular usage var page = pdfWriter.createPage(0,0,595,842);
var font = pdfWriter.getFontForFile(__dirname + '/TestMaterials/fonts/arial.ttf');
pdfWriter.startPageContentContext(page)
.BT()
.k(0,0,0,1)
.Tf(font,1)
.Tm(30,0,0,30,78.4252,662.8997)
.Tj([[68,97],[69,98],[70,99],[71,100]])
.ET();
pdfWriter.writePage(page).end(); Note that Each item in the array marks a glyph. The first number is the glyph ID. The 2nd number is the unicode value that matches it. there might be a third value for surrogate unicode values, but that's CJK characters so Arabic is in the clear. So, if you can prepare something that can take a font and text and get the right glyph IDs that would be awesome. |
I'm a but rusty on unicode, so; just to confirm the problem:
If that's the case, i prefer to fix this on the pdfwriter level by writing a cpp converter which will take the "ا ب ج د" and convert it to "ابجد" with the proper code points, the font should take care of the rest once the proper glyphs are selected. Can you please confirm |
if you wanna do that in PDFWriter all the better. I can point you to the areas in the code that do the translation in there. will that be good? |
Yeah i'd rather do that. Please point me to the code (and if there are cpp samples). |
@galkahana - it would be more easier to convert the arabic unicode characters from the default block to Arabic Presentation Forms-B block. This way I don't need to figure out the glyphs. Granted this block is only meant for compatibility with older systems, but it works fine for my case. I just used this library to convert the string before calling writeText. I just had to reverse the output string for it to render correctly |
I'm considering using either fribidi (http://fribidi.org/) or pango (http://www.pango.org/) to do the trick. I'll run some POCs and post my findings here. |
@hussasad - brilliant! Didn't realize that this was an option. i'll keep that in mind. definitely the easier path. @amrnablus - note that fribidi should give you RTL ordering, not the glyphs [it's what i'm using in hummus as 'bidi', you can look at the source to see how to use it, 'cause it does solve part of the deal (the rtl) - ]. Thanks and good luck! |
I got this from the fribidi mailing list:On 15-12-20 03:55 PM, Amr Shahin wrote:
It does. See fribidi_shape_arabic(). I don't remember the details. bWill try to write some POCs converting a regular string into it's form-b format, if that works out fine i'll try to apply the same to hummus. |
that's super cool :) |
@galkahana So i tried to write a simple cpp application that demonstrates the problem, but it's printing gibberish instead of the arabic letters (Not even the disconnected version). |
Hi, Regards, |
You can use UnicodeString to help you with this. |
Thanks Gal, it was actually a font issue, i'm using "FreeSerif.otf" now and it's working |
@galkahana does the same issue exist for Hebrew? I tested the POC code for both Arabic and Farsi and it seems to be working fine. |
Cool. In terms of your implementation (PR), if i may. If you look into adding this directly to PDFWriter (which i'd love if you could, and thank you a lot) my preference would be that it will be used as part of AbstractContentContext::WriteText (already at its begining). for the sake of providing some manual override it would be super nice if you could:
I'm also good with leaving it as something that someone can calls to before calling writetext, if you deem this better. i can add the WriteText implementation on top of it (just keep it utf8 std::string to utf8 std::string please). I'll also take care of integrating this into HummusJS. If you'll do that i'll thank you very much, and i'm sure others will as well. |
Thanks, that's exactly what i'm doing, except i didn't really separate the bidi conversion outside AbstractContentContext (now that mentioned it, it makes much more sense). |
Something like |
Ok so the code is done and working fine, regarding the commit, should I add fribidi as a "sit-in"? dependency the same way you're using LibJpeg, LibTiff, etc ...? If so should it be a git submodule or just clone the repo and copy it to the sources directory? |
Cool :). |
I am trying to write Arabic text using the writeText function, but I am unable to figure out how to set the direction to be RTL. It is mentioned here that RTL support was added to the rendering service, so i guess there must be some way in Hummus to specify the direction?
The text was updated successfully, but these errors were encountered: