src/openvg/qpaintengine_vg.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 7 3f74d0d4af4c
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtOpenVG module of the Qt Toolkit.
     7 ** This file is part of the QtOpenVG module of the Qt Toolkit.
     8 **
     8 **
   198     VGMatrixMode matrixMode;    // Last matrix mode that was set.
   198     VGMatrixMode matrixMode;    // Last matrix mode that was set.
   199     VGImageMode imageMode;      // Last image mode that was set.
   199     VGImageMode imageMode;      // Last image mode that was set.
   200 
   200 
   201     QRegion scissorRegion;  // Currently active scissor region.
   201     QRegion scissorRegion;  // Currently active scissor region.
   202     bool scissorActive;     // True if scissor region is active.
   202     bool scissorActive;     // True if scissor region is active.
       
   203     bool scissorDirty;      // True if scissor is dirty after native painting.
   203 
   204 
   204     QPaintEngine::DirtyFlags dirty;
   205     QPaintEngine::DirtyFlags dirty;
   205 
   206 
   206     QColor clearColor;      // Last clear color that was set.
   207     QColor clearColor;      // Last clear color that was set.
   207     VGfloat clearOpacity;   // Opacity during the last clear.
   208     VGfloat clearOpacity;   // Opacity during the last clear.
   355     maskValid = false;
   356     maskValid = false;
   356     maskIsSet = false;
   357     maskIsSet = false;
   357     rawVG = false;
   358     rawVG = false;
   358 
   359 
   359     scissorActive = false;
   360     scissorActive = false;
       
   361     scissorDirty = false;
   360 
   362 
   361     dirty = 0;
   363     dirty = 0;
   362 
   364 
   363     clearOpacity = 1.0f;
   365     clearOpacity = 1.0f;
   364 
   366 
   982             target[x] = (source[x>>3] >> (x&7)) & 1 ? fg : bg;
   984             target[x] = (source[x>>3] >> (x&7)) & 1 ? fg : bg;
   983     }
   985     }
   984     return dest;
   986     return dest;
   985 }
   987 }
   986 
   988 
       
   989 // defined in qpixmapdata_vg.cpp.
       
   990 const uchar *qt_vg_imageBits(const QImage& image);
       
   991 
   987 static VGImage toVGImage
   992 static VGImage toVGImage
   988     (const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor)
   993     (const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor)
   989 {
   994 {
   990     QImage img(image);
   995     QImage img(image);
   991 
   996 
  1015         img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
  1020         img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
  1016         format = VG_sARGB_8888_PRE;
  1021         format = VG_sARGB_8888_PRE;
  1017         break;
  1022         break;
  1018     }
  1023     }
  1019 
  1024 
  1020     const uchar *pixels = img.bits();
  1025     const uchar *pixels = qt_vg_imageBits(img);
  1021 
  1026 
  1022     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1027     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1023         (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1028         (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1024     vgImageSubData
  1029     vgImageSubData
  1025         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1030         (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
  1059         img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
  1064         img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
  1060         format = VG_sARGB_8888_PRE;
  1065         format = VG_sARGB_8888_PRE;
  1061         break;
  1066         break;
  1062     }
  1067     }
  1063 
  1068 
  1064     const uchar *pixels = img.bits() + bpp * sr.x() +
  1069     const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() +
  1065                           img.bytesPerLine() * sr.y();
  1070                           img.bytesPerLine() * sr.y();
  1066 
  1071 
  1067     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1072     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1068         (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
  1073         (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
  1069     vgImageSubData
  1074     vgImageSubData
  1081     painter.begin(&img);
  1086     painter.begin(&img);
  1082     painter.setOpacity(opacity);
  1087     painter.setOpacity(opacity);
  1083     painter.drawImage(0, 0, image);
  1088     painter.drawImage(0, 0, image);
  1084     painter.end();
  1089     painter.end();
  1085 
  1090 
  1086     const uchar *pixels = img.bits();
  1091     const uchar *pixels = qt_vg_imageBits(img);
  1087 
  1092 
  1088     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1093     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1089         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1094         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1090     vgImageSubData
  1095     vgImageSubData
  1091         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1096         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1103     painter.begin(&img);
  1108     painter.begin(&img);
  1104     painter.setOpacity(opacity);
  1109     painter.setOpacity(opacity);
  1105     painter.drawImage(QPoint(0, 0), image, sr);
  1110     painter.drawImage(QPoint(0, 0), image, sr);
  1106     painter.end();
  1111     painter.end();
  1107 
  1112 
  1108     const uchar *pixels = img.bits();
  1113     const uchar *pixels = qt_vg_imageBits(img);
  1109 
  1114 
  1110     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1115     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
  1111         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1116         (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  1112     vgImageSubData
  1117     vgImageSubData
  1113         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  1118         (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
  2081         if (isDefaultClipRegion(region)) {
  2086         if (isDefaultClipRegion(region)) {
  2082             // The scissor region is the entire drawing surface,
  2087             // The scissor region is the entire drawing surface,
  2083             // so there is no point doing any scissoring.
  2088             // so there is no point doing any scissoring.
  2084             vgSeti(VG_SCISSORING, VG_FALSE);
  2089             vgSeti(VG_SCISSORING, VG_FALSE);
  2085             d->scissorActive = false;
  2090             d->scissorActive = false;
       
  2091             d->scissorDirty = false;
  2086             return;
  2092             return;
  2087         }
  2093         }
  2088     } else
  2094     } else
  2089 #endif
  2095 #endif
  2090     {
  2096     {
  2098             if (isDefaultClipRegion(region)) {
  2104             if (isDefaultClipRegion(region)) {
  2099                 // The scissor region is the entire drawing surface,
  2105                 // The scissor region is the entire drawing surface,
  2100                 // so there is no point doing any scissoring.
  2106                 // so there is no point doing any scissoring.
  2101                 vgSeti(VG_SCISSORING, VG_FALSE);
  2107                 vgSeti(VG_SCISSORING, VG_FALSE);
  2102                 d->scissorActive = false;
  2108                 d->scissorActive = false;
       
  2109                 d->scissorDirty = false;
  2103                 return;
  2110                 return;
  2104             }
  2111             }
  2105         } else
  2112         } else
  2106 #endif
  2113 #endif
  2107 
  2114 
  2108         // Disable the scissor completely if the system clip is empty.
  2115         // Disable the scissor completely if the system clip is empty.
  2109         if (region.isEmpty()) {
  2116         if (region.isEmpty()) {
  2110             vgSeti(VG_SCISSORING, VG_FALSE);
  2117             vgSeti(VG_SCISSORING, VG_FALSE);
  2111             d->scissorActive = false;
  2118             d->scissorActive = false;
       
  2119             d->scissorDirty = false;
  2112             return;
  2120             return;
  2113         }
  2121         }
  2114     }
  2122     }
  2115 
  2123 
  2116     if (d->scissorActive && region == d->scissorRegion)
  2124     if (d->scissorActive && region == d->scissorRegion && !d->scissorDirty)
  2117         return;
  2125         return;
  2118 
  2126 
  2119     QVector<QRect> rects = region.rects();
  2127     QVector<QRect> rects = region.rects();
  2120     int count = rects.count();
  2128     int count = rects.count();
  2121     if (count > d->maxScissorRects)
  2129     if (count > d->maxScissorRects)
  2129         params[i * 4 + 3] = rects[i].height();
  2137         params[i * 4 + 3] = rects[i].height();
  2130     }
  2138     }
  2131 
  2139 
  2132     vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
  2140     vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
  2133     vgSeti(VG_SCISSORING, VG_TRUE);
  2141     vgSeti(VG_SCISSORING, VG_TRUE);
       
  2142     d->scissorDirty = false;
  2134     d->scissorActive = true;
  2143     d->scissorActive = true;
  2135     d->scissorRegion = region;
  2144     d->scissorRegion = region;
  2136 }
  2145 }
  2137 
  2146 
  2138 QRegion QVGPaintEngine::defaultClipRegion()
  2147 QRegion QVGPaintEngine::defaultClipRegion()
  3164         VGImage vgImage = VG_INVALID_HANDLE;
  3173         VGImage vgImage = VG_INVALID_HANDLE;
  3165         metrics = ti.fontEngine->boundingBox(glyph);
  3174         metrics = ti.fontEngine->boundingBox(glyph);
  3166         if (!scaledImage.isNull()) {  // Not a space character
  3175         if (!scaledImage.isNull()) {  // Not a space character
  3167             if (scaledImage.format() == QImage::Format_Indexed8) {
  3176             if (scaledImage.format() == QImage::Format_Indexed8) {
  3168                 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER);
  3177                 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER);
  3169                 vgImageSubData(vgImage, scaledImage.bits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
  3178                 vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
  3170             } else if (scaledImage.format() == QImage::Format_Mono) {
  3179             } else if (scaledImage.format() == QImage::Format_Mono) {
  3171                 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
  3180                 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
  3172                 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3181                 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3173                 vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
  3182                 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
  3174             } else {
  3183             } else {
  3175                 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
  3184                 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
  3176                 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3185                 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3177                 vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
  3186                 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
  3178             }
  3187             }
  3179         }
  3188         }
  3180         origin[0] = -metrics.x.toReal() + 0.5f;
  3189         origin[0] = -metrics.x.toReal() + 0.5f;
  3181         origin[1] = -metrics.y.toReal() + 0.5f;
  3190         origin[1] = -metrics.y.toReal() + 0.5f;
  3182         escapement[0] = metrics.xoff.toReal();
  3191         escapement[0] = metrics.xoff.toReal();
  3331     d->forceBrushChange = true;
  3340     d->forceBrushChange = true;
  3332     d->penType = (VGPaintType)0;
  3341     d->penType = (VGPaintType)0;
  3333     d->brushType = (VGPaintType)0;
  3342     d->brushType = (VGPaintType)0;
  3334     d->clearColor = QColor();
  3343     d->clearColor = QColor();
  3335     d->fillPaint = d->brushPaint;
  3344     d->fillPaint = d->brushPaint;
       
  3345     d->scissorDirty = true;
  3336     restoreState(QPaintEngine::AllDirty);
  3346     restoreState(QPaintEngine::AllDirty);
  3337     d->dirty = dirty;
  3347     d->dirty = dirty;
  3338     d->rawVG = false;
  3348     d->rawVG = false;
  3339     vgSetPaint(d->penPaint, VG_STROKE_PATH);
  3349     vgSetPaint(d->penPaint, VG_STROKE_PATH);
  3340     vgSetPaint(d->brushPaint, VG_FILL_PATH);
  3350     vgSetPaint(d->brushPaint, VG_FILL_PATH);
  3638             (VG_sARGB_8888_PRE, img.width(), img.height(),
  3648             (VG_sARGB_8888_PRE, img.width(), img.height(),
  3639              VG_IMAGE_QUALITY_FASTER);
  3649              VG_IMAGE_QUALITY_FASTER);
  3640         if (vgImage == VG_INVALID_HANDLE)
  3650         if (vgImage == VG_INVALID_HANDLE)
  3641             return;
  3651             return;
  3642         vgImageSubData
  3652         vgImageSubData
  3643             (vgImage, img.bits() + img.bytesPerLine() * (img.height() - 1),
  3653             (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1),
  3644              -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
  3654              -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
  3645              img.width(), img.height());
  3655              img.width(), img.height());
  3646 
  3656 
  3647         vgDrawImage(vgImage);
  3657         vgDrawImage(vgImage);
  3648         vgDestroyImage(vgImage);
  3658         vgDestroyImage(vgImage);
  3664         params[i * 4 + 3] = rects[i].height();
  3674         params[i * 4 + 3] = rects[i].height();
  3665     }
  3675     }
  3666 
  3676 
  3667     vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
  3677     vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
  3668     vgSeti(VG_SCISSORING, VG_TRUE);
  3678     vgSeti(VG_SCISSORING, VG_TRUE);
       
  3679     d->scissorDirty = false;
  3669     d->scissorActive = true;
  3680     d->scissorActive = true;
  3670     d->scissorRegion = region;
  3681     d->scissorRegion = region;
  3671 }
  3682 }
  3672 
  3683 
  3673 void QVGCompositionHelper::clearScissor()
  3684 void QVGCompositionHelper::clearScissor()
  3674 {
  3685 {
  3675     if (d->scissorActive) {
  3686     if (d->scissorActive || d->scissorDirty) {
  3676         vgSeti(VG_SCISSORING, VG_FALSE);
  3687         vgSeti(VG_SCISSORING, VG_FALSE);
  3677         d->scissorActive = false;
  3688         d->scissorActive = false;
       
  3689         d->scissorDirty = false;
  3678     }
  3690     }
  3679 }
  3691 }
  3680 
  3692 
  3681 #endif // !QVG_NO_SINGLE_CONTEXT && !QT_NO_EGL
  3693 #endif // !QVG_NO_SINGLE_CONTEXT && !QT_NO_EGL
  3682 
  3694