Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Impresión
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #21  
Antiguo 01-06-2018
gguerrini gguerrini is offline
Miembro
 
Registrado: Feb 2006
Ubicación: Cordoba , Argentina
Posts: 14
Poder: 0
gguerrini Va por buen camino
Realmente me resulta raro, hace un tiempo, para que mis Qreport pudieran funcionar en windows 10, tube que cambiar los Fonts de "Courrier New" a "Arial", porque se rompia. Lo cambiamos el año pasado y con Arial funcionaba perfecto. Despues de la actualizacion agua...... Sera que ahora hay que volver a cambiar de fuente ?????
Responder Con Cita
  #22  
Antiguo 04-06-2018
josepvila josepvila is offline
Registrado
 
Registrado: May 2006
Posts: 2
Poder: 0
josepvila Va por buen camino
Cita:
Empezado por JuanPa Ver Mensaje
Finalmente parece que encontramos la solucion al problema de exportar el reporte a pdf en windows 10. Vale indicar que el problema se produce por el tipo de letra que en el caso de mi reporte utilizaba "Arial" y lo he cambiado por otro tipo de letra y ha funcionado correctamente. Tambien hay que corregir la siguiente linea en el archivo QRPDFFilt.pas del QuickReport.

En esta sentencia ntabs:=cvtInt(Buff, 4); es donde se cae por lo cual hay que cambiarlo por lo siguiente:
Código Delphi [-]
if (FontName='Arial') then
  ntabs:=0
else
  ntabs:=cvtInt(Buff, 4);
Espero que puedan resolverlo con lo indicado.
Saludos.
Funciona perfecto, muchas gracias!!
Responder Con Cita
  #23  
Antiguo 04-06-2018
Avatar de adebonis
adebonis adebonis is offline
Miembro
 
Registrado: May 2003
Ubicación: Barcelona
Posts: 135
Poder: 16
adebonis Va por buen camino
Hola.

Yo he cambiado todos los tipos de letra de los reportes de "Arial" a "Tahoma" y funciona perfectamente!!

La verdad es que no me lo explico. ¿Alguuien tiene alguna explicación?

Saludos.
Adolfo de Bonis.
Responder Con Cita
  #24  
Antiguo 04-06-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.604
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Responder Con Cita
  #25  
Antiguo 07-06-2018
bazsar bazsar is offline
Registrado
 
Registrado: Jun 2018
Posts: 2
Poder: 0
bazsar Va por buen camino
Cita:
Empezado por JuanPa Ver Mensaje
Finalmente parece que encontramos la solucion al problema de exportar el reporte a pdf en windows 10. Vale indicar que el problema se produce por el tipo de letra que en el caso de mi reporte utilizaba "Arial" y lo he cambiado por otro tipo de letra y ha funcionado correctamente. Tambien hay que corregir la siguiente linea en el archivo QRPDFFilt.pas del QuickReport.

En esta sentencia ntabs:=cvtInt(Buff, 4); es donde se cae por lo cual hay que cambiarlo por lo siguiente:
Código Delphi [-]
if (FontName='Arial') then
  ntabs:=0
else
  ntabs:=cvtInt(Buff, 4);
Espero que puedan resolverlo con lo indicado.
Saludos.
This is not the correct solution. The problem is that the cvtInt and the cvtDWord functions don't get font data buffer as reference. Use this instead:
Código Delphi [-]
function cvtDWord(const Buf: array of byte; P: Integer): DWORD;

...

function cvtInt(const Buf: array of byte; P: Integer): Integer;
Responder Con Cita
  #26  
Antiguo 07-06-2018
Avatar de juanelo
juanelo juanelo is offline
Miembro
 
Registrado: Sep 2007
Posts: 1.058
Poder: 13
juanelo Va por buen camino
Cita:
Empezado por bazsar Ver Mensaje
This is not the correct solution. The problem is that the cvtInt and the cvtDWord functions don't get font data buffer as reference. Use this instead:
Código Delphi [-]function cvtDWord(const Buf: array of byte; P: Integer): DWORD; ... function cvtInt(const Buf: array of byte; P: Integer): Integer;
Esto funciona a la perfeccion y no hay que cambiar ningun font.
Muchas gracias !!
__________________
Ya tengo Firma!
Responder Con Cita
  #27  
