thinking inside the box: converting scalable vector ...trdata/reports/tr2018-856.pdf · electron...

49
1 Thinking Inside the Box: Converting Scalable Vector Graphics to Encapsulated PostScript Dartmouth Computer Science Technical Report TR2018-856 By Trevor Davis

Upload: others

Post on 20-May-2020

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

1

ThinkingInsidetheBox:

ConvertingScalableVector

GraphicstoEncapsulated

PostScript

DartmouthComputerScienceTechnicalReportTR2018-856ByTrevorDavis

Page 2: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

2 Davis

2

TableofContents1.Introduction............................................................................................................31.1.Background..........................................................................................................................................................31.2.PrimaryTasks.....................................................................................................................................................41.3.OtherTasks..........................................................................................................................................................4

2.DesignDecisions,Frameworks,andLibraries...........................................................52.1.ChoiceofProgrammingLanguages...........................................................................................................62.3.TheElectronFramework...............................................................................................................................72.3.ReactandRedux................................................................................................................................................82.4.ScalableVectorGraphics.............................................................................................................................102.5.AdditionalLibraries......................................................................................................................................113.RenderingShapes...................................................................................................123.1.ANoteonPostScript.....................................................................................................................................123.2.DartDraw’sExportLandingPoint...........................................................................................................123.3.Line-BasedShapes.........................................................................................................................................143.4.Ellipses................................................................................................................................................................213.5.Arcs.......................................................................................................................................................................243.6.RoundedRectangles......................................................................................................................................263.7.BezierCurves...................................................................................................................................................273.7.Text.......................................................................................................................................................................28

4.ComputingBoundingBoxes....................................................................................314.1.TheBoundingBoxObject............................................................................................................................314.2.LinesandFreehandPaths...........................................................................................................................324.3.Rectangles..........................................................................................................................................................344.4.Polygons.............................................................................................................................................................354.5.Ellipses................................................................................................................................................................374.6.Arcs.......................................................................................................................................................................394.7.RoundedRectangles......................................................................................................................................414.8.BezierCurves...................................................................................................................................................41

5.FileSavingandOpening.........................................................................................415.1.SavingfileswithIPC......................................................................................................................................425.2.Openingfiles.....................................................................................................................................................43

6.FutureWork...........................................................................................................446.1.ComplexShapeIntersection......................................................................................................................446.2.ColorFlattening...............................................................................................................................................456.3.FileCompression............................................................................................................................................46

7.Reflection...............................................................................................................47

8.References.............................................................................................................49

Page 3: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

3

1.Introduction

1.1.Background

In1984,avectorgraphicdrawingapplicationcalledMacDrawwasreleasedaspart

ofthefirstAppleMacintoshsystems.Followingitsinitialsuccess,MacDraw

underwentseveraliterationsuntilitbecameClarisDraw1.0v4in1994,which

continuedtofunctiononMacOSXforoveradecade.WhenMacOSX10.5Leopard

debutedinOctober2007,however,itdidnotsupportClassicapplications,including

MacDraw.UsersofIntelbasedMacshavebeenunabletouseMacDrawontheir

machineseversince,promptingacalltocreateacompatibleversionofMacDrawby

theauthorsofIntroductiontoAlgorithms.1

Thecallwentunanswereduntilautumn2017whenProfessorTomCormenof

DartmouthCollegeassignedseveralundergraduatesthetaskofcreatingDartDraw,

areplicaofMacDrawwithafewkeyimprovements.Thesesixundergraduates,

includingmyself,weregivenapproximatelyninemonthstocompletetheirtask,

brokendownintoindividualresponsibilities.

AsoneoftheauthorsofIntroductiontoAlgorithms,Cormenhadpreviouslyused

MacDrawtocreatethefiguresforthebookbyexportingdrawingsfromthedrawing

applicationandembeddingthemwithinhisLaTeXdocuments.Asamemberofthe

1https://en.wikipedia.org/wiki/MacDraw

Page 4: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

4 Davis

4

DartDrawteam,mytaskwastohandlethecreationofEPSfilesfromtheDartDraw

application.

1.2.PrimaryTasks

PostScriptisastackbased,proceduralprogramminglanguagecreatedbyAdobefor

pagedescription.PrinterscanprintdirectlyfromPostScriptfiles.Thereisasimilar

filetypeknownasEncapsulatedPostScript(EPS),whichallowsforthumbnail

imagesoftheresultingPDFaswellasadditionalmetadata.Inparticular,everyEPS

filecontainsinformationabouttheenclosingrectangleoftheimagecreatedbythe

filecalledtheBoundingBox.Thisfeatureisparticularlyusefulforcreatingimages

thatcanbeembeddedinotherfilessuchastextdocuments.

Myprimarytaskforthisthesiswastwofold:

• EnableDartDrawtoexportEPSfilesthatdescribetheimagecreatedbya

user.

• EnsurethattheseEPSfilescontainanink-basedboundingboxoftheimage.

Thecoreofthisdocumentdescribesmyworkonthesetwoprimarytasks.

1.3.OtherTasks

InadditiontohandlingtheEPSexportfunctionality;Imanagedtwootherrelated

tasksinthecreationofDartDraw.

Page 5: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

5

DartDrawneededafilesaveformatsothatuserscansavedrawingsandreturnto

themlater.WhenwecreatedDartDraw,weleveragedtheReduxpredictablestate

container(seesection2.3),whichtracksthestateofauser’sdrawinginanobject

treecalledthestore.Iusedthestoreasthecoreofastandardfilesaveformatwith

theextension“dart.”

Lastly,Icreatedaninter-processcommunicationcomponentintheReactJS

frameworktohandleeventspassedbetweenthemainprocessandwindow

processesinDartDraw.Seesection5.1formoreinformation.

2.DesignDecisions,Frameworks,andLibraries

CreatinganapplicationlikeDartDrawrequiresanunderstandingofmanyexisting

utilitiesthatmakeaprogrammer’slifeeasier.Intheearlystagesofthisproject,the

DartDrawteamspentaconsiderableamountoftimedecidinguponthebase

structureofourproject.Thesectionsbelowdiscussthebenefitsandtradeoffsofour

decisions.

AnonlineGitHubrepositoryisavailableforamorein-depthlookattheproject.

Page 6: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

6 Davis

6

2.1.ChoiceofProgrammingLanguages

Giventheplethoraofprogramminglanguagesthatexisttoday,itwasadaunting

taskforourteamtodecidewhichonetousetocreateDartDraw.Eventually,we

narroweddownourchoicestotwolanguages:SwiftandJavaScript.

SwiftisApple’sproprietaryprogramminglanguagethatisspecificallydesignedfor

easyusewithiOSandOSXapplications.ItworkshandinhandwithObjective-Cand

hasmanycustomlibrariesthatmakethingslikemenuoptionsandstylingtrivialfor

developers.Furthermore,itworkswithApple’sadvancedXcodeIDEthateven

simplifiescertaintaskssuchaslayoutdesigndowntoadrag-and-dropprocedure.

Ontheotherhand,manyundergraduatestudentsdonotknowSwift,andithasa

significantlearningcurve.SwiftisalsoexclusivelyusedforAppleapplications.

JavaScriptbyitselfisprimarilyascriptinglanguageforwebpages,butithas

recentlybecomemoreversatile.Now,librariessuchasReactJSmakeiteasytouse

JavaScriptindesktopapplications.JavaScriptisoneofthemostpopular

programminglanguageswithoneofthefastestgrowinguserbases.Itisfast,multi-

platform,andexpressive.Becauseofitsprevalenceinwebapplications,thereisa

JavaScriptlibraryforvirtuallyeverything.Manyoftheselibrariesresideinthenpm

packageecosystem,anenormouscollectionofJavaScriptlibrariescontrolledbythe

Node.jsJavaScriptruntime(see2.2).

Page 7: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

7

Bothoftheseprogramminglanguagespresentexcellentoptionsforapplicationslike

DartDraw,butourprojectteamwasmuchmorefamiliarwithJavaScriptthanSwift,

makingJavaScripttheclearchoiceforalowentrancebarriertothisproject.Asan

addedbonus,theuseofJavaScriptandcertainlibrariesandframeworksdescribed

belowallowedustomakeDartDrawacrossplatformapplication,includingthe

potentialforaweb-basedversionoftheapplication.

2.3.TheElectronFramework

Thegoalofthisprojectwastocreateauserfriendly,vector-based,robustgraphics

desktopapplication.Tothatend,wedidnotwanttospendexcessivetimeworrying

aboutboilerplatecodingforappframes,menus,andthelike.However,werealized

thatourgoalcouldnotberealizedwithoutconsideringhowthesebasiccomponents

affecttheuserexperiences.TheElectronframeworkprovidedasolutiontothis

conflict.

Accordingtoelectronjs.org,“Electronisaframeworkforcreatingnative

applicationswithwebtechnologieslikeJavaScript,HTML,andCSS.Ittakescareof

thehardpartssoyoucanfocusonthecoreofyourapplication.”2Tobemore

specific,ElectronusesChromium,anopen-sourcewebbrowserprojectstartedby

Google.Thebrowserstructureactsasacontainerofsortsforanofflinedesktop

2“Electron|BuildCrossPlatformDesktopAppswithJavaScript,HTML,andCSS.”Electronjs.AccessedMay9,2018.https://electronjs.org/.

Page 8: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

8 Davis

8

application.Consequentially,Electron-basedapplicationsarecompatiblewithMac,

Windows,andLinuxoutofthebox.Electronevenhandlesnativemenus.

AkeyfeatureofElectronisitsseparationbetweenthemainprocessandthe

browserprocesses.Creation,manipulation,anddestructionofbrowserprocesses

arehandledfromthemainprocess,whichalsohandlesappstartupandmenu

options.BrowserprocessesaretheparentprocessesforeachwindowofanElectron

application.Importantly,thisallowsourteamtocreateamulti-windowapplication

usingaframeworklikeReactJSthatisintendedforsinglepageapplications.Each

windowofDartDrawishandledasaseparateinstanceoftheapplicationthatis

controlledbythemainprocess.

ElectronrunsontheNode.jsruntime.Asaresult,Electron-basedappscanleverage

theentirebodyofthenpmpackageecosystem,includingtheonesdescribedbelow.

2.3.ReactandRedux

React–oftencalledReactJS–isanopensourceJavaScriptlibraryusedforcreating

interactiveuserinterfaces.ThekeyfeatureofReactJSisitsbreakdowninto

components.Acomponentisrenderedindependentlyaccordingtoinputdataanda

stateforeachcomponent.Eachcomponentcanbefurtherbrokendownintosub

components,whichmeansthatapplicationsbuiltwithReactJSareveryscalable.

Importantly,ReactJScomponentscanrenderaccordingtodeveloper-specifiedrules

andanykindofdatathatispassedthroughtheapp.

Page 9: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

9

ReduxisanotheropensourceJavaScriptlibrary,anditisusedtomanagethestateof

theapplication.Reduxstoresthestateofanapplicationinanobjecttreecalledthe

store.SupposeaDartDrawusercreatedadrawingtoexplaintheBreadth-First

Searchalgorithm.Theusermighthaveagraphwithverticesandedges,andthey

mightincludethatgraphseveraltimestodemonstratevariousstagesofthe

algorithm.Itiseasytoimagineanobjecttreewiththedrawingstateattheroot,and

groupsrepresentingthegraphsaschildren.Eachofthegroupswouldhavevertices,

edges,andlabelsaschildren,andeachofthosewouldhavechildrenrepresenting

informationlikedimensions,transformations,andauniqueid.Althoughthisisa

simplifiedexplanationofDartDraw’sReduxstate,itissufficienttoexplainthebasics

oftheinternalstructure.WhentheReduxstateneedstobechanged,anactionis

dispatchedtodoso.Thisideaisexploredfurtherbelow.

AlthoughReactandReduxareseparatelibraries,theyareoftenusedtogether.

ThereisevenanotherJavaScriptlibrarycalledReact-Reduxthatseamlessly

integratesthetwo.ThestateofthedrawingismaintainedbyReduxwhilethe

visualizationofthedrawingishandledbyReact.Whenwewanttochangethe

drawing,weneedtochangeboth.React-Reduxhandlesthiswithitsconnectmodule.

WhenanactionisdispatchedbyReduxtochangetheReduxstate,theconnect

modulemapsthechangingpartsofthestatetoinputoftheappropriateReact

components,therebycausingthemtore-render.

Page 10: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

10 Davis

10

Byutilizingthesethreelibrariesinconjunctionwithoneanother,DartDrawonly

changesthepartsoftheinternalstatethatitneedsto.Atthesametime,individual

componentsofthevisualdrawingre-renderindependently.ADartDrawuser

thereforeexperiencesafastandlightweightapplicationthatletsthemchangethe

drawingwithoutanynoticeabledelay.

2.4.ScalableVectorGraphics

BecausetheElectronframeworkisbasedontheChromiumproject,ourappisable

toleverageChromebrowsersupportforrenderingScalableVectorGraphics(SVG),

anXML-basedstandardforrepresentingtwo-dimensionalgraphicsthatwas

adoptedbytheWorldWideWebConsortium.Notably,SVGsupportsinteractivity,

makingitidealforadrawingappwithinaChromiumshell.

InordertoutilizeSVGasourgraphicsstandard,webasedtheinternalstructureof

theReduxstoreonthesamestandard.Inotherwords,theparametersforvarious

SVGshapesandfiguresarethesameastheparametersforDartDrawfiguresinthe

Reduxstore.Whenausermanipulatesashapeusingtheinteractivecomponentsof

SVGsuchasclickordrag,theyalsomanipulatetheshape’srepresentationinthe

Reduxstore,whichinturnre-rendersthecorrespondingReactcomponents.

Page 11: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

11

2.5.AdditionalLibraries

Anapplicationofthissizeandcomplexityrequiredthatweavoidreinventingthe

wheelwhenpossible.Asawhole,ourteamusedmanydifferentlibrariesalongwith

React,Redux,andReact-Redux.ForthepurposesofexportingEPSfilesandhandling

inter-processcommunication,Ipersonallyreliedontwodistinctlibraries:

• math.jsisamathlibraryforNode.js.Itscorefunctionsdonotdifferinany

meaningfulwayfromJavaScript’sbuilt-inmathlibraryexceptthatmath.js

allowsforcalculationswitharbitraryprecision.Forcomplexcalculations

involvinglarge,irrational,orcomplexnumbers(e.g.solvingquadratic

equations),math.jsisnotonlyhelpfulbutessentialaswell.

• transformation-matrix-jsis“anaffinetransformationmatrixclassfor

JavaScriptthatperformsvarioussuchasrotate,scale,translate[…]and

convertingtoandfromanSVG/DOMmatrix.”3InDartDraw,thislibraryis

usefulinconvertinguseractionsonshapes(transforms)totransformation

matricesstoredaschildnodesofshapesintheReduxstore.These

transformscanpropagatedownthroughtheshapesintheReduxdrawing

statewhenperformedongroups.Whencomputingboundingboxes,itis

sometimesusefultoworkwithcanonicalformsofshapesbeforeapplyingthe

appropriatetransformsviathislibrary.

3“Transformation-matrix-js.”Npm.AccessedMay11,2018.https://www.npmjs.ocom/package/transformation-matrix-js.

Page 12: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

12 Davis

12

3.RenderingShapes

3.1.ANoteonPostScriptAdistinctadvantagewhenitcomestoexportingEPSfilesfromDartDrawisthatEPS

isavectorgraphicsformat,allowingittoeasilyrepresentthescalablevector

graphicsofourapp.EPSalsohastheabilitytodefineproceduresandapply

geometrictransformations.

However,therearenotabledifferencesbetweentherepresentationsoffigures

renderedbyEPSandDartDrawfiguresdescribedintheapplication’sReduxstore.

Mostofthesedifferencesarisefromthestack-basedparadigmofPostScript.All

literalssuchasintegersandfloatsareplacedbythe(Encapsulated)PostScript

interpreteronthestack.PostScriptoperandspoptheirrequirednumberof

argumentsoffofthestackbeforeexecuting.

Section3.2describestheconversionprocessfromReduxrepresentationsofSVGto

figuresrenderedbyEPS.Followingthatsection,theremainderofchapter3

describeshowPostScriptoperandsareusedtorenderthedifferenttypesofshapes

supportedbyDartDraw.

3.2.DartDraw’sExportLandingPoint

TheReactcomponentsthathandlemenuactionsarefoundwithin

DartDraw/src/components.ThefileLeftMenu.jshandlesactionsrelatedtotool

Page 13: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

13

selection,shapemanipulation,andexportingEPSfiles.Eachoftheseactionsis

handledbybuttonswithintheLeftMenurendermethod,whichbindsbuttonclicks

tovariousmethodsoftheLeftMenucomponent.

Whentheexportbuttonisclickedbyauser,thegenerateEpsfunctionfrom

DartDraw/src/eps/eps.jsiscalledwiththedrawingstatenodeoftheReduxstoreas

anargument.ThissimplefunctionlooksthroughallfiguresintheReduxstorebyID

andhandlesthepostscriptgenerationforeachfigure.Thenitappendsthegenerated

EPStoanAdobeEPSpresettemplate.ItalsocreatesaninstanceoftheboundingBox

classtocomputetheboundingboxofthetotaldrawing,whichitwritesintothe

Adobepresettemplate.Finally,thefunctioninvokesthesavedialogandsavesthe

aboveinformationtoafilethatisnamedbytheuser.

ForeachfigureinthedrawingstateoftheReduxstore,anewinstanceofthe

epsShapeclassiscreated.Thisclass-foundinDartDraw/src/eps/epsShape.js–is

responsibleforparsingthefiguresandgeneratingthecorrespondingEPS.This

abstractclasscontainsmethodssuchasgetStrokeWidth,getCoords,andproduceEps,

allofwhichareimplementedbythecorrespondingclassesforeachshape.The

produceEpsmethodreturnsEPS,anditiscalledfromwithineps.jstogeneratethe

contentforeachsavedfile.

Shape-specificclassesarediscussedbelow.

Page 14: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

14 Davis

14

3.3.Line-BasedShapes

PostScriptwascreatedandisprimarilyusedasastandardforprintingdocuments.

Consequentially,thePostScriptgraphicscommandscanbethoughtofas

descriptionsforapen’smovementonpaper.

Forexample,thePostScriptmovetocommandtakestwoarguments:anxcoordinate

andaycoordinate.Whenthiscommandisexecuted,ittakesthetoptwovaluesoff

ofthestackandtreatsthemastheyvalueandxvalue,respectivelybefore“picking

upthepen”andmovingittothespecifiedlocation.ItisworthnotingthatPostScript

alwayshasanotionofthecurrentlocationrelativetotheoriginofthepageatthe

bottomleft-handcorner,whereastheDartDrawappdescribescoordinatesin

relationtotheoriginatthetopleft-handcorner.

Anothercommandcalledlinetoalsotakesanxcoordinateandaycoordinate.Itputs

thepenonthepageatthecurrentlocationanddrawsastraightlinetothegiven

coordinate.

Thisiswheredrawingcommandssuchaslinetobecomeslightlymorenuanced.Ink

isneverrenderedinPostScript-generateddocumentsunlessthecommandstrokeor

filliscalled.Instead,thePostScriptinterpretermaintainsacurrentpaththatis

unrealizeduntiladrawingcommandiscalled.ThisparticularfeatureofPostScript

allowsDartDrawtocreateseverallineswithamovetocommandandseverallineto

commandsbeforerenderingthemallatoncewiththestrokecommand.

Page 15: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

15

Twoothercommandsareworthmentioningbeforediscussingspecificshapes.The

newpathcommandresetsthecurrentpath,afeatureitsharesincommonwiththe

movetocommand.Theclosepathcommanddrawsalineinthecurrentpathfromthe

currentpointtothestartofthecurrentpath.Iftherenderedlinesdonotmakea

cohesiveoutline,PostScriptautomaticallyfillsinthegap.Thiscommandisoften

usedbeforecallingfill.

Thefollowingshapesarerenderedinaverysimilarfashion.Asweshallseein

chapter4,however,theirboundingboxesarerathermorecomplex.

LinesEPSforlinesiscreatedinDartDraw/src/eps/epsLine.js.ThisepsLineobject’s

constructortakesashapeobjectasaparametertotheconstructorandassumesthat

theshapegivenrepresentsaline.Ittakesthefirstpointintheline’spoints attribute

andappliesthepropertransformationsutilizingthetransform-matrix.js libraryand

theline’stransform attribute.Then,itaccountsforthediscrepancybetween

PostScript’scoordinatesystemoriginandDartDraw’scoordinatesystemoriginby

subtractingtheresultingycoordinatesfromtheapplication’scanvasheight.

Afterobtainingtherequiredcoordinates,theproduceEps methodoftheobject

parsesthestrokeattributeofthelinetogetthestrokecolorandtheparsesthe

strokeWidthattributetogetthewidthoftheline.

Page 16: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

16 Davis

16

Finally,theproduceEps methodtakesadvantageofJavaScript’stemplatefeaturethat

allowsvariablevaluestobesubstitutedintoastring.ItcreatesanEPSsnippet

similartothefollowing:

0 0 0 setrgbcolor 5 setlinewidth newpath 10 10 moveto 20 20 lineto stroke (Figure1)

Whichwouldcreateablacklinethatis5pointswidefrom(10,10)to(20,20).

RectanglesandPolygonsBothrectanglesandpolygonsarecreatedinthesamemanneraslineswiththree

keydifferences.

First,awrap-aroundloopthroughthesetofpointsinarectangleorgeneralpolygon

allowstheshapeoutlinetobeclosed.

Second,thecommandsshowninFigure1arerepeatedtwice.Inthefirstofthetwo

identicalsections,thesetlinewidthcommandisomittedandthestrokecommandis

replacedwithfill.ThissequencetellsPostScripttorenderthefilloftheshapebefore

overlayingtheoutline.

Page 17: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

17

Third,theclosepath commandiscalledaftertheendofeachoftheabovesections.

Whenthelinesdonotformacohesivepath(asinFigure2),PostScriptfillsitin

automatically(asinFigure3).Thoughthedifferenceisslight,wecanseethatthe

upperleft-handcornerofFigure2isnotquiterightbecausethepathisnotclosed.

(Figure2) (Figure3)

Free-HandPathsFree-handpathsarerepresentedasanarrayofverysmalllinesbetweencontrol

points.Theyarerenderedinthesamewayaspolygonsexceptthattheyareneither

closednorfilled.Therefore,thefillandclosepathcommandsarenotused.

ArrowsSVGrepresentsarrowsdifferentlythanitrepresentsothershapes.Whendrawing

anarrowheadonaline,SVGfirstrendersthearrowseparatelyinanabstract

viewingbox,whichisvisualizedinauser-friendlydisplaywithintheDartDraw

application.Afterthearrowisrendered,itisattachedtotheappropriatelineby

connectingamarkeronthearrowheadtoamarkerontheline,thusattachingitand

displayinganarrowinthefrontendgraphics.

Page 18: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

18 Davis

18

Renderingarrowsthereforerequiresoneadditionalstepinadditiontothenormal

processofidentifyingandmanipulatingpointsaswithothershapes.

First,wedeterminethearrowhead’sheightandlengtharrowLength andarrowHeight,

whichisamatterofsubtractionofpoints.Inthecaseofbarbedarrowheads,the

arrowheadrepresentationintheReduxstorehasanadditionalpointtoaccountfor

theindentationinthebarbedarrowhead.Weusethispointtocomputeavalue

calledminorLengththatdenotestheEuclidiandistancebetweenthetipofthearrow

andtheintersectionofthelinewiththearrowhead.Thisdistinctionisshownin

Figure4.

(Figure4)

Aftercomputingthesevalues,itisnecessarytoconsiderthelinetowhichthe

arrowheadwillbeattachedinordertocontinuewithrenderingcalculations.First,

supposethatthelineishorizontalandthatthearrowheadispointingtowards(1,0)

ontheunitcircle.Thenwenotethatthetipofthearrowheadisattheendoftheline.

arrowLength

minorLength

Page 19: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

19

Wecancallthispoint𝑃!"#.Theothertwopointsonatriangulararrowhead(ortwo

ofthethreeremainingpointsonabarbedarrowhead)requirethatwefirstcompute

anintermediarypoint,whichwecancall𝑃! .Stillassumingthatthelineishorizontal:

𝑃! = (𝑃!"#. 𝑥 − 𝑎𝑟𝑟𝑜𝑤𝐿𝑒𝑛𝑔𝑡ℎ,𝑃!"#.𝑦)

Lastly,theremainingpoints𝑃!and𝑃!arecomputedrelativeto𝑃! .

𝑃! = (𝑃! . 𝑥,𝑃! .𝑦 − 𝑎𝑟𝑟𝑜𝑤𝐻𝑒𝑖𝑔ℎ𝑡)𝑃! = (𝑃! . 𝑥,𝑃! .𝑦 + 𝑎𝑟𝑟𝑜𝑤𝐻𝑒𝑖𝑔ℎ𝑡)

Notethattheonlydifferencebetweenabarbedarrowheadandatriangular

arrowheadisthatabarbedarrowheadhasanadditionalpoint𝑃!,where

𝑃! = (𝑃!"#. 𝑥 −𝑚𝑖𝑛𝑜𝑟𝐿𝑒𝑛𝑔𝑡ℎ,𝑃!"#.𝑦).

Nowwemusttransformthesepointsaccordingtotheactualpositionoftheline.

Fortunately,itiseasytogettheangleofrotation𝜃 ofthelinetowhichthe

arrowheadisattached.Thenweonlyneedtorotatethepointscomputedaboveby

theangle𝜃togettheactualcoordinatesofthearrowhead.

Finally,weuseamoveto commandandmultiple lineto commandstoconnectthese

pointsinthesamewayaswewouldwitharectangleorotherpolygon.Inthecaseof

atriangulararrowhead,theorderofthesepointsis𝑃!"#,𝑃!,𝑃!,and𝑃!"#.Ifwehavea

barbedarrowhead,thentheorderis𝑃!"#,𝑃!,𝑃!,𝑃!,and𝑃!"#.

Page 20: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

20 Davis

20

Inthecaseofanarrow“tail”astheyarecalledwithintheapp,weonlyneedtoset𝑃!

equaltothestartingpointoftheline(points0and1intheline’spointsattribute),

computethecoordinatesofthearrow’stiprelativeto𝑃! usingthearrowLength,and

processasabove.

Ifarrowsareflipped(accordingtotheBooleanflipattributeinthearrow’sRedux

state),webegininthesamefashionasabove,swap𝑃! and𝑃!"#,andproceedas

above,keepinginmindthatweneedtoinvertthewaythatwecompute𝑃!,𝑃!,and

𝑃!relativeto𝑃! and𝑃!"#sincethedirectionofthearrowsisflipped.

Whilethelogicaboveisallthatisneededtorenderthearrowheads,wearenot

done.Asitstands,wewouldberenderingarrowheadsonalinewithsomespecified

strokethickness.Ifwedonotalterthelineafterrenderingthearrowheads,thenthe

thicknessofthelinewillcauseitto“pokeout”pastthetipofthearrow.Therefore,

weneedtoalterthepointsattributeofthelinebeforemakingitintoalineobject

thatcanberenderedandinfluencetheboundingboxofthedrawing.

Asluckwouldhaveit,wealreadyhavethepointsthatweneed.Bygettingthe

produceEpsmethodofthearrowclasstoreturnanobjectthatincludesdataabout

thearrow’spointsinadditiontotheEPSthatweneedtoexport,wecanchangethe

linetowhichthearrowisattachedwhenwefirstparsetheshapewithineps/eps.js.

Supposethatwehavealinewithaclassictriangulararrowheadthatisnotflipped.

Thepointatwhichwewantthelinetoendisthepointatwhichthelineandthe

Page 21: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

21

arrowheadshapeintersect,whichisofcourse𝑃! .Wecanmakesimilarcomparisons

using𝑃! ,𝑃!"#or𝑃!dependingonwhetherwehaveanarrowheadoranarrow“tail”

andwhetherornottheyareflipped.

Foralinetobemodifiedinthisway,wemustfirstcopytheentiretyoftheoriginal

lineshapeusingDartDraw’sowndeepCopyfunction.Thiswaywecanalterthe

pointsinthecopyandusethattorendertheappropriatelineandaffectthe

boundingbox.Ifweinsteadmodifiedtheoriginallineobjectormodifiedareference

totheoriginalline,itwouldchangethepointsthatthearrowheadusesasreferences

forwheretorenderitself,thuschangingthelocationofthearrowheadandcausing

thesameissueoftheline“stickingout”thatweweretryingtofixinthefirstplace.

Inordertomakesurethatarrowheadsandarrow“tails”arerenderedonthecorrect

lines,eachline’sReduxstatehasfourimportantattributes:arrowHeadId and

arrowTailId,whichdeterminewhicharrowheadswithinthearrowsnodeofthe

Reduxstoretoattachtotheline,and arrowHeadShown and arrowTailShown,which

areBooleanvaluesthatdeterminewhetherornotthearrowheadorarrow“tail”is

renderedandaffectstheboundingboxofthedrawing.

3.4.EllipsesPostScripthasaveryusefulcommandcalledarc thattakesacenterpoint,aradius,a

startingangle,andanendingangleasanargument.Forthemostpart,thiscommand

Page 22: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

22 Davis

22

isusefulindrawingcirclesorpartialcircles.However,withacoupleofclever

modifications,itispossibletousethearc commandtodrawgeneralellipses.

ThefirstmodificationthatwemakeistoapplyPostScriptcoordinatesystem

transformations.Thecommandstranslate, rotate,and scale canbeusedtoaffectthe

PostScriptcoordinatesystemasifthepaperbeingdrawnuponwasbeingshifted,

turned,orstretched.

ThesecondmodificationthatwemakeistodefineaprocedureinPostScript.

Proceduresareapowerfulcomponentofthelanguagethatallowsusersto

modularizecommontasks.Here,weuseittospecifytheorderoftransformations

thatareneededtodrawcomplexshapes.Thefollowingprocedureisusedin

drawingellipseswithinsrc/eps/epsEllipse.js:

/ellipse 6 dict begin /angle exch def /yradius exch def /xradius exch def /yC exch def /xC exch def /savematrix currentmatrix def xC yC translate angle rotate xradius yradius scale 0 0 1 360 arc savematrix setmatrix

(Figure5)TheprocedureshowninFigure5beginsbydeclaringadictionaryforthevariables,

anecessarysyntacticalcomponentofPostScriptprocedures.Theitemsinthe

dictionaryaretheangleofrotationoftheellipse,its𝑦radius,its𝑥radius,the𝑥

Page 23: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

23

coordinateofitscenterpoint,the𝑦coordinateofitscenterpoint,andthecurrent

matrix.Thecurrentmatrix commandreturnsthecurrent3x3transformationmatrix

ofthePostScriptcoordinatesystem.Itallowstransformationstobeappliedand

savedpriortoaproceduresuchas/ellipsesothatthesametransformationmatrix

canberestoredwhentheprocedureexits.

AswecanseefromFigure5,the/ellipse procedureappliestransformationsafter

definingitsdictionary.EllipsesintheDartDrawReduxstorearerepresentedinthe

canonicalform,sotheprocedurefirstmakesatranslationtoresettheoriginofthe

PostScriptcoordinatesystem,followedbyascalinginthexandydirectionsto

stretchthecircleintoanellipse.Finally,arotationinthereversedirectionofthe

rotationoftheellipseisappliedsothattheactual“ink”drawingonthePostScript

coordinatesystemresultsinanellipserotatedbytheintendedamountinthe

correctangulardirection.Lastly,theproceduredrawsacanonicalcircle.

Inorderforthisproceduretowork,wefirstneedtoobtaintheappropriatedatafor

theellipse.Eachellipseinthedrawing.shapes.byIdnodeoftheReduxstorehasthe

followingdata:{cx,cy,fill,id,rx0,ry0,stroke,strokeWidth,transform,type}.Thecx

andcyvariablesarethecoordinatetotranslatetoafterbeingtransformedbythe

transform-matrix.jslibrary.Thetransformedrxvariable(callitrx1)isfoundby

transformingthecenterpoint’sxcoordinate,transformingthepointontheedgeof

theellipsewithbasecoordinates(center.x+rx,center.y),andthetransformedry

Page 24: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

24 Davis

24

variablery1isfoundanalogously.Finally,wehavetoobtaintheangleofrotation,

whichwecandowiththefollowingmethod(showninpseudocode).

Find the point that is rx1 pixels right of the ellipse’s center; call this p0

Transform that point using transform-matrix.js: call this p1

Compute the vector from the center to p1; call this v The cosine of the angle of rotation for v is equal to (v1.y * ry) / (ry2) The above simplifies to v1.y / ry. Call this value c Letα = arccos(c) If v.y < 0, α = - α Return α

(Figure6) Whenallofthevariableshavebeencomputed,theellipseprocedureiscalled.Atthe

endoftheprocedure,thesetmatrixcommandrestorestheprevioustransformation

matrixofthePostScriptcoordinatesystem.Thisstepiscrucialbecauseitoccurs

beforethefill commandiscalled.Ifitdidnot,thenthestrokewouldbeaffectedby

theellipsetransformation.Inthefinaldrawing,theoutlineoftheellipsewouldbe

inconsistentinwidth.

3.5.ArcsArcsinDartDrawcanbeviewedaspartialoutlinesofellipses.Infact,weonlyneed

threeadditionalvariablestorenderarcs–thoughaswewillsee,boundingboxes

requireseveraladditionalconsiderations.

Thefirsttwovariablesarethestartandendanglesofthearc,measuredby

counterclockwiserotationfrom(1,0)ontheunitcircle.Thestartandendpointsof

therotationofthearcaregivenbythepointsattribute.Usingthese,wecancalculate

Page 25: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

25

thetwoanglesinthesamewaythatwecalculatedtheangleofrotationofanellipse.

However,wemustbesuretocalculatetheseanglesbeforeapplyingany

transformations.Otherwise,transformedpointsmaybemistakenfornon-

transformedpoints,resultingininaccurateangles.

ThethirdadditionalvariablethatisneededtorenderarcsisflipArc.Thisisaspecial

SVGcomponentofthearcobjectthattellsuswhichdirectionthearcisdrawn.By

default,flipArcisfalse,whichmeansthatthearcisdrawncounterclockwise

betweenthestartandtheendangleofthearc.IfflipArcistrue,thearcisdrawn

clockwise.TorepresentthisdifferenceinPostScript,thearcncommandisused

insteadofarc,whichtellsPostScripttodrawthearcinthecorrectdirection.

ThePostScriptprocedureforarcsisasfollows:

/arc 8 dict begin /rotateAngle exch def /secondAngle exch def /firstAngle exch def /yradius exch def /xradius exch def /yC exch def /xC exch def /savematrix currentmatrix def xc yc translate rotateAngle rotate xradius yradius scale 0 0 1 secondAngle firstAngle arcDirection savematrix setmatrix

(Figure7)

Here,arcDirectionisequaltoeither“arc”or“arcn.”

Page 26: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

26 Davis

26

3.6.RoundedRectangles

Roundedrectanglesarethesameasnormalrectanglesinalmosteverywayexcept

thattheyhavean𝑥radiusanda𝑦radiusatthecorner.Thesevaluesareequalto

distancesinthe𝑥and𝑦directionfromeachcornertowardstheinsideofthe

rectangle,wheretheresultingpointsarethecentersofellipseswiththexradiusand

yradiusoftherectangleasitsownradii.

Itiseasytorendertheseshapeswithaclevertrick.First,wenotethateachcorner

ofaroundedrectangleisaquadrantofanellipse.Ifweremoveeachofthose

quadrants,across-likeshaperemains(Figure8).

(Figure8)

Wecanrenderthisshapewithtworectangleswithoutastroke.Gettingtherestof

theshapefilledinrequiresthatwerendertheellipsesfirst,thenthecross-like

figureoverthemtooverlapthepartoftheellipses’outlinethatshouldnotbe

showinginsidethefigure.Lastly,werenderthefourlinesthatconnecttheoutlines

oftheellipsequadrants.

Page 27: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

27

Asluckwouldhaveit,wealreadyknowhowtorendereachoftheseshapes,andwe

cantransformallofthemsimultaneouslywhenneededusingthetransformation

matrixoftheroundedrectangleshapeintheReduxstore.

3.7.BezierCurves

InDartDraw,Beziercurvesarecubicratherthanquadratic.CubicBeziercurvesare

representedbytwoendpointsP0andP3alongwithtwointermediarycontrolpoints

P1andP2.Theyaredescribedbythefollowingequation:

𝐵 𝑡 = (1− 𝑡)!𝑃! + 3(1− 𝑡)!𝑡𝑃! + 3 1− 𝑡 𝑡!𝑃! + 𝑡!𝑃!, 0 ≤ 𝑡 ≤ 1

BezierobjectsintheReduxStorehaveapointsattributethatspecifiespointsP0,P1,

P2,andP3foreachcurve.Oncewerotateandtranslatethesepointsaccordingtothe

transformattributeofeachcurve,wecansimplyplugthemintothecurveto

commandofPostScript,asinthefollowingexample:

0 0 moveto 25 50 75 50 100 0 curveto (Figure9) Theabovewouldmovethepento(0,0)thenmakeasemicirclecurveto(100,0)

usingthepoints(25,50)and(75,50)ascontrolpoints.

Page 28: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

28 Davis

28

3.7.Text

PostScripthasaspecialshow commandthatdisplaystextonthescreen.Foritto

workspecifiedtextmustbeonthestackdirectlyontopofaspecifiedfont,as

follows:

/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor newpath 0 0 moveto (hello world) show (Figure10) TheEPSshownaboveusesthefindfont commandtolookuptheappropriatefontin

thePostScriptdictionary.Justastheuser-defineddictionarieswesawearlierto

accessthevariablesusedinthe/ellipseand/arcprocedures,PostScripthasbuilt-in

dictionariesforavarietyofpurposes,includingpre-definedfonts.Italsohasa

fallbackprocedureintheeventthattheuser-specifiedfontisnotfound;inthiscase,

ittypicallyprintsinHelvetica.

TheaboveEPSthenscalesthefonttotheappropriatesizeinpointsandsetsthe

strokecolor. Itbeginsanewpath,movestotheupperleft-handcornerofthetextto

bewritten,andshowsthespecifiedtextusingtheshow command.

Page 29: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

29

Scaling,translating,androtatingtextisfairlystraightforwardaswell,using

commandsthatwehavealreadyseeninearlierprocedures.Forexample,ifwe

wouldliketorotatetextby90degrees,wecandosoasfollows:

/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor gsave newpath 0 0 translate 90 rotate (hello world) show grestore (Figure11)

Notethatthisprocedureislargelythesameasbeforewiththreekeydifferences.

First,weaddarotatecommand.Second,weusethetranslatecommandinsteadof

themovetocommandsothattheoriginofthecoordinatesystemissettotheupper

left-handcornerofthetextandcanberotatedaroundthatpoint.Lastly,weusethe

gsave andgrestore commandstosaveareferencetothecurrenttransformation

matrixofthecoordinatesystempriortoanytransformationsandtorestoreitafter

thetexthasbeenrendered.

ThestructureofthetextboxobjectinDartDrawissuchthatthereisnoautomatic

expansionofthetextboxtoaccommodatetextthatrunsover.Instead,theusersees

textwraparoundtothenextline.Becausethereisnowaytodetectthiswrap

aroundbehaviorfromthebackend,itcannotbehandledbytheexport

functionality.Therefore,weinsteadimposeacoupleofconstraintsupontheuser.

Page 30: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

30 Davis

30

First,anytextthatausertypesbeforeacarriagereturnisassumedtobeonthe

sameline.IftheuserseesthetextwraparoundintheDartDrawdisplay,thisisonly

aproductofthefactthatheorshehasnotmadethetextboxwideenoughto

accommodatethetext.ThecorrespondingEPSfilewillnotrenderanytextthatis

meanttobeonthesamelinebutdoesnotfitwithinthetextbox.Second,the

backendexportfunctionalityusesthenewlinecharacter“\n”asadelimiterwhen

parsing.Theparsercreatesanarrayofstringstodisplayastext,afterwhichit

appliesanynecessarytransformationsandstacksthesestringsonaline.

Forexample,todisplaythefollowingstringoftextinblackHelvetica,startingat

coordinate(100,100),androtatedby45degrees,theexportfunctionalitywould

createtheEPSfragmentshownbelowit:

“Goodmorning,sunshine!TheEarthsays:Hello!”/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor gsave 100 100 translate 45 rotate 0 -24 moveto newpath (Good morning sunshine!) show newpath 0 -48 moveto (The Earth says:) show newpath 0 -72 moveto (Hello!) show (Figure12)

Page 31: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

31

4.ComputingBoundingBoxes

ThemostimportantseparatingfactorbetweenEPSfilesandotherPostScriptfilesis

theconceptofaboundingboxinEPS.Theboundingboxisspecifiedintermsofthe

lowerleft-handxcoordinate(llx),thelowerleft-handycoordinate(lly),theupper

right-handxcoordinate(urx),andtheupperright-handycoordinate(ury).Alarge

portionofmyroleintheDartDrawprojectwastocomputeink-basedbounding

boxesforexportedEPSfiles.

4.1.TheBoundingBoxObject

UsingJavaScriptallowedmetohandlethecreationofboundingboxesinanobject-

orientedfashion.Thefilesrc/eps/eps.jscreatesaboundingboxobject,which

initiallyhasarbitrarilyhighvaluesforllxandllyandarbitrarilylowvaluesforurx

andury;thatis,thereisnoboundingboxasnofigureshaveyetbeenrendered.

Themainjobofeps/eps.jsisthentoparsethroughadeepcopyofthedrawingstate

withintheDartDrawReduxstoretoparseeachshape.Eachoftheseshapesismade

intoanepsShapeobject,whereepsShapeisanabstractclassthatdefinesseveral

methodsincludingproduceEPS,getAngle,andgetCoords.Asitparsesthedrawing

stateandcreateseachepsShapeobject,eps/eps.jscallstheupdateBoundsIfNecessary

methodofthebounding box class,whichtakesanepsShapeasanargument.

Theboundingboxobjectitselfisdefinedwithinsrc/eps/boundingBox.js.The

object’supdateBoundsIfNecessary methodconsistsofaswitchstatementbasedon

Page 32: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

32 Davis

32

thetypeofthegivenepsShape.Forexample,ifthetypeoftheshapeis“ellipse,”the

methodappropriatelycallsitshelpermethodupdateBoundsEllipseHelper.Allsuch

helpermethodshavetheabilitytomanipulatethellx,lly,urx,anduryvaluesofthe

boundingboxobjectbasedontheparametersoftheepsShapeobjectthatit

considers.

Below,IdiscusshowtheboundingboxofeachfigureinDartDrawiscomputed.

4.2.LinesandFreehandPathsForlinesandforallshapes,itisimportanttofirstnotethatastrokeinPostScriptis

dividedoneithersideofapoint.Forexample,averticallineofstrokewidth5,

increasinginyvalueandendingat(10,10)wouldspreadoneithersidetocorner

pointsof(7.5,10)and(12.5,10)(seeFigure9).

(Figure13)

stroke on either side

Page 33: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

33

Second,wemustrememberthattheoriginoftheDartDrawcoordinatesystemisin

theupperleft-handcornerwhiletheoriginofthePostScriptcoordinatesystemisin

thelowerleft-handcorner.It’sthereforenecessarytosubtractthe𝑦valueofashape

fromthecanvasheightoftheDartDrawwindowwheneverthat𝑦valuecomesfrom

theReduxstaterepresentationandwewishtoconvertitanEPSrepresentation.

Theboundingboxesoflinesarefairlyeasytocomputeandformthebasisforthe

boundingboxcomputationsofotherfigures.Giventwopoints𝑃!and𝑃!,wecan

assumeWLOGthatthevectorofthelineistowards𝑃!.Wecangetthe𝑥and𝑦

componentsofthisvectorbysubtractingthecorrespondingpoints.Then,wecan

findtheangleofrotationofthevectorfrom(1,0)ontheunitcircleasfollows:

∆𝑥 = 𝑃!. 𝑥 − 𝑃!. 𝑥∆𝑦 = 𝑃!.𝑦 − 𝑃!.𝑦𝜃 = 𝑡𝑎𝑛!!(∆𝑦,∆𝑥)

NotethattheimplementationofthisequationwithintheDartDrawbackenduses

theatan2functioninplaceof𝑡𝑎𝑛!!,thearctangent.Thatisbecauseatan2can

distinguishbetweendiametricallyopposedanglesandhasarangeof[−𝜋,𝜋]while

𝑡𝑎𝑛!!cannotdosoandislimitedtoarangeof(!!!, !!).

Theendsofthelinesareflat,whichmeansthattheedgeofthisflatlinesegmentis

orthogonalto𝜃.Wecancallthisangle𝜑,and𝜑 = 𝜃 + !!forthepointofthelineend

thatisrotationallyclockwiserelativeto𝑃!.Wecanusethispointasareferenceto

Page 34: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

34 Davis

34

computethe𝑥and𝑦componentsofthevectorbetweenlineendpointsandthe

cornersofthenon-zerostrokeline.Callingthisvector𝑣,weset:

𝑣! = cos 𝜑 × !"#$%&'()"!!

and𝑣! = sin 𝜑 × !"#$%&'()"!!

.

Ourfourcornerpointsarethusequalto:

(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)(𝑃!. 𝑥 − 𝑣! ,𝑃!.𝑦 − 𝑣!)(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)(𝑃!. 𝑥 − 𝑣! ,𝑃!.𝑦 − 𝑣!)

Thenweneedonlycomparethesevaluestotheboundingboxcoordinatesand

updatetheboundingboxaccordingly.

4.3.RectanglesBecauserectanglesarerenderedusinglines,computingtheboundingboxof

rectanglesisaverysimilarprocesstotheoneusedforcomputingtheboundingbox

oflines.However,aswenotedinsection3,PostScriptfillsinthecornersofclosed

shapesrenderedwithlinesafterclosepathiscalled,andwemustaccountforthis.

Becauselinesonlyintersectatanglesof !!inrectangles,weknowthattheadditional

inkfilledinbyPostScriptbetweenrenderedlinesisasquare.Furthermore,we

knowthatthesidesareoflength!"#$%&'()"!!

andthatthediagonalisoflength

!"#$%&'()"!!

× 2.Ifwecanfindtheangleofthevector𝑣fromeachintersectionof

Page 35: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

35

linestothecorrespondingcorneroftheadditionalfilled-inbox,thenwecanfindthe

coordinatesofthecornerofeachfilled-inbox.

Infact,wecansaythatthisangleis𝜑 = 𝜃 − !!

(where𝜃iscomputedinthesame

wayasitisforlines)becausethehypotenuseofthefilled-insquarebisectstheright

angle.Thenweset𝑣! = cos 𝜑 × !"#$%&'()"!!

× 2and

𝑣! = sin 𝜑 × !"#$%&'()"!!

× 2.Foreachlineintherectanglefrom𝑃! 𝑡𝑜 𝑃!,thereis

onlyonesuchcornerpointofafilledinbox.Oncewehave𝑣!and𝑣! ,thispointis:

(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)Thenwecomparethispointtotheboundingboxcoordinatesandupdatethe

boundingbox.

4.4.Polygons

Justastheweneededtoaddanextrasteptomovefromtheboundingboxesoflines

totheboundingboxesofrectangles,wemustaddyetanothersteptomovefromthe

boundingboxesofrectanglestotheboundingboxesofpolygons.

Unlikerectangleswherethecornersarealwaysanglesof !!,thecornersofpolygons

canbeanyangle.Ifthisangleisgreaterthan𝜋,itisnotanextremumofthepolygon,

soitcanbeignored.Supposethatpoints𝑃!,𝑃!,and𝑃!makeacornerat𝑃!.Ifthe

Page 36: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

36 Davis

36

vectorfrom𝑃!to𝑃!hasthesamesignforits𝑥and𝑦componentsasthevectorfrom

𝑃!to𝑃!,thentheangleofthecornerisgreaterthan𝜋,meaningthatwedon’thave

toconsiderthiscornerwhencomputingtheboundingbox.

Otherwise,wemustcomputetheangle𝜔betweenthesetwovectorsforuseinthe

computationofthelengthandangleofthevectorfromtheactualcornertothe

cornerofthefilled-inspace.Wecanusethedotproductrule,whichstatesthat:

𝑨 ∙ 𝑩 = 𝑨 × 𝑩 × cos (𝜔),

so

𝜔 = 𝑐𝑜𝑠!!𝑨 ∙ 𝑩𝑨 × 𝑩

Thefilled-inregionforthecornerofapolygonisaquadrilateralthatcanbebisected

intotwotriangles.Thisdividinglineisthevector𝑣thatwearelookingfor.Sincewe

knowthelengthofoneofthesidesis!"#$%&'()"!!

,andtheangleoppositethissideis

!!,wecanfind 𝑣 .

𝑣 = 𝑠𝑡𝑟𝑜𝑘𝑒𝑊𝑖𝑑𝑡ℎ

2 × 𝑐𝑠𝑐𝜔2

Thenwefindtheangleofrotationof 𝑣fromthepoint(1,0)ontheunitcircle,andwe

callthisangle𝜑.Afterfindingtheangle𝜃ofthevectorfrom𝑃! to𝑃!(computedin

thesamewayasitwasforlines),wecancompute𝜑usingtheparallelogramrule.

Page 37: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

37

𝜑 = 𝜃 +𝜔2

Finally,𝑣! = cos 𝜑 × 𝑣 and𝑣! = sin 𝜑 × 𝑣 ,sowecheckwhetherornotwe

needtoupdatetheboundingboxbasedonthepoint(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!).

4.5.Ellipses

Thefollowingderivationoftheellipseboundingboxequationisbasedonthework

ofMarkC.Hendricks,PhD.

Tobegin,weassumethattheellipseiscenteredattheoriginsincewecanoffsetthe

resultingboundingboxbytheappropriateamountafterthefact.Supposethatwe

havesuchanellipsethathasbeenrotatedaroundtheoriginbyanangle𝛼.Thenwe

recallthatequationforastandardellipsewithhorizontalradiusℎandvertical

radius𝑣:

𝑥!!

ℎ! + 𝑦!!

𝑣! = 1

Here,(𝑥!,𝑦!)isapointontheboundaryoftheellipseaftertheellipsehasbeen

rotatedinreversebyangle𝛼tomakeastandardellipse.Nowwecanfind𝑥!and𝑦!

intermsofthepoints𝑥and𝑦ontheboundaryoftheoriginalnon-rotatedellipse.

𝑥! = 𝑥 cos 𝛼 + y sin 𝛼

Page 38: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

38 Davis

38

𝑦! = 𝑦 cos 𝛼 − 𝑥 𝑠𝑖𝑛 𝛼

Substitutiongetsustheequationofarotatedellipse.

𝑥 cos 𝛼 + y sin 𝛼 !

ℎ! + 𝑦 cos 𝛼 − 𝑥 𝑠𝑖𝑛 𝛼 !

𝑣! = 1

Expandingandsettingtheright-handsideoftheequationto0givesthefollowing.

𝑣!𝑥!𝑐𝑜𝑠! 𝛼 + 2𝑣!𝑥𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝛼 + 𝑣!𝑦!𝑠𝑖𝑛! 𝛼 + ℎ!𝑦!𝑐𝑜𝑠! 𝛼

− 2ℎ!𝑥𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝑎 + ℎ!𝑥!𝑠𝑖𝑛! 𝛼 − ℎ!𝑣! = 0

Whenwehold𝑦constant,wegetaquadraticequationforxwiththefollowing

coefficients:

𝑎 = 𝑣!𝑐𝑜𝑠! 𝛼 + ℎ!𝑠𝑖𝑛! 𝛼 𝑏 = 2𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝑎 (𝑣! − ℎ!)

𝑐 = 𝑦! 𝑣!𝑠𝑖𝑛! 𝛼 + ℎ!𝑐𝑜𝑠! 𝛼 − ℎ!𝑣!Usingthequadraticformula,wegetonesolutionwhen𝑏! − 4𝑎𝑐 = 0.Usingthe

variablesdefinedaboveandalittlebitofalgebratosolveforx,wefindthat:

𝑥! = −𝑎ℎ!𝑣!

𝑐𝑜𝑠! 𝛼 𝑠𝑖𝑛! 𝛼 𝑣! − ℎ! ! − 𝑎 𝑣!𝑐𝑜𝑠! 𝛼 + ℎ!𝑠𝑖𝑛! 𝛼

Page 39: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

39

Wegetthexcoordinatesoftheboundingboxfortherotatedellipsebytakingthe

squarerootofbothsidesoftheaboveequation.Lastly,wemustoffsetthetwox

coordinatesbythexcoordinateoftheellipse’struecentertoaccountforourinitial

assumptionthattheellipseiscenteredattheorigin.

Theyvaluesoftheboundingboxoftherotatedellipsearecomputedanalogously.

Theparametersusedintheaboveequationarederivedaccordingtotheprocess

describedinsection3.

4.6.Arcs

Anarcissimplyapartialoutlineofanellipse.Thelogicforfindingtheextremais

fairlysimplewhilethemathtodosoisrathercumbersome.

Theprocedureisasfollows:

Find the minX and maxX of the base ellipse For each of these values: Find the corresponding y coordinate using the implicit quadratic equation Find the angle of rotation of this x,y pair Determine if this angle lies between the start and end angle of the arc If it does: This is an extremum. Update the bounding box If it does not: This is not an extremum. Repeat the above for minY and maxY. Test the coordinates at the start and end angle of the arc, accounting for stroke width (Figure14)

Page 40: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

40 Davis

40

Findingthecorrespondingycoordinatetominx(forexample)isthedifficultpartof

thisprocedureandtheonlyonewithmaththatwehavenotalreadyexamined.

Tosolvethis,wenotethatwecanalsorepresentellipsesusingtheimplicit

quadraticequation:

𝐴𝑥! + 𝐵𝑥𝑦 + 𝐶𝑦! + 𝐷𝑥 + 𝐸𝑦 + 𝐹 = 0Thevaluesforthecoefficientsareasfollows,withℎ,𝑣,and𝛼definedasbefore.

𝐴 = ℎ!𝑠𝑖𝑛! 𝛼 + 𝑣!𝑐𝑜𝑠! 𝛼 𝐵 = 2 𝑣! − ℎ! 𝑠𝑖𝑛 𝛼 𝑐𝑜𝑠 𝛼 𝐶 = ℎ!𝑐𝑜𝑠! 𝛼 + 𝑣!𝑠𝑖𝑛! 𝛼 𝐷 = −2𝐴𝑥!"#$"% − 𝐵𝑦!"#$"% 𝐸 = −𝐵𝑥!"#$"% − 2𝐶𝑦!"#$"%

𝐹 = 𝐴𝑥!"#$"%! + 𝐵𝑥!"#$"%𝑦!"#$"% + 𝐶𝑦!"#$"%! − ℎ!𝑣!

Thenthecoefficientsofthequadraticequationtosolveforthexcoordinate,for

example,are:

𝑎 = 𝐴

𝑏 = 𝐵𝑦 + 𝑑𝑐 = 𝐶𝑦! + 𝐸𝑦 + 𝐹

Wehaveonesolutionfor𝑦when𝑏! − 4𝑎𝑐 = 0.Wecansolvefor𝑥giventhe𝑦

coordinateofanextremuminasimilarfashion,thoughweneednotshowallofthe

equations.

Page 41: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

41

4.7.RoundedRectanglesSinceroundedrectanglearecreatedfromDartDrawrectanglesandellipses,the

boundingboxofaDartDrawdrawingisalteredseparatelybyeachofthecomponent

shapes.

4.8.BezierCurvesInsection3,wesawthatfourpointsinthecoordinatesystemdefineeachcubic

BeziercurvesusedinDartDraw.AlthoughBeziercurvesarefairlyeasytorender,

computingtheboundingboxesoftheseshapesisadifficultprocessthatisbeyond

thescopeofthisthesis.

However,thesefourpointsareeasytoaccesswithintheBoundingBoxclass.The

updateBoundsBezierHelper methodleveragesthegetCoords methodoftheepsShape

classtogetthefourpointsneededtodefineaBeziercurve.EverycubicBeziercurve

isboundbythepolygondescribedbyitsfourcontrolpoints.Therefore,the

BoundingBoxclasscheckseachpointwithanoffsetofhalfofthestrokeWidthofthe

Beziercurvetoseeifthisboundingpolygonpushespasttheedgesofthecurrent

DartDrawboundingbox.Whilenotprecise,thismethodisaccurate.

5.FileSavingandOpening

Asdiscussedthroughoutthisthesis,theinternalstructureoftheDartDraw

applicationrestsentirelyupontheReduxframework.WhatmakestheRedux

Page 42: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

42 Davis

42

frameworksousefulisthatitstoresexactlywhatweneedtoknowaboutthestate

ofadrawingwithnomissingorsuperfluousinformation.Therefore,itisthebasisof

theDartDrawfilesaveformat.

5.1.SavingfileswithIPCIntheintroductiontothisthesis,IdiscussedtherelationshipbetweentheElectron

mainprocessandthebrowserprocesses.Becauseelectronprocesseshandlemenu

eventsandbrowserprocessescanrenderseparatedrawingsfromeachother,this

relationshipbecomesimportantinthefilesaveprocess.

ThemenuiscreatedusingtheElectronMenumodule,whichallowsadeveloperto

createatemplatemenuformatandsetthatasthenativemenu.Inthiscase,wehave

OSXmenuoptionsforsavingandopening,alongwithotherfunctionalitynot

discussedhere.

Whenauserdecidestosaveafile,theyclickonFile>SavewithintheElectronmenu,

whichthenhandlestheappropriateclickeventdescribedinDartDraw/electron.js.

Inthecaseofafilesave,theclickeventbeginsbygettingthecurrentlyfocused

browserprocess–seenbytheuserasawindowwitharendereddrawing–using

thecommandBrowser.getFocusedWindow().Next,ittakesadvantageofinter-process

communication(IPC)tocommunicatebetweentheElectronmainprocessandthis

specificbrowserprocess.

Page 43: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

43

Electron’sIPCmoduleenablestheprocessestocommuteinthisway.Theideais

thatthemainprocessside“pings”aparticularchannelonthebrowsersideusing

theipcMainsubmodule,sendingamessageandaneventalongwiththeping.The

browsersideusestheipcMain submoduletolistenformessagesonthefilesave

channel.Whenitreceivesaping,itinterpretsthemessageasthemainprocess

askingforafilesave.ThebrowserprocessthenaccessestheReduxstore,convertsit

fromJSONtoastring,andsendsitbacktothemainprocessoverthecorrectchannel

usingtheeventthatwassentbythemainprocess.

Whenthemainprocessreceivesaresponsefromabrowserprocessoverthefile

savechannel,itsaveswhateveritwasgivenusingElectron’sfilesavemodule.

Specifically,thismoduleopensanOSXnativesavedialog,allowingtheusertoinput

afilename.Themainprocesssavesthegivenstringtothisfilename,checkingtosee

ifsuchafilenamealreadyexistsandexitinggracefullywhenitencountersanerror.

5.2.OpeningfilesDartDrawopensfilesinmuchthesamewayasitsavesthem,butinreverse.Whena

useroptstoopenafilefromtheDartDrawmenu,themainprocessshowsanative

OSXopendialogthroughwhichtheusermayselectoneormultiplefiles.Foreach

filethatisselected,themainprocessattemptstoopenthefileandthetextintoa

JSONobjectrepresentingthedrawingstateportionofaDartDrawReduxstore.

Uponeachsuccess,themainprocesscreatesanewbrowserprocess,instantiates

theIPCfilesavechannelinthatprocess,andsendsitaReduxstorerepresentinga

Page 44: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

44 Davis

44

drawing.Finally,eachnewbrowserprocessparsesitsdrawingstateandrendersit

accordingly.

6.FutureWork

ImpressiveastheDartDrawapplicationmaybe,thereareafewimportantwaysin

whichtheapplicationcouldbeimproved.Below,Ifocusonthepotential

improvementsthatwouldfallundermyresponsibility.

6.1.ComplexShapeIntersectionOneusefulfeatureofDartDrawallowsausertoselectacoloroftheirchoiceasthe

canvascolor.Whenevershapesarethesamecolorasthebackground,weavoid

expandingtheboundingboxofthetotaldrawingbasedonthatshape.Wewould

not,forexample,wantanEPSfiletorepresentadrawingofsignificantdimensions

whentheonlyfigurespresentinthedrawingarethesamecolorasthecanvas.

Withoutlossofgenerality,let’sassumethatthecanvasiswhite.Awhiterectangle

drawnbytheusershouldnotresultinacalltoanyboundingboxhelperfunction

becausetheboundingboxshouldnotexpand.However,itmaywellbethatthis

rectangleoverlapsaredellipse.Anink-basedboundingboxshouldaccountforall

partsofthisredellipsethatarenotcoveredbythewhiterectangle,whichmeans

thatwewouldhavetocomputethepointsofintersectionbetweenthetwoshapes.

Page 45: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

45

Additionally,wehavetomakeanextrapassthroughthelistofshapeseverytimewe

considerupdatingtheboundingboxes.Ifweweretodrawtheredellipsefirst,the

boundingboxwouldhavethenecessarydimensionstoencapsulatetheredellipse.If

weweretothendrawthewhiterectangleovertheredellipse,theboundingbox

wouldnotupdatebecausethewhiterectangleisthesamecolorasthecanvas.This

isaproblem;weknowhaveaboundingboxthatisnotink-basedbecauseit

encompassestheareainwhichthepartoftheredellipsethatisnocoveredbythe

whiterectangleusedtobevisible.Therefore,wemustinstead“lookahead”through

thelistofshapesintheReduxstoreeachtimethatweconsiderupdatingthe

boundingboxes.Ifwetakethisapproach,wewouldconsidertheredellipseand

realizethatitisgoingtobeoverlappedbythewhiterectangledowntheroad,sowe

canupdatetheboundingboxaccordingtothepointsofintersectionbetweenthe

twoshapesinsteadofnaivelyconsideringeachshapeonlyinisolation.

Currently,DartDrawexportfunctionalityaccountsforintersectionsbetweenlines,

rectangles,roundedrectangles,andellipses.Futureworkwouldincludeaccounting

forintersectionbetweenmorecomplexshapesincludingarcs,Beziercurves,

freehandpaths,andtext.

6.2.ColorFlatteningEachshapetypeinDartDrawhasanassociatedcontextmenuwithintheappthat

allowsuserstoselectdifferentfeaturesofthatshape.Onefeaturethatiscommonto

allshapesiscolor,whichmayapplytothefilland/orthestrokeofthatshape.The

Page 46: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

46 Davis

46

usercanchoosewhetherthecolorisrepresentedbyRGBorCMYK.Ineithercase,

thecolorinPostScriptisrepresentedinCMYK.

Fortunatelyforthefrontendoftheapplication,theusermayalsomanipulatethe

alphachannelofthecolorpalettewhenstylingtheirdrawings.Unfortunatelyforthe

backendoftheapplication–includingexportingEPSfiles–thisbehaviorisnot

supported.Thatmeansthatthereisnoautomaticwaytoincludeopacityforshapes

dictatedbyEPSfiles.

Adobehandlesthisissuewithatechniqueknownascolorflattening.Theideaisthat

multipleshapeswithsomedegreeofopacitycanoverlapinanymannerofways,

creatinganewcolorattheareasofoverlap.Ofcoursethisnewcolorcanbe

calculatedwithrelativeease,buttheareasofoverlapcanbeverydifficultto

computeforanarbitrarynumberofoverlaps.Whiletheproblemissolvable,itis

beyondthescopeofthisthesis.

6.3.FileCompressionThecurrentversionofDartDrawiscapableofopeningDartDrawfiles,recognizing

whenfilesarenotDartDrawfilesandshouldnotbeopened,andcansavefilesinthe

DartDrawfileformat.Furthermore,JeanZhouhaswrittenastandalonePython

scripttoconvertMacDrawfilesintotheDartDrawfileformat.

Page 47: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

47

However,DartDrawdoesnotcurrentlysupportcompressedfiles.Onepotential

methodthatwouldbeeasilyimplementedinascriptinglanguagelikeJavaScriptis

Huffmanencoding,acompressiontechniquethatcangreatlyreducefilesizewhen

usedonaknownandfinitesetofsymbolssuchastheASCIIcharactersusedto

representtheReduxStoreintheDartDrawfileformat.

7.Reflection

Workingonthisprojecthasbeenbothchallengingandextremelyrewarding.From

thebeginning,IwasopposedtotheideaoftheJavaScript-basedReact-Reduxdesign

thatthemajorityofthegroupfavoredasitmeantthatIwouldhavetolearnanew

programminglanguageinadditiontoPostScript.

Whilegettinguptospeedwasquitechallenging,Icannowconfidentlysaythatmy

colleaguesmadeawisechoicetosetupourprojectthisway.TheReduxAPIis

incrediblyeasytouseandmakestranslationbetweentheapplication’sinformation

andtheexportedPostScriptfilesmuchlesspainlessthanitmighthavebeen.

Furthermore,IseetheruntimebenefitsofusingtheReactframeworkto

individuallyapplychangestofiguresonthefrontend.ComparedtoSwift-based

applicationsthatIhavemadeinthepastusingXcode,DartDrawisquiteaspeedy

anduser-friendlygraphicsapplication.

Page 48: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

48 Davis

48

TherearecertainlydecisionsthatIwouldhavemadedifferentlyifIhadthe

opportunitytogobackanddothisprojectagain.Mostly,Iwoulddoallofthemath

thatIendedupneedingaheadoftime.AfterlearninghowtousetheReact-Redux

framework,readinguponsomebasicPostScript,andcomputingthebounding

boxesforafigureortwo,IwasconvincedthatIwasreadytostartcodinginearnest.

Inreality,thereisnocodewrittenbeforeacoupleofmonthsagothatIdidnot

changeatleastalittlebitinthepastfewweeks.AsIrealizedmorelogicaland

efficientwaystoorganizethisproject–suchastheconnectionbetweenrendering

arcsandellipses,orhowtoapplyquadraticsolverstobotharcsandBeziercurves–

IcametoadmittomyselfthatmyinitialeffortsbeliedthelackofplanningIdidfor

thelongterm.

Evenso,Iamproudoftheapplicationthatwehavemade.Therearecertainlybugs

toworkoutandfeaturestoadd,butIgenuinelybelievethatuserscouldenjoytheir

experiencewithDartDrawasitstandsnow.Whetherwepolishwhatwe’vemade

afterweturninthesethesesorithastowaituntilanotherundergraduatefits

togetherthefinalpieces,it’scleartomethatweaccomplishedanimpressivefeatin

softwareengineeringwithlimitedtime,resources,andinitialknowledge.

IamimpressedbymycolleaguesCollin,Elisabeth,Emma,Jean,Luisa,andMichelle,

andIamthankfultomyadvisor,ThomasCormen.

Page 49: Thinking Inside the Box: Converting Scalable Vector ...trdata/reports/TR2018-856.pdf · Electron runs on the Node.js runtime. As a result, Electron-based apps can leverage the entire

49

8.References

AppleInc.“Swift4.”Swift–AppleDeveloper.2018.AccessedMay9,2018.

https://developer.apple.com/swift/.

“Electron|BuildCrossPlatformDesktopAppswithJavaScript,HTML,andCSS.”

Electronjs.AccessedMay7,2018.https://electronjs.org/.

Hendricks,MarkC.RotatedEllipsesandTheirIntersectionswithLines.PDF.March8,

2012.

“Transformation-matrix-js.”Npm.AccessedMay11,2018.

https://www.npmjs.ocom/package/transformation-matrix-js.

Wikipedia,s.v.,“Ellipse,”lastmodifiedMay23,2018,

https://en.wikipedia.org/wiki/MacDraw

Wikipedia,s.v.,“MacDraw,”lastmodifiedFebruary17,2018,

https://en.wikipedia.org/wiki/MacDraw