コード例 #1
0
        public GameObject MakePrefab(Entity entity)
        {
            GameObject root = new GameObject(entity.Name);
            var mapBuilder = new CharacterMapBuilder();
            charMap = mapBuilder.BuildMap(entity, root);

            foreach (var animation in entity.Animations)
            {
                MakePrefab(animation, root);
            }
            return root;
        }
コード例 #2
0
        public GameObject MakePrefab(Entity entity, GameObject root, string spriteFolder)
        {
            //Set the name (in case it changed)
            root.name = entity.Name;

            //Build the character map first
            var mapBuilder = new CharacterMapBuilder();
            charMap = mapBuilder.BuildMap(entity, root, spriteFolder);

            //Build the GameObject hierarchy
            foreach (var animation in entity.Animations)
            {
                MakePrefab(animation, root);
            }
            return root;
        }
コード例 #3
0
ファイル: UIFontMaker.cs プロジェクト: hanbim520/UFLua
	/// <summary>
	/// Draw the UI for this tool.
	/// </summary>

	void OnGUI ()
	{
		Object fnt = (Object)NGUISettings.FMFont ?? (Object)NGUISettings.BMFont;
		UIFont uiFont = (fnt as UIFont);

		NGUIEditorTools.SetLabelWidth(80f);
		GUILayout.Space(3f);

		NGUIEditorTools.DrawHeader("Input", true);
		NGUIEditorTools.BeginContents(false);

		GUILayout.BeginHorizontal();
		mType = (FontType)EditorGUILayout.EnumPopup("Type", mType, GUILayout.MinWidth(200f));
		NGUIEditorTools.DrawPadding();
		GUILayout.EndHorizontal();
		Create create = Create.None;

		if (mType == FontType.ImportedBitmap)
		{
			NGUISettings.fontData = EditorGUILayout.ObjectField("Font Data", NGUISettings.fontData, typeof(TextAsset), false) as TextAsset;
			NGUISettings.fontTexture = EditorGUILayout.ObjectField("Texture", NGUISettings.fontTexture, typeof(Texture2D), false, GUILayout.Width(140f)) as Texture2D;
			NGUIEditorTools.EndContents();

			// Draw the atlas selection only if we have the font data and texture specified, just to make it easier
			EditorGUI.BeginDisabledGroup(NGUISettings.fontData == null || NGUISettings.fontTexture == null);
			{
				NGUIEditorTools.DrawHeader("Output", true);
				NGUIEditorTools.BeginContents(false);
				ComponentSelector.Draw<UIAtlas>(NGUISettings.atlas, OnSelectAtlas, false);
				NGUIEditorTools.EndContents();
			}
			EditorGUI.EndDisabledGroup();

			if (NGUISettings.fontData == null)
			{
				EditorGUILayout.HelpBox("To create a font from a previously exported FNT file, you need to use BMFont on " +
					"Windows or your choice of Glyph Designer or the less expensive bmGlyph on the Mac.\n\n" +
					"Either of these tools will create a FNT file for you that you will drag & drop into the field above.", MessageType.Info);
			}
			else if (NGUISettings.fontTexture == null)
			{
				EditorGUILayout.HelpBox("When exporting your font, you should get two files: the FNT, and the texture. Only one texture can be used per font.", MessageType.Info);
			}
			else if (NGUISettings.atlas == null)
			{
				EditorGUILayout.HelpBox("You can create a font that doesn't use a texture atlas. This will mean that the text " +
					"labels using this font will generate an extra draw call.\n\nIf you do specify an atlas, the font's texture will be added to it automatically.", MessageType.Info);
			}

			EditorGUI.BeginDisabledGroup(NGUISettings.fontData == null || NGUISettings.fontTexture == null);
			{
				GUILayout.BeginHorizontal();
				GUILayout.Space(20f);
				if (GUILayout.Button("Create the Font")) create = Create.Import;
				GUILayout.Space(20f);
				GUILayout.EndHorizontal();
			}
			EditorGUI.EndDisabledGroup();
		}
		else
		{
			GUILayout.BeginHorizontal();
			if (NGUIEditorTools.DrawPrefixButton("Source"))
				ComponentSelector.Show<Font>(OnUnityFont, new string[] { ".ttf", ".otf" });

			Font ttf = EditorGUILayout.ObjectField(NGUISettings.FMFont, typeof(Font), false) as Font;
			GUILayout.EndHorizontal();

			GUILayout.BeginHorizontal();
			{
				NGUISettings.FMSize = EditorGUILayout.IntField("Size", NGUISettings.FMSize, GUILayout.Width(120f));

				if (mType == FontType.Dynamic)
				{
					NGUISettings.fontStyle = (FontStyle)EditorGUILayout.EnumPopup(NGUISettings.fontStyle);
					NGUIEditorTools.DrawPadding();
				}
			}
			GUILayout.EndHorizontal();

			// Choose the font style if there are multiple faces present
			if (mType == FontType.GeneratedBitmap)
			{
				if (!FreeType.isPresent)
				{
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
					string filename = (Application.platform == RuntimePlatform.WindowsEditor) ? "FreeType.dll" : "FreeType.dylib";
#else
					string filename = (Application.platform == RuntimePlatform.WindowsEditor) ? "FreeType64.dll" : "FreeType64.dylib";
#endif
					EditorGUILayout.HelpBox("Assets/NGUI/Editor/" + filename + " is missing", MessageType.Error);

					GUILayout.BeginHorizontal();
					GUILayout.Space(20f);

					if (GUILayout.Button("Find " + filename))
					{
						string path = EditorUtility.OpenFilePanel("Find " + filename, NGUISettings.currentPath,
							(Application.platform == RuntimePlatform.WindowsEditor) ? "dll" : "dylib");

						if (!string.IsNullOrEmpty(path))
						{
							if (System.IO.Path.GetFileName(path) == filename)
							{
								NGUISettings.currentPath = System.IO.Path.GetDirectoryName(path);
								NGUISettings.pathToFreeType = path;
							}
							else Debug.LogError("The library must be named '" + filename + "'");
						}
					}
					GUILayout.Space(20f);
					GUILayout.EndHorizontal();
				}
				else if (ttf != null)
				{
					string[] faces = FreeType.GetFaces(ttf);

					if (faces != null)
					{
						if (mFaceIndex >= faces.Length) mFaceIndex = 0;

						if (faces.Length > 1)
						{
							GUILayout.Label("Style", EditorStyles.boldLabel);
							for (int i = 0; i < faces.Length; ++i)
							{
								GUILayout.BeginHorizontal();
								GUILayout.Space(10f);
								if (DrawOption(i == mFaceIndex, " " + faces[i]))
									mFaceIndex = i;
								GUILayout.EndHorizontal();
							}
						}
					}

					NGUISettings.fontKerning = EditorGUILayout.Toggle("Kerning", NGUISettings.fontKerning);

					GUILayout.Label("Characters", EditorStyles.boldLabel);

					CharacterMap cm = characterMap;

					GUILayout.BeginHorizontal(GUILayout.Width(100f));
					GUILayout.BeginVertical();
					GUI.changed = false;
					if (DrawOption(cm == CharacterMap.Numeric, " Numeric")) cm = CharacterMap.Numeric;
					if (DrawOption(cm == CharacterMap.Ascii, " ASCII")) cm = CharacterMap.Ascii;
					if (DrawOption(cm == CharacterMap.Latin, " Latin")) cm = CharacterMap.Latin;
					if (DrawOption(cm == CharacterMap.Custom, " Custom")) cm = CharacterMap.Custom;
					if (GUI.changed) characterMap = cm;
					GUILayout.EndVertical();

					EditorGUI.BeginDisabledGroup(cm != CharacterMap.Custom);
					{
						if (cm != CharacterMap.Custom)
						{
							string chars = "";

							if (cm == CharacterMap.Ascii)
							{
								for (int i = 33; i < 127; ++i)
									chars += System.Convert.ToChar(i);
							}
							else if (cm == CharacterMap.Numeric)
							{
								chars = "0123456789";
							}
							else if (cm == CharacterMap.Latin)
							{
								for (int i = 33; i < 127; ++i)
									chars += System.Convert.ToChar(i);

								for (int i = 161; i < 256; ++i)
									chars += System.Convert.ToChar(i);
							}

							NGUISettings.charsToInclude = chars;
						}

						GUI.changed = false;

						string text = NGUISettings.charsToInclude;

						if (cm == CharacterMap.Custom)
						{
							text = EditorGUILayout.TextArea(text, GUI.skin.textArea,
								GUILayout.Height(80f), GUILayout.Width(Screen.width - 100f));
						}
						else
						{
							GUILayout.Label(text, GUI.skin.textArea,
								GUILayout.Height(80f), GUILayout.Width(Screen.width - 100f));
						}

						if (GUI.changed)
						{
							string final = "";

							for (int i = 0; i < text.Length; ++i)
							{
								char c = text[i];
								if (c < 33) continue;
								string s = c.ToString();
								if (!final.Contains(s)) final += s;
							}

							if (final.Length > 0)
							{
								char[] chars = final.ToCharArray();
								System.Array.Sort(chars);
								final = new string(chars);
							}
							else final = "";

							NGUISettings.charsToInclude = final;
						}
					}
					EditorGUI.EndDisabledGroup();
					GUILayout.EndHorizontal();
				}
			}
			NGUIEditorTools.EndContents();

			if (mType == FontType.Dynamic)
			{
				EditorGUI.BeginDisabledGroup(ttf == null);
				GUILayout.BeginHorizontal();
				GUILayout.Space(20f);
				if (GUILayout.Button("Create the Font")) create = Create.Dynamic;
				GUILayout.Space(20f);
				GUILayout.EndHorizontal();
				EditorGUI.EndDisabledGroup();
#if UNITY_3_5
				EditorGUILayout.HelpBox("Dynamic fonts require Unity 4.0 or higher.", MessageType.Error);
#else
				// Helpful info
				if (ttf == null)
				{
					EditorGUILayout.HelpBox("You don't have to create a UIFont to use dynamic fonts. You can just reference the Unity Font directly on the label.", MessageType.Info);
				}
				EditorGUILayout.HelpBox("Please note that dynamic fonts can't be made a part of an atlas, and using dynamic fonts will result in at least one extra draw call.", MessageType.Warning);
#endif
			}
			else
			{
				bool isBuiltIn = (ttf != null) && string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(ttf));

				// Draw the atlas selection only if we have the font data and texture specified, just to make it easier
				EditorGUI.BeginDisabledGroup(ttf == null || isBuiltIn || !FreeType.isPresent);
				{
					NGUIEditorTools.DrawHeader("Output", true);
					NGUIEditorTools.BeginContents(false);
					ComponentSelector.Draw<UIAtlas>(NGUISettings.atlas, OnSelectAtlas, false);
					NGUIEditorTools.EndContents();

					if (ttf == null)
					{
						EditorGUILayout.HelpBox("You can create a bitmap font by specifying a dynamic font to use as the source.", MessageType.Info);
					}
					else if (isBuiltIn)
					{
						EditorGUILayout.HelpBox("You chose an embedded font. You can't create a bitmap font from an embedded resource.", MessageType.Warning);
					}
					else if (NGUISettings.atlas == null)
					{
						EditorGUILayout.HelpBox("You can create a font that doesn't use a texture atlas. This will mean that the text " +
							"labels using this font will generate an extra draw call.\n\nIf you do specify an atlas, the font's texture will be added to it automatically.", MessageType.Info);
					}

					GUILayout.BeginHorizontal();
					GUILayout.Space(20f);
					if (GUILayout.Button("Create the Font")) create = Create.Bitmap;
					GUILayout.Space(20f);
					GUILayout.EndHorizontal();
				}
				EditorGUI.EndDisabledGroup();
			}
		}

		if (create == Create.None) return;

		// Open the "Save As" file dialog
