root/src/haiku_draw_support.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rgb32_to_rgb_color
  2. get_view
  3. BView_StartClip
  4. BView_EndClip
  5. BView_SetHighColor
  6. BView_SetLowColor
  7. BView_SetPenSize
  8. BView_FillRectangle
  9. BView_FillRectangleAbs
  10. BView_StrokeRectangle
  11. BView_SetViewColor
  12. BView_ClipToRect
  13. BView_ClipToInverseRect
  14. BView_StrokeLine
  15. BView_SetFont
  16. BView_MovePenTo
  17. BView_DrawString
  18. BView_DrawChar
  19. BView_CopyBits
  20. rgb_color_hsl
  21. hue_to_rgb
  22. hsl_color_rgb
  23. BView_DrawBitmap
  24. BView_DrawBitmapTiled
  25. BView_DrawBitmapWithEraseOp
  26. be_draw_image_mask
  27. be_apply_affine_transform
  28. be_apply_inverse_transform
  29. BView_FillTriangle
  30. BView_InvertRect
  31. be_draw_cross_on_pixmap_1
  32. be_draw_cross_on_pixmap
  33. be_draw_bitmap_with_mask

     1 /* Haiku window system support.  Hey, Emacs, this is -*- C++ -*-
     2    Copyright (C) 2021-2023 Free Software Foundation, Inc.
     3 
     4 This file is part of GNU Emacs.
     5 
     6 GNU Emacs is free software: you can redistribute it and/or modify
     7 it under the terms of the GNU General Public License as published by
     8 the Free Software Foundation, either version 3 of the License, or (at
     9 your option) any later version.
    10 
    11 GNU Emacs is distributed in the hope that it will be useful,
    12 but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 GNU General Public License for more details.
    15 
    16 You should have received a copy of the GNU General Public License
    17 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    18 
    19 #include <config.h>
    20 
    21 #include <View.h>
    22 #include <Region.h>
    23 #include <Font.h>
    24 #include <Window.h>
    25 #include <Bitmap.h>
    26 
    27 #include <cmath>
    28 
    29 #include "haiku_support.h"
    30 
    31 #define RGB_TO_UINT32(r, g, b) ((255 << 24) | ((r) << 16) | ((g) << 8) | (b))
    32 #define RED_FROM_ULONG(color)   (((color) >> 16) & 0xff)
    33 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
    34 #define BLUE_FROM_ULONG(color)  ((color) & 0xff)
    35 
    36 #define RGB_COLOR_UINT32(r) RGB_TO_UINT32 ((r).red, (r).green, (r).blue)
    37 
    38 static void
    39 rgb32_to_rgb_color (uint32_t rgb, rgb_color *color)
    40 {
    41   color->red = RED_FROM_ULONG (rgb);
    42   color->green = GREEN_FROM_ULONG (rgb);
    43   color->blue = BLUE_FROM_ULONG (rgb);
    44   color->alpha = 255;
    45 }
    46 
    47 static BView *
    48 get_view (void *vw)
    49 {
    50   BView *view = (BView *) find_appropriate_view_for_draw (vw);
    51   return view;
    52 }
    53 
    54 void
    55 BView_StartClip (void *view)
    56 {
    57   BView *vw = get_view (view);
    58   vw->PushState ();
    59 }
    60 
    61 void
    62 BView_EndClip (void *view)
    63 {
    64   BView *vw = get_view (view);
    65   vw->PopState ();
    66 }
    67 
    68 void
    69 BView_SetHighColor (void *view, uint32_t color)
    70 {
    71   BView *vw = get_view (view);
    72   rgb_color col;
    73   rgb32_to_rgb_color (color, &col);
    74 
    75   vw->SetHighColor (col);
    76 }
    77 
    78 void
    79 BView_SetLowColor (void *view, uint32_t color)
    80 {
    81   BView *vw = get_view (view);
    82   rgb_color col;
    83   rgb32_to_rgb_color (color, &col);
    84 
    85   vw->SetLowColor (col);
    86 }
    87 
    88 void
    89 BView_SetPenSize (void *view, int u)
    90 {
    91   BView *vw = get_view (view);
    92   vw->SetPenSize (u);
    93 }
    94 
    95 void
    96 BView_FillRectangle (void *view, int x, int y, int width, int height)
    97 {
    98   BView *vw = get_view (view);
    99   BRect rect = BRect (x, y, x + width - 1, y + height - 1);
   100 
   101   vw->FillRect (rect);
   102 }
   103 
   104 void
   105 BView_FillRectangleAbs (void *view, int x, int y, int x1, int y1)
   106 {
   107   BView *vw = get_view (view);
   108   BRect rect = BRect (x, y, x1, y1);
   109 
   110   vw->FillRect (rect);
   111 }
   112 
   113 void
   114 BView_StrokeRectangle (void *view, int x, int y, int width, int height)
   115 {
   116   BView *vw = get_view (view);
   117   BRect rect = BRect (x, y, x + width - 1, y + height - 1);
   118 
   119   vw->StrokeRect (rect);
   120 }
   121 
   122 void
   123 BView_SetViewColor (void *view, uint32_t color)
   124 {
   125   BView *vw = get_view (view);
   126   rgb_color col;
   127   rgb32_to_rgb_color (color, &col);
   128 
   129 #ifndef USE_BE_CAIRO
   130   vw->SetViewColor (col);
   131 #else
   132   vw->SetViewColor (B_TRANSPARENT_32_BIT);
   133 #endif
   134 }
   135 
   136 void
   137 BView_ClipToRect (void *view, int x, int y, int width, int height)
   138 {
   139   BView *vw = get_view (view);
   140   BRect rect = BRect (x, y, x + width - 1, y + height - 1);
   141 
   142   vw->ClipToRect (rect);
   143 }
   144 
   145 void
   146 BView_ClipToInverseRect (void *view, int x, int y, int width, int height)
   147 {
   148   BView *vw = get_view (view);
   149   BRect rect = BRect (x, y, x + width - 1, y + height - 1);
   150 
   151   vw->ClipToInverseRect (rect);
   152 }
   153 
   154 void
   155 BView_StrokeLine (void *view, int sx, int sy, int tx, int ty)
   156 {
   157   BView *vw = get_view (view);
   158   BPoint from = BPoint (sx, sy);
   159   BPoint to = BPoint (tx, ty);
   160 
   161   vw->StrokeLine (from, to);
   162 }
   163 
   164 void
   165 BView_SetFont (void *view, void *font)
   166 {
   167   BView *vw = get_view (view);
   168 
   169   vw->SetFont ((BFont *) font);
   170 }
   171 
   172 void
   173 BView_MovePenTo (void *view, int x, int y)
   174 {
   175   BView *vw = get_view (view);
   176   BPoint pt = BPoint (x, y);
   177 
   178   vw->MovePenTo (pt);
   179 }
   180 
   181 void
   182 BView_DrawString (void *view, const char *chr, ptrdiff_t len)
   183 {
   184   BView *vw = get_view (view);
   185 
   186   vw->DrawString (chr, len);
   187 }
   188 
   189 void
   190 BView_DrawChar (void *view, char chr)
   191 {
   192   BView *vw = get_view (view);
   193 
   194   vw->DrawChar (chr);
   195 }
   196 
   197 void
   198 BView_CopyBits (void *view, int x, int y, int width, int height,
   199                 int tox, int toy, int towidth, int toheight)
   200 {
   201   BView *vw = get_view (view);
   202 
   203   vw->CopyBits (BRect (x, y, x + width - 1, y + height - 1),
   204                 BRect (tox, toy, tox + towidth - 1, toy + toheight - 1));
   205   vw->Sync ();
   206 }
   207 
   208 /* Convert RGB32 color color from RGB color space to its
   209    HSL components pointed to by H, S and L.  */
   210 void
   211 rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l)
   212 {
   213   rgb_color col;
   214   rgb32_to_rgb_color (rgb, &col);
   215 
   216   double red = col.red / 255.0;
   217   double green = col.green / 255.0;
   218   double blue = col.blue / 255.0;
   219 
   220   double max = std::fmax (std::fmax (red, blue), green);
   221   double min = std::fmin (std::fmin (red, blue), green);
   222   double delta = max - min;
   223   *l = (max + min) / 2.0;
   224 
   225   if (!delta)
   226     {
   227       *h = 0;
   228       *s = 0;
   229       return;
   230     }
   231 
   232   *s = (*l < 0.5) ? delta / (max + min) :
   233     delta / (20 - max - min);
   234   double rc = (max - red) / delta;
   235   double gc = (max - green) / delta;
   236   double bc = (max - blue) / delta;
   237 
   238   if (red == max)
   239     *h = bc - gc;
   240   else if (green == max)
   241     *h = 2.0 + rc + -bc;
   242   else
   243     *h = 4.0 + gc + -rc;
   244   *h = std::fmod (*h / 6, 1.0);
   245 }
   246 
   247 static double
   248 hue_to_rgb (double v1, double v2, double h)
   249 {
   250   if (h < 1 / 6)
   251     return v1 + (v2 - v1) * h * 6.0;
   252   else if (h < 0.5)
   253     return v2;
   254   else if (h < 2.0 / 3)
   255     return v1 + (v2 - v1) * (2.0 / 3 - h) * 6.0;
   256   return v1;
   257 }
   258 
   259 void
   260 hsl_color_rgb (double h, double s, double l, uint32_t *rgb)
   261 {
   262   if (!s)
   263     *rgb = RGB_TO_UINT32 (std::lrint (l * 255),
   264                           std::lrint (l * 255),
   265                           std::lrint (l * 255));
   266   else
   267     {
   268       double m2 = l <= 0.5 ? l * (1 + s) : l + s - l * s;
   269       double m1 = 2.0 * l - m2;
   270 
   271       *rgb = RGB_TO_UINT32
   272         (std::lrint (hue_to_rgb (m1, m2,
   273                                  std::fmod (h + 1 / 3.0, 1)) * 255),
   274          std::lrint (hue_to_rgb (m1, m2, h) * 255),
   275          std::lrint (hue_to_rgb (m1, m2,
   276                                  std::fmod (h - 1 / 3.0, 1)) * 255));
   277     }
   278 }
   279 
   280 void
   281 BView_DrawBitmap (void *view, void *bitmap, int x, int y,
   282                   int width, int height, int vx, int vy, int vwidth,
   283                   int vheight, bool use_bilinear_filtering)
   284 {
   285   BView *vw = get_view (view);
   286   BBitmap *bm = (BBitmap *) bitmap;
   287 
   288   vw->SetDrawingMode (B_OP_OVER);
   289   if (!use_bilinear_filtering)
   290     vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
   291                     BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
   292   else
   293     vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
   294                     BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1),
   295                     B_FILTER_BITMAP_BILINEAR);
   296   vw->SetDrawingMode (B_OP_COPY);
   297 }
   298 
   299 void
   300 BView_DrawBitmapTiled (void *view, void *bitmap, int x, int y,
   301                        int width, int height, int vx, int vy,
   302                        int vwidth, int vheight)
   303 {
   304   BView *vw = get_view (view);
   305   BBitmap *bm = (BBitmap *) bitmap;
   306   BRect bounds = bm->Bounds ();
   307 
   308   if (width == -1)
   309     width = BE_RECT_WIDTH (bounds);
   310 
   311   if (height == -1)
   312     height = BE_RECT_HEIGHT (bounds);
   313 
   314   vw->SetDrawingMode (B_OP_OVER);
   315   vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
   316                   BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1),
   317                   B_TILE_BITMAP);
   318   vw->SetDrawingMode (B_OP_COPY);
   319 }
   320 
   321 void
   322 BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
   323                              int y, int width, int height)
   324 {
   325   BView *vw = get_view (view);
   326   BBitmap *bm = (BBitmap *) bitmap;
   327   BBitmap bc (bm->Bounds (), B_RGBA32);
   328   BRect rect (x, y, x + width - 1, y + height - 1);
   329   uint32_t *bits;
   330   size_t stride;
   331   rgb_color low_color;
   332   BRect bounds;
   333 
   334   if (bc.InitCheck () != B_OK || bc.ImportBits (bm) != B_OK)
   335     return;
   336 
   337   bits = (uint32_t *) bc.Bits ();
   338   stride = bc.BytesPerRow ();
   339 
   340   if (bm->ColorSpace () == B_GRAY1)
   341     {
   342       low_color = vw->LowColor ();
   343       bounds = bc.Bounds ();
   344 
   345       for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y)
   346         {
   347           for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x)
   348             {
   349               if (bits[y * (stride / 4) + x] == 0xFF000000)
   350                 bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color);
   351               else
   352                 bits[y * (stride / 4) + x] = 0;
   353             }
   354         }
   355     }
   356 
   357   vw->SetDrawingMode ((bm->ColorSpace ()
   358                        == B_GRAY1)
   359                       ? B_OP_OVER : B_OP_ERASE);
   360   vw->DrawBitmap (&bc, rect);
   361   vw->SetDrawingMode (B_OP_COPY);
   362 }
   363 
   364 void
   365 be_draw_image_mask (void *src, void *view, int x, int y, int width,
   366                     int height, int vx, int vy, int vwidth, int vheight,
   367                     uint32_t color)
   368 {
   369   BBitmap *source = (BBitmap *) src;
   370   BBitmap bm (source->Bounds (), B_RGBA32);
   371   BRect bounds = bm.Bounds ();
   372   int bx, by, bit;
   373   BView *vw;
   374 
   375   if (bm.InitCheck () != B_OK)
   376     return;
   377 
   378   /* Fill the background color or transparency into the bitmap,
   379      depending on the value of the mask.  */
   380   for (by = 0; by < BE_RECT_HEIGHT (bounds); ++by)
   381     {
   382       for (bx = 0; bx < BE_RECT_WIDTH (bounds); ++bx)
   383         {
   384           bit = haiku_get_pixel ((void *) source, bx, by);
   385 
   386           if (!bit)
   387             haiku_put_pixel ((void *) &bm, bx, by,
   388                              ((uint32_t) 255 << 24) | color);
   389           else
   390             haiku_put_pixel ((void *) &bm, bx, by, 0);
   391         }
   392     }
   393 
   394   vw = get_view (view);
   395   vw->SetDrawingMode (B_OP_OVER);
   396   vw->DrawBitmap (&bm, BRect (x, y, x + width - 1, y + height - 1),
   397                   BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
   398   vw->SetDrawingMode (B_OP_COPY);
   399 }
   400 
   401 void
   402 be_apply_affine_transform (void *view, double m0, double m1, double tx,
   403                            double m2, double m3, double ty)
   404 {
   405   BAffineTransform transform (m0, m2, m1, m3, tx, ty);
   406 
   407   get_view (view)->SetTransform (transform);
   408 }
   409 
   410 void
   411 be_apply_inverse_transform (double (*matrix3x3)[3], int x, int y,
   412                             int *x_out, int *y_out)
   413 {
   414   BAffineTransform transform (matrix3x3[0][0], matrix3x3[1][0],
   415                               matrix3x3[0][1], matrix3x3[1][1],
   416                               matrix3x3[0][2], matrix3x3[1][2]);
   417   BPoint point (x, y);
   418 
   419   transform.ApplyInverse (&point);
   420 
   421   *x_out = std::floor (point.x);
   422   *y_out = std::floor (point.y);
   423 }
   424 
   425 void
   426 BView_FillTriangle (void *view, int x1, int y1,
   427                     int x2, int y2, int x3, int y3)
   428 {
   429   BView *vw = get_view (view);
   430   vw->FillTriangle (BPoint (x1, y1), BPoint (x2, y2),
   431                     BPoint (x3, y3));
   432 }
   433 
   434 void
   435 BView_InvertRect (void *view, int x, int y, int width, int height)
   436 {
   437   BView *vw = get_view (view);
   438 
   439   vw->InvertRect (BRect (x, y, x + width - 1, y + height - 1));
   440 }
   441 
   442 static void
   443 be_draw_cross_on_pixmap_1 (BBitmap *bitmap, int x, int y, int width,
   444                            int height, uint32_t color)
   445 {
   446   BBitmap dest (bitmap->Bounds (),
   447                 bitmap->ColorSpace (),
   448                 true, false);
   449   BView view (bitmap->Bounds (), NULL, B_FOLLOW_NONE, 0);
   450   rgb_color high_color;
   451 
   452   rgb32_to_rgb_color (color, &high_color);
   453   dest.ImportBits (bitmap);
   454 
   455   if (!dest.Lock ())
   456     return;
   457 
   458   dest.AddChild (&view);
   459 
   460   view.SetHighColor (high_color);
   461   view.StrokeLine (BPoint (x, y),
   462                    BPoint (x + width - 1, y + height - 1));
   463   view.StrokeLine (BPoint (x, y + height - 1),
   464                    BPoint (x + width - 1, y));
   465   view.RemoveSelf ();
   466   bitmap->ImportBits (&dest);
   467 }
   468 
   469 void
   470 be_draw_cross_on_pixmap (void *bitmap, int x, int y, int width,
   471                          int height, uint32_t color)
   472 {
   473   BBitmap *target = (BBitmap *) bitmap;
   474 
   475   be_draw_cross_on_pixmap_1 (target, x, y, width, height,
   476                              color);
   477 }
   478 
   479 void
   480 be_draw_bitmap_with_mask (void *view, void *bitmap, void *mask,
   481                           int dx, int dy, int width, int height,
   482                           int vx, int vy, int vwidth, int vheight,
   483                           bool use_bilinear_filtering)
   484 {
   485   BBitmap *source ((BBitmap *) bitmap);
   486   BBitmap combined (source->Bounds (), B_RGBA32);
   487   BRect bounds;
   488   int x, y, bit;
   489   BView *vw;
   490   uint32_t source_mask;
   491   unsigned long pixel;
   492 
   493   if (combined.InitCheck () != B_OK)
   494     return;
   495 
   496   if (combined.ImportBits (source) != B_OK)
   497     return;
   498 
   499   bounds = source->Bounds ();
   500 
   501   if (source->ColorSpace () == B_RGB32)
   502     source_mask = 255u << 24;
   503   else
   504     source_mask = 0;
   505 
   506   for (y = 0; y < BE_RECT_HEIGHT (bounds); ++y)
   507     {
   508       for (x = 0; x < BE_RECT_WIDTH (bounds); ++x)
   509         {
   510           bit = haiku_get_pixel (mask, x, y);
   511 
   512           if (bit)
   513             {
   514               pixel = haiku_get_pixel (bitmap, x, y);
   515               haiku_put_pixel ((void *) &combined, x, y,
   516                                source_mask | pixel);
   517             }
   518           else
   519             haiku_put_pixel ((void *) &combined, x, y, 0);
   520         }
   521     }
   522 
   523   vw = get_view (view);
   524 
   525   vw->SetDrawingMode (B_OP_OVER);
   526   if (!use_bilinear_filtering)
   527     vw->DrawBitmap (&combined,
   528                     BRect (dx, dy, dx + width - 1, dy + height - 1),
   529                     BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
   530   else
   531     vw->DrawBitmap (&combined,
   532                     BRect (dx, dy, dx + width - 1, dy + height - 1),
   533                     BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1),
   534                     B_FILTER_BITMAP_BILINEAR);
   535   vw->SetDrawingMode (B_OP_COPY);
   536 }

/* [<][>][^][v][top][bottom][index][help] */