diff --git a/src/include/bitmap.h b/src/include/bitmap.h index f30f6e6d..78cd6d24 100644 --- a/src/include/bitmap.h +++ b/src/include/bitmap.h @@ -70,7 +70,6 @@ struct _SCALER_INFO_FILLBMP typedef struct { struct _SCALER_INFO_FILLBMP scaler_info; GAL_Rect dst_rect; - int old_bkmode; BYTE* decoded_buff; BYTE* decoded_alpha_buff; diff --git a/src/include/dc.h b/src/include/dc.h index 633213ea..52279879 100644 --- a/src/include/dc.h +++ b/src/include/dc.h @@ -167,6 +167,8 @@ struct tagDC /* surface of this DC */ GAL_Surface* surface; + char __first_attr[0]; // just a zero-length field for the first attribute + /* background color */ gal_pixel bkcolor; @@ -179,7 +181,7 @@ struct tagDC /* text color */ gal_pixel textcolor; - int bkmode; + int bkmode_set; /* the background mode set by user (5.0.12, Issue #107) */ int tabstop; int cExtra; /* Character extra */ @@ -213,6 +215,8 @@ struct tagDC size_t dash_list_len; #endif + char __last_attr[0]; // just a zero-length field for the last attribute + PLOGFONT pLogFont; POINT CurPenPos; @@ -247,6 +251,7 @@ struct tagDC gal_pixel skip_pixel; gal_pixel cur_pixel; int step; + int bkmode; /* the effective background mode */ /* ====================================================================== */ CLIPRECT* cur_ban; diff --git a/src/newgdi/attr.c b/src/newgdi/attr.c index 9fabfd44..22f38aff 100644 --- a/src/newgdi/attr.c +++ b/src/newgdi/attr.c @@ -120,7 +120,7 @@ static int make_alpha_pixel_format (PDC pdc) static void make_gray_pixels (PDC pdc) { - if (pdc->bkmode == BM_TRANSPARENT + if (pdc->bkmode_set == BM_TRANSPARENT && !make_alpha_pixel_format (pdc)) { int i; Uint8 r, g, b, a; diff --git a/src/newgdi/bitmap.c b/src/newgdi/bitmap.c index d174efe1..b87e3d90 100644 --- a/src/newgdi/bitmap.c +++ b/src/newgdi/bitmap.c @@ -467,20 +467,17 @@ PDC __mg_begin_fill_bitmap (HDC hdc, int x, int y, int w, int h, info->line_alpha_buff = NULL; } + if(__mg_enter_drawing (pdc) < 0) { + goto fail; + } + pdc->step = 1; pdc->cur_ban = NULL; pdc->cur_pixel = pdc->brushcolor; pdc->skip_pixel = bmp->bmColorKey; - fill_info->old_bkmode = pdc->bkmode; if (bmp->bmType & BMP_TYPE_COLORKEY) { pdc->bkmode = BM_TRANSPARENT; } - else - pdc->bkmode = BM_OPAQUE; - - if(__mg_enter_drawing (pdc) < 0) { - goto fail; - } fill_info->dst_rect = rect; @@ -501,8 +498,6 @@ fail: void __mg_end_fill_bitmap (PDC pdc, const BITMAP* bmp, FILLINFO *fill_info) { - pdc->bkmode = fill_info->old_bkmode; - __mg_leave_drawing (pdc); if (fill_info->decoded_buff) @@ -968,7 +963,6 @@ BOOL GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h, { PDC pdc; GAL_Rect rect; - int old_bkmode; struct _SCALER_INFO_FILLBMPPART info; if (bmp->bmWidth == 0 || bmp->bmHeight == 0 || bmp->bmBits == NULL) @@ -1021,17 +1015,16 @@ BOOL GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h, info.line_alpha_buff = NULL; } + ENTER_DRAWING (pdc); + pdc->step = 1; pdc->cur_ban = NULL; pdc->cur_pixel = pdc->brushcolor; - pdc->skip_pixel = bmp->bmColorKey; - old_bkmode = pdc->bkmode; if (bmp->bmType & BMP_TYPE_COLORKEY) { pdc->bkmode = BM_TRANSPARENT; + pdc->skip_pixel = bmp->bmColorKey; } - ENTER_DRAWING (pdc); - if (bw != bmp->bmWidth || bh != bmp->bmHeight) { pdc->bitmap_scaler(&info, bmp, bw, bh, @@ -1051,8 +1044,6 @@ BOOL GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h, _dc_fillbox_bmp_clip (pdc, &rect, &part); } - pdc->bkmode = old_bkmode; - LEAVE_DRAWING (pdc); if (info.line_buff) diff --git a/src/newgdi/drawtext.c b/src/newgdi/drawtext.c index 25712680..83becfe9 100644 --- a/src/newgdi/drawtext.c +++ b/src/newgdi/drawtext.c @@ -117,7 +117,6 @@ static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, DRAWTEXTEX2_CTXT* ctxt = (DRAWTEXTEX2_CTXT*)context; int adv_x = 0, adv_y = 0; BBOX bbox; - int bkmode; switch (char_type & ACHARTYPE_BASIC_MASK) { case ACHAR_BASIC_ZEROWIDTH: @@ -145,12 +144,11 @@ static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { - bkmode = ctxt->pdc->bkmode; - //ctxt->pdc->bkmode = BM_TRANSPARENT; + // int bkmode = ctxt->pdc->bkmode; _gdi_draw_one_glyph (ctxt->pdc, glyph_value, (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, ctxt->x, ctxt->y, &adv_x, &adv_y); - ctxt->pdc->bkmode = bkmode; + // ctxt->pdc->bkmode = bkmode; adv_x = adv_y = 0; } break; diff --git a/src/newgdi/gdi.c b/src/newgdi/gdi.c index 684e2500..a0d843b1 100644 --- a/src/newgdi/gdi.c +++ b/src/newgdi/gdi.c @@ -691,6 +691,11 @@ int __mg_enter_drawing (PDC pdc) if (!dc_IsMemDC (pdc)) kernel_ShowCursorForGDI (FALSE, pdc); + /* Since 5.0.12, to fix issue #107. + Always use the background mode set by user as the initial value of + the effective background mode, then override pdc->bkmode + after entering drawing if need. */ + pdc->bkmode = pdc->bkmode_set; return 0; fail: @@ -1913,7 +1918,7 @@ static void dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient) memset (pdc->filter_pixels, 0, sizeof (pdc->filter_pixels)); pdc->bkcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF); - pdc->bkmode = 0; + pdc->bkmode_set = 0; /* Since 5.0.12 */ pdc->pencolor = GAL_MapRGB (pdc->surface->format, 0x00, 0x00, 0x00); pdc->brushcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF); @@ -2067,12 +2072,18 @@ static void dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient) * and copies the DC attributes from the refrence DC. */ static void dc_InitMemDCFrom (PDC pdc, const PDC pdc_ref) { + unsigned nr_bytes = pdc->__last_attr - pdc->__first_attr; + memset (pdc->gray_pixels, 0, sizeof (pdc->gray_pixels)); memset (pdc->filter_pixels, 0, sizeof (pdc->filter_pixels)); +#if 1 + memcpy (pdc->__first_attr, pdc_ref->__first_attr, nr_bytes); +#else /* copy attributes from reference DC * gal_pixel bkcolor, pencolor, brushcolor, textcolor; - * int bkmode, tabstop, cExtra, wExtra, alExtra, blExtra, mapmode, ta_flags, bidi_flags; + * int bkmode, bkmode_set, tabstop, cExtra, wExtra, alExtra, blExtra, + * mapmode, ta_flags, bidi_flags; */ memcpy (&pdc->bkcolor, &pdc_ref->bkcolor, sizeof (gal_pixel)*4 + sizeof (int)*9); @@ -2080,6 +2091,8 @@ static void dc_InitMemDCFrom (PDC pdc, const PDC pdc_ref) memcpy (&pdc->pen_type, &pdc_ref->pen_type, (sizeof(int)*7) + sizeof(POINT) + (sizeof (void*)*3)); #endif +#endif + pdc->pLogFont = pdc_ref->pLogFont; /* reset view point info. */ @@ -2127,7 +2140,7 @@ static void dc_InitScreenDC (PDC pdc, GAL_Surface *surface) pdc->surface = surface; pdc->bkcolor = PIXEL_lightwhite; - pdc->bkmode = 0; + pdc->bkmode_set = 0; pdc->brushcolor = PIXEL_lightwhite; @@ -3784,7 +3797,8 @@ HWND GUIAPI WindowFromDC (HDC hdc) typedef struct _DCSTATE { GAL_Color bkcolor, pencolor, brushcolor, textcolor; - /* bkmode, tabstop, cExtra, wExtra, alExtra, blExtra, mapmode, ta_flags, bidi_flags */ + /* bkmode_set, tabstop, cExtra, wExtra, alExtra, blExtra, + mapmode, ta_flags, bidi_flags */ char attrs_g1 [sizeof(int)*9]; #ifdef _MGHAVE_ADV_2DAPI @@ -3872,7 +3886,7 @@ int GUIAPI SaveDC (HDC hdc) &dc_state->textcolor.r, &dc_state->textcolor.g, &dc_state->textcolor.b, &dc_state->textcolor.a); - memcpy (dc_state->attrs_g1, &pdc->bkmode, sizeof (dc_state->attrs_g1)); + memcpy (dc_state->attrs_g1, &pdc->bkmode_set, sizeof (dc_state->attrs_g1)); #ifdef _MGHAVE_ADV_2DAPI memcpy (dc_state->attrs_adv, &pdc->pen_type, sizeof (dc_state->attrs_adv)); #endif @@ -3976,7 +3990,7 @@ BOOL GUIAPI RestoreDC (HDC hdc, int saved_dc) dc_state->textcolor.r, dc_state->textcolor.g, dc_state->textcolor.b, dc_state->textcolor.a); - memcpy (&pdc->bkmode, dc_state->attrs_g1, sizeof (dc_state->attrs_g1)); + memcpy (&pdc->bkmode_set, dc_state->attrs_g1, sizeof (dc_state->attrs_g1)); #ifdef _MGHAVE_ADV_2DAPI memcpy (&pdc->pen_type, dc_state->attrs_adv, sizeof (dc_state->attrs_adv)); #endif diff --git a/src/newgdi/readbmp.c b/src/newgdi/readbmp.c index 6abc619f..bf250402 100644 --- a/src/newgdi/readbmp.c +++ b/src/newgdi/readbmp.c @@ -1185,7 +1185,7 @@ static void cb_direct_paint_mybmp_sl (void* context, int stepx, int GUIAPI FillBoxWithMyBitmap (HDC hdc, int x, int y, MYBITMAP* mybmp, RGB* pal) { - int i = 0,right,bottom,w,h,oldbkmode,stepy,stepx; + int i = 0,right,bottom,w,h,stepy,stepx; RECT rc_tmp; GAL_Rect dst_rect; PCLIPRECT cliprect; @@ -1314,20 +1314,17 @@ int GUIAPI FillBoxWithMyBitmap (HDC hdc, int x, int y, MYBITMAP* mybmp, RGB* pal w = RECTW (pdc->rc_output); h = RECTH (pdc->rc_output); dst_rect.x = x; dst_rect.y = y; dst_rect.w = w; dst_rect.h = h; - pdc->step = 1; - pdc->cur_ban = NULL; - pdc->cur_pixel = pdc->brushcolor; - pdc->skip_pixel = colorKey; - //fill_info->old_bkmode = pdc->bkmode; - oldbkmode =pdc->bkmode; - if (mybmp->flags & MYBMP_TRANSPARENT) { - pdc->bkmode = BM_TRANSPARENT; - } - if(__mg_enter_drawing (pdc) < 0) { goto fail; } - //bits = mybmp->bits; + + pdc->step = 1; + pdc->cur_ban = NULL; + pdc->cur_pixel = pdc->brushcolor; + if (mybmp->flags & MYBMP_TRANSPARENT) { + pdc->bkmode = BM_TRANSPARENT; + pdc->skip_pixel = colorKey; + } info.hdc = hdc; info.pdc = pdc; @@ -1350,7 +1347,6 @@ int GUIAPI FillBoxWithMyBitmap (HDC hdc, int x, int y, MYBITMAP* mybmp, RGB* pal cliprect = cliprect->next; } - pdc->bkmode =oldbkmode; __mg_leave_drawing (pdc); pdc->rc_output = rc_tmp; UNLOCK_GCRINFO (pdc); diff --git a/src/newgdi/tabbedtextout.c b/src/newgdi/tabbedtextout.c index e8528e6d..90779216 100644 --- a/src/newgdi/tabbedtextout.c +++ b/src/newgdi/tabbedtextout.c @@ -133,7 +133,6 @@ static BOOL cb_tabbedtextout (void* context, Glyph32 glyph_value, TABBEDTEXTOUT_CTXT* ctxt = (TABBEDTEXTOUT_CTXT*)context; int adv_x, adv_y; BBOX bbox; - int bkmode = ctxt->pdc->bkmode; switch (char_type & ACHARTYPE_BASIC_MASK) { case ACHAR_BASIC_ZEROWIDTH: @@ -158,7 +157,8 @@ static BOOL cb_tabbedtextout (void* context, Glyph32 glyph_value, case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { - //ctxt->pdc->bkmode = BM_TRANSPARENT; + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = BM_TRANSPARENT; _gdi_draw_one_glyph (ctxt->pdc, glyph_value, (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, ctxt->x, ctxt->y, &adv_x, &adv_y); diff --git a/src/newgdi/textout.c b/src/newgdi/textout.c index 4f530902..76066d57 100644 --- a/src/newgdi/textout.c +++ b/src/newgdi/textout.c @@ -122,14 +122,13 @@ static BOOL cb_draw_glyph (void* context, Glyph32 glyph_value, unsigned int char { DRAW_GLYPHS_CTXT* ctxt = (DRAW_GLYPHS_CTXT*)context; int adv_x, adv_y; - int bkmode; if (check_zero_width(char_type)) { adv_x = adv_y = 0; } else if (check_vowel(char_type)) { - bkmode = GetBkMode (ctxt->hdc); - //SetBkMode (ctxt->hdc, BM_TRANSPARENT); + int bkmode = GetBkMode (ctxt->hdc); + SetBkMode (ctxt->hdc, BM_TRANSPARENT); DrawGlyph (ctxt->hdc, ctxt->x, ctxt->y, glyph_value, &adv_x, &adv_y); SetBkMode (ctxt->hdc, bkmode); adv_x = 0; @@ -160,22 +159,19 @@ static BOOL cb_textout (void* context, Glyph32 glyph_value, { TEXTOUT_CTXT* ctxt = (TEXTOUT_CTXT*)context; int adv_x, adv_y; - int bkmode; if (check_zero_width (char_type)) { adv_x = adv_y = 0; } else if (check_vowel(char_type)) { if (!ctxt->only_extent) { - bkmode = ctxt->pdc->bkmode; - //ctxt->pdc->bkmode = BM_TRANSPARENT; + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = BM_TRANSPARENT; _gdi_draw_one_glyph (ctxt->pdc, glyph_value, (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, ctxt->x, ctxt->y, &adv_x, &adv_y); ctxt->pdc->bkmode = bkmode; - } - //adv_x = adv_y = 0; adv_x = 0; } else { @@ -324,14 +320,13 @@ static BOOL cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int TEXTOUTOMITTED_CTXT* ctxt = (TEXTOUTOMITTED_CTXT*)context; int adv_x, adv_y; int glyph_advance = 0; - //BBOX bbox; - int bkmode = ctxt->pdc->bkmode; if (check_zero_width(char_type)) { adv_x = adv_y = 0; } else if (check_vowel(char_type)) { - //ctxt->pdc->bkmode = BM_TRANSPARENT; + int bkmode = ctxt->pdc->bkmode; + ctxt->pdc->bkmode = BM_TRANSPARENT; _gdi_draw_one_glyph (ctxt->pdc, glyph_value, (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, ctxt->x, ctxt->y, &adv_x, &adv_y);