src/openvg/qpaintengine_vg.cpp
branchRCL_3
changeset 13 c0432d11811c
parent 7 3f74d0d4af4c
equal deleted inserted replaced
12:cc75c76972ee 13:c0432d11811c
    73 #define QVG_NO_RENDER_TO_MASK 1
    73 #define QVG_NO_RENDER_TO_MASK 1
    74 #endif
    74 #endif
    75 
    75 
    76 #if !defined(QVG_NO_DRAW_GLYPHS)
    76 #if !defined(QVG_NO_DRAW_GLYPHS)
    77 
    77 
    78 extern int qt_defaultDpiX();
    78 Q_DECL_IMPORT extern int qt_defaultDpiX();
    79 extern int qt_defaultDpiY();
    79 Q_DECL_IMPORT extern int qt_defaultDpiY();
    80 
    80 
    81 class QVGPaintEnginePrivate;
    81 class QVGPaintEnginePrivate;
    82 
    82 
    83 class QVGFontGlyphCache
    83 class QVGFontGlyphCache
    84 {
    84 {
   181     QTransform transform;   // Currently active transform.
   181     QTransform transform;   // Currently active transform.
   182     bool simpleTransform;   // True if the transform is simple (non-projective).
   182     bool simpleTransform;   // True if the transform is simple (non-projective).
   183     qreal penScale;         // Pen scaling factor from "transform".
   183     qreal penScale;         // Pen scaling factor from "transform".
   184 
   184 
   185     QTransform pathTransform;  // Calculated VG path transformation.
   185     QTransform pathTransform;  // Calculated VG path transformation.
   186     QTransform glyphTransform; // Calculated VG glyph transformation.
       
   187     QTransform imageTransform; // Calculated VG image transformation.
   186     QTransform imageTransform; // Calculated VG image transformation.
   188     bool pathTransformSet;  // True if path transform set in the VG context.
   187     bool pathTransformSet;  // True if path transform set in the VG context.
   189 
   188 
   190     bool maskValid;         // True if vgMask() contains valid data.
   189     bool maskValid;         // True if vgMask() contains valid data.
   191     bool maskIsSet;         // True if mask would be fully set if it was valid.
   190     bool maskIsSet;         // True if mask would be fully set if it was valid.
   495     mat[7] = transform.m32();
   494     mat[7] = transform.m32();
   496     mat[8] = transform.m33();
   495     mat[8] = transform.m33();
   497     vgLoadMatrix(mat);
   496     vgLoadMatrix(mat);
   498 }
   497 }
   499 
   498 
   500 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
   499 Q_DECL_IMPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
   501 
   500 
   502 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
   501 void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
   503 {
   502 {
   504     VGfloat devh = pdev->height();
   503     VGfloat devh = pdev->height();
   505 
   504 
   506     // Construct the VG transform by combining the Qt transform with
   505     // Construct the VG transform by combining the Qt transform with
   507     // the following viewport transformation:
   506     // the following viewport transformation:
   508     //        | 1  0  0   |
   507     //        | 1  0  0   |
   509     //        | 0 -1 devh |
   508     //        | 0 -1 devh |
   510     //        | 0  0  1   |
   509     //        | 0  0  1   |
   511     // The glyph transform uses a slightly different transformation:
       
   512     //        | 1  0  0       |   | 1 0  0.5 |   | 1  0     0.5      |
       
   513     //        | 0 -1 devh - 1 | * | 0 1 -0.5 | = | 0 -1 (devh - 0.5) |
       
   514     //        | 0  0  1       |   | 0 0   1  |   | 0  0      1       |
       
   515     // The full VG transform is effectively:
   510     // The full VG transform is effectively:
   516     //      1. Apply the user's transformation matrix.
   511     //      1. Apply the user's transformation matrix.
   517     //      2. Translate glyphs by an extra (0.5, -0.5).
   512     //      2. Flip the co-ordinate system upside down.
   518     //      3. Flip the co-ordinate system upside down.
       
   519     QTransform viewport(1.0f, 0.0f, 0.0f,
   513     QTransform viewport(1.0f, 0.0f, 0.0f,
   520                         0.0f, -1.0f, 0.0f,
   514                         0.0f, -1.0f, 0.0f,
   521                         0.0f, devh, 1.0f);
   515                         0.0f, devh, 1.0f);
   522     QTransform gviewport(1.0f, 0.0f, 0.0f,
       
   523                         0.0f, -1.0f, 0.0f,
       
   524                         0.5f, devh - 0.5f, 1.0f);
       
   525 
   516 
   526     // Compute the path transform and determine if it is projective.
   517     // Compute the path transform and determine if it is projective.
   527     pathTransform = transform * viewport;
   518     pathTransform = transform * viewport;
   528     glyphTransform = transform * gviewport;
       
   529     bool projective = (pathTransform.m13() != 0.0f ||
   519     bool projective = (pathTransform.m13() != 0.0f ||
   530                        pathTransform.m23() != 0.0f ||
   520                        pathTransform.m23() != 0.0f ||
   531                        pathTransform.m33() != 1.0f);
   521                        pathTransform.m33() != 1.0f);
   532     if (projective) {
   522     if (projective) {
   533         // The engine cannot do projective path transforms for us,
   523         // The engine cannot do projective path transforms for us,
   534         // so we will have to convert the co-ordinates ourselves.
   524         // so we will have to convert the co-ordinates ourselves.
   535         // Change the matrix to just the viewport transformation.
   525         // Change the matrix to just the viewport transformation.
   536         pathTransform = viewport;
   526         pathTransform = viewport;
   537         glyphTransform = gviewport;
       
   538         simpleTransform = false;
   527         simpleTransform = false;
   539     } else {
   528     } else {
   540         simpleTransform = true;
   529         simpleTransform = true;
   541     }
   530     }
   542     pathTransformSet = false;
   531     pathTransformSet = false;
   973 #endif
   962 #endif
   974 
   963 
   975     return vgpath;
   964     return vgpath;
   976 }
   965 }
   977 
   966 
   978 extern QImage qt_imageForBrush(int style, bool invert);
   967 Q_DECL_IMPORT extern QImage qt_imageForBrush(int style, bool invert);
   979 
   968 
   980 static QImage colorizeBitmap(const QImage &image, const QColor &color)
   969 static QImage colorizeBitmap(const QImage &image, const QColor &color)
   981 {
   970 {
   982     QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
   971     QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
   983     QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
   972     QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
  3246                 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
  3235                 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
  3247                 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3236                 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
  3248                 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
  3237                 vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
  3249             }
  3238             }
  3250         }
  3239         }
  3251         origin[0] = -metrics.x.toReal() + 0.5f;
  3240         origin[0] = -metrics.x.toReal();
  3252         origin[1] = -metrics.y.toReal() + 0.5f;
  3241         origin[1] = -metrics.y.toReal();
  3253         escapement[0] = metrics.xoff.toReal();
  3242         escapement[0] = 0;
  3254         escapement[1] = metrics.yoff.toReal();
  3243         escapement[1] = 0;
  3255         vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
  3244         vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
  3256         vgDestroyImage(vgImage);    // Reduce reference count.
  3245         vgDestroyImage(vgImage);    // Reduce reference count.
  3257 #else
  3246 #else
  3258         // Calculate the path for the glyph and cache it.
  3247         // Calculate the path for the glyph and cache it.
  3259         QPainterPath path;
  3248         QPainterPath path;
  3265             // Probably a "space" character with no visible outline.
  3254             // Probably a "space" character with no visible outline.
  3266             vgPath = VG_INVALID_HANDLE;
  3255             vgPath = VG_INVALID_HANDLE;
  3267         }
  3256         }
  3268         origin[0] = 0;
  3257         origin[0] = 0;
  3269         origin[1] = 0;
  3258         origin[1] = 0;
  3270         escapement[0] = metrics.xoff.toReal();
  3259         escapement[0] = 0;
  3271         escapement[1] = metrics.yoff.toReal();
  3260         escapement[1] = 0;
  3272         vgSetGlyphToPath(font, glyph, vgPath, VG_FALSE, origin, escapement);
  3261         vgSetGlyphToPath(font, glyph, vgPath, VG_FALSE, origin, escapement);
  3273         vgDestroyPath(vgPath);      // Reduce reference count.
  3262         vgDestroyPath(vgPath);      // Reduce reference count.
  3274 #endif // !defined(QVG_NO_IMAGE_GLYPHS)
  3263 #endif // !defined(QVG_NO_IMAGE_GLYPHS)
  3275     }
  3264     }
  3276 }
  3265 }
  3291     }
  3280     }
  3292  
  3281  
  3293     // Get the glyphs and positions associated with the text item.
  3282     // Get the glyphs and positions associated with the text item.
  3294     QVarLengthArray<QFixedPoint> positions;
  3283     QVarLengthArray<QFixedPoint> positions;
  3295     QVarLengthArray<glyph_t> glyphs;
  3284     QVarLengthArray<glyph_t> glyphs;
  3296     QTransform matrix = d->transform;
  3285     QTransform matrix;
  3297     matrix.translate(p.x(), p.y());
  3286     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
  3298     ti.fontEngine->getGlyphPositions
       
  3299         (ti.glyphs, matrix, ti.flags, glyphs, positions);
       
  3300 
  3287 
  3301     // Find the glyph cache for this font.
  3288     // Find the glyph cache for this font.
  3302     QVGFontCache::ConstIterator it = d->fontCache.constFind(ti.fontEngine);
  3289     QVGFontCache::ConstIterator it = d->fontCache.constFind(ti.fontEngine);
  3303     QVGFontGlyphCache *glyphCache;
  3290     QVGFontGlyphCache *glyphCache;
  3304     if (it != d->fontCache.constEnd()) {
  3291     if (it != d->fontCache.constEnd()) {
  3318         QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
  3305         QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
  3319                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3306                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
  3320     }
  3307     }
  3321 
  3308 
  3322     // Set the transformation to use for drawing the current glyphs.
  3309     // Set the transformation to use for drawing the current glyphs.
  3323     QTransform glyphTransform(d->glyphTransform);
  3310     QTransform glyphTransform(d->pathTransform);
  3324     glyphTransform.translate(p.x(), p.y());
  3311     glyphTransform.translate(p.x(), p.y());
  3325 #if defined(QVG_NO_IMAGE_GLYPHS)
  3312 #if defined(QVG_NO_IMAGE_GLYPHS)
  3326     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3313     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
  3327 #endif
  3314 #endif
  3328     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3315     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
  3329 
  3316 
  3330     // Add the glyphs from the text item into the glyph cache.
  3317     // Add the glyphs from the text item into the glyph cache.
  3331     glyphCache->cacheGlyphs(d, ti, glyphs);
  3318     glyphCache->cacheGlyphs(d, ti, glyphs);
  3332 
  3319 
       
  3320     // Create the array of adjustments between glyphs
       
  3321     QVarLengthArray<VGfloat> adjustments_x(glyphs.size());
       
  3322     QVarLengthArray<VGfloat> adjustments_y(glyphs.size());
       
  3323     for (int i = 1; i < glyphs.size(); ++i) {
       
  3324         adjustments_x[i-1] = (positions[i].x - positions[i-1].x).toReal();
       
  3325         adjustments_y[i-1] = (positions[i].y - positions[i-1].y).toReal();
       
  3326     }
       
  3327 
  3333     // Set the glyph drawing origin.
  3328     // Set the glyph drawing origin.
  3334     VGfloat origin[2];
  3329     VGfloat origin[2];
  3335     origin[0] = 0;
  3330     origin[0] = positions[0].x.toReal();
  3336     origin[1] = 0;
  3331     origin[1] = positions[0].y.toReal();
  3337     vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
  3332     vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
  3338 
  3333 
  3339     // Fast anti-aliasing for paths, better for images.
  3334     // Fast anti-aliasing for paths, better for images.
  3340 #if !defined(QVG_NO_IMAGE_GLYPHS)
  3335 #if !defined(QVG_NO_IMAGE_GLYPHS)
  3341     d->setImageQuality(VG_IMAGE_QUALITY_BETTER);
  3336     d->setImageQuality(VG_IMAGE_QUALITY_BETTER);
  3346 
  3341 
  3347     // Draw the glyphs.  We need to fill with the brush associated with
  3342     // Draw the glyphs.  We need to fill with the brush associated with
  3348     // the Qt pen, not the Qt brush.
  3343     // the Qt pen, not the Qt brush.
  3349     d->ensureBrush(state()->pen.brush());
  3344     d->ensureBrush(state()->pen.brush());
  3350     vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
  3345     vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
  3351                  NULL, NULL, VG_FILL_PATH, VG_TRUE);
  3346                  adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
  3352 #else
  3347 #else
  3353     // OpenGL 1.0 does not have support for VGFont and glyphs,
  3348     // OpenGL 1.0 does not have support for VGFont and glyphs,
  3354     // so fall back to the default Qt path stroking algorithm.
  3349     // so fall back to the default Qt path stroking algorithm.
  3355     QPaintEngineEx::drawTextItem(p, textItem);
  3350     QPaintEngineEx::drawTextItem(p, textItem);
  3356 #endif
  3351 #endif