Skip to content

Commit d3a2817

Browse files
committed
Fixa typsnitt i GUI samt hindra inbäddning av otillåtna typsnitt i iXBRL
1 parent fc1ecd3 commit d3a2817

File tree

11 files changed

+184
-8
lines changed

11 files changed

+184
-8
lines changed
344 KB
Binary file not shown.

public/fonts/inter/LICENSE.txt

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
2+
3+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
4+
This license is copied below, and is also available with a FAQ at:
5+
http://scripts.sil.org/OFL
6+
7+
-----------------------------------------------------------
8+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9+
-----------------------------------------------------------
10+
11+
PREAMBLE
12+
The goals of the Open Font License (OFL) are to stimulate worldwide
13+
development of collaborative font projects, to support the font creation
14+
efforts of academic and linguistic communities, and to provide a free and
15+
open framework in which fonts may be shared and improved in partnership
16+
with others.
17+
18+
The OFL allows the licensed fonts to be used, studied, modified and
19+
redistributed freely as long as they are not sold by themselves. The
20+
fonts, including any derivative works, can be bundled, embedded,
21+
redistributed and/or sold with any software provided that any reserved
22+
names are not used by derivative works. The fonts and derivatives,
23+
however, cannot be released under any other type of license. The
24+
requirement for fonts to remain under this license does not apply
25+
to any document created using the fonts or their derivatives.
26+
27+
DEFINITIONS
28+
"Font Software" refers to the set of files released by the Copyright
29+
Holder(s) under this license and clearly marked as such. This may
30+
include source files, build scripts and documentation.
31+
32+
"Reserved Font Name" refers to any names specified as such after the
33+
copyright statement(s).
34+
35+
"Original Version" refers to the collection of Font Software components as
36+
distributed by the Copyright Holder(s).
37+
38+
"Modified Version" refers to any derivative made by adding to, deleting,
39+
or substituting -- in part or in whole -- any of the components of the
40+
Original Version, by changing formats or by porting the Font Software to a
41+
new environment.
42+
43+
"Author" refers to any designer, engineer, programmer, technical
44+
writer or other person who contributed to the Font Software.
45+
46+
PERMISSION AND CONDITIONS
47+
Permission is hereby granted, free of charge, to any person obtaining
48+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
49+
redistribute, and sell modified and unmodified copies of the Font
50+
Software, subject to the following conditions:
51+
52+
1) Neither the Font Software nor any of its individual components,
53+
in Original or Modified Versions, may be sold by itself.
54+
55+
2) Original or Modified Versions of the Font Software may be bundled,
56+
redistributed and/or sold with any software, provided that each copy
57+
contains the above copyright notice and this license. These can be
58+
included either as stand-alone text files, human-readable headers or
59+
in the appropriate machine-readable metadata fields within text or
60+
binary files as long as those fields can be easily viewed by the user.
61+
62+
3) No Modified Version of the Font Software may use the Reserved Font
63+
Name(s) unless explicit written permission is granted by the corresponding
64+
Copyright Holder. This restriction only applies to the primary font name as
65+
presented to the users.
66+
67+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68+
Software shall not be used to promote, endorse or advertise any
69+
Modified Version, except to acknowledge the contribution(s) of the
70+
Copyright Holder(s) and the Author(s) or with their explicit written
71+
permission.
72+
73+
5) The Font Software, modified or unmodified, in part or in whole,
74+
must be distributed entirely under this license, and must not be
75+
distributed under any other license. The requirement for fonts to
76+
remain under this license does not apply to any document created
77+
using the Font Software.
78+
79+
TERMINATION
80+
This license becomes null and void if any of the above conditions are
81+
not met.
82+
83+
DISCLAIMER
84+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92+
OTHER DEALINGS IN THE FONT SOFTWARE.

