#include <cairo.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

cairo_t *crc;

void number(int n, double x, double y)
{
    cairo_text_extents_t extents;
    char str[32];
    const double radius = 15;
    double theta;

    sprintf(str, "%d", n);

    if (n > 999)
        cairo_set_font_size(crc, 10);
    else if (n > 99)
        cairo_set_font_size(crc, 12);   
    else if (n > 9)
        cairo_set_font_size(crc, 14);   
    else
        cairo_set_font_size(crc, 16);   

    cairo_set_source_rgb(crc, 0, 0, 0);
    cairo_move_to(crc, x + radius, y);
    for (theta = 0; theta < M_PI * 2; theta += 0.1)
    {
        double cx = x + radius * cos(theta);
        double cy = y + radius * sin(theta);
        cairo_line_to(crc, cx, cy);
    }
    cairo_close_path(crc);
    if (n % 2)
    {
        cairo_stroke_preserve(crc);
        cairo_set_source_rgb(crc, 1, 1, 1);
        cairo_fill(crc);
    }
    else
        cairo_fill(crc);

    if (n % 2)
        cairo_set_source_rgb(crc, 0, 0, 0);
    else
        cairo_set_source_rgb(crc, 1, 1, 1);

    cairo_text_extents(crc, str, &extents);
    cairo_move_to(crc, x - extents.width / 2, y + extents.height / 2);
    cairo_show_text(crc, str);
}

int main()
{
    double width = 600, height = 510;
    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
    crc = cairo_create(surface);
    cairo_font_options_t* font;
    int *previous;
    int *current;
    int row, col, count;
    double x, y;

    // Set up font  (face is second field in 'xlsfonts'; first field is foundry)
    font = cairo_font_options_create();
    cairo_font_options_set_antialias(font, CAIRO_ANTIALIAS_SUBPIXEL);
    cairo_set_font_options(crc, font);
    cairo_select_font_face(crc, "nimbus sans l", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_font_options_destroy(font);

    // Draw first two rows manually.
    y = 30;
    number(1, 30, y);
    y += 30;

    number(1, 30, y);
    number(1, 30 + 30, y);
    y += 30;

    // Continue with pascal's triangle.
    count = 2;
    previous = malloc(count++ * sizeof(int));
    previous[0] = 1;
    previous[1] = 1;

    for (row = 2; row < 16; row++, count++, y+= 30)
    {
        x = 30;
        current = malloc(count * sizeof(int));
        for (col = 0; col < count; col++)
        {
            if (col == 0 || col == count - 1)
                current[col] = 1;
            else
                current[col] = previous[col] + previous[col - 1];
            number(current[col], x, y);
            x += 30;
        }
        free(previous);
        previous = current;
    }

    free(previous);

    // Done.
    cairo_surface_write_to_png(surface, "pascal.png");
    return 0;
}
