Oh, oops. I left a CGContextSetBlendMode() call in there that is
extraneous. You can remove that. Also you could in theory add an alpha
input double port so you can fade all the text using CGContextSetAlpha
which might be handy in some situations? Of course you could just fade
the billboard/sprite. Anyway :)
On Jan 22, 2010, at 12:57 AM, vade wrote:
<StyledText fixed vade.zip>
this should do it.
I switched to time mode none, so you only draw when there is need to
create and upload a new QCOutputImageProvider.
I switched the drawing use NSAttributedStrings built in drawing code
rather than the layout code.
Use NSGraphicsContext to draw to the CGBitmapContext
Fixed alpha and premultiply issues.
That alpha thing was a pain in the ass. I think I have the ordering
right, but it may need an
#if __BIG_ENDIAN__
use ARGB output provider format
etc. But it works, colors and alpha just fine.
This is a handy QC plugin. Great idea using HTML/styles for fonts.
Lots of options now. :)
:)
On Jan 21, 2010, at 7:17 PM, Adrian Ward wrote:
Hey Toby,
Thanks for the tip. I had already been through your code and tried
your NSImage-in-NSDictionary technique beforehand :-) Certainly
made getting a test idea up and running quickly.
Back to my problem, I'm still no nearer solving this. I've tried
glLoadIdentity, glTranslatef, glScalef etc. I've tried saving and
restoring graphics states, locking contexts whereever I can. I'm
not sure what I should be trying without seeing this problem
elsewhere, which I haven't yet. I even tried putting creation of
the NSAttributedString into the main thread
(performSelectorOnMainThread:) but there's no joy. The QC viewer
window is being messed up by my NSAttributedString, and only when I
use initWithHTML. It's really quite irrational and I have a feeling
it has nothing to do with QC and everything to do with AppKit.
Perhaps someone could give it a bash, and at the very least confirm
the problem I'm experiencing?
<StyledText.zip>
All the best,
Ade.
On 21 Jan 2010, at 08:49, lists @ tobyz wrote:
Adrian,
I can't help with the styled part, but just to see how somebody
else did something fwiw you can look at the code at http://www.tobyz.net/tobyzstuff/diary/2008/02/spk-stringtoimagestructure
, and i have a skunkworks-more-than-alpha stringtopointstructure too
Which is a strange way of saying: go adrian, the better text
handling in qc, the better!
Toby
On 17 Jan 2010, at 19:21, Adrian Ward wrote:
Hello all,
I'm trying to build a plugin that makes it possible to generate
images with attributed strings (ie. support for bold, italic,
etc). Ultimately I'd like this to be a drop-in replacement for
Image With String, but that could accept HTML markup, using a CSS
stylesheet etc.
The technique I'm attempting is:
1. Allocate a bitmap buffer
2. Create a CGContextRef for it
3. Create an NSAttributedString with some suitable formatting
4. Render it into the CGContext using a CTFramesetter (as per
Apple's Core Text Programming Guide)
5. Make a QCPlugInOutputImageProvider using [qccontext
outputImageProviderFromBufferWithPixelFormat:...]
<Untitled Image.png>
As you can see, this technique seems to be working - albeit with
some weirdness, hacks and bugs - however, when I try implementing
step 3 like so:
NSData* htmldata = [self.inputString
dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString* attrString = [[NSAttributedString alloc]
initWithHTML:htmldata baseURL:[qccontext compositionURL]
documentAttributes:nil];
This does work, but Quartz Composer's OpenGL view seems to become
corrupted, and subsequent drawing goes wildly wrong. Sprites with
width 1 suddenly and rapidly render at double their size, and the
corruption gets worse each frame, quickly causing QC to render
nonsense. There's no crashing, just garbage being rendered.
I know that initWithHTML:... causes WebKit to load internally,
and this probably requires all sorts of graphics state changes,
and am guessing that this is causing the problem. However, I'm
not sure what I should be looking at to get around the problem
and would appreciate some tips.
Solutions/workarounds I've tried:
- blindly experimenting with CGContextSaveGState, glLoadIdentity,
etc in attempts to avoid corrupt graphics states (makes no
difference)
- using NSAttributedString's initWithPath:@"/test.html" instead
(same problem)
- using NSAttributedString's initWithPath:@"/test.docx" instead
(works perfectly! ...but isn't what I want to achieve)
- manually building my NSAttributedString instead of using
initWithHTML: (problem goes away, but I lose the convenience of
HTML, CSS etc)
Would anyone with a bit more experience be able to make some kind
suggestions?
Thanks and all the best,
Ade.
- (BOOL) execute:(id<QCPlugInContext>)qccontext atTime:
(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
// CGLContextObj ctl_ctx = [qccontext CGLContextObj];
// Make the backing buffer
NSUInteger width = self.inputWidth;
NSUInteger height = self.inputHeight;
NSUInteger bytesPerRow = width * 4; // FIXME: This must be
modulo 16 - what if width isn't a nice number?
char* buffer = valloc(height * bytesPerRow); // FIXME: What if
the memory wasn't allocated?
// Clear the buffer
memset(buffer, 0, height * bytesPerRow);
// Make a CGContextRef around it FIXME: What if we're running on
a non-Intel platform, where the format wouldn't be ARGB but BGRA?
CGColorSpaceRef cgcolorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgcontext = CGBitmapContextCreate(buffer, width,
height, 8, bytesPerRow, cgcolorspace,
kCGImageAlphaPremultipliedFirst); // FIXME: What if the
CGContextRef wasn't created?
// Create attributed string FIXME: This corrupts QC's graphics
state???
NSData* htmldata = [self.inputString
dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString* attrString = [[NSAttributedString alloc]
initWithHTML:htmldata baseURL:[qccontext compositionURL]
documentAttributes:nil]; // FIXME: What if attrString wasn't
created?
// Draw a string using a typesetter
// Initialize a rectangular path.
CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(0, 0, width, height);
CGPathAddRect(path, NULL, bounds);
// Create the framesetter with the attributed string.
CTFramesetterRef framesetter =
CTFramesetterCreateWithAttributedString
((CFMutableAttributedStringRef)attrString);
// Create the frame and draw it into the graphics context
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,
CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CTFrameDraw(frame, cgcontext);
CFRelease(frame);
CFRelease(path);
// Make the output provider
id<QCPlugInOutputImageProvider> provider = [qccontext
outputImageProviderFromBufferWithPixelFormat:QCPlugInPixelFormatARGB8
pixelsWide:width pixelsHigh:height baseAddress:buffer
bytesPerRow:bytesPerRow releaseCallback:
(QCPlugInBufferReleaseCallback)_bufferReleaseCallback
releaseContext:nil colorSpace:cgcolorspace shouldColorMatch:YES];
self.outputImage = provider;
// Free everything
[attrString release];
CGContextRelease(cgcontext);
CGColorSpaceRelease(cgcolorspace);
return YES;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list ([email protected]
)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/lists%40tobyz.net
This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list ([email protected]
)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/doktorp%40mac.com
This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list ([email protected]
)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/doktorp%40mac.com
This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com
This email sent to [email protected]