#if UNITY_3_5
		string prefabPath = EditorUtility.SaveFilePanel("Save As",
			NGUISettings.currentPath, "New Font.prefab", "prefab");
#else
		string prefabPath = EditorUtility.SaveFilePanelInProject("Save As",
			"New Font.prefab", "prefab", "Save font as...", NGUISettings.currentPath);
#endif
		if (string.IsNullOrEmpty(prefabPath)) return;
		NGUISettings.currentPath = System.IO.Path.GetDirectoryName(prefabPath);

		// Load the font's prefab
		GameObject go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
		Object prefab = null;
		string fontName;

		// Font doesn't exist yet
		if (go == null || go.GetComponent<UIFont>() == null)
		{
			// Create a new prefab for the atlas
			prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);

			fontName = prefabPath.Replace(".prefab", "");
			fontName = fontName.Substring(prefabPath.LastIndexOfAny(new char[] { '/', '\\' }) + 1);

			// Create a new game object for the font
			go = new GameObject(fontName);
			uiFont = go.AddComponent<UIFont>();
		}
		else
		{
			uiFont = go.GetComponent<UIFont>();
			fontName = go.name;
		}

		if (create == Create.Dynamic)
		{
			uiFont.atlas = null;
			uiFont.dynamicFont = NGUISettings.FMFont;
			uiFont.dynamicFontStyle = NGUISettings.fontStyle;
			uiFont.defaultSize = NGUISettings.FMSize;
		}
		else if (create == Create.Import)
		{
			Material mat = null;

			if (NGUISettings.atlas != null)
			{
				// Add the font's texture to the atlas
				UIAtlasMaker.AddOrUpdate(NGUISettings.atlas, NGUISettings.fontTexture);
			}
			else
			{
				// Create a material for the font
				string matPath = prefabPath.Replace(".prefab", ".mat");
				mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

				// If the material doesn't exist, create it
				if (mat == null)
				{
					Shader shader = Shader.Find("Unlit/Transparent Colored");
					mat = new Material(shader);

					// Save the material
					AssetDatabase.CreateAsset(mat, matPath);
					AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

					// Load the material so it's usable
					mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
				}

				mat.mainTexture = NGUISettings.fontTexture;
			}

			uiFont.dynamicFont = null;
			BMFontReader.Load(uiFont.bmFont, NGUITools.GetHierarchy(uiFont.gameObject), NGUISettings.fontData.bytes);

			if (NGUISettings.atlas == null)
			{
				uiFont.atlas = null;
				uiFont.material = mat;
			}
			else
			{
				uiFont.spriteName = NGUISettings.fontTexture.name;
				uiFont.atlas = NGUISettings.atlas;
			}
			NGUISettings.FMSize = uiFont.defaultSize;
		}
		else if (create == Create.Bitmap)
		{
			// Create the bitmap font
			BMFont bmFont;
			Texture2D tex;

			if (FreeType.CreateFont(
				NGUISettings.FMFont,
				NGUISettings.FMSize, mFaceIndex,
				NGUISettings.fontKerning,
				NGUISettings.charsToInclude, 1, out bmFont, out tex))
			{
				uiFont.bmFont = bmFont;
				tex.name = fontName;

				if (NGUISettings.atlas != null)
				{
					// Add this texture to the atlas and destroy it
					UIAtlasMaker.AddOrUpdate(NGUISettings.atlas, tex);
					NGUITools.DestroyImmediate(tex);
					NGUISettings.fontTexture = null;
					tex = null;

					uiFont.atlas = NGUISettings.atlas;
					uiFont.spriteName = fontName;
				}
				else
				{
					string texPath = prefabPath.Replace(".prefab", ".png");
					string matPath = prefabPath.Replace(".prefab", ".mat");

					byte[] png = tex.EncodeToPNG();
					FileStream fs = File.OpenWrite(texPath);
					fs.Write(png, 0, png.Length);
					fs.Close();

					// See if the material already exists
					Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

					// If the material doesn't exist, create it
					if (mat == null)
					{
						Shader shader = Shader.Find("Unlit/Transparent Colored");
						mat = new Material(shader);

						// Save the material
						AssetDatabase.CreateAsset(mat, matPath);
						AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

						// Load the material so it's usable
						mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
					}
					else AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

					// Re-load the texture
					tex = AssetDatabase.LoadAssetAtPath(texPath, typeof(Texture2D)) as Texture2D;

					// Assign the texture
					mat.mainTexture = tex;
					NGUISettings.fontTexture = tex;

					uiFont.atlas = null;
					uiFont.material = mat;
				}
			}
			else return;
		}

		if (prefab != null)
		{
			// Update the prefab
			PrefabUtility.ReplacePrefab(go, prefab);
			DestroyImmediate(go);
			AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

			// Select the atlas
			go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
			uiFont = go.GetComponent<UIFont>();
		}

		if (uiFont != null)
		{
			NGUISettings.FMFont = null;
			NGUISettings.BMFont = uiFont;
		}
		MarkAsChanged();
		Selection.activeGameObject = go;
	}