Antiguo 07-06-2018
gguerrini gguerrini is offline
Miembro
 
Registrado: Feb 2006
Ubicación: Cordoba , Argentina
Posts: 14
Poder: 0
gguerrini Va por buen camino
Felicitaciones !!!!

Muchas Gracias!!!! Funciona Perfecto !!!!!!!!!!
Responder Con Cita
  #28  
Antiguo 07-06-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.604
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por bazsar Ver Mensaje
This is not the correct solution. The problem is that the cvtInt and the cvtDWord functions don't get font data buffer as reference. Use this instead:
Código Delphi [-]function cvtDWord(const Buf: array of byte; P: Integer): DWORD; ... function cvtInt(const Buf: array of byte; P: Integer): Integer;
Responder Con Cita
  #29  
Antiguo 12-06-2018
ginobili20 ginobili20 is offline
Miembro
 
Registrado: Apr 2010
Posts: 11
Poder: 0
ginobili20 Va por buen camino
me pasaron la solucion

En QRPDFFilt.pas reemplazar las llamadas a las funciones cvtInt y cvtDword

x := cvtInt(Buff, y);

se convierte en estas dos lineas:

P := y;
x := (256*byte(Buff[P]))+(byte(Buff[P+1]));

Y

x := cvtDword(Buff, y); becomes

P := y;
x :=(256*256*256*byte(Buff[P]))+(256*256*byte(Buff[P+1]))+(256*byte(Buff[P+2]))+byte(Buff[P+3]);

Funciona perfecto...
Responder Con Cita
  #30  
Antiguo 12-06-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.604
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No olvides poner las etiquetas para el código:


Responder Con Cita
  #31  
Antiguo 12-06-2018
ginobili20 ginobili20 is offline
Miembro
 
Registrado: Apr 2010
Posts: 11
Poder: 0
ginobili20 Va por buen camino
In QRPDFFilt.pas replace calls to functions cvtInt and cvtDword with inline code

Código Delphi [-]
x := cvtInt(Buff, y);

becomes 2 lines

Código Delphi [-]
P := y;
x := (256*byte(Buff[P]))+(byte(Buff[P+1]));

and

Código Delphi [-]

x := cvtDword(Buff, y);

se convierte en

Código Delphi [-]
P := y;
x :=(256*256*256*byte(Buff[P]))+(256*256*byte(Buff[P+1]))+(256*byte(Buff[P+2]))+byte(Buff[P+3]);
Responder Con Cita
  #32  
Antiguo Hace 3 Semanas
REPUSOFT REPUSOFT is offline
Miembro
 
Registrado: Sep 2018
Posts: 3
Poder: 0
REPUSOFT Va por buen camino
Smile Solución al problema de desdoblamiento de QReports al generar PDF's

Hola
Ante todo gracias por dejarme formar parte de vuestro foro ya que, gracias a vosotros he podido encontrar
la guía que me ha llevado a la solución correcta y poder compartirla con vosotros.
Aunque la solución que dais puede que funcione, no es la correcta ya que lo único que
hace es disimular el problema pero éste permanece latente y te puede explotar por otro lado.
El problema es que, desde la última actualización de W10(1803) las fuentes parece ser que son más ricas en cuanto a información(probablemente para trabajar mejor con pantallas de alta resolución) y la información recogida por la función GetFontData para, por ejemplo, la fuente Arial se ha triplicado.
Por ejemplo en la penúltima versión de W10, antes de la actualización "maldita"(1803), GetFontData devolvía unos 350.000 bytes de información y ahora devuelve aproximadamente 1.500.000. El buffer donde se recoge la información de GetFontData es inicializado como una PByteArray con SetLength() y, desgraciadamente esta función parece sufrir un desbordamiento cuando intenta reservar tanta memoria.

Yo he hecho todo el proceso con QuickReport 5.02 y C++Builder 6 pero seguro que se puede aplicar a mas versiones de Delphi

Esto se puede encontrar dentro del módulo QRPDFFilt
procedure MakeTTFont
dentro de la sección 'var'

Canviar
Código Delphi [-]
Buff: array of Byte;
por:
Código Delphi [-]
Buff: PByteArray;

Esto nos permitirá tratar la infomación como un puntero a una matriz de Bytes y, en vez de
usar el gestionador de memoria de Delphi para generar matrices (arrays) de longitud variable (y que
es lo que falla realmente cuando se le pide una cantidad tan astronómica de Bytes mediante SetLength()), utilizar otro más potente del
propio Windows: CoTaskMemAlloc. Éste seguro que no se quedará corto a la hora de guardar memoria ya que es el que
utiliza Windows para su tecnología COM

Para poder usar CoTaskMemAlloc necesitamos poner en la clausula uses de QRPDFFilt 'ActiveX' (naturalmente sin las comillas).
Yo lo he puesto después de Db, pero podría ser en cualquier parte de dicha cláusula

uses
Código Delphi [-]
  Windows, Classes, Controls, StdCtrls, SysUtils, Graphics, Buttons, Forms, ExtCtrls, Dialogs, Printers, Db,
  ActiveX,
  {$IFDEF QRBDE} DBTables, {$ENDIF}
  ComCtrls, qrexport, QRPrntr, QuickRpt, QR5Const, QRCtrls, grimgctrl, pdfconst, LZW;

Y ahora viene lo bueno:
Hacia la línea de código 1628 del módulo QRPDFFilt, donde se hace la reserva de memoria para recuperar la informació de 'GetFontData'
SUBSTITUIR:
Código Delphi [-]
SetLength(Buff,FSize);
POR ESTAS DOS LÍNEAS
Código Delphi [-]
Buff:=CoTaskMemAlloc(FSize);{ahora que nos pidan la cantidad de memoria que quieran que nuesto stack no se desbordará:-)}
if Buff=nil then raise EOutOfMemory.Create('Memoria insuficiente"){esta línea no es necesaria pero me gusta estar seguro}

Como ahora la memoria reservada no se libera sola, hemos de llamar a CoTraskMemFree. Para ello,
en la clausula 'finally'(linea 1627 aproximadamente) que aparece más abajo (justo debajo de SetEncoding) añadir la siguiente línea:
Código Delphi [-]
 SetEncoding;
finally
 if Buff<>nil then CoTaskMemFree(Buff);{añadir esta línea}
 TmpImage.Free;
end;

Como ahora pasamos un PByteArray a las funciones cvtInt y cvtDWord hemos de canviar sus argumentos quedando las
declaraciones de la siguiente manera (el cuerpo de las funciones queda exactamente igual)

Código Delphi [-]
function cvtDWord(Buf: PByteArray; P: Integer) : DWORD;
begin
  Result:=(256*256*256*Buf[P])+(256*256*Buf[P+1])+(256*Buf[P+2])+Buf[P+3];
end;

function cvtInt(Buf: PByteArray; P: Integer) : Integer;
begin
  Result:=(256*Buf[P])+(Buf[P+1]);
end;


Y ya está!!! ahora sí que podeis generar los pdf's sin miedo a desbordamientos de memoria. Además como utilizamos el mismo gestionador
de memoria de COM, el cual está gestionado por Windows no creo que esto vuelva a dar problemas aunque haya más actualizaciones
y la información de las fuentes se vuelva a triplicar.

Por cierto, en el módulo 'pdfobjs.pas' aparece otra llamada a 'GetFontData' en el procedimiento AnalyseTTFOnt, bajando hacia la línia 728 podemos encontrar de nuevo la sentencia SetLength(buff,fsize), justo antes de la llamada a GetFontData os recomiendo que hagais el mismo proceso en este módulo y la cambiéis por CoTaskMalloc. Aseguraros que liberáis la memoria alojada por CoTaskMalloc con CoTaskMemFree en un bloque finally que tendreis que añadir
expresamente al final de 'AnalyseTtFont' . Yo lo he puesto despues de la sentencia
Código Delphi [-]
   encoding := encoding + '>>';{hacia la línia de código 854 de pdfobjs.pas)}
finally
  if Buff<>nil then CoTaskMemFree(Buff);
end;

