StyledTextPrinter

Buona sera,

uso il codice che vi allego qu sotto per creare immagini
partendo da una textArea.

/// immagine una propriet della window
immagine = new picture(300, 300)

/// StyledTextArea la TextArea dove ho il testo
dim t as TextArea = StyledTextArea

Dim p as StyledTextPrinter
p=t.StyledTextPrinter(immagine.Graphics,immagine.Width)
p.DrawBlock (0,0,immagine.Height)

Canvas1.Invalidate

Questo funziona perfettamente su mac, su win no…
Qualcuno conosce un modo per ottenere la stessa cosa su Windows?

Grazie
Enzo

Funziona ma non puoi ottenere direttamente un’immagine trasparente
Se crei l’immagine come new picture(300, 300, 32) funziona
Segnala il bug che sottoscrivo il feedback

Allo stato attuale per ottenere l’immagine trasparente devi ad esempio operare in questo modo:

[code]Private Function getStyledPicture(t as textarea, w as integer, h as Integer) as Picture
#if TargetWin32
dim pp as new Picture(w,h,32)
Dim stp As StyledTextPrinter=t.styledTextPrinter(pp.Graphics,w)
stp.DrawBlock(0,0,w)

dim r as RGBSurface=pp.RGBSurface
dim m as RGBSurface=pp.Mask.RGBSurface
dim ww as integer=pp.Width-1
dim hh as integer=pp.Height-1
dim mx as integer
dim c as Color
for y as integer=0 to hh
  for x as integer=0 to ww
    c=r.Pixel(x,y)
    mx=min(c.Red, c.Blue, c.Green)
    m.Pixel(x,y)=color.rgb(mx, mx, mx)
  next
next
dim retPicture as new Picture(w,h)
retPicture.Graphics.DrawPicture pp,0,0
Return retPicture

#else
dim retPicture as new Picture(w,h)
Dim stp As StyledTextPrinter=t.styledTextPrinter(retPicture.Graphics,w)
stp.DrawBlock(0,0,w)
Return retPicture
#endif
End Function[/code]

In questo caso anche su win hai un risultato accettabile

Ciao Antonio,
prezioso come sempre quando ci son da risolvere casi impossibili !!!

Si cos funziona per se la TextArea grande quanto un foglio A4 ci mette un bel p…
Azz…

Visto che siamo in tema di testo stilizzato avrei un’altro quisito da porti:

ho 2 TextArea t1 e t2

in t1 scrivo del testo stilizzato
ora devo scalare il testo contenuto in t1 (ad esempio * 1.2) e scriverlo nella t2
in modo da avere lo stesso testo di 2 grandezze diverse.

ora lo faccio con un ciclo for che parte dal primo carattere di t1 lo scala e lo scrive in t2
cos fino alla fine

tu conosci un modo migliore?

Grazie
Enzo

Per farlo durare meno devi usare qualche #pragma prima del ciclo di “copia”
Ma questo ciclo ti serve solo se vuoi l’immagine trasparente. Se ti interessa con lo sfondo bianco puoi evitarlo del tutto.
In ogni caso, come ti ho detto, un bug di windows sotto gdi+ e ti consiglierei di segnalarlo.

Sub scaleText(tSourc as TextArea, tDest as TextArea, factor as Double)
  dim st as StyledText
  st=tSourc.StyledText
  
  dim n as integer=st.StyleRunCount-1
  dim stt as StyleRun
  for i as integer=0 to n
    stt=st.StyleRun(i)
//Duplico quello che mi interessa
    tDest.SelBold=stt.Bold
    tDest.SelItalic=stt.Italic
    tDest.SelTextColor=stt.TextColor

//Scalo il carattere
    tDest.SelTextSize=stt.Size*factor

//Copio il testo
    tDest.SelText=stt.Text
  next
End Sub

@Enzo Callegari [quote]Si così funziona però se la TextArea è grande quanto un foglio A4 ci mette un bel pò…[/quote]

Vedendo lo snippet di Antonio, mi è venuto in mente il codice impiegato da un Example Project nella cartella Platform Specific > Windows: WindowShape, per creare finestre trasparenti.
Anche quel codice (che impiega un loop in certo qual modo simile a quello di Antonio) funziona a dovere quando l’immagine è piccola, ma di fronte ad un immagine (rotonda) di 550x550 ci vogliono parecchi secondi, anche usando parecchi “Pragma”.
Chiedo scusa se quindi mi intrometto con una domanda estranea al topic in corso, ma qualcuno è mai riuscito a creare una finestra trasparente di rispettabili dimensioni (es. 550x550) in meno di un secondo?
In piattaforma Mac, usando macosLibrary, la resa è immediata.

Utilizzando
#Pragma BackgroundTasks Off
#Pragma BoundsChecking Off
#Pragma StackOverflowChecking Off
prima dei loop e impostando a delle variabili le dimensioni, ovvero non facendole calcolare ad ogni iterazione, qualcosa guadagni.
Ma chiaramente un metodo “estremo”

I vari #Pragma li avevo utilizzati, come pure avevo impostato le dimensioni a delle variabili, ma purtroppo il guadagno non era stato tale da poter utilizzare tale funzione. Alla fin fine avevo applicato all’immagine circolare uno sfondo colorato e usato tale immagine (non più circolare ma quadrata) come backdrop della splash window.
Grazie per la risposta.

Ciao Antonio,
grazie per la dritta su come scalare il testo.
Decisamente meglio di come facevo io!!!

Con la stessa tecnica per non riesco a farlo girare se la tSource e tDest sono le stesse…

