Ejemplo n.º 1
0
int nxtk_bitmapwindow(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *dest,
                      FAR const void **src,
                      FAR const struct nxgl_point_s *origin, unsigned int stride)
{
  FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hfwnd;
  struct nxgl_point_s wndorigin;
  struct nxgl_rect_s clipdest;

#ifdef CONFIG_DEBUG_FEATURES
  if (!hfwnd || !dest || !src || !origin)
    {
      set_errno(EINVAL);
      return ERROR;
    }
#endif

  /* Clip the rectangle so that it lies within the sub-window bounds
   * then move the rectangle to that it is relative to the containing
   * window.
   */

  nxtk_subwindowclip(fwnd, &clipdest, dest, &fwnd->fwrect);

  /* Now, move the bitmap origin so that it is relative to the containing
   * window, not the sub-window.
   *
   * Temporarily, position the origin in absolute screen coordinates
   */

  nxgl_vectoradd(&wndorigin, origin, &fwnd->fwrect.pt1);

  /* Then move the origin so that is relative to the containing window, not the
   * client subwindow
   */

  nxgl_vectsubtract(&wndorigin, &wndorigin, &fwnd->wnd.bounds.pt1);

  /* Then copy the bitmap */

  nx_bitmap((NXWINDOW)hfwnd, &clipdest, src, &wndorigin, stride);
  return OK;
}
Ejemplo n.º 2
0
int oled_image_draw_img(uint8_t pos_x, uint8_t pos_y, const oled_image_canvas_t  * const img)
{
    int ret = OK;
    FAR struct nxgl_rect_s dest;
    FAR void *src[CONFIG_NX_NPLANES];
    FAR struct nxgl_point_s pos;
    uint32_t i, j;
    uint8_t stride;

    if (pos_x >= OLED_IMG_SCREEN_WIDTH || pos_y >= OLED_IMG_SCREEN_HEIGHT
        || (pos_x + img->width) > OLED_IMG_SCREEN_WIDTH
        || (pos_y + img->height) > OLED_IMG_SCREEN_HEIGHT) {
        lcd_dbg("Wrong coordinates to start draw image"
                "or image too big\n");
        return ERROR;
    }

    pos.x = pos_x;
    pos.y = pos_y;

    dest.pt1.x = pos.x;
    dest.pt2.x = pos.x + img->width - 1;

    stride = img->width / 8 + (!(img->width % 8) ? 0 : 1);

    for (i = 0, j = 0; i < img->height; i++, j += stride) {
        dest.pt1.y = pos.y;
        dest.pt2.y = pos.y;

        src[0] = (FAR void *) (img->bitmap + j);

        ret = nx_bitmap(g_img.hwnd, &dest, (FAR void *)src, &pos, img->width);
        if (ret < 0) {
            lcd_dbg("nx_bitmapwindow failed: %d\n", errno);
            return ERROR;
        }

        pos.y++;
    }

    return ret;
}
Ejemplo n.º 3
0
void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
                     FAR struct nxtext_state_s *st,
                     NXHANDLE hfont, FAR const struct nxtext_bitmap_s *bm)
{
  FAR struct nxtext_glyph_s *glyph;
  struct nxgl_rect_s bounds;
  struct nxgl_rect_s intersection;
  struct nxgl_size_s fsize;
  int ret;

  /* Handle the special case of spaces which have no glyph bitmap */

  if (BM_ISSPACE(bm))
    {
      return;
    }

  /* Get the size of the font glyph (which may not have been created yet) */

  ret = nxtext_fontsize(hfont, bm->code, &fsize);
  if (ret < 0)
    {
      /* This would mean that there is no bitmap for the character code and
       * that the font would be rendered as a space.  But this case should
       * never happen here because the BM_ISSPACE() should have already
       * found all such cases.
       */

      return;
    }

  /* Construct a bounding box for the glyph */

  bounds.pt1.x = bm->pos.x;
  bounds.pt1.y = bm->pos.y;
  bounds.pt2.x = bm->pos.x + fsize.w - 1;
  bounds.pt2.y = bm->pos.y + fsize.h - 1;

  /* Should this also be clipped to a region in the window? */

  if (rect)
    {
      /* Get the intersection of the redraw region and the character bitmap */

      nxgl_rectintersect(&intersection, rect, &bounds);
    }
  else
    {
      /* The intersection is the whole glyph */

      nxgl_rectcopy(&intersection, &bounds);
    }

  /* Check for empty intersections */

  if (!nxgl_nullrect(&intersection))
    {
      FAR const void *src;

      /* Find (or create) the glyph that goes with this font */

       glyph = nxtext_getglyph(hfont, st, bm->code);
       if (!glyph)
         {
           /* Shouldn't happen */

           return;
         }

      /* Blit the font bitmap into the window */

      src = (FAR const void *)glyph->bitmap;
      ret = nx_bitmap((NXWINDOW)hwnd, &intersection, &src,
                      &bm->pos, (unsigned int)glyph->stride);
      if (ret < 0)
        {
          printf("nxtext_fillchar: nx_bitmapwindow failed: %d\n", errno);
        }
    }
}
Ejemplo n.º 4
0
void nxhello_hello(NXWINDOW hwnd)
{
  FAR const struct nx_font_s *fontset;
  FAR const struct nx_fontbitmap_s *fbm;
  FAR uint8_t *glyph;
  FAR const char *ptr;
  FAR struct nxgl_point_s pos;
  FAR struct nxgl_rect_s dest;
  FAR const void *src[CONFIG_NX_NPLANES];
  unsigned int glyphsize;
  unsigned int mxstride;
  int ret;

  /* Get information about the font we are going to use */

  fontset = nxf_getfontset(g_nxhello.hfont);

  /* Allocate a bit of memory to hold the largest rendered font */

  mxstride  = (fontset->mxwidth * CONFIG_EXAMPLES_NXHELLO_BPP + 7) >> 3;
  glyphsize = (unsigned int)fontset->mxheight * mxstride;
  glyph     = (FAR uint8_t*)malloc(glyphsize);

  /* NOTE: no check for failure to allocate the memory.  In a real application
   * you would need to handle that event.
   */

  /* Get a position so the the "Hello, World!" string will be centered on the
   * display.
   */

  nxhello_center(&pos, fontset);
  message("nxhello_hello: Position (%d,%d)\n", pos.x, pos.y);

  /* Now we can say "hello" in the center of the display. */

  for (ptr = g_hello; *ptr; ptr++)
    {
      /* Get the bitmap font for this ASCII code */

      fbm = nxf_getbitmap(g_nxhello.hfont, *ptr);
      if (fbm)
        {
          uint8_t fheight;      /* Height of this glyph (in rows) */
          uint8_t fwidth;       /* Width of this glyph (in pixels) */
          uint8_t fstride;      /* Width of the glyph row (in bytes) */

          /* Get information about the font bitmap */

          fwidth  = fbm->metric.width + fbm->metric.xoffset;
          fheight = fbm->metric.height + fbm->metric.yoffset;
          fstride = (fwidth * CONFIG_EXAMPLES_NXHELLO_BPP + 7) >> 3;

          /* Initialize the glyph memory to the background color */

          nxhello_initglyph(glyph, fheight, fwidth, fstride);

          /* Then render the glyph into the allocated memory */

#if CONFIG_NX_NPLANES > 1
# warning "More logic is needed for the case where CONFIG_NX_PLANES > 1"
#endif
          (void)RENDERER((FAR nxgl_mxpixel_t*)glyph, fheight, fwidth,
                         fstride, fbm, CONFIG_EXAMPLES_NXHELLO_FONTCOLOR);

          /* Describe the destination of the font with a rectangle */

          dest.pt1.x = pos.x;
          dest.pt1.y = pos.y;
          dest.pt2.x = pos.x + fwidth - 1;
          dest.pt2.y = pos.y + fheight - 1;
   
          /* Then put the font on the display */

          src[0] = (FAR const void *)glyph;
#if CONFIG_NX_NPLANES > 1
# warning "More logic is needed for the case where CONFIG_NX_PLANES > 1"
#endif
          ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, fstride);
          if (ret < 0)
            {
              message("nxhello_write: nx_bitmapwindow failed: %d\n", errno);
            }

           /* Skip to the right the width of the font */

          pos.x += fwidth;
        }
      else
        {
           /* No bitmap (probably because the font is a space).  Skip to the
            * right the width of a space.
            */

          pos.x += fontset->spwidth;
        }
    }
Ejemplo n.º 5
0
void nximage_image(NXWINDOW hwnd)
{
  FAR const void *state = NULL;
  FAR struct nxgl_point_s pos;
  FAR struct nxgl_rect_s dest;
  FAR const void *src[CONFIG_NX_NPLANES];
  nxgl_coord_t row;
  int ret;
#if defined(CONFIG_EXAMPLES_NXIMAGE_YSCALEp5) || defined(CONFIG_EXAMPLES_NXIMAGE_YSCALE1p5)
  int i;
#endif

  /* Center the image.  Note: these may extend off the display. */

  pos.x = (g_nximage.xres - SCALED_WIDTH) / 2;
  pos.y = (g_nximage.yres - SCALED_HEIGHT) / 2;

  /* Set up the invariant part of the destination bounding box */

  dest.pt1.x = pos.x;
  dest.pt2.x = pos.x + SCALED_WIDTH - 1;
 
  /* Now output the rows */

  for (row = 0; row < IMAGE_HEIGHT; row += NINPUT_ROWS)
    {
      /* Read input row(s) */

     nximage_blitrow(g_runs[0].run, &state);
#if NINPUT_ROWS > 1
     nximage_blitrow(g_runs[1].run, &state);
#endif

      /* Output rows before averaging */

#if defined(CONFIG_EXAMPLES_NXIMAGE_YSCALE1p5) || defined(CONFIG_EXAMPLES_NXIMAGE_YSCALE2p0)

      /* Output row[0] */

      dest.pt1.y = pos.y;
      dest.pt2.y = pos.y;

      src[0] = (FAR const void *)g_runs[0].run;
#if CONFIG_NX_NPLANES > 1
# warning "More logic is needed for the case where CONFIG_NX_PLANES > 1"
#endif
      ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t));
      if (ret < 0)
        {
          message("nximage_image: nx_bitmapwindow failed: %d\n", errno);
        }

      /* Increment the vertical position */

      pos.y++;
