From: Po Lu Date: Tue, 4 Jan 2022 08:07:53 +0000 (+0000) Subject: Rationalize Haiku rectangle handling X-Git-Tag: emacs-29.0.90~3269 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a851e5a66900fae68e258ad8aaf92321af1db993;p=emacs.git Rationalize Haiku rectangle handling * src/haiku_draw_support.cc (BView_DrawBitmapWithEraseOp): (BView_DrawMask): (rotate_bitmap_270): (rotate_bitmap_90): (BBitmap_transform_bitmap): * src/haiku_support.cc (UnZoom): (GetParentWidthHeight): (MakeFullscreen): (AttachCairoSurface): (AfterResize): (DrawContent): (BView_cr_dump_clipping): Use new rectangle handling macros. * src/haiku_support.h (BE_RECT_WIDTH, BE_RECT_HEIGHT): New macros. --- diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc index 76a5d2e59c7..3e17a08811c 100644 --- a/src/haiku_draw_support.cc +++ b/src/haiku_draw_support.cc @@ -310,9 +310,10 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x, if (bm->ColorSpace () == B_GRAY1) { rgb_color low_color = vw->LowColor (); - for (int y = 0; y <= bc.Bounds ().Height (); ++y) + BRect bounds = bc.Bounds (); + for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y) { - for (int x = 0; x <= bc.Bounds ().Width (); ++x) + for (int x = 0; x <= BE_RECT_WIDTH (bounds); ++x) { if (bits[y * (stride / 4) + x] == 0xFF000000) bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color); @@ -336,11 +337,13 @@ BView_DrawMask (void *src, void *view, { BBitmap *source = (BBitmap *) src; BBitmap bm (source->Bounds (), B_RGBA32); + BRect bounds = bm.Bounds (); + if (bm.InitCheck () != B_OK) return; - for (int y = 0; y <= bm.Bounds ().IntegerHeight (); ++y) + for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y) { - for (int x = 0; x <= bm.Bounds ().IntegerWidth (); ++x) + for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x) { int bit = haiku_get_pixel ((void *) source, x, y); @@ -364,8 +367,8 @@ rotate_bitmap_270 (BBitmap *bmp) bmp->ColorSpace (), true); if (bm->InitCheck () != B_OK) gui_abort ("Failed to init bitmap for rotate"); - int w = bmp->Bounds ().Width () + 1; - int h = bmp->Bounds ().Height () + 1; + int w = BE_RECT_WIDTH (r); + int h = BE_RECT_HEIGHT (r); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) @@ -383,8 +386,8 @@ rotate_bitmap_90 (BBitmap *bmp) bmp->ColorSpace (), true); if (bm->InitCheck () != B_OK) gui_abort ("Failed to init bitmap for rotate"); - int w = bmp->Bounds ().Width () + 1; - int h = bmp->Bounds ().Height () + 1; + int w = BE_RECT_WIDTH (r); + int h = BE_RECT_HEIGHT (r); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) @@ -419,44 +422,42 @@ BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color, } BRect r = bm->Bounds (); - if (r.Width () != desw || r.Height () != desh) + BRect n = BRect (0, 0, desw - 1, desh - 1); + BView vw (n, NULL, B_FOLLOW_NONE, 0); + BBitmap *dst = new BBitmap (n, bm->ColorSpace (), true); + if (dst->InitCheck () != B_OK) + if (bm->InitCheck () != B_OK) + gui_abort ("Failed to init bitmap for scale"); + dst->AddChild (&vw); + + if (!vw.LockLooper ()) + gui_abort ("Failed to lock offscreen view for scale"); + + if (rot != 90 && rot != 270) { - BRect n = BRect (0, 0, desw - 1, desh - 1); - BView vw (n, NULL, B_FOLLOW_NONE, 0); - BBitmap *dst = new BBitmap (n, bm->ColorSpace (), true); - if (dst->InitCheck () != B_OK) - if (bm->InitCheck () != B_OK) - gui_abort ("Failed to init bitmap for scale"); - dst->AddChild (&vw); - - if (!vw.LockLooper ()) - gui_abort ("Failed to lock offscreen view for scale"); - - if (rot != 90 && rot != 270) - { - BAffineTransform tr; - tr.RotateBy (BPoint (desw / 2, desh / 2), rot * M_PI / 180.0); - vw.SetTransform (tr); - } - - vw.MovePenTo (0, 0); - vw.DrawBitmap (bm, n); - if (mk) - BView_DrawMask ((void *) mk, (void *) &vw, - 0, 0, mk->Bounds ().Width () + 1, - mk->Bounds ().Height () + 1, - 0, 0, desw, desh, m_color); - vw.Sync (); - vw.RemoveSelf (); - - if (copied_p) - delete bm; - if (copied_p && mk) - delete mk; - return dst; + BAffineTransform tr; + tr.RotateBy (BPoint (desw / 2, desh / 2), rot * M_PI / 180.0); + vw.SetTransform (tr); } - return bm; + vw.MovePenTo (0, 0); + vw.DrawBitmap (bm, n); + if (mk) + { + BRect k = mk->Bounds (); + BView_DrawMask ((void *) mk, (void *) &vw, + 0, 0, BE_RECT_WIDTH (k), + BE_RECT_HEIGHT (k), + 0, 0, desw, desh, m_color); + } + vw.Sync (); + vw.RemoveSelf (); + + if (copied_p) + delete bm; + if (copied_p && mk) + delete mk; + return dst; } void diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 84f5756f8ca..40f37d577e1 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -821,8 +821,8 @@ public: zoomed_p = 0; EmacsMoveTo (pre_zoom_rect.left, pre_zoom_rect.top); - ResizeTo (pre_zoom_rect.Width (), - pre_zoom_rect.Height ()); + ResizeTo (BE_RECT_WIDTH (pre_zoom_rect), + BE_RECT_HEIGHT (pre_zoom_rect)); } void @@ -833,14 +833,17 @@ public: if (parent) { - *width = parent->Frame ().Width (); - *height = parent->Frame ().Height (); + BRect frame = parent->Frame (); + *width = BE_RECT_WIDTH (frame); + *height = BE_RECT_HEIGHT (frame); } else { BScreen s (this); - *width = s.Frame ().Width (); - *height = s.Frame ().Height (); + BRect frame = s.Frame (); + + *width = BE_RECT_WIDTH (frame); + *height = BE_RECT_HEIGHT (frame); } child_frame_lock.Unlock (); @@ -906,8 +909,8 @@ public: flags &= ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE); EmacsMoveTo (pre_fullscreen_rect.left, pre_fullscreen_rect.top); - ResizeTo (pre_fullscreen_rect.Width (), - pre_fullscreen_rect.Height ()); + ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect), + BE_RECT_HEIGHT (pre_fullscreen_rect)); } SetFlags (flags); } @@ -998,11 +1001,12 @@ public: gui_abort ("Could not lock cr surface during attachment"); if (cr_surface) gui_abort ("Trying to attach cr surface when one already exists"); + BRect bounds = offscreen_draw_bitmap_1->Bounds (); + cr_surface = cairo_image_surface_create_for_data ((unsigned char *) offscreen_draw_bitmap_1->Bits (), - CAIRO_FORMAT_ARGB32, - offscreen_draw_bitmap_1->Bounds ().IntegerWidth () + 1, - offscreen_draw_bitmap_1->Bounds ().IntegerHeight () + 1, + CAIRO_FORMAT_ARGB32, BE_RECT_WIDTH (bounds), + BE_RECT_HEIGHT (bounds), offscreen_draw_bitmap_1->BytesPerRow ()); if (!cr_surface) gui_abort ("Cr surface allocation failed for double-buffered view"); @@ -1056,8 +1060,11 @@ public: if (offscreen_draw_bitmap_1->InitCheck () != B_OK) gui_abort ("Offscreen draw bitmap initialization failed"); - offscreen_draw_view->MoveTo (Frame ().left, Frame ().top); - offscreen_draw_view->ResizeTo (Frame ().Width (), Frame ().Height ()); + BRect frame = Frame (); + + offscreen_draw_view->MoveTo (frame.left, frame.top); + offscreen_draw_view->ResizeTo (BE_RECT_WIDTH (frame), + BE_RECT_HEIGHT (frame)); offscreen_draw_bitmap_1->AddChild (offscreen_draw_view); #ifdef USE_BE_CAIRO AttachCairoSurface (); @@ -1446,7 +1453,7 @@ public: { BRect r = menu->Frame (); int w = menu->StringWidth (key); - menu->MovePenTo (BPoint (r.Width () - w - 4, + menu->MovePenTo (BPoint (BE_RECT_WIDTH (r) - w - 4, menu->PenLocation ().y)); menu->DrawString (key); } @@ -2914,8 +2921,9 @@ BView_cr_dump_clipping (void *view, cairo_t *ctx) for (int i = 0; i < cr.CountRects (); ++i) { BRect r = cr.RectAt (i); - cairo_rectangle (ctx, r.left, r.top, r.Width () + 1, - r.Height () + 1); + cairo_rectangle (ctx, r.left, r.top, + BE_RECT_WIDTH (r), + BE_RECT_HEIGHT (r)); } cairo_clip (ctx); diff --git a/src/haiku_support.h b/src/haiku_support.h index ef90374f69d..550ebd00505 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -32,6 +32,8 @@ along with GNU Emacs. If not, see . */ #include #endif +#include + enum haiku_cursor { CURSOR_ID_NO_CURSOR = 12, @@ -310,6 +312,28 @@ struct haiku_menu_bar_state_event #define HAIKU_BLACK 1000 #define HAIKU_MEDIUM 2000 +#ifdef __cplusplus +/* Haiku's built in Height and Width functions for calculating + rectangle sizes are broken, probably for compatibility with BeOS: + they do not round up in a reasonable fashion, and they return the + numerical difference between the end and start sides in both + directions, instead of the actual size. + + For example: + + BRect (1, 1, 5, 5).IntegerWidth () + + Will return 4, when in reality the rectangle is 5 pixels wide, + since the left corner is also a pixel! + + All code in Emacs should use the macros below to calculate the + dimensions of a BRect, instead of relying on the broken Width and + Height functions. */ + +#define BE_RECT_HEIGHT(rect) (ceil (((rect).bottom - (rect).top) + 1)) +#define BE_RECT_WIDTH(rect) (ceil (((rect).right - (rect).left) + 1)) +#endif /* __cplusplus */ + #ifdef __cplusplus extern "C" {