# Historial de cambios

Este documento resume la evolución de LL-Dominus a partir del historial de Git.
Los cambios confirmados se agrupan por hito estable y se identifican mediante su
hash abreviado para mantener la trazabilidad.

## En desarrollo

- Todos los fragmentos de un texto LL12 dividido 1:N usan en Xailer la misma
  primitiva de dibujo y el mismo origen vertical, aunque un fragmento contenga
  una sola línea o desaparezcan líneas opcionales.
- `Uneraseable=False` elimina también párrafos compuestos solo por espacios,
  como los campos `CHAR` rellenados por XBase, sin alterar la métrica global.
- Los grupos 1:N que suprimen líneas opcionales compactan únicamente ese flujo
  con la métrica GDI de LL12; los grupos sin líneas suprimidas no cambian.

### Importación de etiquetas LL12

- Los fondos transparentes de tablas ya no aparecen negros en el diseñador;
  Harbour evalúa las fórmulas de color de borde y fondo de las celdas, y el
  empaquetado Xailer enlaza por defecto la librería Engine actual.
- El renderer Xailer calibra las métricas tipográficas de LL12 y reutiliza el
  mismo tamaño efectivo para dibujar y calcular el avance vertical, evitando
  textos ligeramente sobredimensionados y encabezados recortados.
- Los textos multilínea con `Spacing.Line=0` usan también el avance vertical
  LL12 en Xailer, sin recurrir al interlineado automático más amplio de
  `TextRect`; los bloques divididos 1:N conservan así todas sus líneas.
- La altura de línea de los textos 1:N se calcula desde la fuente y el
  interlineado LL12, sin repartir sobre la última parte el espacio vertical
  sobrante del objeto. Xailer consume esa métrica explícita.
- Xailer dibuja cada línea del flujo en su coordenada calculada mediante
  `TextOut`, evitando que `TextRect` vuelva a introducir su interlineado GDI
  interno después de la composición.
- La primera familia de certificación visual corrige de forma transversal los
  colores LL12 calculados por fórmula, la alineación de textos ajustados, los
  rellenos avanzados de rectángulos redondeados y la salida silenciosa de
  imágenes ausentes. PHP y Xailer conservan ahora el mismo contrato visual.
- La certificación completa del corpus deja los 278 contenidos únicos en verde:
  0 propiedades `NOT_VERIFIED`, 0 propiedades silenciosas, 0 objetos perdidos
  y 0 objetos sin modelo. La suite de auditoría alcanza 74/74 casos.
- Se incorpora una comparación visual automatizada de los 41 objetos LL12 ID
  10/11, con informe JSON, galería HTML y captura reproducible. La validación
  geométrica y semántica final queda en 41/41 sin diferencias.
- Los crosstabs ID 11 conservan estilos de filas, columnas y celdas, rellenos,
  opacidad, bordes, alineación, padding, formato de salida y visibilidad de
  totales tanto en PHP como en Harbour/Xailer.
- Los objetos LL12 ID 10 se importan como `TFormattedText`, conservan runs RTF,
  fórmulas y estilos, y se renderizan y paginan en PHP y Harbour/Xailer.
- Los objetos LL12 ID 11 se importan como `TChart`: gráficos de barras, líneas
  y sectores y tablas pivote se generan desde los datos en PHP y
  Harbour/Xailer. Las agregaciones de crosstab se calculan una sola vez.
- La auditoría activa queda sin propiedades `NOT_VERIFIED`, sin propiedades
  silenciosas y sin objetos perdidos o sin modelo.
- El interlineado LL12 (`Spacing.Line`) conserva sus puntos adicionales sobre
  el tamaño real de la fuente, sin sumar el antiguo factor base de `1,15`.
  Diseñador, HTML, paginadores PHP/Harbour y Xailer usan ahora la misma medida.
- Los textos LL12 con varios estilos ya no reparten toda la altura del objeto
  proporcionalmente entre sus bloques. El importador posiciona cada cambio de
  estilo con el tamaño de fuente y `Spacing.Paragraph`, evitando huecos
  artificiales entre razón social, NIF, dirección y bloques equivalentes.
- `Spacing.Paragraph` dispone de la propiedad común `nParagraphSpacing`, se
  conserva en JSON/IR y se aplica exclusivamente entre párrafos en el
  diseñador y los renderizadores HTML/Xailer, sin alterar las líneas creadas
  por el ajuste automático.
- `Uneraseable` se importa como `lKeepEmptyParagraphs`; PHP y Harbour conservan
  o suprimen los párrafos vacíos después de evaluar la fórmula.
- `bPageWrap` activa `lAllowPageBreak` a nivel de objeto y reutiliza la
  paginación real existente en PHP y Harbour.
- `SpaceOptimization` se importa como `lTrimSpaces` y aplica `trim`/`AllTrim`
  al resultado evaluado en PHP y Harbour.
- `Adjusted` se importa como `lTextAdjusted` y conserva la justificación
  completa en diseñador, HTML y Xailer.
- Los textos LL12 divididos 1:N conservan metadatos de flujo. Cuando
  `Uneraseable=False`, PHP y Harbour eliminan los fragmentos vacíos y recolocan
  únicamente los siguientes fragmentos del mismo texto.
- Las plantillas de una sola etiqueta (`1 × 1`) destinadas a papel continuo ya
  no conservan por error el formato físico A4 guardado por List & Label. El
  papel se ajusta al tamaño de la etiqueta más sus márgenes; por ejemplo, una
  etiqueta de `94 × 94 mm` con `2 mm` de margen izquierdo genera un papel
  personalizado de `96 × 94 mm`.
- Se añade la conversión de `Left$()` a `Left()` y de `ProjectPath$()` a
  `ProjectPath()`, conservando la función de contexto en vez de eliminarla. La
  función devuelve el directorio de la plantilla o su ruta completa cuando
  recibe `TRUE`.
- Se implementan `ProjectPath()`, `Sum()`, `Hour()`, `Contains()` y
  `AskString()` tanto en PHP como en Harbour. `Sum()` acumula la expresión hasta
  el registro actual y `Hour()` admite una fecha/hora opcional o utiliza la hora
  de impresión. `AskString()` obtiene respuestas del contexto de ejecución y
  usa el valor propuesto cuando no hay una respuesta configurada.
- `TLLEngine` y `TLLDominusPrintJob` detectan las variables de usuario cuya
  fórmula contiene `AskString()`, devuelven sus parámetros —incluido el valor
  predeterminado— y permiten que Xailer entregue la respuesta antes de ejecutar
  mediante `SetAskStringValue()`.
- `TLLDominusPrintJob` resuelve automáticamente esas entradas mediante un
  diálogo Xailer moderno coherente con el progreso de impresión. Precarga el
  valor predeterminado, aplica la longitud máxima, admite respuestas ya
  suministradas y cancela limpiamente el trabajo si el usuario cancela.
- El runtime acepta referencias heredadas de LL12 como `@User03` aunque la
  variable se almacene como `VAR.User03`, sin distinguir mayúsculas. También
  reconoce directamente `Mid$()` y `Chr$()` en plantillas ya convertidas; las
  nuevas importaciones las normalizan a `SubStr()` y `Chr()`.
- El renderizador Xailer aplica el color directamente a `TCanvas:FillRect()`,
  recuperando de forma general los fondos de tablas, cabeceras, pies y demás
  rectángulos rellenos. Esto evita que los textos blancos de las cabeceras
  desaparezcan y que solo queden visibles los separadores de columnas.
- El importador conserva el relleno LL12 de cada celda tanto en la estructura
  de la tabla como en su objeto `TText`, por lo que el diseñador muestra el
  color real de las cabeceras. La lectura de booleanos LL12 admite además
  `True`, `.T.`, valores numéricos distintos de cero y sus variantes textuales.
- La importación de tablas reconoce todos los colores `LL.Color.*` usados por
  las plantillas existentes, conserva los patrones de filas alternas y omite
  las columnas LL12 de ancho cero en lugar de convertirlas en columnas
  visibles. Los rectángulos importan también su valor `Rounding` y el
  renderizador Xailer dibuja el porcentaje de redondeo incluso cuando el fondo
  es transparente.
- El porcentaje `Rounding` se interpreta como lo define List & Label: respecto
  al lado corto y con `100 %` equivalente a media arista. La corrección se
  aplica de forma común al diseñador, HTML, tablas y al renderizador Xailer,
  evitando esquinas con el doble de radio.
- Las líneas LL12 respetan `LineDirection` en vez de deducir su orientación por
  un ancho o alto cero. Esto elimina las rayas horizontales espurias y conserva
  también las diagonales ascendentes y descendentes.
- Los objetos `Datamatrix` generan ahora una matriz ECC200 real en PHP y
  Harbour/Xailer. El patrón anterior basado en un hash, que no era escaneable,
  deja de utilizarse para este tipo; el contenido del albarán se codifica y se
  entrega al renderizador como parte del documento intermedio.
- `TLLDominusPrintJob` deja de sobrescribir el fichero LL12 original al
  convertirlo para un trabajo. La conversión se mantiene en memoria y el
  diseñador solo persiste el resultado en `cDesignerOutputFile`; así las
  ejecuciones posteriores vuelven a detectar el formato antiguo y pueden
  aplicar las correcciones actuales del importador.
- El diseñador envía el nombre de la plantilla al validar fórmulas y el catálogo
  de funciones marca las cinco funciones como probadas y disponibles.
- Se incorporan pruebas de regresión para el tamaño del papel continuo, sin
  alterar la importación de hojas multietiqueta, y para las funciones importadas
  desde LL12.

## Hitos estables

### 2026-07-21

- `40553b1` — Importación desde Xailer de List & Label y Beta 2 de integración
  Dominus. Este hito unifica el runtime PHP, amplía la compatibilidad de
  plantillas e importación LL12 y mantiene la paridad con Harbour/Xailer.

#### Motor y runtime PHP

- Se ha creado `TRuntimeEjecucionPHP` como coordinador único de la ejecución del
  motor, la composición de páginas, la paginación previa y la construcción del
  `TDocumentoRenderizable`.
- `TLLDominusPHP`, `public/motor/index.php`, `public/motor/preview.php` y
  `export_ir.php` pasan a utilizar el runtime común, evitando ejecuciones y
  responsabilidades duplicadas.
- `TLLDominusPHP` incorpora `RunEngine()` y expone los avisos y objetos
  descartados producidos por el motor. La vista previa queda limitada al
  renderizado del documento ya ejecutado.
- Se simplifica `TPreviewPHP`: deja de coordinar el motor y actúa como adaptador de
  renderizado del documento recibido.
- Se conserva el callback de progreso durante la ejecución y se amplía la
  información comunicada por página y por líneas procesadas.

#### Plantillas y persistencia

- Se ha añadido `TPlantillaFisicaPHP` para separar el JSON de una plantilla de su
  sección física opcional `[UserSection]`.
- La lectura conserva BOM UTF-8, saltos CRLF/LF y los bytes de la sección privada,
  incluidos contenidos Base64 y marcadores repetidos.
- La carga, el guardado y la API del diseñador admiten plantillas JSON puras e
  híbridas sin perder la sección privada al hacer un ciclo de carga y guardado.
- Se han endurecido los errores para contenido vacío, JSON inválido y BOM no
  compatible.

#### Paginación, fórmulas y tablas

- `LastPage()` distingue ahora entre un total de páginas conocido y una primera
  pasada de paginación; con total desconocido utiliza el último registro global.
- El runtime aplica finalización selectiva para textos y condiciones basados en
  `LastPage()`, y mantiene la doble pasada cuando una expresión sí necesita los
  totales definitivos de página.