コード例 #4
0
        /// <summary>
        /// Computes the typography availabilities.
        /// It checks the presence of a set of required features in the font
        /// for ranges of unicode code points and set the corresponding bits
        /// in the TypographyAvailabilities enum. TypographyAvailabilities enum is
        /// used to determind whether fast path can be used to format the input.
        /// </summary>
        private void ComputeTypographyAvailabilities()
        {
            int glyphBitsLength = (GlyphCount + 31) >> 5;

            uint[] glyphBits = BufferCache.GetUInts(glyphBitsLength);
            Array.Clear(glyphBits, 0, glyphBitsLength);

            ushort minGlyphId = 65535;
            ushort maxGlyphId = 0;

            WritingSystem[]          complexScripts;
            TypographyAvailabilities typography = TypographyAvailabilities.None;

            GsubGposTables GsubGpos = new GsubGposTables(this);

            // preparing the glyph bits. When the bit is set, it means the corresponding
            // glyph needs to be checked against.
            for (int i = 0; i < fastTextRanges.Length; i++)
            {
                uint[]   codepoints   = fastTextRanges[i].GetFullRange();
                ushort[] glyphIndices = BufferCache.GetUShorts(codepoints.Length);

                unsafe
                {
                    fixed(uint *pCodepoints = &codepoints[0])
                    {
                        fixed(ushort *pGlyphIndices = &glyphIndices[0])
                        {
                            CharacterMap.TryGetValues(pCodepoints, checked ((uint)codepoints.Length), pGlyphIndices);
                        }
                    }
                }

                for (int j = 0; j < codepoints.Length; j++)
                {
                    ushort glyphId = glyphIndices[j];
                    if (glyphId != 0)
                    {
                        glyphBits[glyphId >> 5] |= (uint)(1 << (glyphId % 32));

                        if (glyphId > maxGlyphId)
                        {
                            maxGlyphId = glyphId;
                        }
                        if (glyphId < minGlyphId)
                        {
                            minGlyphId = glyphId;
                        }
                    }
                }

                BufferCache.ReleaseUShorts(glyphIndices);
            }

            //
            // Step 1: call OpenType layout engine to test presence of
            // 'locl' feature. Based on the returned writing systems, set
            // FastTextMajorLanguageLocalizedFormAvailable bit and
            // FastTextExtraLanguageLocalizedFormAvailable bit
            //
            OpenTypeLayoutResult result;

            unsafe
            {
                result = OpenTypeLayout.GetComplexLanguageList(
                    GsubGpos,
                    LoclFeature,
                    glyphBits,
                    minGlyphId,
                    maxGlyphId,
                    out complexScripts
                    );
            }

            if (result != OpenTypeLayoutResult.Success)
            {
                // The check failed. We abort and don't keep partial results that are not reliable
                _typographyAvailabilities = TypographyAvailabilities.None;
                return;
            }
            else if (complexScripts != null)
            {
                // This is the bits for localized form we would want to set
                // if both bits for localized form were set, we can end the loop earlier
                TypographyAvailabilities loclBitsTest =
                    TypographyAvailabilities.FastTextMajorLanguageLocalizedFormAvailable
                    | TypographyAvailabilities.FastTextExtraLanguageLocalizedFormAvailable;

                for (int i = 0; i < complexScripts.Length && typography != loclBitsTest; i++)
                {
                    if (MajorLanguages.Contains((ScriptTags)complexScripts[i].scriptTag, (LanguageTags)complexScripts[i].langSysTag))
                    {
                        typography |= TypographyAvailabilities.FastTextMajorLanguageLocalizedFormAvailable;
                    }
                    else
                    {
                        typography |= TypographyAvailabilities.FastTextExtraLanguageLocalizedFormAvailable;
                    }
                }
            }

            //
            // step 2: continue to find out whether there is common features availabe
            // in the font for the unicode ranges and set the FastTextTypographyAvailable bit
            //
            unsafe
            {
                result = OpenTypeLayout.GetComplexLanguageList(
                    GsubGpos,
                    RequiredTypographyFeatures,
                    glyphBits,
                    minGlyphId,
                    maxGlyphId,
                    out complexScripts
                    );
            }

            if (result != OpenTypeLayoutResult.Success)
            {
                // The check failed. We abort and don't keep partial results that are not reliable
                _typographyAvailabilities = TypographyAvailabilities.None;
                return;
            }
            else if (complexScripts != null)
            {
                typography |= TypographyAvailabilities.FastTextTypographyAvailable;
            }

            //
            // Step 3: call OpenType layout engine to find out if there is any feature present for
            // ideographs. Because there are many ideographs to check for, an alternative is to
            // check for all scripts with the required features in the font by setting all
            // glyph bits to 1, then see whether CJKIdeograph is in the returned list.
            //
            for (int i = 0; i < glyphBitsLength; i++)
            {
                glyphBits[i] = 0xFFFFFFFF;
            }

            unsafe
            {
                result = OpenTypeLayout.GetComplexLanguageList(
                    GsubGpos,
                    RequiredFeatures,
                    glyphBits,
                    minGlyphId,
                    maxGlyphId,
                    out complexScripts
                    );
            }

            if (result != OpenTypeLayoutResult.Success)
            {
                // The check failed. We abort and don't keep partial results that are not reliable
                _typographyAvailabilities = TypographyAvailabilities.None;
                return;
            }
            else if (complexScripts != null)
            {
                for (int i = 0; i < complexScripts.Length; i++)
                {
                    if (complexScripts[i].scriptTag == (uint)ScriptTags.CJKIdeographic)
                    {
                        typography |= TypographyAvailabilities.IdeoTypographyAvailable;
                    }
                    else
                    {
                        typography |= TypographyAvailabilities.Available;
                    }
                }
            }

            if (typography != TypographyAvailabilities.None)
            {
                // if any of the bits were set, set TypographyAvailabilities.Avaialble bit
                // as well to indicate some lookup is available.
                typography |= TypographyAvailabilities.Available;
            }

            _typographyAvailabilities = typography;

            // Note: we don't worry about calling ReleaseUInts in case of early out for a failure
            // above.  Releasing glyphBits is a performance optimization that is not necessary
            // for correctness, and not interesting in the rare failure case.
            BufferCache.ReleaseUInts(glyphBits);
        }
