From 4436eae1a6810e3630679898f91fe1995d1fae7e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 10 Aug 2014 15:29:46 +0200 Subject: Export. Fix for Bug #1166184 (XAML export not compatible with Silverlight). Fixed bugs: - https://launchpad.net/bugs/1166184 (bzr r13505) --- src/extension/implementation/xslt.cpp | 40 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/xslt.cpp b/src/extension/implementation/xslt.cpp index bcea06cb5..85ae9efde 100644 --- a/src/extension/implementation/xslt.cpp +++ b/src/extension/implementation/xslt.cpp @@ -20,6 +20,7 @@ #include "xslt.h" #include "../extension.h" #include "../output.h" +#include "extension/input.h" #include "xml/repr.h" #include "io/sys.h" @@ -53,8 +54,7 @@ XSLT::XSLT(void) : { } -Glib::ustring -XSLT::solve_reldir(Inkscape::XML::Node *reprin) { +Glib::ustring XSLT::solve_reldir(Inkscape::XML::Node *reprin) { gchar const *s = reprin->attribute("reldir"); @@ -90,8 +90,7 @@ XSLT::solve_reldir(Inkscape::XML::Node *reprin) { return ""; } -bool -XSLT::check(Inkscape::Extension::Extension *module) +bool XSLT::check(Inkscape::Extension::Extension *module) { if (load(module)) { unload(module); @@ -101,8 +100,7 @@ XSLT::check(Inkscape::Extension::Extension *module) } } -bool -XSLT::load(Inkscape::Extension::Extension *module) +bool XSLT::load(Inkscape::Extension::Extension *module) { if (module->loaded()) { return true; } @@ -130,8 +128,7 @@ XSLT::load(Inkscape::Extension::Extension *module) return true; } -void -XSLT::unload(Inkscape::Extension::Extension *module) +void XSLT::unload(Inkscape::Extension::Extension *module) { if (!module->loaded()) { return; } xsltFreeStylesheet(_stylesheet); @@ -139,8 +136,8 @@ XSLT::unload(Inkscape::Extension::Extension *module) return; } -SPDocument * -XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename) +SPDocument * XSLT::open(Inkscape::Extension::Input */*module*/, + gchar const *filename) { xmlDocPtr filein = xmlParseFile(filename); if (filein == NULL) { return NULL; } @@ -184,8 +181,7 @@ XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename) return doc; } -void -XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const *filename) +void XSLT::save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename) { /* TODO: Should we assume filename to be in utf8 or to be a raw filename? * See JavaFXOutput::save for discussion. */ @@ -214,10 +210,24 @@ XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const return; } - const char * params[1]; - params[0] = NULL; + std::list params; + module->paramListString(params); + const int max_parameters = params.size() * 2; + const char * xslt_params[max_parameters+1] ; + + int count = 0; + for(std::list::iterator t=params.begin(); t != params.end(); ++t) { + std::size_t pos = t->find("="); + std::ostringstream parameter; + std::ostringstream value; + parameter << t->substr(2,pos-2); + value << t->substr(pos+1); + xslt_params[count++] = g_strdup_printf("%s", parameter.str().c_str()); + xslt_params[count++] = g_strdup_printf("'%s'", value.str().c_str()); + } + xslt_params[count] = NULL; - xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, params); + xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, xslt_params); //xmlSaveFile(filename, newdoc); int success = xsltSaveResultToFilename(filename, newdoc, _stylesheet, 0); -- cgit v1.2.3 From 96126a3b2946c788d4701e35becfb22a4c38012e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 13 Aug 2014 00:30:34 +0200 Subject: Add 'Show handles' LPE (bzr r13341.1.139) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 7 +- src/live_effects/lpe-show_handles.cpp | 211 ++++++++++++++++++++++++++++++++++ src/live_effects/lpe-show_handles.h | 61 ++++++++++ 6 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 src/live_effects/lpe-show_handles.cpp create mode 100644 src/live_effects/lpe-show_handles.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 3c64e5c8e..d126aca9f 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -31,6 +31,7 @@ set(live_effects_SRC lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp lpe-ruler.cpp + lpe-show_handles.cpp lpe-simplify.cpp # lpe-skeleton.cpp lpe-sketch.cpp @@ -99,6 +100,7 @@ set(live_effects_SRC lpe-rough-hatches.h lpe-ruler.h lpe-simplify.h + lpe-show_handles.h lpe-skeleton.h lpe-sketch.h lpe-spiro.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 91651a7c8..e9609a4aa 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -48,6 +48,8 @@ ink_common_sources += \ live_effects/lpe-lattice2.h \ live_effects/lpe-roughen.cpp \ live_effects/lpe-roughen.h \ + live_effects/lpe-show_handles.cpp \ + live_effects/lpe-show_handles.h \ live_effects/lpe-simplify.cpp \ live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index dac44981c..bc77d65c3 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -30,6 +30,7 @@ enum EffectType { LATTICE, LATTICE2, ROUGHEN, + SHOW_HANDLES, SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 387dd7b8d..dc61701df 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -28,6 +28,7 @@ #include "live_effects/lpe-lattice.h" #include "live_effects/lpe-lattice2.h" #include "live_effects/lpe-roughen.h" +#include "live_effects/lpe-show_handles.h" #include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" @@ -126,7 +127,8 @@ const Util::EnumData LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, - {ROUGHEN, N_("Roughen"), "roughen"}, + {SHOW_HANDLES, N_("Show handles"), "show_handles"}, + {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, @@ -274,6 +276,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case ROUGHEN: neweffect = static_cast ( new LPERoughen(lpeobj) ); break; + case SHOW_HANDLES: + neweffect = static_cast ( new LPEShowHandles(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp new file mode 100644 index 000000000..7b2b445b7 --- /dev/null +++ b/src/live_effects/lpe-show_handles.cpp @@ -0,0 +1,211 @@ +/* + * Authors: + * Jabier Arraiza Cenoz +* +* Copyright (C) Jabier Arraiza Cenoz 2014 + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "live_effects/lpe-show_handles.h" +#include "live_effects/parameter/parameter.h" +#include <2geom/sbasis-to-bezier.h> +#include <2geom/svg-path-parser.h> +#include "helper/geom.h" +#include "desktop-style.h" +#include "style.h" +#include "svg/svg.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true), + handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true), + originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true), + scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10) +{ + registerParameter(dynamic_cast(&nodes)); + registerParameter(dynamic_cast(&handles)); + registerParameter(dynamic_cast(&originalPath)); + registerParameter(dynamic_cast(&scaleNodesAndHandles)); + scaleNodesAndHandles.param_set_range(0, 500.); + scaleNodesAndHandles.param_set_increments(1, 1); + scaleNodesAndHandles.param_set_digits(2); + strokeWidth = 1.0; +} + +bool LPEShowHandles::alertsOff = false; + +/** + * Sets default styles to element + * this permanently remove.some styles of the element + */ + +void LPEShowHandles::doOnApply(SPLPEItem const* lpeitem) +{ + if(!alertsOff) { + char *msg = _("The \"show handles\" path effect will remove any custom style on the object you are applying it to. If this is not what you want, click Cancel."); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true); + gint response = dialog.run(); + alertsOff = true; + if(response == GTK_RESPONSE_CANCEL) { + SPLPEItem* item = const_cast(lpeitem); + item->removeCurrentPathEffect(false); + return; + } + } + SPLPEItem* item = const_cast(lpeitem); + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, "stroke", "black"); + sp_repr_css_set_property (css, "stroke-width", "1"); + sp_repr_css_set_property (css, "stroke-linecap", "butt"); + sp_repr_css_set_property(css, "fill", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); +} + +void LPEShowHandles::doBeforeEffect (SPLPEItem const* lpeitem) +{ + SPItem const* item = SP_ITEM(lpeitem); + strokeWidth = item->style->stroke_width.computed; +} + +std::vector LPEShowHandles::doEffect_path (std::vector const & path_in) +{ + std::vector path_out; + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); + if(originalPath) { + for (unsigned int i=0; i < path_in.size(); i++) { + path_out.push_back(path_in[i]); + } + } + if(!outlinepath.empty()) { + outlinepath.clear(); + } + generateHelperPath(original_pathv); + for (unsigned int i=0; i < outlinepath.size(); i++) { + path_out.push_back(outlinepath[i]); + } + return path_out; +} + +void +LPEShowHandles::generateHelperPath(Geom::PathVector result) +{ + if(!handles && !nodes) { + return; + } + + Geom::CubicBezier const *cubic = NULL; + for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { + //Si está vacío... + if (path_it->empty()) { + continue; + } + //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + if(nodes) { + drawNode(curve_it1->initialPoint()); + } + while (curve_it1 != curve_endit) { + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + if(handles) { + if(!are_near((*cubic)[0],(*cubic)[1])){ + drawHandle((*cubic)[1]); + drawHandleLine((*cubic)[0],(*cubic)[1]); + } + if(!are_near((*cubic)[3],(*cubic)[2])){ + drawHandle((*cubic)[2]); + drawHandleLine((*cubic)[3],(*cubic)[2]); + } + } + } + if(nodes) { + drawNode(curve_it1->finalPoint()); + } + ++curve_it1; + if(curve_it2 != curve_endit){ + ++curve_it2; + } + } + } +} + +void +LPEShowHandles::drawNode(Geom::Point p) +{ + if(strokeWidth * scaleNodesAndHandles > 0.0) { + double diameter = strokeWidth * scaleNodesAndHandles; + char const * svgd; + svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); + pathv += p - Geom::Point(diameter/2,diameter/2); + outlinepath.push_back(pathv[0]); + outlinepath.push_back(pathv[1]); + } +} + +void +LPEShowHandles::drawHandle(Geom::Point p) +{ + if(strokeWidth * scaleNodesAndHandles > 0.0) { + double diameter = strokeWidth * scaleNodesAndHandles; + char const * svgd; + svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); + pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35); + outlinepath.push_back(pathv[0]); + } +} + + +void +LPEShowHandles::drawHandleLine(Geom::Point p,Geom::Point p2) +{ + Geom::Path path; + double diameter = strokeWidth * scaleNodesAndHandles; + if(diameter > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){ + Geom::Ray ray2(p, p2); + p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); + } + path.start( p ); + path.appendNew( p2 ); + outlinepath.push_back(path); +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h new file mode 100644 index 000000000..278908bb5 --- /dev/null +++ b/src/live_effects/lpe-show_handles.h @@ -0,0 +1,61 @@ +#ifndef INKSCAPE_LPE_SHOW_HANDLES_H +#define INKSCAPE_LPE_SHOW_HANDLES_H + +/* + * Authors: + * Jabier Arraiza Cenoz +* +* Copyright (C) Jabier Arraiza Cenoz 2014 + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/lpegroupbbox.h" +#include "live_effects/parameter/bool.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEShowHandles : public Effect , GroupBBoxEffect { + +public: + LPEShowHandles(LivePathEffectObject *lpeobject); + virtual ~LPEShowHandles(){} + + virtual void doOnApply(SPLPEItem const* lpeitem); + + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void generateHelperPath(Geom::PathVector result); + + virtual void drawNode(Geom::Point p); + + virtual void drawHandle(Geom::Point p); + + virtual void drawHandleLine(Geom::Point p,Geom::Point p2); + +protected: + + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + + BoolParam nodes; + BoolParam handles; + BoolParam originalPath; + ScalarParam scaleNodesAndHandles; + double strokeWidth; + static bool alertsOff; + + Geom::PathVector outlinepath; + + LPEShowHandles(const LPEShowHandles &); + LPEShowHandles &operator=(const LPEShowHandles &); + +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape +#endif + +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From c73ebf3c732e19f665de2d490a915eabf425905e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 13 Aug 2014 08:24:04 +0200 Subject: Printing. Fix for Bug #264831 (Print settings not persistent). Printing. Fix for Bug #508529 (Printing rastered image offsets the page). Fixed bugs: - https://launchpad.net/bugs/264831 - https://launchpad.net/bugs/508529 (bzr r13509) --- src/ui/dialog/print.cpp | 8 +++++++- src/ui/widget/rendering-options.cpp | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..4d8d512df 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -18,6 +18,7 @@ #include #endif +#include "preferences.h" #include "print.h" #include @@ -44,14 +45,18 @@ static void draw_page( gint /*page_nr*/, gpointer user_data) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data; //printf("%s %d\n",__FUNCTION__, page_nr); if (junk->_tab->as_bitmap()) { // Render as exported PNG + prefs->setBool("/dialogs/printing/asbitmap", true); gdouble width = (junk->_doc)->getWidth().value("px"); gdouble height = (junk->_doc)->getHeight().value("px"); gdouble dpi = junk->_tab->bitmap_dpi(); + prefs->setDouble("/dialogs/printing/dpi", dpi); + std::string tmp_png; std::string tmp_base = "inkscape-print-png-XXXXXX"; @@ -92,7 +97,7 @@ static void draw_page( cairo_get_matrix(cr, &m); cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi); // FIXME: why is the origin offset?? - cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0); + cairo_set_source_surface(cr, png->cobj(), 0, 0); cairo_paint(cr); cairo_set_matrix(cr, &m); } @@ -106,6 +111,7 @@ static void draw_page( } else { // Render as vectors + prefs->setBool("/dialogs/printing/asbitmap", false); Inkscape::Extension::Internal::CairoRenderer renderer; Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index d6248df69..511b0375c 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,7 @@ # include #endif +#include "preferences.h" #include "rendering-options.h" #include "util/units.h" #include @@ -38,6 +39,7 @@ RenderingOptions::RenderingOptions () : Glib::ustring(""), Glib::ustring(""), false) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // set up tooltips _radio_vector.set_tooltip_text( _("Render using Cairo vector operations. " @@ -52,15 +54,21 @@ RenderingOptions::RenderingOptions () : set_border_width(2); - // default to vector operations - _radio_vector.set_active (true); Gtk::RadioButtonGroup group = _radio_vector.get_group (); _radio_bitmap.set_group (group); _radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled)); - + + // default to vector operations + if (prefs->getBool("/dialogs/printing/asbitmap", false)) { + _radio_bitmap.set_active(); + } else { + _radio_vector.set_active(); + } + // configure default DPI _dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0); - _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt")); + _dpi.setValue(prefs->getDouble("/dialogs/printing/dpi", + Inkscape::Util::Quantity::convert(1, "in", "pt"))); _dpi.setIncrements(1.0,10.0); _dpi.setDigits(0); _dpi.update(); -- cgit v1.2.3 From 9d5529ca1b43a144f825fc58d6aa37911a4ac7f6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:12:45 -0400 Subject: Fix build (bzr r13510) --- src/libnrtype/font-lister.cpp | 6 +++++ src/libnrtype/font-lister.h | 7 +---- src/ui/dialog/print.cpp | 4 ++- src/ui/widget/rendering-options.cpp | 2 ++ src/widgets/toolbox.cpp | 52 ++++++++++++++++++------------------- 5 files changed, 38 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 43c3045b1..3c21e62e4 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -268,6 +268,12 @@ namespace Inkscape font_list_store->thaw_notify(); } +Inkscape::FontLister* FontLister::get_instance () +{ + static Inkscape::FontLister* instance = new Inkscape::FontLister(); + return instance; +} + void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index c89dab550..09be16f24 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -149,12 +149,7 @@ namespace Inkscape update_font_list_recursive( SPObject *r, std::list *l ); public: - static Inkscape::FontLister* - get_instance () - { - static Inkscape::FontLister* instance = new Inkscape::FontLister(); - return instance; - } + static Inkscape::FontLister* get_instance (); /** Takes a hand written font spec and returns a Pango generated one in * standard form. diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 4d8d512df..ed39ebb32 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,14 +13,16 @@ #ifdef HAVE_CONFIG_H # include #endif + #ifdef WIN32 #include #include #endif +#include + #include "preferences.h" #include "print.h" -#include #include "extension/internal/cairo-render-context.h" #include "extension/internal/cairo-renderer.h" diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index 511b0375c..837387f7b 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,8 @@ # include #endif +#include + #include "preferences.h" #include "rendering-options.h" #include "util/units.h" diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 939546f78..c7d72f0b8 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -39,35 +39,35 @@ #include #include -#include "../desktop.h" -#include "../desktop-handles.h" -#include "../desktop-style.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "desktop-style.h" #include "document-undo.h" -#include "../ege-adjustment-action.h" -#include "../ege-output-action.h" -#include "../ege-select-one-action.h" -#include "../graphlayout.h" -#include "../helper/action.h" -#include "../helper/action-context.h" +#include "ege-adjustment-action.h" +#include "ege-output-action.h" +#include "ege-select-one-action.h" +#include "graphlayout.h" +#include "helper/action.h" +#include "helper/action-context.h" #include "icon.h" -#include "../ink-action.h" -#include "../ink-comboboxentry-action.h" -#include "../inkscape.h" -#include "../interface.h" -#include "../shortcuts.h" -#include "../sp-namedview.h" -#include "../tools-switch.h" -#include "../ui/icon-names.h" -#include "../ui/widget/style-swatch.h" -#include "../verbs.h" -#include "../widgets/button.h" -#include "../widgets/spinbutton-events.h" +#include "ink-action.h" +#include "ink-comboboxentry-action.h" +#include "inkscape.h" +#include "interface.h" +#include "shortcuts.h" +#include "sp-namedview.h" +#include "tools-switch.h" +#include "ui/icon-names.h" +#include "ui/widget/style-swatch.h" +#include "verbs.h" +#include "widgets/button.h" +#include "widgets/spinbutton-events.h" #include "ui/widget/spinbutton.h" -#include "../widgets/spw-utilities.h" -#include "../widgets/widget-sizes.h" -#include "../xml/attribute-record.h" -#include "../xml/node-event-vector.h" -#include "../xml/repr.h" +#include "widgets/spw-utilities.h" +#include "widgets/widget-sizes.h" +#include "xml/attribute-record.h" +#include "xml/node-event-vector.h" +#include "xml/repr.h" #include "ui/uxmanager.h" -- cgit v1.2.3 From ce41e6c128161e245d9523c0b0cbbba8e12823c7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:15:28 -0400 Subject: Revert unintentional changes (bzr r13511) --- src/libnrtype/font-lister.cpp | 6 ----- src/libnrtype/font-lister.h | 7 +++++- src/widgets/toolbox.cpp | 52 +++++++++++++++++++++---------------------- 3 files changed, 32 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 3c21e62e4..43c3045b1 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -268,12 +268,6 @@ namespace Inkscape font_list_store->thaw_notify(); } -Inkscape::FontLister* FontLister::get_instance () -{ - static Inkscape::FontLister* instance = new Inkscape::FontLister(); - return instance; -} - void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 09be16f24..c89dab550 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -149,7 +149,12 @@ namespace Inkscape update_font_list_recursive( SPObject *r, std::list *l ); public: - static Inkscape::FontLister* get_instance (); + static Inkscape::FontLister* + get_instance () + { + static Inkscape::FontLister* instance = new Inkscape::FontLister(); + return instance; + } /** Takes a hand written font spec and returns a Pango generated one in * standard form. diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c7d72f0b8..939546f78 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -39,35 +39,35 @@ #include #include -#include "desktop.h" -#include "desktop-handles.h" -#include "desktop-style.h" +#include "../desktop.h" +#include "../desktop-handles.h" +#include "../desktop-style.h" #include "document-undo.h" -#include "ege-adjustment-action.h" -#include "ege-output-action.h" -#include "ege-select-one-action.h" -#include "graphlayout.h" -#include "helper/action.h" -#include "helper/action-context.h" +#include "../ege-adjustment-action.h" +#include "../ege-output-action.h" +#include "../ege-select-one-action.h" +#include "../graphlayout.h" +#include "../helper/action.h" +#include "../helper/action-context.h" #include "icon.h" -#include "ink-action.h" -#include "ink-comboboxentry-action.h" -#include "inkscape.h" -#include "interface.h" -#include "shortcuts.h" -#include "sp-namedview.h" -#include "tools-switch.h" -#include "ui/icon-names.h" -#include "ui/widget/style-swatch.h" -#include "verbs.h" -#include "widgets/button.h" -#include "widgets/spinbutton-events.h" +#include "../ink-action.h" +#include "../ink-comboboxentry-action.h" +#include "../inkscape.h" +#include "../interface.h" +#include "../shortcuts.h" +#include "../sp-namedview.h" +#include "../tools-switch.h" +#include "../ui/icon-names.h" +#include "../ui/widget/style-swatch.h" +#include "../verbs.h" +#include "../widgets/button.h" +#include "../widgets/spinbutton-events.h" #include "ui/widget/spinbutton.h" -#include "widgets/spw-utilities.h" -#include "widgets/widget-sizes.h" -#include "xml/attribute-record.h" -#include "xml/node-event-vector.h" -#include "xml/repr.h" +#include "../widgets/spw-utilities.h" +#include "../widgets/widget-sizes.h" +#include "../xml/attribute-record.h" +#include "../xml/node-event-vector.h" +#include "../xml/repr.h" #include "ui/uxmanager.h" -- cgit v1.2.3 From 9fdd8f25ee0f04d337864c7ec5e3216dae727e3c Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 14 Aug 2014 22:09:10 +0200 Subject: Fix some transformation center regressions, related to the viewbox/units changes (bzr r13512) --- src/selection-chemistry.cpp | 7 ++----- src/sp-item-group.cpp | 8 +------- src/sp-item.cpp | 26 +++++++++++++++++++++----- src/ui/dialog/document-properties.cpp | 7 ++++--- 4 files changed, 28 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f058189d3..868a9d743 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1621,13 +1621,10 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate); } - // if we're transforming the actual object, not just updating the repr, we can transform the + // if we're moving the actual object, not just updating the repr, we can transform the // center by the same matrix (only necessary for non-translations) if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { - // If there's a viewbox, we might have an affine with a translation component; - // we will only apply the scaling/skewing components, not the translations - // because otherwise the center will move relative to the item - item->setCenter(old_center * affine.withoutTranslation()); + item->setCenter(old_center * affine); item->updateRepr(); } } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 657aca692..bb52b0c55 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -660,12 +660,6 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) Geom::Translate const s(p); Geom::Affine final = s.inverse() * sc * s; - Geom::Point old_center(0,0); - if (item->isCenterSet()) { - item->scaleCenter(sc.inverse()); // Convert the old relative center position to the new coordinates already now - old_center = item->getCenter(); // because getCenter() will use the bbox midpoint, which is also already in the new coordinates - } - gchar const *conn_type = NULL; if (SP_IS_TEXT_TEXTPATH(item)) { SP_TEXT(item)->optimizeTextpathText(); @@ -710,7 +704,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) } if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) { - item->setCenter(old_center * final); + item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled item->updateRepr(); } } diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 0cacc86b1..428f9555e 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -228,18 +228,25 @@ void SPItem::setExplicitlyHidden(bool val) { } /** - * Sets the transform_center_x and transform_center_y properties to retain the rotation centre - */ + * Sets the transform_center_x and transform_center_y properties to retain the rotation center +*/ void SPItem::setCenter(Geom::Point const &object_centre) { document->ensureUpToDate(); + // Copied from DocumentProperties::onDocUnitChange() + gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); + // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); if (bbox) { - transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X]; + // object centre is document coordinates (i.e. in pixels), so we need to consider the viewbox + // to translate to user units; transform_center_x/y is in user units + transform_center_x = (object_centre[Geom::X] - bbox->midpoint()[Geom::X])/viewscale; if (Geom::are_near(transform_center_x, 0)) // rounding error transform_center_x = 0; - transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y]; + transform_center_y = (object_centre[Geom::Y] - bbox->midpoint()[Geom::Y])/viewscale; if (Geom::are_near(transform_center_y, 0)) // rounding error transform_center_y = 0; } @@ -255,16 +262,25 @@ bool SPItem::isCenterSet() const { return (transform_center_x != 0 || transform_center_y != 0); } +// Get the item's transformation center in document coordinates (i.e. in pixels) Geom::Point SPItem::getCenter() const { document->ensureUpToDate(); + // Copied from DocumentProperties::onDocUnitChange() + gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); + // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); if (bbox) { - return bbox->midpoint() + Geom::Point (transform_center_x, transform_center_y); + // transform_center_x/y are stored in user units, so we have to take the viewbox into account to translate to document coordinates + return bbox->midpoint() + Geom::Point (transform_center_x*viewscale, transform_center_y*viewscale); + } else { return Geom::Point(0, 0); // something's wrong! } + } void diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 9141b2268..4e4616724 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -45,6 +45,7 @@ #include "widgets/icon.h" #include "xml/node-event-vector.h" #include "xml/repr.h" +#include // std::min #include "rdf.h" #include "ui/widget/entity-entry.h" @@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale) - viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); + gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 2f2df21d0c1d977644578c74ac466bcb330f71e5 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Thu, 14 Aug 2014 22:27:49 -0700 Subject: Set pre-release version to 0.91pre2 (bzr r13513) --- src/inkscape-x64.rc | 8 ++++---- src/inkscape.rc | 8 ++++---- src/inkview-x64.rc | 8 ++++---- src/inkview.rc | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc index ce286c2ca..47dbcb2bc 100644 --- a/src/inkscape-x64.rc +++ b/src/inkscape-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkscape.rc b/src/inkscape.rc index 395ef39e1..2c2c0112b 100644 --- a/src/inkscape.rc +++ b/src/inkscape.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc index 2de16060b..f23fe84c9 100644 --- a/src/inkview-x64.rc +++ b/src/inkview-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91,0,0 + PRODUCTVERSION 0,91,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkview.rc b/src/inkview.rc index fd7eb50a1..efbe2568b 100644 --- a/src/inkview.rc +++ b/src/inkview.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", "© 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" -- cgit v1.2.3 From 940176d1a9959328f186cb21c22bf43d4cfed4fc Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 15 Aug 2014 08:43:45 +0200 Subject: Preferences. Fix for Bug #184499 (Inkscape Preferences dialog does not remember tabs/pages). Fixed bugs: - https://launchpad.net/bugs/184499 (bzr r13517) --- src/ui/dialog/inkscape-preferences.cpp | 8 ++++++-- src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index f1a29e971..5d065dc60 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -76,7 +76,8 @@ InkscapePreferences::InkscapePreferences() : UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY), _max_dialog_width(0), _max_dialog_height(0), - _current_page(0) + _current_page(0), + _init(true) { //get the width of a spinbutton Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton; @@ -2000,6 +2001,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter) Gtk::TreeModel::Row row = *iter; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int desired_page = prefs->getInt("/dialogs/preferences/page", 0); + _init = false; if (desired_page == row[_page_list_columns._col_id]) { if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR) @@ -2049,7 +2051,9 @@ void InkscapePreferences::on_pagelist_selection_changed() Gtk::TreeModel::Row row = *iter; _current_page = row[_page_list_columns._col_page]; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + if (!_init) { + prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + } _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); _page_frame.add(*_current_page); _current_page->show(); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 1c2151605..9f37626ed 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -532,6 +532,7 @@ private: InkscapePreferences(); InkscapePreferences(InkscapePreferences const &d); InkscapePreferences operator=(InkscapePreferences const &d); + bool _init; }; } // namespace Dialog -- cgit v1.2.3 From f0d21a859fd6c3594e46339030e7209e0138da04 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 15 Aug 2014 15:11:41 +0200 Subject: suppress compiler warning (bzr r13519) --- src/sp-solid-color.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp index 1f606d176..9f6692f98 100644 --- a/src/sp-solid-color.cpp +++ b/src/sp-solid-color.cpp @@ -72,7 +72,7 @@ Inkscape::XML::Node* SPSolidColor::write(Inkscape::XML::Document* xml_doc, Inksc return repr; } -cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const &bbox, double opacity) { +cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const & /*bbox*/, double opacity) { SPIColor *c = &(this->style->solid_color); cairo_pattern_t *cp = cairo_pattern_create_rgba ( c->value.color.v.c[0], c->value.color.v.c[1], c->value.color.v.c[2], SP_SCALE24_TO_FLOAT(this->style->solid_opacity.value) * opacity ); -- cgit v1.2.3 From ab9df1bf462c32d785e0b146228d5711a0599114 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 15 Aug 2014 15:14:32 +0200 Subject: memleak fix (Bug #1293827: LivePathEffect memory leak ) (bzr r13520) --- src/live_effects/parameter/parameter.cpp | 8 +++++++- src/live_effects/parameter/parameter.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a5de2169e..ad2960cd9 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -36,13 +36,19 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip, { } - void Parameter::param_write_to_repr(const char * svgd) { param_effect->getRepr()->setAttribute(param_key.c_str(), svgd); } +void Parameter::write_to_SVG(void) +{ + gchar * str = param_getSVGValue(); + param_write_to_repr(str); + g_free(str); +} + /*########################################### * REAL PARAM */ diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 785ada92e..2e6cae49f 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -49,7 +49,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted. virtual gchar * param_getSVGValue() const = 0; - void write_to_SVG() { param_write_to_repr(param_getSVGValue()); } + void write_to_SVG(); virtual void param_set_default() = 0; -- cgit v1.2.3 From 13db4e8d7c2250a8b5a88beca4a5800ef90b7f54 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 16 Aug 2014 22:54:37 +0200 Subject: Fix shift of transformation center on pasting Fixed bugs: - https://launchpad.net/bugs/1247799 (bzr r13521) --- src/file.cpp | 6 +++--- src/selection-chemistry.cpp | 14 ++++++++------ src/selection-chemistry.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 51e629c7d..580c93c9e 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1087,9 +1087,9 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) Inkscape::Selection *selection = sp_desktop_selection(desktop); selection->setReprList(pasted_objects); - // invers apply parent transform + // Apply inverse of parent transform Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false); + sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); // Update (among other things) all curves in paths, for bounds() to work target_document->ensureUpToDate(); @@ -1226,7 +1226,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // c2p is identity matrix at this point unless ensureUpToDate is called doc->ensureUpToDate(); Geom::Affine affine = doc->getRoot()->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false); + sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false); // move to mouse pointer { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 868a9d743..01ce20509 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1466,7 +1466,7 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate) +void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) { if (selection->isEmpty()) return; @@ -1621,11 +1621,13 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate); } - // if we're moving the actual object, not just updating the repr, we can transform the - // center by the same matrix (only necessary for non-translations) - if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { - item->setCenter(old_center * affine); - item->updateRepr(); + if (adjust_transf_center) { // The transformation center should not be touched in case of pasting or importing, which is allowed by this if clause + // if we're moving the actual object, not just updating the repr, we can transform the + // center by the same matrix (only necessary for non-translations) + if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { + item->setCenter(old_center * affine); + item->updateRepr(); + } } } } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index d76a67a9d..01c35d65a 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -104,7 +104,7 @@ void sp_selection_to_next_layer( SPDesktop *desktop, bool suppressDone = false ) void sp_selection_to_prev_layer( SPDesktop *desktop, bool suppressDone = false ); void sp_selection_to_layer( SPDesktop *desktop, SPObject *layer, bool suppressDone = false ); -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true); +void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true); void sp_selection_remove_transform (SPDesktop *desktop); void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1); void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale); -- cgit v1.2.3 From 38b8b56f7a45878b6aea857f8bcc15064f44200d Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 16 Aug 2014 20:23:01 -0400 Subject: Fix grid jumping (bug #1342238). Fixed bugs: - https://launchpad.net/bugs/1342238 (bzr r13522) --- src/display/canvas-axonomgrid.cpp | 3 +++ src/util/units.cpp | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 312a8d655..592c962a6 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -387,6 +387,9 @@ _wr.setUpdating (false); _rcp_gmcol->setRgba32 (empcolor); _rsi->setValue (empspacing); + _rsu_ox->setProgrammatically = false; + _rsu_oy->setProgrammatically = false; + return table; } diff --git a/src/util/units.cpp b/src/util/units.cpp index d2053f60b..eb4a313e0 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -291,11 +291,15 @@ Quantity UnitTable::parseQuantity(Glib::ustring const &q) const std::istringstream tmp_v(match_info.fetch(0)); tmp_v >> value; } + int start_pos, end_pos; + match_info.fetch_pos(0, end_pos, start_pos); + end_pos = q.size() - start_pos; + Glib::ustring u = q.substr(start_pos, end_pos); // Extract unit abbreviation Glib::ustring abbr; Glib::RefPtr unit_regex = Glib::Regex::create("[A-z%]+"); - if (unit_regex->match(q, match_info)) { + if (unit_regex->match(u, match_info)) { abbr = match_info.fetch(0); } -- cgit v1.2.3 From 06b2a7b43586148d32f546ad82e6a47ba2a597fd Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:43:35 -0400 Subject: Work around for upstream GTK bug #734915 (speeds launch times) (bzr r13523) --- src/ink-comboboxentry-action.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index ebd238edc..6579c8ff8 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -383,6 +383,15 @@ GtkWidget* create_tool_item( GtkAction* action ) g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action ); + // Optionally add separator function... + if( ink_comboboxentry_action->separator_func != NULL ) { + gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, + GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), + NULL, NULL ); + } + + gtk_widget_show_all (comboBoxEntry); + // Optionally add formatting... if( ink_comboboxentry_action->cell_data_func != NULL ) { GtkCellRenderer *cell = gtk_cell_renderer_text_new(); @@ -393,13 +402,6 @@ GtkWidget* create_tool_item( GtkAction* action ) NULL, NULL ); } - // Optionally add separator function... - if( ink_comboboxentry_action->separator_func != NULL ) { - gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, - GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), - NULL, NULL ); - } - // Optionally widen the combobox width... which widens the drop-down list in list mode. if( ink_comboboxentry_action->extra_width > 0 ) { GtkRequisition req; -- cgit v1.2.3 From 2a2db8af11c2e518bd7bfe520e2f88a7e439d939 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:47:53 -0400 Subject: Merge in font-speedup branch to improve launch times (bzr r13341.1.140) --- src/ink-comboboxentry-action.cpp | 18 +- src/libnrtype/FontFactory.cpp | 76 ++ src/libnrtype/FontFactory.h | 10 +- src/libnrtype/font-lister.cpp | 1697 +++++++++++++++++++------------------- src/libnrtype/font-lister.h | 556 ++++++------- src/ui/dialog/text-edit.cpp | 6 +- src/widgets/font-selector.cpp | 4 +- src/widgets/text-toolbar.cpp | 10 +- 8 files changed, 1239 insertions(+), 1138 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index ebd238edc..6ae2a8485 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -383,6 +383,17 @@ GtkWidget* create_tool_item( GtkAction* action ) g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action ); + // Optionally add separator function... + if( ink_comboboxentry_action->separator_func != NULL ) { + gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, + GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), + NULL, NULL ); + } + + // FIXME: once gtk3 migration is done this can be removed + // https://bugzilla.gnome.org/show_bug.cgi?id=734915 + gtk_widget_show_all (comboBoxEntry); + // Optionally add formatting... if( ink_comboboxentry_action->cell_data_func != NULL ) { GtkCellRenderer *cell = gtk_cell_renderer_text_new(); @@ -393,13 +404,6 @@ GtkWidget* create_tool_item( GtkAction* action ) NULL, NULL ); } - // Optionally add separator function... - if( ink_comboboxentry_action->separator_func != NULL ) { - gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, - GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), - NULL, NULL ); - } - // Optionally widen the combobox width... which widens the drop-down list in list mode. if( ink_comboboxentry_action->extra_width > 0 ) { GtkRequisition req; diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 6859a4a5c..c5e68e264 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -513,6 +513,82 @@ static bool StyleNameCompareInternal(const StyleNames &style1, const StyleNames return( StyleNameValue( style1.CssName ) < StyleNameValue( style2.CssName ) ); } +static bool ustringPairSort(std::pair const& first, std::pair const& second) +{ + // well, this looks weird. + return first.second < second.second; +} + +void font_factory::GetUIFamilies(std::vector& out) +{ + // Gather the family names as listed by Pango + PangoFontFamily** families = NULL; + int numFamilies = 0; + pango_font_map_list_families(fontServer, &families, &numFamilies); + + std::vector > sorted; + + // not size_t + for (int currentFamily = 0; currentFamily < numFamilies; ++currentFamily) { + const char* displayName = pango_font_family_get_name(families[currentFamily]); + + if (displayName == 0 || *displayName == '\0') { + continue; + } + sorted.push_back(std::make_pair(families[currentFamily], displayName)); + } + + std::sort(sorted.begin(), sorted.end(), ustringPairSort); + + for (size_t i = 0; i < sorted.size(); ++i) { + out.push_back(sorted[i].first); + } +} + +GList* font_factory::GetUIStyles(PangoFontFamily * in) +{ + GList* ret = NULL; + // Gather the styles for this family + PangoFontFace** faces = NULL; + int numFaces = 0; + pango_font_family_list_faces(in, &faces, &numFaces); + + for (int currentFace = 0; currentFace < numFaces; currentFace++) { + + // If the face has a name, describe it, and then use the + // description to get the UI family and face strings + const gchar* displayName = pango_font_face_get_face_name(faces[currentFace]); + if (displayName == NULL || *displayName == '\0') { + continue; + } + + PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]); + if (faceDescr) { + Glib::ustring familyUIName = GetUIFamilyString(faceDescr); + Glib::ustring styleUIName = GetUIStyleString(faceDescr); + + // Disable synthesized (faux) font faces except for CSS generic faces + if (pango_font_face_is_synthesized(faces[currentFace]) ) { + if (familyUIName.compare( "sans-serif" ) != 0 && + familyUIName.compare( "serif" ) != 0 && + familyUIName.compare( "monospace" ) != 0 && + familyUIName.compare( "fantasy" ) != 0 && + familyUIName.compare( "cursive" ) != 0 ) { + continue; + } + } + + if (!familyUIName.empty() && !styleUIName.empty()) { + // Add the style information + ret = g_list_append(ret, new StyleNames(styleUIName, displayName)); + } + } + pango_font_description_free(faceDescr); + } + g_free(faces); + return ret; +} + void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) { g_assert(map); diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 513ee4bf7..c48ae831a 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -23,7 +23,7 @@ #include "nr-type-primitives.h" #include "nr-type-pos-def.h" #include "font-style-to-pos.h" -#include "../style.h" +#include "style.h" /* Freetype */ #ifdef USE_PANGO_WIN32 @@ -123,7 +123,13 @@ public: // Gathers all strings needed for UI while storing pango information in // fontInstanceMap and fontStringMap + // don't use this function, it's too slow void GetUIFamiliesAndStyles(FamilyToStylesMap *map); + + // Helpfully inserts all font families into the provided vector + void GetUIFamilies(std::vector& out); + // Retrieves style information about a family in a newly allocated GList. + GList* GetUIStyles(PangoFontFamily * in); /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information font_instance* FaceFromStyle(SPStyle const *style); @@ -177,4 +183,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 43c3045b1..07c80054d 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -1,5 +1,5 @@ #ifdef HAVE_CONFIG_H -# include +#include #endif #include @@ -27,410 +27,432 @@ // CSS dictates that font family names are case insensitive. // This should really implement full Unicode case unfolding. -bool familyNamesAreEqual( const Glib::ustring &a, const Glib::ustring &b ) { +bool familyNamesAreEqual(const Glib::ustring &a, const Glib::ustring &b) +{ + return (a.casefold().compare(b.casefold()) == 0); +} - return( a.casefold().compare( b.casefold() ) == 0 ); +static const char* sp_font_family_get_name(PangoFontFamily* family) +{ + const char* name = pango_font_family_get_name(family); + if (strncmp(name, "Sans", 4) == 0 && strlen(name) == 4) + return "sans-serif"; + if (strncmp(name, "Serif", 5) == 0 && strlen(name) == 5) + return "serif"; + if (strncmp(name, "Monospace", 9) == 0 && strlen(name) == 9) + return "monospace"; + return name; } -namespace Inkscape +namespace Inkscape { + +FontLister::FontLister() { - FontLister::FontLister () - { - font_list_store = Gtk::ListStore::create (FontList); - font_list_store->freeze_notify(); - - FamilyToStylesMap familyStyleMap; - font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); - - // Grab the family names into a list and then sort them - std::list familyList; - for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); - iter != familyStyleMap.end(); - ++iter) { - familyList.push_back((*iter).first); + font_list_store = Gtk::ListStore::create(FontList); + font_list_store->freeze_notify(); + + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append(NULL, new StyleNames("Normal")); + default_styles = g_list_append(default_styles, new StyleNames("Italic")); + default_styles = g_list_append(default_styles, new StyleNames("Bold")); + default_styles = g_list_append(default_styles, new StyleNames("Bold Italic")); + + // Get sorted font families from Pango + std::vector familyVector; + font_factory::Default()->GetUIFamilies(familyVector); + + // Traverse through the family names and set up the list store + for (size_t i = 0; i < familyVector.size(); ++i) { + const char* displayName = sp_font_family_get_name(familyVector[i]); + + if (displayName == 0 || *displayName == '\0') { + continue; } - familyList.sort(); - // Traverse through the family names and set up the list store (note that - // the styles list that are the map's values are already sorted) - while (!familyList.empty()) { - Glib::ustring familyName = familyList.front(); - familyList.pop_front(); - - if (!familyName.empty()) { - Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); - //(*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(familyName.c_str())); - (*treeModelIter)[FontList.family] = familyName; - - // Now go through the styles - GList *styles = NULL; - std::list &styleStrings = familyStyleMap[familyName]; - for (std::list::iterator it=styleStrings.begin(); - it != styleStrings.end(); - ++it) { - // Our own copy - StyleNames *copy = new StyleNames( *it ); - styles = g_list_append(styles, copy); - } - - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = true; - } + Glib::ustring familyName = displayName; + if (!familyName.empty()) { + Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); + (*treeModelIter)[FontList.family] = familyName; + + // we don't set this now (too slow) but the style will be cached if the user + // ever decides to use this font + (*treeModelIter)[FontList.styles] = NULL; + // store the pango representation for generating the style + (*treeModelIter)[FontList.pango_family] = familyVector[i]; + (*treeModelIter)[FontList.onSystem] = true; } - current_family_row = 0; - current_family = "sans-serif"; - current_style = "Normal"; - current_fontspec = "sans-serif"; // Empty style -> Normal - current_fontspec_system = "Sans"; - - /* Create default styles for use when font-family is unknown on system. */ - default_styles = g_list_append( NULL, new StyleNames( "Normal" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Italic" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Bold" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Bold Italic" ) ); - - font_list_store->thaw_notify(); - - style_list_store = Gtk::ListStore::create (FontStyleList); - - // Initialize style store with defaults - style_list_store->freeze_notify(); - style_list_store->clear(); - for (GList *l=default_styles; l; l = l->next) { - Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; - (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; + } + + current_family_row = 0; + current_family = "sans-serif"; + current_style = "Normal"; + current_fontspec = "sans-serif"; // Empty style -> Normal + current_fontspec_system = "Sans"; + + font_list_store->thaw_notify(); + + style_list_store = Gtk::ListStore::create(FontStyleList); + + // Initialize style store with defaults + style_list_store->freeze_notify(); + style_list_store->clear(); + for (GList *l = default_styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName; + } + style_list_store->thaw_notify(); +} + +FontLister::~FontLister() +{ + // Delete default_styles + for (GList *l = default_styles; l; l = l->next) { + delete ((StyleNames *)l->data); + } + + // Delete other styles + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter; + GList *styles = row[FontList.styles]; + for (GList *l = styles; l; l = l->next) { + delete ((StyleNames *)l->data); } - style_list_store->thaw_notify(); + ++iter; } +} - FontLister::~FontLister() { +FontLister *FontLister::get_instance() +{ + static Inkscape::FontLister *instance = new Inkscape::FontLister(); + return instance; +} - // Delete default_styles - for (GList *l=default_styles; l; l = l->next) { - delete ((StyleNames*)l->data); +void FontLister::ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iterator) +{ + Gtk::TreeIter iter(model, iterator); + Gtk::TreeModel::Row row = *iter; + if (!row[FontList.styles]) { + if (row[FontList.pango_family]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); } + } +} - // Delete other styles - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter; - GList *styles = row[FontList.styles]; - for (GList *l=styles; l; l = l->next) { - delete ((StyleNames*)l->data); +// Example of how to use "foreach_iter" +// bool +// FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { +// Gtk::TreeModel::Row row = *iter; +// if( !row[FontList.onSystem] ) { +// std::cout << " Not on system: " << row[FontList.family] << std::endl; +// return false; +// } +// return true; +// } +// font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); + +/* Used to insert a font that was not in the document and not on the system into the font list. */ +void FontLister::insert_font_family(Glib::ustring new_family) +{ + GList *styles = default_styles; + + /* In case this is a fallback list, check if first font-family on system. */ + std::vector tokens = Glib::Regex::split_simple(",", new_family); + if (!tokens.empty() && !tokens[0].empty()) { + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0"); + while (iter2 != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter2; + if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + styles = row[FontList.styles]; + break; } - ++iter; + ++iter2; } } - // Example of how to use "foreach_iter" - // bool - // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { - // Gtk::TreeModel::Row row = *iter; - // if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.family] << std::endl; - // return false; - // } - // return true; - // } - // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); - - /* Used to insert a font that was not in the document and not on the system into the font list. */ - void - FontLister::insert_font_family( Glib::ustring new_family ) { - - GList *styles = default_styles; - - /* In case this is a fallback list, check if first font-family on system. */ - std::vector tokens = Glib::Regex::split_simple(",", new_family ); - if( !tokens.empty() && !tokens[0].empty() ) { - - Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); - while( iter2 != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { - styles = row[FontList.styles]; + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = new_family; + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; +} + +void FontLister::update_font_list(SPDocument *document) +{ + SPObject *r = document->getRoot(); + if (!r) { + return; + } + + font_list_store->freeze_notify(); + + /* Find if current row is in document or system part of list */ + gboolean row_is_system = false; + if (current_family_row > -1) { + Gtk::TreePath path; + path.push_back(current_family_row); + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + row_is_system = (*iter)[FontList.onSystem]; + // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; + } + } + + /* Clear all old document font-family entries */ + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter; + if (!row[FontList.onSystem]) { + // std::cout << " Not on system: " << row[FontList.family] << std::endl; + iter = font_list_store->erase(iter); + } else { + // std::cout << " First on system: " << row[FontList.family] << std::endl; break; - } - ++iter2; } - } + } + + /* Get "font-family"s used in document. */ + std::list fontfamilies; + update_font_list_recursive(r, &fontfamilies); + + fontfamilies.sort(); + fontfamilies.unique(); + fontfamilies.reverse(); + - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(new_family.c_str())); - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = false; + /* Insert separator */ + if (!fontfamilies.empty()) { + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = "#"; + (*treeModelIter)[FontList.onSystem] = false; } - void - FontLister::update_font_list( SPDocument* document ) { - - SPObject *r = document->getRoot(); - if( !r ) { - return; - } - - font_list_store->freeze_notify(); - - /* Find if current row is in document or system part of list */ - gboolean row_is_system = false; - if( current_family_row > -1 ) { - Gtk::TreePath path; - path.push_back( current_family_row ); - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - row_is_system = (*iter)[FontList.onSystem]; - // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; - } - } - - /* Clear all old document font-family entries */ - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter; - if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.family] << std::endl; - iter = font_list_store->erase( iter ); - } else { - // std::cout << " First on system: " << row[FontList.family] << std::endl; - break; - } - } - - /* Get "font-family"s used in document. */ - std::list fontfamilies; - update_font_list_recursive( r, &fontfamilies ); - - fontfamilies.sort(); - fontfamilies.unique(); - fontfamilies.reverse(); - - /* Insert separator */ - if( !fontfamilies.empty() ) { - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = "#"; - (*treeModelIter)[FontList.onSystem] = false; - } - - /* Insert font-family's in document. */ - std::list::iterator i; - for( i = fontfamilies.begin(); i != fontfamilies.end(); ++i) { - - GList *styles = default_styles; + /* Insert font-family's in document. */ + std::list::iterator i; + for (i = fontfamilies.begin(); i != fontfamilies.end(); ++i) { + + GList *styles = default_styles; /* See if font-family (or first in fallback list) is on system. If so, get styles. */ - std::vector tokens = Glib::Regex::split_simple(",", *i ); - if( !tokens.empty() && !tokens[0].empty() ) { - - Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); - while( iter2 != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { - styles = row[FontList.styles]; - break; - } - ++iter2; - } - } - - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup((*i).c_str())); - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = false; - } - - /* Now we do a song and dance to find the correct row as the row corresponding - * to the current_family may have changed. We can't simply search for the - * family name in the list since it can occur twice, once in the document - * font family part and once in the system font family part. Above we determined - * which part it is in. - */ - if( current_family_row > -1 ) { - int start = 0; - if( row_is_system ) start = fontfamilies.size(); - int length = font_list_store->children().size(); - for( int i = 0; i < length; ++i ) { - int row = i + start; - if( row >= length ) row -= length; - Gtk::TreePath path; - path.push_back( row ); - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - if( familyNamesAreEqual( current_family, (*iter)[FontList.family] ) ) { - current_family_row = row; - break; - } - } - } - } - // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; - - font_list_store->thaw_notify(); + std::vector tokens = Glib::Regex::split_simple(",", *i); + if (!tokens.empty() && !tokens[0].empty()) { + + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0"); + while (iter2 != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter2; + if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + styles = row[FontList.styles]; + break; + } + ++iter2; + } + } + + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup((*i).c_str())); + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; + } - void - FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { + /* Now we do a song and dance to find the correct row as the row corresponding + * to the current_family may have changed. We can't simply search for the + * family name in the list since it can occur twice, once in the document + * font family part and once in the system font family part. Above we determined + * which part it is in. + */ + if (current_family_row > -1) { + int start = 0; + if (row_is_system) + start = fontfamilies.size(); + int length = font_list_store->children().size(); + for (int i = 0; i < length; ++i) { + int row = i + start; + if (row >= length) + row -= length; + Gtk::TreePath path; + path.push_back(row); + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + if (familyNamesAreEqual(current_family, (*iter)[FontList.family])) { + current_family_row = row; + break; + } + } + } + } + // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; - const gchar *font_family = r->style->font_family.value; - if( font_family ) { - l->push_back( Glib::ustring( font_family ) ); - } + font_list_store->thaw_notify(); +} - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - update_font_list_recursive( child, l ); - } +void FontLister::update_font_list_recursive(SPObject *r, std::list *l) +{ + const gchar *font_family = r->style->font_family.value; + if (font_family) { + l->push_back(Glib::ustring(font_family)); } - Glib::ustring - FontLister::canonize_fontspec( Glib::ustring fontspec ) { - - // Pass fontspec to and back from Pango to get a the fontspec in - // canonical form. -inkscape-font-specification relies on the - // Pango constructed fontspec not changing form. If it does, - // this is the place to fix it. - PangoFontDescription *descr = pango_font_description_from_string( fontspec.c_str() ); - gchar* canonized = pango_font_description_to_string ( descr ); - Glib::ustring Canonized = canonized; - g_free( canonized ); - pango_font_description_free( descr ); - - // Pango canonized strings remove space after comma between family names. Put it back. - size_t i = 0; - while( (i = Canonized.find(",", i)) != std::string::npos) { - Canonized.replace(i, 1, ", "); - i += 2; - } - - return Canonized; + for (SPObject *child = r->firstChild(); child; child = child->getNext()) { + update_font_list_recursive(child, l); } +} + +Glib::ustring FontLister::canonize_fontspec(Glib::ustring fontspec) +{ - Glib::ustring - FontLister::system_fontspec( Glib::ustring fontspec ) { + // Pass fontspec to and back from Pango to get a the fontspec in + // canonical form. -inkscape-font-specification relies on the + // Pango constructed fontspec not changing form. If it does, + // this is the place to fix it. + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + gchar *canonized = pango_font_description_to_string(descr); + Glib::ustring Canonized = canonized; + g_free(canonized); + pango_font_description_free(descr); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while ((i = Canonized.find(",", i)) != std::string::npos) { + Canonized.replace(i, 1, ", "); + i += 2; + } - // Find what Pango thinks is the closest match. - Glib::ustring out = fontspec; + return Canonized; +} - PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); - font_instance *res = (font_factory::Default())->Face(descr); - if (res->pFont) { +Glib::ustring FontLister::system_fontspec(Glib::ustring fontspec) +{ + + // Find what Pango thinks is the closest match. + Glib::ustring out = fontspec; + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + font_instance *res = (font_factory::Default())->Face(descr); + if (res->pFont) { PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont); out = sp_font_description_get_family(nFaceDesc); - } - pango_font_description_free(descr); - - return out; } + pango_font_description_free(descr); + + return out; +} - std::pair - FontLister::ui_from_fontspec( Glib::ustring fontspec ) { - - PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); - const gchar* family = pango_font_description_get_family(descr); - if(!family) - family = "sans-serif"; - Glib::ustring Family = family; - - // PANGO BUG... - // A font spec of Delicious, 500 Italic should result in a family of 'Delicious' - // and a style of 'Medium Italic'. It results instead with: a family of - // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers - // at the end of the family: match ",[1-9]00^". - Glib::RefPtr weight = Glib::Regex::create(",[1-9]00$"); - Family = weight->replace( Family, 0, "", Glib::REGEX_MATCH_PARTIAL ); - - // Pango canonized strings remove space after comma between family names. Put it back. - size_t i = 0; - while( (i = Family.find(",", i)) != std::string::npos) { - Family.replace(i, 1, ", "); - i += 2; - } - - pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); - gchar* style = pango_font_description_to_string( descr ); - Glib::ustring Style = style; - pango_font_description_free(descr); - g_free( style ); - - return std::make_pair( Family, Style ); +std::pair FontLister::ui_from_fontspec(Glib::ustring fontspec) +{ + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + const gchar *family = pango_font_description_get_family(descr); + if (!family) + family = "sans-serif"; + Glib::ustring Family = family; + + // PANGO BUG... + // A font spec of Delicious, 500 Italic should result in a family of 'Delicious' + // and a style of 'Medium Italic'. It results instead with: a family of + // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers + // at the end of the family: match ",[1-9]00^". + Glib::RefPtr weight = Glib::Regex::create(",[1-9]00$"); + Family = weight->replace(Family, 0, "", Glib::REGEX_MATCH_PARTIAL); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while ((i = Family.find(",", i)) != std::string::npos) { + Family.replace(i, 1, ", "); + i += 2; } - std::pair - FontLister::selection_update () { + pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); + gchar *style = pango_font_description_to_string(descr); + Glib::ustring Style = style; + pango_font_description_free(descr); + g_free(style); + + return std::make_pair(Family, Style); +} + +std::pair FontLister::selection_update() +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::selection_update: entrance" << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::selection_update: entrance" << std::endl; #endif - // Get fontspec from a selection, preferences, or thin air. - Glib::ustring fontspec; - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - - // Directly from stored font specification. - int result = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - //std::cout << " Attempting selected style" << std::endl; - if( result != QUERY_STYLE_NOTHING && query->font_specification.set ) { - fontspec = query->font_specification.value; - //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; - } - - // From style - if( fontspec.empty() ) { + // Get fontspec from a selection, preferences, or thin air. + Glib::ustring fontspec; + SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + + // Directly from stored font specification. + int result = + sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + + //std::cout << " Attempting selected style" << std::endl; + if (result != QUERY_STYLE_NOTHING && query->font_specification.set) { + fontspec = query->font_specification.value; + //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; + } + + // From style + if (fontspec.empty()) { //std::cout << " Attempting desktop style" << std::endl; - int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - - // Must have text in selection - if( rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING ) { - fontspec = fontspec_from_style( query ); - } - //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; - } - - // From preferences - if( fontspec.empty() ) { + int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + + // Must have text in selection + if (rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING) { + fontspec = fontspec_from_style(query); + } + //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; + } + + // From preferences + if (fontspec.empty()) { //std::cout << " Attempting preferences" << std::endl; sp_style_read_from_prefs(query, "/tools/text"); - fontspec = fontspec_from_style( query ); - //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; - } - sp_style_unref(query); + fontspec = fontspec_from_style(query); + //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; + } + sp_style_unref(query); - // From thin air - if( fontspec.empty() ) { + // From thin air + if (fontspec.empty()) { //std::cout << " Attempting thin air" << std::endl; - fontspec = current_family + ", " + current_style; - //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; - } - - // Do we really need? Removes spaces between font-families. - //current_fontspec = canonize_fontspec( fontspec ); - current_fontspec = fontspec; // Ignore for now + fontspec = current_family + ", " + current_style; + //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; + } + + // Do we really need? Removes spaces between font-families. + //current_fontspec = canonize_fontspec( fontspec ); + current_fontspec = fontspec; // Ignore for now - current_fontspec_system = system_fontspec( current_fontspec ); + current_fontspec_system = system_fontspec(current_fontspec); - std::pair ui = ui_from_fontspec( current_fontspec ); - set_font_family( ui.first ); - set_font_style( ui.second ); + std::pair ui = ui_from_fontspec(current_fontspec); + set_font_family(ui.first); + set_font_style(ui.second); #ifdef DEBUG_FONT - std::cout << " family_row: :" << current_family_row << ":" << std::endl; - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: :" << current_family << ":" << std::endl; - std::cout << " style: :" << current_style << ":" << std::endl; - std::cout << "FontLister::selection_update: exit" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::selection_update: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( current_family, current_style ); - } - + return std::make_pair(current_family, current_style); +} + // Set fontspec. If check is false, best style match will not be done. -void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/) +void FontLister::set_fontspec(Glib::ustring new_fontspec, bool /*check*/) { - std::pair ui = ui_from_fontspec( new_fontspec ); + std::pair ui = ui_from_fontspec(new_fontspec); Glib::ustring new_family = ui.first; Glib::ustring new_style = ui.second; @@ -439,13 +461,13 @@ void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/) << " style:" << new_style << std::endl; #endif - set_font_family( new_family, false ); - set_font_style( new_style ); + set_font_family(new_family, false); + set_font_style(new_style); } // TODO: use to determine font-selector best style -std::pair FontLister::new_font_family (Glib::ustring new_family, gboolean /*check_style*/ ) +std::pair FontLister::new_font_family(Glib::ustring new_family, bool /*check_style*/) { #ifdef DEBUG_FONT std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; @@ -453,12 +475,12 @@ std::pair FontLister::new_font_family (Glib::ustri #endif // No need to do anything if new family is same as old family. - if ( familyNamesAreEqual( new_family, current_family ) ) { + if (familyNamesAreEqual(new_family, current_family)) { #ifdef DEBUG_FONT - std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( current_family, current_style ); + return std::make_pair(current_family, current_style); } // We need to do two things: @@ -466,596 +488,597 @@ std::pair FontLister::new_font_family (Glib::ustri // 2. Select best valid style match to old style. // For finding style list, use list of first family in font-family list. - GList* styles = NULL; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { + GList *styles = NULL; + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { - Gtk::TreeModel::Row row = *iter; + Gtk::TreeModel::Row row = *iter; - if( familyNamesAreEqual( new_family, row[FontList.family] ) ) { + if (familyNamesAreEqual(new_family, row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } styles = row[FontList.styles]; break; - } - ++iter; + } + ++iter; } // Newly typed in font-family may not yet be in list... use default list. // TODO: if font-family is list, check if first family in list is on system // and set style accordingly. - if( styles == NULL ) { - styles = default_styles; + if (styles == NULL) { + styles = default_styles; } - + // Update style list. style_list_store->freeze_notify(); style_list_store->clear(); - for (GList *l=styles; l; l = l->next) { - Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; - (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; + for (GList *l = styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName; } style_list_store->thaw_notify(); - + // Find best match to the style from the old font-family to the // styles available with the new font. // TODO: Maybe check if an exact match exists before using Pango. - Glib::ustring best_style = get_best_style_match( new_family, current_style ); + Glib::ustring best_style = get_best_style_match(new_family, current_style); #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( new_family, best_style ); + return std::make_pair(new_family, best_style); } - - std::pair - FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) { + +std::pair FontLister::set_font_family(Glib::ustring new_family, bool check_style) +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::set_font_family: " << new_family << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family: " << new_family << std::endl; #endif - std::pair ui = new_font_family( new_family, check_style ); - current_family = ui.first; - current_style = ui.second; - current_fontspec = canonize_fontspec( current_family + ", " + current_style ); - current_fontspec_system = system_fontspec( current_fontspec ); + std::pair ui = new_font_family(new_family, check_style); + current_family = ui.first; + current_style = ui.second; + current_fontspec = canonize_fontspec(current_family + ", " + current_style); + current_fontspec_system = system_fontspec(current_fontspec); #ifdef DEBUG_FONT - std::cout << " family_row: :" << current_family_row << ":" << std::endl; - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: :" << current_family << ":" << std::endl; - std::cout << " style: :" << current_style << ":" << std::endl; - std::cout << "FontLister::set_font_family: end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::set_font_family: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return ui; - } - + return ui; +} - std::pair - FontLister::set_font_family (int row, gboolean check_style) { + +std::pair FontLister::set_font_family(int row, bool check_style) +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::set_font_family( row ): " << row << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family( row ): " << row << std::endl; #endif - current_family_row = row; - Gtk::TreePath path; - path.push_back( row ); - Glib::ustring new_family = current_family; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - new_family = (*iter)[FontList.family]; - } + current_family_row = row; + Gtk::TreePath path; + path.push_back(row); + Glib::ustring new_family = current_family; + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + new_family = (*iter)[FontList.family]; + } - std::pair ui = set_font_family( new_family, check_style ); + std::pair ui = set_font_family(new_family, check_style); #ifdef DEBUG_FONT - std::cout << "FontLister::set_font_family( row ): end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "FontLister::set_font_family( row ): end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return ui; - } + return ui; +} - void - FontLister::set_font_style (Glib::ustring new_style) { +void FontLister::set_font_style(Glib::ustring new_style) +{ - // TODO: Validate input using Pango. If Pango doesn't recognize a style it will - // attach the "invalid" style to the font-family. +// TODO: Validate input using Pango. If Pango doesn't recognize a style it will +// attach the "invalid" style to the font-family. #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister:set_font_style: " << new_style << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister:set_font_style: " << new_style << std::endl; #endif - current_style = new_style; - current_fontspec = canonize_fontspec( current_family + ", " + current_style ); - current_fontspec_system = system_fontspec( current_fontspec ); + current_style = new_style; + current_fontspec = canonize_fontspec(current_family + ", " + current_style); + current_fontspec_system = system_fontspec(current_fontspec); #ifdef DEBUG_FONT - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: " << current_family << std::endl; - std::cout << " style: " << current_style << std::endl; - std::cout << "FontLister::set_font_style: end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: " << current_family << std::endl; + std::cout << " style: " << current_style << std::endl; + std::cout << "FontLister::set_font_style: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif +} + + +// We do this ourselves as we can't rely on FontFactory. +void FontLister::fill_css(SPCSSAttr *css, Glib::ustring fontspec) +{ + + if (fontspec.empty()) { + fontspec = current_fontspec; + } + std::pair ui = ui_from_fontspec(fontspec); + + Glib::ustring family = ui.first; + + + // Font spec is single quoted... for the moment + Glib::ustring fontspec_quoted(fontspec); + css_quote(fontspec_quoted); + sp_repr_css_set_property(css, "-inkscape-font-specification", fontspec_quoted.c_str()); + + // Font families needs to be properly quoted in CSS (used unquoted in font-lister) + css_font_family_quote(family); + sp_repr_css_set_property(css, "font-family", family.c_str()); + + PangoFontDescription *desc = pango_font_description_from_string(fontspec.c_str()); + PangoWeight weight = pango_font_description_get_weight(desc); + switch (weight) { + case PANGO_WEIGHT_THIN: + sp_repr_css_set_property(css, "font-weight", "100"); + break; + case PANGO_WEIGHT_ULTRALIGHT: + sp_repr_css_set_property(css, "font-weight", "200"); + break; + case PANGO_WEIGHT_LIGHT: + sp_repr_css_set_property(css, "font-weight", "300"); + break; + case PANGO_WEIGHT_BOOK: + sp_repr_css_set_property(css, "font-weight", "380"); + break; + case PANGO_WEIGHT_NORMAL: + sp_repr_css_set_property(css, "font-weight", "normal"); + break; + case PANGO_WEIGHT_MEDIUM: + sp_repr_css_set_property(css, "font-weight", "500"); + break; + case PANGO_WEIGHT_SEMIBOLD: + sp_repr_css_set_property(css, "font-weight", "600"); + break; + case PANGO_WEIGHT_BOLD: + sp_repr_css_set_property(css, "font-weight", "bold"); + break; + case PANGO_WEIGHT_ULTRABOLD: + sp_repr_css_set_property(css, "font-weight", "800"); + break; + case PANGO_WEIGHT_HEAVY: + sp_repr_css_set_property(css, "font-weight", "900"); + break; + case PANGO_WEIGHT_ULTRAHEAVY: + sp_repr_css_set_property(css, "font-weight", "1000"); + break; + } + + PangoStyle style = pango_font_description_get_style(desc); + switch (style) { + case PANGO_STYLE_NORMAL: + sp_repr_css_set_property(css, "font-style", "normal"); + break; + case PANGO_STYLE_OBLIQUE: + sp_repr_css_set_property(css, "font-style", "oblique"); + break; + case PANGO_STYLE_ITALIC: + sp_repr_css_set_property(css, "font-style", "italic"); + break; } + PangoStretch stretch = pango_font_description_get_stretch(desc); + switch (stretch) { + case PANGO_STRETCH_ULTRA_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "ultra-condensed"); + break; + case PANGO_STRETCH_EXTRA_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "extra-condensed"); + break; + case PANGO_STRETCH_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "condensed"); + break; + case PANGO_STRETCH_SEMI_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "semi-condensed"); + break; + case PANGO_STRETCH_NORMAL: + sp_repr_css_set_property(css, "font-stretch", "normal"); + break; + case PANGO_STRETCH_SEMI_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "semi-expanded"); + break; + case PANGO_STRETCH_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "expanded"); + break; + case PANGO_STRETCH_EXTRA_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "extra-expanded"); + break; + case PANGO_STRETCH_ULTRA_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "ultra-expanded"); + break; + } - // We do this ourselves as we can't rely on FontFactory. - void - FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) { - - if( fontspec.empty() ) { - fontspec = current_fontspec; - } - std::pair ui = ui_from_fontspec( fontspec ); - - Glib::ustring family = ui.first; - - - // Font spec is single quoted... for the moment - Glib::ustring fontspec_quoted( fontspec ); - css_quote( fontspec_quoted ); - sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec_quoted.c_str() ); - - // Font families needs to be properly quoted in CSS (used unquoted in font-lister) - css_font_family_quote( family ); - sp_repr_css_set_property (css, "font-family", family.c_str() ); - - PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); - PangoWeight weight = pango_font_description_get_weight( desc ); - switch ( weight ) { - case PANGO_WEIGHT_THIN: - sp_repr_css_set_property (css, "font-weight", "100" ); - break; - case PANGO_WEIGHT_ULTRALIGHT: - sp_repr_css_set_property (css, "font-weight", "200" ); - break; - case PANGO_WEIGHT_LIGHT: - sp_repr_css_set_property (css, "font-weight", "300" ); - break; - case PANGO_WEIGHT_BOOK: - sp_repr_css_set_property (css, "font-weight", "380" ); - break; - case PANGO_WEIGHT_NORMAL: - sp_repr_css_set_property (css, "font-weight", "normal" ); - break; - case PANGO_WEIGHT_MEDIUM: - sp_repr_css_set_property (css, "font-weight", "500" ); - break; - case PANGO_WEIGHT_SEMIBOLD: - sp_repr_css_set_property (css, "font-weight", "600" ); - break; - case PANGO_WEIGHT_BOLD: - sp_repr_css_set_property (css, "font-weight", "bold" ); - break; - case PANGO_WEIGHT_ULTRABOLD: - sp_repr_css_set_property (css, "font-weight", "800" ); - break; - case PANGO_WEIGHT_HEAVY: - sp_repr_css_set_property (css, "font-weight", "900" ); - break; - case PANGO_WEIGHT_ULTRAHEAVY: - sp_repr_css_set_property (css, "font-weight", "1000" ); - break; - } - - PangoStyle style = pango_font_description_get_style( desc ); - switch ( style ) { - case PANGO_STYLE_NORMAL: - sp_repr_css_set_property (css, "font-style", "normal" ); - break; - case PANGO_STYLE_OBLIQUE: - sp_repr_css_set_property (css, "font-style", "oblique" ); - break; - case PANGO_STYLE_ITALIC: - sp_repr_css_set_property (css, "font-style", "italic" ); - break; - } - - PangoStretch stretch = pango_font_description_get_stretch( desc ); - switch ( stretch ) { - case PANGO_STRETCH_ULTRA_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "ultra-condensed" ); - break; - case PANGO_STRETCH_EXTRA_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "extra-condensed" ); - break; - case PANGO_STRETCH_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "condensed" ); - break; - case PANGO_STRETCH_SEMI_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "semi-condensed" ); - break; - case PANGO_STRETCH_NORMAL: - sp_repr_css_set_property (css, "font-stretch", "normal" ); - break; - case PANGO_STRETCH_SEMI_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "semi-expanded" ); - break; - case PANGO_STRETCH_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "expanded" ); - break; - case PANGO_STRETCH_EXTRA_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "extra-expanded" ); - break; - case PANGO_STRETCH_ULTRA_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "ultra-expanded" ); - break; - } - - PangoVariant variant = pango_font_description_get_variant( desc ); - switch ( variant ) { - case PANGO_VARIANT_NORMAL: - sp_repr_css_set_property (css, "font-variant", "normal" ); - break; - case PANGO_VARIANT_SMALL_CAPS: - sp_repr_css_set_property (css, "font-variant", "small-caps" ); - break; - } + PangoVariant variant = pango_font_description_get_variant(desc); + switch (variant) { + case PANGO_VARIANT_NORMAL: + sp_repr_css_set_property(css, "font-variant", "normal"); + break; + case PANGO_VARIANT_SMALL_CAPS: + sp_repr_css_set_property(css, "font-variant", "small-caps"); + break; } +} - // We do this ourselves as we can't rely on FontFactory. - Glib::ustring - FontLister::fontspec_from_style (SPStyle* style) { +// We do this ourselves as we can't rely on FontFactory. +Glib::ustring FontLister::fontspec_from_style(SPStyle *style) +{ - //std::cout << "FontLister:fontspec_from_style: " << std::endl; + //std::cout << "FontLister:fontspec_from_style: " << std::endl; - Glib::ustring fontspec; - if (style) { + Glib::ustring fontspec; + if (style) { - // First try to use the font specification if it is set - if (style->font_specification.set - && style->font_specification.value - && *style->font_specification.value) { + // First try to use the font specification if it is set + if (style->font_specification.set && style->font_specification.value && *style->font_specification.value) { - fontspec = style->font_specification.value; + fontspec = style->font_specification.value; } else { - fontspec = style->font_family.value; - fontspec += ","; - - // Use weight names as defined by Pango - switch (style->font_weight.computed) { + fontspec = style->font_family.value; + fontspec += ","; - case SP_CSS_FONT_WEIGHT_100: - fontspec += " Thin"; - break; - - case SP_CSS_FONT_WEIGHT_200: - fontspec += " Ultra-Light"; - break; + // Use weight names as defined by Pango + switch (style->font_weight.computed) { - case SP_CSS_FONT_WEIGHT_300: - fontspec += " Light"; - break; + case SP_CSS_FONT_WEIGHT_100: + fontspec += " Thin"; + break; - case SP_CSS_FONT_WEIGHT_400: - case SP_CSS_FONT_WEIGHT_NORMAL: - //fontspec += " normal"; - break; - - case SP_CSS_FONT_WEIGHT_500: - fontspec += " Medium"; - break; - - case SP_CSS_FONT_WEIGHT_600: - fontspec += " Semi-Bold"; - break; - - case SP_CSS_FONT_WEIGHT_700: - case SP_CSS_FONT_WEIGHT_BOLD: - fontspec += " Bold"; - break; - - case SP_CSS_FONT_WEIGHT_800: - fontspec += " Ultra-Bold"; - break; - - case SP_CSS_FONT_WEIGHT_900: - fontspec += " Heavy"; - break; - - case SP_CSS_FONT_WEIGHT_LIGHTER: - case SP_CSS_FONT_WEIGHT_BOLDER: - default: - g_warning("Unrecognized font_weight.computed value"); - break; - } - - switch (style->font_style.computed) { - case SP_CSS_FONT_STYLE_ITALIC: - fontspec += " italic"; - break; - - case SP_CSS_FONT_STYLE_OBLIQUE: - fontspec += " oblique"; - break; - - case SP_CSS_FONT_STYLE_NORMAL: - default: - //fontspec += " normal"; - break; - } - - switch (style->font_stretch.computed) { - - case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: - fontspec += " extra-condensed"; - break; - - case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: - fontspec += " extra-condensed"; - break; - - case SP_CSS_FONT_STRETCH_CONDENSED: - case SP_CSS_FONT_STRETCH_NARROWER: - fontspec += " condensed"; - break; - - case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: - fontspec += " semi-condensed"; - break; - - case SP_CSS_FONT_STRETCH_NORMAL: - //fontspec += " normal"; - break; - - case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: - fontspec += " semi-expanded"; - break; - - case SP_CSS_FONT_STRETCH_EXPANDED: - case SP_CSS_FONT_STRETCH_WIDER: - fontspec += " expanded"; - break; - - case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: - fontspec += " extra-expanded"; - break; - - case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: - fontspec += " ultra-expanded"; - break; - - default: - //fontspec += " normal"; - break; - } - - switch (style->font_variant.computed) { - - case SP_CSS_FONT_VARIANT_SMALL_CAPS: - fontspec += "small-caps"; - break; - - default: - //fontspec += "normal"; - break; - } - } - } - return canonize_fontspec( fontspec ); - } + case SP_CSS_FONT_WEIGHT_200: + fontspec += " Ultra-Light"; + break; + case SP_CSS_FONT_WEIGHT_300: + fontspec += " Light"; + break; - Gtk::TreeModel::Row - FontLister::get_row_for_font (Glib::ustring family) - { - Gtk::TreePath path; + case SP_CSS_FONT_WEIGHT_400: + case SP_CSS_FONT_WEIGHT_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_WEIGHT_500: + fontspec += " Medium"; + break; + + case SP_CSS_FONT_WEIGHT_600: + fontspec += " Semi-Bold"; + break; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { + case SP_CSS_FONT_WEIGHT_700: + case SP_CSS_FONT_WEIGHT_BOLD: + fontspec += " Bold"; + break; - Gtk::TreeModel::Row row = *iter; + case SP_CSS_FONT_WEIGHT_800: + fontspec += " Ultra-Bold"; + break; - if( familyNamesAreEqual( family, row[FontList.family] ) ) { - return row; - } + case SP_CSS_FONT_WEIGHT_900: + fontspec += " Heavy"; + break; - ++iter; - } + case SP_CSS_FONT_WEIGHT_LIGHTER: + case SP_CSS_FONT_WEIGHT_BOLDER: + default: + g_warning("Unrecognized font_weight.computed value"); + break; + } - throw FAMILY_NOT_FOUND; - } + switch (style->font_style.computed) { + case SP_CSS_FONT_STYLE_ITALIC: + fontspec += " italic"; + break; - Gtk::TreePath - FontLister::get_path_for_font (Glib::ustring family) - { - return font_list_store->get_path( get_row_for_font ( family ) ); + case SP_CSS_FONT_STYLE_OBLIQUE: + fontspec += " oblique"; + break; + + case SP_CSS_FONT_STYLE_NORMAL: + default: + //fontspec += " normal"; + break; + } + + switch (style->font_stretch.computed) { + + case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: + fontspec += " extra-condensed"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: + fontspec += " extra-condensed"; + break; + + case SP_CSS_FONT_STRETCH_CONDENSED: + case SP_CSS_FONT_STRETCH_NARROWER: + fontspec += " condensed"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: + fontspec += " semi-condensed"; + break; + + case SP_CSS_FONT_STRETCH_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: + fontspec += " semi-expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXPANDED: + case SP_CSS_FONT_STRETCH_WIDER: + fontspec += " expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: + fontspec += " extra-expanded"; + break; + + case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fontspec += " ultra-expanded"; + break; + + default: + //fontspec += " normal"; + break; + } + + switch (style->font_variant.computed) { + + case SP_CSS_FONT_VARIANT_SMALL_CAPS: + fontspec += "small-caps"; + break; + + default: + //fontspec += "normal"; + break; + } + } } + return canonize_fontspec(fontspec); +} - Gtk::TreeModel::Row - FontLister::get_row_for_style (Glib::ustring style) - { - Gtk::TreePath path; - Gtk::TreeModel::iterator iter = style_list_store->get_iter( "0" ); - while( iter != style_list_store->children().end() ) { +Gtk::TreeModel::Row FontLister::get_row_for_font(Glib::ustring family) +{ + Gtk::TreePath path; - Gtk::TreeModel::Row row = *iter; + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { - if( familyNamesAreEqual( style, row[FontStyleList.cssStyle] ) ) { - return row; - } + Gtk::TreeModel::Row row = *iter; - ++iter; - } + if (familyNamesAreEqual(family, row[FontList.family])) { + return row; + } - throw STYLE_NOT_FOUND; + ++iter; } - static gint - compute_distance (const PangoFontDescription *a, - const PangoFontDescription *b ) { - - // Weight: multiples of 100 - gint distance = abs( pango_font_description_get_weight( a ) - - pango_font_description_get_weight( b ) ); - - distance += 10000 * abs( pango_font_description_get_stretch( a ) - - pango_font_description_get_stretch( b ) ); - - PangoStyle style_a = pango_font_description_get_style( a ); - PangoStyle style_b = pango_font_description_get_style( b ); - if( style_a != style_b ) { - if( (style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || - (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC) ) { - distance += 1000; // Oblique and italic are almost the same - } else { - distance += 100000; // Normal vs oblique/italic, not so similar - } - } - - // Normal vs small-caps - distance += 1000000 * abs( pango_font_description_get_variant( a ) - - pango_font_description_get_variant( b ) ); - return distance; + throw FAMILY_NOT_FOUND; +} + +Gtk::TreePath FontLister::get_path_for_font(Glib::ustring family) +{ + return font_list_store->get_path(get_row_for_font(family)); +} + +Gtk::TreeModel::Row FontLister::get_row_for_style(Glib::ustring style) +{ + Gtk::TreePath path; + + Gtk::TreeModel::iterator iter = style_list_store->get_iter("0"); + while (iter != style_list_store->children().end()) { + + Gtk::TreeModel::Row row = *iter; + + if (familyNamesAreEqual(style, row[FontStyleList.cssStyle])) { + return row; + } + + ++iter; } - // This is inspired by pango_font_description_better_match, but that routine - // always returns false if variant or stretch are different. This means, for - // example, that PT Sans Narrow with style Bold Condensed is never matched - // to another font-family with Bold style. - gboolean - font_description_better_match( PangoFontDescription* target, - PangoFontDescription* old_desc, - PangoFontDescription* new_desc ) { + throw STYLE_NOT_FOUND; +} + +static gint compute_distance(const PangoFontDescription *a, const PangoFontDescription *b) +{ - if( old_desc == NULL ) return true; - if( new_desc == NULL ) return false; + // Weight: multiples of 100 + gint distance = abs(pango_font_description_get_weight(a) - + pango_font_description_get_weight(b)); - int old_distance = compute_distance( target, old_desc ); - int new_distance = compute_distance( target, new_desc ); - //std::cout << "font_description_better_match: old: " << old_distance << std::endl; - //std::cout << " new: " << new_distance << std::endl; + distance += 10000 * abs(pango_font_description_get_stretch(a) - + pango_font_description_get_stretch(b)); - return (new_distance < old_distance ); + PangoStyle style_a = pango_font_description_get_style(a); + PangoStyle style_b = pango_font_description_get_style(b); + if (style_a != style_b) { + if ((style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || + (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC)) { + distance += 1000; // Oblique and italic are almost the same + } else { + distance += 100000; // Normal vs oblique/italic, not so similar + } } - // void - // font_description_dump( PangoFontDescription* target ) { - // std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; - // std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; - // std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; - // std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; - // std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; - // std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; - // } - - /* Returns style string */ - // TODO: Remove or turn into function to be used by new_font_family. - Glib::ustring - FontLister::get_best_style_match (Glib::ustring family, Glib::ustring target_style) { + // Normal vs small-caps + distance += 1000000 * abs(pango_font_description_get_variant(a) - + pango_font_description_get_variant(b)); + return distance; +} -#ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; -#endif +// This is inspired by pango_font_description_better_match, but that routine +// always returns false if variant or stretch are different. This means, for +// example, that PT Sans Narrow with style Bold Condensed is never matched +// to another font-family with Bold style. +gboolean font_description_better_match(PangoFontDescription *target, PangoFontDescription *old_desc, PangoFontDescription *new_desc) +{ + if (old_desc == NULL) + return true; + if (new_desc == NULL) + return false; + + int old_distance = compute_distance(target, old_desc); + int new_distance = compute_distance(target, new_desc); + //std::cout << "font_description_better_match: old: " << old_distance << std::endl; + //std::cout << " new: " << new_distance << std::endl; - Glib::ustring fontspec = family + ", " + target_style; - - Gtk::TreeModel::Row row; - try { - row = get_row_for_font( family ); - } catch (...) { - //std::cout << " ERROR: can't find family: " << family << std::endl; - return (target_style); - } - - PangoFontDescription* target = pango_font_description_from_string( fontspec.c_str() ); - PangoFontDescription* best = NULL; - - //font_description_dump( target ); - - GList* styles = row[FontList.styles]; - for (GList *l=styles; l; l = l->next) { - Glib::ustring fontspec = family + ", " + (char*)l->data; - PangoFontDescription* candidate = pango_font_description_from_string( fontspec.c_str() ); - //font_description_dump( candidate ); - //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; - if( font_description_better_match( target, best, candidate ) ) { - pango_font_description_free( best ); - best = candidate; - //std::cout << " ... better: " << std::endl; - } else { - pango_font_description_free( candidate ); - //std::cout << " ... not better: " << std::endl; - } - } - - Glib::ustring best_style = target_style; - if( best ) { - pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY ); - best_style = pango_font_description_to_string( best ); - } - - if( target ) pango_font_description_free( target ); - if( best ) pango_font_description_free( best ); + return (new_distance < old_distance); +} +// void +// font_description_dump( PangoFontDescription* target ) { +// std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; +// std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; +// std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; +// std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; +// std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; +// std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; +// } + +/* Returns style string */ +// TODO: Remove or turn into function to be used by new_font_family. +Glib::ustring FontLister::get_best_style_match(Glib::ustring family, Glib::ustring target_style) +{ #ifdef DEBUG_FONT - std::cout << " Returning: " << best_style << std::endl; - std::cout << "FontLister::get_best_style_match: exit" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; #endif - return best_style; - } - const Glib::RefPtr - FontLister::get_font_list () const + Glib::ustring fontspec = family + ", " + target_style; + + Gtk::TreeModel::Row row; + try { - return font_list_store; + row = get_row_for_font(family); } - - const Glib::RefPtr - FontLister::get_style_list () const + catch (...) { - return style_list_store; + //std::cout << " ERROR: can't find family: " << family << std::endl; + return (target_style); } + + PangoFontDescription *target = pango_font_description_from_string(fontspec.c_str()); + PangoFontDescription *best = NULL; + + //font_description_dump( target ); + + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + GList *styles = row[FontList.styles]; + for (GList *l = styles; l; l = l->next) { + Glib::ustring fontspec = family + ", " + (char *)l->data; + PangoFontDescription *candidate = pango_font_description_from_string(fontspec.c_str()); + //font_description_dump( candidate ); + //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; + if (font_description_better_match(target, best, candidate)) { + pango_font_description_free(best); + best = candidate; + //std::cout << " ... better: " << std::endl; + } else { + pango_font_description_free(candidate); + //std::cout << " ... not better: " << std::endl; + } + } + + Glib::ustring best_style = target_style; + if (best) { + pango_font_description_unset_fields(best, PANGO_FONT_MASK_FAMILY); + best_style = pango_font_description_to_string(best); + } + + if (target) + pango_font_description_free(target); + if (best) + pango_font_description_free(best); + + +#ifdef DEBUG_FONT + std::cout << " Returning: " << best_style << std::endl; + std::cout << "FontLister::get_best_style_match: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return best_style; } +const Glib::RefPtr FontLister::get_font_list() const +{ + return font_list_store; +} + +const Glib::RefPtr FontLister::get_style_list() const +{ + return style_list_store; +} + +} // namespace Inkscape + // Helper functions // Separator function (if true, a separator will be drawn) -gboolean font_lister_separator_func(GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/) +gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { - gchar* text = 0; - gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family - return (text && strcmp(text,"#") == 0); + gchar *text = 0; + gtk_tree_model_get(model, iter, 0, &text, -1); // Column 0: FontList.family + return (text && strcmp(text, "#") == 0); } -void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/) +void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/) { gchar *family; gboolean onSystem = false; gtk_tree_model_get(model, iter, 0, &family, 2, &onSystem, -1); - Glib::ustring family_escaped = g_markup_escape_text(family, -1); + gchar* family_escaped = g_markup_escape_text(family, -1); //g_free(family); Glib::ustring markup; - if( !onSystem ) { + if (!onSystem) { markup = ""; /* See if font-family on system */ - std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped ); - for( size_t i=0; i < tokens.size(); ++i ) { + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped); + for (size_t i = 0; i < tokens.size(); ++i) { Glib::ustring token = tokens[i]; @@ -1064,17 +1087,17 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, gchar *family = 0; gboolean onSystem = true; gboolean found = false; - for( valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(model), &iter ); + for (valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter); valid; - valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) { + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)) { gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1); - if( onSystem && familyNamesAreEqual( token, family ) ) { + if (onSystem && familyNamesAreEqual(token, family)) { found = true; break; } } - if( found ) { + if (found) { markup += g_markup_escape_text(token.c_str(), -1); markup += ", "; } else { @@ -1085,13 +1108,13 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, } } // Remove extra comma and space from end. - if( markup.size() >= 2 ) { - markup.resize( markup.size()-2 ); + if (markup.size() >= 2) { + markup.resize(markup.size() - 2); } markup += ""; // std::cout << markup << std::endl; } else { - markup = family_escaped; + markup = family_escaped; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1099,7 +1122,7 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, if (show_sample) { Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - Glib::ustring sample_escaped = g_markup_escape_text(sample.data(), -1); + Glib::ustring sample_escaped = Glib::Markup::escape_text(sample); markup += " - new_font_family (Glib::ustring family, gboolean check_style = true); - - /** Sets font-family, updating style list and attempting - * to find closest style to old current_style. - * New font-family and style returned. - * Updates current_family and current_style. - * Calls new_font_family(). - * (For use in text-toolbar where update is immediate.) - */ - std::pair - set_font_family (Glib::ustring family, gboolean check_style = true); - - /** Sets font-family from row in list store. - * The row can be used to determine if we are in the - * document or system part of the font-family list. - * This is needed to handle scrolling through the - * font-family list correctly. - * Calls set_font_family(). - */ - std::pair - set_font_family (int row, gboolean check_style = true); - - Glib::ustring - get_font_family () - { - return current_family; - } - - int - get_font_family_row () - { - return current_family_row; - } - - /** Sets style. Does not validate style for family. - */ - void - set_font_style (Glib::ustring style); - - Glib::ustring - get_font_style () - { - return current_style; - } - - Glib::ustring - fontspec_from_style (SPStyle* style); - - /** Fill css using current_fontspec. - */ - void - fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" ); - - Gtk::TreeModel::Row - get_row_for_font (Glib::ustring family); - - Gtk::TreePath - get_path_for_font (Glib::ustring family); - - Gtk::TreeModel::Row - get_row_for_style (Glib::ustring style); - - Gtk::TreePath - get_path_for_style (Glib::ustring style); - - std::pair - get_paths (Glib::ustring family, Glib::ustring style); - - /** Return best style match for new font given style for old font. - */ - Glib::ustring - get_best_style_match (Glib::ustring family, Glib::ustring style); - - /* Not Used */ - const NRNameList - get_name_list () const - { - return families; - } - - private: - - FontLister (); - - NRNameList families; - - Glib::RefPtr font_list_store; - Glib::RefPtr style_list_store; - - /** Info for currently selected font (what is shown in the UI). - * May include font-family lists and fonts not on system. - */ - int current_family_row; - Glib::ustring current_family; - Glib::ustring current_style; - Glib::ustring current_fontspec; - - /** fontspec of system font closest to current_fontspec. - * (What the system will use to display current_fontspec.) - */ - Glib::ustring current_fontspec_system; - - /** If a font-family is not on system, this list of styles is used. - */ - GList *default_styles; - }; -} +namespace Inkscape { + +/** + * This class enumerates fonts using libnrtype into reusable data stores and + * allows for random access to the font-family list and the font-style list. + * Setting the font-family updates the font-style list. "Style" in this case + * refers to everything but family and size (e.g. italic/oblique, weight). + * + * This class handles font-family lists and fonts that are not on the system, + * where there is not an entry in the fontInstanceMap. + * + * This class uses the idea of "font_spec". This is a plain text string as used by + * Pango. It is similar to the CSS font shorthand except that font-family comes + * first and in this class the font-size is not used. + * + * This class uses the FontFactory class to get a list of system fonts + * and to find best matches via Pango. The Pango interface is only setup + * to deal with fonts that are on the system so care must be taken. For + * example, best matches should only be done with the first font-family + * in a font-family list. If the first font-family is not on the system + * then a generic font-family should be used (sans-serif -> Sans). + * + * This class is used by the UI interface (text-toolbar, font-select, etc.). + * + * "Font" includes family and style. It should not be used when one + * means font-family. + */ + +class FontLister { +public: + enum Exceptions { + FAMILY_NOT_FOUND, + STYLE_NOT_FOUND + }; + + virtual ~FontLister(); + + /** + * GtkTreeModelColumnRecord for the font-family list Gtk::ListStore + */ + struct FontListClass : public Gtk::TreeModelColumnRecord { + /** + * Column containing the family name + */ + Gtk::TreeModelColumn family; + + /** + * Column containing the styles for each family name. + */ + Gtk::TreeModelColumn styles; + + /** + * Column containing flag if font is on system + */ + Gtk::TreeModelColumn onSystem; + + /** + * Not actually a column. + * Necessary for quick initialization of FontLister, + * we initially store the pango family and if the + * font style is actually used we'll cache it in + * %styles. + */ + Gtk::TreeModelColumn pango_family; + + FontListClass() + { + add(family); + add(styles); + add(onSystem); + add(pango_family); + } + }; + + FontListClass FontList; + + struct FontStyleListClass : public Gtk::TreeModelColumnRecord { + /** + * Column containing the styles as Font designer used. + */ + Gtk::TreeModelColumn displayStyle; + + /** + * Column containing the styles in CSS/Pango format. + */ + Gtk::TreeModelColumn cssStyle; + + FontStyleListClass() + { + add(cssStyle); + add(displayStyle); + } + }; + + FontStyleListClass FontStyleList; + + /** + * @return the ListStore with the family names + * + * The return is const and the function is declared as const. + * The ListStore is ready to be used after class instantiation + * and should not be modified. + */ + const Glib::RefPtr get_font_list() const; + + /** + * @return the ListStore with the styles + */ + const Glib::RefPtr get_style_list() const; + + /** + * Inserts a font family or font-fallback list (for use when not + * already in document or on system). + */ + void insert_font_family(Glib::ustring new_family); + + /** + * Updates font list to include fonts in document. + */ + void update_font_list(SPDocument *document); + +public: + static Inkscape::FontLister *get_instance(); + + /** + * Takes a hand written font spec and returns a Pango generated one in + * standard form. + */ + Glib::ustring canonize_fontspec(Glib::ustring fontspec); + + /** + * Find closest system font to given font. + */ + Glib::ustring system_fontspec(Glib::ustring fontspec); + + /** + * Gets font-family and style from fontspec. + * font-family and style returned. + */ + std::pair ui_from_fontspec(Glib::ustring fontspec); + + /** + * Sets font-family and style after a selection change. + * New font-family and style returned. + */ + std::pair selection_update(); + + /** + * Sets current_fontspec, etc. If check is false, won't + * try to find best style match (assumes style in fontspec + * valid for given font-family). + */ + void set_fontspec(Glib::ustring fontspec, bool check = true); + + Glib::ustring get_fontspec() + { + return current_fontspec; + } + + /** + * Changes font-family, updating style list and attempting to find + * closest style to current_style style (if check_style is true). + * New font-family and style returned. + * Does NOT update current_family and current_style. + * (For potential use in font-selector which doesn't update until + * "Apply" button clicked.) + */ + std::pair new_font_family(Glib::ustring family, bool check_style = true); + + /** + * Sets font-family, updating style list and attempting + * to find closest style to old current_style. + * New font-family and style returned. + * Updates current_family and current_style. + * Calls new_font_family(). + * (For use in text-toolbar where update is immediate.) + */ + std::pair set_font_family(Glib::ustring family, bool check_style = true); + + /** + * Sets font-family from row in list store. + * The row can be used to determine if we are in the + * document or system part of the font-family list. + * This is needed to handle scrolling through the + * font-family list correctly. + * Calls set_font_family(). + */ + std::pair set_font_family(int row, bool check_style = true); + + Glib::ustring get_font_family() + { + return current_family; + } + + int get_font_family_row() + { + return current_family_row; + } + + /** + * Sets style. Does not validate style for family. + */ + void set_font_style(Glib::ustring style); + + Glib::ustring get_font_style() + { + return current_style; + } + + Glib::ustring fontspec_from_style(SPStyle *style); + + /** + * Fill css using current_fontspec. + */ + void fill_css(SPCSSAttr *css, Glib::ustring fontspec = ""); + + Gtk::TreeModel::Row get_row_for_font(Glib::ustring family); + + Gtk::TreePath get_path_for_font(Glib::ustring family); + + Gtk::TreeModel::Row get_row_for_style(Glib::ustring style); + + Gtk::TreePath get_path_for_style(Glib::ustring style); + + std::pair get_paths(Glib::ustring family, Glib::ustring style); + + /** + * Return best style match for new font given style for old font. + */ + Glib::ustring get_best_style_match(Glib::ustring family, Glib::ustring style); + + void ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iter); + +private: + FontLister(); + + void update_font_list_recursive(SPObject *r, std::list *l); + + Glib::RefPtr font_list_store; + Glib::RefPtr style_list_store; + + /** + * Info for currently selected font (what is shown in the UI). + * May include font-family lists and fonts not on system. + */ + int current_family_row; + Glib::ustring current_family; + Glib::ustring current_style; + Glib::ustring current_fontspec; + + /** + * fontspec of system font closest to current_fontspec. + * (What the system will use to display current_fontspec.) + */ + Glib::ustring current_fontspec_system; + + /** + * If a font-family is not on system, this list of styles is used. + */ + GList *default_styles; +}; + +} // namespace Inkscape // Helper functions gboolean font_lister_separator_func(GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/); + GtkTreeIter *iter, + gpointer /*data*/); -void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/); +void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/); #endif @@ -328,4 +314,4 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..e44809c65 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -344,9 +344,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index ccaf93e55..c9a52ef11 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -303,6 +303,9 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, GtkTreeModel *model; GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; + + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->ensureRowStyles(model, &iter); // Next get family name with its style list gchar *family; @@ -310,7 +313,6 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); // Find best style match for selected family with current style (e.g. of selected text). - Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); Glib::ustring style = fontlister->get_font_style(); Glib::ustring best = fontlister->get_best_style_match (family, style); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 408babf06..88f698bc4 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -819,7 +819,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit) * It is called whenever a text selection is changed, including stepping cursor * through text, or setting focus to text. */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl) +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed { #ifdef DEBUG_TEXT static int count = 0; @@ -859,7 +859,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + if (!subselection) { + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + } fontlister->selection_update(); // Update font list, but only if widget already created. @@ -1154,7 +1156,7 @@ static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, g static void sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) { - sp_text_toolbox_selection_changed (NULL, tbl); + sp_text_toolbox_selection_changed (NULL, tbl, true); } // TODO: possibly share with font-selector by moving most code to font-lister (passing family name) @@ -1640,7 +1642,7 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_TEXT_CONTEXT(ec)) { // Watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder)); + c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); } else { -- cgit v1.2.3 From be103a4ac9f4821db95601b84ffa70f73c49df65 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 10:10:57 -0400 Subject: Fix gtk3 build (bzr r13341.1.141) --- src/libnrtype/font-lister.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 07c80054d..1b4d9d256 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -1122,13 +1122,14 @@ void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, if (show_sample) { Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - Glib::ustring sample_escaped = Glib::Markup::escape_text(sample); + gchar* sample_escaped = g_markup_escape_text(sample.data(), -1); markup += " "; markup += sample_escaped; markup += ""; + g_free(sample_escaped); } g_object_set(G_OBJECT(cell), "markup", markup.c_str(), NULL); -- cgit v1.2.3 From ad180652b5f6b59b3f24d60677bbf8ec97827aed Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 10:33:11 -0400 Subject: Similar workaround to r13523 (text&font dialog not appearing quickly) (bzr r13525) --- src/widgets/font-selector.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index ccaf93e55..f00f05768 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -157,6 +157,10 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_container_add(GTK_CONTAINER(f), sw); fsel->family_treeview = gtk_tree_view_new (); + gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview), + GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func), + NULL, NULL ); + gtk_widget_show_all(GTK_WIDGET (fsel->family_treeview)); GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); @@ -166,9 +170,6 @@ static void sp_font_selector_init(SPFontSelector *fsel) NULL, NULL ); gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->family_treeview), column); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->family_treeview), FALSE); - gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview), - GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func), - NULL, NULL ); /* Muck with style, see text-toolbar.cpp */ gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" ); -- cgit v1.2.3