summaryrefslogtreecommitdiffstats
path: root/src/display/nr-svgfonts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/display/nr-svgfonts.cpp')
-rw-r--r--src/display/nr-svgfonts.cpp107
1 files changed, 86 insertions, 21 deletions
diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp
index 62d52b04b..8869274d4 100644
--- a/src/display/nr-svgfonts.cpp
+++ b/src/display/nr-svgfonts.cpp
@@ -14,12 +14,20 @@
#include <2geom/pathvector.h>
#include <2geom/transforms.h>
-#include "../style.h"
#include <cairo.h>
#include <vector>
+#include "style.h"
#include "svg/svg.h"
-#include "inkscape-cairo.h"
-#include "nr-svgfonts.h"
+#include "display/cairo-utils.h"
+#include "display/nr-svgfonts.h"
+#include "display/nr-svgfonts.h"
+#include "sp-path.h"
+#include "sp-object-group.h"
+#include "sp-use.h"
+#include "sp-use-reference.h"
+#include "display/curve.h"
+#include "xml/repr.h"
+#include "sp-font-face.h"
//*************************//
// UserFont Implementation //
@@ -212,6 +220,47 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/,
return CAIRO_STATUS_SUCCESS;
}
+void
+SvgFont::render_glyph_path(cairo_t* cr, Geom::PathVector* pathv){
+ if (!pathv->empty()){
+ //This glyph has a path description on its d attribute, so we render it:
+ cairo_new_path(cr);
+
+ //adjust scale of the glyph
+// Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x);
+ Geom::Scale s(1.0/1000);//TODO: use here the units-per-em attribute?
+
+ Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here! (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty Geom::OptRect() )
+
+ feed_pathvector_to_cairo (cr, *pathv, s, area, false, 0);
+ cairo_fill(cr);
+ }
+}
+
+void
+SvgFont::glyph_modified(SPObject* /* blah */, unsigned int /* bleh */){
+ this->refresh();
+ //TODO: update rendering on svgfonts preview widget (in the svg fonts dialog)
+}
+
+Geom::PathVector
+SvgFont::flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv){
+ double units_per_em = 1000;
+ SPObject* obj;
+ for (obj = ((SPObject*) spfont)->children; obj; obj=obj->next){
+ if (SP_IS_FONTFACE(obj)){
+ //XML Tree being directly used here while it shouldn't be.
+ sp_repr_get_double(obj->getRepr(), "units_per_em", &units_per_em);
+ }
+ }
+
+ double baseline_offset = units_per_em - spfont->horiz_origin_y;
+
+ //This matrix flips y-axis and places the origin at baseline
+ Geom::Affine m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(baseline_offset));
+ return pathv*m;
+}
+
cairo_status_t
SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/,
unsigned long glyph,
@@ -234,37 +283,53 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/,
node = (SPObject*) this->glyphs[glyph];
}
+ if (!SP_IS_GLYPH(node) && !SP_IS_MISSING_GLYPH(node)) {
+ return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return?
+ }
+
+ SPFont* spfont = (SPFont*) node->parent;
+ if (!spfont) {
+ return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return?
+ }
+
//glyphs can be described by arbitrary SVG declared in the childnodes of a glyph node
// or using the d attribute of a glyph node.
// pathv stores the path description from the d attribute:
Geom::PathVector pathv;
if (SP_IS_GLYPH(node) && ((SPGlyph*)node)->d) {
pathv = sp_svg_read_pathv(((SPGlyph*)node)->d);
+ pathv = flip_coordinate_system(spfont, pathv);
+ this->render_glyph_path(cr, &pathv);
} else if (SP_IS_MISSING_GLYPH(node) && ((SPMissingGlyph*)node)->d) {
pathv = sp_svg_read_pathv(((SPMissingGlyph*)node)->d);
- } else {
- return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return?
+ pathv = flip_coordinate_system(spfont, pathv);
+ this->render_glyph_path(cr, &pathv);
}
- if (!pathv.empty()){
- //This glyph has a path description on its d attribute, so we render it:
- cairo_new_path(cr);
- //adjust scale of the glyph
-// Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x);
- Geom::Scale s(1.0/1000);//TODO: use here the units-per-em attribute?
- //This matrix flips the glyph vertically
- Geom::Affine m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0));
- //then we offset it
-// pathv += Geom::Point(Geom::Coord(0),Geom::Coord(-((SPFont*) node->parent)->horiz_adv_x));
- pathv += Geom::Point(Geom::Coord(0),Geom::Coord(-1000));//TODO: use here the units-per-em attribute?
-
- Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here! (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty Geom::OptRect() )
+ if (node->hasChildren()){
+ //render the SVG described on this glyph's child nodes.
+ for(node = node->children; node; node=node->next){
+ if (SP_IS_PATH(node)){
+ pathv = ((SPShape*)node)->curve->get_pathvector();
+ pathv = flip_coordinate_system(spfont, pathv);
+ this->render_glyph_path(cr, &pathv);
+ }
+ if (SP_IS_OBJECTGROUP(node)){
+ g_warning("TODO: svgfonts: render OBJECTGROUP");
+ }
+ if (SP_IS_USE(node)){
+ SPItem* item = SP_USE(node)->ref->getObject();
+ if (SP_IS_PATH(item)){
+ pathv = ((SPShape*)item)->curve->get_pathvector();
+ pathv = flip_coordinate_system(spfont, pathv);
+ this->render_glyph_path(cr, &pathv);
+ }
- feed_pathvector_to_cairo (cr, pathv, s*m, area, false, 0);
- cairo_fill(cr);
+ glyph_modified_connection = ((SPObject*) item)->connectModified(sigc::mem_fun(*this, &SvgFont::glyph_modified));
+ }
+ }
}
- //TODO: render the SVG described on this glyph's child nodes.
return CAIRO_STATUS_SUCCESS;
}