static void dia_font_check_for_font(int font) { 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); } }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { DiaPsFt2Renderer *renderer = DIA_PS_FT2_RENDERER(self); if (renderer->current_font != font) { if (renderer->current_font != NULL) { dia_font_unref(renderer->current_font); } renderer->current_font = font; /* Dammit! We have a random factor once again! * And not only here but also in dia_font_scaled_build_layout() below ... */ renderer->current_height = height/**4.3*/; dia_font_ref(font); } pango_context_set_font_description(dia_font_get_context(), dia_font_get_description(font)); }
/*! * 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) { 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; } }
PangoLayout* dia_font_build_layout(const char* string, DiaFont* font, real height) { PangoLayout* layout; PangoAttrList* list; PangoAttribute* attr; guint length; PangoFontDescription *pfd; real factor; layout = pango_layout_new(dia_font_get_context()); length = string ? strlen(string) : 0; pango_layout_set_text(layout, string, length); list = pango_attr_list_new(); pfd = pango_font_description_copy (font->pfd); /* 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); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert(list,attr); /* eats attr */ pango_layout_set_attributes(layout,list); pango_attr_list_unref(list); pango_layout_set_indent(layout,0); pango_layout_set_justify(layout,FALSE); pango_layout_set_alignment(layout,PANGO_ALIGN_LEFT); return layout; }
static void draw_text_line(DiaRenderer *self, TextLine *text_line, Point *pos, Alignment alignment, Color *color) { DiaPsFt2Renderer *renderer = DIA_PS_FT2_RENDERER(self); PangoLayout *layout; int line, linecount; double xpos = pos->x, ypos = pos->y; char *text = text_line_get_string(text_line); /* TODO: we could probably pass the alignment down to the PS file? */ xpos -= text_line_get_alignment_adjustment (text_line, alignment); /* Using the global PangoContext does not allow to have renderer specific * different ones. Or it implies the push/pop _context mess. Anyway just * get rid of warnings for now. But the local code may be resurreted * sooner or later... --hb */ #define USE_GLOBAL_CONTEXT #ifndef USE_GLOBAL_CONTEXT PangoAttrList* list; PangoAttribute* attr; guint length; #endif if ((!text)||(text == (const char *)(1))) return; lazy_setcolor(DIA_PS_RENDERER(renderer),color); #define ANNOYING_SCALE_FACTOR 5.9 /* Make sure the letters aren't too wide. */ #ifdef USE_GLOBAL_CONTEXT layout = dia_font_build_layout(text, text_line_get_font(text_line), text_line_get_height(text_line)*ANNOYING_SCALE_FACTOR); #else /* approximately what would be required but w/o dia_font_get_context() */ dia_font_set_height(text_line_get_font(text_line), text_line_get_height(text_line)); layout = pango_layout_new(dia_font_get_context()); length = text ? strlen(text) : 0; pango_layout_set_text(layout,text,length); list = pango_attr_list_new(); attr = pango_attr_font_desc_new(dia_font_get_description(text_line_get_font(text_line))); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert(list,attr); pango_layout_set_attributes(layout,list); pango_attr_list_unref(list); pango_layout_set_indent(layout,0); pango_layout_set_justify(layout,FALSE); #endif pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); linecount = pango_layout_get_line_count(layout); for (line = 0; line < linecount; line++) { PangoLayoutLine *layoutline = pango_layout_get_line(layout, line); /* Not sure scale is the right one here. */ text_line_adjust_layout_line(text_line, layoutline, ANNOYING_SCALE_FACTOR); postscript_draw_contour(DIA_PS_RENDERER(renderer), DPI, /* dpi_x */ layoutline, xpos, ypos); ypos += 10;/* Some line height thing??? */ } }
gboolean text_to_path (const Text *text, GArray *points) { cairo_t *cr; cairo_surface_t *surface; PangoLayout *layout; PangoRectangle ink_rect; char *str; gboolean ret = FALSE; if (!PANGO_IS_CAIRO_FONT_MAP (pango_context_get_font_map (dia_font_get_context()))) return FALSE; layout = pango_layout_new(dia_font_get_context()); pango_layout_set_font_description (layout, dia_font_get_description (text->font)); pango_layout_set_indent (layout, 0); pango_layout_set_justify (layout, FALSE); pango_layout_set_alignment (layout, text->alignment == ALIGN_LEFT ? PANGO_ALIGN_LEFT : text->alignment == ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_CENTER); str = text_get_string_copy (text); pango_layout_set_text (layout, str, -1); g_free (str); pango_layout_get_extents (layout, &ink_rect, NULL); /* any surface should do - this one is always available */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink_rect.width / PANGO_SCALE, ink_rect.height / PANGO_SCALE); cr = cairo_create (surface); cairo_surface_destroy (surface); pango_cairo_layout_path (cr, layout); /* convert the path */ if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) { cairo_path_t *path; int i; path = cairo_copy_path (cr); for (i=0; i < path->num_data; i += path->data[i].header.length) { cairo_path_data_t *data = &path->data[i]; BezPoint bp; switch (data->header.type) { case CAIRO_PATH_MOVE_TO : bp.type = BEZ_MOVE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; break; case CAIRO_PATH_LINE_TO : bp.type = BEZ_LINE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; break; case CAIRO_PATH_CURVE_TO : bp.type = BEZ_CURVE_TO; bp.p1.x = data[1].point.x; bp.p1.y = data[1].point.y; bp.p2.x = data[2].point.x; bp.p2.y = data[2].point.y; bp.p3.x = data[3].point.x; bp.p3.y = data[3].point.y; break; case CAIRO_PATH_CLOSE_PATH : /* can't do anything */ default : continue; } g_array_append_val (points, bp); } ret = (path->status == CAIRO_STATUS_SUCCESS); cairo_path_destroy (path); } /* finally scale it ? */ /* clean up */ g_object_unref (layout); cairo_destroy (cr); return ret; }