mirror of
https://github.com/discourse/discourse.git
synced 2025-02-24 10:09:55 +08:00
FEATURE: Handle special font properties from discourse-fonts (#30891)
In https://github.com/discourse/discourse-fonts/pull/15 we are introducing special font properties for certain fonts, specifically the `font-variation-settings` and `font-feature-settings`. For now this will only apply to Inter, but we may do it for other fonts in future. This commit makes it so the color_definitions.css file includes these special properties for each font, either defined on the root `html` element for the body font or on the `h1-h6` elements for the heading font. This is done in this way because defining them on `@font-face` is ignored by the browser. This also ensures special CSS classes for the wizard container e.g. wizard-container-font-FONTID are defined, this is so we can use these special properties scoped to the font selected in the wizard, which will affect the way the canvas preview is rendered. Here is an example of before/after with special properties applied to Inter, in this case: ```css font-variation-settings: 'opsz' 28; font-feature-settings: 'calt' 0, 'ccmp' 0, 'ss02' 1; ```
This commit is contained in:
parent
32c6d3be06
commit
83cc97994f
@ -125,7 +125,7 @@ GEM
|
||||
diffy (3.4.3)
|
||||
digest (3.1.1)
|
||||
digest-xxhash (0.2.9)
|
||||
discourse-fonts (0.0.14)
|
||||
discourse-fonts (0.0.15)
|
||||
discourse-seed-fu (2.3.12)
|
||||
activerecord (>= 3.1)
|
||||
activesupport (>= 3.1)
|
||||
|
@ -100,6 +100,10 @@ export default class PreviewBase extends Component {
|
||||
}
|
||||
|
||||
loadFontVariants(font) {
|
||||
if (!font) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const fontVariantData = this.fontMap[font.id];
|
||||
|
||||
// System font for example does not need to load from a remote source.
|
||||
@ -206,8 +210,8 @@ export default class PreviewBase extends Component {
|
||||
const options = {
|
||||
ctx,
|
||||
colors,
|
||||
font: font?.label,
|
||||
headingFont: headingFont?.label,
|
||||
font,
|
||||
headingFont,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
};
|
||||
@ -337,7 +341,7 @@ export default class PreviewBase extends Component {
|
||||
const badgeHeight = headerHeight * 2 * 0.25;
|
||||
const headerMargin = headerHeight * 0.2;
|
||||
const fontSize = Math.round(badgeHeight * 0.5);
|
||||
ctx.font = `${fontSize}px '${font}'`;
|
||||
ctx.font = `${fontSize}px '${font.label}'`;
|
||||
|
||||
const allCategoriesText = i18n(
|
||||
"wizard.homepage_preview.nav_buttons.all_categories"
|
||||
@ -406,7 +410,7 @@ export default class PreviewBase extends Component {
|
||||
);
|
||||
ctx.fill();
|
||||
|
||||
ctx.font = `${fontSize}px '${font}'`;
|
||||
ctx.font = `${fontSize}px '${font.label}'`;
|
||||
ctx.fillStyle = colors.secondary;
|
||||
const pillButtonTextY = headerHeight + headerMargin * 1.4 + fontSize;
|
||||
const firstTopMenuItemX = headerMargin * 3.0 + categoriesBoxWidth;
|
||||
|
@ -137,12 +137,12 @@ export default class Index extends PreviewBaseComponent {
|
||||
// Topic title
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = colors.primary;
|
||||
ctx.font = `700 ${titleFontSize}em '${headingFont}'`;
|
||||
ctx.font = `700 ${titleFontSize}em '${headingFont.label}'`;
|
||||
ctx.fillText(i18n("wizard.previews.topic_title"), margin, height * 0.3);
|
||||
|
||||
// Topic OP text
|
||||
const bodyFontSize = 1;
|
||||
ctx.font = `${bodyFontSize}em '${font}'`;
|
||||
ctx.font = `${bodyFontSize}em '${font.label}'`;
|
||||
|
||||
let verticalLinePos = 0;
|
||||
const topicOp = i18n("wizard.homepage_preview.topic_ops.what_books");
|
||||
@ -160,7 +160,7 @@ export default class Index extends PreviewBaseComponent {
|
||||
}
|
||||
);
|
||||
|
||||
ctx.font = `${bodyFontSize}em '${font}'`;
|
||||
ctx.font = `${bodyFontSize}em '${font.label}'`;
|
||||
|
||||
// Share button
|
||||
const shareButtonWidth =
|
||||
@ -221,13 +221,13 @@ export default class Index extends PreviewBaseComponent {
|
||||
// Timeline post count
|
||||
const postCountY = height * 0.3 + margin + 10;
|
||||
ctx.beginPath();
|
||||
ctx.font = `700 ${bodyFontSize}em '${font}'`;
|
||||
ctx.font = `700 ${bodyFontSize}em '${font.label}'`;
|
||||
ctx.fillStyle = colors.primary;
|
||||
ctx.fillText("1 / 20", timelineX + margin / 2, postCountY);
|
||||
|
||||
// Timeline post date
|
||||
ctx.beginPath();
|
||||
ctx.font = `${bodyFontSize * 0.9}em '${font}'`;
|
||||
ctx.font = `${bodyFontSize * 0.9}em '${font.label}'`;
|
||||
ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 70, 65);
|
||||
ctx.fillText(
|
||||
"Nov 22",
|
||||
|
@ -6,6 +6,7 @@ import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import didUpdate from "@ember/render-modifiers/modifiers/did-update";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import emoji from "discourse/helpers/emoji";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import WizardField from "./wizard-field";
|
||||
@ -80,6 +81,20 @@ export default class WizardStepComponent extends Component {
|
||||
return !!this.step.fields.find((f) => f.showInSidebar);
|
||||
}
|
||||
|
||||
get containerFontClasses() {
|
||||
let fontClasses = "";
|
||||
|
||||
if (this.wizard.font) {
|
||||
fontClasses += ` wizard-container-body-font-${this.wizard.font.id}`;
|
||||
}
|
||||
|
||||
if (this.wizard.headingFont) {
|
||||
fontClasses += ` wizard-container-heading-font-${this.wizard.headingFont.id}`;
|
||||
}
|
||||
|
||||
return fontClasses;
|
||||
}
|
||||
|
||||
@action
|
||||
stepChanged() {
|
||||
this.saving = false;
|
||||
@ -195,7 +210,7 @@ export default class WizardStepComponent extends Component {
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="wizard-container">
|
||||
<div class={{concatClass "wizard-container" this.containerFontClasses}}>
|
||||
<div class="wizard-container__step-contents">
|
||||
<div class="wizard-container__step-header">
|
||||
{{#if @step.emoji}}
|
||||
|
@ -42,19 +42,23 @@ module Stylesheet
|
||||
contents = +""
|
||||
|
||||
contents << <<~CSS if body_font.present?
|
||||
// Body font definition
|
||||
#{font_css(body_font)}
|
||||
|
||||
#{render_font_special_properties(body_font, "body")}
|
||||
:root {
|
||||
--font-family: #{body_font[:stack]};
|
||||
}
|
||||
|
||||
CSS
|
||||
|
||||
contents << <<~CSS if heading_font.present?
|
||||
// Heading font definition
|
||||
#{font_css(heading_font)}
|
||||
|
||||
#{render_font_special_properties(heading_font, "heading")}
|
||||
:root {
|
||||
--heading-font-family: #{heading_font[:stack]};
|
||||
}
|
||||
|
||||
CSS
|
||||
|
||||
contents
|
||||
@ -90,6 +94,7 @@ module Stylesheet
|
||||
font-family: #{font[:stack]};
|
||||
}
|
||||
CSS
|
||||
contents << render_wizard_font_special_properties(font)
|
||||
end
|
||||
|
||||
contents
|
||||
@ -108,7 +113,10 @@ module Stylesheet
|
||||
|
||||
if resolved_ids
|
||||
theme = Theme.find_by_id(theme_id)
|
||||
contents << theme&.scss_variables.to_s
|
||||
|
||||
contents << "\n\n// Theme SCSS variables\n\n"
|
||||
contents << theme&.scss_variables.to_s.split(";").join(";\n") + ";\n\n"
|
||||
contents << "\n\n"
|
||||
Theme
|
||||
.list_baked_fields(resolved_ids, :common, :color_definitions)
|
||||
.each do |field|
|
||||
@ -220,6 +228,7 @@ module Stylesheet
|
||||
"url(\"#{fonts_dir}/#{variant[:filename]}?v=#{DiscourseFonts::VERSION}\") format(\"#{variant[:format]}\")"
|
||||
end
|
||||
)
|
||||
|
||||
contents << <<~CSS
|
||||
@font-face {
|
||||
font-family: '#{font[:name]}';
|
||||
@ -232,5 +241,41 @@ module Stylesheet
|
||||
|
||||
contents
|
||||
end
|
||||
|
||||
def render_font_special_properties(font, font_type)
|
||||
contents = +""
|
||||
root_elements = font_type == "body" ? "html" : "h1, h2, h3, h4, h5, h6"
|
||||
contents << "#{root_elements} {\n"
|
||||
contents << font_special_properties(font)
|
||||
contents << "}\n"
|
||||
end
|
||||
|
||||
def render_wizard_font_special_properties(font)
|
||||
contents = +""
|
||||
contents << ".wizard-container-heading-font-#{font[:key]} {\n"
|
||||
contents << " h1, h2, h3, h4, h5, h6 {\n"
|
||||
contents << font_special_properties(font, 4)
|
||||
contents << " }\n"
|
||||
contents << "}\n"
|
||||
contents << ".wizard-container-body-font-#{font[:key]} {\n"
|
||||
contents << font_special_properties(font)
|
||||
contents << "}\n"
|
||||
end
|
||||
|
||||
def font_special_properties(font, indent = 2)
|
||||
contents = +""
|
||||
if font[:font_variation_settings].present?
|
||||
contents << "#{" " * indent}font-variation-settings: #{font[:font_variation_settings]};\n"
|
||||
else
|
||||
contents << "#{" " * indent}font-variation-settings: normal;\n"
|
||||
end
|
||||
|
||||
if font[:font_feature_settings].present?
|
||||
contents << "#{" " * indent}font-feature-settings: #{font[:font_feature_settings]};\n"
|
||||
else
|
||||
contents << "#{" " * indent}font-feature-settings: normal;\n"
|
||||
end
|
||||
contents
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user