2012-07-21 12:23:40 +08:00
|
|
|
/****************************************************************************
|
2014-01-07 11:25:07 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
2013-07-17 17:12:04 +08:00
|
|
|
|
2014-04-27 01:35:57 +08:00
|
|
|
#include "base/CCPlatformConfig.h"
|
2014-01-31 08:51:43 +08:00
|
|
|
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
|
|
|
|
|
2014-04-27 01:11:22 +08:00
|
|
|
#include "2d/platform/CCDevice.h"
|
2012-07-21 12:23:40 +08:00
|
|
|
#include <Foundation/Foundation.h>
|
|
|
|
#include <Cocoa/Cocoa.h>
|
|
|
|
#include <string>
|
2014-04-27 01:11:22 +08:00
|
|
|
#include "2d/ccTypes.h"
|
2012-07-21 12:23:40 +08:00
|
|
|
|
2013-07-18 13:40:32 +08:00
|
|
|
NS_CC_BEGIN
|
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
int Device::getDPI()
|
|
|
|
{
|
|
|
|
//TODO:
|
|
|
|
return 160;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Device::setAccelerometerEnabled(bool isEnabled)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Device::setAccelerometerInterval(float interval)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
2013-12-06 16:32:06 +08:00
|
|
|
int height;
|
|
|
|
int width;
|
2012-07-21 12:23:40 +08:00
|
|
|
bool hasAlpha;
|
|
|
|
bool isPremultipliedAlpha;
|
|
|
|
unsigned char* data;
|
|
|
|
} tImageInfo;
|
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
static bool _initWithString(const char * text, Device::TextAlign align, const char * fontName, int size, tImageInfo* info, Color3B* strokeColor)
|
2012-07-21 12:23:40 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
bool ret = false;
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
CCASSERT(text, "Invalid pText");
|
|
|
|
CCASSERT(info, "Invalid pInfo");
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
do {
|
2013-12-18 17:47:20 +08:00
|
|
|
NSString * string = [NSString stringWithUTF8String:text];
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
// font
|
|
|
|
NSFont *font = [[NSFontManager sharedFontManager]
|
2014-02-13 21:08:43 +08:00
|
|
|
fontWithFamily:[NSString stringWithUTF8String:fontName]
|
2012-07-21 12:23:40 +08:00
|
|
|
traits:NSUnboldFontMask | NSUnitalicFontMask
|
2014-02-13 21:08:43 +08:00
|
|
|
weight:0
|
|
|
|
size:size];
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
if (font == nil) {
|
|
|
|
font = [[NSFontManager sharedFontManager]
|
|
|
|
fontWithFamily:@"Arial"
|
|
|
|
traits:NSUnboldFontMask | NSUnitalicFontMask
|
|
|
|
weight:0
|
2013-12-18 17:47:20 +08:00
|
|
|
size:size];
|
2012-07-21 12:23:40 +08:00
|
|
|
}
|
|
|
|
CC_BREAK_IF(!font);
|
|
|
|
|
|
|
|
// color
|
|
|
|
NSColor* foregroundColor;
|
2013-12-18 17:47:20 +08:00
|
|
|
if (strokeColor) {
|
|
|
|
foregroundColor = [NSColor colorWithDeviceRed:strokeColor->r/255.0 green:strokeColor->g/255.0 blue:strokeColor->b/255.0 alpha:1];
|
2012-07-21 12:23:40 +08:00
|
|
|
} else {
|
|
|
|
foregroundColor = [NSColor whiteColor];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// alignment, linebreak
|
2013-12-18 17:47:20 +08:00
|
|
|
unsigned horiFlag = (int)align & 0x0f;
|
|
|
|
unsigned vertFlag = ((int)align >> 4) & 0x0f;
|
|
|
|
NSTextAlignment textAlign = (2 == horiFlag) ? NSRightTextAlignment
|
2014-02-13 21:08:43 +08:00
|
|
|
: (3 == horiFlag) ? NSCenterTextAlignment
|
|
|
|
: NSLeftTextAlignment;
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
|
|
|
|
[paragraphStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
|
|
|
|
[paragraphStyle setLineBreakMode:NSLineBreakByCharWrapping];
|
2013-12-18 17:47:20 +08:00
|
|
|
[paragraphStyle setAlignment:textAlign];
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
// attribute
|
|
|
|
NSDictionary* tokenAttributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
foregroundColor,NSForegroundColorAttributeName,
|
|
|
|
font, NSFontAttributeName,
|
|
|
|
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2014-02-17 14:35:49 +08:00
|
|
|
// linebreak
|
2013-12-18 17:47:20 +08:00
|
|
|
if (info->width > 0) {
|
|
|
|
if ([string sizeWithAttributes:tokenAttributesDict].width > info->width) {
|
2012-07-21 12:23:40 +08:00
|
|
|
NSMutableString *lineBreak = [[[NSMutableString alloc] init] autorelease];
|
|
|
|
NSUInteger length = [string length];
|
|
|
|
NSRange range = NSMakeRange(0, 1);
|
2014-02-17 14:35:49 +08:00
|
|
|
CGSize textSize;
|
2013-05-29 22:40:19 +08:00
|
|
|
NSUInteger lastBreakLocation = 0;
|
2014-02-17 14:35:49 +08:00
|
|
|
NSUInteger insertCount = 0;
|
2012-07-21 12:23:40 +08:00
|
|
|
for (NSUInteger i = 0; i < length; i++) {
|
|
|
|
range.location = i;
|
2013-05-29 22:40:19 +08:00
|
|
|
NSString *character = [string substringWithRange:range];
|
2013-05-24 01:30:56 +08:00
|
|
|
[lineBreak appendString:character];
|
2014-02-17 14:35:49 +08:00
|
|
|
if ([@"!?.,-= " rangeOfString:character].location != NSNotFound) {
|
|
|
|
lastBreakLocation = i + insertCount;
|
|
|
|
}
|
|
|
|
textSize = [lineBreak sizeWithAttributes:tokenAttributesDict];
|
|
|
|
if(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;
|
2012-07-21 12:23:40 +08:00
|
|
|
}
|
|
|
|
}
|
2014-02-17 14:35:49 +08:00
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
string = lineBreak;
|
|
|
|
}
|
|
|
|
}
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
NSAttributedString *stringWithAttributes =[[[NSAttributedString alloc] initWithString:string
|
2014-02-13 21:08:43 +08:00
|
|
|
attributes:tokenAttributesDict] autorelease];
|
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
NSSize realDimensions = [stringWithAttributes size];
|
|
|
|
// Mac crashes if the width or height is 0
|
|
|
|
CC_BREAK_IF(realDimensions.width <= 0 || realDimensions.height <= 0);
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
CGSize dimensions = CGSizeMake(info->width, info->height);
|
2012-07-21 12:23:40 +08:00
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
if(dimensions.width <= 0 && dimensions.height <= 0) {
|
|
|
|
dimensions.width = realDimensions.width;
|
|
|
|
dimensions.height = realDimensions.height;
|
|
|
|
} else if (dimensions.height <= 0) {
|
|
|
|
dimensions.height = realDimensions.height;
|
|
|
|
}
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2013-12-06 16:32:06 +08:00
|
|
|
NSInteger POTWide = dimensions.width;
|
|
|
|
NSInteger POTHigh = MAX(dimensions.height, realDimensions.height);
|
2012-07-21 12:23:40 +08:00
|
|
|
unsigned char* data;
|
|
|
|
//Alignment
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2012-07-21 12:23:40 +08:00
|
|
|
CGFloat xPadding = 0;
|
2013-12-18 17:47:20 +08:00
|
|
|
switch (textAlign) {
|
2012-07-21 12:23:40 +08:00
|
|
|
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;
|
|
|
|
}
|
2014-02-13 21:08:43 +08:00
|
|
|
|
2013-06-12 05:59:40 +08:00
|
|
|
// 1: TOP
|
|
|
|
// 2: BOTTOM
|
|
|
|
// 3: CENTER
|
2013-12-18 17:47:20 +08:00
|
|
|
CGFloat yPadding = (1 == vertFlag || realDimensions.height >= dimensions.height) ? (dimensions.height - realDimensions.height) // align to top
|
|
|
|
: (2 == vertFlag) ? 0 // align to bottom
|
2012-07-21 12:23:40 +08:00
|
|
|
: (dimensions.height - realDimensions.height) / 2.0f; // align to center
|
|
|
|
|
|
|
|
|
|
|
|
NSRect textRect = NSMakeRect(xPadding, POTHigh - dimensions.height + yPadding, realDimensions.width, realDimensions.height);
|
|
|
|
//Disable antialias
|
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
|
2012-07-21 12:23:40 +08:00
|
|
|
|
|
|
|
NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(POTWide, POTHigh)];
|
2013-02-27 11:10:42 +08:00
|
|
|
|
|
|
|
[image lockFocus];
|
|
|
|
|
|
|
|
// patch for mac retina display and lableTTF
|
|
|
|
[[NSAffineTransform transform] set];
|
2012-07-21 12:23:40 +08:00
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
//[stringWithAttributes drawAtPoint:NSMakePoint(xPadding, offsetY)]; // draw at offset position
|
2012-07-21 12:23:40 +08:00
|
|
|
[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.
|
|
|
|
|
|
|
|
NSUInteger textureSize = POTWide*POTHigh*4;
|
|
|
|
|
2014-02-18 10:11:04 +08:00
|
|
|
unsigned char* dataNew = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
|
2012-08-25 12:39:41 +08:00
|
|
|
if (dataNew) {
|
|
|
|
memcpy(dataNew, data, textureSize);
|
|
|
|
// output params
|
2013-12-18 17:47:20 +08:00
|
|
|
info->width = static_cast<int>(POTWide);
|
|
|
|
info->height = static_cast<int>(POTHigh);
|
|
|
|
info->data = dataNew;
|
|
|
|
info->hasAlpha = true;
|
|
|
|
info->isPremultipliedAlpha = true;
|
|
|
|
ret = true;
|
2012-08-25 12:39:41 +08:00
|
|
|
}
|
2012-07-21 12:23:40 +08:00
|
|
|
[bitmap release];
|
2012-08-25 12:39:41 +08:00
|
|
|
[image release];
|
2012-07-21 12:23:40 +08:00
|
|
|
} while (0);
|
2013-12-18 17:47:20 +08:00
|
|
|
return ret;
|
2012-07-21 12:23:40 +08:00
|
|
|
}
|
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
Data Device::getTextureDataForText(const char * text,const FontDefinition& textDefinition,TextAlign align,int &width,int &height)
|
2012-07-21 12:23:40 +08:00
|
|
|
{
|
2014-02-13 21:08:43 +08:00
|
|
|
Data ret;
|
|
|
|
do {
|
|
|
|
tImageInfo info = {0};
|
|
|
|
info.width = textDefinition._dimensions.width;
|
|
|
|
info.height = textDefinition._dimensions.height;
|
|
|
|
|
|
|
|
if (! _initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info, nullptr)) //pStrokeColor))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
height = (short)info.height;
|
2014-02-14 09:41:06 +08:00
|
|
|
width = (short)info.width;
|
2014-02-13 21:08:43 +08:00
|
|
|
ret.fastSet(info.data,width * height * 4);
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
return ret;
|
2012-07-21 12:23:40 +08:00
|
|
|
}
|
2012-09-05 16:15:09 +08:00
|
|
|
NS_CC_END
|
2012-07-21 12:23:40 +08:00
|
|
|
|
2014-01-31 08:51:43 +08:00
|
|
|
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_MAC
|