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.
This commit is contained in:
parent
cbbe235a90
commit
a851e5a669
3 changed files with 92 additions and 59 deletions
|
@ -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
|
||||
|
|
|
@ -821,8 +821,8 @@ class EmacsWindow : public BWindow
|
|||
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 @@ class EmacsWindow : public BWindow
|
|||
|
||||
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 @@ class EmacsWindow : public BWindow
|
|||
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 @@ class EmacsView : public BView
|
|||
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 @@ class EmacsView : public BView
|
|||
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 @@ class EmacsMenuItem : public BMenuItem
|
|||
{
|
||||
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);
|
||||
|
|
|
@ -32,6 +32,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
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"
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue