Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8156797
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T17:04:12+00:00 2026-06-06T17:04:12+00:00

I am writing an application using Cairo in C that does the following: Load

  • 0

I am writing an application using Cairo in C that does the following:

  • Load background PNG (wheel)
  • rotate wheel 90 degrees
  • draw on wheel a set of numbers from other PNG files
  • do this until all 6 parts of the wheel have the numbers drawn on the wheel
  • save the PNG to a file ( results.png )

The problem I’m having is if I don’t rotate the wheel, the numbers are drawn properly as seen in this image, except the wheel isn’t rotated as needed.

However, if I attempt to rotate AND draw the numbers on the wheel I get a rotated wheel with no numbers as seen in this image.

I’ve tried various permutations of the code, but I can’t seem to make it work. I would appreciate some hints and / or sample code that shows what I’m doing wrong. I’ve checked the Cairo documentation to no avail.

The code can be found here.

And here:

#include <cairo.h>
#include <stdio.h>
#include <string.h>
#include <math.h>


typedef struct
{
    int numImages;      /* Number of images in win amount string */
    int indexes[7];     /* indexes into NumberImages[] */
}WinAmountData;

/***** Function Prototypes *****************/
int InitImages( void );
void DestroyNumberImages( void );
int ParseWinAmountString( char *string, WinAmountData *amtData );
int Rotate( cairo_t *cr , cairo_surface_t *image, double degrees );
/*******************************************/


typedef struct
{
    int xOffset;    /* pixel count offsete before next digit */
    char fileName[20];
    cairo_surface_t *image; 
}ImageInfo;

ImageInfo NumberImages[] =
{
    { 8, "images/0.png", NULL },
    { 10, "images/1.png", NULL },
    { 10, "images/2.png", NULL },
    { 10, "images/3.png", NULL },
    { 10, "images/4.png", NULL },
    { 10, "images/5.png", NULL },
    { 10, "images/6.png", NULL },
    { 10, "images/7.png", NULL },
    { 10, "images/8.png", NULL },
    { 10, "images/9.png", NULL },
    { 7, "images/$.png", NULL },
    { 10, "images/euro.png", NULL },
    { 7, "images/pound.png", NULL },
    { 7, "images/yen.png", NULL }
};

enum { DOLLAR = 10, EURO, POUND, YEN };

#define FALSE 0
#define TRUE 1

int InitImages( void )
{
    int i;
    int ret = TRUE;
    cairo_status_t imgStatus;


    for( i = 0; i < ( sizeof( NumberImages ) / sizeof( ImageInfo ) ) && ret == TRUE; i++ )
    {
        NumberImages[i].image = cairo_image_surface_create_from_png( NumberImages[i].fileName );    
        imgStatus = cairo_surface_status(NumberImages[i].image);
        ret = ( CAIRO_STATUS_SUCCESS == imgStatus );
    }

    return( ret );
}


void DestroyNumberImages( void )
{
    int i;

    for( i = 0; i < ( sizeof( NumberImages ) / sizeof( ImageInfo ) ); i++ )
    {
        cairo_surface_destroy(NumberImages[i].image);
    }

    return;
}

int ParseWinAmountString( char *string, WinAmountData *amtData )
{
    int ret = TRUE;
    int i = 0, len;

    len = strlen( string );
    if( (len > 0) && (len < 8) )
    {
        amtData->numImages = len;

        for( i = 0; i < amtData->numImages && TRUE == ret; i++ )
        {
            if( string[i] >= '0' && string[i] <= '9' )
            {
                amtData->indexes[i] = string[i] - '0';
            }
            else
            {
                switch( string[i] )
                {
                    case 'D':
                        amtData->indexes[i] = DOLLAR;
                    break;

                    case 'Y':
                        amtData->indexes[i] = YEN;
                    break;

                    case 'E':
                        amtData->indexes[i] = EURO;
                    break;

                    case 'P':
                        amtData->indexes[i] = POUND;
                    break;

                    default:
                        ret = FALSE;
                    break;
                }
            }
        }
    } 
    else
    {
        ret = FALSE;
    }   

    return( ret );
}

double DegreesToRadians( double degrees )
{
    return((double)((double)degrees * ( (double)M_PI/(double)180.0 )));
}

