diff --git a/scripts/gen_eo_logo.py b/scripts/gen_eo_logo.py new file mode 100644 index 000000000..ca89abca0 --- /dev/null +++ b/scripts/gen_eo_logo.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +"""Generate Qt-friendly path-only Euro-Office title-bar logos.""" + +from __future__ import annotations + +import sys +from pathlib import Path + +from fontTools.ttLib import TTFont +from fontTools.pens.svgPathPen import SVGPathPen +from fontTools.pens.transformPen import TransformPen + + +def find_font() -> str: + candidates = [ + # nix noto + *Path("/nix/store").glob("*/share/fonts/noto/NotoSans.ttf"), + *Path("/run/current-system/sw/share/fonts").glob("**/NotoSans.ttf"), + "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", + ] + for c in candidates: + p = Path(c) + if p.is_file(): + return str(p) + raise SystemExit("No suitable sans font found") + + +def doc_icon_path(x: float, y: float, size: float) -> str: + """Simple document mark (fold + lines), path-only.""" + k = size / 24.0 + + def X(v: float) -> float: + return x + v * k + + def Y(v: float) -> float: + return y + v * k + + r = 2 * k + return ( + f"M{X(6):.3f},{Y(2):.3f} " + f"H{X(14):.3f} " + f"L{X(20):.3f},{Y(8):.3f} " + f"V{Y(20):.3f} " + f"A{r:.3f},{r:.3f} 0 0 1 {X(18):.3f},{Y(22):.3f} " + f"H{X(6):.3f} " + f"A{r:.3f},{r:.3f} 0 0 1 {X(4):.3f},{Y(20):.3f} " + f"V{Y(4):.3f} " + f"A{r:.3f},{r:.3f} 0 0 1 {X(6):.3f},{Y(2):.3f} Z " + f"M{X(14):.3f},{Y(2):.3f} V{Y(8):.3f} H{X(20):.3f} " + f"M{X(8):.3f},{Y(13):.3f} H{X(16):.3f} " + f"M{X(8):.3f},{Y(17):.3f} H{X(14):.3f}" + ) + + +def wordmark_path(font_path: str, text: str, text_h: float = 12.0) -> tuple[str, float]: + font = TTFont(font_path) + glyph_set = font.getGlyphSet() + cmap = font.getBestCmap() + upem = font["head"].unitsPerEm + scale = text_h / upem + baseline = 14.5 + + x = 0.0 + chunks: list[str] = [] + for ch in text: + gname = cmap.get(ord(ch)) + if not gname: + raise SystemExit(f"missing glyph for {ch!r}") + glyph = glyph_set[gname] + pen = SVGPathPen(glyph_set) + tpen = TransformPen(pen, (scale, 0, 0, -scale, x, baseline)) + glyph.draw(tpen) + d = pen.getCommands() + if d: + chunks.append(d) + x += glyph.width * scale + return " ".join(chunks), x + + +def write_logo(out: Path, fill: str, font_path: str) -> None: + icon_size = 14.0 + icon_x = 1.0 + icon_y = (20.0 - icon_size) / 2.0 + gap = 4.0 + word, word_w = wordmark_path(font_path, "Euro-Office") + text_x = icon_x + icon_size + gap + total_w = int(text_x + word_w + 2.0 + 0.5) + icon_d = doc_icon_path(icon_x, icon_y, icon_size) + + svg = f""" + + + + + + + +""" + out.write_text(svg) + print(f"wrote {out} ({total_w}x20)") + + +def main() -> None: + out_dir = Path(sys.argv[1] if len(sys.argv) > 1 else ".") + out_dir.mkdir(parents=True, exist_ok=True) + font_path = find_font() + print("font:", font_path) + # light chrome → dark ink; dark chrome → light ink + write_logo(out_dir / "logo-light-eo.svg", "#3D4A5C", font_path) + write_logo(out_dir / "logo-dark-eo.svg", "#E8EEF5", font_path) + + +if __name__ == "__main__": + main() diff --git a/win-linux/res/icons/logo-dark-eo.png b/win-linux/res/icons/logo-dark-eo.png index 884010b29..a00644aa2 100644 Binary files a/win-linux/res/icons/logo-dark-eo.png and b/win-linux/res/icons/logo-dark-eo.png differ diff --git a/win-linux/res/icons/logo-dark-eo.svg b/win-linux/res/icons/logo-dark-eo.svg index a0fac4c36..fd260e3b4 100644 --- a/win-linux/res/icons/logo-dark-eo.svg +++ b/win-linux/res/icons/logo-dark-eo.svg @@ -1,6 +1,8 @@ - - - - - Euro-Office + + + + + + + diff --git a/win-linux/res/icons/logo-dark-eo@1.25x.png b/win-linux/res/icons/logo-dark-eo@1.25x.png index f947cacf3..fea6dfb4e 100644 Binary files a/win-linux/res/icons/logo-dark-eo@1.25x.png and b/win-linux/res/icons/logo-dark-eo@1.25x.png differ diff --git a/win-linux/res/icons/logo-dark-eo@1.5x.png b/win-linux/res/icons/logo-dark-eo@1.5x.png index ce129f656..100b10196 100644 Binary files a/win-linux/res/icons/logo-dark-eo@1.5x.png and b/win-linux/res/icons/logo-dark-eo@1.5x.png differ diff --git a/win-linux/res/icons/logo-dark-eo@1.75x.png b/win-linux/res/icons/logo-dark-eo@1.75x.png index 85b866ac0..aa9134a78 100644 Binary files a/win-linux/res/icons/logo-dark-eo@1.75x.png and b/win-linux/res/icons/logo-dark-eo@1.75x.png differ diff --git a/win-linux/res/icons/logo-light-eo.png b/win-linux/res/icons/logo-light-eo.png index 90db90412..a23b69f2a 100644 Binary files a/win-linux/res/icons/logo-light-eo.png and b/win-linux/res/icons/logo-light-eo.png differ diff --git a/win-linux/res/icons/logo-light-eo.svg b/win-linux/res/icons/logo-light-eo.svg index b9b4921a2..3cb6121ff 100644 --- a/win-linux/res/icons/logo-light-eo.svg +++ b/win-linux/res/icons/logo-light-eo.svg @@ -1,6 +1,8 @@ - - - - - Euro-Office + + + + + + + diff --git a/win-linux/res/icons/logo-light-eo@1.25x.png b/win-linux/res/icons/logo-light-eo@1.25x.png index 8e4a9cbcc..3767bcf3f 100644 Binary files a/win-linux/res/icons/logo-light-eo@1.25x.png and b/win-linux/res/icons/logo-light-eo@1.25x.png differ diff --git a/win-linux/res/icons/logo-light-eo@1.5x.png b/win-linux/res/icons/logo-light-eo@1.5x.png index 7d1ad3f0f..ddf8f4456 100644 Binary files a/win-linux/res/icons/logo-light-eo@1.5x.png and b/win-linux/res/icons/logo-light-eo@1.5x.png differ diff --git a/win-linux/res/icons/logo-light-eo@1.75x.png b/win-linux/res/icons/logo-light-eo@1.75x.png index 7e0b2a6ea..c4bd0ac70 100644 Binary files a/win-linux/res/icons/logo-light-eo@1.75x.png and b/win-linux/res/icons/logo-light-eo@1.75x.png differ diff --git a/win-linux/src/prop/cmainpanelimpl.cpp b/win-linux/src/prop/cmainpanelimpl.cpp index c3f41a826..287ed516b 100644 --- a/win-linux/src/prop/cmainpanelimpl.cpp +++ b/win-linux/src/prop/cmainpanelimpl.cpp @@ -125,8 +125,13 @@ void CMainPanelImpl::updateScaling(double dpiratio) { CMainPanel::updateScaling(dpiratio); - m_pButtonMain->setIcon(":/logo.svg", AscAppManager::themes().current().isDark() ? "logo-light" : "logo-dark"); - m_pButtonMain->setIconSize(QSize(85,20)*dpiratio); + // Use Euro-Office branded SVGs registered in resources.qrc (logo-light-eo / + // logo-dark-eo). The legacy ONLYOFFICE :/logo.svg sprite is not packaged. + const QString logo = AscAppManager::themes().current().isDark() + ? QStringLiteral(":/logo-dark-eo.svg") + : QStringLiteral(":/logo-light-eo.svg"); + m_pButtonMain->setIcon(logo); + m_pButtonMain->setIconSize(QSize(84,20)*dpiratio); } void CMainPanelImpl::applyTheme(const std::wstring& theme) @@ -134,8 +139,11 @@ void CMainPanelImpl::applyTheme(const std::wstring& theme) CMainPanel::applyTheme(theme); double dpiratio = scaling(); - m_pButtonMain->setIcon(":/logo.svg", AscAppManager::themes().current().isDark() ? "logo-light" : "logo-dark"); - m_pButtonMain->setIconSize(QSize(85,20)*dpiratio); + const QString logo = AscAppManager::themes().current().isDark() + ? QStringLiteral(":/logo-dark-eo.svg") + : QStringLiteral(":/logo-light-eo.svg"); + m_pButtonMain->setIcon(logo); + m_pButtonMain->setIconSize(QSize(84,20)*dpiratio); } void CMainPanelImpl::onLocalOptions(const QString& json)