diff options
Diffstat (limited to 'files/practicum/Uitlijnen.icl')
-rw-r--r-- | files/practicum/Uitlijnen.icl | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/files/practicum/Uitlijnen.icl b/files/practicum/Uitlijnen.icl new file mode 100644 index 0000000..44bb8ac --- /dev/null +++ b/files/practicum/Uitlijnen.icl @@ -0,0 +1,159 @@ +module Uitlijnen
+
+import StdEnv, StdIO
+
+// Een aantal synomiem types:
+:: UitlijnMode :== Char
+:: Tekst :== String
+:: Woord :== String
+:: Regel :== String
+:: TekstBreedte :== Int
+:: LetterBreedte :== Int
+:: Spatie :== String // De witruimte tussen twee woorden. Lengte > 0, en alle tekens zijn ' '.
+
+// UitlijnMode geeft de mogelijkheden weer van het algoritme.
+Links = 'l'
+Centreren = 'c'
+Rechts = 'r'
+Uitlijnen = 'u'
+
+/* uitlijnen is de functie die je zelf moet schrijven.
+ Argumenten:
+ UitlijnMode: hoe moet de uitvoer uitgelijnd worden (links, gecentreerd, rechts, of uitgelijnd)
+ LetterBreedte: breedte van een letterteken (alle lettertekens zijn even breed)
+ TekstBreedte: breedte van het uitvoervenster
+ Tekst: de brontekst die uitgelijnd dient te worden.
+ Uitvoer:
+ [Regel]: de lijst van regels die onder elkaar getekend worden.
+ De lengte van alle regels moet gelijk zijn.
+*/
+
+uitlijnen :: UitlijnMode LetterBreedte TekstBreedte Tekst -> [Regel]
+uitlijnen ...
+
+
+/* Vanaf hier volgt het voorgegeven deel van het programma dat een venster op je scherm
+ tevoorschijn tovert. Dit deel hoef je niet te snappen. We nodigen je wel van harte uit
+ om eens naar dit stuk functioneel programma te kijken als je nieuwsgierig bent hoe dat
+ werkt.
+ Uit gewoonte is de rest van dit programma in het Engels geschreven.
+*/
+
+// The data types used in the program:
+:: FontInfo
+ = { font :: !Font
+ , width :: !Int
+ , height :: !Int
+ }
+:: State
+ = { fontInfo:: !FontInfo
+ , mode :: !UitlijnMode
+ , window :: !Id
+ }
+
+/* The text to be outlined. You can change this value to test your program. This example contains sufficient
+ problems. ;-)
+*/
+text =: "In dit kleine verhaaltje komen korte woorden voor, zoals 'a', 'b', 'c' en 'd' maar ook " +++
+ "exorbitant lange woorden zoals 'hottentottententententoonstellingexhibitieruimte'. " +++
+ "Je algoritme moet natuurlijk ook regels met zulke lange woorden aankunnen. "
+
+Start :: *World -> *World
+Start world
+# (fontInfo,world) = accScreenPicture (getFontInfo 8) world
+# (windowId,world) = openId world
+# initialState = {fontInfo=fontInfo,mode=Links,window=windowId}
+= startIO SDI initialState initialiseGUI [ProcessClose closeProcess] world
+where
+// initialiseGUI creates the window and menu of this interactive process.
+ initialiseGUI :: (PSt State) -> PSt State
+ initialiseGUI pst=:{ls=state}
+ # (error,pst) = openWindow undef wdef pst
+ | error<>NoError= abort "Could not open the window."
+ # (error,pst) = openMenu undef mdef pst
+ | error<>NoError= abort "Could not open the menu."
+ | otherwise = pst
+ where
+ // mdef defines the menu of the application.
+ mdef = Menu
+ "&File" // The menu title
+ ( // The menu elements
+ SubMenu "Font&Size"
+ ( RadioMenu [ (toString fsize,Nothing,Nothing,noLS (setFontSize fsize))
+ \\ fsize<-[8,10..30]
+ ] 0 []
+ ) []
+ :+: SubMenu "Mode"
+ ( RadioMenu [ (toString mode,Nothing,Nothing,noLS (setMode mode))
+ \\ mode<-[Links,Centreren,Rechts,Uitlijnen]
+ ] 0 []
+ ) []
+ :+: MenuSeparator []
+ :+: MenuItem "E&xit" [MenuShortKey 'q',MenuFunction (noLS closeProcess)]
+ ) [] // The menu has no attributes
+ where
+ // setFontSize sets the new size of the current font and redraws everything.
+ setFontSize :: Int (PSt State) -> PSt State
+ setFontSize fsize pst=:{ls=state,io}
+ # (maybe_info,io) = accWindowPicture window (getFontInfo fsize) io
+ | isNothing maybe_info
+ = abort ("Could not retrieve font information of size "+++toString fsize)
+ | otherwise
+ # info = fromJust maybe_info
+ # state = {state & fontInfo=fromJust maybe_info}
+ # io = appWindowPicture window (setPenFont info.font) io
+ # io = setWindowLook window True (False,look state) io
+ = {pst & ls=state,io=io}
+ where
+ window = state.window
+
+ // setMode sets the new UitlijnMode and redraws everything.
+ setMode :: UitlijnMode (PSt State) -> PSt State
+ setMode mode pst=:{ls=state,io}
+ # state = {state & mode=mode}
+ # io = setWindowLook window True (False,look state) io
+ = {pst & ls=state,io=io}
+ where
+ window = state.window
+
+
+ // wdef defines the window that displays the text.
+ wdef = Window
+ "Uitlijnen" // The window title
+ NilLS // The window contains no controls
+ [ // Window attributes:
+ WindowClose (noLS closeProcess) // Closing the window terminates the program
+ , WindowLook False (look state) // The visible content of the window
+ , WindowId state.window // The identification value of the window
+ , WindowInit (noLS (appPIO (appWindowPicture state.window (setPenFont state.fontInfo.font))))
+ // Set a non-proportional font
+ , WindowViewSize {w=300,h=300}
+ ]
+
+// getFontInfo retrieves the font metrics and non-proportional font.
+ getFontInfo :: Int *Picture -> (FontInfo,*Picture)
+ getFontInfo fsize picture
+ # ((ok,font),picture) = openFont {NonProportionalFontDef & fSize=fsize} picture
+ | not ok
+ = abort "Could not retrieve NonProportionalFontDef from screen picture"
+ | otherwise
+ # (metrics,picture) = getFontMetrics font picture
+ = ({font=font,width=metrics.fMaxWidth,height=fontLineHeight metrics},picture)
+
+// look draws the visible content of the window.
+ look :: State SelectState UpdateState *Picture -> *Picture
+ look {fontInfo,mode} _ {oldFrame,newFrame} picture
+ # picture = unfill newFrame picture
+ # picture = setPenColour Red picture
+ # picture = drawAt {zero & x=framewidth/charwidth*charwidth} {zero & vy=frameheight} picture
+ # picture = setPenColour Black picture
+ = seq [ drawAt {x=i*charwidth,y=y} line.[i]
+ \\ line<-linedtext & y<-[lineheight,2*lineheight..], i<-[0..size line-1]
+ ] picture
+ where
+ linedtext = uitlijnen mode charwidth framewidth text
+ framesize = rectangleSize newFrame
+ framewidth = framesize.w
+ frameheight = framesize.h
+ lineheight = fontInfo.height
+ charwidth = fontInfo.width
|