Files
SmartReports/docs/superpowers/specs/2026-03-20-page1-header-restyle-design.md

7.8 KiB

Design Spec: Page 1 Header Restyle & Label Fixes

Date: 2026-03-20 Status: Approved Scope: AnagraficaSectionRenderer.cs, EventiSectionRenderer.cs, PdfTheme.cs


Overview

Piccolo insieme di modifiche visive e testuali alla pagina 1 del report PDF e alla sezione eventi, senza alterare la struttura generale del report.


1. Nuovo layout header Pagina 1 (AnagraficaSectionRenderer.DrawTitle)

Layout approvato

        Scheda Prodotto   XS1234567890          ← centrato, blu bold, font grande
────────────────────────────────────────────────  ← linea separatrice AccentBlue (2pt)
[TIPOLOGIA / Cert. Bonus Cap] [DATA / 18/03/26] [BID / 98.50] [ASK / 99.20]

Specifiche riquadri (riga inferiore)

Tutti i box hanno la stessa altezza (28pt) e la stessa struttura a due righe:

  • Riga 1: label piccola (9pt, uppercase, bold, colore accent), altezza 11pt
  • Riga 2: valore (13pt bold, colore accent scuro), altezza 17pt

Il padding interno è 5pt verticale, 10pt orizzontale (dopo il bordo sinistro da 4pt).

Box Larghezza Sfondo Bordo sinistro Colore label Colore valore
Tipologia PageW - 3*6 - 84 - 70 - 70 PdfTheme.BoxLightBlueBg PdfTheme.AccentBlue 4pt PdfTheme.AccentBlue PdfTheme.AccentBlueDark
Data 84pt fisso PdfTheme.BoxGrayBg PdfTheme.BoxGrayAccent 4pt PdfTheme.BoxGrayLabel PdfTheme.BoxGrayValue
Bid 70pt fisso PdfTheme.BoxLightBlueBg PdfTheme.AccentBlue 4pt PdfTheme.AccentBlue PdfTheme.AccentBlueDark
Ask 70pt fisso PdfTheme.BoxLightBlueBg PdfTheme.AccentBlue 4pt PdfTheme.AccentBlue PdfTheme.AccentBlueDark

Gap tra box: 6pt.

Nuove costanti da aggiungere a PdfTheme.cs

public static readonly Color AccentBlueDark   = Color.FromArgb(255, 13,  71, 161); // #0D47A1
public static readonly Color BoxLightBlueBg   = Color.FromArgb(255,235,242,251); // #EBF2FB
public static readonly Color BoxGrayBg        = Color.FromArgb(255,245,245,245); // #F5F5F5
public static readonly Color BoxGrayAccent    = Color.FromArgb(255,136,136,136); // #888888
public static readonly Color BoxGrayLabel     = Color.FromArgb(255,102,102,102); // #666666
public static readonly Color BoxGrayValue     = Color.FromArgb(255, 51, 51, 51); // #333333

// Brush corrispondenti
public static readonly PdfBrush BoxLightBlueBgBrush = new PdfSolidBrush(BoxLightBlueBg);
public static readonly PdfBrush BoxGrayBgBrush      = new PdfSolidBrush(BoxGrayBg);
public static readonly PdfBrush BoxGrayAccentBrush  = new PdfSolidBrush(BoxGrayAccent);
public static readonly PdfBrush BoxGrayLabelBrush   = new PdfSolidBrush(BoxGrayLabel);
public static readonly PdfBrush BoxGrayValueBrush   = new PdfSolidBrush(BoxGrayValue);
public static readonly PdfBrush AccentBlueDarkBrush = new PdfSolidBrush(AccentBlueDark);

Font per i box

Riusare i font esistenti in PdfTheme:

  • Label: PdfTheme.Small (9pt) — già esistente
  • Valore Bid/Ask/Data: PdfTheme.Bold (stesso usato altrove)
  • Valore Tipologia: nuovo font PdfTheme.BoldSmall (11pt bold) — aggiungere se non esistente, altrimenti usare font bold a 11pt inline

Implementazione PDF (Syncfusion) — helper DrawInfoBox

Creare un metodo privato in AnagraficaSectionRenderer:

