giovedì 24 maggio 2007

Struttura base script

Di seguito presentiamo uno script che può servire come modello di base per lo sviluppo dei vostri progetti. Sulla bachceca del corso c'è un pdf scaricabile con il listato ragionato. Buon lavoro!

import robofab
from robofab.world import CurrentFont
font = CurrentFont()
# inserisco i miei parametri
l=500 # attributo larghezza
h=500 # attributo altezza
r=50 # r è il mio parametro di graziatura della lettera

# LETTERA ‘c’
g = font[“c”]
g.clear()
pen=g.getPen()
pen.moveTo((l,r))
pen.lineTo((l,0))
pen.qCurveTo((0,-h/5),(0,h+h/5),(l-l/10,h))
pen.lineTo((l-l/10,h-r))
pen.closePath()
g.update()

# LETTERA ‘e’
g = font[‘e’]
g.clear()
pen=g.getPen()
pen.moveTo((l-l/20,r))
pen.lineTo((l-l/20,0))
pen.qCurveTo((0,-h/5),(0,h+h/20),(l,h+h/20),(l,h*0.62))
pen.lineTo((0+l/50,h*0.62))
pen.closePath()
g.update()

# routine per il raffinamento dei tracciati e l’expand stroke
# le istruzioni sono applicate a ogni glifo della font creato
for glifo in fl.font.glyphs :
g = glifo.index
fl.Select(g)
fl.iglyph = g
fl.EditGlyph()
fl.CallCommand(40156)
glifo[glifo.nodes_number-1].selected = 1
fl.CallCommand(32812)
fl.CallCommand(33622)
fl.CallCommand(32846)

# comando di aggiornamento
font.update()

#ciclo for in per l’assegnazione di spaziatura ai glifi della font
for glifo in font:
fl.Select(glifo.name)
print glifo.name
glifo.leftMargin=l/5
glifo.rightMargin=l/7

font.update()

18 commenti:

boot ha detto...

Path e sub path e quant'altri ne volete, basta usare il moveTo e cambiare un parametro
Qua un esempio

import robofab
from robofab.world import *
font = CurrentFont()
g = CurrentGlyph()

g.clear()
pen=g.getPen()
pen.moveTo((0,400))
pen.lineTo((0,0))
pen.lineTo((200,400))
pen.closePath()

pen.moveTo((0,250))
pen.lineTo((150,250))
pen.closePath()


g.update()


#inizio codice
g = fl.iglyph
glifo = fl.font.glyphs[g]
fl.EditGlyph()
fl.CallCommand(40156)
# il parametro da cambiare è questo qua sotto
glifo[glifo.nodes_number-1].selected = 0
fl.CallCommand(32812)
fl.CallCommand(33622)
#fine codice

Manuel Colombo ha detto...

Grande Fede, appena ci vediamo ti offro una birra.

Visto che le mie provocazioni creano interessanti sviluppi, provo a sottoporre a tutti un altro mio cruccio:

è possibile definire il pennino a priori?
senza far apparire la form dove inserire i valori di grandezza, inclinazione, ecc...
parametrizzando ad inizio codice anche quello, in modo da poter gestire i tracciati anche in relazione allo spessore dei tratti.

se qualche temerario volesse darmi una mano in questo, in palio c'è sempre la birra ;)

Manuel Colombo ha detto...

purtroppo lo script di dfe non funziona se si utilizzano delle curve, in realtà lo script non fa altro che non cancellare l'ultimo punto della path (quello che chiude) se le linee sono rette non c'è nessun problema poiché si ricalcano ma una linea curva viene chiusa seguendo altre traiettorie.

federica colamaria ha detto...

Ho problemi con lo script di base: copiandolo nella edit macro ed avviandolo mi dà errore
alla stringa: g = glifo.index

mi appare il seguente messaggio:
SyntaxError: invalid syntax
File "string", line 38
g = glifo.index
^
IndentationError: expected an indented block

Praticamente non riesco ad usare il codice di routine per il raffinamento dei tracciati
e l’expand stroke e quello per l’assegnazione di spaziatura ai glifi della font.

Non venendone a capo, ho provato comunque a scrivere dei parametri comuni alle lettere, ma
ho il problema della sovrapposizione delle lettere. copio sotto i codici reletivi alle
lettere "C" ed "I":




#SCRIPT CREAZIONE ALFABETO

#comandi caricamento libreria robofab
import robofab
from robofab.world import CurrentFont
font= CurrentFont()

#definizione parametri
l=300 #larghezza lettera
h=600 #altezza lettera
r=50 #graziatura(in realtà non saprei come definirlo)
c=-100 #curvatura tratti

#LETTERA C:
g= font["C"] #richiamo lettera "C"
g.clear() #pulisco schermo

#DISEGNO LETTERA C:
pen=g.getPen()
pen.moveTo((h,r))
pen.qCurveTo((2*r,0+c),(r,l-r+c))
pen.qCurveTo((r,h+c),(h,h+c))

pen.closePath()
g.update()
#inizio codice vedi scheletro
g = fl.iglyph
glifo = fl.font.glyphs[g]
fl.EditGlyph()
fl.CallCommand(40156)
glifo[glifo.nodes_number-1].selected = 1
fl.CallCommand(32812)
fl.CallCommand(33622) #disegna col pennino
fl.CallCommand(32846)#unione tratti
#fine codice

#LETTERA I:
g= font["I"] #richiamo lettera "I"
g.clear() #pulisco schermo

#DISEGNO LETTERA I:
pen=g.getPen()
pen.moveTo((h,12*r))
pen.qCurveTo((12*r,0-c/4),(12*r,l-12*r-c/4))
pen.qCurveTo((12*r,h-c/4),(h,h-c/4))

pen.closePath()
g.update()
#inizio codice vedi scheletro
g = fl.iglyph
glifo = fl.font.glyphs[g]
fl.EditGlyph()
fl.CallCommand(40156)
glifo[glifo.nodes_number-1].selected = 1
fl.CallCommand(32812)
fl.CallCommand(33622) #disegna col pennino
fl.CallCommand(32846)#unione tratti
#fine codice





Al di là di tale esperimento, mi sono accorta di un fatto strano, ovvero che il medesimo
codice usato per il disegno della "C" dà origine a lettere differenti se ai parametri
iniziali si attribuiscono determinati valori. Ho fatto alcuni esperimenti, in realtà
non so quanto siano utili e pertinenti.....comunque ecco cosa ho ricavato per ora:

ALTRO APPROCCIO:

1) individuazione dei parametri di base, uguali per tutto l'alfabeto:

l= larghezza lettera
h= altezza lettera
r= "graziatura"
c= curvatura tratti


2) creazione di un unico codice, sempre identico, per il disegno di più lettere:


ad es. per la "C" (ma dovrebbe essere lo stesso con qualsiasi lettera):

#LETTERA C:
g= font["C"] #richiamo lettera "C"
g.clear() #pulisco schermo

#DISEGNO LETTERA C:
pen=g.getPen()
pen.moveTo((h,r))
pen.qCurveTo((2*r,0+c),(r,l-r+c))
pen.qCurveTo((r,h+c),(h,h+c))

pen.closePath()
g.update()




3) Esperimenti su assegnazione valore ai parametri, variando i quali
varia la lettera che scaturisce da suddetto codice. I valori sono stati assegnati
in seguito a risultati casuali, ma sto cercando di ragionare su come poterli assegnare
ai parametri secondo una logica, una sorta di "parametrizzazione" anch'essa.
Di seguito gli esperimanti fatti sui valori:


SE:

l=300 oppure 100 h=600 200
r=50 0
c=-100 0
OTTENGO: lettera "C"


(i valori riportati sono di esempio, ma la lettera appare comunque se si variano i valori
secondo la medesima logica)


SE: valori centrali uguali

l=300 h=600
r=600
c=10
OTTENGO: lettera "D"





SE:valori tutti uguali

l=600 h=600
r=600
c=600
OTTENGO: lettera "L"



SE:

l=300 oppure 600 h=600 600
r=600 600
c=600 300
OTTENGO: lettera minuscola "b"



SE:

l=500 oppure 0 h=0 0
r=0 0
c=0 500
OTTENGO: lettera "I"






Questo è quanto ho fatto al momento....mi chidevo se potesse essere di una qualche utilità
o se è meglio lasciar perdere....Se qualcuno sa dirmi qualcosa lo ringrazio!

federica colamaria ha detto...

...scusate, riscrivo meglio i valori:



SE:

l=300
h=600
r=50
c=-100
oppure
l=100
h=200
r=0
c=0
OTTENGO: lettera "C"


(i valori riportati sono di esempio, ma la lettera appare comunque se si variano i valori
secondo la medesima logica)


SE: valori centrali uguali

l=300 h=600
r=600
c=10
OTTENGO: lettera "D"





SE:valori tutti uguali

l=600 h=600
r=600
c=600
OTTENGO: lettera "L"



SE:

l=300
h=600
r=600
c=600
oppure
l=600
h=600
r=600
c=300
OTTENGO: lettera minuscola "b"



SE:

l=500
h=0
r=0
c=0
oppure
l=0
h=0
r=0
c=500
OTTENGO: lettera "I"

Anonimo ha detto...

@Manuel
ni…
attualmente i CallCommand non fanno altro che richiamare delle funzioni di FontLab. Dato che FontLab ltd. non rende pubblici tali metodi la soluzione è scrivere un algoritmo di expand stroke alternativo. Giro comunque la domanda a Giorgo nel caso lui abbia più informazioni o uno script.

@Federica

purtroppo nel pubblicare lo script sono saltate delle formattazioni. Magari è anche un problema di browser. Sostituisci [‘e’] con gli apici singoli o doppi dalla tua tastiera e vedrai che andrà (il blocco compreso tra parentesi quadre si deve colorare di rosso). Inoltre ti darà un intentation error, aggiungi dei rientri dopo la dichiarazione di ogni ciclo for.

il parametro r, graziataura, serve a definire una variabile che puoi richiamare ogni volta che devi applicare la grazia. Così come l'hai implementata non mi pare di vederci un uso finalizzato a questo scopo. Lo usi come punto coordinata di curve senza disegnare alcuna grazia.

non so che 'I' tu voglia fare ma hai messo due curveTo. Non basta un moveTo solo?

al punto 3 ammetto di essermi perso. I parametri che tu assegni non disegnano una lettera automaticamente. Sono valori fissi che richiami quando disegni.

Anonimo ha detto...

Federica rimane valido quello che ti han detto i professori in classe, non ero al corrente della situazione.

federica colamaria ha detto...

grazie, ho risolto i problemi con lo script...per quanto riguarda il resto, sì, infatti tutto è nato da un tentativo di disegnare una "C" e poi da una serie di casualità, pertanto ammetto che la "logica" che vi è dietro sia discutibile...parlandone però con i professori, è sembrato interessante provare comunque ad approfondire l'esperimento....vedremo cosa ne salta fuori!

Anonimo ha detto...

Riguardo al problema della presenza di due o più tracciati in uno stesso glifo, sono riuscito a disegnarli dando a ciascuno un "nome di riferimento", ma senza riuscire nella corretta eliminazione dei punti di chiusura. Il fatto è che non so come applicare il comando a ciascuno di questi tracciati e in generale se questa cosa dei nomi possa servire a qualcosa.
Nella speranza che sia di ispirazione per qualcuno scrivo di seguito un esempio.

#inizio del codice
import robofab
from robofab.world import *
font=CurrentFont()

#inserisco i miei parametri
y=500
x=y/(1.95/1.3)
z=y/1.95

glif=font['B']
#pulisco lo schermo
glif.clear()
#inizio a disegnare usando i parametri sopra definiti
pen=glif.getPen()

path1=(pen.moveTo((0,0)),
pen.lineTo((0,y)),
pen.lineTo((x/3.5,y)),
pen.qCurveTo(((12*x)/13,y),((12*x)/13,z),(x/3.5,z)),
pen.lineTo((0,z)),
pen.endPath()
)

path2=(pen.moveTo((x/3.5,z)),
pen.qCurveTo((x,z),(x,0),(x/3.5,0)),
pen.lineTo((0,0)),
pen.closePath()
)

#comando di aggiornamento
font.update()

Anonimo ha detto...

Anche io e fede ci stiamo provando ma con scarsi risultati... per ora ci accontentiamo di usare lo stesso tracciato per tutto il glifo.

Invece, oggi volevo provare a usare il nostro font, ma per utilizzarlo bisogna assegnare l'unicode a ciascun glifo.

Per chi non lo sapesse, ecco la funzione:

for glifo in font:
g = glifo
g.autoUnicodes()

Manuel Colombo ha detto...

Ragazzi, era una ca**ta, bastava leggere il manuale ed usare appendGlyph

ecco il codice (occhio all'indentazione)

import robofab

from robofab.world import CurrentFont
font = CurrentFont()

g1= font['b']

g.clear()



pen=g.getPen()



pen.moveTo((0,0))

pen.curveTo((50,50),(70,70),(100,100))

pen.closePath()

g1= font['c']

g.clear()

pen=g.getPen()

pen.moveTo((200,200))
pen.curveTo((250,270),(270,270),(300,300))
pen.closePath()


for glifo in fl.font.glyphs:

g=glifo.index

fl.Select(g)

fl.iglyph=g

fl.EditGlyph()

fl.CallCommand(40156)

glifo[glifo.nodes_number-1].selected = 1

fl.CallCommand(32812)

fl.CallCommand(33622)

g1= font['b']



g2= font['c']



g3=font['a']



g3.clear()



g3.appendGlyph(g2)



g3.appendGlyph(g1)



g3.update()

mattjakob ha detto...

ciao.
è un po che non mi faccio vivo (anche in classe)... quindi ho pensato di iniziare a mettere il link del mio progetto anche se molte cose non sono ancora on-line.
Giusto per dire che anch'io ci sono :-D

CODE.MATTJAKOB.COM/GROWING_TXT/

Le uniche cose divertenti sono le applets che si trovano come link nelle varie "fasi" (sezione "overview").

ZAO - MJ

Chef Rien Argént ha detto...

da anche a me sto errore:

SyntaxError: invalid syntax
File "string", line 38
g = glifo.index

non ho capito se e come l'avete risolto

Manuel Colombo ha detto...

devi indentare questa parte in modo che python la consideri interna al ciclo for

g=glifo.index

fl.Select(g)

fl.iglyph=g

fl.EditGlyph()

fl.CallCommand(40156)

glifo[glifo.nodes_number-1].selected = 1

fl.CallCommand(32812)

fl.CallCommand(33622)

Anonimo ha detto...

Vorrei impostare tre variabili (x1, x2 e x3) e dire a Robofab che, per esempio:

_ per 'glifoA', 'glifoB' e 'glifoC' x=x1;

_ per 'glifoD', 'glifoE' e 'glifoF' x=x2;

_ per 'glifoG', 'glifoH' e 'glifoI' x=x3.

Se imposto queste uguaglianze all'inizio del disegno della lettera, tutto ok, funziona; però vorrei impostare il tutto all'inizio del codice, in modo da dover ripetere x=xn per ogni lettera... qualcuno sa dirmi come si può fare?

Grazie...

Anonimo ha detto...

scusate, qualcuno sa dirmi come si fa a impostare la spaziatura in alto e in basso?
che poi sarebbe quella tra le righe...
così andando a capo mi si sovrappongono i caratteri con ascendenti e discendenti...

e altra cosa:
per impostare la spaziatura a tutto uso il ciclo for alla fine, ma per impostarla ai singoli glifi cosa devo scrivere e dove?

se mi fate qualche esempio...

grazie!

Anonimo ha detto...

Per la spaziatura inserisci al termine del disegno della lettera:
g.leftMargin=x
g.rightMargin=y

Se applichi la spaziatura prima di fare l'Expand stroke dovrai tenere conto dello spessore del pennino che andrà ad influenzare l'avvicinamento delle lettere.

Type Design Polimi ha detto...

valentina, guarda nella guida:
font.info.unitsPerEm, ascender e descender
c'è anche un esempio di come impostarle


paolo