Допустим, требуется отрисовка некоего сложного векторного рисунка, или раскраска диалогового окна. Как грамотнее: создать заранее некий пул всех перьев и кистей и только выбирать их оттуда, или каждый раз при отрисовке создавать перо (кисть), рисовать им и затем уничтожать?
Для меня второй способ проще, т.к. не нужно порождать дополнительные сущности и количество возможных цветов/стилей в принципе ничем не ограничено.
Т.е. что вообще в Windows представляет собой операция создания пера или кисти — просто занесение данных в какую-то структуру (свободную ячейку в некой таблице GDI объектов) или что-то большее? И как обычно поступают в таких случаях?
Re: перья и кисти
От:
Аноним
Дата:
26.05.08 09:52
Оценка:
А>Т.е. что вообще в Windows представляет собой операция создания пера или кисти — просто занесение данных в какую-то структуру (свободную ячейку в некой таблице GDI объектов) или что-то большее? И как обычно поступают в таких случаях?
Сделайте себе объекты-обертки вокруг GDIшных объектов, без лишний наворотов поначалу. Если потом юзера пожалуются на низкую скорость, а профайлер покажет что тормоза в создании пера/кисти — сделаете кэш.
Здравствуйте, Аноним, Вы писали:
А>Т.е. что вообще в Windows представляет собой операция создания пера или кисти — просто занесение данных в какую-то структуру (свободную ячейку в некой таблице GDI объектов) или что-то большее?
Намного большее. Создаются стуктуры ядра, происходит при этом переключение в нулевое кольцо. Подробности — см. книгу Фень Юаня, она тут много раз обсуждалась.
>И как обычно поступают в таких случаях?
По-разному. Зависит от того, сколько этих перьев/кистей, есть ли среди них часто используемые и более редко, какая эффективность требуется и т.д. Лучше, действительно, для начала идти по пути 2, может, ничего и не надо. Имей в виду, что кроме создания объектов, там еще много тяжелого кода, так что мб, создание будет лишь 1% времени отнимать. Не устроит — изменишь.
Здравствуйте, Аноним, Вы писали:
А>Допустим, требуется отрисовка некоего сложного векторного рисунка, или раскраска диалогового окна. Как грамотнее: создать заранее некий пул всех перьев и кистей и только выбирать их оттуда, или каждый раз при отрисовке создавать перо (кисть), рисовать им и затем уничтожать?
Лично я использую первый способ (создаю пул). Делаю это для того, чтобы мое приложение было одного стиля — контролы выглядят одинаково (есть перо для границы выделенной, невыделенной, есть перо для цвета линий сетки и т.д.).
А>Допустим, требуется отрисовка некоего сложного векторного рисунка, или раскраска диалогового окна. Как грамотнее: создать заранее некий пул всех перьев и кистей и только выбирать их оттуда, или каждый раз при отрисовке создавать перо (кисть), рисовать им и затем уничтожать?
Похрен. С bitmapами вот не похрен.
А>Т.е. что вообще в Windows представляет собой операция создания пера или кисти — просто занесение данных в какую-то структуру (свободную ячейку в некой таблице GDI объектов)
Понятие "свободная ячейка в таблице" умерло вместе с Win16. Естественно, все структуры GDI в наше время аллоцируются.
CreatePen(Indirect) создает внутри GDI структурку и тупо копирует туда параметры. То же и с brushем.
SelectObject для кисти может позвать DrvRealizeBrush в графическом драйвере, где драйверу предлагается построить свое представление кисти и сассоциировать его с объектом.
Потом зовется DrvStroke/FillPath, по умолчанию оно замкнуто на EngStroke/FillPath, но, если драйвер умеет рисовать и заливать сам без применения GRE, то он может иметь свою имплементацию этих функций и рисовать, как он считает нужным (программируя железо, например), при этом он имеет право пользоваться тем своим внутренним представлением, что создано в DrvRealizeBrush.
EngStrokePath делает сначала FlattenPath (из кривой прямолинейные хорды), потом WidenPath (из хорд многоугольник с толстыми линиями), потом PathToRegion, потом FillRegion. Последнее может обращаться к драйверу в одну из DrvXxx функций заливки (забыл, какую), если ее нет — то зовется соответствующая функция EngXxx, которая просто упрощенный BitBlt.
Если же линия не толстая, то вместо WidenPath зовется StrokeCosmetic, которая рисует линию Брезенхэмом с субпиксельной точностью.
EngFillPath делает то же самое, но без шага WidenPath.