diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index e28264eff9aa2166476c14103418e9ef47c7605d..e343dbf338a62d404c7c2f6c12679d7acc532dcb 100644 (file)
# include <config.h>
#endif
+#include <string>
+
#ifdef HAVE_POPPLER
#include "svg-builder.h"
#include "io/stringstream.h"
#include "io/base64stream.h"
#include "display/nr-filter-utils.h"
-#include "libnr/nr-matrix-ops.h"
#include "libnr/nr-macros.h"
#include "libnrtype/font-instance.h"
// 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) {
_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;
}
static gchar *svgConvertRGBToText(double r, double g, double b) {
+ using Inkscape::Filters::clamp;
static gchar tmp[1023] = {0};
snprintf(tmp, 1023,
"#%02x%02x%02x",
- NR::clamp(SP_COLOR_F_TO_U(r)),
- NR::clamp(SP_COLOR_F_TO_U(g)),
- NR::clamp(SP_COLOR_F_TO_U(b)));
+ clamp(SP_COLOR_F_TO_U(r)),
+ clamp(SP_COLOR_F_TO_U(g)),
+ clamp(SP_COLOR_F_TO_U(b)));
return (gchar *)&tmp;
}
@@ -596,7 +608,8 @@ gchar *SvgBuilder::_createPattern(GfxPattern *pattern, GfxState *state, bool is_
if ( pattern->getType() == 2 ) { // Shading pattern
GfxShadingPattern *shading_pattern = (GfxShadingPattern*)pattern;
id = _createGradient(shading_pattern->getShading(),
- shading_pattern->getMatrix());
+ shading_pattern->getMatrix(),
+ !is_stroke);
} else if ( pattern->getType() == 1 ) { // Tiling pattern
id = _createTilingPattern((GfxTilingPattern*)pattern, state, is_stroke);
}
}
}
+/*
+ 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
*/
}
// 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
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
last_delta_pos = delta_pos;
// Append the character to the text buffer
- text_buffer.append((char *)&glyph.code, 1);
+ if ( !glyph.code.empty() ) {
+ text_buffer.append(1, glyph.code[0]);
+ }
glyphs_in_a_row++;
i++;
return;
}
// Allow only one space in a row
- if ( is_space && _glyphs[_glyphs.size() - 1].code_size == 1 &&
- _glyphs[_glyphs.size() - 1].code[0] == 32 ) {
+ if ( is_space && (_glyphs[_glyphs.size() - 1].code.size() == 1) &&
+ (_glyphs[_glyphs.size() - 1].code[0] == 32) ) {
Geom::Point delta(dx, dy);
_text_position += delta;
return;
_text_position += delta;
// Convert the character to UTF-8 since that's our SVG document's encoding
- static UnicodeMap *u_map = NULL;
- if ( u_map == NULL ) {
- GooString *enc = new GooString("UTF-8");
- u_map = globalParams->getUnicodeMap(enc);
- u_map->incRefCnt();
- delete enc;
- }
- int code_size = 0;
- for ( int i = 0 ; i < uLen ; i++ ) {
- code_size += u_map->mapUnicode(u[i], (char *)&new_glyph.code[code_size], sizeof(new_glyph.code) - code_size);
+ {
+ gunichar2 uu[8] = {0};
+
+ for (int i = 0; i < uLen; i++) {
+ uu[i] = u[i];
+ }
+
+ gchar *tmp = g_utf16_to_utf8(uu, uLen, NULL, NULL, NULL);
+ if ( tmp && *tmp ) {
+ new_glyph.code = tmp;
+ } else {
+ new_glyph.code.clear();
+ }
+ g_free(tmp);
}
- new_glyph.code_size = code_size;
// Copy current style if it has changed since the previous glyph
if (_invalidated_style || _glyphs.size() == 0 ) {
@@ -1362,9 +1448,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);
@@ -1453,7 +1539,7 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height
}
png_write_row(png_ptr, (png_bytep)buffer);
}
- delete buffer;
+ delete [] buffer;
} else if (color_map) {
image_stream = new ImageStream(str, width,
color_map->getNumPixelComps(),
@@ -1492,7 +1578,7 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height
png_write_row(png_ptr, (png_bytep)buffer);
}
}
- delete buffer;
+ delete [] buffer;
} else { // A colormap must be provided, so quit
png_destroy_write_struct(&png_ptr, &info_ptr);