// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/gfx/vector_device.h"

#include "base/gfx/bitmap_header.h"
#include "base/gfx/skia_utils.h"
#include "base/logging.h"
#include "base/scoped_handle.h"

#include "SkUtils.h"

namespace gfx {

VectorDevice* VectorDevice::create(HDC dc, int width, int height) {
  InitializeDC(dc);

  // Link the SkBitmap to the current selected bitmap in the device context.
  SkBitmap bitmap;
  HGDIOBJ selected_bitmap = GetCurrentObject(dc, OBJ_BITMAP);
  bool succeeded = false;
  if (selected_bitmap != NULL) {
    BITMAP bitmap_data;
    if (GetObject(selected_bitmap, sizeof(BITMAP), &bitmap_data) ==
        sizeof(BITMAP)) {
      // The context has a bitmap attached. Attach our SkBitmap to it.
      // Warning: If the bitmap gets unselected from the HDC, VectorDevice has
      // no way to detect this, so the HBITMAP could be released while SkBitmap
      // still has a reference to it. Be cautious.
      if (width == bitmap_data.bmWidth &&
          height == bitmap_data.bmHeight) {
        bitmap.setConfig(SkBitmap::kARGB_8888_Config,
                         bitmap_data.bmWidth,
                         bitmap_data.bmHeight,
                         bitmap_data.bmWidthBytes);
        bitmap.setPixels(bitmap_data.bmBits);
        succeeded = true;
      }
    }
  }

  if (!succeeded)
    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);

  return new VectorDevice(dc, bitmap);
}

VectorDevice::VectorDevice(HDC dc, const SkBitmap& bitmap)
    : PlatformDeviceWin(bitmap),
      hdc_(dc),
      previous_brush_(NULL),
      previous_pen_(NULL),
      offset_x_(0),
      offset_y_(0) {
  transform_.reset();
}

VectorDevice::~VectorDevice() {
  DCHECK(previous_brush_ == NULL);
  DCHECK(previous_pen_ == NULL);
}


void VectorDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
  // TODO(maruel):  Bypass the current transformation matrix.
  SkRect rect;
  rect.fLeft = 0;
  rect.fTop = 0;
  rect.fRight = SkIntToScalar(width() + 1);
  rect.fBottom = SkIntToScalar(height() + 1);
  drawRect(draw, rect, paint);
}

void VectorDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
                              size_t count, const SkPoint pts[],
                              const SkPaint& paint) {
  if (!count)
    return;

  if (mode == SkCanvas::kPoints_PointMode) {
    NOTREACHED();
    return;
  }

  SkPaint tmp_paint(paint);
  tmp_paint.setStyle(SkPaint::kStroke_Style);

  // Draw a path instead.
  SkPath path;
  switch (mode) {
    case SkCanvas::kLines_PointMode:
      if (count % 2) {
        NOTREACHED();
        return;
      }
      for (size_t i = 0; i < count / 2; ++i) {
        path.moveTo(pts[2 * i]);
        path.lineTo(pts[2 * i + 1]);
      }
      break;
    case SkCanvas::kPolygon_PointMode:
      path.moveTo(pts[0]);
      for (size_t i = 1; i < count; ++i) {
        path.lineTo(pts[i]);
      }
      break;
    default:
      NOTREACHED();
      return;
  }
  // Draw the calculated path.
  drawPath(draw, path, tmp_paint);
}

void VectorDevice::drawRect(const SkDraw& draw, const SkRect& rect,
                            const SkPaint& paint) {
  if (paint.getPathEffect()) {
    // Draw a path instead.
    SkPath path_orginal;
    path_orginal.addRect(rect);

    // Apply the path effect to the rect.
    SkPath path_modified;
    paint.getFillPath(path_orginal, &path_modified);

    // Removes the path effect from the temporary SkPaint object.
    SkPaint paint_no_effet(paint);
    paint_no_effet.setPathEffect(NULL)->safeUnref();

    // Draw the calculated path.
    drawPath(draw, path_modified, paint_no_effet);
    return;
  }

  if (!ApplyPaint(paint)) {
    return;
  }
  HDC dc = getBitmapDC();
  if (!Rectangle(dc, SkScalarRound(rect.fLeft),
                 SkScalarRound(rect.fTop),
                 SkScalarRound(rect.fRight),
                 SkScalarRound(rect.fBottom))) {
    NOTREACHED();
  }
  Cleanup();
}

void VectorDevice::drawPath(const SkDraw& draw, const SkPath& path,
                            const SkPaint& paint) {
  if (paint.getPathEffect()) {
    // Apply the path effect forehand.
    SkPath path_modified;
    paint.getFillPath(path, &path_modified);

    // Removes the path effect from the temporary SkPaint object.
    SkPaint paint_no_effet(paint);
    paint_no_effet.setPathEffect(NULL)->safeUnref();

    // Draw the calculated path.
    drawPath(draw, path_modified, paint_no_effet);
    return;
  }

  if (!ApplyPaint(paint)) {
    return;
  }
  HDC dc = getBitmapDC();
  PlatformDeviceWin::LoadPathToDC(dc, path);
  switch (paint.getStyle()) {
    case SkPaint::kFill_Style: {
      BOOL res = StrokeAndFillPath(dc);
      DCHECK(res != 0);
      break;
    }
    case SkPaint::kStroke_Style: {
      BOOL res = StrokePath(dc);
      DCHECK(res != 0);
      break;
    }
    case SkPaint::kStrokeAndFill_Style: {
      BOOL res = StrokeAndFillPath(dc);
      DCHECK(res != 0);
      break;
    }
    default:
      NOTREACHED();
      break;
  }
  Cleanup();
}

void VectorDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
                              const SkMatrix& matrix, const SkPaint& paint) {
  // Load the temporary matrix. This is what will translate, rotate and resize
  // the bitmap.
  SkMatrix actual_transform(transform_);
  actual_transform.preConcat(matrix);
  LoadTransformToDC(hdc_, actual_transform);

  InternalDrawBitmap(bitmap, 0, 0, paint);

  // Restore the original matrix.
  LoadTransformToDC(hdc_, transform_);
}

void VectorDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
                              int x, int y, const SkPaint& paint) {
  SkMatrix identity;
  identity.reset();
  LoadTransformToDC(hdc_, identity);

  InternalDrawBitmap(bitmap, x, y, paint);

  // Restore the original matrix.
  LoadTransformToDC(hdc_, transform_);
}

void VectorDevice::drawText(const SkDraw& draw, const void* text, size_t byteLength,
                            SkScalar x, SkScalar y, const SkPaint& paint) {
  // This function isn't used in the code. Verify this assumption.
  NOTREACHED();
}

void VectorDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
                               const SkScalar pos[], SkScalar constY,
                               int scalarsPerPos, const SkPaint& paint) {
  // This function isn't used in the code. Verify this assumption.
  NOTREACHED();
}

void VectorDevice::drawTextOnPath(const SkDraw& draw, const void* text,
                                  size_t len,
                                  const SkPath& path, const SkMatrix* matrix,
                                  const SkPaint& paint) {
  // This function isn't used in the code. Verify this assumption.
  NOTREACHED();
}

void VectorDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
                                int vertexCount,
                                const SkPoint vertices[], const SkPoint texs[],
                                const SkColor colors[], SkXfermode* xmode,
                                const uint16_t indices[], int indexCount,
                                const SkPaint& paint) {
  // This function isn't used in the code. Verify this assumption.
  NOTREACHED();
}

void VectorDevice::drawDevice(const SkDraw& draw, SkDevice* device, int x,
                              int y, const SkPaint& paint) {
  // TODO(maruel):  http://b/1183870 Playback the EMF buffer at printer's dpi if
  // it is a vectorial device.
  drawSprite(draw, device->accessBitmap(false), x, y, paint);
}

bool VectorDevice::ApplyPaint(const SkPaint& paint) {
  // Note: The goal here is to transfert the SkPaint's state to the HDC's state.
  // This function does not execute the SkPaint drawing commands. These should
  // be executed in drawPaint().

  SkPaint::Style style = paint.getStyle();
  if (!paint.getAlpha())
    style = SkPaint::kStyleCount;

  switch (style) {
    case SkPaint::kFill_Style:
      if (!CreateBrush(true, paint) ||
          !CreatePen(false, paint))
        return false;
      break;
    case SkPaint::kStroke_Style:
      if (!CreateBrush(false, paint) ||
          !CreatePen(true, paint))
        return false;
      break;
    case SkPaint::kStrokeAndFill_Style:
      if (!CreateBrush(true, paint) ||
          !CreatePen(true, paint))
        return false;
      break;
    default:
      if (!CreateBrush(false, paint) ||
          !CreatePen(false, paint))
        return false;
      break;
  }

  /*
  getFlags();
    isAntiAlias();
    isDither()
    isLinearText()
    isSubpixelText()
    isUnderlineText()
    isStrikeThruText()
    isFakeBoldText()
    isDevKernText()
    isFilterBitmap()

  // Skia's text is not used. This should be fixed.
  getTextAlign()
  getTextScaleX()
  getTextSkewX()
  getTextEncoding()
  getFontMetrics()
  getFontSpacing()
  */

  // BUG 1094907: Implement shaders. Shaders currently in use:
  //  SkShader::CreateBitmapShader
  //  SkGradientShader::CreateRadial
  //  SkGradientShader::CreateLinear
  // DCHECK(!paint.getShader());

  // http://b/1106647 Implement loopers and mask filter. Looper currently in
  // use:
  //   SkBlurDrawLooper is used for shadows.
  // DCHECK(!paint.getLooper());
  // DCHECK(!paint.getMaskFilter());

  // http://b/1165900 Implement xfermode.
  // DCHECK(!paint.getXfermode());

  // The path effect should be processed before arriving here.
  DCHECK(!paint.getPathEffect());

  // These aren't used in the code. Verify this assumption.
  DCHECK(!paint.getColorFilter());
  DCHECK(!paint.getRasterizer());
  // Reuse code to load Win32 Fonts.
  DCHECK(!paint.getTypeface());
  return true;
}

void VectorDevice::setMatrixClip(const SkMatrix& transform,
                                 const SkRegion& region) {
  transform_ = transform;
  LoadTransformToDC(hdc_, transform_);
  clip_region_ = region;
  if (!clip_region_.isEmpty())
    LoadClipRegion();
}

void VectorDevice::setDeviceOffset(int x, int y) {
  offset_x_ = x;
  offset_y_ = y;
}

void VectorDevice::drawToHDC(HDC dc, int x, int y, const RECT* src_rect) {
  NOTREACHED();
}

void VectorDevice::LoadClipRegion() {
  // We don't use transform_ for the clipping region since the translation is
  // already applied to offset_x_ and offset_y_.
  SkMatrix t;
  t.reset();
  t.postTranslate(SkIntToScalar(-offset_x_), SkIntToScalar(-offset_y_));
  LoadClippingRegionToDC(hdc_, clip_region_, t);
}

bool VectorDevice::CreateBrush(bool use_brush, COLORREF color) {
  DCHECK(previous_brush_ == NULL);
  // We can't use SetDCBrushColor() or DC_BRUSH when drawing to a EMF buffer.
  // SetDCBrushColor() calls are not recorded at all and DC_BRUSH will use
  // WHITE_BRUSH instead.

  if (!use_brush) {
    // Set the transparency.
    if (0 == SetBkMode(hdc_, TRANSPARENT)) {
      NOTREACHED();
      return false;
    }

    // Select the NULL brush.
    previous_brush_ = SelectObject(GetStockObject(NULL_BRUSH));
    return previous_brush_ != NULL;
  }

  // Set the opacity.
  if (0 == SetBkMode(hdc_, OPAQUE)) {
    NOTREACHED();
    return false;
  }

  // Create and select the brush.
  previous_brush_ = SelectObject(CreateSolidBrush(color));
  return previous_brush_ != NULL;
}

bool VectorDevice::CreatePen(bool use_pen, COLORREF color, int stroke_width,
                             float stroke_miter, DWORD pen_style) {
  DCHECK(previous_pen_ == NULL);
  // We can't use SetDCPenColor() or DC_PEN when drawing to a EMF buffer.
  // SetDCPenColor() calls are not recorded at all and DC_PEN will use BLACK_PEN
  // instead.

  // No pen case
  if (!use_pen) {
    previous_pen_ = SelectObject(GetStockObject(NULL_PEN));
    return previous_pen_ != NULL;
  }

  // Use the stock pen if the stroke width is 0.
  if (stroke_width == 0) {
    // Create a pen with the right color.
    previous_pen_ = SelectObject(::CreatePen(PS_SOLID, 0, color));
    return previous_pen_ != NULL;
  }

  // Load a custom pen.
  LOGBRUSH brush;
  brush.lbStyle = BS_SOLID;
  brush.lbColor = color;
  brush.lbHatch = 0;
  HPEN pen = ExtCreatePen(pen_style, stroke_width, &brush, 0, NULL);
  DCHECK(pen != NULL);
  previous_pen_ = SelectObject(pen);
  if (previous_pen_ == NULL)
    return false;

  if (!SetMiterLimit(hdc_, stroke_miter, NULL)) {
    NOTREACHED();
    return false;
  }
  return true;
}

void VectorDevice::Cleanup() {
  if (previous_brush_) {
    HGDIOBJ result = SelectObject(previous_brush_);
    previous_brush_ = NULL;
    if (result) {
      BOOL res = DeleteObject(result);
      DCHECK(res != 0);
    }
  }
  if (previous_pen_) {
    HGDIOBJ result = SelectObject(previous_pen_);
    previous_pen_ = NULL;
    if (result) {
      BOOL res = DeleteObject(result);
      DCHECK(res != 0);
    }
  }
  // Remove any loaded path from the context.
  AbortPath(hdc_);
}

HGDIOBJ VectorDevice::SelectObject(HGDIOBJ object) {
  HGDIOBJ result = ::SelectObject(hdc_, object);
  DCHECK(result != HGDI_ERROR);
  if (result == HGDI_ERROR)
    return NULL;
  return result;
}

bool VectorDevice::CreateBrush(bool use_brush, const SkPaint& paint) {
  // Make sure that for transparent color, no brush is used.
  if (paint.getAlpha() == 0) {
    // Test if it ever happen.
    NOTREACHED();
    use_brush = false;
  }

  return CreateBrush(use_brush, SkColorToCOLORREF(paint.getColor()));
}

bool VectorDevice::CreatePen(bool use_pen, const SkPaint& paint) {
  // Make sure that for transparent color, no pen is used.
  if (paint.getAlpha() == 0) {
    // Test if it ever happen.
    NOTREACHED();
    use_pen = false;
  }

  DWORD pen_style = PS_GEOMETRIC | PS_SOLID;
  switch (paint.getStrokeJoin()) {
    case SkPaint::kMiter_Join:
      // Connects path segments with a sharp join.
      pen_style |= PS_JOIN_MITER;
      break;
    case SkPaint::kRound_Join:
      // Connects path segments with a round join.
      pen_style |= PS_JOIN_ROUND;
      break;
    case SkPaint::kBevel_Join:
      // Connects path segments with a flat bevel join.
      pen_style |= PS_JOIN_BEVEL;
      break;
    default:
      NOTREACHED();
      break;
  }
  switch (paint.getStrokeCap()) {
    case SkPaint::kButt_Cap:
      // Begin/end contours with no extension.
      pen_style |= PS_ENDCAP_FLAT;
      break;
    case SkPaint::kRound_Cap:
      // Begin/end contours with a semi-circle extension.
      pen_style |= PS_ENDCAP_ROUND;
      break;
    case SkPaint::kSquare_Cap:
      // Begin/end contours with a half square extension.
      pen_style |= PS_ENDCAP_SQUARE;
      break;
    default:
      NOTREACHED();
      break;
  }

  return CreatePen(use_pen,
                   SkColorToCOLORREF(paint.getColor()),
                   SkScalarRound(paint.getStrokeWidth()),
                   paint.getStrokeMiter(),
                   pen_style);
}

