Example #1
0
RT_B RT_API RtGdipStretchBitmap(RT_H hBitmap, RT_H hDc, RT_N nWidth, RT_N nHeight, RT_GDIP_INTERPOLATION_MODE nInterpolationMode)
{
  GpGraphics* lpGraphics;
  GpBitmap* lpBitmap;
  GpBrush* lpBrush;
  GpStatus nStatus;
  RT_B bResult;

  lpGraphics = RT_NULL;
  lpBitmap = RT_NULL;
  lpBrush = RT_NULL;

  /* Create destination graphics hDc. */
  nStatus = GdipCreateFromHDC(hDc, &lpGraphics);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  /* Adjust quality. */
  nStatus = GdipSetInterpolationMode(lpGraphics, (InterpolationMode)nInterpolationMode);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  /* Create a brush to fill the background. */
  nStatus = GdipCreateSolidFill(0xFFFFFFFF, &lpBrush);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  /* Fill the destination DC with a background. Necessary to avoid edges artifacts. */
  nStatus = GdipFillRectangleI(lpGraphics, lpBrush, 0, 0, nWidth, nHeight);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  /* Create source image/bitmap from hBitmap. */
  nStatus = GdipCreateBitmapFromHBITMAP(hBitmap, RT_NULL, &lpBitmap);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  /* Stretch. */
  nStatus = GdipDrawImageRectI(lpGraphics, lpBitmap, 0, 0, nWidth, nHeight);
  if (nStatus)
  {
    RtGdipSetLastErrorFromGpStatus(nStatus);
    goto handle_error;
  }

  bResult = RT_TRUE;
  goto free_resources;
handle_error:
  bResult = RT_FALSE;
free_resources:
  if (lpGraphics)
  {
    nStatus = GdipDeleteGraphics(lpGraphics);
    lpGraphics = RT_NULL;
    if (nStatus && bResult)
    {
      RtGdipSetLastErrorFromGpStatus(nStatus);
      goto handle_error;
    }
  }
  if (lpBitmap)
  {
    nStatus = GdipDisposeImage(lpBitmap);
    lpBitmap = RT_NULL;
    if (nStatus && bResult)
    {
      RtGdipSetLastErrorFromGpStatus(nStatus);
      goto handle_error;
    }
  }
  if (lpBrush)
  {
    nStatus = GdipDeleteBrush(lpBrush);
    lpBrush = RT_NULL;
    if (nStatus && bResult)
    {
      RtGdipSetLastErrorFromGpStatus(nStatus);
      goto handle_error;
    }
  }
  return bResult;
}
Example #2
0
void
win_emoji_show(int x, int y, wchar * efn, int elen, ushort lattr)
{
  GpStatus s;

  static GdiplusStartupInput gi = (GdiplusStartupInput){1, NULL, FALSE, FALSE};
  static ULONG_PTR gis = 0;
  if (!gis) {
    s = GdiplusStartup(&gis, &gi, NULL);
    gpcheck("startup", s);
  }

  bool use_stream = true;
  IStream * fs = 0;
  if (use_stream) {
    s = GdipCreateStreamOnFile(efn, 0 /* FileMode.Open */, &fs);
    gpcheck("stream", s);
  }
  else
    s = NotImplemented;

  GpImage * img = 0;
  if (s == Ok) {
    s = GdipLoadImageFromStream(fs, &img);
    gpcheck("load stream", s);
  }
  else {
    // This is reported to generate a memory leak, so rather use the stream.
    s = GdipLoadImageFromFile(efn, &img);
    gpcheck("load file", s);
  }

  int col = PADDING + x * cell_width;
  int row = PADDING + y * cell_height;
  if ((lattr & LATTR_MODE) >= LATTR_BOT)
    row -= cell_height;
  int w = elen * cell_width;
  if ((lattr & LATTR_MODE) != LATTR_NORM)
    w *= 2;
  int h = cell_height;
  if ((lattr & LATTR_MODE) >= LATTR_TOP)
    h *= 2;

  if (cfg.emoji_placement) {
    uint iw, ih;
    s = GdipGetImageWidth(img, &iw);
    gpcheck("width", s);
    s = GdipGetImageHeight(img, &ih);
    gpcheck("height", s);
    // consider aspect ratio so that ih/iw == h/w;
    // if EMPL_FULL, always adjust w
    // if ih/iw > h/w, make w smaller
    // if iw/ih > w/h, make h smaller
    if (cfg.emoji_placement == EMPL_FULL && ih * w != h * iw) {
      w = h * iw / ih;
    }
    else if (ih * w > h * iw) {
      int w0 = w;
      w = h * iw / ih;
      if (cfg.emoji_placement == EMPL_MIDDLE) {
        // horizontally center
        col += (w0 - w) / 2;
      }
    }
    else if (iw * h > w * ih) {
      int h0 = h;
      h = w * ih / iw;
      // vertically center
      row += (h0 - h) / 2;
    }
  }

  GpGraphics * gr;
  s = GdipCreateFromHDC(GetDC(wnd), &gr);
  gpcheck("hdc", s);
  s = GdipDrawImageRectI(gr, img, col, row, w, h);
  gpcheck("draw", s);
  s = GdipFlush(gr, FlushIntentionFlush);
  gpcheck("flush", s);

  s = GdipDeleteGraphics(gr);
  gpcheck("delete gr", s);
  s = GdipDisposeImage(img);
  gpcheck("dispose img", s);
  if (fs) {
    // Release stream resources, close file.
    fs->lpVtbl->Release(fs);
  }
}