From 3ca107f1edf68ec4b80c02f20139bf464fa5292e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 6 Oct 2007 13:19:52 +0000 Subject: [PATCH] implement dc alpha for Windows svn: r7438 --- src/worksp/gc2/make.ss | 14 ++++++-- src/wxwindow/include/msw/wx_gdi.h | 6 ++-- src/wxwindow/include/msw/wx_graphics.h | 4 +-- src/wxwindow/src/msw/wx_dc.cxx | 50 +++++++++++++++++++------- src/wxwindow/src/msw/wx_gdi.cxx | 37 ++++++++++++++----- src/wxwindow/src/msw/wx_graph_glue.cxx | 16 +++++---- 6 files changed, 94 insertions(+), 33 deletions(-) diff --git a/src/worksp/gc2/make.ss b/src/worksp/gc2/make.ss index 7a335bc94b..83c79c09a8 100644 --- a/src/worksp/gc2/make.ss +++ b/src/worksp/gc2/make.ss @@ -62,6 +62,12 @@ (define common-cpp-defs " /D _CRT_SECURE_NO_DEPRECATE ") +(define (check-timestamp t2 dep) + (when (t2 . > . (current-seconds)) + (fprintf (current-error-port) + "WARNING: timestamp is in the future: ~e\n" + dep))) + (define (try src deps dest objdest includes use-precomp extra-compile-flags expand-extra-flags msvc-pch indirect?) (when (or (not re:only) (regexp-match re:only dest)) (unless (and (file-exists? dest) @@ -71,7 +77,9 @@ (let ([dep (cond [(bytes? dep) (bytes->path dep)] [else dep])]) - (> t (file-or-directory-modify-seconds dep)))) + (let ([t2 (file-or-directory-modify-seconds dep)]) + (check-timestamp t2 dep) + (> t t2)))) (append deps (if use-precomp (list use-precomp) null) (let ([deps (path-replace-suffix dest #".sdep")]) @@ -122,7 +130,9 @@ (and (>= t (file-or-directory-modify-seconds c)) (andmap (lambda (f) - (>= t (file-or-directory-modify-seconds f))) + (let ([t2 (file-or-directory-modify-seconds f)]) + (check-timestamp t2 f) + (>= t t2))) deps)))) (unless (system- (format "cl.exe ~a /MT /Zi ~a /c ~a /Fdxsrc/ /Fo~a" flags opt-flags c o)) (error "failed compile")))) diff --git a/src/wxwindow/include/msw/wx_gdi.h b/src/wxwindow/include/msw/wx_gdi.h index 121bb258d7..cb53330931 100644 --- a/src/wxwindow/include/msw/wx_gdi.h +++ b/src/wxwindow/include/msw/wx_gdi.h @@ -78,6 +78,7 @@ class wxPen: public wxbPen wxBitmap *old_stipple; COLORREF old_color; Pen *g_p, *a_g_p; + double g_alpha, a_g_alpha; Bool use_const; wxPen *const_pen; @@ -92,7 +93,7 @@ class wxPen: public wxbPen void ChangePen(); HPEN SelectPen(HDC dc, double scale = 1.0); - Pen *GraphicsPen(Bool align, double sx); + Pen *GraphicsPen(Bool align, double sx, double alpha); void ReleaseGraphics(); }; @@ -108,6 +109,7 @@ class wxBrush: public wxbBrush wxBitmap *old_stipple; COLORREF old_color; Brush *g_b; + double g_alpha; Bool use_const; wxBrush *const_brush; @@ -119,7 +121,7 @@ class wxBrush: public wxbBrush void ChangeBrush(); HBRUSH SelectBrush(HDC dc); - Brush *GraphicsBrush(); + Brush *GraphicsBrush(double alpha); void ReleaseGraphics(); }; diff --git a/src/wxwindow/include/msw/wx_graphics.h b/src/wxwindow/include/msw/wx_graphics.h index 9f88d74217..438fd8c48a 100644 --- a/src/wxwindow/include/msw/wx_graphics.h +++ b/src/wxwindow/include/msw/wx_graphics.h @@ -57,10 +57,10 @@ WX_GRAPHICS_EXPORT void WX_GPROC(wxGMatrixRelease)(Matrix *m); WX_GRAPHICS_EXPORT void WX_GPROC(wxGMatrixTranslate)(Matrix *m, double x, double y); WX_GRAPHICS_EXPORT void WX_GPROC(wxGMatrixScale)(Matrix *m, double x, double y); -WX_GRAPHICS_EXPORT Brush *WX_GPROC(wxGBrushNew)(COLORREF c); +WX_GRAPHICS_EXPORT Brush *WX_GPROC(wxGBrushNew)(COLORREF c, double alpha); WX_GRAPHICS_EXPORT void WX_GPROC(wxGBrushRelease)(Brush *b); -WX_GRAPHICS_EXPORT Pen *WX_GPROC(wxGPenNew)(COLORREF c, double pw, LineCap cap, LineJoin join, int ndash, REAL *dashes, REAL offset); +WX_GRAPHICS_EXPORT Pen *WX_GPROC(wxGPenNew)(COLORREF c, double alpha, double pw, LineCap cap, LineJoin join, int ndash, REAL *dashes, REAL offset); WX_GRAPHICS_EXPORT void WX_GPROC(wxGPenRelease)(Pen *b); WX_GRAPHICS_EXPORT Font *WX_GPROC(wxGFontNew)(HDC dc); diff --git a/src/wxwindow/src/msw/wx_dc.cxx b/src/wxwindow/src/msw/wx_dc.cxx index 841f62cd16..e8a354b028 100644 --- a/src/wxwindow/src/msw/wx_dc.cxx +++ b/src/wxwindow/src/msw/wx_dc.cxx @@ -720,7 +720,8 @@ void wxDC::DrawLine(double x1, double y1, double x2, double y2) xx2 = SmoothingXFormX(x2); yy2 = SmoothingXFormY(y2); - wxGDrawLine(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), xx1, yy1, xx2, yy2); + wxGDrawLine(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), + xx1, yy1, xx2, yy2); } DoneDC(dc); return; @@ -877,7 +878,7 @@ void wxDC::DrawArc(double x, double y, double w, double h, double start, double ww = SmoothingXFormW(w, x); hh = SmoothingXFormH(h, y); - wxGFillPie(g, current_brush->GraphicsBrush(), xx, yy, ww, hh, init, span); + wxGFillPie(g, current_brush->GraphicsBrush(current_alpha), xx, yy, ww, hh, init, span); } if (current_pen && (current_pen->GetStyle() != wxTRANSPARENT)) { @@ -888,7 +889,8 @@ void wxDC::DrawArc(double x, double y, double w, double h, double start, double ww = SmoothingXFormWL(w, x); hh = SmoothingXFormHL(h, y); - wxGDrawArc(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), xx, yy, ww, hh, init, span); + wxGDrawArc(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), + xx, yy, ww, hh, init, span); } DoneDC(dc); @@ -1058,12 +1060,13 @@ void wxDC::DrawPolygon(int n, wxPoint points[], double xoffset, double yoffset,i } if (current_brush && (current_brush->GetStyle() != wxTRANSPARENT)) { - wxGFillPolygon(g, current_brush->GraphicsBrush(), pts, n, + wxGFillPolygon(g, current_brush->GraphicsBrush(current_alpha), pts, n, (fillStyle == wxODDEVEN_RULE) ? FillModeAlternate : FillModeWinding); } if (current_pen && (current_pen->GetStyle() != wxTRANSPARENT)) { - wxGDrawPolygon(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), pts, n); + wxGDrawPolygon(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), + pts, n); } DoneDC(dc); @@ -1138,11 +1141,11 @@ void wxDC::DrawPath(wxPath *p, double xoffset, double yoffset,int fillStyle) } if (current_brush && (current_brush->GetStyle() != wxTRANSPARENT)) { - wxGFillPath(g, current_brush->GraphicsBrush(), gp); + wxGFillPath(g, current_brush->GraphicsBrush(current_alpha), gp); } if (current_pen && (current_pen->GetStyle() != wxTRANSPARENT)) { - wxGDrawPath(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), gp); + wxGDrawPath(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), gp); } wxGPathRelease(gp); @@ -1266,7 +1269,7 @@ void wxDC::DrawLines(int n, wxPoint points[], double xoffset, double yoffset) } - wxGDrawLines(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), pts, n); + wxGDrawLines(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), pts, n); } DoneDC(dc); @@ -1317,7 +1320,7 @@ void wxDC::DrawRectangle(double x, double y, double width, double height) ww = SmoothingXFormW(width, x); hh = SmoothingXFormH(height, y); - wxGFillRectangle(g, current_brush->GraphicsBrush(), xx, yy, ww, hh); + wxGFillRectangle(g, current_brush->GraphicsBrush(current_alpha), xx, yy, ww, hh); } if (current_pen && (current_pen->GetStyle() != wxTRANSPARENT)) { @@ -1328,7 +1331,7 @@ void wxDC::DrawRectangle(double x, double y, double width, double height) ww = SmoothingXFormWL(width, x); hh = SmoothingXFormHL(height, y); - wxGDrawRectangle(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), xx, yy, ww, hh); + wxGDrawRectangle(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), xx, yy, ww, hh); } DoneDC(dc); @@ -1412,7 +1415,7 @@ void wxDC::DrawRoundedRectangle(double x, double y, double width, double height, wxGPathAddLine(gp, xx + ww - rr, yy + hh, xx + rr, yy + hh); wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90); wxGPathCloseFigure(gp); - wxGFillPath(g, current_brush->GraphicsBrush(), gp); + wxGFillPath(g, current_brush->GraphicsBrush(current_alpha), gp); wxGPathRelease(gp); } @@ -1438,7 +1441,7 @@ void wxDC::DrawRoundedRectangle(double x, double y, double width, double height, wxGPathAddLine(gp, xx + ww - rr, yy + hh, xx + rr, yy + hh); wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90); wxGPathCloseFigure(gp); - wxGDrawPath(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x), gp); + wxGDrawPath(g, current_pen->GraphicsPen(AlignSmoothing(), user_scale_x, current_alpha), gp); wxGPathRelease(gp); } @@ -1871,6 +1874,25 @@ void wxDC::DrawText(const char *text, double x, double y, Bool combine, Bool ucs : OPAQUE)); SetRop(dc, wxSOLID); SetScaleMode(wxWINDOWS_SCALE, dc); + + if (current_alpha != 1.0) { + /* Approximate alpha blending... */ + UINT c; + int r, gr, b; + + if (current_text_foreground->Ok()) + c = current_text_foreground->pixel; + else + c = RGB(0, 0, 0); + + r = 255 - (int)((255 - GetRValue(c)) * current_alpha); + gr = 255 - (int)((255 - GetGValue(c)) * current_alpha); + b = 255 - (int)((255 - GetBValue(c)) * current_alpha); + + SetTextColor(dc, RGB(r, gr, b)); + + SetROP2(dc, R2_MASKPEN); + } w = 0; h = 0; @@ -1907,6 +1929,10 @@ void wxDC::DrawText(const char *text, double x, double y, Bool combine, Bool ucs SetDeviceOrigin(oox, ooy); + if (current_alpha != 1.0) { + SetROP2(dc, R2_COPYPEN); + } + if (current_text_background->Ok()) (void)SetBkColor(dc, old_background); diff --git a/src/wxwindow/src/msw/wx_gdi.cxx b/src/wxwindow/src/msw/wx_gdi.cxx index aa39f7c168..279ab948b4 100644 --- a/src/wxwindow/src/msw/wx_gdi.cxx +++ b/src/wxwindow/src/msw/wx_gdi.cxx @@ -787,10 +787,22 @@ static REAL gp_short_dashed[] = {4, 4, /* offset */ 2}; static REAL gp_long_dashed[] = {4, 8, /* offset */ 2}; static REAL gp_dotted_dashed[] = {6, 6, 2, 6, /* offset */ 4}; -Pen *wxPen::GraphicsPen(Bool align, double xs) +Pen *wxPen::GraphicsPen(Bool align, double xs, double alpha) { if (const_pen) - return const_pen->GraphicsPen(align, xs); + return const_pen->GraphicsPen(align, xs, alpha); + + if (!align) { + if (g_p && (g_alpha != alpha)) { + wxGPenRelease(g_p); + g_p = NULL; + } + } else { + if (a_g_p && (a_g_alpha != alpha)) { + wxGPenRelease(g_p); + a_g_p = NULL; + } + } if ((!align && !g_p) || (align && !a_g_p)) { @@ -798,6 +810,7 @@ Pen *wxPen::GraphicsPen(Bool align, double xs) double pw; REAL offset, *dashes; int ndash; + COLORREF px; switch (style) { case wxDOT: @@ -836,14 +849,17 @@ Pen *wxPen::GraphicsPen(Bool align, double xs) } else pw = width; - p = wxGPenNew(colour->pixel, pw, + p = wxGPenNew(colour->pixel, alpha, pw, graphics_caps[cap - wxCAP_ROUND], graphics_joins[join - wxJOIN_BEVEL], ndash, dashes, offset); - if (align) + if (align) { a_g_p = p; - else + a_g_alpha = alpha; + } else { g_p = p; + g_alpha = alpha; + } } return (align ? a_g_p : g_p); } @@ -1129,15 +1145,20 @@ wxBrush::wxBrush(wxColour *col, int Style, Bool _use_const) ChangeBrush(); } -Brush *wxBrush::GraphicsBrush() +Brush *wxBrush::GraphicsBrush(double alpha) { if (const_brush) - return const_brush->GraphicsBrush(); + return const_brush->GraphicsBrush(alpha); + + if (g_b && (g_alpha != alpha)) { + ReleaseGraphics(); + } if (!g_b) { Brush *b; - b = wxGBrushNew(colour->pixel); + b = wxGBrushNew(colour->pixel, alpha); g_b = b; + g_alpha = alpha; } return g_b; } diff --git a/src/wxwindow/src/msw/wx_graph_glue.cxx b/src/wxwindow/src/msw/wx_graph_glue.cxx index 93a4a40c36..840b428b62 100644 --- a/src/wxwindow/src/msw/wx_graph_glue.cxx +++ b/src/wxwindow/src/msw/wx_graph_glue.cxx @@ -19,9 +19,11 @@ typedef int GpMatrixOrder; #define UnitWorld 0 #define MatrixOrderPrepend 0 -static inline UINT32 COLORREF_ARGB(UINT c) +static inline UINT32 COLORREF_ARGB(UINT c, double alpha) { - return (0xFF000000 + UINT32 a = ((UINT32)(255 * alpha)) << 24; + + return (a | GetRValue(c) << 16 | GetGValue(c) << 8 | GetBValue(c)); @@ -137,7 +139,7 @@ void wxGDrawLines(Graphics *g, Pen *p, PointF *pts, int n) void wxGFillRectangleColor(Graphics *g, COLORREF c, double x, double y, double w, double h) { Brush *b; - ck(pGdipCreateSolidFill(COLORREF_ARGB(c), &b)); + ck(pGdipCreateSolidFill(COLORREF_ARGB(c, 1.0), &b)); ck(pGdipFillRectangle(g, b, (REAL)x, (REAL)y, (REAL)w, (REAL)h)); ck(pGdipDeleteBrush(b)); } @@ -253,10 +255,10 @@ void wxGMatrixScale(Matrix *m, double x, double y) pGdipScaleMatrix(m, (REAL)x, (REAL)y, MatrixOrderPrepend); } -Brush *wxGBrushNew(COLORREF c) +Brush *wxGBrushNew(COLORREF c, double alpha) { Brush *b; - pGdipCreateSolidFill(COLORREF_ARGB(c), &b); + pGdipCreateSolidFill(COLORREF_ARGB(c, alpha), &b); return b; } @@ -265,11 +267,11 @@ void wxGBrushRelease(Brush *b) pGdipDeleteBrush(b); } -Pen *wxGPenNew(COLORREF c, double pw, LineCap cap, LineJoin join, int ndash, REAL *dashes, REAL offset) +Pen *wxGPenNew(COLORREF c, double alpha, double pw, LineCap cap, LineJoin join, int ndash, REAL *dashes, REAL offset) { Pen *p; - pGdipCreatePen1(COLORREF_ARGB(c), pw, UnitWorld, &p); + pGdipCreatePen1(COLORREF_ARGB(c, alpha), pw, UnitWorld, &p); pGdipSetPenEndCap(p, cap); pGdipSetPenLineJoin(p, join);