OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 21 Сентябрь, 2023 22:48

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
СообщениеДобавлено: Среда, 10 Май, 2023 11:28 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1098
нашёл некоторый… скажем так, недочёт в TextViews. как мы знаем, оригинальный виндовый BBCB в принципе забивает большой и толстый на кернинг. лин-версия использует панго (или, в случае LC, свою рисовалку на основе FreeType), и кернинг уважает. это почти работает, за одним интересным исключением.

штука такая, что TextSetters.Reader разбивает текст не только по кусочкам с разными атрибутами, но и на некоторых специальных символах типа переноса и минуса. он это делает для реализации wrapping. также максимальный размер возвращаемого кусочка — 64. и вот тут возникает противоречие между `TextViews.DrawLine()` и `TextViews.GetThisLocation()`. `DrawLine()` кэширует строки кусками по 128, и вдобавок не разбивает их по границам спецсимволов. а `GetThisLocation()` такого не делает. из-за этого в некоторых случаях вычисленая позиция каретки может не соответствовать реальной позиции глифа на экране.

то есть: `GetThisLocation()` двигается ровно по кусочкам, возвращённым Reader, через `StringWidth()`. а теперь представим такой случай: знак минуса имеет ненулевой кернинг с некоторыми буквами (так, например, в вердане: "A-" — тут минус смещают немного влево. `DrawLine()` накопит строку "A-" и нарисует минус с правильным кернингом. а `GetThisLocation()` вычислит сумму длин строк "A" и "-" отдельно, и каретка уедет немного дальше вправо, чем надо.

такая штука очень малозаметна, но тем не менее она существует. если в строке накопится много минусов с кернингом — каретка довольно заметно визуально сместится.

вариантов решения я тут вижу два: или учить `GetThisLocation()` кэшировать текст точно так же, как делает `DrawLine()`, или выкинуть из `DrawLine()` кэширование совсем. второй вариант мне кажется более правильным: просто отключить кэширование в `DrawLine()`. техника сейчас достаточно быстрая, чтобы не имело смысла собирать там кусочки (тем более что частично кусочки уже собирает Reader).

Код:
      PROCEDURE CacheString (x, y: INTEGER; c: INTEGER; IN s: ARRAY OF CHAR; f: Fonts.Font);
      VAR i, j, len: INTEGER;
      BEGIN
         len := LEN(s$);
         IF FALSE THEN (* old code, unused *)
            IF (cache.len + len >= cacheLen) OR (cache.y # y) OR
               (cache.color # c) OR (cache.font # f)
            THEN
               FlushCaches
            END;
            ASSERT(cache.len + len < cacheLen, 100);
            IF cache.len = 0 THEN
               cache.x := x; cache.y := y;
               cache.color := c; cache.font := f
            END;
            i := 0; j := cache.len;
            WHILE i < len DO cache.buf[j] := s[i]; INC(i); INC(j) END;
            cache.len := j
         ELSE
            FlushCaches;
            ASSERT(cache.len = 0);
            cache.x := x; cache.y := y;
            cache.color := c; cache.font := f;
            cache.buf := s$; cache.len := len
         END
      END CacheString;

старый код не удаляем — пусть будет, мало ли. просто вместо этого не склеиваем строки, даже если возможно. это не ломает никакой логики, и решает все потенциальные проблемы с кернингом.

в LC я просто удалил всю логику кэширования из `DrawLine()`. реально она почти ничего не ускоряет, только зря усложняет код.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Среда, 10 Май, 2023 11:48 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3721
Что-то не получается пока воспроизвести проблему с А-


Вложения:
Aaaa.png
Aaaa.png [ 7.69 КБ | Просмотров: 1122 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Среда, 10 Май, 2023 13:00 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1098
это сильно зависит от конкретных шрифтов и шрифтового движка. pango, например, делает кернинг несколько не так, как FreeType (там реально для одного и того же шрифта по какой-то причине отличаются то ли значения кернинга, то ли кернинговые пары). я и налетел на это, когда перешёл с панги на фритайп, и долго искал ошибку в своей реализации HostFonts, хех.

тут сложно конкретно показать воспроизводимость бага, но он есть. я потому и привёл такое длинное описание, чтобы можно было вывести существование бага чисто логическим путём.

в большинстве случаев бага не будет, я тоже его замечал только на конкретных кернинговых парах же. а вот когда я стал писать регулярки типа `[A-F]` — оно полезло.

p.s.: панго, кстати, похоже, не делает кернинг минуса с 'A'. там вообще внизу harfbuzz, а он почти все метрики шрифта обрабатывает сам, минуя фритайп. но где-то кернинг будет — и ой.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2023, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB