46static cairo_user_data_key_t
key;
48static cairo_status_t
font_init_cb (cairo_scaled_font_t *scaled_font,
49 cairo_t * , cairo_font_extents_t *metrics){
50 cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
51 SvgFont* instance =
static_cast<SvgFont*
>(cairo_font_face_get_user_data(face, &
key));
58 cairo_glyph_t **glyphs,
60 cairo_text_cluster_t **clusters,
62 cairo_text_cluster_flags_t *flags){
63 cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
64 SvgFont* instance =
static_cast<SvgFont*
>(cairo_font_face_get_user_data(face, &
key));
71 cairo_text_extents_t *metrics){
72 cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
73 SvgFont* instance =
static_cast<SvgFont*
>(cairo_font_face_get_user_data(face, &
key));
78 this->
face = cairo_user_font_face_create ();
83 cairo_font_face_set_user_data (this->
face, &
key, (
void*)instance, (cairo_destroy_func_t)
nullptr);
97 cairo_font_extents_t *)
102 return CAIRO_STATUS_SUCCESS;
106 const gchar* original_substring = substring;
108 while((g_utf8_get_char(substring)==g_utf8_get_char(str)) && g_utf8_get_char(substring) != 0 && g_utf8_get_char(str) != 0){
109 substring = g_utf8_next_char(substring);
110 str = g_utf8_next_char(str);
112 if (g_utf8_get_char(substring)==0)
113 return substring - original_substring;
123bool MatchVKerningRule(
SPVkern const *vkern,
125 char const *previous_unicode,
126 gchar
const *previous_glyph_name)
128 bool value = (vkern->
u1->
contains(previous_unicode[0])
136bool MatchHKerningRule(
SPHkern const *hkern,
138 char const *previous_unicode,
139 gchar
const *previous_glyph_name)
141 bool value = (hkern->
u1->
contains(previous_unicode[0])
155 cairo_glyph_t **glyphs,
157 cairo_text_cluster_t **,
159 cairo_text_cluster_flags_t *)
168 gchar* _utf8 = (gchar*) utf8;
173 while(g_utf8_get_char(_utf8)){
175 for (i=0; i < (
unsigned long) this->glyphs.size(); i++){
193 *
glyphs = (cairo_glyph_t*) malloc(count*
sizeof(cairo_glyph_t));
195 char* previous_unicode =
nullptr;
196 gchar* previous_glyph_name =
nullptr;
200 bool is_horizontal_text =
true;
201 _utf8 = (
char*) utf8;
204 while(g_utf8_get_char(_utf8)){
206 for (i=0; i < (
unsigned long) this->glyphs.size(); i++){
211 if (!previous_unicode) {
215 auto hkern = cast<SPHkern>(&
node);
216 if (hkern && is_horizontal_text &&
217 MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){
218 x -= (hkern->
k / font_height);
220 auto vkern = cast<SPVkern>(&
node);
221 if (vkern && !is_horizontal_text &&
222 MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){
223 y -= (vkern->
k / font_height);
226 previous_unicode =
const_cast<char*
>(this->glyphs[i]->unicode.c_str());
227 previous_glyph_name =
const_cast<char*
>(this->glyphs[i]->glyph_name.c_str());
228 (*glyphs)[count].index = i;
229 (*glyphs)[count].x = x;
230 (*glyphs)[count++].y = y;
233 if (is_horizontal_text) {
234 if (this->glyphs[i]->horiz_adv_x != 0) {
235 x+=(this->glyphs[i]->horiz_adv_x/font_height);
249 (*glyphs)[count].index = i;
250 (*glyphs)[count].x = x;
251 (*glyphs)[count++].y = y;
257 _utf8 = g_utf8_next_char(_utf8);
261 return CAIRO_STATUS_SUCCESS;
266 if (!pathv->
empty()){
289 if (is<SPFontFace>(&obj)) {
306 cairo_text_extents_t *)
314 if (glyph > this->
glyphs.size())
return CAIRO_STATUS_SUCCESS;
317 if (glyph ==
glyphs.size()){
319 return CAIRO_STATUS_SUCCESS;
326 if (!is<SPGlyph>(
node) && !is<SPMissingGlyph>(
node)) {
327 return CAIRO_STATUS_SUCCESS;
332 return CAIRO_STATUS_SUCCESS;
340 auto glyphNode = cast<SPGlyph>(
node);
341 if (glyphNode && glyphNode->d) {
346 auto missing = cast<SPMissingGlyph>(
node);
347 if (missing && missing->d) {
354 if (
node->hasChildren()){
358 auto path = cast<SPPath>(&
child);
360 pathv = path->curve()->get_pathvector();
365 if (is<SPObjectGroup>(&
child)) {
366 g_warning(
"TODO: svgfonts: render OBJECTGROUP");
368 auto use = cast<SPUse>(&
child);
371 auto path = cast<SPPath>(
item);
373 auto shape = cast<SPShape>(
item);
374 g_assert(shape !=
nullptr);
375 pathv = shape->curve()->get_pathvector();
385 return CAIRO_STATUS_SUCCESS;
392 auto glyph = cast<SPGlyph>(&
node);
396 auto missing = cast<SPMissingGlyph>(&
node);
415 if (is<SPFontFace>(&obj)) {
void feed_pathvector_to_cairo(cairo_t *ct, Geom::PathVector const &pathv, Geom::Affine trans, Geom::OptRect area, bool optimize_stroke, double stroke_width)
Feeds path-creating calls to the cairo context translating them from the PathVector,...
Cairo integration helpers.
3x3 matrix representing an affine transformation.
bool empty() const
Check whether the vector contains any paths.
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
bool contains(char const *name)
virtual Node * parent()=0
Get the parent of this node.
Base class for visual SVG elements.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
sigc::connection connectModified(sigc::slot< void(SPObject *, unsigned int)> slot)
Connects to the modification notification signal.
void render_glyph_path(cairo_t *cr, Geom::PathVector *pathv)
sigc::connection glyph_modified_connection
Geom::PathVector flip_coordinate_system(SPFont *spfont, Geom::PathVector pathv)
SPMissingGlyph * missingglyph
void glyph_modified(SPObject *, unsigned int)
cairo_font_face_t * get_font_face()
cairo_status_t scaled_font_render_glyph(cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics)
std::vector< SPGlyph * > glyphs
cairo_status_t scaled_font_init(cairo_scaled_font_t *scaled_font, cairo_font_extents_t *metrics)
cairo_status_t scaled_font_text_to_glyphs(cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *flags)
bool contains(char unicode)
UserFont(SvgFont *instance)
double Coord
Floating point type used to store coordinates.
Inkscape::XML::Node * node
unsigned int size_of_substring(const char *substring, gchar *str)
static cairo_status_t font_text_to_glyphs_cb(cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *flags)
static cairo_status_t font_init_cb(cairo_scaled_font_t *scaled_font, cairo_t *, cairo_font_extents_t *metrics)
static cairo_user_data_key_t key
static cairo_status_t font_render_glyph_cb(cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics)
PathVector - a sequence of subpaths.
Geom::PathVector sp_svg_read_pathv(char const *str)