|
Packit Service |
e3b512 |
#include <cairomm/cairomm.h>
|
|
Packit Service |
e3b512 |
#include <iostream>
|
|
Packit Service |
e3b512 |
#include <map>
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
const double HEIGHT = 200.0;
|
|
Packit Service |
e3b512 |
const double WIDTH = 400.0;
|
|
Packit Service |
e3b512 |
const double FONT_SIZE = 64.0;
|
|
Packit Service |
e3b512 |
const double TEXT_ORIGIN_Y = (HEIGHT / 2.0) + (FONT_SIZE / 2.0);
|
|
Packit Service |
e3b512 |
const double TEXT_ORIGIN_X = 50.0; // arbitrary
|
|
Packit Service |
e3b512 |
const double GLYPH_SPACING = 0.1;
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
struct GlyphBounds
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
unsigned long glyph;
|
|
Packit Service |
e3b512 |
double width;
|
|
Packit Service |
e3b512 |
double height;
|
|
Packit Service |
e3b512 |
};
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
// an array that stores the bounds of the glyphs that we're going to draw
|
|
Packit Service |
e3b512 |
static const GlyphBounds glyphs[] =
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
{ 'c', 0.45, 0.5 },
|
|
Packit Service |
e3b512 |
{ 'a', 0.45, 0.5 },
|
|
Packit Service |
e3b512 |
{ 'i', 0.2, 0.75 },
|
|
Packit Service |
e3b512 |
{ 'r', 0.4, 0.5 },
|
|
Packit Service |
e3b512 |
{ 'o', 0.44, 0.5 },
|
|
Packit Service |
e3b512 |
{ 'm', 0.75, 0.5 },
|
|
Packit Service |
e3b512 |
{ '!', 0.2, 0.75 }
|
|
Packit Service |
e3b512 |
};
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
// A *very* simple font that just draws a box for every glyph
|
|
Packit Service |
e3b512 |
class BoxFontFace : public Cairo::UserFontFace
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
public:
|
|
Packit Service |
e3b512 |
// Derived user font classes should have a factory method to create an object
|
|
Packit Service |
e3b512 |
// and return it with a RefPtr
|
|
Packit Service |
e3b512 |
static Cairo::RefPtr<BoxFontFace> create()
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
return Cairo::RefPtr<BoxFontFace>(new BoxFontFace());
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
Cairo::ErrorStatus
|
|
Packit Service |
e3b512 |
init(const Cairo::RefPtr<Cairo::ScaledFont>& /*scaled_font*/,
|
|
Packit Service |
e3b512 |
const Cairo::RefPtr<Cairo::Context>& /*cr*/,
|
|
Packit Service |
e3b512 |
Cairo::FontExtents &extents) override
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
double max = 0;
|
|
Packit Service |
e3b512 |
for (unsigned int i = 0; i < sizeof (glyphs) / sizeof (GlyphBounds); ++i) {
|
|
Packit Service |
e3b512 |
if (glyphs[i].width > max)
|
|
Packit Service |
e3b512 |
max = glyphs[i].width;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
// add some spacing between characters
|
|
Packit Service |
e3b512 |
max += GLYPH_SPACING;
|
|
Packit Service |
e3b512 |
extents.max_x_advance = max;
|
|
Packit Service |
e3b512 |
return CAIRO_STATUS_SUCCESS;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
Cairo::ErrorStatus
|
|
Packit Service |
e3b512 |
unicode_to_glyph (const Cairo::RefPtr<Cairo::ScaledFont>& /*scaled_font*/,
|
|
Packit Service |
e3b512 |
unsigned long unicode, unsigned long& glyph) override
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
glyph = 0;
|
|
Packit Service |
e3b512 |
// yes this is a stupid an ineffienct way to do this but we only have a few
|
|
Packit Service |
e3b512 |
// glyphs and this is just demonstration code
|
|
Packit Service |
e3b512 |
for (unsigned int i = 0; i < sizeof (glyphs) / sizeof (GlyphBounds); ++i) {
|
|
Packit Service |
e3b512 |
if (glyphs[i].glyph == unicode) {
|
|
Packit Service |
e3b512 |
// glyph 0 is often a special glyph-not-found value, so offset it by 1
|
|
Packit Service |
e3b512 |
glyph = i+1;
|
|
Packit Service |
e3b512 |
break;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
return CAIRO_STATUS_SUCCESS;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
Cairo::ErrorStatus
|
|
Packit Service |
e3b512 |
render_glyph(const Cairo::RefPtr<Cairo::ScaledFont>& /*scaled_font*/,
|
|
Packit Service |
e3b512 |
unsigned long glyph,
|
|
Packit Service |
e3b512 |
const Cairo::RefPtr<Cairo::Context>& cr,
|
|
Packit Service |
e3b512 |
Cairo::TextExtents& metrics) override
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
// check that the glyph is in our table
|
|
Packit Service |
e3b512 |
if (glyph >= 1 && glyph <= sizeof(glyphs)/sizeof(GlyphBounds)) {
|
|
Packit Service |
e3b512 |
cr->set_line_width(0.05);
|
|
Packit Service |
e3b512 |
// Need a negative Y value since the text origin is at the bottom left point
|
|
Packit Service |
e3b512 |
// and cairo's positive Y axis is down and we want to draw up
|
|
Packit Service |
e3b512 |
cr->rectangle(0.0, 0.0, glyphs[glyph-1].width, -glyphs[glyph-1].height);
|
|
Packit Service |
e3b512 |
cr->stroke();
|
|
Packit Service |
e3b512 |
metrics.x_advance = glyphs[glyph-1].width + GLYPH_SPACING;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
return CAIRO_STATUS_SUCCESS;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
protected:
|
|
Packit Service |
e3b512 |
// FontFace is a ref-counted object, so the constructor should be protected so
|
|
Packit Service |
e3b512 |
// it is not created without a refptr to manage it. See the create() method
|
|
Packit Service |
e3b512 |
BoxFontFace() : UserFontFace() { }
|
|
Packit Service |
e3b512 |
};
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
int main(int, char**)
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
auto surface =
|
|
Packit Service |
e3b512 |
Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, WIDTH, HEIGHT);
|
|
Packit Service |
e3b512 |
auto cr = Cairo::Context::create(surface);
|
|
Packit Service |
e3b512 |
// fill background in white
|
|
Packit Service |
e3b512 |
cr->set_source_rgb(1.0, 1.0, 1.0);
|
|
Packit Service |
e3b512 |
cr->paint();
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
// draw a little dot at the point where text will be drawn
|
|
Packit Service |
e3b512 |
cr->arc(TEXT_ORIGIN_X, TEXT_ORIGIN_Y, FONT_SIZE / 4.0, 0, 2*M_PI);
|
|
Packit Service |
e3b512 |
cr->set_source_rgba(0.0, 1.0, 0.0, 0.5);
|
|
Packit Service |
e3b512 |
cr->fill();
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
// draw the text
|
|
Packit Service |
e3b512 |
cr->move_to(TEXT_ORIGIN_X, TEXT_ORIGIN_Y);
|
|
Packit Service |
e3b512 |
cr->set_source_rgb(0.8, 0.2, 0.2);
|
|
Packit Service |
e3b512 |
auto font = BoxFontFace::create();
|
|
Packit Service |
e3b512 |
cr->set_font_face(font);
|
|
Packit Service |
e3b512 |
cr->set_font_size(FONT_SIZE);
|
|
Packit Service |
e3b512 |
cr->show_text("cairomm!");
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
// Now show it with the toy text API to demonstrate how the glyphs match up
|
|
Packit Service |
e3b512 |
cr->move_to(TEXT_ORIGIN_X, TEXT_ORIGIN_Y);
|
|
Packit Service |
e3b512 |
cr->set_source_rgba(0.2, 0.2, 0.2, 0.3);
|
|
Packit Service |
e3b512 |
auto toy_font =
|
|
Packit Service |
e3b512 |
Cairo::ToyFontFace::create("Bitstream Charter",
|
|
Packit Service |
e3b512 |
Cairo::FONT_SLANT_NORMAL,
|
|
Packit Service |
e3b512 |
Cairo::FONT_WEIGHT_BOLD);
|
|
Packit Service |
e3b512 |
cr->set_font_face(toy_font);
|
|
Packit Service |
e3b512 |
cr->set_font_size(FONT_SIZE);
|
|
Packit Service |
e3b512 |
cr->show_text("cairomm!");
|
|
Packit Service |
e3b512 |
|
|
Packit Service |
e3b512 |
const char* filename = "user-font.png";
|
|
Packit Service |
e3b512 |
try {
|
|
Packit Service |
e3b512 |
surface->write_to_png(filename);
|
|
Packit Service |
e3b512 |
std::cout << "Wrote Image " << filename << std::endl;
|
|
Packit Service |
e3b512 |
return 0;
|
|
Packit Service |
e3b512 |
} catch (const std::exception& e)
|
|
Packit Service |
e3b512 |
{
|
|
Packit Service |
e3b512 |
std::cout << "** Unable to write Image " << filename << std::endl;
|
|
Packit Service |
e3b512 |
return 1;
|
|
Packit Service |
e3b512 |
}
|
|
Packit Service |
e3b512 |
}
|