Функция 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 ∈) 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() и считывать маски побайтно, сдвигая биты и используя маску для получения правильных значений.

Перейти на страницу:

Похожие книги