File: cairoCFerBind_drawText.c

package info (click to toggle)
pyferret 7.6.5-10
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 138,136 kB
  • sloc: fortran: 240,609; ansic: 25,235; python: 24,026; sh: 1,618; makefile: 1,123; pascal: 569; csh: 307; awk: 18
file content (128 lines) | stat: -rw-r--r-- 4,537 bytes parent folder | download | duplicates (5)
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
/* Python.h should always be first */
#include <Python.h>
#include <string.h>
#include "ferret.h"
#include "grdel.h"
#include "cferbind.h"
#include "cairoCFerBind.h"
#include "FerMem.h"

/*
 * Draw text to this "Window".  Text is a UTF-8 encoding of the desired text, 
 * and textlen is length of the text array (which may be more than the number 
 * of "characters" in the text).  Rotation is in degrees clockwise from horizontal.
 *
 * Returns one if successful.   If an error occurs, grdelerrmsg
 * is assigned an appropriate error message and zero is returned.
 */
grdelBool cairoCFerBind_drawText(CFerBind *self, const char *text, int textlen,
                                 double startx, double starty, grdelType font,
                                 grdelType color, double rotation)
{
    CairoCFerBindData *instdata;
    CCFBFont *fontobj;
    CCFBColor *colorobj;
    double unitfactor;
    char *utf8str;
#ifdef USEPANGOCAIRO
    PangoLayout *layout;
#endif
    cairo_status_t result;

    /* Sanity check */
    if ( (self->enginename != CairoCFerBindName) &&
         (self->enginename != PyQtCairoCFerBindName) ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: unexpected error, "
                            "self is not a valid CFerBind struct");
        return 0;
    }
    instdata = (CairoCFerBindData *) self->instancedata;
    if ( instdata->context == NULL ) {
        /* Create the Cairo Surface and Context if they do not exist */
        if ( ! cairoCFerBind_createSurface(self) ) {
            /* grdelerrmsg already assigned */
            return 0;
        }
    }
    fontobj = (CCFBFont *) font;
    if ( fontobj->id != CCFBFontId ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: unexpected error, "
                            "font is not CCFBFont struct");
        return 0;
    }
    colorobj = (CCFBColor *) color;
    if ( colorobj->id != CCFBColorId ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: unexpected error, "
                            "color is not CCFBColor struct");
        return 0;
    }
    if ( textlen < 0 ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: textlen is not positive");
        return 0;
    }

    /* Assign the color for this text */
    if ( instdata->noalpha )
        cairo_set_source_rgb(instdata->context, colorobj->redfrac, 
                             colorobj->greenfrac, colorobj->bluefrac);
    else
        cairo_set_source_rgba(instdata->context, colorobj->redfrac, 
                              colorobj->greenfrac, colorobj->bluefrac, 
                              colorobj->opaquefrac);

    /* Conversion factor for those surfaces that expect points instead of pixels */
    if ( instdata->imageformat == CCFBIF_PNG ) {
        unitfactor = 1.0;
    }
    else {
        unitfactor = 72.0 / instdata->pixelsperinch;
    }

    /* Move to the place to start drawing this text */
    cairo_move_to(instdata->context, startx * unitfactor, starty * unitfactor);

    /* If no text to draw, just return at this point */
    if ( textlen == 0 )
        return 1;

    /* Null-terminated the UTF-8 string */
    utf8str = (char *) FerMem_Malloc((textlen + 1) * sizeof(char), __FILE__, __LINE__);
    if ( utf8str == NULL ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: "
                            "out of memory for a copy of the text string");
        return 0;
    }
    strncpy(utf8str, text, textlen);
    utf8str[textlen] = '\0';

    /* draw the text */
    cairo_save(instdata->context);
    cairo_rotate(instdata->context, rotation * M_PI / 180.0);
#ifdef USEPANGOCAIRO
    layout = pango_cairo_create_layout(instdata->context);
    pango_layout_set_font_description(layout, fontobj->fontdesc);
    pango_layout_set_text(layout, text, textlen);
    pango_cairo_show_layout(instdata->context, layout);
    g_object_unref(layout);
#else
    cairo_set_font_face(instdata->context, fontobj->fontface);
    /* fontsize has already been adjusted appropriately for this surface */
    cairo_set_font_size(instdata->context, fontobj->fontsize);
    cairo_show_text(instdata->context, utf8str);
#endif
    result = cairo_status(instdata->context);
    cairo_restore(instdata->context);

    FerMem_Free(utf8str, __FILE__, __LINE__);
    instdata->somethingdrawn = 1;
    instdata->imagechanged = 1;

    if ( result != CAIRO_STATUS_SUCCESS ) {
        strcpy(grdelerrmsg, "cairoCFerBind_drawText: "
                            "drawing the text was not successful");
        return 0;
    }

    return 1;
}