コード例 #5
0
ファイル: Cmap.cs プロジェクト: cs-phillips/PixelFarm
        static CharacterMap ReadCharacterMap(CMapEntry entry, BinaryReader input)
        {
            ushort format = input.ReadUInt16();
            ushort length = input.ReadUInt16();

            switch (format)
            {
            default:
            {
                throw new Exception("Unknown cmap subtable: " + format);         // TODO: Replace all application exceptions
            }

            case 0:
            {
                //Format 0: Byte encoding table
                //This is the Apple standard character to glyph index mapping table.
                //Type  Name    Description
                //USHORT    format  Format number is set to 0.
                //USHORT    length  This is the length in bytes of the subtable.
                //USHORT    language    Please see “Note on the language field in 'cmap' subtables“ in this document.
                //BYTE  glyphIdArray[256]   An array that maps character codes to glyph index values.
                //This is a simple 1 to 1 mapping of character codes to glyph indices.
                //The glyph set is limited to 256. Note that if this format is used to index into a larger glyph set,
                //only the first 256 glyphs will be accessible.

                ushort   language            = input.ReadUInt16();
                byte[]   only256Glyphs       = input.ReadBytes(256);
                ushort[] only256UInt16Glyphs = new ushort[256];
                for (int i = 255; i >= 0; --i)
                {
                    //expand
                    only256UInt16Glyphs[i] = only256Glyphs[i];
                }
                //convert to format4 cmap table
                return(CharacterMap.BuildFromFormat4(1, new ushort[] { 0 }, new ushort[] { 255 }, null, null, only256UInt16Glyphs));
            }

            case 4:
            {
                //This is the Microsoft standard character to glyph index mapping table for fonts that support Unicode ranges other than the range [U+D800 - U+DFFF] (defined as Surrogates Area, in Unicode v 3.0)
                //which is used for UCS-4 characters.
                //If a font supports this character range (i.e. in turn supports the UCS-4 characters) a subtable in this format with a platform specific encoding ID 1 is yet needed,
                //in addition to a subtable in format 12 with a platform specific encoding ID 10. Please see details on format 12 below, for fonts that support UCS-4 characters on Windows.
                //
                //This format is used when the character codes for the characters represented by a font fall into several contiguous ranges,
                //possibly with holes in some or all of the ranges (that is, some of the codes in a range may not have a representation in the font).
                //The format-dependent data is divided into three parts, which must occur in the following order:
                //    A four-word header gives parameters for an optimized search of the segment list;
                //    Four parallel arrays describe the segments (one segment for each contiguous range of codes);
                //    A variable-length array of glyph IDs (unsigned words).
                long tableStartEndAt = input.BaseStream.Position + length;

                ushort language = input.ReadUInt16();
                //Note on the language field in 'cmap' subtables:
                //Note on the language field in 'cmap' subtables:
                //The language field must be set to zero for all cmap subtables whose platform IDs are other than Macintosh (platform ID 1).
                //For cmap subtables whose platform IDs are Macintosh, set this field to the Macintosh language ID of the cmap subtable plus one,
                //or to zero if the cmap subtable is not language-specific.
                //For example, a Mac OS Turkish cmap subtable must set this field to 18, since the Macintosh language ID for Turkish is 17.
                //A Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman is not a language-specific encoding.

                ushort   segCountX2    = input.ReadUInt16();                     //2 * segCount
                ushort   searchRange   = input.ReadUInt16();                     //2 * (2**FLOOR(log2(segCount)))
                ushort   entrySelector = input.ReadUInt16();                     //2 * (2**FLOOR(log2(segCount)))
                ushort   rangeShift    = input.ReadUInt16();                     //2 * (2**FLOOR(log2(segCount)))
                int      segCount      = segCountX2 / 2;
                ushort[] endCode       = Utils.ReadUInt16Array(input, segCount); //Ending character code for each segment, last = 0xFFFF.
                //>To ensure that the search will terminate, the final endCode value must be 0xFFFF.
                //>This segment need not contain any valid mappings. It can simply map the single character code 0xFFFF to the missing character glyph, glyph 0.

                input.ReadUInt16();                                              // Reserved = 0
                ushort[] startCode     = Utils.ReadUInt16Array(input, segCount); //Starting character code for each segment
                ushort[] idDelta       = Utils.ReadUInt16Array(input, segCount); //Delta for all character codes in segment
                ushort[] idRangeOffset = Utils.ReadUInt16Array(input, segCount); //Offset in bytes to glyph indexArray, or 0
                //------------------------------------------------------------------------------------
                long     remainingLen = tableStartEndAt - input.BaseStream.Position;
                int      recordNum2   = (int)(remainingLen / 2);
                ushort[] glyphIdArray = Utils.ReadUInt16Array(input, recordNum2);        //Glyph index array
                return(CharacterMap.BuildFromFormat4(segCount, startCode, endCode, idDelta, idRangeOffset, glyphIdArray));
            }

            case 6:
            {
                //Format 6: Trimmed table mapping
                //Type    Name Description
                //USHORT format  Format number is set to 6.
                //USHORT  length This is the length in bytes of the subtable.
                //USHORT language    Please see “Note on the language field in 'cmap' subtables“ in this document.
                //USHORT firstCode   First character code of subrange.
                //USHORT entryCount  Number of character codes in subrange.
                //USHORT glyphIdArray[entryCount]   Array of glyph index values for character codes in the range.

                //The firstCode and entryCount values specify a subrange(beginning at firstCode, length = entryCount) within the range of possible character codes.
                //Codes outside of this subrange are mapped to glyph index 0.
                //The offset of the code(from the first code) within this subrange is used as index to the glyphIdArray,
                //which provides the glyph index value.

                long     tableStartEndAt = input.BaseStream.Position + length;
                ushort   language        = input.ReadUInt16();
                ushort   firstCode       = input.ReadUInt16();
                ushort   entryCount      = input.ReadUInt16();
                ushort[] glyphIdArray    = Utils.ReadUInt16Array(input, entryCount);

                return(CharacterMap.BuildFromFormat6(firstCode, glyphIdArray));
            }
            }
        }
コード例 #6
0
    /// <summary>
    /// Draw the UI for this tool.
    /// </summary>

    void OnGUI()
    {
        Object fnt    = (Object)NGUISettings.FMFont ?? (Object)NGUISettings.BMFont;
        UIFont uiFont = (fnt as UIFont);

        NGUIEditorTools.SetLabelWidth(80f);
        GUILayout.Space(3f);

        NGUIEditorTools.DrawHeader("Input", true);
        NGUIEditorTools.BeginContents(false);

        GUILayout.BeginHorizontal();
        mType = (FontType)EditorGUILayout.EnumPopup("Type", mType, GUILayout.MinWidth(200f));
        NGUIEditorTools.DrawPadding();
        GUILayout.EndHorizontal();
        Create create = Create.None;

        if (mType == FontType.ImportedBitmap)
        {
            NGUISettings.fontData    = EditorGUILayout.ObjectField("Font Data", NGUISettings.fontData, typeof(TextAsset), false) as TextAsset;
            NGUISettings.fontTexture = EditorGUILayout.ObjectField("Texture", NGUISettings.fontTexture, typeof(Texture2D), false, GUILayout.Width(140f)) as Texture2D;
            NGUIEditorTools.EndContents();

            // Draw the atlas selection only if we have the font data and texture specified, just to make it easier
            EditorGUI.BeginDisabledGroup(NGUISettings.fontData == null || NGUISettings.fontTexture == null);
            {
                NGUIEditorTools.DrawHeader("Output", true);
                NGUIEditorTools.BeginContents(false);
                ComponentSelector.Draw <UIAtlas>(NGUISettings.atlas, OnSelectAtlas, false);
                NGUIEditorTools.EndContents();
            }
            EditorGUI.EndDisabledGroup();

            if (NGUISettings.fontData == null)
            {
                EditorGUILayout.HelpBox("To create a font from a previously exported FNT file, you need to use BMFont on " +
                                        "Windows or your choice of Glyph Designer or the less expensive bmGlyph on the Mac.\n\n" +
                                        "Either of these tools will create a FNT file for you that you will drag & drop into the field above.", MessageType.Info);
            }
            else if (NGUISettings.fontTexture == null)
            {
                EditorGUILayout.HelpBox("When exporting your font, you should get two files: the FNT, and the texture. Only one texture can be used per font.", MessageType.Info);
            }
            else if (NGUISettings.atlas == null)
            {
                EditorGUILayout.HelpBox("You can create a font that doesn't use a texture atlas. This will mean that the text " +
                                        "labels using this font will generate an extra draw call.\n\nIf you do specify an atlas, the font's texture will be added to it automatically.", MessageType.Info);
            }

            EditorGUI.BeginDisabledGroup(NGUISettings.fontData == null || NGUISettings.fontTexture == null);
            {
                GUILayout.BeginHorizontal();
                GUILayout.Space(20f);
                if (GUILayout.Button("Create the Font"))
                {
                    create = Create.Import;
                }
                GUILayout.Space(20f);
                GUILayout.EndHorizontal();
            }
            EditorGUI.EndDisabledGroup();
        }
        else
        {
            GUILayout.BeginHorizontal();
            if (NGUIEditorTools.DrawPrefixButton("Source"))
            {
                ComponentSelector.Show <Font>(OnUnityFont, new string[] { ".ttf", ".otf" });
            }

            Font ttf = EditorGUILayout.ObjectField(NGUISettings.FMFont, typeof(Font), false) as Font;
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            {
                NGUISettings.FMSize = EditorGUILayout.IntField("Size", NGUISettings.FMSize, GUILayout.Width(120f));

                if (mType == FontType.Dynamic)
                {
                    NGUISettings.fontStyle = (FontStyle)EditorGUILayout.EnumPopup(NGUISettings.fontStyle);
                    NGUIEditorTools.DrawPadding();
                }
            }
            GUILayout.EndHorizontal();

            // Choose the font style if there are multiple faces present
            if (mType == FontType.GeneratedBitmap)
            {
                if (!FreeType.isPresent)
                {
                    string filename = (Application.platform == RuntimePlatform.WindowsEditor) ? "FreeType.dll" : "FreeType.dylib";
                    EditorGUILayout.HelpBox(filename + " is missing", MessageType.Error);

                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20f);

                    if (GUILayout.Button("Find " + filename))
                    {
                        string path = EditorUtility.OpenFilePanel("Find " + filename, NGUISettings.currentPath,
                                                                  (Application.platform == RuntimePlatform.WindowsEditor) ? "dll" : "dylib");

                        if (!string.IsNullOrEmpty(path))
                        {
                            if (System.IO.Path.GetFileName(path) == filename)
                            {
                                NGUISettings.currentPath    = System.IO.Path.GetDirectoryName(path);
                                NGUISettings.pathToFreeType = path;
                            }
                            else
                            {
                                Debug.LogError("The library must be named '" + filename + "'");
                            }
                        }
                    }
                    GUILayout.Space(20f);
                    GUILayout.EndHorizontal();
                }
                else if (ttf != null)
                {
                    string[] faces = FreeType.GetFaces(ttf);

                    if (faces != null)
                    {
                        if (mFaceIndex >= faces.Length)
                        {
                            mFaceIndex = 0;
                        }

                        if (faces.Length > 1)
                        {
                            GUILayout.Label("Style", EditorStyles.boldLabel);
                            for (int i = 0; i < faces.Length; ++i)
                            {
                                GUILayout.BeginHorizontal();
                                GUILayout.Space(10f);
                                if (DrawOption(i == mFaceIndex, " " + faces[i]))
                                {
                                    mFaceIndex = i;
                                }
                                GUILayout.EndHorizontal();
                            }
                        }
                    }

                    NGUISettings.fontKerning = EditorGUILayout.Toggle("Kerning", NGUISettings.fontKerning);

                    GUILayout.Label("Characters", EditorStyles.boldLabel);

                    CharacterMap cm = characterMap;

                    GUILayout.BeginHorizontal(GUILayout.Width(100f));
                    GUILayout.BeginVertical();
                    GUI.changed = false;
                    if (DrawOption(cm == CharacterMap.Numeric, " Numeric"))
                    {
                        cm = CharacterMap.Numeric;
                    }
                    if (DrawOption(cm == CharacterMap.Ascii, " ASCII"))
                    {
                        cm = CharacterMap.Ascii;
                    }
                    if (DrawOption(cm == CharacterMap.Latin, " Latin"))
                    {
                        cm = CharacterMap.Latin;
                    }
                    if (DrawOption(cm == CharacterMap.Custom, " Custom"))
                    {
                        cm = CharacterMap.Custom;
                    }
                    if (GUI.changed)
                    {
                        characterMap = cm;
                    }
                    GUILayout.EndVertical();

                    EditorGUI.BeginDisabledGroup(cm != CharacterMap.Custom);
                    {
                        if (cm != CharacterMap.Custom)
                        {
                            string chars = "";

                            if (cm == CharacterMap.Ascii)
                            {
                                for (int i = 33; i < 127; ++i)
                                {
                                    chars += System.Convert.ToChar(i);
                                }
                            }
                            else if (cm == CharacterMap.Numeric)
                            {
                                chars = "0123456789";
                            }
                            else if (cm == CharacterMap.Latin)
                            {
                                for (int i = 33; i < 127; ++i)
                                {
                                    chars += System.Convert.ToChar(i);
                                }

                                for (int i = 161; i < 256; ++i)
                                {
                                    chars += System.Convert.ToChar(i);
                                }
                            }

                            NGUISettings.charsToInclude = chars;
                        }

                        GUI.changed = false;

                        string text = NGUISettings.charsToInclude;

                        if (cm == CharacterMap.Custom)
                        {
                            text = EditorGUILayout.TextArea(text, GUI.skin.textArea,
                                                            GUILayout.Height(80f), GUILayout.Width(Screen.width - 100f));
                        }
                        else
                        {
                            GUILayout.Label(text, GUI.skin.textArea,
                                            GUILayout.Height(80f), GUILayout.Width(Screen.width - 100f));
                        }

                        if (GUI.changed)
                        {
                            string final = "";

                            for (int i = 0; i < text.Length; ++i)
                            {
                                char c = text[i];
                                if (c < 33)
                                {
                                    continue;
                                }
                                string s = c.ToString();
                                if (!final.Contains(s))
                                {
                                    final += s;
                                }
                            }

                            if (final.Length > 0)
                            {
                                char[] chars = final.ToCharArray();
                                System.Array.Sort(chars);
                                final = new string(chars);
                            }
                            else
                            {
                                final = "";
                            }

                            NGUISettings.charsToInclude = final;
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                    GUILayout.EndHorizontal();
                }
            }
            NGUIEditorTools.EndContents();

            if (mType == FontType.Dynamic)
            {
                EditorGUI.BeginDisabledGroup(ttf == null);
                GUILayout.BeginHorizontal();
                GUILayout.Space(20f);
                if (GUILayout.Button("Create the Font"))
                {
                    create = Create.Dynamic;
                }
                GUILayout.Space(20f);
                GUILayout.EndHorizontal();
                EditorGUI.EndDisabledGroup();
#if UNITY_3_5
                EditorGUILayout.HelpBox("Dynamic fonts require Unity 4.0 or higher.", MessageType.Error);
#else
                // Helpful info
                if (ttf == null)
                {
                    EditorGUILayout.HelpBox("You don't have to create a UIFont to use dynamic fonts. You can just reference the Unity Font directly on the label.", MessageType.Info);
                }
                EditorGUILayout.HelpBox("Please note that dynamic fonts can't be made a part of an atlas, and using dynamic fonts will result in at least one extra draw call.", MessageType.Warning);
#endif
            }
            else
            {
                bool isBuiltIn = (ttf != null) && string.IsNullOrEmpty(UnityEditor.AssetDatabase.GetAssetPath(ttf));

                // Draw the atlas selection only if we have the font data and texture specified, just to make it easier
                EditorGUI.BeginDisabledGroup(ttf == null || isBuiltIn || !FreeType.isPresent);
                {
                    NGUIEditorTools.DrawHeader("Output", true);
                    NGUIEditorTools.BeginContents(false);
                    ComponentSelector.Draw <UIAtlas>(NGUISettings.atlas, OnSelectAtlas, false);
                    NGUIEditorTools.EndContents();

                    if (ttf == null)
                    {
                        EditorGUILayout.HelpBox("You can create a bitmap font by specifying a dynamic font to use as the source.", MessageType.Info);
                    }
                    else if (isBuiltIn)
                    {
                        EditorGUILayout.HelpBox("You chose an embedded font. You can't create a bitmap font from an embedded resource.", MessageType.Warning);
                    }
                    else if (NGUISettings.atlas == null)
                    {
                        EditorGUILayout.HelpBox("You can create a font that doesn't use a texture atlas. This will mean that the text " +
                                                "labels using this font will generate an extra draw call.\n\nIf you do specify an atlas, the font's texture will be added to it automatically.", MessageType.Info);
                    }

                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20f);
                    if (GUILayout.Button("Create the Font"))
                    {
                        create = Create.Bitmap;
                    }
                    GUILayout.Space(20f);
                    GUILayout.EndHorizontal();
                }
                EditorGUI.EndDisabledGroup();
            }
        }

        if (create == Create.None)
        {
            return;
        }

        // Open the "Save As" file dialog
#if UNITY_3_5
        string prefabPath = EditorUtility.SaveFilePanel("Save As",
                                                        NGUISettings.currentPath, "New Font.prefab", "prefab");
#else
        string prefabPath = EditorUtility.SaveFilePanelInProject("Save As",
                                                                 "New Font.prefab", "prefab", "Save font as...", NGUISettings.currentPath);
#endif
        if (string.IsNullOrEmpty(prefabPath))
        {
            return;
        }
        NGUISettings.currentPath = System.IO.Path.GetDirectoryName(prefabPath);

        // Load the font's prefab
        GameObject go     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
        Object     prefab = null;
        string     fontName;

        // Font doesn't exist yet
        if (go == null || go.GetComponent <UIFont>() == null)
        {
            // Create a new prefab for the atlas
            prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);

            fontName = prefabPath.Replace(".prefab", "");
            fontName = fontName.Substring(prefabPath.LastIndexOfAny(new char[] { '/', '\\' }) + 1);

            // Create a new game object for the font
            go     = new GameObject(fontName);
            uiFont = go.AddComponent <UIFont>();
        }
        else
        {
            uiFont   = go.GetComponent <UIFont>();
            fontName = go.name;
        }

        if (create == Create.Dynamic)
        {
            uiFont.atlas            = null;
            uiFont.dynamicFont      = NGUISettings.FMFont;
            uiFont.dynamicFontStyle = NGUISettings.fontStyle;
            uiFont.defaultSize      = NGUISettings.FMSize;
        }
        else if (create == Create.Import)
        {
            Material mat = null;

            if (NGUISettings.atlas != null)
            {
                // Add the font's texture to the atlas
                UIAtlasMaker.AddOrUpdate(NGUISettings.atlas, NGUISettings.fontTexture);
            }
            else
            {
                // Create a material for the font
                string matPath = prefabPath.Replace(".prefab", ".mat");
                mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

                // If the material doesn't exist, create it
                if (mat == null)
                {
                    Shader shader = Shader.Find("Unlit/Transparent Colored");
                    mat = new Material(shader);

                    // Save the material
                    AssetDatabase.CreateAsset(mat, matPath);
                    AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

                    // Load the material so it's usable
                    mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
                }

                mat.mainTexture = NGUISettings.fontTexture;
            }

            uiFont.dynamicFont = null;
            BMFontReader.Load(uiFont.bmFont, NGUITools.GetHierarchy(uiFont.gameObject), NGUISettings.fontData.bytes);

            if (NGUISettings.atlas == null)
            {
                uiFont.atlas    = null;
                uiFont.material = mat;
            }
            else
            {
                uiFont.spriteName = NGUISettings.fontTexture.name;
                uiFont.atlas      = NGUISettings.atlas;
            }
            NGUISettings.FMSize = uiFont.defaultSize;
        }
        else if (create == Create.Bitmap)
        {
            // Create the bitmap font
            BMFont    bmFont;
            Texture2D tex;

            if (FreeType.CreateFont(
                    NGUISettings.FMFont,
                    NGUISettings.FMSize, mFaceIndex,
                    NGUISettings.fontKerning,
                    NGUISettings.charsToInclude, 1, out bmFont, out tex))
            {
                uiFont.bmFont = bmFont;
                tex.name      = fontName;

                if (NGUISettings.atlas != null)
                {
                    // Add this texture to the atlas and destroy it
                    UIAtlasMaker.AddOrUpdate(NGUISettings.atlas, tex);
                    NGUITools.DestroyImmediate(tex);
                    NGUISettings.fontTexture = null;
                    tex = null;

                    uiFont.atlas      = NGUISettings.atlas;
                    uiFont.spriteName = fontName;
                }
                else
                {
                    string texPath = prefabPath.Replace(".prefab", ".png");
                    string matPath = prefabPath.Replace(".prefab", ".mat");

                    byte[]     png = tex.EncodeToPNG();
                    FileStream fs  = File.OpenWrite(texPath);
                    fs.Write(png, 0, png.Length);
                    fs.Close();

                    // See if the material already exists
                    Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;

                    // If the material doesn't exist, create it
                    if (mat == null)
                    {
                        Shader shader = Shader.Find("Unlit/Transparent Colored");
                        mat = new Material(shader);

                        // Save the material
                        AssetDatabase.CreateAsset(mat, matPath);
                        AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

                        // Load the material so it's usable
                        mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
                    }
                    else
                    {
                        AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
                    }

                    // Re-load the texture
                    tex = AssetDatabase.LoadAssetAtPath(texPath, typeof(Texture2D)) as Texture2D;

                    // Assign the texture
                    mat.mainTexture          = tex;
                    NGUISettings.fontTexture = tex;

                    uiFont.atlas    = null;
                    uiFont.material = mat;
                }
            }
            else
            {
                return;
            }
        }

        if (prefab != null)
        {
            // Update the prefab
            PrefabUtility.ReplacePrefab(go, prefab);
            DestroyImmediate(go);
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

            // Select the atlas
            go     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
            uiFont = go.GetComponent <UIFont>();
        }

        if (uiFont != null)
        {
            NGUISettings.FMFont = null;
            NGUISettings.BMFont = uiFont;
        }
        MarkAsChanged();
        Selection.activeGameObject = go;
    }
