And adding the background attributes. We're done with the Pango one! Now for the Windows one... yay.
This commit is contained in:
parent
4ba4e4ba23
commit
75c2c80534
101
unix/attrstr.c
101
unix/attrstr.c
|
@ -10,7 +10,8 @@ struct foreachParams {
|
||||||
// keys are pointers to size_t maintained by g_new0()/g_free()
|
// keys are pointers to size_t maintained by g_new0()/g_free()
|
||||||
// values are GStrings
|
// values are GStrings
|
||||||
GHashTable *features;
|
GHashTable *features;
|
||||||
//TODO GArray *backgroundBlocks;
|
// TODO use pango's built-in background attribute?
|
||||||
|
GPtrArray *backgroundClosures;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean featurePosEqual(gconstpointer a, gconstpointer b)
|
static gboolean featurePosEqual(gconstpointer a, gconstpointer b)
|
||||||
|
@ -55,21 +56,51 @@ static void ensureFeaturesInRange(struct foreachParams *p, size_t start, size_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* TODO */
|
struct closureParams {
|
||||||
static backgroundBlock mkBackgroundBlock(size_t start, size_t end, double r, double g, double b, double a)
|
size_t start;
|
||||||
{
|
size_t end;
|
||||||
return Block_copy(^(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y) {
|
double r;
|
||||||
uiDrawBrush brush;
|
double g;
|
||||||
|
double b;
|
||||||
|
double a;
|
||||||
|
};
|
||||||
|
|
||||||
brush.Type = uiDrawBrushTypeSolid;
|
static void backgroundClosure(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y, gpointer data)
|
||||||
brush.R = r;
|
{
|
||||||
brush.G = g;
|
struct closureParams *p = (struct closureParams *) data;
|
||||||
brush.B = b;
|
uiDrawBrush brush;
|
||||||
brush.A = a;
|
|
||||||
drawTextBackground(c, x, y, layout, start, end, &brush, 0);
|
brush.Type = uiDrawBrushTypeSolid;
|
||||||
});
|
brush.R = p->r;
|
||||||
|
brush.G = p->g;
|
||||||
|
brush.B = p->b;
|
||||||
|
brush.A = p->a;
|
||||||
|
drawTextBackground(c, x, y, layout, p->start, p->end, &brush, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeClosureParams(gpointer data, GClosure *closure)
|
||||||
|
{
|
||||||
|
uiFree((struct closureParams *) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GClosure *mkBackgroundClosure(size_t start, size_t end, double r, double g, double b, double a)
|
||||||
|
{
|
||||||
|
struct closureParams *p;
|
||||||
|
GClosure *closure;
|
||||||
|
|
||||||
|
p = uiNew(struct closureParams);
|
||||||
|
p->start = start;
|
||||||
|
p->end = end;
|
||||||
|
p->r = r;
|
||||||
|
p->g = g;
|
||||||
|
p->b = b;
|
||||||
|
p->a = a;
|
||||||
|
closure = (GClosure *) g_cclosure_new(G_CALLBACK(backgroundClosure), p, freeClosureParams);
|
||||||
|
// TODO write a specific marshaler
|
||||||
|
// TODO or drop the closure stuff entirely
|
||||||
|
g_closure_set_marshal(closure, g_cclosure_marshal_generic);
|
||||||
|
return closure;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
struct otParam {
|
struct otParam {
|
||||||
struct foreachParams *p;
|
struct foreachParams *p;
|
||||||
|
@ -107,7 +138,7 @@ static void addattr(struct foreachParams *p, size_t start, size_t end, PangoAttr
|
||||||
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
||||||
{
|
{
|
||||||
struct foreachParams *p = (struct foreachParams *) data;
|
struct foreachParams *p = (struct foreachParams *) data;
|
||||||
//TODO backgroundBlock block;
|
GClosure *closure;
|
||||||
PangoGravity gravity;
|
PangoGravity gravity;
|
||||||
PangoUnderline underline;
|
PangoUnderline underline;
|
||||||
PangoLanguage *lang;
|
PangoLanguage *lang;
|
||||||
|
@ -145,14 +176,11 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
||||||
FUTURE_pango_attr_foreground_alpha_new(
|
FUTURE_pango_attr_foreground_alpha_new(
|
||||||
(guint16) (spec->A * 65535.0)));
|
(guint16) (spec->A * 65535.0)));
|
||||||
break;
|
break;
|
||||||
#if 0 /* TODO */
|
|
||||||
case uiAttributeBackground:
|
case uiAttributeBackground:
|
||||||
block = mkBackgroundBlock(ostart, oend,
|
closure = mkBackgroundClosure(start, end,
|
||||||
spec->R, spec->G, spec->B, spec->A);
|
spec->R, spec->G, spec->B, spec->A);
|
||||||
[p->backgroundBlocks addObject:block];
|
g_ptr_array_add(p->backgroundClosures, closure);
|
||||||
Block_release(block);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case uiAttributeVerticalForms:
|
case uiAttributeVerticalForms:
|
||||||
gravity = PANGO_GRAVITY_SOUTH;
|
gravity = PANGO_GRAVITY_SOUTH;
|
||||||
if (spec->Value != 0)
|
if (spec->Value != 0)
|
||||||
|
@ -249,7 +277,12 @@ static void applyAndFreeFeatureAttributes(struct foreachParams *p)
|
||||||
g_hash_table_destroy(p->features);
|
g_hash_table_destroy(p->features);
|
||||||
}
|
}
|
||||||
|
|
||||||
PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p/*TODO, NSArray **backgroundBlocks*/)
|
static void unrefClosure(gpointer data)
|
||||||
|
{
|
||||||
|
g_closure_unref((GClosure *) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **backgroundClosures)
|
||||||
{
|
{
|
||||||
struct foreachParams fep;
|
struct foreachParams fep;
|
||||||
|
|
||||||
|
@ -258,7 +291,33 @@ PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p/*TODO, NSArray *
|
||||||
fep.features = g_hash_table_new_full(
|
fep.features = g_hash_table_new_full(
|
||||||
featurePosHash, featurePosEqual,
|
featurePosHash, featurePosEqual,
|
||||||
g_free, freeFeatureString);
|
g_free, freeFeatureString);
|
||||||
|
fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure);
|
||||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||||
applyAndFreeFeatureAttributes(&fep);
|
applyAndFreeFeatureAttributes(&fep);
|
||||||
|
*backgroundClosures = fep.backgroundClosures;
|
||||||
return fep.attrs;
|
return fep.attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invokeBackgroundClosure(GClosure *closure, uiDrawContext *c, uiDrawTextLayout *layout, double x, double y)
|
||||||
|
{
|
||||||
|
GValue values[4] = {
|
||||||
|
// the zero-initialization is needed for g_value_init() to work
|
||||||
|
G_VALUE_INIT,
|
||||||
|
G_VALUE_INIT,
|
||||||
|
G_VALUE_INIT,
|
||||||
|
G_VALUE_INIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
g_value_init(values + 0, G_TYPE_POINTER);
|
||||||
|
g_value_set_pointer(values + 0, c);
|
||||||
|
g_value_init(values + 1, G_TYPE_POINTER);
|
||||||
|
g_value_set_pointer(values + 1, layout);
|
||||||
|
g_value_init(values + 2, G_TYPE_DOUBLE);
|
||||||
|
g_value_set_double(values + 2, x);
|
||||||
|
g_value_init(values + 3, G_TYPE_DOUBLE);
|
||||||
|
g_value_set_double(values + 3, y);
|
||||||
|
g_closure_invoke(closure,
|
||||||
|
NULL,
|
||||||
|
4, values,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
struct uiDrawTextLayout {
|
struct uiDrawTextLayout {
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
|
GPtrArray *backgroundClosures;
|
||||||
uiDrawTextLayoutLineMetrics *lineMetrics;
|
uiDrawTextLayoutLineMetrics *lineMetrics;
|
||||||
int nLines;
|
int nLines;
|
||||||
};
|
};
|
||||||
|
@ -138,7 +139,7 @@ uiDrawTextLayout *uiDrawNewTextLayout(uiDrawTextLayoutParams *p)
|
||||||
|
|
||||||
pango_layout_set_alignment(tl->layout, pangoAligns[p->Align]);
|
pango_layout_set_alignment(tl->layout, pangoAligns[p->Align]);
|
||||||
|
|
||||||
attrs = attrstrToPangoAttrList(p);
|
attrs = attrstrToPangoAttrList(p, &(tl->backgroundClosures));
|
||||||
pango_layout_set_attributes(tl->layout, attrs);
|
pango_layout_set_attributes(tl->layout, attrs);
|
||||||
pango_attr_list_unref(attrs);
|
pango_attr_list_unref(attrs);
|
||||||
|
|
||||||
|
@ -151,12 +152,22 @@ uiDrawTextLayout *uiDrawNewTextLayout(uiDrawTextLayoutParams *p)
|
||||||
void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
||||||
{
|
{
|
||||||
uiFree(tl->lineMetrics);
|
uiFree(tl->lineMetrics);
|
||||||
|
g_ptr_array_unref(tl->backgroundClosures);
|
||||||
g_object_unref(tl->layout);
|
g_object_unref(tl->layout);
|
||||||
uiFree(tl);
|
uiFree(tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
||||||
{
|
{
|
||||||
|
guint i;
|
||||||
|
GClosure *closure;
|
||||||
|
|
||||||
|
for (i = 0; i < tl->backgroundClosures->len; i++) {
|
||||||
|
closure = (GClosure *) g_ptr_array_index(tl->backgroundClosures, i);
|
||||||
|
invokeBackgroundClosure(closure, c, tl, x, 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);
|
cairo_move_to(c->cr, x, y);
|
||||||
pango_cairo_show_layout(c->cr, tl->layout);
|
pango_cairo_show_layout(c->cr, tl->layout);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path,
|
||||||
extern void fontdescFromPangoFontDescription(PangoFontDescription *pdesc, uiDrawFontDescriptor *uidesc);
|
extern void fontdescFromPangoFontDescription(PangoFontDescription *pdesc, uiDrawFontDescriptor *uidesc);
|
||||||
|
|
||||||
// attrstr.c
|
// attrstr.c
|
||||||
extern PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p/*TODO, NSArray **backgroundBlocks*/);
|
extern PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **backgroundClosures);
|
||||||
|
extern void invokeBackgroundClosure(GClosure *closure, uiDrawContext *c, uiDrawTextLayout *layout, double x, double y);
|
||||||
|
|
||||||
// drawtext.c
|
// drawtext.c
|
||||||
// TODO get rid of these (for attrstr.c)
|
// TODO get rid of these (for attrstr.c)
|
||||||
|
|
Loading…
Reference in New Issue