2012-04-25

iOS 內建字型

參考這篇文章,iOS 內建的字型列出如下 :

Family name: Hiragino Kaku Gothic ProN W3
    Font name: HiraKakuProN-W3

Family name: Courier
    Font name: Courier
    Font name: Courier-BoldOblique
    Font name: Courier-Oblique
    Font name: Courier-Bold

Family name: Arial
    Font name: ArialMT
    Font name: Arial-BoldMT
    Font name: Arial-BoldItalicMT
    Font name: Arial-ItalicMT

Family name: STHeiti TC
    Font name: STHeitiTC-Light
    Font name: STHeitiTC-Medium

Family name: AppleGothic
    Font name: AppleGothic

Family name: Courier New
    Font name: CourierNewPS-BoldMT
    Font name: CourierNewPS-ItalicMT
    Font name: CourierNewPS-BoldItalicMT
    Font name: CourierNewPSMT

Family name: Zapfino
    Font name: Zapfino

Family name: Hiragino Kaku Gothic ProN W6
    Font name: HiraKakuProN-W6

Family name: Arial Unicode MS
    Font name: ArialUnicodeMS

Family name: STHeiti SC
    Font name: STHeitiSC-Medium
    Font name: STHeitiSC-Light

Family name: American Typewriter
    Font name: AmericanTypewriter
    Font name: AmericanTypewriter-Bold

Family name: Helvetica
    Font name: Helvetica-Oblique
    Font name: Helvetica-BoldOblique
    Font name: Helvetica
    Font name: Helvetica-Bold

Family name: Marker Felt
    Font name: MarkerFelt-Thin

Family name: Helvetica Neue
    Font name: HelveticaNeue
    Font name: HelveticaNeue-Bold

Family name: DB LCD Temp
    Font name: DBLCDTempBlack

Family name: Verdana
    Font name: Verdana-Bold
    Font name: Verdana-BoldItalic
    Font name: Verdana
    Font name: Verdana-Italic

Family name: Times New Roman
    Font name: TimesNewRomanPSMT
    Font name: TimesNewRomanPS-BoldMT
    Font name: TimesNewRomanPS-BoldItalicMT
    Font name: TimesNewRomanPS-ItalicMT

Family name: Georgia
    Font name: Georgia-Bold
    Font name: Georgia
    Font name: Georgia-BoldItalic
    Font name: Georgia-Italic

Family name: STHeiti J
    Font name: STHeitiJ-Medium
    Font name: STHeitiJ-Light

Family name: Arial Rounded MT Bold
    Font name: ArialRoundedMTBold

Family name: Trebuchet MS
    Font name: TrebuchetMS-Italic
    Font name: TrebuchetMS
    Font name: Trebuchet-BoldItalic
    Font name: TrebuchetMS-Bold

Family name: STHeiti K
    Font name: STHeitiK-Medium
    Font name: STHeitiK-Light

2012-04-24

Unity 3D 在 iOS 上顯示中文字串


之前使用 Unity3D 寫遊戲程式都是以 Dynamic Font 功能來顯示中文字串,最近才發現這功能不支援 iOS,因此若要在 iOS 上使用 Dynamic Font 就得自己做了,幸運的是實作起來並不複雜,底下敘述如何將中文字串轉成圖片 ( Texture2D ) 的方法 : ( 概略是利用 iOS 內建的 Font Renderer 先把字串畫在主記憶體裡,再利用 OpenGL 指令將記憶體裡字串的圖片轉成貼圖 )

全部範例檔案有三個 :
1. main.cs
    a. 放在 Assets 目錄底下
    b. 此 Script 依附在 Main Camera 上

2. dynaFont.cs
    a. 放在 Assets/Plugins 目錄底下
    b. 此檔案為 unity3d 內部 script 與 plugin 之間的介面

3. dynaFont.m
    a. 放在 Assets/Plugins/iOS 目錄底下 (轉成 xcode project 時將自動引入)
    b. 不需事先編譯

首先看 main.cs 檔案內容 :


using UnityEngine;
using System.Collections;

public class main : MonoBehaviour {

    // Use this for initialization
    void Start ()
    {
        int nWidth =128;
int nHeight =128;

        //產生 128x128 (注意大小為2冪次方)之 texture
Texture2D tex =
            new Texture2D(
                nWidth, 
                nHeight, 
                TextureFormat.Alpha8
                false);

        //把中文字畫在 texture 上
        genTexture(
            tex.GetNativeTextureID(), 
            "中文測試"
            "Arial"
            10
            128
            128);
}
}


dynaFont.cs 檔案內容如下 :


using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
//
//此為 unity3d 內部程式呼叫外部 plugin 函數之間的介面
//
public class dynaFont
{
    //指示 getTexture 為外部 plugin 函數
  [DllImport("__Internal")]
  public static extern bool genTexture(
        int nTexID, 
        string strText, 
        string strFontName, 
        int nFontSz, 
        int nTexWidth, 
        int nTexHeight);
}


dynaFont.m 檔案內容如下 :


#import <Foundation/Foundation.h>
//
// 將 char 指標 (對應 C# 的 string) 轉成 iOS 字串格式 (NSString)
//
NSString* dynaFont_GetString(const char* pChar)
{
  if (pChar ==NULL)
      return [NSString stringWithUTF8String:""];
return [NSString stringWithUTF8String:pChar];
}


