⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpaintengine_raster.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    ++x;                    continue;                }                if (current == NSPANS) {                    d->penData.blend(current, spans, &d->penData);                    current = 0;                }                spans[current].x = x + rx;                spans[current].y = y + ry;                spans[current].coverage = 255;                int len = 1;                ++x;                // extend span until we find a different one.                while (x < w && monoVal(scanline, x)) {                    ++x;                    ++len;                }                spans[current].len = len;                ++current;            }            scanline += bpl;        }    } else {        for (int y=y0; y < h; ++y) {            for (int x = x0; x < w; ) {                // Skip those with 0 coverage                if (scanline[x] == 0) {                    ++x;                    continue;                }                if (current == NSPANS) {                    d->penData.blend(current, spans, &d->penData);                    current = 0;                }                int coverage = scanline[x];                spans[current].x = x + rx;                spans[current].y = y + ry;                spans[current].coverage = coverage;                int len = 1;                ++x;                // extend span until we find a different one.                while (x < w && scanline[x] == coverage) {                    ++x;                    ++len;                }                spans[current].len = len;                ++current;            }            scanline += bpl;        }    }//     qDebug() << "alphaPenBlt: num spans=" << current//              << "span:" << spans->x << spans->y << spans->len << spans->coverage;        // Call span func for current set of spans.    if (current != 0)        d->penData.blend(current, spans, &d->penData);}/* Fills a rect with the current pen */void QRasterPaintEngine::qwsFillRect(int x, int y, int w, int h){    Q_D(QRasterPaintEngine);    int x1 = qMax(x,0);    int x2 = qMin(x+w, d->rasterBuffer->width());    int y1 = qMax(y, 0);    int y2 = qMin(y+h, d->rasterBuffer->height());;    int len = x2 - x1;    if (d->penData.blend && len > 0) {        QT_FT_Span span;        span.x = x1;        span.len = x2 - x1;        span.y = y;        span.coverage = 255;        // draw the fill        for (int y=y1; y<y2; ++y) {            d->penData.blend(1, &span, &d->penData);        }    }}#endif#ifdef Q_WS_X11void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem){    QPaintEngine::drawTextItem(p, textItem);    // #####}#else#if defined(Q_WS_WIN)bool QRasterPaintEngine::drawTextInFontBuffer(const QRect &devRect, int xmin, int ymin, int xmax,                                              int ymax, const QTextItem &textItem, bool clearType,                                              qreal leftBearingReserve){    Q_D(QRasterPaintEngine);    const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);    if (d->mono_surface) {        // Some extra work to get proper rasterization of text on monochrome targets        HBITMAP bitmap = CreateBitmap(devRect.width(), devRect.height(), 1, 1, 0);        HDC hdc = CreateCompatibleDC(qt_win_display_dc());        HGDIOBJ null_bitmap = SelectObject(hdc, bitmap);        SelectObject(hdc, GetStockObject(WHITE_BRUSH));        SelectObject(hdc, GetStockObject(NULL_PEN));        Rectangle(hdc, 0, 0, devRect.width() + 1, devRect.height() + 1);        // Fill buffer with stuff        SelectObject(hdc, GetStockObject(BLACK_BRUSH));        SelectObject(hdc, GetStockObject(BLACK_PEN));        SetTextColor(hdc, RGB(0,0,0));        qt_draw_text_item(QPoint(qRound(leftBearingReserve), ti.ascent.toInt()), ti, hdc);        BitBlt(d->fontRasterBuffer->hdc(), 0, 0, devRect.width(), devRect.height(),               hdc, 0, 0, SRCCOPY);        SelectObject(hdc, null_bitmap);        DeleteObject(bitmap);        DeleteDC(hdc);        return false;    } else {        // Let Windows handle the composition of background and foreground for cleartype text        QRgb penColor = 0;        if (clearType) {            penColor = d->penData.solid.color;            // Copy background from raster buffer            for (int y=ymin; y<ymax; ++y) {                QRgb *sourceScanline = (QRgb *) d->rasterBuffer->scanLine(y);                QRgb *destScanline = (QRgb *) d->fontRasterBuffer->scanLine(y - devRect.y());                for (int x=xmin; x<xmax; ++x) {                    // If the background is transparent, set it to completely opaque so we will                    // recognize it after Windows screws up the alpha channel of font buffer.                    // Otherwise, just copy the contents.                    if (qAlpha(sourceScanline[x]) == 0x00)                        destScanline[x - devRect.x()] |= 0xff000000;                    else                        destScanline[x - devRect.x()] = sourceScanline[x];                }            }        } else {            d->fontRasterBuffer->resetBuffer(255);        }        // Draw the text item        if (d->clear_type_text) {            COLORREF cf = RGB(qRed(penColor), qGreen(penColor), qBlue(penColor));            SelectObject(d->fontRasterBuffer->hdc(), CreateSolidBrush(cf));            SelectObject(d->fontRasterBuffer->hdc(), CreatePen(PS_SOLID, 1, cf));            SetTextColor(d->fontRasterBuffer->hdc(), cf);        }        qt_draw_text_item(QPoint(qRound(leftBearingReserve), ti.ascent.toInt()), ti,                          d->fontRasterBuffer->hdc());        if (d->clear_type_text) {            DeleteObject(SelectObject(d->fontRasterBuffer->hdc(),GetStockObject(NULL_BRUSH)));            DeleteObject(SelectObject(d->fontRasterBuffer->hdc(),GetStockObject(BLACK_PEN)));        }        // Clean up alpha channel        if (clearType) {            for (int y=ymin; y<ymax; ++y) {                QRgb *scanline = (QRgb *) d->fontRasterBuffer->scanLine(y - devRect.y());                QRgb *rbScanline = (QRgb *) d->rasterBuffer->scanLine(y);                for (int x=xmin; x<xmax; ++x) {                    // If alpha is 0, then Windows has drawn text on top of the pixel, so set                    // the pixel to opaque. Otherwise, Windows has not touched the pixel, so                    // we can set it to transparent so the background shines through instead.                    switch (qAlpha(scanline[x - devRect.x()])) {                    case 0x0:                        // Special case: If Windows has drawn on top of a transparent pixel, then                        // we bail out. This is an attempt at avoiding the problem where Windows                        // has no background to use for composition, but also minimizing the                        // number of cases hit by the fall back.                        // ### This is far from optimal.                        if (qAlpha(rbScanline[x]) == 0) {                            return drawTextInFontBuffer(devRect, xmin, ymin, xmax, ymax, textItem,                                false, leftBearingReserve);                        }                        scanline[x - devRect.x()] |= 0xff000000;                        break ;                    default: scanline[x - devRect.x()] = 0x0; break ;                    };                }            }        }    }    return clearType;}#endif // Q_WS_WINvoid QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem){    const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);#ifdef QT_DEBUG_DRAW    printf(" - QRasterPaintEngine::drawTextItem(), (%.2f,%.2f), string=%s\n",           p.x(), p.y(), QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());#endif    Q_D(QRasterPaintEngine);#if defined(Q_WS_WIN)    if (!d->penData.blend)        return;    if (d->txop >= QPainterPrivate::TxScale) {        QPaintEngine::drawTextItem(p, textItem);        return;    }    // Only support cleartype for solid pens, 32 bit target buffers and when the pen color is    // opaque    bool clearType = d->clear_type_text                     && d->penData.type == QSpanData::Solid                     && d->deviceDepth == 32                     &&  qAlpha(d->penData.solid.color) == 255;    QFixed x_buffering = ti.ascent;    // Hack to reserve some space on the left side of the string in case    // the character has a large negative bearing (e.g. it should be drawn on top    // of the previous character)    qreal leftBearingReserve = ti.fontEngine->maxCharWidth();    QRectF logRect(p.x() - leftBearingReserve, p.y() - ti.ascent.toReal(),                   (ti.width + x_buffering).toReal() + leftBearingReserve,                   (ti.ascent + ti.descent + 1).toReal());    QRect devRect = d->matrix.mapRect(logRect).toRect();    if(devRect.width() == 0 || devRect.height() == 0)        return;    d->fontRasterBuffer->prepare(devRect.width(), devRect.height());    // Boundaries    int ymax = qMin(devRect.y() + devRect.height(), d->rasterBuffer->height());    int ymin = qMax(devRect.y(), 0);    int xmax = qMin(devRect.x() + devRect.width(), d->rasterBuffer->width());    int xmin = qMax(devRect.x(), 0);    QClipData *clip = d->rasterBuffer->clipEnabled ? d->rasterBuffer->clip : 0;    if (clip) {        xmin = qMax(xmin, clip->xmin);        xmax = qMin(xmax, clip->xmax);        ymin = qMax(ymin, clip->ymin);        ymax = qMin(ymax, clip->ymax);    }    if (xmax - xmin <= 0 || ymax - ymin <= 0)        return;    // Fill the font raster buffer with text    clearType = drawTextInFontBuffer(devRect, xmin, ymin, xmax, ymax, textItem,                                     clearType, leftBearingReserve);    const int NSPANS = 256;    QSpan spans[NSPANS];    int current = 0;    if (d->mono_surface) {        for (int y=ymin; y<ymax; ++y) {            QRgb *scanline = (QRgb *) d->fontRasterBuffer->scanLine(y - devRect.y()) - devRect.x();            // Generate spans for this y coord            for (int x = xmin; x<xmax; ) {                // Skip those with 0 coverage (black on white so inverted)                while (x < xmax && qBlue(scanline[x]) > 0x80) ++x;                if (x >= xmax) break;                QT_FT_Span span = { x, 0, y, 255 };                // extend span until we find a different one.                while (x < xmax && qBlue(scanline[x]) < 0x80) ++x;                span.len = x - span.x;                if (current == NSPANS) {                    d->penData.blend(current, spans, &d->penData);                    current = 0;                }                spans[current++] = span;            }        }    } else if (clearType) {        QSpanData data;        data.init(d->rasterBuffer);        data.type = QSpanData::Texture;        data.texture.type = TextureData::Plain;        data.texture.imageData = d->fontRasterBuffer->buffer();        data.texture.width = d->fontRasterBuffer->bytesPerLine() / 4;        data.texture.height = d->fontRasterBuffer->height();        data.texture.bytesPerLine = d->fontRasterBuffer->bytesPerLine();        data.texture.hasAlpha = true;        data.bilinear = false;        data.texture.format = QImage::Format_ARGB32_Premultiplied;        data.texture.colorTable = 0;        data.dx = -devRect.x();        data.dy = -devRect.y();        data.adjustSpanMethods();        fillRect(QRect(xmin, ymin, xmax - xmin, ymax - ymin), &data);    } else if (d->clear_type_text) {        for (int y=ymin; y<ymax; ++y) {            QRgb *scanline = (QRgb *) d->fontRasterBuffer->scanLine(y - devRect.y()) - devRect.x();            // Generate spans for this y coord            for (int x = xmin; x<xmax; ) {                // Skip those with 0 coverage (black on white so inverted)                while (x < xmax && qGray(scanline[x]) == 255) ++x;                if (x >= xmax) break;                int prev = qGray(scanline[x]);                QT_FT_Span span = { x, 0, y, 255 - prev };                // extend span until we find a different one.                while (x < xmax && qGray(scanline[x]) == prev) ++x;                span.len = x - span.x;                if (current == NSPANS) {                    d->penData.blend(current, spans, &d->penData);                    current = 0;                }                spans[current++] = span;            }        }    } else {        // For the noncleartype/grayscale text we can look at only one color component,        // and save a bit of qGray effort...        for (int y=ymin; y<ymax; ++y) {            QRgb *scanline = (QRgb *) d->fontRasterBuffer->scanLine(y - devRect.y()) - devRect.x();            // Generate spans for this y coord            for (int x = xmin; x<xmax; ) {                // Skip those with 0 coverage (black on white so inverted)                while (x < xmax && qBlue(scanline[x]) == 255) ++x;                if (x >= xmax) break;                int prev = qBlue(scanline[x]);                QT_FT_Span span = { x, 0, y, 255 - prev };                // extend span until we find a different one.                while (x < xmax && qBlue(scanline[x]) == prev) ++x;                span.len = x - span.x;                if (current == NSPANS) {                    d->penData.blend(current, spans, &d->penData);                    current = 0;                }                spans[current++] = span;            }        }    }    if (current != 0)        d->penData.blend(current, spans, &d->penData);    return;#elif defined Q_WS_QWS    if (d->txop < QPainterPrivate::TxScale) {#ifndef QT_NO_FREETYPE        if (!(ti.fontEngine->type() == QFontEngine::Freetype              && static_cast<QFontEngineFT*>(ti.fontEngine)->drawAsOutline()))#endif        {            ti.fontEngine->draw(this, qRound(p.x()), qRound(p.y()), ti);            return;        }    }#endif // Q_WS_WIN    // Fallthrough for embedded and default for mac.    bool aa = d->antialiased;    d->antialiased = true;    QPaintEngine::drawTextItem(p, ti);    d->antialiased = aa;    return;}#endifvoid Q

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -