Qt 가지고 삽질좀 했습니다.

비행소년의 이미지

Qt가 Wince에서 돌아 간다는 얘기를 듣고, MFC보다는 백만배는 쉽겠다는 생각이 들어서

Qt로 개발을 진행했습니다.

물론 MFC 보다 백만배는 개발 하기 쉽습니다. GDI 가지고 고민 하지 않고, 추상화 되어 있는 클래스를 가지고 작업만 진행 하면 되니깐요.

그러나, 텍스트 출력에서 문제에 봉착하게 됩니다.

Wince/Qt는 Anti-Aliasing이 안된다는 사실을 알게 되었습니다. -_-;;;

개발의 편리함과 개발 속도, Drawing 속도 때문에 절대로 Qt를 포기 못한다고 배째라 했습니다. -_-;

이 때 부터 삽질이 시작 되었습니다.

열심히 mailing list를 뒤졌더니 Qt/Jira 에 버그로 올라와 있었고, native feature 때문에 지원을 안한다고, 이슈가 close 되었습니다.

그렇다고, 여기서 멈추면 삽질러가 아니라는 생각에 더 파보기 시작 합니다.

Native feature 때문에 안된다면 Anti-Aliasing 이 DDB plane에서 가능 하고, DIB Plane에서는 불 가능 한것이 아닌가 하고 자료를 찾아 보기 시작 합니다.

뉴스그룹에서는 DIB도 Primary Plane과 속성이 같다면 출력이 가능하다고 어느 MVP가 답변을 달았습니다.

다시 원점에서 생각해 보면 DDB/DIB 둘다 cleartype 출력이 가능 하다.

그런데, 출력은 안된다.

그래서 다시 테스트를 시작해 봅니다.

Qt에서 쓰고 있는 Text Mask를 가지고 테스트를 해봅니다.

중간에 DDB를 만들어서 DIB로 복사를 합니다.

그러나 화면에서는 여전히 그상태 입니다. -_-;

다시 중간에 만든 DDB를 화면에 출력 해 봅니다. cleartype이 적용이 된 것이 출력 됩니다.

아... 되돌아 가서 생각을 정리해보니 무언가가 중간에 출력 데이터를 변조 시킨 것으로 확신이 듭니다.

현상을 다시 파악해보기 위해서 ce의 스크린샷을 떠서 확대를 시켜 봅니다.

텍스트에 anti-aliasing이 적용이 되지만 너무 희미 하게 적용이 되서 안되는 것 처럼 보이는 것 이었습니다. =_=;;

좀 허무한 내용 이지만, 다시 코드를 살펴 보기 시작 했습니다.

QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
 
QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
 
    // ### This part is kinda pointless, but we'll crash later if we dont because some
    // code paths expects there to be colortables for index8-bit...
    QVector<QRgb> colors(256);
    for (int i=0; i<256; ++i)
        colors[i] = qRgba(0, 0, 0, i);
    indexed.setColorTable(colors);
 
    // Copy data... Cannot use QPainter here as GDI has messed up the
    // Alpha channel of the ni.image pixels...
    for (int y=0; y<mask->height(); ++y) {
        uchar *dest = indexed.scanLine(y);
        if (mask->image.format() == QImage::Format_RGB16) {
            const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y);
            for (int x=0; x<mask->width(); ++x)
                dest[x] = 255 - qGray(src[x]);
        } else {
            const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y);
            for (int x=0; x<mask->width(); ++x) {
#ifdef Q_OS_WINCE
                dest[x] = 255 - qGray(src[x]);
#else
                if (QNativeImage::systemFormat() == QImage::Format_RGB16)
                    dest[x] = 255 - qGray(src[x]);
                else
                    dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
#endif
            }
        }
    }

위의 함수를 노려 보다 보니 이상한 부분을 발견 했습니다.

dest[x] = 255 - qGray(src[x]);

32bit RGB가 565 RGB가 같은 함수를 호출 합니다. 다시 qGray() 소스를 추적 했더니 RGB 필터가 각각 8bit 입니다.

아... 16비트 RGB에서는 색상이 제대로 변환이 안되는게 맞습니다.

다시 qGray 코드를 수정해서 565 포맷에 맞춰서 수정 해서 돌려 보는 순간 변화된 텍스트가 보입니다.

결론적으로 native feature 때문이 아니라, Glyph Mask를 만드는데 RGB 변환을 잘 못 해서 안되는 것 처럼 보이는 것 이었습니다.

허무 하기는 했지만, 그래도 보람 있는 삽질 이었습니다.

winner의 이미지

Patch 보내시면 좋을 듯.

처로의 이미지

와, 삽질의 정석입니다. Patch 보내세요! ^^

jg의 이미지

짝짝짝. 마저 고생해주시면 좋겠네요.

$Myoungjin_JEON=@@=qw^rekcaH lreP rehtonA tsuJ^;$|++;{$i=$like=pop@@;unshift@@,$i;$~=18-length$i;print"\r[","~"x abs,(scalar reverse$i),"~"x($~-abs),"]"and select$good,$day,$mate,1/$~for 0..$~,-$~+1..-1;redo}

비행소년의 이미지

Qt Jira에 올렸더니 공헌에 감사 하지만 그곳은 버그를 받는 곳이지 코드를 받는 곳이 아니라고 하네요.

gitorious에 merge request로 올려 달랍니다.

누구 merge request 방법 아시는 분 있으면 알려 주세요.

높이 날다 떨어지면.
아푸다 ㅡ,.ㅡ