void VectorDevice::InternalDrawBitmap(const SkBitmap& bitmap, int x, int y,
                                      const SkPaint& paint) {
  uint8 alpha = paint.getAlpha();
  if (alpha == 0)
    return;

  bool is_translucent;
  if (alpha != 255) {
    // ApplyPaint expect an opaque color.
    SkPaint tmp_paint(paint);
    tmp_paint.setAlpha(255);
    if (!ApplyPaint(tmp_paint))
      return;
    is_translucent = true;
  } else {
    if (!ApplyPaint(paint))
      return;
    is_translucent = false;
  }
  int src_size_x = bitmap.width();
  int src_size_y = bitmap.height();
  if (!src_size_x || !src_size_y)
    return;

  // Create a BMP v4 header that we can serialize.
  BITMAPV4HEADER bitmap_header;
  gfx::CreateBitmapV4Header(src_size_x, src_size_y, &bitmap_header);
  HDC dc = getBitmapDC();
  SkAutoLockPixels lock(bitmap);
  DCHECK_EQ(bitmap.getConfig(), SkBitmap::kARGB_8888_Config);
  const uint32_t* pixels = static_cast<const uint32_t*>(bitmap.getPixels());
  if (pixels == NULL) {
    NOTREACHED();
    return;
  }

  if (!is_translucent) {
    int row_length = bitmap.rowBytesAsPixels();
    // There is no quick way to determine if an image is opaque.
    for (int y2 = 0; y2 < src_size_y; ++y2) {
      for (int x2 = 0; x2 < src_size_x; ++x2) {
        if (SkColorGetA(pixels[(y2 * row_length) + x2]) != 255) {
          is_translucent = true;
          y2 = src_size_y;
          break;
        }
      }
    }
  }

  BITMAPINFOHEADER hdr;
  gfx::CreateBitmapHeader(src_size_x, src_size_y, &hdr);
  if (is_translucent) {
    // The image must be loaded as a bitmap inside a device context.
    ScopedHDC bitmap_dc(::CreateCompatibleDC(dc));
    void* bits = NULL;
    ScopedBitmap hbitmap(::CreateDIBSection(
        bitmap_dc, reinterpret_cast<const BITMAPINFO*>(&hdr),
        DIB_RGB_COLORS, &bits, NULL, 0));
    memcpy(bits, pixels, bitmap.getSize());
    DCHECK(hbitmap);
    HGDIOBJ old_bitmap = ::SelectObject(bitmap_dc, hbitmap);
    DeleteObject(old_bitmap);

    // After some analysis of IE7's behavior, this is the thing to do. I was
    // sure IE7 was doing so kind of bitmasking due to the way translucent image
    // where renderered but after some windbg tracing, it is being done by the
    // printer driver after all (mostly HP printers). IE7 always use AlphaBlend
    // for bitmasked images. The trick seems to switch the stretching mode in
    // what the driver expects.
    DWORD previous_mode = GetStretchBltMode(dc);
    BOOL result = SetStretchBltMode(dc, COLORONCOLOR);
    DCHECK(result);
    // Note that this function expect premultiplied colors (!)
    BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
    result = AlphaBlend(dc,
                        x, y,  // Destination origin.
                        src_size_x, src_size_y,  // Destination size.
                        bitmap_dc,
                        0, 0,  // Source origin.
                        src_size_x, src_size_y,  // Source size.
                        blend_function);
    DCHECK(result);
    result = SetStretchBltMode(dc, previous_mode);
    DCHECK(result);
  } else {
    BOOL result = StretchDIBits(dc,
                                x, y,  // Destination origin.
                                src_size_x, src_size_y,
                                0, 0,  // Source origin.
                                src_size_x, src_size_y,  // Source size.
                                pixels,
                                reinterpret_cast<const BITMAPINFO*>(&hdr),
                                DIB_RGB_COLORS,
                                SRCCOPY);
    DCHECK(result);
  }
  Cleanup();
}

}  // namespace gfx