Última edición por REPUSOFT fecha: Hace 3 Semanas a las 13:37:40.
Responder Con Cita
  #33  
Antiguo Hace 3 Semanas
REPUSOFT REPUSOFT is offline
Miembro
 
Registrado: Sep 2018
Posts: 3
Poder: 0
REPUSOFT Va por buen camino
Hola Ginobili20 y gracias por tu respuesta, la cual me ha ayudado mucho para encontrar la verdadera causa del problema.
Aunque el código que das aparentemente funciona no es la solución correcta porque el desbordamiento del buffer
se produce ya cuando vuelves de SetLength(). Tu código funciona porque pones el cuerpo de las funciones 'inline'
y por tanto no hace falta utilizar el stack para pasar el buffer desbordado a las funciones pero el
desbordamiento ya está latente.
Saludos y gracias de nuevo a tí y a todos los miembros del foro
Responder Con Cita
  #34  
Antiguo Hace 3 Semanas
REPUSOFT REPUSOFT is offline
Miembro
 
Registrado: Sep 2018
Posts: 3
Poder: 0
REPUSOFT Va por buen camino
Rectificación del título

El título del mensaje debería decir "Solución al problema de de desbordamiento de QReports al general PDF´s" Perdonad!
Responder Con Cita
  #35  
Antiguo Hace 3 Semanas
Avatar de juanelo
juanelo juanelo is offline
Miembro
 
Registrado: Sep 2007
Posts: 1.058
Poder: 13
juanelo Va por buen camino
Cita:
Empezado por REPUSOFT Ver Mensaje
El título del mensaje debería decir "Solución al problema de de desbordamiento de QReports al general PDF´s" Perdonad!
Sería de gran ayuda si puedes compartir las unidades pas que has modificado.
Gracias
__________________
Ya tengo Firma!
Responder Con Cita
  #36  
Antiguo Hace 2 Semanas
bazsar bazsar is offline
Registrado
 
Registrado: Jun 2018
Posts: 2
Poder: 0
bazsar Va por buen camino
Cita:
Empezado por REPUSOFT Ver Mensaje
Hola
Ante todo gracias por dejarme formar parte de vuestro foro ya que, gracias a vosotros he podido encontrar
la guía que me ha llevado a la solución correcta y poder compartirla con vosotros.
Aunque la solución que dais puede que funcione, no es la correcta ya que lo único que
hace es disimular el problema pero éste permanece latente y te puede explotar por otro lado.
El problema es que, desde la última actualización de W10(1803) las fuentes parece ser que son más ricas en cuanto a información(probablemente para trabajar mejor con pantallas de alta resolución) y la información recogida por la función GetFontData para, por ejemplo, la fuente Arial se ha triplicado.
Por ejemplo en la penúltima versión de W10, antes de la actualización "maldita"(1803), GetFontData devolvía unos 350.000 bytes de información y ahora devuelve aproximadamente 1.500.000. El buffer donde se recoge la información de GetFontData es inicializado como una PByteArray con SetLength() y, desgraciadamente esta función parece sufrir un desbordamiento cuando intenta reservar tanta memoria.

Yo he hecho todo el proceso con QuickReport 5.02 y C++Builder 6 pero seguro que se puede aplicar a mas versiones de Delphi

Esto se puede encontrar dentro del módulo QRPDFFilt
procedure MakeTTFont
dentro de la sección 'var'

Canviar
Código Delphi [-]
Buff: array of Byte;
por:
Código Delphi [-]
Buff: PByteArray;

Esto nos permitirá tratar la infomación como un puntero a una matriz de Bytes y, en vez de
usar el gestionador de memoria de Delphi para generar matrices (arrays) de longitud variable (y que
es lo que falla realmente cuando se le pide una cantidad tan astronómica de Bytes mediante SetLength()), utilizar otro más potente del
propio Windows: CoTaskMemAlloc. Éste seguro que no se quedará corto a la hora de guardar memoria ya que es el que
utiliza Windows para su tecnología COM

Para poder usar CoTaskMemAlloc necesitamos poner en la clausula uses de QRPDFFilt 'ActiveX' (naturalmente sin las comillas).
Yo lo he puesto después de Db, pero podría ser en cualquier parte de dicha cláusula

