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

на главную

Жанры

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

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

Шрифт:

Завершив чтение файла, проверяем состояние потока QDataStream. Так можно поступать, потому что, если QDataStream переходит в состояние ошибки, это состояние сохраняется в дальнейшем и последующие операции чтения могут выдать только нули. Например, если чтение первого массива бит завершается неудачей, попытка чтения второго массива в результате даст пустой массив QBitArray.

32 *image = QImage(width, height, QImage::Format_ARGB32);

33 for (int i = 0; i < int(height); ++i) {

34 for (int j = 0; j < int(width); ++j) {

35 QRgb color;

36 int bit = (i * width) + j;

37 if (andBitmap.testBit(bit)) {

38 if (xorBitmap.testBit(bit)) {

39 color = 0x7F7F7F7F;

40 } else {

41 color = 0x00FFFFFF;

42 }

43 } else {

44 if (xorBitmap.testBit(bit)) {

45 color = 0xFFFFFFFF;

46 } else {

47 color = 0xFF000000;

48 }

50 }

51 image->setPixel(j, i, color);

52 }

53 }

Мы

конструируем новый объект QImage с правильными размерами и устанавливаем на него указатель изображения. Затем проходим по каждому пикселю битовых массивов XOR и AND и преобразуем их в 32-битовый цветовой формат ARGB. С помощью массивов битов AND и XOR цвет каждого пикселя курсора всегда получается в соответствии со следующей таблицей:

С получением черного, белого и прозрачного пикселей нет проблем, однако нельзя получить инвертированный пиксель фона, используя цветовой формат ARGB, если не знаешь цвет исходного пикселя фона. В качестве замены используем полупрозрачный серый цвет (0x7F7F7F7F).

54 ++currentImageNo;

55 if (currentImageNo == numImages)

56 state = AfterLastImage;

57 return true;

58 }

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

01 bool CursorHandler::jumpToNextImage

02 {

03 QImage image;

04 return read(&image);

05 }

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

01 void CursorHandler::readHeaderIfNecessary const

02 {

03 if (state != BeforeHeader)

04 return;

05 quint16 reserved;

06 quint16 type;

07 quint16 count;

08 QDataStream in(device);

09 in.setByteOrder(QDataStream::LittleEndian);

10 in >> reserved >> type >> count;

11 in.skipRawData(16 * count);

12 if (in.status != QDataStream::Ok || reserved != 0

13 || type != 2 || count == 0) {

14 enterErrorState;

15 return;

16 }

17 state = BeforeImage;

18 currentImageNo = 0;

19 numImages = int(count);

20 }

Закрытая

функция readHeaderIfNecessary вызывается из imageCount и read. Если заголовок файла уже был прочитан, состояние не будет иметь значение BeforeHeader (перед заголовком) и сразу же делается возврат управления. В противном случае открываем на устройстве поток данных, считываем некоторые общие данные (в частности, количество курсоров, содержащихся в файле) и устанавливаем состояние в значение BeforeImage (перед изображением). В конце указатель файла данного устройства устанавливается перед первым изображением.

01 void CursorHandler::enterErrorState const

02 {

03 currentImageNo = 0;

04 numImages = 0;

05 state = Error;

06 }

При возникновении ошибки считаем, что файл не содержит изображений требуемого формата, и устанавливаем состояние в значение Error. В дальнейшем такое состояние обработчика не может быть изменено.

01 QBitArray CursorHandler::readBitmap(int width, int height,

02 QDataStream &in) const

03 {

04 QBitArray bitmap(width * height);

05 quint8 byte;

06 quint32 word;

07 for (int i = 0; i < height; ++i) {

08 for (int j = 0; j < width; ++j) {

09 if ((j % 32) == 0) {

10 word = 0;

11 for (int k = 0; k < 4; ++k) {

12 in >> byte;

13 word = (word << 8) | byte;

14 }

15 }

16 bitmap.setBit(((height - i - 1) * width) + j,

17 word & 0x80000000);

18 word <<= 1;

19 }

20 }

21 return bitmap;

22 }

Функция readBitmap используется для чтения масок курсора AND и XOR. Эти маски обладают двумя необычными свойствами. Во-первых, строки в них располагаются, начиная с нижних, вместо обычного расположения строк сверху вниз. Во-вторых, оказывается, что используемый здесь порядок байтов отличается от порядка байтов любых других данных в файлах .cur. В связи с этим нам приходится инвертировать координату у в вызове setBit и считывать маски побайтно, сдвигая биты и используя маску для получения правильных значений.

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

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

Ковальчук Олег Валентинович
4. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 4

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4