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;
}
|