コード例 #7
0
        /// <summary>
        /// Transliterate Unicode character to ASCII string.
        /// </summary>
        /// <param name="c">Character you want to transliterate into ASCII</param>
        /// <param name="level">Level of transliteration.</param>
        /// <returns>
        /// Transliterated string.
        /// </returns>
        public static string Unidecode(this char c, UnidecoderLevel level = UnidecoderLevel.Ascii)
        {
            if (level == UnidecoderLevel.Off)
            {
                return(new String(c, 1));
            }

            if (c < 0x80)/*128*/
            {
                return(new string(c, 1));
            }
            else if (c < 161)
            {
                return(String.Empty);
            }
            else if (c < 256)
            {
                switch (level)
                {
                case UnidecoderLevel.Ansi:
                    return(new string(c, 1));

                case UnidecoderLevel.AnsiPlus:
                    return(new string(c, 1));
                }
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 306)
            {
                return("IJ");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 307)
            {
                return("ij");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 312)
            {
                return("k");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 319)
            {
                return("L");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 320)
            {
                return("l");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 329)
            {
                return("'n");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 330)
            {
                return("ng");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 331)
            {
                return("NG");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 383)
            {
                return("s");
            }
            else if (level == UnidecoderLevel.AnsiPlus && c < 384)
            {
                return(new string(c, 1));
            }
            else if (level == UnidecoderLevel.AnsiPlus && c == 393)
            {
                return(new string(c, 1));
            }

            // By default:
            {
                int      high = c >> 8;
                int      low  = c & 0xff;
                string[] transliterations;
                string   result;
                if (CharacterMap.TryGetValue(high, out transliterations))
                {
                    result = transliterations[low];
                }
                else
                {
                    result = "";
                }
                return(result);
            }
        }
