bzr branch
/browse/iphone/common
| Line | Revision | Contents |
| 1 | 65 | #import "GLString.h" |
| 2 | #import "gfx.h" |
|
| 3 | #import "VertexArray.h" |
|
| 4 | ||
| 5 | #import <OpenGLES/ES2/gl.h> |
|
| 6 | #import <CoreGraphics/CoreGraphics.h> |
|
| 7 | ||
| 8 | ||
| 9 | // The following is a NSBezierPath category to allow |
|
| 10 | // for rounded corners of the border |
|
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | #pragma mark - |
|
| 15 | ||
| 16 | @implementation GLQuartzTexture |
|
| 17 | ||
| 18 | - (id) init |
|
| 19 | { |
|
| 20 | if (!(self = [super init])) |
|
| 21 | return nil; |
|
| 22 | ||
| 23 | antialias = YES; |
|
| 24 | subpixelAA = YES; |
|
| 25 | filterTexture = NO; |
|
| 26 | |
|
| 27 | texturePadding = 1.0; |
|
| 28 | requiresUpdate = YES; |
|
| 29 | ||
| 30 | return self; |
|
| 31 | } |
|
| 32 | ||
| 33 | - (void) finalize |
|
| 34 | { |
|
| 35 | if (texName) |
|
| 36 | [GLResourceDisposal disposeOfResourcesWithTypes: texName, GL_TEXTURE, NULL]; |
|
| 37 | ||
| 38 | [super finalize]; |
|
| 39 | } |
|
| 40 | ||
| 41 | - (void) deleteTexture |
|
| 42 | { |
|
| 43 | if (texName) |
|
| 44 | { |
|
| 45 | glDeleteTextures(1, &texName); |
|
| 46 | texName = 0; |
|
| 47 | requiresUpdate = YES; |
|
| 48 | textureSize = CGSizeZero; |
|
| 49 | } |
|
| 50 | } |
|
| 51 | ||
| 52 | - (void) freeGLResources |
|
| 53 | { |
|
| 54 | [self deleteTexture]; |
|
| 55 | } |
|
| 56 | ||
| 57 | - (void) updateTextureIfRequired |
|
| 58 | { |
|
| 59 | if (requiresUpdate) |
|
| 60 | [self genTexture]; |
|
| 61 | } |
|
| 62 | ||
| 63 | - (void) bindTexture |
|
| 64 | { |
|
| 65 | if (!texName) |
|
| 66 | [self genTexture]; |
|
| 67 | glBindTexture(GL_TEXTURE_2D, texName); |
|
| 68 | } |
|
| 69 | ||
| 70 | - (void) setAntialias:(BOOL)request |
|
| 71 | { |
|
| 72 | antialias = request; |
|
| 73 | requiresUpdate = YES; |
|
| 74 | } |
|
| 75 | ||
| 76 | - (void) setSubpixelAA:(BOOL)request |
|
| 77 | { |
|
| 78 | subpixelAA = request; |
|
| 79 | requiresUpdate = YES; |
|
| 80 | } |
|
| 81 | ||
| 82 | - (void) setFilterTexture:(BOOL)request |
|
| 83 | { |
|
| 84 | filterTexture = request; |
|
| 85 | requiresUpdate = YES; |
|
| 86 | } |
|
| 87 | ||
| 88 | - (void) setMipmapTexture:(BOOL)request |
|
| 89 | { |
|
| 90 | mipmapTexture = request; |
|
| 91 | requiresUpdate = YES; |
|
| 92 | } |
|
| 93 | ||
| 94 | - (void) setTexturePadding:(double)rad |
|
| 95 | { |
|
| 96 | texturePadding = rad; |
|
| 97 | requiresUpdate = YES; |
|
| 98 | } |
|
| 99 | ||
| 100 | - (void) doQuartzDrawingInContext: (CGContextRef) context sized: (CGSize) imgSize |
|
| 101 | { |
|
| 102 | } |
|
| 103 | ||
| 104 | - (void) generateTextureSized: (CGSize) texSize; // generates the texture without drawing texture to current context |
|
| 105 | { |
|
| 106 | //CGSize previousSize = textureSize; |
|
| 107 | 68 | |
| 108 | 65 | int width = texSize.width; |
| 109 | int height = texSize.height; |
|
| 110 | ||
| 111 | void* spriteData = calloc(1, width * height * 4); |
|
| 112 | |
|
| 113 | |
|
| 114 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
|
| 115 | CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); |
|
| 116 | assert(spriteContext); |
|
| 117 | |
|
| 118 | UIGraphicsPushContext(spriteContext); |
|
| 119 | ||
| 120 | CGContextSetShouldSmoothFonts(spriteContext, subpixelAA); |
|
| 121 | ||
| 122 | [self doQuartzDrawingInContext: spriteContext sized: texSize]; |
|
| 123 | ||
| 124 | UIGraphicsPopContext(); |
|
| 125 | CGContextRelease(spriteContext); |
|
| 126 | CGColorSpaceRelease(colorSpace); |
|
| 127 | |
|
| 128 | if (!texName) |
|
| 129 | glGenTextures(1, &texName); |
|
| 130 | glBindTexture(GL_TEXTURE_2D, texName); |
|
| 131 | ||
| 132 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); |
|
| 133 | ||
| 134 | free(spriteData); |
|
| 135 | ||
| 136 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
| 137 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
| 138 | ||
| 139 | if (mipmapTexture) |
|
| 140 | glGenerateMipmap(GL_TEXTURE_2D); |
|
| 141 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterTexture ? (mipmapTexture ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : GL_NEAREST); |
|
| 142 | ||
| 143 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterTexture ? GL_LINEAR : GL_NEAREST); |
|
| 144 | |
|
| 145 | textureSize = texSize; |
|
| 146 | |
|
| 147 | requiresUpdate = NO; |
|
| 148 | } |
|
| 149 | ||
| 150 | - (CGSize) updatedTextureSize |
|
| 151 | { |
|
| 152 | return CGSizeZero; |
|
| 153 | } |
|
| 154 | ||
| 155 | - (void) genTexture |
|
| 156 | { |
|
| 157 | [self generateTextureSized: [self updatedTextureSize]]; |
|
| 158 | } |
|
| 159 | ||
| 160 | - (CGSize) textureSize |
|
| 161 | { |
|
| 162 | if (requiresUpdate) |
|
| 163 | return [self updatedTextureSize]; |
|
| 164 | else |
|
| 165 | return textureSize; |
|
| 166 | } |
|
| 167 | ||
| 168 | - (void) drawWithBounds:(CGRect)bounds |
|
| 169 | { |
|
| 170 | [self updateTextureIfRequired]; |
|
| 171 | ||
| 172 | if ([self texName]) |
|
| 173 | { |
|
| 174 | |
|
| 175 | //glDisable (GL_DEPTH_TEST); // ensure text is not remove by depth buffer test. |
|
| 176 | //glEnable (GL_BLEND); // for text fading |
|
| 177 | //glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto |
|
| 178 | glEnable (GL_TEXTURE_2D); |
|
| 179 | |
|
| 180 | glBindTexture (GL_TEXTURE_2D, [self texName]); |
|
| 181 | |
|
| 182 | [[VertexArray sharedQuad] draw]; |
|
| 183 | |
|
| 184 | } |
|
| 185 | } |
|
| 186 | ||
| 187 | - (void) drawAtPoint:(CGPoint)point scaled: (double) scale |
|
| 188 | { |
|
| 189 | [self drawWithBounds: CGRectMake(point.x-[self texturePadding]*scale, point.y-[self texturePadding]*scale, [self textureSize].width*scale, [self textureSize].height*scale)]; |
|
| 190 | } |
|
| 191 | - (void) drawAtPoint:(CGPoint)point |
|
| 192 | { |
|
| 193 | [self drawAtPoint: point scaled: 1.0]; |
|
| 194 | } |
|
| 195 | ||
| 196 | - (void) drawCenteredAtPoint:(CGPoint)point scaled: (double) scale |
|
| 197 | { |
|
| 198 | [self drawWithBounds: CGRectMake(point.x-0.5*[self textureSize].width*scale, point.y-0.5*[self textureSize].height*scale, [self textureSize].width*scale, [self textureSize].height*scale)]; |
|
| 199 | } |
|
| 200 | - (void) drawCenteredAtPoint:(CGPoint)point |
|
| 201 | { |
|
| 202 | [self drawCenteredAtPoint: point scaled: 1.0]; |
|
| 203 | } |
|
| 204 | ||
| 205 | ||
| 206 | @synthesize antialias, subpixelAA, texturePadding, filterTexture, mipmapTexture, textureSize, texName; |
|
| 207 | ||
| 208 | @end |
|
| 209 | ||
| 210 | #pragma mark - |
|
| 211 | ||
| 212 | @implementation GLQuartzBox |
|
| 213 | ||
| 214 | - (id) init |
|
| 215 | { |
|
| 216 | if (!(self = [super init])) |
|
| 217 | return nil; |
|
| 218 | ||
| 219 | cornerRadius = 4.0; |
|
| 220 | borderWidth = 1.0; |
|
| 221 | // borderColor = [NSColor clearColor]; |
|
| 222 | ||
| 223 | return self; |
|
| 224 | } |
|
| 225 | ||
| 226 | CGPathRef CGPathCreateWithRoundedRect(CGRect rect, CGFloat r) |
|
| 227 | 78 | { |
| 228 | 65 | CGMutablePathRef path = CGPathCreateMutable(); |
| 229 | CGPathMoveToPoint(path, NULL, |
|
| 230 | rect.origin.x + rect.size.width - r, rect.origin.y); |
|
| 231 | CGPathAddArcToPoint(path, NULL, |
|
| 232 | rect.origin.x + rect.size.width, rect.origin.y, |
|
| 233 | rect.origin.x + rect.size.width, rect.origin.y + r, r); |
|
| 234 | CGPathAddLineToPoint(path, NULL, |
|
| 235 | rect.origin.x + rect.size.width, rect.origin.y + rect.size.height - r); |
|
| 236 | CGPathAddArcToPoint(path, NULL, |
|
| 237 | rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, |
|
| 238 | rect.origin.x + rect.size.width - r, rect.origin.y + rect.size.height, r); |
|
| 239 | CGPathAddLineToPoint(path, NULL, |
|
| 240 | rect.origin.x + r, rect.origin.y + rect.size.height); |
|
| 241 | CGPathAddArcToPoint(path, NULL, |
|
| 242 | rect.origin.x, rect.origin.y + rect.size.height, |
|
| 243 | rect.origin.x, rect.origin.y + rect.size.height - r, r); |
|
| 244 | CGPathAddLineToPoint(path, NULL, |
|
| 245 | rect.origin.x, rect.origin.y + r); |
|
| 246 | CGPathAddArcToPoint(path, NULL, |
|
| 247 | rect.origin.x, rect.origin.y, |
|
| 248 | rect.origin.x + r, rect.origin.y, r); |
|
| 249 | CGPathAddLineToPoint(path, NULL, |
|
| 250 | rect.origin.x + r, rect.origin.y); |
|
| 251 | ||
| 252 | 78 | CGPathCloseSubpath(path); |
| 253 | 65 | return path; |
| 254 | } |
|
| 255 | ||
| 256 | - (void) doQuartzDrawingInContext: (CGContextRef) context sized: (CGSize) imgSize |
|
| 257 | { |
|
| 258 | float borderAlpha = 0.0; |
|
| 259 | float boxAlpha = 0.0; |
|
| 260 | |
|
| 261 | if (borderColor) |
|
| 262 | borderAlpha = CGColorGetAlpha([borderColor CGColor]); |
|
| 263 | if (boxColor) |
|
| 264 | boxAlpha = CGColorGetAlpha([boxColor CGColor]); |
|
| 265 | ||
| 266 | double bw = (borderAlpha ? borderWidth : 0.0); |
|
| 267 | |
|
| 268 | if (boxAlpha) |
|
| 269 | { // this should be == 0.0f but need to make sure |
|
| 270 | [boxColor set]; |
|
| 271 | CGPathRef path = CGPathCreateWithRoundedRect(CGRectInset(CGRectMake(texturePadding, texturePadding, frameSize.width, frameSize.height), 0.5*borderWidth, 0.5*borderWidth), cornerRadius); |
|
| 272 | 78 | CGContextAddPath(context, path); |
| 273 | 65 | CGContextDrawPath(context, kCGPathFill); |
| 274 | CGPathRelease(path); |
|
| 275 | 78 | } |
| 276 | 65 | |
| 277 | if (borderAlpha) |
|
| 278 | { |
|
| 279 | [borderColor set]; |
|
| 280 | CGPathRef path = CGPathCreateWithRoundedRect(CGRectInset(CGRectMake(texturePadding, texturePadding, frameSize.width, frameSize.height), 0.5*borderWidth, 0.5*borderWidth), cornerRadius); |
|
| 281 | 78 | |
| 282 | 65 | CGContextAddPath(context, path); |
| 283 | CGContextSetLineWidth(context, bw); |
|
| 284 | CGContextDrawPath(context, kCGPathStroke); |
|
| 285 | CGPathRelease(path); |
|
| 286 | 78 | } |
| 287 | 65 | |
| 288 | } |
|
| 289 | ||
| 290 | - (CGSize) updatedTextureSize |
|
| 291 | { |
|
| 292 | CGSize texSize = CGSizeMake(ceil(frameSize.width+2.0*texturePadding), ceil(frameSize.height+2.0*texturePadding)); |
|
| 293 | return texSize; |
|
| 294 | } |
|
| 295 | ||
| 296 | - (void) setBoxColor:(UIColor *)color // set default text color |
|
| 297 | { |
|
| 298 | boxColor = color; |
|
| 299 | 94 | requiresUpdate = YES; |
| 300 | 65 | } |
| 301 | ||
| 302 | ||
| 303 | - (void) setBorderColor:(UIColor *)color // set default text color |
|
| 304 | { |
|
| 305 | borderColor = color; |
|
| 306 | 94 | requiresUpdate = YES; |
| 307 | 65 | } |
| 308 | ||
| 309 | - (void) setCornerRadius:(double)rad |
|
| 310 | { |
|
| 311 | cornerRadius = rad; |
|
| 312 | requiresUpdate = YES; |
|
| 313 | } |
|
| 314 | ||
| 315 | - (void) setBorderWidth:(double)rad |
|
| 316 | { |
|
| 317 | borderWidth = rad; |
|
| 318 | requiresUpdate = YES; |
|
| 319 | } |
|
| 320 | ||
| 321 | @synthesize cornerRadius, borderWidth, boxColor, borderColor, frameSize; |
|
| 322 | ||
| 323 | @end |
|
| 324 | ||
| 325 | #pragma mark - |
|
| 326 | ||
| 327 | @implementation GLQuartzArc |
|
| 328 | ||
| 329 | - (id) init |
|
| 330 | { |
|
| 331 | if (!(self = [super init])) |
|
| 332 | return nil; |
|
| 333 | ||
| 334 | outerRadius = 10.0; |
|
| 335 | borderWidth = 1.0; |
|
| 336 | endAngle = 2.0*M_PI; |
|
| 337 | cornerRadius = 5.0; |
|
| 338 | ||
| 339 | return self; |
|
| 340 | } |
|
| 341 | ||
| 342 | - (void) doQuartzDrawingInContext: (CGContextRef) context sized: (CGSize) imgSize // generates the texture without drawing texture to current context |
|
| 343 | { |
|
| 344 | double bw = (CGColorGetAlpha([borderColor CGColor]) ? borderWidth : 0.0); |
|
| 345 | |
|
| 346 | // double meanRadius = 0.5*(innerRadius+outerRadius); |
|
| 347 | // double rdiff = (outerRadius-innerRadius); |
|
| 348 | double angleRange = endAngle - startAngle; |
|
| 349 | // double innerOffset = texturePadding + rdiff; |
|
| 350 | |
|
| 351 | double cornerCenterRadius = outerRadius - cornerRadius; |
|
| 352 | double cornerAngle = cornerRadius/cornerCenterRadius; |
|
| 353 | |
|
| 354 | BOOL fullCircle = (angleRange > 2.0*M_PI*(1.0-FLT_EPSILON)); |
|
| 355 | |
|
| 356 | if (fullCircle) |
|
| 357 | { |
|
| 358 | cornerAngle = 0.0; |
|
| 359 | cornerCenterRadius = outerRadius; |
|
| 360 | endAngle = 2.0*M_PI + startAngle; |
|
| 361 | } |
|
| 362 | |
|
| 363 | double startArc = startAngle + cornerAngle; |
|
| 364 | double endArc = endAngle - cornerAngle; |
|
| 365 | |
|
| 366 | CGPoint center = CGPointMake(imgSize.width*0.5, imgSize.height*0.5); |
|
| 367 | |
|
| 368 | CGMutablePathRef path = CGPathCreateMutable(); |
|
| 369 | // [path setLineJoinStyle: NSRoundLineJoinStyle]; |
|
| 370 | // [path setLineJoinStyle: NSBevelLineJoinStyle]; |
|
| 371 | ||
| 372 | CGPathMoveToPoint(path, NULL, center.x + cos(startAngle)*cornerCenterRadius, center.y + sin(startAngle)*cornerCenterRadius); |
|
| 373 | |
|
| 374 | double startArcDegrees = 180.0/M_PI*startArc; |
|
| 375 | double endArcDegrees = 180.0/M_PI*endArc; |
|
| 376 | double startAngleDegrees = 180.0/M_PI*startAngle; |
|
| 377 | double endAngleDegrees = 180.0/M_PI*endAngle; |
|
| 378 | |
|
| 379 | if (!fullCircle && (cornerRadius > 0.0)) |
|
| 380 | { |
|
| 381 | CGPoint cc = CGPointMake(center.x + cos(startArc)*cornerCenterRadius, center.y + sin(startArc)*cornerCenterRadius); |
|
| 382 | CGPathAddArc(path, NULL, cc.x, cc.y, cornerRadius, startAngleDegrees - 90.0, startArcDegrees, NO); |
|
| 383 | } |
|
| 384 | |
|
| 385 | CGPathAddArc(path, NULL, center.x, center.y, cornerRadius, startArcDegrees, endArcDegrees, NO); |
|
| 386 | ||
| 387 | if (!fullCircle && (cornerRadius > 0.0)) |
|
| 388 | { |
|
| 389 | CGPoint cc = CGPointMake(center.x + cos(endArc)*cornerCenterRadius, center.y + sin(endArc)*cornerCenterRadius); |
|
| 390 | CGPathAddArc(path, NULL, cc.x, cc.y, cornerRadius, endAngleDegrees, endArcDegrees + 90, NO); |
|
| 391 | } |
|
| 392 | |
|
| 393 | ||
| 394 | if (innerRadius > 0.0) |
|
| 395 | { |
|
| 396 | if (fullCircle) |
|
| 397 | { |
|
| 398 | CGPathCloseSubpath(path); |
|
| 399 | CGPathMoveToPoint(path, NULL, center.x + cos(endArc)*innerRadius, center.y + sin(endArc)*innerRadius); |
|
| 400 | } |
|
| 401 | |
|
| 402 | CGPathAddArc(path, NULL, center.x, center.y, innerRadius, endArcDegrees, startArcDegrees, YES); |
|
| 403 | ||
| 404 | ||
| 405 | } |
|
| 406 | else if (!fullCircle) |
|
| 407 | CGPathAddLineToPoint(path, NULL, center.x, center.y); |
|
| 408 | ||
| 409 | CGPathCloseSubpath(path); |
|
| 410 | ||
| 411 | if (CGColorGetAlpha([fillColor CGColor])) |
|
| 412 | { // this should be == 0.0f but need to make sure |
|
| 413 | [fillColor set]; |
|
| 414 | CGContextAddPath(context, path); |
|
| 415 | CGContextDrawPath(context, kCGPathFill); |
|
| 416 | } |
|
| 417 | ||
| 418 | if (CGColorGetAlpha([borderColor CGColor])) |
|
| 419 | { |
|
| 420 | [borderColor set]; |
|
| 421 | CGContextSetLineWidth(context, bw); |
|
| 422 | CGContextAddPath(context, path); |
|
| 423 | CGContextDrawPath(context, kCGPathStroke); |
|
| 424 | } |
|
| 425 | CGPathRelease(path); |
|
| 426 | 68 | } |
| 427 | 65 | |
| 428 | - (CGSize) updatedTextureSize |
|
| 429 | { |
|
| 430 | CGSize texSize = CGSizeMake(ceil(2.0*outerRadius+2.0*texturePadding), ceil(2.0*outerRadius+2.0*texturePadding)); |
|
| 431 | return texSize; |
|
| 432 | } |
|
| 433 | ||
| 434 | - (void) setFillColor:(UIColor *)color |
|
| 435 | { |
|
| 436 | fillColor = color; |
|
| 437 | 94 | requiresUpdate = YES; |
| 438 | 65 | } |
| 439 | ||
| 440 | ||
| 441 | - (void) setBorderColor:(UIColor *)color |
|
| 442 | { |
|
| 443 | borderColor = color; |
|
| 444 | 94 | requiresUpdate = YES; |
| 445 | 65 | } |
| 446 | ||
| 447 | - (void) setOuterRadius:(double)rad |
|
| 448 | { |
|
| 449 | outerRadius = rad; |
|
| 450 | requiresUpdate = YES; |
|
| 451 | } |
|
| 452 | ||
| 453 | - (void) setInnerRadius:(double)rad |
|
| 454 | { |
|
| 455 | innerRadius = rad; |
|
| 456 | requiresUpdate = YES; |
|
| 457 | } |
|
| 458 | ||
| 459 | - (void) setBorderWidth:(double)rad |
|
| 460 | { |
|
| 461 | borderWidth = rad; |
|
| 462 | requiresUpdate = YES; |
|
| 463 | } |
|
| 464 | ||
| 465 | - (void) setCornerRadius:(double)rad |
|
| 466 | { |
|
| 467 | cornerRadius = rad; |
|
| 468 | requiresUpdate = YES; |
|
| 469 | } |
|
| 470 | ||
| 471 | - (void) setStartAngle:(double)rad |
|
| 472 | { |
|
| 473 | startAngle = rad; |
|
| 474 | requiresUpdate = YES; |
|
| 475 | } |
|
| 476 | ||
| 477 | - (void) setEndAngle:(double)rad |
|
| 478 | { |
|
| 479 | endAngle = rad; |
|
| 480 | requiresUpdate = YES; |
|
| 481 | } |
|
| 482 | ||
| 483 | @synthesize innerRadius, outerRadius, startAngle, endAngle, borderWidth, cornerRadius, fillColor, borderColor; |
|
| 484 | ||
| 485 | @end |
|
| 486 | ||
| 487 | #pragma mark - |
|
| 488 | ||
| 489 | @implementation GLString |
|
| 490 | ||
| 491 | + (UIFont*) defaultFont |
|
| 492 | { |
|
| 493 | UIFont* font = [UIFont systemFontOfSize: [UIFont systemFontSize]]; |
|
| 494 | return font; |
|
| 495 | } |
|
| 496 | ||
| 497 | ||
| 498 | #pragma mark - |
|
| 499 | #pragma mark Initializers |
|
| 500 | ||
| 501 | // designated initializer |
|
| 502 | - (id) initWithString:(NSString *)aString withFont: (UIFont*) aFont withTextColor:(UIColor *)text withBoxColor:(UIColor *)box withBorderColor:(UIColor *)border |
|
| 503 | { |
|
| 504 | if (!(self = [super init])) |
|
| 505 | return nil; |
|
| 506 | ||
| 507 | string = aString; |
|
| 508 | |
|
| 509 | font = aFont; |
|
| 510 | 94 | |
| 511 | 65 | self.textColor = text; |
| 512 | self.boxColor = box; |
|
| 513 | self.borderColor = border; |
|
| 514 | staticFrame = NO; |
|
| 515 | marginSize.width = 4.0f; // standard margins |
|
| 516 | marginSize.height = 2.0f; |
|
| 517 | ||
| 518 | return self; |
|
| 519 | } |
|
| 520 | ||
| 521 | // basic methods that pick up defaults |
|
| 522 | - (id) initWithString:(NSString *)astring; |
|
| 523 | { |
|
| 524 | return [self initWithString: astring withFont: [GLString defaultFont] withTextColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f] withBoxColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.0f] withBorderColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.0f]]; |
|
| 525 | } |
|
| 526 | ||
| 527 | - (id) initWithString:(NSString *)aString withFont:(UIFont *)aFont |
|
| 528 | { |
|
| 529 | return [self initWithString: aString withFont: aFont withTextColor: nil withBoxColor: nil withBorderColor: nil]; |
|
| 530 | } |
|
| 531 | ||
| 532 | - (CGSize) frameSize |
|
| 533 | { |
|
| 534 | if (NO == staticFrame) |
|
| 535 | { // find frame size if we have not already found it |
|
| 536 | frameSize = [string sizeWithFont: font]; // current string size |
|
| 537 | frameSize.width += marginSize.width * 2.0f; // add padding |
|
| 538 | frameSize.height += marginSize.height * 2.0f; |
|
| 539 | } |
|
| 540 | return frameSize; |
|
| 541 | } |
|
| 542 | ||
| 543 | - (CGSize) updatedTextureSize |
|
| 544 | { |
|
| 545 | if (NO == staticFrame) |
|
| 546 | { // find frame size if we have not already found it |
|
| 547 | frameSize = [string sizeWithFont: font]; // current string size |
|
| 548 | frameSize.width += marginSize.width * 2.0f; // add padding |
|
| 549 | frameSize.height += marginSize.height * 2.0f; |
|
| 550 | } |
|
| 551 | return [super updatedTextureSize]; |
|
| 552 | } |
|
| 553 | ||
| 554 | - (void) doQuartzDrawingInContext: (CGContextRef) context sized: (CGSize) imgSize // generates the texture without drawing texture to current context |
|
| 555 | { |
|
| 556 | |
|
| 557 | [super doQuartzDrawingInContext: context sized: imgSize]; |
|
| 558 | |
|
| 559 | [textColor set]; |
|
| 560 | [string drawAtPoint: CGPointMake(marginSize.width+texturePadding, marginSize.height+texturePadding) withFont: font]; // draw at offset position |
|
| 561 | } |
|
| 562 | ||
| 563 | ||
| 564 | - (void) setTextColor:(UIColor *)color // set default text color |
|
| 565 | { |
|
| 566 | textColor = color; |
|
| 567 | 94 | requiresUpdate = YES; |
| 568 | 65 | } |
| 569 | ||
| 570 | ||
| 571 | #pragma mark Margin Size |
|
| 572 | ||
| 573 | // these will force the texture to be regenerated at the next draw |
|
| 574 | - (void) setMargins:(CGSize)size // set offset size and size to fit with offset |
|
| 575 | { |
|
| 576 | marginSize = size; |
|
| 577 | if (NO == staticFrame) { // ensure dynamic frame sizes will be recalculated |
|
| 578 | frameSize.width = 0.0f; |
|
| 579 | frameSize.height = 0.0f; |
|
| 580 | } |
|
| 581 | requiresUpdate = YES; |
|
| 582 | } |
|
| 583 | ||
| 584 | - (CGSize) marginSize |
|
| 585 | { |
|
| 586 | return marginSize; |
|
| 587 | } |
|
| 588 | ||
| 589 | ||
| 590 | #pragma mark Frame |
|
| 591 | ||
| 592 | ||
| 593 | - (BOOL) staticFrame |
|
| 594 | { |
|
| 595 | return staticFrame; |
|
| 596 | } |
|
| 597 | ||
| 598 | - (void) useStaticFrame:(CGSize)size // set static frame size and size to frame |
|
| 599 | { |
|
| 600 | requiresUpdate = requiresUpdate || !staticFrame || !CGSizeEqualToSize(frameSize,size); |
|
| 601 | frameSize = size; |
|
| 602 | staticFrame = YES; |
|
| 603 | } |
|
| 604 | ||
| 605 | - (void) useDynamicFrame |
|
| 606 | { |
|
| 607 | if (staticFrame) { // set to dynamic frame and set to regen texture |
|
| 608 | staticFrame = NO; |
|
| 609 | frameSize.width = 0.0f; // ensure frame sizes will be recalculated |
|
| 610 | frameSize.height = 0.0f; |
|
| 611 | requiresUpdate = YES; |
|
| 612 | } |
|
| 613 | } |
|
| 614 | ||
| 615 | #pragma mark String |
|
| 616 | ||
| 617 | - (void) setString:(NSString *)theString // set string after initial creation |
|
| 618 | { |
|
| 619 | string = [theString copy]; |
|
| 620 | if (NO == staticFrame) { // ensure dynamic frame sizes will be recalculated |
|
| 621 | frameSize.width = 0.0f; |
|
| 622 | frameSize.height = 0.0f; |
|
| 623 | } |
|
| 624 | requiresUpdate = YES; |
|
| 625 | } |
|
| 626 | ||
| 627 | - (void) setFont: (UIFont*) aFont |
|
| 628 | { |
|
| 629 | font = aFont; |
|
| 630 | 94 | if (NO == staticFrame) { // ensure dynamic frame sizes will be recalculated |
| 631 | 65 | frameSize.width = 0.0f; |
| 632 | frameSize.height = 0.0f; |
|
| 633 | } |
|
| 634 | requiresUpdate = YES; |
|
| 635 | } |
|
| 636 | ||
| 637 | @synthesize textColor; |
|
| 638 | ||
| 639 | @end |
|
| 640 |
Loggerhead 1.17 is a web-based interface for Bazaar branches