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:

View the 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.