fix: fit an imported as-character image to the text column
An inline atom wider than the column is pushed onto a line of its own and leaves the empty line above it in the document — 5mm per image. A picture the file sizes to the column lands there anyway once its cm/EMU width is rounded to whole px, which is how a full-width Word picture triggered it.
This commit is contained in:
1 parent
c34fb4312a
commit
273654640c
3 files changed
+15
-1
No files matched your search
@@ -44,6 +44,16 @@ export function parsePx(value: string | null): number | null {
|
||||
|
||||
export const clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));
|
||||
|
||||
// An as-character image wider than the text column takes a line of its own and leaves an
|
||||
// empty one above it. Fitting it to the column is where an image the file sizes to the
|
||||
// column lands anyway, once its cm/EMU width is rounded to whole px (importers).
|
||||
export function fitInlineImage(attrs: Record<string, unknown>, maxWidthPx: number): void {
|
||||
const w = attrs.width;
|
||||
if (typeof w !== 'number' || w <= maxWidthPx) return;
|
||||
if (typeof attrs.height === 'number') attrs.height = Math.max(1, Math.round((attrs.height * maxWidthPx) / w));
|
||||
attrs.width = maxWidthPx;
|
||||
}
|
||||
|
||||
// The page text height in px, capping how tall an image can be stretched. Read live
|
||||
// from the :root vars the editor maintains (orientation/margins change them).
|
||||
export function pageContentHeightPx(): number {
|
||||
|
||||
@@ -4,13 +4,14 @@ import { lengthToPt } from './styleResolver';
|
||||
import { HEADING_STYLE_OVERRIDES, MAX_HEADING_LEVEL, normalizeColor } from '../export/odt';
|
||||
import { builtinStyleSheet, DEFAULT_STYLE, type ParaProps, type Style, type StyleSheet, type TextProps } from '../styles/styleSheet';
|
||||
import { HEADER_SHADE } from '../editor/extensions/tableHeaderRow';
|
||||
import { fitInlineImage } from '../editor/extensions/image';
|
||||
import { formatTabStops } from '../editor/extensions/tabStops';
|
||||
import { tableLookAttr } from '../styles/tableStyles';
|
||||
import { orderedTypeFromFormat, orderedTypeAttrAt, childCycle, ROOT_ORDERED_CYCLE, type OrderedCycle } from '../utils/orderedListTypes';
|
||||
import { bulletCharAttr, bulletCharFromDocx } from '../utils/bulletListTypes';
|
||||
import { DATE_FORMATS, TIME_FORMATS, docxPicture, toDateValue } from '../utils/dateTime';
|
||||
import { imageDataUrl, type ConvertedImages } from './imageFormats';
|
||||
import { PX_PER_CM, type PageMargins } from '../storage/pageMargins';
|
||||
import { PX_PER_CM, cmToPx, type PageMargins } from '../storage/pageMargins';
|
||||
import type { Orientation } from '../storage/pageOrientation';
|
||||
import { formatFromCm, type PageFormat } from '../storage/pageFormat';
|
||||
import { languageFromOdf, NO_LANGUAGE, type DocumentLanguage } from '../storage/documentLanguage';
|
||||
@@ -1142,6 +1143,7 @@ function convertDrawing(drawing: Element, ctx: Ctx): Node | null {
|
||||
if (Number.isFinite(rot) && rot) attrs.rotation = ((Math.round(rot / 60000) % 360) + 360) % 360;
|
||||
|
||||
if (anchor) attrs.wrap = anchorWrap(anchor, ctx);
|
||||
else fitInlineImage(attrs, Math.floor(cmToPx(ctx.contentWidthCm)));
|
||||
return { type: 'image', attrs };
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { StyleResolver, NS, lengthToPt, lengthToCm, layerTextProps, type PropMap
|
||||
import { HEADING_STYLE_OVERRIDES, MAX_HEADING_LEVEL, ODF_LOOK_ATTRS, normalizeColor } from '../export/odt';
|
||||
import { builtinStyleSheet, DEFAULT_STYLE, type ParaProps, type Style, type StyleSheet, type TextProps } from '../styles/styleSheet';
|
||||
import { HEADER_SHADE } from '../editor/extensions/tableHeaderRow';
|
||||
import { fitInlineImage } from '../editor/extensions/image';
|
||||
import { formatTabStops } from '../editor/extensions/tabStops';
|
||||
import { TABLE_REGIONS, tableLookAttr, type TableLook, type TableRegion } from '../styles/tableStyles';
|
||||
import { orderedTypeFromFormat, orderedTypeAttrAt, childCycle, ROOT_ORDERED_CYCLE, type OrderedCycle } from '../utils/orderedListTypes';
|
||||
@@ -158,6 +159,7 @@ function convertFrame(frame: Element, ctx: Ctx): Node | null {
|
||||
const title = frame.getElementsByTagNameNS(NS.svg, 'title')[0]?.textContent;
|
||||
if (title) attrs.alt = title;
|
||||
applyFrameRotationAndWrap(frame, attrs, ctx.resolver.graphicProps(frame.getAttributeNS(NS.draw, 'style-name')));
|
||||
if (!attrs.wrap || attrs.wrap === 'inline') fitInlineImage(attrs, Math.floor(cmToPx(ctx.contentWidthCm)));
|
||||
return { type: 'image', attrs };
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user