- Se actualizan después de paginar las fórmulas `Page()`, `Pages()`,
  `TotalPages()`, `PageBy()`, `TotalPagesBy()` y `LastPageBy()` que lo requieren.
- Se corrige la propagación del estado de página y de registro entre el contexto
  de ejecución y el evaluador, tanto en PHP como en Harbour.
- Las tablas calculan los acumuladores después de representar la fila actual, de
  modo que el detalle ve el acumulado anterior y los pies reciben el total final.
- Los pies condicionados por acumuladores se vuelven a evaluar al terminar el
  detalle y conservan sus bordes y posición.
- Se ajustan los saltos de página, la unión de pies con el bloque anterior, la
  continuación de grupos y el tratamiento opcional de valores de grupo vacíos.
- Se corrigen el ancho y la alineación horizontal de líneas de tabla y separadores
  en distintas secciones.
- Se verifican comparaciones con cadenas vacías, valores nulos, espacios, números,
  booleanos y nombres de variables sin distinción de mayúsculas.

#### Diseñador y vista previa

- Las imágenes pueden usar `valorDisenoImagen` en la vista previa del diseñador
  sin sustituir el valor real de la variable utilizado por las fórmulas.
- La vista previa diferencia correctamente el modo diseñador del modo real: en
  diseño mantiene visibles los objetos condicionados y en ejecución evalúa sus
  condiciones.
- Se conserva el zoom visual, la posición inicial de etiquetas y la salida de
  documentos sin detalle al pasar por el runtime unificado.

#### Importador de List & Label 12

- Se amplía la normalización de fórmulas con operadores lógicos `AND`, `OR`,
  `.AND.` y `.OR.` sin modificar literales de texto.
- `Date$()` se convierte a `DToC()` y se refinan las máscaras numéricas europeas.
- El marcador de retorno de LL12 se transforma en `CRLF` dentro de literales.
- Los nombres de variables planas con varios puntos se adaptan al convenio de
  campos Dominus; se conservan `ñ`/`Ñ` y los ordinales se normalizan como
  separadores.
- Se revisan condiciones, fórmulas y contenido importado de las plantillas
  existentes y se regeneran sus informes de diagnóstico.
- Se incorporan las plantillas y datos de muestra `ivacli` y `prepenc` junto con
  sus resultados de importación.

#### Harbour y Xailer

- Se mantienen alineados con PHP el conector de datos, el contexto de ejecución,
  el evaluador de fórmulas, las funciones, el motor principal y `TTable`.
- La API del diseñador, el trabajo de impresión y `TRenderTPrinter` reciben los
  ajustes del runtime, la paginación final y el progreso de ejecución.
- Se actualiza la biblioteca estática de Harbour y el proceso de construcción de
  la biblioteca para Xailer.

#### Pruebas

- Se añaden suites PHP específicas para el runtime, `LastPage()`, condiciones con
  `observa` y la lectura física de plantillas.
- Se amplían las pruebas de datos, registros y paginación de tablas en PHP y
  Harbour.
- Se añaden pruebas Playwright para el runtime de `index.php` y `preview.php`, la
  imagen visual de sesión, las condiciones por modo y la estabilidad de la API.
- Se refuerzan las pruebas del importador con fórmulas, máscaras, codificación,
  saltos de línea y nuevas plantillas reales.

### 2026-07-19

- `ea0b49a` — Beta 2 de integración Dominus: persistencia y API del diseñador,
  edición de secciones de usuario, progreso en Xailer, ajustes de impresión y
  motor Harbour, pruebas de codificación y casos reales de importación.

### 2026-07-17

- `ad41404` — Beta 1 de integración Dominus e importación desde Xailer: API de
  cliente/diseñador, geometría de objetos rotados, renderizado e impresión en
  Xailer, evaluador Harbour y pruebas del cliente PHP.

### 2026-07-16

- `0fc879f` — Optimización de bucles y recorridos críticos del motor Harbour,
  conectores, evaluador, funciones, imágenes, códigos de barras y tablas.
