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
|
#include "tile_page.h"
#include "tile_colour.h"
#include "tile.h"
tile_page::tile_page() : m_width(1024), m_height(0)
{
}
tile_page::~tile_page()
{
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
delete m_tiles[i];
}
m_tiles.clear();
m_counts.clear();
}
bool tile_page::place_images()
{
// locate all the tiles on the page, so we can determine its size
// and the tex coords.
m_offsets.clear();
m_texcoords.clear();
int ymin, ycur, ymax;
int xmin, xcur, xmax;
ymin = ycur = ymax = xmin = xcur = xmax = 0;
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
int ofs_x, ofs_y, tilew, tileh;
if (m_tiles[i]->shrink())
{
m_tiles[i]->get_bounding_box(ofs_x, ofs_y, tilew, tileh);
}
else
{
ofs_x = 0;
ofs_y = 0;
tilew = m_tiles[i]->width();
tileh = m_tiles[i]->height();
}
m_offsets.push_back(ofs_x);
m_offsets.push_back(ofs_y);
m_offsets.push_back(m_tiles[i]->width());
m_offsets.push_back(m_tiles[i]->height());
if (xcur + tilew > m_width)
{
ycur = ymin = ymax;
xcur = xmin = xmax = 0;
}
if (tileh + ycur >= ymax)
{
if (ycur != ymin)
{
ycur = ymin;
xcur = xmax;
xmin = xmax = xcur;
}
if (xcur + tilew > m_width)
{
ycur = ymin = ymax;
xcur = xmin = xmax = 0;
}
if (ycur == ymin)
{
ymax = std::max(ymin + (int)tileh, ymax);
}
}
m_height = ymax;
m_texcoords.push_back(xcur);
m_texcoords.push_back(ycur);
m_texcoords.push_back(xcur + tilew);
m_texcoords.push_back(ycur + tileh);
// Only add downwards, stretching out xmax as we go.
xmax = std::max(xmax, xcur + (int)tilew);
xcur = xmin;
ycur += tileh;
}
return true;
}
bool tile_page::write_image(const char *filename)
{
if (m_width * m_height <= 0)
{
fprintf(stderr, "Error: failed to write image. No images placed?\n");
return false;
}
tile_colour *pixels = new tile_colour[m_width * m_height];
memset(pixels, 0, m_width * m_height * sizeof(tile_colour));
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
int sx = m_texcoords[i*4];
int sy = m_texcoords[i*4+1];
int ex = m_texcoords[i*4+2];
int ey = m_texcoords[i*4+3];
int wx = ex - sx;
int wy = ey - sy;
int ofs_x = m_offsets[i*4];
int ofs_y = m_offsets[i*4+1];
for (int y = 0; y < wy; y++)
{
for (int x = 0; x < wx; x++)
{
tile_colour &dest = pixels[(sx+x) + (sy+y)*m_width];
tile_colour &src = m_tiles[i]->get_pixel(ofs_x+x, ofs_y+y);
dest = src;
}
}
}
bool success = write_png(filename, pixels, m_width, m_height);
delete[] pixels;
return success;
}
|