implement dc alpha for Windows

svn: r7438
This commit is contained in:
Matthew Flatt 2007-10-06 13:19:52 +00:00
parent 5a22fa9a16
commit 3ca107f1ed
6 changed files with 94 additions and 33 deletions

View File

@ -62,6 +62,12 @@
(define common-cpp-defs " /D _CRT_SECURE_NO_DEPRECATE ") (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?) (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)) (when (or (not re:only) (regexp-match re:only dest))
(unless (and (file-exists? dest) (unless (and (file-exists? dest)
@ -71,7 +77,9 @@
(let ([dep (cond (let ([dep (cond
[(bytes? dep) (bytes->path dep)] [(bytes? dep) (bytes->path dep)]
[else 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 (append deps
(if use-precomp (list use-precomp) null) (if use-precomp (list use-precomp) null)
(let ([deps (path-replace-suffix dest #".sdep")]) (let ([deps (path-replace-suffix dest #".sdep")])
@ -122,7 +130,9 @@
(and (>= t (file-or-directory-modify-seconds c)) (and (>= t (file-or-directory-modify-seconds c))
(andmap (andmap
(lambda (f) (lambda (f)
(>= t (file-or-directory-modify-seconds f))) (let ([t2 (file-or-directory-modify-seconds f)])
(check-timestamp t2 f)
(>= t t2)))
deps)))) deps))))
(unless (system- (format "cl.exe ~a /MT /Zi ~a /c ~a /Fdxsrc/ /Fo~a" flags opt-flags c o)) (unless (system- (format "cl.exe ~a /MT /Zi ~a /c ~a /Fdxsrc/ /Fo~a" flags opt-flags c o))
(error "failed compile")))) (error "failed compile"))))

View File

@ -78,6 +78,7 @@ class wxPen: public wxbPen
wxBitmap *old_stipple; wxBitmap *old_stipple;
COLORREF old_color; COLORREF old_color;
Pen *g_p, *a_g_p; Pen *g_p, *a_g_p;
double g_alpha, a_g_alpha;
Bool use_const; Bool use_const;
wxPen *const_pen; wxPen *const_pen;
@ -92,7 +93,7 @@ class wxPen: public wxbPen
void ChangePen(); void ChangePen();
HPEN SelectPen(HDC dc, double scale = 1.0); HPEN SelectPen(HDC dc, double scale = 1.0);
Pen *GraphicsPen(Bool align, double sx); Pen *GraphicsPen(Bool align, double sx, double alpha);
void ReleaseGraphics(); void ReleaseGraphics();
}; };
@ -108,6 +109,7 @@ class wxBrush: public wxbBrush
wxBitmap *old_stipple; wxBitmap *old_stipple;
COLORREF old_color; COLORREF old_color;
Brush *g_b; Brush *g_b;
double g_alpha;
Bool use_const; Bool use_const;
wxBrush *const_brush; wxBrush *const_brush;
@ -119,7 +121,7 @@ class wxBrush: public wxbBrush
void ChangeBrush(); void ChangeBrush();
HBRUSH SelectBrush(HDC dc); HBRUSH SelectBrush(HDC dc);
Brush *GraphicsBrush(); Brush *GraphicsBrush(double alpha);
void ReleaseGraphics(); void ReleaseGraphics();
}; };

View File

@ -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(wxGMatrixTranslate)(Matrix *m, double x, double y);
WX_GRAPHICS_EXPORT void WX_GPROC(wxGMatrixScale)(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 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 void WX_GPROC(wxGPenRelease)(Pen *b);
WX_GRAPHICS_EXPORT Font *WX_GPROC(wxGFontNew)(HDC dc); WX_GRAPHICS_EXPORT Font *WX_GPROC(wxGFontNew)(HDC dc);

View File

@ -720,7 +720,8 @@ void wxDC::DrawLine(double x1, double y1, double x2, double y2)
xx2 = SmoothingXFormX(x2); xx2 = SmoothingXFormX(x2);
yy2 = SmoothingXFormY(y2); 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); DoneDC(dc);
return; return;
@ -877,7 +878,7 @@ void wxDC::DrawArc(double x, double y, double w, double h, double start, double
ww = SmoothingXFormW(w, x); ww = SmoothingXFormW(w, x);
hh = SmoothingXFormH(h, y); 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)) { 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); ww = SmoothingXFormWL(w, x);
hh = SmoothingXFormHL(h, y); 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); 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)) { 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); (fillStyle == wxODDEVEN_RULE) ? FillModeAlternate : FillModeWinding);
} }
if (current_pen && (current_pen->GetStyle() != wxTRANSPARENT)) { 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); DoneDC(dc);
@ -1138,11 +1141,11 @@ void wxDC::DrawPath(wxPath *p, double xoffset, double yoffset,int fillStyle)
} }
if (current_brush && (current_brush->GetStyle() != wxTRANSPARENT)) { 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)) { 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); 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); DoneDC(dc);
@ -1317,7 +1320,7 @@ void wxDC::DrawRectangle(double x, double y, double width, double height)
ww = SmoothingXFormW(width, x); ww = SmoothingXFormW(width, x);
hh = SmoothingXFormH(height, y); 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)) { 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); ww = SmoothingXFormWL(width, x);
hh = SmoothingXFormHL(height, y); 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); 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); wxGPathAddLine(gp, xx + ww - rr, yy + hh, xx + rr, yy + hh);
wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90); wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90);
wxGPathCloseFigure(gp); wxGPathCloseFigure(gp);
wxGFillPath(g, current_brush->GraphicsBrush(), gp); wxGFillPath(g, current_brush->GraphicsBrush(current_alpha), gp);
wxGPathRelease(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); wxGPathAddLine(gp, xx + ww - rr, yy + hh, xx + rr, yy + hh);
wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90); wxGPathAddArc(gp, xx, yy + hh - 2 * rr, 2 * rr, 2 * rr, 90, 90);
wxGPathCloseFigure(gp); 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); wxGPathRelease(gp);
} }
@ -1872,6 +1875,25 @@ void wxDC::DrawText(const char *text, double x, double y, Bool combine, Bool ucs
SetRop(dc, wxSOLID); SetRop(dc, wxSOLID);
SetScaleMode(wxWINDOWS_SCALE, dc); 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; w = 0;
h = 0; h = 0;
d = 0; d = 0;
@ -1907,6 +1929,10 @@ void wxDC::DrawText(const char *text, double x, double y, Bool combine, Bool ucs
SetDeviceOrigin(oox, ooy); SetDeviceOrigin(oox, ooy);
if (current_alpha != 1.0) {
SetROP2(dc, R2_COPYPEN);
}
if (current_text_background->Ok()) if (current_text_background->Ok())
(void)SetBkColor(dc, old_background); (void)SetBkColor(dc, old_background);

View File

@ -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_long_dashed[] = {4, 8, /* offset */ 2};
static REAL gp_dotted_dashed[] = {6, 6, 2, 6, /* offset */ 4}; 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) 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) if ((!align && !g_p)
|| (align && !a_g_p)) { || (align && !a_g_p)) {
@ -798,6 +810,7 @@ Pen *wxPen::GraphicsPen(Bool align, double xs)
double pw; double pw;
REAL offset, *dashes; REAL offset, *dashes;
int ndash; int ndash;
COLORREF px;
switch (style) { switch (style) {
case wxDOT: case wxDOT:
@ -836,14 +849,17 @@ Pen *wxPen::GraphicsPen(Bool align, double xs)
} else } else
pw = width; pw = width;
p = wxGPenNew(colour->pixel, pw, p = wxGPenNew(colour->pixel, alpha, pw,
graphics_caps[cap - wxCAP_ROUND], graphics_caps[cap - wxCAP_ROUND],
graphics_joins[join - wxJOIN_BEVEL], graphics_joins[join - wxJOIN_BEVEL],
ndash, dashes, offset); ndash, dashes, offset);
if (align) if (align) {
a_g_p = p; a_g_p = p;
else a_g_alpha = alpha;
} else {
g_p = p; g_p = p;
g_alpha = alpha;
}
} }
return (align ? a_g_p : g_p); return (align ? a_g_p : g_p);
} }
@ -1129,15 +1145,20 @@ wxBrush::wxBrush(wxColour *col, int Style, Bool _use_const)
ChangeBrush(); ChangeBrush();
} }
Brush *wxBrush::GraphicsBrush() Brush *wxBrush::GraphicsBrush(double alpha)
{ {
if (const_brush) if (const_brush)
return const_brush->GraphicsBrush(); return const_brush->GraphicsBrush(alpha);
if (g_b && (g_alpha != alpha)) {
ReleaseGraphics();
}
if (!g_b) { if (!g_b) {
Brush *b; Brush *b;
b = wxGBrushNew(colour->pixel); b = wxGBrushNew(colour->pixel, alpha);
g_b = b; g_b = b;
g_alpha = alpha;
} }
return g_b; return g_b;
} }