private void DrawInfoBox(PdfGraphics g, float x, float y, float w, float boxH,
    string label, string value,
    PdfBrush bgBrush, PdfBrush accentBrush, PdfBrush labelBrush, PdfBrush valueBrush,
    PdfFont valueFont)
{
    // Sfondo
    g.DrawRectangle(bgBrush, new RectangleF(x, y, w, boxH));
    // Bordo sinistro 4pt
    g.DrawRectangle(accentBrush, new RectangleF(x, y, 4f, boxH));
    // Label (riga 1) — parte dopo il bordo + padding
    float innerX = x + 4f + 6f;
    float innerW = w - 4f - 6f - 4f;
    g.DrawString(label, PdfTheme.Small, labelBrush,
        new RectangleF(innerX, y + 4f, innerW, 11f));
    // Valore (riga 2)
    g.DrawString(value, valueFont, valueBrush,
        new RectangleF(innerX, y + 14f, innerW, 14f));
}

Nota Syncfusion: RectangleF non supporta named arguments — usare sempre la forma posizionale new RectangleF(x, y, w, h).

Gestione casi nulli / vuoti

  • Bid e Ask: se string.IsNullOrEmpty(info.Bid) || string.IsNullOrEmpty(info.Ask), i box Bid e Ask non vengono disegnati; la larghezza liberata viene assorbita dal box Tipologia. Il box Data viene comunque disegnato se LastPriceDate non è vuoto.
  • Data: se string.IsNullOrEmpty(info.LastPriceDate), il box Data viene omesso.
  • Tipologia: se string.IsNullOrEmpty(info.Categoria), il box Tipologia viene omesso; in quel caso i box rimanenti (Data/Bid/Ask) si dispongono da sinistra normalmente.

Troncamento testo Tipologia

Il box Tipologia usa RectangleF con larghezza calcolata. Syncfusion tronca automaticamente il testo che eccede la RectangleF — nessuna logica extra necessaria. Il font 11pt consente fino a ~45 caratteri nella larghezza tipica (~290pt). Per tipologie più lunghe il testo viene tagliato dal renderer PDF senza errori.

Rimozione logica precedente

Il vecchio DrawTitle disegnava:

  • Titolo a sinistra in w * 0.65f + Bid/Ask come stringa a destra in w * 0.35f
  • Tipologia come riga di testo grigio Regular sotto il titolo

Tutta la logica di DrawTitle viene riscritta. Il metodo DrawTitle torna float y (la nuova y dopo il titolo + linea + box row).


2. Rinomina colonne Tabella Sottostanti (AnagraficaSectionRenderer.DrawSottostanti)

Modifica solo le stringhe nell'array degli header:

Vecchio Nuovo
"Barr.K" "Barriera Capitale"
"Buffer K" "Buffer Capitale"
"Trig.CPN" "Trigger Cedola"
"Buf.CPN" "Buffer Cedola"

Le altre colonne (Nome, Strike, Last, % Perf., Trig.AC) rimangono invariate. Le larghezze colonna possono richiedere un piccolo aggiustamento se i nuovi header non entrano — da verificare a runtime.


3. Rinomina colonna Tabella Eventi (EventiSectionRenderer)

Vecchio Nuovo
"Trigger CPN" "Trigger Cedola"

La colonna è alla posizione 4 (0-indexed), larghezza corrente 52pt. "Trigger Cedola" a font Small ha larghezza simile a "Trigger CPN" — la larghezza 52pt è sufficiente, non richiede modifica. Da verificare visivamente dopo il build.


Situazione attuale

Il codice esistente già usa "Powered by " (con spazio finale) come testo di prefisso, e calcola la X del link tramite MeasureString. Il bug visivo è che PdfStandardFont.MeasureString può restituire una larghezza che esclude il trailing space, causando sovrapposizione tra "by" e il link "Smart Roots".

Fix

Aggiungere un offset fisso di 2pt alla X del link, dopo il valore restituito da MeasureString:

// PRIMA:
float prefixWidth = prefixFont.MeasureString(prefixText).Width;
webLink.DrawTextWebLink(g, new PointF(prefixWidth, footerY));

// DOPO:
float prefixWidth = prefixFont.MeasureString(prefixText).Width + 2f;
webLink.DrawTextWebLink(g, new PointF(prefixWidth, footerY));

Files modificati

File Modifica
CertReports.Syncfusion/Helpers/PdfTheme.cs Nuove costanti colore/brush, fix footer offset +2pt
CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs Riscrittura DrawTitle, helper DrawInfoBox, rinomina colonne sottostanti
CertReports.Syncfusion/Services/Implementations/EventiSectionRenderer.cs Rinomina colonna "Trigger CPN" → "Trigger Cedola"

Non in scope

  • Modifiche al grafico, agli scenari, o ad altre sezioni del report
  • Modifiche al DB o alle stored procedure
  • Modifiche al layout delle sezioni A, B del report (Caratteristiche, Analisi)