Sono un nuovo utente entusiasta (nuovo solo per dire avendo ai me superato la sessantina) di Linux e di Gambas che trovo fantastici. Mi scuso anticipatamente se il tema in oggetto è stato già trattato ma io non sono stato capace di scovarlo.
Lavoro con:
[System]
Gambas=3.5.90
OperatingSystem=Linux
Kernel=3.11.0-15-generic
Architecture=x86_64
Distribution=Ubuntu 13.10
Desktop=GNOME
Theme=QGtk
Language=it_IT.UTF-8
Memory=15978M
[Libraries]
Cairo=libcairo.so.2.11200.16
Curl=libcurl.so.4.3.0
DBus=libdbus-1.so.3.7.4
GStreamer=libgstreamer-0.10.so.0.30.0
GStreamer=libgstreamer-1.0.so.0.200.0
GTK+3=libgtk-3.so.0.800.6
GTK+=libgtk-x11-2.0.so.0.2400.20
OpenGL=libGL.so.1.2.0
Poppler=libpoppler.so.43.0.0
Qt4=libQtCore.so.4.8.4
SDL=libSDL-1.2.so.0.11.4
[SVN]
3.5.99.1+svn20140131+build18~ubuntu13.10.1
Ho avuto conoscenza in Windows con VBA su VBE e li la stampa era gestita in automatico, quindi per me disegnare testo per la stampante è una nuova esperienza.
Problema:
non riesco a far combaciare le misure del testo disegnato sulla DrawingArea con le misure stampate su foglio.
Se io stampo la stringa “TESTOCORTO” con carattere “Ubuntu” 11 otterrò un testo di circa millimetri 3 in altezza per 24,5 di lunghezza qualunque software io usi per scrivere.
Perché invece Gambas mi da misure diverse?
Per esemplificare quanto chiedo ho creato un programmino il cui codice allego, è un progetto grafico con una DrawingArea denominata “da” su cui il codice disegna per poi mandare alla stampa (metodo commentato per evitare sprechi di carta) la scritta “TESTOCORTO” che viene riquadrata sulla base delle misure fornite da Paint.Font.TestWidth e Paint.Font.TextHeight e poi disegna anche un riquadro giallo che è quello delle misure giuste usate dalla stampante.
Cosa sbaglio? Cosa non ho capito? Dove posso avere una risposta elementare adeguata alla mia bassa conoscenza della programmazione?
Tante grazie anticipate a chiunque vorrà aiutarmi.
Gianluigi
' Gambas class file
'' Ho creato questo esempio come progetto grafico con l'aggiunta alla Main form di una DrawingArea nominata "da".
Private miaStampante As Printer
Private Const MM_X_PX As Float = 0.3527 'per mutare millimetri in pixel e viceversa
Public Sub _new()
End
Public Sub Form_Open()
miaStampante = New Printer As "Stampa"
' mie misure arbitrarie.
Me.W = 600
Me.H = 450
da.Left = 0
da.Top = 0
da.W = 550
da.H = 400
da.Background = Color.White
' Crea subito il disegno e la stampa
StampoSu("Video")
'Stampare()
End
Public Sub Stampare()
With miaStampante
'Verticale
.Orientation = 0
' A4 orizzontale
'.Orientation = 1
'.PaperWidth = 297
'.PaperHeight = 210
.Resolution = Desktop.Resolution '300
.FullPage = True 'parte da X0 e Y0 di paper
'Print .Resolution
End With
Me.Enabled = False
Inc Application.Busy
miaStampante.Print
Dec Application.Busy
Me.Enabled = True
End
Public Sub Stampa_Draw()
StampoSu("Stampante")
End
Public Sub StampoSu(sDevice As String)
Dim iH, iW As Integer
Dim fSpazInLarg, fSpazInAlt, fLargRet, fAltRet As Float
Dim sTesto As String
Dim fTratteggio As Float[] = [3.0, 2.0]
Select Case sDevice
Case "Video"
da.Cached = True
da.Clear
Paint.Begin(da)
'Paint.Scale(2, 2)
Case "Stampante"
Paint.Begin(miaStampante)
Case Else
Return
End Select
'Spazi iniziali di 20 mm.
fSpazInLarg = 20 / MM_X_PX
fSpazInAlt = 20 / MM_X_PX
Paint.Background = Color.Black
Paint.Save
'Disegna testo
'Paint.Font.Name = "Sans Serif"
Paint.Font.Name = "Ubuntu"
Paint.Font.Size = "11"
'Paint.Font.Bold = True
sTesto = "TESTOCORTO"
iW = Paint.Font.TextWidth(sTesto)
iH = Paint.Font.TextHeight(sTesto)
Print Paint.Font.Size
Print Paint.Font.Name
Print "H testo = " & iH
Print "L teso = " & iW
Paint.DrawText(sTesto, fSpazInLarg, fSpazInAlt, 1, 1, 17) '35 = bottom; 33 = BottomLeft; 32 = BottomNormal; 17 = TopLeft
Paint.Restore
' Disegna rettangolo
fLargRet = CFloat(iW)
fAltRet = CFloat(iH)
Paint.LineWidth = 0.5
'Paint.Background = Color.Black
Paint.Rectangle(fSpazInLarg, fSpazInAlt, fLargRet, fAltRet)
Paint.Stroke(True)
Paint.Clip
' Visualizza a schermo (rettangolo giallo) l'ingombro reale della scritta sul foglio stampato.
fLargRet = 24.5 / MM_X_PX
fAltRet = 3 / MM_X_PX
Paint.Rectangle(fSpazInLarg, fSpazInAlt + (1 / MM_X_PX), fLargRet, fAltRet)
Paint.Background = Color.RGB(255, 218, 90, 0)
Paint.Dash = fTratteggio
Paint.Stroke(True)
Paint.Background = Color.RGB(255, 218, 90, 180)
Paint.Fill
Paint.End
End
Ringrazio Vuott e se ho compreso bene,anche a te (posso dare del tu?) Gambas da misure diverse fra video e stampa.
L'unica cosa che mi è venuta in mente per far combaciare le due cose è inserire dei fattori di compensazione.
A questo scopo aggiungo il codice sottostante che mi è costato un po di carta.
Rimane il fatto che mi sembra impossibile che questo approccio sia corretto.
Sono andato a guardare in CAIRO ma onestamente non ho capito un tubo.
A parte che il mio inglese è ridicolo (approfitto per ringraziare il traduttore di Google) io il C non lo so e no mi ci metto neppure a provare in quanto i miei studi si sono fermati alle elementari anche se posso “vantare” una licenza media.
Ci dovrà pur essere un modo corretto per mostrare a video ciò che si andrà a stampare! :rolleyes: :hard:
' Gambas class file
'' Ho creato questo esempio come progetto grafico con l'aggiunta alla Main form di una DrawingArea nominata "da".
'' Questa è la seconda parte di codice che attraverso alcune aggiustature riesce a ottenere misure abbastanza
'' simili al reale.
'' Vale a dire quanto stampato e quanto visto a video sono simili nelle misure reali pur non perfettamente uguali.
Private miaStampante As Printer
Private iH As Integer
Private iW As Integer
Private Const MM_X_PX As Float = 0.3527 'per mutare millimetri in pixel e viceversa
Public Sub _new()
End
Public Sub Form_Open()
miaStampante = New Printer As "Stampa"
' mie misure arbitrarie.
Me.W = 600
Me.H = 450
da.Left = 0
da.Top = 0
da.W = 550
da.H = 400
da.Background = Color.White
' Crea subito il disegno e la stampa
StampoSu("Video")
'Stampare()
End
Public Sub Stampare()
With miaStampante
'Verticale
.Orientation = 0
' A4 orizzontale
'.Orientation = 1
'.PaperWidth = 297
'.PaperHeight = 210
.Resolution = Desktop.Resolution '300
.FullPage = True 'parte da X0 e Y0 di paper
'Print .Resolution
End With
Me.Enabled = False
Inc Application.Busy
miaStampante.Print
Dec Application.Busy
Me.Enabled = True
End
Public Sub Stampa_Draw()
StampoSu("Stampante")
End
Public Sub StampoSu(sDevice As String)
'Dim iH, iW As Integer
Dim fSpazInLarg, fSpazInAlt, fLargRet, fAltRet As Float
Dim sTesto As String
Dim fTratteggio As Float[] = [3.0, 2.0]
Select Case sDevice
Case "Video"
da.Cached = True
da.Clear
Paint.Begin(da)
'Paint.Scale(2, 2)
Case "Stampante"
Paint.Begin(miaStampante)
Case Else
Return
End Select
'Spazi iniziali di 20 mm.
fSpazInLarg = 20 / MM_X_PX
fSpazInAlt = 20 / MM_X_PX
Paint.Background = Color.Black
'Disegna testo
'Paint.Font.Name = "Serif"
'Paint.Font.Name = "Sans Serif"
Paint.Font.Name = "Ubuntu"
Paint.Font.Size = 12
'Paint.Font.Bold = True
sTesto = "TESTOCORTO"
'sTesto = "questocorto"
'sTesto = "QUESTOCORTO"
If sDevice = "Video" Then
' Riduce il font per renderlo sinile a quello stampato
' Memorizza altezza e larghezza del rettangolo di confronto
' che a video sembrerebbe sempre perfetto mentre stampato no.
Paint.Font.Size *= 73 / 100
iW = Paint.Font.TextWidth(sTesto)
iH = Paint.Font.TextHeight(sTesto)
Endif
Print iH * MM_X_PX
Print iW * MM_X_PX
Paint.DrawText(sTesto, fSpazInLarg, fSpazInAlt, 1, 1, 17) '35 = bottom; 33 = BottomLeft; 32 = BottomNormal; 17 = TopLeft
' Disegna rettangolo del formato della scritta (quasi) senza differenze tra video e foglio stampato.
fLargRet = CFloat(iW)
fAltRet = CFloat(iH)
Paint.LineWidth = 0.5
' Ho tenuto conto dei tratti discendenti dei caratteri tipo la g minuscola la q sia minuscola che maiuscola ecc.
' per lasciare lo spazio inferiore.
If sDevice = "Video" Then
Paint.Rectangle(fSpazInLarg, fSpazInAlt + (fAltRet * 16 / 100), fLargRet, fAltRet * 82 / 100)
Else
If CInt(Paint.Font.Size) Mod 2 = 1 Then
Paint.Rectangle(fSpazInLarg, fSpazInAlt + (fAltRet * 16 / 100), fLargRet + (fLargRet * 6 / 100), fAltRet * 82 / 100)
Print "DISPARI"
Print Paint.Font.Size
Else
Paint.Rectangle(fSpazInLarg, fSpazInAlt + (fAltRet * 16 / 100), fLargRet + (fLargRet * 2 / 100), fAltRet * 82 / 100)
Print "ELSE"
Endif
Endif
Paint.Stroke
Paint.End
End
procedendo empiricamente, nel tuo programma il rapporto per il font dovrebb essere 0.744
ovvero quando disegni sullo schermo il font che usi deve avere il size desiderato moltiplicato per 0.744
ti consiglio di creare la seguente funzione:
public sub ridimensiona(size as float)as float
If Paint.Device = da Then
Return size * 0.744
Else
Return size
Endif
end
in questo modo nel modulo disegno per cambiare font darai
paint.font.size=ridimensiona(15)
così il programma cambierà automaticamente la dimensione del font nel caso tu stia stampando oppure disegnando a schermo
Diciamo che si può sempre agire in diversi modi, nel tuo caso mi e sembrato piu semplice giocherellare con il font lasciando il resto invariato.
Facendo delle prove con il tuo software modificato tutto sembra funzionare correttamente ed il testo occupa il giusto spazio anche a monitor
Guarda un po questo codice a me restituisce un foglio A4 esatto esatto, ma non ho idea del perché ;)
' Gambas class file
'' Solita DrawingArea denominata da
Private fRatio As Float
Private fRatioS As Float
Private fRatioD As Float
Private Const MM_X_DOT As Float = 0.352778
Public Sub _new()
End
Public Sub Form_Open()
fRatioS = CFloat(Screen.Width / Screen.Height)
fRatioD = CFloat(Desktop.Width / Desktop.Height)
fRatio = Frac((fRatioD + fRatioS) / 2)
Me.H = 210 / MM_X_DOT / fRatio
Me.W = 297 / MM_X_DOT / fRatio
da.X = 0
da.Y = 0
da.H = Me.H
da.W = Me.W
End
....a me restituisce un foglio A4 esatto esatto, ma non ho idea del perché ;)
...secondo me, a questo punto, sta prendendo il sopravvento la ceskhonite ! :rotfl:
(http://www.federazionesanita.confcooperative.it/PublishingImages/autoambulanza.jpg)
Ho preso una piccola pausa di riflessione ma nel frattempo non sono stato con le mani in mano e grazie ai favolosi consigli di fsurfing penso di essere arrivato ad una più che soddisfacente risoluzione del problema.
Be a dire il vero mi è stato brillantemente risolto da fsurfing ma non bisogna dimenticare il fattivo stimolante aiuto di vuott, specialmente quando mi ha mandato l'ambulanza, il ricovero penso (o almeno spero) che mi abbia fatto bene. :)
In effetti in questa discussione ho inserito del codice che può nuocere gravemente alla salute mentale e me ne scuso.
A parte gli scherzi grazie davvero dei vari aiuti e consigli.
Però siccome al peggio non c'è mai fine insisto e vi propino la (mia?) soluzione.
Occorre fare una premessa all'inizio della terza pagina di questa discussione fsurfing mi consigliava già la soluzione: :-[
procedendo empiricamente, nel tuo programma il rapporto per il font dovrebb essere 0.744....
ti consiglio di creare la seguente funzione:
public sub ridimensiona(size as float)as float
If Paint.Device = da Then
Return size * 0.744
Else
Return size
Endif
end
in questo modo nel modulo disegno per cambiare font darai
paint.font.size=ridimensiona(15)
così il programma cambierà automaticamente la dimensione del font nel caso tu stia stampando oppure disegnando a schermo
ma ai me io non l'ho capita subito e siccome sono di coccio anche dopo che mi sono reso conto che funzionava benissimo ho avuto bisogno di ulteriori delucidazioni e voi non ci crederete ma ho ancora delle domande da pormi e da porvi.
Comunque andiamo per ordine ho esemplificato “a modo mio” come ottenere un preciso riscontro fra il testo e il disegno mostrato a video, con quanto andremo poi a stampare.
Per il codice che segue ho tratto ispirazione dal codice mostrato negli esempi di Gambas – esempi di disegno.
' Gambas class file
'' Ho creato questo esempio come progetto grafico con l'aggiunta alla Main form (l.800x500 circa)di una DrawingArea nominata "da".
'' Una textbox1 e tre button Disegna, Stampa e Cancella.
'' Questo esempio è stato ispirato dall'esempio di disegno degli esempi di Ganbas.
Private fFontVideo As Float
Private fFontOrig As Float
'Private sFont As String
Private sTestoText As String
Private miaStampante As Printer
Private Const MM_X_PX As Float = 0.352778 'per mutare millimetri in pixel e viceversa
Private Const F_FSURFING_VIDEO As Float = 0.744 ' Per creare il giusto font a video :)
Private Const F_GAMBERETTO_STAMPA As Float = 1.3441 ' Per riportare il font alle giuste proporzioni :)
Public Sub _new()
End
Public Sub Form_Open()
miaStampante = New Printer As "Stampa"
'Avrei voluto usare una fontbox ma non sono riuscito a capire come funziona
'e allora accontentiamoci.
sTestoText = "TO BE OR NOT TO BE: THAT IS THE QUESTION"
fFontOrig = 26
da.W = 210 / MM_X_PX
End
'' Non ho inserito questa bella funzione di fsurfing nel codice perchè mi confondevo durante il ciclo di ridimensionamento
'' ma occorre che ci ritorni su comunque la riporto per conoscenza.
'' Poi nel codice la si usa così: Paint.Font.size = ridimensiona(11)
''Public Sub ridimensiona(size As Float) As Float
' If Paint.Device = da Then
' Return size * 0.744
' Else
' Return size
' Endif
''End
Public Sub Stampa_Draw()
DisegnoX("Stampante")
End
'' Qui si sarebbe dovuta(?) usare la funzione Paint.Device al posto della string sDevice
'' ...ma le vecchie abitudini sono dure a morire.
Public Sub DisegnoX(sDevice As String)
Dim fLarghezza, fAltezza As Float
Dim fSpazInLarg, fSpazInAlt As Float
Select Case sDevice
Case "Video"
da.Cached = True
da.Clear
Paint.Begin(da)
'Paint.Scale(1.2, 1.2) '' Qui non ho capito bene se si può zoomare senza agire sui font!
Case "Stampante"
Paint.Begin(miaStampante)
Case Else
' Avete idea di quale altro caso?
Return
End Select
'Spazi iniziali di 20 mm.
fSpazInLarg = 20 / MM_X_PX
fSpazInAlt = 20 / MM_X_PX
fLarghezza = 150 / MM_X_PX
fAltezza = 80 / MM_X_PX
Paint.Background = Color.Black
Paint.Rectangle(fSpazInLarg, fSpazInAlt, fLarghezza, fAltezza)
Paint.Stroke(True)
Paint.Save
Paint.Clip
Paint.Font.Size = fFontVideo
Print Paint.Font.Size
Print Paint.Font.TextWidth(sTestoText)
'Qui inserisco un ciclo per ridurre la scritta e farla stare all'interno del rettangolo.
While Paint.Font.TextWidth(sTestoText) > fLarghezza
Paint.Font.Size = Paint.Font.Size - 0.1
Wend
If sDevice = "Stampante" Then Paint.Font.Size = Round(Paint.Font.Size * F_GAMBERETTO_STAMPA, -2)
Print Paint.Font.Size
'Paint.Restore
Paint.Text(sTestoText, fSpazInLarg, fSpazInAlt + 50)
Print sTestoText
Paint.Fill(True)
Paint.Restore
Paint.Font.Size = fFontVideo
If sDevice = "Stampante" Then Paint.Font.Size = Round(Paint.Font.Size * F_GAMBERETTO_STAMPA, -2)
Print Paint.Font.Size
'Paint.Background = Color.Blue
Paint.Text(sTestoText, fSpazInLarg, fSpazInAlt + 100)
Paint.Fill
Paint.End
End
Public Sub Button3_Click()
' Invece di cancellare e basta ripristina la scritta di default
' altro trucco copiato ma non mi ricordo più da chi :)
TextBox1.Text = "TO BE OR NOT TO BE: THAT IS THE QUESTION"
End
Public Sub Button1_Click()
fFontVideo = Round(fFontOrig * F_FSURFING_VIDEO, -2)
Print fFontVideo
'Disegna
DisegnoX("Video")
End
Public Sub TextBox1_Change()
sTestoText = TextBox1.Text
End
Public Sub Button2_Click()
'' Come giustamente ricorda fsurfing se vuoi risparmiare carta stampa le prove su file PDF.
fFontVideo = Round(fFontOrig * F_FSURFING_VIDEO, -2)
With miaStampante
If .Configure() Then Return
'Verticale
.Orientation = 0
.PaperWidth = 210
.PaperHeight = 297
'.OutputFile = "/home/gianluigi/ProvaGambas.pdf" ' vedi sotto!
'' metti il tuo nome^
.Resolution = 300 ' Desktop.Resolution '200 '100
.FullPage = True 'parte da X0 e Y0 di paper
'Print .Resolution
End With
Me.Enabled = False
Inc Application.Busy
miaStampante.Print
Dec Application.Busy
Me.Enabled = True
End
Per quelli che come me sono poco istruiti riporto l'esemplificazione di come è stato ottenuto il fattore video fattami da fsurfing che è veramente chiara, io per mia maggiore comprensione ho inserito dei numeri che ho lasciato e messo fra parentesi:
''###################################codice di esempio####################################################
Paint.Font.Name = "Ubuntu"
Paint.Font.size = 11
'sapento che un il testo "TESTOCORTO" IN UBUNTU 11 in stampa occupa 24mm in larghezza
'procedo empiricamente costringendo il programma a diminuire il font finchè la larghezza corrisponde
While Paint.Font.TextWidth("TESTOCORTO") > 24 / fMm_x_Dot ' (0.352778)
Paint.Font.Size = Paint.Font.Size - 0.1
Wend
'uscendo da while il font avrà la dimensione corretta
font_finale = Paint.Font.size
'ora creo un equazione
'dim_font_campione:font_finale=nuovo_font:x
'quindi:
'dim_font_campione/font_finale=nuovo_font/x
'********* (11) **** (8.184) **(es.26)
'ovvero
'xr=nuovo_font*(font_finale/dim_font_campione)
'
'considerando
r = font_finale / 11
'e quindi
'il font da usare per mostrare a video le giuste proporzioni va moltiplicato per r
Message.Info("il rapporto per il video è: " & Chr(10) & Round(r, -4)) ' round serve per arrotondare
'##################fine codice di esempio########################################################################################
Continuando con lo stesso ragionamento e udite udite si potrebbe quasi sostenere che è farina del mio sacco:
z = Round(11/8.184,-4) che corrisponde a 1.3441 ora abbiamo anche il fattore che ci riporta un font proporzionato alla stampa e che serve come avete visto nell'esempio di codice quando dobbiamo rimpicciolire i caratteri per far rientrare la stringa in uno spazio più piccolo.
Bene io spero che questa discussione sia stata proficua, per me lo è stata moltissimo ho imparato diverse cose fra cui una molto confortevole che ci sono persone che si aiutano e questo fa sempre bene all'umore.
Comunque prima di mettere RISOLTO sarà meglio che attenda un attimino i vostri pareri e poi non vorreste rispondere alle ultime domande scusate? ;) :ok: