src/hbcore/ovgeffects/hbvghsleffect.cpp
changeset 5 627c4a0fd0e7
parent 0 16d8024aca5e
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
    62 }
    62 }
    63 
    63 
    64 void HbVgHslEffect::setHue(qreal hue)
    64 void HbVgHslEffect::setHue(qreal hue)
    65 {
    65 {
    66     Q_D(HbVgHslEffect);
    66     Q_D(HbVgHslEffect);
    67     if (d->hue == hue)
    67     if (d->hue == hue) {
    68         return;
    68         return;
       
    69     }
    69     d->hue = hue;
    70     d->hue = hue;
    70     updateEffect();
    71     updateEffect();
    71     emit hueChanged(hue);
    72     emit hueChanged(hue);
    72 }
    73 }
    73 
    74 
    78 }
    79 }
    79 
    80 
    80 void HbVgHslEffect::setSaturation(qreal saturation)
    81 void HbVgHslEffect::setSaturation(qreal saturation)
    81 {
    82 {
    82     Q_D(HbVgHslEffect);
    83     Q_D(HbVgHslEffect);
    83     if (d->saturation == saturation)
    84     if (d->saturation == saturation) {
    84         return;
    85         return;
       
    86     }
    85     d->saturation = saturation;
    87     d->saturation = saturation;
    86     updateEffect();
    88     updateEffect();
    87     emit saturationChanged(saturation);
    89     emit saturationChanged(saturation);
    88 }
    90 }
    89 
    91 
    94 }
    96 }
    95 
    97 
    96 void HbVgHslEffect::setLightness(qreal lightness)
    98 void HbVgHslEffect::setLightness(qreal lightness)
    97 {
    99 {
    98     Q_D(HbVgHslEffect);
   100     Q_D(HbVgHslEffect);
    99     if (d->lightness == lightness)
   101     if (d->lightness == lightness) {
   100         return;
   102         return;
       
   103     }
   101     d->lightness = lightness;
   104     d->lightness = lightness;
   102     updateEffect();
   105     updateEffect();
   103     emit lightnessChanged(lightness);
   106     emit lightnessChanged(lightness);
   104 }
   107 }
   105 
   108 
   116 }
   119 }
   117 
   120 
   118 #ifdef HB_EFFECTS_OPENVG
   121 #ifdef HB_EFFECTS_OPENVG
   119 
   122 
   120 inline void getSaturationRotationMatrix(VGfloat *effectMatrix, VGfloat opacity,
   123 inline void getSaturationRotationMatrix(VGfloat *effectMatrix, VGfloat opacity,
   121                                         VGfloat saturation, VGfloat angle) 
   124                                         VGfloat saturation, VGfloat angle)
   122 {
   125 {
   123     const VGfloat sa = saturation;            
   126     const VGfloat sa = saturation;
   124     const VGfloat as = 1.0f - saturation;
   127     const VGfloat as = 1.0f - saturation;
   125     
   128 
   126     const VGfloat o = opacity;
   129     const VGfloat o = opacity;
   127     const VGfloat ao = 1.0f - o;
   130     const VGfloat ao = 1.0f - o;
   128     
   131 
   129     const VGfloat c = qCos(angle);
   132     const VGfloat c = qCos(angle);
   130     const VGfloat s = qSin(angle);
   133     const VGfloat s = qSin(angle);
   131     
   134 
   132     effectMatrix[0] = o * ((-0.02473f*as+0.66667f*sa)*c+ (0.30450f*as*s+(0.33333f*as+0.33333f*sa))) + ao;
   135     effectMatrix[0] = o * ((-0.02473f * as + 0.66667f * sa) * c + (0.30450f * as * s + (0.33333f * as + 0.33333f * sa))) + ao;
   133     effectMatrix[1] = o * ((-0.02473f*as-0.33333f*sa)*c+((0.30450f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   136     effectMatrix[1] = o * ((-0.02473f * as - 0.33333f * sa) * c + ((0.30450f * as + 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   134     effectMatrix[2] = o * ((-0.02473f*as-0.33333f*sa)*c+((0.30450f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   137     effectMatrix[2] = o * ((-0.02473f * as - 0.33333f * sa) * c + ((0.30450f * as - 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   135     effectMatrix[3] = 0.0f;
   138     effectMatrix[3] = 0.0f;
   136     effectMatrix[4] = o * ((0.27607f*as-0.33333f*sa)*c+((-0.13083f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   139     effectMatrix[4] = o * ((0.27607f * as - 0.33333f * sa) * c + ((-0.13083f * as - 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   137     effectMatrix[5] = o * ((0.27607f*as+0.66667f*sa)*c+ (-0.13083f*as*s+(0.33333f*as+0.33333f*sa))) + ao;
   140     effectMatrix[5] = o * ((0.27607f * as + 0.66667f * sa) * c + (-0.13083f * as * s + (0.33333f * as + 0.33333f * sa))) + ao;
   138     effectMatrix[6] = o * ((0.27607f*as-0.33333f*sa)*c+((-0.13083f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   141     effectMatrix[6] = o * ((0.27607f * as - 0.33333f * sa) * c + ((-0.13083f * as + 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   139     effectMatrix[7] = 0.0f;
   142     effectMatrix[7] = 0.0f;
   140     effectMatrix[8] = o * ((-0.25134f*as-0.33333f*sa)*c+((-0.17367f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   143     effectMatrix[8] = o * ((-0.25134f * as - 0.33333f * sa) * c + ((-0.17367f * as + 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   141     effectMatrix[9] = o * ((-0.25134f*as-0.33333f*sa)*c+((-0.17367f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa)));
   144     effectMatrix[9] = o * ((-0.25134f * as - 0.33333f * sa) * c + ((-0.17367f * as - 0.57736f * sa) * s + (0.33333f * as + 0.33333f * sa)));
   142     effectMatrix[10] = o * ((-0.25134f*as+0.66667f*sa)*c+ (-0.17367f*as*s+(0.33333f*as+0.33333f*sa))) + ao;
   145     effectMatrix[10] = o * ((-0.25134f * as + 0.66667f * sa) * c + (-0.17367f * as * s + (0.33333f * as + 0.33333f * sa))) + ao;
   143     effectMatrix[11] = 0.0f;
   146     effectMatrix[11] = 0.0f;
   144     effectMatrix[12] = 0.0f;
   147     effectMatrix[12] = 0.0f;
   145     effectMatrix[13] = 0.0f;
   148     effectMatrix[13] = 0.0f;
   146     effectMatrix[14] = 0.0f;
   149     effectMatrix[14] = 0.0f;
   147     effectMatrix[15] = 1.0f;
   150     effectMatrix[15] = 1.0f;
   151 const VGfloat Gw = 0.6094f;
   154 const VGfloat Gw = 0.6094f;
   152 const VGfloat Bw = 0.0820f;
   155 const VGfloat Bw = 0.0820f;
   153 
   156 
   154 inline void getSaturationMatrix(VGfloat *effectMatrix, VGfloat opacity, VGfloat saturation)
   157 inline void getSaturationMatrix(VGfloat *effectMatrix, VGfloat opacity, VGfloat saturation)
   155 {
   158 {
   156     const VGfloat sa = saturation;            
   159     const VGfloat sa = saturation;
   157     const VGfloat as = 1.0f - saturation;
   160     const VGfloat as = 1.0f - saturation;
   158     
   161 
   159     const VGfloat o = opacity;
   162     const VGfloat o = opacity;
   160     const VGfloat ao = 1.0f - o;
   163     const VGfloat ao = 1.0f - o;
   161 
   164 
   162     const VGfloat asRw = o * as * Rw;
   165     const VGfloat asRw = o * as * Rw;
   163     const VGfloat asGw = o * as * Gw;
   166     const VGfloat asGw = o * as * Gw;
   164     const VGfloat asBw = o * as * Bw;
   167     const VGfloat asBw = o * as * Bw;
   165     
   168 
   166     effectMatrix[0] = asRw + sa + ao;
   169     effectMatrix[0] = asRw + sa + ao;
   167     effectMatrix[1] = asRw;
   170     effectMatrix[1] = asRw;
   168     effectMatrix[2] = asRw;
   171     effectMatrix[2] = asRw;
   169     effectMatrix[3] = 0.0f;
   172     effectMatrix[3] = 0.0f;
   170     effectMatrix[4] = asGw;
   173     effectMatrix[4] = asGw;
   183 
   186 
   184 inline void getRotationMatrix(VGfloat *effectMatrix, VGfloat opacity, VGfloat angle)
   187 inline void getRotationMatrix(VGfloat *effectMatrix, VGfloat opacity, VGfloat angle)
   185 {
   188 {
   186     const VGfloat o = opacity;
   189     const VGfloat o = opacity;
   187     const VGfloat ao = 1.0f - o;
   190     const VGfloat ao = 1.0f - o;
   188     
   191 
   189     const VGfloat c = qCos(angle);
   192     const VGfloat c = qCos(angle);
   190     const VGfloat s = qSin(angle);
   193     const VGfloat s = qSin(angle);
   191     
   194 
   192     effectMatrix[0] = o * ( 0.66667f*c+0.33333f) + ao;
   195     effectMatrix[0] = o * (0.66667f * c + 0.33333f) + ao;
   193     effectMatrix[1] = o * (-0.33333f*c+(0.57736f*s+0.33333f));
   196     effectMatrix[1] = o * (-0.33333f * c + (0.57736f * s + 0.33333f));
   194     effectMatrix[2] = o * (-0.33333f*c+(-0.57736f*s+0.33333f));
   197     effectMatrix[2] = o * (-0.33333f * c + (-0.57736f * s + 0.33333f));
   195     effectMatrix[3] =  0.0f;
   198     effectMatrix[3] =  0.0f;
   196     effectMatrix[4] = o * (-0.33333f*c+(-0.57736f*s+0.33333f));
   199     effectMatrix[4] = o * (-0.33333f * c + (-0.57736f * s + 0.33333f));
   197     effectMatrix[5] = o * ( 0.66667f*c+0.33333f) + ao;
   200     effectMatrix[5] = o * (0.66667f * c + 0.33333f) + ao;
   198     effectMatrix[6] = o * (-0.33333f*c+(0.57736f*s+0.33333f));
   201     effectMatrix[6] = o * (-0.33333f * c + (0.57736f * s + 0.33333f));
   199     effectMatrix[7] =  0.0f;
   202     effectMatrix[7] =  0.0f;
   200     effectMatrix[8] = o * (-0.33333f*c+(0.57736f*s+0.33333f));
   203     effectMatrix[8] = o * (-0.33333f * c + (0.57736f * s + 0.33333f));
   201     effectMatrix[9] = o * (-0.33333f*c+(-0.57736f*s+0.33333f));
   204     effectMatrix[9] = o * (-0.33333f * c + (-0.57736f * s + 0.33333f));
   202     effectMatrix[10] = o * (0.66667f*c+0.33333f) + ao;
   205     effectMatrix[10] = o * (0.66667f * c + 0.33333f) + ao;
   203     effectMatrix[11] = 0.0f;
   206     effectMatrix[11] = 0.0f;
   204     effectMatrix[12] = 0.0f;
   207     effectMatrix[12] = 0.0f;
   205     effectMatrix[13] = 0.0f;
   208     effectMatrix[13] = 0.0f;
   206     effectMatrix[14] = 0.0f;
   209     effectMatrix[14] = 0.0f;
   207     effectMatrix[15] = 1.0f;
   210     effectMatrix[15] = 1.0f;
   228 }
   231 }
   229 
   232 
   230 #endif // HB_EFFECTS_OPENVG
   233 #endif // HB_EFFECTS_OPENVG
   231 
   234 
   232 void HbVgHslEffect::performEffect(QPainter *painter,
   235 void HbVgHslEffect::performEffect(QPainter *painter,
   233                                    const QPointF &offset,
   236                                   const QPointF &offset,
   234                                    const QVariant &vgImage,
   237                                   const QVariant &vgImage,
   235                                    const QSize &vgImageSize)
   238                                   const QSize &vgImageSize)
   236 {
   239 {
   237 #ifdef HB_EFFECTS_OPENVG
   240 #ifdef HB_EFFECTS_OPENVG
   238     QPixmap cachedPm = cached(vgImageSize);
   241     QPixmap cachedPm = cached(vgImageSize);
   239     if (!cachedPm.isNull()) {
   242     if (!cachedPm.isNull()) {
   240         painter->drawPixmap(offset, cachedPm);
   243         painter->drawPixmap(offset, cachedPm);
   248     if (opacity > HBVG_EPSILON) {
   251     if (opacity > HBVG_EPSILON) {
   249         if (d->paramsChanged) {
   252         if (d->paramsChanged) {
   250             // a helpful constant
   253             // a helpful constant
   251             const qreal radsPerDeg = 2.0f * (qreal) M_PI / 360.0f;
   254             const qreal radsPerDeg = 2.0f * (qreal) M_PI / 360.0f;
   252 
   255 
   253             // make sure parametres are in range
   256             // make sure parameters are in range
   254             const VGfloat o = (VGfloat) opacity;
   257             const VGfloat o = (VGfloat) opacity;
   255             const VGfloat angle = (VGfloat) clamp(d->hue * radsPerDeg, 0.0f, 2.0f * (qreal) M_PI); // angle [0, 2*pi]
   258             const VGfloat angle = (VGfloat) clamp(d->hue * radsPerDeg, 0.0f, 2.0f * (qreal) M_PI); // angle [0, 2*pi]
   256             const VGfloat saturation = (VGfloat) clamp(d->saturation, 0.0f, 100.0f); // saturation [0, N]
   259             const VGfloat saturation = (VGfloat) clamp(d->saturation, 0.0f, 100.0f); // saturation [0, N]
   257             const VGfloat lightness = (VGfloat) clamp(d->lightness, -1.0f, 1.0f); // lightness [-1, 1]
   260             const VGfloat lightness = (VGfloat) clamp(d->lightness, -1.0f, 1.0f); // lightness [-1, 1]
   258     
   261 
   259             // check parametres which precalculated matrix we have to use.
   262             // check parameters which precalculated matrix we have to use.
   260             // Note: lightness affects offset and not matrix so we don't bother optimising that.
   263             // Note: lightness affects offset and not matrix so we don't bother optimising that.
   261             const bool enableSaturation  = (saturation < 1.0f - HBVG_EPSILON || saturation > 1.0f + HBVG_EPSILON);
   264             const bool enableSaturation  = (saturation < 1.0f - HBVG_EPSILON || saturation > 1.0f + HBVG_EPSILON);
   262             const bool enableHueRotation = (HBVG_EPSILON < angle && angle < (2.0f * (qreal) M_PI - HBVG_EPSILON));
   265             const bool enableHueRotation = (HBVG_EPSILON < angle && angle < (2.0f * (qreal) M_PI - HBVG_EPSILON));
   263 
   266 
   264             if (enableSaturation && enableHueRotation) {
   267             if (enableSaturation && enableHueRotation) {
   265                 // contains SaturateT*PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices
   268                 // contains SaturateT*PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices
   266                 // --- ugly, but saves lot of operations in FPU.
   269                 // --- ugly, but saves lot of operations in FPU.
   267                 // note: there are plenty of redundancy in these calculations
   270                 // note: there are plenty of redundancy in these calculations
   268                 // --- let compiler optimise them.
   271                 // --- let compiler optimize them.
   269                 getSaturationRotationMatrix(&d->colorMatrix[0], o, saturation, angle);
   272                 getSaturationRotationMatrix(&d->colorMatrix[0], o, saturation, angle);
   270             } else if (enableSaturation && !enableHueRotation) {
   273             } else if (enableSaturation && !enableHueRotation) {
   271                 // saturationT*I*opacity+I*(1 - opacity) matrix without hue rotation
   274                 // saturationT*I*opacity+I*(1 - opacity) matrix without hue rotation
   272                 getSaturationMatrix(&d->colorMatrix[0], o, saturation);
   275                 getSaturationMatrix(&d->colorMatrix[0], o, saturation);
   273             } else if(!enableSaturation && enableHueRotation) {
   276             } else if (!enableSaturation && enableHueRotation) {
   274                 // PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices without saturation matrix
   277                 // PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices without saturation matrix
   275                 getRotationMatrix(&d->colorMatrix[0], o, angle);
   278                 getRotationMatrix(&d->colorMatrix[0], o, angle);
   276             } else {
   279             } else {
   277                 // identity matrix
   280                 // identity matrix
   278                 getIdentityMatrix(&d->colorMatrix[0]);
   281                 getIdentityMatrix(&d->colorMatrix[0]);