dia r4179 - in trunk: lib plug-ins/cairo plug-ins/svg plug-ins/wmf



Author: hans
Date: Fri Jan  9 21:25:33 2009
New Revision: 4179
URL: http://svn.gnome.org/viewvc/dia?rev=4179&view=rev

Log:
2009-01-09  Hans Breuer  <hans breuer org>

	* lib/font.h : declare dia_font_get_size()
	* lib/libdia.def : export it
	* lib/font.c : use pango_font_description_set_absolute_size() - the 
	magic factor which tried to compensate for fontmap resolution issues 
	_and_ the difference between Dia's intention of "font_height" and 
	Pango's "font size" is gone. 
	There is a much less magic factor just compensating the second issue. 
	Dia's font-height always meant something like line height, i.e. a 
	good difference between two consecutive lines baselines (Pango itself 
	is using line_height=ascent+descent).
	Instead of searching the right size for a given height a new factor 
	got introduced, which unfortunately changes the font-size on win32 
	and X, but all this finally fixes bug the OS dependent part of 
	bug #108293

	* plug-ins/cairo/diacairo-renderer.c : use dia_font_get_size() and 
	pango_font_description_set_absolute_size instead of magic number 0.7
	fixing bug #538499
	* plug-ins/wmf/wmf.cpp : same here 

	* lib/diasvgrenderer.c(draw_string): moved #if-0-ed original ...
	* plug-ins/svg/render_svg.c : ... implementation to be used in SVG
	export but not for shape export. For SVG export we apparently want 
	the font-size instead of it's line-height - although my interpretation
	of the specs differs ... should fix bug #345538

	* lib/font-height.c : test program evaluating font size relations
	* lib/makefile.msc : build it

	[bugs found along the way]
	* lib/text.c : don't use font_ref when a copy is needed
	
	* lib/textline.c : removed superfluous g_warning



Added:
   trunk/lib/font-height.c   (contents, props changed)
Modified:
   trunk/lib/diasvgrenderer.c
   trunk/lib/font.c
   trunk/lib/font.h
   trunk/lib/libdia.def
   trunk/lib/makefile.msc
   trunk/lib/text.c
   trunk/lib/textline.c
   trunk/plug-ins/cairo/diacairo-renderer.c
   trunk/plug-ins/svg/render_svg.c
   trunk/plug-ins/wmf/wmf.cpp

