2018-03-11 18:32:08 -05:00
// 11 march 2018
2018-03-11 18:59:11 -05:00
# include "uipriv_unix.h"
# include "draw.h"
# include "attrstr.h"
2018-03-11 17:12:15 -05:00
struct uiDrawTextLayout {
PangoLayout * layout ;
} ;
// we need a context for a few things
// the documentation suggests creating cairo_t-specific, GdkScreen-specific, or even GtkWidget-specific contexts, but we can't really do that because we want our uiDrawTextFonts and uiDrawTextLayouts to be context-independent
// we could use pango_font_map_create_context(pango_cairo_font_map_get_default()) but that will ignore GDK-specific settings
// so let's use gdk_pango_context_get() instead; even though it's for the default screen only, it's good enough for us
# define mkGenericPangoCairoContext() (gdk_pango_context_get())
static const PangoAlignment pangoAligns [ ] = {
[ uiDrawTextAlignLeft ] = PANGO_ALIGN_LEFT ,
[ uiDrawTextAlignCenter ] = PANGO_ALIGN_CENTER ,
[ uiDrawTextAlignRight ] = PANGO_ALIGN_RIGHT ,
} ;
uiDrawTextLayout * uiDrawNewTextLayout ( uiDrawTextLayoutParams * p )
{
uiDrawTextLayout * tl ;
PangoContext * context ;
PangoFontDescription * desc ;
PangoAttrList * attrs ;
int pangoWidth ;
tl = uiprivNew ( uiDrawTextLayout ) ;
// in this case, the context is necessary to create the layout
// the layout takes a ref on the context so we can unref it afterward
context = mkGenericPangoCairoContext ( ) ;
tl - > layout = pango_layout_new ( context ) ;
g_object_unref ( context ) ;
// this is safe; pango_layout_set_text() copies the string
pango_layout_set_text ( tl - > layout , uiAttributedStringString ( p - > String ) , - 1 ) ;
2018-03-11 18:32:08 -05:00
desc = uiprivFontDescriptorToPangoFontDescription ( p - > DefaultFont ) ;
2018-03-11 17:12:15 -05:00
pango_layout_set_font_description ( tl - > layout , desc ) ;
// this is safe; the description is copied
pango_font_description_free ( desc ) ;
pangoWidth = cairoToPango ( p - > Width ) ;
if ( p - > Width < 0 )
pangoWidth = - 1 ;
pango_layout_set_width ( tl - > layout , pangoWidth ) ;
pango_layout_set_alignment ( tl - > layout , pangoAligns [ p - > Align ] ) ;
2018-03-11 19:23:18 -05:00
attrs = uiprivAttributedStringToPangoAttrList ( p ) ;
2018-03-11 17:12:15 -05:00
pango_layout_set_attributes ( tl - > layout , attrs ) ;
pango_attr_list_unref ( attrs ) ;
return tl ;
}
void uiDrawFreeTextLayout ( uiDrawTextLayout * tl )
{
g_object_unref ( tl - > layout ) ;
uiprivFree ( tl ) ;
}
void uiDrawText ( uiDrawContext * c , uiDrawTextLayout * tl , double x , double y )
{
// TODO have an implicit save/restore on each drawing functions instead? and is this correct?
cairo_set_source_rgb ( c - > cr , 0.0 , 0.0 , 0.0 ) ;
cairo_move_to ( c - > cr , x , y ) ;
pango_cairo_show_layout ( c - > cr , tl - > layout ) ;
}
void uiDrawTextLayoutExtents ( uiDrawTextLayout * tl , double * width , double * height )
{
PangoRectangle logical ;
pango_layout_get_extents ( tl - > layout , NULL , & logical ) ;
* width = pangoToCairo ( logical . width ) ;
* height = pangoToCairo ( logical . height ) ;
}