425
449
// We consider paint "effectively set" for anything within text hierarchy
426
450
SPObject *parent = SP_OBJECT_PARENT (obj);
427
bool paint_effectively_set = paint->set || (SP_IS_TEXT(parent) || SP_IS_TEXTPATH(parent) || SP_IS_TSPAN(parent) || SP_IS_FLOWTEXT(parent) || SP_IS_FLOWDIV(parent) || SP_IS_FLOWPARA(parent) || SP_IS_FLOWTSPAN(parent) || SP_IS_FLOWLINE(parent));
451
bool paint_effectively_set =
452
paint->set || (SP_IS_TEXT(parent) || SP_IS_TEXTPATH(parent) || SP_IS_TSPAN(parent)
453
|| SP_IS_FLOWTEXT(parent) || SP_IS_FLOWDIV(parent) || SP_IS_FLOWPARA(parent)
454
|| SP_IS_FLOWTSPAN(parent) || SP_IS_FLOWLINE(parent));
429
456
// 1. Bail out with QUERY_STYLE_MULTIPLE_DIFFERENT if necessary
431
if ((paint_res->type != SP_PAINT_TYPE_IMPOSSIBLE) && (paint->type != paint_res->type || (paint_res->set != paint_effectively_set))) {
458
if ((!paintImpossible) && (!paint->isSameType(*paint_res) || (paint_res->set != paint_effectively_set))) {
432
459
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different types of paint
435
if (paint_res->set && paint->set && paint_res->type == SP_PAINT_TYPE_PAINTSERVER) {
462
if (paint_res->set && paint->set && paint_res->isPaintserver()) {
436
463
// both previous paint and this paint were a server, see if the servers are compatible
438
465
SPPaintServer *server_res = isfill? SP_STYLE_FILL_SERVER (style_res) : SP_STYLE_STROKE_SERVER (style_res);
499
if (paint_res->set && paint_effectively_set && paint->type == SP_PAINT_TYPE_PAINTSERVER) { // copy the server
533
paintImpossible = false;
534
paint_res->colorSet = paint->colorSet;
535
paint_res->currentcolor = paint->currentcolor;
536
if (paint_res->set && paint_effectively_set && paint->isPaintserver()) { // copy the server
501
SP_STYLE_FILL_SERVER (style_res) = SP_STYLE_FILL_SERVER (style);
538
sp_style_set_to_uri_string (style_res, true, style->getFillURI());
503
SP_STYLE_STROKE_SERVER (style_res) = SP_STYLE_STROKE_SERVER (style);
540
sp_style_set_to_uri_string (style_res, false, style->getStrokeURI());
506
paint_res->type = paint->type;
507
543
paint_res->set = paint_effectively_set;
508
544
style_res->fill_rule.computed = style->fill_rule.computed; // no averaging on this, just use the last one
511
547
// After all objects processed, divide the color if necessary and return
512
if (paint_res->set && paint_res->type == SP_PAINT_TYPE_COLOR) { // set the color
548
if (paint_res->set && paint_res->isColor()) { // set the color
513
549
g_assert (num >= 1);
519
sp_color_set_rgb_float(&paint_res->value.color, c[0], c[1], c[2]);
555
paint_res->setColor(c[0], c[1], c[2]);
521
557
style_res->fill_opacity.value = SP_SCALE24_FROM_FLOAT (c[3]);
523
559
style_res->stroke_opacity.value = SP_SCALE24_FROM_FLOAT (c[3]);
563
if ( iccSeen && iccColor ) {
564
// TODO check for existing
565
SVGICCColor* tmp = new SVGICCColor(*iccColor);
566
paint_res->value.color.icc = tmp;
527
571
return QUERY_STYLE_MULTIPLE_SAME;
1057
objects_query_fontspecification (GSList *objects, SPStyle *style_res)
1059
bool different = false;
1062
if (style_res->text->font_specification.value) {
1063
g_free(style_res->text->font_specification.value);
1064
style_res->text->font_specification.value = NULL;
1066
style_res->text->font_specification.set = FALSE;
1068
for (GSList const *i = objects; i != NULL; i = i->next) {
1069
SPObject *obj = SP_OBJECT (i->data);
1071
if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj)
1072
&& !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj)
1073
&& !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj))
1076
SPStyle *style = SP_OBJECT_STYLE (obj);
1077
if (!style) continue;
1081
if (style_res->text->font_specification.value && style_res->text->font_specification.set &&
1082
style->text->font_specification.value && style->text->font_specification.set &&
1083
strcmp (style_res->text->font_specification.value, style->text->font_specification.value)) {
1084
different = true; // different fonts
1087
if (style->text->font_specification.set) {
1089
if (style_res->text->font_specification.value) {
1090
g_free(style_res->text->font_specification.value);
1091
style_res->text->font_specification.value = NULL;
1094
style_res->text->font_specification.set = TRUE;
1095
style_res->text->font_specification.value = g_strdup(style->text->font_specification.value);
1100
return QUERY_STYLE_NOTHING;
1104
return QUERY_STYLE_MULTIPLE_DIFFERENT;
1106
return QUERY_STYLE_MULTIPLE_SAME;
1109
return QUERY_STYLE_SINGLE;
1114
objects_query_blend (GSList *objects, SPStyle *style_res)
1116
const int empty_prev = -2;
1117
const int complex_filter = 5;
1119
float blend_prev = empty_prev;
1120
bool same_blend = true;
1123
for (GSList const *i = objects; i != NULL; i = i->next) {
1124
SPObject *obj = SP_OBJECT (i->data);
1125
SPStyle *style = SP_OBJECT_STYLE (obj);
1126
if(!style || !SP_IS_ITEM(obj)) continue;
1130
//if object has a filter
1131
if (style->filter.set && style->getFilter()) {
1135
// determine whether filter is simple (blend and/or blur) or complex
1136
for(SPObject *primitive_obj = style->getFilter()->children;
1137
primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj);
1138
primitive_obj = primitive_obj->next) {
1139
SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj);
1140
if(SP_IS_FEBLEND(primitive))
1142
else if(SP_IS_GAUSSIANBLUR(primitive))
1145
blurcount = complex_filter;
1151
if(blurcount == 1 || blendcount == 1) {
1152
for(SPObject *primitive_obj = style->getFilter()->children;
1153
primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj);
1154
primitive_obj = primitive_obj->next) {
1155
if(SP_IS_FEBLEND(primitive_obj)) {
1156
SPFeBlend *spblend = SP_FEBLEND(primitive_obj);
1157
blend = spblend->blend_mode;
1162
blend = complex_filter;
1165
// defaults to blend mode = "normal"
1170
if(blend_prev != empty_prev && blend_prev != blend)
1176
style_res->filter_blend_mode.value = blend;
1180
return QUERY_STYLE_NOTHING;
1181
} else if (items == 1) {
1182
return QUERY_STYLE_SINGLE;
1185
return QUERY_STYLE_MULTIPLE_SAME;
1187
return QUERY_STYLE_MULTIPLE_DIFFERENT;
1192
* Write to style_res the average blurring of a list of objects.
1195
objects_query_blur (GSList *objects, SPStyle *style_res)
1197
if (g_slist_length(objects) == 0) {
1198
/* No objects, set empty */
1199
return QUERY_STYLE_NOTHING;
1203
float blur_prev = -1;
1204
bool same_blur = true;
1205
guint blur_items = 0;
1208
for (GSList const *i = objects; i != NULL; i = i->next) {
1209
SPObject *obj = SP_OBJECT (i->data);
1210
SPStyle *style = SP_OBJECT_STYLE (obj);
1211
if (!style) continue;
1212
if (!SP_IS_ITEM(obj)) continue;
1214
NR::Matrix i2d = sp_item_i2d_affine (SP_ITEM(obj));
1218
//if object has a filter
1219
if (style->filter.set && style->getFilter()) {
1220
//cycle through filter primitives
1221
SPObject *primitive_obj = style->getFilter()->children;
1222
while (primitive_obj) {
1223
if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) {
1224
SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj);
1226
//if primitive is gaussianblur
1227
if(SP_IS_GAUSSIANBLUR(primitive)) {
1228
SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
1229
float num = spblur->stdDeviation.getNumber();
1230
blur_sum += num * NR::expansion(i2d);
1231
if (blur_prev != -1 && fabs (num - blur_prev) > 1e-2) // rather low tolerance because difference in blur radii is much harder to notice than e.g. difference in sizes
1234
//TODO: deal with opt number, for the moment it's not necessary to the ui.
1238
primitive_obj = primitive_obj->next;
1245
blur_sum /= blur_items;
1246
style_res->filter_gaussianBlur_deviation.value = blur_sum;
1250
return QUERY_STYLE_NOTHING;
1251
} else if (items == 1) {
1252
return QUERY_STYLE_SINGLE;
1255
return QUERY_STYLE_MULTIPLE_SAME;
1257
return QUERY_STYLE_MULTIPLE_AVERAGED;
1013
1262
* Query the given list of objects for the given property, write
1014
1263
* the result to style, return appropriate flag.
1033
1282
} else if (property == QUERY_STYLE_PROPERTY_MASTEROPACITY) {
1034
1283
return objects_query_opacity (list, style);
1285
} else if (property == QUERY_STYLE_PROPERTY_FONT_SPECIFICATION) {
1286
return objects_query_fontspecification (list, style);
1036
1287
} else if (property == QUERY_STYLE_PROPERTY_FONTFAMILY) {
1037
1288
return objects_query_fontfamily (list, style);
1038
1289
} else if (property == QUERY_STYLE_PROPERTY_FONTSTYLE) {
1039
1290
return objects_query_fontstyle (list, style);
1040
1291
} else if (property == QUERY_STYLE_PROPERTY_FONTNUMBERS) {
1041
1292
return objects_query_fontnumbers (list, style);
1294
} else if (property == QUERY_STYLE_PROPERTY_BLEND) {
1295
return objects_query_blend (list, style);
1296
} else if (property == QUERY_STYLE_PROPERTY_BLUR) {
1297
return objects_query_blur (list, style);
1044
1299
return QUERY_STYLE_NOTHING;
1078
1333
int result_strokecap = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKECAP);
1079
1334
int result_strokejoin = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
1080
1335
int result_opacity = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
1082
return (result_family != QUERY_STYLE_NOTHING && result_fstyle != QUERY_STYLE_NOTHING && result_fnumbers != QUERY_STYLE_NOTHING && result_fill != QUERY_STYLE_NOTHING && result_stroke != QUERY_STYLE_NOTHING && result_opacity != QUERY_STYLE_NOTHING && result_strokewidth != QUERY_STYLE_NOTHING && result_strokemiterlimit != QUERY_STYLE_NOTHING && result_strokecap != QUERY_STYLE_NOTHING && result_strokejoin != QUERY_STYLE_NOTHING);
1336
int result_blur = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_BLUR);
1338
return (result_family != QUERY_STYLE_NOTHING ||
1339
result_fstyle != QUERY_STYLE_NOTHING ||
1340
result_fnumbers != QUERY_STYLE_NOTHING ||
1341
result_fill != QUERY_STYLE_NOTHING ||
1342
result_stroke != QUERY_STYLE_NOTHING ||
1343
result_opacity != QUERY_STYLE_NOTHING ||
1344
result_strokewidth != QUERY_STYLE_NOTHING ||
1345
result_strokemiterlimit != QUERY_STYLE_NOTHING ||
1346
result_strokecap != QUERY_STYLE_NOTHING ||
1347
result_strokejoin != QUERY_STYLE_NOTHING ||
1348
result_blur != QUERY_STYLE_NOTHING);