[iOS] Support Khmer and Lao fallback fonts
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jun 2014 21:17:39 +0000 (21:17 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jun 2014 21:17:39 +0000 (21:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134114

Reviewed by Enrica Casucci.

Source/WebCore:
iOS has fonts which have glyphs for the Khmer and Lao languages.

This patch also does a little refactoring of the language-specific fallback
font path to increase readability.

Test: fast/text/khmer-lao-font.html

* platform/graphics/ios/FontCacheIOS.mm:
(WebCore::languageSpecificFallbackFont):
(WebCore::FontCache::systemFallbackForCharacters):

LayoutTests:
Simply dump the render tree of a page that includes Khmer and Lao text. The success
of this test depends on font font metrics being different than system fallback font
(which just shows rectangles instead of glyphs).

* fast/text/khmer-lao-font.html: Added.
* platform/ios-sim/fast/text/khmer-lao-font-expected.txt: Added.
* platform/mac/fast/text/khmer-lao-font-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170207 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/text/khmer-lao-font.html [new file with mode: 0644]
LayoutTests/platform/ios-sim/fast/text/khmer-lao-font-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/text/khmer-lao-font-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ios/FontCacheIOS.mm

index 8386abbd8077f9fae280c41e2a4ac03c374f2ed5..198fdbeeb09b5e952c314be4d7247b1533395ef0 100644 (file)
@@ -1,3 +1,18 @@
+2014-06-20  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [iOS] Support Khmer and Lao fallback fonts
+        https://bugs.webkit.org/show_bug.cgi?id=134114
+
+        Reviewed by Enrica Casucci.
+
+        Simply dump the render tree of a page that includes Khmer and Lao text. The success
+        of this test depends on font font metrics being different than system fallback font
+        (which just shows rectangles instead of glyphs).
+
+        * fast/text/khmer-lao-font.html: Added.
+        * platform/ios-sim/fast/text/khmer-lao-font-expected.txt: Added.
+        * platform/mac/fast/text/khmer-lao-font-expected.txt: Added.
+
 2014-06-20  Simon Fraser  <simon.fraser@apple.com>
 
         REGRESSION (r169972): fix issue when removing masks from compositing layers
diff --git a/LayoutTests/fast/text/khmer-lao-font.html b/LayoutTests/fast/text/khmer-lao-font.html
new file mode 100644 (file)
index 0000000..c299ee4
--- /dev/null
@@ -0,0 +1,45 @@
+<meta charset="utf-8">
+<p>
+This file includes Khmer and Lao text, and makes sure that the render tree metrics match what they should be.
+</p>
+
+Khmer:
+<p>
+រៃឡង់ របស់ខ្មែរ
+លទ្ធផល​ប្រហែល
+បកប្រែ​ទំព័រ​នេះ
+ស្វែងរក
+រូបភាព
+ផែនទី
+បក​ប្រែ
+រូបភាព​សម្រាប់
+ច្រើន​ទៀត​ដោយ
+ជំនួយ ផ្ញើ​មតិ​ប្រតិកម្ម ឯកជនភាព & គោលការណ៍
+ពល​លាវ ជា​ខេត្ត​មួយ​នៃ​ដែនដី​កម្ពុជា​ក្រោម ឋិត​នៅ​តំបន់ ដែនដី​សណ្ត​ទន្លេមេគង្គ ។ ខេត្ត​ពល​លាវសម្បូរ ដោយ ភោគផល​កសិកម្ម មាន​ចំការ ដំណាំ​ស្រែ​ស្រូវ ស្រែអំបិល ជលផល​ទឹកសាប​ទឹក ប្រៃ និង​រចនាសម្ព័ន្ធធារាសាស្ត្រ ធម្មជាតិ​ខ្វាត់ខ្វែង។​
+ពល​លាវ ស្ថិតនៅ​បែក​ខាងលិច​នៃ​ដែនដី​កម្ពុជា​ក្រោម មជ្ឈមណ្ឌល​នៃ​ខេត្ត​នេះ​គឺ ទី​រួម​ខេត្ត​ពល​លាវ។ ពី​ទី​រួម​ខេត្ត​ពល​លាវ​ទៅ​ទីក្រុង​ព្រៃនគរមាន​ចម្ងាយ ២៨០ គ​.​ម​. តាមផ្លូវ​ជាតិ លេខ ១
+</p>
+
+<br/>
+
+Lao:
+<p>
+ຄົ້ນຫາ
+ຮູບພາບ
+ແຜນທີ່
+ແປພາສາ
+ມືຖື
+ບລັອກເກີ
+ເພີ່ມເຕີມຈາກ
+ແປໜ້ານີ້
+ຮູບພາບສຳລັບ
+ແປໜ້ານີ້
+ຫຼັງຈາກທີ່ເປີດເວັບໄຊ ບສາມປີ ຕັ້ງແຕ່ປີ ຈົນຕອນນີ້ປີ ແລ້ວ ກໍມີຫຼາຍສິ່ງຫຼາຍຢ່າງເກີດຂຶ້ນ ຫຼາຍຄົນກໍໄດ້ຮຽນຮູ້ວິທີການໃຊ້ ຫຼາຍຄົນກໍງົງກັບການໃຊ້ ເຂົ້າໄປອີກ (ອ້າວ!) ແຕ່ຢ່າງໃດກໍຕາມ ຂ້າພະເຈົ້າ ໃນນາມຂອງຜູ່ສ້າງເວັບໄຊນີ້ ກໍຕ້ອງຂໍຂອບໃຈທຸກໆ ທ່ານທີ່ມີສ່ວນຮ່ວມ ທັງການຖາມ ແລະຕອບທີ່ເກີດຂຶ້ນໃນບົດຄວາມ ແລະກະທູ້ຕ່າງໆ ໃນເວັບບອດ ເຊິ່ງກໍຖືວ່າເປັນການແລກປ່ຽນຄວາມຮູ້ກັນ.
+
+ສຳລັບໃນປີ 2011 ນີ້ ຂ້າພະເຈົ້າມີຄວາມຄາດຫວັງເປັນຢ່າງສູງວ່າ ຈະປັບປຸງເວັບໄຊແຫ່ງນີ້ ໃຫ້ດີຍິ່ງໆ ຂຶ້ນໄປອີກ ໂດຍສະເພາະແມ່ນໃນດ້ານ Localization ຫຼືການແປພາສາລາວຂອງ ນັ້ນເອງ. ເຖິງແມ່ນວ່າຈະມີໄຟລ໌ພາສາລາວເກົ່າຢູ່ແລ້ວ ແຕ່ກໍຍັງບໍ່ສົມບູນ ແລະມີຄວາມຜິດພາດຫຼາຍປະການ ບໍ່ວ່າຈະເປັນພິມຜິດ ຫຼືແປບໍ່ຖືກ ເປັນຕົ້ນ. ດັ່ງນັ້ນ ການແປຄືນພາສາລາວສຳລັບ ກໍເປັນເປົ້າໝາຍອັນນຶ່ງ ເຊັ່ນດຽວກັບການແປ Component ໂຕອື່ນໆ ທີ່ນິຍົມໃຊ້ກັນ ຢ່າງເຊັ່ນ Kunena ເຊິ່ງເປັນລະບົບເວັບບອດສຳລັບ
+
+ນອກຈາກນັ້ນ ໃນດ້ານການສອນ ຂ້າພະເຈົ້າກໍຫວັງເປັນຢ່າງຍິ່ງວ່າ ຈະສາມາດເປີດຄອສສອນ ໃນວຽງຈັນໄດ້ເປັນຮູບເປັນຮ່າງ ເຊິ່ງສຳລັບຕອນນີ້ກໍແມ່ນມີຄວາມຂາດເຂີນໃນດ້ານເງື່ອນໄຂຕ່າງໆ ໂດຍສະເພາະກໍແມ່ນສະຖານທີ່. ເຖິງຢ່າງໃດກໍຕາມ ຂ້າພະເຈົ້າເຊື່ອໝັ້ນວ່າ ຈະມີມື້ນຶ່ງ ທີ່ຄວາມຫວັງນີ້ຈະເປັນຈິງຂຶ້ນມາໄດ້.
+
+໑໖ ມັງກອນ ໒໐໑໑
+ທະນະວໍລະກິດ ກຸນທະວັດພິນໂຍ
+ເວັບມາສເຕີ
+</p>
diff --git a/LayoutTests/platform/ios-sim/fast/text/khmer-lao-font-expected.txt b/LayoutTests/platform/ios-sim/fast/text/khmer-lao-font-expected.txt
new file mode 100644 (file)
index 0000000..95c6461
--- /dev/null
@@ -0,0 +1,36 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x20
+        RenderText {#text} at (0,0) size 706x19
+          text run at (0,0) width 706: "This file includes Khmer and Lao text, and makes sure that the render tree metrics match what they should be."
+      RenderBlock (anonymous) at (0,36) size 784x20
+        RenderText {#text} at (0,0) size 49x19
+          text run at (0,0) width 49: "Khmer:"
+      RenderBlock {P} at (0,72) size 784x145
+        RenderText {#text} at (0,3) size 779x135
+          text run at (0,3) width 779: "\x{179A}\x{17C3}\x{17A1}\x{1784}\x{17CB} \x{179A}\x{1794}\x{179F}\x{17CB}\x{1781}\x{17D2}\x{1798}\x{17C2}\x{179A} \x{179B}\x{1791}\x{17D2}\x{1792}\x{1795}\x{179B}\x{200B}\x{1794}\x{17D2}\x{179A}\x{17A0}\x{17C2}\x{179B} \x{1794}\x{1780}\x{1794}\x{17D2}\x{179A}\x{17C2}\x{200B}\x{1791}\x{17C6}\x{1796}\x{17D0}\x{179A}\x{200B}\x{1793}\x{17C1}\x{17C7} \x{179F}\x{17D2}\x{179C}\x{17C2}\x{1784}\x{179A}\x{1780} \x{179A}\x{17BC}\x{1794}\x{1797}\x{17B6}\x{1796} \x{1795}\x{17C2}\x{1793}\x{1791}\x{17B8} \x{1794}\x{1780}\x{200B}\x{1794}\x{17D2}\x{179A}\x{17C2} \x{179A}\x{17BC}\x{1794}\x{1797}\x{17B6}\x{1796}\x{200B}\x{179F}\x{1798}\x{17D2}\x{179A}\x{17B6}\x{1794}\x{17CB} \x{1785}\x{17D2}\x{179A}\x{17BE}\x{1793}\x{200B}\x{1791}\x{17C0}\x{178F}\x{200B}\x{178A}\x{17C4}\x{1799} \x{1787}\x{17C6}\x{1793}\x{17BD}\x{1799} \x{1795}\x{17D2}\x{1789}\x{17BE}\x{200B}\x{1798}\x{178F}\x{17B7}\x{200B}\x{1794}\x{17D2}\x{179A}\x{178F}\x{17B7}\x{1780}\x{1798}\x{17D2}\x{1798}"
+          text run at (0,32) width 747: "\x{17AF}\x{1780}\x{1787}\x{1793}\x{1797}\x{17B6}\x{1796} & \x{1782}\x{17C4}\x{179B}\x{1780}\x{17B6}\x{179A}\x{178E}\x{17CD} \x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C} \x{1787}\x{17B6}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1798}\x{17BD}\x{1799}\x{200B}\x{1793}\x{17C3}\x{200B}\x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{1780}\x{1798}\x{17D2}\x{1796}\x{17BB}\x{1787}\x{17B6}\x{200B}\x{1780}\x{17D2}\x{179A}\x{17C4}\x{1798} \x{178B}\x{17B7}\x{178F}\x{200B}\x{1793}\x{17C5}\x{200B}\x{178F}\x{17C6}\x{1794}\x{1793}\x{17CB} \x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{179F}\x{178E}\x{17D2}\x{178F}\x{200B}\x{1791}\x{1793}\x{17D2}\x{179B}\x{17C1}\x{1798}\x{17C1}\x{1782}\x{1784}\x{17D2}\x{1782} \x{17D4} \x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C}\x{179F}\x{1798}\x{17D2}\x{1794}\x{17BC}\x{179A}"
+          text run at (0,61) width 766: "\x{178A}\x{17C4}\x{1799} \x{1797}\x{17C4}\x{1782}\x{1795}\x{179B}\x{200B}\x{1780}\x{179F}\x{17B7}\x{1780}\x{1798}\x{17D2}\x{1798} \x{1798}\x{17B6}\x{1793}\x{200B}\x{1785}\x{17C6}\x{1780}\x{17B6}\x{179A} \x{178A}\x{17C6}\x{178E}\x{17B6}\x{17C6}\x{200B}\x{179F}\x{17D2}\x{179A}\x{17C2}\x{200B}\x{179F}\x{17D2}\x{179A}\x{17BC}\x{179C} \x{179F}\x{17D2}\x{179A}\x{17C2}\x{17A2}\x{17C6}\x{1794}\x{17B7}\x{179B} \x{1787}\x{179B}\x{1795}\x{179B}\x{200B}\x{1791}\x{17B9}\x{1780}\x{179F}\x{17B6}\x{1794}\x{200B}\x{1791}\x{17B9}\x{1780} \x{1794}\x{17D2}\x{179A}\x{17C3} \x{1793}\x{17B7}\x{1784}\x{200B}\x{179A}\x{1785}\x{1793}\x{17B6}\x{179F}\x{1798}\x{17D2}\x{1796}\x{17D0}\x{1793}\x{17D2}\x{1792}\x{1792}\x{17B6}\x{179A}\x{17B6}\x{179F}\x{17B6}\x{179F}\x{17D2}\x{178F}\x{17D2}\x{179A} \x{1792}\x{1798}\x{17D2}\x{1798}\x{1787}\x{17B6}\x{178F}\x{17B7}\x{200B}\x{1781}\x{17D2}\x{179C}\x{17B6}\x{178F}\x{17CB}\x{1781}\x{17D2}\x{179C}\x{17C2}\x{1784}\x{17D4}\x{200B}"
+          text run at (0,90) width 776: "\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C} \x{179F}\x{17D2}\x{1790}\x{17B7}\x{178F}\x{1793}\x{17C5}\x{200B}\x{1794}\x{17C2}\x{1780}\x{200B}\x{1781}\x{17B6}\x{1784}\x{179B}\x{17B7}\x{1785}\x{200B}\x{1793}\x{17C3}\x{200B}\x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{1780}\x{1798}\x{17D2}\x{1796}\x{17BB}\x{1787}\x{17B6}\x{200B}\x{1780}\x{17D2}\x{179A}\x{17C4}\x{1798} \x{1798}\x{1787}\x{17D2}\x{1788}\x{1798}\x{178E}\x{17D2}\x{178C}\x{179B}\x{200B}\x{1793}\x{17C3}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1793}\x{17C1}\x{17C7}\x{200B}\x{1782}\x{17BA} \x{1791}\x{17B8}\x{200B}\x{179A}\x{17BD}\x{1798}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C}\x{17D4} \x{1796}\x{17B8}\x{200B}\x{1791}\x{17B8}\x{200B}\x{179A}\x{17BD}\x{1798}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C}\x{200B}\x{1791}\x{17C5}\x{200B}\x{1791}\x{17B8}\x{1780}\x{17D2}\x{179A}\x{17BB}\x{1784}\x{200B}\x{1796}\x{17D2}\x{179A}\x{17C3}\x{1793}\x{1782}\x{179A}"
+          text run at (0,119) width 244: "\x{1798}\x{17B6}\x{1793}\x{200B}\x{1785}\x{1798}\x{17D2}\x{1784}\x{17B6}\x{1799} \x{17E2}\x{17E8}\x{17E0} \x{1782}\x{200B}.\x{200B}\x{1798}\x{200B}. \x{178F}\x{17B6}\x{1798}\x{1795}\x{17D2}\x{179B}\x{17BC}\x{179C}\x{200B}\x{1787}\x{17B6}\x{178F}\x{17B7} \x{179B}\x{17C1}\x{1781} \x{17E1}"
+      RenderBlock (anonymous) at (0,233) size 784x40
+        RenderBR {BR} at (0,0) size 0x19
+        RenderText {#text} at (0,20) size 30x19
+          text run at (0,20) width 30: "Lao:"
+      RenderBlock {P} at (0,289) size 784x210
+        RenderText {#text} at (0,1) size 784x208
+          text run at (0,1) width 774: "\x{E84}\x{EBB}\x{EC9}\x{E99}\x{EAB}\x{EB2} \x{EAE}\x{EB9}\x{E9A}\x{E9E}\x{EB2}\x{E9A} \x{EC1}\x{E9C}\x{E99}\x{E97}\x{EB5}\x{EC8} \x{EC1}\x{E9B}\x{E9E}\x{EB2}\x{EAA}\x{EB2} \x{EA1}\x{EB7}\x{E96}\x{EB7} \x{E9A}\x{EA5}\x{EB1}\x{EAD}\x{E81}\x{EC0}\x{E81}\x{EB5} \x{EC0}\x{E9E}\x{EB5}\x{EC8}\x{EA1}\x{EC0}\x{E95}\x{EB5}\x{EA1}\x{E88}\x{EB2}\x{E81} \x{EC1}\x{E9B}\x{EDC}\x{EC9}\x{EB2}\x{E99}\x{EB5}\x{EC9} \x{EAE}\x{EB9}\x{E9A}\x{E9E}\x{EB2}\x{E9A}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} \x{EC1}\x{E9B}\x{EDC}\x{EC9}\x{EB2}\x{E99}\x{EB5}\x{EC9} \x{EAB}\x{EBC}\x{EB1}\x{E87}\x{E88}\x{EB2}\x{E81}\x{E97}\x{EB5}\x{EC8}\x{EC0}\x{E9B}\x{EB5}\x{E94}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A} \x{E9A}\x{EAA}\x{EB2}\x{EA1}\x{E9B}\x{EB5} \x{E95}\x{EB1}\x{EC9}\x{E87}\x{EC1}\x{E95}\x{EC8}\x{E9B}\x{EB5} \x{E88}\x{EBB}\x{E99}"
+          text run at (0,22) width 750: "\x{E95}\x{EAD}\x{E99}\x{E99}\x{EB5}\x{EC9}\x{E9B}\x{EB5} \x{EC1}\x{EA5}\x{EC9}\x{EA7} \x{E81}\x{ECD}\x{EA1}\x{EB5}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{EAA}\x{EB4}\x{EC8}\x{E87}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC0}\x{E81}\x{EB5}\x{E94}\x{E82}\x{EB6}\x{EC9}\x{E99} \x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E84}\x{EBB}\x{E99}\x{E81}\x{ECD}\x{EC4}\x{E94}\x{EC9}\x{EAE}\x{EBD}\x{E99}\x{EAE}\x{EB9}\x{EC9}\x{EA7}\x{EB4}\x{E97}\x{EB5}\x{E81}\x{EB2}\x{E99}\x{EC3}\x{E8A}\x{EC9} \x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E84}\x{EBB}\x{E99}\x{E81}\x{ECD}\x{E87}\x{EBB}\x{E87}\x{E81}\x{EB1}\x{E9A}\x{E81}\x{EB2}\x{E99}\x{EC3}\x{E8A}\x{EC9} \x{EC0}\x{E82}\x{EBB}\x{EC9}\x{EB2}\x{EC4}\x{E9B}\x{EAD}\x{EB5}\x{E81} (\x{EAD}\x{EC9}\x{EB2}\x{EA7}!) \x{EC1}\x{E95}\x{EC8}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC3}\x{E94}\x{E81}\x{ECD}\x{E95}\x{EB2}\x{EA1}"
+          text run at (0,43) width 781: "\x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2} \x{EC3}\x{E99}\x{E99}\x{EB2}\x{EA1}\x{E82}\x{EAD}\x{E87}\x{E9C}\x{EB9}\x{EC8}\x{EAA}\x{EC9}\x{EB2}\x{E87}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A}\x{E99}\x{EB5}\x{EC9} \x{E81}\x{ECD}\x{E95}\x{EC9}\x{EAD}\x{E87}\x{E82}\x{ECD}\x{E82}\x{EAD}\x{E9A}\x{EC3}\x{E88}\x{E97}\x{EB8}\x{E81}\x{EC6} \x{E97}\x{EC8}\x{EB2}\x{E99}\x{E97}\x{EB5}\x{EC8}\x{EA1}\x{EB5}\x{EAA}\x{EC8}\x{EA7}\x{E99}\x{EAE}\x{EC8}\x{EA7}\x{EA1} \x{E97}\x{EB1}\x{E87}\x{E81}\x{EB2}\x{E99}\x{E96}\x{EB2}\x{EA1} \x{EC1}\x{EA5}\x{EB0}\x{E95}\x{EAD}\x{E9A}\x{E97}\x{EB5}\x{EC8}\x{EC0}\x{E81}\x{EB5}\x{E94}\x{E82}\x{EB6}\x{EC9}\x{E99}\x{EC3}\x{E99}\x{E9A}\x{EBB}\x{E94}\x{E84}\x{EA7}\x{EB2}\x{EA1} \x{EC1}\x{EA5}\x{EB0}\x{E81}\x{EB0}\x{E97}\x{EB9}\x{EC9}\x{E95}\x{EC8}\x{EB2}\x{E87}\x{EC6}"
+          text run at (0,64) width 302: "\x{EC3}\x{E99}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{E9A}\x{EAD}\x{E94} \x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{E81}\x{ECD}\x{E96}\x{EB7}\x{EA7}\x{EC8}\x{EB2}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{EA5}\x{E81}\x{E9B}\x{EC8}\x{EBD}\x{E99}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{EAE}\x{EB9}\x{EC9}\x{E81}\x{EB1}\x{E99}. "
+          text run at (301,64) width 477: "\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A}\x{EC3}\x{E99}\x{E9B}\x{EB5} 2011 \x{E99}\x{EB5}\x{EC9} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E84}\x{EB2}\x{E94}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EAA}\x{EB9}\x{E87}\x{EA7}\x{EC8}\x{EB2} \x{E88}\x{EB0}\x{E9B}\x{EB1}\x{E9A}\x{E9B}\x{EB8}\x{E87}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A}\x{EC1}\x{EAB}\x{EC8}\x{E87}\x{E99}\x{EB5}\x{EC9}"
+          text run at (0,85) width 779: "\x{EC3}\x{EAB}\x{EC9}\x{E94}\x{EB5}\x{E8D}\x{EB4}\x{EC8}\x{E87}\x{EC6} \x{E82}\x{EB6}\x{EC9}\x{E99}\x{EC4}\x{E9B}\x{EAD}\x{EB5}\x{E81} \x{EC2}\x{E94}\x{E8D}\x{EAA}\x{EB0}\x{EC0}\x{E9E}\x{EB2}\x{EB0}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99} Localization \x{EAB}\x{EBC}\x{EB7}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{E82}\x{EAD}\x{E87} \x{E99}\x{EB1}\x{EC9}\x{E99}\x{EC0}\x{EAD}\x{E87}. \x{EC0}\x{E96}\x{EB4}\x{E87}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EA7}\x{EC8}\x{EB2}\x{E88}\x{EB0}\x{EA1}\x{EB5}\x{EC4}\x{E9F}\x{EA5}\x{ECC}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{EC0}\x{E81}\x{EBB}\x{EC8}\x{EB2}\x{EA2}\x{EB9}\x{EC8}\x{EC1}\x{EA5}\x{EC9}\x{EA7}"
+          text run at (0,106) width 766: "\x{EC1}\x{E95}\x{EC8}\x{E81}\x{ECD}\x{E8D}\x{EB1}\x{E87}\x{E9A}\x{ECD}\x{EC8}\x{EAA}\x{EBB}\x{EA1}\x{E9A}\x{EB9}\x{E99} \x{EC1}\x{EA5}\x{EB0}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E9C}\x{EB4}\x{E94}\x{E9E}\x{EB2}\x{E94}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E9B}\x{EB0}\x{E81}\x{EB2}\x{E99} \x{E9A}\x{ECD}\x{EC8}\x{EA7}\x{EC8}\x{EB2}\x{E88}\x{EB0}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E9E}\x{EB4}\x{EA1}\x{E9C}\x{EB4}\x{E94} \x{EAB}\x{EBC}\x{EB7}\x{EC1}\x{E9B}\x{E9A}\x{ECD}\x{EC8}\x{E96}\x{EB7}\x{E81} \x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E95}\x{EBB}\x{EC9}\x{E99}. \x{E94}\x{EB1}\x{EC8}\x{E87}\x{E99}\x{EB1}\x{EC9}\x{E99} \x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B}\x{E84}\x{EB7}\x{E99}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} \x{E81}\x{ECD}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EC0}\x{E9B}\x{EBB}\x{EC9}\x{EB2}"
+          text run at (0,127) width 665: "\x{EDD}\x{EB2}\x{E8D}\x{EAD}\x{EB1}\x{E99}\x{E99}\x{EB6}\x{EC8}\x{E87} \x{EC0}\x{E8A}\x{EB1}\x{EC8}\x{E99}\x{E94}\x{EBD}\x{EA7}\x{E81}\x{EB1}\x{E9A}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B} Component \x{EC2}\x{E95}\x{EAD}\x{EB7}\x{EC8}\x{E99}\x{EC6} \x{E97}\x{EB5}\x{EC8}\x{E99}\x{EB4}\x{E8D}\x{EBB}\x{EA1}\x{EC3}\x{E8A}\x{EC9}\x{E81}\x{EB1}\x{E99} \x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC0}\x{E8A}\x{EB1}\x{EC8}\x{E99} Kunena \x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA5}\x{EB0}\x{E9A}\x{EBB}\x{E9A}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{E9A}\x{EAD}\x{E94}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} "
+          text run at (664,127) width 120: "\x{E99}\x{EAD}\x{E81}\x{E88}\x{EB2}\x{E81}\x{E99}\x{EB1}\x{EC9}\x{E99} \x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99}"
+          text run at (0,148) width 770: "\x{E81}\x{EB2}\x{E99}\x{EAA}\x{EAD}\x{E99} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{E81}\x{ECD}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{E8D}\x{EB4}\x{EC8}\x{E87}\x{EA7}\x{EC8}\x{EB2} \x{E88}\x{EB0}\x{EAA}\x{EB2}\x{EA1}\x{EB2}\x{E94}\x{EC0}\x{E9B}\x{EB5}\x{E94}\x{E84}\x{EAD}\x{EAA}\x{EAA}\x{EAD}\x{E99} \x{EC3}\x{E99}\x{EA7}\x{EBD}\x{E87}\x{E88}\x{EB1}\x{E99}\x{EC4}\x{E94}\x{EC9}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EAE}\x{EB9}\x{E9A}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EAE}\x{EC8}\x{EB2}\x{E87} \x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A}\x{E95}\x{EAD}\x{E99}\x{E99}\x{EB5}\x{EC9}\x{E81}\x{ECD}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E82}\x{EB2}\x{E94}\x{EC0}\x{E82}\x{EB5}\x{E99}"
+          text run at (0,169) width 780: "\x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99}\x{EC0}\x{E87}\x{EB7}\x{EC8}\x{EAD}\x{E99}\x{EC4}\x{E82}\x{E95}\x{EC8}\x{EB2}\x{E87}\x{EC6} \x{EC2}\x{E94}\x{E8D}\x{EAA}\x{EB0}\x{EC0}\x{E9E}\x{EB2}\x{EB0}\x{E81}\x{ECD}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EAA}\x{EB0}\x{E96}\x{EB2}\x{E99}\x{E97}\x{EB5}\x{EC8}. \x{EC0}\x{E96}\x{EB4}\x{E87}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC3}\x{E94}\x{E81}\x{ECD}\x{E95}\x{EB2}\x{EA1} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{EC0}\x{E8A}\x{EB7}\x{EC8}\x{EAD}\x{EDD}\x{EB1}\x{EC9}\x{E99}\x{EA7}\x{EC8}\x{EB2} \x{E88}\x{EB0}\x{EA1}\x{EB5}\x{EA1}\x{EB7}\x{EC9}\x{E99}\x{EB6}\x{EC8}\x{E87} \x{E97}\x{EB5}\x{EC8}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{E99}\x{EB5}\x{EC9}\x{E88}\x{EB0}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E88}\x{EB4}\x{E87}\x{E82}\x{EB6}\x{EC9}\x{E99}\x{EA1}\x{EB2}\x{EC4}\x{E94}\x{EC9}."
+          text run at (0,190) width 354: "\x{ED1}\x{ED6} \x{EA1}\x{EB1}\x{E87}\x{E81}\x{EAD}\x{E99} \x{ED2}\x{ED0}\x{ED1}\x{ED1} \x{E97}\x{EB0}\x{E99}\x{EB0}\x{EA7}\x{ECD}\x{EA5}\x{EB0}\x{E81}\x{EB4}\x{E94} \x{E81}\x{EB8}\x{E99}\x{E97}\x{EB0}\x{EA7}\x{EB1}\x{E94}\x{E9E}\x{EB4}\x{E99}\x{EC2}\x{E8D} \x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EA1}\x{EB2}\x{EAA}\x{EC0}\x{E95}\x{EB5}"
diff --git a/LayoutTests/platform/mac/fast/text/khmer-lao-font-expected.txt b/LayoutTests/platform/mac/fast/text/khmer-lao-font-expected.txt
new file mode 100644 (file)
index 0000000..db3a707
--- /dev/null
@@ -0,0 +1,37 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 691x18
+          text run at (0,0) width 691: "This file includes Khmer and Lao text, and makes sure that the render tree metrics match what they should be."
+      RenderBlock (anonymous) at (0,34) size 784x18
+        RenderText {#text} at (0,0) size 48x18
+          text run at (0,0) width 48: "Khmer:"
+      RenderBlock {P} at (0,68) size 784x108
+        RenderText {#text} at (0,2) size 783x99
+          text run at (0,2) width 783: "\x{179A}\x{17C3}\x{17A1}\x{1784}\x{17CB} \x{179A}\x{1794}\x{179F}\x{17CB}\x{1781}\x{17D2}\x{1798}\x{17C2}\x{179A} \x{179B}\x{1791}\x{17D2}\x{1792}\x{1795}\x{179B}\x{200B}\x{1794}\x{17D2}\x{179A}\x{17A0}\x{17C2}\x{179B} \x{1794}\x{1780}\x{1794}\x{17D2}\x{179A}\x{17C2}\x{200B}\x{1791}\x{17C6}\x{1796}\x{17D0}\x{179A}\x{200B}\x{1793}\x{17C1}\x{17C7} \x{179F}\x{17D2}\x{179C}\x{17C2}\x{1784}\x{179A}\x{1780} \x{179A}\x{17BC}\x{1794}\x{1797}\x{17B6}\x{1796} \x{1795}\x{17C2}\x{1793}\x{1791}\x{17B8} \x{1794}\x{1780}\x{200B}\x{1794}\x{17D2}\x{179A}\x{17C2} \x{179A}\x{17BC}\x{1794}\x{1797}\x{17B6}\x{1796}\x{200B}\x{179F}\x{1798}\x{17D2}\x{179A}\x{17B6}\x{1794}\x{17CB} \x{1785}\x{17D2}\x{179A}\x{17BE}\x{1793}\x{200B}\x{1791}\x{17C0}\x{178F}\x{200B}\x{178A}\x{17C4}\x{1799} \x{1787}\x{17C6}\x{1793}\x{17BD}\x{1799} \x{1795}\x{17D2}\x{1789}\x{17BE}\x{200B}\x{1798}\x{178F}\x{17B7}\x{200B}\x{1794}\x{17D2}\x{179A}\x{178F}\x{17B7}\x{1780}\x{1798}\x{17D2}\x{1798} \x{17AF}\x{1780}\x{1787}\x{1793}\x{1797}\x{17B6}\x{1796} & \x{1782}\x{17C4}\x{179B}\x{1780}\x{17B6}\x{179A}\x{178E}\x{17CD}"
+          text run at (0,29) width 772: "\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C} \x{1787}\x{17B6}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1798}\x{17BD}\x{1799}\x{200B}\x{1793}\x{17C3}\x{200B}\x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{1780}\x{1798}\x{17D2}\x{1796}\x{17BB}\x{1787}\x{17B6}\x{200B}\x{1780}\x{17D2}\x{179A}\x{17C4}\x{1798} \x{178B}\x{17B7}\x{178F}\x{200B}\x{1793}\x{17C5}\x{200B}\x{178F}\x{17C6}\x{1794}\x{1793}\x{17CB} \x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{179F}\x{178E}\x{17D2}\x{178F}\x{200B}\x{1791}\x{1793}\x{17D2}\x{179B}\x{17C1}\x{1798}\x{17C1}\x{1782}\x{1784}\x{17D2}\x{1782} \x{17D4} \x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C}\x{179F}\x{1798}\x{17D2}\x{1794}\x{17BC}\x{179A} \x{178A}\x{17C4}\x{1799} \x{1797}\x{17C4}\x{1782}\x{1795}\x{179B}\x{200B}\x{1780}\x{179F}\x{17B7}\x{1780}\x{1798}\x{17D2}\x{1798} \x{1798}\x{17B6}\x{1793}\x{200B}\x{1785}\x{17C6}\x{1780}\x{17B6}\x{179A} \x{178A}\x{17C6}\x{178E}\x{17B6}\x{17C6}\x{200B}\x{179F}\x{17D2}\x{179A}\x{17C2}\x{200B}\x{179F}\x{17D2}\x{179A}\x{17BC}\x{179C} \x{179F}\x{17D2}\x{179A}\x{17C2}\x{17A2}\x{17C6}\x{1794}\x{17B7}\x{179B}"
+          text run at (0,56) width 766: "\x{1787}\x{179B}\x{1795}\x{179B}\x{200B}\x{1791}\x{17B9}\x{1780}\x{179F}\x{17B6}\x{1794}\x{200B}\x{1791}\x{17B9}\x{1780} \x{1794}\x{17D2}\x{179A}\x{17C3} \x{1793}\x{17B7}\x{1784}\x{200B}\x{179A}\x{1785}\x{1793}\x{17B6}\x{179F}\x{1798}\x{17D2}\x{1796}\x{17D0}\x{1793}\x{17D2}\x{1792}\x{1792}\x{17B6}\x{179A}\x{17B6}\x{179F}\x{17B6}\x{179F}\x{17D2}\x{178F}\x{17D2}\x{179A} \x{1792}\x{1798}\x{17D2}\x{1798}\x{1787}\x{17B6}\x{178F}\x{17B7}\x{200B}\x{1781}\x{17D2}\x{179C}\x{17B6}\x{178F}\x{17CB}\x{1781}\x{17D2}\x{179C}\x{17C2}\x{1784}\x{17D4}\x{200B} \x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C} \x{179F}\x{17D2}\x{1790}\x{17B7}\x{178F}\x{1793}\x{17C5}\x{200B}\x{1794}\x{17C2}\x{1780}\x{200B}\x{1781}\x{17B6}\x{1784}\x{179B}\x{17B7}\x{1785}\x{200B}\x{1793}\x{17C3}\x{200B}\x{178A}\x{17C2}\x{1793}\x{178A}\x{17B8}\x{200B}\x{1780}\x{1798}\x{17D2}\x{1796}\x{17BB}\x{1787}\x{17B6}\x{200B}\x{1780}\x{17D2}\x{179A}\x{17C4}\x{1798} \x{1798}\x{1787}\x{17D2}\x{1788}\x{1798}\x{178E}\x{17D2}\x{178C}\x{179B}\x{200B}\x{1793}\x{17C3}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1793}\x{17C1}\x{17C7}\x{200B}\x{1782}\x{17BA} \x{1791}\x{17B8}\x{200B}\x{179A}\x{17BD}\x{1798}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}"
+          text run at (0,83) width 415: "\x{179B}\x{17B6}\x{179C}\x{17D4} \x{1796}\x{17B8}\x{200B}\x{1791}\x{17B8}\x{200B}\x{179A}\x{17BD}\x{1798}\x{200B}\x{1781}\x{17C1}\x{178F}\x{17D2}\x{178F}\x{200B}\x{1796}\x{179B}\x{200B}\x{179B}\x{17B6}\x{179C}\x{200B}\x{1791}\x{17C5}\x{200B}\x{1791}\x{17B8}\x{1780}\x{17D2}\x{179A}\x{17BB}\x{1784}\x{200B}\x{1796}\x{17D2}\x{179A}\x{17C3}\x{1793}\x{1782}\x{179A}\x{1798}\x{17B6}\x{1793}\x{200B}\x{1785}\x{1798}\x{17D2}\x{1784}\x{17B6}\x{1799} \x{17E2}\x{17E8}\x{17E0} \x{1782}\x{200B}.\x{200B}\x{1798}\x{200B}. \x{178F}\x{17B6}\x{1798}\x{1795}\x{17D2}\x{179B}\x{17BC}\x{179C}\x{200B}\x{1787}\x{17B6}\x{178F}\x{17B7} \x{179B}\x{17C1}\x{1781} \x{17E1}"
+      RenderBlock (anonymous) at (0,192) size 784x36
+        RenderBR {BR} at (0,0) size 0x18
+        RenderText {#text} at (0,18) size 29x18
+          text run at (0,18) width 29: "Lao:"
+      RenderBlock {P} at (0,244) size 784x242
+        RenderText {#text} at (0,0) size 777x238
+          text run at (0,0) width 759: "\x{E84}\x{EBB}\x{EC9}\x{E99}\x{EAB}\x{EB2} \x{EAE}\x{EB9}\x{E9A}\x{E9E}\x{EB2}\x{E9A} \x{EC1}\x{E9C}\x{E99}\x{E97}\x{EB5}\x{EC8} \x{EC1}\x{E9B}\x{E9E}\x{EB2}\x{EAA}\x{EB2} \x{EA1}\x{EB7}\x{E96}\x{EB7} \x{E9A}\x{EA5}\x{EB1}\x{EAD}\x{E81}\x{EC0}\x{E81}\x{EB5} \x{EC0}\x{E9E}\x{EB5}\x{EC8}\x{EA1}\x{EC0}\x{E95}\x{EB5}\x{EA1}\x{E88}\x{EB2}\x{E81} \x{EC1}\x{E9B}\x{EDC}\x{EC9}\x{EB2}\x{E99}\x{EB5}\x{EC9} \x{EAE}\x{EB9}\x{E9A}\x{E9E}\x{EB2}\x{E9A}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} \x{EC1}\x{E9B}\x{EDC}\x{EC9}\x{EB2}\x{E99}\x{EB5}\x{EC9} \x{EAB}\x{EBC}\x{EB1}\x{E87}\x{E88}\x{EB2}\x{E81}\x{E97}\x{EB5}\x{EC8}\x{EC0}\x{E9B}\x{EB5}\x{E94}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A} \x{E9A}\x{EAA}\x{EB2}\x{EA1}\x{E9B}\x{EB5} \x{E95}\x{EB1}\x{EC9}\x{E87}\x{EC1}\x{E95}\x{EC8}\x{E9B}\x{EB5}"
+          text run at (0,22) width 775: "\x{E88}\x{EBB}\x{E99}\x{E95}\x{EAD}\x{E99}\x{E99}\x{EB5}\x{EC9}\x{E9B}\x{EB5} \x{EC1}\x{EA5}\x{EC9}\x{EA7} \x{E81}\x{ECD}\x{EA1}\x{EB5}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{EAA}\x{EB4}\x{EC8}\x{E87}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC0}\x{E81}\x{EB5}\x{E94}\x{E82}\x{EB6}\x{EC9}\x{E99} \x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E84}\x{EBB}\x{E99}\x{E81}\x{ECD}\x{EC4}\x{E94}\x{EC9}\x{EAE}\x{EBD}\x{E99}\x{EAE}\x{EB9}\x{EC9}\x{EA7}\x{EB4}\x{E97}\x{EB5}\x{E81}\x{EB2}\x{E99}\x{EC3}\x{E8A}\x{EC9} \x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E84}\x{EBB}\x{E99}\x{E81}\x{ECD}\x{E87}\x{EBB}\x{E87}\x{E81}\x{EB1}\x{E9A}\x{E81}\x{EB2}\x{E99}\x{EC3}\x{E8A}\x{EC9} \x{EC0}\x{E82}\x{EBB}\x{EC9}\x{EB2}\x{EC4}\x{E9B}\x{EAD}\x{EB5}\x{E81} (\x{EAD}\x{EC9}\x{EB2}\x{EA7}!) \x{EC1}\x{E95}\x{EC8}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC3}\x{E94}\x{E81}\x{ECD}\x{E95}\x{EB2}\x{EA1}"
+          text run at (0,44) width 698: "\x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2} \x{EC3}\x{E99}\x{E99}\x{EB2}\x{EA1}\x{E82}\x{EAD}\x{E87}\x{E9C}\x{EB9}\x{EC8}\x{EAA}\x{EC9}\x{EB2}\x{E87}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A}\x{E99}\x{EB5}\x{EC9} \x{E81}\x{ECD}\x{E95}\x{EC9}\x{EAD}\x{E87}\x{E82}\x{ECD}\x{E82}\x{EAD}\x{E9A}\x{EC3}\x{E88}\x{E97}\x{EB8}\x{E81}\x{EC6} \x{E97}\x{EC8}\x{EB2}\x{E99}\x{E97}\x{EB5}\x{EC8}\x{EA1}\x{EB5}\x{EAA}\x{EC8}\x{EA7}\x{E99}\x{EAE}\x{EC8}\x{EA7}\x{EA1} \x{E97}\x{EB1}\x{E87}\x{E81}\x{EB2}\x{E99}\x{E96}\x{EB2}\x{EA1} \x{EC1}\x{EA5}\x{EB0}\x{E95}\x{EAD}\x{E9A}\x{E97}\x{EB5}\x{EC8}\x{EC0}\x{E81}\x{EB5}\x{E94}\x{E82}\x{EB6}\x{EC9}\x{E99}\x{EC3}\x{E99}\x{E9A}\x{EBB}\x{E94}\x{E84}\x{EA7}\x{EB2}\x{EA1}"
+          text run at (0,66) width 400: "\x{EC1}\x{EA5}\x{EB0}\x{E81}\x{EB0}\x{E97}\x{EB9}\x{EC9}\x{E95}\x{EC8}\x{EB2}\x{E87}\x{EC6} \x{EC3}\x{E99}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{E9A}\x{EAD}\x{E94} \x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{E81}\x{ECD}\x{E96}\x{EB7}\x{EA7}\x{EC8}\x{EB2}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{EA5}\x{E81}\x{E9B}\x{EC8}\x{EBD}\x{E99}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{EAE}\x{EB9}\x{EC9}\x{E81}\x{EB1}\x{E99}. "
+          text run at (400,66) width 355: "\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A}\x{EC3}\x{E99}\x{E9B}\x{EB5} 2011 \x{E99}\x{EB5}\x{EC9} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E84}\x{EB2}\x{E94}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EAA}\x{EB9}\x{E87}\x{EA7}\x{EC8}\x{EB2}"
+          text run at (0,88) width 666: "\x{E88}\x{EB0}\x{E9B}\x{EB1}\x{E9A}\x{E9B}\x{EB8}\x{E87}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EC4}\x{E8A}\x{EC1}\x{EAB}\x{EC8}\x{E87}\x{E99}\x{EB5}\x{EC9} \x{EC3}\x{EAB}\x{EC9}\x{E94}\x{EB5}\x{E8D}\x{EB4}\x{EC8}\x{E87}\x{EC6} \x{E82}\x{EB6}\x{EC9}\x{E99}\x{EC4}\x{E9B}\x{EAD}\x{EB5}\x{E81} \x{EC2}\x{E94}\x{E8D}\x{EAA}\x{EB0}\x{EC0}\x{E9E}\x{EB2}\x{EB0}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99} Localization \x{EAB}\x{EBC}\x{EB7}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{E82}\x{EAD}\x{E87} \x{E99}\x{EB1}\x{EC9}\x{E99}\x{EC0}\x{EAD}\x{E87}."
+          text run at (0,110) width 762: "\x{EC0}\x{E96}\x{EB4}\x{E87}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EA7}\x{EC8}\x{EB2}\x{E88}\x{EB0}\x{EA1}\x{EB5}\x{EC4}\x{E9F}\x{EA5}\x{ECC}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{EC0}\x{E81}\x{EBB}\x{EC8}\x{EB2}\x{EA2}\x{EB9}\x{EC8}\x{EC1}\x{EA5}\x{EC9}\x{EA7} \x{EC1}\x{E95}\x{EC8}\x{E81}\x{ECD}\x{E8D}\x{EB1}\x{E87}\x{E9A}\x{ECD}\x{EC8}\x{EAA}\x{EBB}\x{EA1}\x{E9A}\x{EB9}\x{E99} \x{EC1}\x{EA5}\x{EB0}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E9C}\x{EB4}\x{E94}\x{E9E}\x{EB2}\x{E94}\x{EAB}\x{EBC}\x{EB2}\x{E8D}\x{E9B}\x{EB0}\x{E81}\x{EB2}\x{E99} \x{E9A}\x{ECD}\x{EC8}\x{EA7}\x{EC8}\x{EB2}\x{E88}\x{EB0}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E9E}\x{EB4}\x{EA1}\x{E9C}\x{EB4}\x{E94} \x{EAB}\x{EBC}\x{EB7}\x{EC1}\x{E9B}\x{E9A}\x{ECD}\x{EC8}\x{E96}\x{EB7}\x{E81} \x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E95}\x{EBB}\x{EC9}\x{E99}."
+          text run at (0,132) width 759: "\x{E94}\x{EB1}\x{EC8}\x{E87}\x{E99}\x{EB1}\x{EC9}\x{E99} \x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B}\x{E84}\x{EB7}\x{E99}\x{E9E}\x{EB2}\x{EAA}\x{EB2}\x{EA5}\x{EB2}\x{EA7}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} \x{E81}\x{ECD}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EC0}\x{E9B}\x{EBB}\x{EC9}\x{EB2}\x{EDD}\x{EB2}\x{E8D}\x{EAD}\x{EB1}\x{E99}\x{E99}\x{EB6}\x{EC8}\x{E87} \x{EC0}\x{E8A}\x{EB1}\x{EC8}\x{E99}\x{E94}\x{EBD}\x{EA7}\x{E81}\x{EB1}\x{E9A}\x{E81}\x{EB2}\x{E99}\x{EC1}\x{E9B} Component \x{EC2}\x{E95}\x{EAD}\x{EB7}\x{EC8}\x{E99}\x{EC6} \x{E97}\x{EB5}\x{EC8}\x{E99}\x{EB4}\x{E8D}\x{EBB}\x{EA1}\x{EC3}\x{E8A}\x{EC9}\x{E81}\x{EB1}\x{E99} \x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC0}\x{E8A}\x{EB1}\x{EC8}\x{E99} Kunena"
+          text run at (0,154) width 171: "\x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA5}\x{EB0}\x{E9A}\x{EBB}\x{E9A}\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{E9A}\x{EAD}\x{E94}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A} "
+          text run at (171,154) width 507: "\x{E99}\x{EAD}\x{E81}\x{E88}\x{EB2}\x{E81}\x{E99}\x{EB1}\x{EC9}\x{E99} \x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99}\x{E81}\x{EB2}\x{E99}\x{EAA}\x{EAD}\x{E99} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{E81}\x{ECD}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{E8D}\x{EB4}\x{EC8}\x{E87}\x{EA7}\x{EC8}\x{EB2} \x{E88}\x{EB0}\x{EAA}\x{EB2}\x{EA1}\x{EB2}\x{E94}\x{EC0}\x{E9B}\x{EB5}\x{E94}\x{E84}\x{EAD}\x{EAA}\x{EAA}\x{EAD}\x{E99}"
+          text run at (0,176) width 696: "\x{EC3}\x{E99}\x{EA7}\x{EBD}\x{E87}\x{E88}\x{EB1}\x{E99}\x{EC4}\x{E94}\x{EC9}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EAE}\x{EB9}\x{E9A}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{EAE}\x{EC8}\x{EB2}\x{E87} \x{EC0}\x{E8A}\x{EB4}\x{EC8}\x{E87}\x{EAA}\x{EB3}\x{EA5}\x{EB1}\x{E9A}\x{E95}\x{EAD}\x{E99}\x{E99}\x{EB5}\x{EC9}\x{E81}\x{ECD}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EA1}\x{EB5}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{E82}\x{EB2}\x{E94}\x{EC0}\x{E82}\x{EB5}\x{E99}\x{EC3}\x{E99}\x{E94}\x{EC9}\x{EB2}\x{E99}\x{EC0}\x{E87}\x{EB7}\x{EC8}\x{EAD}\x{E99}\x{EC4}\x{E82}\x{E95}\x{EC8}\x{EB2}\x{E87}\x{EC6} \x{EC2}\x{E94}\x{E8D}\x{EAA}\x{EB0}\x{EC0}\x{E9E}\x{EB2}\x{EB0}\x{E81}\x{ECD}\x{EC1}\x{EA1}\x{EC8}\x{E99}\x{EAA}\x{EB0}\x{E96}\x{EB2}\x{E99}\x{E97}\x{EB5}\x{EC8}."
+          text run at (0,198) width 488: "\x{EC0}\x{E96}\x{EB4}\x{E87}\x{EA2}\x{EC8}\x{EB2}\x{E87}\x{EC3}\x{E94}\x{E81}\x{ECD}\x{E95}\x{EB2}\x{EA1} \x{E82}\x{EC9}\x{EB2}\x{E9E}\x{EB0}\x{EC0}\x{E88}\x{EBB}\x{EC9}\x{EB2}\x{EC0}\x{E8A}\x{EB7}\x{EC8}\x{EAD}\x{EDD}\x{EB1}\x{EC9}\x{E99}\x{EA7}\x{EC8}\x{EB2} \x{E88}\x{EB0}\x{EA1}\x{EB5}\x{EA1}\x{EB7}\x{EC9}\x{E99}\x{EB6}\x{EC8}\x{E87} \x{E97}\x{EB5}\x{EC8}\x{E84}\x{EA7}\x{EB2}\x{EA1}\x{EAB}\x{EA7}\x{EB1}\x{E87}\x{E99}\x{EB5}\x{EC9}\x{E88}\x{EB0}\x{EC0}\x{E9B}\x{EB1}\x{E99}\x{E88}\x{EB4}\x{E87}\x{E82}\x{EB6}\x{EC9}\x{E99}\x{EA1}\x{EB2}\x{EC4}\x{E94}\x{EC9}. "
+          text run at (488,198) width 289: "\x{ED1}\x{ED6} \x{EA1}\x{EB1}\x{E87}\x{E81}\x{EAD}\x{E99} \x{ED2}\x{ED0}\x{ED1}\x{ED1} \x{E97}\x{EB0}\x{E99}\x{EB0}\x{EA7}\x{ECD}\x{EA5}\x{EB0}\x{E81}\x{EB4}\x{E94} \x{E81}\x{EB8}\x{E99}\x{E97}\x{EB0}\x{EA7}\x{EB1}\x{E94}\x{E9E}\x{EB4}\x{E99}\x{EC2}\x{E8D}"
+          text run at (0,220) width 65: "\x{EC0}\x{EA7}\x{EB1}\x{E9A}\x{EA1}\x{EB2}\x{EAA}\x{EC0}\x{E95}\x{EB5}"
index c1913e9be1bc52456f48308792b9a63af57a99b0..0e415cd404fde7349d7ec452aa065b972d74696c 100644 (file)
@@ -1,3 +1,21 @@
+2014-06-20  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [iOS] Support Khmer and Lao fallback fonts
+        https://bugs.webkit.org/show_bug.cgi?id=134114
+
+        Reviewed by Enrica Casucci.
+
+        iOS has fonts which have glyphs for the Khmer and Lao languages.
+
+        This patch also does a little refactoring of the language-specific fallback
+        font path to increase readability.
+
+        Test: fast/text/khmer-lao-font.html
+
+        * platform/graphics/ios/FontCacheIOS.mm:
+        (WebCore::languageSpecificFallbackFont):
+        (WebCore::FontCache::systemFallbackForCharacters):
+
 2014-06-20  Anders Carlsson  <andersca@apple.com>
 
         Give NPAPI post requests a default content type
index e04c734714f1eb6855c055d938408b6ef45190f8..01177f0f8beacf1fe2635516941c07d70c49f66a 100644 (file)
@@ -99,10 +99,103 @@ PassRefPtr<SimpleFontData> FontCache::getSystemFontFallbackForCharacters(const F
     return getCachedFontData(&alternateFont, DoNotRetain);
 }
 
-PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDescription& description, const SimpleFontData* originalFontData, bool, const UChar* characters, int length)
+enum class LanguageSpecificFont {
+    None,
+    ChineseJapanese,
+    Korean,
+    Cyrillic,
+    Arabic,
+    Hebrew,
+    Indic,
+    Thai,
+    Lao,
+    Tibetan,
+    CanadianAboriginalSyllabic,
+    Khmer,
+    Emoji,
+};
+
+static LanguageSpecificFont languageSpecificFallbackFont(UChar32 c)
 {
     static bool isGB18030ComplianceRequired = wkIsGB18030ComplianceRequired();
 
+    // The following ranges are Korean Hangul and should be rendered by AppleSDGothicNeo
+    // U+1100 - U+11FF
+    // U+3130 - U+318F
+    // U+AC00 - U+D7A3
+
+    // These are Cyrillic and should be rendered by Helvetica Neue
+    // U+0400 - U+052F
+
+    if (c < 0x400)
+        return LanguageSpecificFont::None;
+    if (c <= 0x52F)
+        return LanguageSpecificFont::Cyrillic;
+    if (c < 0x590)
+        return LanguageSpecificFont::None;
+    if (c < 0x600)
+        return LanguageSpecificFont::Hebrew;
+    if (c <= 0x6FF)
+        return LanguageSpecificFont::Arabic;
+    if (c < 0x900)
+        return LanguageSpecificFont::None;
+    if (c < 0xE00)
+        return LanguageSpecificFont::Arabic;
+    if (c <= 0xE7F)
+        return LanguageSpecificFont::Thai;
+    if (c < 0x0F00)
+        return LanguageSpecificFont::Lao;
+    if (c <= 0x0FFF)
+        return LanguageSpecificFont::Tibetan;
+    if (c < 0x1100)
+        return LanguageSpecificFont::None;
+    if (c <= 0x11FF)
+        return LanguageSpecificFont::Korean;
+    if (c > 0x1400 && c < 0x1780)
+        return LanguageSpecificFont::CanadianAboriginalSyllabic;
+    if (c < 0x1800)
+        return LanguageSpecificFont::Khmer;
+    if (c < 0x2E80)
+        return LanguageSpecificFont::None;
+    if (c < 0x3130)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c <= 0x318F)
+        return LanguageSpecificFont::Korean;
+    if (c < 0xAC00)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c <= 0xD7A3)
+        return LanguageSpecificFont::Korean;
+    if (c <= 0xDFFF)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c < 0xE000)
+        return LanguageSpecificFont::None;
+    if (c < 0xE600)
+        return isGB18030ComplianceRequired ? LanguageSpecificFont::ChineseJapanese : LanguageSpecificFont::Emoji;
+    if (c <= 0xE864 && isGB18030ComplianceRequired)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c <= 0xF8FF)
+        return LanguageSpecificFont::None;
+    if (c < 0xFB00)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c < 0xFB50)
+        return LanguageSpecificFont::None;
+    if (c <= 0xFDFF)
+        return LanguageSpecificFont::Arabic;
+    if (c < 0xFE20)
+        return LanguageSpecificFont::None;
+    if (c < 0xFE70)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c < 0xFF00)
+        return LanguageSpecificFont::Arabic;
+    if (c < 0xFFF0)
+        return LanguageSpecificFont::ChineseJapanese;
+    if (c >=0x20000 && c <= 0x2FFFF)
+        return LanguageSpecificFont::ChineseJapanese;
+    return LanguageSpecificFont::None;
+}
+
+PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDescription& description, const SimpleFontData* originalFontData, bool, const UChar* characters, int length)
+{
     // Unlike OS X, our fallback font on iPhone is Arial Unicode, which doesn't have some apple-specific glyphs like F8FF.
     // Fall back to the Apple Fallback font in this case.
     if (length > 0 && requiresCustomFallbackFont(*characters))
@@ -119,139 +212,14 @@ PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDesc
             return getSystemFontFallbackForCharacters(description, originalFontData, characters, length);
     }
 
-    bool useCJFont = false;
-    bool useKoreanFont = false;
-    bool useCyrillicFont = false;
-    bool useArabicFont = false;
-    bool useHebrewFont = false;
-    bool useIndicFont = false;
-    bool useThaiFont = false;
-    bool useTibetanFont = false;
-    bool useCanadianAboriginalSyllabicsFont = false;
-    bool useEmojiFont = false;
-    if (length > 0) {
-        do {
-            // This isn't a loop but a way to efficiently check for ranges of characters.
-
-            // The following ranges are Korean Hangul and should be rendered by AppleSDGothicNeo
-            // U+1100 - U+11FF
-            // U+3130 - U+318F
-            // U+AC00 - U+D7A3
-
-            // These are Cyrillic and should be rendered by Helvetica Neue
-            // U+0400 - U+052F
-
-            if (c < 0x400)
-                break;
-            if (c <= 0x52F) {
-                useCyrillicFont = true;
-                break;
-            }
-            if (c < 0x590)
-                break;
-            if (c < 0x600) {
-                useHebrewFont = true;
-                break;
-            }
-            if (c <= 0x6FF) {
-                useArabicFont = true;
-                break;
-            }
-            if (c < 0x900)
-                break;
-            if (c < 0xE00) {
-                useIndicFont = true;
-                break;
-            }
-            if (c <= 0xE7F) {
-                useThaiFont = true;
-                break;
-            }
-            if (c < 0x0F00)
-                break;
-            if (c <= 0x0FFF) {
-                useTibetanFont = true;
-                break;
-            }
-            if (c < 0x1100)
-                break;
-            if (c <= 0x11FF) {
-                useKoreanFont = true;
-                break;
-            }
-            if (c > 0x1400 && c < 0x1780) {
-                useCanadianAboriginalSyllabicsFont = true;
-                break;
-            }
-            if (c < 0x2E80)
-                break;
-            if (c < 0x3130) {
-                useCJFont = true;
-                break;
-            }
-            if (c <= 0x318F) {
-                useKoreanFont = true;
-                break;
-            }
-            if (c < 0xAC00) {
-                useCJFont = true;
-                break;
-            }
-            if (c <= 0xD7A3) {
-                useKoreanFont = true;
-                break;
-            }
-            if ( c <= 0xDFFF) {
-                useCJFont = true;
-                break;
-            }
-            if ( c < 0xE000)
-                break;
-            if ( c < 0xE600) {
-                if (isGB18030ComplianceRequired)
-                    useCJFont = true;
-                else
-                    useEmojiFont = true;
-                break;
-            }
-            if ( c <= 0xE864 && isGB18030ComplianceRequired) {
-                useCJFont = true;
-                break;
-            }
-            if (c <= 0xF8FF)
-                break;
-            if (c < 0xFB00) {
-                useCJFont = true;
-                break;
-            }
-            if (c < 0xFB50)
-                break;
-            if (c <= 0xFDFF) {
-                useArabicFont = true;
-                break;
-            }
-            if (c < 0xFE20)
-                break;
-            if (c < 0xFE70) {
-                useCJFont = true;
-                break;
-            }
-            if (c < 0xFF00) {
-                useArabicFont = true;
-                break;
-            }
-            if (c < 0xFFF0) {
-                useCJFont = true;
-                break;
-            }
-            if (c >=0x20000 && c <= 0x2FFFF)
-                useCJFont = true;
-        } while (0);
-    }
+    LanguageSpecificFont languageSpecificFont = LanguageSpecificFont::None;
+    if (length > 0)
+        languageSpecificFont = languageSpecificFallbackFont(c);
 
     RefPtr<SimpleFontData> simpleFontData;
 
-    if (useCJFont) {
+    switch (languageSpecificFont) {
+    case LanguageSpecificFont::ChineseJapanese: {
         // By default, Chinese font is preferred, fall back on Japanese.
 
         enum CJKFontVariant {
@@ -339,23 +307,33 @@ PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDesc
 
         if (useSecondaryFont)
             simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? *cjkBold[secondaryCJKFont] : *cjkPlain[secondaryCJKFont], false, DoNotRetain);
-    } else if (useKoreanFont) {
+        break;
+    }
+    case LanguageSpecificFont::Korean: {
         static NeverDestroyed<AtomicString> koreanPlain("AppleSDGothicNeo-Medium", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> koreanBold("AppleSDGothicNeo-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? koreanBold : koreanPlain, false, DoNotRetain);
-    } else if (useCyrillicFont) {
+        break;
+    }
+    case LanguageSpecificFont::Cyrillic: {
         static NeverDestroyed<AtomicString> cyrillicPlain("HelveticaNeue", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> cyrillicBold("HelveticaNeue-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? cyrillicBold : cyrillicPlain, false, DoNotRetain);
-    } else if (useArabicFont) {
+        break;
+    }
+    case LanguageSpecificFont::Arabic: {
         static NeverDestroyed<AtomicString> arabicPlain("GeezaPro", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> arabicBold("GeezaPro-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? arabicBold : arabicPlain, false, DoNotRetain);
-    } else if (useHebrewFont) {
+        break;
+    }
+    case LanguageSpecificFont::Hebrew: {
         static NeverDestroyed<AtomicString> hebrewPlain("ArialHebrew", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> hebrewBold("ArialHebrew-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? hebrewBold : hebrewPlain, false, DoNotRetain);
-    } else if (useIndicFont) {
+        break;
+    }
+    case LanguageSpecificFont::Indic: {
         static NeverDestroyed<AtomicString> devanagariFont("KohinoorDevanagari-Book", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> bengaliFont("BanglaSangamMN", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> gurmukhiFont("GurmukhiMN", AtomicString::ConstructFromLiteral); // Might be replaced in a future release with a Sangam version.
@@ -410,26 +388,47 @@ PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDesc
             if (indicFontString)
                 simpleFontData = getCachedFontData(description, *indicFontString, false, DoNotRetain);
         }
-    } else if (useThaiFont) {
+        break;
+    }
+    case LanguageSpecificFont::Thai: {
         static NeverDestroyed<AtomicString> thaiPlain("Thonburi", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> thaiBold("Thonburi-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? thaiBold : thaiPlain, false, DoNotRetain);
-    } else if (useTibetanFont) {
+        break;
+    }
+    case LanguageSpecificFont::Tibetan: {
         static NeverDestroyed<AtomicString> tibetanPlain("Kailasa", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> tibetanBold("Kailasa-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? tibetanBold : tibetanPlain, false, DoNotRetain);
-    } else if (useCanadianAboriginalSyllabicsFont) {
+        break;
+    }
+    case LanguageSpecificFont::CanadianAboriginalSyllabic: {
         static NeverDestroyed<AtomicString> casPlain("EuphemiaUCAS", AtomicString::ConstructFromLiteral);
         static NeverDestroyed<AtomicString> casBold("EuphemiaUCAS-Bold", AtomicString::ConstructFromLiteral);
         simpleFontData = getCachedFontData(description, isFontWeightBold(description.weight()) ? casBold : casPlain, false, DoNotRetain);
-    } else {
+        break;
+    }
+    case LanguageSpecificFont::Khmer: {
+        static NeverDestroyed<AtomicString> khmer("KhmerSangamMN", AtomicString::ConstructFromLiteral);
+        simpleFontData = getCachedFontData(description, khmer, false, DoNotRetain);
+        break;
+    }
+    case LanguageSpecificFont::Lao: {
+        static NeverDestroyed<AtomicString> lao("LaoSangamMN", AtomicString::ConstructFromLiteral);
+        simpleFontData = getCachedFontData(description, lao, false, DoNotRetain);
+        break;
+    }
+    default: {
         static NeverDestroyed<AtomicString> appleColorEmoji("AppleColorEmoji", AtomicString::ConstructFromLiteral);
+        bool useEmojiFont = languageSpecificFont == LanguageSpecificFont::Emoji;
         if (!useEmojiFont) {
             if (!CFCharacterSetIsLongCharacterMember(phoneFallbackCharacterSet(), c))
                 useEmojiFont = CFCharacterSetIsLongCharacterMember(appleColorEmojiCharacterSet(), c);
         }
         if (useEmojiFont)
             simpleFontData = getCachedFontData(description, appleColorEmoji, false, DoNotRetain);
+        break;
+    }
     }
 
     if (simpleFontData)