QImage createShadowImage(const ShadowSettings &settings) { const int radius = settings.radius + 32; const int size = 2 * radius + 1; QImage shadowImage(size, size, QImage::Format_ARGB32_Premultiplied); shadowImage.fill(0); QRadialGradient gradient(radius + 0.5, radius + 0.5, radius + 0.5); for (qreal v = 0.0; v <= 1.0; v += 1.0 / 64) { qreal k; QColor color = settings.color; if (v * radius < radius - (32.0 + settings.size)) { k = 0.0; } else { qreal x = (radius - 32.0) / radius; k = (v - x) / (1.0 - x); k = pow(1.0 - k, settings.linearDecay) * exp(-settings.exponentialDecay * k); } color.setAlpha(qBound(0, qRound(color.alpha() * k), 255)); gradient.setColorAt(v, color); } QPainter p(&shadowImage); p.setCompositionMode(QPainter::CompositionMode_Source); p.setRenderHint(QPainter::Antialiasing, true); p.setBrush(gradient); p.setPen(Qt::NoPen); p.drawEllipse(0, 0, size, size); p.end(); return shadowImage; }
void CHuiShadowBorderBrush::Draw(CHuiGc& aGc, const MHuiBrushGuide& aGuide) const { TRect content = aGuide.BrushRect().Round(); TReal32 opacity = aGuide.BrushOpacity() * iOpacity.Now(); if(opacity <= 0) { return; } aGc.SetPenAlpha(TInt(opacity * 255)); aGc.SetPenColor(TRgb(0, 0, 30)); const CHuiTexture* shadowTexture = NULL; TInt err = aGuide.BrushSkin().GetTexture(EHuiSkinShadowTexture, shadowTexture); if (err!=KErrNone) { ASSERT(EFalse); // failed to get the shadow texture - unable to proceed! return; } ASSERT(shadowTexture); THuiImage shadowImage(*shadowTexture); aGc.Disable(CHuiGc::EFeatureDepthWrite); TReal32 widthInPixels = WidthInPixels(BrushGuide()); content.Grow(HUI_ROUND_FLOAT_TO_INT(widthInPixels), HUI_ROUND_FLOAT_TO_INT(widthInPixels)); // ID: EHJK-7G5AHB - shadow border leaves artifacts in the display while visual is moved. TReal32 offset = 0.0f; // NOTE: It was 1.f. // Note: DrawBorders does not (yet) support different widths for every border. aGc.DrawBorders(content, widthInPixels-offset, widthInPixels+offset, widthInPixels-offset, widthInPixels+offset, CHuiGc::EBorderImage, &shadowImage); aGc.Enable(CHuiGc::EFeatureDepthWrite); }
void CHuiRasterizedTextMesh::DrawLines(CHuiGc& aGc, const THuiRealPoint& aOffset, THuiAlignHorizontal aLineAlignment, TReal32 aShadowOpacity) const { TInt y = 0; // Draw the built lines using THuiImages. for(TInt i = 0; i < iLines.Count(); ++i) { const SRasterizedLine& line = iLines[i]; if(line.iTexture) { THuiImage textImage(*line.iTexture); THuiRealPoint linePos(0.f, TReal32(y)); THuiRealSize lineSize = line.iTexture->Size(); // Do a downward scaling for line texture from TV resolution to LCD resolution. if(iTextMeshScale != 1) { lineSize.iHeight = lineSize.iHeight/iTextMeshScale; lineSize.iWidth = lineSize.iWidth/iTextMeshScale; } // Choose the line-specific alignment. switch(aLineAlignment) { case EHuiAlignHRight: linePos.iX = Extents().iWidth - lineSize.iWidth; break; case EHuiAlignHCenter: linePos.iX = (Extents().iWidth - lineSize.iWidth) / 2; break; default: break; } // Is there a shadow? if ( RasterizedShadow() ) { const TInt requestedBlurredSize = HUI_ROUND_FLOAT_TO_INT( 2*iVisual->DropShadowHandler()->iRadius.Now() ); THuiTextureHandle shadow; TBool haveShadowTexture = line.iTexture->GetShadowTexture(shadow,requestedBlurredSize ); if ( haveShadowTexture ) { THuiImage shadowImage(shadow); const THuiRealRect shadowDrawingRect = iVisual->DropShadowHandler()->ShadowDrawingRealRect( linePos, lineSize, shadow.Size(), *iVisual ); const TRgb oldColor = aGc.PenColorAlpha(); aGc.SetPenColor(iVisual->DropShadowHandler()->Color()); aGc.SetPenAlpha(HUI_ROUND_FLOAT_TO_INT(aShadowOpacity * 255.0f)); const THuiQuality oldQuality = aGc.Quality(); aGc.SetQuality(EHuiQualityFast); aGc.DrawImage(shadowImage, shadowDrawingRect.iTl + aOffset, shadowDrawingRect.Size()); aGc.SetPenColorAlpha(oldColor); aGc.SetQuality(oldQuality); } } aGc.DrawImage(textImage, linePos + aOffset, lineSize); // Move one line downwards. y += TInt(lineSize.iHeight) + line.iGap; } // Move extra gap downwards. y += line.iGap; // Add line spacing. y += iLineSpacing; } }