Changeset View
Changeset View
Standalone View
Standalone View
kcms/fonts/kxftconfig.cpp
Show First 20 Lines • Show All 111 Lines • ▼ Show 20 Line(s) | |||||
112 | 112 | | |||
113 | static time_t getTimeStamp(const QString &item) | 113 | static time_t getTimeStamp(const QString &item) | ||
114 | { | 114 | { | ||
115 | KDE_struct_stat info; | 115 | KDE_struct_stat info; | ||
116 | 116 | | |||
117 | return !item.isNull() && 0 == KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0; | 117 | return !item.isNull() && 0 == KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0; | ||
118 | } | 118 | } | ||
119 | 119 | | |||
120 | // | | |||
121 | // Obtain location of config file to use. | | |||
122 | QString getConfigFile() | | |||
123 | { | | |||
124 | FcStrList *list = FcConfigGetConfigFiles(FcConfigGetCurrent()); | | |||
125 | QStringList files; | | |||
126 | FcChar8 *file; | | |||
127 | QString home(dirSyntax(QDir::homePath())); | | |||
128 | | ||||
129 | while ((file = FcStrListNext(list))) { | | |||
130 | QString f((const char *)file); | | |||
131 | | ||||
132 | if (fExists(f) && 0 == f.indexOf(home)) { | | |||
133 | files.append(f); | | |||
134 | } | | |||
135 | } | | |||
136 | FcStrListDone(list); | | |||
137 | | ||||
138 | // | | |||
139 | // Go through list of files, looking for the preferred one... | | |||
140 | if (files.count()) { | | |||
141 | QStringList::const_iterator it(files.begin()), | | |||
142 | end(files.end()); | | |||
143 | | ||||
144 | for (; it != end; ++it) | | |||
145 | if (-1 != (*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) { | | |||
146 | return *it; | | |||
147 | } | | |||
148 | return files.front(); // Just return the 1st one... | | |||
149 | } else { // Hmmm... no known files? | | |||
150 | if (FcGetVersion() >= 21000) { | | |||
151 | QString targetPath(KGlobal::dirs()->localxdgconfdir() + "fontconfig"); | | |||
152 | QDir target(targetPath); | | |||
153 | if (!target.exists()) { | | |||
154 | target.mkpath(targetPath); | | |||
155 | } | | |||
156 | return targetPath + "/fonts.conf"; | | |||
157 | } else { | | |||
158 | return home + "/.fonts.conf"; | | |||
159 | } | | |||
160 | } | | |||
161 | } | | |||
162 | | ||||
163 | static QString getEntry(QDomElement element, const char *type, unsigned int numAttributes, ...) | 120 | static QString getEntry(QDomElement element, const char *type, unsigned int numAttributes, ...) | ||
164 | { | 121 | { | ||
165 | if (numAttributes == element.attributes().length()) { | 122 | if (numAttributes == element.attributes().length()) { | ||
166 | va_list args; | 123 | va_list args; | ||
167 | unsigned int arg; | 124 | unsigned int arg; | ||
168 | bool ok = true; | 125 | bool ok = true; | ||
169 | 126 | | |||
170 | va_start(args, numAttributes); | 127 | va_start(args, numAttributes); | ||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Line(s) | 189 | { | |||
233 | qDebug() << "Using fontconfig file:" << m_file; | 190 | qDebug() << "Using fontconfig file:" << m_file; | ||
234 | reset(); | 191 | reset(); | ||
235 | } | 192 | } | ||
236 | 193 | | |||
237 | KXftConfig::~KXftConfig() | 194 | KXftConfig::~KXftConfig() | ||
238 | { | 195 | { | ||
239 | } | 196 | } | ||
240 | 197 | | |||
241 | bool KXftConfig::reset() | 198 | // | ||
199 | // Obtain location of config file to use. | ||||
200 | QString KXftConfig::getConfigFile() | ||||
242 | { | 201 | { | ||
243 | bool ok = false; | 202 | FcStrList *list = FcConfigGetConfigFiles(FcConfigGetCurrent()); | ||
244 | 203 | QStringList localFiles; | |||
245 | m_madeChanges = false; | 204 | FcChar8 *file; | ||
246 | m_hint.reset(); | 205 | QString home(dirSyntax(QDir::homePath())); | ||
247 | m_hinting.reset(); | | |||
248 | m_excludeRange.reset(); | | |||
249 | m_excludePixelRange.reset(); | | |||
250 | m_subPixel.reset(); | | |||
251 | m_antiAliasing.reset(); | | |||
252 | 206 | | |||
253 | QFile f(m_file); | 207 | m_globalFiles.clear(); | ||
254 | 208 | | |||
255 | if (f.open(QIODevice::ReadOnly)) { | 209 | while ((file = FcStrListNext(list))) { | ||
256 | m_time = getTimeStamp(m_file); | 210 | QString f((const char *)file); | ||
257 | ok = true; | | |||
258 | m_doc.clear(); | | |||
259 | 211 | | |||
260 | if (m_doc.setContent(&f)) { | 212 | if (fExists(f) && 0 == f.indexOf(home)) { | ||
261 | readContents(); | 213 | localFiles.append(f); | ||
262 | } | | |||
263 | f.close(); | | |||
264 | } else { | 214 | } else { | ||
265 | ok = !fExists(m_file) && dWritable(getDir(m_file)); | 215 | m_globalFiles.append(f); | ||
266 | } | 216 | } | ||
267 | | ||||
268 | if (m_doc.documentElement().isNull()) { | | |||
269 | m_doc.appendChild(m_doc.createElement("fontconfig")); | | |||
270 | } | 217 | } | ||
218 | FcStrListDone(list); | ||||
271 | 219 | | |||
272 | if (ok) { | | |||
273 | // | 220 | // | ||
274 | // Check exclude range values - i.e. size and pixel size... | 221 | // Go through list of localFiles, looking for the preferred one... | ||
275 | // If "size" range is set, ensure "pixelsize" matches... | 222 | if (localFiles.count()) { | ||
276 | if (!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) { | 223 | QStringList::const_iterator it(localFiles.begin()), | ||
277 | double pFrom = (double)point2Pixel(m_excludeRange.from), | 224 | end(localFiles.end()); | ||
278 | pTo = (double)point2Pixel(m_excludeRange.to); | | |||
279 | 225 | | |||
280 | if (!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) { | 226 | for (; it != end; ++it) | ||
281 | m_excludePixelRange.from = pFrom; | 227 | if (-1 != (*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) { | ||
282 | m_excludePixelRange.to = pTo; | 228 | return *it; | ||
283 | m_madeChanges = true; | | |||
284 | } | 229 | } | ||
285 | } else if (!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) { | 230 | return localFiles.front(); // Just return the 1st one... | ||
286 | // "pixelsize" set, but not "size" !!! | 231 | } else { // Hmmm... no known localFiles? | ||
287 | m_excludeRange.from = (int)pixel2Point(m_excludePixelRange.from); | 232 | if (FcGetVersion() >= 21000) { | ||
288 | m_excludeRange.to = (int)pixel2Point(m_excludePixelRange.to); | 233 | QString targetPath(KGlobal::dirs()->localxdgconfdir() + "fontconfig"); | ||
289 | m_madeChanges = true; | 234 | QDir target(targetPath); | ||
235 | if (!target.exists()) { | ||||
236 | target.mkpath(targetPath); | ||||
237 | } | ||||
238 | return targetPath + "/fonts.conf"; | ||||
239 | } else { | ||||
240 | return home + "/.fonts.conf"; | ||||
290 | } | 241 | } | ||
291 | } | 242 | } | ||
243 | } | ||||
244 | | ||||
245 | bool KXftConfig::reset() | ||||
246 | { | ||||
247 | bool ok = false; | ||||
248 | | ||||
249 | m_madeChanges = false; | ||||
250 | m_hint.reset(); | ||||
251 | m_hinting.reset(); | ||||
252 | m_excludeRange.reset(); | ||||
253 | m_excludePixelRange.reset(); | ||||
254 | m_subPixel.reset(); | ||||
255 | m_antiAliasing.reset(); | ||||
256 | | ||||
257 | QStringList::const_iterator it(m_globalFiles.begin()), | ||||
258 | end(m_globalFiles.end()); | ||||
259 | for (; it != end; ++it) { | ||||
260 | ok |= parseConfigFile(*it); | ||||
261 | } | ||||
262 | ok |= parseConfigFile(m_file); | ||||
292 | 263 | | |||
293 | return ok; | 264 | return ok; | ||
294 | } | 265 | } | ||
295 | 266 | | |||
296 | bool KXftConfig::apply() | 267 | bool KXftConfig::apply() | ||
297 | { | 268 | { | ||
298 | bool ok = true; | 269 | bool ok = true; | ||
299 | 270 | | |||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Line(s) | 483 | case Hint::None: | |||
513 | return "hintnone"; | 484 | return "hintnone"; | ||
514 | case Hint::Slight: | 485 | case Hint::Slight: | ||
515 | return "hintslight"; | 486 | return "hintslight"; | ||
516 | case Hint::Full: | 487 | case Hint::Full: | ||
517 | return "hintfull"; | 488 | return "hintfull"; | ||
518 | } | 489 | } | ||
519 | } | 490 | } | ||
520 | 491 | | |||
492 | bool KXftConfig::parseConfigFile(const QString& filename) | ||||
493 | { | ||||
494 | bool ok = false; | ||||
495 | | ||||
496 | QFile f(filename); | ||||
497 | | ||||
498 | if (f.open(QIODevice::ReadOnly)) { | ||||
499 | m_time = getTimeStamp(filename); | ||||
500 | ok = true; | ||||
501 | m_doc.clear(); | ||||
502 | | ||||
503 | if (m_doc.setContent(&f)) { | ||||
504 | readContents(); | ||||
505 | } | ||||
506 | f.close(); | ||||
507 | } else { | ||||
508 | ok = !fExists(filename) && dWritable(getDir(filename)); | ||||
509 | } | ||||
510 | | ||||
511 | if (m_doc.documentElement().isNull()) { | ||||
512 | m_doc.appendChild(m_doc.createElement("fontconfig")); | ||||
513 | } | ||||
514 | | ||||
515 | if (ok) { | ||||
516 | // | ||||
517 | // Check exclude range values - i.e. size and pixel size... | ||||
518 | // If "size" range is set, ensure "pixelsize" matches... | ||||
519 | if (!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) { | ||||
520 | double pFrom = (double)point2Pixel(m_excludeRange.from), | ||||
521 | pTo = (double)point2Pixel(m_excludeRange.to); | ||||
522 | | ||||
523 | if (!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) { | ||||
524 | m_excludePixelRange.from = pFrom; | ||||
525 | m_excludePixelRange.to = pTo; | ||||
526 | m_madeChanges = true; | ||||
527 | } | ||||
528 | } else if (!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) { | ||||
529 | // "pixelsize" set, but not "size" !!! | ||||
530 | m_excludeRange.from = (int)pixel2Point(m_excludePixelRange.from); | ||||
531 | m_excludeRange.to = (int)pixel2Point(m_excludePixelRange.to); | ||||
532 | m_madeChanges = true; | ||||
533 | } | ||||
534 | } | ||||
535 | | ||||
536 | return ok; | ||||
537 | } | ||||
538 | | ||||
521 | void KXftConfig::readContents() | 539 | void KXftConfig::readContents() | ||
522 | { | 540 | { | ||
523 | QDomNode n = m_doc.documentElement().firstChild(); | 541 | QDomNode n = m_doc.documentElement().firstChild(); | ||
524 | 542 | | |||
525 | while (!n.isNull()) { | 543 | while (!n.isNull()) { | ||
526 | QDomElement e = n.toElement(); | 544 | QDomElement e = n.toElement(); | ||
527 | 545 | | |||
528 | if (!e.isNull()) { | 546 | if (!e.isNull()) { | ||
529 | if ("match" == e.tagName()) { | 547 | if ("match" == e.tagName()) { | ||
530 | QString str; | 548 | QString str; | ||
531 | 549 | | |||
532 | switch (e.childNodes().count()) { | 550 | int childNodesCount = e.childNodes().count(); | ||
551 | QDomNode en = e.firstChild(); | ||||
552 | while (!en.isNull()) { | ||||
553 | if (en.isComment()) { | ||||
554 | childNodesCount--; | ||||
555 | } | ||||
556 | en = en.nextSibling(); | ||||
557 | } | ||||
558 | | ||||
559 | switch (childNodesCount) { | ||||
533 | case 1: | 560 | case 1: | ||
534 | if ("font" == e.attribute("target")) { | 561 | if ("font" == e.attribute("target") || "pattern" == e.attribute("target")) { | ||
535 | QDomElement ene = e.firstChild().toElement(); | 562 | QDomNode en = e.firstChild(); | ||
563 | while (!en.isNull()) { | ||||
564 | QDomElement ene = en.toElement(); | ||||
565 | | ||||
566 | while (ene.isComment()) { | ||||
567 | ene = ene.nextSiblingElement(); | ||||
568 | } | ||||
536 | 569 | | |||
537 | if (!ene.isNull() && "edit" == ene.tagName()) { | 570 | if (!ene.isNull() && "edit" == ene.tagName()) { | ||
538 | if (!(str = getEntry(ene, "const", 2, "name", "rgba", "mode", | 571 | if (!(str = getEntry(ene, "const", 2, "name", "rgba", "mode", | ||
539 | "assign")).isNull()) { | 572 | "assign")).isNull() | ||
573 | || (m_subPixel.type == SubPixel::NotSet && !(str = getEntry(ene, "const", 2, "name", "rgba", "mode", | ||||
574 | "append")).isNull())) { | ||||
540 | m_subPixel.node = n; | 575 | m_subPixel.node = n; | ||
541 | m_subPixel.type = strToType(str.toLatin1()); | 576 | m_subPixel.type = strToType(str.toLatin1()); | ||
542 | } else if (!(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", | 577 | } else if (!(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", | ||
543 | "assign")).isNull()) { | 578 | "assign")).isNull() | ||
579 | || (m_hint.style == Hint::NotSet && !(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", | ||||
580 | "append")).isNull())) { | ||||
544 | m_hint.node = n; | 581 | m_hint.node = n; | ||
545 | m_hint.style = strToStyle(str.toLatin1()); | 582 | m_hint.style = strToStyle(str.toLatin1()); | ||
546 | } else if (!(str = getEntry(ene, "bool", 2, "name", "hinting", "mode", | 583 | } else if (!(str = getEntry(ene, "bool", 2, "name", "hinting", "mode", | ||
547 | "assign")).isNull()) { | 584 | "assign")).isNull()) { | ||
548 | m_hinting.node = n; | 585 | m_hinting.node = n; | ||
549 | m_hinting.set = str.toLower() != "false"; | 586 | m_hinting.set = str.toLower() != "false"; | ||
550 | } else if (!(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", | 587 | } else if (!(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", | ||
551 | "assign")).isNull()) { | 588 | "assign")).isNull() | ||
589 | || (m_antiAliasing.state == AntiAliasing::NotSet && !(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", | ||||
590 | "append")).isNull())) { | ||||
552 | m_antiAliasing.node = n; | 591 | m_antiAliasing.node = n; | ||
553 | m_antiAliasing.state = str.toLower() != "false" ? | 592 | m_antiAliasing.state = str.toLower() != "false" ? | ||
554 | AntiAliasing::Enabled : AntiAliasing::Disabled; | 593 | AntiAliasing::Enabled : AntiAliasing::Disabled; | ||
555 | } | 594 | } | ||
556 | } | 595 | } | ||
596 | | ||||
597 | en = en.nextSibling(); | ||||
598 | } | ||||
557 | } | 599 | } | ||
558 | break; | 600 | break; | ||
559 | case 3: // CPD: Is target "font" or "pattern" ???? | 601 | case 3: // CPD: Is target "font" or "pattern" ???? | ||
560 | if ("font" == e.attribute("target")) { | 602 | if ("font" == e.attribute("target")) { | ||
561 | bool foundFalse = false; | 603 | bool foundFalse = false; | ||
562 | QDomNode en = e.firstChild(); | 604 | QDomNode en = e.firstChild(); | ||
605 | while (en.isComment()) { | ||||
606 | en = en.nextSibling(); | ||||
607 | } | ||||
563 | QString family; | 608 | QString family; | ||
564 | double from = -1.0, | 609 | double from = -1.0, | ||
565 | to = -1.0, | 610 | to = -1.0, | ||
566 | pixelFrom = -1.0, | 611 | pixelFrom = -1.0, | ||
567 | pixelTo = -1.0; | 612 | pixelTo = -1.0; | ||
568 | 613 | | |||
569 | while (!en.isNull()) { | 614 | while (!en.isNull()) { | ||
570 | QDomElement ene = en.toElement(); | 615 | QDomElement ene = en.toElement(); | ||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |