summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-03-05 08:43:18 +0000
committerJabiertxo Arraiza Zenotz <jtx@jtx.marker.es>2013-03-05 08:43:18 +0000
commita33dbbc4fbad29c187611660d3651bbe57243903 (patch)
tree1260bfa9c376aa441bb26087283ed0014f5986ec /src
parentFix sintax (diff)
parentmerge from branch (diff)
downloadinkscape-a33dbbc4fbad29c187611660d3651bbe57243903.tar.gz
inkscape-a33dbbc4fbad29c187611660d3651bbe57243903.zip
refactor bsplineSpirolive
(bzr r11950.1.44)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/display/cairo-utils.cpp91
-rw-r--r--src/display/nr-filter-turbulence.cpp5
-rw-r--r--src/dom/io/domstream.cpp218
-rw-r--r--src/dom/io/domstream.h233
-rw-r--r--src/dom/io/uristream.cpp6
-rw-r--r--src/dom/io/uristream.h2
-rw-r--r--src/extension/internal/filter/paint.h2
-rw-r--r--src/extension/internal/odf.cpp32
-rw-r--r--src/io/base64stream.cpp5
-rw-r--r--src/io/base64stream.h2
-rw-r--r--src/io/gzipstream.cpp6
-rw-r--r--src/io/gzipstream.h2
-rw-r--r--src/io/inkscapestream.cpp42
-rw-r--r--src/io/inkscapestream.h8
-rw-r--r--src/io/stringstream.cpp3
-rw-r--r--src/io/stringstream.h2
-rw-r--r--src/io/uristream.cpp8
-rw-r--r--src/io/uristream.h2
-rw-r--r--src/io/xsltstream.cpp3
-rw-r--r--src/io/xsltstream.h2
-rw-r--r--src/isinf.h3
-rw-r--r--src/libnrtype/font-lister.cpp76
-rw-r--r--src/libnrtype/font-lister.h52
-rw-r--r--src/live_effects/lpe-bspline.cpp106
-rw-r--r--src/pen-context.cpp821
-rw-r--r--src/sp-guide.cpp8
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp13
-rw-r--r--src/ui/dialog/glyphs.cpp15
-rw-r--r--src/ui/dialog/glyphs.h2
-rw-r--r--src/ui/dialog/text-edit.cpp103
-rw-r--r--src/ui/dialog/text-edit.h15
-rw-r--r--src/widgets/font-selector.cpp253
-rw-r--r--src/widgets/font-selector.h27
-rw-r--r--src/widgets/text-toolbar.cpp6
35 files changed, 887 insertions, 1292 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a899c7b35..2a4e2960c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -65,7 +65,7 @@ BUILT_SOURCES =
# Extra files to distribute
EXTRA_DIST =
-INCLUDES = \
+AM_CPPFLAGS = \
$(PERL_CFLAGS) $(PYTHON_CFLAGS) \
$(EXIF_CFLAGS) \
$(FREETYPE_CFLAGS) \
@@ -88,8 +88,7 @@ INCLUDES = \
$(WIN32_CFLAGS) \
-I$(srcdir)/bind/javainc \
-I$(srcdir)/bind/javainc/linux \
- -I$(builddir)/extension/dbus \
- $(AM_CPPFLAGS)
+ -I$(builddir)/extension/dbus
CXXTEST_TEMPLATE = $(srcdir)/cxxtest-template.tpl
CXXTESTGENFLAGS = --root --have-eh --template=$(CXXTEST_TEMPLATE)
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp
index 8eeee0277..a55b05fe3 100644
--- a/src/display/cairo-utils.cpp
+++ b/src/display/cairo-utils.cpp
@@ -26,6 +26,7 @@
#include "color.h"
#include "style.h"
#include "helper/geom-curves.h"
+#include "display/cairo-templates.h"
namespace {
@@ -633,6 +634,22 @@ static guint32 linear_to_srgb( const guint32 c, const guint32 a ) {
return premul_alpha( c2, a );
}
+struct SurfaceSrgbToLinear {
+
+ guint32 operator()(guint32 in) {
+ EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting
+ if( a != 0 ) {
+ r = srgb_to_linear( r, a );
+ g = srgb_to_linear( g, a );
+ b = srgb_to_linear( b, a );
+ }
+ ASSEMBLE_ARGB32(out, a,r,g,b);
+ return out;
+ }
+private:
+ /* None */
+};
+
int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface)
{
cairo_surface_flush(surface);
@@ -641,23 +658,41 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface)
int stride = cairo_image_surface_get_stride(surface);
unsigned char *data = cairo_image_surface_get_data(surface);
+ ink_cairo_surface_filter( surface, surface, SurfaceSrgbToLinear() );
+
/* TODO convert this to OpenMP somehow */
- for (int y = 0; y < height; ++y, data += stride) {
- for (int x = 0; x < width; ++x) {
- guint32 px = *reinterpret_cast<guint32*>(data + 4*x);
- EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting
- if( a != 0 ) {
- r = srgb_to_linear( r, a );
- g = srgb_to_linear( g, a );
- b = srgb_to_linear( b, a );
- }
- ASSEMBLE_ARGB32(px2, a,r,g,b);
- *reinterpret_cast<guint32*>(data + 4*x) = px2;
- }
- }
+ // for (int y = 0; y < height; ++y, data += stride) {
+ // for (int x = 0; x < width; ++x) {
+ // guint32 px = *reinterpret_cast<guint32*>(data + 4*x);
+ // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting
+ // if( a != 0 ) {
+ // r = srgb_to_linear( r, a );
+ // g = srgb_to_linear( g, a );
+ // b = srgb_to_linear( b, a );
+ // }
+ // ASSEMBLE_ARGB32(px2, a,r,g,b);
+ // *reinterpret_cast<guint32*>(data + 4*x) = px2;
+ // }
+ // }
return width * height;
}
+struct SurfaceLinearToSrgb {
+
+ guint32 operator()(guint32 in) {
+ EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting
+ if( a != 0 ) {
+ r = linear_to_srgb( r, a );
+ g = linear_to_srgb( g, a );
+ b = linear_to_srgb( b, a );
+ }
+ ASSEMBLE_ARGB32(out, a,r,g,b);
+ return out;
+ }
+private:
+ /* None */
+};
+
int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface)
{
cairo_surface_flush(surface);
@@ -666,20 +701,22 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface)
int stride = cairo_image_surface_get_stride(surface);
unsigned char *data = cairo_image_surface_get_data(surface);
- /* TODO convert this to OpenMP somehow */
- for (int y = 0; y < height; ++y, data += stride) {
- for (int x = 0; x < width; ++x) {
- guint32 px = *reinterpret_cast<guint32*>(data + 4*x);
- EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting
- if( a != 0 ) {
- r = linear_to_srgb( r, a );
- g = linear_to_srgb( g, a );
- b = linear_to_srgb( b, a );
- }
- ASSEMBLE_ARGB32(px2, a,r,g,b);
- *reinterpret_cast<guint32*>(data + 4*x) = px2;
- }
- }
+ ink_cairo_surface_filter( surface, surface, SurfaceLinearToSrgb() );
+
+ // /* TODO convert this to OpenMP somehow */
+ // for (int y = 0; y < height; ++y, data += stride) {
+ // for (int x = 0; x < width; ++x) {
+ // guint32 px = *reinterpret_cast<guint32*>(data + 4*x);
+ // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting
+ // if( a != 0 ) {
+ // r = linear_to_srgb( r, a );
+ // g = linear_to_srgb( g, a );
+ // b = linear_to_srgb( b, a );
+ // }
+ // ASSEMBLE_ARGB32(px2, a,r,g,b);
+ // *reinterpret_cast<guint32*>(data + 4*x) = px2;
+ // }
+ // }
return width * height;
}
diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp
index 76b877fbc..333074f55 100644
--- a/src/display/nr-filter-turbulence.cpp
+++ b/src/display/nr-filter-turbulence.cpp
@@ -283,7 +283,12 @@ private:
// other constants
static int const BSize = 0x100;
static int const BMask = 0xff;
+
+#if __cplusplus < 201103L
static double const PerlinOffset = 4096.0;
+#else
+ static double constexpr PerlinOffset = 4096.0;
+#endif
Geom::Rect _tile;
Geom::Point _baseFreq;
diff --git a/src/dom/io/domstream.cpp b/src/dom/io/domstream.cpp
index 21d09662a..b9ff7e9d2 100644
--- a/src/dom/io/domstream.cpp
+++ b/src/dom/io/domstream.cpp
@@ -424,12 +424,11 @@ static int dprintf(Writer &outs, const DOMString &fmt, va_list ap)
//# B A S I C I N P U T S T R E A M
//#########################################################################
-
/**
*
- */
-BasicInputStream::BasicInputStream(const InputStream &sourceStream)
- : source((InputStream &)sourceStream)
+ */
+BasicInputStream::BasicInputStream(InputStream &sourceStream)
+ : source(sourceStream)
{
closed = false;
}
@@ -438,7 +437,7 @@ BasicInputStream::BasicInputStream(const InputStream &sourceStream)
* Returns the number of bytes that can be read (or skipped over) from
* this input stream without blocking by the next caller of a method for
* this input stream.
- */
+ */
int BasicInputStream::available()
{
if (closed)
@@ -446,11 +445,11 @@ int BasicInputStream::available()
return source.available();
}
-
+
/**
* Closes this input stream and releases any system resources
* associated with the stream.
- */
+ */
void BasicInputStream::close()
{
if (closed)
@@ -458,10 +457,10 @@ void BasicInputStream::close()
source.close();
closed = true;
}
-
+
/**
* Reads the next byte of data from the input stream. -1 if EOF
- */
+ */
int BasicInputStream::get()
{
if (closed)
@@ -477,9 +476,9 @@ int BasicInputStream::get()
/**
*
- */
-BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
- : destination((OutputStream &)destinationStream)
+ */
+BasicOutputStream::BasicOutputStream(OutputStream &destinationStream)
+ : destination(destinationStream)
{
closed = false;
}
@@ -487,7 +486,7 @@ BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
/**
* Closes this output stream and releases any system resources
* associated with this stream.
- */
+ */
void BasicOutputStream::close()
{
if (closed)
@@ -495,40 +494,33 @@ void BasicOutputStream::close()
destination.close();
closed = true;
}
-
+
/**
* Flushes this output stream and forces any buffered output
* bytes to be written out.
- */
+ */
void BasicOutputStream::flush()
{
if (closed)
return;
destination.flush();
}
-
+
/**
* Writes the specified byte to this output stream.
- */
+ */
int BasicOutputStream::put(gunichar ch)
{
if (closed)
return -1;
- if (destination.put(ch) < 0)
- return -1;
- return 1;
+ destination.put(ch);
+ return 1;
}
-
//#########################################################################
//# B A S I C R E A D E R
//#########################################################################
-
-
-/**
- *
- */
BasicReader::BasicReader(Reader &sourceReader)
{
source = &sourceReader;
@@ -538,7 +530,7 @@ BasicReader::BasicReader(Reader &sourceReader)
* Returns the number of bytes that can be read (or skipped over) from
* this reader without blocking by the next caller of a method for
* this reader.
- */
+ */
int BasicReader::available()
{
if (source)
@@ -547,69 +539,65 @@ int BasicReader::available()
return 0;
}
-
+
/**
* Closes this reader and releases any system resources
* associated with the reader.
- */
+ */
void BasicReader::close()
{
if (source)
source->close();
}
-
+
/**
* Reads the next byte of data from the reader.
- */
-int BasicReader::get()
+ */
+gunichar BasicReader::get()
{
if (source)
return source->get();
else
- return -1;
+ return (gunichar)-1;
}
-
-
-
-
-
+
/**
* Reads a line of data from the reader.
- */
-DOMString BasicReader::readLine()
+ */
+Glib::ustring BasicReader::readLine()
{
- DOMString str;
+ Glib::ustring str;
while (available() > 0)
{
- XMLCh ch = get();
+ gunichar ch = get();
if (ch == '\n')
break;
str.push_back(ch);
}
return str;
}
-
+
/**
* Reads a line of data from the reader.
- */
-DOMString BasicReader::readWord()
+ */
+Glib::ustring BasicReader::readWord()
{
- DOMString str;
+ Glib::ustring str;
while (available() > 0)
{
- XMLCh ch = get();
- if (uni_is_space(ch))
+ gunichar ch = get();
+ if (!g_unichar_isprint(ch))
break;
str.push_back(ch);
}
return str;
}
+
-
-static bool getLong(DOMString &str, long *val)
+static bool getLong(Glib::ustring &str, long *val)
{
- const char *begin = str.c_str();
+ const char *begin = str.raw().c_str();
char *end;
long ival = strtol(begin, &end, 10);
if (str == end)
@@ -618,25 +606,23 @@ static bool getLong(DOMString &str, long *val)
return true;
}
-static bool getULong(const DOMString &str, unsigned long *val)
+static bool getULong(Glib::ustring &str, unsigned long *val)
{
- DOMString tmp = str;
- char *begin = (char *)tmp.c_str();
+ const char *begin = str.raw().c_str();
char *end;
unsigned long ival = strtoul(begin, &end, 10);
- if (begin == end)
+ if (str == end)
return false;
*val = ival;
return true;
}
-static bool getDouble(const DOMString &str, double *val)
+static bool getDouble(Glib::ustring &str, double *val)
{
- DOMString tmp = str;
- const char *begin = tmp.c_str();
+ const char *begin = str.raw().c_str();
char *end;
double ival = strtod(begin, &end);
- if (begin == end)
+ if (str == end)
return false;
*val = ival;
return true;
@@ -644,13 +630,9 @@ static bool getDouble(const DOMString &str, double *val)
-
-/**
- *
- */
-Reader &BasicReader::readBool (bool& val )
+const Reader &BasicReader::readBool (bool& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
if (buf == "true")
val = true;
else
@@ -658,96 +640,72 @@ Reader &BasicReader::readBool (bool& val )
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readShort (short& val )
+const Reader &BasicReader::readShort (short& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
long ival;
if (getLong(buf, &ival))
val = (short) ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readUnsignedShort (unsigned short& val )
+const Reader &BasicReader::readUnsignedShort (unsigned short& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
unsigned long ival;
if (getULong(buf, &ival))
val = (unsigned short) ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readInt (int& val )
+const Reader &BasicReader::readInt (int& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
long ival;
if (getLong(buf, &ival))
val = (int) ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readUnsignedInt (unsigned int& val )
+const Reader &BasicReader::readUnsignedInt (unsigned int& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
unsigned long ival;
if (getULong(buf, &ival))
val = (unsigned int) ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readLong (long& val )
+const Reader &BasicReader::readLong (long& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
long ival;
if (getLong(buf, &ival))
val = ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readUnsignedLong (unsigned long& val )
+const Reader &BasicReader::readUnsignedLong (unsigned long& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
unsigned long ival;
if (getULong(buf, &ival))
val = ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readFloat (float& val )
+const Reader &BasicReader::readFloat (float& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
double ival;
if (getDouble(buf, &ival))
val = (float)ival;
return *this;
}
-/**
- *
- */
-Reader &BasicReader::readDouble (double& val )
+const Reader &BasicReader::readDouble (double& val )
{
- DOMString buf = readWord();
+ Glib::ustring buf = readWord();
double ival;
if (getDouble(buf, &ival))
val = ival;
@@ -761,12 +719,12 @@ Reader &BasicReader::readDouble (double& val )
//#########################################################################
-InputStreamReader::InputStreamReader(const InputStream &inputStreamSource)
- : inputStream((InputStream &)inputStreamSource)
+InputStreamReader::InputStreamReader(InputStream &inputStreamSource)
+ : inputStream(inputStreamSource)
{
}
-
+
/**
* Close the underlying OutputStream
@@ -775,7 +733,7 @@ void InputStreamReader::close()
{
inputStream.close();
}
-
+
/**
* Flush the underlying OutputStream
*/
@@ -783,15 +741,15 @@ int InputStreamReader::available()
{
return inputStream.available();
}
-
+
/**
* Overloaded to receive its bytes from an InputStream
* rather than a Reader
*/
-int InputStreamReader::get()
+gunichar InputStreamReader::get()
{
//Do we need conversions here?
- int ch = (XMLCh)inputStream.get();
+ gunichar ch = (gunichar)inputStream.get();
return ch;
}
@@ -818,7 +776,7 @@ StdReader::~StdReader()
delete inputStream;
}
-
+
/**
* Close the underlying OutputStream
@@ -827,7 +785,7 @@ void StdReader::close()
{
inputStream->close();
}
-
+
/**
* Flush the underlying OutputStream
*/
@@ -835,22 +793,21 @@ int StdReader::available()
{
return inputStream->available();
}
-
+
/**
* Overloaded to receive its bytes from an InputStream
* rather than a Reader
*/
-int StdReader::get()
+gunichar StdReader::get()
{
//Do we need conversions here?
- XMLCh ch = (XMLCh)inputStream->get();
+ gunichar ch = (gunichar)inputStream->get();
return ch;
}
-
//#########################################################################
//# B A S I C W R I T E R
//#########################################################################
@@ -1145,13 +1102,6 @@ int StdWriter::put(gunichar ch)
-
-
-
-
-
-
-
//###############################################
//# O P E R A T O R S
//###############################################
@@ -1165,31 +1115,31 @@ int StdWriter::put(gunichar ch)
-Reader& operator>> (Reader &reader, bool& val )
+const Reader& operator>> (Reader &reader, bool& val )
{ return reader.readBool(val); }
-Reader& operator>> (Reader &reader, short &val)
+const Reader& operator>> (Reader &reader, short &val)
{ return reader.readShort(val); }
-Reader& operator>> (Reader &reader, unsigned short &val)
+const Reader& operator>> (Reader &reader, unsigned short &val)
{ return reader.readUnsignedShort(val); }
-Reader& operator>> (Reader &reader, int &val)
+const Reader& operator>> (Reader &reader, int &val)
{ return reader.readInt(val); }
-Reader& operator>> (Reader &reader, unsigned int &val)
+const Reader& operator>> (Reader &reader, unsigned int &val)
{ return reader.readUnsignedInt(val); }
-Reader& operator>> (Reader &reader, long &val)
+const Reader& operator>> (Reader &reader, long &val)
{ return reader.readLong(val); }
-Reader& operator>> (Reader &reader, unsigned long &val)
+const Reader& operator>> (Reader &reader, unsigned long &val)
{ return reader.readUnsignedLong(val); }
-Reader& operator>> (Reader &reader, float &val)
+const Reader& operator>> (Reader &reader, float &val)
{ return reader.readFloat(val); }
-Reader& operator>> (Reader &reader, double &val)
+const Reader& operator>> (Reader &reader, double &val)
{ return reader.readDouble(val); }
diff --git a/src/dom/io/domstream.h b/src/dom/io/domstream.h
index 925e52bfe..a021676fa 100644
--- a/src/dom/io/domstream.h
+++ b/src/dom/io/domstream.h
@@ -44,23 +44,21 @@ namespace dom
namespace io
{
-
-
-class StreamException
+class StreamException : public std::exception
{
public:
- StreamException(const DOMString &theReason) throw()
- : reason(theReason)
- {}
+ StreamException(const char *theReason) throw()
+ { reason = theReason; }
+ StreamException(Glib::ustring &theReason) throw()
+ { reason = theReason; }
virtual ~StreamException() throw()
{ }
- char const *what()
+ char const *what() const throw()
{ return reason.c_str(); }
-
+
private:
-
- DOMString reason;
+ Glib::ustring reason;
};
@@ -95,14 +93,14 @@ public:
* to be read
*/
virtual int available() = 0;
-
+
/**
* Do whatever it takes to 'close' this input stream
* The most likely implementation of this method will be
* for endpoints that use a resource for their data.
*/
virtual void close() = 0;
-
+
/**
* Read one byte from this input stream. This is a blocking
* call. If no data is currently available, this call will
@@ -113,7 +111,7 @@ public:
* This call returns -1 on end-of-file.
*/
virtual int get() = 0;
-
+
}; // class InputStream
@@ -129,22 +127,22 @@ class BasicInputStream : public InputStream
public:
- BasicInputStream(const InputStream &sourceStream);
-
+ BasicInputStream(InputStream &sourceStream);
+
virtual ~BasicInputStream() {}
-
+
virtual int available();
-
+
virtual void close();
-
+
virtual int get();
-
+
protected:
bool closed;
InputStream &source;
-
+
private:
@@ -161,10 +159,10 @@ public:
int available()
{ return 0; }
-
+
void close()
{ /* do nothing */ }
-
+
int get()
{ return getchar(); }
@@ -174,7 +172,6 @@ public:
-
//#########################################################################
//# O U T P U T S T R E A M
//#########################################################################
@@ -207,14 +204,14 @@ public:
* 3. close the destination stream
*/
virtual void close() = 0;
-
+
/**
* This call should push any pending data it might have to
* the destination stream. It should NOT call flush() on
* the destination stream.
*/
virtual void flush() = 0;
-
+
/**
* Send one byte to the destination stream.
*/
@@ -233,14 +230,14 @@ class BasicOutputStream : public OutputStream
public:
- BasicOutputStream(const OutputStream &destinationStream);
-
+ BasicOutputStream(OutputStream &destinationStream);
+
virtual ~BasicOutputStream() {}
virtual void close();
-
+
virtual void flush();
-
+
virtual int put(gunichar ch);
protected:
@@ -263,12 +260,12 @@ public:
void close()
{ }
-
+
void flush()
{ }
-
+
int put(gunichar ch)
- { putchar(ch); return 1; }
+ { return putchar(ch); }
};
@@ -279,7 +276,6 @@ public:
//# R E A D E R
//#########################################################################
-
/**
* This interface and its descendants are for unicode character-oriented input
*
@@ -301,33 +297,42 @@ public:
virtual int available() = 0;
-
+
virtual void close() = 0;
-
- virtual int get() = 0;
-
- virtual DOMString readLine() = 0;
-
- virtual DOMString readWord() = 0;
-
+
+ virtual gunichar get() = 0;
+
+ virtual Glib::ustring readLine() = 0;
+
+ virtual Glib::ustring readWord() = 0;
+
/* Input formatting */
- virtual Reader& readBool (bool& val ) = 0;
-
- virtual Reader& readShort (short &val) = 0;
-
- virtual Reader& readUnsignedShort (unsigned short &val) = 0;
-
- virtual Reader& readInt (int &val) = 0;
-
- virtual Reader& readUnsignedInt (unsigned int &val) = 0;
-
- virtual Reader& readLong (long &val) = 0;
-
- virtual Reader& readUnsignedLong (unsigned long &val) = 0;
-
- virtual Reader& readFloat (float &val) = 0;
-
- virtual Reader& readDouble (double &val) = 0;
+ virtual const Reader& readBool (bool& val ) = 0;
+ virtual const Reader& operator>> (bool& val ) = 0;
+
+ virtual const Reader& readShort (short &val) = 0;
+ virtual const Reader& operator>> (short &val) = 0;
+
+ virtual const Reader& readUnsignedShort (unsigned short &val) = 0;
+ virtual const Reader& operator>> (unsigned short &val) = 0;
+
+ virtual const Reader& readInt (int &val) = 0;
+ virtual const Reader& operator>> (int &val) = 0;
+
+ virtual const Reader& readUnsignedInt (unsigned int &val) = 0;
+ virtual const Reader& operator>> (unsigned int &val) = 0;
+
+ virtual const Reader& readLong (long &val) = 0;
+ virtual const Reader& operator>> (long &val) = 0;
+
+ virtual const Reader& readUnsignedLong (unsigned long &val) = 0;
+ virtual const Reader& operator>> (unsigned long &val) = 0;
+
+ virtual const Reader& readFloat (float &val) = 0;
+ virtual const Reader& operator>> (float &val) = 0;
+
+ virtual const Reader& readDouble (double &val) = 0;
+ virtual const Reader& operator>> (double &val) = 0;
}; // interface Reader
@@ -343,37 +348,56 @@ class BasicReader : public Reader
public:
BasicReader(Reader &sourceStream);
-
+
virtual ~BasicReader() {}
virtual int available();
-
+
virtual void close();
-
- virtual int get();
-
- virtual DOMString readLine();
-
- virtual DOMString readWord();
-
+
+ virtual gunichar get();
+
+ virtual Glib::ustring readLine();
+
+ virtual Glib::ustring readWord();
+
/* Input formatting */
- virtual Reader& readBool (bool& val );
-
- virtual Reader& readShort (short &val) ;
-
- virtual Reader& readUnsignedShort (unsigned short &val) ;
-
- virtual Reader& readInt (int &val) ;
-
- virtual Reader& readUnsignedInt (unsigned int &val) ;
-
- virtual Reader& readLong (long &val) ;
-
- virtual Reader& readUnsignedLong (unsigned long &val) ;
-
- virtual Reader& readFloat (float &val) ;
-
- virtual Reader& readDouble (double &val) ;
+ virtual const Reader& readBool (bool& val );
+ virtual const Reader& operator>> (bool& val )
+ { return readBool(val); }
+
+ virtual const Reader& readShort (short &val);
+ virtual const Reader& operator>> (short &val)
+ { return readShort(val); }
+
+ virtual const Reader& readUnsignedShort (unsigned short &val);
+ virtual const Reader& operator>> (unsigned short &val)
+ { return readUnsignedShort(val); }
+
+ virtual const Reader& readInt (int &val);
+ virtual const Reader& operator>> (int &val)
+ { return readInt(val); }
+
+ virtual const Reader& readUnsignedInt (unsigned int &val);
+ virtual const Reader& operator>> (unsigned int &val)
+ { return readUnsignedInt(val); }
+
+ virtual const Reader& readLong (long &val);
+ virtual const Reader& operator>> (long &val)
+ { return readLong(val); }
+
+ virtual const Reader& readUnsignedLong (unsigned long &val);
+ virtual const Reader& operator>> (unsigned long &val)
+ { return readUnsignedLong(val); }
+
+ virtual const Reader& readFloat (float &val);
+ virtual const Reader& operator>> (float &val)
+ { return readFloat(val); }
+
+ virtual const Reader& readDouble (double &val);
+ virtual const Reader& operator>> (double &val)
+ { return readDouble(val); }
+
protected:
@@ -388,27 +412,6 @@ private:
-Reader& operator>> (Reader &reader, bool& val );
-
-Reader& operator>> (Reader &reader, short &val);
-
-Reader& operator>> (Reader &reader, unsigned short &val);
-
-Reader& operator>> (Reader &reader, int &val);
-
-Reader& operator>> (Reader &reader, unsigned int &val);
-
-Reader& operator>> (Reader &reader, long &val);
-
-Reader& operator>> (Reader &reader, unsigned long &val);
-
-Reader& operator>> (Reader &reader, float &val);
-
-Reader& operator>> (Reader &reader, double &val);
-
-
-
-
/**
* Class for placing a Reader on an open InputStream
*
@@ -417,14 +420,14 @@ class InputStreamReader : public BasicReader
{
public:
- InputStreamReader(const InputStream &inputStreamSource);
-
+ InputStreamReader(InputStream &inputStreamSource);
+
/*Overload these 3 for your implementation*/
virtual int available();
-
+
virtual void close();
-
- virtual int get();
+
+ virtual gunichar get();
private:
@@ -445,13 +448,13 @@ public:
StdReader();
virtual ~StdReader();
-
+
/*Overload these 3 for your implementation*/
virtual int available();
-
+
virtual void close();
-
- virtual int get();
+
+ virtual gunichar get();
private:
@@ -463,8 +466,6 @@ private:
-
-
//#########################################################################
//# W R I T E R
//#########################################################################
diff --git a/src/dom/io/uristream.cpp b/src/dom/io/uristream.cpp
index 68a14a166..f6172d9e0 100644
--- a/src/dom/io/uristream.cpp
+++ b/src/dom/io/uristream.cpp
@@ -235,10 +235,10 @@ void UriReader::close() throw(StreamException)
/**
*
*/
-int UriReader::get() throw(StreamException)
+gunichar UriReader::get() throw(StreamException)
{
- int ch = (int)inputStream->get();
- return ch;
+ //int ch = (int)inputStream->get();
+ return inputStream->get();//ch;
}
diff --git a/src/dom/io/uristream.h b/src/dom/io/uristream.h
index 2a659d030..51227acc9 100644
--- a/src/dom/io/uristream.h
+++ b/src/dom/io/uristream.h
@@ -111,7 +111,7 @@ public:
virtual void close() throw(StreamException);
- virtual int get() throw(StreamException);
+ virtual gunichar get() throw(StreamException);
private:
diff --git a/src/extension/internal/filter/paint.h b/src/extension/internal/filter/paint.h
index ad396e08f..f04dd92f9 100644
--- a/src/extension/internal/filter/paint.h
+++ b/src/extension/internal/filter/paint.h
@@ -88,7 +88,7 @@ public:
"<param name=\"noise\" gui-text=\"" N_("Noise reduction:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"1000\">10</param>\n"
"<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1</param>\n"
"</page>\n"
- "<page name=\"graintab\" _gui-text=\""N_("Grain") "\">\n"
+ "<page name=\"graintab\" _gui-text=\"" N_("Grain") "\">\n"
"<param name=\"grain\" gui-text=\"" N_("Grain mode") "\" type=\"boolean\" >true</param>\n"
"<param name=\"grainxf\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n"
"<param name=\"grainyf\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n"
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp
index 0639ae8d0..bd74ba47c 100644
--- a/src/extension/internal/odf.cpp
+++ b/src/extension/internal/odf.cpp
@@ -83,8 +83,8 @@
#include "dom/io/stringstream.h"
+#include "inkscape-version.h"
#include "document.h"
-
#include "extension/extension.h"
@@ -1240,7 +1240,8 @@ bool OdfOutput::writeMeta(ZipFile &zf)
outs.printf("xmlns:anim=\"urn:oasis:names:tc:opendocument:xmlns:animation:1.0\"\n");
outs.printf("office:version=\"1.0\">\n");
outs.printf("<office:meta>\n");
- outs.printf(" <meta:generator>Inkscape.org - 0.45</meta:generator>\n");
+ Glib::ustring tmp = Glib::ustring(" <meta:generator>Inkscape.org - ") + Inkscape::version_string + "</meta:generator>\n";
+ outs.writeString(tmp);
outs.printf(" <meta:initial-creator>%#s</meta:initial-creator>\n",
creator.c_str());
outs.printf(" <meta:creation-date>%#s</meta:creation-date>\n", date.c_str());
@@ -1465,7 +1466,7 @@ bool OdfOutput::writeStyle(ZipFile &zf)
outs.printf("<!--\n");
outs.printf("*************************************************************************\n");
outs.printf(" E N D O F F I L E\n");
- outs.printf(" Have a nice day - ishmal\n");
+ outs.printf(" Have a nice day\n");
outs.printf("*************************************************************************\n");
outs.printf("-->\n");
outs.printf("\n");
@@ -2170,7 +2171,7 @@ bool OdfOutput::writeStyleFooter(Writer &outs)
outs.printf("<!--\n");
outs.printf("*************************************************************************\n");
outs.printf(" E N D O F F I L E\n");
- outs.printf(" Have a nice day - ishmal\n");
+ outs.printf(" Have a nice day\n");
outs.printf("*************************************************************************\n");
outs.printf("-->\n");
outs.printf("\n");
@@ -2281,7 +2282,7 @@ bool OdfOutput::writeContentFooter(Writer &outs)
outs.printf("<!--\n");
outs.printf("*************************************************************************\n");
outs.printf(" E N D O F F I L E\n");
- outs.printf(" Have a nice day - ishmal\n");
+ outs.printf(" Have a nice day\n");
outs.printf("*************************************************************************\n");
outs.printf("-->\n");
outs.printf("\n");
@@ -2441,27 +2442,6 @@ OdfOutput::check (Inkscape::Extension::Extension */*module*/)
-//########################################################################
-//# I N P U T
-//########################################################################
-
-
-
-//#######################
-//# L A T E R !!! :-)
-//#######################
-
-
-
-
-
-
-
-
-
-
-
-
} //namespace Internal
} //namespace Extension
diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp
index 42a6ba1e4..28c819347 100644
--- a/src/io/base64stream.cpp
+++ b/src/io/base64stream.cpp
@@ -290,12 +290,12 @@ void Base64OutputStream::putCh(int ch)
/**
* Writes the specified byte to this output stream.
*/
-void Base64OutputStream::put(gunichar ch)
+int Base64OutputStream::put(gunichar ch)
{
if (closed)
{
//probably throw an exception here
- return;
+ return -1;
}
outBuf <<= 8;
@@ -322,6 +322,7 @@ void Base64OutputStream::put(gunichar ch)
bitCount = 0;
outBuf = 0L;
}
+ return 1;
}
diff --git a/src/io/base64stream.h b/src/io/base64stream.h
index 836939130..4bc99acac 100644
--- a/src/io/base64stream.h
+++ b/src/io/base64stream.h
@@ -88,7 +88,7 @@ public:
virtual void flush();
- virtual void put(gunichar ch);
+ virtual int put(gunichar ch);
/**
* Sets the maximum line length for base64 output. If
diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp
index 071179b48..8db7155db 100644
--- a/src/io/gzipstream.cpp
+++ b/src/io/gzipstream.cpp
@@ -433,19 +433,19 @@ void GzipOutputStream::flush()
/**
* Writes the specified byte to this output stream.
*/
-void GzipOutputStream::put(gunichar ch)
+int GzipOutputStream::put(gunichar ch)
{
if (closed)
{
//probably throw an exception here
- return;
+ return -1;
}
//Add char to buffer
inputBuf.push_back(ch);
totalIn++;
-
+ return 1;
}
diff --git a/src/io/gzipstream.h b/src/io/gzipstream.h
index 5af57b4c5..390ec1225 100644
--- a/src/io/gzipstream.h
+++ b/src/io/gzipstream.h
@@ -98,7 +98,7 @@ public:
virtual void flush();
- virtual void put(gunichar ch);
+ virtual int put(gunichar ch);
private:
diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp
index 3270127d6..4c7fa4d49 100644
--- a/src/io/inkscapestream.cpp
+++ b/src/io/inkscapestream.cpp
@@ -125,11 +125,12 @@ void BasicOutputStream::flush()
/**
* Writes the specified byte to this output stream.
*/
-void BasicOutputStream::put(gunichar ch)
+int BasicOutputStream::put(gunichar ch)
{
if (closed)
- return;
+ return -1;
destination.put(ch);
+ return 1;
}
@@ -137,8 +138,6 @@ void BasicOutputStream::put(gunichar ch)
//#########################################################################
//# B A S I C R E A D E R
//#########################################################################
-
-
/**
*
*/
@@ -183,10 +182,6 @@ gunichar BasicReader::get()
}
-
-
-
-
/**
* Reads a line of data from the reader.
*/
@@ -255,13 +250,6 @@ static bool getDouble(Glib::ustring &str, double *val)
-
-
-
-
-/**
- *
- */
const Reader &BasicReader::readBool (bool& val )
{
Glib::ustring buf = readWord();
@@ -272,9 +260,6 @@ const Reader &BasicReader::readBool (bool& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readShort (short& val )
{
Glib::ustring buf = readWord();
@@ -284,9 +269,6 @@ const Reader &BasicReader::readShort (short& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readUnsignedShort (unsigned short& val )
{
Glib::ustring buf = readWord();
@@ -296,9 +278,6 @@ const Reader &BasicReader::readUnsignedShort (unsigned short& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readInt (int& val )
{
Glib::ustring buf = readWord();
@@ -308,9 +287,6 @@ const Reader &BasicReader::readInt (int& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readUnsignedInt (unsigned int& val )
{
Glib::ustring buf = readWord();
@@ -320,9 +296,6 @@ const Reader &BasicReader::readUnsignedInt (unsigned int& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readLong (long& val )
{
Glib::ustring buf = readWord();
@@ -332,9 +305,6 @@ const Reader &BasicReader::readLong (long& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readUnsignedLong (unsigned long& val )
{
Glib::ustring buf = readWord();
@@ -344,9 +314,6 @@ const Reader &BasicReader::readUnsignedLong (unsigned long& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readFloat (float& val )
{
Glib::ustring buf = readWord();
@@ -356,9 +323,6 @@ const Reader &BasicReader::readFloat (float& val )
return *this;
}
-/**
- *
- */
const Reader &BasicReader::readDouble (double& val )
{
Glib::ustring buf = readWord();
diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h
index a9854ae6d..d19dbbe95 100644
--- a/src/io/inkscapestream.h
+++ b/src/io/inkscapestream.h
@@ -189,7 +189,7 @@ public:
/**
* Send one byte to the destination stream.
*/
- virtual void put(gunichar ch) = 0;
+ virtual int put(gunichar ch) = 0;
}; // class OutputStream
@@ -212,7 +212,7 @@ public:
virtual void flush();
- virtual void put(gunichar ch);
+ virtual int put(gunichar ch);
protected:
@@ -238,8 +238,8 @@ public:
void flush()
{ }
- void put(gunichar ch)
- { putchar(ch); }
+ int put(gunichar ch)
+ {return putchar(ch); }
};
diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp
index f204a99d5..5a76e24a3 100644
--- a/src/io/stringstream.cpp
+++ b/src/io/stringstream.cpp
@@ -112,9 +112,10 @@ void StringOutputStream::flush()
/**
* Writes the specified byte to this output stream.
*/
-void StringOutputStream::put(gunichar ch)
+int StringOutputStream::put(gunichar ch)
{
buffer.push_back(ch);
+ return 1;
}
diff --git a/src/io/stringstream.h b/src/io/stringstream.h
index a78935599..939a87455 100644
--- a/src/io/stringstream.h
+++ b/src/io/stringstream.h
@@ -67,7 +67,7 @@ public:
virtual void flush();
- virtual void put(gunichar ch);
+ virtual int put(gunichar ch);
virtual Glib::ustring &getString()
{ return buffer; }
diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp
index 8d7fd9b38..37c13ada0 100644
--- a/src/io/uristream.cpp
+++ b/src/io/uristream.cpp
@@ -402,17 +402,17 @@ void UriOutputStream::flush() throw(StreamException)
/**
* Writes the specified byte to this output stream.
*/
-void UriOutputStream::put(gunichar ch) throw(StreamException)
+int UriOutputStream::put(gunichar ch) throw(StreamException)
{
if (closed)
- return;
+ return -1;
unsigned char uch;
switch (scheme) {
case SCHEME_FILE:
if (!outf)
- return;
+ return -1;
uch = (unsigned char)(ch & 0xff);
if (fputc(uch, outf) == EOF) {
Glib::ustring err = "ERROR writing to file ";
@@ -425,7 +425,7 @@ void UriOutputStream::put(gunichar ch) throw(StreamException)
break;
}//switch
-
+ return 1;
}
diff --git a/src/io/uristream.h b/src/io/uristream.h
index e519335e8..3080519de 100644
--- a/src/io/uristream.h
+++ b/src/io/uristream.h
@@ -115,7 +115,7 @@ public:
virtual void flush() throw(StreamException);
- virtual void put(gunichar ch) throw(StreamException);
+ virtual int put(gunichar ch) throw(StreamException);
private:
diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp
index 1c260c0b3..7a6632233 100644
--- a/src/io/xsltstream.cpp
+++ b/src/io/xsltstream.cpp
@@ -230,9 +230,10 @@ void XsltOutputStream::flush() throw (StreamException)
/**
* Writes the specified byte to this output stream.
*/
-void XsltOutputStream::put(gunichar ch) throw (StreamException)
+int XsltOutputStream::put(gunichar ch) throw (StreamException)
{
outbuf.push_back(ch);
+ return 1;
}
diff --git a/src/io/xsltstream.h b/src/io/xsltstream.h
index 9b8e19215..31ee89e10 100644
--- a/src/io/xsltstream.h
+++ b/src/io/xsltstream.h
@@ -120,7 +120,7 @@ public:
virtual void flush() throw (StreamException);
- virtual void put(gunichar ch) throw (StreamException);
+ virtual int put(gunichar ch) throw (StreamException);
private:
diff --git a/src/isinf.h b/src/isinf.h
index 7799d2876..b4c56f79d 100644
--- a/src/isinf.h
+++ b/src/isinf.h
@@ -12,6 +12,9 @@
#elif defined(__APPLE__) && __GNUC__ == 3
#define isinf(x) __isinf(x)
+#elif __cplusplus >= 201103L
+# include <cmath>
+# define isinf std::isinf
#endif
#endif /* __ISINF_H__ */
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp
index 5e67c5991..97d3c66d4 100644
--- a/src/libnrtype/font-lister.cpp
+++ b/src/libnrtype/font-lister.cpp
@@ -82,7 +82,6 @@ namespace Inkscape
font_list_store->thaw_notify();
style_list_store = Gtk::ListStore::create (FontStyleList);
- style_list_store_trial = Gtk::ListStore::create (FontStyleList);
}
// Example of how to use "foreach_iter"
@@ -375,6 +374,24 @@ namespace Inkscape
}
+ // Set fontspec. If check is false, best style match will not be done.
+ void
+ FontLister::set_fontspec (Glib::ustring new_fontspec, gboolean check) {
+
+ std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( new_fontspec );
+ Glib::ustring new_family = ui.first;
+ Glib::ustring new_style = ui.second;
+
+#ifdef DEBUG_FONT
+ std::cout << "FontLister::set_fontspec: family: " << new_family
+ << " style:" << new_style << std::endl;
+#endif
+
+ set_font_family( new_family, false );
+ set_font_style( new_style );
+ }
+
+
// TODO: use to determine font-selector best style
std::pair<Glib::ustring, Glib::ustring>
FontLister::new_font_family (Glib::ustring new_family, gboolean check_style ) {
@@ -419,7 +436,6 @@ namespace Inkscape
}
// Update style list.
- // TODO: create a second "temporary" style_list_store for font_selector.
style_list_store->freeze_notify();
style_list_store->clear();
@@ -524,11 +540,6 @@ namespace Inkscape
}
- // void
- // FontLister::new_font_style (Glib::ustring new_style) {
- // // Is this needed? What do we do?
- // }
-
void
FontLister::set_font_style (Glib::ustring new_style) {
@@ -554,27 +565,22 @@ namespace Inkscape
#endif
}
- // For use by font-selector where we already know that the style is valid
- void
- FontLister::set_font (Glib::ustring new_family, Glib::ustring new_style) {
-
-#ifdef DEBUG_FONT
- std::cout << "FonLister::set_font: " << new_family << " " << new_style << std::endl;
-#endif
- set_font_family( new_family, false );
- set_font_style( new_style );
- }
// We do this ourselves as we can't rely on FontFactory.
void
- FontLister::set_css( SPCSSAttr *css ) {
+ FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) {
+
+ if( fontspec.empty() ) {
+ fontspec = current_fontspec;
+ }
+ std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( fontspec );
- //std::cout << "FontLister:set_css: " << std::endl;
+ Glib::ustring family = ui.first;
- sp_repr_css_set_property (css, "-inkscape-font-specification", current_fontspec.c_str() );
- sp_repr_css_set_property (css, "font-family", current_family.c_str() ); //Canonized w/ spaces
+ sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec.c_str() );
+ sp_repr_css_set_property (css, "font-family", family.c_str() ); //Canonized w/ spaces
- PangoFontDescription *desc = pango_font_description_from_string( current_fontspec.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:
@@ -837,6 +843,26 @@ namespace Inkscape
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( style.compare( row[FontStyleList.styles] ) == 0 ) {
+ return row;
+ }
+
+ ++iter;
+ }
+
+ throw STYLE_NOT_FOUND;
+ }
+
/* Returns style string */
// TODO: Remove or turn into function to be used by new_font_family.
Glib::ustring
@@ -905,12 +931,6 @@ namespace Inkscape
{
return style_list_store;
}
-
- const Glib::RefPtr<Gtk::ListStore>
- FontLister::get_style_list_trial () const
- {
- return style_list_store_trial;
- }
}
// Helper functions
diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h
index aaa996247..5c48bf7a8 100644
--- a/src/libnrtype/font-lister.h
+++ b/src/libnrtype/font-lister.h
@@ -111,7 +111,6 @@ namespace Inkscape
};
FontStyleListClass FontStyleList;
- FontStyleListClass FontStyleListTrial;
/** Returns the ListStore with the family names
*
@@ -128,12 +127,6 @@ namespace Inkscape
const Glib::RefPtr<Gtk::ListStore>
get_style_list () const;
- /** Returns the ListStore with the styles - trial
- *
- */
- const Glib::RefPtr<Gtk::ListStore>
- get_style_list_trial () const;
-
/** Updates font list to include fonts in document
*
*/
@@ -173,6 +166,19 @@ namespace Inkscape
std::pair<Glib::ustring, Glib::ustring>
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, gboolean 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.
@@ -215,10 +221,6 @@ namespace Inkscape
return current_family_row;
}
- /* Not Used */
- void
- new_font_style (Glib::ustring style);
-
/** Sets style. Does not validate style for family.
*/
void
@@ -230,32 +232,13 @@ namespace Inkscape
return current_style;
}
- /** Sets both family and style. Does not attempt to find
- * best match for style (assume that style is already valid
- * for family).
- */
- void
- set_font (Glib::ustring family, Glib::ustring style);
-
- /** Sets both family and style. Does not attempt to find
- * best match for style (assume that style is already valid
- * for family).
- */
- void
- new_font (Glib::ustring family, Glib::ustring style);
-
- std::pair<Glib::ustring, Glib::ustring>
- get_try_font () {
- return ( std::make_pair( try_family, try_style ) );
- }
-
Glib::ustring
fontspec_from_style (SPStyle* style);
/** Fill css using current_fontspec.
*/
void
- set_css( SPCSSAttr *css );
+ fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" );
Gtk::TreeModel::Row
get_row_for_font (Glib::ustring family);
@@ -292,7 +275,6 @@ namespace Inkscape
Glib::RefPtr<Gtk::ListStore> font_list_store;
Glib::RefPtr<Gtk::ListStore> style_list_store;
- Glib::RefPtr<Gtk::ListStore> style_list_store_trial;
/** Info for currently selected font (what is shown in the UI).
* May include font-family lists and fonts not on system.
@@ -307,12 +289,6 @@ namespace Inkscape
*/
Glib::ustring current_fontspec_system;
- /** Info for proposed font (what is shown in the font-selection UI).
- * May include font-family lists and fonts not on system.
- */
- Glib::ustring try_family;
- Glib::ustring try_style;
-
/** If a font-family is not on system, this list of styles is used.
*/
GList *default_styles;
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index ed4791155..d91f7297e 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -53,7 +53,6 @@ LPEBSpline::doEffect(SPCurve * curve)
//Esto hace que la curva BSpline no pierda su condición aunque se trasladen
//dichos manejadores
SPCurve *nCurve = new SPCurve();
- Geom::Point startNode(0,0);
Geom::Point previousNode(0,0);
Geom::Point node(0,0);
Geom::Point pointAt1(0,0);
@@ -65,63 +64,19 @@ LPEBSpline::doEffect(SPCurve * curve)
Geom::D2< Geom::SBasis > SBasisOut;
Geom::D2< Geom::SBasis > SBasisHelper;
Geom::CubicBezier const *cubic = NULL;
- //Si la curva está cerrada calculamos el punto donde
- //deveria estar el nodo BSpline de cierre/inicio de la curva
- //en posible caso de que se cierre con una linea recta creando un nodo BSPline
-
if (path_it->closed()) {
- //Calculamos el nodo de inicio BSpline
- const Geom::Curve &closingline = path_it->back_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();
}
-
- SPCurve * in = new SPCurve();
- in->moveto(curve_it1->initialPoint());
- in->lineto(curve_it1->finalPoint());
- SBasisIn = in->first_segment()->toSBasis();
-
- SPCurve *lineHelper = new SPCurve();
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if(cubic){
- lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())));
- }else{
- lineHelper->moveto(in->first_segment()->initialPoint());
- }
- in->reset();
- delete in;
-
- SPCurve * end = new SPCurve();
- end->moveto(curve_endit->initialPoint());
- end->lineto(curve_endit->finalPoint());
- Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
- //Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_endit);
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_endit);
- if(cubic){
- lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
- }else{
- lineHelper->lineto(end->first_segment()->finalPoint());
- }
- end->reset();
- delete end;
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- //Guardamos el principio de la curva
- startNode = SBasisHelper.valueAt(0.5);
- //Definimos el punto de inicio original de la curva resultante
- node = startNode;
- }else{
- //Guardamos el principio de la curva
- SPCurve * in = new SPCurve();
- in->moveto(curve_it1->initialPoint());
- in->lineto(curve_it1->finalPoint());
- startNode = in->first_segment()->initialPoint();
- in->reset();
- delete in;
- //Definimos el punto de inicio original de la curva resultante
- node = startNode;
}
+ //Si la curva está cerrada calculamos el punto donde
+ //deveria estar el nodo BSpline de cierre/inicio de la curva
+ //en posible caso de que se cierre con una linea recta creando un nodo BSPline
+
//Recorremos todos los segmentos menos el último
while ( curve_it2 != curve_endit )
{
@@ -190,13 +145,54 @@ LPEBSpline::doEffect(SPCurve * curve)
curveHelper->moveto(node);
//Si está cerrada la curva, la cerramos sobre el valor guardado previamente
//Si no finalizamos en el punto final
+ Geom::Point startNode(0,0);
if (path_it->closed()) {
+ SPCurve * start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ Geom::D2< Geom::SBasis > SBasisStart = start->first_segment()->toSBasis();
+ SPCurve *lineHelper = new SPCurve();
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*path_it->begin());
+ if(cubic){
+ lineHelper->moveto(SBasisStart.valueAt(Geom::nearest_point((*cubic)[1],*start->first_segment())));
+ }else{
+ lineHelper->moveto(start->first_segment()->initialPoint());
+ }
+ start->reset();
+ delete start;
+
+ SPCurve * end = new SPCurve();
+ end->moveto(curve_it1->initialPoint());
+ end->lineto(curve_it1->finalPoint());
+ Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
+ //Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_endit);
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
+ }else{
+ lineHelper->lineto(end->first_segment()->finalPoint());
+ }
+ end->reset();
+ delete end;
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ //Guardamos el principio de la curva
+ startNode = SBasisHelper.valueAt(0.5);
curveHelper->curveto(nextPointAt1, nextPointAt2, startNode);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,startNode);
}else{
+ SPCurve * start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ startNode = start->first_segment()->initialPoint();
+ start->reset();
+ delete start;
curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,nextPointAt3);
}
- //añadimos este último segmento
- nCurve->append_continuous(curveHelper, 0.0625);
curveHelper->reset();
delete curveHelper;
//y cerramos la curva
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index e781a048f..26f800328 100644
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
@@ -94,35 +94,22 @@ static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p);
*/
static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode);
//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro
-static void spiro_color(SPPenContext *const pc);
-//Guarda el valor si se ha pulsado la tecla SHIFT al continuar una curva
-static void spiro(SPPenContext *const pc,bool shift);
-static void spiroOn(SPPenContext *const pc);
-static void spiroOff(SPPenContext *const pc);
-static void spiroStartAnchor(SPPenContext *const pc,bool shift);
-static void spiroStartAnchorOn(SPPenContext *const pc);
-static void spiroStartAnchorOff(SPPenContext *const pc);
-static void spiroMotion(SPPenContext *const pc,bool shift);
-static void spiroEndAnchorOn(SPPenContext *const pc);
-static void spiroEndAnchorOff(SPPenContext *const pc);
+static void bspline_spiro_color(SPPenContext *const pc);
+static void bspline_spiro(SPPenContext *const pc,bool shift);
+static void bspline_spiro_on(SPPenContext *const pc);
+static void bspline_spiro_off(SPPenContext *const pc);
+static void bspline_spiro_start_anchor(SPPenContext *const pc,bool shift);
+static void bspline_spiro_start_anchor_on(SPPenContext *const pc);
+static void bspline_spiro_start_anchor_off(SPPenContext *const pc);
+static void bspline_spiro_motion(SPPenContext *const pc,bool shift);
+static void bspline_spiro_end_anchor_on(SPPenContext *const pc);
+static void bspline_spiro_end_anchor_off(SPPenContext *const pc);
//Unimos todas las curvas en juego y llamamos a la función doEffect.
-static void spiro_build(SPPenContext *const pc);
-//function spiro cloned from lpe-spiro.cpp
-static void spiro_doEffect(SPCurve * curve);
-//Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT
-static void bspline(SPPenContext *const pc,bool shift);
-static void bsplineOn(SPPenContext *const pc);
-static void bsplineOff(SPPenContext *const pc);
-static void bsplineStartAnchor(SPPenContext *const pc,bool shift);
-static void bsplineStartAnchorOn(SPPenContext *const pc);
-static void bsplineStartAnchorOff(SPPenContext *const pc);
-static void bsplineMotion(SPPenContext *const pc,bool shift);
-static void bsplineEndAnchorOn(SPPenContext *const pc);
-static void bsplineEndAnchorOff(SPPenContext *const pc);
-//Unimos todas las curvas en juego y llamamos a la función doEffect.
-static void bspline_build(SPPenContext *const pc);
+static void bspline_spiro_build(SPPenContext *const pc);
//function bspline cloned from lpe-bspline.cpp
static void bspline_doEffect(SPCurve * curve);
+//function spiro cloned from lpe-spiro.cpp
+static void spiro_doEffect(SPCurve * curve);
//BSpline end
@@ -472,9 +459,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
Geom::Point event_dt(desktop->w2d(event_w));
SPEventContext *event_context = SP_EVENT_CONTEXT(pc);
//Test whether we hit any anchor.
- //Anchor changed from Const because need to update pc->ea for BSpline.
- SPDrawAnchor * anchor = spdc_test_inside(pc, event_w);
- //BSpline
+ SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w);
//with this we avoid creating a new point over the existing one
if((pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){
return FALSE;
@@ -545,12 +530,8 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
pc->sa = anchor;
//BSpline
if(anchor){
- if(pc->spiro){
- spiroStartAnchor(pc,(bevent.state & GDK_SHIFT_MASK));
- }
- if(pc->bspline){
- bsplineStartAnchor(pc,(bevent.state & GDK_SHIFT_MASK));
- }
+ if(pc->bspline || pc->spiro)
+ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK));
}
//BSpline End
if (anchor && !sp_pen_context_has_waiting_LPE(pc)) {
@@ -674,7 +655,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
//"spiro_color" lo ejecutamos siempre sea o no spiro
- spiro_color(pc);
+ bspline_spiro_color(pc);
if (pen_within_tolerance) {
if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance) {
return FALSE; // Do not drag if we're within tolerance from origin.
@@ -798,12 +779,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons
}
//BSpline
if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) {
- if(pc->spiro){
- spiroMotion(pc,(mevent.state & GDK_SHIFT_MASK));
- }
- if(pc->bspline){
- bsplineMotion(pc,(mevent.state & GDK_SHIFT_MASK));
- }
+ bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK));
pen_drag_origin_w = event_w;
}
//BSpline End
@@ -852,11 +828,8 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con
pc->sa = anchor;
//BSpline
if (anchor) {
- if(pc->spiro){
- spiroStartAnchor(pc,(revent.state & GDK_SHIFT_MASK));
- }
- if(pc->bspline){
- bsplineStartAnchor(pc,(revent.state & GDK_SHIFT_MASK));
+ if(pc->bspline || pc->spiro){
+ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK));
}
}
//BSpline End
@@ -1042,14 +1015,9 @@ static void pen_redraw_all (SPPenContext *const pc)
//Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm.
//como es un redibujo simplemente no llamamos a la función global
//sino al final de esta
- if(pc->spiro){
- //we redraw spiro
- spiro_build(pc);
- }
- if(pc->bspline){
- //we redraw bspline
- bspline_build(pc);
- }
+
+ //BSpline
+ bspline_spiro_build(pc);
//BSpline End
}
@@ -1432,7 +1400,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
spdc_pen_set_subsequent_point(pc, pt, true);
pen_last_paraxial_dir = !pen_last_paraxial_dir;
//BSpline
- if(pc->spiro || pc->bspline) bspline_build(pc);
+ bspline_spiro_build(pc);
//BSpline End
ret = TRUE;
}
@@ -1506,7 +1474,7 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G
//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro
-static void spiro_color(SPPenContext *const pc)
+static void bspline_spiro_color(SPPenContext *const pc)
{
bool remake_green_bpaths = false;
if(pc->spiro){
@@ -1550,435 +1518,19 @@ static void spiro_color(SPPenContext *const pc)
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->red_bpath), pc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
}
-
-//Unimos todas las curvas en juego y llamamos a la función doEffect.
-
-static void spiro(SPPenContext *const pc, bool shift)
-{
- if(!pc->anchor_statusbar)
- shift?spiroOff(pc):spiroOn(pc);
-
- spiro_build(pc);
-}
-
-static void spiroOn(SPPenContext *const pc){
- if(!pc->red_curve->is_empty()){
- using Geom::X;
- using Geom::Y;
- pc->npoints = 5;
- pc->p[0] = pc->red_curve->first_segment()->initialPoint();
- pc->p[3] = pc->red_curve->first_segment()->finalPoint();
- pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]);
- pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625);
- }
-}
-
-static void spiroOff(SPPenContext *const pc)
-{
- if(!pc->red_curve->is_empty()){
- pc->npoints = 5;
- pc->p[0] = pc->red_curve->first_segment()->initialPoint();
- pc->p[3] = pc->red_curve->first_segment()->finalPoint();
- pc->p[2] = pc->p[3];
- }
-}
-
-static void spiroStartAnchor(SPPenContext *const pc, bool shift)
+static void bspline_spiro(SPPenContext *const pc, bool shift)
{
- if(pc->sa->curve->is_empty())
+ if(!pc->spiro && !pc->bspline)
return;
- if(shift)
- bsplineStartAnchorOff(pc);
- else
- bsplineStartAnchorOn(pc);
-}
-
-static void spiroStartAnchorOn(SPPenContext *const pc)
-{
- using Geom::X;
- using Geom::Y;
- SPCurve *tmpCurve = new SPCurve();
- tmpCurve = pc->sa->curve->copy();
- if(pc->sa->start)
- tmpCurve = tmpCurve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- SPCurve *lastSeg = new SPCurve();
- Geom::Point A = tmpCurve->last_segment()->initialPoint();
- Geom::Point D = tmpCurve->last_segment()->finalPoint();
- Geom::Point C = D + (1./3)*(A - D);
- C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625);
- if(cubic){
- lastSeg->moveto(A);
- lastSeg->curveto((*cubic)[1],C,D);
- }else{
- lastSeg->moveto(A);
- lastSeg->curveto(A,C,D);
- }
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- if (pc->sa->start) {
- tmpCurve = tmpCurve->create_reverse();
- }
- pc->sa->curve->reset();
- pc->sa->curve = tmpCurve;
-}
-
-static void spiroStartAnchorOff(SPPenContext *const pc)
-{
- SPCurve *tmpCurve = new SPCurve();
- tmpCurve = pc->sa->curve->copy();
- if(pc->sa->start)
- tmpCurve = tmpCurve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- if(cubic){
- SPCurve *lastSeg = new SPCurve();
- lastSeg->moveto((*cubic)[0]);
- lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- if (pc->sa->start) {
- tmpCurve = tmpCurve->create_reverse();
- }
- pc->sa->curve->reset();
- pc->sa->curve = tmpCurve;
- }
-
-}
-
-static void spiroMotion(SPPenContext *const pc, bool shift){
- using Geom::X;
- using Geom::Y;
- SPCurve *tmpCurve = new SPCurve();
- if(shift)
- pc->p[2] = pc->p[3];
- else
- pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]);
- pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625);
-
- if(pc->green_curve->is_empty() && !pc->sa){
- pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]);
- }else if(!pc->green_curve->is_empty()){
- tmpCurve = pc->green_curve->copy();
- }else{
- tmpCurve = pc->sa->curve->copy();
- if(pc->sa->start)
- tmpCurve = tmpCurve->create_reverse();
- }
- if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- if(cubic){
- pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] );
- }else{
- pc->p[1] = pc->p[0];
- }
- }
-
- if(pc->anchor_statusbar && !pc->red_curve->is_empty()){
- if(shift)
- bsplineEndAnchorOff(pc);
- else
- bsplineEndAnchorOn(pc);
- }
-
- spiro_build(pc);
-}
-
-static void spiroEndAnchorOn(SPPenContext *const pc)
-{
- using Geom::X;
- using Geom::Y;
- pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]);
- pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625);
- SPCurve *tmpCurve = new SPCurve();
- SPCurve *lastSeg = new SPCurve();
- Geom::Point C(0,0);
- if(!pc->sa || pc->sa->curve->is_empty()){
- tmpCurve = pc->green_curve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- C = tmpCurve->last_segment()->finalPoint() + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]);
- if(cubic){
- lastSeg->moveto((*cubic)[0]);
- lastSeg->curveto((*cubic)[1],C,(*cubic)[3]);
- }else{
- lastSeg->moveto(tmpCurve->last_segment()->initialPoint());
- lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint());
- }
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- tmpCurve = tmpCurve->create_reverse();
- pc->green_curve->reset();
- pc->green_curve = tmpCurve;
- }else{
- tmpCurve = pc->sa->curve->copy();
- if(!pc->sa->start)
- tmpCurve = tmpCurve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- C = tmpCurve->last_segment()->finalPoint() + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]);
- if(cubic){
- lastSeg->moveto((*cubic)[0]);
- lastSeg->curveto((*cubic)[1],C,(*cubic)[3]);
- }else{
- lastSeg->moveto(tmpCurve->last_segment()->initialPoint());
- lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint());
- }
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- if (!pc->sa->start) {
- tmpCurve = tmpCurve->create_reverse();
- }
- pc->sa->curve->reset();
- pc->sa->curve = tmpCurve;
- }
-}
-
-static void spiroEndAnchorOff(SPPenContext *const pc)
-{
- pc->p[2] = pc->p[3];
- SPCurve *tmpCurve = new SPCurve();
- SPCurve *lastSeg = new SPCurve();
- if(!pc->sa || pc->sa->curve->is_empty()){
- tmpCurve = pc->green_curve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- if(cubic){
- lastSeg->moveto((*cubic)[0]);
- lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- tmpCurve = tmpCurve->create_reverse();
- pc->green_curve->reset();
- pc->green_curve = tmpCurve;
- }
- }else{
- tmpCurve = pc->sa->curve->copy();
- if(!pc->sa->start)
- tmpCurve = tmpCurve->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- if(cubic){
- lastSeg->moveto((*cubic)[0]);
- lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
- if( tmpCurve->get_segment_count() == 1){
- tmpCurve = lastSeg;
- }else{
- //we eliminate the last segment
- tmpCurve->backspace();
- //and we add it again with the recreation
- tmpCurve->append_continuous(lastSeg, 0.0625);
- }
- if (!pc->sa->start) {
- tmpCurve = tmpCurve->create_reverse();
- }
- pc->sa->curve->reset();
- pc->sa->curve = tmpCurve;
- }
- }
-}
-
-//Unimos todas las curvas en juego y llamamos a la función doEffect.
-static void spiro_build(SPPenContext *const pc)
-{
- //We create the base curve
- SPCurve *curve = new SPCurve();
- //If we continuate the existing curve we add it at the start
- if(pc->sa && !pc->sa->curve->is_empty()){
- curve = pc->sa->curve->copy();
- if (pc->sa->start) {
- curve = curve->create_reverse();
- }
- }
- //We add also the green curve
- if (!pc->green_curve->is_empty())
- curve->append_continuous(pc->green_curve, 0.0625);
-
- //and the red one
- if (!pc->red_curve->is_empty()){
- pc->red_curve->reset();
- pc->red_curve->moveto(pc->p[0]);
- pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
- curve->append_continuous(pc->red_curve, 0.0625);
- }
-
- if(!curve->is_empty()){
- //cerramos la curva si estan cerca los puntos finales de la curva spiro
- if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){
- curve->closepath_current();
- }
- //TODO: CALL TO CLONED FUNCTION SPIRO::doEffect IN lpe-spiro.cpp
- //For example
- //using namespace Inkscape::LivePathEffect;
- //LivePathEffectObject *lpeobj = static_cast<LivePathEffectObject*> (curve);
- //Effect *spr = static_cast<Effect*> ( new LPEspiro(lpeobj) );
- //spr->doEffect(curve);
- spiro_doEffect(curve);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve);
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
- sp_canvas_item_show(pc->blue_bpath);
- curve->unref();
- sp_canvas_item_show(pc->c1);
- pc->blue_curve->reset();
- SP_CTRL(pc->c1)->moveto(pc->p[0]);
- //We hide the holders that doesn't contribute anything
- sp_canvas_item_hide(pc->cl1);
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->cl0);
- }else{
- //if the curve is empty
- sp_canvas_item_hide(pc->blue_bpath);
- }
-}
-//Spiro function cloned from lpe-spiro.cpp
-static void spiro_doEffect(SPCurve * curve)
-{
- using Geom::X;
- using Geom::Y;
-
- // Make copy of old path as it is changed during processing
- Geom::PathVector const original_pathv = curve->get_pathvector();
- guint len = curve->get_segment_count() + 2;
-
- curve->reset();
- Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len);
- int ip = 0;
-
- for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
- if (path_it->empty())
- continue;
-
- // start of path
- {
- Geom::Point p = path_it->front().pointAt(0);
- path[ip].x = p[X];
- path[ip].y = p[Y];
- path[ip].ty = '{' ; // for closed paths, this is overwritten
- ip++;
- }
-
- // midpoints
- 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();
- }
- }
-
- while ( curve_it2 != curve_endit )
- {
- /* This deals with the node between curve_it1 and curve_it2.
- * Loop to end_default (so without last segment), loop ends when curve_it2 hits the end
- * and then curve_it1 points to end or closing segment */
- Geom::Point p = curve_it1->finalPoint();
- path[ip].x = p[X];
- path[ip].y = p[Y];
-
- // Determine type of spiro node this is, determined by the tangents (angles) of the curves
- // TODO: see if this can be simplified by using /helpers/geom-nodetype.cpp:get_nodetype
- bool this_is_line = is_straight_curve(*curve_it1);
- bool next_is_line = is_straight_curve(*curve_it2);
-
- Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
-
- if ( nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM )
- {
- if (this_is_line && !next_is_line) {
- path[ip].ty = ']';
- } else if (next_is_line && !this_is_line) {
- path[ip].ty = '[';
- } else {
- path[ip].ty = 'c';
- }
- } else {
- path[ip].ty = 'v';
- }
-
- ++curve_it1;
- ++curve_it2;
- ip++;
- }
-
- // add last point to the spiropath
- Geom::Point p = curve_it1->finalPoint();
- path[ip].x = p[X];
- path[ip].y = p[Y];
- if (path_it->closed()) {
- // curve_it1 points to the (visually) closing segment. determine the match between first and this last segment (the closing node)
- Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front());
- switch (nodetype) {
- case Geom::NODE_NONE: // can't happen! but if it does, it means the path isn't closed :-)
- path[ip].ty = '}';
- ip++;
- break;
- case Geom::NODE_CUSP:
- path[0].ty = path[ip].ty = 'v';
- break;
- case Geom::NODE_SMOOTH:
- case Geom::NODE_SYMM:
- path[0].ty = path[ip].ty = 'c';
- break;
- }
- } else {
- // set type to path closer
- path[ip].ty = '}';
- ip++;
- }
-
- // run subpath through spiro
- int sp_len = ip;
- Spiro::spiro_run(path, sp_len, *curve);
- ip = 0;
- }
-
- g_free (path);
-}
-
-//Unimos todas las curvas en juego y llamamos a la función doEffect.
-
-static void bspline(SPPenContext *const pc, bool shift)
-{
if(!pc->anchor_statusbar)
- shift?bsplineOff(pc):bsplineOn(pc);
+ shift?bspline_spiro_off(pc):bspline_spiro_on(pc);
- bspline_build(pc);
+ bspline_spiro_build(pc);
}
-static void bsplineOn(SPPenContext *const pc){
+static void bspline_spiro_on(SPPenContext *const pc)
+{
if(!pc->red_curve->is_empty()){
using Geom::X;
using Geom::Y;
@@ -1990,7 +1542,7 @@ static void bsplineOn(SPPenContext *const pc){
}
}
-static void bsplineOff(SPPenContext *const pc)
+static void bspline_spiro_off(SPPenContext *const pc)
{
if(!pc->red_curve->is_empty()){
pc->npoints = 5;
@@ -2000,18 +1552,21 @@ static void bsplineOff(SPPenContext *const pc)
}
}
-static void bsplineStartAnchor(SPPenContext *const pc, bool shift)
+static void bspline_spiro_start_anchor(SPPenContext *const pc, bool shift)
{
+ if(!pc->spiro && !pc->bspline)
+ return;
+
if(pc->sa->curve->is_empty())
return;
if(shift)
- bsplineStartAnchorOff(pc);
+ bspline_spiro_start_anchor_off(pc);
else
- bsplineStartAnchorOn(pc);
+ bspline_spiro_start_anchor_on(pc);
}
-static void bsplineStartAnchorOn(SPPenContext *const pc)
+static void bspline_spiro_start_anchor_on(SPPenContext *const pc)
{
using Geom::X;
using Geom::Y;
@@ -2047,7 +1602,7 @@ static void bsplineStartAnchorOn(SPPenContext *const pc)
pc->sa->curve = tmpCurve;
}
-static void bsplineStartAnchorOff(SPPenContext *const pc)
+static void bspline_spiro_start_anchor_off(SPPenContext *const pc)
{
SPCurve *tmpCurve = new SPCurve();
tmpCurve = pc->sa->curve->copy();
@@ -2075,7 +1630,10 @@ static void bsplineStartAnchorOff(SPPenContext *const pc)
}
-static void bsplineMotion(SPPenContext *const pc, bool shift){
+static void bspline_spiro_motion(SPPenContext *const pc, bool shift){
+ if(!pc->spiro && !pc->bspline)
+ return;
+
using Geom::X;
using Geom::Y;
SPCurve *tmpCurve = new SPCurve();
@@ -2097,18 +1655,22 @@ static void bsplineMotion(SPPenContext *const pc, bool shift){
if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
if(cubic){
- SPCurve * WPower = new SPCurve();
- Geom::D2< Geom::SBasis > SBasisWPower;
- WPower->moveto(tmpCurve->last_segment()->finalPoint());
- WPower->lineto(tmpCurve->last_segment()->initialPoint());
- float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment());
- WPower->reset();
- WPower->moveto(pc->red_curve->last_segment()->initialPoint());
- WPower->lineto(pc->red_curve->last_segment()->finalPoint());
- SBasisWPower = WPower->first_segment()->toSBasis();
- WPower->reset();
- pc->p[1] = SBasisWPower.valueAt(WP);
- pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625);
+ if(pc->bspline){
+ SPCurve * WPower = new SPCurve();
+ Geom::D2< Geom::SBasis > SBasisWPower;
+ WPower->moveto(tmpCurve->last_segment()->finalPoint());
+ WPower->lineto(tmpCurve->last_segment()->initialPoint());
+ float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment());
+ WPower->reset();
+ WPower->moveto(pc->red_curve->last_segment()->initialPoint());
+ WPower->lineto(pc->red_curve->last_segment()->finalPoint());
+ SBasisWPower = WPower->first_segment()->toSBasis();
+ WPower->reset();
+ pc->p[1] = SBasisWPower.valueAt(WP);
+ pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625);
+ }else{
+ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] );
+ }
}else{
pc->p[1] = pc->p[0];
}
@@ -2116,16 +1678,17 @@ static void bsplineMotion(SPPenContext *const pc, bool shift){
if(pc->anchor_statusbar && !pc->red_curve->is_empty()){
if(shift)
- bsplineEndAnchorOff(pc);
+ bspline_spiro_end_anchor_off(pc);
else
- bsplineEndAnchorOn(pc);
+ bspline_spiro_end_anchor_on(pc);
}
- bspline_build(pc);
+ bspline_spiro_build(pc);
}
-static void bsplineEndAnchorOn(SPPenContext *const pc)
+static void bspline_spiro_end_anchor_on(SPPenContext *const pc)
{
+
using Geom::X;
using Geom::Y;
pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]);
@@ -2136,8 +1699,12 @@ static void bsplineEndAnchorOn(SPPenContext *const pc)
if(!pc->sa || pc->sa->curve->is_empty()){
tmpCurve = pc->green_curve->create_reverse();
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint());
- C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625);
+ if(pc->bspline){
+ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint());
+ C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625);
+ }else{
+ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] );
+ }
if(cubic){
lastSeg->moveto((*cubic)[0]);
lastSeg->curveto((*cubic)[1],C,(*cubic)[3]);
@@ -2161,8 +1728,12 @@ static void bsplineEndAnchorOn(SPPenContext *const pc)
if(!pc->sa->start)
tmpCurve = tmpCurve->create_reverse();
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmpCurve->last_segment());
- C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint());
- C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625);
+ if(pc->bspline){
+ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint());
+ C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625);
+ }else{
+ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] );
+ }
if(cubic){
lastSeg->moveto((*cubic)[0]);
lastSeg->curveto((*cubic)[1],C,(*cubic)[3]);
@@ -2186,8 +1757,9 @@ static void bsplineEndAnchorOn(SPPenContext *const pc)
}
}
-static void bsplineEndAnchorOff(SPPenContext *const pc)
+static void bspline_spiro_end_anchor_off(SPPenContext *const pc)
{
+
pc->p[2] = pc->p[3];
SPCurve *tmpCurve = new SPCurve();
SPCurve *lastSeg = new SPCurve();
@@ -2236,8 +1808,11 @@ static void bsplineEndAnchorOff(SPPenContext *const pc)
//preparates the curves for its trasformation into BSline curves.
-static void bspline_build(SPPenContext *const pc)
+static void bspline_spiro_build(SPPenContext *const pc)
{
+ if(!pc->spiro && !pc->bspline)
+ return;
+
//We create the base curve
SPCurve *curve = new SPCurve();
//If we continuate the existing curve we add it at the start
@@ -2271,7 +1846,10 @@ static void bspline_build(SPPenContext *const pc)
//LivePathEffectObject *lpeobj = static_cast<LivePathEffectObject*> (curve);
//Effect *spr = static_cast<Effect*> ( new LPEbspline(lpeobj) );
//spr->doEffect(curve);
- bspline_doEffect(curve);
+ if(pc->bspline)
+ bspline_doEffect(curve);
+ else
+ spiro_doEffect(curve);
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve);
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
sp_canvas_item_show(pc->blue_bpath);
@@ -2311,7 +1889,6 @@ static void bspline_doEffect(SPCurve * curve)
//Esto hace que la curva BSpline no pierda su condición aunque se trasladen
//dichos manejadores
SPCurve *nCurve = new SPCurve();
- Geom::Point startNode(0,0);
Geom::Point previousNode(0,0);
Geom::Point node(0,0);
Geom::Point pointAt1(0,0);
@@ -2323,63 +1900,19 @@ static void bspline_doEffect(SPCurve * curve)
Geom::D2< Geom::SBasis > SBasisOut;
Geom::D2< Geom::SBasis > SBasisHelper;
Geom::CubicBezier const *cubic = NULL;
- //Si la curva está cerrada calculamos el punto donde
- //deveria estar el nodo BSpline de cierre/inicio de la curva
- //en posible caso de que se cierre con una linea recta creando un nodo BSPline
-
if (path_it->closed()) {
- //Calculamos el nodo de inicio BSpline
- const Geom::Curve &closingline = path_it->back_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();
}
-
- SPCurve * in = new SPCurve();
- in->moveto(curve_it1->initialPoint());
- in->lineto(curve_it1->finalPoint());
- SBasisIn = in->first_segment()->toSBasis();
-
- SPCurve *lineHelper = new SPCurve();
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if(cubic){
- lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())));
- }else{
- lineHelper->moveto(in->first_segment()->initialPoint());
- }
- in->reset();
- delete in;
-
- SPCurve * end = new SPCurve();
- end->moveto(curve_endit->initialPoint());
- end->lineto(curve_endit->finalPoint());
- Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
- //Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_endit);
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_endit);
- if(cubic){
- lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
- }else{
- lineHelper->lineto(end->first_segment()->finalPoint());
- }
- end->reset();
- delete end;
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- //Guardamos el principio de la curva
- startNode = SBasisHelper.valueAt(0.5);
- //Definimos el punto de inicio original de la curva resultante
- node = startNode;
- }else{
- //Guardamos el principio de la curva
- SPCurve * in = new SPCurve();
- in->moveto(curve_it1->initialPoint());
- in->lineto(curve_it1->finalPoint());
- startNode = in->first_segment()->initialPoint();
- in->reset();
- delete in;
- //Definimos el punto de inicio original de la curva resultante
- node = startNode;
}
+ //Si la curva está cerrada calculamos el punto donde
+ //deveria estar el nodo BSpline de cierre/inicio de la curva
+ //en posible caso de que se cierre con una linea recta creando un nodo BSPline
+
//Recorremos todos los segmentos menos el último
while ( curve_it2 != curve_endit )
{
@@ -2448,13 +1981,54 @@ static void bspline_doEffect(SPCurve * curve)
curveHelper->moveto(node);
//Si está cerrada la curva, la cerramos sobre el valor guardado previamente
//Si no finalizamos en el punto final
+ Geom::Point startNode(0,0);
if (path_it->closed()) {
+ SPCurve * start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ Geom::D2< Geom::SBasis > SBasisStart = start->first_segment()->toSBasis();
+ SPCurve *lineHelper = new SPCurve();
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*path_it->begin());
+ if(cubic){
+ lineHelper->moveto(SBasisStart.valueAt(Geom::nearest_point((*cubic)[1],*start->first_segment())));
+ }else{
+ lineHelper->moveto(start->first_segment()->initialPoint());
+ }
+ start->reset();
+ delete start;
+
+ SPCurve * end = new SPCurve();
+ end->moveto(curve_it1->initialPoint());
+ end->lineto(curve_it1->finalPoint());
+ Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
+ //Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_endit);
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
+ }else{
+ lineHelper->lineto(end->first_segment()->finalPoint());
+ }
+ end->reset();
+ delete end;
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ //Guardamos el principio de la curva
+ startNode = SBasisHelper.valueAt(0.5);
curveHelper->curveto(nextPointAt1, nextPointAt2, startNode);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,startNode);
}else{
+ SPCurve * start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ startNode = start->first_segment()->initialPoint();
+ start->reset();
+ delete start;
curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,nextPointAt3);
}
- //añadimos este último segmento
- nCurve->append_continuous(curveHelper, 0.0625);
curveHelper->reset();
delete curveHelper;
//y cerramos la curva
@@ -2466,6 +2040,118 @@ static void bspline_doEffect(SPCurve * curve)
delete nCurve;
}
}
+
+//Spiro function cloned from lpe-spiro.cpp
+static void spiro_doEffect(SPCurve * curve)
+{
+ using Geom::X;
+ using Geom::Y;
+
+ // Make copy of old path as it is changed during processing
+ Geom::PathVector const original_pathv = curve->get_pathvector();
+ guint len = curve->get_segment_count() + 2;
+
+ curve->reset();
+ Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len);
+ int ip = 0;
+
+ for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
+ if (path_it->empty())
+ continue;
+
+ // start of path
+ {
+ Geom::Point p = path_it->front().pointAt(0);
+ path[ip].x = p[X];
+ path[ip].y = p[Y];
+ path[ip].ty = '{' ; // for closed paths, this is overwritten
+ ip++;
+ }
+
+ // midpoints
+ 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();
+ }
+ }
+
+ while ( curve_it2 != curve_endit )
+ {
+ /* This deals with the node between curve_it1 and curve_it2.
+ * Loop to end_default (so without last segment), loop ends when curve_it2 hits the end
+ * and then curve_it1 points to end or closing segment */
+ Geom::Point p = curve_it1->finalPoint();
+ path[ip].x = p[X];
+ path[ip].y = p[Y];
+
+ // Determine type of spiro node this is, determined by the tangents (angles) of the curves
+ // TODO: see if this can be simplified by using /helpers/geom-nodetype.cpp:get_nodetype
+ bool this_is_line = is_straight_curve(*curve_it1);
+ bool next_is_line = is_straight_curve(*curve_it2);
+
+ Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
+
+ if ( nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM )
+ {
+ if (this_is_line && !next_is_line) {
+ path[ip].ty = ']';
+ } else if (next_is_line && !this_is_line) {
+ path[ip].ty = '[';
+ } else {
+ path[ip].ty = 'c';
+ }
+ } else {
+ path[ip].ty = 'v';
+ }
+
+ ++curve_it1;
+ ++curve_it2;
+ ip++;
+ }
+
+ // add last point to the spiropath
+ Geom::Point p = curve_it1->finalPoint();
+ path[ip].x = p[X];
+ path[ip].y = p[Y];
+ if (path_it->closed()) {
+ // curve_it1 points to the (visually) closing segment. determine the match between first and this last segment (the closing node)
+ Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front());
+ switch (nodetype) {
+ case Geom::NODE_NONE: // can't happen! but if it does, it means the path isn't closed :-)
+ path[ip].ty = '}';
+ ip++;
+ break;
+ case Geom::NODE_CUSP:
+ path[0].ty = path[ip].ty = 'v';
+ break;
+ case Geom::NODE_SMOOTH:
+ case Geom::NODE_SYMM:
+ path[0].ty = path[ip].ty = 'c';
+ break;
+ }
+ } else {
+ // set type to path closer
+ path[ip].ty = '}';
+ ip++;
+ }
+
+ // run subpath through spiro
+ int sp_len = ip;
+ Spiro::spiro_run(path, sp_len, *curve);
+ ip = 0;
+ }
+
+ g_free (path);
+}
+
//BSpline end
static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status)
@@ -2569,12 +2255,7 @@ static void spdc_pen_finish_segment(SPPenContext *const pc, Geom::Point const p,
++pc->num_clicks;
if (!pc->red_curve->is_empty()) {
- if(pc->spiro){
- spiro(pc,(state & GDK_SHIFT_MASK));
- }
- if(pc->bspline){
- bspline(pc,(state & GDK_SHIFT_MASK));
- }
+ bspline_spiro(pc,(state & GDK_SHIFT_MASK));
pc->green_curve->append_continuous(pc->red_curve, 0.0625);
SPCurve *curve = pc->red_curve->copy();
/// \todo fixme:
diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp
index 7445b0b75..48596cbc0 100644
--- a/src/sp-guide.cpp
+++ b/src/sp-guide.cpp
@@ -280,10 +280,10 @@ sp_guide_create_guides_around_page(SPDesktop *dt) {
Geom::Point B(C[Geom::X], 0);
Geom::Point D(0, C[Geom::Y]);
- pts.push_back(std::make_pair<Geom::Point, Geom::Point>(A, B));
- pts.push_back(std::make_pair<Geom::Point, Geom::Point>(B, C));
- pts.push_back(std::make_pair<Geom::Point, Geom::Point>(C, D));
- pts.push_back(std::make_pair<Geom::Point, Geom::Point>(D, A));
+ pts.push_back(std::pair<Geom::Point, Geom::Point>(A, B));
+ pts.push_back(std::pair<Geom::Point, Geom::Point>(B, C));
+ pts.push_back(std::pair<Geom::Point, Geom::Point>(C, D));
+ pts.push_back(std::pair<Geom::Point, Geom::Point>(D, A));
sp_guide_pt_pairs_to_guides(doc, pts);
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 7dc94c92f..fd368ed9f 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -20,6 +20,11 @@
#include "dialog-manager.h"
#include <gtkmm/imagemenuitem.h>
+
+#if GTK_CHECK_VERSION(3,0,0)
+# include <gdkmm/devicemanager.h>
+#endif
+
#include "ui/widget/spinbutton.h"
#include <glibmm/i18n.h>
@@ -1784,7 +1789,15 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtr<Cair
// Check mouse state
int mx, my;
Gdk::ModifierType mask;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ Glib::RefPtr<Gdk::Display> display = get_bin_window()->get_display();
+ Glib::RefPtr<Gdk::DeviceManager> dm = display->get_device_manager();
+ Glib::RefPtr<const Gdk::Device> device = dm->get_client_pointer();
+ get_bin_window()->get_device_position(device, mx, my, mask);
+#else
get_bin_window()->get_pointer(mx, my, mask);
+#endif
// Outline the bottom of the connection area
const int outline_x = x + fheight * (row_count - row_index);
diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp
index eec904ee4..be44794d0 100644
--- a/src/ui/dialog/glyphs.cpp
+++ b/src/ui/dialog/glyphs.cpp
@@ -1,6 +1,7 @@
/* Authors:
* Jon A. Cruz
* Abhishek Sharma
+ * Tavmjong Bah
*
* Copyright (C) 2010 Jon A. Cruz
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -343,7 +344,8 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
GtkWidget *fontsel = sp_font_selector_new();
fsel = SP_FONT_SELECTOR(fontsel);
- sp_font_selector_set_font(fsel, sp_font_selector_get_font(fsel), 12.0);
+ sp_font_selector_set_fontspec( fsel, sp_font_selector_get_fontspec(fsel), 12.0 );
+
gtk_widget_set_size_request (fontsel, 0, 150);
g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this );
@@ -520,6 +522,7 @@ void GlyphsPanel::setTargetDesktop(SPDesktop *desktop)
}
}
+// Append selected glyphs to selected text
void GlyphsPanel::insertText()
{
SPItem *textItem = 0;
@@ -611,7 +614,7 @@ void GlyphsPanel::glyphSelectionChanged()
calcCanInsert();
}
-void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, font_instance * /*font*/, GlyphsPanel *self)
+void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, Glib::ustring /*fontspec*/, GlyphsPanel *self)
{
if (self) {
self->rebuild();
@@ -667,7 +670,13 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ )
void GlyphsPanel::rebuild()
{
- font_instance *font = fsel ? sp_font_selector_get_font(fsel) : 0;
+ Glib::ustring fontspec = fsel ? sp_font_selector_get_fontspec(fsel) : "";
+
+ font_instance* font = 0;
+ if( !fontspec.empty() ) {
+ font = font_factory::Default()->FaceFromFontSpecification( fontspec.c_str() );
+ }
+
if (font) {
//double sp_font_selector_get_size (SPFontSelector *fsel);
diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h
index 162c7b296..6571af0a4 100644
--- a/src/ui/dialog/glyphs.h
+++ b/src/ui/dialog/glyphs.h
@@ -54,7 +54,7 @@ private:
static GlyphColumns *getColumns();
- static void fontChangeCB(SPFontSelector *fontsel, font_instance *font, GlyphsPanel *self);
+ static void fontChangeCB(SPFontSelector *fontsel, Glib::ustring fontspec, GlyphsPanel *self);
void rebuild();
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 97cd28cdd..a71227861 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -8,8 +8,9 @@
* Johan Engelen <goejendaagh@zonnet.nl>
* Abhishek Sharma
* John Smith
+ * Tavmjong Bah
*
- * Copyright (C) 1999-2012 Authors
+ * Copyright (C) 1999-2013 Authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -32,6 +33,7 @@ extern "C" {
#include <gtkmm/stock.h>
#include <libnrtype/font-instance.h>
#include <libnrtype/font-style-to-pos.h>
+#include <libnrtype/font-lister.h>
#include <xml/repr.h>
#include "macros.h"
@@ -305,18 +307,20 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
// FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists
- // Get a font_instance using the font-specification attribute stored in SPStyle if available
- font_instance *font = font_factory::Default()->FaceFromStyle(query);
+ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
- if (font) {
+ // 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();
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- sp_font_selector_set_font (fsel, font, sp_style_css_size_px_to_units(query->font_size.computed, unit) );
- setPreviewText(font, phrase);
- font->Unref();
- font=NULL;
- }
+ Glib::ustring fontspec = fontlister->get_fontspec();
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
+ double size = sp_style_css_size_px_to_units(query->font_size.computed, unit);
+ sp_font_selector_set_fontspec(fsel, fontspec, size );
+
+ setPreviewText (fontspec, phrase);
if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) {
if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) {
@@ -351,30 +355,31 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
blocked = false;
}
-void TextEdit::setPreviewText (font_instance *font, Glib::ustring phrase)
+
+void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
{
- if (!font) {
+ if (font_spec.empty()) {
return;
}
- char *desc = pango_font_description_to_string(font->descr);
+ Glib::ustring phrase_escaped = Glib::Markup::escape_text( phrase );
+
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * PT_PER_PX;
- gchar *const phrase_escaped = g_markup_escape_text(phrase.c_str(), -1);
-
// Pango font size is in 1024ths of a point
- gchar *markup = g_strdup_printf("<span font=\"%s\" size=\"%d\">%s</span>",
- desc, (int) (pt_size * PANGO_SCALE ), phrase_escaped);
+ // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE );
+ std::ostringstream size_st;
+ size_st << pt_size * PANGO_SCALE;
- preview_label.set_markup(markup);
+ Glib::ustring markup = "<span font=\"" + font_spec +
+ "\" size=\"" + size_st.str() + "\">" + phrase_escaped + "</span>";
- g_free(desc);
- g_free(phrase_escaped);
- g_free(markup);
+ preview_label.set_markup(markup.c_str());
}
+
SPItem *TextEdit::getSelectedTextItem (void)
{
if (!SP_ACTIVE_DESKTOP)
@@ -430,34 +435,18 @@ void TextEdit::updateObjectText ( SPItem *text )
}
}
-SPCSSAttr *TextEdit::getTextStyle ()
+SPCSSAttr *TextEdit::fillTextStyle ()
{
SPCSSAttr *css = sp_repr_css_attr_new ();
- // font
- font_instance *font = sp_font_selector_get_font (fsel);
-
- if ( font ) {
- Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font);
- sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str());
-
- gchar c[256];
-
- font->Family(c, 256);
- sp_repr_css_set_property (css, "font-family", c);
-
- font->Attribute( "weight", c, 256);
- sp_repr_css_set_property (css, "font-weight", c);
+ Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
- font->Attribute("style", c, 256);
- sp_repr_css_set_property (css, "font-style", c);
+ if( !fontspec.empty() ) {
- font->Attribute("stretch", c, 256);
- sp_repr_css_set_property (css, "font-stretch", c);
-
- font->Attribute("variant", c, 256);
- sp_repr_css_set_property (css, "font-variant", c);
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->fill_css( css, fontspec );
+ // TODO, possibly move this to FontLister::set_css to be shared.
Inkscape::CSSOStringStream os;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
@@ -467,9 +456,6 @@ SPCSSAttr *TextEdit::getTextStyle ()
os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit);
}
sp_repr_css_set_property (css, "font-size", os.str().c_str());
-
- font->Unref();
- font=NULL;
}
// Layout
@@ -505,7 +491,7 @@ SPCSSAttr *TextEdit::getTextStyle ()
void TextEdit::onSetDefault()
{
- SPCSSAttr *css = getTextStyle ();
+ SPCSSAttr *css = fillTextStyle ();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
blocked = true;
@@ -525,7 +511,7 @@ void TextEdit::onApply()
unsigned items = 0;
const GSList *item_list = sp_desktop_selection(desktop)->itemList();
- SPCSSAttr *css = getTextStyle ();
+ SPCSSAttr *css = fillTextStyle ();
sp_desktop_set_style(desktop, css, true);
for (; item_list != NULL; item_list = item_list->next) {
@@ -556,6 +542,13 @@ void TextEdit::onApply()
}
}
+ // Update FontLister
+ Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
+ if( !fontspec.empty() ) {
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->set_fontspec( fontspec, false );
+ }
+
// complete the transaction
DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
_("Set text style"));
@@ -577,11 +570,11 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self)
GtkTextIter end;
gtk_text_buffer_get_bounds (text_buffer, &start, &end);
gchar *str = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE);
- font_instance *font = sp_font_selector_get_font(self->fsel);
+ Glib::ustring fontspec = sp_font_selector_get_fontspec(self->fsel);
- if (font) {
+ if( !fontspec.empty() ) {
const gchar *phrase = str && *str ? str : self->samplephrase.c_str();
- self->setPreviewText(font, phrase);
+ self->setPreviewText(fontspec, phrase);
} else {
self->preview_label.set_markup("");
}
@@ -594,7 +587,7 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self)
self->setasdefault_button.set_sensitive ( true);
}
-void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, TextEdit *self)
+void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextEdit *self)
{
GtkTextIter start, end;
gchar *str;
@@ -607,9 +600,9 @@ void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font,
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
str = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE);
- if (font) {
+ if (fontspec) {
const gchar *phrase = str && *str ? str : self->samplephrase.c_str();
- self->setPreviewText(font, phrase);
+ self->setPreviewText(fontspec, phrase);
} else {
self->preview_label.set_markup("");
}
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index bca6cee90..3fdeea05d 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -7,8 +7,9 @@
* Johan Engelen <goejendaagh@zonnet.nl>
* John Smith
* Kris De Gussem <Kris.DeGussem@gmail.com>
+ * Tavmjong Bah
*
- * Copyright (C) 1999-2012 Authors
+ * Copyright (C) 1999-2013 Authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -100,10 +101,10 @@ protected:
* onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label.
*
* @param fontsel pointer to SPFontSelector (currently not used).
- * @param font pointer to the font instance for the text to be previewed
+ * @param fontspec for the text to be previewed.
* @param self pointer to the current instance of the dialog.
*/
- static void onFontChange (SPFontSelector *fontsel, font_instance *font, TextEdit *self);
+ static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self);
/**
* Get the selected text off the main canvas.
@@ -118,15 +119,15 @@ protected:
unsigned getSelectedTextCount (void);
/**
- * Helper function to create markup from a font definition and display in the preview label.
+ * Helper function to create markup from a fontspec and display in the preview label.
*
- * @param font pointer to the font instance for the text to be previewed
+ * @param fontspec for the text to be previewed
* @param phrase text to be shown
*/
- void setPreviewText (font_instance *font, Glib::ustring phrase);
+ void setPreviewText (Glib::ustring font_spec, Glib::ustring phrase);
void updateObjectText ( SPItem *text );
- SPCSSAttr *getTextStyle ();
+ SPCSSAttr *fillTextStyle ();
/**
* Helper function to style radio buttons with icons, tooltips.
diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp
index 59fe25fa1..453ef683f 100644
--- a/src/widgets/font-selector.cpp
+++ b/src/widgets/font-selector.cpp
@@ -8,10 +8,11 @@
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ * Tavmjong Bah <tavmjong@free.fr>
*
* Copyright (C) 1999-2001 Ximian, Inc.
* Copyright (C) 2002 Lauris Kaplinski
- * Copyright (C) -2007 Authors
+ * Copyright (C) -2013 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -53,7 +54,7 @@ struct SPFontSelector
NRStyleList styles;
gfloat fontsize;
bool fontsize_dirty;
- font_instance *font;
+ Glib::ustring *fontspec;
};
@@ -61,7 +62,7 @@ struct SPFontSelectorClass
{
GtkHBoxClass parent_class;
- void (* font_set) (SPFontSelector *fsel, font_instance *font);
+ void (* font_set) (SPFontSelector *fsel, gchar *fontspec);
};
enum {
@@ -136,6 +137,9 @@ static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel)
}
+/*
+ * Create a widget with children for selecting font-family, font-style, and font-size.
+ */
static void sp_font_selector_init(SPFontSelector *fsel)
{
gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE);
@@ -153,8 +157,6 @@ static void sp_font_selector_init(SPFontSelector *fsel)
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
gtk_container_add(GTK_CONTAINER(f), sw);
- Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
-
fsel->family_treeview = gtk_tree_view_new ();
GtkTreeViewColumn *column = gtk_tree_view_column_new ();
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
@@ -175,6 +177,7 @@ static void sp_font_selector_init(SPFontSelector *fsel)
"widget \"*font_selector_family\" style \"fontfamily-separator-style\"");
+ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list();
gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store)));
gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview);
@@ -229,6 +232,7 @@ static void sp_font_selector_init(SPFontSelector *fsel)
gtk_widget_show(hb);
gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0);
+ // Font-size
fsel->size = gtk_combo_box_text_new_with_entry ();
sp_font_selector_set_size_tooltip(fsel);
@@ -244,18 +248,20 @@ static void sp_font_selector_init(SPFontSelector *fsel)
gtk_widget_show_all (fsel->size);
+ // Set default size... next two lines must match
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(fsel->size))), "18.0");
fsel->fontsize = 18.0;
fsel->fontsize_dirty = false;
- fsel->font = NULL;
+
+ fsel->fontspec = new Glib::ustring;
}
static void sp_font_selector_dispose(GObject *object)
{
SPFontSelector *fsel = SP_FONT_SELECTOR (object);
- if (fsel->font) {
- fsel->font->Unref();
- fsel->font = NULL;
+ if (fsel->fontspec) {
+ delete fsel->fontspec;
}
if (fsel->families.length > 0) {
@@ -273,46 +279,62 @@ static void sp_font_selector_dispose(GObject *object)
}
}
+// Callback when family changed, updates style list for new family.
static void sp_font_selector_family_select_row(GtkTreeSelection *selection,
SPFontSelector *fsel)
{
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkListStore *store;
- GtkTreePath *path;
- GList *list=0;
+ // We need our own copy of the style list store since the font-family
+ // may not be the same in the font-selector as stored in the font-lister
+ // TODO: use font-lister class for this by modifying new_font_family to accept an optional style list
+ // TODO: add store to SPFontSelector struct and reuse.
+
+ // Start by getting iterator to selected font
+ GtkTreeModel *model;
+ GtkTreeIter iter;
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return;
- path = gtk_tree_model_get_path (model, &iter);
- gtk_tree_model_get (model, &iter, 1, &list, -1);
+ // Next get family name with its style list
+ gchar *family;
+ GList *list=0;
+ gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1);
- store = gtk_list_store_new (1, G_TYPE_STRING);
+ // 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);
+ // Create our own store of styles for selected font-family and find index of best style match
+ int path_index = 0;
+ int index = 0;
+ GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted?
for ( ; list ; list = list->next )
{
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, static_cast<char*>(list->data), -1);
+ gtk_list_store_set (store, &iter, 0, (char*)list->data, -1);
+
+ if( best.compare( (char*)list->data ) == 0 ) {
+ path_index = index;
+ }
+ ++index;
}
+ // Attach store to tree view. Can trigger style changed signal (but not FONT_SET):
gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store));
- path = gtk_tree_path_new ();
- gtk_tree_path_append_index (path, 0);
+
+ // Get path to best style
+ GtkTreePath *path = gtk_tree_path_new ();
+ gtk_tree_path_append_index (path, path_index);
+
+ // Highlight best style. Triggers style changed signal:
gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path);
gtk_tree_path_free (path);
}
+// Callback when row changed
static void sp_font_selector_style_select_row (GtkTreeSelection *selection,
SPFontSelector *fsel)
{
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return;
-
- path = gtk_tree_model_get_path (model, &iter);
-
if (!fsel->block_emit)
{
sp_font_selector_emit_set (fsel);
@@ -322,6 +344,7 @@ static void sp_font_selector_style_select_row (GtkTreeSelection *selection,
/*
* Set the default list of font sizes, scaled to the users preferred unit
+ * TODO: This routine occurs both here and in text-toolbar. Move to font-lister?
*/
static void sp_font_selector_set_sizes( SPFontSelector *fsel )
{
@@ -348,6 +371,7 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel )
}
+// Callback when size changed
static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel )
{
char *text = NULL;
@@ -381,9 +405,13 @@ static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector
sp_font_selector_emit_set (fsel);
}
+
+// Called from sp_font_selector_style_select_row
+// Called from sp_font_selector_size_changed
+// Called indirectly for sp_font_selector_family_select_row (since style changes).
+// Emits FONT_SET signal (handled by TextEdit::onFontChange, GlyphsPanel::fontChangeCB).
static void sp_font_selector_emit_set (SPFontSelector *fsel)
{
- font_instance *font;
GtkTreeSelection *selection_family;
GtkTreeSelection *selection_style;
@@ -398,41 +426,27 @@ static void sp_font_selector_emit_set (SPFontSelector *fsel)
model_family = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->family_treeview));
if (!model_family) return;
- model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview));
- if (!model_style) return;
+ model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview));
+ if (!model_style ) return;
selection_family = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview));
- selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview));
+ selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview ));
if (!gtk_tree_selection_get_selected (selection_family, NULL, &iter_family)) return;
- if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style)) return;
+ if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style )) return;
gtk_tree_model_get (model_family, &iter_family, 0, &family, -1);
- gtk_tree_model_get (model_style, &iter_style, 0, &style, -1);
+ gtk_tree_model_get (model_style, &iter_style, 0, &style, -1);
if ((!family) || (!style)) return;
- font = (font_factory::Default())->FaceFromUIStrings (family, style);
+ Glib::ustring fontspec = family;
+ fontspec += ", ";
+ fontspec += style;
- // FIXME: when a text object uses non-available font, font==NULL and we can't set size
- // (and the size shown in the widget is invalid). To fix, here we must always get some
- // default font, exactly the same as sptext uses for on-canvas display, so that
- // font!=NULL ever.
- if (font != fsel->font || ( font && fsel->fontsize_dirty ) ) {
- if ( font ) {
- font->Ref();
- }
- if ( fsel->font ) {
- fsel->font->Unref();
- }
- fsel->font = font;
- g_signal_emit(fsel, fs_signals[FONT_SET], 0, fsel->font);
- }
- fsel->fontsize_dirty = false;
- if (font) {
- font->Unref();
- }
- font = NULL;
+ *(fsel->fontspec) = fontspec;
+
+ g_signal_emit(fsel, fs_signals[FONT_SET], 0, fontspec.c_str());
}
GtkWidget *sp_font_selector_new()
@@ -442,116 +456,53 @@ GtkWidget *sp_font_selector_new()
return GTK_WIDGET(fsel);
}
+
/*
- * Returns the index of the fonts closest style match from the provided list of styles
- * Used in both the Text dialog and the Text toolbar to set the style combo on selection change
+ * Sets the values displayed in the font-selector from a fontspec.
+ * It is only called from TextEdit with a new selection and from GlyphsPanel
*/
-unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list)
+void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size)
{
- if ( !font || !list) {
- return 0;
- }
-
- font_instance *tempFont = NULL;
- unsigned int currentStyleNumber = 0;
- unsigned int bestStyleNumber = 0;
-
- Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr);
-
- PangoFontDescription *incomingFont = pango_font_description_copy(font->descr);
- pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE);
-
- char *incomingFontString = pango_font_description_to_string(incomingFont);
-
- tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data));
-
- PangoFontDescription *bestMatchForFont = NULL;
- if (tempFont) {
- bestMatchForFont = pango_font_description_copy(tempFont->descr);
- tempFont->Unref();
- tempFont = NULL;
- }
-
- if( bestMatchForFont != NULL ) {
- pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE);
- }
-
- list = list->next;
-
- while (list) {
- currentStyleNumber++;
-
- tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data));
-
- PangoFontDescription *currentMatchForFont = NULL;
- if (tempFont) {
- currentMatchForFont = pango_font_description_copy(tempFont->descr);
- tempFont->Unref();
- tempFont = NULL;
- }
-
- if (currentMatchForFont) {
- pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE);
-
- char *currentMatchString = pango_font_description_to_string(currentMatchForFont);
-
- if (!strcmp(incomingFontString, currentMatchString)
- || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) {
- // Found a better match for the font we are looking for
- pango_font_description_free(bestMatchForFont);
- bestMatchForFont = pango_font_description_copy(currentMatchForFont);
- bestStyleNumber = currentStyleNumber;
- }
-
- g_free(currentMatchString);
-
- pango_font_description_free(currentMatchForFont);
- }
-
- list = list->next;
- }
-
- if (bestMatchForFont)
- pango_font_description_free(bestMatchForFont);
- if (incomingFont)
- pango_font_description_free(incomingFont);
- g_free(incomingFontString);
+ if (!fontspec.empty())
+ {
- return bestStyleNumber;
-}
+ Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance();
+ std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec );
+ Glib::ustring family = ui.first;
+ Glib::ustring style = ui.second;
-void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size)
-{
- if (font)
- {
Gtk::TreePath path;
-
- Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr);
-
try {
- path = Inkscape::FontLister::get_instance()->get_row_for_font (family);
+ path = font_lister->get_row_for_font (family);
} catch (...) {
+ g_warning( "Couldn't find row for font-family: %s", family.c_str() );
return;
}
+ // High light selected family and scroll so it is in view.
fsel->block_emit = TRUE;
gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj());
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5);
- fsel->block_emit = FALSE;
+ fsel->block_emit = FALSE; // TODO: Should this be moved to the end?
- GList *list = 0;
- GtkTreeIter iter;
- GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview));
- gtk_tree_model_get_iter (model, &iter, path.gobj());
- gtk_tree_model_get (model, &iter, 1, &list, -1);
- unsigned int bestStyleNumber = sp_font_selector_get_best_style(font, list);
+ // We don't need to get best style since this is only called on a new
+ // selection where we already know the "best" style.
+ // Glib::ustring bestStyle = font_lister->get_best_style_match (family, style);
+ // std::cout << "Best: " << bestStyle << std::endl;
+
+ // The "trial" style list and the regular list are the same in this case.
+ Gtk::TreePath path_c;
+ try {
+ path_c = font_lister->get_row_for_style( style );
+ } catch (...) {
+ g_warning( "Couldn't find row for style: %s (%s)", style.c_str(), family.c_str() );
+ return;
+ }
+
+ gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c.gobj());
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c.gobj(), NULL, TRUE, 0.5, 0.5);
- GtkTreePath *path_c = gtk_tree_path_new ();
- gtk_tree_path_append_index (path_c, bestStyleNumber);
- gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c);
- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5);
-
if (size != fsel->fontsize)
{
gchar s[8];
@@ -565,13 +516,9 @@ void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, doubl
}
-font_instance* sp_font_selector_get_font(SPFontSelector *fsel)
+Glib::ustring sp_font_selector_get_fontspec(SPFontSelector *fsel)
{
- if (fsel->font) {
- fsel->font->Ref();
- }
-
- return fsel->font;
+ return *(fsel->fontspec);
}
/*
diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h
index 80e8b1e4d..66715f048 100644
--- a/src/widgets/font-selector.h
+++ b/src/widgets/font-selector.h
@@ -7,9 +7,11 @@
* Authors:
* Chris Lahey <clahey@ximian.com>
* Lauris Kaplinski <lauris@kaplinski.com>
+ * Tavmjong Bah <tavmjong@free.fr>
*
* Copyright (C) 1999-2001 Ximian, Inc.
* Copyright (C) 2002 Lauris Kaplinski
+ * Copyright (C) 1999-2013 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -22,7 +24,24 @@ struct SPFontSelector;
#define SP_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_FONT_SELECTOR, SPFontSelector))
#define SP_IS_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_FONT_SELECTOR))
-class font_instance;
+/*
+ * The routines here create and manage a font selector widget with three parts,
+ * one each for font-family, font-style, and font-size.
+ *
+ * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used
+ * to access the list of font-families and their associated styles for fonts either
+ * on the system or in the document. The FontLister class is also used by the Text
+ * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the
+ * strings that Pango generates.
+ *
+ * The main functions are:
+ * Create the font-seletor widget.
+ * Update the lists when a new text selection is made.
+ * Update the Style list when a new font-family is selected, highlighting the
+ * best match to the original font style (as not all fonts have the same style options).
+ * Emit a signal when any change is made so that the Text Preview can be updated.
+ * Provide the currently selected values.
+ */
/* SPFontSelector */
@@ -30,13 +49,11 @@ GType sp_font_selector_get_type (void);
GtkWidget *sp_font_selector_new (void);
-void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size);
+void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size);
+Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel);
-font_instance *sp_font_selector_get_font (SPFontSelector *fsel);
double sp_font_selector_get_size (SPFontSelector *fsel);
-unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list);
-
#endif // SP_FONT_SELECTOR_H
/*
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index cc6d02ea8..ef7d31d76 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -18,8 +18,8 @@
*
* Copyright (C) 2004 David Turner
* Copyright (C) 2003 MenTaLguY
- * Copyright (C) 1999-2013 authors
* Copyright (C) 2001-2002 Ximian, Inc.
+ * Copyright (C) 1999-2013 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -170,7 +170,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb
// active text set in sp_text_toolbox_selection_changed()
SPCSSAttr *css = sp_repr_css_attr_new ();
- fontlister->set_css( css );
+ fontlister->fill_css( css );
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice.
@@ -272,7 +272,7 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj
// active text set in sp_text_toolbox_seletion_changed()
SPCSSAttr *css = sp_repr_css_attr_new ();
- fontlister->set_css( css );
+ fontlister->fill_css( css );
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
sp_desktop_set_style (desktop, css, true, true);