Modified: trunk/lib/diasvgrenderer.c
==============================================================================
--- trunk/lib/diasvgrenderer.c	(original)
+++ trunk/lib/diasvgrenderer.c	Fri Jan  9 21:25:33 2009
@@ -561,7 +561,10 @@
   for (i = 1; i < numpoints; i++)
     switch (points[i].type) {
     case BEZ_MOVE_TO:
-      g_warning("only first BezPoint can be a BEZ_MOVE_TO");
+      g_warning("only first BezPoint shoul be a BEZ_MOVE_TO");
+      g_string_printf(str, "M %s %s",
+		      dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
+		      dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
       break;
     case BEZ_LINE_TO:
       g_string_append_printf(str, " L %s,%s",
@@ -615,7 +618,10 @@
   for (i = 1; i < numpoints; i++)
     switch (points[i].type) {
     case BEZ_MOVE_TO:
-      g_warning("only first BezPoint can be a BEZ_MOVE_TO");
+      g_warning("only first BezPoint should be a BEZ_MOVE_TO");
+      g_string_printf(str, "M %s %s",
+		      dia_svg_dtostr(p1x_buf, (gdouble) points[i].p1.x),
+		      dia_svg_dtostr(p1y_buf, (gdouble) points[i].p1.y) );
       break;
     case BEZ_LINE_TO:
       g_string_append_printf(str, " L %s,%s",
@@ -646,60 +652,6 @@
   TextLine *text_line = text_line_new(text, self->font, self->font_height);
   draw_text_line(self, text_line, pos, alignment, colour);
   text_line_destroy(text_line);
-  return;
-#if 0
-  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
-  xmlNodePtr node;
-  char *style, *tmp;
-  real saved_width;
-  gchar d_buf[DTOSTR_BUF_SIZE];
-
-  node = xmlNewChild(renderer->root, renderer->svg_name_space, "text", text);
- 
-  saved_width = renderer->linewidth;
-  renderer->linewidth = 0.001;
-  style = (char*)get_fill_style(renderer, colour);
-  /* return value must not be freed */
-  renderer->linewidth = saved_width;
-  /* This is going to break for non-LTR texts, as SVG thinks 'start' is
-   * 'right' for those.
-   */
-  switch (alignment) {
-  case ALIGN_LEFT:
-    style = g_strconcat(style, "; text-anchor:start", NULL);
-    break;
-  case ALIGN_CENTER:
-    style = g_strconcat(style, "; text-anchor:middle", NULL);
-    break;
-  case ALIGN_RIGHT:
-    style = g_strconcat(style, "; text-anchor:end", NULL);
-    break;
-  }
-  tmp = g_strdup_printf("%s; font-size: %s", style,
-			dia_svg_dtostr(d_buf, self->font_height) );
-  g_free (style);
-  style = tmp;
-
-  if (self->font) {
-     tmp = g_strdup_printf("%s; font-family: %s; font-style: %s; "
-                           "font-weight: %s",style,
-                           dia_font_get_family(self->font),
-                           dia_font_get_slant_string(self->font),
-                           dia_font_get_weight_string(self->font));
-     g_free(style);
-     style = tmp;
-  }
-
-  /* have to do something about fonts here ... */
-
-  xmlSetProp(node, "style", style);
-  g_free(style);
-
-  dia_svg_dtostr(d_buf, pos->x);
-  xmlSetProp(node, "x", d_buf);
-  dia_svg_dtostr(d_buf, pos->y);
-  xmlSetProp(node, "y", d_buf);
-#endif
 }
 
 

Added: trunk/lib/font-height.c
==============================================================================
--- (empty file)
+++ trunk/lib/font-height.c	Fri Jan  9 21:25:33 2009
@@ -0,0 +1,130 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * Dynamic calculat
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pango/pango.h>
+#ifdef HAVE_FREETYPE
+#include <pango/pangoft2.h>
+#endif
+#include <gdk/gdk.h>
+#ifdef GDK_WINDOWING_WIN32
+/* avoid namespace clashes caused by inclusion of windows.h */
+#define Rectangle Win32Rectangle
+#define WIN32_LEAN_AND_MEAN
+#include <pango/pangowin32.h>
+#undef Rectangle
+#endif
+
+#include "font.h"
+
+static const char *test_families[] = {
+  "sans",
+  "serif",
+  "monospace",
+  "Arial",
+  "Times New Roman",
+  "Courier New",
+  NULL
+};
+static real pixels_per_cm = 20.0;
+
+typedef enum {
+  DUMP_FACTORS = (1<<0),
+  DUMP_ABSOLUTE = (1<<1)
+} DumpFlags;
+
+static void
+dump_font_sizes (PangoContext *context, FILE *f, guint flags)
+{
+  PangoFont *font;
+  PangoFontDescription *pfd;
+  int nf;
+  real height;
+  
+  fprintf (f, "height/cm");
+  for (nf = 0; test_families[nf] != NULL; ++nf)
+    fprintf (f, "\t%s", test_families[nf]);
+  fprintf (f, "\n");
+  
+  for (height = 0.1; height <= 10.0; height += 0.1) {
+    fprintf (f, "%g", height);
+    for (nf = 0; test_families[nf] != NULL; ++nf) {
+      pfd = pango_font_description_new ();
+      pango_font_description_set_family (pfd, test_families[nf]);
+      //pango_font_description_set_size (pfd, height * pixels_per_cm * PANGO_SCALE);
+      if (flags & DUMP_ABSOLUTE)
+        pango_font_description_set_absolute_size (pfd, height * pixels_per_cm * PANGO_SCALE);
+      else
+        pango_font_description_set_size (pfd, height * pixels_per_cm * PANGO_SCALE);
+      
+      font = pango_context_load_font (context, pfd);
+      if (font) {
+        PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL);
+	/* now make a font-size where the font/line-height matches the given pixel size */
+	real total = ((double)pango_font_metrics_get_ascent (metrics) 
+	                    + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
+	real factor = height*pixels_per_cm/total;
+	real line_height;
+
+        if (flags & DUMP_ABSOLUTE)
+          pango_font_description_set_absolute_size (pfd, factor * height * pixels_per_cm * PANGO_SCALE);
+	else
+          pango_font_description_set_size (pfd, factor * height * pixels_per_cm * PANGO_SCALE);
+	pango_font_metrics_unref (metrics);
+	g_object_unref (font);
+	
+	font = pango_context_load_font (context, pfd);
+	metrics = pango_font_get_metrics (font, NULL);
+
+	line_height = ((double)pango_font_metrics_get_ascent (metrics) 
+	                     + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
+        fprintf (f, "\t%.3g",  flags & DUMP_FACTORS ? factor : line_height);
+	g_object_unref (font);
+      }
+      pango_font_description_free (pfd);
+    }
+    fprintf (f, "\n");
+  }
+}
+
+int 
+main (int argc, char **argv)
+{
+  guint flags = DUMP_ABSOLUTE;
+  int i;
+  PangoContext *context;
+  
+  for (i = 1; i < argc; ++i) {
+    if (strcmp (argv[i], "--factors") == 0)
+      flags |= DUMP_FACTORS;
+    else if (strcmp (argv[i], "--relative") == 0)
+      flags &= ~(DUMP_ABSOLUTE);
+  }
+#ifdef G_OS_WIN32
+  context = pango_win32_get_context ();
+#else
+  context = pango_ft2_get_context(75,75);
+#endif
+
+  dump_font_sizes (context, fdopen(1, "wb"), flags);
+}

Modified: trunk/lib/font.c
==============================================================================
--- trunk/lib/font.c	(original)
+++ trunk/lib/font.c	Fri Jan  9 21:25:33 2009
@@ -53,7 +53,15 @@
 
   PangoFontDescription* pfd;    
   /* mutable */ char* legacy_name;
-  PangoFont *font_ref;
+
+  /* there is a difference between Pango's font size and Dia's font height */
+  /* Calculated  font_size is to make 'font_height = ascent + descent */
+  /* The font_height is used as default line height, there used to be a hard-coded size = 0.7 * height  */
+  /* before using pango_set_absolute_size() to overcome font size differences between renderers */
+  real height;
+  /* Need to load a font to query it's metrics */
+  PangoFont *loaded;
+  PangoFontMetrics *metrics;
 };
 
 
@@ -66,45 +74,17 @@
 static void
 dia_font_check_for_font(int font) 
 {
-    DiaFont *check;
-    PangoFont *loaded;
-    static real size = 1.0;
-
-    check = dia_font_new_from_style(font, size);
-    size += 1.0;
-    loaded = pango_context_load_font(dia_font_get_context(),
-				     check->pfd);
-    if (loaded == NULL) {
-      message_error(_("Can't load font %s.\n"), dia_font_get_family(check));
-    } else {
-      PangoFont *font2;
-      PangoFontDescription *pfd2 = pango_font_description_copy (check->pfd);
-      PangoFontMetrics *m1, *m2;
-      real factor;
-      g_print ("Loaded '%s'\n", pango_font_description_to_string (check->pfd));
-      
-      if (pango_font_description_get_size_is_absolute (check->pfd))
-        pango_font_description_set_size (pfd2, pango_font_description_get_size (check->pfd));
-      else
-        pango_font_description_set_absolute_size (pfd2, pango_font_description_get_size (check->pfd));
-      
-      font2 = pango_context_load_font(dia_font_get_context(), pfd2);
-
-      m1 = pango_font_get_metrics (loaded, NULL);
-      m2 = pango_font_get_metrics (font2, NULL);
-
-      factor = (real)pango_font_metrics_get_ascent (m1) / pango_font_metrics_get_ascent (m2);
-      g_print ("Magic font-factor %g (ascents = %g / %g)\n", 
-               factor, 
-               (real)pango_font_metrics_get_ascent (m1) / PANGO_SCALE,
-               (real)pango_font_metrics_get_ascent (m2) / PANGO_SCALE);
-
-      g_object_unref (loaded);
-      g_object_unref (font2);
-      pango_font_description_free (pfd2);
-      pango_font_metrics_unref (m1);
-      pango_font_metrics_unref (m2);
-    }
+  DiaFont *check;
+  PangoFont *loaded;
+  static real height = 1.0;
+
+  check = dia_font_new_from_style(font, height);
+  loaded = pango_context_load_font(dia_font_get_context(), check->pfd);
+  if (!loaded) {
+    message_error(_("Can't load font %s.\n"), dia_font_get_family(check));
+  } else {
+    g_object_unref (loaded);
+  }
 }
 
 void
@@ -224,20 +204,60 @@
         /*GObject *gobject = G_OBJECT(font);  */
 }
 
+static void 
+dia_pfd_set_height(PangoFontDescription* pfd, real height)
+{ 
+  /* ONLY place for the magic factor! */
+  pango_font_description_set_absolute_size(pfd, dcm_to_pdu(height) * 0.8);
+}
+
+/*!
+ * In Dia a font is usually referred to by it's (line-) height, not it's size.
+ *
+ * This methods "calculates" the latter from the former. This used to be some magic factor of 0.7 which did not 
+ * solve the resolution dependencance of the former calculation. In fact there is new magic factor now because
+ * really calculating the font size from the height would involve two font loads which seem to be two expensive.
+ */
+static void
+_dia_font_adjust_size (DiaFont *font, real height, gboolean recalc_alwways)
+{
+  
+  if (font->height != height || !font->metrics || recalc_alwways) {
+    PangoFontMetrics *metrics;
+    PangoFont *loaded;
+
+    dia_pfd_set_height (font->pfd, height);
+    /* need to load a font to get it's metrics */
+    loaded = font->loaded;
+    font->loaded = pango_context_load_font(dia_font_get_context(), font->pfd);
+    if (loaded) /* drop old reference */
+      g_object_unref (loaded);
+    if (font->metrics)
+      pango_font_metrics_unref (font->metrics);
+
+    /* caching metrics */
+    font->metrics = pango_font_get_metrics (font->loaded, NULL);
+    font->height = height;
+  }
+}
 DiaFont*
 dia_font_new(const char *family, DiaFontStyle style, real height)
 {
-  DiaFont* retval = dia_font_new_from_style(style, height);
+  DiaFont* font = dia_font_new_from_style(style, height);
+  gboolean changed;
 
-  pango_font_description_set_family(retval->pfd,family);
+  changed = family != NULL && strcmp (pango_font_description_get_family(font->pfd), family) != 0;
+  pango_font_description_set_family(font->pfd, family);
 
-  retval->font_ref = pango_context_load_font(dia_font_get_context(), retval->pfd);
+  if (changed)
+    _dia_font_adjust_size (font, font->height, TRUE);
 
-  return retval;
+  return font;
 }
 
 static void
-dia_pfd_set_family(PangoFontDescription* pfd, DiaFontFamily fam) {
+dia_pfd_set_family(PangoFontDescription* pfd, DiaFontFamily fam) 
+{
   switch (fam) {
   case DIA_FONT_SANS :
     pango_font_description_set_family(pfd, "sans");
@@ -249,8 +269,9 @@
     pango_font_description_set_family(pfd, "monospace");
     break;
   default :
-          /* Pango does allow fonts without a name */
-      ;
+    /* Pango does _not_ allow fonts without a name (or at least they are not useful) */
+    pango_font_description_set_family(pfd, "sans");
+    break;
   }
 }
 
@@ -306,13 +327,6 @@
   }
 }
 
-static void 
-dia_pfd_set_size(PangoFontDescription* pfd, real height)
-{ /* inline candidate... */
-  pango_font_description_set_size(pfd, dcm_to_pdu(height) );
-}
-
-
 DiaFont*
 dia_font_new_from_style(DiaFontStyle style, real height)
 {
@@ -325,11 +339,11 @@
   dia_pfd_set_family(pfd,DIA_FONT_STYLE_GET_FAMILY(style));
   dia_pfd_set_weight(pfd,DIA_FONT_STYLE_GET_WEIGHT(style));
   dia_pfd_set_slant(pfd,DIA_FONT_STYLE_GET_SLANT(style));
-  dia_pfd_set_size(pfd,height);
+  dia_pfd_set_height(pfd,height);
   
   retval = DIA_FONT(g_object_new(DIA_TYPE_FONT, NULL));
-  
   retval->pfd = pfd;
+  _dia_font_adjust_size (retval, height, FALSE);
   retval->legacy_name = NULL;
   return retval;
 }
@@ -350,8 +364,13 @@
   
   if (font->pfd)
     pango_font_description_free(font->pfd);
-  if (font->font_ref) 
-    g_object_unref(font->font_ref);
+  font->pfd = NULL;
+  if (font->metrics)
+    pango_font_metrics_unref(font->metrics);
+  font->metrics = NULL;
+  if (font->loaded) 
+    g_object_unref(font->loaded);
+  font->loaded = NULL;
   G_OBJECT_CLASS(parent_class)->finalize(object);
 }
 
@@ -409,16 +428,21 @@
 real
 dia_font_get_height(const DiaFont* font)
 {
+  return font->height;
+}
+
+real
+dia_font_get_size(const DiaFont* font)
+{
+  if (!pango_font_description_get_size_is_absolute (font->pfd))
+    g_warning ("dia_font_get_size() : no absolute size");
   return pdu_to_dcm(pango_font_description_get_size(font->pfd));
 }
 
 void
 dia_font_set_height(DiaFont* font, real height)
 {
-  dia_pfd_set_size (font->pfd, height);
-/* not
-  pango_font_description_set_size(font->pfd, dcm_to_pdu(height));
- */
+  _dia_font_adjust_size (font, height, FALSE);
 }
 
 
@@ -448,8 +472,14 @@
 void 
 dia_font_set_any_family(DiaFont* font, const char* family)
 {
+  gboolean changed;
+  
   g_return_if_fail(font != NULL);
+  
+  changed = strcmp (pango_font_description_get_family(font->pfd), family) != 0;
   pango_font_description_set_family(font->pfd, family);
+  if (changed) /* force recalculation on name change */
+    _dia_font_adjust_size (font, font->height, TRUE);
   if (font->legacy_name) {
     g_free(font->legacy_name);
     font->legacy_name = NULL;
@@ -459,6 +489,8 @@
 void 
 dia_font_set_family(DiaFont* font, DiaFontFamily family)
 {
+  gboolean changed;
+
   g_return_if_fail(font != NULL);
   dia_pfd_set_family(font->pfd,family);  
   if (font->legacy_name) {
@@ -470,15 +502,21 @@
 void 
 dia_font_set_weight(DiaFont* font, DiaFontWeight weight)
 {
-  g_assert(font != NULL);    
+  DiaFontWeight old_weight = DIA_FONT_STYLE_GET_WEIGHT(dia_font_get_style(font));
+  g_return_if_fail(font != NULL);    
   dia_pfd_set_weight(font->pfd,weight);
+  if (old_weight != weight)
+    _dia_font_adjust_size (font, font->height, TRUE);
 }
 
 void 
 dia_font_set_slant(DiaFont* font, DiaFontSlant slant)
 {
-  g_assert(font != NULL);    
+  DiaFontSlant old_slant = DIA_FONT_STYLE_GET_SLANT(dia_font_get_style(font));
+  g_return_if_fail(font != NULL);    
   dia_pfd_set_slant(font->pfd,slant);
+  if (slant != old_slant)
+    _dia_font_adjust_size (font, font->height, TRUE);
 }
 
 
@@ -593,19 +631,31 @@
 real
 dia_font_ascent(const char* string, DiaFont* font, real height)
 {
-  TextLine *text_line = text_line_new(string, font, height);
-  real result = text_line_get_ascent(text_line);
-  text_line_destroy(text_line);
-  return result;
+  if (font->metrics) {
+    real ascent = pdu_to_dcm(pango_font_metrics_get_ascent (font->metrics));
+    return ascent * (height / font->height);
+  } else {
+    /* previous, _expensive_ but string specific way */
+    TextLine *text_line = text_line_new(string, font, height);
+    real result = text_line_get_ascent(text_line);
+    text_line_destroy(text_line);
+    return result;
+  }
 }
 
 real 
 dia_font_descent(const char* string, DiaFont* font, real height)
 {
-  TextLine *text_line = text_line_new(string, font, height);
-  real result = text_line_get_descent(text_line);
-  text_line_destroy(text_line);
-  return result;
+  if (font->metrics) {
+    real descent = pdu_to_dcm(pango_font_metrics_get_descent (font->metrics));
+    return descent * (height / font->height);
+  } else {
+    /* previous, _expensive_ but string specific way */
+    TextLine *text_line = text_line_new(string, font, height);
+    real result = text_line_get_descent(text_line);
+    text_line_destroy(text_line);
+    return result;
+  }
 }
 
 
@@ -618,6 +668,7 @@
   guint length;
   gchar *desc = NULL;
   PangoFontDescription *pfd;
+  real factor;
 
   layout = pango_layout_new(dia_font_get_context());
 
@@ -627,7 +678,9 @@
   list = pango_attr_list_new();
 
   pfd = pango_font_description_copy (font->pfd);
-  pango_font_description_set_size (pfd, dcm_to_pdu (height) * .7);
+  /* account for difference between size and height as well as between font height and given one */
+  factor = dia_font_get_size(font) / dia_font_get_height (font);
+  pango_font_description_set_absolute_size (pfd, dcm_to_pdu (height) * factor);
   attr = pango_attr_font_desc_new(pfd);
   pango_font_description_free (pfd);
 

Modified: trunk/lib/font.h
==============================================================================
--- trunk/lib/font.h	(original)
+++ trunk/lib/font.h	Fri Jan  9 21:25:33 2009
@@ -107,7 +107,6 @@
 void dia_font_pop_context(void);
 /* Retrieve the current context (used for the font widget) */
 PangoContext *dia_font_get_context(void);
-                         
                              
     /* Get a font matching family,style,height. MUST be freed with
        dia_font_unref(). */
@@ -143,6 +142,8 @@
 real dia_font_get_height(const DiaFont* font);
     /* Change the height inside a font record. */
 void dia_font_set_height(DiaFont* font, real height);
+    /* Delivers the size of the font */                         
+real dia_font_get_size(const DiaFont* font);
 
     /* Changes the slant of an existing font */
 void dia_font_set_slant(DiaFont* font, DiaFontSlant slant);

Modified: trunk/lib/libdia.def
==============================================================================
--- trunk/lib/libdia.def	(original)
+++ trunk/lib/libdia.def	Fri Jan  9 21:25:33 2009
@@ -213,6 +213,7 @@
  dia_font_get_height
  dia_font_get_legacy_name
  dia_font_get_psfontname
+ dia_font_get_size
  dia_font_get_slant_string
  dia_font_get_style
  dia_font_get_weight_string

Modified: trunk/lib/makefile.msc
==============================================================================
--- trunk/lib/makefile.msc	(original)
+++ trunk/lib/makefile.msc	Fri Jan  9 21:25:33 2009
@@ -161,6 +161,10 @@
 $(PRJ_TOP)\config.h: $(PRJ_TOP)\config.h.win32
 	copy $(PRJ_TOP)\config.h.win32 $(PRJ_TOP)\config.h
 
+font-height.exe : font-height.obj
+	$(CC) $(CFLAGS) -Fe$@ font-height.obj \
+	$(PKG_LINK) $(LDFLAGS) gdi32.lib user32.lib $(LDFLAGS) /subsystem:console
+
 .c.obj :
 	$(CC) $(CFLAGS) -c $(PKG_CFLAGS) $<
 

Modified: trunk/lib/text.c
==============================================================================
--- trunk/lib/text.c	(original)
+++ trunk/lib/text.c	Fri Jan  9 21:25:33 2009
@@ -311,7 +311,7 @@
   copy->numlines = text->numlines;
   copy->lines = g_new(TextLine *, text->numlines);
   
-  copy->font = dia_font_ref(text->font);
+  copy->font = dia_font_copy(text->font);
   copy->height = text->height;
   copy->position = text->position;
   copy->color = text->color;

Modified: trunk/lib/textline.c
==============================================================================
--- trunk/lib/textline.c	(original)
+++ trunk/lib/textline.c	Fri Jan  9 21:25:33 2009
@@ -238,10 +238,6 @@
       text_line->height != text_line->height_cache) {
     int n_offsets;
 
-    if (text_line->font != text_line->font_cache)
-      if (text_line->font_cache != NULL)
-        g_warning("leak?");
-
     if (text_line->offsets != NULL) {
       g_free(text_line->offsets);
       text_line->offsets = NULL;

Modified: trunk/plug-ins/cairo/diacairo-renderer.c
==============================================================================
--- trunk/plug-ins/cairo/diacairo-renderer.c	(original)
+++ trunk/plug-ins/cairo/diacairo-renderer.c	Fri Jan  9 21:25:33 2009
@@ -295,13 +295,15 @@
   DiaFontStyle style = dia_font_get_style (font);
   const char *family_name;
 #endif
+  /* pango/cairo wants the font size, not the (line-) height */
+  real size = dia_font_get_size (font) * (height / dia_font_get_height (font));
 
   PangoFontDescription *pfd = pango_font_description_copy (dia_font_get_description (font));
   DIAG_NOTE(g_message("set_font %f %s", height, dia_font_get_family(font)));
 
 #ifdef HAVE_PANGOCAIRO_H
   /* select font and size */
-  pango_font_description_set_size (pfd, (int)(height * 0.7 * PANGO_SCALE)); /* same magic factor as in lib/font.c */
+  pango_font_description_set_absolute_size (pfd, (int)(size * PANGO_SCALE));
   pango_layout_set_font_description (renderer->layout, pfd);
   pango_font_description_free (pfd);
 #else
@@ -312,7 +314,7 @@
       family_name,
       DIA_FONT_STYLE_GET_SLANT(style) == DIA_FONT_NORMAL ? CAIRO_FONT_SLANT_NORMAL : CAIRO_FONT_SLANT_ITALIC,
       DIA_FONT_STYLE_GET_WEIGHT(style) < DIA_FONT_MEDIUM ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD); 
-  cairo_set_font_size (renderer->cr, height * 0.7); /* same magic factor as in lib/font.c */
+  cairo_set_font_size (renderer->cr, size);
 #endif
 
   DIAG_STATE(renderer->cr)

Modified: trunk/plug-ins/svg/render_svg.c
==============================================================================
--- trunk/plug-ins/svg/render_svg.c	(original)
+++ trunk/plug-ins/svg/render_svg.c	Fri Jan  9 21:25:33 2009
@@ -44,6 +44,7 @@
 #include "diagramdata.h"
 #include "dia_xml_libxml.h"
 #include "object.h"
+#include "textline.h"
 
 G_BEGIN_DECLS
 
@@ -83,6 +84,12 @@
 static void fill_rounded_rect (DiaRenderer *renderer, 
                                Point *ul_corner, Point *lr_corner,
                                Color *colour, real rounding);
+static void draw_string       (DiaRenderer *self,
+	                       const char *text,
+			       Point *pos, Alignment alignment,
+			       Color *colour);
+static void draw_text_line    (DiaRenderer *self, TextLine *text_line,
+	                       Point *pos, Alignment alignment, Color *colour);
 
 static void svg_renderer_class_init (SvgRendererClass *klass);
 
@@ -167,6 +174,8 @@
   renderer_class->draw_object = draw_object;
   renderer_class->draw_rounded_rect = draw_rounded_rect;
   renderer_class->fill_rounded_rect = fill_rounded_rect;
+  renderer_class->draw_string  = draw_string;
+  renderer_class->draw_text_line  = draw_text_line;
 }
 
 
@@ -348,6 +357,111 @@
   xmlSetProp(node, (const xmlChar *)"ry", (xmlChar *) buf);
 }
 
+#define dia_svg_dtostr(buf,d) \
+  g_ascii_formatd(buf,sizeof(buf),"%g",(d)*renderer->scale)
+
+static void
+node_set_text_style (xmlNodePtr node,
+                     DiaSvgRenderer *renderer,
+		     const DiaFont  *font,
+		     real            font_height,
+                     Alignment       alignment,
+		     Color          *colour)
+{
+  char *style, *tmp;
+  real saved_width;
+  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];
+  DiaSvgRendererClass *svg_renderer_class = DIA_SVG_RENDERER_CLASS (renderer);
+  /* SVG font-size is the (line-) height, from SVG Spec:
+   * ... property refers to the size of the font from baseline to baseline when multiple lines of text are set ...
+  so we should be able to use font_height directly instead of:
+   */
+  real font_size = dia_font_get_size (font) * (font_height / dia_font_get_height (font));
+  /* ... but at least Inkscape and Firefox would produce the wrong font-size */
+
+  saved_width = renderer->linewidth;
+  renderer->linewidth = 0.001;
+  style = (char*)svg_renderer_class->get_fill_style(renderer, colour);
+  /* return value must not be freed */
+  renderer->linewidth = saved_width;
+  /* This is going to break for non-LTR texts, as SVG thinks 'start' is
+   * 'right' for those.
+   */
+  switch (alignment) {
+  case ALIGN_LEFT:
+    style = g_strconcat(style, "; text-anchor:start", NULL);
+    break;
+  case ALIGN_CENTER:
+    style = g_strconcat(style, "; text-anchor:middle", NULL);
+    break;
+  case ALIGN_RIGHT:
+    style = g_strconcat(style, "; text-anchor:end", NULL);
+    break;
+  }
+  tmp = g_strdup_printf("%s; font-size: %s", style,
+			dia_svg_dtostr(d_buf, font_size) );
+  g_free (style);
+  style = tmp;
+
+  if (font) {
+     tmp = g_strdup_printf("%s; font-family: %s; font-style: %s; "
+                           "font-weight: %s",style,
+                           dia_font_get_family(font),
+                           dia_font_get_slant_string(font),
+                           dia_font_get_weight_string(font));
+     g_free(style);
+     style = tmp;
+  }
+
+  /* have to do something about fonts here ... */
+
+  xmlSetProp(node, "style", style);
+  g_free(style);
+}
+
+static void
+draw_string(DiaRenderer *self,
+	    const char *text,
+	    Point *pos, Alignment alignment,
+	    Color *colour)
+{    
+  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
+  xmlNodePtr node;
+  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];
+
+  node = xmlNewChild(renderer->root, renderer->svg_name_space, "text", text);
+
+  node_set_text_style(node, DIA_SVG_RENDERER (self), self->font, self->font_height, alignment, colour);
+  
+  dia_svg_dtostr(d_buf, pos->x);
+  xmlSetProp(node, "x", d_buf);
+  dia_svg_dtostr(d_buf, pos->y);
+  xmlSetProp(node, "y", d_buf);
+}
+
+static void
+draw_text_line(DiaRenderer *self, TextLine *text_line,
+	       Point *pos, Alignment alignment, Color *colour)
+{
+  DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
+  xmlNodePtr node;
+  DiaFont *font = text_line_get_font(text_line); /* no reference? */
+  real font_height = text_line_get_height(text_line);
+  gchar d_buf[G_ASCII_DTOSTR_BUF_SIZE];
+  
+  node = xmlNewChild(renderer->root, renderer->svg_name_space, (const xmlChar *)"text", 
+		     (xmlChar *) text_line_get_string(text_line));
+
+  /* not using the renderers font but the textlines */
+  node_set_text_style(node, DIA_SVG_RENDERER (self), font, font_height, alignment, colour);
+
+  dia_svg_dtostr(d_buf, pos->x);
+  xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf);
+  dia_svg_dtostr(d_buf, pos->y);
+  xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf);
+  dia_svg_dtostr(d_buf, text_line_get_width(text_line));
+  xmlSetProp(node, (const xmlChar*)"textLength", (xmlChar *) d_buf);
+}
 static void
 export_svg(DiagramData *data, const gchar *filename, 
            const gchar *diafilename, void* user_data)

