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 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/*
GlyphBuffer Example
*/
#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>
#include <ClanLib/gl.h>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
void gen_circle_text(CL_GlyphBuffer& gb)
{
//Use 0,0 as the center of the circle
//It doesnt really matter where we put the center, as drawing the GlyphBuffer into a rect aligns its contents
const CL_Point circle_center(0, 0);
//Use 150 as the initial diameter
const int diameter = 150;
//We move glyphs around by messing the glyphs vector within the GlyphBuffer
//This vector which contains each character and its position
vector<CL_GlyphBuffer::Glyph>& glyphs = gb.get_glyphs();
const int glyphs_count = glyphs.size();
//And we rotate each character by using the angle effects map in GlyphBuffer
//This map lets you set each glyph's individual angle
map<int, float>& angle_effects = gb.get_angle_effects();
//Find the average of the widths of every glyph
float avg = 0.0;
int x;
for (x = 0; x < glyphs_count; ++x)
avg += (float)(gb.get_font_for(x)->second.get_width(glyphs[x].character));
avg /= (float)glyphs_count;
//The current distance around the circle
float angle = 0.0;
//Rearrange the glyphs around the center, by moving and rotating each glyph to its new position
for (x = 0; x < glyphs_count; ++x)
{
unsigned char letter = glyphs[x].character; //The character for the current glyph
float glyph_width = (float)(gb.get_font_for(x)->second.get_width(letter)); //The width of the current glyph
//Our initial position is 0 degrees along the circle's edge, directly above the center
CL_Point new_pos(circle_center.x, circle_center.y - diameter);
//Rotate the glyph around the circle to our currently calculated angle
glyphs[x].pos = new_pos.rotate(circle_center, angle);
//Change the glyph's drawing angle
angle_effects[x] = angle;
//Advance around the circle for this glyph, after having drawn it
angle += (glyph_width/avg)*(360/glyphs_count);
}
}
class GlyphBufferApp : public CL_ClanApplication
{
public:
int main(int, char **)
{
try
{
CL_SetupCore setup_core;
CL_SetupDisplay setup_display;
CL_SetupGL setup_gl;
CL_ResourceManager resources("glyphbuffer.xml");
CL_DisplayWindow window("ClanLib GlyphBuffer Example", 640, 480);
CL_Rect screen_rect(0, 0, 640, 480);
//Load the font from the resource "Font" in the resources file
CL_Font font("Font", &resources);
//Create a GlyphBuffer, and render some text into it
CL_GlyphBuffer gb;
gb.set_alignment(origin_center);
std::string message;
message += "A and D to rotate, W and S to resize, ";
message += "R to reset, Esc to quit. ClanLib: Phear the Power!";
font.draw_to_gb(message, gb, CL_Size(0,0));
//Post process the text so that it's circular
gen_circle_text(gb);
//Scale the GlyphBuffer so that it fills the window vertically
float initial_scale = (float)screen_rect.get_height()/(float)gb.get_height();
gb.set_scale(initial_scale, initial_scale);
// Connect the Window close event
CL_Slot slot_quit = window.sig_window_close().connect(this, &GlyphBufferApp::on_window_close);
quit = false;
while(!CL_Keyboard::get_keycode(CL_KEY_ESCAPE) && !quit)
{
CL_Display::clear(CL_Color::white);
//Reset the circle to its initial state
if (CL_Keyboard::get_keycode(CL_KEY_R)) {
gb.set_angle(0);
gb.set_scale(initial_scale, initial_scale);
}
//Use the GlyphBuffer rotation property to rotate the glyphs when drawn
if (CL_Keyboard::get_keycode(CL_KEY_A))
gb.rotate(-0.5);
if (CL_Keyboard::get_keycode(CL_KEY_D))
gb.rotate(0.5);
//Alter the diameter if requested, using the GlyphBuffer scale proprety
if (CL_Keyboard::get_keycode(CL_KEY_W))
{
float gbscale_x, gbscale_y;
gb.get_scale(gbscale_x, gbscale_y);
gb.set_scale(gbscale_x + 0.01f, gbscale_y + 0.01f);
}
if (CL_Keyboard::get_keycode(CL_KEY_S))
{
float gbscale_x, gbscale_y;
gb.get_scale(gbscale_x, gbscale_y);
if (gbscale_x > 0.01f)
gb.set_scale(gbscale_x - 0.01f, gbscale_y - 0.01f);
}
//Draw the GlyphBuffer centered on-screen (we set gb's alignment to center above)
gb.draw(screen_rect);
CL_Display::flip();
CL_System::keep_alive(15);
}
}
catch (CL_Error err)
{
std::cout << "Exception caught: " << err.message.c_str() << std::endl;
return -1;
}
return 0;
}
private:
void on_window_close()
{
quit = true;
}
bool quit;
} app;
|