3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アイコン用文字+フォントを32bitで表現

Posted at

背景

画像の代わりにフォントを使用に書いた通り、僕はベクター画像データとしてフォントを多用しています。フォントを使う場合に厄介なのが、文字(NSString)と、フォント(UIFont)を組み合わせないと適切なアイコンにならないことです。
アイコンは様々な種類を使うので、シンプルにアイコンを定義する方法が欲しくなりました。

文字+フォント=?

NSString + UIFontのテーブルを作るのはいけてません。。。そこで思いついたのが、Unicodeのコードポイント(32bit)を使う方法です。
基本的に「普通の1文字」は、32bit整数の「1コードポイント」で表現できます。そして、コードポイントは下位21ビットしか使用していないので、使われていない上位ビットにフォント情報を入れることができます。

この方法なら32bit整数で文字+フォントが表現できるので、普通にenumとしてアイコンが定義できます。
あとは、このenumからNSAttributedStringや、UIImageを生成すれば良い訳です。

下記のように一度enumを定義すれば、あとはこのenumだけで一意にアイコンを決めることが出来ます。

typedef enum PPIconFontType : uint32_t{
    PPIconFontType_SS_PIKA                      = 1 << 24,
    //フォントも本当は数種類
}PPIconFontType;

typedef enum PPIconCodePoint : uint32_t{
    // SS-PIKA
    PPIconCodePoint_PIKA_CURSOR    = PPIconFontType_SS_PIKA | 0xE001,
    PPIconCodePoint_PIKA_CROSSHAIR = PPIconFontType_SS_PIKA | 0x2316,
    PPIconCodePoint_PIKA_SEARCH    = PPIconFontType_SS_PIKA | 0x1F50E,
    //以下定義が続く...

Unicode Code PointからNSStringへの変換

32bitのコードポイントを16bitのunicharで表現すると1文字か、2文字になります。これは扱いにくいので、僕はNSStringに変換して使用しています。言うまでもないですが、フォント情報はマスクしてから処理する必要があります。

NSString+BTKUnicode.h
//
//  NSString+BTKUnicode.h
//  BTKCommons
//
//  Created by Tomohisa Ota on 3/5/14.
//
//

#import <Foundation/Foundation.h>

@interface NSString (BTKUnicode)

+ (NSString*) btkStringWithCodePoint : (int32_t) codePoint;

@end
NSString+BTKUnicode.m
//
//  NSString+BTKUnicode.m
//  BTKCommons
//
//  Created by Tomohisa Ota on 3/5/14.
//
//

#import "NSString+BTKUnicode.h"

@implementation NSString (BTKUnicode)

+ (NSString*) btkStringWithCodePoint : (int32_t)codePoint;

{
    unichar characters[2];
    NSUInteger length;
    if (codePoint <= 0xD7FF || (0xE000 <= codePoint && codePoint <= 0xFFFF) ) {
        characters[0] = codePoint;
        length = 1;
    }
    else if (0x10000 <= codePoint && codePoint <= 0x10ffff ) {
        codePoint -= 0x10000;
        characters[0] = 0xD800 + (codePoint >> 10);
        characters[1] = 0xDC00 + (codePoint & 0x3ff);
        length = 2;
    }
    else {
        return nil;
    }
    return [NSString stringWithCharacters:characters length:length];
}

@end
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?