- `b6f7158` — Diseñador desde Harbour Beta 3: estabilización de fórmulas y sesión,
  motor `TLLEngine`, API del diseñador, ejemplos y proceso de construcción.

### 2026-07-15

- `fa76bea` — Diseñador desde Harbour Beta 2: API de sesiones entre Xailer y el
  diseñador web, intercambio de variables, preview, exportación IR y primeras
  clases de integración visual.
- `b0e7d58` — Diseñador desde Harbour Beta 1: retirada de las clases Xailer de
  compatibilidad copiadas al proyecto para pasar a la integración real.

### 2026-07-12

- `0e7dd0d` — Vista previa en Xailer: cliente Harbour, renderizador para
  `TPrinter`, generación y consumo de IR, pruebas de objetos y correcciones de
  color, ancho y alineación en tablas.

### 2026-07-11

- `a9d040d` — Portado a Harbour del núcleo restante del motor: documento,
  plantilla, conectores, composición, paginación, ejecución, documento
  renderizable y tablas, con pruebas individuales.

### 2026-07-10

- `e1a4fca` — Integración del conector `TConectorDatosReg` con `TLLDominusPHP` y
  avance de contexto, evaluador, funciones y objetos en Harbour.
- `c172100` — Primera fase del portado del motor a Harbour: objetos base, texto,
  rectángulo, línea, elipse, imagen y código de barras, utilidades y pruebas de
  equivalencia con PHP.
- `67d0582` — Creación del entorno oficial de compilación y pruebas Harbour;
  además se corrigieron incidencias del diseñador, sus fórmulas y objetos.

### 2026-07-09

- `d0b6e34` — Selección de tipo y formato de papel mediante catálogo, integrada
  en documento, diseñador, preview, etiquetas, motor y cliente PHP.

### 2026-07-07

- `2a937e1` — Soporte de documentos de etiquetas: catálogo de formatos,
  distribución por filas y columnas, posición inicial e integración con el
  importador LL12. También se reorganizaron las clases JavaScript por módulos de
  diseñador y objetos.
- `770adf0` — Zoom independiente en la pestaña de vista previa del diseñador.
- `24d1abd` — Importación y ejecución del informe de extracto con cabeceras y pies
  de grupo, con pruebas de paginación de tablas.
- `b295576` — Representación de bordes en preview e importación de cabeceras de
  grupo LL12; se ampliaron fórmulas, datos de demostración y pruebas.

### 2026-07-06

- `bbba0ec` — Exportación de la representación intermedia (IR) para depuración y
  ayuda de teclado dentro del diseñador.

### 2026-07-05

- `70b6658` — Zoom completo del área de diseño, reglas y barra de herramientas.
- `98496c4` — Primera fase del importador List & Label 12, con auditoría de
  plantillas, conversión de objetos, propiedades, tablas y fórmulas, además de
  fixtures y pruebas de importación.
- `d616e36` — Fase 5 del motor de informes estabilizada: ampliación del lenguaje,
  evaluador, contexto, cliente PHP, preview y documentación del motor.
- `5fb82d7` — Paginación avanzada de informes y tablas, funciones asociadas al
  estado de ejecución y correcciones de interfaz en el editor de secciones.

### 2026-07-04

- `92c049c` — Runtime Demo 1.0: cliente `TLLDominusPHP`, carga de trabajos y datos,
  ejemplo ejecutable y servicio PHP de vista previa.
- `1c6cc09` — Diseñador visual estable previo a la integración cliente/servidor:
  refactor en clases, nuevos objetos (`TText`, `TLine`, `TEllipse`, `TImage`,
  `TBarcode` y `TTable`), editor de fórmulas y secciones, lenguaje documentado,
  preview y pruebas Playwright.

### 2026-06-29

- `c8d6e62` — Inicio del proyecto: arquitectura base, diseñador web, documento y
  objetos compartidos, almacenamiento de plantillas JSON, primer motor PHP,
  composición, paginación, renderizador HTML, conector de datos y evaluador de
  fórmulas inicial.
