summaryrefslogtreecommitdiffstats
path: root/widget/windows/WindowsEMF.h
blob: 3a7a20173c01222a19ab2dc95f9096c4d972c7c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_WIDGET_WINDOWSEMF_H
#define MOZILLA_WIDGET_WINDOWSEMF_H

/* include windows.h for the HDC definitions that we need. */
#include <windows.h>

namespace mozilla {
namespace widget {

/**
 * Windows Enhance Metafile: https://en.wikipedia.org/wiki/Windows_Metafile
 * A metafile, also called a vector image, is an image that is stored as a
 * sequence of drawing commands and settings. The commands and settings
 * recorded in a Metafile object can be stored in memory or saved to a file.
 *
 * The metafile device context is used for all drawing operations required to
 * create the picture. When the system processes a GDI function associated with
 * a metafile DC, it converts the function into the appropriate data and stores
 * this data in a record appended to the metafile.
 */
class WindowsEMF {
 public:
  WindowsEMF();
  ~WindowsEMF();

  /**
   * Initializes the object with the path of a file where the EMF data stream
   * should be stored. Callers are then expected to call GetDC() to draw output
   * before going on to call Playback() or SaveToFile() to generate the EMF
   * output.
   */
  bool InitForDrawing(const wchar_t* aMetafilePath = nullptr);

  /**
   * Initializes the object with an existing EMF file. Consumers cannot use
   * GetDC() to obtain an HDC to modify the file. They can only use Playback().
   */
  bool InitFromFileContents(const wchar_t* aMetafilePath);

  /**
   * Creates the EMF from the specified data
   *
   * @param aByte Pointer to a buffer that contains EMF data.
   * @param aSize Specifies the size, in bytes, of aByte.
   */
  bool InitFromFileContents(PBYTE aBytes, UINT aSize);

  /**
   * If this object was initiaziled using InitForDrawing() then this function
   * returns an HDC that can be drawn to generate the EMF output. Otherwise it
   * returns null. After finishing with the HDC, consumers could call Playback()
   * to draw EMF onto the given DC or call SaveToFile() to finish writing the
   * EMF file.
   */
  HDC GetDC() const {
    MOZ_ASSERT(mDC,
               "GetDC can be used only after "
               "InitForDrawing/ InitFromFileContents and before"
               "Playback/ SaveToFile");
    return mDC;
  }

  /**
   * Play the EMF's drawing commands onto the given DC.
   */
  bool Playback(HDC aDeviceContext, const RECT& aRect);

  /**
   * Called to generate the EMF file once a consumer has finished drawing to
   * the HDC returned by GetDC(), if initializes the object with the path of a
   * file.
   */
  bool SaveToFile();

  /**
   * Return the size of the enhanced metafile, in bytes.
   */
  UINT GetEMFContentSize();

  /**
   * Retrieves the contents of the EMF and copies them into a buffer.
   *
   * @param aByte the buffer to receive the data.
   */
  bool GetEMFContentBits(PBYTE aBytes);

 private:
  WindowsEMF(const WindowsEMF& aEMF) = delete;
  bool FinishDocument();
  void ReleaseEMFHandle();
  void ReleaseAllResource();

  /* Compiled EMF data handle. */
  HENHMETAFILE mEmf;
  HDC mDC;
};

}  // namespace widget
}  // namespace mozilla

#endif /* MOZILLA_WIDGET_WINDOWSEMF_H */