Migrated attrstr.c back.
This commit is contained in:
parent
1cce6dc704
commit
7dc5c6d940
|
@ -454,7 +454,7 @@ static CTParagraphStyleRef mkParagraphStyle(uiDrawTextLayoutParams *p)
|
|||
return ps;
|
||||
}
|
||||
|
||||
// TODO either rename this to uiprivDrawTextLayoutParams... or rename this file or both or split the struct or something else...
|
||||
// TODO either rename this (on all platforms) to uiprivDrawTextLayoutParams... or rename this file or both or split the struct or something else...
|
||||
CFAttributedStringRef uiprivAttributedStringToCFAttributedString(uiDrawTextLayoutParams *p, NSArray **backgroundParams)
|
||||
{
|
||||
CFStringRef cfstr;
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
// 12 february 2017
|
||||
#include "uipriv_unix.h"
|
||||
|
||||
// TODO pango alpha attributes turn 0 into 65535 :|
|
||||
|
||||
// TODO make this name less generic?
|
||||
struct foreachParams {
|
||||
PangoAttrList *attrs;
|
||||
// TODO use pango's built-in background attribute?
|
||||
GPtrArray *backgroundClosures;
|
||||
};
|
||||
|
||||
struct closureParams {
|
||||
size_t start;
|
||||
size_t end;
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
double a;
|
||||
};
|
||||
|
||||
static void backgroundClosure(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y, gpointer data)
|
||||
{
|
||||
struct closureParams *p = (struct closureParams *) data;
|
||||
uiDrawBrush brush;
|
||||
|
||||
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 = 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;
|
||||
}
|
||||
|
||||
static void addattr(struct foreachParams *p, size_t start, size_t end, PangoAttribute *attr)
|
||||
{
|
||||
if (attr == NULL) // in case of a future attribute
|
||||
return;
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert(p->attrs, attr);
|
||||
}
|
||||
|
||||
static uiForEach processAttribute(const uiAttributedString *s, const uiAttributeSpec *spec, size_t start, size_t end, void *data)
|
||||
{
|
||||
struct foreachParams *p = (struct foreachParams *) data;
|
||||
GClosure *closure;
|
||||
PangoUnderline underline;
|
||||
char *featurestr;
|
||||
|
||||
switch (spec->Type) {
|
||||
case uiAttributeFamily:
|
||||
addattr(p, start, end,
|
||||
pango_attr_family_new(spec->Family));
|
||||
break;
|
||||
case uiAttributeSize:
|
||||
addattr(p, start, end,
|
||||
pango_attr_size_new(cairoToPango(spec->Double)));
|
||||
break;
|
||||
case uiAttributeWeight:
|
||||
// TODO reverse the misalignment from drawtext.c if it is corrected
|
||||
addattr(p, start, end,
|
||||
pango_attr_weight_new((PangoWeight) (spec->Value)));
|
||||
break;
|
||||
case uiAttributeItalic:
|
||||
addattr(p, start, end,
|
||||
pango_attr_style_new(pangoItalics[(uiDrawTextItalic) (spec->Value)]));
|
||||
break;
|
||||
case uiAttributeStretch:
|
||||
addattr(p, start, end,
|
||||
pango_attr_stretch_new(pangoStretches[(uiDrawTextStretch) (spec->Value)]));
|
||||
break;
|
||||
case uiAttributeColor:
|
||||
addattr(p, start, end,
|
||||
pango_attr_foreground_new(
|
||||
(guint16) (spec->R * 65535.0),
|
||||
(guint16) (spec->G * 65535.0),
|
||||
(guint16) (spec->B * 65535.0)));
|
||||
addattr(p, start, end,
|
||||
FUTURE_pango_attr_foreground_alpha_new(
|
||||
(guint16) (spec->A * 65535.0)));
|
||||
break;
|
||||
case uiAttributeBackground:
|
||||
closure = mkBackgroundClosure(start, end,
|
||||
spec->R, spec->G, spec->B, spec->A);
|
||||
g_ptr_array_add(p->backgroundClosures, closure);
|
||||
break;
|
||||
case uiAttributeUnderline:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineStyleNone:
|
||||
underline = PANGO_UNDERLINE_NONE;
|
||||
break;
|
||||
case uiDrawUnderlineStyleSingle:
|
||||
underline = PANGO_UNDERLINE_SINGLE;
|
||||
break;
|
||||
case uiDrawUnderlineStyleDouble:
|
||||
underline = PANGO_UNDERLINE_DOUBLE;
|
||||
break;
|
||||
case uiDrawUnderlineStyleSuggestion:
|
||||
underline = PANGO_UNDERLINE_ERROR;
|
||||
break;
|
||||
}
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_new(underline));
|
||||
break;
|
||||
case uiAttributeUnderlineColor:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineColorCustom:
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(
|
||||
(guint16) (spec->R * 65535.0),
|
||||
(guint16) (spec->G * 65535.0),
|
||||
(guint16) (spec->B * 65535.0)));
|
||||
break;
|
||||
case uiDrawUnderlineColorSpelling:
|
||||
// TODO GtkTextView style property error-underline-color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(65535, 0, 0));
|
||||
break;
|
||||
case uiDrawUnderlineColorGrammar:
|
||||
// TODO find a more appropriate color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(0, 65535, 0));
|
||||
break;
|
||||
case uiDrawUnderlineColorAuxiliary:
|
||||
// TODO find a more appropriate color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(0, 0, 65535));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case uiAttributeFeatures:
|
||||
// only generate an attribute if spec->Features is not NULL
|
||||
// TODO state that this is allowed
|
||||
if (spec->Features == NULL)
|
||||
break;
|
||||
featurestr = otfToPangoCSSString(spec->Features);
|
||||
addattr(p, start, end,
|
||||
FUTURE_pango_attr_font_features_new(featurestr));
|
||||
g_free(featurestr);
|
||||
break;
|
||||
default:
|
||||
// TODO complain
|
||||
;
|
||||
}
|
||||
return uiForEachContinue;
|
||||
}
|
||||
|
||||
static void unrefClosure(gpointer data)
|
||||
{
|
||||
g_closure_unref((GClosure *) data);
|
||||
}
|
||||
|
||||
PangoAttrList *attrstrToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **backgroundClosures)
|
||||
{
|
||||
struct foreachParams fep;
|
||||
|
||||
fep.attrs = pango_attr_list_new();
|
||||
fep.backgroundClosures = g_ptr_array_new_with_free_func(unrefClosure);
|
||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||
*backgroundClosures = fep.backgroundClosures;
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
// 12 february 2017
|
||||
#include "uipriv_unix.h"
|
||||
#include "attrstr.h"
|
||||
|
||||
// TODO pango alpha attributes turn 0 into 65535 :|
|
||||
|
||||
// TODO make this name less generic?
|
||||
struct foreachParams {
|
||||
PangoAttrList *attrs;
|
||||
// TODO use pango's built-in background attribute
|
||||
GPtrArray *backgroundParams;
|
||||
};
|
||||
|
||||
static void backgroundClosure(uiDrawContext *c, uiDrawTextLayout *layout, double x, double y, gpointer data)
|
||||
{
|
||||
struct closureParams *p = (struct closureParams *) data;
|
||||
uiDrawBrush brush;
|
||||
|
||||
brush.Type = uiDrawBrushTypeSolid;
|
||||
brush.R = p->r;
|
||||
brush.G = p->g;
|
||||
brush.B = p->b;
|
||||
brush.A = p->a;
|
||||
//TODO drawTextBackground(c, x, y, layout, p->start, p->end, &brush, 0);
|
||||
}
|
||||
|
||||
static void addBackgroundAttribute(struct foreachParams *p, size_t start, size_t end, double r, double g, double b, double a)
|
||||
{
|
||||
uiprivDrawTextBackgroundParams *dtb;
|
||||
|
||||
dtb = uiprivNew(uiprivDrawTextBackgroundParams);
|
||||
dtb->start = start;
|
||||
dtb->end = end;
|
||||
dtb->r = r;
|
||||
dtb->g = g;
|
||||
dtb->b = b;
|
||||
dtb->a = a;
|
||||
g_ptr_array_add(p->backgroundParams, dtb);
|
||||
}
|
||||
|
||||
static void addattr(struct foreachParams *p, size_t start, size_t end, PangoAttribute *attr)
|
||||
{
|
||||
if (attr == NULL) // in case of a future attribute
|
||||
return;
|
||||
attr->start_index = start;
|
||||
attr->end_index = end;
|
||||
pango_attr_list_insert(p->attrs, attr);
|
||||
}
|
||||
|
||||
static uiForEach processAttribute(const uiAttributedString *s, const uiAttribute *attr, size_t start, size_t end, void *data)
|
||||
{
|
||||
struct foreachParams *p = (struct foreachParams *) data;
|
||||
double r, g, b, a;
|
||||
PangoUnderline underline;
|
||||
uiUnderlineColor colorType;
|
||||
const uiOpenTypeFeatures *features;
|
||||
GString *featurestr;
|
||||
|
||||
switch (uiAttributeGetType(attr)) {
|
||||
case uiAttributeTypeFamily:
|
||||
addattr(p, start, end,
|
||||
pango_attr_family_new(uiAttributeFamily(attr)));
|
||||
break;
|
||||
case uiAttributeTypeSize:
|
||||
addattr(p, start, end,
|
||||
pango_attr_size_new(cairoToPango(uiAttributeSize(attr))));
|
||||
break;
|
||||
case uiAttributeTypeWeight:
|
||||
// TODO reverse the misalignment from drawtext.c if it is corrected
|
||||
addattr(p, start, end,
|
||||
pango_attr_weight_new((PangoWeight) uiAttributeWeight(attr)));
|
||||
break;
|
||||
case uiAttributeTypeItalic:
|
||||
addattr(p, start, end,
|
||||
pango_attr_style_new(pangoItalics[uiAttributeItalic(attr)]));
|
||||
break;
|
||||
case uiAttributeTypeStretch:
|
||||
addattr(p, start, end,
|
||||
pango_attr_stretch_new(pangoStretches[uiAttributeStretch(attr)]));
|
||||
break;
|
||||
case uiAttributeTypeColor:
|
||||
uiAttributeColor(attr, &r, &g, &b, &a);
|
||||
addattr(p, start, end,
|
||||
pango_attr_foreground_new(
|
||||
(guint16) (r * 65535.0),
|
||||
(guint16) (g * 65535.0),
|
||||
(guint16) (b * 65535.0)));
|
||||
addattr(p, start, end,
|
||||
FUTURE_pango_attr_foreground_alpha_new(
|
||||
(guint16) (a * 65535.0)));
|
||||
break;
|
||||
case uiAttributeTypeBackground:
|
||||
uiAttributeColor(attr, &r, &g, &b, &a);
|
||||
addBackgroundAttribute(p, start, end, r, g, b, a);
|
||||
break;
|
||||
case uiAttributeTypeUnderline:
|
||||
switch (uiAttributeUnderline(attr)) {
|
||||
case uiUnderlineNone:
|
||||
underline = PANGO_UNDERLINE_NONE;
|
||||
break;
|
||||
case uiUnderlineSingle:
|
||||
underline = PANGO_UNDERLINE_SINGLE;
|
||||
break;
|
||||
case uiUnderlineDouble:
|
||||
underline = PANGO_UNDERLINE_DOUBLE;
|
||||
break;
|
||||
case uiUnderlineSuggestion:
|
||||
underline = PANGO_UNDERLINE_ERROR;
|
||||
break;
|
||||
}
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_new(underline));
|
||||
break;
|
||||
case uiAttributeTypeUnderlineColor:
|
||||
uiAttributeUnderlineColor(attr, &colorType, &r, &g, &b, &a);
|
||||
switch (colorType) {
|
||||
case uiUnderlineColorCustom:
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(
|
||||
(guint16) (r * 65535.0),
|
||||
(guint16) (g * 65535.0),
|
||||
(guint16) (b * 65535.0)));
|
||||
break;
|
||||
case uiUnderlineColorSpelling:
|
||||
// TODO GtkTextView style property error-underline-color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(65535, 0, 0));
|
||||
break;
|
||||
case uiUnderlineColorGrammar:
|
||||
// TODO find a more appropriate color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(0, 65535, 0));
|
||||
break;
|
||||
case uiUnderlineColorAuxiliary:
|
||||
// TODO find a more appropriate color
|
||||
addattr(p, start, end,
|
||||
pango_attr_underline_color_new(0, 0, 65535));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case uiAttributeTypeFeatures:
|
||||
// only generate an attribute if the features object is not NULL
|
||||
// TODO state that this is allowed
|
||||
features = uiAttributeFeatures(attr);
|
||||
if (features == NULL)
|
||||
break;
|
||||
featurestr = uiprivOpenTypeFeaturesToPangoCSSFeaturesString(features);
|
||||
addattr(p, start, end,
|
||||
FUTURE_pango_attr_font_features_new(featurestr->str));
|
||||
g_string_free(featurestr, TRUE);
|
||||
break;
|
||||
default:
|
||||
// TODO complain
|
||||
;
|
||||
}
|
||||
return uiForEachContinue;
|
||||
}
|
||||
|
||||
static void freeBackgroundParams(gpointer data)
|
||||
{
|
||||
uiprivFree((uiprivDrawTextBackgroundParams *) data);
|
||||
}
|
||||
|
||||
PangoAttrList *uiprivAttributedStringToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **backgroundParams)
|
||||
{
|
||||
struct foreachParams fep;
|
||||
|
||||
fep.attrs = pango_attr_list_new();
|
||||
fep.backgroundParams = g_ptr_array_new_with_free_func(freeBackgroundParams);
|
||||
uiAttributedStringForEachAttribute(p->String, processAttribute, &fep);
|
||||
*backgroundParams = fep.backgroundParams;
|
||||
return fep.attrs;
|
||||
}
|
|
@ -1,4 +1,20 @@
|
|||
// 11 march 2018
|
||||
#import "../common/attrstr.h"
|
||||
|
||||
// opentype.c
|
||||
extern GString *uiprivOpenTypeFeaturesToPangoCSSFeaturesString(const uiOpenTypeFeatures *otf);
|
||||
|
||||
// attrstr.c
|
||||
extern PangoAttrList *uiprivAttributedStringToPangoAttrList(uiDrawTextLayoutParams *p, GPtrArray **backgroundParams);
|
||||
|
||||
// drawtext.c
|
||||
// TODO figure out where this type should *really* go in all the headers...
|
||||
typedef struct uiprivDrawTextBackgroundParams uiprivDrawTextBackgroundParams;
|
||||
struct uiprivDrawTextBackgroundParams {
|
||||
size_t start;
|
||||
size_t end;
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
double a;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue