RTL
Arabic & Hebrew
ctx.fillText()
No bidi algorithm — glyphs render left-to-right, punctuation misplaced.
drawElementImage()
مرحباً بالعالم! هذا نص عربي.
!שלום עולם — טקסט עברי
Browser's bidi algorithm handles direction, punctuation, and shaping.
Vertical
CJK (Chinese / Japanese / Korean)
ctx.fillText()
No writing-mode support — text forced horizontal.
drawElementImage()
国境の長いトンネルを抜けると雪国であった。
CSS
writing-mode: vertical-rl
works natively.
Complex
Thai Script with Stacking Diacritics
ctx.fillText()
Stacking marks may misalign — platform-dependent shaping.
drawElementImage()
สวัสดีครับ ยินดีต้อนรับสู่เว็บไซต์
Browser's text shaping engine handles all mark positioning.
Mixed
Bidirectional Text with Numbers
ctx.fillText()
fillText renders a single direction — mixed runs break.
drawElementImage()
The term
إنترنت
(Internet) was adopted in
١٩٩٥
and is used alongside
אינטרנט
in multilingual documents.
Unicode bidi algorithm resolves each embedded run correctly.
Emoji
Skin Tones & ZWJ Sequences
ctx.fillText()
ZWJ sequences may split into separate glyphs.
drawElementImage()
👩🏽💻 👨🏿🎨 👩🏻🔬 🧑🏾🍳 👨🏼🚀 👩🏽⚕️
Browser's emoji engine composes ZWJ sequences and skin tones.
Ruby
Japanese Furigana Annotations
ctx.fillText()
No ruby support — annotations drawn inline, breaking flow.
drawElementImage()
東
ひがし
京
きょう
都
と
の
渋
しぶ
谷
や
で
会
あ
いましょう。
HTML <ruby> and <rt> render with proper positioning.