Conosci un modo per farlo

grazie
Enzo

Eccolo:

Public Sub scaleText(tSourc as TextArea, factor as Double)
  dim st as StyledText
  st=tSourc.StyledText
  
  dim dt as new StyledText
  
  dim n as integer=st.StyleRunCount-1
  dim stt,dtt as StyleRun
  for i as integer=0 to n
    stt=st.StyleRun(i)
    dtt=new StyleRun
    
    //Duplico quello che mi interessa
    dtt.Bold=stt.Bold
    dtt.Italic=stt.Italic
    dtt.TextColor=stt.TextColor
    
    //Scalo il carattere
    dtt.Size=stt.Size*factor
    
    //Copio il testo
    dtt.Text=stt.Text
    
    //Appendo il nuovo StyleRun
    dt.AppendStyleRun dtt
  next
  
  //Cambio tutto
  tSourc.StyledText=dt
End Sub

Ciao Antonio,
grazie

subito non posso provarlo ma ti faccio sapere.

Per quel bug che abbiamo riscontrato su window
io non sono riuscito a dar funzionare il mio feedback
ho anche scaricato l’ultima versione ma picche…
per cortesia puoi segnalarlo tu?

Grazie
Enzo

Era gi stato segnalato tempo fa:<https://xojo.com/issue/29280>

Magari se altri lo sottoscrivono il suo punteggio sale

Ciao Antonio,

per cortesia sai darmi lumi sulla situazione del bug?

grazie
Enzo

Ciao Enzo,
ho promosso ulteriormente il feedback, vediamo cosa succede.

in ogni caso il tuo problema che l’immagine su windows non trasparente?

Ciao Antonio,
si devo creare un’ immagine trasparente delle dimensioni di un A4 a 300 dpi.
Il metodo che crea l’immagine viene richiamato dall’evento TextChance della TextArea, ad ogni carattere digitato devo ricreare l’immagine. La soluzione che mi hai suggerito per aggirare il bug su windows funziona ma lentissimo per una immagine cos grande e sopratutto per il fatto che deve ricreare l’immagine ogni volta che viene digitato un carattere.

Grazie per il tuo interessamento
Enzo Callegari

Immaginavo.
Ho sollecitato una review del Feedback, visto che con l’ultima release si cambiato il motore grafico di Windows. Magari riusciamo ad agganciarlo a quello.

Ciao Antonio,
speriamo che lo sistemino presto altrimenti sono nei guai…

Grazie
Enzo

Ho trovato un workaround che dovrebbe essere veloce

Private Function getStyledPicture(t as TextArea, w as integer, h as integer) as Picture
  #if TargetLinux
    //Non disponibile su Linux
    Return nil
  #Elseif TargetWindows
    //Creo l'immagine come al solito
    dim retPicture as new Picture(w,h)
    Dim stp As StyledTextPrinter=t.styledTextPrinter(retPicture.Graphics,w)
    stp.DrawBlock(0,0,w)
    
    //Preparo la maschera con il fondo bianco in quanto DrawBlock riempie solo la parte utile
    dim mPicture as new Picture(w,h)
    mPicture.Graphics.ForeColor=&cffffff
    mPicture.Graphics.FillRect 0, 0, w, h

    //Cambio i colori in nero e li memorizzo
    dim st as StyledText
    st=t.StyledText
    dim vColors() as color
    dim n as integer=st.StyleRunCount-1
    dim stt as StyleRun
    for i as integer=0 to n
      stt=st.StyleRun(i)
      vColors.Append stt.TextColor
      stt.TextColor=&c000000
    next

    //Riempio la maschera
    stp=t.styledTextPrinter(mPicture.Graphics,w)
    stp.DrawBlock(0,0,w)

    //Ripristino i colori originali
    for i as integer=0 to n
      stt=st.StyleRun(i)
      stt.TextColor=vColors(i)
    next
    
    //Applico la maschera
    retPicture.ApplyMask mPicture

    Return retPicture
  #Else //MAC tutto semplice
    dim retPicture as new Picture(w,h)
    Dim stp As StyledTextPrinter=t.styledTextPrinter(retPicture.Graphics,w)
    stp.DrawBlock(0,0,w)
    Return retPicture
  #Endif
End Function

Ciao Antonio,
grazie infinite per il tuo interessamento!!
Per qualche giorno non ho modo di testarlo ma appena ho fatto ti aggiorno.

Grazie
Enzo

Ciao Antonio,
ho fatto un paio di prove,
con questo metodo effettivamente la risposta sulla textarea editata leggermente migliore, ma sembra ritornare un’ immagine completamente trasparente… ed in ogni caso rimane sempre troppo lenta…

Non ho la possibilit di provarla in debug da windows…

Ti allego un link per aggiornarti su cosa ne venuto fuori con il tuo aiuto…
www.ifuner.it

Grazie
Enzo Callegari

Mi sembra strano. Forse ti sei scordato di fare il rendering sulla pagina principale.
Una nota: ovviamente in DrawBlock il parametro h non w.

In pratica hai solo il tempo di creazione dell’immagine doppio (in quanto crei l’immagine e la maschera). Il tempo per settare il colore a nero e poi ripristinarlo trascurabile a meno che tu non abbia migliaia di stili nello stesso testo.
Certo poi dipende dalla macchina, sistema operativo e versione di Xojo.
Io ho utilizzato una macchina virtuale Win10 con l’ultima versione di Xojo e l’ho testato anche con l’attuale pre-release.
In realt ho anche una versione che HiDpi ready.