Anti-Grain Geometry Tutorial
tutorial_path_3.cpp
1 /*
2  * Copyright (c) 2019 Heng Yuan
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <agg_pixfmt_rgba.h>
17 #include <agg_rasterizer_scanline_aa.h>
18 #include <agg_renderer_base.h>
19 #include <agg_renderer_scanline.h>
20 #include <agg_scanline_p.h>
21 
22 #include "path.h"
23 #include "writepng.h"
24 
25 int
26 main (int argc, const char* argv[])
27 {
28  try
29  {
30  const int imageWidth = 100;
31  const int imageHeight = 100;
32 
35 
36  const int pixelSize = PixelFormat::pix_width;
37 
38  agg::rendering_buffer renderBuffer;
39  PixelFormat pixFmt;
40  RendererBaseType rBase;
41 
42  unsigned char *imageBuffer = new unsigned char[imageWidth * imageHeight * pixelSize];
43 
44  // Hook everything up
45  renderBuffer.attach (imageBuffer, imageWidth, imageHeight, imageWidth * pixelSize);
46  pixFmt.attach(renderBuffer);
47  rBase.attach(pixFmt);
48 
49  const agg::rgba8 transparentWhiteColor (0xff, 0xff, 0xff, 0);
50  const agg::rgba8 redColor (0xff, 0, 0, 0xff);
51 
52  // clear the buffer with transparent white color
53  rBase.clear(transparentWhiteColor);
54 
56  agg::scanline_p8 scanline;
57 
58  ras.auto_close(false);
59 
60  {
61  // draw a square with a square hole
62  CmdVertex squares[] =
63  {
64  // outer square is CW
65  { agg::path_cmd_move_to, 10, 10 },
66  { agg::path_cmd_line_to, 90, 10 },
67  { agg::path_cmd_line_to, 90, 90 },
68  { agg::path_cmd_line_to, 10, 90 },
69  { agg::path_cmd_line_to, 10, 10 },
70 
71  // inner square is also CW
72  { agg::path_cmd_move_to, 30, 30 },
73  { agg::path_cmd_line_to, 70, 30 },
74  { agg::path_cmd_line_to, 70, 70 },
75  { agg::path_cmd_line_to, 30, 70 },
76  { agg::path_cmd_line_to, 30, 30 },
77  };
78 
79  // We need to make sure the inner square has a
80  // different ordering from the outer square.
81  //
82  // If the outer square is CCW, then the inner
83  // square needs to be CW in order to properly
84  // show the hole.
85  //
86  // Likewise, if the outer square is CW, then
87  // the inner square needs to be CCW.
88 
89  // In this case, we only need to swap vertex 6 and 8
90  // to change the inner square to be CCW
91  CmdVertex tmp = squares[6];
92  squares[6] = squares[8];
93  squares[8] = tmp;
94 
95  CmdVertexPath path (squares, sizeof(squares) / sizeof(CmdVertex));
96 
97  ras.reset();
98  ras.add_path(path);
99 
100  agg::render_scanlines_aa_solid(ras, scanline, rBase, redColor);
101  }
102 
103  // now write the image out for visualization
104  char fileName[1000] = { 0 };
105  if (argc > 1)
106  {
107  sprintf (fileName, "%s/", argv[1]);
108  }
109  strcat(fileName, "tutorial_path_3.png");
110  writePng<RendererBaseType> (fileName, rBase);
111 
112  delete imageBuffer;
113  }
114  catch (TutorialException& ex)
115  {
116  printf ("%s\n", ex.getMessage());
117  return 1;
118  }
119  catch (...)
120  {
121  printf ("Unknown exception detected.\n");
122  return 1;
123  }
124 
125  return 0;
126 }
Definition: path.h:76