Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ResearchStudio-Reel/skills/paper2poster/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ The first three are **full themes** (they retheme the header + page background);

v1–v4 each render the conference **logo** when `assets/logos/_venue.png` exists (Step 6 `fetch_conf_logo.py`), else a text venue/year fallback in the same chip; v5 uses a text venue badge by design. All work for **2–6 institutions** (empty `LOGO_n` slots auto-hide). Logos are sized to **fill** their zone (single venue logo + a 2-row institution grid), and the logo chips **theme to the chosen style** via `--tb-chip-bg` / `--tb-chip-shadow`: solid → flat white chip (no shadow) on the accent band; framed → flat white chip on the white card; **simple → transparent chip (no frame), logos sit directly on the white header**. Default: pass **`--header random`** — `compose_poster.py` picks one DETERMINISTICALLY from the configured seed from **all five (v1–v5)**; v5 fills its own titlebar QR via `{{HDR_QR_*}}` (see the QR contract). Override via `POSTER_HEADER={v1|v2|v3|v4|v5}`.

**Default font policy:** the poster body defaults to **Arial**, and `--font-latin` may select any of the 8 Mac/Windows PowerPoint-safe family names: `Calibri | Aptos | Cambria | Arial | "Times New Roman" | Verdana | Georgia | "Trebuchet MS"`. These proprietary OS fonts are not reliably installed on the Linux renderer or every HTML client. Before browser geometry is measured, `check_poster.py` / `render_poster.py` therefore freeze their **browser** rendering to a self-contained, open-licensed DejaVu face of the same category (Sans or Serif), stored under `assets/fonts/` with its license but exposed under the requested CSS family name. This makes fill measurements, standalone HTML, PDF, and PNG deterministic while html2pptx continues emitting the requested native family name into `.pptx`; the deck can still have small metric differences because PowerPoint uses the real OS font. Literal Georgia/Arial/etc. in every artifact requires separately licensed webfont files. The optional `POSTER_FONT` env var, when set, carries the same choice — but the default lives in the templates. To use **Inter** (the bundled webfont — more editorial), flip `--font-latin` back to `Inter, …` *and* run the html2pptx Inter embed step so the `.pptx` ships the font; the 4 Inter `@font-face` blocks stay defined in every template for exactly this override.
**Default font policy:** the poster body defaults to **Arial**, and `--font-latin` may select any of the 8 Mac/Windows PowerPoint-safe family names: `Calibri | Aptos | Cambria | Arial | "Times New Roman" | Verdana | Georgia | "Trebuchet MS"`. These proprietary OS fonts are not reliably installed on the Linux renderer or every HTML client. Before browser geometry is measured, `check_poster.py` / `render_poster.py` freeze browser rendering to a compact, self-contained open-licensed subset under `assets/fonts/`, while html2pptx continues emitting the requested native family into `.pptx`. Arial uses bundled Arimo Regular/Bold because Arimo is metrically compatible with Arial; the other selections preserve an open DejaVu or Noto face from the renderer's actual fallback category. A fresh Arial poster, an old Arial/DejaVu fidelity block, or a local-first Arimo block is migrated to packaged-first Arimo through a directional media gate: media identity must stay fixed, every research figure must satisfy the absolute 90% minimum after migration, and no axis may newly exceed 101%. After that one repair, the Arimo layout becomes the strict source baseline for durable HTML, PDF, PNG, and Reel checks. The optional `POSTER_FONT` env var carries the same choice, but the default lives in the templates. To use **Inter**, flip `--font-latin` back to `Inter, …` and run the html2pptx Inter embed step so the `.pptx` ships the font; the 4 Inter `@font-face` blocks stay defined in every template for exactly this override.

**Composition catalog (landscape and portrait):**

Expand Down
Binary file not shown.
155 changes: 155 additions & 0 deletions ResearchStudio-Reel/skills/paper2poster/assets/fonts/Arimo-LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Noto
Upstream-Contact: https://github.com/googlei18n/noto-fonts/issues
http://groups.google.com/group/noto-font
Source: https://github.com/googlei18n/noto-fonts

Files: *
Copyright:
2010,2012-2020, Google Inc.
2015-2020, Google LLC.
License-Grant:
This Font Software is licensed under the SIL Open Font License,
Version 1.1.
License: OFL-1.1