public/fonts/inter/inter.css

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@font-face {
2+
font-family: InterVariable;
3+
font-style: normal;
4+
font-weight: 100 900;
5+
font-display: swap;
6+
src: url("InterVariable.woff2") format("woff2");
7+
}
8+
9+
@font-feature-values InterVariable {
10+
@character-variant {
11+
cv01: 1;
12+
cv02: 2;
13+
cv03: 3;
14+
cv04: 4;
15+
cv05: 5;
16+
cv06: 6;
17+
cv07: 7;
18+
cv08: 8;
19+
cv09: 9;
20+
cv10: 10;
21+
cv11: 11;
22+
cv12: 12;
23+
cv13: 13;
24+
alt-1: 1; /* Alternate one */
25+
alt-3: 9; /* Flat-top three */
26+
open-4: 2; /* Open four */
27+
open-6: 3; /* Open six */
28+
open-9: 4; /* Open nine */
29+
lc-l-with-tail: 5; /* Lower-case L with tail */
30+
simplified-u: 6; /* Simplified u */
31+
alt-double-s: 7; /* Alternate German double s */
32+
uc-i-with-serif: 8; /* Upper-case i with serif */
33+
uc-g-with-spur: 10; /* Capital G with spur */
34+
single-story-a: 11; /* Single-story a */
35+
compact-lc-f: 12; /* Compact f */
36+
compact-lc-t: 13; /* Compact t */
37+
}
38+
@styleset {
39+
ss01: 1;
40+
ss02: 2;
41+
ss03: 3;
42+
ss04: 4;
43+
ss05: 5;
44+
ss06: 6;
45+
ss07: 7;
46+
ss08: 8;
47+
open-digits: 1; /* Open digits */
48+
disambiguation: 2; /* Disambiguation (with zero) */
49+
disambiguation-except-zero: 4; /* Disambiguation (no zero) */
50+
round-quotes-and-commas: 3; /* Round quotes & commas */
51+
square-punctuation: 7; /* Square punctuation */
52+
square-quotes: 8; /* Square quotes */
53+
circled-characters: 5; /* Circled characters */
54+
squared-characters: 6; /* Squared characters */
55+
}
56+
}

src/App.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ main {
167167
168168
strong {
169169
color: $secondary-color;
170+
font-weight: 600;
170171
}
171172
172173
.bi-arrow-down-square-fill {

src/assets/_variables.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ $background-dark: #e5e5e5; // Mörk bakgrund
2424
$background-input: #ffffff; // Bakgrund för inmatningsfält
2525

2626
// Typografi
27-
$font-family-base: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
27+
$font-family-base: InterVariable, sans-serif;
2828
$font-family-serif: "EB Garamond", serif;
2929
$font-family-sans: "FreeSans", sans-serif;
3030

src/assets/base.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ body {
2929
text-rendering: optimizeLegibility;
3030
-webkit-font-smoothing: antialiased;
3131
-moz-osx-font-smoothing: grayscale;
32+
font-optical-sizing: auto;
3233
}
3334

3435
// För tillgänglighet

src/assets/main.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@import "@/assets/_variables.scss";
22
@import "@/assets/base.scss";
3+
@import "$fonts/inter/inter.css";
34
@import "$fonts/ebgaramond/EBGaramond.css";
45
@import "$fonts/freesans/FreeSans.css";
56

@@ -78,16 +79,15 @@ $bootstrap-icons-font-dir: "bootstrap-icons/font/fonts";
7879
outline-offset: 2px;
7980
box-shadow: 0 0 0 0.25rem rgba($primary-color, 0.25);
8081
}
81-
}
8282

83-
.btn {
83+
// Knappar med ikoner
8484
&:has(i.bi), &:has(img) {
8585
display: flex;
8686
align-items: center;
8787
}
8888

89+
// Knapp-ikoner
8990
i.bi, img {
90-
// Knapp-ikoner
9191
margin-right: var(--bs-btn-padding-x);
9292
}
9393
}

src/components/tools/ToolsFinish.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import SendWizard from "@/components/tools/finish/send/SendWizard.vue";
1313
import FinalizeWizard from "@/components/tools/finish/finalize/FinalizeWizard.vue";
1414
import { getConfigValue } from "@/util/configUtils.ts";
1515
import type { TodoList } from "@/model/todolist/TodoList.ts";
16+
import { RENDER_FONT_FAMILY_WHITELIST } from "@/util/renderUtils.ts";
1617
1718
const props = defineProps<{
1819
/** Årsredovisningen som ska exporteras. */
@@ -39,6 +40,7 @@ async function getIXBRL(): Promise<string | undefined> {
3940
return await convertVueHTMLToiXBRL(
4041
arsredovisningForExport,
4142
`${foretagsinformation.organisationsnummer} ${foretagsinformation.foretagsnamn} - Årsredovisning`,
43+
RENDER_FONT_FAMILY_WHITELIST,
4244
);
4345
}
4446
}

src/components/tools/finish/common/composables/useIXBRLGenerator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ComponentExposed } from "vue-component-type-helpers";
33
import RenderMain from "@/components/render/RenderMain.vue";
44
import type { Arsredovisning } from "@/model/arsredovisning/Arsredovisning.ts";
55
import type { Ref } from "vue";
6+
import { RENDER_FONT_FAMILY_WHITELIST } from "@/util/renderUtils.ts";
67

