Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
  3.  * Copyright 2010 Michael Drake <tlsa@netsurf-browser.org>
  4.  *
  5.  * This file is part of libnsfb, http://www.netsurf-browser.org/
  6.  * Licenced under the MIT License,
  7.  *                http://www.opensource.org/licenses/mit-license.php
  8.  */
  9.  
  10. #include <stdbool.h>
  11. #include <endian.h>
  12. #include <stdlib.h>
  13.  
  14. #include "libnsfb.h"
  15. #include "libnsfb_plot.h"
  16. #include "libnsfb_plot_util.h"
  17.  
  18. #include "nsfb.h"
  19. #include "plot.h"
  20.  
  21. #define UNUSED __attribute__((unused))
  22.  
  23. static inline uint16_t *get_xy_loc(nsfb_t *nsfb, int x, int y)
  24. {
  25.         return (void *)(nsfb->ptr + (y * nsfb->linelen) + (x << 1));
  26. }
  27.  
  28. static inline nsfb_colour_t pixel_to_colour(UNUSED nsfb_t *nsfb, uint16_t pixel)
  29. {
  30.         return ((pixel & 0x1F) << 19) |
  31.               ((pixel & 0x7E0) << 5) |
  32.               ((pixel & 0xF800) >> 8);
  33. }
  34.  
  35. /* convert a colour value to a 16bpp pixel value ready for screen output */
  36. static inline uint16_t colour_to_pixel(UNUSED nsfb_t *nsfb, nsfb_colour_t c)
  37. {
  38.         return ((c & 0xF8) << 8) | ((c & 0xFC00 ) >> 5) | ((c & 0xF80000) >> 19);
  39. }
  40.  
  41. #define PLOT_TYPE uint16_t
  42. #define PLOT_LINELEN(ll) ((ll) >> 1)
  43.  
  44. #include "common.c"
  45.  
  46.  
  47. static bool fill(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t c)
  48. {
  49.         int w;
  50.         uint16_t *pvid16;
  51.         uint16_t ent16;
  52.         uint32_t *pvid32;
  53.         uint32_t ent32;
  54.         uint32_t llen;
  55.         uint32_t width;
  56.         uint32_t height;
  57.  
  58.         if (!nsfb_plot_clip_ctx(nsfb, rect))
  59.                 return true; /* fill lies outside current clipping region */
  60.  
  61.         ent16 = colour_to_pixel(nsfb, c);
  62.         width = rect->x1 - rect->x0;
  63.         height = rect->y1 - rect->y0;
  64.  
  65.         pvid16 = get_xy_loc(nsfb, rect->x0, rect->y0);
  66.  
  67.         if (((rect->x0 & 1) == 0) && ((width & 1) == 0)) {
  68.                 /* aligned to 32bit value and width is even */
  69.                 width = width >> 1;
  70.                 llen = (nsfb->linelen >> 2) - width;
  71.                 ent32 = ent16 | (ent16 << 16);
  72.                 pvid32 = (void *)pvid16;
  73.  
  74.                 while (height-- > 0) {
  75.                         w = width;
  76.                         while (w >= 16) {
  77.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  78.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  79.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  80.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  81.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  82.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  83.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  84.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  85.                                 w-=16;
  86.                         }
  87.                         while (w >= 4) {
  88.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  89.                                 *pvid32++ = ent32; *pvid32++ = ent32;
  90.                                 w-=4;
  91.                         }
  92.                         while (w > 0) {
  93.                                 *pvid32++ = ent32;
  94.                                 w--;
  95.                         }
  96.                         // for (w = width; w > 0; w--) *pvid32++ = ent32;
  97.                         pvid32 += llen;
  98.                 }
  99.  
  100.         } else {
  101.                 llen = (nsfb->linelen >> 1) - width;
  102.  
  103.  
  104.                 while (height-- > 0) {
  105.                         for (w = width; w > 0; w--) *pvid16++ = ent16;
  106.                         pvid16 += llen;
  107.                 }
  108.         }
  109.         return true;
  110. }
  111.  
  112. const nsfb_plotter_fns_t _nsfb_16bpp_plotters = {
  113.         .line = line,
  114.         .fill = fill,
  115.         .point = point,
  116.         .bitmap = bitmap,
  117.         .glyph8 = glyph8,
  118.         .glyph1 = glyph1,
  119.         .readrect = readrect,
  120. };
  121.  
  122. /*
  123.  * Local Variables:
  124.  * c-basic-offset:8
  125.  * End:
  126.  */
  127.