Qt: use QConicalGradient to draw triangle gradient, not best solution, but better than using QLinearGradient. Do not invert pixels if 1st pixel isn't 0 or $FF.

git-svn-id: trunk@31495 -
This commit is contained in:
zeljko 2011-07-02 12:31:59 +00:00
parent a7c53b715e
commit dbd9fd02b7
2 changed files with 53 additions and 21 deletions

View File

@ -635,6 +635,7 @@ var
R: TRect; R: TRect;
Width, Height: Integer; Width, Height: Integer;
InvertPixels: Boolean; InvertPixels: Boolean;
Px: QRgb;
begin begin
Result := False; Result := False;
@ -694,12 +695,14 @@ begin
InvertPixels := False; InvertPixels := False;
if WorkImage <> nil then if WorkImage <> nil then
begin begin
Px := QImage_pixel(WorkImage.Handle, 0, 0);
InvertPixels := InvertPixels :=
not QImage_hasAlphaChannel(WorkMask.Handle) and not QImage_hasAlphaChannel(WorkMask.Handle) and
not QImage_hasAlphaChannel(WorkImage.Handle) and not QImage_hasAlphaChannel(WorkImage.Handle) and
// invert only if WorkImage is RGB32 fmt and allGray // invert only if WorkImage is RGB32 fmt and allGray
(WorkImage.getFormat = QImageFormat_RGB32) and (WorkImage.getFormat = QImageFormat_RGB32) and
QImage_allGray(WorkImage.Handle); QImage_allGray(WorkImage.Handle) and
((Px = 0) or (Px = $FF))
end; end;
if InvertPixels then if InvertPixels then
WorkMask.invertPixels(QImageInvertRGB); WorkMask.invertPixels(QImageInvertRGB);

View File

@ -3883,10 +3883,13 @@ function TQtWidgetSet.GradientFill(DC: HDC; Vertices: PTriVertex;
function FillTriMesh(Mesh: tagGradientTriangle) : Boolean; function FillTriMesh(Mesh: tagGradientTriangle) : Boolean;
var var
V1, V2, V3: tagTRIVERTEX; V1, V2, V3: tagTRIVERTEX;
C: TQColor; C1, C2, C3: TQColor;
Grad: QLinearGradientH; Grad: QConicalGradientH;
Brush: QBrushH; Brush: QBrushH;
Path: QPainterPathH; Triangle: QPolygonH;
R: TRect;
Painter: QPainterH;
Rgn: QRegionH;
begin begin
with Mesh do with Mesh do
begin begin
@ -3904,25 +3907,51 @@ function TQtWidgetSet.GradientFill(DC: HDC; Vertices: PTriVertex;
V2 := Vertices[Vertex2]; V2 := Vertices[Vertex2];
V3 := Vertices[Vertex3]; V3 := Vertices[Vertex3];
// todo: how to create a triangle gradient using QLinearGradient? Painter := TQtDeviceContext(DC).Widget;
//Grad := QConicalGradient_create(V2.x, V2.y, 0); QPainter_save(Painter);
Grad := QLinearGradient_create(V1.x, V1.y, V2.x, V2.y); Triangle := QPolygon_create(3);
C := VertexToColor(V1); QPolygon_setPoint(Triangle, 0, V1.X, V1.Y);
QGradient_setColorAt(Grad, 0, @C); QPolygon_setPoint(Triangle, 1, V2.X, V2.Y);
C := VertexToColor(V2); QPolygon_setPoint(Triangle, 2, V3.X, V3.Y);
QGradient_setColorAt(Grad, 0.5, @C); QPolygon_boundingRect(Triangle, @R);
C := VertexToColor(V3);
QGradient_setColorAt(Grad, 1, @C); Dec(R.Bottom);
Dec(R.Right);
Rgn := QRegion_create(@R);
// make our poly clip region , so gradient center is at real center
QPainter_setClipRegion(Painter, Rgn, QtIntersectClip);
Grad := QConicalGradient_create(R.Right div 2, R.Bottom div 2, 90);
C1 := VertexToColor(V1);
C2 := VertexToColor(V2);
C3 := VertexToColor(V3);
QGradient_setColorAt(Grad, 0.0, @C1); // open
QGradient_setColorAt(Grad, 0.33, @C2); // left corner
QGradient_setColorAt(Grad, 0.66, @C3); // right corner
QGradient_setColorAt(Grad, 1.0, @C1); // close
Brush := QBrush_create(Grad); Brush := QBrush_create(Grad);
Path := QPainterPath_create(); QPainter_setPen(Painter, QtNoPen);
QPainterPath_moveTo(Path, V1.x, V1.y); QPainter_setBrush(Painter, Brush);
QPainterPath_lineTo(Path, V2.x, V2.y);
QPainterPath_lineTo(Path, V3.x, V3.y); // move center point down, so we remove reflections of C2 and C3
QPainterPath_lineTo(Path, V1.X, V1.y); // TODO: C1 reflection is still visible
QPainter_fillPath(TQtDeviceContext(DC).Widget, Path, Brush); QPainter_setBrushOrigin(Painter, 0, R.Bottom div 5);
QGradient_destroy(Grad); QPainter_drawPolygon(Painter, Triangle);
//TODO: now me must make it look "softer" because reflection look of
// first color is ugly.
QBrush_destroy(Brush); QBrush_destroy(Brush);
QPainterPath_destroy(Path); QPolygon_destroy(Triangle);
QGradient_destroy(Grad);
QRegion_destroy(Rgn);
QPainter_restore(Painter);
end; end;
end; end;