#endif

      /* Perform averaging */

#if defined(CONFIG_EXAMPLES_NXIMAGE_YSCALEp5) || defined(CONFIG_EXAMPLES_NXIMAGE_YSCALE1p5)

      /* Average row[0] and row[1], output results in row[0] */

      for (i = 0; i < SCALED_WIDTH; i++)
        {
          /* Only average if the corresponding pixels in each row differ */

          nxgl_mxpixel_t pix0 = g_runs[0].run[i];
          nxgl_mxpixel_t pix1 = g_runs[1].run[i];
          if (pix0 != pix1)
            {
              g_runs[0].run[i] = nximage_avgcolor(pix0, pix1);
            }
        }

#endif

      /* Output rows after averaging */

      /* Output row[0] */

      dest.pt1.y = pos.y;
      dest.pt2.y = pos.y;

      src[0] = (FAR const void *)g_runs[0].run;
#if CONFIG_NX_NPLANES > 1
# warning "More logic is needed for the case where CONFIG_NX_PLANES > 1"
#endif
      ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t));
      if (ret < 0)
        {
          message("nximage_image: nx_bitmapwindow failed: %d\n", errno);
        }

      /* Increment the vertical position */

      pos.y++;

#if defined(CONFIG_EXAMPLES_NXIMAGE_YSCALE1p5)

      /* Output row[0] and row[1] */

      dest.pt1.y = pos.y;
      dest.pt2.y = pos.y;

      src[0] = (FAR const void *)g_runs[1].run;
