581 lines
20 KiB
C#
581 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Drawing.Text;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using TSpdf.Kernel.Font;
|
|
using TSpdf.IO.Font.Constants;
|
|
using static tsPDFUtilsCore.Imagenes;
|
|
using static tsPDFUtilsCore.Enums;
|
|
|
|
|
|
namespace tsPDFUtilsCore
|
|
{
|
|
public class Imagenes
|
|
{
|
|
public static Bitmap RedimensionaImagen(Bitmap Original, int NuevoAlto, int NuevoAncho, int CoordenadaX, int CoordenadaY)
|
|
{
|
|
Bitmap newImage = new Bitmap(NuevoAncho, NuevoAlto);
|
|
using (Graphics g = Graphics.FromImage(newImage))
|
|
{
|
|
g.Clear(Color.Transparent);
|
|
g.DrawImage(Original, CoordenadaX, CoordenadaY, Original.Width, Original.Height);
|
|
}
|
|
return newImage;
|
|
}
|
|
|
|
public static Bitmap crearBitMapFirmas(List<DatosTextos> listadoTextos, List<DatosImagenFirma> listadoImagenes, List<DatosFuente> ListadoFuentes, TSpdf.Kernel.Geom.Rectangle medidas)
|
|
{
|
|
int dpi = 600;
|
|
|
|
int anchoPixeles = (int)medidas.GetWidth() * dpi / 72;
|
|
int altoPixeles = (int)medidas.GetHeight() * dpi / 72;
|
|
|
|
Bitmap bmp = new Bitmap(anchoPixeles, altoPixeles, PixelFormat.Format32bppArgb);
|
|
bmp.SetResolution(dpi, dpi);
|
|
Graphics g = Graphics.FromImage(bmp);
|
|
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
|
|
|
g.Clear(Color.Transparent);
|
|
|
|
|
|
|
|
|
|
// Dibujar textos
|
|
foreach (var texto in listadoTextos)
|
|
{
|
|
Font font = null;
|
|
|
|
if (FontFamily.Families.Any(x => x.Name == texto.NombreFuente))
|
|
font = new Font(FontFamily.Families.Where(x => x.Name == texto.NombreFuente).First(), texto.size, texto.estiloTexto, GraphicsUnit.Point);
|
|
else if (ListadoFuentes != null && ListadoFuentes.Any(x => x.NombreFuente == texto.NombreFuente))
|
|
{
|
|
var fuente = ListadoFuentes.Where(x => x.NombreFuente == texto.NombreFuente).First();
|
|
|
|
int dataLength = fuente.memoryFont.Length;
|
|
IntPtr ptrData = Marshal.AllocCoTaskMem(dataLength);
|
|
|
|
Marshal.Copy(fuente.memoryFont, 0, ptrData, dataLength);
|
|
|
|
PrivateFontCollection privateFontCollection = new PrivateFontCollection();
|
|
privateFontCollection.AddMemoryFont(ptrData, dataLength);
|
|
|
|
font = new Font(privateFontCollection.Families.FirstOrDefault(), texto.size, texto.estiloTexto, GraphicsUnit.Point);
|
|
}
|
|
else
|
|
throw new Exception("Fuente " + texto.NombreFuente + " no encontrada");
|
|
|
|
|
|
var sizeTexto = g.MeasureString(texto.texto, font);
|
|
|
|
var coordenadaX = calcularX(texto.distanciaX, texto.distanciaY, texto.PosicionEsquina, bmp, texto.anguloRotacion, (int)sizeTexto.Width, (int)sizeTexto.Height);
|
|
var coordenadaY = calcularY(texto.distanciaY, texto.distanciaX, texto.PosicionEsquina, bmp, texto.anguloRotacion, (int)sizeTexto.Width, (int)sizeTexto.Height);
|
|
|
|
PointF rotationPoint = new PointF(texto.distanciaX, texto.distanciaY);
|
|
|
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
|
|
|
|
StringFormat stringFormat = new StringFormat();
|
|
|
|
g.TranslateTransform(0, 0);
|
|
g.RotateTransform(texto.anguloRotacion);
|
|
|
|
if (texto.AlineacionTexto != AlineamientoEnum.JUSTIFICADO)
|
|
g.DrawString(texto.texto, font, texto.colorTexto, new PointF(coordenadaX, coordenadaY));
|
|
else
|
|
DrawJustifiedString(ref g, texto.texto, font, texto.colorTexto, new RectangleF(coordenadaX, coordenadaY, altoPixeles, sizeTexto.Height), stringFormat);
|
|
g.ResetTransform();
|
|
}
|
|
|
|
foreach (var imagen in listadoImagenes)
|
|
{
|
|
MemoryStream stream = new MemoryStream();
|
|
stream.Write(imagen.Imagen, 0, imagen.Imagen.Length);
|
|
System.Drawing.Image myImage = System.Drawing.Image.FromStream(stream);
|
|
|
|
g.TranslateTransform(0, 0);
|
|
g.RotateTransform(imagen.AnguloRotacion);
|
|
|
|
int coordenadaX = calcularX(imagen.PosicionX, imagen.PosicionY, imagen.PosicionEsquina, bmp, imagen.AnguloRotacion, myImage.Width, myImage.Height);
|
|
int coordenadaY = calcularY(imagen.PosicionY, imagen.PosicionX, imagen.PosicionEsquina, bmp, imagen.AnguloRotacion, myImage.Width, myImage.Height);
|
|
|
|
if (altoPixeles > anchoPixeles)
|
|
g.DrawImage(myImage, new Rectangle(coordenadaX, coordenadaY, altoPixeles, anchoPixeles));
|
|
else
|
|
g.DrawImage(myImage, new Rectangle(coordenadaX, coordenadaY, anchoPixeles, altoPixeles));
|
|
|
|
|
|
g.ResetTransform();
|
|
}
|
|
return bmp;
|
|
}
|
|
public static byte[] BitMapAByteArray(Bitmap bmp)
|
|
{
|
|
MemoryStream msSalida = new MemoryStream();
|
|
bmp.Save(msSalida, ImageFormat.Png);
|
|
byte[] byteArray = msSalida.ToArray();
|
|
msSalida.Close();
|
|
return byteArray;
|
|
}
|
|
|
|
public static void DrawJustifiedString(ref Graphics g, string txt, Font font, Brush brush, RectangleF destination, StringFormat format)
|
|
{
|
|
using (StringFormat fmt = (StringFormat)format.Clone())
|
|
{
|
|
fmt.FormatFlags = fmt.FormatFlags | StringFormatFlags.MeasureTrailingSpaces;
|
|
CharacterRange[] cr = { new CharacterRange(0, 1) };
|
|
fmt.SetMeasurableCharacterRanges(cr);
|
|
fmt.Alignment = StringAlignment.Center;
|
|
|
|
float txtWidth = g.MeasureString(txt, font, destination.Location, fmt).Width;
|
|
float spacing = (destination.Width - txtWidth) / (txt.Length - 1);
|
|
|
|
RectangleF dest = new RectangleF(destination.X, destination.Y, 0, destination.Height);
|
|
foreach (char c in txt.AsEnumerable())
|
|
{
|
|
// Graphics#MeasureString is too inaccurate for character placement
|
|
dest.Width = g.MeasureCharacterRanges(c.ToString(), font, destination, fmt)[0].GetBounds(g).Width;
|
|
g.DrawString(c.ToString(), font, brush, dest, fmt);
|
|
dest.X += dest.Width + spacing;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int calcularX(int coordenadaX, int coordenadaY, EsquinaEnum PosicionEsquina, Bitmap medidasFirma, float rotacionElemento, int anchoElemento, int altoElemento)
|
|
{
|
|
int anchoFirma = medidasFirma.Width;
|
|
int altoFirma = medidasFirma.Height;
|
|
|
|
int ejeX = 0;
|
|
|
|
switch (PosicionEsquina)
|
|
{
|
|
case EsquinaEnum.SUPERIOR_IZQUIERDA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeX = coordenadaY;
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeX = -coordenadaX - anchoElemento;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeX = -coordenadaY - anchoElemento;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeX = coordenadaX;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.INFERIOR_IZQUIERDA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeX = (altoFirma - (coordenadaY + anchoElemento));
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeX = -coordenadaX - anchoElemento;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeX = coordenadaY - altoFirma;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeX = coordenadaX;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.SUPERIOR_DERECHA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeX = coordenadaY;
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeX = -anchoFirma + coordenadaX;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeX = -coordenadaY - anchoElemento;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeX = anchoFirma - (anchoElemento + coordenadaX);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.INFERIOR_DERECHA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeX = (altoFirma - (coordenadaY + anchoElemento));
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeX = -anchoFirma + coordenadaX;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeX = coordenadaY - altoFirma;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeX = anchoFirma - (anchoElemento + coordenadaX);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ejeX;
|
|
}
|
|
private static int calcularY(int coordenadaY, int coordenadaX, EsquinaEnum PosicionEsquina, Bitmap medidasFirma, float rotacionElemento, int anchoElemento, int altoElemento)
|
|
{
|
|
int anchoFirma = medidasFirma.Width;
|
|
int altoFirma = medidasFirma.Height;
|
|
int ejeY = 0;
|
|
|
|
switch (PosicionEsquina)
|
|
{
|
|
case EsquinaEnum.SUPERIOR_IZQUIERDA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeY = -coordenadaX - altoElemento;
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeY = -coordenadaY - altoElemento;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeY = coordenadaX;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeY = coordenadaY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.INFERIOR_IZQUIERDA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeY = -coordenadaX - altoElemento;
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeY = -altoFirma + coordenadaY;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeY = coordenadaX;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeY = altoFirma - (altoElemento + coordenadaY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.SUPERIOR_DERECHA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeY = coordenadaX - (anchoFirma);
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeY = -coordenadaY - altoElemento;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeY = anchoFirma - (altoElemento + coordenadaX);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeY = coordenadaY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case EsquinaEnum.INFERIOR_DERECHA:
|
|
{
|
|
switch (rotacionElemento)
|
|
{
|
|
case 90:
|
|
{
|
|
ejeY = coordenadaX - (anchoFirma);
|
|
break;
|
|
}
|
|
|
|
case 180:
|
|
{
|
|
ejeY = -altoFirma + coordenadaY;
|
|
break;
|
|
}
|
|
|
|
case 270:
|
|
{
|
|
ejeY = anchoFirma - (altoElemento + coordenadaX);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ejeY = altoFirma - (altoElemento + coordenadaY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ejeY;
|
|
}
|
|
private static TSpdf.Kernel.Font.PdfFont devolverTipoFuente(string nombreFuente)
|
|
{
|
|
TSpdf.Kernel.Font.PdfFont tipoFuente;
|
|
|
|
switch (nombreFuente)
|
|
{
|
|
case "COURIER":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.COURIER);
|
|
break;
|
|
}
|
|
|
|
case "COURIER_BOLD":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.COURIER_BOLD);
|
|
break;
|
|
}
|
|
|
|
case "COURIER_BOLDOBLIQUE":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.COURIER_BOLDOBLIQUE);
|
|
break;
|
|
}
|
|
|
|
case "COURIER_OBLIQUE":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.COURIER_OBLIQUE);
|
|
break;
|
|
}
|
|
|
|
case "HELVETICA":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
|
|
break;
|
|
}
|
|
|
|
case "HELVETICA_BOLD":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
|
|
break;
|
|
}
|
|
|
|
case "HELVETICA_BOLDOBLIQUE":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLDOBLIQUE);
|
|
break;
|
|
}
|
|
|
|
case "HELVETICA_OBLIQUE":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_OBLIQUE);
|
|
break;
|
|
}
|
|
|
|
case "SYMBOL":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.SYMBOL);
|
|
break;
|
|
}
|
|
|
|
case "TIMES_ROMAN":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
|
|
break;
|
|
}
|
|
|
|
case "TIMES_BOLD":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.TIMES_BOLD);
|
|
break;
|
|
}
|
|
|
|
case "TIMES_BOLDITALIC":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.TIMES_BOLDITALIC);
|
|
break;
|
|
}
|
|
|
|
case "TIMES_ITALIC":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.TIMES_ITALIC);
|
|
break;
|
|
}
|
|
|
|
case "ZAPFDINGBATS":
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.ZAPFDINGBATS);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
tipoFuente = PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tipoFuente;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public enum EsquinaEnum : int
|
|
{
|
|
INFERIOR_IZQUIERDA = 0,
|
|
INFERIOR_DERECHA = 1,
|
|
SUPERIOR_IZQUIERDA = 2,
|
|
SUPERIOR_DERECHA = 3
|
|
}
|
|
|
|
public enum AlineamientoEnum : int
|
|
{
|
|
IZQUIERDA = 0,
|
|
DERECHA = 1,
|
|
CENTRO = 2,
|
|
JUSTIFICADO = 3,
|
|
JUSTIFICADO_ALL = 4
|
|
}
|
|
|
|
|
|
public enum TipoTextoEnum : int
|
|
{
|
|
NORMAL = 0,
|
|
NUMERO_PAGINA = 1,
|
|
NUMERO_PAGINA_TOTAL_PAGINAS = 2,
|
|
}
|
|
public enum FuenteEnum
|
|
{
|
|
COURIER,
|
|
COURIER_BOLD,
|
|
COURIER_BOLDOBLIQUE,
|
|
COURIER_OBLIQUE,
|
|
HELVETICA,
|
|
HELVETICA_BOLD,
|
|
HELVETICA_BOLDOBLIQUE,
|
|
HELVETICA_OBLIQUE,
|
|
SYMBOL,
|
|
TIMES_ROMAN,
|
|
TIMES_BOLD,
|
|
TIMES_BOLDITALIC,
|
|
TIMES_ITALIC,
|
|
ZAPFDINGBATS
|
|
}
|
|
|
|
|
|
|
|
|
|
|