Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

12 void readHeaderIfNecessary const;

13 QBitArray readBitmap(int width, int height, QDataStream &in) const;

14 void enterErrorState const;

15 mutable State state;

16 mutable int currentImageNo;

17 mutable int numImages;

18 };

Открытые функции имеют фиксированную сигнатуру. Здесь нет некоторых функций, которые не надо переопределять в обработчике, обеспечивающем только чтение, в частности отсутствует функция write. Переменные—члены объявляются

с ключевым словом mutable, потому что они изменяются внутри константных функций.

01 CursorHandler::CursorHandler

02 {

03 state = BeforeHeader;

04 currentImageNo = 0;

05 numImages = 0;

06 }

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

01 bool CursorHandler::canRead const

02 {

03 if (state == BeforeHeader) {

04 return device->peek(4) == QByteArray("\0\0\2\0", 4);

05 } else {

06 return state != Error;

07 }

08 }

Функция canRead может вызываться в любой момент для определения возможности считывания обработчиком изображений дополнительных данных с устройства. Если функция вызывается до чтения данных в состоянии BeforeHeader, выполняется проверка конкретной метки, по которой опознаются файлы курсоров в Windows. Вызов QIODevice::peek считывает первые четыре байта без изменения указателя файла на данном устройстве. Если функция canRead вызывается позже, мы возвращаем true при отсутствии ошибки.

01 int CursorHandler::currentImageNumber const

02 {

03 return currentImageNo;

04 }

Эта простая функция возвращает номер курсора, на который позиционирован указатель файла устройства.

После создания обработчика пользователь может вызвать любую его открытую функцию, причем последовательность вызовов функций может быть произвольной. В этом кроется потенциальная проблема, поскольку необходимо исходить из того, что файл можно читать только последовательно, поэтому сначала надо один раз считать заголовок файла и затем выполнять какие-то другие действия. Эту проблему решаем путем вызова readHeaderIfNecessary в тех функциях, для которых требуется предварительное считывание заголовка файла.

01 int CursorHandler::imageCount const

02 {

03 readHeaderIfNecessary;

04 return numImages;

05 }

Эта функция возвращает количество изображений, содержащихся в файле. Для правильного файла, при чтении которого не возникает ошибок, она возвращает по крайней мере 1.

Рис. 19.2. Формат файла .cur.

Следующая функция довольно сложная, поэтому мы

рассмотрим ее по частям:

01 bool CursorHandler::read(QImage *image)

02 {

03 readHeaderIfNecessary;

04 if (state != BeforeImage)

05 return false;

Функция read считывает данные изображения, начинающегося в текущей позиции указателя устройства. Если успешно считан заголовок файла или указатель устройства после чтения изображения находится в начале другого изображения, можно считывать следующее изображение.

06 quint32 size;

07 quint32 width;

08 quint32 height;

09 quint16 numPlanes;

10 quint16 bitsPerPixel;

11 quint32 compression;

12 QDataStream in(device);

13 in.setByteOrder(QDataStream::LittleEndian);

14 in >> size;

15 if (size != 40) {

16 enterErrorState;

17 return false;

18 }

19 in >> width >> height >> numPlanes >> bitsPerPixel >> compression;

20 height /= 2;

21 if (numPlanes != 1 || bitsPerPixel != 1 || compression != 0) {

22 enterErrorState;

23 return false;

24 }

25 in.skipRawData((size - 20) + 8);

Мы создаем объект QDataStream для чтения устройства. Необходимо установить порядок байтов в соответствии с тем, который определен спецификацией формата файла .cur. Задавать версию потока QDataStream нет необходимости, поскольку форматы целых чисел и чисел с плавающей запятой не зависят от версии потока данных. Затем считываем элементы заголовка курсора и пропускаем неиспользуемые части заголовка и 8-байтовую таблицу цветов с помощью функции QDataStream::skipRawData.

Необходимо учитывать все характерные особенности формата, например, уменьшая вдвое высоту изображения, потому что она в формате .cur в два раза превышает высоту реального изображения. Переменные bitsPerPixel и compression всегда имеют значения 1 и 0 в монохромных файлах .cur. При возникновении каких-либо проблем вызываем функцию enterErrorState и возвращаем false.

26 QBitArray xorBitmap = readBitmap(width, height, in);

27 QBitArray andBitmap = readBitmap(width, height, in);

28 if (in.status != QDataStream::Ok) {

29 enterErrorState;

30 return false;

31 }

Следующими элементами файла являются две битовые маски: одна XOR—маска, а другая AND—маска. Мы их считываем в массивы QBitArray, а не в QBitmap. Класс QBitmap предназначен для выполнения с ним операций рисования и вывода рисунка на экран, а нам нужен простой массив битов.

Поделиться:
Популярные книги

Атаман царского Спецназа

Корчевский Юрий Григорьевич
Боевая фантастика Ю. Корчевского
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.00
рейтинг книги
Атаман царского Спецназа

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Виконт, который любил меня

Куин Джулия
2. Бриджертоны
Любовные романы:
исторические любовные романы
9.13
рейтинг книги
Виконт, который любил меня

Эпоха Опустошителя. Том IX

Павлов Вел
9. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Эпоха Опустошителя. Том IX

Четники. Королевская армия

Тимофеев Алексей Юрьевич
Документальная литература:
биографии и мемуары
публицистика
5.00
рейтинг книги
Четники. Королевская армия

Древесный маг Орловского княжества 13

Павлов Игорь Васильевич
13. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 13

Ученик

Первухин Андрей Евгеньевич
1. Ученик
Фантастика:
фэнтези
6.20
рейтинг книги
Ученик

Неучтенный элемент. Том 5

NikL
5. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 5

Мажор. Дилогия.

Соколов Вячеслав Иванович
Фантастика:
боевая фантастика
8.05
рейтинг книги
Мажор. Дилогия.

Телохранитель Генсека. Том 2

Алмазный Петр
2. Медведев
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Телохранитель Генсека. Том 2

Простолюдин

Рокотов Алексей
1. Путь князя
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Простолюдин

Последний Паладин. Том 10

Саваровский Роман
10. Путь Паладина
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Последний Паладин. Том 10

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Граф Книга третья

Первухин Андрей Евгеньевич
10. Ученик
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Граф Книга третья