Update ODT handling of font
This commit is contained in:
@@ -36,7 +36,6 @@ from time import time
|
||||
from PyQt5.QtCore import QCoreApplication, QRegularExpression
|
||||
from PyQt5.QtGui import QFont
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.common import checkInt, formatTimeStamp, numberToRoman
|
||||
from novelwriter.constants import (
|
||||
nwHeadFmt, nwKeyWords, nwLabels, nwRegEx, nwShortcode, nwUnicode, trConst
|
||||
@@ -141,7 +140,7 @@ class Tokenizer(ABC):
|
||||
self._markdown: list[str] = []
|
||||
|
||||
# User Settings
|
||||
self._textFont = CONFIG.textFont # Output text font
|
||||
self._textFont = QFont("Serif", 11) # Output text font
|
||||
self._lineHeight = 1.15 # Line height in units of em
|
||||
self._blockIndent = 4.00 # Block indent in units of em
|
||||
self._firstIndent = False # Enable first line indent
|
||||
|
||||
+58
-38
@@ -35,11 +35,14 @@ from hashlib import sha256
|
||||
from pathlib import Path
|
||||
from zipfile import ZipFile
|
||||
|
||||
from PyQt5.QtGui import QFont
|
||||
|
||||
from novelwriter import __version__
|
||||
from novelwriter.common import xmlIndent
|
||||
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.tokenizer import T_Formats, Tokenizer, stripEscape
|
||||
from novelwriter.types import FONT_WEIGHTS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -108,6 +111,10 @@ S_TEXT = "Text_20_body"
|
||||
S_META = "Text_20_Meta"
|
||||
S_HNF = "Header_20_and_20_Footer"
|
||||
|
||||
# Font Data
|
||||
FONT_WEIGHT_NUM = ["100", "200", "300", "400", "500", "600", "700", "800", "900"]
|
||||
FONT_WEIGHT_MAP = {"400": "normal", "700": "bold"}
|
||||
|
||||
|
||||
class ToOdt(Tokenizer):
|
||||
"""Core: Open Document Writer
|
||||
@@ -149,16 +156,17 @@ class ToOdt(Tokenizer):
|
||||
self._errData = [] # List of errors encountered
|
||||
|
||||
# Properties
|
||||
self._textFont = "Liberation Serif"
|
||||
self._textSize = 12
|
||||
self._textFixed = False
|
||||
self._textFont = QFont("Liberation Serif", 12)
|
||||
self._colourHead = False
|
||||
self._headerFormat = ""
|
||||
self._pageOffset = 0
|
||||
|
||||
# Internal
|
||||
self._fontFamily = "'Liberation Serif'"
|
||||
self._fontFamily = "Liberation Serif"
|
||||
self._fontSize = 12
|
||||
self._fontWeight = "normal"
|
||||
self._fontPitch = "variable"
|
||||
self._fontBold = "bold"
|
||||
self._fSizeTitle = "30pt"
|
||||
self._fSizeHead1 = "24pt"
|
||||
self._fSizeHead2 = "20pt"
|
||||
@@ -260,19 +268,24 @@ class ToOdt(Tokenizer):
|
||||
# Initialise Variables
|
||||
# ====================
|
||||
|
||||
self._fontFamily = self._textFont
|
||||
if len(self._textFont.split()) > 1:
|
||||
self._fontFamily = f"'{self._textFont}'"
|
||||
self._fontPitch = "fixed" if self._textFixed else "variable"
|
||||
intWeight = FONT_WEIGHTS.get(self._textFont.weight(), 400)
|
||||
fontWeight = str(intWeight)
|
||||
fontBold = str(min(intWeight + 300, 900))
|
||||
|
||||
self._fSizeTitle = f"{round(2.50 * self._textSize):d}pt"
|
||||
self._fSizeHead1 = f"{round(2.00 * self._textSize):d}pt"
|
||||
self._fSizeHead2 = f"{round(1.60 * self._textSize):d}pt"
|
||||
self._fSizeHead3 = f"{round(1.30 * self._textSize):d}pt"
|
||||
self._fSizeHead4 = f"{round(1.15 * self._textSize):d}pt"
|
||||
self._fSizeHead = f"{round(1.15 * self._textSize):d}pt"
|
||||
self._fSizeText = f"{self._textSize:d}pt"
|
||||
self._fSizeFoot = f"{round(0.8*self._textSize):d}pt"
|
||||
self._fontFamily = self._textFont.family()
|
||||
self._fontSize = self._textFont.pointSize()
|
||||
self._fontWeight = FONT_WEIGHT_MAP.get(fontWeight, fontWeight)
|
||||
self._fontPitch = "fixed" if self._textFont.fixedPitch() else "variable"
|
||||
self._fontBold = FONT_WEIGHT_MAP.get(fontBold, fontBold)
|
||||
|
||||
self._fSizeTitle = f"{round(2.50 * self._fontSize):d}pt"
|
||||
self._fSizeHead1 = f"{round(2.00 * self._fontSize):d}pt"
|
||||
self._fSizeHead2 = f"{round(1.60 * self._fontSize):d}pt"
|
||||
self._fSizeHead3 = f"{round(1.30 * self._fontSize):d}pt"
|
||||
self._fSizeHead4 = f"{round(1.15 * self._fontSize):d}pt"
|
||||
self._fSizeHead = f"{round(1.15 * self._fontSize):d}pt"
|
||||
self._fSizeText = f"{self._fontSize:d}pt"
|
||||
self._fSizeFoot = f"{round(0.8*self._fontSize):d}pt"
|
||||
|
||||
mScale = self._lineHeight/1.15
|
||||
|
||||
@@ -320,8 +333,9 @@ class ToOdt(Tokenizer):
|
||||
tAttr[_mkTag("office", "version")] = X_VERS
|
||||
|
||||
fAttr = {}
|
||||
fAttr[_mkTag("style", "name")] = self._textFont
|
||||
fAttr[_mkTag("style", "name")] = self._fontFamily
|
||||
fAttr[_mkTag("style", "font-pitch")] = self._fontPitch
|
||||
fAttr[_mkTag("style", "font-weight")] = self._fontWeight
|
||||
|
||||
if self._isFlat:
|
||||
|
||||
@@ -726,7 +740,7 @@ class ToOdt(Tokenizer):
|
||||
|
||||
style = ODTTextStyle(f"T{len(self._autoText)+1:d}")
|
||||
if hFmt & X_BLD:
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
if hFmt & X_ITA:
|
||||
style.setFontStyle("italic")
|
||||
if hFmt & X_DEL:
|
||||
@@ -764,7 +778,7 @@ class ToOdt(Tokenizer):
|
||||
|
||||
def _emToCm(self, value: float) -> str:
|
||||
"""Converts an em value to centimetres."""
|
||||
return f"{value*2.54/72*self._textSize:.3f}cm"
|
||||
return f"{value*2.54/72*self._fontSize:.3f}cm"
|
||||
|
||||
##
|
||||
# Style Elements
|
||||
@@ -808,8 +822,9 @@ class ToOdt(Tokenizer):
|
||||
_mkTag("style", "writing-mode"): "page",
|
||||
})
|
||||
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
|
||||
_mkTag("style", "font-name"): self._textFont,
|
||||
_mkTag("style", "font-name"): self._fontFamily,
|
||||
_mkTag("fo", "font-family"): self._fontFamily,
|
||||
_mkTag("fo", "font-weight"): self._fontWeight,
|
||||
_mkTag("fo", "font-size"): self._fSizeText,
|
||||
_mkTag("fo", "language"): self._dLanguage,
|
||||
_mkTag("fo", "country"): self._dCountry,
|
||||
@@ -822,8 +837,9 @@ class ToOdt(Tokenizer):
|
||||
_mkTag("style", "class"): "text",
|
||||
})
|
||||
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
|
||||
_mkTag("style", "font-name"): self._textFont,
|
||||
_mkTag("style", "font-name"): self._fontFamily,
|
||||
_mkTag("fo", "font-family"): self._fontFamily,
|
||||
_mkTag("fo", "font-weight"): self._fontWeight,
|
||||
_mkTag("fo", "font-size"): self._fSizeText,
|
||||
})
|
||||
|
||||
@@ -841,8 +857,9 @@ class ToOdt(Tokenizer):
|
||||
_mkTag("fo", "keep-with-next"): "always",
|
||||
})
|
||||
ET.SubElement(xStyl, _mkTag("style", "text-properties"), attrib={
|
||||
_mkTag("style", "font-name"): self._textFont,
|
||||
_mkTag("style", "font-name"): self._fontFamily,
|
||||
_mkTag("fo", "font-family"): self._fontFamily,
|
||||
_mkTag("fo", "font-weight"): self._fontWeight,
|
||||
_mkTag("fo", "font-size"): self._fSizeHead,
|
||||
})
|
||||
|
||||
@@ -868,9 +885,10 @@ class ToOdt(Tokenizer):
|
||||
style.setMarginBottom(self._mBotText)
|
||||
style.setLineHeight(self._fLineHeight)
|
||||
style.setTextAlign(self._textAlign)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeText)
|
||||
style.setFontWeight(self._fontWeight)
|
||||
style.packXML(self._xStyl)
|
||||
self._mainPara[style.name] = style
|
||||
|
||||
@@ -891,9 +909,10 @@ class ToOdt(Tokenizer):
|
||||
style.setMarginTop(self._mTopMeta)
|
||||
style.setMarginBottom(self._mBotMeta)
|
||||
style.setLineHeight(self._fLineHeight)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeText)
|
||||
style.setFontWeight(self._fontWeight)
|
||||
style.setColour(self._colMetaTx)
|
||||
style.setOpacity(self._opaMetaTx)
|
||||
style.packXML(self._xStyl)
|
||||
@@ -908,10 +927,10 @@ class ToOdt(Tokenizer):
|
||||
style.setMarginTop(self._mTopTitle)
|
||||
style.setMarginBottom(self._mBotTitle)
|
||||
style.setTextAlign("center")
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeTitle)
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
style.packXML(self._xStyl)
|
||||
self._mainPara[style.name] = style
|
||||
|
||||
@@ -925,9 +944,10 @@ class ToOdt(Tokenizer):
|
||||
style.setMarginBottom(self._mBotText)
|
||||
style.setLineHeight(self._fLineHeight)
|
||||
style.setTextAlign("center")
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeText)
|
||||
style.setFontWeight(self._fontWeight)
|
||||
style.packXML(self._xStyl)
|
||||
self._mainPara[style.name] = style
|
||||
|
||||
@@ -940,10 +960,10 @@ class ToOdt(Tokenizer):
|
||||
style.setClass("text")
|
||||
style.setMarginTop(self._mTopHead1)
|
||||
style.setMarginBottom(self._mBotHead1)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeHead1)
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
style.setColour(self._colHead12)
|
||||
style.setOpacity(self._opaHead12)
|
||||
style.packXML(self._xStyl)
|
||||
@@ -958,10 +978,10 @@ class ToOdt(Tokenizer):
|
||||
style.setClass("text")
|
||||
style.setMarginTop(self._mTopHead2)
|
||||
style.setMarginBottom(self._mBotHead2)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeHead2)
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
style.setColour(self._colHead12)
|
||||
style.setOpacity(self._opaHead12)
|
||||
style.packXML(self._xStyl)
|
||||
@@ -976,10 +996,10 @@ class ToOdt(Tokenizer):
|
||||
style.setClass("text")
|
||||
style.setMarginTop(self._mTopHead3)
|
||||
style.setMarginBottom(self._mBotHead3)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeHead3)
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
style.setColour(self._colHead34)
|
||||
style.setOpacity(self._opaHead34)
|
||||
style.packXML(self._xStyl)
|
||||
@@ -994,10 +1014,10 @@ class ToOdt(Tokenizer):
|
||||
style.setClass("text")
|
||||
style.setMarginTop(self._mTopHead4)
|
||||
style.setMarginBottom(self._mBotHead4)
|
||||
style.setFontName(self._textFont)
|
||||
style.setFontName(self._fontFamily)
|
||||
style.setFontFamily(self._fontFamily)
|
||||
style.setFontSize(self._fSizeHead4)
|
||||
style.setFontWeight("bold")
|
||||
style.setFontWeight(self._fontBold)
|
||||
style.setColour(self._colHead34)
|
||||
style.setOpacity(self._opaHead34)
|
||||
style.packXML(self._xStyl)
|
||||
@@ -1077,7 +1097,7 @@ class ODTParagraphStyle:
|
||||
VALID_BREAK = ["auto", "column", "page", "even-page", "odd-page", "inherit"]
|
||||
VALID_LEVEL = ["1", "2", "3", "4"]
|
||||
VALID_CLASS = ["text", "chapter", "extra"]
|
||||
VALID_WEIGHT = ["normal", "inherit", "bold"]
|
||||
VALID_WEIGHT = ["normal", "bold"] + FONT_WEIGHT_NUM
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
|
||||
@@ -1320,8 +1340,8 @@ class ODTTextStyle:
|
||||
Only the used settings are exposed here to keep the class minimal
|
||||
and fast.
|
||||
"""
|
||||
VALID_WEIGHT = ["normal", "inherit", "bold"]
|
||||
VALID_STYLE = ["normal", "inherit", "italic"]
|
||||
VALID_WEIGHT = ["normal", "bold"] + FONT_WEIGHT_NUM
|
||||
VALID_STYLE = ["normal", "italic", "oblique"]
|
||||
VALID_POS = ["super", "sub"]
|
||||
VALID_LSTYLE = ["none", "solid"]
|
||||
VALID_LTYPE = ["single", "double"]
|
||||
|
||||
Reference in New Issue
Block a user