/** Add font data to an attribute node. * @param attr The attribute node. * @param font The value to set. */ void data_add_font(AttributeNode attr, const DiaFont *font) { DataNode data_node; DiaFontStyle style; char buffer[20+1]; /* Enought for 64bit int + zero */ data_node = xmlNewChild(attr, NULL, (const xmlChar *)"font", NULL); style = dia_font_get_style (font); xmlSetProp(data_node, (const xmlChar *)"family", (xmlChar *) dia_font_get_family(font)); g_snprintf(buffer, 20, "%d", dia_font_get_style(font)); xmlSetProp(data_node, (const xmlChar *)"style", (xmlChar *) buffer); /* Legacy support: don't crash older Dia on missing 'name' attribute */ xmlSetProp(data_node, (const xmlChar *)"name", (xmlChar *) dia_font_get_legacy_name(font)); }
G_CONST_RETURN char* dia_font_get_legacy_name(const DiaFont *font) { const char* matched_name = NULL; const char* family; DiaFontStyle style; int i; /* if we have loaded it from an old file, use the old name */ if (font->legacy_name) return font->legacy_name; family = dia_font_get_family (font); style = dia_font_get_style (font); for (i = 0; i < G_N_ELEMENTS(legacy_fonts); i++) { if (0 == g_ascii_strcasecmp (legacy_fonts[i].newname, family)) { /* match weight and slant */ DiaFontStyle st = legacy_fonts[i].style; if ((DIA_FONT_STYLE_GET_SLANT(style) | DIA_FONT_STYLE_GET_WEIGHT(style)) == (DIA_FONT_STYLE_GET_SLANT(st) | DIA_FONT_STYLE_GET_WEIGHT(st))) { return legacy_fonts[i].oldname; /* exact match */ } else if (0 == (DIA_FONT_STYLE_GET_SLANT(st) | DIA_FONT_STYLE_GET_WEIGHT(st))) { matched_name = legacy_fonts[i].oldname; /* 'unmodified' font, continue matching */ } } } return matched_name ? matched_name : "Courier"; }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self); /* 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_absolute_size (pfd, (int)(size * PANGO_SCALE)); pango_layout_set_font_description (renderer->layout, pfd); pango_font_description_free (pfd); #else if (renderer->cr) { DiaFontStyle style = dia_font_get_style (font); const char *family_name = dia_font_get_family(font); cairo_select_font_face ( renderer->cr, 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, size); DIAG_STATE(renderer->cr) }
DiaFont* dia_font_copy(const DiaFont* font) { if (!font) return NULL; return dia_font_new(dia_font_get_family(font), dia_font_get_style(font), dia_font_get_height(font)); }
void dia_font_set_slant(DiaFont* font, DiaFontSlant slant) { 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); }
void dia_font_set_weight(DiaFont* font, DiaFontWeight weight) { 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); }
G_CONST_RETURN char * dia_font_get_weight_string(const DiaFont* font) { const WeightName* p; DiaFontWeight fw = DIA_FONT_STYLE_GET_WEIGHT(dia_font_get_style(font)); for (p = weight_names; p->name != NULL; ++p) { if (p->fw == fw) return p->name; } return "normal"; }
G_CONST_RETURN char * dia_font_get_slant_string(const DiaFont* font) { const SlantName* p; DiaFontSlant fo = DIA_FONT_STYLE_GET_SLANT(dia_font_get_style(font)); for (p = slant_names; p->name != NULL; ++p) { if (p->fo == fo) return p->name; } return "normal"; }
void dia_font_set_slant_from_string(DiaFont* font, const char* obli) { DiaFontSlant fo = DIA_FONT_NORMAL; const SlantName* p; DiaFontStyle old_style; DiaFontSlant old_fo; old_style = dia_font_get_style(font); old_fo = DIA_FONT_STYLE_GET_SLANT(old_style); for (p = slant_names; p->name != NULL; ++p) { if (0 == strncmp(obli,p->name,8)) { fo = p->fo; break; } } dia_font_set_slant(font,fo); }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { WmfRenderer *renderer = WMF_RENDERER (self); W32::LPCTSTR sFace; 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", dia_font_get_family (font), height); if (renderer->hFont) { W32::DeleteObject(renderer->hFont); renderer->hFont = NULL; } if (renderer->pango_context) { g_object_unref (renderer->pango_context); renderer->pango_context = NULL; } if (renderer->use_pango) { #ifdef __PANGOWIN32_H__ /* with the pangowin32 backend there is a better way */ if (!renderer->pango_context) renderer->pango_context = pango_win32_get_context (); PangoFont* pf = pango_context_load_font (renderer->pango_context, dia_font_get_description (font)); if (pf) { 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); } else { gchar *desc = pango_font_description_to_string (dia_font_get_description (font)); dia_context_add_message(renderer->ctx, _("Cannot render unknown font:\n%s"), desc); g_free (desc); } #else g_assert_not_reached(); #endif } else { sFace = dia_font_get_family (font); dwItalic = DIA_FONT_STYLE_GET_SLANT(style) != DIA_FONT_NORMAL; /* although there is a known algorithm avoid it for cleanness */ switch (DIA_FONT_STYLE_GET_WEIGHT(style)) { case DIA_FONT_ULTRALIGHT : dwWeight = FW_ULTRALIGHT; break; case DIA_FONT_LIGHT : dwWeight = FW_LIGHT; break; case DIA_FONT_MEDIUM : dwWeight = FW_MEDIUM; break; case DIA_FONT_DEMIBOLD : dwWeight = FW_DEMIBOLD; break; case DIA_FONT_BOLD : dwWeight = FW_BOLD; break; case DIA_FONT_ULTRABOLD : dwWeight = FW_ULTRABOLD; break; case DIA_FONT_HEAVY : dwWeight = FW_HEAVY; break; default : dwWeight = FW_NORMAL; break; } //Hack to get BYTE out of namespace W32 # ifndef BYTE # define BYTE unsigned char # endif renderer->hFont = (W32::HFONT)W32::CreateFont( - SC (font_size), // logical height of font 0, // logical average character width 0, // angle of escapement 0, // base-line orientation angle dwWeight, // font weight dwItalic, // italic attribute flag 0, // underline attribute flag 0, // strikeout attribute flag DEFAULT_CHARSET, // character set identifier OUT_TT_PRECIS, // output precision CLIP_DEFAULT_PRECIS, // clipping precision PROOF_QUALITY, // output quality DEFAULT_PITCH, // pitch and family sFace); // pointer to typeface name string } }
/*! * \brief Object update function called after property change * * Not in the object interface but very important anyway. * Used to recalculate the object data after a change * \protected \memberof Outline */ static void outline_update_data (Outline *outline) { DiaObject *obj = &outline->object; /* calculate the ink_rect from two points and the given rotation */ cairo_t *cr; cairo_surface_t *surface; cairo_text_extents_t extents; real x, y; DiaFontStyle style; if (outline->path) cairo_path_destroy (outline->path); outline->path = NULL; /* surface will not be used to render anything, it is just to create the cairo context */ surface = cairo_svg_surface_create_for_stream (write_nul, NULL, 100, 100); cr = cairo_create (surface); cairo_surface_destroy (surface); /* in fact: unref() */ style = dia_font_get_style (outline->font); /* not exact matching but almost the best we can do with the toy api */ cairo_select_font_face (cr, dia_font_get_family (outline->font), 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 (cr, outline->font_height); cairo_text_extents (cr, outline->name, &extents); /* unfortunately this has no effect on the returned path? See below. */ cairo_rotate (cr, outline->rotation/(2*G_PI)); outline->mat.xx = cos(G_PI*outline->rotation/180); outline->mat.xy = sin(G_PI*outline->rotation/180); outline->mat.yx = -sin(G_PI*outline->rotation/180); outline->mat.yy = cos(G_PI*outline->rotation/180); /* fix point */ outline->ink_rect[0].x = x = obj->position.x; outline->ink_rect[0].y = y = obj->position.y; /* handle rotation */ outline->ink_rect[1].x = x + extents.width * outline->mat.xx; outline->ink_rect[1].y = y + extents.width * outline->mat.yx; outline->ink_rect[2].x = x + extents.width * outline->mat.xx + extents.height * outline->mat.xy; outline->ink_rect[2].y = y + extents.width * outline->mat.yx + extents.height * outline->mat.yy; outline->ink_rect[3].x = x + extents.height * outline->mat.xy; outline->ink_rect[3].y = y + extents.height * outline->mat.yy; /* x_advance? */ /* calculate bounding box */ { PolyBBExtras bbex = {0, 0, outline->line_width/2, 0, 0 }; polyline_bbox (&outline->ink_rect[0], 4, &bbex, TRUE, &obj->bounding_box); } outline_update_handles (outline), cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing); #if 0 /* reset the matrix to not yet change the outline_draw method */ outline->mat.xx = 1.0; outline->mat.xy = 0.0; outline->mat.yx = 0.0; outline->mat.yy = 1.0; #endif cairo_text_path (cr, outline->name); /* reset the rotation to not have the path rotated back and forth: no effect */ cairo_rotate (cr, 0.0); outline->path = cairo_copy_path (cr); /* the cairo context is only used in this fuinction */ cairo_destroy (cr); }