Code

patch 179589 with UI added: optionally, try to replace a font name specified in PDF...
authorbuliabyak <buliabyak@users.sourceforge.net>
Wed, 15 Apr 2009 21:26:22 +0000 (21:26 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Wed, 15 Apr 2009 21:26:22 +0000 (21:26 +0000)
src/extension/internal/pdfinput/pdf-input.cpp
src/extension/internal/pdfinput/pdf-input.h
src/extension/internal/pdfinput/svg-builder.cpp
src/extension/internal/pdfinput/svg-builder.h

index e34c76cb1e84330ad990e0c1421376f6fbd836d0..4a8a1eb4be43b4a193ec71e806a019c96ef46c5d 100644 (file)
@@ -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 {
index 3f545a8d0737d0fd8456e11be384b409e6f280d5..6bf0f11a21b33c545f179fe66ed0848c86a9d30b 100644 (file)
@@ -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;
index 00c9e81fb29c5f1bd532a1f597749f6a4a54a901..00bd8fa4d8df9e00b2f09492381cd60b99cdd275 100644 (file)
@@ -14,6 +14,8 @@
 # include <config.h>
 #endif
 
+#include <string> 
+
 #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);
index 29add9a622b9faf427b694d145496812c225c0a1..3b9192d31a80097e55d6e73a56e00b412c25edd1 100644 (file)
@@ -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<std::string> _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;