From db0f8faa3ba62d0c60d5a6c5cc0dec479eb79021 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 21 May 2012 15:33:00 +0200 Subject: Change default font to a CSS valid default font (Sans -> sans-serif). (bzr r11393) --- src/libnrtype/FontFactory.cpp | 8 ++++---- src/libnrtype/Layout-TNG-Input.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 63f9bd6b0..8de9d4795 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -929,9 +929,9 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) res = NULL; if ( canFail ) { char *tc = pango_font_description_to_string(descr); - PANGO_DEBUG("falling back from %s to Sans because InstallFace failed\n",tc); + PANGO_DEBUG("falling back from %s to 'sans-serif' because InstallFace failed\n",tc); g_free(tc); - pango_font_description_set_family(descr,"Sans"); + pango_font_description_set_family(descr,"sans-serif"); res = Face(descr,false); } } else { @@ -942,9 +942,9 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } else { // no match if ( canFail ) { - PANGO_DEBUG("falling back to Sans\n"); + PANGO_DEBUG("falling back to 'sans-serif'\n"); descr = pango_font_description_new(); - pango_font_description_set_family(descr,"Sans"); + pango_font_description_set_family(descr,"sans-serif"); res = Face(descr,false); pango_font_description_free(descr); } diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index c5ea3969d..07bf207c8 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -291,7 +291,7 @@ PangoFontDescription *Layout::InputStreamTextSource::styleGetFontDescription() c // pango, so it's not the limiting factor Glib::ustring family; if (style->text->font_family.value == NULL) { - family = "Sans"; + family = "sans-serif"; } else { gchar **families = g_strsplit(style->text->font_family.value, ",", -1); if (families) { -- cgit v1.2.3 From 53fe022959ca3f120d07401366bb2a9e5618f262 Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 4 Jul 2012 09:48:30 +0900 Subject: Fix for 168658 : Font substitution warning dialog (bzr r11522) --- src/libnrtype/Layout-TNG-Output.cpp | 12 ++++++++++++ src/libnrtype/Layout-TNG.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 0ce00e43b..bf6516b42 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -340,6 +340,18 @@ static char const *weight_to_text(PangoWeight w) return "???"; } +Glib::ustring Layout::getFontFamily(unsigned span_index) const +{ + if (span_index < 0 || span_index >= _spans.size()) + return ""; + + if (_spans[span_index].font) { + return pango_font_description_get_family(_spans[span_index].font->descr); + } + + return ""; +} + Glib::ustring Layout::dumpAsText() const { Glib::ustring result; diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 4406d9f93..f4a09f25b 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -353,6 +353,9 @@ public: void showGlyphs(CairoRenderContext *ctx) const; #endif + /** Returns the font family of the indexed span */ + Glib::ustring getFontFamily(unsigned span_index) const; + /** debug and unit test method. Creates a textual representation of the contents of this object. The output is designed to be both human-readable and comprehensible when diffed with a known-good dump. */ -- cgit v1.2.3 From a7ec2e1016abb19f3b67213b060c9532d0ff38b9 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 9 Aug 2012 19:06:15 +0200 Subject: Warnings. Fix for Bug #323414 (strict-aliasing rules warnings). (bzr r11601) --- src/libnrtype/Layout-TNG-Output.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index bf6516b42..4bdd2c6cb 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -342,7 +342,7 @@ static char const *weight_to_text(PangoWeight w) Glib::ustring Layout::getFontFamily(unsigned span_index) const { - if (span_index < 0 || span_index >= _spans.size()) + if (span_index >= _spans.size()) return ""; if (_spans[span_index].font) { @@ -387,11 +387,13 @@ Glib::ustring Layout::dumpAsText() const Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; // very inefficent code. what the hell, it's only debug stuff. for (unsigned char_index = 0 ; char_index < _characters.size() ; char_index++) { + union {const PangoLogAttr* pattr; const unsigned* uattr;} u; + u.pattr = &_characters[char_index].char_attributes; if (_characters[char_index].in_span != span_index) continue; if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) { - snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *(unsigned*) &_characters[char_index].char_attributes, _characters[char_index].in_glyph); + snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); } else { - snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *(unsigned*) &_characters[char_index].char_attributes, _characters[char_index].in_glyph); + snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); iter_char++; } result += line; -- cgit v1.2.3 From 89bb2602a15a830b7e2133307a8ec6a08ebd0f84 Mon Sep 17 00:00:00 2001 From: su_v Date: Sun, 23 Sep 2012 19:19:33 +0200 Subject: Fixes bug #988601: omnibus patch for EMF input/output support (cross-platform) (bzr r11668.1.8) --- src/libnrtype/Layout-TNG-Output.cpp | 58 +++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 4bdd2c6cb..48d18850e 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -20,6 +20,7 @@ #include "extension/internal/cairo-render-context.h" #include "display/curve.h" #include <2geom/pathvector.h> +#include "libunicode-convert/unicode-convert.h" #if !PANGO_VERSION_CHECK(1,24,0) #define PANGO_WEIGHT_THIN static_cast(100) @@ -43,6 +44,27 @@ using Inkscape::Extension::Internal::CairoGlyphInfo; namespace Inkscape { namespace Text { +// the dx array is smuggled through to the EMF (ignored by others) as: +// textN w1 w2 w3 ...wN +// where the widths are floats 7 characters wide, including the space +char *smuggle_adx_in(const char *string, int ndx, int size, float *adx){ + int slen=strlen(string); + // holds: string, fake terminator, Number of offsets, series of offsets, real (double) terminator. + int newsize=slen + 1 + 7 + 7*ndx + 2; + newsize = 8*((7 + newsize)/8); // suppress valgrind messages if it is a multiple of 8 bytes??? + char *smuggle=(char *)calloc(newsize,1); //initialize all bytes, inluding terminators + strcpy(smuggle,string); + char *cptr = smuggle + slen + 1; // immediately after the first terminator + sprintf(cptr,"%07d",ndx); + cptr+=7; + for(int i=0; imodule->textToPath(); + doUTN = CanUTN(); // Unicode to Nonunicode translation enabled if true for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; ) { if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) { // invisible glyphs @@ -180,25 +210,49 @@ void Layout::print(SPPrintContext *ctx, } // try to output as many characters as possible in one go by detecting kerning and stopping when we encounter it + // also break spans at changes in Unicode->nonunicode translations, so that each span + // sent down from here is translated the same way. The translation happens much later + // in the emf-print code. + // Note that the incoming stream has a predefined notion of what is in each "span" and it is not + // entirely clear why. For instance, the string "%%% text %%%%", where % is the Unicode "Sagittarius" + // character has 3 spans, with the first two ending on the spaces. Yet in the XML there is only one tspan. + // Consequently when the Unicode->NonUnicode detection is on the first space will go out by itself, + // because it is at the end of a span, whereas the second space goes with the "text". + Glib::ustring span_string; double char_x = _characters[_glyphs[glyph_index].in_character].x; unsigned this_span_index = _characters[_glyphs[glyph_index].in_character].in_span; + if(doUTN)newtarget=lasttarget=SingleUnicodeToNon(*span_iter); + do { span_string += *span_iter; span_iter++; + if(doUTN)newtarget=SingleUnicodeToNon(*span_iter); unsigned same_character = _glyphs[glyph_index].in_character; while (glyph_index < _glyphs.size() && _glyphs[glyph_index].in_character == same_character) { char_x += _glyphs[glyph_index].width; + if(ndx < MAX_DX){ hold_dx[ndx++] = _glyphs[glyph_index].width; } glyph_index++; } } while (glyph_index < _glyphs.size() && _path_fitted == NULL && _characters[_glyphs[glyph_index].in_character].in_span == this_span_index - && fabs(char_x - _characters[_glyphs[glyph_index].in_character].x) < 1e-4); + && fabs(char_x - _characters[_glyphs[glyph_index].in_character].x) < 1e-4 + && (doUTN ? (lasttarget==newtarget ? 1 : 0) : 1 ) + ); sp_print_bind(ctx, glyph_matrix, 1.0); - sp_print_text(ctx, span_string.c_str(), g_pos, text_source->style); + + // the dx array is smuggled through to the EMF (ignored by others) as: + // textw1 w2 w3 ...wn + // where the widths are floats 7 characters wide, including the space + + char *smuggle_string=smuggle_adx_in(span_string.c_str(),ndx,MAX_DX, &hold_dx[0]); +// sp_print_text(ctx, span_string.c_str(), g_pos, text_source->style); + sp_print_text(ctx, smuggle_string, g_pos, text_source->style); + free(smuggle_string); sp_print_release(ctx); + ndx=0; } } } -- cgit v1.2.3 From 9cd8a52b37ccd640131769e04bbefac21249339d Mon Sep 17 00:00:00 2001 From: David Mathog <> Date: Thu, 27 Sep 2012 08:50:36 +0200 Subject: initial changes to address problem of importing chunks of text into something editable (See also: bug #366744) (bzr r11668.1.17) --- src/libnrtype/Layout-TNG-Output.cpp | 66 +++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 18 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 48d18850e..1d293e360 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -44,24 +44,37 @@ using Inkscape::Extension::Internal::CairoGlyphInfo; namespace Inkscape { namespace Text { -// the dx array is smuggled through to the EMF (ignored by others) as: -// textN w1 w2 w3 ...wN -// where the widths are floats 7 characters wide, including the space -char *smuggle_adx_in(const char *string, int ndx, int size, float *adx){ +/* + dx array (character widths) and + ky (vertical kerning for entire span) + + are smuggled through to the EMF (ignored by others) as: + textN w1 w2 w3 ...wNy1 y2 y3 .. yN + where the widths and y kern values are floats 7 characters wide, including the space +*/ +char *smuggle_adxky_in(const char *string, int ndx, float *adx, float ky){ int slen=strlen(string); - // holds: string, fake terminator, Number of offsets, series of offsets, real (double) terminator. - int newsize=slen + 1 + 7 + 7*ndx + 2; - newsize = 8*((7 + newsize)/8); // suppress valgrind messages if it is a multiple of 8 bytes??? - char *smuggle=(char *)calloc(newsize,1); //initialize all bytes, inluding terminators - strcpy(smuggle,string); - char *cptr = smuggle + slen + 1; // immediately after the first terminator - sprintf(cptr,"%07d",ndx); + /* holds: string + fake terminator (one \0) + Number of widths (ndxy) + series of widths (ndxy entries) + fake terminator (one \0) + y kern value (one float) + real terminator (two \0) + */ + int newsize=slen + 1 + 7 + 7*ndx + 1 + 7 + 2; + newsize = 8*((7 + newsize)/8); // suppress valgrind messages if it is a multiple of 8 bytes??? + char *smuggle=(char *)calloc(newsize,1); // initialize all bytes, inluding terminators + strcpy(smuggle,string); // text to pass + char *cptr = smuggle + slen + 1; // immediately after the first fake terminator + sprintf(cptr,"%07d",ndx); // number of widths to pass cptr+=7; - for(int i=0; iw1 w2 w3 ...wn // where the widths are floats 7 characters wide, including the space - char *smuggle_string=smuggle_adx_in(span_string.c_str(),ndx,MAX_DX, &hold_dx[0]); + char *smuggle_string=smuggle_adxky_in(span_string.c_str(),ndx, &hold_dx[0], ky); // sp_print_text(ctx, span_string.c_str(), g_pos, text_source->style); sp_print_text(ctx, smuggle_string, g_pos, text_source->style); free(smuggle_string); -- cgit v1.2.3 From 8bb515cbaffa18aa2baee841c4ec2269336e39df Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 15 Oct 2012 16:53:47 -0500 Subject: Files in /src that no longer exist (bzr r11804.1.2) --- src/libnrtype/Makefile_insert | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Makefile_insert b/src/libnrtype/Makefile_insert index 7cd99e1a8..0ce8f1fd5 100644 --- a/src/libnrtype/Makefile_insert +++ b/src/libnrtype/Makefile_insert @@ -11,7 +11,6 @@ ink_common_sources += \ libnrtype/nr-type-pos-def.h \ libnrtype/nr-type-primitives.cpp \ libnrtype/nr-type-primitives.h \ - libnrtype/nrtype-forward.h \ libnrtype/FontFactory.cpp \ libnrtype/FontFactory.h \ libnrtype/FontInstance.cpp \ -- cgit v1.2.3 From d463240d8fd961d45b47ba96e0d93c37e1719da7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 21 Nov 2012 09:55:55 +1100 Subject: code cleanup: quiet warnings with gcc. (bzr r11888) --- src/libnrtype/FontFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 8de9d4795..76a3df0e8 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -276,7 +276,7 @@ family_name_compare(char const *a, char const *b) #endif } -void noop(...) {} +static void noop(...) {} //#define PANGO_DEBUG g_print #define PANGO_DEBUG noop @@ -285,7 +285,7 @@ void noop(...) {} ///////////////////// FontFactory #ifndef USE_PANGO_WIN32 // the substitute function to tell fontconfig to enforce outline fonts -void FactorySubstituteFunc(FcPattern *pattern,gpointer /*data*/) +static void FactorySubstituteFunc(FcPattern *pattern,gpointer /*data*/) { FcPatternAddBool(pattern, "FC_OUTLINE",FcTrue); //char *fam = NULL; -- cgit v1.2.3 From 4a76e2728f29933fece00149b2edc86c48f119ae Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 9 Dec 2012 11:35:25 +0000 Subject: Tidy up GTK/Glib deprecation flags and drop ancient pango support (<1.24) Fixed bugs: - https://launchpad.net/bugs/1088134 (bzr r11938) --- src/libnrtype/FontFactory.cpp | 7 ------- src/libnrtype/FontInstance.cpp | 7 ------- src/libnrtype/Layout-TNG-Input.cpp | 6 ------ src/libnrtype/Layout-TNG-Output.cpp | 6 ------ 4 files changed, 26 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 76a3df0e8..ed1e1dc5c 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -22,13 +22,6 @@ #include "libnrtype/font-instance.h" #include "util/unordered-containers.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast(100) -#define PANGO_WEIGHT_BOOK static_cast(380) -#define PANGO_WEIGHT_MEDIUM static_cast(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast(1000) -#endif - typedef INK_UNORDERED_MAP FaceMapType; // need to avoid using the size field diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index f8b2c3b9d..4ca8bf2a0 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -27,13 +27,6 @@ #include "livarot/Path.h" #include "util/unordered-containers.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast(100) -#define PANGO_WEIGHT_BOOK static_cast(380) -#define PANGO_WEIGHT_MEDIUM static_cast(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast(1000) -#endif - struct font_style_hash : public std::unary_function { size_t operator()(font_style const &x) const; diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 07bf207c8..10310b4aa 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -19,12 +19,6 @@ #include "sp-string.h" #include "FontFactory.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast(100) -#define PANGO_WEIGHT_BOOK static_cast(380) -#define PANGO_WEIGHT_MEDIUM static_cast(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast(1000) -#endif namespace Inkscape { namespace Text { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 4bdd2c6cb..bf746b41f 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -21,12 +21,6 @@ #include "display/curve.h" #include <2geom/pathvector.h> -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast(100) -#define PANGO_WEIGHT_BOOK static_cast(380) -#define PANGO_WEIGHT_MEDIUM static_cast(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast(1000) -#endif namespace Inkscape { namespace Extension { -- cgit v1.2.3 From 979914865d4db2debe2f86059f11e4b93a266fb9 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 13 Jan 2013 15:40:39 +0000 Subject: Stop using deprecated pang_ft2 functions Fixed bugs: - https://launchpad.net/bugs/166276 (bzr r12020) --- src/libnrtype/FontFactory.cpp | 12 +++++++++--- src/libnrtype/FontInstance.cpp | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index ed1e1dc5c..98904a47a 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -315,9 +315,15 @@ font_factory::font_factory(void) : { #ifdef USE_PANGO_WIN32 #else - pango_ft2_font_map_set_resolution((PangoFT2FontMap*)fontServer, 72, 72); - fontContext = pango_ft2_font_map_create_context((PangoFT2FontMap*)fontServer); - pango_ft2_font_map_set_default_substitute((PangoFT2FontMap*)fontServer,FactorySubstituteFunc,this,NULL); + pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontServer), + 72, 72); + + fontContext = pango_font_map_create_context(fontServer); + + pango_ft2_font_map_set_default_substitute(PANGO_FT2_FONT_MAP(fontServer), + FactorySubstituteFunc, + this, + NULL); #endif } diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 4ca8bf2a0..f26b157da 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -399,7 +399,7 @@ void font_instance::InitTheFace() SetGraphicsMode(daddy->hScreenDC, GM_COMPATIBLE); SelectObject(daddy->hScreenDC,theFace); #else - theFace=pango_ft2_font_get_face(pFont); // Deprecated, use pango_fc_font_lock_face() instead + theFace=pango_fc_font_lock_face(PANGO_FC_FONT(pFont)); if ( theFace ) { FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol); } @@ -411,6 +411,8 @@ void font_instance::FreeTheFace() #ifdef USE_PANGO_WIN32 SelectObject(daddy->hScreenDC,GetStockObject(SYSTEM_FONT)); pango_win32_font_cache_unload(daddy->pangoFontCache,theFace); +#else + pango_fc_font_unlock_face(PANGO_FC_FONT(pFont)); #endif theFace=NULL; } @@ -454,12 +456,13 @@ int font_instance::MapUnicodeChar(gunichar c) #ifdef USE_PANGO_WIN32 res = pango_win32_font_get_glyph_index(pFont, c); #else - theFace = pango_ft2_font_get_face(pFont); + theFace = pango_fc_font_lock_face(PANGO_FC_FONT(pFont)); if ( c > 0xf0000 ) { res = CLAMP(c, 0xf0000, 0x1fffff) - 0xf0000; } else { res = FT_Get_Char_Index(theFace, c); } + pango_fc_font_unlock_face(PANGO_FC_FONT(pFont)); #endif } return res; -- cgit v1.2.3 From 25d130b355b637193ee24937c7f287acf6dfa7d5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 31 Jan 2013 15:04:28 +0100 Subject: Partial fix for bug 595432 "Clicking Arial Black selects Arial Bold" (bzr r12080) --- src/libnrtype/FontFactory.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 98904a47a..af46d6986 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -454,7 +454,7 @@ Glib::ustring font_factory::ReplaceFontSpecificationFamily(const Glib::ustring & // what constitutes a "family" in our own UI may be different from how Pango // sees it. - // Find the PangoFontDescription associated with the font specification string. + // Find the PangoFontDescription associated with the old font specification string. PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec); @@ -464,15 +464,23 @@ Glib::ustring font_factory::ReplaceFontSpecificationFamily(const Glib::ustring & // Make copy PangoFontDescription *descr = pango_font_description_copy((*it).second); - // Grab the UI Family string from the descr + // Grab the old UI Family string from the descr Glib::ustring uiFamily = GetUIFamilyString(descr); // Replace the UI Family name with the new family name std::size_t found = fontSpec.find(uiFamily); if (found != Glib::ustring::npos) { + + // Add comma to end of newFamily... commas at end don't hurt but are + // required if the last part of a family name is a valid font style + // (e.g. "Arial Black"). + Glib::ustring newFamilyComma = newFamily; + if( *newFamilyComma.rbegin() != ',' ) { + newFamilyComma += ","; + } newFontSpec = fontSpec; newFontSpec.erase(found, uiFamily.size()); - newFontSpec.insert(found, newFamily); + newFontSpec.insert(found, newFamilyComma); // If the new font specification does not exist in the reference maps, // search for the next best match for the faces in that style @@ -716,6 +724,7 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) FamilyToStylesMap::iterator iter = map->find(familyUIName); + // Insert new family if (iter == map->end()) { map->insert(std::make_pair(familyUIName, std::list())); } -- cgit v1.2.3 From baa52078f68c3c07e4e88447b4808d8bb791332b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 31 Jan 2013 17:52:48 +0100 Subject: Partial fix to allow change of style when the font-family is a font list. (bzr r12081) --- src/libnrtype/FontFactory.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index af46d6986..2cf4b8673 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -824,7 +824,12 @@ font_instance* font_factory::FaceFromUIStrings(char const *uiFamily, char const g_assert(uiFamily && uiStyle); if (uiFamily && uiStyle) { - Glib::ustring uiString = Glib::ustring(uiFamily) + Glib::ustring(uiStyle); + + // If font list, take only first font in list + gchar** tokens = g_strsplit( uiFamily, ",", 0 ); + g_strstrip( tokens[0] ); + + Glib::ustring uiString = Glib::ustring(tokens[0]) + Glib::ustring(uiStyle); UIStringToPangoStringMap::iterator uiToPangoIter = fontStringMap.find(uiString); -- cgit v1.2.3 From 6a597dc85342abf8c88a5b4f1ba99d50589f64ef Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 31 Jan 2013 19:35:26 +0100 Subject: Text toolbar will display style options for the first font in a font-family list. Also, fix mem leak. (bzr r12082) --- src/libnrtype/FontFactory.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 2cf4b8673..fdb02aa0f 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -831,6 +831,8 @@ font_instance* font_factory::FaceFromUIStrings(char const *uiFamily, char const Glib::ustring uiString = Glib::ustring(tokens[0]) + Glib::ustring(uiStyle); + g_strfreev( tokens ); + UIStringToPangoStringMap::iterator uiToPangoIter = fontStringMap.find(uiString); if (uiToPangoIter != fontStringMap.end ()) { -- cgit v1.2.3 From b4394b6d2a5db9fe935824c946d8a81333614ae8 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 2 Feb 2013 16:44:07 +0900 Subject: Fix for 1002757 : Regressions with new default font 'sans-serif' (bzr r12089) --- src/libnrtype/FontFactory.cpp | 42 +++++++++++++++++++++++++++++++------ src/libnrtype/FontFactory.h | 3 +++ src/libnrtype/FontInstance.cpp | 4 ++-- src/libnrtype/Layout-TNG-Output.cpp | 4 ++-- 4 files changed, 43 insertions(+), 10 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index fdb02aa0f..6c95c0363 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -28,7 +28,7 @@ typedef INK_UNORDERED_MAP fontNameMap; + std::map::iterator it; + + fontNameMap.insert(std::make_pair("Sans", "sans-serif")); + fontNameMap.insert(std::make_pair("Serif", "serif")); + fontNameMap.insert(std::make_pair("Monospace", "monospace")); + //fontNameMap.insert(std::make_pair("", "cursive")); + //fontNameMap.insert(std::make_pair("", "fantasy")); + + const char *pangoFamily = pango_font_description_get_family(fontDescr); + + if (pangoFamily && ((it = fontNameMap.find(pangoFamily)) != fontNameMap.end())) { + return ((Glib::ustring)it->second).c_str(); + } + + return pangoFamily; +} + Glib::ustring font_factory::GetUIFamilyString(PangoFontDescription const *fontDescr) { Glib::ustring family; @@ -403,7 +430,8 @@ Glib::ustring font_factory::GetUIFamilyString(PangoFontDescription const *fontDe if (fontDescr) { // For now, keep it as family name taken from pango - const char *pangoFamily = pango_font_description_get_family(fontDescr); + const char *pangoFamily = sp_font_description_get_family(fontDescr); + if( pangoFamily ) { family = pangoFamily; } @@ -719,6 +747,7 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) Glib::ustring styleUIName = GetUIStyleString(faceDescr); if (!familyUIName.empty() && !styleUIName.empty()) { + // Find the right place to put the style information, adding // a map entry for the family name if it doesn't yet exist @@ -754,6 +783,7 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) ConstructFontSpecification(faceDescr))); fontInstanceMap.insert( std::make_pair(ConstructFontSpecification(faceDescr), faceDescr)); + } else { pango_font_description_free(faceDescr); } @@ -870,7 +900,7 @@ font_instance* font_factory::FaceFromPangoString(char const *pangoString) descr = pango_font_description_from_string(pangoString); } - if (descr && (pango_font_description_get_family(descr) != NULL)) { + if (descr && (sp_font_description_get_family(descr) != NULL)) { fontInstance = Face(descr); } @@ -918,7 +948,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // workaround for bug #1025565. // fonts without families blow up Pango. - if (pango_font_description_get_family(descr) != NULL) { + if (sp_font_description_get_family(descr) != NULL) { nFace = pango_font_map_load_font(fontServer,fontContext,descr); } else { diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 42f975ab7..12046079e 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -54,6 +54,9 @@ struct font_descr_equal : public std::binary_function > FamilyToStylesMap; diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index f26b157da..61225ad0c 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -285,14 +285,14 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int bool b = (weight >= PANGO_WEIGHT_BOLD); res = g_strdup_printf ("%s%s%s%s", - pango_font_description_get_family(descr), + sp_font_description_get_family(descr), (b || i || o) ? "-" : "", (b) ? "Bold" : "", (i) ? "Italic" : ((o) ? "Oblique" : "") ); free_res = true; } } else if ( strcmp(key,"family") == 0 ) { - res=(char*)pango_font_description_get_family(descr); + res=(char*)sp_font_description_get_family(descr); free_res=false; } else if ( strcmp(key,"style") == 0 ) { PangoStyle v=pango_font_description_get_style(descr); diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index bf746b41f..1d086b57b 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -340,7 +340,7 @@ Glib::ustring Layout::getFontFamily(unsigned span_index) const return ""; if (_spans[span_index].font) { - return pango_font_description_get_family(_spans[span_index].font->descr); + return sp_font_description_get_family(_spans[span_index].font->descr); } return ""; @@ -368,7 +368,7 @@ Glib::ustring Layout::dumpAsText() const snprintf(line, sizeof(line), " in chunk %d (x=%f, baselineshift=%f)\n", _spans[span_index].in_chunk, _chunks[_spans[span_index].in_chunk].left_x, _spans[span_index].baseline_shift); result += line; if (_spans[span_index].font) { - snprintf(line, sizeof(line), " font '%s' %f %s %s\n", pango_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); + snprintf(line, sizeof(line), " font '%s' %f %s %s\n", sp_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); result += line; } snprintf(line, sizeof(line), " x_start = %f, x_end = %f\n", _spans[span_index].x_start, _spans[span_index].x_end); -- cgit v1.2.3 From 04ba54c3e2586155cef3421ef2a9b27565a8dbe7 Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 4 Feb 2013 10:33:03 +0900 Subject: Fix for 1002757 : Regressions with new default font 'sans-serif' - fix map (bzr r12096) --- src/libnrtype/FontFactory.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 6c95c0363..a9220d867 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -407,11 +407,11 @@ const char *sp_font_description_get_family(PangoFontDescription const *fontDescr static std::map fontNameMap; std::map::iterator it; - fontNameMap.insert(std::make_pair("Sans", "sans-serif")); - fontNameMap.insert(std::make_pair("Serif", "serif")); - fontNameMap.insert(std::make_pair("Monospace", "monospace")); - //fontNameMap.insert(std::make_pair("", "cursive")); - //fontNameMap.insert(std::make_pair("", "fantasy")); + if (fontNameMap.empty()) { + fontNameMap.insert(std::make_pair("Sans", "sans-serif")); + fontNameMap.insert(std::make_pair("Serif", "serif")); + fontNameMap.insert(std::make_pair("Monospace", "monospace")); + } const char *pangoFamily = pango_font_description_get_family(fontDescr); -- cgit v1.2.3 From aeabdef63219b5369907c767f692e929013c3507 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 6 Feb 2013 10:07:00 +0100 Subject: Add fonts (and font-lists) used in document to top of Text tool-bar font-family drop-down menu. If font is not on system, draws strikethrough on top of font name. (bzr r12104) --- src/libnrtype/font-lister.cpp | 2 +- src/libnrtype/font-lister.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 710e0b84f..6df576866 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -52,7 +52,7 @@ namespace Inkscape } (*treeModelIter)[FontList.styles] = styles; - + (*treeModelIter)[FontList.onSystem] = true; font_list_store_iter_map.insert(std::make_pair(familyName, Gtk::TreePath(treeModelIter))); } } diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index c9ab7b21d..7a7db5615 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -54,10 +54,15 @@ namespace Inkscape */ Gtk::TreeModelColumn styles; + /** Column containing flag if font is on system + */ + Gtk::TreeModelColumn onSystem; + FontListClass () { add (font); add (styles); + add (onSystem); } }; -- cgit v1.2.3 From e330f37cfa5949bb505bb846a467f10c2c711d8f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 9 Feb 2013 10:30:08 +0100 Subject: Add function to add document font-family entries to store. Remove font-family to interator map as we can now have duplicate font-family names in store. (bzr r12111) --- src/libnrtype/font-lister.cpp | 149 +++++++++++++++++++++++++++++++++++++++++- src/libnrtype/font-lister.h | 40 +++++------- 2 files changed, 165 insertions(+), 24 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 6df576866..9949be208 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -14,6 +14,11 @@ #include "font-lister.h" #include "FontFactory.h" +#include "sp-object.h" +#include "sp-root.h" +#include "document.h" +#include "xml/repr.h" + namespace Inkscape { FontLister::FontLister () @@ -53,11 +58,153 @@ namespace Inkscape (*treeModelIter)[FontList.styles] = styles; (*treeModelIter)[FontList.onSystem] = true; - font_list_store_iter_map.insert(std::make_pair(familyName, Gtk::TreePath(treeModelIter))); } } } + // Example of how to use "foreach_iter" + // bool + // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { + // Gtk::TreeModel::Row row = *iter; + // if( !row[FontList.onSystem] ) { + // std::cout << " Not on system: " << row[FontList.font] << std::endl; + // return false; + // } + // return true; + // } + // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); + + void + FontLister::update_font_list( SPDocument* document ) { + + SPObject *r = document->getRoot(); + if( !r ) { + return; + } + + /* Clear all old document font-family entries */ + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + Gtk::TreeModel::Row row = *iter; + if( !row[FontList.onSystem] ) { + // std::cout << " Not on system: " << row[FontList.font] << std::endl; + iter = font_list_store->erase( iter ); + } else { + // std::cout << " First on system: " << row[FontList.font] << std::endl; + break; + } + } + + /* Create default styles for use when font-family is unknown on system. */ + static GList *default_styles = NULL; + if( default_styles == NULL ) { + default_styles = g_list_append( default_styles, g_strdup("Normal") ); + default_styles = g_list_append( default_styles, g_strdup("Italic") ); + default_styles = g_list_append( default_styles, g_strdup("Bold") ); + default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); + default_styles = g_list_append( default_styles, g_strdup("Loopy") ); + } + + /* Get "font-family"s used in document. */ + std::list fontfamilies; + update_font_list_recursive( r, &fontfamilies ); + + fontfamilies.sort(); + fontfamilies.unique(); + fontfamilies.reverse(); + + /* Insert separator */ + if( !fontfamilies.empty() ) { + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.font] = "separatoR"; + (*treeModelIter)[FontList.onSystem] = false; + } + + /* Insert font-family's in document. */ + std::list::iterator i; + for( i = fontfamilies.begin(); i != fontfamilies.end(); ++i) { + + GList *styles = default_styles; + + /* See if font-family (or first in fallback list) is on system. If so, get styles. */ + std::vector tokens = Glib::Regex::split_simple(",", *i ); + if( !tokens[0].empty() ) { + + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); + while( iter2 != font_list_store->children().end() ) { + Gtk::TreeModel::Row row = *iter2; + if( row[FontList.onSystem] && tokens[0].compare( row[FontList.font] ) == 0 ) { + styles = row[FontList.styles]; + break; + } + ++iter2; + } + } + + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.font] = reinterpret_cast(g_strdup((*i).c_str())); + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; + } + } + + void + FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { + + const gchar *style = r->getRepr()->attribute("style"); + if( style != NULL ) { + + std::vector tokens = Glib::Regex::split_simple(";", style ); + for( size_t i=0; i < tokens.size(); ++i ) { + + Glib::ustring token = tokens[i]; + size_t found = token.find("font-family:"); + + if( found != Glib::ustring::npos ) { + + // Remove "font-family:" + token.erase(found,12); + + // Remove any leading single or double quote + if( token[0] == '\'' || token[0] == '"' ) { + token.erase(0,1); + } + + // Remove any trailing single or double quote + if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) { + token.erase(token.length()-1); + } + + l->push_back( token ); + } + } + } + + for (SPObject *child = r->firstChild(); child; child = child->getNext()) { + update_font_list_recursive( child, l ); + } + } + + Gtk::TreePath + FontLister::get_row_for_font (Glib::ustring family) + { + Gtk::TreePath path; + + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + + Gtk::TreeModel::Row row = *iter; + + if( family.compare( row[FontList.font] ) == 0 ) { + return font_list_store->get_path( iter ); + } + + ++iter; + } + + throw FAMILY_NOT_FOUND; + } + FontLister::~FontLister () { }; diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 7a7db5615..d4c48dd52 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -7,9 +7,11 @@ * Authors: * Chris Lahey * Lauris Kaplinski + * Tavmjong Bah * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2013 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -21,6 +23,9 @@ #include #include "nr-type-primitives.h" +class SPObject; +class SPDocument; + namespace Inkscape { /** @@ -66,22 +71,7 @@ namespace Inkscape } }; - /* Case-insensitive < compare for standard strings */ - class StringLessThan - { - public: - bool operator () (std::string str1, std::string str2) const - { - std::string s1=str1; // Can't transform the originals! - std::string s2=str2; - std::transform(s1.begin(), s1.end(), s1.begin(), (int(*)(int)) toupper); - std::transform(s2.begin(), s2.end(), s2.begin(), (int(*)(int)) toupper); - return s1 IterMapType; /** Returns the ListStore with the font names * @@ -92,6 +82,17 @@ namespace Inkscape const Glib::RefPtr get_font_list () const; + /** Updates font list to include fonts in document + * + */ + void + update_font_list ( SPDocument* document); + + private: + void + update_font_list_recursive( SPObject *r, std::list *l ); + + public: static Inkscape::FontLister* get_instance () { @@ -100,12 +101,7 @@ namespace Inkscape } Gtk::TreePath - get_row_for_font (Glib::ustring family) - { - IterMapType::iterator iter = font_list_store_iter_map.find (family); - if (iter == font_list_store_iter_map.end ()) throw FAMILY_NOT_FOUND; - return (*iter).second; - } + get_row_for_font (Glib::ustring family); const NRNameList get_name_list () const @@ -113,7 +109,6 @@ namespace Inkscape return families; } - private: FontLister (); @@ -121,7 +116,6 @@ namespace Inkscape NRNameList families; Glib::RefPtr font_list_store; - IterMapType font_list_store_iter_map; }; } -- cgit v1.2.3 From 83ae846627474ee5aad75c1f4816a3faa7240a47 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 9 Feb 2013 13:52:04 +0100 Subject: Use update_font_list() in font-lister.cpp. Remove equivalent code in text-toolbar.cpp. Change separator "tag" from "separatoR" to "#" in attempt to speed up start up. (bzr r12112) --- src/libnrtype/font-lister.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 9949be208..1e51d8803 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -116,7 +116,7 @@ namespace Inkscape /* Insert separator */ if( !fontfamilies.empty() ) { Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.font] = "separatoR"; + (*treeModelIter)[FontList.font] = "#"; (*treeModelIter)[FontList.onSystem] = false; } -- cgit v1.2.3 From d950a5453a26c6d887e3fcd597da9a7818bab7f3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 10 Feb 2013 07:33:41 +0100 Subject: Attempt to speed up font-family handling be freezing/thawing Gtk::ListStore when modifying. (bzr r12113) --- src/libnrtype/font-lister.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 1e51d8803..647bbc056 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -24,7 +24,8 @@ namespace Inkscape FontLister::FontLister () { font_list_store = Gtk::ListStore::create (FontList); - + font_list_store->freeze_notify(); + FamilyToStylesMap familyStyleMap; font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); @@ -60,6 +61,7 @@ namespace Inkscape (*treeModelIter)[FontList.onSystem] = true; } } + font_list_store->thaw_notify(); } // Example of how to use "foreach_iter" @@ -82,6 +84,8 @@ namespace Inkscape return; } + font_list_store->freeze_notify(); + /* Clear all old document font-family entries */ Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); while( iter != font_list_store->children().end() ) { @@ -146,6 +150,8 @@ namespace Inkscape (*treeModelIter)[FontList.styles] = styles; (*treeModelIter)[FontList.onSystem] = false; } + + font_list_store->thaw_notify(); } void -- cgit v1.2.3 From cb07768f46fef63b0e0f48e3b12be97467d46a9c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 11 Feb 2013 16:35:47 +0100 Subject: Move cell_data_func and separator_func from text-toolbar to font-lister. Use functions with font-selector (in Text dialog). (bzr r12116) --- src/libnrtype/font-lister.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++- src/libnrtype/font-lister.h | 15 +++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 647bbc056..04859185c 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -18,6 +18,7 @@ #include "sp-root.h" #include "document.h" #include "xml/repr.h" +#include "preferences.h" namespace Inkscape { @@ -106,7 +107,6 @@ namespace Inkscape default_styles = g_list_append( default_styles, g_strdup("Italic") ); default_styles = g_list_append( default_styles, g_strdup("Bold") ); default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); - default_styles = g_list_append( default_styles, g_strdup("Loopy") ); } /* Get "font-family"s used in document. */ @@ -222,6 +222,77 @@ namespace Inkscape } } +// Helper functions +void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/) +{ + gchar *family; + gboolean onSystem = false; + gtk_tree_model_get(model, iter, 0, &family, 2, &onSystem, -1); + Glib::ustring family_escaped = g_markup_escape_text(family, -1); + //g_free(family); + Glib::ustring markup; + + if( !onSystem ) { + markup = ""; + + /* See if font-family on system */ + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped ); + for( size_t i=0; i < tokens.size(); ++i ) { + + Glib::ustring token = tokens[i]; + + GtkTreeIter iter; + gboolean valid; + gchar *family = 0; + gboolean onSystem = true; + gboolean found = false; + for( valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(model), &iter ); + valid; + valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) { + + gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1); + if( onSystem && token.compare( family ) == 0 ) { + found = true; + break; + } + } + if( found ) { + markup += g_markup_escape_text(token.c_str(), -1); + markup += ", "; + } else { + markup += ""; + markup += g_markup_escape_text(token.c_str(), -1); + markup += ""; + markup += ", "; + } + } + // Remove extra comma and space from end. + if( markup.size() >= 2 ) { + markup.resize( markup.size()-2 ); + } + markup += ""; + // std::cout << markup << std::endl; + } else { + markup = family_escaped; + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int show_sample = prefs->getInt("/tools/text/show_sample_in_list", 1); + if (show_sample) { + Glib::ustring sample = prefs->getString("/tools/text/font_sample"); + Glib::ustring sample_escaped = g_markup_escape_text(sample.data(), -1); + markup += " "; + markup += sample_escaped; + markup += ""; + } + + g_object_set (G_OBJECT (cell), "markup", markup.c_str(), NULL); +} diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index d4c48dd52..751350407 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -120,6 +120,21 @@ namespace Inkscape }; } +// Helper functions +// Separator function (if true, a separator will be drawn) +static gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) +{ + gchar* text = 0; + gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.font + return (text && strcmp(text,"#") == 0); +} + +void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/); + #endif /* -- cgit v1.2.3 From 479b07573269be8c736b8a65b8f5a608254cd0e4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 17 Feb 2013 13:37:27 +0100 Subject: Move code from text-toolbar to font-lister in preparation to share code with font-selector/text-edit. (bzr r12131) --- src/libnrtype/font-lister.cpp | 667 ++++++++++++++++++++++++++++++++++++++++-- src/libnrtype/font-lister.h | 203 ++++++++++++- 2 files changed, 837 insertions(+), 33 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 04859185c..91671f627 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -14,11 +14,16 @@ #include "font-lister.h" #include "FontFactory.h" +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "inkscape.h" +#include "preferences.h" #include "sp-object.h" #include "sp-root.h" -#include "document.h" #include "xml/repr.h" -#include "preferences.h" + +//#define DEBUG_FONT namespace Inkscape { @@ -29,7 +34,7 @@ namespace Inkscape FamilyToStylesMap familyStyleMap; font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); - + // Grab the family names into a list and then sort them std::list familyList; for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); @@ -47,7 +52,8 @@ namespace Inkscape if (!familyName.empty()) { Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); - (*treeModelIter)[FontList.font] = reinterpret_cast(g_strdup(familyName.c_str())); + //(*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(familyName.c_str())); + (*treeModelIter)[FontList.family] = familyName; // Now go through the styles GList *styles = NULL; @@ -62,7 +68,21 @@ namespace Inkscape (*treeModelIter)[FontList.onSystem] = true; } } + current_family = "sans-serif"; + current_style = "Normal"; + current_fontspec = "sans-serif"; // Empty style -> Normal + current_fontspec_system = "Sans"; + + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append( NULL, g_strdup("Normal") ); + default_styles = g_list_append( default_styles, g_strdup("Italic") ); + default_styles = g_list_append( default_styles, g_strdup("Bold") ); + default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); + 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" @@ -70,7 +90,7 @@ namespace Inkscape // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { // Gtk::TreeModel::Row row = *iter; // if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.font] << std::endl; + // std::cout << " Not on system: " << row[FontList.family] << std::endl; // return false; // } // return true; @@ -92,23 +112,14 @@ namespace Inkscape while( iter != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter; if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.font] << std::endl; + // std::cout << " Not on system: " << row[FontList.family] << std::endl; iter = font_list_store->erase( iter ); } else { - // std::cout << " First on system: " << row[FontList.font] << std::endl; + // std::cout << " First on system: " << row[FontList.family] << std::endl; break; } } - /* Create default styles for use when font-family is unknown on system. */ - static GList *default_styles = NULL; - if( default_styles == NULL ) { - default_styles = g_list_append( default_styles, g_strdup("Normal") ); - default_styles = g_list_append( default_styles, g_strdup("Italic") ); - default_styles = g_list_append( default_styles, g_strdup("Bold") ); - default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); - } - /* Get "font-family"s used in document. */ std::list fontfamilies; update_font_list_recursive( r, &fontfamilies ); @@ -120,7 +131,7 @@ namespace Inkscape /* Insert separator */ if( !fontfamilies.empty() ) { Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.font] = "#"; + (*treeModelIter)[FontList.family] = "#"; (*treeModelIter)[FontList.onSystem] = false; } @@ -137,7 +148,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.font] ) == 0 ) { + if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { styles = row[FontList.styles]; break; } @@ -146,7 +157,7 @@ namespace Inkscape } Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.font] = reinterpret_cast(g_strdup((*i).c_str())); + (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup((*i).c_str())); (*treeModelIter)[FontList.styles] = styles; (*treeModelIter)[FontList.onSystem] = false; } @@ -191,7 +202,548 @@ namespace Inkscape } } - Gtk::TreePath + Glib::ustring + FontLister::canonize_fontspec( Glib::ustring fontspec ) { + + // Pass fontspec to and back from Pango to get a the fontspec in + // canonical form. -inkscape-font-specification relies on the + // Pango constructed fontspec not changing form. If it does, + // this is the place to fix it. + PangoFontDescription *descr = pango_font_description_from_string( fontspec.c_str() ); + gchar* canonized = pango_font_description_to_string ( descr ); + Glib::ustring Canonized = canonized; + g_free( canonized ); + pango_font_description_free( descr ); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while( (i = Canonized.find(",", i)) != std::string::npos) { + Canonized.replace(i, 1, ", "); + i += 2; + } + + return Canonized; + } + + Glib::ustring + FontLister::system_fontspec( Glib::ustring fontspec ) { + + // Find what Pango thinks is the closest match. + Glib::ustring out = fontspec; + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + font_instance *res = (font_factory::Default())->Face(descr); + if (res->pFont) { + PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont); + out = sp_font_description_get_family(nFaceDesc); + } + pango_font_description_free(descr); + + return out; + } + + std::pair + FontLister::ui_from_fontspec( Glib::ustring fontspec ) { + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + const gchar* family = pango_font_description_get_family(descr); + Glib::ustring Family = family; + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while( (i = Family.find(",", i)) != std::string::npos) { + Family.replace(i, 1, ", "); + i += 2; + } + + pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); + gchar* style = pango_font_description_to_string( descr ); + Glib::ustring Style = style; + pango_font_description_free(descr); + g_free( style ); + + return std::make_pair( Family, Style ); + } + + std::pair + FontLister::selection_update () { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::selection_update: entrance" << std::endl; +#endif + // Get fontspec from a selection, preferences, or thin air. + Glib::ustring fontspec; + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + + // Directly from stored font specification. + int result = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + + //std::cout << " Attempting selected style" << std::endl; + if( result != QUERY_STYLE_NOTHING && query->text->font_specification.set ) { + fontspec = query->text->font_specification.value; + //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; + } + + // From style + if( fontspec.empty() ) { + //std::cout << " Attempting desktop style" << std::endl; + int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + + // Must have text in selection + if( rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING ) { + fontspec = fontspec_from_style( query ); + } + //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; + } + + // From preferences + if( fontspec.empty() ) { + //std::cout << " Attempting preferences" << std::endl; + sp_style_read_from_prefs(query, "/tools/text"); + fontspec = fontspec_from_style( query ); + //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; + } + sp_style_unref(query); + + // From thin air + if( fontspec.empty() ) { + //std::cout << " Attempting thin air" << std::endl; + fontspec = current_family + ", " + current_style; + //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; + } + + // Do we really need? Removes spaces between font-families. + //current_fontspec = canonize_fontspec( fontspec ); + current_fontspec = fontspec; // Ignore for now + + current_fontspec_system = system_fontspec( current_fontspec ); + + std::pair ui = ui_from_fontspec( current_fontspec ); + set_font_family( ui.first ); + +#ifdef DEBUG_FONT + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::selection_update: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( current_family, current_style ); + } + + + // TODO: use to determine font-selector best style + std::pair + FontLister::new_font_family (Glib::ustring new_family, gboolean check_style ) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::new_font_family: " << new_family << std::endl; +#endif + + // No need to do anything if new family is same as old family. + if( new_family.compare( current_family ) == 0 ) { +#ifdef DEBUG_FONT + std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( current_family, current_style ); + } + + // We need to do two things: + // 1. Update style list for new family. + // 2. Select best valid style match to old style. + + // For finding style list, use list of first family in font-family list. + GList* styles = NULL; + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + + Gtk::TreeModel::Row row = *iter; + + if( new_family.compare( row[FontList.family] ) == 0 ) { + styles = row[FontList.styles]; + break; + } + ++iter; + } + + // Newly typed in font-family may not yet be in list... use default list. + // TODO: if font-family is list, check if first family in list is on system + // and set style accordingly. + if( styles == NULL ) { + styles = default_styles; + } + + // Update style list. + // TODO: create a second "temporary" style_list_store for font_selector. + style_list_store->freeze_notify(); + style_list_store->clear(); + + for (GList *l=styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + } + + style_list_store->thaw_notify(); + + // Find best match to the style from the old font-family to the + // styles available with the new font. + // TODO: Maybe check if an exact match exists before using Pango. + Glib::ustring best_style = current_style; + if( check_style ) { + //std::cout << " Trying to match: " << current_fontspec << std::endl; + PangoFontDescription *desc_old + = pango_font_description_from_string( current_fontspec.c_str() ); + PangoFontDescription* desc_best = NULL; + + for (GList *l=styles; l; l = l->next) { + Glib::ustring candidate = new_family + ", " + (char*)l->data; + PangoFontDescription* desc_candidate + = pango_font_description_from_string( candidate.c_str() ); + //std::cout << " Testing: " << pango_font_description_to_string( desc_candidate ) << std::endl; + if( pango_font_description_better_match( desc_old, desc_best, desc_candidate ) ) { + pango_font_description_free( desc_best ); + desc_best = desc_candidate; + //std::cout << " ... better: " << std::endl; + } else { + pango_font_description_free( desc_candidate ); + //std::cout << " ... not better: " << std::endl; + } + } + if( desc_best ) { + pango_font_description_unset_fields( desc_best, PANGO_FONT_MASK_FAMILY ); + best_style = pango_font_description_to_string( desc_best ); + } + + if( desc_old ) pango_font_description_free( desc_old ); + if( desc_best ) pango_font_description_free( desc_best ); + } + +#ifdef DEBUG_FONT + std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( new_family, best_style ); + } + + std::pair + FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family: " << new_family << std::endl; +#endif + + std::pair ui = new_font_family( new_family, check_style ); + current_family = ui.first; + current_style = ui.second; + current_fontspec = canonize_fontspec( current_family + ", " + current_style ); + current_fontspec_system = system_fontspec( current_fontspec ); + +#ifdef DEBUG_FONT + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::set_font_family: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return ui; + } + + // 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) { + + // TODO: Validate input using Pango. If Pango doesn't recognize a style it will + // attach the "invalid" style to the font-family. + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister:set_font_style: " << new_style << std::endl; +#endif + + current_style = new_style; + current_fontspec = canonize_fontspec( current_family + ", " + current_style ); + current_fontspec_system = system_fontspec( current_fontspec ); + +#ifdef DEBUG_FONT + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: " << current_family << std::endl; + std::cout << " style: " << current_style << std::endl; + std::cout << "FontLister::set_font_style: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#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 ) { + + //std::cout << "FontLister:set_css: " << std::endl; + + PangoFontDescription *desc = pango_font_description_from_string( current_fontspec.c_str() ); + sp_repr_css_set_property (css, "-inkscape-font-specification", current_fontspec.c_str() ); + sp_repr_css_set_property (css, "font-family", pango_font_description_get_family( desc ) ); + + PangoWeight weight = pango_font_description_get_weight( desc ); + switch ( weight ) { + case PANGO_WEIGHT_THIN: + sp_repr_css_set_property (css, "font-weight", "100" ); + break; + case PANGO_WEIGHT_ULTRALIGHT: + sp_repr_css_set_property (css, "font-weight", "200" ); + break; + case PANGO_WEIGHT_LIGHT: + sp_repr_css_set_property (css, "font-weight", "300" ); + break; + case PANGO_WEIGHT_BOOK: + sp_repr_css_set_property (css, "font-weight", "380" ); + break; + case PANGO_WEIGHT_NORMAL: + sp_repr_css_set_property (css, "font-weight", "normal" ); + break; + case PANGO_WEIGHT_MEDIUM: + sp_repr_css_set_property (css, "font-weight", "500" ); + break; + case PANGO_WEIGHT_SEMIBOLD: + sp_repr_css_set_property (css, "font-weight", "600" ); + break; + case PANGO_WEIGHT_BOLD: + sp_repr_css_set_property (css, "font-weight", "bold" ); + break; + case PANGO_WEIGHT_ULTRABOLD: + sp_repr_css_set_property (css, "font-weight", "800" ); + break; + case PANGO_WEIGHT_HEAVY: + sp_repr_css_set_property (css, "font-weight", "900" ); + break; + case PANGO_WEIGHT_ULTRAHEAVY: + sp_repr_css_set_property (css, "font-weight", "1000" ); + break; + } + + PangoStyle style = pango_font_description_get_style( desc ); + switch ( style ) { + case PANGO_STYLE_NORMAL: + sp_repr_css_set_property (css, "font-style", "normal" ); + break; + case PANGO_STYLE_OBLIQUE: + sp_repr_css_set_property (css, "font-style", "oblique" ); + break; + case PANGO_STYLE_ITALIC: + sp_repr_css_set_property (css, "font-style", "italic" ); + break; + } + + PangoStretch stretch = pango_font_description_get_stretch( desc ); + switch ( stretch ) { + case PANGO_STRETCH_ULTRA_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "ultra-condensed" ); + break; + case PANGO_STRETCH_EXTRA_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "extra-condensed" ); + break; + case PANGO_STRETCH_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "condensed" ); + break; + case PANGO_STRETCH_SEMI_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "semi-condensed" ); + break; + case PANGO_STRETCH_NORMAL: + sp_repr_css_set_property (css, "font-stretch", "normal" ); + break; + case PANGO_STRETCH_SEMI_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "semi-expanded" ); + break; + case PANGO_STRETCH_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "expanded" ); + break; + case PANGO_STRETCH_EXTRA_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "extra-expanded" ); + break; + case PANGO_STRETCH_ULTRA_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "ultra-expanded" ); + break; + } + + PangoVariant variant = pango_font_description_get_variant( desc ); + switch ( variant ) { + case PANGO_VARIANT_NORMAL: + sp_repr_css_set_property (css, "font-variant", "normal" ); + break; + case PANGO_VARIANT_SMALL_CAPS: + sp_repr_css_set_property (css, "font-variant", "small-caps" ); + break; + } + } + + // We do this ourselves as we can't rely on FontFactory. + Glib::ustring + FontLister::fontspec_from_style (SPStyle* style) { + + //std::cout << "FontLister:fontspec_from_style: " << std::endl; + + Glib::ustring fontspec; + if (style) { + + // First try to use the font specification if it is set + if (style->text->font_specification.set + && style->text->font_specification.value + && *style->text->font_specification.value) { + + fontspec = style->text->font_specification.value; + + } else { + + fontspec = style->text->font_family.value; + fontspec += ","; + + switch (style->font_weight.computed) { + + case SP_CSS_FONT_WEIGHT_100: + fontspec += " 100"; + break; + + case SP_CSS_FONT_WEIGHT_200: + fontspec += " 200"; + break; + + case SP_CSS_FONT_WEIGHT_300: + fontspec += " 300"; + break; + + case SP_CSS_FONT_WEIGHT_400: + case SP_CSS_FONT_WEIGHT_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_WEIGHT_500: + fontspec += " 500"; + break; + + case SP_CSS_FONT_WEIGHT_600: + fontspec += " 600"; + break; + + case SP_CSS_FONT_WEIGHT_700: + case SP_CSS_FONT_WEIGHT_BOLD: + fontspec += " bold"; + break; + + case SP_CSS_FONT_WEIGHT_800: + fontspec += " 800"; + break; + + case SP_CSS_FONT_WEIGHT_900: + fontspec += " 900"; + break; + + case SP_CSS_FONT_WEIGHT_LIGHTER: + case SP_CSS_FONT_WEIGHT_BOLDER: + default: + g_warning("Unrecognized font_weight.computed value"); + break; + } + + switch (style->font_style.computed) { + case SP_CSS_FONT_STYLE_ITALIC: + fontspec += " italic"; + break; + + case SP_CSS_FONT_STYLE_OBLIQUE: + fontspec += " oblique"; + break; + + case SP_CSS_FONT_STYLE_NORMAL: + default: + //fontspec += " normal"; + break; + } + + switch (style->font_stretch.computed) { + + case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: + fontspec += " extra_condensed"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: + fontspec += " extra_condensed"; + break; + + case SP_CSS_FONT_STRETCH_CONDENSED: + case SP_CSS_FONT_STRETCH_NARROWER: + fontspec += " condensed"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: + fontspec += " semi_condensed"; + break; + + case SP_CSS_FONT_STRETCH_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: + fontspec += " semi_expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXPANDED: + case SP_CSS_FONT_STRETCH_WIDER: + fontspec += " expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: + fontspec += " extra_expanded"; + break; + + case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fontspec += " ultra_expanded"; + break; + + default: + //fontspec += " normal"; + break; + } + + switch (style->font_variant.computed) { + + case SP_CSS_FONT_VARIANT_SMALL_CAPS: + fontspec += "small-caps"; + break; + + default: + //fontspec += "normal"; + break; + } + } + } + return canonize_fontspec( fontspec ); + } + + + Gtk::TreeModel::Row FontLister::get_row_for_font (Glib::ustring family) { Gtk::TreePath path; @@ -201,8 +753,8 @@ namespace Inkscape Gtk::TreeModel::Row row = *iter; - if( family.compare( row[FontList.font] ) == 0 ) { - return font_list_store->get_path( iter ); + if( family.compare( row[FontList.family] ) == 0 ) { + return row; } ++iter; @@ -211,6 +763,65 @@ namespace Inkscape throw FAMILY_NOT_FOUND; } + Gtk::TreePath + FontLister::get_path_for_font (Glib::ustring family) + { + return font_list_store->get_path( get_row_for_font ( family ) ); + } + + /* Returns style string */ + // TODO: Remove or turn into function to be used by new_font_family. + Glib::ustring + FontLister::get_best_style_match (Glib::ustring family, Glib::ustring target_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; +#endif + + Glib::ustring font_string = family + " " + target_style; + + Gtk::TreeModel::Row row; + try { + row = get_row_for_font( family ); + } catch (...) { + //std::cout << " ERROR: can't find family: " << family << std::endl; + return (target_style); + } + + PangoFontDescription* target = pango_font_description_from_string( font_string.c_str() ); + PangoFontDescription* best = NULL; + + //std::cout << " Target: " << pango_font_description_to_string( target ) << std::endl; + + GList* styles = row[FontList.styles]; + for (GList *l=styles; l; l = l->next) { + Glib::ustring font_string_test = family + " " + (char*)l->data; + PangoFontDescription* candidate = pango_font_description_from_string( font_string_test.c_str() ); + // std::cout << " Testing: " << pango_font_description_to_string( candidate ) << std::endl; + if( pango_font_description_better_match( target, best, candidate ) ) { + best = candidate; + } + } + + Glib::ustring best_style; + if( best ) { + //std::cout << " Best: " << pango_font_description_to_string( best ) << std::endl; + pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY ); + best_style = pango_font_description_to_string( best ); + } else { + //std::cout << " Failed: " << family << std::endl; + best_style = target_style; + } + +#ifdef DEBUG_FONT + std::cout << " Returning: " << best_style << std::endl; + std::cout << "FontLister::get_best_style_match: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return best_style; + } + FontLister::~FontLister () { }; @@ -220,6 +831,18 @@ namespace Inkscape { return font_list_store; } + + const Glib::RefPtr + FontLister::get_style_list () const + { + return style_list_store; + } + + const Glib::RefPtr + 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 751350407..10a269771 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -25,12 +25,35 @@ class SPObject; class SPDocument; +class SPCSSAttr; +struct SPStyle; namespace Inkscape { /** * This class enumerates fonts using libnrtype into reusable data stores and - * allows for random access to the font list + * allows for random access to the font-family list and the font-style list. + * Setting the font-family updates the font-style list. "Style" in this case + * refers to everything but family and size (e.g. italic/oblique, weight). + * + * This class handles font-family lists and fonts that are not on the system, + * where there is not an entry in the fontInstanceMap. + * + * This class uses the idea of "font_spec". This is a plain text string as used by + * Pango. It is similar to the CSS font shorthand except that font-family comes + * first and in this class the font-size is not used. + * + * This class uses the FontFactory class to get a list of system fonts + * and to find best matches via Pango. The Pango interface is only setup + * to deal with fonts that are on the system so care must be taken. For + * example, best matches should only be done with the first font-family + * in a font-family list. If the first font-family is not on the system + * then a generic font-family should be used (sans-serif -> Sans). + * + * This class is used by the UI interface (text-toolbar, font-select, etc.). + * + * "Font" includes family and style. It should not be used when one + * means font-family. */ class FontLister { @@ -38,13 +61,14 @@ namespace Inkscape enum Exceptions { - FAMILY_NOT_FOUND + FAMILY_NOT_FOUND, + STYLE_NOT_FOUND }; virtual ~FontLister (); - /** GtkTreeModelColumnRecord for the font list Gtk::ListStore + /** GtkTreeModelColumnRecord for the font-family list Gtk::ListStore */ class FontListClass : public Gtk::TreeModelColumnRecord @@ -52,10 +76,9 @@ namespace Inkscape public: /** Column containing the family name */ - Gtk::TreeModelColumn font; + Gtk::TreeModelColumn family; - /** Column containing an std::vector with style names - * for the corresponding family + /** Column containing the styles for each family name. */ Gtk::TreeModelColumn styles; @@ -65,7 +88,7 @@ namespace Inkscape FontListClass () { - add (font); + add (family); add (styles); add (onSystem); } @@ -73,7 +96,24 @@ namespace Inkscape FontListClass FontList; - /** Returns the ListStore with the font names + class FontStyleListClass + : public Gtk::TreeModelColumnRecord + { + public: + /** Column containing the styles + */ + Gtk::TreeModelColumn styles; + + FontStyleListClass () + { + add (styles); + } + }; + + FontStyleListClass FontStyleList; + FontStyleListClass FontStyleListTrial; + + /** Returns the ListStore with the family names * * The return is const and the function is declared as const. * The ListStore is ready to be used after class instantiation @@ -82,6 +122,18 @@ namespace Inkscape const Glib::RefPtr get_font_list () const; + /** Returns the ListStore with the styles + * + */ + const Glib::RefPtr + get_style_list () const; + + /** Returns the ListStore with the styles - trial + * + */ + const Glib::RefPtr + get_style_list_trial () const; + /** Updates font list to include fonts in document * */ @@ -96,13 +148,119 @@ namespace Inkscape static Inkscape::FontLister* get_instance () { - static Inkscape::FontLister* instance = new Inkscape::FontLister(); + static Inkscape::FontLister* instance = new Inkscape::FontLister(); return instance; } - Gtk::TreePath + /** Takes a hand written font spec and returns a Pango generated one in + * standard form. + */ + Glib::ustring canonize_fontspec( Glib::ustring fontspec ); + + /** Find closest system font to given font. + */ + Glib::ustring system_fontspec( Glib::ustring fontspec ); + + /** Gets font-family and style from fontspec. + * font-family and style returned. + */ + std::pair + ui_from_fontspec (Glib::ustring fontspec); + + /** Sets font-family and style after a selection change. + * New font-family and style returned. + */ + std::pair + selection_update (); + + /** Changes font-family, updating style list and attempting to find + * closest style to current_style style (if check_style is true). + * New font-family and style returned. + * Does NOT update current_family and current_style. + * (For potential use in font-selector which doesn't update until + * "Apply" button clicked.) + */ + std::pair + new_font_family (Glib::ustring family, gboolean check_style = true); + + /** Sets font-family, updating style list and attempting + * to find closest style to old current_style. + * New font-family and style returned. + * Updates current_family and current_style. + * (For use in text-toolbar where update is immediate.) + */ + std::pair + set_font_family (Glib::ustring family, gboolean check_style = true); + + Glib::ustring + get_font_family () + { + return current_family; + } + + /* Not Used */ + void + new_font_style (Glib::ustring style); + + /** Sets style. Does not validate style for family. + */ + void + set_font_style (Glib::ustring style); + + Glib::ustring + get_font_style () + { + 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 + 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 ); + + Gtk::TreeModel::Row get_row_for_font (Glib::ustring family); + Gtk::TreePath + get_path_for_font (Glib::ustring family); + + Gtk::TreeModel::Row + get_row_for_style (Glib::ustring style); + + Gtk::TreePath + get_path_for_style (Glib::ustring style); + + std::pair + get_paths (Glib::ustring family, Glib::ustring style); + + /** Return best style match for new font given style for old font. + */ + Glib::ustring + get_best_style_match (Glib::ustring family, Glib::ustring style); + + /* Not Used */ const NRNameList get_name_list () const { @@ -116,7 +274,30 @@ namespace Inkscape NRNameList families; Glib::RefPtr font_list_store; + Glib::RefPtr style_list_store; + Glib::RefPtr 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. + */ + Glib::ustring current_family; + Glib::ustring current_style; + Glib::ustring current_fontspec; + + /** fontspec of system font closest to current_fontspec. + * (What the system will use to display current_fontspec.) + */ + Glib::ustring current_fontspec_system; + + /** 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; }; } @@ -125,7 +306,7 @@ namespace Inkscape static gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { gchar* text = 0; - gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.font + gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family return (text && strcmp(text,"#") == 0); } -- cgit v1.2.3 From 7b9700a6e7cd59b45a0707b3225e0b45d5061cfc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 19 Feb 2013 11:42:43 +0100 Subject: Small bug fix (fix format of font-family in some cases). (bzr r12133) --- src/libnrtype/font-lister.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 91671f627..2c22ecff0 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -503,10 +503,10 @@ namespace Inkscape //std::cout << "FontLister:set_css: " << std::endl; - PangoFontDescription *desc = pango_font_description_from_string( current_fontspec.c_str() ); sp_repr_css_set_property (css, "-inkscape-font-specification", current_fontspec.c_str() ); - sp_repr_css_set_property (css, "font-family", pango_font_description_get_family( desc ) ); + sp_repr_css_set_property (css, "font-family", current_family.c_str() ); //Canonized w/ spaces + PangoFontDescription *desc = pango_font_description_from_string( current_fontspec.c_str() ); PangoWeight weight = pango_font_description_get_weight( desc ); switch ( weight ) { case PANGO_WEIGHT_THIN: -- cgit v1.2.3 From 59732b62d22fa2b395eb0cb0e5fb079ab71e66cb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 23 Feb 2013 12:47:01 +0100 Subject: Small step towards fixing font-family scrolling issue (bug 1122553). (bzr r12142) --- src/libnrtype/font-lister.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++ src/libnrtype/font-lister.h | 18 ++++++++++++ 2 files changed, 85 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 2c22ecff0..57a019e96 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -68,6 +68,7 @@ namespace Inkscape (*treeModelIter)[FontList.onSystem] = true; } } + current_family_row = 0; current_family = "sans-serif"; current_style = "Normal"; current_fontspec = "sans-serif"; // Empty style -> Normal @@ -107,6 +108,18 @@ namespace Inkscape font_list_store->freeze_notify(); + /* Find if current row is in document or system part of list */ + gboolean row_is_system = false; + if( current_family_row > -1 ) { + Gtk::TreePath path; + path.push_back( current_family_row ); + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + row_is_system = (*iter)[FontList.onSystem]; + // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; + } + } + /* Clear all old document font-family entries */ Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); while( iter != font_list_store->children().end() ) { @@ -162,6 +175,32 @@ namespace Inkscape (*treeModelIter)[FontList.onSystem] = false; } + /* Now we do a song and dance to find the correct row as the row corresponding + * to the current_family may have changed. We can't simply search for the + * family name in the list since it can occur twice, once in the document + * font family part and once in the system font family part. Above we determined + * which part it is in. + */ + if( current_family_row > -1 ) { + int start = 0; + if( row_is_system ) start = fontfamilies.size(); + int length = font_list_store->children().size(); + for( int i = 0; i < length; ++i ) { + int row = i + start; + if( row >= length ) row -= length; + Gtk::TreePath path; + path.push_back( row ); + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + if( current_family.compare( (*iter)[FontList.family] ) == 0 ) { + current_family_row = row; + break; + } + } + } + } + // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; + font_list_store->thaw_notify(); } @@ -456,6 +495,34 @@ namespace Inkscape return ui; } + + std::pair + FontLister::set_font_family (int row, gboolean check_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family( row ): " << row << std::endl; +#endif + + current_family_row = row; + Gtk::TreePath path; + path.push_back( row ); + Glib::ustring new_family = current_family; + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + current_family = (*iter)[FontList.family]; + } + + std::pair ui = set_font_family( new_family, check_style ); + +#ifdef DEBUG_FONT + std::cout << "FontLister::set_font_family( row ): end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return ui; + } + + // void // FontLister::new_font_style (Glib::ustring new_style) { // // Is this needed? What do we do? diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 10a269771..aaa996247 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -187,17 +187,34 @@ namespace Inkscape * to find closest style to old current_style. * New font-family and style returned. * Updates current_family and current_style. + * Calls new_font_family(). * (For use in text-toolbar where update is immediate.) */ std::pair set_font_family (Glib::ustring family, gboolean check_style = true); + /** Sets font-family from row in list store. + * The row can be used to determine if we are in the + * document or system part of the font-family list. + * This is needed to handle scrolling through the + * font-family list correctly. + * Calls set_font_family(). + */ + std::pair + set_font_family (int row, gboolean check_style = true); + Glib::ustring get_font_family () { return current_family; } + int + get_font_family_row () + { + return current_family_row; + } + /* Not Used */ void new_font_style (Glib::ustring style); @@ -280,6 +297,7 @@ namespace Inkscape /** Info for currently selected font (what is shown in the UI). * May include font-family lists and fonts not on system. */ + int current_family_row; Glib::ustring current_family; Glib::ustring current_style; Glib::ustring current_fontspec; -- cgit v1.2.3 From ae56bd6349992b95e44850a930440f81538545c5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 24 Feb 2013 15:31:21 +0100 Subject: Fix for font-family scrolling in text-tool tool-controls (bug 1122553). (bzr r12149) --- src/libnrtype/font-lister.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 57a019e96..5e67c5991 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -10,7 +10,6 @@ #include #include #include - #include "font-lister.h" #include "FontFactory.h" @@ -364,10 +363,11 @@ namespace Inkscape set_font_family( ui.first ); #ifdef DEBUG_FONT - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: :" << current_family << ":" << std::endl; - std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; std::cout << "FontLister::selection_update: exit" << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif @@ -485,6 +485,7 @@ namespace Inkscape current_fontspec_system = system_fontspec( current_fontspec ); #ifdef DEBUG_FONT + std::cout << " family_row: :" << current_family_row << ":" << std::endl; std::cout << " canonized: :" << current_fontspec << ":" << std::endl; std::cout << " system: :" << current_fontspec_system << ":" << std::endl; std::cout << " family: :" << current_family << ":" << std::endl; @@ -510,7 +511,7 @@ namespace Inkscape Glib::ustring new_family = current_family; Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); if( iter ) { - current_family = (*iter)[FontList.family]; + new_family = (*iter)[FontList.family]; } std::pair ui = set_font_family( new_family, check_style ); -- cgit v1.2.3 From f71eb7bbf5a09eb685c655762465cea23f5f9aee Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 1 Mar 2013 17:48:58 +0100 Subject: Convert font-selector, text-edit, glyphs to use updated font-lister (use fontspec rather than font). (bzr r12164) --- src/libnrtype/font-lister.cpp | 76 +++++++++++++++++++++++++++---------------- src/libnrtype/font-lister.h | 52 ++++++++--------------------- 2 files changed, 62 insertions(+), 66 deletions(-) (limited to 'src/libnrtype') 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 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 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 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 - 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 get_style_list () const; - /** Returns the ListStore with the styles - trial - * - */ - const Glib::RefPtr - get_style_list_trial () const; - /** Updates font list to include fonts in document * */ @@ -173,6 +166,19 @@ namespace Inkscape std::pair selection_update (); + /** Sets current_fontspec, etc. If check is false, won't + * try to find best style match (assumes style in fontspec + * valid for given font-family). + */ + void + set_fontspec (Glib::ustring fontspec, 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 - 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 font_list_store; Glib::RefPtr style_list_store; - Glib::RefPtr 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; -- cgit v1.2.3 From 168941350f6b28eab1a60e25682f1e958321ab11 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 4 Mar 2013 17:24:16 +0100 Subject: Use our own font_description_better_match which takes into account font-stretch and font-variant. (bzr r12171) --- src/libnrtype/font-lister.cpp | 120 +++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 42 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 97d3c66d4..1e3ba01e9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -449,35 +449,7 @@ namespace Inkscape // Find best match to the style from the old font-family to the // styles available with the new font. // TODO: Maybe check if an exact match exists before using Pango. - Glib::ustring best_style = current_style; - if( check_style ) { - //std::cout << " Trying to match: " << current_fontspec << std::endl; - PangoFontDescription *desc_old - = pango_font_description_from_string( current_fontspec.c_str() ); - PangoFontDescription* desc_best = NULL; - - for (GList *l=styles; l; l = l->next) { - Glib::ustring candidate = new_family + ", " + (char*)l->data; - PangoFontDescription* desc_candidate - = pango_font_description_from_string( candidate.c_str() ); - //std::cout << " Testing: " << pango_font_description_to_string( desc_candidate ) << std::endl; - if( pango_font_description_better_match( desc_old, desc_best, desc_candidate ) ) { - pango_font_description_free( desc_best ); - desc_best = desc_candidate; - //std::cout << " ... better: " << std::endl; - } else { - pango_font_description_free( desc_candidate ); - //std::cout << " ... not better: " << std::endl; - } - } - if( desc_best ) { - pango_font_description_unset_fields( desc_best, PANGO_FONT_MASK_FAMILY ); - best_style = pango_font_description_to_string( desc_best ); - } - - if( desc_old ) pango_font_description_free( desc_old ); - if( desc_best ) pango_font_description_free( desc_best ); - } + Glib::ustring best_style = get_best_style_match( new_family, current_style ); #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; @@ -863,6 +835,64 @@ namespace Inkscape throw STYLE_NOT_FOUND; } + static gint + compute_distance (const PangoFontDescription *a, + const PangoFontDescription *b ) { + + // Weight: multiples of 100 + gint distance = abs( pango_font_description_get_weight( a ) - + pango_font_description_get_weight( b ) ); + + distance += 10000 * abs( pango_font_description_get_stretch( a ) - + pango_font_description_get_stretch( b ) ); + + PangoStyle style_a = pango_font_description_get_style( a ); + PangoStyle style_b = pango_font_description_get_style( b ); + if( style_a != style_b ) { + if( (style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || + (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC) ) { + distance += 1000; // Oblique and italic are almost the same + } else { + distance += 100000; // Normal vs oblique/italic, not so similar + } + } + + // Normal vs small-caps + distance += 1000000 * abs( pango_font_description_get_variant( a ) - + pango_font_description_get_variant( b ) ); + return distance; + } + + // This is inspired by pango_font_description_better_match, but that routine + // always returns false if variant or stretch are different. This means, for + // example, that PT Sans Narrow with style Bold Condensed is never matched + // to another font-family with Bold style. + gboolean + font_description_better_match( PangoFontDescription* target, + PangoFontDescription* old_desc, + PangoFontDescription* new_desc ) { + + if( old_desc == NULL ) return true; + if( new_desc == NULL ) return false; + + int old_distance = compute_distance( target, old_desc ); + int new_distance = compute_distance( target, new_desc ); + //std::cout << "font_description_better_match: old: " << old_distance << std::endl; + //std::cout << " new: " << new_distance << std::endl; + + return (new_distance < old_distance ); + } + + // void + // font_description_dump( PangoFontDescription* target ) { + // std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; + // std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; + // std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; + // std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; + // std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; + // std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; + // } + /* Returns style string */ // TODO: Remove or turn into function to be used by new_font_family. Glib::ustring @@ -873,7 +903,7 @@ namespace Inkscape std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; #endif - Glib::ustring font_string = family + " " + target_style; + Glib::ustring fontspec = family + ", " + target_style; Gtk::TreeModel::Row row; try { @@ -883,31 +913,37 @@ namespace Inkscape return (target_style); } - PangoFontDescription* target = pango_font_description_from_string( font_string.c_str() ); + PangoFontDescription* target = pango_font_description_from_string( fontspec.c_str() ); PangoFontDescription* best = NULL; - //std::cout << " Target: " << pango_font_description_to_string( target ) << std::endl; + //font_description_dump( target ); GList* styles = row[FontList.styles]; for (GList *l=styles; l; l = l->next) { - Glib::ustring font_string_test = family + " " + (char*)l->data; - PangoFontDescription* candidate = pango_font_description_from_string( font_string_test.c_str() ); - // std::cout << " Testing: " << pango_font_description_to_string( candidate ) << std::endl; - if( pango_font_description_better_match( target, best, candidate ) ) { - best = candidate; + Glib::ustring fontspec = family + ", " + (char*)l->data; + PangoFontDescription* candidate = pango_font_description_from_string( fontspec.c_str() ); + //font_description_dump( candidate ); + //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; + if( font_description_better_match( target, best, candidate ) ) { + pango_font_description_free( best ); + best = candidate; + //std::cout << " ... better: " << std::endl; + } else { + pango_font_description_free( candidate ); + //std::cout << " ... not better: " << std::endl; } } - Glib::ustring best_style; + Glib::ustring best_style = target_style; if( best ) { - //std::cout << " Best: " << pango_font_description_to_string( best ) << std::endl; pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY ); best_style = pango_font_description_to_string( best ); - } else { - //std::cout << " Failed: " << family << std::endl; - best_style = target_style; } + if( target ) pango_font_description_free( target ); + if( best ) pango_font_description_free( best ); + + #ifdef DEBUG_FONT std::cout << " Returning: " << best_style << std::endl; std::cout << "FontLister::get_best_style_match: exit" << std::endl; -- cgit v1.2.3 From 4a5edfac0c0408d97c1ecd1b547cea87d06ab113 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 7 Mar 2013 22:03:29 +0100 Subject: Disable "faux" or "synthesized" font faces. (bzr r12177) --- src/libnrtype/FontFactory.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index a9220d867..a1a9ddc89 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -741,6 +741,11 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) continue; } + // Disable synthesized (faux) font faces + if (pango_font_face_is_synthesized(faces[currentFace]) ) { + continue; + } + PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]); if (faceDescr) { Glib::ustring familyUIName = GetUIFamilyString(faceDescr); -- cgit v1.2.3 From 14f6e2bcab3830c642ee4cf3591dc38831485fb1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 8 Mar 2013 12:52:07 +0100 Subject: Restore CSS generic faux faces. (bzr r12182) --- src/libnrtype/FontFactory.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index a1a9ddc89..bb8b0887f 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -741,16 +741,23 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) continue; } - // Disable synthesized (faux) font faces - if (pango_font_face_is_synthesized(faces[currentFace]) ) { - continue; - } - PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]); if (faceDescr) { Glib::ustring familyUIName = GetUIFamilyString(faceDescr); Glib::ustring styleUIName = GetUIStyleString(faceDescr); + // Disable synthesized (faux) font faces except for CSS generic faces + if (pango_font_face_is_synthesized(faces[currentFace]) ) { + if( familyUIName.compare( "sans-serif" ) != 0 && + familyUIName.compare( "serif" ) != 0 && + familyUIName.compare( "monospace" ) != 0 && + familyUIName.compare( "fantasy" ) != 0 && + familyUIName.compare( "cursive" ) != 0 ) { + //std::cout << "faux: " << familyUIName << " | " << styleUIName << std::endl; + continue; + } + } + if (!familyUIName.empty() && !styleUIName.empty()) { // Find the right place to put the style information, adding -- cgit v1.2.3 From f8e68d9b5bf61f2c68e766c4d75cb50240d93364 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 8 Mar 2013 13:31:05 +0100 Subject: Use font-weight names rather than numerical values. Fixes bug when scrolling to URW Chancery L. (bzr r12183) --- src/libnrtype/font-lister.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 1e3ba01e9..712c17915 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -556,13 +556,13 @@ namespace Inkscape PangoWeight weight = pango_font_description_get_weight( desc ); switch ( weight ) { case PANGO_WEIGHT_THIN: - sp_repr_css_set_property (css, "font-weight", "100" ); + sp_repr_css_set_property (css, "font-weight", "thin" ); break; case PANGO_WEIGHT_ULTRALIGHT: - sp_repr_css_set_property (css, "font-weight", "200" ); + sp_repr_css_set_property (css, "font-weight", "extra light" ); break; case PANGO_WEIGHT_LIGHT: - sp_repr_css_set_property (css, "font-weight", "300" ); + sp_repr_css_set_property (css, "font-weight", "light" ); break; case PANGO_WEIGHT_BOOK: sp_repr_css_set_property (css, "font-weight", "380" ); @@ -571,19 +571,19 @@ namespace Inkscape sp_repr_css_set_property (css, "font-weight", "normal" ); break; case PANGO_WEIGHT_MEDIUM: - sp_repr_css_set_property (css, "font-weight", "500" ); + sp_repr_css_set_property (css, "font-weight", "medium" ); break; case PANGO_WEIGHT_SEMIBOLD: - sp_repr_css_set_property (css, "font-weight", "600" ); + sp_repr_css_set_property (css, "font-weight", "semi bold" ); break; case PANGO_WEIGHT_BOLD: sp_repr_css_set_property (css, "font-weight", "bold" ); break; case PANGO_WEIGHT_ULTRABOLD: - sp_repr_css_set_property (css, "font-weight", "800" ); + sp_repr_css_set_property (css, "font-weight", "extra bold" ); break; case PANGO_WEIGHT_HEAVY: - sp_repr_css_set_property (css, "font-weight", "900" ); + sp_repr_css_set_property (css, "font-weight", "black" ); break; case PANGO_WEIGHT_ULTRAHEAVY: sp_repr_css_set_property (css, "font-weight", "1000" ); -- cgit v1.2.3 From c2fc1ca64cb822e76211d145a2ebcd6ff62a66d2 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 14 Mar 2013 10:28:27 +0000 Subject: Fix another tonne of forward declaration tags (bzr r12204) --- src/libnrtype/Layout-TNG.h | 2 +- src/libnrtype/font-style-to-pos.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index f4a09f25b..488a974ea 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -34,7 +34,7 @@ namespace Inkscape { using Inkscape::Extension::Internal::CairoRenderContext; #endif -class SPStyle; +struct SPStyle; class Shape; class SPPrintContext; class SVGLength; diff --git a/src/libnrtype/font-style-to-pos.h b/src/libnrtype/font-style-to-pos.h index 41ba6cf72..56eb391c2 100644 --- a/src/libnrtype/font-style-to-pos.h +++ b/src/libnrtype/font-style-to-pos.h @@ -3,7 +3,7 @@ #include -class SPStyle; +struct SPStyle; NRTypePosDef font_style_to_pos(SPStyle const &style); -- cgit v1.2.3 From 4c75974f2ac6bfe751e583fca37ffdd8b14ea84d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 14 Mar 2013 23:24:17 +0000 Subject: Fix another load of forward declaration tags (bzr r12205) --- src/libnrtype/Layout-TNG.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 488a974ea..0f5f08a53 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -36,7 +36,7 @@ using Inkscape::Extension::Internal::CairoRenderContext; struct SPStyle; class Shape; -class SPPrintContext; +struct SPPrintContext; class SVGLength; class Path; class SPCurve; -- cgit v1.2.3 From 78b82d1a27484ccbfe5fe2d7e14a486b8275ac3a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Fri, 15 Mar 2013 00:39:02 +0000 Subject: Fix even more forward declaration tags (bzr r12206) --- src/libnrtype/Layout-TNG-Output.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1d086b57b..0f853c681 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -26,7 +26,6 @@ namespace Inkscape { namespace Extension { namespace Internal { class CairoRenderContext; - class CairoGlyphInfo; } } } -- cgit v1.2.3 From be604f252f3f917a4b9fba73867980f81b3c8530 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Fri, 15 Mar 2013 01:08:49 +0000 Subject: Fix remaining forward declaration tags (except for unavoidable internal errors in Gtkmm headers) (bzr r12208) --- src/libnrtype/font-lister.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 712c17915..90900baba 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,7 +2,6 @@ # include #endif -#include #include #include #include -- cgit v1.2.3 From 6753a094002684a8f14232934c9cdeba13e00e8e Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 18 Mar 2013 00:36:01 +0000 Subject: Fix -Wunused-function warnings (bzr r12221) --- src/libnrtype/font-lister.cpp | 21 +++++++++++++++++++++ src/libnrtype/font-lister.h | 10 +++------- 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 90900baba..5b495d14d 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -969,6 +969,17 @@ namespace Inkscape } // Helper functions + +// Separator function (if true, a separator will be drawn) +gboolean font_lister_separator_func(GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/) +{ + gchar* text = 0; + gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family + return (text && strcmp(text,"#") == 0); +} + void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, GtkCellRenderer *cell, GtkTreeModel *model, @@ -1042,3 +1053,13 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, g_object_set (G_OBJECT (cell), "markup", markup.c_str(), NULL); } +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 5c48bf7a8..5a8f578d9 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -296,13 +296,9 @@ namespace Inkscape } // Helper functions -// Separator function (if true, a separator will be drawn) -static gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) -{ - gchar* text = 0; - gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family - return (text && strcmp(text,"#") == 0); -} +gboolean font_lister_separator_func(GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/); void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, GtkCellRenderer *cell, -- cgit v1.2.3 From 9cef6be6fbc166e1d97b258611905af8b92a0317 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 24 Mar 2013 18:41:57 -0700 Subject: Fixed uninitialized variables & misc warnings. (bzr r12241) --- src/libnrtype/font-lister.cpp | 98 +++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 50 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 5b495d14d..75d9d29fa 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -373,89 +373,87 @@ 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 ui = ui_from_fontspec( new_fontspec ); - Glib::ustring new_family = ui.first; - Glib::ustring new_style = ui.second; +// 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 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; + 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 ); - } - + set_font_family( new_family, false ); + set_font_style( new_style ); +} - // TODO: use to determine font-selector best style - std::pair - FontLister::new_font_family (Glib::ustring new_family, gboolean check_style ) { +// TODO: use to determine font-selector best style +std::pair FontLister::new_font_family (Glib::ustring new_family, gboolean /*check_style*/ ) +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::new_font_family: " << new_family << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::new_font_family: " << new_family << std::endl; #endif - // No need to do anything if new family is same as old family. - if( new_family.compare( current_family ) == 0 ) { + // No need to do anything if new family is same as old family. + if ( new_family.compare( current_family ) == 0 ) { #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif return std::make_pair( current_family, current_style ); - } + } - // We need to do two things: - // 1. Update style list for new family. - // 2. Select best valid style match to old style. + // We need to do two things: + // 1. Update style list for new family. + // 2. Select best valid style match to old style. - // For finding style list, use list of first family in font-family list. - GList* styles = NULL; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { + // For finding style list, use list of first family in font-family list. + GList* styles = NULL; + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter; if( new_family.compare( row[FontList.family] ) == 0 ) { - styles = row[FontList.styles]; - break; + styles = row[FontList.styles]; + break; } ++iter; - } + } - // Newly typed in font-family may not yet be in list... use default list. - // TODO: if font-family is list, check if first family in list is on system - // and set style accordingly. - if( styles == NULL ) { + // Newly typed in font-family may not yet be in list... use default list. + // TODO: if font-family is list, check if first family in list is on system + // and set style accordingly. + if( styles == NULL ) { styles = default_styles; - } + } - // Update style list. - style_list_store->freeze_notify(); - style_list_store->clear(); + // Update style list. + style_list_store->freeze_notify(); + style_list_store->clear(); - for (GList *l=styles; l; l = l->next) { + for (GList *l=styles; l; l = l->next) { Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); (*treeModelIter)[FontStyleList.styles] = (char*)l->data; - } + } - style_list_store->thaw_notify(); + style_list_store->thaw_notify(); - // Find best match to the style from the old font-family to the - // styles available with the new font. - // TODO: Maybe check if an exact match exists before using Pango. - Glib::ustring best_style = get_best_style_match( new_family, current_style ); + // Find best match to the style from the old font-family to the + // styles available with the new font. + // TODO: Maybe check if an exact match exists before using Pango. + Glib::ustring best_style = get_best_style_match( new_family, current_style ); #ifdef DEBUG_FONT - std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( new_family, best_style ); - } + return std::make_pair( new_family, best_style ); +} std::pair FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) { -- cgit v1.2.3 From 0cdd007ebf8dcfbd39c1d36ab53f43617eb692df Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 25 Mar 2013 17:42:31 +0000 Subject: Workaround usage of deprecated glib symbols in 3rd party libraries Fixed bugs: - https://launchpad.net/bugs/1122774 (bzr r12243) --- src/libnrtype/font-lister.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 75d9d29fa..a0db12c2b 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,13 +2,14 @@ # include #endif +#include +#include + #include #include #include #include -#include -#include #include "font-lister.h" #include "FontFactory.h" -- cgit v1.2.3 From 77a8c9fa992c28c916d783727965aa6a05ed0071 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 26 Mar 2013 15:43:02 +0100 Subject: Revert r12183 and replace with better work-around for Pango bug (incorrect font-family if weight is expressed as a number). Also fixed bug with font-stretch. (bzr r12246) --- src/libnrtype/font-lister.cpp | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index a0db12c2b..ace4a9ca9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -286,6 +286,14 @@ namespace Inkscape const gchar* family = pango_font_description_get_family(descr); Glib::ustring Family = family; + // PANGO BUG... + // A font spec of Delicious, 500 Italic should result in a family of 'Delicious' + // and a style of 'Medium Italic'. It results instead with: a family of + // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers + // at the end of the family: match ",[1-9]00^". + Glib::RefPtr weight = Glib::Regex::create(",[1-9]00$"); + Family = weight->replace( Family, 0, "", Glib::REGEX_MATCH_PARTIAL ); + // Pango canonized strings remove space after comma between family names. Put it back. size_t i = 0; while( (i = Family.find(",", i)) != std::string::npos) { @@ -325,7 +333,7 @@ namespace Inkscape // From style if( fontspec.empty() ) { - //std::cout << " Attempting desktop style" << std::endl; + //std::cout << " Attempting desktop style" << std::endl; int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); @@ -338,7 +346,7 @@ namespace Inkscape // From preferences if( fontspec.empty() ) { - //std::cout << " Attempting preferences" << std::endl; + //std::cout << " Attempting preferences" << std::endl; sp_style_read_from_prefs(query, "/tools/text"); fontspec = fontspec_from_style( query ); //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; @@ -347,7 +355,7 @@ namespace Inkscape // From thin air if( fontspec.empty() ) { - //std::cout << " Attempting thin air" << std::endl; + //std::cout << " Attempting thin air" << std::endl; fontspec = current_family + ", " + current_style; //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; } @@ -554,13 +562,13 @@ std::pair FontLister::new_font_family (Glib::ustri PangoWeight weight = pango_font_description_get_weight( desc ); switch ( weight ) { case PANGO_WEIGHT_THIN: - sp_repr_css_set_property (css, "font-weight", "thin" ); + sp_repr_css_set_property (css, "font-weight", "100" ); break; case PANGO_WEIGHT_ULTRALIGHT: - sp_repr_css_set_property (css, "font-weight", "extra light" ); + sp_repr_css_set_property (css, "font-weight", "200" ); break; case PANGO_WEIGHT_LIGHT: - sp_repr_css_set_property (css, "font-weight", "light" ); + sp_repr_css_set_property (css, "font-weight", "300" ); break; case PANGO_WEIGHT_BOOK: sp_repr_css_set_property (css, "font-weight", "380" ); @@ -569,19 +577,19 @@ std::pair FontLister::new_font_family (Glib::ustri sp_repr_css_set_property (css, "font-weight", "normal" ); break; case PANGO_WEIGHT_MEDIUM: - sp_repr_css_set_property (css, "font-weight", "medium" ); + sp_repr_css_set_property (css, "font-weight", "500" ); break; case PANGO_WEIGHT_SEMIBOLD: - sp_repr_css_set_property (css, "font-weight", "semi bold" ); + sp_repr_css_set_property (css, "font-weight", "600" ); break; case PANGO_WEIGHT_BOLD: sp_repr_css_set_property (css, "font-weight", "bold" ); break; case PANGO_WEIGHT_ULTRABOLD: - sp_repr_css_set_property (css, "font-weight", "extra bold" ); + sp_repr_css_set_property (css, "font-weight", "800" ); break; case PANGO_WEIGHT_HEAVY: - sp_repr_css_set_property (css, "font-weight", "black" ); + sp_repr_css_set_property (css, "font-weight", "900" ); break; case PANGO_WEIGHT_ULTRAHEAVY: sp_repr_css_set_property (css, "font-weight", "1000" ); @@ -729,11 +737,11 @@ std::pair FontLister::new_font_family (Glib::ustri switch (style->font_stretch.computed) { case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: - fontspec += " extra_condensed"; + fontspec += " extra-condensed"; break; case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: - fontspec += " extra_condensed"; + fontspec += " extra-condensed"; break; case SP_CSS_FONT_STRETCH_CONDENSED: @@ -742,7 +750,7 @@ std::pair FontLister::new_font_family (Glib::ustri break; case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: - fontspec += " semi_condensed"; + fontspec += " semi-condensed"; break; case SP_CSS_FONT_STRETCH_NORMAL: @@ -750,7 +758,7 @@ std::pair FontLister::new_font_family (Glib::ustri break; case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: - fontspec += " semi_expanded"; + fontspec += " semi-expanded"; break; case SP_CSS_FONT_STRETCH_EXPANDED: @@ -759,11 +767,11 @@ std::pair FontLister::new_font_family (Glib::ustri break; case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: - fontspec += " extra_expanded"; + fontspec += " extra-expanded"; break; case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: - fontspec += " ultra_expanded"; + fontspec += " ultra-expanded"; break; default: -- cgit v1.2.3 From d2bba282171a9e2c70a624794650689ec4531047 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Mar 2013 16:03:49 +0000 Subject: Fix Glibmm inclusions for Gtk+ 3 builds and implement a Gtk+ 3 compatible check for X11 backend Fixed bugs: - https://launchpad.net/bugs/1160252 - https://launchpad.net/bugs/1122774 (bzr r12247) --- src/libnrtype/font-lister.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index ace4a9ca9..39a04914b 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -9,7 +9,6 @@ #include #include -#include #include "font-lister.h" #include "FontFactory.h" @@ -22,6 +21,8 @@ #include "sp-root.h" #include "xml/repr.h" +#include + //#define DEBUG_FONT namespace Inkscape -- cgit v1.2.3 From d6b24c1540e9a7f388dd1500c762f73586119280 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Mar 2013 23:46:08 +0000 Subject: Stop using top-level glibmm header (bzr r12251) --- src/libnrtype/FontFactory.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index bb8b0887f..74c706a1b 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -14,9 +14,7 @@ # include "config.h" #endif -#include -#include -#include // _() +#include #include #include "libnrtype/FontFactory.h" #include "libnrtype/font-instance.h" -- cgit v1.2.3 From d19db89e2e22d4e09c539bd42823d511aebb669f Mon Sep 17 00:00:00 2001 From: David Mathog <> Date: Wed, 19 Jun 2013 19:20:33 +0200 Subject: changes_2013_05_22a.patch: 1. Resolves issue of bug #988601 message 170 (Support of 'Unset' styles in EMF export). 2. Implements CSS 3 (and CSS 2) text-decoration support. Note that it does not yet provide any method of adding these features - at present it just shows whatever is in the SVG. This new code is also used to display EMF/WMF strike-through and underline text decorations when these files are read in. Those decorations may also be written out to EMF/WMF. Other text decoration features, like overline, or dotted lines, are dropped. For SVG text-decoration -line, -style, -color are all implemented. CSS3 provides two ways to represent the same state, this code uses the compound text-decoration method rather than the 3 fields method. Also it leaves out keywords that are not needed and would break backwards compatibility. For instance: text-decoration: underline solid is valid, but would break CSS2. Solid is the default, so that sort of case is written as: text-decoration: underline If the state is CSS3 specific all of the needed fields are of course include, like text-decoration: underline wavy red 3. It incorporates the fix for bug 1181326 (Text edit mishandles span of just colored spaces) 4. It incorporates further changes to text editing so that style can be changed on spans consisting of only spaces when text decorations are present in the span. 5. It incorporates code to disable text decorations when text so marked is mapped onto a path. 6. Fixed more bugs in Hebrew language support than I can remember. Hebrew language export/import to EMF now works quite well. (See the examples in libTERE v 0.7.) WMF does not support unicode and for all intents and purposes Inkscape has no way to read or write Hebrew to it. Some of more important things that now work that didn't (or didn't always): Hebrew diacritical marks, R/L/center justification, and bidirectional text. The Hebrew fonts "Ezra SIL" and "EZRA SIL SR" should be installed before viewing the libTERE examples, otherwise font substitutions will cause some text shifts. 7. Implemented font failover in Text Reassemble, which makes the process more robust. (Again, see the examples in libTERE. ) (bzr r11668.1.71) --- src/libnrtype/FontInstance.cpp | 35 ++++ src/libnrtype/Layout-TNG-Compute.cpp | 234 ++++++++++++++++++------- src/libnrtype/Layout-TNG-Output.cpp | 324 ++++++++++++++++++++++++----------- src/libnrtype/Layout-TNG.h | 4 + src/libnrtype/font-instance.h | 2 + 5 files changed, 440 insertions(+), 159 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 61225ad0c..fd0cdd3d4 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -675,6 +675,41 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) return true; } +bool font_instance::FontDecoration( + double &underline_position, double &underline_thickness, + double &linethrough_position, double &linethrough_thickness +){ + if ( pFont == NULL ) { + return false; + } + InitTheFace(); + if ( theFace == NULL ) { + return false; + } +#ifdef USE_PANGO_WIN32 + OUTLINETEXTMETRIC otm; + if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) { + return false; + } + double scale=1.0/daddy->fontSize; + underline_position = fabs(otm.otmUnderscorePosition *scale); + underline_thickness = fabs(otm.otmUnderscoreSize *scale); + linethrough_position = fabs(otm.otmStrikeoutPosition *scale); + linethrough_thickness = fabs(otm.otmStrikeoutSize *scale); +#else + if ( theFace->units_per_EM == 0 ) { + return false; // bitmap font + } + underline_position = fabs(((double)theFace->underline_position )/((double)theFace->units_per_EM)); + underline_thickness = fabs(((double)theFace->underline_thickness)/((double)theFace->units_per_EM)); + // there is no specific linethrough information, mock it up from other font fields + linethrough_position = fabs(((double)theFace->ascender / 3.0 )/((double)theFace->units_per_EM)); + linethrough_thickness = fabs(((double)theFace->underline_thickness)/((double)theFace->units_per_EM)); +#endif + return true; +} + + bool font_instance::FontSlope(double &run, double &rise) { run = 0.0; diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7e684e7e3..1b2704a7e 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -120,8 +120,8 @@ class Layout::Calculator BrokenSpan. */ struct UnbrokenSpan { PangoGlyphString *glyph_string; - int pango_item_index; /// index into _para.pango_items, or -1 if this is style only - unsigned input_index; /// index into Layout::_input_stream + int pango_item_index; /// index into _para.pango_items, or -1 if this is style only + unsigned input_index; /// index into Layout::_input_stream Glib::ustring::const_iterator input_stream_first_character; double font_size; LineHeight line_height; /// This is not the CSS line-height attribute! @@ -213,6 +213,43 @@ class Layout::Calculator /* *********************************************************************************************************/ // Per-line functions +/** + * For debugging, not called in distributed code + * + * Input: para->first_input_index, para->pango_items + */ +static void dumpPangoItemsOut(ParagraphInfo *para){ + std::cout << "Pango items: " << para->pango_items.size() << std::endl; + for(unsigned pidx = 0 ; pidx < para->pango_items.size(); pidx++){ + std::cout + << "idx: " << pidx + << " offset: " + << para->pango_items[pidx].item->offset + << " length: " + << para->pango_items[pidx].item->length + << std::endl; + } +} + +/** + * For debugging, not called in distributed code + * + * Input: para->first_input_index, para->pango_items + */ +static void dumpUnbrokenSpans(ParagraphInfo *para){ + std::cout << "Unbroken Spans: " << para->unbroken_spans.size() << std::endl; + for(unsigned uidx = 0 ; uidx < para->unbroken_spans.size(); uidx++){ + std::cout + << "idx: " << uidx + << " pango_item_index: " << para->unbroken_spans[uidx].pango_item_index + << " input_index: " << para->unbroken_spans[uidx].input_index + << " char_index_in_para: " << para->unbroken_spans[uidx].char_index_in_para + << " text_bytes: " << para->unbroken_spans[uidx].text_bytes + << std::endl; + } +} + + bool _goToNextWrapShape(); @@ -246,8 +283,10 @@ class Layout::Calculator { span->setZero(); - if (span->start.iter_span->dx._set && span->start.char_byte == 0) - span->width += span->start.iter_span->dx.computed; + if (span->start.iter_span->dx._set && span->start.char_byte == 0){ + if(para.direction == RIGHT_TO_LEFT){ span->width -= span->start.iter_span->dx.computed; } + else { span->width += span->start.iter_span->dx.computed; } + } if (span->start.iter_span->pango_item_index == -1) { // if this is a style-only span there's no text in it @@ -510,15 +549,19 @@ class Layout::Calculator x = 0.0; } else { direction_sign = -1.0; - if (para.alignment == FULL && !_flow._input_wrap_shapes.empty()) + if (para.alignment == FULL && !_flow._input_wrap_shapes.empty()){ x = it_chunk->scanrun_width; - else + } + else { x = it_chunk->text_width; + } } for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { // begin adding spans to the list UnbrokenSpan const &unbroken_span = *it_span->start.iter_span; + double x_in_span_last = 0.0; // set at the END when a new cluster starts + double x_in_span = 0.0; // set from the preceding at the START when a new cluster starts. if (it_span->start.char_byte == 0) { // Start of an unbroken span, we might have dx, dy or rotate still to process @@ -535,7 +578,6 @@ class Layout::Calculator } Layout::Span new_span; - double x_in_span = 0.0; new_span.in_chunk = _flow._chunks.size() - 1; new_span.line_height = unbroken_span.line_height; @@ -581,14 +623,19 @@ class Layout::Calculator InputStreamTextSource const *text_source = static_cast(_flow._input_stream[unbroken_span.input_index]); Glib::ustring::const_iterator iter_source_text = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte) ; unsigned char_index_in_unbroken_span = it_span->start.char_index; - unsigned cluster_start_char_index = _flow._characters.size(); - double font_size_multiplier = new_span.font_size / (PANGO_SCALE * _font_factory_size_multiplier); + double font_size_multiplier = new_span.font_size / (PANGO_SCALE * _font_factory_size_multiplier); + int log_cluster_size_glyphs = 0; // Number of glyphs in this log_cluster + int log_cluster_size_chars = 0; // Number of characters in this log_cluster + unsigned end_byte = 0; for (unsigned glyph_index = it_span->start_glyph_index ; glyph_index < it_span->end_glyph_index ; glyph_index++) { - unsigned char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); - if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start) - cluster_start_char_index = _flow._characters.size(); - + unsigned char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); + int newcluster = 0; + if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start){ + newcluster = 1; + x_in_span = x_in_span_last; + } + if (unbroken_span.glyph_string->log_clusters[glyph_index] < (int)unbroken_span.text_bytes && *iter_source_text == UNICODE_SOFT_HYPHEN && glyph_index + 1 != it_span->end_glyph_index) { @@ -611,7 +658,7 @@ class Layout::Calculator // create the Layout::Glyph Layout::Glyph new_glyph; new_glyph.glyph = unbroken_span.glyph_string->glyphs[glyph_index].glyph; - new_glyph.in_character = cluster_start_char_index; + new_glyph.in_character = _flow._characters.size(); new_glyph.rotation = glyph_rotate; /* put something like this back in when we do glyph-rotation-horizontal/vertical @@ -652,28 +699,42 @@ class Layout::Calculator } new_glyph.x -= cluster_width; } - _flow._glyphs.push_back(new_glyph); + _flow._glyphs.push_back(new_glyph); // create the Layout::Character(s) double advance_width = new_glyph.width; - unsigned end_byte; - if (glyph_index == (unsigned)unbroken_span.glyph_string->num_glyphs - 1) - end_byte = it_span->start.iter_span->text_bytes; - else { - // output chars for the whole cluster that is commenced by this glyph - if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start) { - int next_cluster_glyph_index = glyph_index + 1; - while (next_cluster_glyph_index < unbroken_span.glyph_string->num_glyphs - && !unbroken_span.glyph_string->glyphs[next_cluster_glyph_index].attr.is_cluster_start) - next_cluster_glyph_index++; - if (next_cluster_glyph_index < unbroken_span.glyph_string->num_glyphs) - end_byte = unbroken_span.glyph_string->log_clusters[next_cluster_glyph_index]; - else - end_byte = it_span->start.iter_span->text_bytes; - } else - end_byte = char_byte; // don't output any chars if we're not at the start of a cluster + if (newcluster){ + // find where the text ends for this log_cluster + end_byte = it_span->start.iter_span->text_bytes; // Upper limit + for(unsigned next_glyph_index = glyph_index+1; next_glyph_index < it_span->end_glyph_index; next_glyph_index++){ + if(unbroken_span.glyph_string->glyphs[next_glyph_index].attr.is_cluster_start){ + end_byte = unbroken_span.glyph_string->log_clusters[next_glyph_index]; + break; + } + } + // Figure out how many glyphs and characters are in the log_cluster. + log_cluster_size_glyphs = 0; + log_cluster_size_chars = 0; + for(; log_cluster_size_glyphs + glyph_index < it_span->end_glyph_index; log_cluster_size_glyphs++){ + if(unbroken_span.glyph_string->log_clusters[glyph_index ] != + unbroken_span.glyph_string->log_clusters[glyph_index + log_cluster_size_glyphs])break; + } + Glib::ustring::const_iterator lclist = iter_source_text; + unsigned lcb = char_byte; + while(lcb < end_byte){ + log_cluster_size_chars++; + lclist++; + lcb = lclist.base() - unbroken_span.input_stream_first_character.base(); + } } while (char_byte < end_byte) { + /* Hack to survive ligatures: in log_cluster keep the number of available chars >= number of glyphs remaining. + When there are no ligatures these two sizes are always the same. + */ + if(log_cluster_size_chars < log_cluster_size_glyphs){ + log_cluster_size_glyphs--; + break; + } Layout::Character new_character; new_character.in_span = _flow._spans.size(); new_character.x = x_in_span; @@ -687,23 +748,27 @@ class Layout::Calculator iter_source_text++; char_index_in_unbroken_span++; char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); + log_cluster_size_chars--; } - advance_width *= direction_sign; - if (new_span.direction != para.direction) { - counter_directional_width_remaining -= advance_width; - x -= advance_width; - x_in_span -= advance_width; - } else { - x += advance_width; - x_in_span += advance_width; + if (newcluster){ + advance_width *= direction_sign; + if (new_span.direction != para.direction) { + counter_directional_width_remaining -= advance_width; + x -= advance_width; + x_in_span_last -= advance_width; + } else { + x += advance_width; + x_in_span_last += advance_width; + } } + newcluster = 0; } } else if (_flow._input_stream[unbroken_span.input_index]->Type() == CONTROL_CODE) { x += static_cast(_flow._input_stream[unbroken_span.input_index])->width; } - new_span.x_end = new_span.x_start + x_in_span; + new_span.x_end = new_span.x_start + x_in_span_last; _flow._spans.push_back(new_span); previous_direction = new_span.direction; } @@ -879,8 +944,9 @@ void Layout::Calculator::ParagraphInfo::free() * * Input: para.first_input_index. * Output: para.direction, para.pango_items, para.char_attributes. + * Returns: the number of spans created by pango_itemize */ -void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) const +void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) const { Glib::ustring para_text; PangoAttrList *attributes_list; @@ -974,8 +1040,9 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font line_height->setZero(); *line_height_multiplier = 1.0; } - else + else { font->FontMetrics(line_height->ascent, line_height->descent, line_height->leading); + } *line_height *= font_size; // yet another borked SPStyle member that we're going to have to fix ourselves @@ -1008,6 +1075,11 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font *line_height_multiplier = LINE_HEIGHT_NORMAL * font_size / line_height->total(); } +bool compareGlyphWidth(const PangoGlyphInfo &a, const PangoGlyphInfo &b) +{ + return (a.geometry.width > b.geometry.width); +} + /** * Split the paragraph into spans. Also call pango_shape() on them. @@ -1034,13 +1106,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const break; // stop at the end of the paragraph else if (control_code->code == ARBITRARY_GAP) { UnbrokenSpan new_span; - new_span.pango_item_index = -1; - new_span.input_index = input_index; - new_span.line_height.ascent = control_code->ascent; + new_span.pango_item_index = -1; + new_span.input_index = input_index; + new_span.line_height.ascent = control_code->ascent; new_span.line_height.descent = control_code->descent; new_span.line_height.leading = 0.0; - new_span.text_bytes = 0; - new_span.char_index_in_para = char_index_in_para; + new_span.text_bytes = 0; + new_span.char_index_in_para = char_index_in_para; para->unbroken_spans.push_back(new_span); TRACE(("add gap span %d\n", para->unbroken_spans.size() - 1)); } @@ -1123,6 +1195,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const g_assert( span_start_byte_in_source + new_span.text_bytes <= text_source->text->bytes() ); g_assert( memchr(text_source->text->data() + span_start_byte_in_source, '\0', static_cast(new_span.text_bytes)) == NULL ); + /* Notes as of 4/29/13. Pango_shape is not generating English language ligatures, but it is generating + them for Hebrew (and probably other similar languages). In the case observed 3 unicode characters (a base + and 2 Mark, nonspacings) are merged into two glyphs (the base + first Mn, the 2nd Mn). All of these map + from glyph to first character of the log_cluster range. This destroys the 1:1 correspondence between + characters and glyphs. A big chunk of the conditional code which immediately follows this call + is there to clean up the resulting mess. + */ pango_shape(text_source->text->data() + span_start_byte_in_source, new_span.text_bytes, ¶->pango_items[pango_item_index].item->analysis, @@ -1134,24 +1213,55 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const // let's reverse the glyphstring on a cluster-by-cluster basis const unsigned nglyphs = new_span.glyph_string->num_glyphs; std::vector infos(nglyphs); - std::vector clusters(nglyphs); - unsigned i, cluster_start = 0; - - for (i = 0 ; i < nglyphs ; ++i) { - if (new_span.glyph_string->glyphs[i].attr.is_cluster_start) { - if (i != cluster_start) { - std::copy(&new_span.glyph_string->glyphs[cluster_start], &new_span.glyph_string->glyphs[i], infos.end() - i); - std::copy(&new_span.glyph_string->log_clusters[cluster_start], &new_span.glyph_string->log_clusters[i], clusters.end() - i); - } - cluster_start = i; + std::vector clusters(nglyphs); + unsigned i, j; + for (i = 0 ; i < nglyphs ; i++)new_span.glyph_string->glyphs[i].attr.is_cluster_start = 0; + for (i = 0 ; i < nglyphs ; i++) { + j=i; + while( (j < nglyphs-1) && + (new_span.glyph_string->log_clusters[j+1] == new_span.glyph_string->log_clusters[i]) + )j++; + /* + CAREFUL, within a log_cluster the order of glyphs may not map 1:1, or + even in the same order, to the original unicode characters!!! Among + other things, diacritical mark glyphs can end up in front of the base + character. That makes determining kerning, even approximately, difficult + later on. To resolve this somewhat sort the glyphs with the same + log_cluster into descending order by width. In theory there should be 1 + that is nonzero, and N that are zero. The order of the zero width ones + does not matter. Sort the glyphs before copying. If ligatures other than with + Mark, nonspacing are ever implemented in Pango this will screw up, for instance + changing "fi" to "if". + */ + if(j - i){ + std::sort(&(new_span.glyph_string->glyphs[i]), &(new_span.glyph_string->glyphs[j+1]), compareGlyphWidth); } - } - if (i != cluster_start) { - std::copy(&new_span.glyph_string->glyphs[cluster_start], &new_span.glyph_string->glyphs[i], infos.end() - i); - std::copy(&new_span.glyph_string->log_clusters[cluster_start], &new_span.glyph_string->log_clusters[i], clusters.end() - i); + + new_span.glyph_string->glyphs[i].attr.is_cluster_start = 1; + std::copy(&new_span.glyph_string->glyphs[ i], &new_span.glyph_string->glyphs[ j+1], infos.end() - j -1); + std::copy(&new_span.glyph_string->log_clusters[i], &new_span.glyph_string->log_clusters[j+1], clusters.end() - j -1); + i = j; } std::copy(infos.begin(), infos.end(), new_span.glyph_string->glyphs); std::copy(clusters.begin(), clusters.end(), new_span.glyph_string->log_clusters); + /* glyphs[].x_offset values are probably out of order within any log_clusters, apparently harmless */ + } + else { // ltr sections are in order but glyphs in a log_cluster following a ligature may not be. Sort, but no block swapping. + const unsigned nglyphs = new_span.glyph_string->num_glyphs; + unsigned i, j; + for (i = 0 ; i < nglyphs ; i++)new_span.glyph_string->glyphs[i].attr.is_cluster_start = 0; + for (i = 0 ; i < nglyphs ; i++) { + j=i; + while( (j < nglyphs-1) && + (new_span.glyph_string->log_clusters[j+1] == new_span.glyph_string->log_clusters[i]) + )j++; + if(j - i){ + std::sort(&(new_span.glyph_string->glyphs[i]), &(new_span.glyph_string->glyphs[j+1]), compareGlyphWidth); + } + new_span.glyph_string->glyphs[i].attr.is_cluster_start = 1; + i = j; + } + /* glyphs[].x_offset values may be out of order within any log_clusters, apparently harmless */ } new_span.pango_item_index = pango_item_index; _computeFontLineHeight(para->pango_items[pango_item_index].font, new_span.font_size, text_source->style, &new_span.line_height, &new_span.line_height_multiplier); @@ -1469,7 +1579,7 @@ bool Layout::Calculator::calculate() if (_scanline_maker == NULL) break; // we're trying to flow past the last wrap shape - _buildPangoItemizationForPara(¶); + _buildPangoItemizationForPara(¶); unsigned para_end_input_index = _buildSpansForPara(¶); if (_flow._input_stream[para.first_input_index]->Type() == TEXT_SOURCE) diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 8ede0a38e..153ef1ef0 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -39,35 +39,44 @@ namespace Text { /* dx array (character widths) and - ky (vertical kerning for entire span) + ky (vertical kerning for entire span) + rtl (+1 for LTR, -1 RTL) are smuggled through to the EMF (ignored by others) as: textN w1 w2 w3 ...wNy1 y2 y3 .. yN - where the widths and y kern values are floats 7 characters wide, including the space + The ndx, widths, y kern, and rtl are all 7 characters wide. ndx and rtl are ints, the widths and ky are + formatted as ' 6f'. */ -char *smuggle_adxky_in(const char *string, int ndx, float *adx, float ky){ - int slen=strlen(string); +char *smuggle_adxkyrtl_in(const char *string, int ndx, float *adx, float ky, float rtl){ + int slen = strlen(string); /* holds: string fake terminator (one \0) - Number of widths (ndxy) - series of widths (ndxy entries) + Number of widths (ndx) + series of widths (ndx entries) fake terminator (one \0) y kern value (one float) + rtl value (one float) real terminator (two \0) */ - int newsize=slen + 1 + 7 + 7*ndx + 1 + 7 + 2; + int newsize=slen + 1 + 7 + 7*ndx + 1 + 7 + 7 + 2; newsize = 8*((7 + newsize)/8); // suppress valgrind messages if it is a multiple of 8 bytes??? - char *smuggle=(char *)calloc(newsize,1); // initialize all bytes, inluding terminators - strcpy(smuggle,string); // text to pass + char *smuggle=(char *)malloc(newsize); + strcpy(smuggle,string); // text to pass, includes the first fake terminator char *cptr = smuggle + slen + 1; // immediately after the first fake terminator sprintf(cptr,"%07d",ndx); // number of widths to pass - cptr+=7; + cptr+=7; // advance over ndx for(int i=0; iType() != TEXT_SOURCE) continue; InputStreamTextSource const *text_source = static_cast(_input_stream[_spans[span_index].in_input_stream_item]); + text_source->style->text_decoration_data.tspan_width = _spans[span_index].width(); + text_source->style->text_decoration_data.ascender = _spans[span_index].line_height.getAscent(); + text_source->style->text_decoration_data.descender = _spans[span_index].line_height.getDescent(); + text_source->style->text_decoration_data.line_gap = _spans[span_index].line_height.getLeading(); + if(!span_index || + (_chunks[_spans[span_index].in_chunk].in_line != _chunks[_spans[span_index-1].in_chunk].in_line)){ + text_source->style->text_decoration_data.tspan_line_start = true; + } + else { + text_source->style->text_decoration_data.tspan_line_start = false; + } + if((span_index == _spans.size() -1) || + (_chunks[_spans[span_index].in_chunk].in_line != _chunks[_spans[span_index+1].in_chunk].in_line)){ + text_source->style->text_decoration_data.tspan_line_end = true; + } + else { + text_source->style->text_decoration_data.tspan_line_end = false; + } + if(_spans[span_index].font){ + double underline_thickness, underline_position, line_through_thickness,line_through_position; + _spans[span_index].font->FontDecoration(underline_position, underline_thickness, line_through_position, line_through_thickness); + text_source->style->text_decoration_data.underline_thickness = underline_thickness; + text_source->style->text_decoration_data.underline_position = underline_position; + text_source->style->text_decoration_data.line_through_thickness = line_through_thickness; + text_source->style->text_decoration_data.line_through_position = line_through_position; + } + else { // can this case ever occur? + text_source->style->text_decoration_data.underline_thickness = + text_source->style->text_decoration_data.underline_position = + text_source->style->text_decoration_data.line_through_thickness = + text_source->style->text_decoration_data.line_through_position = 0.0; + } + DrawingText *nr_text = new DrawingText(in_arena->drawing()); - nr_text->setStyle(text_source->style); + bool first_line_glyph = true; while (glyph_index < (int)_glyphs.size() && _characters[_glyphs[glyph_index].in_character].in_span == span_index) { if (_characters[_glyphs[glyph_index].in_character].in_glyph != -1) { Geom::Affine glyph_matrix; _getGlyphTransformMatrix(glyph_index, &glyph_matrix); - nr_text->addComponent(_spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix); + if(first_line_glyph && text_source->style->text_decoration_data.tspan_line_start){ + first_line_glyph = false; + phase0 = glyph_matrix.translation()[Geom::X]; + } + // save the starting coordinates for the line - these are needed for figuring out dot/dash/wave phase + (void) nr_text->addComponent(_spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix, + _glyphs[glyph_index].width, + _spans[span_index].line_height.getAscent(), + _spans[span_index].line_height.getDescent(), + glyph_matrix.translation()[Geom::X] - phase0 + ); } glyph_index++; } + nr_text->setStyle(text_source->style); nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); } @@ -158,36 +212,30 @@ Geom::OptRect Layout::bounds(Geom::Affine const &transform, int start, int lengt return bbox; } +/* This version is much simpler than the old one +*/ void Layout::print(SPPrintContext *ctx, Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox, Geom::Affine const &ctm) const { -int doUTN=0; -int lasttarget=0; -int newtarget=0; +bool text_to_path = ctx->module->textToPath(); +int oldtarget = 0; +int newtarget = 0; #define MAX_DX 2048 -float hold_dx[MAX_DX]; // For smuggling dx values (character widths) into print functions, unlikely any simple text output will be longer than this. -float ky; // For smuggling y kern value for span -int ndx=0; +float hold_dx[MAX_DX]; // For smuggling dx values (character widths) into print functions, unlikely any simple text output will be longer than this. +float ky; // For smuggling y kern value for span +int ndx = 0; +double rtl = 1.0; // 1 L->R, -1 R->L, constant across a span. 1.0 for t->b b->t??? +Geom::Affine glyph_matrix; if (_input_stream.empty()) return; - - Direction block_progression = _blockProgression(); - bool text_to_path = ctx->module->textToPath(); - doUTN = CanUTN(); // Unicode to Nonunicode translation enabled if true - for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; ) { - if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) { - // invisible glyphs - unsigned same_character = _glyphs[glyph_index].in_character; - while (_glyphs[glyph_index].in_character == same_character) - glyph_index++; - continue; - } - Geom::Affine glyph_matrix; - Span const &span = _spans[_characters[_glyphs[glyph_index].in_character].in_span]; - InputStreamTextSource const *text_source = static_cast(_input_stream[span.in_input_stream_item]); - if (text_to_path || _path_fitted) { + if (!_glyphs.size()) return; // yes, this can happen. + if (text_to_path || _path_fitted) { + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { + if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1)continue; //invisible glyphs + Span const &span = _spans[_characters[_glyphs[glyph_index].in_character].in_span]; Geom::PathVector const * pv = span.font->PathVector(_glyphs[glyph_index].glyph); + InputStreamTextSource const *text_source = static_cast(_input_stream[span.in_input_stream_item]); if (pv) { _getGlyphTransformMatrix(glyph_index, &glyph_matrix); Geom::PathVector temp_pv = (*pv) * glyph_matrix; @@ -196,9 +244,28 @@ int ndx=0; if (!text_source->style->stroke.isNone()) sp_print_stroke(ctx, temp_pv, ctm, text_source->style, pbox, dbox, bbox); } - glyph_index++; - } else { - Geom::Point g_pos(0,0); // all strings are output at (0,0) because we do the translation using the matrix + } + } + else { + /* index by characters, referencing glyphs and spans only as needed */ + double char_x; + int doUTN = CanUTN(); // Unicode to Nonunicode translation enabled if true + Direction block_progression = _blockProgression(); + + for (unsigned char_index = 0 ; char_index < _characters.size() ; ) { + Glib::ustring text_string; // accumulate text for record in this + Geom::Point g_pos(0,0); // all strings are output at (0,0) because we do the translation using the matrix + int glyph_index = _characters[char_index].in_glyph; + if(glyph_index == -1){ // if the character maps to an invisible glyph we cannot know its geometry, so skip it and move on + char_index++; + continue; + } + ky = _glyphs[glyph_index].y; // same value for all positions in a span + unsigned span_index = _characters[char_index].in_span; + Span const &span = _spans[span_index]; + char_x = 0.0; + Glib::ustring::const_iterator text_iter = span.input_stream_first_character; + InputStreamTextSource const *text_source = static_cast(_input_stream[span.in_input_stream_item]); glyph_matrix = Geom::Scale(1.0, -1.0) * (Geom::Affine)Geom::Rotate(_glyphs[glyph_index].rotation); if (block_progression == LEFT_TO_RIGHT || block_progression == RIGHT_TO_LEFT) { glyph_matrix[4] = span.line(this).baseline_y + span.baseline_shift; @@ -208,78 +275,113 @@ int ndx=0; glyph_matrix[4] = span.chunk(this).left_x + span.x_start + _characters[_glyphs[glyph_index].in_character].x; glyph_matrix[5] = span.line(this).baseline_y + span.baseline_shift; } - Glib::ustring::const_iterator span_iter = span.input_stream_first_character; - unsigned char_index = _glyphs[glyph_index].in_character; - unsigned original_span = _characters[char_index].in_span; - while (char_index && _characters[char_index - 1].in_span == original_span) { - char_index--; - span_iter++; + switch(span.direction){ + case Layout::TOP_TO_BOTTOM: + case Layout::BOTTOM_TO_TOP: + case Layout::LEFT_TO_RIGHT: rtl = 1.0; break; + case Layout::RIGHT_TO_LEFT: rtl = -1.0; break; } + if(doUTN)oldtarget=SingleUnicodeToNon(*text_iter); // this should only ever be with a 1:1 glyph:character situation + + // accumulate a record to write + + unsigned lc_index = char_index; + unsigned hold_iisi = _spans[span_index].in_input_stream_item; + while(1){ + glyph_index = _characters[lc_index].in_glyph; + if(glyph_index == -1){ // end of a line within a paragraph, for instance + lc_index++; + break; + } - // try to output as many characters as possible in one go by detecting kerning and stopping when we encounter it - // also break spans at changes in Unicode->nonunicode translations, so that each span - // sent down from here is translated the same way. The translation happens much later - // in the emf-print code. - // Note that the incoming stream has a predefined notion of what is in each "span" and it is not - // entirely clear why. For instance, the string "%%% text %%%%", where % is the Unicode "Sagittarius" - // character has 3 spans, with the first two ending on the spaces. Yet in the XML there is only one tspan. - // Consequently when the Unicode->NonUnicode detection is on the first space will go out by itself, - // because it is at the end of a span, whereas the second space goes with the "text". - - Glib::ustring span_string; - double char_x = _characters[_glyphs[glyph_index].in_character].x; - unsigned this_span_index = _characters[_glyphs[glyph_index].in_character].in_span; - if(doUTN)newtarget=lasttarget=SingleUnicodeToNon(*span_iter); - - do { + // always append if here + text_string += *text_iter; + + // figure out char widths, used by EMF, not currently used elsewhere + double cwidth; + if(lc_index == _glyphs[glyph_index].in_character){ // Glyph width is used only for the first character, these may be 0 + cwidth = rtl * _glyphs[glyph_index].width; // width might be zero + } + else { + cwidth = 0; + } + char_x += cwidth; /* -std::cout << "glyph info at:" << glyph_index -<< " glyphNo:" << _glyphs[glyph_index].glyph -<< " in_character:" << _glyphs[glyph_index].in_character -<< " x:" << _glyphs[glyph_index].x -<< " y:" << _glyphs[glyph_index].y -<< " rotation:" << _glyphs[glyph_index].rotation -<< " width:" << _glyphs[glyph_index].width -<< std::endl; +std:: cout << "DEBUG Layout::print in while " +<< " char_index " << char_index +<< " lc_index " << lc_index +<< " character " << std::hex << (int) *text_iter << std::dec +<< " glyph_index " << glyph_index +<< " glyph_xy " << _glyphs[glyph_index].x << " , " << _glyphs[glyph_index].y +<< " span_index " << span_index +<< " hold_iisi " << hold_iisi +<< std::endl; //DEBUG */ - span_string += *span_iter; - span_iter++; - if(doUTN)newtarget=SingleUnicodeToNon(*span_iter); - - unsigned same_character = _glyphs[glyph_index].in_character; - ky = _glyphs[glyph_index].y; // same value for all positions in a span - while (glyph_index < _glyphs.size() && _glyphs[glyph_index].in_character == same_character) { - char_x += _glyphs[glyph_index].width; - if(ndx < MAX_DX){ - hold_dx[ndx++] = _glyphs[glyph_index].width; - } - else { // silently truncate any text line silly enough to be longer than MAX_DX - break; - } - glyph_index++; + if(ndx < MAX_DX){ + hold_dx[ndx++] = fabs(cwidth); + } + else { // silently truncate any text line silly enough to be longer than MAX_DX + lc_index = _characters.size(); + break; } - } while (glyph_index < _glyphs.size() - && _path_fitted == NULL - && _characters[_glyphs[glyph_index].in_character].in_span == this_span_index - && fabs(char_x - _characters[_glyphs[glyph_index].in_character].x) < 1e-4 - && (doUTN ? (lasttarget==newtarget ? 1 : 0) : 1 ) - ); + + + // conditions that prevent this character from joining the record + lc_index++; + if(lc_index >= _characters.size()) break; // nothing more to process, so it must be the end of the record + text_iter++; + if(doUTN)newtarget=SingleUnicodeToNon(*text_iter); // this should only ever be with a 1:1 glyph:character situation + if(newtarget != oldtarget)break; // change in unicode to nonunicode translation status + // MUST exit on any major span change, but not on some little events, like a font substitution event irrelvant for the file save + unsigned next_span_index = _characters[lc_index].in_span; + if(span_index != next_span_index){ + /* on major changes break out of loop. + 1st case usually indicates an entire input line has been processed (out of several in a paragraph) + 2nd case usually indicates that a format change within a line (font/size/color/etc) is present. + */ +/* +std:: cout << "DEBUG Layout::print in while --- " +<< " char_index " << char_index +<< " lc_index " << lc_index +<< " cwidth " << cwidth +<< " _char.x (next) " << (lc_index < _characters.size() ? _characters[lc_index].x : -1) +<< " char_x (end this)" << char_x +<< " diff " << fabs(char_x - _characters[lc_index].x) +<< " oldy " << ky +<< " nexty " << _glyphs[_characters[lc_index].in_glyph].y +<< std::endl; //DEBUG +*/ + if(hold_iisi != _spans[next_span_index].in_input_stream_item)break; // major change, font, size, color, etc, must exit + if(fabs(char_x - _spans[next_span_index].x_start) >= 1e-4)break; // xkerning change + if(ky != _glyphs[_characters[lc_index].in_glyph].y)break; // ykerning change + /* + None of the above? Then this is a minor "pangito", update span_index and keep going. + The font used by the display may have failed over, but print does not care and can continue to use + whatever was specified in the XML. + */ + span_index = next_span_index; + text_iter = _spans[span_index].input_stream_first_character; + } + + } + // write it sp_print_bind(ctx, glyph_matrix, 1.0); - // the dx array is smuggled through to the EMF (ignored by others) as: + // the dx array is smuggled through to the EMF driver (ignored by others) as: // textw1 w2 w3 ...wn // where the widths are floats 7 characters wide, including the space - char *smuggle_string=smuggle_adxky_in(span_string.c_str(),ndx, &hold_dx[0], ky); -// sp_print_text(ctx, span_string.c_str(), g_pos, text_source->style); + char *smuggle_string=smuggle_adxkyrtl_in(text_string.c_str(),ndx, &hold_dx[0], ky, rtl); sp_print_text(ctx, smuggle_string, g_pos, text_source->style); free(smuggle_string); sp_print_release(ctx); ndx=0; + char_index = lc_index; } } } + #ifdef HAVE_CAIRO_PDF void Layout::showGlyphs(CairoRenderContext *ctx) const { @@ -432,10 +534,38 @@ Glib::ustring Layout::getFontFamily(unsigned span_index) const Glib::ustring Layout::dumpAsText() const { Glib::ustring result; + char line[256]; + + Glib::ustring::const_iterator icc; + + snprintf(line, sizeof(line), "spans %d\n", _spans.size()); + result += line; + snprintf(line, sizeof(line), "chars %d\n", _characters.size()); + result += line; + snprintf(line, sizeof(line), "glyphs %d\n", _glyphs.size()); + result += line; + unsigned lastspan=5000; + if(_characters.size() > 1){ + for(unsigned j = 0; j < _characters.size() ; j++){ + if(lastspan != _characters[j].in_span){ + lastspan = _characters[j].in_span; + icc = _spans[lastspan].input_stream_first_character; + } + snprintf(line, sizeof(line), "char %4d: '%c' 0x%4.4x x=%8.4f glyph=%3d span=%3d\n", j, *icc, *icc, _characters[j].x, _characters[j].in_glyph, _characters[j].in_span); + result += line; + icc++; + } + } + if(_glyphs.size()){ + for(unsigned j = 0; j < _glyphs.size() ; j++){ + snprintf(line, sizeof(line), "glyph %4d: %4d (%8.4f,%8.4f) rot=%8.4f cx=%8.4f char=%4d\n", + j, _glyphs[j].glyph, _glyphs[j].x, _glyphs[j].y, _glyphs[j].rotation, _glyphs[j].width, _glyphs[j].in_character); + result += line; + } + } for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { - char line[256]; - snprintf(line, sizeof(line), "==== span %d\n", span_index); + snprintf(line, sizeof(line), "==== span %d \n", span_index); result += line; snprintf(line, sizeof(line), " in para %d (direction=%s)\n", _lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph, direction_to_text(_paragraphs[_lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph].base_direction)); @@ -469,8 +599,8 @@ Glib::ustring Layout::dumpAsText() const if (_characters[char_index].in_span != span_index) continue; if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) { snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); - } else { - snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); + } else { // some text has empty tspans, iter_char cannot be dereferenced + snprintf(line, sizeof(line), " %d: '%c' 0x%4.4x x=%f flags=%03x glyph=%d\n", char_index, *iter_char, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); iter_char++; } result += line; diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 0f5f08a53..573301c69 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -568,6 +568,9 @@ public: inline void setZero() {ascent = descent = leading = 0.0;} inline LineHeight& operator*=(double x) {ascent *= x; descent *= x; leading *= x; return *this;} void max(LineHeight const &other); /// makes this object contain the largest of all three members between this object and other + inline double getAscent() const {return ascent; } + inline double getDescent() const {return descent; } + inline double getLeading() const {return leading; } }; /// see _enum_converter() @@ -717,6 +720,7 @@ private: float font_size; float x_start; /// relative to the start of the chunk float x_end; /// relative to the start of the chunk + inline float width() const {return std::abs(x_start - x_end);} LineHeight line_height; double baseline_shift; /// relative to the line's baseline Direction direction; /// See CSS3 section 3.2. Either rtl or ltr diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index d00569984..ef10a04d0 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -59,6 +59,8 @@ public: double Advance(int glyph_id, bool vertical); // nominal advance of the font. bool FontMetrics(double &ascent, double &descent, double &leading); + bool FontDecoration(double &underline_position, double &underline_thickness, + double &linethrough_position, double &linethrough_thickness); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts Geom::OptRect BBox(int glyph_id); -- cgit v1.2.3 From d1ffa8dc98f836a601d83afeb7625f7ecf954c1d Mon Sep 17 00:00:00 2001 From: David Mathog <> Date: Fri, 16 Aug 2013 12:46:33 +0200 Subject: Fix compiler warnings (bzr r11668.1.74) --- src/libnrtype/Layout-TNG-Output.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 153ef1ef0..162400aab 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -538,11 +538,11 @@ Glib::ustring Layout::dumpAsText() const Glib::ustring::const_iterator icc; - snprintf(line, sizeof(line), "spans %d\n", _spans.size()); + snprintf(line, sizeof(line), "spans %zu\n", _spans.size()); result += line; - snprintf(line, sizeof(line), "chars %d\n", _characters.size()); + snprintf(line, sizeof(line), "chars %zu\n", _characters.size()); result += line; - snprintf(line, sizeof(line), "glyphs %d\n", _glyphs.size()); + snprintf(line, sizeof(line), "glyphs %zu\n", _glyphs.size()); result += line; unsigned lastspan=5000; if(_characters.size() > 1){ -- cgit v1.2.3 From 14f607efe6cb318756d74604c3cd6810799b5434 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 31 Aug 2013 18:05:13 +0200 Subject: Move libuemf to a separate directory. Rename libunicode-convert to symbol_convert and put it in libuemf. (bzr r12490) --- src/libnrtype/Layout-TNG-Output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 162400aab..f7f910c2f 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -20,7 +20,7 @@ #include "extension/internal/cairo-render-context.h" #include "display/curve.h" #include <2geom/pathvector.h> -#include "libunicode-convert/unicode-convert.h" +#include namespace Inkscape { -- cgit v1.2.3 From 0f85e2c60c4406eaddc7a96d8ddcc05d36d458f2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 18 Sep 2013 14:46:36 -0400 Subject: Remove setItemBounds and _item_bbox because aren't sensible, replace with bbox. Fixed bugs: - https://launchpad.net/bugs/243729 (bzr r12528) --- src/libnrtype/Layout-TNG-Output.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index f7f910c2f..9967ba149 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,7 +181,6 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); - nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); } } -- cgit v1.2.3 From ddd3d527a7845b8e9d51db00847d1242ce3571cc Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 18 Sep 2013 14:59:42 -0400 Subject: Merge in David Mathog (mathog) patch for bug #1224486 Fixed bugs: - https://launchpad.net/bugs/1224486 (bzr r12529) --- src/libnrtype/Layout-TNG-Compute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 1b2704a7e..7ea089c93 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -706,7 +706,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (newcluster){ // find where the text ends for this log_cluster end_byte = it_span->start.iter_span->text_bytes; // Upper limit - for(unsigned next_glyph_index = glyph_index+1; next_glyph_index < it_span->end_glyph_index; next_glyph_index++){ + for(int next_glyph_index = glyph_index+1; next_glyph_index < unbroken_span.glyph_string->num_glyphs; next_glyph_index++){ if(unbroken_span.glyph_string->glyphs[next_glyph_index].attr.is_cluster_start){ end_byte = unbroken_span.glyph_string->log_clusters[next_glyph_index]; break; -- cgit v1.2.3 From 23b4c7fcb81ee195acb9bfd470723728f89bfc4a Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 19 Sep 2013 08:35:32 -0400 Subject: Revert some agressive changes and allow a seperate filter bbox for FER, should be refactored at some point. (bzr r12536) --- src/libnrtype/Layout-TNG-Output.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 9967ba149..f7f910c2f 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,6 +181,7 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); + nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); } } -- cgit v1.2.3 From d332b7a8d0e55612abc377a107bb1768fc657637 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 20 Sep 2013 16:27:08 -0400 Subject: Fix the text filter issue and revert many changes. (bzr r12556) --- src/libnrtype/Layout-TNG-Output.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index f7f910c2f..060cecebf 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,8 +181,9 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); - nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); + // Set item bounds without filter enlargement + in_arena->setItemBounds(paintbox); } } -- cgit v1.2.3 From 0d4a38635fc26ed09d56b46e462b373489c8a4e2 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 21 Sep 2013 11:42:33 +0100 Subject: Fix format security errors Fixed bugs: - https://launchpad.net/bugs/1193025 (bzr r12563) --- src/libnrtype/FontFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 74c706a1b..c91e57065 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -962,7 +962,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) nFace = pango_font_map_load_font(fontServer,fontContext,descr); } else { - g_warning(_("Ignoring font without family that will crash Pango")); + g_warning("%s", _("Ignoring font without family that will crash Pango")); } if ( nFace ) { -- cgit v1.2.3 From e6402fab7e8e858314ea0ea3b5c496c17a2c272b Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Thu, 26 Sep 2013 23:01:36 +0200 Subject: cppcheck: performance (bzr r12598) --- src/libnrtype/FontFactory.cpp | 8 ++++---- src/libnrtype/Layout-TNG-Input.cpp | 4 ++-- src/libnrtype/Layout-TNG-Output.cpp | 14 +++++++------- src/libnrtype/font-lister.cpp | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index c91e57065..c896cc470 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -348,7 +348,7 @@ font_factory::~font_factory(void) PangoStringToDescrMap::iterator it = fontInstanceMap.begin(); while (it != fontInstanceMap.end()) { pango_font_description_free((*it).second); - it++; + ++it; } } @@ -662,7 +662,7 @@ Glib::ustring font_factory::FontSpecificationBestMatch(const Glib::ustring & fon Glib::ustring bestMatchDescription; bool setFirstFamilyMatch = false; - for (it = fontInstanceMap.begin(); it != fontInstanceMap.end(); it++) { + for (it = fontInstanceMap.begin(); it != fontInstanceMap.end(); ++it) { Glib::ustring currentFontSpec = (*it).first; Glib::ustring currentFamily = GetUIFamilyString((*it).second); @@ -776,7 +776,7 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) for (std::list::iterator it=styleList.begin(); it != styleList.end(); - it++) { + ++it) { if (*it == styleUIName) { exists = true; break; @@ -809,7 +809,7 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) families = 0; // Sort the style lists - for (FamilyToStylesMap::iterator iter = map->begin() ; iter != map->end(); iter++) { + for (FamilyToStylesMap::iterator iter = map->begin() ; iter != map->end(); ++iter) { (*iter).second.sort(StyleNameCompareInternal); } } diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 10310b4aa..c7b0948e8 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -25,7 +25,7 @@ namespace Text { void Layout::_clearInputObjects() { - for(std::vector::iterator it = _input_stream.begin() ; it != _input_stream.end() ; it++) + for(std::vector::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) delete *it; _input_stream.clear(); _input_wrap_shapes.clear(); @@ -46,7 +46,7 @@ void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_ sp_style_ref(style); new_source->text_length = 0; - for ( ; text_begin != text_end && text_begin != text.end() ; text_begin++) + for ( ; text_begin != text_end && text_begin != text.end() ; ++text_begin) new_source->text_length++; // save this because calculating the length of a UTF-8 string is expensive if (optional_attributes) { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 060cecebf..1989c495a 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -85,7 +85,7 @@ void Layout::_clearOutputObjects() _paragraphs.clear(); _lines.clear(); _chunks.clear(); - for (std::vector::iterator it_span = _spans.begin() ; it_span != _spans.end() ; it_span++) + for (std::vector::iterator it_span = _spans.begin() ; it_span != _spans.end() ; ++it_span) if (it_span->font) it_span->font->Unref(); _spans.clear(); _characters.clear(); @@ -330,7 +330,7 @@ std:: cout << "DEBUG Layout::print in while " // conditions that prevent this character from joining the record lc_index++; if(lc_index >= _characters.size()) break; // nothing more to process, so it must be the end of the record - text_iter++; + ++text_iter; if(doUTN)newtarget=SingleUnicodeToNon(*text_iter); // this should only ever be with a 1:1 glyph:character situation if(newtarget != oldtarget)break; // change in unicode to nonunicode translation status // MUST exit on any major span change, but not on some little events, like a font substitution event irrelvant for the file save @@ -424,7 +424,7 @@ void Layout::showGlyphs(CairoRenderContext *ctx) const unsigned original_span = _characters[char_index].in_span; while (char_index && _characters[char_index - 1].in_span == original_span) { char_index--; - span_iter++; + ++span_iter; } // try to output as many characters as possible in one go @@ -434,7 +434,7 @@ void Layout::showGlyphs(CairoRenderContext *ctx) const glyphtext.clear(); do { span_string += *span_iter; - span_iter++; + ++span_iter; unsigned same_character = _glyphs[glyph_index].in_character; while (glyph_index < _glyphs.size() && _glyphs[glyph_index].in_character == same_character) { @@ -550,11 +550,11 @@ Glib::ustring Layout::dumpAsText() const for(unsigned j = 0; j < _characters.size() ; j++){ if(lastspan != _characters[j].in_span){ lastspan = _characters[j].in_span; - icc = _spans[lastspan].input_stream_first_character; + icc = _spans[lastspan].input_stream_first_character; } snprintf(line, sizeof(line), "char %4d: '%c' 0x%4.4x x=%8.4f glyph=%3d span=%3d\n", j, *icc, *icc, _characters[j].x, _characters[j].in_glyph, _characters[j].in_span); result += line; - icc++; + ++icc; } } if(_glyphs.size()){ @@ -602,7 +602,7 @@ Glib::ustring Layout::dumpAsText() const snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); } else { // some text has empty tspans, iter_char cannot be dereferenced snprintf(line, sizeof(line), " %d: '%c' 0x%4.4x x=%f flags=%03x glyph=%d\n", char_index, *iter_char, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); - iter_char++; + ++iter_char; } result += line; } diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 39a04914b..0a83f55e9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -39,7 +39,7 @@ namespace Inkscape std::list familyList; for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); iter != familyStyleMap.end(); - iter++) { + ++iter) { familyList.push_back((*iter).first); } familyList.sort(); @@ -60,7 +60,7 @@ namespace Inkscape std::list &styleStrings = familyStyleMap[familyName]; for (std::list::iterator it=styleStrings.begin(); it != styleStrings.end(); - it++) { + ++it) { styles = g_list_append(styles, g_strdup((*it).c_str())); } -- cgit v1.2.3 From c83329cdf1c37fd1ee123a0f30e8b6582ac51547 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:24:31 -0300 Subject: prevent redundant firing of InitTheFace (pFont never changes, but init is called all over the place); also some nulling and freeing to prevent leaks, and removing the redundant daddy unreffing that is done in ~FontInstance anyway (bzr r12618) --- src/libnrtype/FontInstance.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index fd0cdd3d4..38a105459 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -192,6 +192,7 @@ font_instance::~font_instance(void) //printf("font instance death\n"); if ( pFont ) { + FreeTheFace(); g_object_unref(pFont); pFont = 0; } @@ -232,10 +233,6 @@ void font_instance::Unref(void) //printf("font %x %s unref'd %i\n",this,tc,refCount); //free(tc); if ( refCount <= 0 ) { - if ( daddy ) { - daddy->UnrefFace(this); - } - daddy=NULL; delete this; } } @@ -387,6 +384,7 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int void font_instance::InitTheFace() { + if (theFace == NULL && pFont != NULL) { #ifdef USE_PANGO_WIN32 if ( !theFace ) { LOGFONT *lf=pango_win32_font_logfont(pFont); @@ -404,6 +402,7 @@ void font_instance::InitTheFace() FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol); } #endif + } } void font_instance::FreeTheFace() @@ -423,6 +422,7 @@ void font_instance::InstallFace(PangoFont* iFace) return; } pFont=iFace; + iFace = NULL; InitTheFace(); -- cgit v1.2.3 From 6cc0d44d20de8e537e42dac66de344354ea80d1c Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:26:16 -0300 Subject: order correction: unreffing fonts in ents needs loadedPtr so that must go before loadedPrt is nulled; this didn't crash simply because we never freed FontFactory before; also some comments and remove redundant multiply in hash function (bzr r12619) --- src/libnrtype/FontFactory.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index c896cc470..9fc553efd 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -25,7 +25,6 @@ typedef INK_UNORDERED_MAP(g_malloc(maxEnt*sizeof(font_entry)))), @@ -327,12 +326,6 @@ font_factory::font_factory(void) : font_factory::~font_factory(void) { - if (loadedPtr) { - FaceMapType* tmp = static_cast(loadedPtr); - delete tmp; - loadedPtr = 0; - } - for (int i = 0;i < nbEnt;i++) ents[i].f->Unref(); if ( ents ) g_free(ents); @@ -344,6 +337,12 @@ font_factory::~font_factory(void) #endif //g_object_unref(fontContext); + if (loadedPtr) { + FaceMapType* tmp = static_cast(loadedPtr); + delete tmp; + loadedPtr = 0; + } + // Delete the pango font pointers in the string to instance map PangoStringToDescrMap::iterator it = fontInstanceMap.begin(); while (it != fontInstanceMap.end()) { @@ -1126,7 +1125,7 @@ void font_factory::AddInCache(font_instance *who) return; } who->Ref(); - if ( nbEnt == maxEnt ) { + if ( nbEnt == maxEnt ) { // cache is filled, unref the oldest-accessed font in it int bi = 0; double ba = ents[bi].age; for (int i = 1;i < nbEnt;i++) { -- cgit v1.2.3 From 6b8c701e9d74cff5c0b2eaa2b678d8e9f7410658 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:27:10 -0300 Subject: FontInstances were being leaked here by overreffing - every call to Face must unref when done (bzr r12620) --- src/libnrtype/Layout-TNG-Compute.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7ea089c93..973db0165 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -980,6 +980,7 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con attribute_font_description->end_index = para_text.bytes(); pango_attr_list_insert(attributes_list, attribute_font_description); // ownership of attribute is assumed by the list + font->Unref(); } } -- cgit v1.2.3 From 87d93e27330577c2fd632dbaccbd3103884aa590 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 1 Oct 2013 15:25:44 +0200 Subject: Comprehensive fix for the issues with disappearing filtered objects. Fixes #304407 and possibly a few other bugs. Revert incorrect _item_bbox changes from r12528. Fixed bugs: - https://launchpad.net/bugs/304407 (bzr r12648) --- src/libnrtype/Layout-TNG-Output.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1989c495a..bdc786749 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,6 +181,7 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); + nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); // Set item bounds without filter enlargement in_arena->setItemBounds(paintbox); -- cgit v1.2.3 From 56a5a5f6726defecb1e3c3f34f8264becc05f7c7 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Thu, 3 Oct 2013 20:49:09 -0300 Subject: FIXME comment (bzr r12652) --- src/libnrtype/font-lister.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 0a83f55e9..aa50f4be0 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -203,6 +203,7 @@ namespace Inkscape font_list_store->thaw_notify(); } + // FIXME: why do we parse the style attribute instead of the object's SPStyle? void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { -- cgit v1.2.3 From 1c843a738c91d47468fbc5d97e225a6d0d19d7a4 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 6 Oct 2013 22:59:49 +0200 Subject: cppcheck (bzr r12666) --- src/libnrtype/Layout-TNG-Output.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index bdc786749..149f600b7 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -221,13 +221,9 @@ void Layout::print(SPPrintContext *ctx, Geom::Affine const &ctm) const { bool text_to_path = ctx->module->textToPath(); -int oldtarget = 0; -int newtarget = 0; #define MAX_DX 2048 float hold_dx[MAX_DX]; // For smuggling dx values (character widths) into print functions, unlikely any simple text output will be longer than this. -float ky; // For smuggling y kern value for span -int ndx = 0; -double rtl = 1.0; // 1 L->R, -1 R->L, constant across a span. 1.0 for t->b b->t??? + Geom::Affine glyph_matrix; if (_input_stream.empty()) return; @@ -253,7 +249,10 @@ Geom::Affine glyph_matrix; double char_x; int doUTN = CanUTN(); // Unicode to Nonunicode translation enabled if true Direction block_progression = _blockProgression(); - + int oldtarget = 0; + int ndx = 0; + double rtl = 1.0; // 1 L->R, -1 R->L, constant across a span. 1.0 for t->b b->t??? + for (unsigned char_index = 0 ; char_index < _characters.size() ; ) { Glib::ustring text_string; // accumulate text for record in this Geom::Point g_pos(0,0); // all strings are output at (0,0) because we do the translation using the matrix @@ -262,7 +261,7 @@ Geom::Affine glyph_matrix; char_index++; continue; } - ky = _glyphs[glyph_index].y; // same value for all positions in a span + float ky = _glyphs[glyph_index].y; // For smuggling y kern value for span // same value for all positions in a span unsigned span_index = _characters[char_index].in_span; Span const &span = _spans[span_index]; char_x = 0.0; @@ -283,12 +282,15 @@ Geom::Affine glyph_matrix; case Layout::LEFT_TO_RIGHT: rtl = 1.0; break; case Layout::RIGHT_TO_LEFT: rtl = -1.0; break; } - if(doUTN)oldtarget=SingleUnicodeToNon(*text_iter); // this should only ever be with a 1:1 glyph:character situation + if(doUTN){ + oldtarget=SingleUnicodeToNon(*text_iter); // this should only ever be with a 1:1 glyph:character situation + } // accumulate a record to write unsigned lc_index = char_index; unsigned hold_iisi = _spans[span_index].in_input_stream_item; + int newtarget = 0; while(1){ glyph_index = _characters[lc_index].in_glyph; if(glyph_index == -1){ // end of a line within a paragraph, for instance @@ -377,7 +379,7 @@ std:: cout << "DEBUG Layout::print in while --- " sp_print_text(ctx, smuggle_string, g_pos, text_source->style); free(smuggle_string); sp_print_release(ctx); - ndx=0; + ndx = 0; char_index = lc_index; } } @@ -546,28 +548,29 @@ Glib::ustring Layout::dumpAsText() const result += line; snprintf(line, sizeof(line), "glyphs %zu\n", _glyphs.size()); result += line; - unsigned lastspan=5000; + if(_characters.size() > 1){ + unsigned lastspan=5000; for(unsigned j = 0; j < _characters.size() ; j++){ if(lastspan != _characters[j].in_span){ lastspan = _characters[j].in_span; icc = _spans[lastspan].input_stream_first_character; } - snprintf(line, sizeof(line), "char %4d: '%c' 0x%4.4x x=%8.4f glyph=%3d span=%3d\n", j, *icc, *icc, _characters[j].x, _characters[j].in_glyph, _characters[j].in_span); + snprintf(line, sizeof(line), "char %4u: '%c' 0x%4.4x x=%8.4f glyph=%3d span=%3d\n", j, *icc, *icc, _characters[j].x, _characters[j].in_glyph, _characters[j].in_span); result += line; ++icc; } } if(_glyphs.size()){ for(unsigned j = 0; j < _glyphs.size() ; j++){ - snprintf(line, sizeof(line), "glyph %4d: %4d (%8.4f,%8.4f) rot=%8.4f cx=%8.4f char=%4d\n", + snprintf(line, sizeof(line), "glyph %4u: %4d (%8.4f,%8.4f) rot=%8.4f cx=%8.4f char=%4d\n", j, _glyphs[j].glyph, _glyphs[j].x, _glyphs[j].y, _glyphs[j].rotation, _glyphs[j].width, _glyphs[j].in_character); result += line; } } for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { - snprintf(line, sizeof(line), "==== span %d \n", span_index); + snprintf(line, sizeof(line), "==== span %u \n", span_index); result += line; snprintf(line, sizeof(line), " in para %d (direction=%s)\n", _lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph, direction_to_text(_paragraphs[_lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph].base_direction)); @@ -600,9 +603,9 @@ Glib::ustring Layout::dumpAsText() const u.pattr = &_characters[char_index].char_attributes; if (_characters[char_index].in_span != span_index) continue; if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) { - snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); + snprintf(line, sizeof(line), " %u: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); } else { // some text has empty tspans, iter_char cannot be dereferenced - snprintf(line, sizeof(line), " %d: '%c' 0x%4.4x x=%f flags=%03x glyph=%d\n", char_index, *iter_char, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); + snprintf(line, sizeof(line), " %u: '%c' 0x%4.4x x=%f flags=%03x glyph=%d\n", char_index, *iter_char, *iter_char, _characters[char_index].x, *u.uattr, _characters[char_index].in_glyph); ++iter_char; } result += line; @@ -610,7 +613,7 @@ Glib::ustring Layout::dumpAsText() const result += " ** glyphs:\n"; for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { if (_characters[_glyphs[glyph_index].in_character].in_span != span_index) continue; - snprintf(line, sizeof(line), " %d: %d (%f,%f) rot=%f cx=%f char=%d\n", glyph_index, _glyphs[glyph_index].glyph, _glyphs[glyph_index].x, _glyphs[glyph_index].y, _glyphs[glyph_index].rotation, _glyphs[glyph_index].width, _glyphs[glyph_index].in_character); + snprintf(line, sizeof(line), " %u: %d (%f,%f) rot=%f cx=%f char=%d\n", glyph_index, _glyphs[glyph_index].glyph, _glyphs[glyph_index].x, _glyphs[glyph_index].y, _glyphs[glyph_index].rotation, _glyphs[glyph_index].width, _glyphs[glyph_index].in_character); result += line; } result += "\n"; -- cgit v1.2.3 From 3962e37e9e3a26e0f48ec92668892df3439e7cbe Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 6 Oct 2013 23:08:32 +0200 Subject: initialisation (bzr r12667) --- src/libnrtype/Layout-TNG.cpp | 5 +++-- src/libnrtype/Layout-TNG.h | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp index bda0d1697..dd9c90949 100644 --- a/src/libnrtype/Layout-TNG.cpp +++ b/src/libnrtype/Layout-TNG.cpp @@ -16,9 +16,10 @@ namespace Text { const gunichar Layout::UNICODE_SOFT_HYPHEN = 0x00AD; const double Layout::LINE_HEIGHT_NORMAL = 1.25; -Layout::Layout() +Layout::Layout() : + _input_truncated(0), + _path_fitted(NULL) { - _path_fitted = NULL; } Layout::~Layout() diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 573301c69..d16c2843d 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -817,7 +817,12 @@ class Layout::iterator { public: friend class Layout; // this is just so you can create uninitialised iterators - don't actually try to use one - iterator() : _parent_layout(NULL) {} + iterator() : + _parent_layout(NULL), + _glyph_index(-1), + _char_index(0), + _cursor_moving_vertically(false), + _x_coordinate(0.0){} // no copy constructor required, the default does what we want bool operator== (iterator const &other) const {return _glyph_index == other._glyph_index && _char_index == other._char_index;} -- cgit v1.2.3 From ea793393baaaf1e195799618470f0f35b24fb6fe Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Thu, 17 Oct 2013 20:08:10 +0200 Subject: fix memory reallocation (bzr r12700) --- src/libnrtype/TextWrapper.cpp | 84 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 10 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/TextWrapper.cpp b/src/libnrtype/TextWrapper.cpp index 63af17f2e..32877e275 100644 --- a/src/libnrtype/TextWrapper.cpp +++ b/src/libnrtype/TextWrapper.cpp @@ -107,8 +107,24 @@ void text_wrapper::AppendUTF8(char const *text, int len) /* effic: (Not an issue for the sole caller at the time of writing.) This implementation takes quadratic time if the text is composed of n appends. Use a proper data structure. STL vector would suffice. */ - utf8_text = (char*)realloc(utf8_text, (utf8_length + nlen + 1) * sizeof(char)); - uni32_codepoint = (int*)realloc(uni32_codepoint, (utf8_length + nlen + 1) * sizeof(int)); + char *newdata = static_cast(realloc(utf8_text, (utf8_length + nlen + 1) * sizeof(char))); + if (newdata != NULL) + { + utf8_text = newdata; + } + else + { + g_warning("Failed to reallocate utf8_text"); + } + int* newdata2 = static_cast(realloc(uni32_codepoint, (utf8_length + nlen + 1) * sizeof(int))); + if (newdata2 != NULL) + { + uni32_codepoint = newdata2; + } + else + { + g_warning("Failed to reallocate uni32_codepoint"); + } // copy the source text in the newly lengthened array memcpy(utf8_text + utf8_length, text, nlen * sizeof(char)); @@ -164,11 +180,27 @@ void text_wrapper::AppendUTF8(char const *text, int len) // so setting the dx to 0 is mandatory if ( uni32_length > last_addition ) { if ( kern_x ) { - kern_x = (double*)realloc(kern_x, (uni32_length + 1) * sizeof(double)); + double *newdata = static_cast(realloc(kern_x, (uni32_length + 1) * sizeof(double))); + if (newdata != NULL) + { + kern_x = newdata; + } + else + { + g_warning("Failed to reallocate kern_x"); + } for (int i = last_addition; i <= uni32_length; i++) kern_x[i] = 0; } if ( kern_y ) { - kern_y = (double*)realloc(kern_y, (uni32_length + 1) * sizeof(double)); + double *newdata = static_cast(realloc(kern_y, (uni32_length + 1) * sizeof(double))); + if (newdata != NULL) + { + kern_y = newdata; + } + else + { + g_warning("Failed to reallocate kern_y"); + } for (int i = last_addition; i <= uni32_length; i++) kern_y[i] = 0; } } @@ -214,7 +246,15 @@ void text_wrapper::DoLayout(void) // realloc the structures if ( glyph_length >= max_g ) { max_g = 2 * glyph_length + 1; - glyph_text = (one_glyph*)realloc(glyph_text, (max_g + 1) * sizeof(one_glyph)); + one_glyph *newdata = static_cast(realloc(glyph_text, (max_g + 1) * sizeof(one_glyph))); + if (newdata != NULL) + { + glyph_text = newdata; + } + else + { + g_warning("Failed to reallocate glyph_text"); + } } // fill the glyph info glyph_text[glyph_length].font = pRun->item->analysis.font; @@ -354,7 +394,15 @@ void text_wrapper::ChunkText(void) } while ( n_en < g_en && glyph_text[n_en].font == curPF ); if ( nbBox >= maxBox ) { maxBox = 2 * nbBox + 1; - boxes = (one_box*)realloc(boxes, maxBox * sizeof(one_box)); + one_box *newdata = static_cast(realloc(boxes, maxBox * sizeof(one_box))); + if (newdata != NULL) + { + boxes = newdata; + } + else + { + g_warning("Failed to reallocate boxes"); + } } boxes[nbBox].g_st = n_st; boxes[nbBox].g_en = n_en; @@ -378,7 +426,15 @@ void text_wrapper::ChunkText(void) if ( b_en < nbBox && boxes[b_en].g_en == g_en ) { if ( nbPara >= maxPara ) { maxPara = 2 * nbPara + 1; - paras = (one_para*)realloc(paras, maxPara * sizeof(one_para)); + one_para *newdata = static_cast(realloc(paras, maxPara * sizeof(one_para))); + if (newdata != NULL) + { + paras = newdata; + } + else + { + g_warning("Failed to reallocate paras"); + } } paras[nbPara].b_st = b_st; paras[nbPara].b_en = b_en; @@ -571,7 +627,15 @@ unsigned text_wrapper::AddBoundary(text_boundary const &ib) { if ( nbBound >= maxBound ) { maxBound = 2 * nbBound + 1; - bounds = (text_boundary*)realloc(bounds, maxBound * sizeof(text_boundary)); + text_boundary *newdata = static_cast(realloc(bounds, maxBound * sizeof(text_boundary))); + if (newdata != NULL) + { + bounds = newdata; + } + else + { + g_warning("Failed to reallocate bounds"); + } } unsigned const ix = nbBound++; bounds[ix] = ib; @@ -893,7 +957,7 @@ void text_wrapper::AddDxDy(void) } else if ( l_pos > n_pos ) { for (int j = l_pos; j > n_pos; j--) sum -= kern_x[j]; } - l_pos = n_pos; + // l_pos = n_pos; glyph_text[glyph_length].x += sum; } } @@ -918,7 +982,7 @@ void text_wrapper::AddDxDy(void) } else if ( l_pos > n_pos ) { for (int j = l_pos; j > n_pos; j--) sum -= kern_y[j]; } - l_pos = n_pos; + // l_pos = n_pos; glyph_text[glyph_length].y += sum; } } -- cgit v1.2.3 From 0350e015e0b322e0651cec49346dff42e630711a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Oct 2013 20:06:12 +0100 Subject: fix crash Fixed bugs: - https://launchpad.net/bugs/1230241 (bzr r12740) --- src/libnrtype/font-lister.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index aa50f4be0..759acfb26 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -155,7 +155,7 @@ namespace Inkscape /* See if font-family (or first in fallback list) is on system. If so, get styles. */ std::vector tokens = Glib::Regex::split_simple(",", *i ); - if( !tokens[0].empty() ) { + if( !tokens.empty() && !tokens[0].empty() ) { Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { -- cgit v1.2.3 From 41dba93edb0570bd910510c031cdc4fe6e407818 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 13 Nov 2013 00:22:29 +0100 Subject: fix C++11 compilation. There A LOT of const_casts in this file... :-( (bzr r12804) --- src/libnrtype/Layout-TNG-OutIter.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 4e61c10a0..8d8621d64 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -168,7 +168,7 @@ Layout::iterator Layout::getLetterAt(double x, double y) const return end(); } -Layout::iterator Layout::sourceToIterator(void *source_cookie, Glib::ustring::const_iterator text_iterator) const +Layout::iterator Layout::sourceToIterator(void *source_cookie /*, Glib::ustring::const_iterator text_iterator*/) const { unsigned source_index; if (_characters.empty()) return end(); @@ -182,6 +182,8 @@ Layout::iterator Layout::sourceToIterator(void *source_cookie, Glib::ustring::co return iterator(this, char_index); InputStreamTextSource const *text_source = static_cast(_input_stream[source_index]); + return iterator(this, char_index); + /* This code was never used, the text_iterator argument was "NULL" in all calling code if (text_iterator <= text_source->text_begin) return iterator(this, char_index); if (text_iterator >= text_source->text_end) { if (source_index == _input_stream.size() - 1) return end(); @@ -194,11 +196,7 @@ Layout::iterator Layout::sourceToIterator(void *source_cookie, Glib::ustring::co iter_text++; } return end(); // never happens -} - -Layout::iterator Layout::sourceToIterator(void *source_cookie) const -{ - return sourceToIterator(source_cookie, Glib::ustring::const_iterator(std::string::const_iterator(NULL))); + */ } Geom::OptRect Layout::glyphBoundingBox(iterator const &it, double *rotation) const @@ -534,19 +532,24 @@ void Layout::getSourceOfCharacter(iterator const &it, void **source_cookie, Glib InputStreamItem *stream_item = _input_stream[_spans[_characters[it._char_index].in_span].in_input_stream_item]; *source_cookie = stream_item->source_cookie; if (text_iterator && stream_item->Type() == TEXT_SOURCE) { - InputStreamTextSource const *text_source = static_cast(stream_item); - Glib::ustring::const_iterator text_iter_const = text_source->text_begin; + InputStreamTextSource *text_source = dynamic_cast(stream_item); + + // In order to return a non-const iterator in text_iterator, do the const_cast here. + // Note that, although ugly, it is safe because we do not write to *iterator anywhere. + Glib::ustring::iterator text_iter = const_cast(text_source->text)->begin(); + unsigned char_index = it._char_index; unsigned original_input_source_index = _spans[_characters[char_index].in_span].in_input_stream_item; // confusing algorithm because the iterator goes forwards while the index goes backwards. // It's just that it's faster doing it that way while (char_index && _spans[_characters[char_index - 1].in_span].in_input_stream_item == original_input_source_index) { - ++text_iter_const; + ++text_iter; char_index--; } - text_source->text->begin().base() + (text_iter_const.base() - text_source->text->begin().base()); - *text_iterator = Glib::ustring::iterator(std::string::iterator(const_cast(&*text_source->text->begin().base() + (text_iter_const.base() - text_source->text->begin().base())))); - // the caller owns the string, so they're going to want a non-const iterator + + if (text_iterator) { + *text_iterator = text_iter; + } } } -- cgit v1.2.3 From df6e9a1f54aae71497f1e808c9102c739d91981d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 13 Nov 2013 01:15:52 +0100 Subject: fix build, complementary to rev12804 (forgot to commit) (bzr r12805) --- src/libnrtype/Layout-TNG.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index d16c2843d..c3ccbffb5 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -432,16 +432,17 @@ public: iterator getLetterAt(double x, double y) const; inline iterator getLetterAt(Geom::Point &point) const; - /** Returns an iterator pointing to the character in the output which + /* Returns an iterator pointing to the character in the output which was created from the given input. If the character at the given byte offset was removed (soft hyphens, for example) the next character after it is returned. If no input was added with the given cookie, end() is returned. If more than one input has the same cookie, the first will be used regardless of the value of \a text_iterator. If \a text_iterator is out of bounds, the first or last character belonging - to the given input will be returned accordingly. */ + to the given input will be returned accordingly. iterator sourceToIterator(void *source_cookie, Glib::ustring::const_iterator text_iterator) const; - + */ + /** Returns an iterator pointing to the first character in the output which was created from the given source. If \a source_cookie is invalid, end() is returned. If more than one input has the same cookie, the -- cgit v1.2.3 From ed4835f4cd19e112677377e53039cdc42df0c53f Mon Sep 17 00:00:00 2001 From: su_v Date: Sat, 30 Nov 2013 11:30:47 +0100 Subject: Fix build with freetype >= 2.5.1 Fixed bugs: - https://launchpad.net/bugs/1255830 (bzr r12833) --- src/libnrtype/FontFactory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 12046079e..7b606d200 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -30,7 +30,8 @@ #include #else #include -#include +#include +#include FT_FREETYPE_H #endif -- cgit v1.2.3 From bc9b1244c8cf0852df0e23b660b4f7e6123c6ec2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 9 Jan 2014 21:49:49 -0500 Subject: Make Sans the default if pango can't get the family name from the font description. Helps fix bug #1230241 Fixed bugs: - https://launchpad.net/bugs/1230241 (bzr r12908) --- src/libnrtype/font-lister.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 759acfb26..8dd6a2091 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -286,6 +286,8 @@ namespace Inkscape PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); const gchar* family = pango_font_description_get_family(descr); + if(!family) + family = "Sans"; Glib::ustring Family = family; // PANGO BUG... -- cgit v1.2.3 From 84a5554a6a1dd4791a895f9c500e3e254b692f9d Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 9 Jan 2014 22:26:45 -0500 Subject: Change Sans to sans-serif on suv's advice in bug #1230241 (bzr r12909) --- src/libnrtype/font-lister.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 8dd6a2091..89d0cb037 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -287,7 +287,7 @@ namespace Inkscape PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); const gchar* family = pango_font_description_get_family(descr); if(!family) - family = "Sans"; + family = "sans-serif"; Glib::ustring Family = family; // PANGO BUG... -- cgit v1.2.3 From 5eb9b4815a12cc0dafd07905f7715a7e15a92b41 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 13 Jan 2014 00:25:39 +0100 Subject: update 2geom's copy to r2142 (bzr r12921) --- src/libnrtype/FontInstance.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 38a105459..434f3ee47 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -21,7 +21,7 @@ #include FT_TRUETYPE_TABLES_H #include #include <2geom/pathvector.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include "libnrtype/font-glyph.h" #include "libnrtype/font-instance.h" #include "livarot/Path.h" @@ -618,7 +618,7 @@ void font_instance::LoadGlyph(int glyph_id) doAdd=true; } #endif - path_builder.finish(); + path_builder.flush(); if ( doAdd ) { Geom::PathVector pv = path_builder.peek(); -- cgit v1.2.3 From c7731033ef400fccb6a49d830ded86068fcd3432 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 5 Feb 2014 12:29:11 +0100 Subject: Fix for Bug #1250685 (Unnecessary gender-specific terms in code). Fixed bugs: - https://launchpad.net/bugs/1250685 (bzr r12997) --- src/libnrtype/FontFactory.cpp | 4 ++-- src/libnrtype/FontInstance.cpp | 40 ++++++++++++++++++++-------------------- src/libnrtype/TextWrapper.cpp | 2 +- src/libnrtype/font-instance.h | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 9fc553efd..f05b75aaa 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -973,12 +973,12 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // point) whether loadedFaces[that_descr] is free or not (and overwriting // an entry will bring deallocation problems) res->descr = pango_font_description_copy(descr); - res->daddy = this; + res->parent = this; res->InstallFace(nFace); if ( res->pFont == NULL ) { // failed to install face -> bitmap font // printf("face failed\n"); - res->daddy = NULL; + res->parent = NULL; delete res; res = NULL; if ( canFail ) { diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 434f3ee47..a5b782344 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -174,7 +174,7 @@ font_instance::font_instance(void) : pFont(0), descr(0), refCount(0), - daddy(0), + parent(0), nbGlyph(0), maxGlyph(0), glyphs(0), @@ -185,9 +185,9 @@ font_instance::font_instance(void) : font_instance::~font_instance(void) { - if ( daddy ) { - daddy->UnrefFace(this); - daddy = 0; + if ( parent ) { + parent->UnrefFace(this); + parent = 0; } //printf("font instance death\n"); @@ -389,13 +389,13 @@ void font_instance::InitTheFace() if ( !theFace ) { LOGFONT *lf=pango_win32_font_logfont(pFont); g_assert(lf != NULL); - theFace=pango_win32_font_cache_load(daddy->pangoFontCache,lf); + theFace=pango_win32_font_cache_load(parent->pangoFontCache,lf); g_free(lf); } XFORM identity = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; - SetWorldTransform(daddy->hScreenDC, &identity); - SetGraphicsMode(daddy->hScreenDC, GM_COMPATIBLE); - SelectObject(daddy->hScreenDC,theFace); + SetWorldTransform(parent->hScreenDC, &identity); + SetGraphicsMode(parent->hScreenDC, GM_COMPATIBLE); + SelectObject(parent->hScreenDC,theFace); #else theFace=pango_fc_font_lock_face(PANGO_FC_FONT(pFont)); if ( theFace ) { @@ -408,8 +408,8 @@ void font_instance::InitTheFace() void font_instance::FreeTheFace() { #ifdef USE_PANGO_WIN32 - SelectObject(daddy->hScreenDC,GetStockObject(SYSTEM_FONT)); - pango_win32_font_cache_unload(daddy->pangoFontCache,theFace); + SelectObject(parent->hScreenDC,GetStockObject(SYSTEM_FONT)); + pango_win32_font_cache_unload(parent->pangoFontCache,theFace); #else pango_fc_font_unlock_face(PANGO_FC_FONT(pFont)); #endif @@ -443,7 +443,7 @@ bool font_instance::IsOutlineFont(void) InitTheFace(); #ifdef USE_PANGO_WIN32 TEXTMETRIC tm; - return GetTextMetrics(daddy->hScreenDC,&tm) && tm.tmPitchAndFamily&(TMPF_TRUETYPE|TMPF_DEVICE); + return GetTextMetrics(parent->hScreenDC,&tm) && tm.tmPitchAndFamily&(TMPF_TRUETYPE|TMPF_DEVICE); #else return FT_IS_SCALABLE(theFace); #endif @@ -513,10 +513,10 @@ void font_instance::LoadGlyph(int glyph_id) MAT2 identity = {{0,1},{0,0},{0,0},{0,1}}; OUTLINETEXTMETRIC otm; - GetOutlineTextMetrics(daddy->hScreenDC, sizeof(otm), &otm); + GetOutlineTextMetrics(parent->hScreenDC, sizeof(otm), &otm); GLYPHMETRICS metrics; - DWORD bufferSize=GetGlyphOutline (daddy->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); - double scale=1.0/daddy->fontSize; + DWORD bufferSize=GetGlyphOutline (parent->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); + double scale=1.0/parent->fontSize; n_g.h_advance=metrics.gmCellIncX*scale; n_g.v_advance=otm.otmTextMetrics.tmHeight*scale; n_g.h_width=metrics.gmBlackBoxX*scale; @@ -528,7 +528,7 @@ void font_instance::LoadGlyph(int glyph_id) doAdd=true; } else { char *buffer = new char[bufferSize]; - if ( GetGlyphOutline (daddy->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, bufferSize, buffer, &identity) <= 0 ) { + if ( GetGlyphOutline (parent->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, bufferSize, buffer, &identity) <= 0 ) { // shit happened } else { // Platform SDK is rubbish, read KB87115 instead @@ -655,10 +655,10 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) } #ifdef USE_PANGO_WIN32 OUTLINETEXTMETRIC otm; - if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) { + if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { return false; } - double scale=1.0/daddy->fontSize; + double scale=1.0/parent->fontSize; ascent=fabs(otm.otmAscent*scale); descent=fabs(otm.otmDescent*scale); leading=fabs(otm.otmLineGap*scale); @@ -688,10 +688,10 @@ bool font_instance::FontDecoration( } #ifdef USE_PANGO_WIN32 OUTLINETEXTMETRIC otm; - if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) { + if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { return false; } - double scale=1.0/daddy->fontSize; + double scale=1.0/parent->fontSize; underline_position = fabs(otm.otmUnderscorePosition *scale); underline_thickness = fabs(otm.otmUnderscoreSize *scale); linethrough_position = fabs(otm.otmStrikeoutPosition *scale); @@ -725,7 +725,7 @@ bool font_instance::FontSlope(double &run, double &rise) #ifdef USE_PANGO_WIN32 OUTLINETEXTMETRIC otm; - if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) return false; + if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) return false; run=otm.otmsCharSlopeRun; rise=otm.otmsCharSlopeRise; #else diff --git a/src/libnrtype/TextWrapper.cpp b/src/libnrtype/TextWrapper.cpp index 32877e275..380e9ba3f 100644 --- a/src/libnrtype/TextWrapper.cpp +++ b/src/libnrtype/TextWrapper.cpp @@ -327,7 +327,7 @@ void text_wrapper::DoLayout(void) for (int i = 0; i < glyph_length; i++) { glyph_text[i].uni_st = uni32_codepoint[glyph_text[i].uni_st]; glyph_text[i].uni_en = uni32_codepoint[glyph_text[i].uni_en]; - glyph_text[i].x /= 512; // why is this not default_font->daddy->fontsize? + glyph_text[i].x /= 512; // why is this not default_font->parent->fontsize? glyph_text[i].y /= 512; } if ( glyph_length > 0 ) { diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index ef10a04d0..75106617b 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -29,7 +29,7 @@ public: // refcount int refCount; // font_factory owning this font_instance - font_factory* daddy; + font_factory* parent; // common glyph definitions for all the rasterfonts std::map id_to_no; -- cgit v1.2.3 From 9e9db3f8ec260992295cc85ce1e7da52ba725ba4 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Tue, 11 Feb 2014 14:39:37 +0100 Subject: fix compiler warnings (bug #1278049 ) (bzr r13022) --- src/libnrtype/Layout-TNG-Output.cpp | 46 ++++++++++++------------------------- 1 file changed, 15 insertions(+), 31 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 149f600b7..77534e706 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -538,17 +538,10 @@ Glib::ustring Layout::getFontFamily(unsigned span_index) const Glib::ustring Layout::dumpAsText() const { Glib::ustring result; - char line[256]; - Glib::ustring::const_iterator icc; + char line[256]; - snprintf(line, sizeof(line), "spans %zu\n", _spans.size()); - result += line; - snprintf(line, sizeof(line), "chars %zu\n", _characters.size()); - result += line; - snprintf(line, sizeof(line), "glyphs %zu\n", _glyphs.size()); - result += line; - + result = Glib::ustring::compose("spans %1\nchars %2\nglyphs %3\n", _spans.size(), _characters.size(), _glyphs.size()); if(_characters.size() > 1){ unsigned lastspan=5000; for(unsigned j = 0; j < _characters.size() ; j++){ @@ -570,32 +563,23 @@ Glib::ustring Layout::dumpAsText() const } for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { - snprintf(line, sizeof(line), "==== span %u \n", span_index); - result += line; - snprintf(line, sizeof(line), " in para %d (direction=%s)\n", _lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph, - direction_to_text(_paragraphs[_lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph].base_direction)); - result += line; - snprintf(line, sizeof(line), " in source %d (type=%d, cookie=%p)\n", _spans[span_index].in_input_stream_item, + result += Glib::ustring::compose("==== span %1 \n", span_index) + + Glib::ustring::compose(" in para %1 (direction=%2)\n", _lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph, + direction_to_text(_paragraphs[_lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph].base_direction)) + + Glib::ustring::compose(" in source %1 (type=%2, cookie=%3)\n", _spans[span_index].in_input_stream_item, _input_stream[_spans[span_index].in_input_stream_item]->Type(), - _input_stream[_spans[span_index].in_input_stream_item]->source_cookie); - result += line; - snprintf(line, sizeof(line), " in line %d (baseline=%f, shape=%d)\n", _chunks[_spans[span_index].in_chunk].in_line, + _input_stream[_spans[span_index].in_input_stream_item]->source_cookie) + + Glib::ustring::compose(" in line %1 (baseline=%2, shape=%3)\n", _chunks[_spans[span_index].in_chunk].in_line, _lines[_chunks[_spans[span_index].in_chunk].in_line].baseline_y, - _lines[_chunks[_spans[span_index].in_chunk].in_line].in_shape); - result += line; - snprintf(line, sizeof(line), " in chunk %d (x=%f, baselineshift=%f)\n", _spans[span_index].in_chunk, _chunks[_spans[span_index].in_chunk].left_x, _spans[span_index].baseline_shift); - result += line; + _lines[_chunks[_spans[span_index].in_chunk].in_line].in_shape) + + Glib::ustring::compose(" in chunk %1 (x=%2, baselineshift=%3)\n", _spans[span_index].in_chunk, _chunks[_spans[span_index].in_chunk].left_x, _spans[span_index].baseline_shift); if (_spans[span_index].font) { - snprintf(line, sizeof(line), " font '%s' %f %s %s\n", sp_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); - result += line; + result += Glib::ustring::compose(" font '%1' %2 %3 %4\n", sp_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); } - snprintf(line, sizeof(line), " x_start = %f, x_end = %f\n", _spans[span_index].x_start, _spans[span_index].x_end); - result += line; - snprintf(line, sizeof(line), " line height: ascent %f, descent %f leading %f\n", _spans[span_index].line_height.ascent, _spans[span_index].line_height.descent, _spans[span_index].line_height.leading); - result += line; - snprintf(line, sizeof(line), " direction %s, block-progression %s\n", direction_to_text(_spans[span_index].direction), direction_to_text(_spans[span_index].block_progression)); - result += line; - result += " ** characters:\n"; + result += Glib::ustring::compose(" x_start = %1, x_end = %2\n", _spans[span_index].x_start, _spans[span_index].x_end) + + Glib::ustring::compose(" line height: ascent %1, descent %2 leading %3\n", _spans[span_index].line_height.ascent, _spans[span_index].line_height.descent, _spans[span_index].line_height.leading) + + Glib::ustring::compose(" direction %1, block-progression %2\n", direction_to_text(_spans[span_index].direction), direction_to_text(_spans[span_index].block_progression)) + + " ** characters:\n"; Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; // very inefficent code. what the hell, it's only debug stuff. for (unsigned char_index = 0 ; char_index < _characters.size() ; char_index++) { -- cgit v1.2.3 From 474c6455b1d0ef04ca416e42f09bd48efee6a186 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 28 Feb 2014 19:31:08 -0800 Subject: Remove unused variable. (bzr r13079) --- src/libnrtype/Layout-TNG-OutIter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 8d8621d64..6dc42d998 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -181,9 +181,10 @@ Layout::iterator Layout::sourceToIterator(void *source_cookie /*, Glib::ustring: if (_input_stream[source_index]->Type() != TEXT_SOURCE) return iterator(this, char_index); - InputStreamTextSource const *text_source = static_cast(_input_stream[source_index]); return iterator(this, char_index); /* This code was never used, the text_iterator argument was "NULL" in all calling code + InputStreamTextSource const *text_source = static_cast(_input_stream[source_index]); + if (text_iterator <= text_source->text_begin) return iterator(this, char_index); if (text_iterator >= text_source->text_end) { if (source_index == _input_stream.size() - 1) return end(); -- cgit v1.2.3 From de29fdf792fc739be65787538a3bf6da6cd01f8b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 21 Mar 2014 18:53:05 +0100 Subject: fix macro redefinition errors (bzr r13179) --- src/libnrtype/FontFactory.cpp | 6 ++++-- src/libnrtype/FontInstance.cpp | 6 ++++-- src/libnrtype/Layout-TNG-Input.cpp | 10 +++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index f05b75aaa..7c0b4ffba 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -8,12 +8,14 @@ * */ -#define PANGO_ENABLE_ENGINE - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + #include #include #include "libnrtype/FontFactory.h" diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index a5b782344..20eca6740 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -8,12 +8,14 @@ * */ -#define PANGO_ENABLE_ENGINE - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + #include #include FT_OUTLINE_H #include FT_BBOX_H diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index c7b0948e8..cb3e6f620 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -9,7 +9,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef PANGO_ENABLE_ENGINE #define PANGO_ENABLE_ENGINE +#endif #include #include "Layout-TNG.h" @@ -25,8 +31,10 @@ namespace Text { void Layout::_clearInputObjects() { - for(std::vector::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) + for(std::vector::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) { delete *it; + } + _input_stream.clear(); _input_wrap_shapes.clear(); } -- cgit v1.2.3