Modified: trunk/plug-ins/wmf/wmf.cpp
==============================================================================
--- trunk/plug-ins/wmf/wmf.cpp	(original)
+++ trunk/plug-ins/wmf/wmf.cpp	Fri Jan  9 21:25:33 2009
@@ -470,6 +470,7 @@
     W32::DWORD dwItalic = 0;
     W32::DWORD dwWeight = FW_DONTCARE;
     DiaFontStyle style = dia_font_get_style(font);
+    real font_size = dia_font_get_size (font) * (height / dia_font_get_height (font));
 
 
     DIAG_NOTE(renderer, "set_font %s %f\n", 
@@ -494,6 +495,7 @@
 	    W32::LOGFONT* lf = pango_win32_font_logfont (pf);
 	    /* .93 : sligthly smaller looks much better */
 	    lf->lfHeight = -SC(height*.93);
+	    lf->lfHeight = -SC(font_size);
 	    renderer->hFont = (W32::HFONT)W32::CreateFontIndirect (lf);
 	    g_free (lf);
 	    g_object_unref (pf);
@@ -528,7 +530,7 @@
 #       endif
 
 	renderer->hFont = (W32::HFONT)W32::CreateFont( 
-		- SC (height),  // logical height of font 
+		- SC (font_size),  // logical height of font 
 		0,		// logical average character width 
 		0,		// angle of escapement
 		0,		// base-line orientation angle 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]