summaryrefslogtreecommitdiffstats
path: root/src/desktop-style.cpp
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-07-24 19:53:33 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-07-24 19:53:33 +0000
commit5a37f06c70e0e4e2519812564f4dcdced7c0246a (patch)
treef959f73813cb6f968072aee1100323b24e294136 /src/desktop-style.cpp
parentupdate to trunk (diff)
parentFix a bug continuing a bezier path whith a LPE one like spiro or bspline on a... (diff)
downloadinkscape-5a37f06c70e0e4e2519812564f4dcdced7c0246a.tar.gz
inkscape-5a37f06c70e0e4e2519812564f4dcdced7c0246a.zip
update to trunk
(bzr r13879.1.17)
Diffstat (limited to 'src/desktop-style.cpp')
-rw-r--r--src/desktop-style.cpp275
1 files changed, 212 insertions, 63 deletions
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index c713e0d61..02c18339b 100644
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
@@ -194,10 +194,10 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write
sp_repr_css_merge(css_write, css);
sp_css_attr_unset_uris(css_write);
prefs->mergeStyle("/desktop/style", css_write);
-
- for (const GSList *i = desktop->selection->itemList(); i != NULL; i = i->next) {
+ std::vector<SPItem*> const itemlist = desktop->selection->itemList();
+ for (std::vector<SPItem*>::const_iterator i = itemlist.begin(); i!= itemlist.end(); i++) {
/* last used styles for 3D box faces are stored separately */
- SPObject *obj = reinterpret_cast<SPObject *>(i->data); // TODO unsafe until Selection is refactored.
+ SPObject *obj = *i;
Box3DSide *side = dynamic_cast<Box3DSide *>(obj);
if (side) {
const char * descr = box3d_side_axes_string(side);
@@ -234,8 +234,9 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write
sp_repr_css_merge(css_no_text, css);
css_no_text = sp_css_attr_unset_text(css_no_text);
- for (GSList const *i = desktop->selection->itemList(); i != NULL; i = i->next) {
- SPItem *item = reinterpret_cast<SPItem *>(i->data);
+ std::vector<SPItem*> const itemlist = desktop->selection->itemList();
+ for (std::vector<SPItem*>::const_iterator i = itemlist.begin(); i!= itemlist.end(); i++) {
+ SPItem *item = *i;
// If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME)
if (isTextualItem(item)) {
@@ -438,18 +439,16 @@ sp_desktop_get_font_size_tool(SPDesktop *desktop)
/** Determine average stroke width, simple method */
// see TODO in dialogs/stroke-style.cpp on how to get rid of this eventually
gdouble
-stroke_average_width (GSList const *objects)
+stroke_average_width (const std::vector<SPItem*> &objects)
{
- if (g_slist_length ((GSList *) objects) == 0)
+ if (objects.empty())
return Geom::infinity();
gdouble avgwidth = 0.0;
bool notstroked = true;
int n_notstroked = 0;
-
- for (GSList const *l = objects; l != NULL; l = l->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(l->data);
- SPItem *item = dynamic_cast<SPItem *>(obj);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPItem *item = *i;
if (!item) {
continue;
}
@@ -471,7 +470,7 @@ stroke_average_width (GSList const *objects)
if (notstroked)
return Geom::infinity();
- return avgwidth / (g_slist_length ((GSList *) objects) - n_notstroked);
+ return avgwidth / (objects.size() - n_notstroked);
}
static bool vectorsClose( std::vector<double> const &lhs, std::vector<double> const &rhs )
@@ -492,9 +491,9 @@ static bool vectorsClose( std::vector<double> const &lhs, std::vector<double> co
* Write to style_res the average fill or stroke of list of objects, if applicable.
*/
int
-objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill)
+objects_query_fillstroke (const std::vector<SPItem*> &objects, SPStyle *style_res, bool const isfill)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -514,8 +513,8 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
prev[0] = prev[1] = prev[2] = 0.0;
bool same_color = true;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i!= objects.end(); i++) {
+ SPObject *obj = *i;
if (!obj) {
continue;
}
@@ -577,8 +576,8 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server
}
- SPPattern *pat = pattern_getroot (pattern);
- SPPattern *pat_res = pattern_getroot (pattern_res);
+ SPPattern *pat = SP_PATTERN (server)->rootPattern();
+ SPPattern *pat_res = SP_PATTERN (server_res)->rootPattern();
if (pat_res != pat) {
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots
}
@@ -674,7 +673,7 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
}
// Not color
- if (g_slist_length(objects) > 1) {
+ if (objects.size() > 1) {
return QUERY_STYLE_MULTIPLE_SAME;
} else {
return QUERY_STYLE_SINGLE;
@@ -685,9 +684,9 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill
* Write to style_res the average opacity of a list of objects.
*/
int
-objects_query_opacity (GSList *objects, SPStyle *style_res)
+objects_query_opacity (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -698,8 +697,8 @@ objects_query_opacity (GSList *objects, SPStyle *style_res)
guint opacity_items = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!obj) {
continue;
}
@@ -739,9 +738,9 @@ objects_query_opacity (GSList *objects, SPStyle *style_res)
* Write to style_res the average stroke width of a list of objects.
*/
int
-objects_query_strokewidth (GSList *objects, SPStyle *style_res)
+objects_query_strokewidth (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -754,8 +753,8 @@ objects_query_strokewidth (GSList *objects, SPStyle *style_res)
int n_stroked = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!obj) {
continue;
}
@@ -815,9 +814,9 @@ objects_query_strokewidth (GSList *objects, SPStyle *style_res)
* Write to style_res the average miter limit of a list of objects.
*/
int
-objects_query_miterlimit (GSList *objects, SPStyle *style_res)
+objects_query_miterlimit (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -828,8 +827,8 @@ objects_query_miterlimit (GSList *objects, SPStyle *style_res)
gdouble prev_ml = -1;
bool same_ml = true;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!dynamic_cast<SPItem *>(obj)) {
continue;
}
@@ -875,9 +874,9 @@ objects_query_miterlimit (GSList *objects, SPStyle *style_res)
* Write to style_res the stroke cap of a list of objects.
*/
int
-objects_query_strokecap (GSList *objects, SPStyle *style_res)
+objects_query_strokecap (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -887,8 +886,8 @@ objects_query_strokecap (GSList *objects, SPStyle *style_res)
bool same_cap = true;
int n_stroked = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!dynamic_cast<SPItem *>(obj)) {
continue;
}
@@ -929,9 +928,9 @@ objects_query_strokecap (GSList *objects, SPStyle *style_res)
* Write to style_res the stroke join of a list of objects.
*/
int
-objects_query_strokejoin (GSList *objects, SPStyle *style_res)
+objects_query_strokejoin (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -941,8 +940,8 @@ objects_query_strokejoin (GSList *objects, SPStyle *style_res)
bool same_join = true;
int n_stroked = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!dynamic_cast<SPItem *>(obj)) {
continue;
}
@@ -984,7 +983,7 @@ objects_query_strokejoin (GSList *objects, SPStyle *style_res)
* Write to style_res the average font size and spacing of objects.
*/
int
-objects_query_fontnumbers (GSList *objects, SPStyle *style_res)
+objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
@@ -1004,8 +1003,8 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res)
int texts = 0;
int no_size = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!isTextualItem(obj)) {
continue;
@@ -1116,15 +1115,15 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res)
* Write to style_res the average font style of objects.
*/
int
-objects_query_fontstyle (GSList *objects, SPStyle *style_res)
+objects_query_fontstyle (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
bool set = false;
int texts = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!isTextualItem(obj)) {
continue;
@@ -1169,11 +1168,156 @@ objects_query_fontstyle (GSList *objects, SPStyle *style_res)
}
}
+int
+objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_res)
+{
+ bool set = false;
+
+ int texts = 0;
+
+ SPILigatures* ligatures_res = &(style_res->font_variant_ligatures);
+ SPIEnum* position_res = &(style_res->font_variant_position);
+ SPIEnum* caps_res = &(style_res->font_variant_caps);
+ SPINumeric* numeric_res = &(style_res->font_variant_numeric);
+
+ // Stores 'and' of all values
+ ligatures_res->computed = SP_CSS_FONT_VARIANT_LIGATURES_NORMAL;
+ position_res->computed = SP_CSS_FONT_VARIANT_POSITION_NORMAL;
+ caps_res->computed = SP_CSS_FONT_VARIANT_CAPS_NORMAL;
+ numeric_res->computed = SP_CSS_FONT_VARIANT_NUMERIC_NORMAL;
+
+ // Stores only differences
+ ligatures_res->value = 0;
+ position_res->value = 0;
+ caps_res->value = 0;
+ numeric_res->value = 0;
+
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
+
+ if (!isTextualItem(obj)) {
+ continue;
+ }
+
+ SPStyle *style = obj->style;
+ if (!style) {
+ continue;
+ }
+
+ texts ++;
+
+ SPILigatures* ligatures_in = &(style->font_variant_ligatures);
+ SPIEnum* position_in = &(style->font_variant_position);
+ SPIEnum* caps_in = &(style->font_variant_caps);
+ SPINumeric* numeric_in = &(style->font_variant_numeric);
+ // computed stores which bits are on/off, only valid if same between all selected objects.
+ // value stores which bits are different between objects. This is a bit of an abuse of
+ // the values but then we don't need to add new variables to class.
+ if (set) {
+ ligatures_res->value |= (ligatures_res->computed ^ ligatures_in->computed );
+ ligatures_res->computed &= ligatures_in->computed;
+
+ position_res->value |= (position_res->computed ^ position_in->computed );
+ position_res->computed &= position_in->computed;
+
+ caps_res->value |= (caps_res->computed ^ caps_in->computed );
+ caps_res->computed &= caps_in->computed;
+
+ numeric_res->value |= (numeric_res->computed ^ numeric_in->computed );
+ numeric_res->computed &= numeric_in->computed;
+
+ } else {
+ ligatures_res->computed = ligatures_in->computed;
+ position_res->computed = position_in->computed;
+ caps_res->computed = caps_in->computed;
+ numeric_res->computed = numeric_in->computed;
+ }
+
+ set = true;
+ }
+
+ bool different = (style_res->font_variant_ligatures.value != 0 ||
+ style_res->font_variant_position.value != 0 ||
+ style_res->font_variant_caps.value != 0 ||
+ style_res->font_variant_numeric.value != 0 );
+
+ if (texts == 0 || !set)
+ return QUERY_STYLE_NOTHING;
+
+ if (texts > 1) {
+ if (different) {
+ return QUERY_STYLE_MULTIPLE_DIFFERENT;
+ } else {
+ return QUERY_STYLE_MULTIPLE_SAME;
+ }
+ } else {
+ return QUERY_STYLE_SINGLE;
+ }
+}
+
+
+int
+objects_query_fontfeaturesettings (const std::vector<SPItem*> &objects, SPStyle *style_res)
+{
+ bool different = false;
+ int texts = 0;
+
+ if (style_res->font_feature_settings.value) {
+ g_free(style_res->font_feature_settings.value);
+ style_res->font_feature_settings.value = NULL;
+ }
+ style_res->font_feature_settings.set = FALSE;
+
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
+
+ // std::cout << " " << reinterpret_cast<SPObject*>(i->data)->getId() << std::endl;
+ if (!isTextualItem(obj)) {
+ continue;
+ }
+
+ SPStyle *style = obj->style;
+ if (!style) {
+ continue;
+ }
+
+ texts ++;
+
+ if (style_res->font_feature_settings.value && style->font_feature_settings.value &&
+ strcmp (style_res->font_feature_settings.value, style->font_feature_settings.value)) {
+ different = true; // different fonts
+ }
+
+ if (style_res->font_feature_settings.value) {
+ g_free(style_res->font_feature_settings.value);
+ style_res->font_feature_settings.value = NULL;
+ }
+
+ style_res->font_feature_settings.set = TRUE;
+ style_res->font_feature_settings.value = g_strdup(style->font_feature_settings.value);
+ }
+
+ if (texts == 0 || !style_res->font_feature_settings.set) {
+ return QUERY_STYLE_NOTHING;
+ }
+
+ if (texts > 1) {
+ if (different) {
+ return QUERY_STYLE_MULTIPLE_DIFFERENT;
+ } else {
+ return QUERY_STYLE_MULTIPLE_SAME;
+ }
+ } else {
+ return QUERY_STYLE_SINGLE;
+ }
+}
+
+
/**
* Write to style_res the baseline numbers.
*/
static int
-objects_query_baselines (GSList *objects, SPStyle *style_res)
+objects_query_baselines (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
@@ -1192,8 +1336,8 @@ objects_query_baselines (GSList *objects, SPStyle *style_res)
int texts = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!isTextualItem(obj)) {
continue;
@@ -1269,7 +1413,7 @@ objects_query_baselines (GSList *objects, SPStyle *style_res)
* Write to style_res the average font family of objects.
*/
int
-objects_query_fontfamily (GSList *objects, SPStyle *style_res)
+objects_query_fontfamily (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
int texts = 0;
@@ -1280,8 +1424,8 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res)
}
style_res->font_family.set = FALSE;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
// std::cout << " " << reinterpret_cast<SPObject*>(i->data)->getId() << std::endl;
if (!isTextualItem(obj)) {
@@ -1325,7 +1469,7 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res)
}
static int
-objects_query_fontspecification (GSList *objects, SPStyle *style_res)
+objects_query_fontspecification (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
bool different = false;
int texts = 0;
@@ -1336,8 +1480,8 @@ objects_query_fontspecification (GSList *objects, SPStyle *style_res)
}
style_res->font_specification.set = FALSE;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
// std::cout << " " << reinterpret_cast<SPObject*>(i->data)->getId() << std::endl;
if (!isTextualItem(obj)) {
@@ -1385,7 +1529,7 @@ objects_query_fontspecification (GSList *objects, SPStyle *style_res)
}
static int
-objects_query_blend (GSList *objects, SPStyle *style_res)
+objects_query_blend (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
const int empty_prev = -2;
const int complex_filter = 5;
@@ -1394,8 +1538,8 @@ objects_query_blend (GSList *objects, SPStyle *style_res)
bool same_blend = true;
guint items = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!obj) {
continue;
}
@@ -1471,9 +1615,9 @@ objects_query_blend (GSList *objects, SPStyle *style_res)
* Write to style_res the average blurring of a list of objects.
*/
int
-objects_query_blur (GSList *objects, SPStyle *style_res)
+objects_query_blur (const std::vector<SPItem*> &objects, SPStyle *style_res)
{
- if (g_slist_length(objects) == 0) {
+ if (objects.empty()) {
/* No objects, set empty */
return QUERY_STYLE_NOTHING;
}
@@ -1484,8 +1628,8 @@ objects_query_blur (GSList *objects, SPStyle *style_res)
guint blur_items = 0;
guint items = 0;
- for (GSList const *i = objects; i != NULL; i = i->next) {
- SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
if (!obj) {
continue;
}
@@ -1553,7 +1697,7 @@ objects_query_blur (GSList *objects, SPStyle *style_res)
* the result to style, return appropriate flag.
*/
int
-sp_desktop_query_style_from_list (GSList *list, SPStyle *style, int property)
+sp_desktop_query_style_from_list (const std::vector<SPItem*> &list, SPStyle *style, int property)
{
if (property == QUERY_STYLE_PROPERTY_FILL) {
return objects_query_fillstroke (list, style, true);
@@ -1578,6 +1722,10 @@ sp_desktop_query_style_from_list (GSList *list, SPStyle *style, int property)
return objects_query_fontfamily (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTSTYLE) {
return objects_query_fontstyle (list, style);
+ } else if (property == QUERY_STYLE_PROPERTY_FONTVARIANTS) {
+ return objects_query_fontvariants (list, style);
+ } else if (property == QUERY_STYLE_PROPERTY_FONTFEATURESETTINGS) {
+ return objects_query_fontfeaturesettings (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTNUMBERS) {
return objects_query_fontnumbers (list, style);
} else if (property == QUERY_STYLE_PROPERTY_BASELINES) {
@@ -1599,6 +1747,7 @@ sp_desktop_query_style_from_list (GSList *list, SPStyle *style, int property)
int
sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property)
{
+ // Used by text tool and in gradient dragging
int ret = desktop->_query_style_signal.emit(style, property);
if (ret != QUERY_STYLE_NOTHING)
@@ -1606,7 +1755,7 @@ sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property)
// otherwise, do querying and averaging over selection
if (desktop->selection != NULL) {
- return sp_desktop_query_style_from_list ((GSList *) desktop->selection->itemList(), style, property);
+ return sp_desktop_query_style_from_list (desktop->selection->itemList(), style, property);
}
return QUERY_STYLE_NOTHING;