//
// 利用 NSString 的 drawInRect 畫出字串後再以 glTexImage2D 產生貼圖
//
bool genTexture( int nTexID, 
                 const char* pStrText, 
                 const char* pStrFontName, 
                 int nFontSz, 
                 int nTexWidth, 
                 int nTexHeight)
{
    unsigned char* pData =
        (unsigned char*)calloc(nTexWidth, nTexHeight);

    CGColorSpaceRef pcs =CGColorSpaceCreateDeviceGray();
    CGContextRef pcon =
        CGBitmapContextCreate(
            pData, 
            nTexWidth, 
            nTexHeight, 
            8
            nTexWidth, 
            pcs, 
            kCGImageAlphaNone);
    CGColorSpaceRelease(pcs);

    if (!pcon)
    {
      free(pData);
      return false;
    }
    else
    {
      CGContextSetGrayFillColor(pcon, 1.0f, 1.0f);

    CGSize rc =CGSizeMake(nTexWidth, nTexHeight);
    UIFont* pf =
            [ UIFont
              fontWithName:dynaFont_GetString(pStrFontName) 
              size:nFontSz];

    UIGraphicsPushContext(pcon);
        [ dynaFont_GetString(pStrText)
          drawInRect:CGRectMake(0,0,rc.width, rc.height) 
          withFont:pf lineBreakMode:UILineBreakModeWordWrap 
          alignment:UITextAlignmentLeft];
    UIGraphicsPopContext();

    glBindTexture(GL_TEXTURE_2D, nTexID);
    glTexImage2D(
            GL_TEXTURE_2D, 
            0
            GL_ALPHA, 
           (GLsizei)nTexWidth, (GLsizei)nTexHeight, 
            0
            GL_ALPHA, 
            GL_UNSIGNED_BYTE, 
            pData);
    CGContextRelease(pcon);

    free(pData);
    }
    return true;
}


2012-04-14

關於 iOS 開發環境設定的兩三事

2012-04-14 :
  1. 若是使用自己的 apple id 取得 ios developer program 則直接參考 此聯結 做設定。
  2. 若是某人已取得 ios developer program ,要讓自己也可以開發 ( 不同/或相同的電腦,作業系統裡使用不同的使用者帳號名稱 ),則按下列步驟設定 :
    • 使用已取得 ios developer program 的 apple id 到此頁面,按下 invite person ,邀請自己,按下後自己將收到邀請函,按下邀請函上面的連結之後,會開啟網頁詢問是否已有 apple id,若已有 apple id,登入過後就會發現自己的 apple id 也加入 ios developer program 了。
    • 以自己的  apple id 參考 此聯結 做後續設定。
  3. ( 尚未測試 ) 若是某人已取得 ios developer program,後來再買了一台電腦,想要在另一台電腦上也可以開發 ( 不同的電腦,作業系統裡使用相同的使用者帳號名稱 ) ,則按下列步驟設定 :
    • 至 applications > utilities >  Keychain Access 選擇左下方 ‘Keys’ 。
    • 找到具有 iOS Development Certificate 的 private key,按下右鍵 (control +左鍵) 選 export ...。最後會得到一個 (.p12) 的檔案。
    • 將檔案複製在另一台電腦並安裝之。
    • 參考 此聯結 並跳至第六項之後做後續設定。
  4. 因為 Snow Leopard 上的 xcode 只到 4.2 版就沒有再更新了,因此若手機上的 iOS 是 5.1 版,則要升級作業系統至 Lion ( 才可安裝 xcode 4.3 以上版本) 或將手機 iOS 降級至 5.0 才可讓 xcode 支援使用。若不想升級作業系統或降級 iOS,還是可以按照下列步驟將 iOS 5.1 SDK 強制安裝至 xcode 4.2 (參考 此聯結 ) :
    • 這裡 下載最新版 xcode。
    • 進入 terminal (applications > utilities > terminal ),依序輸入下列指令 ( 此指令是針對 xcode 4.2 安裝至 /Developer )
sudo cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
sudo cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/
sudo cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/5.1\ \(9B176\) /Developer/Platforms/iPhoneOS.platform/DeviceSupport/
sudo rm -f /Developer/Platforms/iPhoneOS.platform/DeviceSupport/Latestcd /Developer/Platforms/iPhoneOS.platform/DeviceSupport/
sudo ln -s ./5.1\ \(9B176\) ./Latest

2012-04-06

NodeJS 執行時期更新程式碼

這是一個很酷的特性!nodejs 在執行期間不必重新啟動就可以更新程式碼!例如有個用 nodejs 寫的 http / socket server 正在執行當中,現在要為它修改或是增加新的功能,則直接修改程式碼後儲存,完全不必重新啟動伺服器。
底下是一個簡單的範例,把 main.js 執行起來,它會監控 module0.js ,並定時呼叫 module0.js 的 say function ,當 module0.js 更動後(例如更改 say funciton 裡要顯示出的字串),它會自動重新載入 module0.js 的程式碼:

檔案 main.js :
var l_module =require('./module0');
var l_fs =require('fs');

l_fs.watch('module0.js',
    function(event, pFilename)
    {
        console.log('new event='+event+', filename='+pFilename);
        if (event ==='change')
        {
            var name =require.resolve('./module0');
            delete require.cache[name];
            console.log('resolved modulename ='+name);
               
            try
            {
                l_module =require('./module0');               
            }
            catch(err)
            {
                console.log(err);
                l_module =undefined;
            }
        }
    }
);

var dosomething =
    function()
    {
        if (l_module !==undefined &&
            l_module.hasOwnProperty('say')===true)
        {
            l_module.say();
        }
        else
        {
            console.log('module unavailable');
        }
       
        setTimeout(dosomething, 1000);
    };
   
setTimeout( dosomething, 1000 );


檔案 module0.js :
exports.say =
    function()
    {
        console.log('im module0 -version 0');
    };