[WASTE-list] Views

Marco Piovanelli marco.piovanelli at pobox.com
Thu Jan 4 17:25:14 EST 2007


On Thu, 4 Jan 2007 09:12:36 +0100,
Andreas Binner (andreasb at vmlabs.de) wrote:



>Hi,

>

>I wonder if here is some documentation on the "Views" API. Currently I

>have no clue what I can do with it, but it looks interesting because of

>possibility to specify a CG context directly. Can use this to force

>WASTE to render the text into a given CG context (even off-screen)?

>Perhaps you can briefly explain me the concept of "Views"?


I hope you don't mind if I copy my reply to the WASTE mailing
list.

Basically, a view represents an area of the screen (or some
other output device) where text is drawn and scrolled.
View objects are responsible for painting the background,
highlight regions, carets, and text.

Views can be either "Quartz-bound" or "Quickdraw-bound", even
if all drawing ultimately takes place in a Core Graphics context.
In Quartz-bound views, you explicitly provide a Core Graphics
context to draw into, while in Quickdraw-bound views (needed for
backward compatibility with WASTE 2.1), you provide a Quickdraw
port, and WASTE will set up a suitable CG context on the fly.

Controllers (the objects represented by the WEReference opaque
data type) can have zero, one, or several views associated with
them. Since earlier versions of WASTE allowed only one view per
controller, many APIs that should take view references take
controller references instead, so WASTE 3.0 has the concept of
"current" view, i.e., the view acted upon when you call APIs
such as WEScroll() or WEAdjustCursor().

For compatibility with WASTE 2.1, WENew() creates a new controller
and a new QD-bound view associated with it. But as you noticed,
there are new APIs that allow you to create additional views,
either Quickdraw-bound (WENewView) or Quartz-bound (WENewViewWithCGContext).
You can also use WENew() to create a controller with no associated
views by passing NULL in the destRect and viewRect parameters.

And yes, all this means you can have WASTE render text into
a CG context of your liking, even offscreen. For example,
here's some code that renders some RTF source into a PDF
Core Graphics context. The code also shows some other
interesting techniques, like inserting RTF from an in-memory
buffer, and setting the background color to transparent:


OSStatus ImageToPDF(CGContextRef inPDFContext, CGRect inDestRect, const
void * inRTFBufferPtr, ByteCount inRTFBufferLength)
{
WEReference controller = 0;
WEViewReference view = 0;
const ATSURGBAlphaColor backgroundColor = {0.0f, 0.0f, 0.0f, 0.0f};
OSStatus err;

// create a text controller
if ((err = WENew(0, 0, weDoInhibitRedraw, &controller)) != noErr)
{
goto cleanup;
}

// insert some RTF at the beginning
if ((err = WEPut(0, 0, inRTFBufferPtr, inRTFBufferLength, 0, wePutRTF,
0, 0, 0, controller)) != noErr)
{
goto cleanup;
}

// create a new view for imaging into the specified CG context
if ((err = WENewViewWithCGContext(inPDFContext, inDestRect, inDestRect,
controller, &view)) != noErr)
{
goto cleanup;
}

// make this the current view
WESetCurrentView(view);

// set the background color to transparent (by using an alpha value of 0.0)
// this is important to prevent WASTE from erasing the background to white
if ((err = WESetViewInfo(weBackgroundColor, &backgroundColor, view)) !=
noErr)
{
goto cleanup;
}

// image the document
WEUpdate(0, controller);

cleanup:
// we're done
WEDispose(controller);

return err;
}

void PDFTest()
{
const char * rtfContent = "{\\rtf1\\mac\\ansicpg10000\\cocoartf824\
\cocoasubrtf380"
"{\\fonttbl\\f0\\froman\\fcharset77 Times-Roman;\\f1\\fnil\\fcharset78
HiraMinPro-W6;\\f2\\froman\\fcharset77 Times-Italic;}"
"{\\colortbl\\red0\\green0\\blue0;\\red250\\green161\\blue154;}"
"\\paperw11900\\paperh16840\\vieww12000\\viewh15840\\viewkind0"
"\\deftab720"
"\\pard\\pardeftab720\\ql"
"\\f0\\fs36 \\cf0 Hello {\\highlight1 Cruel} World "
"\\f1\\b \\'93\\'fa\\'96\\'7b\\'8c\\'ea"
"\\f0\\b0 .\\\r"
"\\fs28 This is a test of imaging some simple RTF content into a PDF
box using WASTE 3.0. This is "
"\\f2\\i only"
"\\f0\\i0 a test. Balancing precariously on their yellow bumps, the
traffic wardens unremittingly tease one another "
"with their innocent games of slap and tickle.}";
FSRef desktopRef;
CFURLRef pdfURL = 0;
CFURLRef desktopURL = 0;
CGContextRef pdfContext = 0;
const CGRect mediaBox = CGRectMake(0, 0, 595, 842); // A4 page
const CGRect textBox = CGRectMake(75, 100, 250, 90);
OSStatus err;

// we want to create the test.pdf file on the desktop
if ((err = FSFindFolder(kOnAppropriateDisk, kDesktopFolderType,
kCreateFolder, &desktopRef)) != noErr)
{
goto cleanup;
}

if ((desktopURL = CFURLCreateFromFSRef(kCFAllocatorDefault,
&desktopRef)) == 0)
{
err = coreFoundationUnknownErr;
goto cleanup;
}
if ((pdfURL = CFURLCreateCopyAppendingPathComponent
(kCFAllocatorDefault, desktopURL, CFSTR("test.pdf"), false)) == 0)
{
err = coreFoundationUnknownErr;
goto cleanup;
}

// create a new PDF context
if ((pdfContext = CGPDFContextCreateWithURL(pdfURL, &mediaBox, 0)) == 0)
{
err = coreFoundationUnknownErr;
goto cleanup;
}

// start a new page
CGContextBeginPage(pdfContext, &mediaBox);

// draw some rectangles
CGContextSetRGBFillColor (pdfContext, 1, 0, 0, 1);
CGContextFillRect (pdfContext, CGRectMake (50, 50, 200, 100 ));
CGContextSetRGBFillColor (pdfContext, 0, 0, 1, .5);
CGContextFillRect (pdfContext, CGRectMake (50, 50, 100, 200 ));
CGContextStrokeRect(pdfContext, textBox);

// image RTF content using WASTE
err = ImageToPDF(pdfContext, textBox, rtfContent, strlen(rtfContent));

// close the page and release the PDF context
CGContextEndPage(pdfContext);

cleanup:
if (desktopURL)
{
CFRelease(desktopURL);
desktopURL = 0;
}
if (pdfURL)
{
CFRelease(pdfURL);
pdfURL = 0;
}
if (pdfContext)
{
CGContextRelease(pdfContext);
pdfContext = 0;
}
}


Hope this helps,


-- marco

--
It's not the data universe only, it's human conversation.
They want to turn it into a one-way flow that they have entirely
monetized. I look at the collective human mind as a kind of
ecosystem. They want to clear cut it. They want to go into the
rainforest of human thought and mow the thing down.



More information about the WASTE-list mailing list