Files:
debian/*
Copyright:
2013-2020, Jonas Smedegaard <dr@jones.dk>
2020, Purism, SPC
2013, Vasudev Kamath <kamathvasudev@gmail.com>
License-Grant:
This program is free software;
you can redistribute it and/or modify it
under the terms of the GNU General Public License
as published by the Free Software Foundation;
either version 3, or (at your option) any later version.
License: GPL-3+

Files:
debian/NotoMono/NotoMono-Regular.ttf
Copyright:
2007, Google Inc.
License-Grant:
This Font Software is licensed under the SIL Open Font License,
Version 1.1.
License: OFL-1.1

License: OFL-1.1
PREAMBLE
.
The goals of the Open Font License (OFL) are to stimulate
worldwide development of collaborative font projects,
to support the font creation efforts
of academic and linguistic communities,
and to provide a free and open framework
in which fonts may be shared and improved
in partnership with others.
.
The OFL allows the licensed fonts to be used, studied,
modified and redistributed freely
as long as they are not sold by themselves.
The fonts, including any derivative works,
can be bundled, embedded,
redistributed and/or sold with any software
provided that any reserved names are not used
by derivative works.
The fonts and derivatives, however,
cannot be released under any other type of license.
The requirement for fonts to remain under this license
does not apply to any document
created using the fonts or their derivatives.
.
DEFINITIONS
.
"Font Software" refers to the set of files
released by the Copyright Holder(s) under this license
and clearly marked as such.
This may include source files, build scripts and documentation.
.
"Reserved Font Name" refers to any names specified as such
after the copyright statement(s).
.
"Original Version" refers to the collection
of Font Software components
as distributed by the Copyright Holder(s).
.
"Modified Version" refers to any derivative
made by adding to, deleting, or substituting --
in part or in whole --
any of the components of the Original Version,
by changing formats
or by porting the Font Software to a new environment.
.
"Author" refers to any designer, engineer, programmer,
technical writer or other person
who contributed to the Font Software.
.
PERMISSION & CONDITIONS
.
Permission is hereby granted, free of charge,
to any person obtaining a copy of the Font Software,
to use, study, copy, merge, embed, modify, redistribute,
and sell modified and unmodified copies of the Font Software,
subject to the following conditions:
.
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions,
may be sold by itself.
.
2) Original or Modified Versions of the Font Software
may be bundled, redistributed and/or sold with any software,
provided that each copy contains the above copyright notice
and this license.
These can be included either as stand-alone text files,
human-readable headers or in the appropriate
machine-readable metadata fields within text or binary files
as long as those fields can be easily viewed by the user.
.
3) No Modified Version of the Font Software may use
the Reserved Font Name(s)
unless explicit written permission is granted
by the corresponding Copyright Holder.
This restriction only applies to the primary font name
as presented to the users.
.
4) The name(s) of the Copyright Holder(s)
or the Author(s) of the Font Software
shall not be used to promote,
endorse or advertise any Modified Version,
except to acknowledge the contribution(s)
of the Copyright Holder(s) and the Author(s)
or with their explicit written permission.
.
5) The Font Software,
modified or unmodified, in part or in whole,
must be distributed entirely under this license,
and must not be distributed under any other license.
The requirement for fonts to remain under this license
does not apply to any document
created using the Font Software.
.
TERMINATION
.
This license becomes null and void
if any of the above conditions are not met.
.
DISCLAIMER
.
THE FONT SOFTWARE IS PROVIDED "AS IS",
WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO
ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT.
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF THE USE OR INABILITY TO USE
THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

License: GPL-3+
License-Reference: /usr/share/common-licenses/GPL-3
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,34 @@
EMBEDDED_FONT_FAMILIES: set[str] = {"inter"}


def _pick_font_family(font_family_css: str) -> str:
def _pick_font_family(
font_family_css: str,
font_fidelity: dict | None = None,
) -> str:
"""Pick the first font from a CSS font-family stack, applying our alias
map. Walks the list left-to-right until it finds a name we recognize as
installed (or maps to one), avoiding generic CSS keywords like sans-serif
that PPT renders as a system default."""
if not font_family_css:
return ""
GENERIC = {"sans-serif", "serif", "monospace", "cursive", "fantasy"}
fidelity = font_fidelity or {}
requested = str(fidelity.get("requested") or "").strip()
browser_faces = {
str(fidelity.get(key) or "").strip().casefold()
for key in ("source", "fallback")
if str(fidelity.get(key) or "").strip()
}
for raw in font_family_css.split(","):
name = raw.strip().strip('"').strip("'")
if not name:
continue
# paper2poster's browser fidelity block deliberately computes to the
# exact Linux-rendered face (plus a metric-identical bundled fallback).
# That is a browser portability detail: editable PowerPoint should keep
# the user's requested native family such as Calibri or Arial.
if requested and name.casefold() in browser_faces:
return requested
if name in FONT_ALIASES:
return FONT_ALIASES[name]
if name.lower() in GENERIC:
Expand Down Expand Up @@ -1690,10 +1706,16 @@ def _route_katex(route):
_pushMath(k, _tex.trim(), k.closest('.katex-display') !== null);
}

const _fidelity = document.getElementById('poster-font-fidelity');
const font_fidelity = _fidelity ? {
requested:_fidelity.getAttribute('data-requested-family') || '',
source:_fidelity.getAttribute('data-source-family') || '',
fallback:_fidelity.getAttribute('data-fallback-family') || '',
} : null;
return {viewport_w: window.innerWidth, viewport_h: window.innerHeight,
body_w: document.body.scrollWidth,
body_h: document.body.scrollHeight,
elements, text_blocks, math_blocks};
elements, text_blocks, math_blocks, font_fidelity};
}""")
# Rasterize each equation region as a PNG fallback while the page is open.
# PowerPoint renders the native OMML we emit in Pass 3, but LibreOffice/
Expand Down Expand Up @@ -2165,7 +2187,10 @@ def emu_y(px): return _px_to_emu(px, slide_h_emu, body_h_px)
run.text = chip_text
fsz_px = el.get("font_size_px", 14) or 14
run.font.size = Pt(fsz_px * 72 / 96 * slide_scale)
fam = _pick_font_family(el.get("font_family", "Inter"))
fam = _pick_font_family(
el.get("font_family", "Inter"),
dom.get("font_fidelity"),
)
if fam:
run.font.name = fam
fw = el.get("font_weight", "400")
Expand Down Expand Up @@ -2741,7 +2766,9 @@ def _has_non_embedded_font_run(rs):
run.text = _hyphenate(run.text)
font = run.font
ff = run_data.get("font_family") or ""
first_family = _pick_font_family(ff)
first_family = _pick_font_family(
ff, dom.get("font_fidelity"),
)
# OOXML's classic embedded-font spec gives each typeface only
# 4 slots (Regular / Bold / Italic / BoldItalic) — there's
# no slot for SemiBold (600) or ExtraBold (800). If we just
Expand Down
Loading