Имеется ошибка в программе libfont.so. Она проявляется при растризации так называемых композитных глифов (Composite Glyph) шрифтов TrueType. Эта ошибка известна как BugID 4546277. И вот как Sun её замотал: |
|
Bug ID Synopsis Date 4546277 S8 - Solaris 8 X86 (intel) displays Cyrillic TrueType fonts incorrectly 29 Jan 2002 Product sunos Category library Subcategory l10n-europe Bug-RFE-EOU bug State incomplete Development Status NYI Keywords TrueType, ansi-1251, font, koi8-r, no-s9+, s9-reviewed Severity 2 Severity Impact 1 Severity Functionality 0 Priority 2 Responsible Manager: XXXXXXXX Responsible Engineer: XXXXXXXX Description Please see screenshot in attachment. Some letters in Arial, Courier and Times TrueType koi8-r and and ansi-1251 displayed incorrectly (wrong kerning). For example: xfd -fn "-monotype-arial-regular-r-*-*-*-*-*-*-*-*-koi8-r" characters 0x00dc and 0x00fc have incorrect metrics - displayed outside of rectangle. The same fonts look fine and are diplayed correctly on Solaris Sparc. Justification These are the only koi-8 and ansi-1251 fonts supplied in Solaris Work Around (none) Suggested Fix (none) State Triggers Accepted: yes Evaluated: no Evaluation (none) Commit to fix in releases (none) Fixed in releases (none) Integrated in releases (none) Verified in releases (none) Closed because (none) Incomplete because need more info Duplicate of (none) Introduced in release (none) Root Cause (none) Program Management (none) Fix Affects Documentation no Exempt from dev rel no Fix affects L10N no Interest List XXXXXX.XXXXXXX@sun.com, XXXXXX@omega.ru Patch ID (none) Comments ============================================================================= X.XXX@sun.com 2002-01-14 Sol8 UR has finished. This is not occurring in Solaris 9. This occurs in Solaris 8 FCS. If you need a patch for Solaris 8, you will need to escalate the bug. The patch will include updated files in /usr/openwin/lib/locale/KOI8-R/X11/fonts/TrueType If not, then this bug will be closed after 1 working week ============================================================================= See also: Hooks Hook 1: Hook 2: Hook 3: Hook 4: Hook 5: Hook 6: History Submitter: XXXXXXXX Date: Dec 4 2001 1:31AM Dispatch operator: bugtraq Date: Dec 4 2001 1:31AM Acceptor: XXXXXXX Date: Dec 11 2001 6:16AM Evaluator: Date: Commit operator: Date: Fix operator: Date: Integrating operator: Date: Verify operator: Date: Closeout operator: Date: Called in by Customer: Company: Sun Microsystems Russia Employee: XXXXXXX XXXXXXXX User Role: D, Development User Type: I, Internal (SMI) Customer Release: s28u6_08 Hardware Version: x86 O/S version (unbundled products): 5.8 SO Number: Sun Contact: XXXXXXXX Contact Name: Contact Mailaddr: |
Переписка с X.XXX@sun.com ничего не дала. Однако перейдём к делу. Композитный глиф состоит из набора простых глифов (образов), каждый из которых перед наложением на плоскость отрисовки может быть подвергнут трансформации: перемасштабированию, вращению, сдвигу. Простые глифы, входящие в состав композитного, могут использоваться самостоятельно. Например, глиф буквы 'Ё' может быть композитным и состоять из двух простых: 'Е' и "двоеточия", причём глиф 'Е' может использоваться самостоятельно, а "двоеточие" входить в состав других композитных глифов - 'ё' и некоторых других символов, входящих в набор iso8859-1. Другой пример - глифы букв 'R' и 'Я'. Один из них, обычно 'R' является простым, а другой ('Я') композитным. Он получается путём масштабирования простого глифа с коэффициентом -1 по X и +1 по Y и сдвига по оси X. Использование композитных глифов уменьшает размер файла шрифта TrueType, потому, что вместо длинной программы отрисовки глифа в файл шрифта помещается несколько двухбайтовых чисел (в формате BIG_ENDIAN) описывающих матрицу преобразования. При установленных по-умолчанию путях к шрифтам, ошибка растризации композитных глифов видна только при работе под кириллическими локализациями ru_RU.KOI8-R и ru_RU.ANSI1251. В локализации же ru_RU.ISO8859-5 пути к шрифтам установлены так, что система перед TrueType, выбирает шрифты Adobe Type1 с теми-же именами, которые растризуются правильно. Солярис 8 имеет 12 TrueType шрифтов: |
|
$ uname -a SunOS lev 5.8 Generic_108528-11 sun4u sparc SUNW,Ultra-1 $ pwd /usr/openwin/lib/locale/euro_fonts/X11/fonts/TrueType $ ls -l total 4336 -rw-r--r-- 1 root bin 147664 Окт 13 1999 ArialBold.ttf -rw-r--r-- 1 root bin 167488 Окт 13 1999 ArialBoldItalic.ttf -rw-r--r-- 1 root bin 147084 Окт 13 1999 ArialItalic.ttf -rw-r--r-- 1 root bin 146436 Окт 13 1999 ArialRegular.ttf -rw-r--r-- 1 root bin 176860 Окт 13 1999 CourierBold.ttf -rw-r--r-- 1 root bin 182284 Окт 13 1999 CourierBoldItalic.ttf -rw-r--r-- 1 root bin 190660 Окт 13 1999 CourierItalic.ttf -rw-r--r-- 1 root bin 175336 Окт 13 1999 CourierRegular.ttf -rw-r--r-- 1 root bin 186032 Окт 13 1999 TimesBold.ttf -rw-r--r-- 1 root bin 174588 Окт 13 1999 TimesBoldItalic.ttf -rw-r--r-- 1 root bin 184644 Окт 13 1999 TimesItalic.ttf -rw-r--r-- 1 root bin 192332 Окт 13 1999 TimesRegular.ttf |
Это шрифты в формате unicode, и они содержат глифы букв всех европейских языков. Выбор того или иного набора осуществляется с помощью задания encoding-вектора для требуемой локализации. Некоторые, неправильно отображаемые, русские буквы "прямых" (не "italic") шрифтов выполнены в виде композитных глифов: |
|
Основной глиф: Композитный глиф: CYRILLIC CAPITAL LETTER UKRAINIAN IE -> CYRILLIC CAPITAL LETTER E afii10053, unicode 0x0404 afii10047, unicode 0x042d CYRILLIC SMALL LETTER UKRAINIAN IE -> CYRILLIC SMALL LETTER E afii10101, unicode 0x0454 afii10095, unicode 0x044d Latin-1 letter R (unicode 0x052) -> CYRILLIC CAPITAL LETTER YA afii10049, unicode 0x042f |
В результате проявления ошибки получаем: |
|
Не следует думать, что только русским (украинцам, белорусcам etc.) не повезло. Испаноговорящие товарищи имеют аналогичные проблемы с символами '!' и '?'. Эти символы используются в начале восклицательного и вопросительного предложений в "перевёрнутом" виде (exclamdown, questiondown) и оформлены в некоторых TrueType шрифтах как композитные глифы. Смотри, например, /usr/openwin/lib/X11/fonts/TrueType/GillSans-BoldItalic.ttf Ошибка обусловлена неправильным считыванием данных матрицы масштабирования из описания символа в таблице glyf шрифта TrueType. Эта матрица считывается из файла шрифта при обработке флагового бита WE_HAVE_AN_X_AND_Y_SCALE или WE_HAVE_A_TWO_BY_TWO. При считывании данных необходимо не только переставить порядок байт, но и обеспечить расширение знака при присваивании четырёхбайтовым числам значений двухбайтовых чисел. Нижеследующий фрагмент текста, часто используемый и, возможно, оформленный в программе libfont.so.1 как макро, читает два байта данных по адресу 4(%eax), переставляет их, но не расширяет знак для отрицательных чисел: |
|
3c2f0: 66 8b 50 04 movw 4(%eax),%dx ; Загрузка 2-х байт. Байт содержащий ; старшие разряды числа - попадёт в %dl, ; байт содержащий младшие разряды числа ; попадёт в %dh 3c2f4: 0f bf ca movswl %dx,%ecx 3c2f7: c1 f9 08 sarl $0x8,%ecx ; В %ecx младший байт. Знаковый бит расширен ; на весь регистр %ecx. Расширение знака ; лишено смысла, поскольку нужно расширять ; знаковый бит старшего байта. Мало того, ; следующие команда затирают три старших ; байта регистров %ecx и %edx нулями 3c2fa: 0f b6 c9 movzbl %cl,%ecх ; Младший байт 3c2fd: 0f b6 d2 movzbl %dl,%edx ; Старший байт, здесь и надо расширить ; знак, т.е. применить команду movsbl 3c300: c1 e2 08 shll $0x8,%edx 3c303: 0b ca orl %edx,%ecx ; Байты числа переставлены, однако отрицательные ; числа превращаются в положительные. 3c305: c1 e1 02 shll $0x2,%ecx ; Масштабирование 3c308: 89 8d 34 ff ff ff movl %ecx,-0xcc(%ebp) |
Ошибка не проявляется на Солярис 8 для SPARC. Детрансляция и анализ кода показали, что исходный код программы libfont.so.1 различен для SPARC и x86. Причём у меня сложилось впечатление, что в для SPARC растризация TrueType шрифтов сделана более корректно. Программу можно поправить. Поскольку исходный код недоступен, то исправления придётся вносить в двоичный код библиотеки libfont.so.1. Дополнительной сложностью является то, что в зависимости от версии патча на X программа libfont.so.1 имеет различное распределение адресов. Далее описана процедура поиска адресов команд, которые должны быть исправлены. Выполните команды: |
|
$ su Password: # cd /usr/openwin/server/lib # cp -p libfont.so.1 libfont.so.1.orig # exit $ cd $HOME $ mkdir libfont $ cd libfont $ dis /usr/openwin/server/lib/libfont.so.1.orig > libfont.so.1.orig.dis |
В файле libfont.so.1.orig.dis найдите функцию sfnt_ReadSFNT() и сравните её текст с нижеприведённым. Запишите адреса команд в Вашем листинге, которые необходимо скорректировать. В нижеприведённом листинге команды, которые необходимо скорректировать отмечены символами '-->': |
|
sfnt_ReadSFNT() 3bfb8: 55 pushl %ebp 3bfb9: 8b ec movl %esp,%ebp 3bfbb: 81 ec d0 00 00 00 subl $0xd0,%esp 3bfc1: 53 pushl %ebx 3bfc2: 56 pushl %esi 3bfc3: 57 pushl %edi 3bfc4: e8 00 00 00 00 call .+5 3bfc9: 5b popl %ebx 3bfca: 81 c3 37 80 01 00 addl $0x18037,%ebx 3bfd0: c7 45 c4 00 00 00 00 movl $0x0,-0x3c(%ebp) 3bfd7: c7 45 fc 00 00 00 00 movl $0x0,-4(%ebp) 3bfde: c7 45 f8 00 00 00 00 movl $0x0,-8(%ebp) 3bfe5: 66 8b 45 10 movw 0x10(%ebp),%ax 3bfe9: 50 pushl %eax 3bfea: ff 75 08 pushl 8(%ebp) 3bfed: e8 1a e3 fc ff call sfnt_ReadSFNTMetrics 3bff2: 83 c4 08 addl $0x8,%esp 3bff5: 8d 45 c4 leal -0x3c(%ebp),%eax 3bff8: 50 pushl %eax 3bff9: 8d 45 c0 leal -0x40(%ebp),%eax 3bffc: 50 pushl %eax 3bffd: 66 8b 45 10 movw 0x10(%ebp),%ax 3c001: 50 pushl %eax 3c002: ff 75 08 pushl 8(%ebp) 3c005: e8 a6 fe ff ff call sfnt_GetGlyphLocation 3c00a: 8b 45 c4 movl -0x3c(%ebp),%eax 3c00d: 23 c0 andl %eax,%eax 3c00f: 0f 8e af 00 00 00 jle .+0xb5 [0x3c0c4] 3c015: 6a 01 pushl $0x1 3c017: 6a 06 pushl $0x6 3c019: 50 pushl %eax 3c01a: ff 75 c0 pushl -0x40(%ebp) 3c01d: ff 75 08 pushl 8(%ebp) 3c020: e8 f7 f9 ff ff call sfnt_GetDataPtr 3c025: 89 45 f8 movl %eax,-8(%ebp) ; адрес таблицы glif 3c028: 66 8b 08 movw (%eax),%cx 3c02b: 0f bf c1 movswl %cx,%eax 3c02e: c1 f8 08 sarl $0x8,%eax 3c031: 0f b6 c0 movzbl %al,%eax 3c034: 0f b6 c9 movzbl %cl,%ecx 3c037: c1 e1 08 shll $0x8,%ecx 3c03a: 66 0b c8 orw %ax,%cx 3c03d: 66 89 4d a4 movw %cx,-0x5c(%ebp) ; число контуров numberOfContours 3c041: 8b 45 f8 movl -8(%ebp),%eax 3c044: 66 8b 70 02 movw 2(%eax),%si ; xMin 3c048: 0f bf c6 movswl %si,%eax 3c04b: c1 f8 08 sarl $0x8,%eax 3c04e: 0f b6 d0 movzbl %al,%edx 3c051: 8b c6 movl %esi,%eax 3c053: 0f b6 c0 movzbl %al,%eax 3c056: c1 e0 08 shll $0x8,%eax 3c059: 66 0b c2 orw %dx,%ax 3c05c: 66 89 45 b8 movw %ax,-0x48(%ebp) 3c060: 8b 45 f8 movl -8(%ebp),%eax 3c063: 66 8b 70 04 movw 4(%eax),%si ; yMin 3c067: 0f bf c6 movswl %si,%eax 3c06a: c1 f8 08 sarl $0x8,%eax 3c06d: 0f b6 d0 movzbl %al,%edx 3c070: 8b c6 movl %esi,%eax 3c072: 0f b6 c0 movzbl %al,%eax 3c075: c1 e0 08 shll $0x8,%eax 3c078: 66 0b c2 orw %dx,%ax 3c07b: 66 89 45 ba movw %ax,-0x46(%ebp) 3c07f: 8b 45 f8 movl -8(%ebp),%eax 3c082: 66 8b 50 06 movw 6(%eax),%dx ; xMax 3c086: 0f bf c2 movswl %dx,%eax 3c089: c1 f8 08 sarl $0x8,%eax 3c08c: 0f b6 c0 movzbl %al,%eax 3c08f: 0f b6 d2 movzbl %dl,%edx 3c092: c1 e2 08 shll $0x8,%edx 3c095: 66 0b d0 orw %ax,%dx 3c098: 66 89 55 bc movw %dx,-0x44(%ebp) 3c09c: 8b 45 f8 movl -8(%ebp),%eax 3c09f: 66 8b 50 08 movw 8(%eax),%dx ; yMax 3c0a3: 0f bf c2 movswl %dx,%eax 3c0a6: c1 f8 08 sarl $0x8,%eax 3c0a9: 0f b6 c0 movzbl %al,%eax 3c0ac: 0f b6 d2 movzbl %dl,%edx 3c0af: c1 e2 08 shll $0x8,%edx 3c0b2: 66 0b d0 orw %ax,%dx 3c0b5: 66 89 55 be movw %dx,-0x42(%ebp) 3c0b9: 8b 75 f8 movl -8(%ebp),%esi 3c0bc: 83 c6 0a addl $0xa,%esi ; esi -> data for glyph 3c0bf: eb 0d jmp .+0xf [0x3c0ce] 3c0c1: 90 nop 3c0c2: 90 nop 3c0c3: 90 nop 3c0c4: 66 c7 45 a4 01 00 movw $0x1,-0x5c(%ebp) 3c0ca: 66 b9 01 00 movw $0x1,%cx 3c0ce: 66 23 c9 andw %cx,%cx ; число контуров? 3c0d1: 0f 8c a5 00 00 00 jl .+0xab [0x3c17c] ; jmp, если compound 3c0d7: 8b 45 c4 movl -0x3c(%ebp),%eax 3c0da: 89 45 f0 movl %eax,-0x10(%ebp) 3c0dd: 8b 45 08 movl 8(%ebp),%eax 3c0e0: 66 83 b8 e6 01 00 00 00 cmpw $0x0,0x1e6(%eax) 3c0e8: 74 0b je .+0xd [0x3c0f5] 3c0ea: 66 8b 80 e8 01 00 00 movw 0x1e8(%eax),%ax 3c0f1: a8 20 testb $0x20,%al 3c0f3: 75 07 jne .+9 [0x3c0fc] 3c0f5: ba 01 00 00 00 movl $0x1,%edx 3c0fa: eb 02 jmp .+4 [0x3c0fe] 3c0fc: 2b d2 subl %edx,%edx 3c0fe: 8b 45 08 movl 8(%ebp),%eax 3c101: 66 89 90 22 02 00 00 movw %dx,0x222(%eax) 3c108: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) 3c10c: 7e 2f jle .+0x31 [0x3c13d] 3c10e: 89 75 a8 movl %esi,-0x58(%ebp) 3c111: 0f bf d1 movswl %cx,%edx 3c114: 66 8b 0c 56 movw (%esi,%edx,2),%cx 3c118: 0f bf c1 movswl %cx,%eax 3c11b: c1 f8 08 sarl $0x8,%eax 3c11e: 0f b6 c0 movzbl %al,%eax 3c121: 0f b6 c9 movzbl %cl,%ecx 3c124: c1 e1 08 shll $0x8,%ecx 3c127: 66 0b c8 orw %ax,%cx 3c12a: 66 89 4d ac movw %cx,-0x54(%ebp) 3c12e: 8d 54 56 02 leal 2(%esi,%edx,2),%edx 3c132: 89 55 b0 movl %edx,-0x50(%ebp) 3c135: 0f bf c1 movswl %cx,%eax 3c138: 03 c2 addl %edx,%eax 3c13a: 89 45 b4 movl %eax,-0x4c(%ebp) 3c13d: ff 75 0c pushl 0xc(%ebp) 3c140: ff 75 f0 pushl -0x10(%ebp) 3c143: 8d 45 9c leal -0x64(%ebp),%eax 3c146: 50 pushl %eax 3c147: 8d 45 a0 leal -0x60(%ebp),%eax 3c14a: 50 pushl %eax 3c14b: 8d 45 a4 leal -0x5c(%ebp),%eax 3c14e: 50 pushl %eax 3c14f: ff 75 08 pushl 8(%ebp) 3c152: e8 41 f2 ff ff call sfnt_UnfoldCurve 3c157: 8b f0 movl %eax,%esi 3c159: 23 f6 andl %esi,%esi 3c15b: 0f 85 9c 03 00 00 jne .+0x3a2 [0x3c4fd] 3c161: 6a 00 pushl $0x0 3c163: ff 75 9c pushl -0x64(%ebp) 3c166: ff 75 a0 pushl -0x60(%ebp) 3c169: 8d 45 b8 leal -0x48(%ebp),%eax 3c16c: 50 pushl %eax 3c16d: ff 75 18 pushl 0x18(%ebp) 3c170: 8a 45 14 movb 0x14(%ebp),%al 3c173: 89 45 f4 movl %eax,-0xc(%ebp) 3c176: e9 67 03 00 00 jmp .+0x36c [0x3c4e2] 3c17b: 90 nop 3c17c: 66 83 f9 ff cmpw $-0x1,%cx 3c180: 66 b8 00 00 movw $0x0,%ax 3c184: 0f 94 c0 sete %eax 3c187: 8b 4d 08 movl 8(%ebp),%ecx 3c18a: 66 89 81 e6 01 00 00 movw %ax,0x1e6(%ecx) 3c191: 66 23 c0 andw %ax,%ax 3c194: 0f 84 5e 03 00 00 je .+0x364 [0x3c4f8] 3c19a: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) 3c1a1: 8b 45 0c movl 0xc(%ebp),%eax 3c1a4: 89 45 e8 movl %eax,-0x18(%ebp) 3c1a7: 8b 45 18 movl 0x18(%ebp),%eax 3c1aa: 89 45 e4 movl %eax,-0x1c(%ebp) 3c1ad: 8a 45 14 movb 0x14(%ebp),%al 3c1b0: 89 45 f4 movl %eax,-0xc(%ebp) ; -0x20(%ebp) ptr на component glyph part description 3c1b3: 89 75 e0 movl %esi,-0x20(%ebp) 3c1b6: 8b 4d e0 movl -0x20(%ebp),%ecx 3c1b9: 66 8b 09 movw (%ecx),%cx ; component flag 3c1bc: 0f bf c1 movswl %cx,%eax 3c1bf: c1 f8 08 sarl $0x8,%eax 3c1c2: 0f b6 f0 movzbl %al,%esi 3c1c5: 0f b6 f9 movzbl %cl,%edi 3c1c8: c1 e7 08 shll $0x8,%edi 3c1cb: 8b c6 movl %esi,%eax 3c1cd: 66 0b c7 orw %di,%ax 3c1d0: 89 45 dc movl %eax,-0x24(%ebp) ; 0x24(%ebp) component flag 3c1d3: 8b 45 e0 movl -0x20(%ebp),%eax 3c1d6: 66 8b 48 02 movw 2(%eax),%cx ; gliphIndex 3c1da: 0f bf c1 movswl %cx,%eax 3c1dd: c1 f8 08 sarl $0x8,%eax 3c1e0: 0f b6 c0 movzbl %al,%eax 3c1e3: 0f b6 c9 movzbl %cl,%ecx 3c1e6: c1 e1 08 shll $0x8,%ecx 3c1e9: 0b c8 orl %eax,%ecx 3c1eb: 89 4d d8 movl %ecx,-0x28(%ebp) ; gliphIndex 3c1ee: 8b 45 e0 movl -0x20(%ebp),%eax 3c1f1: 05 04 00 00 00 addl $0x4,%eax ; X-offset 3c1f6: 8b d6 movl %esi,%edx 3c1f8: 80 e2 01 andb $0x1,%dl 3c1fb: 8b cf movl %edi,%ecx 3c1fd: 80 e1 01 andb $0x1,%cl 3c200: 0a d1 orb %cl,%dl 3c202: 74 38 je .+0x3a [0x3c23c] 3c204: 8b 4d e0 movl -0x20(%ebp),%ecx 3c207: 66 8b 51 04 movw 4(%ecx),%dx 3c20b: 0f bf ca movswl %dx,%ecx 3c20e: c1 f9 08 sarl $0x8,%ecx 3c211: 0f b6 c9 movzbl %cl,%ecx 3c214: 0f b6 d2 movzbl %dl,%edx 3c217: c1 e2 08 shll $0x8,%edx 3c21a: 66 0b d1 orw %cx,%dx 3c21d: 89 55 d4 movl %edx,-0x2c(%ebp) 3c220: 05 02 00 00 00 addl $0x2,%eax 3c225: 66 8b 10 movw (%eax),%dx 3c228: 0f bf ca movswl %dx,%ecx 3c22b: c1 f9 08 sarl $0x8,%ecx 3c22e: 0f b6 c9 movzbl %cl,%ecx 3c231: 0f b6 d2 movzbl %dl,%edx 3c234: c1 e2 08 shll $0x8,%edx 3c237: 66 0b d1 orw %cx,%dx 3c23a: eb 2f jmp .+0x31 [0x3c26b] 3c23c: 8b d6 movl %esi,%edx 3c23e: 80 e2 02 andb $0x2,%dl 3c241: 8b cf movl %edi,%ecx 3c243: 80 e1 02 andb $0x2,%cl 3c246: 0a d1 orb %cl,%dl 3c248: 8b 4d e0 movl -0x20(%ebp),%ecx 3c24b: 74 13 je .+0x15 [0x3c260] 3c24d: 0f be 49 04 movsbl 4(%ecx),%ecx 3c251: 89 4d d4 movl %ecx,-0x2c(%ebp) 3c254: 8b 4d e0 movl -0x20(%ebp),%ecx 3c257: 0f be 49 05 movsbl 5(%ecx),%ecx 3c25b: 89 4d d0 movl %ecx,-0x30(%ebp) 3c25e: eb 0e jmp .+0x10 [0x3c26e] 3c260: 0f b6 51 04 movzbl 4(%ecx),%edx 3c264: 89 55 d4 movl %edx,-0x2c(%ebp) 3c267: 0f b6 51 05 movzbl 5(%ecx),%edx 3c26b: 89 55 d0 movl %edx,-0x30(%ebp) 3c26e: 8d 48 02 leal 2(%eax),%ecx ; -0x20(%ebp) ptr на transformation option 3c271: 89 4d e0 movl %ecx,-0x20(%ebp) 3c274: f6 45 dc c8 testb $0xc8,-0x24(%ebp) 3c278: 0f 84 7b 01 00 00 je .+0x181 [0x3c3f9] ; jmp, если нет флагов масштабирования 3c27e: 8b 4d 08 movl 8(%ebp),%ecx 3c281: 81 c1 0c 01 00 00 addl $0x10c,%ecx 3c287: 89 4d cc movl %ecx,-0x34(%ebp) 3c28a: 8b 4d 08 movl 8(%ebp),%ecx 3c28d: 81 c1 30 01 00 00 addl $0x130,%ecx 3c293: 89 4d c8 movl %ecx,-0x38(%ebp) 3c296: 8b 55 08 movl 8(%ebp),%edx 3c299: 8d bd 78 ff ff ff leal -0x88(%ebp),%edi 3c29f: 8d b2 0c 01 00 00 leal 0x10c(%edx),%esi 3c2a5: fc cld 3c2a6: b9 09 00 00 00 movl $0x9,%ecx 3c2ab: f3 a5 repz movsl (%esi),(%edi) 3c2ad: 8d bd 54 ff ff ff leal -0xac(%ebp),%edi 3c2b3: 8d b2 30 01 00 00 leal 0x130(%edx),%esi 3c2b9: fc cld 3c2ba: b9 09 00 00 00 movl $0x9,%ecx 3c2bf: f3 a5 repz movsl (%esi),(%edi) 3c2c1: c7 45 ec 01 00 00 00 movl $0x1,-0x14(%ebp) 3c2c8: f6 45 dc 80 testb $0x80,-0x24(%ebp) ; WE HAVE_A_TWO_BY_TWO 3c2cc: 0f 84 9e 00 00 00 je .+0xa4 [0x3c370] 3c2d2: 66 8b 50 02 movw 2(%eax),%dx ; xscale 3c2d6: 0f bf ca movswl %dx,%ecx 3c2d9: c1 f9 08 sarl $0x8,%ecx 3c2dc: 0f b6 c9 movzbl %cl,%ecx -->3c2df: 0f b6 d2 movzbl %dl,%edx 3c2e2: c1 e2 08 shll $0x8,%edx 3c2e5: 0b ca orl %edx,%ecx 3c2e7: c1 e1 02 shll $0x2,%ecx 3c2ea: 89 8d 30 ff ff ff movl %ecx,-0xd0(%ebp) 3c2f0: 66 8b 50 04 movw 4(%eax),%dx ; scale01 3c2f4: 0f bf ca movswl %dx,%ecx 3c2f7: c1 f9 08 sarl $0x8,%ecx 3c2fa: 0f b6 c9 movzbl %cl,%ecx -->3c2fd: 0f b6 d2 movzbl %dl,%edx 3c300: c1 e2 08 shll $0x8,%edx 3c303: 0b ca orl %edx,%ecx 3c305: c1 e1 02 shll $0x2,%ecx 3c308: 89 8d 34 ff ff ff movl %ecx,-0xcc(%ebp) 3c30e: 66 8b 50 06 movw 6(%eax),%dx ; scale10 3c312: 0f bf ca movswl %dx,%ecx 3c315: c1 f9 08 sarl $0x8,%ecx 3c318: 0f b6 c9 movzbl %cl,%ecx -->3c31b: 0f b6 d2 movzbl %dl,%edx 3c31e: c1 e2 08 shll $0x8,%edx 3c321: 0b ca orl %edx,%ecx 3c323: c1 e1 02 shll $0x2,%ecx 3c326: 89 8d 3c ff ff ff movl %ecx,-0xc4(%ebp) 3c32c: 66 8b 50 08 movw 8(%eax),%dx ; yscale 3c330: 0f bf c2 movswl %dx,%eax 3c333: c1 f8 08 sarl $0x8,%eax 3c336: 0f b6 c8 movzbl %al,%ecx -->3c339: 0f b6 c2 movzbl %dl,%eax 3c33c: c1 e0 08 shll $0x8,%eax 3c33f: 0b c1 orl %ecx,%eax 3c341: 83 45 e0 08 addl $0x8,-0x20(%ebp) ; продвижение указателя по файлу 3c345: c1 e0 02 shll $0x2,%eax 3c348: 89 85 40 ff ff ff movl %eax,-0xc0(%ebp) 3c34e: ff 75 cc pushl -0x34(%ebp) 3c351: 8d b5 30 ff ff ff leal -0xd0(%ebp),%esi 3c357: 56 pushl %esi 3c358: e8 6f e0 fc ff call fsg_MxConcat2x2 3c35d: 83 c4 08 addl $0x8,%esp 3c360: ff 75 c8 pushl -0x38(%ebp) 3c363: 56 pushl %esi 3c364: e8 63 e0 fc ff call fsg_MxConcat2x2 3c369: 83 c4 08 addl $0x8,%esp 3c36c: eb 76 jmp .+0x78 [0x3c3e4] 3c36e: 90 nop 3c36f: 90 nop 3c370: f6 45 dc 40 testb $0x40,-0x24(%ebp) ; WE_HAVE_AN_X_AND_Y_SCALE 3c374: 74 36 je .+0x38 [0x3c3ac] 3c376: 66 8b 50 02 movw 2(%eax),%dx ; xscale 3c37a: 0f bf ca movswl %dx,%ecx 3c37d: c1 f9 08 sarl $0x8,%ecx 3c380: 0f b6 f1 movzbl %cl,%esi -->3c383: 0f b6 ca movzbl %dl,%ecx 3c386: c1 e1 08 shll $0x8,%ecx 3c389: 0b f1 orl %ecx,%esi 3c38b: c1 e6 02 shll $0x2,%esi 3c38e: 66 8b 48 04 movw 4(%eax),%cx ; yscale 3c392: 0f bf c1 movswl %cx,%eax 3c395: c1 f8 08 sarl $0x8,%eax 3c398: 0f b6 c0 movzbl %al,%eax -->3c39b: 0f b6 f9 movzbl %cl,%edi 3c39e: c1 e7 08 shll $0x8,%edi 3c3a1: 0b f8 orl %eax,%edi 3c3a3: 83 45 e0 04 addl $0x4,-0x20(%ebp) ; продвижение указателя по файлу 3c3a7: c1 e7 02 shll $0x2,%edi 3c3aa: eb 1e jmp .+0x20 [0x3c3ca] 3c3ac: 66 8b 48 02 movw 2(%eax),%cx 3c3b0: 0f bf c1 movswl %cx,%eax 3c3b3: c1 f8 08 sarl $0x8,%eax 3c3b6: 0f b6 c0 movzbl %al,%eax -->3c3b9: 0f b6 f9 movzbl %cl,%edi 3c3bc: c1 e7 08 shll $0x8,%edi 3c3bf: 0b f8 orl %eax,%edi 3c3c1: 83 45 e0 02 addl $0x2,-0x20(%ebp) ; продвижение указателя по файлу 3c3c5: c1 e7 02 shll $0x2,%edi 3c3c8: 8b f7 movl %edi,%esi 3c3ca: ff 75 cc pushl -0x34(%ebp) 3c3cd: 57 pushl %edi 3c3ce: 56 pushl %esi 3c3cf: e8 08 e0 fc ff call fsg_MxScaleAB 3c3d4: 83 c4 0c addl $0xc,%esp 3c3d7: ff 75 c8 pushl -0x38(%ebp) 3c3da: 57 pushl %edi 3c3db: 56 pushl %esi 3c3dc: e8 fb df fc ff call fsg_MxScaleAB 3c3e1: 83 c4 0c addl $0xc,%esp 3c3e4: ff 75 08 pushl 8(%ebp) 3c3e7: e8 e0 de fc ff call fsg_InitInterpreterTrans 3c3ec: 83 c4 04 addl $0x4,%esp 3c3ef: 8b 45 08 movl 8(%ebp),%eax 3c3f2: c6 80 54 01 00 00 00 movb $0x0,0x154(%eax) 3c3f9: 8b 4d dc movl -0x24(%ebp),%ecx 3c3fc: 8b 45 08 movl 8(%ebp),%eax 3c3ff: 66 89 88 e8 01 00 00 movw %cx,0x1e8(%eax) 3c406: 8b 4d d4 movl -0x2c(%ebp),%ecx 3c409: 66 89 88 ea 01 00 00 movw %cx,0x1ea(%eax) 3c410: 8b 4d d0 movl -0x30(%ebp),%ecx 3c413: 66 89 88 ec 01 00 00 movw %cx,0x1ec(%eax) 3c41a: ff 75 e4 pushl -0x1c(%ebp) 3c41d: 8b 45 f4 movl -0xc(%ebp),%eax 3c420: 50 pushl %eax 3c421: ff 75 d8 pushl -0x28(%ebp) 3c424: ff 75 e8 pushl -0x18(%ebp) 3c427: ff 75 08 pushl 8(%ebp) 3c42a: e8 4d df fc ff call sfnt_ReadSFNT 3c42f: 83 c4 14 addl $0x14,%esp 3c432: 8b f0 movl %eax,%esi 3c434: 80 7d ec 00 cmpb $0x0,-0x14(%ebp) 3c438: 74 42 je .+0x44 [0x3c47c] 3c43a: 8b 45 08 movl 8(%ebp),%eax 3c43d: 56 pushl %esi 3c43e: 8d b8 0c 01 00 00 leal 0x10c(%eax),%edi 3c444: 8d b5 78 ff ff ff leal -0x88(%ebp),%esi 3c44a: fc cld 3c44b: b9 09 00 00 00 movl $0x9,%ecx 3c450: f3 a5 repz movsl (%esi),(%edi) 3c452: 5e popl %esi 3c453: 50 pushl %eax 3c454: e8 73 de fc ff call fsg_InitInterpreterTrans 3c459: 83 c4 04 addl $0x4,%esp 3c45c: 8b 45 08 movl 8(%ebp),%eax 3c45f: 56 pushl %esi 3c460: 8d b8 30 01 00 00 leal 0x130(%eax),%edi 3c466: 8d b5 54 ff ff ff leal -0xac(%ebp),%esi 3c46c: fc cld 3c46d: b9 09 00 00 00 movl $0x9,%ecx 3c472: f3 a5 repz movsl (%esi),(%edi) 3c474: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) 3c47b: 5e popl %esi 3c47c: f6 45 dc 20 testb $0x20,-0x24(%ebp) ; jmp, если есть ещё компоненты 3c480: 74 08 je .+0xa [0x3c48a] 3c482: 23 f6 andl %esi,%esi 3c484: 0f 84 2c fd ff ff je .-0x2ce [0x3c1b6] 3c48a: 8b 7d dc movl -0x24(%ebp),%edi 3c48d: 8b 75 e0 movl -0x20(%ebp),%esi 3c490: 66 8b 45 10 movw 0x10(%ebp),%ax 3c494: 50 pushl %eax 3c495: ff 75 08 pushl 8(%ebp) 3c498: e8 6f de fc ff call sfnt_ReadSFNTMetrics 3c49d: 83 c4 08 addl $0x8,%esp 3c4a0: 66 f7 c7 00 01 testw $0x100,%di 3c4a5: 74 25 je .+0x27 [0x3c4cc] 3c4a7: 66 8b 0e movw (%esi),%cx 3c4aa: 0f bf c1 movswl %cx,%eax 3c4ad: c1 f8 08 sarl $0x8,%eax 3c4b0: 0f b6 c0 movzbl %al,%eax 3c4b3: 0f b6 c9 movzbl %cl,%ecx 3c4b6: c1 e1 08 shll $0x8,%ecx 3c4b9: 66 0b c8 orw %ax,%cx 3c4bc: 0f b7 c1 movzwl %cx,%eax 3c4bf: 89 45 fc movl %eax,-4(%ebp) 3c4c2: 89 45 a0 movl %eax,-0x60(%ebp) 3c4c5: 8d 46 02 leal 2(%esi),%eax 3c4c8: eb 08 jmp .+0xa [0x3c4d2] 3c4ca: 90 nop 3c4cb: 90 nop 3c4cc: 8b 45 fc movl -4(%ebp),%eax 3c4cf: 89 45 a0 movl %eax,-0x60(%ebp) 3c4d2: 89 45 9c movl %eax,-0x64(%ebp) 3c4d5: 6a 01 pushl $0x1 3c4d7: 50 pushl %eax 3c4d8: ff 75 fc pushl -4(%ebp) 3c4db: 8d 45 b8 leal -0x48(%ebp),%eax 3c4de: 50 pushl %eax 3c4df: ff 75 e4 pushl -0x1c(%ebp) 3c4e2: 0f b6 45 f4 movzbl -0xc(%ebp),%eax 3c4e6: 50 pushl %eax 3c4e7: ff 75 08 pushl 8(%ebp) 3c4ea: e8 fd de fc ff call fsg_InnerGridFit 3c4ef: 83 c4 1c addl $0x1c,%esp 3c4f2: 8b f0 movl %eax,%esi 3c4f4: eb 07 jmp .+9 [0x3c4fd] 3c4f6: 90 nop 3c4f7: 90 nop 3c4f8: be 07 14 00 00 movl $0x1407,%esi 3c4fd: 83 7d f8 00 cmpl $0x0,-8(%ebp) 3c501: 74 0c je .+0xe [0x3c50f] 3c503: ff 75 f8 pushl -8(%ebp) 3c506: 8b 45 08 movl 8(%ebp),%eax 3c509: ff 50 08 call *8(%eax) 3c50c: 83 c4 04 addl $0x4,%esp 3c50f: 8b c6 movl %esi,%eax 3c511: 5f popl %edi 3c512: 5e popl %esi 3c513: 5b popl %ebx 3c514: c9 leave 3c515: c3 ret 3c516: 00 .byte 0 3c517: 00 .byte 0 |
Т.е. для данного экземпляра libfont.so.1 необходимо заменить команды movzbl на movsbl по адресам: |
|
0x3c2df 0x3c2fd 0x3c31b 0x3c339 0x3c383 0x3c39b 0x3c3b9 |
Для этого используйте программу: |
|
/* * patch.c * * (C) Vitaly Filatov, https://members.tripod.com/Vitaly_Filatov Mar 2002 * */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #define SOURCE_FILE "/usr/openwin/lib/libfont.so.1.orig" #define DEST_FILE "/tmp/libfont.so.1" int main() { int in, out, ret, k; long length; char *buf; in = open(SOURCE_FILE, O_RDONLY); if (in == -1) { printf("Can't open source file\n"); exit(1); } out = open(DEST_FILE, O_CREAT | O_RDWR, 0775); if (out == -1) { printf("Can't open dest file\n"); exit(1); } length = lseek(in, 0L, SEEK_END); lseek(in, 0L, SEEK_SET); buf = (char *) malloc(length); if (buf == NULL) { printf("Can't malloc\n"); exit(1); } ret = read(in, buf, length); if (ret != length) { printf("ret = %d : Can't read source file\n", ret); exit(1); } /* Заменяйте адреса здесь: */ k = 0x3c2df; /* xscale */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c2fd; /* scale01 */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c31b; /* scale10 */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c339; /* yscale */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c383; /* xscale */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c39b; /* yscale */ buf[k++] = 0x0f; buf[k++] = 0xbe; k = 0x3c3b9; /* xscale = yscale */ buf[k++] = 0x0f; buf[k++] = 0xbe; write(out, buf, length); close(in); close(out); return 0; } |
Сохраните эту программу под именем patch.c и выполните команды: |
|
$ gcc -o patch patch.c $ ./patch |
Программа создаст новую версию библиотеки libfont.so.1 в каталоге /tmp. Для проверки правильности изменения команд, Вы можете дизассемблировать модифицированную программу /tmp/libfont.so.1. Затем, выйдите из графической оболочки (CDE, OpenWindows, и т.д.) и войдите в систему как пользователь root в режиме командной строки. Выполните команды: |
|
# cd /tmp # chown root:bin libfont.so.1 # cp -p libfont.so.1 /usr/openwin/server/lib |
Всё готово. Загрузите графическую оболочку и проверьте правильность растризации шрифтов (звёздочками отмечены те шрифты, которые ранее растризовались неправильно): |
|
$ xset +fp /usr/openwin/lib/locale/iso_8859_5/X11/fonts/TrueType $ xfd -fn "-monotype-arial-bold-r-normal--30-300-0-0-p-0-iso8859-5" $ xfd -fn "-monotype-arial-bold-i-normal--30-300-0-0-p-0-iso8859-5" $ xfd -fn "-monotype-arial-regular-i-normal--30-300-0-0-p-0-iso8859-5" *$ xfd -fn "-monotype-arial-regular-r-normal--30-300-0-0-p-0-iso8859-5" *$ xfd -fn "-monotype-courier-bold-r-normal--30-300-0-0-m-0-iso8859-5" $ xfd -fn "-monotype-courier-bold-i-normal--30-300-0-0-m-0-iso8859-5" $ xfd -fn "-monotype-courier-regular-i-normal--30-300-0-0-m-0-iso8859-5" *$ xfd -fn "-monotype-courier-regular-r-normal--30-300-0-0-m-0-iso8859-5" *$ xfd -fn "-monotype-times-bold-r-normal--30-300-0-0-p-0-iso8859-5" $ xfd -fn "-monotype-times-bold-i-normal--30-300-0-0-p-0-iso8859-5" $ xfd -fn "-monotype-times-regular-i-normal--30-300-0-0-p-0-iso8859-5" *$ xfd -fn "-monotype-times-regular-r-normal--30-300-0-0-p-0-iso8859-5" $ xset -fp /usr/openwin/lib/locale/iso_8859_5/X11/fonts/TrueType |
Имеется ещё одна ошибка (очевидно не последняя), которую пока исправить не удалось. Шрифт garait.ttf -monotype-Garamond-medium-i-normal--0-0-0-0-p-0-iso8859-15 взят из набора шрифтов MS Windows 98: |
|
Глиф неверно воспроизводимой буквы 'CE' является простым. Остальные шрифты из Win31, Win98 растризуются правильно. Все TrueType шрифты штатно включённые в Солярис растризуются правильно. При загрузке StarOffice Вы можете поставить пути к TrueType шрифтам первыми. Я попробовал также многие TrueType шрифты с компакт-диска |
|
"Виртуальная библиотека компьютерных шрифтов 2001" (C) 2001 DELTA.MM Corp. (C) 2001 "Навигатор" (ООО "Программа 2000") www.cdboom.com |
На диске можно найти более-менее правильно сформированные TrueType шрифты. Однако неправильно "encoded" шрифтов довольно много. Также, довольно редко, видны некоторые погрешности растризации, однако трудно понять вызваны ли они ошибками libfont.so.1 или это ошибки кодирования самих шрифтов. Требуется дополнительное разбирательство. Файл fonts.scale создавался программой ttmkfdir из XFree86, скомпилированной в Солярисе. Программа ttmkfdir для Солярис 8 x86 находится здесь. Чтобы подключить шрифты к X11 выполните команды:
|
|
$ cd в каталог со шрифтами $ ttmkfdir > fonts.scale $ mkfontdir $ xset +fp `pwd` |