#if 1 // fix macOS 10.15 system font 修复添加代码
#else // 删除代码
static bool _initWithString(const char * text, Device::TextAlign align, const char * fontName, int size, tImageInfo* info, const Color3B* strokeColor)
{
bool ret = false;
CCASSERT(text, "Invalid pText");
CCASSERT(info, "Invalid pInfo");
do {
NSString * string = [NSString stringWithUTF8String:text];
NSString * fntName = [NSString stringWithUTF8String:fontName];
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
// font
NSFont *font = [[NSFontManager sharedFontManager]
fontWithFamily:fntName
traits:NSUnboldFontMask | NSUnitalicFontMask
weight:0
size:size];
if (font == nil) {
font = [[NSFontManager sharedFontManager]
fontWithFamily:@"Arial"
traits:NSUnboldFontMask | NSUnitalicFontMask
weight:0
size:size];
}
CC_BREAK_IF(!font);
// color
NSColor* foregroundColor;
if (strokeColor) {
foregroundColor = [NSColor colorWithDeviceRed:strokeColor->r/255.0 green:strokeColor->g/255.0 blue:strokeColor->b/255.0 alpha:1];
} else {
foregroundColor = [NSColor whiteColor];
}
// alignment, linebreak
unsigned horiFlag = (int)align & 0x0f;
unsigned vertFlag = ((int)align >> 4) & 0x0f;
NSTextAlignment textAlign = (2 == horiFlag) ? NSRightTextAlignment
: (3 == horiFlag) ? NSCenterTextAlignment
: NSLeftTextAlignment;
NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
[paragraphStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
[paragraphStyle setLineBreakMode:NSLineBreakByCharWrapping];
[paragraphStyle setAlignment:textAlign];
// attribute
NSDictionary* tokenAttributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
foregroundColor,NSForegroundColorAttributeName,
font, NSFontAttributeName,
paragraphStyle, NSParagraphStyleAttributeName, nil];
// linebreak
if (info->width > 0) {
if ([string sizeWithAttributes:tokenAttributesDict].width > info->width) {
NSMutableString *lineBreak = [[[NSMutableString alloc] init] autorelease];
NSUInteger length = [string length];
NSRange range = NSMakeRange(0, 1);
NSSize textSize;
NSUInteger lastBreakLocation = 0;
NSUInteger insertCount = 0;
for (NSUInteger i = 0; i < length; i++) {
range.location = i;
NSString *character = [string substringWithRange:range];
[lineBreak appendString:character];
if ([@"!?.,-= " rangeOfString:character].location != NSNotFound) {
lastBreakLocation = i + insertCount;
}
textSize = [lineBreak sizeWithAttributes:tokenAttributesDict];
if(info->height > 0 && textSize.height > info->height)
break;
if (textSize.width > info->width) {
if(lastBreakLocation > 0) {
[lineBreak insertString:@"\r" atIndex:lastBreakLocation];
lastBreakLocation = 0;
}
else {
[lineBreak insertString:@"\r" atIndex:[lineBreak length] - 1];
}
insertCount += 1;
}
}
string = lineBreak;
}
}
NSAttributedString *stringWithAttributes =[[[NSAttributedString alloc] initWithString:string
attributes:tokenAttributesDict] autorelease];
NSSize realDimensions = [stringWithAttributes size];
// Mac crashes if the width or height is 0
CC_BREAK_IF(realDimensions.width <= 0 || realDimensions.height <= 0);
CGSize dimensions = CGSizeMake(info->width, info->height);
if(dimensions.width <= 0 && dimensions.height <= 0) {
dimensions.width = realDimensions.width;
dimensions.height = realDimensions.height;
} else if (dimensions.height <= 0) {
dimensions.height = realDimensions.height;
}
NSInteger POTWide = dimensions.width;
NSInteger POTHigh = MAX(dimensions.height, realDimensions.height);
unsigned char* data;
//Alignment
CGFloat xPadding = 0;
switch (textAlign) {
case NSLeftTextAlignment: xPadding = 0; break;
case NSCenterTextAlignment: xPadding = (dimensions.width-realDimensions.width)/2.0f; break;
case NSRightTextAlignment: xPadding = dimensions.width-realDimensions.width; break;
default: break;
}
// 1: TOP
// 2: BOTTOM
// 3: CENTER
CGFloat yPadding = (1 == vertFlag || realDimensions.height >= dimensions.height) ? (dimensions.height - realDimensions.height) // align to top
: (2 == vertFlag) ? 0 // align to bottom
: (dimensions.height - realDimensions.height) / 2.0f; // align to center
NSRect textRect = NSMakeRect(xPadding, POTHigh - dimensions.height + yPadding, realDimensions.width, realDimensions.height);
#if 1 // fix macOS 10.15 system font
NSBitmapImageRep* offscreenRep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:POTWide
pixelsHigh:POTHigh
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat: 0
bytesPerRow:4 * POTWide
bitsPerPixel:32] autorelease];
NSGraphicsContext* g = [NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:g];
[stringWithAttributes drawInRect:textRect];
[NSGraphicsContext restoreGraphicsState];
data = (unsigned char*) [offscreenRep bitmapData]; //Use the same buffer to improve the performance.
#else
//Disable antialias
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(POTWide, POTHigh)];
[image lockFocus];
// patch for mac retina display and lableTTF
[[NSAffineTransform transform] set];
//[stringWithAttributes drawAtPoint:NSMakePoint(xPadding, offsetY)]; // draw at offset position
[stringWithAttributes drawInRect:textRect];
//[stringWithAttributes drawInRect:textRect withAttributes:tokenAttributesDict];
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect (0.0f, 0.0f, POTWide, POTHigh)];
[image unlockFocus];
data = (unsigned char*) [bitmap bitmapData]; //Use the same buffer to improve the performance.
#endif
NSUInteger textureSize = POTWide*POTHigh*4;
unsigned char* dataNew = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
if (dataNew) {
memcpy(dataNew, data, textureSize);
// output params
info->width = static_cast<int>(POTWide);
info->height = static_cast<int>(POTHigh);
info->data = dataNew;
info->hasAlpha = true;
info->isPremultipliedAlpha = true;
ret = true;
}
#if 1 // fix macOS 10.15 system font
#else
[bitmap release];
[image release];
#endif
} while (0);
return ret;
}