Handle `xml:lang`/`lang` attribute updates (7fa5d668) · Commits · René de Hesselle / inkscape · GitLab
Alvin Wong
·
2025-12-06
·
via inkscape:windows_ci_14x commits
Handle `xml:lang`/`lang` attribute updates
The change of language needs to trigger descendant text objects to be
updated, since it is effectively a font change that may change the glyph
selection and even metrics.
The language handling in `SPObject` is refactored such that the
effective language of the object is dynamically inherited from its
parent(s) on demand, instead of cached in the `SPObject` itself.
Added test `test_sp-object-lang` to check the language handling.
| Original line number |
Diff line number |
Diff line |
|
@@ -1365,8 +1365,9 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con |
|
|
|
|
|
// Set language
|
|
|
SPObject * object = text_source->source;
|
|
|
if (!object->lang.empty()) {
|
|
|
PangoLanguage* language = pango_language_from_string(object->lang.c_str());
|
|
|
char const *lang = object->getLanguage();
|
|
|
if (lang && lang[0] != '\0') {
|
|
|
PangoLanguage *language = pango_language_from_string(lang);
|
|
|
PangoAttribute *attribute_language = pango_attr_language_new( language );
|
|
|
pango_attr_list_insert(attributes_list, attribute_language);
|
|
|
}
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -35,6 +35,7 @@ |
|
|
#include "live_effects/lpeobject.h"
|
|
|
#include "sp-factory.h"
|
|
|
#include "sp-font.h"
|
|
|
#include "sp-glyph.h"
|
|
|
#include "sp-paint-server.h"
|
|
|
#include "sp-root.h"
|
|
|
#include "sp-use.h"
|
|
@@ -229,6 +230,17 @@ std::string SPObject::getUrl() const { |
|
|
return "";
|
|
|
}
|
|
|
|
|
|
char const *SPObject::getLanguage() const
|
|
|
{
|
|
|
if (_lang_attribute) {
|
|
|
return _lang_attribute->c_str();
|
|
|
}
|
|
|
if (parent) {
|
|
|
return parent->getLanguage();
|
|
|
}
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
Inkscape::XML::Node * SPObject::getRepr() {
|
|
|
return repr;
|
|
|
}
|
|
@@ -788,11 +800,6 @@ void SPObject::build(SPDocument *document, Inkscape::XML::Node *repr) { |
|
|
object->readAttr(SPAttr::INKSCAPE_LABEL);
|
|
|
object->readAttr(SPAttr::INKSCAPE_COLLECT);
|
|
|
|
|
|
// Inherit if not set
|
|
|
if (lang.empty() && object->parent) {
|
|
|
lang = object->parent->lang;
|
|
|
}
|
|
|
|
|
|
if(object->cloned && (repr->attribute("id")) ) // The cases where this happens are when the "original" has no id. This happens
|
|
|
// if it is a SPString (a TextNode, e.g. in a <title>), or when importing
|
|
|
// stuff externally modified to have no id.
|
|
@@ -1088,18 +1095,22 @@ void SPObject::set(SPAttr key, gchar const* value) { |
|
|
break;
|
|
|
|
|
|
case SPAttr::LANG:
|
|
|
if (value) {
|
|
|
lang = value;
|
|
|
// To do: sanity check
|
|
|
}
|
|
|
case SPAttr::XML_LANG: {
|
|
|
// Note: An empty string _is_ valid for `xml:lang` and `lang`
|
|
|
// `xml:lang` takes precedence
|
|
|
if (key == SPAttr::LANG && getAttribute("xml:lang")) {
|
|
|
break;
|
|
|
|
|
|
case SPAttr::XML_LANG:
|
|
|
if (value) {
|
|
|
lang = value;
|
|
|
// To do: sanity check
|
|
|
}
|
|
|
break;
|
|
|
gchar const *lang_attr_value = value;
|
|
|
if (key == SPAttr::XML_LANG && !lang_attr_value && !is<SPGlyph>(this)) {
|
|
|
// Use `lang` only if `xml:lang` is not set.
|
|
|
// Also SVG 1.1 <glyph> has a different spec for the `lang` attribute that should not be used.
|
|
|
lang_attr_value = getAttribute("lang");
|
|
|
}
|
|
|
_lang_attribute = lang_attr_value ? std::make_optional(lang_attr_value) : std::nullopt;
|
|
|
// To do: sanity check
|
|
|
requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
|
|
|
} break;
|
|
|
|
|
|
case SPAttr::STYLE:
|
|
|
object->style->readFromObject( object );
|
|
@@ -1199,6 +1210,18 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML |
|
|
repr->setAttribute("xml:space", xml_space);
|
|
|
}
|
|
|
|
|
|
if (_lang_attribute) {
|
|
|
repr->setAttribute("xml:lang", *_lang_attribute);
|
|
|
} else {
|
|
|
repr->removeAttribute("xml:lang");
|
|
|
// SVG 1.1 <glyph> has a different spec for the `lang` attribute, so don't touch that.
|
|
|
if (!is<SPGlyph>(this)) {
|
|
|
// Only remove `lang` if removing `xml:lang`.
|
|
|
// We can leave `lang` otherwise. It does not matter since `xml:lang` takes precedence.
|
|
|
repr->removeAttribute("lang");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ( flags & SP_OBJECT_WRITE_EXT &&
|
|
|
this->collectionPolicy() == SPObject::ALWAYS_COLLECT )
|
|
|
{
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -168,7 +168,6 @@ public: |
|
|
unsigned int uflags : 8;
|
|
|
unsigned int mflags : 8;
|
|
|
SPIXmlSpace xml_space;
|
|
|
Glib::ustring lang;
|
|
|
unsigned int hrefcount{0}; /* number of xlink:href references */
|
|
|
unsigned int _total_hrefcount{0}; /* our hrefcount + total descendants */
|
|
|
SPDocument *document{nullptr}; /* Document we are part of */
|
|
@@ -178,6 +177,11 @@ private: |
|
|
char *id{nullptr}; /* Our very own unique id */
|
|
|
Inkscape::XML::Node *repr{nullptr}; /* Our xml representation */
|
|
|
|
|
|
/**
|
|
|
* The value of the `xml:lang` or `lang` attribute, if set.
|
|
|
*/
|
|
|
std::optional<Glib::ustring> _lang_attribute;
|
|
|
|
|
|
public:
|
|
|
int refCount{1};
|
|
|
std::list<SPObject *> hrefList;
|
|
@@ -194,6 +198,24 @@ public: |
|
|
*/
|
|
|
std::string getUrl() const;
|
|
|
|
|
|
/**
|
|
|
* Get the value of the language attribute explicitly set on this object, if available.
|
|
|
*
|
|
|
* To get the effective language of this object, use getLanguage() instead.
|
|
|
*/
|
|
|
std::optional<Glib::ustring> const &getLangAttribute() const { return _lang_attribute; }
|
|
|
|
|
|
/**
|
|
|
* Get the effective language of this object, either set by the `xml:lang`/`lang` attributes or inherited from
|
|
|
* the parent.
|
|
|
*/
|
|
|
char const *getLanguage() const;
|
|
|
|
|
|
/**
|
|
|
* Set the language of this object. Use std::nullopt to unset and inherit from the parent.
|
|
|
*/
|
|
|
void setLanguage(std::optional<Glib::ustring> value) { _lang_attribute = std::move(value); }
|
|
|
|
|
|
/**
|
|
|
* Returns the XML representation of tree
|
|
|
*/
|
|
|
| Original line number |
Diff line number |
Diff line |
|
@@ -74,6 +74,7 @@ set(TEST_SOURCES |
|
|
oklab-color-test
|
|
|
sp-item-test
|
|
|
sp-object-test
|
|
|
sp-object-lang-test
|
|
|
sp-object-tags-test
|
|
|
object-links-test
|
|
|
object-set-test
|
|
|
File added.
Preview size limit exceeded, changes collapsed.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。