#include "config.h"
/*
* SVGFonts rendering implementation
*
* Authors:
* Felipe C. da S. Sanches <juca@members.fsf.org>
* Jon A. Cruz <jon@joncruz.org>
*
* Copyright (C) 2008 Felipe C. da S. Sanches
*
* Released under GNU GPL version 2 or later.
* Read the file 'COPYING' for more information.
*/
#include <cairo.h>
#include <vector>
#include "sp-object.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 "sp-font-face.h"
#include "sp-glyph.h"
#include "sp-missing-glyph.h"
#include "sp-font.h"
#include "sp-glyph-kerning.h"
// ************************//
// UserFont Implementation //
// ************************//
// I wrote this binding code because Cairomm does not yet support userfonts. I have moved this code to cairomm and sent them a patch.
// Once Cairomm incorporate the UserFonts binding, this code should be removed from inkscape and Cairomm API should be used.
}
const char *utf8,
int utf8_len,
int *num_glyphs,
int *num_clusters,
return instance->scaled_font_text_to_glyphs(scaled_font, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, flags);
}
unsigned long glyph,
}
this->face = cairo_user_font_face_create ();
}
//******************************//
// SvgFont class Implementation //
//******************************//
this->missingglyph = NULL;
}
cairo_font_extents_t */*metrics*/)
{
//TODO
// metrics->ascent = .75;
// metrics->descent = .25;
return CAIRO_STATUS_SUCCESS;
}
while((g_utf8_get_char(substring)==g_utf8_get_char(str)) && g_utf8_get_char(substring) != 0 && g_utf8_get_char(str) != 0){
}
if (g_utf8_get_char(substring)==0)
return substring - original_substring;
else
return 0;
}
namespace {
//TODO: in these functions, verify what happens when using unicode strings.
char const *previous_unicode,
gchar const *previous_glyph_name)
{
return value;
}
char const *previous_unicode,
gchar const *previous_glyph_name)
{
return value;
}
} // namespace
const char *utf8,
int /*utf8_len*/,
int *num_glyphs,
cairo_text_cluster_t **/*clusters*/,
int */*num_clusters*/,
cairo_text_cluster_flags_t */*flags*/)
{
//This function receives a text string to be rendered. It then defines what is the sequence of glyphs that
// is used to properly render this string. It also defines the respective coordinates of each glyph. Thus, it
// has to read the attributes of the SVGFont hkern and vkern nodes in order to adjust the glyph kerning.
//It also determines the usage of the missing-glyph in portions of the string that does not match any of the declared glyphs.
unsigned long i;
int count = 0;
unsigned int len;
bool missing;
//First we findout whats the number of glyphs needed.
while(g_utf8_get_char(_utf8)){
missing = true;
//TODO: store this cluster
count++;
missing=false;
break;
}
}
if (missing){
//TODO: store this cluster
_utf8++;
count++;
}
}
//We use that info to allocate memory for the glyphs
count=0;
double x=0, y=0;//These vars store the position of the glyph within the rendered string
while(g_utf8_get_char(_utf8)){
len = 0;
//check whether is there a glyph declared on the SVG document
// that matches with the text string in its current position
//apply glyph kerning if appropriate
if (hkern && is_horizontal_text && MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){
}
if (vkern && !is_horizontal_text && MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){
}
}
previous_glyph_name = const_cast<char*>(this->glyphs[i]->glyph_name.c_str());//used for kerning checking
//advance glyph coordinates:
//continue;
goto raptorz;
}
}
if (len==0){
//advance glyph coordinates:
}
}
*num_glyphs = count;
return CAIRO_STATUS_SUCCESS;
}
void
//This glyph has a path description on its d attribute, so we render it:
//adjust scale of the glyph
// Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x);
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() )
cairo_fill(cr);
}
}
void
this->refresh();
//TODO: update rendering on svgfonts preview widget (in the svg fonts dialog)
}
if (dynamic_cast<SPFontFace *>(obj)) {
//XML Tree being directly used here while it shouldn't be.
}
}
//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;
}
unsigned long glyph,
cairo_text_extents_t */*metrics*/)
{
// This method does the actual rendering of glyphs.
// We have glyphs.size() glyphs and possibly one missing-glyph declared on this SVG document
// The id of the missing-glyph is always equal to glyphs.size()
// All the other glyphs have ids ranging from 0 to glyphs.size()-1
if (!missingglyph) {
return CAIRO_STATUS_SUCCESS;
}
node = missingglyph;
} else {
}
return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return?
}
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:
} else {
}
}
if (node->hasChildren()){
//render the SVG described on this glyph's child nodes.
{
if (path) {
}
}
if (dynamic_cast<SPObjectGroup *>(node)) {
g_warning("TODO: svgfonts: render OBJECTGROUP");
}
if (use) {
if (path) {
}
}
}
}
return CAIRO_STATUS_SUCCESS;
}
if (!this->userfont) {
if (glyph) {
}
if (missing) {
}
}
}
}
delete this->userfont;
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :