Суть даже не в крестике, а как рисовать в нужном месте. Координаты? Да, слыхал. И рисовал как бы даже... Но стоило с MSWindows перейти на Android - и "Шеф, всё пропало, все пропало!"(© Козодоев Г.П.)
Вот пример, замечательно работающий в Винде, но не работающий на моём Nexus 4:
const Ident = 10; ... DrawLine( //Horizontal TPointF.Create( Ident, ( FRawBitmap.Height / 2 ) ), TPointF.Create( FRawBitmap.Width - Ident, FRawBitmap.Height / 2 ), 0.5 ); DrawLine( //Vertical TPointF.Create( FRawBitmap.Width / 2, Ident ), TPointF.Create( FRawBitmap.Width / 2, FRawBitmap.Height - Ident ), 0.5 );
Вот на компе рисует, а в телефоне - нет!
Отладчик говорит, что всё нормально - методы проходят. А сдвиг координат подсказал, что действительно - всё рисуется, но где-то за пределами картинки. Гром и молния! Как может что-то рисоваться за пределами, если мы рисуем в точке с координатами меньше пределов?!
Посмотрев в FMX.Objects как рисует TImage, я среди прочего заметил странную такую штуку - FScreenScale. Не "паблик", не свойство, а чисто "для себя". И берётся оно из свойства TControl.Scene:IScene. А Scene - это, как можно легко заметить, интерфейс, у которого есть даже не свойство SceneScale, а именно метод GetSceneScale. Мало того, интерфейс этот ещё может и отсутствовать, и тогда FScreenScale = 1.
Ещё есть у IScene функции расчёта координат экран-локаль, но они тут не работают, нужен именно "Scale". Этот Скэйл у меня на ПК - 1, а на Нексусе - 2. Сама же Сцена есть и там, и там. Т.е. вроде бы получается, что проверять её наличие не обязательно (но я себе проверку всё же скопипастил), а нужно взять коэффициент и разделить координаты на него.
Поскольку я много делить не люблю, я разделил один раз, а потом умножаю:
var FScreenScale : Single; ... if Assigned(Scene) then FScreenScale := 1 / Scene.GetSceneScale else FScreenScale := 1.0;...
DrawLine( //Horizontal TPointF.Create( FScreenScale * Ident, FScreenScale * ( FRawBitmap.Height / 2 ) ), TPointF.Create( FScreenScale * ( FRawBitmap.Width - Ident ), FScreenScale * FRawBitmap.Height / 2 ), 0.5 ); DrawLine( //Vertical TPointF.Create( FScreenScale * FRawBitmap.Width / 2, FScreenScale * Ident ), TPointF.Create( FScreenScale * FRawBitmap.Width / 2, FScreenScale * ( FRawBitmap.Height - Ident ) ), 0.5 );
Ну вот, теперь мой крестик ровно в середине рисунка.
- Погоди-ка, а если там всё в два раза больше, то попиксельно ничего не нарисуешь????
- Да нарисуешь, координаты-то не целые!
Только зачем такие странности? Чтобы понять это, как сказал Ярослав Бровин "В общем ничего кроме стандартных знаний линейной алгебры здесь не требуется". И мне остаётся стыдливо воспринимать эти обстоятельства как данность, данную нам свыше.
Комментариев нет:
Отправить комментарий