uses
Código Delphi [-]
  Windows, Classes, Controls, StdCtrls, SysUtils, Graphics, Buttons, Forms, ExtCtrls, Dialogs, Printers, Db,
  ActiveX,
  {$IFDEF QRBDE} DBTables, {$ENDIF}
  ComCtrls, qrexport, QRPrntr, QuickRpt, QR5Const, QRCtrls, grimgctrl, pdfconst, LZW;

Y ahora viene lo bueno:
Hacia la línea de código 1628 del módulo QRPDFFilt, donde se hace la reserva de memoria para recuperar la informació de 'GetFontData'
SUBSTITUIR:
Código Delphi [-]
SetLength(Buff,FSize);
POR ESTAS DOS LÍNEAS
Código Delphi [-]
Buff:=CoTaskMemAlloc(FSize);{ahora que nos pidan la cantidad de memoria que quieran que nuesto stack no se desbordará:-)}
if Buff=nil then raise EOutOfMemory.Create('Memoria insuficiente"){esta línea no es necesaria pero me gusta estar seguro}

Como ahora la memoria reservada no se libera sola, hemos de llamar a CoTraskMemFree. Para ello,
en la clausula 'finally'(linea 1627 aproximadamente) que aparece más abajo (justo debajo de SetEncoding) añadir la siguiente línea:
Código Delphi [-]
 SetEncoding;
finally
 if Buff<>nil then CoTaskMemFree(Buff);{añadir esta línea}
 TmpImage.Free;
end;

Como ahora pasamos un PByteArray a las funciones cvtInt y cvtDWord hemos de canviar sus argumentos quedando las
declaraciones de la siguiente manera (el cuerpo de las funciones queda exactamente igual)

Código Delphi [-]
function cvtDWord(Buf: PByteArray; P: Integer) : DWORD;
begin
  Result:=(256*256*256*Buf[P])+(256*256*Buf[P+1])+(256*Buf[P+2])+Buf[P+3];
end;

function cvtInt(Buf: PByteArray; P: Integer) : Integer;
begin
  Result:=(256*Buf[P])+(Buf[P+1]);
end;


Y ya está!!! ahora sí que podeis generar los pdf's sin miedo a desbordamientos de memoria. Además como utilizamos el mismo gestionador
de memoria de COM, el cual está gestionado por Windows no creo que esto vuelva a dar problemas aunque haya más actualizaciones
y la información de las fuentes se vuelva a triplicar.

Por cierto, en el módulo 'pdfobjs.pas' aparece otra llamada a 'GetFontData' en el procedimiento AnalyseTTFOnt, bajando hacia la línia 728 podemos encontrar de nuevo la sentencia SetLength(buff,fsize), justo antes de la llamada a GetFontData os recomiendo que hagais el mismo proceso en este módulo y la cambiéis por CoTaskMalloc. Aseguraros que liberáis la memoria alojada por CoTaskMalloc con CoTaskMemFree en un bloque finally que tendreis que añadir
expresamente al final de 'AnalyseTtFont' . Yo lo he puesto despues de la sentencia
Código Delphi [-]
   encoding := encoding + '>>';{hacia la línia de código 854 de pdfobjs.pas)}
finally
  if Buff<>nil then CoTaskMemFree(Buff);
end;
This is too complicated, see my previous comment, there you can find a simply solution for the problem. The issue is, that the the functions don't get the parametes by reference, but by copy over the heap. When the buffer is bigger than the heap can handle, then the application crashes. If you use the 'const' keyword passing the parameter, then it will be given by reference. Not to mention it faster then copy the buffer.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
QReport con Win10 inetplus Impresión 3 13-08-2018 20:37:25
desbordamiento de pila danielmj Varios 4 30-10-2016 20:27:48
Como saber si un problema esta SOLUCIONADO cloayza La Taberna 16 24-02-2010 16:30:10
Desbordamiento de pila ecfisa OOP 2 06-12-2007 16:08:35
Desbordamiento de Pila Durbed Conexión con bases de datos 5 21-06-2006 20:05:31


La franja horaria es GMT +2. Ahora son las 14:40:46.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi