What is This?#
This is a NewtonScript routine (not an application) that takes a Notes entry (paperroll stationery) and converts it into SVG code.
What’s it for?#
Maybe it will grow into an application someday.
Some what’s left to do?#
Well, the hardest part, believe it or not, is handling text and fonts.
- SVG does not support text wrapping, so the converter will have to manually wrap the text.
- It is hard to wrap the text when you don’t know how long each character is.
- It is possible to embed the font into the SVG document, but that involves writing a Newton font-to-SVG converter. I’m not sure I really want to get that involved. (Though it is possible.) Then you’d be certain that the fonts in the SVG document render exactly as they do on the Newton.
- Rich strings (text with inkWords mixed in) need to be handled too. I haven’t even looked at that yet.
The code#
A few constants are in a different file, but you should get the idea.
func(frame roll) begin // Prepare the SVG header local svg := kXMLDocTypeHeader; svg := svg & kSVGTagStart; // For each child in the paperroll entry foreach item in roll.data do begin // Default penWidth is 2. If there's a viewFormat, // parse out the penWidth from there. local penWidth := 0; if (item.viewFormat exists) then //This extracts penWidth from viewFormat. penWidth := Band(item.viewFormat >> 8, 15); if (penWidth := 0) then penWidth := 2; // Determine what kind of child it is. If we have ink, // go down the ink conversion route if (item.ink exists) then begin // We have ink. Expand the ink to a strokeBundle. strokeBundle := ExpandInk(item, 0); // one stroke bundle can have more than one stroke. // For instance, a "t" character would have two strokes for one // character, but both strokes are in the same stroke bundle num := CountStrokes(strokeBundle); // Start the group tag for this item local path := "n"; // For each stroke, calculate the points for i := 0 to num-1 do begin stroke := GetStroke(strokeBundle, i); points := GetStrokePointsArray(stroke, 0); for j := 0 to Length(points)-1 by 2 do begin y := points[j]; x := points[j+1]; if (j = 0) then path := path & "tn"; // the path Tag end; path := path & "n"; // Close the group tag svg := svg & path; // Append to the SVG document. end else if (item.viewStationery = 'poly) then begin // We have a polygon. Process the polygon. Extract the points points := PointsToArray(item.points); // points[0] is the polygon type. 0=circle if (points[0] = 0) then begin //Figure out the circle bounds and convert to a tag. w:=item.viewBounds.right - item.viewBounds.left; h:=item.viewBounds.bottom - item.viewBounds.top; r:=w/2; cx:=item.viewBounds.left + r; cy:=item.viewBounds.top + r; local shape := "n"; svg := svg & shape; end else if (points[0] = 1) then begin // 1 = elipse - convert to an tag w:=item.viewBounds.right - item.viewBounds.left; h:=item.viewBounds.bottom - item.viewBounds.top; rx:=w/2; ry:=h/2; cx:=item.viewBounds.left + rx; cy:=item.viewBounds.top + ry; local shape := "n"; svg := svg & shape; end else begin // Everything else, convert to a path tag. local shape := "n"; //first iteration already has M, others are L. shape := shape & "t 2) then shape := shape & "L"; shape := shape & x & "," & y & " "; end; //tells the tag to return to the start (close) if (closedPath) then shape := shape & "Z"; shape := shape & "\"/>n"; shape := shape & "n"; svg := svg & shape; end; end else if (item.viewStationery = 'para) then begin //process a paragraph item (text) //TODO: Figure out what the heck to do here. local x := item.viewBounds.left; local y := item.viewBounds.bottom; local text := "" & item.text & "n"; svg := svg & text; end; end; svg := svg & kSVGTagEnd; return svg; end
How does it look#
Here is an example SVG file:
Just an example of what the SVG converter routine does. This has been modified a bit in Inkscape as part of my development efforts to figure out the the text stuff.