78
/**
89
* Argument som krävs för att generera en iXBRL-årsredovisning.
@@ -42,6 +43,7 @@ function tryGenerateIXBRLInInterval(args: Args) {
4243
args.ixbrlOutput.value = await convertVueHTMLToiXBRL(
4344
arsredovisningRoot,
4445
`${foretagsinformation.organisationsnummer} ${foretagsinformation.foretagsnamn} - Årsredovisning`,
46+
RENDER_FONT_FAMILY_WHITELIST,
4547
);
4648
}
4749
}, 250);

src/util/documentUtils.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ import xmlFormat from "xml-formatter";
1111
* @param rootElement - HTML-elementet som ska konverteras. Elementets innehåll
1212
* bearbetas och omvandlas till iXBRL-format.
1313
* @param title - Titeln på det resulterande iXBRL-dokumentet.
14+
* @param fontFamilyWhitelist - En lista med typsnitt som får bäddas in i
15+
* iXBRL-dokumentet.
1416
* @returns En sträng som representerar det konverterade iXBRL-innehållet.
1517
*/
1618
export async function convertVueHTMLToiXBRL(
1719
rootElement: HTMLElement,
1820
title: string,
21+
fontFamilyWhitelist: string[],
1922
): Promise<string> {
2023
const doc = new DOMParser().parseFromString(
2124
rootElement.innerHTML,
2225
"text/html",
2326
);
2427

2528
// Lägg till CSS
26-
let rulesCss = await getCssTextForUsedRules(doc);
29+
let rulesCss = await getCssTextForUsedRules(doc, fontFamilyWhitelist);
2730

2831
// Omvandla CSS-attribut som inte är kompatibla med wkhtmltopdf som Bolagsverket använder
2932
rulesCss = rulesCss.replace(
@@ -154,10 +157,15 @@ export async function convertVueHTMLToiXBRL(
154157
* det angivna dokumentet.
155158
*
156159
* @param doc - Ett dokument som ska kontrolleras för matchande CSS-regler.
160+
* @param fontFamilyWhitelist - En lista med typsnitt som får bäddas in i
161+
* iXBRL-dokumentet.
157162
* @returns En sträng som innehåller den sammanfogade CSS-texten för alla
158163
* matchande regler.
159164
*/
160-
async function getCssTextForUsedRules(doc: Document): Promise<string> {
165+
async function getCssTextForUsedRules(
166+
doc: Document,
167+
fontFamilyWhitelist: string[],
168+
): Promise<string> {
161169
const rulesUsed = new Set<CSSRule>();
162170
const fontFamiliesUsed = new Set<string>();
163171

@@ -212,7 +220,8 @@ async function getCssTextForUsedRules(doc: Document): Promise<string> {
212220
rulesCss += rule.cssText + "\n";
213221
}
214222

215-
const fontReferencesInDocument = await getFontReferencesInDocument();
223+
const fontReferencesInDocument =
224+
await getFontReferencesInDocument(fontFamilyWhitelist);
216225
for (const fontReference of fontReferencesInDocument) {
217226
if (fontFamiliesUsed.has(fontReference.fontFamily)) {
218227
rulesCss += `
@@ -235,6 +244,8 @@ async function getCssTextForUsedRules(doc: Document): Promise<string> {
235244
* CSS-stilmallar i dokumentet och extraherar detaljer som fontfamilj, vikt,
236245
* stil, källa (src) och unicode-område.
237246
*
247+
* @param fontFamilyWhitelist - En lista med typsnitt som får bäddas in i
248+
* iXBRL-dokumentet.
238249
* @returns En array med objekt som innehåller typsnittsinformation:
239250
* - fontFamily: Namnet på typsnittet.
240251
* - fontWeight: Vikten för typsnittet, t.ex. 400 för normal vikt.
@@ -243,7 +254,7 @@ async function getCssTextForUsedRules(doc: Document): Promise<string> {
243254
* - srcBase64: Källa till typsnittet i base64-format.
244255
* - unicodeRange: Det unicode-intervall som typsnittet gäller för.
245256
*/
246-
async function getFontReferencesInDocument() {
257+
async function getFontReferencesInDocument(fontFamilyWhitelist: string[]) {
247258
// Ursprunglig källa: https://stackoverflow.com/a/75857870
248259

249260
const fontFiles: Array<{
@@ -274,6 +285,15 @@ async function getFontReferencesInDocument() {
274285
const src = style.getPropertyValue("src");
275286
const unicodeRange = style.getPropertyValue("unicode-range");
276287

288+
// Kolla att aktuell fontFamily får bäddas in i iXBRL-dokumentet
289+
if (
290+
!fontFamilyWhitelist
291+
.map((ff) => ff.toLowerCase())
292+
.includes(fontFamily.toLowerCase())
293+
) {
294+
continue;
295+
}
296+
277297
// Konvertera till base64
278298
const urlMatches = new RegExp(/\(([^)]+)\)/).exec(src.split(",")[0]);
279299
const url = urlMatches ? urlMatches[1].replace(/"/g, "") : "";

0 commit comments

Comments
 (0)