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 (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"))))

View File

@ -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();
};

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(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);

View File

@ -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);

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_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;
}

View File

@ -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);