int Rotate( cairo_t *cr , cairo_surface_t *image, double degrees )
{
    int ret = 0;

    cairo_translate(cr, 90, 90);
    cairo_rotate(cr, DegreesToRadians( degrees ));
    cairo_set_source_surface(cr, image, -90, -90);

    cairo_paint(cr);

    return ( ret );
}


int main(int argc, char *argv[])
{
    int i,x,y;
    cairo_surface_t *imgWheelBg = NULL;
    WinAmountData amtData;


    if( argc == 2 )
    {
        printf("Parsing [%s]\n", argv[1]);
        if ( ParseWinAmountString( argv[1], &amtData ) == TRUE )
        {
            printf("Amount indexes = [ ");
            for( i = 0; i < amtData.numImages; i++ )
            {
                printf("%d ", amtData.indexes[i]);
            }
            printf("]\n");
        }
        else
        {
            printf("Failed to parse amount.\n");
            return( 1 );
        }
    }
    else
    {
        printf("Usage: %s <Amount String>\n", argv[0]);
        return( 1 );
    }

    if( InitImages() == TRUE )
    {
        imgWheelBg = cairo_image_surface_create_from_png("images/blankwheel.png");

        //Create the background image
        cairo_surface_t *imgResult = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 180, 180);

        //Create the cairo context
        cairo_t *cr = cairo_create(imgResult);

        //Paint empty wheel image
        cairo_set_source_surface(cr, imgWheelBg, 0, 0);
        cairo_paint(cr);

        // At this point the wheel is painted ( blankwheel.png )

        // vvvvvvvvvv THIS PART SEEMS TO BE CAUSING TROUBLES vvvvvvvvvv     

        // With this call the wheel DOES get rotated 90 degress. Confirmed
        // by viewing the resulting PNG file. 
        // HOWEVER, after the Rotate() is called the numbers aren't put on the wheel.
        // if I remove the Rotate() call, the wheel is drawn, not rotated, but the
        // numbers are properly composited over the image.

        //Rotate( cr, imgWheelBg, 90 );

        // ^^^^^^^^^^^ THIS PART SEEMS TO BE CAUSING TROUBLES ^^^^^^^^^^^       

        /* Set drawing begin point in pixels */
        x = 101;
        y = 82;

        /* Draw all characters in win amount string */
        for( i = 0; i < amtData.numImages; i++ )
        {
            cairo_set_source_surface(cr, NumberImages[amtData.indexes[i]].image, x, y);
            cairo_paint(cr);
            x += NumberImages[i].xOffset;
        }

        //Destroy the cairo context and/or flush the destination image
        cairo_surface_flush(imgResult);
        cairo_destroy(cr);

        //And write the results into a new file
        cairo_surface_write_to_png(imgResult, "result.png");

        // Destroy resources
        cairo_surface_destroy(imgResult);
        cairo_surface_destroy(imgWheelBg);
        DestroyNumberImages();
        printf("SUCCESS\n");
    }
    else
    {
        printf("FAILED Init Images\n");
    }

    return 0;
}

EDIT: The ultimate goal is to generate an image like this one programmatically and the animate it as needed in real time within a GTK application.

EDIT: With the comments from Mikhail Kozhevnikov and Uli Schlachter I was able to find a solution using this code.

Thank you very much!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T17:04:13+00:00Added an answer on June 6, 2026 at 5:04 pm

    I think the problem is that the transformation is applied to everything, including the number images, and they get drawn somewhere outside the picture because of this transformation. I’d suggest that the matrix be stored before applying the transformation and restored after the circle is drawn. Or would you like the numbers to rotate too?..

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm currently writing an application using Vala that requires me to send data over
I'm writing an application using WPF, and I need to make something that looks
I am writing an application using Symfony. I have some reusable components that I
I am writing an application using Sencha Touch that will require a login to
I'm writing an application using WPF, and I need to make something that looks
I'm writing an application using Perl and Gtk2-Perl that keeps track of elapsed time.
I'm writing an application using gtkmm. I wrote a simple widget class, that I
I am writing an application using jQuery (with the jPlayer plugin) that needs to
I'm writing an application using Python that adds videos to a user's playlist on
I'm writing a web application using Spring/Hibernate that displays a report to a user,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.