#if CONFIG_NX_NPLANES > 1
# warning "More logic is needed for the case where CONFIG_NX_PLANES > 1"
#endif
      ret = nx_bitmap((NXWINDOW)hwnd, &dest, src, &pos, SCALED_WIDTH*sizeof(nxgl_mxpixel_t));
      if (ret < 0)
        {
          message("nximage_image: nx_bitmapwindow failed: %d\n", errno);
        }

      /* Increment the vertical position */

      pos.y++;
#endif
    }
}
Ejemplo n.º 6
0
int oled_image_crop_img(uint8_t pos_x, uint8_t pos_y, oled_image_canvas_t *img, oled_image_crop_pxs_t *crop_pxs)
{
    const uint8_t byte_length = 8;
    int ret = OK;
    FAR struct nxgl_rect_s dest;
    FAR void *src[CONFIG_NX_NPLANES];
    FAR struct nxgl_point_s pos;
    uint32_t i, j, pxs;
    uint8_t stride;
    uint16_t left_pad,top_pad;
    uint8_t img_width_crop, img_height_crop;
    uint8_t pic_line[16] = { 0 };
    /* The only way to draw line from the image
     * is addressing to this line byte by byte.
     * Thus we need variables to save pixels pads
     * from the left side of the image */
    uint8_t left_pxs_offset;

    /* check if crop_pxs structure's data is valid */

    if (crop_pxs->bottom_pxs >= img->height || crop_pxs->top_pxs >= img->height
        || crop_pxs->left_pxs >= img->width || crop_pxs->right_pxs >= img->width
        || (crop_pxs->left_pxs + crop_pxs->right_pxs) >= img->width
        || (crop_pxs->top_pxs + crop_pxs->bottom_pxs) >= img->height) {
        lcd_lldbg("Cannot proceed. Amount of pixels to be cropped is greater or equal to the"
                  " image height or width\n");
        return ERROR;
    }

    /* check, will image fit on the screen after crop */

    if (pos_x >= OLED_IMG_SCREEN_WIDTH || pos_y >= OLED_IMG_SCREEN_HEIGHT
        || (pos_x + img->width - crop_pxs->left_pxs - crop_pxs->right_pxs) > OLED_IMG_SCREEN_WIDTH
        || (pos_y + img->height - crop_pxs->top_pxs - crop_pxs->bottom_pxs) > OLED_IMG_SCREEN_HEIGHT) {
        lcd_dbg("Wrong coordinates to start draw image"
                "or image too big\n");
        return ERROR;
    }

    left_pad = crop_pxs->left_pxs / byte_length;
    left_pxs_offset = crop_pxs->left_pxs % byte_length;
    top_pad = crop_pxs->top_pxs;
    /* New width and height calculation */
    img_width_crop = img->width - crop_pxs->left_pxs - crop_pxs->right_pxs;
    img_height_crop = img->height - crop_pxs->top_pxs - crop_pxs->bottom_pxs;

    pos.x = pos_x - left_pxs_offset;
    pos.y = pos_y;

    dest.pt1.x = pos.x;
    dest.pt2.x = pos.x + img_width_crop - 1;

    stride = img->width / 8 + (!(img->width % 8) ? 0 : 1);

    for (i = 0, j = left_pad + stride * top_pad; i < img_height_crop; i++, j += stride) {
        dest.pt1.y = pos.y;
        dest.pt2.y = pos.y;

        memcpy(pic_line, (const uint8_t *)(img->bitmap + j), stride - left_pad);
        for (pxs = 0; pxs < left_pxs_offset; pxs++) {
            DEBUGASSERT(pxs <= byte_length);
            if (!CONFIG_THINGSEE_DISPLAY_BKGND_COLOR) {
                *(pic_line) &= ~(1 << (byte_length - pxs));
            } else {
                *(pic_line) |= (1 << (byte_length - pxs));
            }
        }

        src[0] = (FAR void *) pic_line;

        ret = nx_bitmap(g_img.hwnd, &dest, (FAR void *)src, &pos, img_width_crop);
        if (ret < 0) {
            lcd_dbg("nx_bitmapwindow failed: %d\n", errno);
            return ERROR;
        }

        pos.y++;
    }

    return ret;
}