// Copyright (c) 2012 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.

#ifndef PRINTING_EMF_WIN_H_
#define PRINTING_EMF_WIN_H_

#include <stddef.h>
#include <stdint.h>
#include <windows.h>

#include <memory>
#include <vector>

#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "printing/metafile.h"

namespace base {
class FilePath;
}

namespace gfx {
class Rect;
class Size;
}  // namespace gfx

namespace printing {

// Simple wrapper class that manage an EMF data stream and its virtual HDC.
class COMPONENT_EXPORT(PRINTING_METAFILE) Emf : public Metafile {
 public:
  class Record;
  class Enumerator;
  struct EnumerationContext;

  // Generates a virtual HDC that will record every GDI commands and compile
  // it in a EMF data stream.
  Emf();
  Emf(const Emf&) = delete;
  Emf& operator=(const Emf&) = delete;
  ~Emf() override;

  // Closes metafile.
  void Close();

  // Generates a new metafile that will record every GDI command, and will
  // be saved to `metafile_path`.
  bool InitToFile(const base::FilePath& metafile_path);

  // Initializes the Emf with the data in `metafile_path`.
  bool InitFromFile(const base::FilePath& metafile_path);

  // Metafile methods.
  bool Init() override;
  bool InitFromData(base::span<const uint8_t> data) override;

  // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
  // (since StartPage and EndPage do not work in a metafile DC). Only valid
  // when hdc_ is non-NULL. `page_size`, `content_area`, and `scale_factor` are
  // ignored.
  void StartPage(const gfx::Size& page_size,
                 const gfx::Rect& content_area,
                 float scale_factor,
                 mojom::PageOrientation page_orientation) override;
  bool FinishPage() override;
  bool FinishDocument() override;

  uint32_t GetDataSize() const override;
  bool GetData(void* buffer, uint32_t size) const override;
  bool ShouldCopySharedMemoryRegionData() const override;
  mojom::MetafileDataType GetDataType() const override;

  // Should be passed to Playback to keep the exact same size.
  gfx::Rect GetPageBounds(unsigned int page_number) const override;

  unsigned int GetPageCount() const override;
  HDC context() const override;
  bool Playback(HDC hdc, const RECT* rect) const override;
  bool SafePlayback(HDC hdc) const override;

  HENHMETAFILE emf() const { return emf_; }

 private:
  FRIEND_TEST_ALL_PREFIXES(EmfTest, DC);
  FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak);
  FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedEmf);

  // Playbacks safely one EMF record.
  static int CALLBACK SafePlaybackProc(HDC hdc,
                                       HANDLETABLE* handle_table,
                                       const ENHMETARECORD* record,
                                       int objects_count,
                                       LPARAM param);

  // Compiled EMF data handle.
  HENHMETAFILE emf_;

  // Valid when generating EMF data through a virtual HDC.
  HDC hdc_;
};

struct Emf::EnumerationContext {
  EnumerationContext();

  raw_ptr<HANDLETABLE> handle_table;
  int objects_count;
  HDC hdc;
  raw_ptr<const XFORM> base_matrix;
  int dc_on_page_start;
};

// One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_.
// The entries become invalid once Emf::CloseEmf() is called.
class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Record {
 public:
  // Plays the record.
  bool Play(EnumerationContext* context) const;

  // Plays the record working around quirks with SetLayout,
  // SetWorldTransform and ModifyWorldTransform. See implementation for details.
  bool SafePlayback(EnumerationContext* context) const;

  // Access the underlying EMF record.
  const ENHMETARECORD* record() const { return record_; }

 protected:
  explicit Record(const ENHMETARECORD* record);

 private:
  friend class Emf;
  friend class Enumerator;
  const ENHMETARECORD* record_;
};

// Retrieves individual records out of a Emf buffer. The main use is to skip
// over records that are unsupported on a specific printer or to play back
// only a part of an EMF buffer.
class COMPONENT_EXPORT(PRINTING_METAFILE) Emf::Enumerator {
 public:
  // Iterator type used for iterating the records.
  typedef std::vector<Record>::const_iterator const_iterator;

  // Enumerates the records at construction time. `hdc` and `rect` are
  // both optional at the same time or must both be valid.
  // Warning: `emf` must be kept valid for the time this object is alive.
  Enumerator(const Emf& emf, HDC hdc, const RECT* rect);
  Enumerator(const Enumerator&) = delete;
  Enumerator& operator=(const Enumerator&) = delete;
  ~Enumerator();

  // Retrieves the first Record.
  const_iterator begin() const;

  // Retrieves the end of the array.
  const_iterator end() const;

 private:
  FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate);

  // Processes one EMF record and saves it in the items_ array.
  static int CALLBACK EnhMetaFileProc(HDC hdc,
                                      HANDLETABLE* handle_table,
                                      const ENHMETARECORD* record,
                                      int objects_count,
                                      LPARAM param);

  // The collection of every EMF records in the currently loaded EMF buffer.
  // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by
  // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called.
  std::vector<Record> items_;

  EnumerationContext context_;
};

}  // namespace printing

#endif  // PRINTING_EMF_WIN_H_