コード例 #8
0
        /// <summary>
        /// Transliterate Unicode string to ASCII string.
        /// </summary>
        /// <param name="input">String you want to transliterate into ASCII</param>
        /// <param name="level">Level of transliteration.</param>
        /// <returns>
        /// Transliterated string.
        /// </returns>
        public static string Unidecode(this string input, UnidecoderLevel level = UnidecoderLevel.Ascii)
        {
            if (level == UnidecoderLevel.Off)
            {
                return(input);
            }
            else if (string.IsNullOrEmpty(input))
            {
                return(input);
            }
            else if (input.All(x => x < 0x80))
            {
                return(input);
            }

            // Unidecode result often can be at least two times longer than input string.
            var sb = new StringBuilder(input.Length * 2);

            if (level == UnidecoderLevel.Ascii)
            {
                foreach (char c in input)
                {
                    if (c < 0x80)/*128*/
                    {
                        sb.Append(c);
                    }
                    else if (c < 161)
                    {
                        sb.Append("");
                    }
                    else
                    {
                        int      high = c >> 8;
                        int      low  = c & 0xff;
                        string[] transliterations;
                        string   result;
                        if (CharacterMap.TryGetValue(high, out transliterations))
                        {
                            result = transliterations[low];
                        }
                        else
                        {
                            result = "";
                        }
                        sb.Append(result);
                    }
                }
            }
            else if (level == UnidecoderLevel.Ansi)
            {
                foreach (char c in input)
                {
                    if (c < 0x80)/*128*/
                    {
                        sb.Append(c);
                    }
                    else if (c < 160)
                    {
                        sb.Append(unkn);
                    }
                    else if (c == 160)
                    {
                        sb.Append(" ");
                    }
                    else if (c < 256)
                    {
                        sb.Append(c);
                    }
                    else
                    {
                        int      high = c >> 8;
                        int      low  = c & 0xff;
                        string[] transliterations;
                        string   result;
                        if (CharacterMap.TryGetValue(high, out transliterations))
                        {
                            result = transliterations[low];
                        }
                        else
                        {
                            result = "";
                        }
                        sb.Append(result);
                    }
                }
            }
            else if (level == UnidecoderLevel.AnsiPlus)
            {
                foreach (char c in input)
                {
                    if (c < 0x80)/*128*/
                    {
                        sb.Append(c);
                    }
                    else if (c < 160)
                    {
                        sb.Append(unkn);
                    }
                    else if (c == 160)
                    {
                        sb.Append(" ");
                    }
                    else if (c < 256)
                    {
                        sb.Append(c);
                    }
                    else if (c == 306)
                    {
                        sb.Append("IJ");
                    }
                    else if (c == 307)
                    {
                        sb.Append("ij");
                    }
                    else if (c == 312)
                    {
                        sb.Append("k");
                    }
                    else if (c == 319)
                    {
                        sb.Append("L");
                    }
                    else if (c == 320)
                    {
                        sb.Append("l");
                    }
                    else if (c == 329)
                    {
                        sb.Append("'n");
                    }
                    else if (c == 330)
                    {
                        sb.Append("ng");
                    }
                    else if (c == 331)
                    {
                        sb.Append("NG");
                    }
                    else if (c == 383)
                    {
                        sb.Append("s");
                    }
                    else if (c < 384)
                    {
                        sb.Append(c);
                    }
                    else if (c == 393)
                    {
                        sb.Append(c);
                    }
                    else
                    {
                        int      high = c >> 8;
                        int      low  = c & 0xff;
                        string[] transliterations;
                        string   result;
                        if (CharacterMap.TryGetValue(high, out transliterations))
                        {
                            result = transliterations[low];
                        }
                        else
                        {
                            result = "";
                        }
                        sb.Append(result);
                    }
                }
            }
            else
            {
                throw new ArgumentException("Unsupported level argument value.", "level");
            }

            return(sb.ToString());
        }
