bitmap fonts in cocoa touch - iphone

Is it possible to use bitmap fonts in cocoa touch / quartz 2d? If yes how do I do that?

Look at CGContextSelectFont below:
void MyDrawText (CGContextRef myContext, CGRect contextRect)
{
float w, h;
w = contextRect.size.width;
h = contextRect.size.height;
CGAffineTransform myTextTransform;
CGContextSelectFont (myContext, "Helvetica-Bold", h/10, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (myContext, 10);
CGContextSetTextDrawingMode (myContext, kCGTextFillStroke);
CGContextSetRGBFillColor (myContext, 0, 1, 0, .5);
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);
myTextTransform = CGAffineTransformMakeRotation (MyRadians (45));
CGContextSetTextMatrix (myContext, myTextTransform);
CGContextShowTextAtPoint (myContext, 40, 0, "Quartz 2D", 9);
}

Related

iOS - scaling text vertically on Quartz

I am writing some text to a quartz context.
I have a box of 500 x 200 pixels and I am writing some text inside. The box can have any aspect ratio but the text will always write with the font proportions as it is. What I want is to scale the font vertically and keep the horizontal scale.
See the picture. The first box represents what I am getting, the second one, what I want.
this is how I am writing it...
CGRect rect = CGRectMake(0,0,500,200);
[myText drawInRect:rect
withFont:aFont
lineBreakMode:UILineBreakModeTailTruncation
alignment:UITextAlignmentCenter];
is there a way to scale the font vertically?
NOTE: as this is being written in a PDF context, I don't want to
render the text to a image context and scale it vertically, because I
don't want to lose resolution.
thanks
- (void) scaleTextVerticallyWithContext:(CGContextRef)myContext withRect:(CGRect)contextRect
{
CGFloat w, h;
w = contextRect.size.width;
h = contextRect.size.height;
CGAffineTransform myTextTransform;
CGContextSelectFont (myContext, "Helvetica-Bold", h/10, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (myContext, 10);
CGContextSetTextDrawingMode (myContext, kCGTextFillStroke);
CGContextSetRGBFillColor (myContext, 0, 1, 0, .5);
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);
/*
* CGAffineTransformMakeScale ( CGFloat sx, CGFloat sy );
* sx: The factor by which to scale the x-axis of the coordinate system.
* sy: The factor by which to scale the y-axis of the coordinate system.
*/
myTextTransform = CGAffineTransformMakeScale(1,8);
CGContextSetTextMatrix (myContext, myTextTransform);
CGContextShowTextAtPoint (myContext, 40, 0, "Hello There", 9);
}
- (void)drawRect:(CGRect)rect{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect viewBounds = self.bounds;
CGContextTranslateCTM(context, 0, viewBounds.size.height);
CGContextScaleCTM(context, 1, -1);
[self scaleTextVerticallyWithContext:context withRect:viewBounds];
}

iPhone PDF creation text inverting issue

i am creating an iphone app for creating pdf. I am using the following code:
[self drawRect:CGRectMake(0, 0, 100, 20 )text:#"last Name"xVal:10 yVal:-30 len:9];
[self drawRect:CGRectMake(0, 0, 100, 20 )text:#"First Name"xVal:180 yVal:30 len:10];
[self drawRect:CGRectMake(0, 0, 100, 20 )text:#"Middle Name"xVal:330 yVal:-30 len:11];
+ (void) drawRect:(CGRect)rect text:(NSString *)string xVal:(int)x yVal:(int)y len:(int)length{
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGRect viewBounds = rect;
CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
CGContextScaleCTM(theContext, 1, -1);
// Draw the text using the MyDrawText function
MyDrawText(theContext, viewBounds,string, x, y,length);
}
void MyDrawText (CGContextRef myContext, CGRect contextRect, NSString *textToDraw, int x, int y, int len){
float w, h;
w = contextRect.size.width;
h = contextRect.size.height;
CGAffineTransform myTextTransform;
CGContextSelectFont (myContext,"Helvetica-Bold", h, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (myContext, 3);
CGContextSetTextDrawingMode (myContext, kCGTextFill);
CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);
CGContextSetRGBStrokeColor (myContext, 0, 0, 0, 0);
myTextTransform = CGAffineTransformMakeRotation(0.0);
CGContextSetTextMatrix (myContext, myTextTransform);
const char *str = [textToDraw UTF8String];
CGContextShowTextAtPoint (myContext, x, y,str, len);
}
When I use this code I am getting the output like, first and third word is fine but the second one is coming like inverted (head down). Why so? Any idea?
The issue was with CGContextRef theContext = UIGraphicsGetCurrentContext();, when each time the function calls, the CGContext taking the last state, that's why getting the inverting output. So, i added,
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(theContext);
//code to draw....
CGContextRestoreGState(theContext);
this solved the issue. Thanks :)
Core Graphics considers Bottom-Left corner as the origin for drawing.(In UIKit its Top-Left).
Here in your method call for second string you are providing yVal as 30 and other values as -30.
Thanks,

How to change the perspective on a 3D cube in OpenGL ES?

I draw a cube with OpenGL ES and I want to have an above perspective on it.But I don't know what should I modify...Maybe you can help.
- (void)render:(CADisplayLink*)displayLink {
//-(void) render{
glClearColor(255.0, 255.0/255.0, 255.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//projection
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:8];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
// _currentScaling += displayLink.duration * 1.0;
[modelView populateFromTranslation:CC3VectorMake(sin(30), _currentScaling , -7)];
[modelView rotateBy:CC3VectorMake(0, -15, 0)];
// [modelView scaleByY:_currentScaling];
if(_currentScaling > 2 ){
[displayLink invalidate];
_running = 1;
// scale = 0;
}
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE, 0);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
I recently started looking into OpenGL myself and found this same example. I believe what you are looking for is to change this line to change the perspective:
[modelView rotateBy:CC3VectorMake(0, -15, 0)];
and specify the degrees of rotation you want for the x,y,z axes.

Hot can I add a shadow to an image using CoreGraphics on the iPhone?

I have a problem concerning Core Graphics drawing a shadow under my masked image.
I wrote a method to turn a grey image (actually it's an icon) into a white using a mask. Now I want to draw a shadow underneath it.
That's my code so far:
CGContextRef context = CGBitmapContextCreate(NULL, imageRect.size.width, imageRect.size.height, 8, 0, CGImageGetColorSpace(image.CGImage), kCGImageAlphaPremultipliedLast);
CGContextSetRGBFillColor(context, 1, 1, 1, 1);
CGContextFillRect(context, imageRect);
CGContextClipToMask(context, imageRect, image.CGImage);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
CGContextFillRect(context, imageRect);
CGImageRef bwCGImage = CGBitmapContextCreateImage(context);
UIImage *bwImage = [UIImage imageWithCGImage:bwCGImage scale:image.scale orientation:image.imageOrientation];
CGContextRelease(context);
CGImageRelease(bwCGImage);
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
[[UIColor whiteColor] set];
UIRectFill(CGRectMake(0, 0, image.size.width, image.size.height));
UIImage *normalBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(bwImage.CGImage), CGImageGetHeight(bwImage.CGImage), CGImageGetBitsPerComponent(bwImage.CGImage), CGImageGetBitsPerPixel(bwImage.CGImage), CGImageGetBytesPerRow(bwImage.CGImage), CGImageGetDataProvider(bwImage.CGImage), NULL, YES);
CGImageRef normalImageRef = CGImageCreateWithMask(normalBackgroundImage.CGImage, imageMask);
UIImage *normalImage = [UIImage imageWithCGImage:normalImageRef scale:image.scale orientation:image.imageOrientation];
CGImageRelease(imageMask);
CGImageRelease(normalImageRef);
Actually everything is working fine. Only the shadow is missing. How can I draw it?
I always recommend the great Quartz 2D Guide by Apple. Considering your question you should read the Shadows Chapter
It includes a great demo (including comments)
void MyDrawWithShadows (CGContextRef myContext, // 1
float wd, float ht);
{
CGSize myShadowOffset = CGSizeMake (-15, 20);// 2
float myColorValues[] = {1, 0, 0, .6};// 3
CGColorRef myColor;// 4
CGColorSpaceRef myColorSpace;// 5
CGContextSaveGState(myContext);// 6
CGContextSetShadow (myContext, myShadowOffset, 5); // 7
// Your drawing code here// 8
CGContextSetRGBFillColor (myContext, 0, 1, 0, 1);
CGContextFillRect (myContext, CGRectMake (wd/3 + 75, ht/2 , wd/4, ht/4));
myColorSpace = CGColorSpaceCreateDeviceRGB ();// 9
myColor = CGColorCreate (myColorSpace, myColorValues);// 10
CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);// 11
// Your drawing code here// 12
CGContextSetRGBFillColor (myContext, 0, 0, 1, 1);
CGContextFillRect (myContext, CGRectMake (wd/3-75,ht/2-100,wd/4,ht/4));
CGColorRelease (myColor);// 13
CGColorSpaceRelease (myColorSpace); // 14
CGContextRestoreGState(myContext);// 15
}

iPhone Glossy Icons Using Core Graphics

I was wondering if anyone knows how to take an Image using CoreGraphics and add a gloss effect like you see on iOS. Specifically I want to take an image that gets downloaded from the web and style it like this. I've searched high and low and all I found was examples of how to do it in PhotoShop and not in code. Any code snippets or pointers to resources that can help I would appreciate.
I figured it out on my own after wasting a few hours trying to figure this out... Here's my code:
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) {
float fw, fh;
if (ovalWidth == 0 || ovalHeight == 0) {
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);
CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);
fw = CGRectGetWidth (rect) / ovalWidth;
fh = CGRectGetHeight (rect) / ovalHeight;
CGContextMoveToPoint(context, fw, fh/2);
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
CGContextClosePath(context);
CGContextRestoreGState(context);
}
static void addGlossPath(CGContextRef context, CGRect rect) {
CGFloat quarterHeight = CGRectGetMidY(rect) / 2;
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, -20, 0);
CGContextAddLineToPoint(context, -20, quarterHeight);
CGContextAddQuadCurveToPoint(context, CGRectGetMidX(rect), quarterHeight * 3, CGRectGetMaxX(rect) + 20, quarterHeight);
CGContextAddLineToPoint(context, CGRectGetMaxX(rect) + 20, 0);
CGContextClosePath(context);
CGContextRestoreGState(context);
}
UIImage *applyIconHighlightToImage(UIImage *icon) {
UIImage *newImage;
CGContextRef context;
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
CGRect currentBounds = CGRectMake(0, 0, icon.size.width, icon.size.height);
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));
CGFloat locations[2] = {0.0, 1.0};
CGFloat components[8] = {1.0, 1.0, 1.0, 0.75, 1.0, 1.0, 1.0, 0.2};
UIGraphicsBeginImageContext(icon.size);
context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
addRoundedRectToPath(context, currentBounds, 10, 10);
CGContextClosePath(context);
CGContextClip(context);
[icon drawInRect:currentBounds];
addGlossPath(context, currentBounds);
CGContextClip(context);
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, 2);
CGContextDrawLinearGradient(context, glossGradient, topCenter, midCenter, 0);
UIGraphicsPopContext();
newImage = UIGraphicsGetImageFromCurrentImageContext();
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
UIGraphicsEndImageContext();
return newImage;
}
Edit:
Wanted to make sure I gave credit where credit is due. Thanks to Brad Larson for the code on adding a glossy gradient.
I provide code to draw a glossy gradient using Core Graphics in my answer here.
If all that you wish to do is overlay a gloss effect on your image, it may be more performant to generate this using a CAGradientLayer, as decribed by Mirko in his answer there.