summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ffc918b)
raw | patch | inline | side by side (parent: ffc918b)
author | bryce <bryce@users.sourceforge.net> | |
Sat, 5 Jan 2008 10:38:18 +0000 (10:38 +0000) | ||
committer | bryce <bryce@users.sourceforge.net> | |
Sat, 5 Jan 2008 10:38:18 +0000 (10:38 +0000) |
(Closes LP: #169973)
- New attribute in an object's style string called
-inkscape-font-specification stores full font name
- This will be useful when we can support fonts that don't fit into the
confines of CSS (if either pango enhances their PangoFontDescription
structure, or we can get around its limitations)
- Framework in place to separate font families from their "styles"
(faces)
in the text and font dialog - need only the code that does the actual
separation
- Text and Styles dialog shows only fonts it can handle
- New attribute in an object's style string called
-inkscape-font-specification stores full font name
- This will be useful when we can support fonts that don't fit into the
confines of CSS (if either pango enhances their PangoFontDescription
structure, or we can get around its limitations)
- Framework in place to separate font families from their "styles"
(faces)
in the text and font dialog - need only the code that does the actual
separation
- Text and Styles dialog shows only fonts it can handle
21 files changed:
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 4169dee51997ca7362ddebbd01e5708c1be2489b..c00268b968a913e4ade645c68917b5f78911b549 100644 (file)
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
{SP_ATTR_LAYOUT_OPTIONS,"inkscape:layoutOptions"},
/* CSS2 */
+ {SP_PROP_INKSCAPE_FONT_SPEC, "-inkscape-font-specification"},
/* Font */
{SP_PROP_FONT, "font"},
{SP_PROP_FONT_FAMILY, "font-family"},
diff --git a/src/attributes.h b/src/attributes.h
index 33e06089351237909ed41d97eb48c0367bb9b1b9..89b3f4d04a6ae329f386ccfd42692705c8a0e443 100644 (file)
--- a/src/attributes.h
+++ b/src/attributes.h
* True iff k is a property in SVG, i.e. something that can be written either in a style attribute
* or as its own XML attribute.
*/
-#define SP_ATTRIBUTE_IS_CSS(k) (((k) >= SP_PROP_FONT) && ((k) <= SP_PROP_TEXT_RENDERING))
+#define SP_ATTRIBUTE_IS_CSS(k) (((k) >= SP_PROP_INKSCAPE_FONT_SPEC) && ((k) <= SP_PROP_TEXT_RENDERING))
enum SPAttributeEnum {
SP_ATTR_INVALID, ///< Must have value 0.
SP_ATTR_LAYOUT_OPTIONS,
/* CSS2 */
+ /* Custom full font name because Font stuff below is inadequate */
+ SP_PROP_INKSCAPE_FONT_SPEC,
/* Font */
SP_PROP_FONT,
SP_PROP_FONT_FAMILY,
diff --git a/src/axis-manip.h b/src/axis-manip.h
index 7513bebaf5237a1a69478a2b49ff1c7455c848ce..8fb8fdc8e972ce5f4a556d2106eff77816a02c6a 100644 (file)
--- a/src/axis-manip.h
+++ b/src/axis-manip.h
namespace Proj {
enum VPState {
- FINITE = 0,
- INFINITE
+ VP_FINITE = 0,
+ VP_INFINITE
};
// The X-/Y-/Z-axis corresponds to the first/second/third digit
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index d0cecda03673b8b4cc306b47e1c78bd4e260fe97..e56e7fbbe8acf99eb26155b5eb2f617e83f226ed 100644 (file)
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
}
}
+int
+objects_query_fontspecification (GSList *objects, SPStyle *style_res)
+{
+ bool different = false;
+ int texts = 0;
+
+ if (style_res->text->font_specification.value) {
+ g_free(style_res->text->font_specification.value);
+ style_res->text->font_specification.value = NULL;
+ }
+ style_res->text->font_specification.set = FALSE;
+
+ for (GSList const *i = objects; i != NULL; i = i->next) {
+ SPObject *obj = SP_OBJECT (i->data);
+
+ if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj)
+ && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj)
+ && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj))
+ continue;
+
+ SPStyle *style = SP_OBJECT_STYLE (obj);
+ if (!style) continue;
+
+ texts ++;
+
+ if (style_res->text->font_specification.value && style->text->font_specification.value &&
+ strcmp (style_res->text->font_specification.value, style->text->font_specification.value)) {
+ different = true; // different fonts
+ }
+
+ if (style_res->text->font_specification.value) {
+ g_free(style_res->text->font_specification.value);
+ style_res->text->font_specification.value = NULL;
+ }
+
+ style_res->text->font_specification.set = TRUE;
+ style_res->text->font_specification.value = g_strdup(style->text->font_specification.value);
+ }
+
+ if (texts == 0 || !style_res->text->font_specification.set)
+ return QUERY_STYLE_NOTHING;
+
+ if (texts > 1) {
+ if (different) {
+ return QUERY_STYLE_MULTIPLE_DIFFERENT;
+ } else {
+ return QUERY_STYLE_MULTIPLE_SAME;
+ }
+ } else {
+ return QUERY_STYLE_SINGLE;
+ }
+}
+
int
objects_query_blend (GSList *objects, SPStyle *style_res)
{
} else if (property == QUERY_STYLE_PROPERTY_MASTEROPACITY) {
return objects_query_opacity (list, style);
-
+
+ } else if (property == QUERY_STYLE_PROPERTY_FONT_SPECIFICATION) {
+ return objects_query_fontspecification (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTFAMILY) {
return objects_query_fontfamily (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTSTYLE) {
diff --git a/src/desktop-style.h b/src/desktop-style.h
index 3f201aa285ce03d4cda9ff9c64295065fe1047d8..b99f12fde972289caaf8c3263f6ae8b6611954f1 100644 (file)
--- a/src/desktop-style.h
+++ b/src/desktop-style.h
QUERY_STYLE_PROPERTY_STROKEJOIN, // stroke join
QUERY_STYLE_PROPERTY_STROKECAP, // stroke cap
QUERY_STYLE_PROPERTY_STROKESTYLE, // markers, dasharray, miterlimit, stroke-width, stroke-cap, stroke-join
+ QUERY_STYLE_PROPERTY_FONT_SPECIFICATION, //-inkscape-font-specification
QUERY_STYLE_PROPERTY_FONTFAMILY, // font-family
QUERY_STYLE_PROPERTY_FONTSTYLE, // font style
QUERY_STYLE_PROPERTY_FONTNUMBERS, // size, spacings
index 279c5b5e714bb4c14b6b3d2e24c0edfaef7698f3..d96583f8522000347371fd92ee2d5d9cbedca2d3 100644 (file)
font_instance *font = sp_font_selector_get_font (SP_FONT_SELECTOR (fontsel));
if ( font ) {
+ Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font);
+ sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str());
+
gchar c[256];
+
font->Family(c, 256);
sp_repr_css_set_property (css, "font-family", c);
// create temporary style
SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
// query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
- int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
- int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
+ int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+ int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
+ int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
// If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) {
+ // (Ok to not get a font specification - must just rely on the family and style in that case)
+ if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING
+ || result_numbers == QUERY_STYLE_NOTHING) {
repr = inkscape_get_repr (INKSCAPE, "tools.text");
if (repr) {
gtk_widget_set_sensitive (notebook, TRUE);
}
// FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists
- font_instance *font = (font_factory::Default())->Face ( query->text->font_family.value, font_style_to_pos(*query) );
+
+ // Get a font_instance using the font-specification attribute stored in SPStyle if available
+ font_instance *font = font_factory::Default()->FaceFromStyle(query);
+
+
if (font) {
// the font is oversized, so we need to pass the true size separately
sp_font_selector_set_font (SP_FONT_SELECTOR (fontsel), font, query->font_size.computed);
index 4baab1740c0f7f253d036af9a610d256082943c0..ae17a6edd5b25ca6b164a7c5b36bd461f3e27107 100644 (file)
@@ -830,7 +830,7 @@ PrintCairoPDF::text(Inkscape::Extension::Print *mod, char const *text, NR::Point
}
// create font instance from style and use it
- font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value, font_style_to_pos(*style));
+ font_instance *tf = font_factory::Default()->FaceFromStyle(style);
if (tf == NULL) { // do something
g_printf("Warning: trouble getting font_instance\n");
tf = (font_factory::Default())->Face("sans", font_style_to_pos(*style));
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index 3d96991a6e3a0bb7a8fe1c32b64ea44c4f6373b2..076f12906440e0127dac6f115464c8c9e51b7678 100644 (file)
break;
} else {
tspan_node = _xml_doc->createElement("svg:tspan");
- tspan_node->setAttribute("inkscape:font-specification", glyph.font_specification);
+
+ ///////
+ // Create a font specification string and save the attribute in the style
+ PangoFontDescription *descr = pango_font_description_from_string(glyph.font_specification);
+ Glib::ustring properFontSpec = font_factory::Default()->ConstructFontSpecification(descr);
+ pango_font_description_free(descr);
+ sp_repr_css_set_property(glyph.style, "-inkscape-font-specification", properFontSpec.c_str());
+
// Set style and unref SPCSSAttr if it won't be needed anymore
sp_repr_css_change(tspan_node, glyph.style, "style");
if ( glyph.style_changed && i != _glyphs.begin() ) { // Free previous style
index fedde86a2020989542902721f35c67641d61e89f..6cc27988dc4e9deff00b50d1d2cf7204a16ff0c2 100644 (file)
@@ -913,7 +913,7 @@ PrintPS::image(Inkscape::Extension::Print *mod, guchar *px, unsigned int w, unsi
char const *
PrintPS::PSFontName(SPStyle const *style)
{
- font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value, font_style_to_pos(*style));
+ font_instance *tf = font_factory::Default()->FaceFromStyle(style);
char const *n;
char name_buf[256];
* that's why using PSFontName() method just to get the PS fontname
* is not enough and not appropriate
*/
- font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value, font_style_to_pos(*style));
+ font_instance *tf = font_factory::Default()->FaceFromStyle(style);
+
const gchar *fn = NULL;
char name_buf[256];
index 32f71aed0a2349b08c3a1b65eeef911633c671fe..2d56a1a41e89278c8ebe676a7daaa9b002af080d 100644 (file)
#include "FontFactory.h"
#include <libnrtype/font-instance.h>
+#include <glibmm.h>
+
#ifdef HAVE_CONFIG_H
# include "config.h"
* Q: Shouldn't this include the other tests such as is_outline, etc.?
* Q: Is there a problem with strcasecmp on Win32? Should it use stricmp?
*/
-static int
-style_name_compare(void const *aa, void const *bb)
+int
+style_name_compare(char const *aa, char const *bb)
{
char const *a = (char const *) aa;
char const *b = (char const *) bb;
/**
* On Win32 performs a stricmp(a,b), otherwise does a strcasecmp(a,b)
*/
-static int
-family_name_compare(void const *a, void const *b)
+int
+family_name_compare(char const *a, char const *b)
{
#ifndef WIN32
return strcasecmp((*((char const **) a)), (*((char const **) b)));
//pango_ft2_shutdown_display();
#endif
//g_object_unref(fontContext);
+
+ // Delete the pango font pointers in the string to instance map
+ PangoStringToDescrMap::iterator it = fontInstanceMap.begin();
+ while (it != fontInstanceMap.end()) {
+ pango_font_description_free((*it).second);
+ it++;
+ }
+}
+
+
+Glib::ustring font_factory::ConstructFontSpecification(PangoFontDescription *font)
+{
+ Glib::ustring pangoString;
+
+ g_assert(font);
+
+ if (font) {
+ // Once the format for the font specification is decided, it must be
+ // kept.. if it is absolutely necessary to change it, the attribute
+ // it is written to needs to have a new version so the legacy files
+ // can be read.
+
+ PangoFontDescription *copy = pango_font_description_copy(font);
+
+ pango_font_description_unset_fields (copy, PANGO_FONT_MASK_SIZE);
+ pangoString = Glib::ustring(pango_font_description_to_string(copy));
+
+ pango_font_description_free(copy);
+
+ }
+
+ return pangoString;
+}
+
+Glib::ustring font_factory::ConstructFontSpecification(font_instance *font)
+{
+ Glib::ustring pangoString;
+
+ g_assert(font);
+
+ if (font) {
+ pangoString = ConstructFontSpecification(font->descr);
+ }
+
+ return pangoString;
+}
+
+Glib::ustring font_factory::GetUIFamilyString(PangoFontDescription const *fontDescr)
+{
+ Glib::ustring family;
+
+ g_assert(fontDescr);
+
+ if (fontDescr) {
+ // For now, keep it as family name taken from pango
+ family = pango_font_description_get_family(fontDescr);
+ }
+
+ return family;
+}
+
+Glib::ustring font_factory::GetUIStyleString(PangoFontDescription const *fontDescr)
+{
+ Glib::ustring style;
+
+ g_assert(fontDescr);
+
+ if (fontDescr) {
+ PangoFontDescription *fontDescrCopy = pango_font_description_copy(fontDescr);
+
+ pango_font_description_unset_fields(fontDescrCopy, PANGO_FONT_MASK_FAMILY);
+ pango_font_description_unset_fields(fontDescrCopy, PANGO_FONT_MASK_SIZE);
+
+ // For now, keep it as style name taken from pango
+ style = pango_font_description_to_string(fontDescrCopy);
+
+ pango_font_description_free(fontDescrCopy);
+ }
+
+ return style;
+}
+
+Glib::ustring font_factory::ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily)
+{
+ Glib::ustring newFontSpec;
+
+ // Although we are using the string from pango_font_description_to_string for the
+ // font specification, we definitely cannot just set the new family in the
+ // PangoFontDescription structure and ask for a new string. This is because
+ // what constitutes a "family" in our own UI may be different from how Pango
+ // sees it.
+
+ // Find the PangoFontDescription associated to this fontSpec
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ g_assert(it != fontInstanceMap.end());
+
+ if (it != fontInstanceMap.end()) {
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ // Grab the UI Family string from the descr
+ Glib::ustring uiFamily = GetUIFamilyString(descr);
+
+ // Replace the UI Family name with the new family name
+ std::size_t found = fontSpec.find(uiFamily);
+ if (found != Glib::ustring::npos) {
+ newFontSpec = fontSpec;
+ newFontSpec.erase(found, uiFamily.size());
+ newFontSpec.insert(found, newFamily);
+
+ // If the new font specification does not exist in the reference maps,
+ // search for the next best match for the faces in that style
+ it = fontInstanceMap.find(newFontSpec);
+ if (it == fontInstanceMap.end()) {
+
+ PangoFontDescription *newFontDescr = pango_font_description_from_string(newFontSpec.c_str());
+
+ PangoFontDescription *bestMatchForNewDescr = NULL;
+ Glib::ustring bestMatchFontDescription;
+
+ bool setFirstFamilyMatch = false;
+ for (it = fontInstanceMap.begin(); it != fontInstanceMap.end(); it++) {
+
+ Glib::ustring currentFontSpec = (*it).first;
+
+ // Save some time by only looking at the right family
+ if (currentFontSpec.find(newFamily) != Glib::ustring::npos) {
+ if (!setFirstFamilyMatch) {
+ // This ensures that the closest match is at least within the correct
+ // family rather than the first font in the list
+ bestMatchForNewDescr = pango_font_description_copy((*it).second);
+ bestMatchFontDescription = currentFontSpec;
+ setFirstFamilyMatch = true;
+ } else {
+ // Get the font description that corresponds, and
+ // then see if we've found a better match
+ PangoFontDescription *possibleMatch = pango_font_description_copy((*it).second);
+
+ if (pango_font_description_better_match(
+ newFontDescr, bestMatchForNewDescr, possibleMatch)) {
+
+ pango_font_description_free(bestMatchForNewDescr);
+ bestMatchForNewDescr = possibleMatch;
+ bestMatchFontDescription = currentFontSpec;
+ } else {
+ pango_font_description_free(possibleMatch);
+ }
+ }
+ }
+ }
+
+ newFontSpec = bestMatchFontDescription;
+
+ pango_font_description_free(newFontDescr);
+ pango_font_description_free(bestMatchForNewDescr);
+ }
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+Glib::ustring font_factory::FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn)
+{
+ Glib::ustring newFontSpec;
+
+ // Find the PangoFontDesecription that goes with this font specification string
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ g_assert(it != fontInstanceMap.end());
+
+ if (it != fontInstanceMap.end()) {
+ // If we did find one, make a copy and set/unset the italic as needed
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ PangoStyle style;
+ if (turnOn) {
+ style = PANGO_STYLE_ITALIC;
+ } else {
+ style = PANGO_STYLE_NORMAL;
+ }
+ pango_font_description_set_style(descr, style);
+
+ newFontSpec = ConstructFontSpecification(descr);
+ if (fontInstanceMap.find(newFontSpec) == fontInstanceMap.end()) {
+ // If the new font does not have an italic face, don't
+ // allow italics to be set!
+ newFontSpec = fontSpec;
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+Glib::ustring font_factory::FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn)
+{
+ Glib::ustring newFontSpec;
+
+ // Find the PangoFontDesecription that goes with this font specification string
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ if (it != fontInstanceMap.end()) {
+ // If we did find one, make a copy and set/unset the bold as needed
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ PangoWeight weight;
+ if (turnOn) {
+ weight = PANGO_WEIGHT_BOLD;
+ } else {
+ weight = PANGO_WEIGHT_NORMAL;
+ }
+ pango_font_description_set_weight(descr, weight);
+
+ newFontSpec = ConstructFontSpecification(descr);
+ if (fontInstanceMap.find(newFontSpec) == fontInstanceMap.end()) {
+ // If the new font does not have a bold face, don't
+ // allow bold to be set!
+ newFontSpec = fontSpec;
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+/////
+
+static bool StyleNameCompareInternal(Glib::ustring style1, Glib::ustring style2)
+{
+ return (style_name_compare(style1.c_str(), style2.c_str()) < 0);
+}
+
+void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map)
+{
+ g_assert(map);
+
+ if (map) {
+
+ // Gather the family names as listed by Pango
+ PangoFontFamily** families = NULL;
+ int numFamilies = 0;
+ pango_font_map_list_families(fontServer, &families, &numFamilies);
+
+ for (int currentFamily=0; currentFamily < numFamilies; currentFamily++) {
+
+ // Gather the styles for this family
+ PangoFontFace** faces = NULL;
+ int numFaces = 0;
+ pango_font_family_list_faces(families[currentFamily], &faces, &numFaces);
+
+ for (int currentFace=0; currentFace < numFaces; currentFace++) {
+
+ // If the face has a name, describe it, and then use the
+ // description to get the UI family and face strings
+
+ if (pango_font_face_get_face_name(faces[currentFace]) == NULL) {
+ continue;
+ }
+
+ PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]);
+ if (faceDescr) {
+ Glib::ustring familyUIName = GetUIFamilyString(faceDescr);
+ Glib::ustring styleUIName = GetUIStyleString(faceDescr);
+
+ if (!familyUIName.empty() && !styleUIName.empty()) {
+ // Find the right place to put the style information, adding
+ // a map entry for the family name if it doesn't yet exist
+
+ FamilyToStylesMap::iterator iter = map->find(familyUIName);
+
+ if (iter == map->end()) {
+ map->insert(std::make_pair(familyUIName, std::list<Glib::ustring>()));
+ }
+
+ // Insert into the style list and save the info in the reference maps
+ // only if the style does not yet exist
+
+ bool exists = false;
+ std::list<Glib::ustring> &styleList = (*map)[familyUIName];
+
+ for (std::list<Glib::ustring>::iterator it=styleList.begin();
+ it != styleList.end();
+ it++) {
+ if (*it == styleUIName) {
+ exists = true;
+ break;
+ }
+ }
+
+ if (!exists) {
+ styleList.push_back(styleUIName);
+
+ // Add the string info needed in the reference maps
+ fontStringMap.insert(
+ std::make_pair(
+ Glib::ustring(familyUIName) + Glib::ustring(styleUIName),
+ ConstructFontSpecification(faceDescr)));
+ fontInstanceMap.insert(
+ std::make_pair(ConstructFontSpecification(faceDescr), faceDescr));
+ } else {
+ pango_font_description_free(faceDescr);
+ }
+ } else {
+ pango_font_description_free(faceDescr);
+ }
+ }
+ }
+ }
+
+ // Sort the style lists
+ for (FamilyToStylesMap::iterator iter = map->begin() ; iter != map->end(); iter++) {
+ (*iter).second.sort(StyleNameCompareInternal);
+ }
+ }
+}
+
+font_instance* font_factory::FaceFromStyle(SPStyle const *style)
+{
+ font_instance *font = NULL;
+
+ g_assert(style);
+
+ if (style) {
+ // First try to use the font specification if it is set
+ if (style->text->font_specification.set
+ && style->text->font_specification.value
+ && *style->text->font_specification.value) {
+
+ font = FaceFromFontSpecification(style->text->font_specification.value);
+ }
+
+ // If that failed, try using the CSS information in the style
+ if (!font) {
+ font = Face(style->text->font_family.value, font_style_to_pos(*style));
+ }
+ }
+
+ return font;
}
font_instance *font_factory::FaceFromDescr(char const *family, char const *style)
@@ -334,6 +679,81 @@ font_instance *font_factory::FaceFromDescr(char const *family, char const *style
return res;
}
+font_instance* font_factory::FaceFromUIStrings(char const *uiFamily, char const *uiStyle)
+{
+ font_instance *fontInstance = NULL;
+
+ g_assert(uiFamily && uiStyle);
+ if (uiFamily && uiStyle) {
+ Glib::ustring uiString = Glib::ustring(uiFamily) + Glib::ustring(uiStyle);
+
+ UIStringToPangoStringMap::iterator uiToPangoIter = fontStringMap.find(uiString);
+
+ if (uiToPangoIter != fontStringMap.end ()) {
+ PangoStringToDescrMap::iterator pangoToDescrIter = fontInstanceMap.find((*uiToPangoIter).second);
+ if (pangoToDescrIter != fontInstanceMap.end()) {
+ // We found the pango description - now we can make a font_instance
+ PangoFontDescription *tempDescr = pango_font_description_copy((*pangoToDescrIter).second);
+ fontInstance = Face(tempDescr);
+ pango_font_description_free(tempDescr);
+ }
+ }
+ }
+
+ return fontInstance;
+}
+
+font_instance* font_factory::FaceFromPangoString(char const *pangoString)
+{
+ font_instance *fontInstance = NULL;
+
+ g_assert(pangoString);
+
+ if (pangoString) {
+ PangoFontDescription *descr = NULL;
+
+ // First attempt to find the font specification in the reference map
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(Glib::ustring(pangoString));
+ if (it != fontInstanceMap.end()) {
+ descr = pango_font_description_copy((*it).second);
+ }
+
+ // Or create a font description from the string - this may fail or
+ // produce unexpected results if the string does not have a good format
+ if (!descr) {
+ descr = pango_font_description_from_string(pangoString);
+ }
+
+ if (descr && (pango_font_description_get_family(descr) != NULL)) {
+ fontInstance = Face(descr);
+ }
+
+ if (descr) {
+ pango_font_description_free(descr);
+ }
+ }
+
+ return fontInstance;
+}
+
+font_instance* font_factory::FaceFromFontSpecification(char const *fontSpecification)
+{
+ font_instance *font = NULL;
+
+ g_assert(fontSpecification);
+
+ if (fontSpecification) {
+ // How the string is used to reconstruct a font depends on how it
+ // was constructed in ConstructFontSpecification. As it stands,
+ // the font specification is a pango-created string
+ font = FaceFromPangoString(fontSpecification);
+ }
+
+ return font;
+}
+
+
+
font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
{
#ifdef USE_PANGO_WIN32
}
}
-NRNameList *font_factory::Families(NRNameList *flist)
-{
- PangoFontFamily** fams = NULL;
- int nbFam = 0;
- pango_font_map_list_families(fontServer, &fams, &nbFam);
-
- PANGO_DEBUG("got %d families\n", nbFam);
-
- flist->length = nbFam;
- flist->names = (guchar **)g_malloc(nbFam*sizeof(guchar*));
- flist->destructor = font_factory_name_list_destructor;
-
- for (int i = 0;i < nbFam;i++) {
-// Note: on Windows, pango_font_family_get_name always returns lowercase name.
-// As a result the list of fonts in the dialog is lowercase.
-// We could work around by loading the font and taking pango_font_description_get_family from its descr (that gives correct case),
-// but this is slow, and it's better to fix Pango instead.
- flist->names[i]=(guchar*)strdup(pango_font_family_get_name(fams[i]));
- }
-
- qsort(flist->names, nbFam, sizeof(guchar *), family_name_compare);
-
- g_free(fams);
-
- return flist;
-}
-
-NRStyleList *font_factory::Styles(gchar const *family, NRStyleList *slist)
-{
- PangoFontFamily *theFam = NULL;
-
- // search available families
- {
- PangoFontFamily** fams = NULL;
- int nbFam = 0;
- pango_font_map_list_families(fontServer, &fams, &nbFam);
-
- for (int i = 0;i < nbFam;i++) {
- char const *fname = pango_font_family_get_name(fams[i]);
- if ( fname && strcmp(family,fname) == 0 ) {
- theFam = fams[i];
- break;
- }
- }
-
- g_free(fams);
- }
-
- // nothing found
- if ( theFam == NULL ) {
- slist->length = 0;
- slist->records = NULL;
- slist->destructor = NULL;
- return slist;
- }
-
- // search faces in the found family
- PangoFontFace** faces = NULL;
- int nFaces = 0;
- pango_font_family_list_faces(theFam, &faces, &nFaces);
-
- slist->records = (NRStyleRecord *) g_malloc(nFaces * sizeof(NRStyleRecord));
- slist->destructor = font_factory_style_list_destructor;
-
- int nr = 0;
- for (int i = 0; i < nFaces; i++) {
-
- // no unnamed faces
- if (pango_font_face_get_face_name(faces[i]) == NULL)
- continue;
- PangoFontDescription *nd = pango_font_face_describe(faces[i]);
- if (nd == NULL)
- continue;
- char const *descr = pango_font_description_to_string(nd);
- if (descr == NULL) {
- pango_font_description_free(nd);
- continue;
- }
-
- char const *name = g_strdup(pango_font_face_get_face_name(faces[i]));
- pango_font_description_free(nd);
-
- slist->records[nr].name = name;
- slist->records[nr].descr = descr;
- nr ++;
- }
-
- slist->length = nr;
-
- qsort(slist->records, slist->length, sizeof(NRStyleRecord), style_record_compare);
- /* effic: Consider doing strdown and all the is_italic etc. tests once off and store the
- * results in a table, rather than having the sort invoke multiple is_italic tests per
- * record.
- */
-
- g_free(faces);
-
- return slist;
-}
-
void font_factory::AddInCache(font_instance *who)
{
if ( who == NULL ) return;
index ba00102469984d0d8b944bac9ff2febe2d121491..9f4b31a2e5c776f967d85ef1e7ccec5412a24f4a 100644 (file)
#ifndef my_font_factory
#define my_font_factory
+//#include <glibmm/ustring.h>
+
#include <functional>
#include <algorithm>
#include <ext/hash_map>
#include <pango/pango.h>
#include "nr-type-primitives.h"
#include "nr-type-pos-def.h"
+#include "font-style-to-pos.h"
#include <libnrtype/nrtype-forward.h>
+#include "../style.h"
/* Freetype */
#ifdef USE_PANGO_WIN32
#include <freetype/freetype.h>
#endif
+namespace Glib
+{
+ class ustring;
+}
+
// the font_factory keeps a hashmap of all the loaded font_instances, and uses the PangoFontDescription
// as index (nota: since pango already does that, using the PangoFont could work too)
struct font_descr_hash : public std::unary_function<PangoFontDescription*,size_t> {
bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b);
};
+// Comparison functions for style names
+int style_name_compare(char const *aa, char const *bb);
+int family_name_compare(char const *a, char const *b);
+
+// Map type for gathering UI family and style strings
+typedef std::map<Glib::ustring, std::list<Glib::ustring> > FamilyToStylesMap;
+
class font_factory {
public:
static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would
/// Returns the default font_factory.
static font_factory* Default();
+
+ /// Constructs a pango string for use with the fontStringMap (see below)
+ Glib::ustring ConstructFontSpecification(PangoFontDescription *font);
+ Glib::ustring ConstructFontSpecification(font_instance *font);
+
+ /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled)
+ Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr);
+ Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr);
+
+ /// Modifiers for the font specification (returns new font specification)
+ Glib::ustring ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily);
+ Glib::ustring FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn);
+ Glib::ustring FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn);
+
+ // Gathers all strings needed for UI while storing pango information in
+ // fontInstanceMap and fontStringMap
+ void GetUIFamiliesAndStyles(FamilyToStylesMap *map);
+
+ /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information
+ font_instance* FaceFromStyle(SPStyle const *style);
// Various functions to get a font_instance from different descriptions.
font_instance* FaceFromDescr(char const *family, char const *style);
+ font_instance* FaceFromUIStrings(char const *uiFamily, char const *uiStyle);
+ font_instance* FaceFromPangoString(char const *pangoString);
+ font_instance* FaceFromFontSpecification(char const *fontSpecification);
font_instance* Face(PangoFontDescription *descr, bool canFail=true);
font_instance* Face(char const *family,
int variant=PANGO_VARIANT_NORMAL, int style=PANGO_STYLE_NORMAL,
/// Semi-private: tells the font_factory taht the font_instance 'who' has died and should be removed from loadedFaces
void UnrefFace(font_instance* who);
- // Queries for the font-selector.
- NRNameList* Families(NRNameList *flist);
- NRStyleList* Styles(const gchar *family, NRStyleList *slist);
-
// internal
void AddInCache(font_instance *who);
+
+private:
+ // These two maps are used for translating between what's in the UI and a pango
+ // font description. This is necessary because Pango cannot always
+ // reproduce these structures from the names it gave us in the first place.
+
+ // Key: A string produced by font_factory::ConstructFontSpecification
+ // Value: The associated PangoFontDescription
+ typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap;
+ PangoStringToDescrMap fontInstanceMap;
+
+ // Key: Family name in UI + Style name in UI
+ // Value: The associated string that should be produced with font_factory::ConstructFontSpecification
+ typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap;
+ UIStringToPangoStringMap fontStringMap;
};
index 0b37b14ec9c9f6ca0b32056f673ce86850ea284a..228a34f83d7a92aa396a1618f50b677bbd223a5d 100644 (file)
@@ -278,8 +278,10 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
res="normal";
} else if ( v <= PANGO_WEIGHT_BOLD ) {
res="bold";
- } else {
- res="800";
+ } else if ( v <= PANGO_WEIGHT_ULTRABOLD ) {
+ res="800";
+ } else { // HEAVY
+ res="900";
}
free_res=false;
} else if ( strcmp(key,"stretch") == 0 ) {
index 1a2f6d9c8f7ea3fe2a6fb4b7310f866fee55a6fe..a7160f5f0d7446a7b0a6a4eafa41c72b1b36e6eb 100644 (file)
#include <gtkmm/liststore.h>
#include "font-lister.h"
+#include "FontFactory.h"
namespace Inkscape
{
- FontLister::FontLister ()
- {
- font_list_store = Gtk::ListStore::create (FontList);
-
- if (font_factory::Default()->Families(&families))
- {
- for (unsigned int i = 0; i < families.length; ++i)
- {
- Gtk::TreeModel::iterator iter = font_list_store->append();
- (*iter)[FontList.font] = reinterpret_cast<const char*>(families.names[i]);
-
- NRStyleList styles;
- if (font_factory::Default()->Styles (reinterpret_cast<const char*>(families.names[i]), &styles));
-
- GList *Styles=0;
- for (unsigned int n = 0; n < styles.length; ++n)
- {
- NRStyleRecord style_record = styles.records[n];
- Styles = g_list_append (Styles, strdup(style_record.name));
- }
-
- (*iter)[FontList.styles] = Styles;
-
- font_list_store_iter_map.insert (std::make_pair (reinterpret_cast<const char*>(families.names[i]), Gtk::TreePath (iter)));
- }
- }
-
+ FontLister::FontLister ()
+ {
+ font_list_store = Gtk::ListStore::create (FontList);
+
+ FamilyToStylesMap familyStyleMap;
+ font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap);
+
+ // Grab the family names into a list and then sort them
+ std::list<Glib::ustring> familyList;
+ for (FamilyToStylesMap::iterator iter = familyStyleMap.begin();
+ iter != familyStyleMap.end();
+ iter++) {
+ familyList.push_back((*iter).first);
+ }
+ familyList.sort();
+
+ // Traverse through the family names and set up the list store (note that
+ // the styles list that are the map's values are already sorted)
+ while (!familyList.empty()) {
+ Glib::ustring familyName = familyList.front();
+ familyList.pop_front();
+
+ if (!familyName.empty()) {
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->append();
+ (*treeModelIter)[FontList.font] = reinterpret_cast<const char*>(g_strdup(familyName.c_str()));
+
+ // Now go through the styles
+ GList *styles = NULL;
+ std::list<Glib::ustring> &styleStrings = familyStyleMap[familyName];
+ for (std::list<Glib::ustring>::iterator it=styleStrings.begin();
+ it != styleStrings.end();
+ it++) {
+ styles = g_list_append(styles, g_strdup((*it).c_str()));
}
+
+ (*treeModelIter)[FontList.styles] = styles;
+
+ font_list_store_iter_map.insert(std::make_pair(familyName, Gtk::TreePath(treeModelIter)));
+ }
+ }
+ }
- FontLister::~FontLister ()
- {
- };
+ FontLister::~FontLister ()
+ {
+ };
- const Glib::RefPtr<Gtk::ListStore>
- FontLister::get_font_list () const
- {
- return font_list_store;
- }
+ const Glib::RefPtr<Gtk::ListStore>
+ FontLister::get_font_list () const
+ {
+ return font_list_store;
+ }
}
+
+
+
index 39953c11cfad3e70db7ad9ce407ad9ccb3aa6528..b2d2a3ecf5a48023e188803ff8f01538232dd2e1 100644 (file)
public:
/** Column containing the family name
*/
- Gtk::TreeModelColumn<std::string> font;
+ Gtk::TreeModelColumn<Glib::ustring> font;
/** Column containing an std::vector<std::string> with style names
* for the corresponding family
};
FontListClass FontList;
- typedef std::map<std::string, Gtk::TreePath> IterMapType;
+ typedef std::map<Glib::ustring, Gtk::TreePath> IterMapType;
/** Returns the ListStore with the font names
*
}
Gtk::TreePath
- get_row_for_font (std::string family)
+ get_row_for_font (Glib::ustring family)
{
IterMapType::iterator iter = font_list_store_iter_map.find (family);
if (iter == font_list_store_iter_map.end ()) throw FAMILY_NOT_FOUND;
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index 1029516f7cff016f4821e8eb1d83bbfe098264fb..27701c80deff7fd642a531997ba4f10881238b5e 100644 (file)
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
void
persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state) {
- if (persp3d_VP_is_finite(persp, axis) != (state == Proj::FINITE)) {
+ if (persp3d_VP_is_finite(persp, axis) != (state == Proj::VP_FINITE)) {
persp3d_toggle_VP(persp, axis);
}
}
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index 1609afa92aef0cefef0850bde09d13a6655ca914..5d1abbb3a21a9a9c4c3634ebcfc7716381c5dd4f 100644 (file)
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
SPText *text = (SPText *) item;
SPStyle *style = SP_OBJECT_STYLE(text);
- font_instance *tf = (font_factory::Default())->Face(style->text->font_family.value,
- font_style_to_pos(*style));
+ font_instance *tf = font_factory::Default()->FaceFromStyle(style);
+
char name_buf[256];
char *n;
if (tf) {
diff --git a/src/style.cpp b/src/style.cpp
index 06855087808622d96ab168070dca9cf02c3a455b..357fe5f0e2a81dd95eb3003a4468036699405142 100644 (file)
--- a/src/style.cpp
+++ b/src/style.cpp
style->stroke_dashoffset_set = FALSE;
}
}
+
+ /* -inkscape-font-specification */
+ if (!style->text_private || !style->text->font_specification.set) {
+ val = repr->attribute("-inkscape-font-specification");
+ if (val) {
+ if (!style->text_private) sp_style_privatize_text(style);
+ gchar *val_unquoted = attribute_unquote(val);
+ sp_style_read_istring(&style->text->font_specification, val_unquoted);
+ if (val_unquoted) g_free (val_unquoted);
+ }
+ }
/* font-family */
if (!style->text_private || !style->text->font_family.set) {
g_return_if_fail(val != NULL);
switch (id) {
+ case SP_PROP_INKSCAPE_FONT_SPEC:
+ if (!style->text_private) sp_style_privatize_text(style);
+ if (!style->text->font_specification.set) {
+ gchar *val_unquoted = attribute_unquote(val);
+ sp_style_read_istring(&style->text->font_specification, val_unquoted);
+ if (val_unquoted) g_free (val_unquoted);
+ }
+ break;
/* CSS2 */
/* Font */
case SP_PROP_FONT_FAMILY:
@@ -1500,6 +1519,13 @@ sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent)
}
}
+ if (style->text && parent->text) {
+ if (!style->text->font_specification.set || style->text->font_specification.inherit) {
+ g_free(style->text->font_specification.value);
+ style->text->font_specification.value = g_strdup(parent->text->font_specification.value);
+ }
+ }
+
/* Markers - Free the old value and make copy of the new */
for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) {
if (!style->marker[i].set || style->marker[i].inherit) {
@@ -1885,10 +1911,14 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare
/* Font */
if (style->text && parent->text) {
+ sp_style_merge_string_prop_from_dying_parent(style->text->font_specification,
+ parent->text->font_specification);
+
sp_style_merge_string_prop_from_dying_parent(style->text->font_family,
parent->text->font_family);
}
+
/* Properties that don't inherit by default. Most of these need special handling. */
{
/*
style->text = text;
style->text_private = text_private;
- /* fixme: */
+ style->text->font_specification.set = FALSE;
style->text->font.set = FALSE;
style->text->font_family.set = FALSE;
ts->refcount = 1;
sp_text_style_clear(ts);
+ ts->font_specification.value = g_strdup("Bitstream Vera Sans");
ts->font.value = g_strdup("Bitstream Vera Sans");
ts->font_family.value = g_strdup("Bitstream Vera Sans");
static void
sp_text_style_clear(SPTextStyle *ts)
{
+ ts->font_specification.set = FALSE;
ts->font.set = FALSE;
ts->font_family.set = FALSE;
}
st->refcount -= 1;
if (st->refcount < 1) {
+ g_free(st->font_specification.value);
g_free(st->font.value);
g_free(st->font_family.value);
g_free(st);
SPTextStyle *nt = g_new0(SPTextStyle, 1);
nt->refcount = 1;
+ nt->font_specification.value = g_strdup(st->font_specification.value);
nt->font.value = g_strdup(st->font.value);
nt->font_family.value = g_strdup(st->font_family.value);
@@ -2701,6 +2735,7 @@ sp_text_style_write(gchar *p, guint const len, SPTextStyle const *const st, guin
flags = SP_STYLE_FLAG_IFSET;
d += sp_style_write_istring(p + d, len - d, "font-family", &st->font_family, NULL, flags);
+ d += sp_style_write_istring(p + d, len - d, "-inkscape-font-specification", &st->font_specification, NULL, flags);
return d;
}
if (style->stroke_dashoffset_set) {
repr->setAttribute("stroke-dashoffset", NULL);
}
+ if (style->text_private && style->text->font_specification.set) {
+ repr->setAttribute("-inkscape-font-specification", NULL);
+ }
if (style->text_private && style->text->font_family.set) {
repr->setAttribute("font-family", NULL);
}
sp_css_attr_unset_text(SPCSSAttr *css)
{
sp_repr_css_set_property(css, "font", NULL); // not implemented yet
+ sp_repr_css_set_property(css, "-inkscape-font-specification", NULL);
sp_repr_css_set_property(css, "font-size", NULL);
sp_repr_css_set_property(css, "font-size-adjust", NULL); // not implemented yet
sp_repr_css_set_property(css, "font-style", NULL);
diff --git a/src/style.h b/src/style.h
index 6e62187bc1f431184de1d9bd1b25a6de894a86d0..47ba6955e6a2d09388270d78895915633f7f5364 100644 (file)
--- a/src/style.h
+++ b/src/style.h
/* CSS font properties */
SPIString font_family;
+ /* Full font name, as font_factory::ConstructFontSpecification would give */
+ SPIString font_specification;
+
/** \todo fixme: The 'font' property is ugly, and not working (lauris) */
SPIString font;
};
index c9e5d0bbbc94720c0c8b0f967b7a54bc4efd252b..9da48d0e63ede4fd7d45c4a8138227674104ff3c 100644 (file)
if ((!family) || (!style)) return;
- font = (font_factory::Default())->FaceFromDescr (family, style);
+ font = (font_factory::Default())->FaceFromUIStrings (family, style);
// FIXME: when a text object uses non-available font, font==NULL and we can't set size
// (and the size shown in the widget is invalid). To fix, here we must always get some
void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size)
{
if (font)
- {
- gchar family[256];
- font->Family (family, 256);
-
- Gtk::TreePath path;
+ {
+ Gtk::TreePath path;
+ font_instance *tempFont = NULL;
+
+ Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr);
+
+ try {
+ path = Inkscape::FontLister::get_instance()->get_row_for_font (family);
+ } catch (...) {
+ return;
+ }
- try {
- path = Inkscape::FontLister::get_instance()->get_row_for_font (family);
- } catch (...) {
- return;
+ fsel->block_emit = TRUE;
+ gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj());
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5);
+ fsel->block_emit = FALSE;
+
+ GList *list = 0;
+ GtkTreeIter iter;
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview));
+ gtk_tree_model_get_iter (model, &iter, path.gobj());
+ gtk_tree_model_get (model, &iter, 1, &list, -1);
+
+ unsigned int currentStyleNumber = 0;
+ unsigned int bestStyleNumber = 0;
+
+ PangoFontDescription *incomingFont = pango_font_description_copy(font->descr);
+ pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE);
+
+ char *incomingFontString = pango_font_description_to_string(incomingFont);
+
+ tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), (char*)list->data);
+
+ PangoFontDescription *bestMatchForFont = NULL;
+ if (tempFont) {
+ bestMatchForFont = pango_font_description_copy(tempFont->descr);
+ tempFont->Unref();
+ tempFont = NULL;
+ }
+
+ pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE);
+
+ list = list->next;
+
+ while (list) {
+ currentStyleNumber++;
+
+ tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), (char*)list->data);
+
+ PangoFontDescription *currentMatchForFont = NULL;
+ if (tempFont) {
+ currentMatchForFont = pango_font_description_copy(tempFont->descr);
+ tempFont->Unref();
+ tempFont = NULL;
}
-
- fsel->block_emit = TRUE;
- gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj());
- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5);
- fsel->block_emit = FALSE;
-
- GList *list = 0;
- GtkTreeIter iter;
- GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview));
- gtk_tree_model_get_iter (model, &iter, path.gobj());
- gtk_tree_model_get (model, &iter, 1, &list, -1);
-
- gchar descr[256];
- font->Name(descr, 256);
- std::string descr_best (family);
- descr_best += " ";
- descr_best += ((char*)list->data);
-
- PangoFontDescription *descr_ = pango_font_description_from_string(descr);
- PangoFontDescription *best_ = pango_font_description_from_string(descr_best.c_str());
-
- unsigned int i = 0;
- unsigned int best_i = 0;
-
- // try to find best match with style description (i.e. bold, italic ?)
- for (list = list->next ; list ; list = list->next)
- {
- i++;
- std::string descr_try (family);
- descr_try += " ";
- descr_try += ((char*)list->data);
- PangoFontDescription *try_ = pango_font_description_from_string(descr_try.c_str());
- if (pango_font_description_better_match (descr_, best_, try_))
- {
- pango_font_description_free (best_);
- best_ = pango_font_description_from_string (descr_try.c_str ());
- best_i = i;
+
+ if (currentMatchForFont) {
+ pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE);
+
+ char *currentMatchString = pango_font_description_to_string(currentMatchForFont);
+
+ if (!strcmp(incomingFontString, currentMatchString)
+ || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) {
+ // Found a better match for the font we are looking for
+ pango_font_description_free(bestMatchForFont);
+ bestMatchForFont = pango_font_description_copy(currentMatchForFont);
+ bestStyleNumber = currentStyleNumber;
}
- pango_font_description_free(try_);
- }
- pango_font_description_free(descr_);
- pango_font_description_free(best_);
-
- GtkTreePath *path_c = gtk_tree_path_new ();
- gtk_tree_path_append_index (path_c, best_i);
- gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c);
- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5);
-
- if (size != fsel->fontsize)
- {
- gchar s[8];
- g_snprintf (s, 8, "%.5g", size); // UI, so printf is ok
- gtk_entry_set_text (GTK_ENTRY (GTK_BIN(fsel->size)->child), s);
- fsel->fontsize = size;
+
+ g_free(currentMatchString);
+
+ pango_font_description_free(currentMatchForFont);
}
+
+ list = list->next;
+ }
+
+ if (bestMatchForFont)
+ pango_font_description_free(bestMatchForFont);
+ if (incomingFont)
+ pango_font_description_free(incomingFont);
+ g_free(incomingFontString);
+
+ GtkTreePath *path_c = gtk_tree_path_new ();
+ gtk_tree_path_append_index (path_c, bestStyleNumber);
+ gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5);
+
+ if (size != fsel->fontsize)
+ {
+ gchar s[8];
+ g_snprintf (s, 8, "%.5g", size); // UI, so printf is ok
+ gtk_entry_set_text (GTK_ENTRY (GTK_BIN(fsel->size)->child), s);
+ fsel->fontsize = size;
+ }
}
+
}
font_instance* sp_font_selector_get_font(SPFontSelector *fsel)
index 9e9686e77763d36ce92d10c1428563c7bd63bcec..81eedaeb8b3a2534dcc59b6c09fb5367ad1b3133 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
#include "document-private.h"
#include "desktop-style.h"
#include "../libnrtype/font-lister.h"
+#include "../libnrtype/font-instance.h"
#include "../connection-pool.h"
#include "../prefs-utils.h"
#include "../inkscape-stock.h"
@@ -2360,7 +2361,7 @@ static void box3d_toggle_vp_changed (GtkToggleAction *act, GObject *dataKludge,
// in turn, prevent listener from responding
g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
- persp3d_set_VP_state(persp, axis, gtk_toggle_action_get_active(act) ? Proj::INFINITE : Proj::FINITE);
+ persp3d_set_VP_state(persp, axis, (gtk_toggle_action_get_active(act) ? Proj::VP_INFINITE : Proj::VP_FINITE));
// FIXME: Can we merge this functionality with the one in box3d_persp_tb_event_attr_changed()?
gchar *str;
@@ -3948,6 +3949,9 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
{
SPStyle *query =
sp_style_new (SP_ACTIVE_DOCUMENT);
+
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
int result_family =
sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
@@ -3981,15 +3985,27 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
gtk_entry_set_text (GTK_ENTRY (entry), "");
- } else if (query->text->font_family.value) {
+ } else if (query->text->font_specification.value || query->text->font_family.value) {
GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
- gtk_entry_set_text (GTK_ENTRY (entry), query->text->font_family.value);
+
+ // Get the font that corresponds
+ Glib::ustring familyName;
+
+ font_instance * font = font_factory::Default()->FaceFromStyle(query);
+ if (font) {
+ familyName = font_factory::Default()->GetUIFamilyString(font->descr);
+ font->Unref();
+ font = NULL;
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (entry), familyName.c_str());
Gtk::TreePath path;
try {
- path = Inkscape::FontLister::get_instance()->get_row_for_font (query->text->font_family.value);
+ path = Inkscape::FontLister::get_instance()->get_row_for_font (familyName);
} catch (...) {
+ g_warning("Family name %s does not have an entry in the font lister.", familyName.c_str());
return;
}
SPStyle *query =
sp_style_new (SP_ACTIVE_DOCUMENT);
- int result_numbers =
- sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
-
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
SPCSSAttr *css = sp_repr_css_attr_new ();
- sp_repr_css_set_property (css, "font-family", family);
+
+ std::string fontSpec = query->text->font_specification.value;
+ if (!fontSpec.empty()) {
+ Glib::ustring newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family);
+ if (!newFontSpec.empty() && fontSpec != newFontSpec) {
+ font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str());
+ if (font) {
+ sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
+
+ // Set all the these just in case they were altered when finding the best
+ // match for the new family and old style...
+
+ gchar c[256];
+
+ font->Family(c, 256);
+ sp_repr_css_set_property (css, "font-family", c);
+
+ font->Attribute( "weight", c, 256);
+ sp_repr_css_set_property (css, "font-weight", c);
+
+ font->Attribute("style", c, 256);
+ sp_repr_css_set_property (css, "font-style", c);
+
+ font->Attribute("stretch", c, 256);
+ sp_repr_css_set_property (css, "font-stretch", c);
+
+ font->Attribute("variant", c, 256);
+ sp_repr_css_set_property (css, "font-variant", c);
+
+ font->Unref();
+ }
+ }
+ }
// If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- if (result_numbers == QUERY_STYLE_NOTHING)
+ if (result_fontspec == QUERY_STYLE_NOTHING)
{
sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace trough a verb
int prop = GPOINTER_TO_INT(data);
bool active = gtk_toggle_button_get_active (button);
+ SPStyle *query =
+ sp_style_new (SP_ACTIVE_DOCUMENT);
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
+ Glib::ustring fontSpec = query->text->font_specification.value;
+ Glib::ustring newFontSpec;
switch (prop)
{
case 0:
{
- sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+ if (!fontSpec.empty()) {
+ newFontSpec = font_factory::Default()->FontSpecificationSetBold(fontSpec, active);
+ }
+ if (fontSpec != newFontSpec) {
+ sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+ }
break;
}
case 1:
{
- sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+ if (!fontSpec.empty()) {
+ newFontSpec = font_factory::Default()->FontSpecificationSetItalic(fontSpec, active);
+ }
+ if (fontSpec != newFontSpec) {
+ sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+ }
break;
}
}
- SPStyle *query =
- sp_style_new (SP_ACTIVE_DOCUMENT);
- int result_numbers =
- sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ if (!fontSpec.empty()) {
+ sp_repr_css_set_property (css, "-inkscape-font-specification", fontSpec.c_str());
+ }
// If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- if (result_numbers == QUERY_STYLE_NOTHING)
+ if (result_fontspec == QUERY_STYLE_NOTHING)
{
sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
}
@@ -5200,3 +5264,5 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+
+
diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp
index d3c39e5a201717bc13afe990681f16774c75b3b9..ec5848366676678967c13b4b544a48558b746367 100644 (file)
--- a/src/xml/repr-css.cpp
+++ b/src/xml/repr-css.cpp
buffer.append(g_quark_to_string(iter->key));
buffer.push_back(':');
- if (!strcmp(g_quark_to_string(iter->key), "font-family")) { // we only quote font-family, as SPStyle does
+ if (!strcmp(g_quark_to_string(iter->key), "font-family")
+ || !strcmp(g_quark_to_string(iter->key), "-inkscape-font-specification")) {
+ // we only quote font-family/font-specification, as SPStyle does
gchar *t = g_strdup (iter->value);
g_free (t);
gchar *val_quoted = css2_escape_quote (iter->value);