View File

@ -19,9 +19,11 @@ typedef int GpMatrixOrder;
#define UnitWorld 0 #define UnitWorld 0
#define MatrixOrderPrepend 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 | GetRValue(c) << 16
| GetGValue(c) << 8 | GetGValue(c) << 8
| GetBValue(c)); | 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) void wxGFillRectangleColor(Graphics *g, COLORREF c, double x, double y, double w, double h)
{ {
Brush *b; 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(pGdipFillRectangle(g, b, (REAL)x, (REAL)y, (REAL)w, (REAL)h));
ck(pGdipDeleteBrush(b)); ck(pGdipDeleteBrush(b));
} }
@ -253,10 +255,10 @@ void wxGMatrixScale(Matrix *m, double x, double y)
pGdipScaleMatrix(m, (REAL)x, (REAL)y, MatrixOrderPrepend); pGdipScaleMatrix(m, (REAL)x, (REAL)y, MatrixOrderPrepend);
} }
Brush *wxGBrushNew(COLORREF c) Brush *wxGBrushNew(COLORREF c, double alpha)
{ {
Brush *b; Brush *b;
pGdipCreateSolidFill(COLORREF_ARGB(c), &b); pGdipCreateSolidFill(COLORREF_ARGB(c, alpha), &b);
return b; return b;
} }
@ -265,11 +267,11 @@ void wxGBrushRelease(Brush *b)
pGdipDeleteBrush(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; Pen *p;
pGdipCreatePen1(COLORREF_ARGB(c), pw, UnitWorld, &p); pGdipCreatePen1(COLORREF_ARGB(c, alpha), pw, UnitWorld, &p);
pGdipSetPenEndCap(p, cap); pGdipSetPenEndCap(p, cap);
pGdipSetPenLineJoin(p, join); pGdipSetPenLineJoin(p, join);