Стряхну пыль с темы. ))
Заменял этой процедурой процедуру заливки в BGE 3.12 Demo, поскольку эта меньше по размеру а места катострофически не хватало. И соответственно она перешла по наследству в BGE 4.0 demo где места ещё меньше осталось )) , и вот внезапно спустя 4 года обнаружил что процедура имеет баг.
Судя по тому что о нём никто не упоминал - это показатель использования. )) Глюк наиболее вероятно можно словить при заливке малых областей, а так как заливают чаще крупные, то ,,,
Смысл бага в том, что при некоторых выборах точки заливки, заливалась область снаружи выделения.
По факту я даже не сразу заподозрил процедуру заливки, думал в коде выбора точки ошибка. Но в конце концов условия срабатывания бага удалось выявить.
Итак условия проявления бага (должены быть соблюдены все):
1) Позиция выбора начала заливки (в дальнейшем курсор ) не должна попадать на установленный пиксель. (Собственно это условие проверяется самой процедурой, я записал его лишь потому что при моём фиксе обвесами приходится проверять его дополнительно.)
2)Байт на который попадает курсор не должен быть нулевым, т.е. хотя бы один пиксель должен быть.
3) В байте слева до курсора не должно быть пикселей, т.е. все пиксели в байте должны быть справа за курсором.
4) Либо байт на который попадает курсор должен быть в крайнем слева знакоместе экрана, либо же в байте предыдущего знакоместа должен быть выставлен в 1 - bit0 (т.е. крайняя правая точка в той же линии предыдущего знакоместа)
При соблюдении этих условий, вместо положенного действия процедура заливает совсем другую область.
Моя попытка вникнуть в суть данной проги успехом не увенчалась.
Абы какое решение я нашёл, это обвес проги дополнением проверяющим попадание в условия бага и соответственно изменяющим эти условия (тупо точку в крайней левой позиции в байте устанавливает), но размер проги соответственно тоже значителино увеличился (хотя всё ещё меньше чем был в изначальной процедуре BGE)
Вопрос: может ли автор или кто-либо разобраться и как-то исправить баг в самой процедуре ?
А мой обвес работает примерно так :
Проверяем попадание на установленную точку, если да, то выход.
Иначе создаётся заготовка для двойного циклического вызова расширенной процедуры, т.е. процедура будет вызвана 2 или более раза (исключая случай крайней нижней позиции), в стандартном случае один раз по позиции, а другой на один пиксель ниже. Поскольку в нормальном варианте там будет уже заполненный или граничный пиксель, то ничего лишнего не нарисуется ))
А затем расширенная процедура:
1. Проверяет попадание на установленную точку, если да, то выход.
2. Прверяет на условия возникновения глюка, если нет то переход к основной процедуре
3. Ну а если всё сбылось для появления глюка, то X позиции выбора для циклических вызовов устанавливается в крайнюю левую позицию знакоместа, а для вызова основной процедуры устанавливается крайняя левая точка байта, а позиция курсора смещается за неё.
После, если снова попадаем на условия глюка, расширенная процедура вызывается снова, вначале движемся по ветке вверх, потом вниз.
- - - Добавлено - - -
Упс. ошибочка, при нулевом байте тоже срабатывает глюк, если в следующем байте установлен крайний левый пиксель или знакоместо курсора крайнее правое.





Ответить с цитированием