Portable headless output
With you since version 2.384.100 as a bounded output pipeline with explicit capture and rendering APIs
Capture a supported rectangle from a Classic XLS or XLSX workbook on Windows, transfer the immutable snapshot, then render PDF, SVG or PNG on Linux or macOS with Free Pascal and native Cairo
The capture adapter runs on the workbook engine; Windows capture uses its default geometry service, whilst native Linux and macOS capture can bring an explicit FreeType/HarfBuzz geometry service backed by application-selected font files
The separate native consumer takes lxPortableRender scenes via lxPortableCairo, with no Excel or desktop session in sight; its geometry API likewise uses the existing portable workbook-view and render-geometry units
The consumer takes an immutable scene or transfer stream; platform requirements for loading and calculating workbooks are covered separately in Free Pascal support
Capture an existing workbook rectangle
CaptureXLSPortableRenderSnapshot in lxPortableWorkbookCapture takes an IXLSWorkbook or IXLSXWorkbookOwner with explicit or default TXLSPortableRenderLimits; two further overloads take explicit limits followed by an IXLSRenderGeometry provider scoped to the capture view
SheetIndex and the inclusive Row1, Col1, Row2, Col2 are one-based; the resulting snapshot keeps zero-based positions relative to the captured rectangle
program CaptureRectangle;
{$APPTYPE CONSOLE}
uses SysUtils, Classes, lxHandleX, lxPortableRender,
lxPortableWorkbookCapture;
var
Workbook: TXLSXWorkbook;
Owner: IXLSXWorkbookOwner;
Snapshot: IXLSPortableRenderSnapshot;
Stream: TFileStream;
begin
Workbook := TXLSXWorkbook.Create;
Owner := Workbook;
if Workbook.Open('report.xlsx') <> 1 then
raise Exception.Create('Cannot open report.xlsx');
Snapshot := CaptureXLSPortableRenderSnapshot(Owner, 1, 1, 1, 30, 6);
Stream := TFileStream.Create('report.hxrs', fmCreate);
try
SaveXLSPortableRenderSnapshot(Snapshot, Stream,
XLSDefaultPortableRenderLimits);
finally
Stream.Free;
end;
Owner := nil;
end.
Keep the owner interface alive for as long as you use the workbook object; release the interface rather than manually freeing an interface-owned workbook
For Classic XLS, use TXLSWorkbook and IXLSWorkbook out of lxHandle with the same capture call
Capture reads the existing formula caches and refuses any formula in the rectangle lacking a cache; it never recalculates implicitly, fetches external data or interns new styles in the source workbook
Recalculate explicitly before capture whenever your application needs fresh formula results; an existing cache is rendered exactly as stored, so capture vouches nothing for its freshness
The operation holds a read view and checks the workbook generation before handing back; the returned snapshot is detached from workbook ownership and stays usable once the workbook is released
Appearance and capture boundaries
The snapshot holds formatted display text, physical dimensions in points, resolved RGB colours, supported cell fonts and alignments, fills, borders and complete merged rectangles; hidden rows and columns have zero size
Supported font appearance covers bold, italic, single underline and strikeout; supported cell appearance covers solid fills, left/centre/right horizontal alignment, top/centre/bottom vertical alignment, wrap, shrink and right-to-left reading order
Thin, medium, thick, hair, double, dotted, dashed and medium-dashed workbook borders map onto the portable border styles and point widths; other border styles are refused
Supported rich text carries effective run fonts, point sizes, RGB colours, bold, italic, single underline, strikeout and run-level superscript or subscript; plain cell outline/shadow/vertical font effects, unsupported underline styles, gradient or patterned fills, diagonal borders, indent, text rotation and unsupported alignments are refused
A capture rectangle must take in every merged cell completely; clipped, overlapping or inconsistent merges and incompatible styles along a merged outside edge are refused
Sheet backgrounds and unsupported sheet kinds sink the capture; supported PNG/JPEG images and ordinary rectangle/ellipse text shapes in both workbook facades are captured as ordered scene objects, alongside XLSX cell images, Boolean checkboxes and the supported cached XLSX chart subset described below; unsupported charts, shape presets, WordArt, grouped transforms, floating controls, Slicers, Timelines and sparklines are refused when their resolved footprints intersect the rectangle
Unsupported content with a reliably resolved footprint outside the rectangle can coexist with capture; an unresolvable drawing footprint is refused rather than silently dropping potentially overlapping content
Classic table styling intersecting the rectangle is refused; XLSX built-in and supported custom Table sections are resolved in detached style context, with section-sized stripes and direct cell format overrides
For supported imported Table solid or implicit differential fills, RGB bgColor provides the visible background; RGB fgColor on its own leaves the inherited background alone, and a section carrying both colours uses its background colour
Imported Table sections carrying appearance the typed summary cannot represent are refused when that section applies, underline, number formats, explicitly cleared bold/italic, font schemes, an explicit no-fill pattern and unsupported colour forms included; an unrelated section outside the captured rectangle does not block capture
Supported conditional formatting is applied with no formula evaluation: cached numeric or date comparisons against literal numeric bounds, literal Boolean or numeric expressions, text containment/prefix/suffix rules, blanks and errors; higher-priority appearance wins per supported property, and XLSX StopIfTrue halts lower-priority matching rules
Classic text rules call for a literal string needle and match cached string cells; XLSX text rules work from their stored text criteria
Supported differential appearance covers resolved theme colours with tint and plain indexed colours; imported automatic colours, non-theme tint, a differential fill carrying both foreground and background colours, and unsupported border, alignment, strike or other unrepresented differential appearance are refused when the matching rule applies
Conditional formulas needing evaluation, aggregate or date-dependent rules, colour scales, data bars and icon sets are refused wherever encountered; overlapping conditional-format rule counts are bounded
Date1904 conversion picks the applicable raw numeric-format section before applying the calendar offset; inactive calendar sections leave ordinary numeric display alone, and Boolean values remain Boolean
A selected Date1904 calendar section combined with format conditions or elapsed-time constructs is refused; quoted or escaped section separators are likewise refused, and this boundary does not block a selected ordinary numeric section just because another section happens to be a calendar format
Rich text and ordered drawing scenes
TXLSPortableCell.RichText is an array of TXLSPortableTextRun records holding Text, FontFamily, FontSizePoints, FontStyles, ColorRGB and BaselineShiftPoints; the concatenated run text must match the cell display text exactly
XLSX runs inherit omitted properties from the effective captured cell font, supported table and conditional formatting included; explicitly assigned false flags and explicit none/baseline/automatic colour values override the inheritance
Native shared strings and inline strings preserve run boundaries and whitespace; unsupported native font children, attributes, namespaces, theme/indexed rich colours and phonetic annotations are refused rather than silently losing visible appearance
Classic runs resolve their stored BIFF font indices into full effective run fonts; phonetic metadata and unsupported run fonts are refused, and capture keeps the workbook generation and style pools
Classic text shapes read the existing OfficeArt properties and TXO font runs without creating drawing wrappers or changing the workbook; anchors use real row/column dimensions and offsets, supported solid fills and outlines keep their colours and widths, and embedded PNG/JPEG bytes are detached before transfer
Rectangle text uses the native 7.2pt horizontal and 3.6pt vertical margins; ellipse text additionally works with its inscribed text rectangle, keeping ordinary text inside the shape outline in both workbook facades
Imported Classic rectangle and ellipse containers keep their typed text and formatting; skipped native shape or group metadata with no resolved footprint sinks the capture explicitly, whilst unknown object-tail records, drawing extensions, rotation, non-solid fills and unsupported line styles sink an intersecting object
Imported XLSX two-cell rectangle and ellipse anchors support explicit RGB solid fills with alpha, solid or dashed/dotted outlines, physical anchor offsets and a single ordinary rich-text paragraph; each run keeps its effective typeface, point size, colour, bold, italic, single underline and strikeout, explicit bold or italic resets included
The imported shape reader sets aside raw XML scratch storage before parsing and checks the item, byte and text budgets cooperatively; it keeps workbook drawing order and read leases without creating shape models or absent cells
Unknown native shape properties, effects, themes, rotations, grouped transforms, multiple paragraphs and unsupported anchor kinds are refused explicitly; a resolved unsupported footprint outside the capture rectangle does not block the requested region
Run-level superscript and subscript use two-thirds of the run font size and a baseline shift of one-third of its original point size; a style boundary splitting a Unicode shaping cluster, or a CRLF sequence crossing incompatible run boundaries, is refused during native layout
TXLSPortableSceneObject carries a Kind, point-based X, Y, Width, Height, a clipping rectangle, fill/outline colours and opacity, optional path points, a text cell, or encoded raster bytes and dimensions
TXLSPortableSceneKind contains xpskRectangle, xpskEllipse, xpskPolyline, xpskPolygon, xpskText, xpskPNG and xpskJPEG; array order doubles as drawing order, later objects covering earlier ones
The additional CreateXLSPortableRenderSnapshot overload takes a TXLSPortableSceneObjects array; query IXLSPortableRenderSceneSnapshot for zero-based Objects and ObjectCount, whose getters hand back detached copies including run, point and raster arrays
Cell images and checkbox paths come before floating drawings; floating drawings keep workbook order, physical anchors and viewport clipping, and text shapes use the minor theme font at 11 points with 7.2-point horizontal and 3.6-point vertical text margins
PNG and JPEG images are decoded natively after header, pixel-size and byte preflight; supported floating images keep transparency and stretch geometry, whilst cell images fit inside the cell or complete merged rectangle with their aspect ratio preserved
Crop, rotation, shadows, luminance/gamma adjustment, tiling, SVG companions and live camera bindings stay unsupported; preserved image XML is validated against the supported appearance, so hidden images, unknown nested metadata, foreign namespaced properties, nonrectangular image geometry and unmodelled transforms are refused only where their footprint overlaps capture
Boolean cell checkboxes use a theme-neutral vector box and optional check mark, effective controls inherited from row and column formats included; the requested cell walk is bounded before traversal, other control kinds and blank or non-Boolean checkbox values are refused, and supported cell scenes suppress scalar Boolean or image-error fallback text
A checkbox default counts as insertion metadata and manufactures no Boolean for an absent cell; explicit direct-cell control clearing masks an inherited control, whilst capture reads preserve sparse absence and the workbook generation
XLSReadPortableImageDimensions validates a bounded PNG IHDR or a supported eight-bit sequential/progressive JPEG frame and hands back its declared width and height; decoding stays the renderer's responsibility
IXLSPortableSceneCaptureSource.ReadPortableSceneObjects works in one-based workbook coordinates and point-based scene coordinates relative to the range, validates the range and cooperative limits, and returns consumed byte, text and item counts; HasPortableCellScene picks out cells whose scalar display is replaced by their captured scene
Native layout CellCount counts grid cells and LineCount also takes in text scene objects; a text object's line CellIndex comes out as CellCount plus its zero-based sequence among text scene objects, whilst GetCellGeometry stays restricted to grid cells
Scalar snapshots continue to serialise as HXRSNP01; snapshots carrying runs or scene objects serialise as HXRSNP02, and the loader takes both versions with the same immutable ownership and input-position rollback contract
The combined item budget covers stored cells, rich runs, scene objects and path points; byte limits take account of staged and detached arrays, text, encoded raster payloads and bounded native metadata inspection before allocation
Portable snapshot API
| Symbol | Contract |
|---|---|
EXLSPortableRender | Exception raised for invalid snapshot data, unsupported capture appearance, an unavailable native backend, resource limits or rendering failures |
TXLSPortableFontStyle, TXLSPortableFontStyles | xpfsBold, xpfsItalic, xpfsUnderline and xpfsStrikeout, combined as a set |
TXLSPortableHorizontal, TXLSPortableVertical | xphLeft, xphCenter, xphRight and xpvTop, xpvCenter, xpvBottom |
TXLSPortableBorderStyle, TXLSPortableBorder | xpbsNone, xpbsSolid, xpbsDashed, xpbsDotted and xpbsDouble; each border carries Style, WidthPoints and ColorRGB |
TXLSPortableCell | Zero-based Row/Column, positive RowSpan/ColumnSpan, display Text, FontFamily, FontSizePoints, FontStyles, TextColorRGB, FillColorRGB, HasFill, WrapText, ShrinkToFit, RightToLeft, Horizontal, Vertical and four LeftBorder/TopBorder/RightBorder/BottomBorder records |
TXLSPortableCells, TXLSPortableSizes | Dynamic arrays of the stored cells and physical row/column sizes in points |
TXLSPortableRenderLimits | MaxGridCells, MaxStoredCells, MaxBytes and MaxTextCharacters bound construction, capture and serialisation |
XLSDefaultPortableRenderLimits | Hands back 2000000 grid cells, 2000000 stored cells, 67108864 bytes and 16777216 UTF-16 text characters |
XLSDefaultPortableCell | Initialises a one-cell span with Calibri at 11 points and default zero-valued appearance; set its position and desired appearance before construction |
CreateXLSPortableRenderSnapshot | Validates and copies generation, row heights, column widths and stored cells into a detached immutable interface; cells must be unique, in row-major order, within bounds and carry nonoverlapping spans |
IXLSPortableRenderSnapshot | Read-only Generation, RowCount, ColumnCount, CellCount, zero-based RowHeightPoints and ColumnWidthPoints, and copied Cells records |
| Snapshot getter methods | GetGeneration, GetRowCount, GetColumnCount, GetCellCount, GetRowHeight, GetColumnWidth and GetCell expose the same values; invalid indexed access raises an exception |
SaveXLSPortableRenderSnapshot | Validates and serialises one snapshot to a bounded private buffer, then copies the complete HXRSNP01 or HXRSNP02 payload into the supplied stream at its current position |
LoadXLSPortableRenderSnapshot | Reads the versioned little-endian snapshot with strict UTF-8 text, validates counts, geometry, styles and spans and refuses trailing data; failure restores the input stream position |
Every limit must be positive; the validated maximum is 2000000 grid/stored cells, 1073741824 bytes and 268435456 text characters, with dimensions no bigger than 1048576 rows by 16384 columns
MaxGridCells counts the entire rectangle, unstored blank cells included; CellCount counts stored visible cells and merged anchors, and may come out smaller
Generation records the source generation or an application-supplied value; it is metadata, not a live link to a workbook nor an automatic freshness check
Native rendering and explicit fonts
XLSPortableCairoBackendAvailable reports whether the compiled native backend is available; native output needs Free Pascal on Linux or macOS, with the Cairo, FreeType, HarfBuzz and FriBidi libraries available to the process
macOS builds link the four native libraries explicitly; a private dependency prefix and an explicit child-process loader path can supply them without touching shared compiler settings or shell profiles
Windows Delphi XE5, Win32 and Win64 can compile the portable interfaces and use snapshot serialisation, but native Cairo layout preparation reports backend unavailability there
Pass an explicit font chain to PrepareXLSPortableCairoLayout; the renderer first tries the matching family and bold/italic style, then same-style fallbacks in the supplied order, demanding glyph coverage for each supported text cluster
Supply the actual regular, bold, italic and bold-italic files your captured content calls for; there is no system-font discovery or synthetic bold/italic substitution, and missing files, style mappings or glyph coverage are refused
Font bytes are captured before shaping, so altering a file affects later layouts whilst an existing layout keeps its captured bytes; FaceIndex selects the nonnegative face in a font file or collection
Native operations are serialised for FreeType face safety; immutable snapshots and prepared layout inspection need no live workbook
Fonts[0].FamilyName := 'Calibri'; Fonts[0].FileName := '/srv/fonts/Regular.ttf'; Fonts[0].FaceIndex := 0; Fonts[0].Bold := False; Fonts[0].Italic := False;
Here Calibri is an explicit family alias for the chosen file, permitting an application-controlled font mapping; inspect the output metrics when mapping to a different font
The renderer handles hard line breaks, four-space tab expansion, paragraph bidirectional ordering, shaped ligatures and combining marks, greedy wrapping and shrink-to-fit; wrap wins over shrink
Wrapping preserves the implemented combining-mark, variation-selector, ZWJ and virama cluster boundaries and favours spaces and ideographic spaces; it is not a complete UAX #29 grapheme implementation nor a Unicode line-breaking algorithm, and regional-indicator and Hangul-Jamo wrapping boundaries come with no guarantee
Font sizes resolve to 1/64 point and text clips to the cell bounds; PDF embeds the explicit fonts with logical text mappings, SVG uses vector glyph paths, and PNG draws those same positioned glyphs at the requested DPI
Prepare and inspect a layout
| Symbol | Contract |
|---|---|
TXLSPortableFontFile, TXLSPortableFontFiles | One explicit mapping holds FamilyName, FileName, FaceIndex, Bold and Italic; the dynamic array is ordered and carries between 1 and 64 mappings |
TXLSPortableCairoFormat, TXLSPortableOutputFiles | xpcfPDF, xpcfSVG or xpcfPNG, plus an array of output filenames handed back by file save |
TXLSPortableCairoOptions | Page width/height, four margins, cell padding and raster DPI, together with page, glyph, line, layout, output, font, shaping and drawing limits |
XLSDefaultPortableCairoOptions | Initialises every option with bounded defaults; use it before overriding individual fields |
PrepareXLSPortableCairoLayout | Validates and copies a snapshot, captures the explicit font bytes and returns an owned prepared TXLSPortableCairoLayout; release it with Free |
TXLSPortableCairoLayout | Exposes PageCount, LineCount, CellCount, GetTextLine, GetCellGeometry, SaveToStream, Save and Destroy |
TXLSPortableTextLineInfo | A copied line record carries CellIndex, GlyphCount, XPoints, BaselinePoints, WidthPoints, FontSizePoints and logical Text |
TXLSPortableCellGeometry | A copied rectangle carries XPoints, YPoints, WidthPoints and HeightPoints in the full layout |
GetTextLine(Index), GetCellGeometry(Index) | Zero-based indexed inspection of prepared lines and stored cells; invalid indices are refused |
Pagination clips fixed printable-area tiles in across-then-down order; a cell or text fragment crossing page boundaries shows up on every intersecting page, with no automatic whole-cell fitting, worksheet print-title repetition or workbook page-setup interpretation
Renderer options and bounds
| Fields | Defaults and meaning |
|---|---|
PageWidthPoints, PageHeightPoints | 595 by 842 points |
MarginLeftPoints, MarginTopPoints, MarginRightPoints, MarginBottomPoints | 36 points each; the margins must leave a positive printable rectangle |
CellPaddingPoints, RasterDPI | 2 points and 96 DPI; DPI shapes PNG dimensions |
MaxPages, MaxGlyphs, MaxLines | 256 pages, 2000000 shaped glyphs and 200000 text lines |
MaxLayoutBytes | 268435456 bytes for bounded layout work and raster surface checks |
MaxOutputBytes | 268435456 bytes per rendered output buffer, covering the whole PDF or one SVG/PNG page rather than the sum of separate page files |
MaxFontBytes | 134217728 bytes across explicit font input files for a layout |
MaxShapedCharacters, MaxDrawOperations | 16000000 each, bounding shaping work and page-by-cell drawing work |
Invalid or non-finite geometry and nonpositive work budgets are refused; page dimensions are capped at 100000 points and raster DPI at 1200, with further byte, count and raster-area checks before rendering
The native process-wide font-byte pool additionally allows no more than 256 distinct buffers and 256 MiB; exactly identical bytes may share storage, and capacity is released only when the actual Cairo-owned font face lets go of its buffer
Free each layout once finished; the library does not reset shared Cairo caches, and a logically completed layout may leave font bytes resident whilst native Cairo still owns a face
Write output and handle failures
SaveToStream(Stream, Format, PageIndex = 0) writes every page for PDF, requiring PageIndex = 0; SVG and PNG write the selected zero-based page
Snapshot serialisation and native rendering complete in private bounded buffers before copying to the destination stream; validation or render failures leave it intact, but a caller stream write failure can leave partial bytes and follows that stream's own failure behaviour
Save(FileName, Format) writes one PDF file or one SVG/PNG file per page and hands back their paths; multipage filenames insert -0001, -0002 and later suffixes before the extension
Existing file or directory destinations are refused; each save stages every page, publishes exclusive new destinations and removes its own staged/published outputs on failure
The filesystem has to support the native exclusive staging and link publication operations; separate PDF, SVG and PNG saves are separate operations and form no combined transaction
Standalone Linux consumer
Tests/Portable/RenderPortableSnapshot.pas is a complete consumer that loads a snapshot, prepares one layout and saves all three formats; build it on Linux with the portable units and native libraries in place
fpc -Mdelphiunicode -Fu/path/to/HotXLS/Lib RenderPortableSnapshot.pas ./RenderPortableSnapshot report.hxrs /srv/output/report fonts.tsv 595 842 96
fonts.tsv is UTF-8 text carrying four tab-separated fields per mapping: family alias, absolute Linux font path, face index and one of regular, bold, italic or bolditalic
Calibri /srv/fonts/Regular.ttf 0 regular Calibri /srv/fonts/Bold.ttf 0 bold Calibri /srv/fonts/Italic.ttf 0 italic Calibri /srv/fonts/BoldItalic.ttf 0 bolditalic
Use genuinely installed or application-supplied font files, and pick a new output base since existing destination files are refused; include extra same-style fallbacks for scripts the first mapping does not cover
Stream := TFileStream.Create('report.hxrs', fmOpenRead or fmShareDenyWrite);
try
Snapshot := LoadXLSPortableRenderSnapshot(Stream,
XLSDefaultPortableRenderLimits);
finally
Stream.Free;
end;
Options := XLSDefaultPortableCairoOptions;
Layout := PrepareXLSPortableCairoLayout(Snapshot, Fonts, Options);
try
Files := Layout.Save('/srv/output/report.pdf', xpcfPDF);
Files := Layout.Save('/srv/output/report.svg', xpcfSVG);
Files := Layout.Save('/srv/output/report.png', xpcfPNG);
finally
Layout.Free;
end;
Cached chart recording
XLSRecordCachedChartScene in lxPagination records the existing chart layout renderer's point-based primitives into an immutable portable scene form; its source has to be a detached TXLSXChart that owns no worksheet and carries no preserved native XML, so recording cannot resolve worksheet references or refresh workbook caches
The current subset supports column, bar, line, scatter, pie, doughnut and ordinary single-series area charts with one primary plot group, finite numeric value caches and strictly increasing bounded cache indices; scatter category caches hold numeric X coordinates, whilst the other families use stored category labels
Column, bar, line and area value caches must carry contiguous zero-based indices; sparse category value gaps are refused, and recording never expands missing indices into a large array
Bar plots keep horizontal geometry and categorical labels; pie and doughnut plots use category legends, honour FirstSliceAng and HoleSize and omit numeric axes, whilst ordinary single-series area plots keep a filled polygon around the zero baseline
Line and scatter series support independent line visibility, explicit RGB colour and point width via LineVisible, LineColorRGB and LineWidthPoints; LineStyleSet, LineColorSet and LineWidthSet tell explicit settings apart from inherited defaults, and EffectiveLineVisible resolves the existing fill-only series convention
Markers support the automatic circle, an explicit circle or no marker at all; an explicit MarkerSize from 2 through 72 fixes its point diameter, and MarkerFillSet and MarkerBorderSet tell an explicit black RGB value of zero apart from automatic colour selection; connecting segments are painted before opaque data markers
Explicit marker borders lacking a stored width use the ordinary 0.75-point line, whilst legend samples cap circle diameter at 6 points; requested title fonts are written on the actual rich-text run as well as its default text properties, keeping their visible size, colour and emphasis when Excel exports the chart
Unsupported chart families, stacked or multiple-series area plots, multiple-series circular plots, gallery styles, rounded corners, secondary or combined plot groups, date axes, custom number formats, logarithmic axes, custom crossing behaviour, rotated text, trendlines, error bars, hierarchical categories, data labels, other marker shapes and missing value caches raise EXLSPortableRender before rendering
Custom value-axis tick fonts, minor grids, explicit major/minor units, invalid explicit series colours and unsupported axis positions are refused; bar legends currently demand the ordinary right-hand placement, and circular plots demand a finite nonzero cached total and bounded geometry with an early conservative reservation for arc scratch storage
The returned array keeps primitive drawing order, explicit colours, fonts, text alignment, opacity and chart clipping bounds; item, byte and text accounting includes conservative renderer scratch reservations, and cooperative cache checks come before scratch array allocation
XLSValidateCachedChartSceneModel runs the same bounded cache and appearance preflight on a model without resolving worksheet cells; the XLSX capture bridge uses this check before cloning and records supported authored chart models with local one-dimensional A1 references, physical native anchor offsets, range clipping and drawing order
The platform-neutral recorder lives in lxPortableChart; the existing lxPagination entry points share the same layout and primitive recording bodies, keeping the Windows renderer's behaviour and matching immutable scene bytes and budget accounting for each supported family
Native Linux and macOS Workbook capture uses the explicit geometry overload described below; imported series RGB fill, plot-area background, chart background and chart border are recovered from their own namespace-resolved shape properties so that a nested series colour cannot overwrite the plot background
Imported preserved ChartML is taken only when its namespace-expanded element, attribute and significant-text stream match the supported typed reconstruction; namespace aliases and attribute order normalise, whilst unmodelled native extensions, foreign attributes and unsupported appearance are refused conservatively
Raw XML and reconstruction scratch budgets are checked before any cloning and projection work; only the detached copy clears its validated preserved XML, and the source keeps native metadata, cell storage, cache contents and generation
Capture walks the underlying OfficeArt drawing order, chart frames absent from the public Shapes wrapper included, and refuses an intersecting unsupported frame rather than silently omitting it
Classic cached charts with declared appearance
Classic BIFF8 capture supports the seven ordinary chart families above where their core records, local stored values, explicit linear scales and appearance are representable; it reads retained records and available formula caches without evaluating formulas, expanding sparse storage or cloning compiled formula trees
Use TXLSWorkbook.CreateReadOnlyViewWithChartAppearance(Source, Limits, Geometry) to create a separate read-only view with a frozen set of TXLSClassicChartAppearanceDeclaration values supplied by IXLSClassicChartAppearanceSource; Geometry is optional on Windows and provides explicit native font measurements on Linux or macOS
TXLSClassicChartAppearanceDeclarations is the dynamic array of primitive declarations an application can use to implement that source
Pass that configured view to CaptureXLSPortableViewRenderSnapshot(View, SheetIndex, Row1, Col1, Row2, Col2, Limits); coordinates are one-based and the adapter restores the caller's active worksheet once capture finishes or refuses
The ordinary capture entry points still refuse unresolved effective Classic layout or legend fonts; the distinct view entry point uses the already frozen declarations and geometry provider
| Declaration member | Contract |
|---|---|
Generation, SheetIndex, ObjectId | The pinned workbook generation, one-based worksheet index and the actual stored chart object identity; stale generations, missing or repeated identities and identities belonging to another object are refused |
HasChartSize, ChartWidthPoints, ChartHeightPoints | An explicit finite positive chart-frame size in points; it keeps the stored anchor origin and drawing order, whilst a false flag sticks with the anchor-derived dimensions |
HasPlotInnerRectangle, PlotInnerRectangle | An explicit inner plotting rectangle leaving out labels and axis titles; it is required on this declared appearance path |
HasTitleRectangle, TitleRectangle | An explicit title rectangle where the chart has a title; source text, font family, emphasis and colour still come from validated core records |
HasLegendRectangle, LegendRectangle | The declared legend bounds when a legend is present |
HasLegendFontSize, LegendFontSizePoints | The caller's explicit effective point size for a present legend; core font family, emphasis and colour are retained |
TXLSPortableChartRectangle | Left, Top, Width and Height are finite points relative to the captured chart frame; active rectangles call for positive dimensions within that frame |
Count, GetCount, ReadDeclaration | The source reports a bounded count and hands back one primitive record for each zero-based index whilst the view is configured; declarations are copied before later capture |
These values are caller-declared appearance, not automatic Excel layout nor inferred font scaling; obtain them from an independently checked source or an application-defined layout and review the output with the explicit native font mapping used for rendering
Explicit frame dimensions and inner plotting bounds must leave sufficient room for the validated axis-label fonts; insufficient label space is refused rather than clipping text or applying a fitted scale factor
Applications keep the workbook owner alive until the view is released; the borrowed view holds a read lease and keeps the declaration source, whilst the resulting immutable snapshot retains neither the workbook nor the provider
Supported core projection takes in literal solid fills, visible solid lines, circle markers, title and legend text, category placement and bounded explicit numeric ticks; automatic scales, unresolved automatic marker appearance, smoothing, unknown rich extensions, foreign or nonlinear series references and unrepresented point styles are refused before output
Declaring geometry or a legend size authorises no ignoring of unknown chart extensions or unvalidated styles; byte, text, stored-cell and scene limits remain effective for retained source data, declarations, detached caches and recording scratch space
The additional XLSValidateCachedChartSceneModel and XLSRecordCachedChartScene overloads take TXLSCachedChartSceneAppearance for a detached model; initialise it with XLSDefaultCachedChartSceneAppearance before setting explicit controls
The lower-level XLSReadClassicChartScene in lxClassicChartScene hands back a caller-owned detached TXLSXChart plus primitive appearance and budget counters from a retained TXLSCustomChart, its exact source calculator and a leased TXLSClassicChartSceneSource; free the returned model after recording
TXLSClassicChartSceneSource.ReadAppearance supplies a primitive declaration, ReadCell reads bounded pinned local stored values, ReadFont fills the supplied text style with bounded effective core font data, and PaletteColor resolves explicit stored palette entries; application implementations must preserve the pinned source and honour every supplied byte and character quota
| Scene appearance member | Meaning |
|---|---|
SeriesMarkerSizePoints | Bounded per-series point diameters, fractional values included; zero keeps the model's marker size and a nonzero override must run from 2 through 72 points |
OverrideBorder, BorderColorRGB, BorderWidthPoints | Explicit chart-frame outline appearance |
AxisColorRGB, TickColorRGB, GridlineColorRGB, AxisWidthPoints, TickWidthPoints, GridlineWidthPoints | Explicit axis, tick and major-grid paints and point widths |
AreaFillOpacity, SeriesFillAlpha | Area opacity and series fill alpha |
UseAxisTickControls, CategoryBetween | Validated explicit axis controls and categorical placement |
TitleOffsetXPoints, TitleOffsetYPoints | Finite offsets applied to the recorder's ordinary title position |
OverridePlotInnerRectangle, OverrideTitleRectangle, OverrideLegendRectangle, PlotInnerRectangle, TitleRectangle, LegendRectangle | Literal point rectangles relative to the chart frame |
PieRadiusRatio | Circular-plot radius as a bounded fraction of the smaller plot dimension |
Chart primitives follow HotXLS's existing layout policy; chart gallery appearance relying on Excel's unmodelled defaults remains an explicit unsupported boundary
Direct native workbook capture
CreateXLSPortableCairoRenderGeometry(Fonts, Calibration, Generation, Backend, Options, CacheCapacity) returns an IXLSRenderGeometry backed by the same explicit font files, FreeType, HarfBuzz and text shaping that native output uses; column widths come from actual measured maximum-digit width with the workbook calibration
The provider owns detached font bytes and a bounded metric cache, checks font and layout budgets before allocation and validates measurement requests before changing cached state; a full cache can still return uncached measurements without expanding beyond its capacity
Capture verifies that the provider generation and every calibration field match the current read-only workbook view, retains the provider for that view and leaves the workbook's default geometry factory unchanged; ordinary default native geometry stays an explicit GDI boundary
Capture the generation through an explicitly released view before creating the provider; holding on to a temporary interface result can keep its read lease alive until the surrounding scope ends
View := Owner.CreateReadOnlyView; Generation := View.Generation; View := nil; Geometry := CreateXLSPortableCairoRenderGeometry(Fonts, Workbook.CaptureRenderCalibration, Generation, xlsrgbBitmap, XLSDefaultPortableCairoOptions, 4096); Snapshot := CaptureXLSPortableRenderSnapshot(Owner, 1, 1, 1, 30, 6, XLSDefaultPortableRenderLimits, Geometry);
Native consumers compile with LX_PORTABLE_CORE and the corresponding native dependencies; Windows calls to the native Cairo geometry factory are refused explicitly, whilst Windows capture can use its existing geometry factory through the same scoped overloads
Actual native capture supports the modelled scalar, rich-text, supported raster, ordinary shape and seven cached chart families described above; chart capture preserves the original imported ChartML, cached points, sparse cell storage, packed storage and Workbook generation
For immutable print areas, margins, fit or percentage scaling, repeated titles, manual breaks and whole-cell or merged-cell pagination, see portable print plans
Advanced capture bridge
IXLSRenderCaptureSource in lxSemanticSnapshot is the internal coordination interface implemented by supported read-only workbook views; ordinary applications ought to call the owner-based capture overloads
TXLSClassicReadOnlyWorkbookView and TXLSXReadOnlyWorkbookView implement IXLSRenderCaptureSource, the eight render methods below included; these classes coordinate capture through read-only views, and the adapter manages their lifetime whilst applications retain their workbook owner interface and call CaptureXLSPortableRenderSnapshot
Their existing TryReadCell method supplies a stored-cell snapshot through the read-only view; the render methods add detached appearance and geometry on top for portable capture
| Member or helper | Purpose |
|---|---|
ValidateRenderRange | Checks one-based rectangle bounds and unsupported appearance footprints ahead of capture |
ReadRenderStyle | Returns detached TXLSSemanticCellStyle metadata plus a rich-text presence flag for a one-based cell |
IXLSRenderRichTextCaptureSource, ReadRenderRichText | Optional view extension returning bounded detached TXLSRenderTextRuns; each TXLSRenderTextRun contains Text and an effective semantic Style, using the supplied base style and positive run/byte quotas without materialising cells or modifying style pools |
RenderRowHeightPoints, RenderColumnWidthPoints | Return physical geometry, collapsing hidden dimensions to zero |
IXLSRenderGeometryCaptureSource, SetRenderCaptureGeometry | Optional view extension keeping an explicit provider only after generation and calibration validation; invalid providers leave the retained view provider unchanged |
ReadRenderMerge | Reports the complete inclusive one-based merge rectangle holding a cell |
ResolveRenderColor | Resolves semantic theme/indexed/RGB appearance to a portable RGB colour, using the supplied default where supported |
RenderDate1904, RenderRightToLeft | Expose workbook date-system and sheet reading-order context |
XLSRenderCaptureLiteral | Recognises the supported literal Boolean, finite number or simple quoted text subset for capture without evaluation |
XLSRenderCaptureIntersects | Tests whitespace-separated local A1 ranges against a one-based rectangle, refusing unresolved range syntax |
XLSRenderCaptureCondition | Evaluates the supported condition subset against an existing scalar; comparison operator codes 1 to 8 mean between, not-between, equal, not-equal, greater, less, greater-or-equal and less-or-equal |
XLSRenderCaptureApplyDxf | Applies supported detached differential appearance with an AppliedSlots mask to retain higher-priority formatting |
TXLSDxfStyle._MarkRenderUnsupportedAppearance, TXLSDxfStyle._HasRenderUnsupportedAppearance | Internal-prefixed import coordination methods record and inspect appearance the typed differential model cannot render safely; Assign keeps the marker, and capture refuses a marked matching style |
These bridge helpers can raise EXLSSemanticSnapshot; the public capture adapter turns that exception into EXLSPortableRender