forked from microsoft/Xbox-ATG-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGGO_Glyph.h
142 lines (116 loc) · 3.81 KB
/
GGO_Glyph.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//--------------------------------------------------------------------------------------
// GGO_Glyph.h
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include <stdint.h>
#include <memory>
#include <Windows.h>
namespace ATG
{
// --------------------------------------------------------------------------------
// GGO_Glyph
// a glyph helper class based on GetGlyphOutline
// --------------------------------------------------------------------------------
class GGO_Glyph
{
public:
GGO_Glyph();
GGO_Glyph(HDC hdc, wchar_t wc, uint32_t ggoFormat);
GGO_Glyph(const GGO_Glyph&) = delete;
GGO_Glyph &operator=(const GGO_Glyph&) = delete;
GGO_Glyph(GGO_Glyph &&moveFrom);
GGO_Glyph &operator=(GGO_Glyph &&moveFrom);
uint32_t GetGGOFormat() const
{
return m_ggoFormat;
}
uint32_t GetCharacterCode() const
{
return m_character;
}
const GLYPHMETRICS &GetMetrics() const
{
return m_glyphMetrics;
}
uint8_t *GetPixels() const
{
return m_spritePixels.get();
}
unsigned GetBufferSize() const
{
return m_bufferSize;
}
template<typename ACTION_T>
void ForEachPixel(ACTION_T fn) const
{
if (m_ggoFormat == GGO_BITMAP)
{
ForEach_GGO_Pixel(fn);
}
else
{
ForEach_GGO_GRAY_N_Pixel(fn);
}
}
private:
template <typename ACTION_T>
void ForEach_GGO_Pixel(ACTION_T fn) const
{
const unsigned rows = m_glyphMetrics.gmBlackBoxY;
const unsigned cols = m_glyphMetrics.gmBlackBoxX;
const unsigned doubleWordsPerRow = GetStorageSize<uint32_t>(cols);
const unsigned bytesPerRow = doubleWordsPerRow * 4;
uint8_t *srcByte = m_spritePixels.get();
if (srcByte == nullptr)
{
return;
}
for (unsigned row = 0; row < rows; ++row)
{
unsigned col = 0;
for (unsigned b = 0; b < bytesPerRow; ++b)
{
for (int shift = 7; shift >= 0; --shift)
{
if (col >= cols)
break;
uint8_t clr = (((srcByte[b]) >> shift) & 0x1) * 0xFF;
fn(col, row, clr);
++col;
}
if (col >= cols)
break;
}
srcByte += bytesPerRow;
}
}
template <typename ACTION_T>
void ForEach_GGO_GRAY_N_Pixel(ACTION_T fn) const
{
unsigned rows = m_glyphMetrics.gmBlackBoxY;
unsigned cols = m_glyphMetrics.gmBlackBoxX;
unsigned stride = m_bufferSize / rows;
uint8_t *srcPixels = m_spritePixels.get();
if (srcPixels == nullptr)
{
return;
}
for (unsigned i = 0; i < cols; ++i)
{
for (unsigned j = 0; j < rows; ++j)
{
uint8_t clr = srcPixels[i + j * stride];
fn(i, j, clr);
}
}
}
uint32_t m_ggoFormat;
uint32_t m_character;
GLYPHMETRICS m_glyphMetrics;
std::unique_ptr<uint8_t[]> m_spritePixels;
unsigned m_bufferSize;
};
} // namespace ATG