From da49b977d3a7e002c88780c24d9c4020cbe80b0e Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sun, 13 Dec 2009 14:00:22 +0100 Subject: Position of baseline anchor is now dependent of the text alignment Fixed bugs: - https://launchpad.net/bugs/168329 (bzr r8887) --- src/libnrtype/Layout-TNG-OutIter.cpp | 29 +++++++++++++++++++++++++++-- src/libnrtype/Layout-TNG.h | 4 ++++ 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 0fc061bfc..f4e8e4031 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -221,6 +221,31 @@ Geom::Point Layout::characterAnchorPoint(iterator const &it) const } } +boost::optional Layout::baselineAnchorPoint() const +{ + iterator pos = this->begin(); + Geom::Point left_pt = this->characterAnchorPoint(pos); + pos.thisEndOfLine(); + Geom::Point right_pt = this->characterAnchorPoint(pos); + Geom::Point mid_pt = (left_pt + right_pt)/2; + + switch (this->paragraphAlignment(pos)) { + case LEFT: + case FULL: + return left_pt; + break; + case CENTER: + return mid_pt; + break; + case RIGHT: + return right_pt; + break; + default: + return boost::optional(); + break; + } +} + Geom::Point Layout::chunkAnchorPoint(iterator const &it) const { unsigned chunk_index; @@ -705,7 +730,7 @@ bool Layout::iterator::nextLineCursor(int n) unsigned line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; if (line_index == _parent_layout->_lines.size() - 1) return false; // nowhere to go - else + else n = MIN (n, static_cast(_parent_layout->_lines.size() - 1 - line_index)); if (_parent_layout->_lines[line_index + n].in_shape != _parent_layout->_lines[line_index].in_shape) { // switching between shapes: adjust the stored x to compensate @@ -728,7 +753,7 @@ bool Layout::iterator::prevLineCursor(int n) line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; if (line_index == 0) return false; // nowhere to go - else + else n = MIN (n, static_cast(line_index)); if (_parent_layout->_lines[line_index - n].in_shape != _parent_layout->_lines[line_index].in_shape) { // switching between shapes: adjust the stored x to compensate diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 19680b140..8cd26edef 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -480,6 +480,10 @@ public: /** For latin text, the left side of the character, on the baseline */ Geom::Point characterAnchorPoint(iterator const &it) const; + /** For left aligned text, the leftmost end of the baseline + For rightmost text, the rightmost... you probably got it by now ;-)*/ + boost::optional baselineAnchorPoint() const; + /** This is that value to apply to the x,y attributes of tspan role=line elements, and hence it takes alignment into account. */ Geom::Point chunkAnchorPoint(iterator const &it) const; -- cgit v1.2.3 From 4cc7eb64107fc32a7c364545acc635e504736cf6 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Mon, 21 Dec 2009 01:23:37 -0400 Subject: utilities and UI support for identifying truncated flowtext and text-on-path (bzr r8898) --- src/libnrtype/Layout-TNG-Input.cpp | 69 ++++++++++++++++++++++++++++++++++++++ src/libnrtype/Layout-TNG.h | 2 ++ 2 files changed, 71 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 2ee0051a4..33371ab10 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -16,8 +16,11 @@ #include "style.h" #include "svg/svg-length.h" #include "sp-object.h" +#include "sp-string.h" #include "FontFactory.h" +#include "text-editing.h" // for inputTruncated() + namespace Inkscape { namespace Text { @@ -321,5 +324,71 @@ Layout::InputStreamTextSource::~InputStreamTextSource() sp_style_unref(style); } +bool +Layout::inputTruncated() const +{ + if (!inputExists()) + return false; + + // Find out the SPObject to which the last visible character corresponds: + Layout::iterator last = end(); + if (last == begin()) { + // FIXME: this returns a wrong "not truncated" when a flowtext is entirely + // truncated, so there are no visible characters. But how can I find out the + // originator SPObject without having anything to do getSourceOfCharacter + // from? + return false; + } + last.prevCharacter(); + void *source; + Glib::ustring::iterator offset; + getSourceOfCharacter(last, &source, &offset); + SPObject *obj = SP_OBJECT(source); + + // if that is SPString, see if it has further characters beyond the last visible + if (obj && SP_IS_STRING(obj)) { + Glib::ustring::iterator offset_next = offset; + offset_next ++; + if (offset_next != SP_STRING(obj)->string.end()) { + // truncated: source SPString has next char + return true; + } + } + + // otherwise, see if the SPObject at end() or any of its text-tree ancestors + // (excluding top-level SPText or SPFlowText) have a text-tree next sibling with + // visible text + if (obj) { + for (SPObject *ascend = obj; + ascend && (is_part_of_text_subtree (ascend) && !is_top_level_text_object(ascend)); + ascend = SP_OBJECT_PARENT(ascend)) { + if (SP_OBJECT_NEXT(ascend)) { + SPObject *next = SP_OBJECT_NEXT(ascend); + if (next && is_part_of_text_subtree(next) && has_visible_text(next)) { + // truncated: source text object has next text sibling + return true; + } + } + } + } + + // the above works for flowed text, but not for text on path. + // so now, we also check if the last of the _characters, if coming from a TEXT_SOURCE, + // has in_glyph different from -1 + unsigned last_char = _characters.size() - 1; + unsigned span_index = _characters[last_char].in_span; + Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; + + if (_input_stream[_spans[span_index].in_input_stream_item]->Type() == TEXT_SOURCE) { + if (_characters[last_char].in_glyph == -1) { + //truncated: last char has no glyph + return true; + } + } + + // not truncated + return false; +} + }//namespace Text }//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 8cd26edef..05b5103fc 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -212,6 +212,8 @@ public: bool inputExists() const {return !_input_stream.empty();} + bool inputTruncated() const; + /** adds a new piece of text to the end of the current list of text to be processed. This method can only add text of a consistent style. To add lots of different styles, call it lots of times. -- cgit v1.2.3 From 387ffc573407e64bb604d4014c59f397675f3ea2 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 26 Dec 2009 19:35:08 -0800 Subject: Encapsulating use of gcc hash_map extension. (bzr r8916) --- src/libnrtype/FontFactory.cpp | 63 +++++++++++++++-------- src/libnrtype/FontFactory.h | 21 ++++---- src/libnrtype/FontInstance.cpp | 114 ++++++++++++++++++++++++++++------------- src/libnrtype/font-instance.h | 58 +++++++++------------ 4 files changed, 154 insertions(+), 102 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index fec9316b9..1f85ee5ca 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -26,6 +26,10 @@ /* Freetype2 */ # include +#include + + +typedef __gnu_cxx::hash_map FaceMapType; // need to avoid using the size field size_t font_descr_hash::operator()( PangoFontDescription *const &x) const { @@ -299,20 +303,25 @@ font_factory *font_factory::Default(void) return lUsine; } -font_factory::font_factory(void) -{ - fontSize = 512; - nbEnt = 0; - maxEnt = 32; - ents = (font_entry*)g_malloc(maxEnt*sizeof(font_entry)); +font_factory::font_factory(void) : + nbEnt(0), + maxEnt(32), + ents(static_cast(g_malloc(maxEnt*sizeof(font_entry)))), #ifdef USE_PANGO_WIN32 - hScreenDC = pango_win32_get_dc(); - fontServer = pango_win32_font_map_for_display(); - fontContext = pango_win32_get_context(); - pangoFontCache = pango_win32_font_map_get_font_cache(fontServer); + fontServer(pango_win32_font_map_for_display()), + fontContext(pango_win32_get_context()), + pangoFontCache(pango_win32_font_map_get_font_cache(fontServer)), + hScreenDC(pango_win32_get_dc()), +#else + fontServer(pango_ft2_font_map_new()), + fontContext(0), +#endif + fontSize(512), + loadedPtr(new FaceMapType()) +{ +#ifdef USE_PANGO_WIN32 #else - fontServer = pango_ft2_font_map_new(); 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); @@ -321,6 +330,11 @@ font_factory::font_factory(void) font_factory::~font_factory(void) { + if (loadedPtr) { + FaceMapType* tmp = static_cast(loadedPtr); + loadedPtr = 0; + } + for (int i = 0;i < nbEnt;i++) ents[i].f->Unref(); if ( ents ) g_free(ents); @@ -793,6 +807,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) font_instance *res = NULL; + FaceMapType& loadedFaces = *static_cast(loadedPtr); if ( loadedFaces.find(descr) == loadedFaces.end() ) { // not yet loaded PangoFont *nFace = NULL; @@ -849,8 +864,9 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) res->Ref(); AddInCache(res); } - if(res) - res->InitTheFace(); + if (res) { + res->InitTheFace(); + } return res; } @@ -924,15 +940,18 @@ font_instance *font_factory::Face(char const *family, NRTypePosDef apos) void font_factory::UnrefFace(font_instance *who) { - if ( who == NULL ) return; - if ( loadedFaces.find(who->descr) == loadedFaces.end() ) { - // not found - char *tc = pango_font_description_to_string(who->descr); - g_warning("unrefFace %p=%s: failed\n",who,tc); - g_free(tc); - } else { - loadedFaces.erase(loadedFaces.find(who->descr)); - // printf("unrefFace %p: success\n",who); + if ( who ) { + FaceMapType& loadedFaces = *static_cast(loadedPtr); + + if ( loadedFaces.find(who->descr) == loadedFaces.end() ) { + // not found + char *tc = pango_font_description_to_string(who->descr); + g_warning("unrefFace %p=%s: failed\n",who,tc); + g_free(tc); + } else { + loadedFaces.erase(loadedFaces.find(who->descr)); + // printf("unrefFace %p: success\n",who); + } } } diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 9f4b31a2e..8d85bcf3e 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -11,7 +11,6 @@ #include #include -#include #ifdef HAVE_CONFIG_H # include @@ -84,31 +83,29 @@ public: double fontSize; /**< The huge fontsize used as workaround for hinting. * Different between freetype and win32. */ - __gnu_cxx::hash_map loadedFaces; - font_factory(); virtual ~font_factory(); /// Returns the default font_factory. static font_factory* Default(); - + /// Constructs a pango string for use with the fontStringMap (see below) Glib::ustring ConstructFontSpecification(PangoFontDescription *font); Glib::ustring ConstructFontSpecification(font_instance *font); - + /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled) Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr); Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr); - + /// Modifiers for the font specification (returns new font specification) Glib::ustring ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily); Glib::ustring FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn); Glib::ustring FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn); - + // Gathers all strings needed for UI while storing pango information in // fontInstanceMap and fontStringMap void GetUIFamiliesAndStyles(FamilyToStylesMap *map); - + /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information font_instance* FaceFromStyle(SPStyle const *style); @@ -129,17 +126,19 @@ public: // internal void AddInCache(font_instance *who); - + private: + void* loadedPtr; + // These two maps are used for translating between what's in the UI and a pango // font description. This is necessary because Pango cannot always // reproduce these structures from the names it gave us in the first place. - + // Key: A string produced by font_factory::ConstructFontSpecification // Value: The associated PangoFontDescription typedef std::map PangoStringToDescrMap; PangoStringToDescrMap fontInstanceMap; - + // Key: Family name in UI + Style name in UI // Value: The associated string that should be produced with font_factory::ConstructFontSpecification typedef std::map UIStringToPangoStringMap; diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index e1413b46e..f34a230c1 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -29,6 +29,22 @@ # include FT_TRUETYPE_TABLES_H # include +#include + + +// the various raster_font in use at a given time are held in a hash_map whose indices are the +// styles, hence the 2 following 'classes' +struct font_style_hash : public std::unary_function { + size_t operator()(font_style const &x) const; +}; + +struct font_style_equal : public std::binary_function { + bool operator()(font_style const &a, font_style const &b); +}; + + +typedef __gnu_cxx::hash_map StyleMap; + size_t font_style_hash::operator()(const font_style &x) const { @@ -155,36 +171,61 @@ static int ft2_cubic_to(FREETYPE_VECTOR *control1, FREETYPE_VECTOR *control2, FR * */ -font_instance::font_instance(void) +font_instance::font_instance(void) : + pFont(0), + descr(0), + refCount(0), + daddy(0), + nbGlyph(0), + maxGlyph(0), + glyphs(0), + loadedPtr(new StyleMap()), + theFace(0) { - //printf("font instance born\n"); - descr=NULL; - pFont=NULL; - refCount=0; - daddy=NULL; - nbGlyph=maxGlyph=0; - glyphs=NULL; - theFace=NULL; + //printf("font instance born\n"); } font_instance::~font_instance(void) { - if ( daddy ) daddy->UnrefFace(this); - //printf("font instance death\n"); - if ( pFont ) g_object_unref(pFont); - pFont=NULL; - if ( descr ) pango_font_description_free(descr); - descr=NULL; - // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch - theFace=NULL; - - for (int i=0;i(loadedPtr); + delete tmp; + loadedPtr = 0; + } + + if ( daddy ) { + daddy->UnrefFace(this); + daddy = 0; + } + + //printf("font instance death\n"); + if ( pFont ) { + g_object_unref(pFont); + pFont = 0; + } + + if ( descr ) { + pango_font_description_free(descr); + descr = 0; + } + + // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch + theFace = 0; + + for (int i=0;i(loadedPtr); + if ( loadedStyles.find(nStyle) == loadedStyles.end() ) { raster_font *nR = new raster_font(nStyle); nR->Ref(); nR->daddy=this; @@ -746,15 +788,17 @@ raster_font* font_instance::RasterFont(const font_style &inStyle) void font_instance::RemoveRasterFont(raster_font* who) { - if ( who == NULL ) return; - if ( loadedStyles.find(who->style) == loadedStyles.end() ) { - //g_print("RemoveRasterFont failed \n"); - // not found - } else { - loadedStyles.erase(loadedStyles.find(who->style)); - //g_print("RemoveRasterFont\n"); - Unref(); - } + if ( who ) { + StyleMap& loadedStyles = *static_cast(loadedPtr); + if ( loadedStyles.find(who->style) == loadedStyles.end() ) { + //g_print("RemoveRasterFont failed \n"); + // not found + } else { + loadedStyles.erase(loadedStyles.find(who->style)); + //g_print("RemoveRasterFont\n"); + Unref(); + } + } } diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 4209a20af..521c9a424 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -1,7 +1,6 @@ #ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H #define SEEN_LIBNRTYPE_FONT_INSTANCE_H -#include #include #include #include @@ -16,33 +15,21 @@ #include <2geom/d2.h> // the font_instance are the template of several raster_font; they provide metrics and outlines -// that are drawn by the raster_font, so the raster_font needs info relative to the way the +// that are drawn by the raster_font, so the raster_font needs info relative to the way the // font need to be drawn. note that fontsize is a scale factor in the transform matrix // of the style -// the various raster_font in use at a given time are held in a hash_map whose indices are the -// styles, hence the 2 following 'classes' -struct font_style_hash : public std::unary_function { - size_t operator()(font_style const &x) const; -}; - -struct font_style_equal : public std::binary_function { - bool operator()(font_style const &a, font_style const &b); -}; - class font_instance { public: - // hashmap to get the raster_font for a given style - __gnu_cxx::hash_map loadedStyles; - // the real source of the font + // the real source of the font PangoFont* pFont; - // depending on the rendering backend, different temporary data + // depending on the rendering backend, different temporary data - // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance - // resides in the font_factory loadedFaces hash_map + // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance + // resides in the font_factory loadedFaces hash_map PangoFontDescription* descr; - // refcount + // refcount int refCount; - // font_factory owning this font_instance + // font_factory owning this font_instance font_factory* daddy; // common glyph definitions for all the rasterfonts @@ -58,38 +45,38 @@ public: bool IsOutlineFont(void); // utility void InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed - // in case the PangoFont is a bitmap font, for example. that way, the calling function - // will be able to check the validity of the font before installing it in loadedFaces + // in case the PangoFont is a bitmap font, for example. that way, the calling function + // will be able to check the validity of the font before installing it in loadedFaces void InitTheFace(); int MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function void LoadGlyph(int glyph_id); // the main backend-dependent function - // loads the given glyph's info - - // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply - // by the fontsize to get the real sizes + // loads the given glyph's info + + // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply + // by the fontsize to get the real sizes Path* Outline(int glyph_id, Path *copyInto=NULL); - // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead - // of allocating a new Path if copyInto != NULL + // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead + // of allocating a new Path if copyInto != NULL Geom::PathVector* PathVector(int glyph_id); // returns the 2geom-type pathvector for this glyph. no refcounting needed, it's deallocated when the font_instance dies double Advance(int glyph_id, bool vertical); - // nominal advance of the font. + // nominal advance of the font. bool FontMetrics(double &ascent, double &descent, double &leading); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts Geom::OptRect BBox(int glyph_id); - // creates a rasterfont for the given style + // creates a rasterfont for the given style raster_font* RasterFont(Geom::Matrix const &trs, double stroke_width, bool vertical = false, JoinType stroke_join = join_straight, ButtType stroke_cap = butt_straight, float miter_limit = 4.0); - // the dashes array in iStyle is copied + // the dashes array in iStyle is copied raster_font* RasterFont(font_style const &iStyle); - // private use: tells the font_instance that the raster_font 'who' has died + // private use: tells the font_instance that the raster_font 'who' has died void RemoveRasterFont(raster_font *who); - // attribute queries + // attribute queries unsigned Name(gchar *str, unsigned size); unsigned PSName(gchar *str, unsigned size); unsigned Family(gchar *str, unsigned size); @@ -98,10 +85,13 @@ public: private: void FreeTheFace(); + // hashmap to get the raster_font for a given style + void* loadedPtr; // Pointer to a hash_map. Moved into .cpp to not expose use of __gnu_cxx extension. + #ifdef USE_PANGO_WIN32 HFONT theFace; #else - FT_Face theFace; + FT_Face theFace; // it's a pointer in fact; no worries to ref/unref it, pango does its magic // as long as pFont is valid, theFace is too #endif -- cgit v1.2.3 From 95aae7353480cc5090afd4fefd27db1843e97d91 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Mon, 28 Dec 2009 13:31:56 +0100 Subject: Use correct text anchor for vertical text and when aligning or distributing (bzr r8922) --- src/libnrtype/Layout-TNG-OutIter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index f4e8e4031..0682e3570 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -227,7 +227,11 @@ boost::optional Layout::baselineAnchorPoint() const Geom::Point left_pt = this->characterAnchorPoint(pos); pos.thisEndOfLine(); Geom::Point right_pt = this->characterAnchorPoint(pos); - Geom::Point mid_pt = (left_pt + right_pt)/2; + + if (this->_blockProgression() == LEFT_TO_RIGHT || this->_blockProgression() == RIGHT_TO_LEFT) { + left_pt = Geom::Point(left_pt[Geom::Y], left_pt[Geom::X]); + right_pt = Geom::Point(right_pt[Geom::Y], right_pt[Geom::X]); + } switch (this->paragraphAlignment(pos)) { case LEFT: @@ -235,7 +239,7 @@ boost::optional Layout::baselineAnchorPoint() const return left_pt; break; case CENTER: - return mid_pt; + return (left_pt + right_pt)/2; // middle point break; case RIGHT: return right_pt; -- cgit v1.2.3 From ed4ddd304ffed5f3206ee1cf5fd9c74a78c108a6 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Wed, 6 Jan 2010 20:24:25 -0400 Subject: a better truncation detection, suggested by Richard Hughes (bzr r8950) --- src/libnrtype/Layout-TNG-Compute.cpp | 6 +++- src/libnrtype/Layout-TNG-Input.cpp | 68 ------------------------------------ src/libnrtype/Layout-TNG-Output.cpp | 2 ++ src/libnrtype/Layout-TNG.h | 4 ++- 4 files changed, 10 insertions(+), 70 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7a2924d98..f6b9688bb 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1467,8 +1467,12 @@ bool Layout::Calculator::calculate() } para.free(); - if (_scanline_maker) + if (_scanline_maker) { delete _scanline_maker; + _flow._input_truncated = false; + } else { + _flow._input_truncated = true; + } return true; } diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 33371ab10..fb2769edc 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -19,8 +19,6 @@ #include "sp-string.h" #include "FontFactory.h" -#include "text-editing.h" // for inputTruncated() - namespace Inkscape { namespace Text { @@ -324,71 +322,5 @@ Layout::InputStreamTextSource::~InputStreamTextSource() sp_style_unref(style); } -bool -Layout::inputTruncated() const -{ - if (!inputExists()) - return false; - - // Find out the SPObject to which the last visible character corresponds: - Layout::iterator last = end(); - if (last == begin()) { - // FIXME: this returns a wrong "not truncated" when a flowtext is entirely - // truncated, so there are no visible characters. But how can I find out the - // originator SPObject without having anything to do getSourceOfCharacter - // from? - return false; - } - last.prevCharacter(); - void *source; - Glib::ustring::iterator offset; - getSourceOfCharacter(last, &source, &offset); - SPObject *obj = SP_OBJECT(source); - - // if that is SPString, see if it has further characters beyond the last visible - if (obj && SP_IS_STRING(obj)) { - Glib::ustring::iterator offset_next = offset; - offset_next ++; - if (offset_next != SP_STRING(obj)->string.end()) { - // truncated: source SPString has next char - return true; - } - } - - // otherwise, see if the SPObject at end() or any of its text-tree ancestors - // (excluding top-level SPText or SPFlowText) have a text-tree next sibling with - // visible text - if (obj) { - for (SPObject *ascend = obj; - ascend && (is_part_of_text_subtree (ascend) && !is_top_level_text_object(ascend)); - ascend = SP_OBJECT_PARENT(ascend)) { - if (SP_OBJECT_NEXT(ascend)) { - SPObject *next = SP_OBJECT_NEXT(ascend); - if (next && is_part_of_text_subtree(next) && has_visible_text(next)) { - // truncated: source text object has next text sibling - return true; - } - } - } - } - - // the above works for flowed text, but not for text on path. - // so now, we also check if the last of the _characters, if coming from a TEXT_SOURCE, - // has in_glyph different from -1 - unsigned last_char = _characters.size() - 1; - unsigned span_index = _characters[last_char].in_span; - Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; - - if (_input_stream[_spans[span_index].in_input_stream_item]->Type() == TEXT_SOURCE) { - if (_characters[last_char].in_glyph == -1) { - //truncated: last char has no glyph - return true; - } - } - - // not truncated - return false; -} - }//namespace Text }//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 2b4b80e7c..d6b68ab40 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -513,8 +513,10 @@ void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) _glyphs[glyph_index].y = midpoint[1] - _lines.front().baseline_y + tangent[1] * tangent_shift + tangent[0] * normal_shift; _glyphs[glyph_index].rotation += rotation; } + _input_truncated = false; } else { // outside the bounds of the path: hide the glyphs _characters[char_index].in_glyph = -1; + _input_truncated = true; } g_free(midpoint_otp); diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 05b5103fc..0a2463a56 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -212,7 +212,9 @@ public: bool inputExists() const {return !_input_stream.empty();} - bool inputTruncated() const; + bool _input_truncated; + bool inputTruncated() const + {return _input_truncated;} /** adds a new piece of text to the end of the current list of text to be processed. This method can only add text of a consistent style. -- cgit v1.2.3