From 75b857d473541532819bd791105cb352c9a43214 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Wed, 15 Apr 2009 21:26:22 +0000 Subject: [PATCH] patch 179589 with UI added: optionally, try to replace a font name specified in PDF with the closest-named local installed font (since we do not extract any fonts, nor can we embed them into svg) --- src/extension/internal/pdfinput/pdf-input.cpp | 12 +++ src/extension/internal/pdfinput/pdf-input.h | 1 + .../internal/pdfinput/svg-builder.cpp | 94 +++++++++++++++++-- src/extension/internal/pdfinput/svg-builder.h | 3 + 4 files changed, 103 insertions(+), 7 deletions(-) diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index e34c76cb1..4a8a1eb4b 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -117,6 +117,7 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar *uri) _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText()); _textHandlingCombo->append_text(_("Import text as text")); _textHandlingCombo->set_active_text(_("Import text as text")); + _localFontsCheck = Gtk::manage(new class Gtk::CheckButton(_("Replace PDF fonts by closest-named installed fonts"))); hbox5 = Gtk::manage(new class Gtk::HBox(false, 4)); _embedImagesCheck = Gtk::manage(new class Gtk::CheckButton(_("Embed images"))); @@ -211,6 +212,10 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar *uri) _labelText->set_selectable(false); hbox5->pack_start(*_labelText, Gtk::PACK_SHRINK, 0); hbox5->pack_start(*_textHandlingCombo, Gtk::PACK_SHRINK, 0); + _localFontsCheck->set_flags(Gtk::CAN_FOCUS); + _localFontsCheck->set_relief(Gtk::RELIEF_NORMAL); + _localFontsCheck->set_mode(true); + _localFontsCheck->set_active(true); _embedImagesCheck->set_flags(Gtk::CAN_FOCUS); _embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL); _embedImagesCheck->set_mode(true); @@ -219,6 +224,7 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar *uri) vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0); vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0); vbox3->pack_start(*hbox5, Gtk::PACK_SHRINK, 4); + vbox3->pack_start(*_localFontsCheck, Gtk::PACK_SHRINK, 0); vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0); alignment4->add(*vbox3); _labelImportSettings->set_alignment(0.5,0.5); @@ -269,6 +275,7 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar *uri) _labelText->show(); _textHandlingCombo->show(); hbox5->show(); + _localFontsCheck->show(); _embedImagesCheck->show(); vbox3->show(); alignment4->show(); @@ -364,6 +371,11 @@ void PdfImportDialog::getImportSettings(Inkscape::XML::Node *prefs) { } sp_repr_set_svg_double(prefs, "approximationPrecision", _fallbackPrecisionSlider->get_value()); + if (_localFontsCheck->get_active()) { + prefs->setAttribute("localFonts", "1"); + } else { + prefs->setAttribute("localFonts", "0"); + } if (_embedImagesCheck->get_active()) { prefs->setAttribute("embedImages", "1"); } else { diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h index 3f545a8d0..6bf0f11a2 100644 --- a/src/extension/internal/pdfinput/pdf-input.h +++ b/src/extension/internal/pdfinput/pdf-input.h @@ -85,6 +85,7 @@ private: class Gtk::Label * _labelText; class Gtk::ComboBoxText * _textHandlingCombo; class Gtk::HBox * hbox5; + class Gtk::CheckButton * _localFontsCheck; class Gtk::CheckButton * _embedImagesCheck; class Gtk::VBox * vbox3; class Gtk::Alignment * alignment4; diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 00c9e81fb..00bd8fa4d 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -14,6 +14,8 @@ # include #endif +#include + #ifdef HAVE_POPPLER #include "svg-builder.h" @@ -88,6 +90,7 @@ SvgBuilder::SvgBuilder(SPDocument *document, gchar *docname, XRef *xref) { // Set default preference settings _preferences = _xml_doc->createElement("svgbuilder:prefs"); _preferences->setAttribute("embedImages", "1"); + _preferences->setAttribute("localFonts", "1"); } SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) { @@ -112,6 +115,15 @@ void SvgBuilder::_init() { _current_font = NULL; _current_state = NULL; + // Fill _availableFontNames (Bug LP #179589) (code cfr. FontLister) + FamilyToStylesMap familyStyleMap; + font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); + for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); + iter != familyStyleMap.end(); + iter++) { + _availableFontNames.push_back(iter->first.c_str()); + } + _transp_group_stack = NULL; SvgGraphicsState initial_state; initial_state.softmask = NULL; @@ -851,6 +863,67 @@ void SvgBuilder::updateStyle(GfxState *state) { } } +/* + MatchingChars + Count for how many characters s1 matches sp taking into account + that a space in sp may be removed or replaced by some other tokens + specified in the code. (Bug LP #179589) +*/ +static int MatchingChars(std::string s1, std::string sp) +{ + unsigned int is = 0; + unsigned int ip = 0; + + while(is < s1.length() && ip < sp.length()) { + if (s1[is] == sp[ip]) { + is++; ip++; + } else if (sp[ip] == ' ') { + ip++; + if (s1[is] == '_') { // Valid matches to spaces in sp. + is++; + } + } else { + break; + } + } + return(ip); +} + +/* + SvgBuilder::_BestMatchingFont + Scan the available fonts to find the font name that best matches PDFname. + (Bug LP #179589) +*/ +std::string SvgBuilder::_BestMatchingFont(std::string PDFname) +{ + double bestMatch = 0; + std::string bestFontname = "Arial"; + + for (guint i = 0; i < _availableFontNames.size(); i++) { + std::string fontname = _availableFontNames[i]; + + // At least the first word of the font name should match. + guint minMatch = fontname.find(" "); + if (minMatch == std::string::npos) { + minMatch = fontname.length(); + } + + int Match = MatchingChars(PDFname, fontname); + if (Match >= minMatch) { + double relMatch = (float)Match / (fontname.length() + PDFname.length()); + if (relMatch > bestMatch) { + bestMatch = relMatch; + bestFontname = fontname; + } + } + } + + if (bestMatch == 0) + return PDFname; + else + return bestFontname; +} + /** * This array holds info about translating font weight names to more or less CSS equivalents */ @@ -917,10 +990,17 @@ void SvgBuilder::updateFont(GfxState *state) { } // Font family - if (font->getFamily()) { + if (font->getFamily()) { // if font family is explicitly given use it. sp_repr_css_set_property(_font_style, "font-family", font->getFamily()->getCString()); - } else { - sp_repr_css_set_property(_font_style, "font-family", font_family); + } else { + int attr_value = 1; + sp_repr_get_int(_preferences, "localFonts", &attr_value); + if (attr_value != 0) { + // Find the font that best matches the stripped down (orig)name (Bug LP #179589). + sp_repr_css_set_property(_font_style, "font-family", _BestMatchingFont(font_family).c_str()); + } else { + sp_repr_css_set_property(_font_style, "font-family", font_family); + } } // Font style @@ -1177,7 +1257,7 @@ void SvgBuilder::_flushText() { Glib::ustring properFontSpec = font_factory::Default()->ConstructFontSpecification(descr); pango_font_description_free(descr); sp_repr_css_set_property(glyph.style, "-inkscape-font-specification", properFontSpec.c_str()); - + // Set style and unref SPCSSAttr if it won't be needed anymore sp_repr_css_change(tspan_node, glyph.style, "style"); if ( glyph.style_changed && i != _glyphs.begin() ) { // Free previous style @@ -1365,9 +1445,9 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height return NULL; } // Decide whether we should embed this image - double attr_value = 1.0; - sp_repr_get_double(_preferences, "embedImages", &attr_value); - bool embed_image = ( attr_value != 0.0 ); + int attr_value = 1; + sp_repr_get_int(_preferences, "embedImages", &attr_value); + bool embed_image = ( attr_value != 0 ); // Set read/write functions Inkscape::IO::StringOutputStream base64_string; Inkscape::IO::Base64OutputStream base64_stream(base64_string); diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index 29add9a62..3b9192d31 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -196,6 +196,8 @@ private: void _flushText(); // Write buffered text into doc + std::string _BestMatchingFont(std::string PDFname); + // Handling of node stack Inkscape::XML::Node *pushNode(const char* name); Inkscape::XML::Node *popNode(); @@ -215,6 +217,7 @@ private: bool _in_text_object; // Whether we are inside a text object bool _invalidated_style; GfxState *_current_state; + std::vector _availableFontNames; // Full names, used for matching font names (Bug LP #179589). bool _is_top_level; // Whether this SvgBuilder is the top-level one SPDocument *_doc; -- 2.30.2