コード例 #9
0
        protected ParserList(IEnumerable <T> parsersArg) : base(parsersArg)
        {
            var charCounter   = new Dictionary <char, int>();
            int globalCounter = 0;

            for (int i = 0; i < Count; i++)
            {
                var parser = this[i];
                if (parser == null)
                {
                    throw new InvalidOperationException("Unexpected null parser found");
                }

                parser.Initialize();
                parser.Index = i;
                if (parser.OpeningCharacters != null && parser.OpeningCharacters.Length != 0)
                {
                    foreach (var openingChar in parser.OpeningCharacters)
                    {
                        if (!charCounter.ContainsKey(openingChar))
                        {
                            charCounter[openingChar] = 0;
                        }
                        charCounter[openingChar]++;
                    }
                }
                else
                {
                    globalCounter++;
                }
            }

            if (globalCounter > 0)
            {
                globalParsers = new T[globalCounter];
            }

            var tempCharMap = new Dictionary <char, T[]>();

            foreach (var parser in this)
            {
                if (parser.OpeningCharacters != null && parser.OpeningCharacters.Length != 0)
                {
                    foreach (var openingChar in parser.OpeningCharacters)
                    {
                        T[] parsers;
                        if (!tempCharMap.TryGetValue(openingChar, out parsers))
                        {
                            parsers = new T[charCounter[openingChar]];
                            tempCharMap[openingChar] = parsers;
                        }

                        var index = parsers.Length - charCounter[openingChar];
                        parsers[index] = parser;
                        charCounter[openingChar]--;
                    }
                }
                else
                {
                    globalParsers[globalParsers.Length - globalCounter] = parser;
                    globalCounter--;
                }
            }

            charMap = new CharacterMap <T[]>(tempCharMap);
        }
コード例 #10
0
ファイル: Entity.cs プロジェクト: siquel/SaNi.Spriter
 internal virtual void AddCharacterMap(CharacterMap map)
 {
     this.characterMaps[charMapPointer++] = map;
 }
コード例 #11
0
        /// <summary>
        /// Convert specified text to equivalent persian text
        /// </summary>
        /// <param name="text">Text to convert</param>
        /// <returns>Converted text</returns>
        public string Convert(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                LastConvertedText = string.Empty;
            }
            else if (LastConvertedText != null && LastConvertedText.Equals(text, StringComparison.Ordinal))
            {
                return(LastConvertedText);
            }
            else
            {
                // make sure that we alocated enough space for text
                EnsureCharSize(text.Length);

                if (LastConvertedText == null)
                {
                    LastConvertedText = string.Empty;
                }
                int startoldIndex = 0;
                int lastoldIndex  = LastConvertedText.Length - 1;

                if (LastConvertedText.Length == text.Length + 1) // characters removed
                {
                    int index = LastConvertedText.IndexOf(text);
                    if (index >= 0)
                    {
                        if (index == 0)
                        {
                            PersianCharacter pc = CharacterMap.GetMappedCharacter(LastConvertedText[LastConvertedText.Length - 1]);
                            if (pc != null && !pc.LeftToRight)
                            {
                                // we have to remove from first because text is reversed
                                startoldIndex = LastConvertedText.Length - text.Length;
                            }
                            else
                            {
                                lastoldIndex = text.Length - 1;
                            }
                        }
                        else
                        {
                            lastoldIndex = text.Length - 1;
                        }
                        text = LastConvertedText.Substring(startoldIndex, text.Length);
                    }
                }

                bool findDiff = false;
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    cf.SourceChar         = text[i];
                    cf.Character          = CharacterMap.GetMappedCharacter(cf.SourceChar);
                    cf.Form               = PersianCharacterForm.Isolated;
                    _RepositionedChars[i] = null;
                    cf.IsReversed         = false;

                    // start from begin and search for missmatch
                    if (!findDiff && startoldIndex < LastConvertedText.Length)
                    {
                        if (cf.SourceChar == LastConvertedText[startoldIndex])
                        {
                            startoldIndex++;
                            cf.IsReversed = true;
                        }
                        else
                        {
                            findDiff = true;
                        }
                    }
                }

                if (findDiff) // if we found missmatch start from last index to find last missmatch
                {
                    for (int i = text.Length - 1; i >= 0; i--)
                    {
                        CharInfo cf = _SourceChars[i];
                        if (lastoldIndex >= startoldIndex)
                        {
                            if (cf.SourceChar == LastConvertedText[lastoldIndex])
                            {
                                lastoldIndex--;
                                cf.IsReversed = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }


                // find none persian characters and place them in correct position
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    if (!cf.IsReversed)
                    {
                        _RepositionedChars[text.Length - i - 1] = cf;
                    }
                }

                // place persian characters ( that we found them in previous text change) in correct position
                int j = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    if (_RepositionedChars[i] == null)
                    {
                        for (; j < text.Length; j++)
                        {
                            if (_SourceChars[j].IsReversed)
                            {
                                _RepositionedChars[i] = _SourceChars[j];
                                j++;
                                break;
                            }
                        }
                    }
                }

                // place Left To Right characters to correct place

                // find one left to right character
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _RepositionedChars[i];
                    if (!cf.IsReversed && (cf.Character == null || cf.Character.LeftToRight))
                    {
                        // find surrounding ltf chars
                        int startIndex = i;
                        int endIndex   = i;

                        //find most previous valid ltf index
                        for (int k = i - 1; k >= 0; k--)
                        {
                            CharInfo cf2 = _RepositionedChars[k];
                            if (cf2.IsReversed && (cf2.Character == null || cf2.Character.LeftToRight))
                            {
                                startIndex = k;
                            }
                            else
                            {
                                break;
                            }
                        }

                        //find most next valid ltf index
                        for (int k = i + 1; k < text.Length; k++)
                        {
                            CharInfo cf2 = _RepositionedChars[k];
                            if (cf2.IsReversed && (cf2.Character == null || cf2.Character.LeftToRight))
                            {
                                endIndex = k;
                            }
                            else
                            {
                                break;
                            }
                        }

                        int index = endIndex - (i - startIndex);
                        int sign  = Math.Sign(index - i);

                        for (int k = i; k != index; k += sign)
                        {
                            _RepositionedChars[k] = _RepositionedChars[k + sign];
                        }

                        _RepositionedChars[index] = cf;
                        cf.IsReversed             = true;
                    }
                }

                // calc forms of each character
                for (int i = 0; i < text.Length; i++)
                {
                    PersianCharacter     currentPc = _RepositionedChars[i].Character;
                    PersianCharacter     prePc     = null;
                    PersianCharacter     nextPc    = null;
                    PersianCharacterForm form      = PersianCharacterForm.Isolated;

                    if (currentPc != null)
                    {
                        if (i > 0)
                        {
                            nextPc = _RepositionedChars[i - 1].Character;
                        }
                        if (i < text.Length - 1)
                        {
                            prePc = _RepositionedChars[i + 1].Character;
                        }

                        if (prePc == null)
                        {
                            if (nextPc != null && nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                        else if (nextPc == null)
                        {
                            if (prePc != null && prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                        }
                        else
                        {
                            if (nextPc.CanStickToPrevious && prePc.CanStickToNext)
                            {
                                if (currentPc.CanStickToNext)
                                {
                                    form = PersianCharacterForm.Medial;
                                }
                                else
                                {
                                    form = PersianCharacterForm.Final;
                                }
                            }
                            else if (prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                            else if (nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                    }
                    _RepositionedChars[i].Form = form;
                }

                // build text from end to start
                StringBuilder result = new StringBuilder();

                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _RepositionedChars[i];
                    if (cf.Character != null)
                    {
                        result.Append(cf.Character[cf.Form]);
                    }
                    else
                    {
                        result.Append(cf.SourceChar);
                    }
                }

                if (ConvertLigature)
                {
                    result.Replace("\uFE8E\uFEDF", "\uFEFB");
                    result.Replace("\uFE8E\uFEE0", "\uFEFC");
                    result.Replace("\uFEEA\uFEE0\uFEDF\uFE8D", "\uFDF2");
                }
                LastConvertedText = result.ToString();
            }
            return(LastConvertedText);
        }