diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16effc9..777fbad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,15 +1,60 @@
# Changelog
These are the release notes for the TextMesh Pro UPM package which was first introduced with Unity 2018.1. Please see the following link for the Release Notes for prior versions of TextMesh Pro. http://digitalnativestudios.com/forum/index.php?topic=1363.0
+## [3.2.0-pre.1] - 2021-08-06
+## [2.2.0-preview.1] - 2021-08-06
+## [1.6.0-preview.1] - 2021-08-06
+### Changes
+- Added support for manually defining Diacritical Mark-to-Base and Mark-to-Mark glyph positional adjustments in font assets.
+- Updated the font asset editor to include new Mark-to-Base and Mark-to-Mark adjustment tables along with new Preview window to make it easier to edit adjustment records.
+- Added OnMissingCharacter event delegate called when the requested Unicode character is missing from the font asset.
+- Fixed Argument Null Exception when attempting to create a font asset via the Create Context menu prior to importing the TMP Essential Resources. Case #1290444
+- Changes to Sorting Layer ID and Sorting Order of <TextMeshPro> will now be reflected on any potential sub text objects.
+- Replaced Word Wrapping in the text component inspector by Text Wrapping Mode to introduce new text wrapping options that control whether whitespaces are preserved or ignored at the end of a line.
+- Input Field OnSubmit event will no longer be invoked on focus change or edit cancellation. OnEndEdit will continue to be invoked on submit, focus change or cancellation of edit.
+- Added support for <SHY> tag which is replaced internally by a soft hyphen or \u00AD.
+- Fixed potential text parsing issue when using markup tags without using quotes to encapsulate their values or attribute values. Case #1316658.
+- Revised the textInfo property to return a new TMP_TextInfo instance instead of null when the text component has not yet been awaken. Case #1318194.
+- Added new property to TMP Settings to control whether or not sub text objects will be visible in the scene hierarchy.
+- Added new "Clear Dynamic Data On Build" property to TMP Settings which determines if the "clearDynamicDataOnBuild" font asset property will be set to true or false on newly created dynamic font assets.
+- Added fallback character lookup caching to improve subsequent lookups of these characters coming from font assets assigned as local or global fallbacks.
+- Added support for Dynamic OS Font Assets. This new dynamic font asset type will enable users to use fonts present on target platforms and devices. See the following video for more details.
+- Changed text geometry UV layout which was necessary to support SRP. This change may require updating any code dealing with text geometry modifications such as the VertexColorCycler.cs script included in the TMP Examples & Extras.
+
The new UV layout is as follows:
+ - UV0 has changed from a Vector2 to Vector4. The "x" and "y" properties continue to contain the UV coordinates of the glyph in the font asset atlas texture. The "z" property is reserved for future use and "w" contains the SDF Scale.
+ - UV2 contains the UV coordinates for the font face and outline texture. Previously, the UV coordinates for the face and outline texture was encoded in UV2.x.
+- Added Multi Select support to TMP Dropdown.
+- Fixed issue where the <mark> tag color may be incorrect based on line breaking location. See [forum post](https://forum.unity.com/threads/rich-text-tags-dont-apply-to-space-characters-is-there-a-way.1103887/) for details.
+- Fixed glyph positional adjustment (kerning) incorrectly being applied to some characters at the end of a line.
+- Fixed incorrect text alignment when using <cspace> tag. Case 1333571
+- Fixed potential NullReferenceException in TMP Input Field in SendTouchScreenKeyboardStatusChanged(). See [forum post](https://forum.unity.com/threads/nullreferenceexception-at-tmpro-tmp_inputfield-sendtouchscreenkeyboardstatuschanged.1109678/) for details.
+- Obsoleted the SetText(string, bool) function since the text in the Text Input Box is always synced now. Re-added the SetText(string) function. See [forum post](https://forum.unity.com/threads/updating-unity-broke-tmpro.1110794/#post-7183375) for details.
+- Revised GetPreferredValues(string, float, float) where it will now return the width of the longest line of text given the width restrictions. See [forum post](https://forum.unity.com/threads/question-on-getpreferredvalues-and-text-wrapping.564970/#post-7189120) for details.
+- Fixed GetPreferredValues() potentially returning incorrect values. See [forum post](https://forum.unity.com/threads/question-on-getpreferredvalues-and-text-wrapping.564970/#post-7189120) for details.
+- Fixed potential sub text object shader mismatch when changing the shader of the text object.
+- Added isAlert property to the TMP Input Field to control if the TouchScreenKeyboard is opened in alert mode. See [forum post](https://forum.unity.com/threads/tmp_inputfield-dark-keyboard-option.698900/#post-7126367) for details.
+- Added new property "shouldActivateOnSelect" to the TMP Input Field which determines if the input field will be activated automatically when selected.
+- Fixed potential text rendering issue due to incorrect "Additional Shader Channels" when using nested canvases. Case #1337742
+- Newly created sprite assets will now be given a unique name to prevent potential AssetDatabase issue. Case #1345123
+- Fixed potential IndexOutOfRangeException in the Input Field when the text height exceeds the height of the Text Area in conjunction with using text overflow mode Ellipsis or Truncate. Case #1341172
+- Fixed <mark> tag not rendering correctly when using one of the SSD shaders. See [forum post](https://forum.unity.com/threads/mobile-tmpro-support-for-mark-mark.1132414/#post-7335727) for details.
+- Fixed potential culling issue that was resulting in the culling being delayed by one frame. Case #1335854
+- Vertex colors of the <TextMeshPro> component will be converted to linear space when Project Settings are set to Linear color space. Case #1349920
+- Fixed potential TouchScreenKeyboard handling issue in the TMP Input Field with UWP. Case #1337129
+- Revised handling of <CR><LF> in the Input Field text where these characters will be treated as one when using Left, Right, Backspace and Del keys when "Allow Rich Text Editing" property is disabled. See [forum post](https://forum.unity.com/threads/pasted-r-n-arent-removed-and-break-input-fields.1139056/#post-7397879) for details.
+- Added new property "keepTextSelectionVisible" to the Input Field which maintains the text selection visible when selecting other Input Fields or UI Elements. See [forum post](https://forum.unity.com/threads/input-field-selection-disappear-when-another-ui-item-is-activated.1145375/) for details.
+- Fixed potential Input Field text area viewport vertical alignment issue when using a vertical scrollbar and when the child text object's vertical margins are not zero. Case #1353535
+- Revised handling of SDF Scale updates where the SDF Scale will now only be updated when the lossy scale of the text object changes by more than 20%. Case #1352120
+
## [3.0.6] - 2021-04-23
-## [2.1.6]
-## [1.5.6]
+## [2.1.6] - 2021-04-23
+## [1.5.6] - 2021-04-23
### Changes
-- Added compiler conditional to exclude reference to PS5 in Unity 2019.4.22f1 or older and similar for Unity 2020.2.2f1 or older.
+- Removed the use of Out Variable Declarations since it is not support in C# 6.0 and causing internal testing issue on UWP.
## [3.0.5] - 2021-04-09
-## [2.1.5]
-## [1.5.5]
+## [2.1.5] - 2021-04-09
+## [1.5.5] - 2021-04-09
### Changes
- Added compiler conditional to address error related to missing RectMask2D padding property which was added in Unity 2019.4.12f1. See [forum post](https://forum.unity.com/threads/update-textmesh-pro-to-latest-in-2019-4.945332/#post-6906851) for details.
- Fixed GetPreferredValues(string text) and GetPreferredValues(string text, float width, float height) incorrectly changing the text. See [forum post](https://forum.unity.com/threads/preferred-width-height-sometimes-0.980022/#post-6991058) for details.
@@ -22,8 +67,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Added support for PS4 and PS5 to TMP Input Field.
## [3.0.4] - 2021-02-19
-## [2.1.4]
-## [1.5.4]
+## [2.1.4] - 2021-02-19
+## [1.5.4] - 2021-02-19
### Changes
- Improved sprite tag anim functionality to take into consideration the sprite character and glyph scale. Case #1309707
- Improved Ellipsis character insertion handling to prevent potential issues when the Ellipsis glyph ascender and descender exceed those of the primary font asset. See [forum post](https://forum.unity.com/threads/ellipsis-exception.995680/#post-6472790) for details.
@@ -54,8 +99,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed an issue with Text Overflow Linked mode where text would not flow correctly from one component to the other when the last character present at the break point was a linefeed "\n" or vertical tab "\v". See [forum post](https://forum.unity.com/threads/odd-line-break-behavior-in-text-with-overflow-linked.1056821/) for details.
## [3.0.3] - 2020-10-27
-## [2.1.3]
-## [1.5.3]
+## [2.1.3] - 2020-10-27
+## [1.5.3] - 2020-10-27
### Changes
- Fixed potential null reference exception in the Input Field that can occur as a result of using a workflow that involves enabling and disabling Canvases. See [forum post](https://forum.unity.com/threads/tmp_inputfield-generatecaret-m_textcomponent-canvas-exception.940659/) for details.
- Fixed potential Invalid AssetDatabase path warning that can be issued when assets are imported from outside the project. See [forum post](https://forum.unity.com/threads/textmesh-pro-invalid-assetdatabase-path-use-path-relative-to-the-project-folder.955731/) for details.
@@ -86,8 +131,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed minor UI cosmetic issue in the Sprite Asset Sprite Glyph Table inspector. Case #1285022
## [3.0.1] - 2020-07-26
-## [2.1.1]
-## [1.5.1]
+## [2.1.1] - 2020-07-26
+## [1.5.1] - 2020-07-26
### Changes
- Addressed compiler warning related to the new virtual event OnPreRenderText.
- Added one additional layer of missing character search where in the even the missing glyph character \u0000 or space character \u0020 is not available in any font asset or potential fallbacks, the End of Text (ETX) \u0003 will be used instead.
@@ -97,8 +142,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed potential issue when using multiple <font> tag in the same text object where these referencing several font assets derived from the same font file. Since their Default Material all have the same name, this was causing an issue in the Material Reference Manager. See [forum post](https://forum.unity.com/threads/argumentexception-on-v2-1-0-unity-2019-4-4f1-identified-bug.934789/) for details. Case #1264596.
## [3.0.0] - 2020-06-30
-## [2.1.0]
-## [1.5.0]
+## [2.1.0] - 2020-06-30
+## [1.5.0] - 2020-06-30
### Changes
- Added support to control if a text object is Maskable and affected by UI Mask components. The new setting is found in the Extra Settings section of the <TextMeshProUGUI> component inspector.
- Fixed potential Null Reference Exception when trying to add characters and / or glyphs to a font asset via scripting and before it has been initialized or ReadFontAssetDefinition() has been called.
@@ -114,8 +159,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- It will no longer be possible to create Editor Presets for the TMP_FontAsset, TMP_SpriteAsset, TMP_StyleSheet, TMP_ColorGradient and TMP_Settings as these are persistent and runtime assets. Case #1251229
## [3.0.0-preview.14] - 2020-06-08
-## [2.1.0-preview.14]
-## [1.5.0-preview.14]
+## [2.1.0-preview.14] - 2020-06-08
+## [1.5.0-preview.14] - 2020-06-08
### Changes
- Fixed sprite character and sprite glyph scale not being reflected in the text layout. See [forum post](https://forum.unity.com/threads/glyph-scale-dont-change-line-height.898817/) for details.
- Fixed potential null reference exception in the CrossFadeColor or CrossFadeAlpha functions. See [forum post](https://forum.unity.com/threads/version-1-5-0-2-1-0-3-0-0-preview-13-now-available-for-testing.753587/page-4#post-5885075) for details.
@@ -125,8 +170,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed InvalidOperationException that could occur when changing text Overflow linked components via code. Case #1251283
## [3.0.0-preview.13] - 2020-05-22
-## [2.1.0-preview.13]
-## [1.5.0-preview.13]
+## [2.1.0-preview.13] - 2020-05-22
+## [1.5.0-preview.13] - 2020-05-22
### Changes
- Fixed potential issue where the Font Asset Creator could get stuck in the packing phase of the atlas generation process. See [forum post](https://forum.unity.com/threads/font-asset-creator-stuck-at-packing-glyphs-pass-8.811863/) for details.
- Fixed issue potentially affecting text layout as a result of the width of the RectTransform being incorrectly reported. See [forum post](https://forum.unity.com/threads/textmesh-pro-forcemeshupdate-true-not-working-when-object-inactive.524507/#post-5798515) for details.
@@ -134,8 +179,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed culling issue where lossy scale was not considered in the determination of the bounds of the text geometry.
## [3.0.0-preview.12] - 2020-05-09
-## [2.1.0-preview.12]
-## [1.5.0-preview.12]
+## [2.1.0-preview.12] - 2020-05-09
+## [1.5.0-preview.12] - 2020-05-09
### Changes
- Added synchronization of the RaycastTarget property of the parent <TextMeshProUGUI> with potential child sub text objects. Case #1240784
- Fixed Font Asset Bold Spacing adjustment scaling based on the text object point size instead of current point size. Case #1241132
@@ -149,15 +194,15 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed NullReferenceException when setting the Atlas Texture to None in the Debug Settings of the Material Inspector of a text object. Case #1245104
## [3.0.0-preview.11] - 2020-04-22
-## [2.1.0-preview.11]
-## [1.5.0-preview.11]
+## [2.1.0-preview.11] - 2020-04-22
+## [1.5.0-preview.11] - 2020-04-22
### Changes
- Fixed incorrect culling of text object by RectMask2D component when the parent Canvas Render Mode is set to Screen Space - Camera or World Space. Case #1240595
- Added special handling to ForceMeshUpdate() when the parent Canvas is disabled.
## [3.0.0-preview.10] - 2020-04-21
-## [2.1.0-preview.10]
-## [1.5.0-preview.10]
+## [2.1.0-preview.10] - 2020-04-21
+## [1.5.0-preview.10] - 2020-04-21
### Changes
- Revised caching of Preferred Width and Height to further reduce the amount of time it has to be recomputed when using a complex structure of Layout components.
- Fixed potential issue when using Text Overflow Ellipsis and Truncate modes when the text contains characters using superscript, subscript or using the <voffset> tag.
@@ -184,8 +229,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed mouse cursor flickering when hovering the Text Input Box of a text prefab with RTL enabled. Case #1206395
## [3.0.0-preview.8] - 2020-03-14
-## [2.1.0-preview.8]
-## [1.5.0-preview.8]
+## [2.1.0-preview.8] - 2020-03-14
+## [1.5.0-preview.8] - 2020-03-14
### Changes
- Fixed a minor issue where the preferred width of a text object can be incorrect when using multiple font assets, fallbacks and sprites in the same line of text.
- Added Alpha Fade Speed property to the TMP_DropDown inspector.
@@ -201,8 +246,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fix incorrect material reference when current font asset is not the primary or a fallback that is missing a character which is present in the primary font asset.
## [3.0.0-preview.7] - 2020-03-07
-## [2.1.0-preview.7]
-## [1.5.0-preview.7]
+## [2.1.0-preview.7] - 2020-03-07
+## [1.5.0-preview.7] - 2020-03-07
### Changes
- Reverted recent change to the TMP_SubMeshUI OnDisable() function that could result in a Missing Reference Exception in the GraphicRaycaster.cs script. See the following [forum post](https://forum.unity.com/threads/version-1-5-0-2-1-0-preview-5-now-available-for-testing.753587/page-2#post-5523412).
- Fixed glyph drawing issue in the Font Asset Inspector Glyph Adjustment Table when Multi Atlas Texture is enabled and the glyph is not located in the main atlas texture or at atlasTextures[0].
@@ -218,8 +263,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- As requested by a few users, TMP_FontAsset.faceInfo setter is now public instead of internal.
## [3.0.0-preview.5] - 2020-02-25
-## [2.1.0-preview.5]
-## [1.5.0-preview.5]
+## [2.1.0-preview.5] - 2020-02-25
+## [1.5.0-preview.5] - 2020-02-25
### Changes
- Revised SetText function formatting options to including ability to specify padding for integral part of the value. Revised format is as follows: {Arg Index:Integral Padding.Decimal Precision} Example: TMP_Text.SetText("Value = {0:000.00}", 10.375f); result in "Value = 010.38".
- Fixed issue where text objects isTextObjectScaleStatic property would be ignored when OnCanvasHierarchyChanged() is called.
@@ -232,8 +277,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Text object InternalUpdate() used to handle potential scale changes of text objects now uses willRenderCanvases event instead of onPreCull. This avoids a potential one frame delay in updating of objects and no impact on objects. Case #1216007
## [3.0.0-preview.4] - 2020-01-31
-## [2.1.0-preview.4]
-## [1.5.0-preview.4]
+## [2.1.0-preview.4] - 2020-01-31
+## [1.5.0-preview.4] - 2020-01-31
### Changes
- Fixed Input Field issue where scrolling events could prevent OnEndEdit event from firing. See [forum post](https://forum.unity.com/threads/mouse-wheel-on-multiline-input-field-with-no-scrollbar-hangs-input-field-stops-event-firing.794607/) for details.
- Improved Input Field handling of Vertical Scrollbar in conjunction with the ResetOnDeActivation property. Using the Vertical Scrollbar no longer triggers OnEndEdit event.
@@ -249,8 +294,8 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Added public ITextPreprocessor textPreprocessor; property to allow setting the text preprocessor for a given text component.
## [3.0.0-preview.3] - 2019-12-16
-## [2.1.0-preview.3]
-## [1.5.0-preview.3]
+## [2.1.0-preview.3] - 2019-12-16
+## [1.5.0-preview.3] - 2019-12-16
### Changes
- Fixed potential issue with TMP Dropdown where calling Show() and Hide() in very short interval could result in additional Blockers. Case #1194114
- Fixed potential issues that could occur when upgrading to version 1.5.0-preview.2 or newer of the TMP package without also updating the TMP Essential Resources in the project.
@@ -274,7 +319,7 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Optimization to ensure the TMP Update Manager only rebuilds text objects once per frame regardless of the number of cameras in the scene.
## [2.1.0-preview.2] - 2019-10-30
-## [1.5.0-preview.2]
+## [1.5.0-preview.2] - 2019-10-30
### Changes
- Fixed Input Field issue when Read Only flag is set preventing the initial setting of the text. Also fixed Read Only flag not being respected when using IME input.
- Fixed potential infinite loop when using text overflow mode ScrollRect. See Case #1188867
@@ -299,7 +344,7 @@ These are the release notes for the TextMesh Pro UPM package which was first int
- Fixed potential Null Reference Exception in the Editor when assigning new font asset to disabled game object when no previous font asset was assigned.
## [2.1.0-preview.1] - 2019-09-30
-## [1.5.0-preview.1]
+## [1.5.0-preview.1] - 2019-09-30
### Changes
- Fixed an issue when using Overflow Ellipsis mode where the Ellipsis character would not be displayed correctly when the preceding character is a sprite.
- Added the ability to define the Resource path for Style Sheets in the TMP Settings.
diff --git a/Editor Resources/Shaders/TMP_SDF_SSD.cginc b/Editor Resources/Shaders/TMP_SDF_SSD.cginc
index 0f587bd..b16f269 100644
--- a/Editor Resources/Shaders/TMP_SDF_SSD.cginc
+++ b/Editor Resources/Shaders/TMP_SDF_SSD.cginc
@@ -3,7 +3,7 @@
float4 position : POSITION;
float3 normal : NORMAL;
float4 color : COLOR;
- float2 texcoord0 : TEXCOORD0;
+ float4 texcoord0 : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
@@ -34,7 +34,7 @@ pixel_t VertShader(vertex_t input)
{
pixel_t output;
- float bold = step(input.texcoord1.y, 0);
+ float bold = step(input.texcoord0.w, 0);
float4 vert = input.position;
vert.x += _VertexOffsetX;
diff --git a/Package Resources/TMP Essential Resources.unitypackage b/Package Resources/TMP Essential Resources.unitypackage
index df07702..6fa68f5 100644
Binary files a/Package Resources/TMP Essential Resources.unitypackage and b/Package Resources/TMP Essential Resources.unitypackage differ
diff --git a/Package Resources/TMP Examples & Extras.unitypackage b/Package Resources/TMP Examples & Extras.unitypackage
index e0f2c77..91fcf7d 100644
Binary files a/Package Resources/TMP Examples & Extras.unitypackage and b/Package Resources/TMP Examples & Extras.unitypackage differ
diff --git a/Package Resources/TMP Shaders.unitypackage b/Package Resources/TMP Shaders.unitypackage
new file mode 100644
index 0000000..ad9285a
Binary files /dev/null and b/Package Resources/TMP Shaders.unitypackage differ
diff --git a/ValidationExceptions.json.meta b/Package Resources/TMP Shaders.unitypackage.meta
similarity index 62%
rename from ValidationExceptions.json.meta
rename to Package Resources/TMP Shaders.unitypackage.meta
index 91e0542..f46fe34 100644
--- a/ValidationExceptions.json.meta
+++ b/Package Resources/TMP Shaders.unitypackage.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: c5aeade3b36c0b246936762b3673d9bf
-TextScriptImporter:
+guid: d3549aab78e3f3742af31b3d196f049d
+DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
diff --git a/Scripts/Editor/DropdownOptionListDrawer.cs b/Scripts/Editor/DropdownOptionListDrawer.cs
index 2b7dc85..144085e 100644
--- a/Scripts/Editor/DropdownOptionListDrawer.cs
+++ b/Scripts/Editor/DropdownOptionListDrawer.cs
@@ -20,7 +20,7 @@ private void Init(SerializedProperty property)
m_ReorderableList = new ReorderableList(property.serializedObject, array);
m_ReorderableList.drawElementCallback = DrawOptionData;
m_ReorderableList.drawHeaderCallback = DrawHeader;
- m_ReorderableList.elementHeight += 16;
+ m_ReorderableList.elementHeight += 40;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
@@ -40,14 +40,17 @@ private void DrawOptionData(Rect rect, int index, bool isActive, bool isFocused)
SerializedProperty itemData = m_ReorderableList.serializedProperty.GetArrayElementAtIndex(index);
SerializedProperty itemText = itemData.FindPropertyRelative("m_Text");
SerializedProperty itemImage = itemData.FindPropertyRelative("m_Image");
+ SerializedProperty itemColor = itemData.FindPropertyRelative("m_Color");
RectOffset offset = new RectOffset(0, 0, -1, -3);
rect = offset.Add(rect);
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(rect, itemText, GUIContent.none);
- rect.y += EditorGUIUtility.singleLineHeight;
+ rect.y += EditorGUIUtility.singleLineHeight + 2;
EditorGUI.PropertyField(rect, itemImage, GUIContent.none);
+ rect.y += EditorGUIUtility.singleLineHeight + 2;
+ EditorGUI.PropertyField(rect, itemColor, GUIContent.none);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
diff --git a/Scripts/Editor/GlyphMetricsPropertyDrawer.cs b/Scripts/Editor/GlyphMetricsPropertyDrawer.cs
index bcd25a6..e83441a 100644
--- a/Scripts/Editor/GlyphMetricsPropertyDrawer.cs
+++ b/Scripts/Editor/GlyphMetricsPropertyDrawer.cs
@@ -8,7 +8,7 @@ namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(GlyphMetrics))]
- public class GlyphMetricsPropertyDrawer : PropertyDrawer
+ internal class GlyphMetricsPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
diff --git a/Scripts/Editor/HDRP.meta b/Scripts/Editor/HDRP.meta
new file mode 100644
index 0000000..4081097
--- /dev/null
+++ b/Scripts/Editor/HDRP.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: eecc124dc0b994047aac97ccf8c8ed0a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs b/Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs
new file mode 100644
index 0000000..eda18d1
--- /dev/null
+++ b/Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs
@@ -0,0 +1,83 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEditor.Rendering.HighDefinition;
+
+// Include material common properties names
+using static UnityEngine.Rendering.HighDefinition.HDMaterialProperties;
+
+namespace TMPro.EditorUtilities
+{
+ ///
+ /// Common GUI for Lit ShaderGraphs
+ ///
+ internal class HDRP_LitShaderGUI : HDShaderGUI
+ {
+ // For surface option shader graph we only want all unlit features but alpha clip and back then front rendering
+ const SurfaceOptionUIBlock.Features surfaceOptionFeatures = SurfaceOptionUIBlock.Features.Lit
+ | SurfaceOptionUIBlock.Features.ShowDepthOffsetOnly;
+
+ const EmissionUIBlock.Features emissionFeatures = EmissionUIBlock.Features.All ^ EmissionUIBlock.Features.EnableEmissionForGI;
+
+ MaterialUIBlockList m_UIBlocks = new MaterialUIBlockList
+ {
+ new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: surfaceOptionFeatures),
+ new ShaderGraphUIBlock(MaterialUIBlock.Expandable.ShaderGraph),
+ //new EmissionUIBlock(MaterialUIBlock.Expandable.Emissive),
+ new AdvancedOptionsUIBlock(MaterialUIBlock.Expandable.Advance, ~AdvancedOptionsUIBlock.Features.SpecularOcclusion)
+ };
+
+ protected MaterialUIBlockList uiBlocks => m_UIBlocks;
+
+ ///
+ /// Implement your custom GUI in this function. To display a UI similar to HDRP shaders, use a MaterialUIBlock.
+ ///
+ /// The current material editor.
+ /// The list of properties the material has.
+ protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] props)
+ {
+ using (var changed = new EditorGUI.ChangeCheckScope())
+ {
+ m_UIBlocks.OnGUI(materialEditor, props);
+ ApplyKeywordsAndPassesIfNeeded(changed.changed, m_UIBlocks.materials);
+ }
+ }
+
+ //const string kUVEmissive = "_UVEmissive";
+
+ ///
+ /// Sets up the keywords and passes for a Lit Shader Graph material.
+ ///
+ /// The target material.
+ public static void SetupMaterialKeywordsAndPass(Material material)
+ {
+ SynchronizeShaderGraphProperties(material);
+
+ BaseLitGUI.SetupBaseLitKeywords(material);
+ BaseLitGUI.SetupBaseLitMaterialPass(material);
+
+ bool receiveSSR = false;
+ if (material.GetSurfaceType() == SurfaceType.Transparent)
+ receiveSSR = material.HasProperty(kReceivesSSRTransparent) ? material.GetFloat(kReceivesSSRTransparent) != 0 : false;
+ else
+ receiveSSR = material.HasProperty(kReceivesSSR) ? material.GetFloat(kReceivesSSR) != 0 : false;
+ bool useSplitLighting = material.HasProperty(kUseSplitLighting) ? material.GetInt(kUseSplitLighting) != 0: false;
+ BaseLitGUI.SetupStencil(material, receiveSSR, useSplitLighting);
+
+ if (material.HasProperty(kAddPrecomputedVelocity))
+ CoreUtils.SetKeyword(material, "_ADD_PRECOMPUTED_VELOCITY", material.GetInt(kAddPrecomputedVelocity) != 0);
+
+ /*if (material.HasProperty(kUVEmissive) && material.HasProperty(kEmissiveColorMap))
+ {
+ CoreUtils.SetKeyword(material, "_EMISSIVE_MAPPING_PLANAR", ((UVEmissiveMapping)material.GetFloat(kUVEmissive)) == UVEmissiveMapping.Planar && material.GetTexture(kEmissiveColorMap));
+ CoreUtils.SetKeyword(material, "_EMISSIVE_MAPPING_TRIPLANAR", ((UVEmissiveMapping)material.GetFloat(kUVEmissive)) == UVEmissiveMapping.Triplanar && material.GetTexture(kEmissiveColorMap));
+ CoreUtils.SetKeyword(material, "_EMISSIVE_MAPPING_BASE", ((UVEmissiveMapping)material.GetFloat(kUVEmissive)) == UVEmissiveMapping.SameAsBase && material.GetTexture(kEmissiveColorMap));
+ CoreUtils.SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
+ }*/
+ }
+
+ protected override void SetupMaterialKeywordsAndPassInternal(Material material) => SetupMaterialKeywordsAndPass(material);
+ }
+}
+#endif
diff --git a/Scripts/Editor/TMPro_FontPlugin.cs.meta b/Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs.meta
similarity index 74%
rename from Scripts/Editor/TMPro_FontPlugin.cs.meta
rename to Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs.meta
index 66f3a87..c7bd79c 100644
--- a/Scripts/Editor/TMPro_FontPlugin.cs.meta
+++ b/Scripts/Editor/HDRP/HDRP_LitShaderGUI.cs.meta
@@ -1,6 +1,7 @@
fileFormatVersion: 2
-guid: 9edc9283e7d6409fab242fe8fb6a822c
+guid: bbe5cdecf49c00345827736b4c46fe52
MonoImporter:
+ externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
diff --git a/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs b/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs
new file mode 100644
index 0000000..7443759
--- /dev/null
+++ b/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs
@@ -0,0 +1,57 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEditor;
+using UnityEngine;
+using UnityEditor.Rendering.HighDefinition;
+
+
+namespace TMPro.EditorUtilities
+{
+ ///
+ /// Common GUI for Lit ShaderGraphs
+ ///
+ internal class HDRP_UnlitShaderGUI : HDShaderGUI
+ {
+ const SurfaceOptionUIBlock.Features surfaceOptionFeatures = SurfaceOptionUIBlock.Features.Unlit;
+
+ MaterialUIBlockList m_UIBlocks = new MaterialUIBlockList
+ {
+ new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: surfaceOptionFeatures),
+ new ShaderGraphUIBlock(MaterialUIBlock.Expandable.ShaderGraph, ShaderGraphUIBlock.Features.Unlit),
+ new AdvancedOptionsUIBlock(MaterialUIBlock.Expandable.Advance, ~AdvancedOptionsUIBlock.Features.SpecularOcclusion)
+ };
+
+ /// List of UI Blocks used to render the material inspector.
+ protected MaterialUIBlockList uiBlocks => m_UIBlocks;
+
+ ///
+ /// Implement your custom GUI in this function. To display a UI similar to HDRP shaders, use a MaterialUIBlockList.
+ ///
+ /// The current material editor.
+ /// The list of properties the material has.
+ protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] props)
+ {
+ using (var changed = new EditorGUI.ChangeCheckScope())
+ {
+ m_UIBlocks.OnGUI(materialEditor, props);
+ ApplyKeywordsAndPassesIfNeeded(changed.changed, m_UIBlocks.materials);
+ }
+ }
+
+ ///
+ /// Sets up the keywords and passes for the Unlit Shader Graph material you pass in.
+ ///
+ /// The target material.
+ public static void SetupUnlitKeywordsAndPass(Material material)
+ {
+ SynchronizeShaderGraphProperties(material);
+ UnlitGUI.SetupUnlitMaterialKeywordsAndPass(material);
+ }
+
+ ///
+ /// Sets up the keywords and passes for the current selected material.
+ ///
+ /// The selected material.
+ protected override void SetupMaterialKeywordsAndPassInternal(Material material) => SetupUnlitKeywordsAndPass(material);
+ }
+}
+#endif
diff --git a/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs.meta b/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs.meta
new file mode 100644
index 0000000..d000e8c
--- /dev/null
+++ b/Scripts/Editor/HDRP/HDRP_UnlitShaderGUI.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 93ee4ad131ebc114b8799cb8484b86f6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs b/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs
new file mode 100644
index 0000000..b9272e1
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs
@@ -0,0 +1,677 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.Rendering.HighDefinition;
+
+
+namespace TMPro.EditorUtilities
+{
+ /// Base class for TextMesh Pro shader GUIs.
+ internal abstract class TMP_BaseHDRPLitShaderGUI : HDRP_LitShaderGUI
+ {
+ /// Representation of a #pragma shader_feature.
+ /// It is assumed that the first feature option is for no keyword (underscores).
+ protected class ShaderFeature
+ {
+ public string undoLabel;
+
+ public GUIContent label;
+
+ /// The keyword labels, for display. Include the no-keyword as the first option.
+ public GUIContent[] keywordLabels;
+
+ /// The shader keywords. Exclude the no-keyword option.
+ public string[] keywords;
+
+ int m_State;
+
+ public bool Active
+ {
+ get { return m_State >= 0; }
+ }
+
+ public int State
+ {
+ get { return m_State; }
+ }
+
+ public void ReadState(Material material)
+ {
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ if (material.IsKeywordEnabled(keywords[i]))
+ {
+ m_State = i;
+ return;
+ }
+ }
+
+ m_State = -1;
+ }
+
+ public void SetActive(bool active, Material material)
+ {
+ m_State = active ? 0 : -1;
+ SetStateKeywords(material);
+ }
+
+ public void DoPopup(MaterialEditor editor, Material material)
+ {
+ EditorGUI.BeginChangeCheck();
+ int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels);
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_State = selection - 1;
+ editor.RegisterPropertyChangeUndo(undoLabel);
+ SetStateKeywords(material);
+ }
+ }
+
+ void SetStateKeywords(Material material)
+ {
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ if (i == m_State)
+ {
+ material.EnableKeyword(keywords[i]);
+ }
+ else
+ {
+ material.DisableKeyword(keywords[i]);
+ }
+ }
+ }
+ }
+
+ static GUIContent s_TempLabel = new GUIContent();
+
+ protected static bool s_DebugExtended;
+
+ static int s_UndoRedoCount, s_LastSeenUndoRedoCount;
+
+ static float[][] s_TempFloats =
+ {
+ null, new float[1], new float[2], new float[3], new float[4]
+ };
+
+ protected static GUIContent[] s_XywhVectorLabels =
+ {
+ new GUIContent("X"),
+ new GUIContent("Y"),
+ new GUIContent("W", "Width"),
+ new GUIContent("H", "Height")
+ };
+
+ protected static GUIContent[] s_LbrtVectorLabels =
+ {
+ new GUIContent("L", "Left"),
+ new GUIContent("B", "Bottom"),
+ new GUIContent("R", "Right"),
+ new GUIContent("T", "Top")
+ };
+
+ protected static GUIContent[] s_CullingTypeLabels =
+ {
+ new GUIContent("Off"),
+ new GUIContent("Front"),
+ new GUIContent("Back")
+ };
+
+ static TMP_BaseHDRPLitShaderGUI()
+ {
+ // Keep track of how many undo/redo events happened.
+ Undo.undoRedoPerformed += () => s_UndoRedoCount += 1;
+ }
+
+ bool m_IsNewGUI = true;
+
+ float m_DragAndDropMinY;
+
+ protected MaterialEditor m_Editor;
+
+ protected Material m_Material;
+
+ protected MaterialProperty[] m_Properties;
+
+ void PrepareGUI()
+ {
+ m_IsNewGUI = false;
+ ShaderUtilities.GetShaderPropertyIDs();
+
+ // New GUI just got constructed. This happens in response to a selection,
+ // but also after undo/redo events.
+ if (s_LastSeenUndoRedoCount != s_UndoRedoCount)
+ {
+ // There's been at least one undo/redo since the last time this GUI got constructed.
+ // Maybe the undo/redo was for this material? Assume that is was.
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material);
+ }
+
+ s_LastSeenUndoRedoCount = s_UndoRedoCount;
+ }
+
+ protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
+ {
+ m_Editor = materialEditor;
+ m_Material = materialEditor.target as Material;
+ this.m_Properties = properties;
+
+ if (m_IsNewGUI)
+ {
+ PrepareGUI();
+ }
+
+ DoDragAndDropBegin();
+ EditorGUI.BeginChangeCheck();
+ DoGUI();
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
+ }
+
+ DoDragAndDropEnd();
+ }
+
+ /// Override this method to create the specific shader GUI.
+ protected abstract void DoGUI();
+
+ static string[] s_PanelStateLabel = new string[] { "\t- Click to collapse -", "\t- Click to expand -" };
+
+ protected bool BeginPanel(string panel, bool expanded)
+ {
+ EditorGUI.indentLevel = 0;
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
+ r.x += 20;
+ r.width += 6;
+
+ bool enabled = GUI.enabled;
+ GUI.enabled = true;
+ expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
+ r.width -= 30;
+ EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
+ GUI.enabled = enabled;
+
+ EditorGUI.indentLevel += 1;
+ EditorGUI.BeginDisabledGroup(false);
+
+ return expanded;
+ }
+
+ protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true)
+ {
+ EditorGUI.indentLevel = 0;
+
+ if (readState)
+ {
+ feature.ReadState(m_Material);
+ }
+
+ EditorGUI.BeginChangeCheck();
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ GUILayout.BeginHorizontal();
+
+ Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f)));
+ bool active = EditorGUI.Toggle(r, feature.Active);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo(feature.undoLabel);
+ feature.SetActive(active, m_Material);
+ }
+
+ r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
+ r.width += 6;
+
+ bool enabled = GUI.enabled;
+ GUI.enabled = true;
+ expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
+ r.width -= 10;
+ EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
+ GUI.enabled = enabled;
+
+ GUILayout.EndHorizontal();
+
+ EditorGUI.indentLevel += 1;
+ EditorGUI.BeginDisabledGroup(!active);
+
+ return expanded;
+ }
+
+ protected void EndPanel()
+ {
+ EditorGUI.EndDisabledGroup();
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.EndVertical();
+ }
+
+ MaterialProperty BeginProperty(string name)
+ {
+ MaterialProperty property = FindProperty(name, m_Properties);
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.showMixedValue = property.hasMixedValue;
+ m_Editor.BeginAnimatedCheck(Rect.zero, property);
+
+ return property;
+ }
+
+ bool EndProperty()
+ {
+ m_Editor.EndAnimatedCheck();
+ EditorGUI.showMixedValue = false;
+ return EditorGUI.EndChangeCheck();
+ }
+
+ protected void DoPopup(string name, string label, GUIContent[] options)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options);
+ if (EndProperty())
+ {
+ property.floatValue = index;
+ }
+ }
+
+ protected void DoCubeMap(string name, string label)
+ {
+ DoTexture(name, label, typeof(Cubemap));
+ }
+
+ protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null)
+ {
+ DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames);
+ }
+
+ void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null)
+ {
+ float objFieldSize = 60f;
+ bool smallLayout = EditorGUIUtility.currentViewWidth <= 440f && (withTilingOffset || speedNames != null);
+ float controlHeight = smallLayout ? objFieldSize * 2 : objFieldSize;
+
+ MaterialProperty property = FindProperty(name, m_Properties);
+ m_Editor.BeginAnimatedCheck(Rect.zero, property);
+
+ Rect rect = EditorGUILayout.GetControlRect(true, controlHeight);
+ float totalWidth = rect.width;
+ rect.width = EditorGUIUtility.labelWidth + objFieldSize;
+ rect.height = objFieldSize;
+ s_TempLabel.text = label;
+
+ EditorGUI.BeginChangeCheck();
+ Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false);
+ if (EditorGUI.EndChangeCheck())
+ {
+ property.textureValue = tex as Texture;
+ }
+
+ float additionalHeight = controlHeight - objFieldSize;
+ float xOffset = smallLayout ? rect.width - objFieldSize : rect.width;
+
+ rect.y += additionalHeight;
+ rect.x += xOffset;
+ rect.width = totalWidth - xOffset;
+ rect.height = EditorGUIUtility.singleLineHeight;
+
+ if (withTilingOffset)
+ {
+ DoTilingOffset(rect, property);
+ rect.y += (rect.height + 2f) * 2f;
+ }
+
+ m_Editor.EndAnimatedCheck();
+
+ if (speedNames != null)
+ {
+ DoUVSpeed(rect, speedNames);
+ }
+ }
+
+ void DoTilingOffset(Rect rect, MaterialProperty property)
+ {
+ float labelWidth = EditorGUIUtility.labelWidth;
+ int indentLevel = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
+
+ Vector4 vector = property.textureScaleAndOffset;
+
+ bool changed = false;
+ float[] values = s_TempFloats[2];
+
+ s_TempLabel.text = "Tiling";
+ Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ values[0] = vector.x;
+ values[1] = vector.y;
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
+ if (EditorGUI.EndChangeCheck())
+ {
+ vector.x = values[0];
+ vector.y = values[1];
+ changed = true;
+ }
+
+ rect.y += rect.height + 2f;
+ s_TempLabel.text = "Offset";
+ vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ values[0] = vector.z;
+ values[1] = vector.w;
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
+ if (EditorGUI.EndChangeCheck())
+ {
+ vector.z = values[0];
+ vector.w = values[1];
+ changed = true;
+ }
+
+ if (changed)
+ {
+ property.textureScaleAndOffset = vector;
+ }
+
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUI.indentLevel = indentLevel;
+ }
+
+ void DoUVSpeed(Rect rect, string[] names)
+ {
+ float labelWidth = EditorGUIUtility.labelWidth;
+ int indentLevel = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
+
+ s_TempLabel.text = "Speed";
+ rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+
+ EditorGUIUtility.labelWidth = 10f;
+ rect.width = rect.width * 0.5f - 2f;
+
+ if (names.Length == 1)
+ {
+ DoFloat2(rect, names[0]);
+ }
+ else
+ {
+ DoFloat(rect, names[0], "X");
+ rect.x += rect.width + 4f;
+ DoFloat(rect, names[1], "Y");
+ }
+
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUI.indentLevel = indentLevel;
+ }
+
+ protected void DoToggle(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f);
+ if (EndProperty())
+ {
+ property.floatValue = value ? 1f : 0f;
+ }
+ }
+
+ protected void DoFloat(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Rect rect = EditorGUILayout.GetControlRect();
+ rect.width = EditorGUIUtility.labelWidth + 55f;
+ s_TempLabel.text = label;
+ float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoColor(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true);
+ if (EndProperty())
+ {
+ property.colorValue = value;
+ }
+ }
+
+ void DoFloat(Rect rect, string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ void DoFloat2(Rect rect, string name)
+ {
+ MaterialProperty property = BeginProperty(name);
+
+ float x = EditorGUI.FloatField(rect, "X", property.vectorValue.x);
+ rect.x += rect.width + 4f;
+ float y = EditorGUI.FloatField(rect, "Y", property.vectorValue.y);
+
+ if (EndProperty())
+ {
+ property.vectorValue = new Vector2(x, y);
+ }
+ }
+
+ protected void DoOffset(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoSlider(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Vector2 range = property.rangeLimits;
+ s_TempLabel.text = label;
+ float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoSlider(string name, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoSlider(string propertyName, string propertyField, string label)
+ {
+ MaterialProperty property = BeginProperty(propertyName);
+ Vector2 range = property.rangeLimits;
+ s_TempLabel.text = label;
+
+ Vector4 value = property.vectorValue;
+
+ switch (propertyField)
+ {
+ case "X":
+ value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
+ break;
+ case "Y":
+ value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
+ break;
+ case "Z":
+ value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
+ break;
+ case "W":
+ value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
+ break;
+ }
+
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(propertyName);
+ s_TempLabel.text = label;
+
+ Vector4 value = property.vectorValue;
+
+ switch (propertyField)
+ {
+ case "X":
+ value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
+ break;
+ case "Y":
+ value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
+ break;
+ case "Z":
+ value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
+ break;
+ case "W":
+ value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
+ break;
+ }
+
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector2(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector3(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector(string name, string label, GUIContent[] subLabels)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Rect rect = EditorGUILayout.GetControlRect();
+ s_TempLabel.text = label;
+ rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ Vector4 vector = property.vectorValue;
+
+ float[] values = s_TempFloats[subLabels.Length];
+ for (int i = 0; i < subLabels.Length; i++)
+ {
+ values[i] = vector[i];
+ }
+
+ EditorGUI.MultiFloatField(rect, subLabels, values);
+ if (EndProperty())
+ {
+ for (int i = 0; i < subLabels.Length; i++)
+ {
+ vector[i] = values[i];
+ }
+
+ property.vectorValue = vector;
+ }
+ }
+
+ void DoDragAndDropBegin()
+ {
+ m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
+ }
+
+ void DoDragAndDropEnd()
+ {
+ Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+ Event evt = Event.current;
+ if (evt.type == EventType.DragUpdated)
+ {
+ DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
+ evt.Use();
+ }
+ else if (
+ evt.type == EventType.DragPerform &&
+ Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition)
+ )
+ {
+ DragAndDrop.AcceptDrag();
+ evt.Use();
+ Material droppedMaterial = DragAndDrop.objectReferences[0] as Material;
+ if (droppedMaterial && droppedMaterial != m_Material)
+ {
+ PerformDrop(droppedMaterial);
+ }
+ }
+ }
+
+ void PerformDrop(Material droppedMaterial)
+ {
+ Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
+ if (!droppedTex)
+ {
+ return;
+ }
+
+ Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex);
+ TMP_FontAsset requiredFontAsset = null;
+ if (droppedTex != currentTex)
+ {
+ requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial);
+ if (!requiredFontAsset)
+ {
+ return;
+ }
+ }
+
+ foreach (GameObject o in Selection.gameObjects)
+ {
+ if (requiredFontAsset)
+ {
+ TMP_Text textComponent = o.GetComponent();
+ if (textComponent)
+ {
+ Undo.RecordObject(textComponent, "Font Asset Change");
+ textComponent.font = requiredFontAsset;
+ }
+ }
+
+ TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial);
+ EditorUtility.SetDirty(o);
+ }
+ }
+ }
+}
+#endif
diff --git a/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs.meta b/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs.meta
new file mode 100644
index 0000000..6520fed
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_BaseHDRPLitShaderGUI.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e3795795b029fde4395e6953ce72b5a6
+timeCreated: 1469844810
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs b/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs
new file mode 100644
index 0000000..e1f3e5b
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs
@@ -0,0 +1,677 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.Rendering.HighDefinition;
+
+
+namespace TMPro.EditorUtilities
+{
+ /// Base class for TextMesh Pro shader GUIs.
+ internal abstract class TMP_BaseHDRPUnlitShaderGUI : HDRP_UnlitShaderGUI
+ {
+ /// Representation of a #pragma shader_feature.
+ /// It is assumed that the first feature option is for no keyword (underscores).
+ protected class ShaderFeature
+ {
+ public string undoLabel;
+
+ public GUIContent label;
+
+ /// The keyword labels, for display. Include the no-keyword as the first option.
+ public GUIContent[] keywordLabels;
+
+ /// The shader keywords. Exclude the no-keyword option.
+ public string[] keywords;
+
+ int m_State;
+
+ public bool Active
+ {
+ get { return m_State >= 0; }
+ }
+
+ public int State
+ {
+ get { return m_State; }
+ }
+
+ public void ReadState(Material material)
+ {
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ if (material.IsKeywordEnabled(keywords[i]))
+ {
+ m_State = i;
+ return;
+ }
+ }
+
+ m_State = -1;
+ }
+
+ public void SetActive(bool active, Material material)
+ {
+ m_State = active ? 0 : -1;
+ SetStateKeywords(material);
+ }
+
+ public void DoPopup(MaterialEditor editor, Material material)
+ {
+ EditorGUI.BeginChangeCheck();
+ int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels);
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_State = selection - 1;
+ editor.RegisterPropertyChangeUndo(undoLabel);
+ SetStateKeywords(material);
+ }
+ }
+
+ void SetStateKeywords(Material material)
+ {
+ for (int i = 0; i < keywords.Length; i++)
+ {
+ if (i == m_State)
+ {
+ material.EnableKeyword(keywords[i]);
+ }
+ else
+ {
+ material.DisableKeyword(keywords[i]);
+ }
+ }
+ }
+ }
+
+ static GUIContent s_TempLabel = new GUIContent();
+
+ protected static bool s_DebugExtended;
+
+ static int s_UndoRedoCount, s_LastSeenUndoRedoCount;
+
+ static float[][] s_TempFloats =
+ {
+ null, new float[1], new float[2], new float[3], new float[4]
+ };
+
+ protected static GUIContent[] s_XywhVectorLabels =
+ {
+ new GUIContent("X"),
+ new GUIContent("Y"),
+ new GUIContent("W", "Width"),
+ new GUIContent("H", "Height")
+ };
+
+ protected static GUIContent[] s_LbrtVectorLabels =
+ {
+ new GUIContent("L", "Left"),
+ new GUIContent("B", "Bottom"),
+ new GUIContent("R", "Right"),
+ new GUIContent("T", "Top")
+ };
+
+ protected static GUIContent[] s_CullingTypeLabels =
+ {
+ new GUIContent("Off"),
+ new GUIContent("Front"),
+ new GUIContent("Back")
+ };
+
+ static TMP_BaseHDRPUnlitShaderGUI()
+ {
+ // Keep track of how many undo/redo events happened.
+ Undo.undoRedoPerformed += () => s_UndoRedoCount += 1;
+ }
+
+ bool m_IsNewGUI = true;
+
+ float m_DragAndDropMinY;
+
+ protected MaterialEditor m_Editor;
+
+ protected Material m_Material;
+
+ protected MaterialProperty[] m_Properties;
+
+ void PrepareGUI()
+ {
+ m_IsNewGUI = false;
+ ShaderUtilities.GetShaderPropertyIDs();
+
+ // New GUI just got constructed. This happens in response to a selection,
+ // but also after undo/redo events.
+ if (s_LastSeenUndoRedoCount != s_UndoRedoCount)
+ {
+ // There's been at least one undo/redo since the last time this GUI got constructed.
+ // Maybe the undo/redo was for this material? Assume that is was.
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material);
+ }
+
+ s_LastSeenUndoRedoCount = s_UndoRedoCount;
+ }
+
+ protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
+ {
+ m_Editor = materialEditor;
+ m_Material = materialEditor.target as Material;
+ this.m_Properties = properties;
+
+ if (m_IsNewGUI)
+ {
+ PrepareGUI();
+ }
+
+ DoDragAndDropBegin();
+ EditorGUI.BeginChangeCheck();
+ DoGUI();
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
+ }
+
+ DoDragAndDropEnd();
+ }
+
+ /// Override this method to create the specific shader GUI.
+ protected abstract void DoGUI();
+
+ static string[] s_PanelStateLabel = new string[] { "\t- Click to collapse -", "\t- Click to expand -" };
+
+ protected bool BeginPanel(string panel, bool expanded)
+ {
+ EditorGUI.indentLevel = 0;
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
+ r.x += 20;
+ r.width += 6;
+
+ bool enabled = GUI.enabled;
+ GUI.enabled = true;
+ expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
+ r.width -= 30;
+ EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
+ GUI.enabled = enabled;
+
+ EditorGUI.indentLevel += 1;
+ EditorGUI.BeginDisabledGroup(false);
+
+ return expanded;
+ }
+
+ protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true)
+ {
+ EditorGUI.indentLevel = 0;
+
+ if (readState)
+ {
+ feature.ReadState(m_Material);
+ }
+
+ EditorGUI.BeginChangeCheck();
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ GUILayout.BeginHorizontal();
+
+ Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f)));
+ bool active = EditorGUI.Toggle(r, feature.Active);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo(feature.undoLabel);
+ feature.SetActive(active, m_Material);
+ }
+
+ r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
+ r.width += 6;
+
+ bool enabled = GUI.enabled;
+ GUI.enabled = true;
+ expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
+ r.width -= 10;
+ EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
+ GUI.enabled = enabled;
+
+ GUILayout.EndHorizontal();
+
+ EditorGUI.indentLevel += 1;
+ EditorGUI.BeginDisabledGroup(!active);
+
+ return expanded;
+ }
+
+ protected void EndPanel()
+ {
+ EditorGUI.EndDisabledGroup();
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.EndVertical();
+ }
+
+ MaterialProperty BeginProperty(string name)
+ {
+ MaterialProperty property = FindProperty(name, m_Properties);
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.showMixedValue = property.hasMixedValue;
+ m_Editor.BeginAnimatedCheck(Rect.zero, property);
+
+ return property;
+ }
+
+ bool EndProperty()
+ {
+ m_Editor.EndAnimatedCheck();
+ EditorGUI.showMixedValue = false;
+ return EditorGUI.EndChangeCheck();
+ }
+
+ protected void DoPopup(string name, string label, GUIContent[] options)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options);
+ if (EndProperty())
+ {
+ property.floatValue = index;
+ }
+ }
+
+ protected void DoCubeMap(string name, string label)
+ {
+ DoTexture(name, label, typeof(Cubemap));
+ }
+
+ protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null)
+ {
+ DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames);
+ }
+
+ void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null)
+ {
+ float objFieldSize = 60f;
+ bool smallLayout = EditorGUIUtility.currentViewWidth <= 440f && (withTilingOffset || speedNames != null);
+ float controlHeight = smallLayout ? objFieldSize * 2 : objFieldSize;
+
+ MaterialProperty property = FindProperty(name, m_Properties);
+ m_Editor.BeginAnimatedCheck(Rect.zero, property);
+
+ Rect rect = EditorGUILayout.GetControlRect(true, controlHeight);
+ float totalWidth = rect.width;
+ rect.width = EditorGUIUtility.labelWidth + objFieldSize;
+ rect.height = objFieldSize;
+ s_TempLabel.text = label;
+
+ EditorGUI.BeginChangeCheck();
+ Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false);
+ if (EditorGUI.EndChangeCheck())
+ {
+ property.textureValue = tex as Texture;
+ }
+
+ float additionalHeight = controlHeight - objFieldSize;
+ float xOffset = smallLayout ? rect.width - objFieldSize : rect.width;
+
+ rect.y += additionalHeight;
+ rect.x += xOffset;
+ rect.width = totalWidth - xOffset;
+ rect.height = EditorGUIUtility.singleLineHeight;
+
+ if (withTilingOffset)
+ {
+ DoTilingOffset(rect, property);
+ rect.y += (rect.height + 2f) * 2f;
+ }
+
+ m_Editor.EndAnimatedCheck();
+
+ if (speedNames != null)
+ {
+ DoUVSpeed(rect, speedNames);
+ }
+ }
+
+ void DoTilingOffset(Rect rect, MaterialProperty property)
+ {
+ float labelWidth = EditorGUIUtility.labelWidth;
+ int indentLevel = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
+
+ Vector4 vector = property.textureScaleAndOffset;
+
+ bool changed = false;
+ float[] values = s_TempFloats[2];
+
+ s_TempLabel.text = "Tiling";
+ Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ values[0] = vector.x;
+ values[1] = vector.y;
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
+ if (EditorGUI.EndChangeCheck())
+ {
+ vector.x = values[0];
+ vector.y = values[1];
+ changed = true;
+ }
+
+ rect.y += rect.height + 2f;
+ s_TempLabel.text = "Offset";
+ vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ values[0] = vector.z;
+ values[1] = vector.w;
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
+ if (EditorGUI.EndChangeCheck())
+ {
+ vector.z = values[0];
+ vector.w = values[1];
+ changed = true;
+ }
+
+ if (changed)
+ {
+ property.textureScaleAndOffset = vector;
+ }
+
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUI.indentLevel = indentLevel;
+ }
+
+ void DoUVSpeed(Rect rect, string[] names)
+ {
+ float labelWidth = EditorGUIUtility.labelWidth;
+ int indentLevel = EditorGUI.indentLevel;
+ EditorGUI.indentLevel = 0;
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
+
+ s_TempLabel.text = "Speed";
+ rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+
+ EditorGUIUtility.labelWidth = 10f;
+ rect.width = rect.width * 0.5f - 2f;
+
+ if (names.Length == 1)
+ {
+ DoFloat2(rect, names[0]);
+ }
+ else
+ {
+ DoFloat(rect, names[0], "X");
+ rect.x += rect.width + 4f;
+ DoFloat(rect, names[1], "Y");
+ }
+
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUI.indentLevel = indentLevel;
+ }
+
+ protected void DoToggle(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f);
+ if (EndProperty())
+ {
+ property.floatValue = value ? 1f : 0f;
+ }
+ }
+
+ protected void DoFloat(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Rect rect = EditorGUILayout.GetControlRect();
+ rect.width = EditorGUIUtility.labelWidth + 55f;
+ s_TempLabel.text = label;
+ float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoColor(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true);
+ if (EndProperty())
+ {
+ property.colorValue = value;
+ }
+ }
+
+ void DoFloat(Rect rect, string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ void DoFloat2(Rect rect, string name)
+ {
+ MaterialProperty property = BeginProperty(name);
+
+ float x = EditorGUI.FloatField(rect, "X", property.vectorValue.x);
+ rect.x += rect.width + 4f;
+ float y = EditorGUI.FloatField(rect, "Y", property.vectorValue.y);
+
+ if (EndProperty())
+ {
+ property.vectorValue = new Vector2(x, y);
+ }
+ }
+
+ protected void DoOffset(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoSlider(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Vector2 range = property.rangeLimits;
+ s_TempLabel.text = label;
+ float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoSlider(string name, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
+ protected void DoSlider(string propertyName, string propertyField, string label)
+ {
+ MaterialProperty property = BeginProperty(propertyName);
+ Vector2 range = property.rangeLimits;
+ s_TempLabel.text = label;
+
+ Vector4 value = property.vectorValue;
+
+ switch (propertyField)
+ {
+ case "X":
+ value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
+ break;
+ case "Y":
+ value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
+ break;
+ case "Z":
+ value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
+ break;
+ case "W":
+ value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
+ break;
+ }
+
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(propertyName);
+ s_TempLabel.text = label;
+
+ Vector4 value = property.vectorValue;
+
+ switch (propertyField)
+ {
+ case "X":
+ value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
+ break;
+ case "Y":
+ value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
+ break;
+ case "Z":
+ value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
+ break;
+ case "W":
+ value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
+ break;
+ }
+
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector2(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector3(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
+ protected void DoVector(string name, string label, GUIContent[] subLabels)
+ {
+ MaterialProperty property = BeginProperty(name);
+ Rect rect = EditorGUILayout.GetControlRect();
+ s_TempLabel.text = label;
+ rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
+ Vector4 vector = property.vectorValue;
+
+ float[] values = s_TempFloats[subLabels.Length];
+ for (int i = 0; i < subLabels.Length; i++)
+ {
+ values[i] = vector[i];
+ }
+
+ EditorGUI.MultiFloatField(rect, subLabels, values);
+ if (EndProperty())
+ {
+ for (int i = 0; i < subLabels.Length; i++)
+ {
+ vector[i] = values[i];
+ }
+
+ property.vectorValue = vector;
+ }
+ }
+
+ void DoDragAndDropBegin()
+ {
+ m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
+ }
+
+ void DoDragAndDropEnd()
+ {
+ Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+ Event evt = Event.current;
+ if (evt.type == EventType.DragUpdated)
+ {
+ DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
+ evt.Use();
+ }
+ else if (
+ evt.type == EventType.DragPerform &&
+ Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition)
+ )
+ {
+ DragAndDrop.AcceptDrag();
+ evt.Use();
+ Material droppedMaterial = DragAndDrop.objectReferences[0] as Material;
+ if (droppedMaterial && droppedMaterial != m_Material)
+ {
+ PerformDrop(droppedMaterial);
+ }
+ }
+ }
+
+ void PerformDrop(Material droppedMaterial)
+ {
+ Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
+ if (!droppedTex)
+ {
+ return;
+ }
+
+ Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex);
+ TMP_FontAsset requiredFontAsset = null;
+ if (droppedTex != currentTex)
+ {
+ requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial);
+ if (!requiredFontAsset)
+ {
+ return;
+ }
+ }
+
+ foreach (GameObject o in Selection.gameObjects)
+ {
+ if (requiredFontAsset)
+ {
+ TMP_Text textComponent = o.GetComponent();
+ if (textComponent)
+ {
+ Undo.RecordObject(textComponent, "Font Asset Change");
+ textComponent.font = requiredFontAsset;
+ }
+ }
+
+ TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial);
+ EditorUtility.SetDirty(o);
+ }
+ }
+ }
+}
+#endif
diff --git a/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs.meta b/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs.meta
new file mode 100644
index 0000000..e7f11a6
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 645409e9544820042937871953f20509
+timeCreated: 1469844810
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs b/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs
new file mode 100644
index 0000000..7d04490
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs
@@ -0,0 +1,638 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEngine;
+using UnityEditor;
+
+using UnityEditor.Rendering.HighDefinition;
+
+namespace TMPro.EditorUtilities
+{
+ internal class TMP_SDF_HDRPLitShaderGUI : TMP_BaseHDRPLitShaderGUI
+ {
+ // private readonly MaterialUIBlockList uiBlocks = new MaterialUIBlockList
+ // {
+ // new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: SurfaceOptionUIBlock.Features.Lit),
+ // new AdvancedOptionsUIBlock(MaterialUIBlock.Expandable.Advance, AdvancedOptionsUIBlock.Features.StandardLit) //AdvancedOptionsUIBlock.Features.Instancing | AdvancedOptionsUIBlock.Features.AddPrecomputedVelocity)
+ // };
+
+ static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature;
+
+ static bool s_Face = true, s_Outline = true, s_Outline2 = true, s_Outline3 = true, s_Underlay = true, s_Lighting = true, s_Glow, s_Bevel, s_Light, s_Bump, s_Env;
+
+ static string[]
+ s_FaceUVSpeedName = { "_FaceUVSpeed" },
+ s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" },
+ s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" },
+ s_OutlineUvSpeedName = { "_OutlineUVSpeed" };
+
+ ///
+ ///
+ ///
+ static TMP_SDF_HDRPLitShaderGUI()
+ {
+ s_OutlineFeature = new ShaderFeature()
+ {
+ undoLabel = "Outline",
+ keywords = new[] { "OUTLINE_ON" }
+ };
+
+ s_UnderlayFeature = new ShaderFeature()
+ {
+ undoLabel = "Underlay",
+ keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" },
+ label = new GUIContent("Underlay Type"),
+ keywordLabels = new[]
+ {
+ new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner")
+ }
+ };
+
+ s_BevelFeature = new ShaderFeature()
+ {
+ undoLabel = "Bevel",
+ keywords = new[] { "BEVEL_ON" }
+ };
+
+ s_GlowFeature = new ShaderFeature()
+ {
+ undoLabel = "Glow",
+ keywords = new[] { "GLOW_ON" }
+ };
+
+ s_MaskFeature = new ShaderFeature()
+ {
+ undoLabel = "Mask",
+ keywords = new[] { "MASK_HARD", "MASK_SOFT" },
+ label = new GUIContent("Mask"),
+ keywordLabels = new[]
+ {
+ new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft")
+ }
+ };
+ }
+
+ ///
+ ///
+ ///
+ public TMP_SDF_HDRPLitShaderGUI()
+ {
+ // Remove the ShaderGraphUIBlock to avoid having duplicated properties in the UI.
+ uiBlocks.RemoveAll(b => b is ShaderGraphUIBlock);
+
+ // Insert the color block just after the Surface Option block.
+ //uiBlocks.Insert(1, new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: SurfaceOptionUIBlock.Features.Lit));
+ }
+
+ protected override void DoGUI()
+ {
+ s_Face = BeginPanel("Face", s_Face);
+ if (s_Face)
+ {
+ DoFacePanel();
+ }
+
+ EndPanel();
+
+ // Outline panels
+ DoOutlinePanels();
+
+ // Underlay panel
+ s_Underlay = BeginPanel("Underlay", s_Underlay);
+ if (s_Underlay)
+ {
+ DoUnderlayPanel();
+ }
+
+ EndPanel();
+
+ // Lighting panel
+ DrawLightingPanel();
+
+ /*
+ if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor))
+ {
+ s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow);
+ if (s_Glow)
+ {
+ DoGlowPanel();
+ }
+
+ EndPanel();
+ }
+ */
+
+ s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
+ if (s_DebugExtended)
+ {
+ DoDebugPanelSRP();
+ }
+ EndPanel();
+
+ EditorGUILayout.Space();
+ EditorGUILayout.Space();
+
+ using (var changed = new EditorGUI.ChangeCheckScope())
+ {
+ uiBlocks.OnGUI(m_Editor, m_Properties);
+ ApplyKeywordsAndPassesIfNeeded(changed.changed, uiBlocks.materials);
+ }
+ }
+
+ void DoFacePanel()
+ {
+ EditorGUI.indentLevel += 1;
+
+ DoColor("_FaceColor", "Color");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
+ {
+ if (m_Material.HasProperty("_FaceUVSpeedX"))
+ {
+ DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames);
+ }
+ else if (m_Material.HasProperty("_FaceUVSpeed"))
+ {
+ DoTexture2D("_FaceTex", "Texture", true, s_FaceUVSpeedName);
+ }
+ else
+ {
+ DoTexture2D("_FaceTex", "Texture", true);
+ }
+ }
+
+ if (m_Material.HasProperty("_Softness"))
+ {
+ DoSlider("_Softness", "X", new Vector2(0, 1), "Softness");
+ }
+
+ if (m_Material.HasProperty("_OutlineSoftness"))
+ {
+ DoSlider("_OutlineSoftness", "Softness");
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_FaceDilate))
+ {
+ DoSlider("_FaceDilate", "Dilate");
+ if (m_Material.HasProperty(ShaderUtilities.ID_Shininess))
+ {
+ DoSlider("_FaceShininess", "Gloss");
+ }
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
+ {
+ DoSlider("_IsoPerimeter", "X", new Vector2(-1, 1), "Dilate");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoOutlinePanels()
+ {
+ s_Outline = BeginPanel("Outline 1", s_Outline);
+ if (s_Outline)
+ DoOutlinePanelWithTexture(1, "Y", "Color");
+
+ EndPanel();
+
+ s_Outline2 = BeginPanel("Outline 2", s_Outline2);
+ if (s_Outline2)
+ DoOutlinePanel(2, "Z", "Color");
+
+ EndPanel();
+
+ s_Outline3 = BeginPanel("Outline 3", s_Outline3);
+ if (s_Outline3)
+ DoOutlinePanel(3, "W", "Color");
+
+ EndPanel();
+ }
+
+ void DoOutlinePanel(int outlineID, string propertyField, string label)
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_OutlineColor" + outlineID, label);
+
+ if (outlineID != 3)
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ else
+ {
+ if (m_Material.GetFloat(ShaderUtilities.ID_OutlineMode) == 0)
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ }
+
+ DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
+ DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
+
+ if (outlineID == 3)
+ {
+ DoToggle("_OutlineMode", "Outline Mode");
+ }
+
+ if (m_Material.HasProperty("_OutlineShininess"))
+ {
+ //DoSlider("_OutlineShininess", "Gloss");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoOutlinePanelWithTexture(int outlineID, string propertyField, string label)
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_OutlineColor" + outlineID, label);
+ if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
+ {
+ if (m_Material.HasProperty("_OutlineUVSpeedX"))
+ {
+ DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
+ }
+ else if (m_Material.HasProperty("_OutlineUVSpeed"))
+ {
+ DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
+ }
+ else
+ {
+ DoTexture2D("_OutlineTex", "Texture", true);
+ }
+ }
+
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
+ DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
+
+ if (m_Material.HasProperty("_OutlineShininess"))
+ {
+ //DoSlider("_OutlineShininess", "Gloss");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoUnderlayPanel()
+ {
+ EditorGUI.indentLevel += 1;
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
+ {
+ DoColor("_UnderlayColor", "Color");
+ DoSlider("_UnderlayOffset", "X", new Vector2(-1, 1), "Offset X");
+ DoSlider("_UnderlayOffset", "Y", new Vector2(-1, 1), "Offset Y");
+ DoSlider("_UnderlayDilate", new Vector2(-1, 1), "Dilate");
+ DoSlider("_UnderlaySoftness", new Vector2(0, 1), "Softness");
+ }
+ else
+ {
+ s_UnderlayFeature.DoPopup(m_Editor, m_Material);
+ DoColor("_UnderlayColor", "Color");
+ DoSlider("_UnderlayOffsetX", "Offset X");
+ DoSlider("_UnderlayOffsetY", "Offset Y");
+ DoSlider("_UnderlayDilate", "Dilate");
+ DoSlider("_UnderlaySoftness", "Softness");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ static GUIContent[] s_BevelTypeLabels =
+ {
+ new GUIContent("Outer Bevel"),
+ new GUIContent("Inner Bevel")
+ };
+
+ void DrawLightingPanel()
+ {
+ s_Lighting = BeginPanel("Lighting", s_Lighting);
+ if (s_Lighting)
+ {
+ s_Bevel = BeginPanel("Bevel", s_Bevel);
+ if (s_Bevel)
+ {
+ DoBevelPanel();
+ }
+ EndPanel();
+
+ s_Light = BeginPanel("Local Lighting", s_Light);
+ if (s_Light)
+ {
+ DoLocalLightingPanel();
+ }
+ EndPanel();
+
+ /*
+ s_Bump = BeginPanel("Bump Map", s_Bump);
+ if (s_Bump)
+ {
+ DoBumpMapPanel();
+ }
+
+ EndPanel();
+
+ s_Env = BeginPanel("Environment Map", s_Env);
+ if (s_Env)
+ {
+ DoEnvMapPanel();
+ }
+
+ EndPanel();
+ */
+ }
+
+ EndPanel();
+ }
+
+ void DoBevelPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoPopup("_BevelType", "Type", s_BevelTypeLabels);
+ DoSlider("_BevelAmount", "Amount");
+ DoSlider("_BevelOffset", "Offset");
+ DoSlider("_BevelWidth", "Width");
+ DoSlider("_BevelRoundness", "Roundness");
+ DoSlider("_BevelClamp", "Clamp");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoLocalLightingPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoSlider("_LightAngle", "Light Angle");
+ DoColor("_SpecularColor", "Specular Color");
+ DoSlider("_SpecularPower", "Specular Power");
+ DoSlider("_Reflectivity", "Reflectivity Power");
+ DoSlider("_Diffuse", "Diffuse Shadow");
+ DoSlider("_Ambient", "Ambient Shadow");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoSurfaceLightingPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_SpecColor", "Specular Color");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoBumpMapPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_BumpMap", "Texture");
+ DoSlider("_BumpFace", "Face");
+ DoSlider("_BumpOutline", "Outline");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoEnvMapPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_ReflectFaceColor", "Face Color");
+ DoColor("_ReflectOutlineColor", "Outline Color");
+ DoCubeMap("_Cube", "Texture");
+ DoVector3("_EnvMatrixRotation", "Rotation");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoGlowPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_GlowColor", "Color");
+ DoSlider("_GlowOffset", "Offset");
+ DoSlider("_GlowInner", "Inner");
+ DoSlider("_GlowOuter", "Outer");
+ DoSlider("_GlowPower", "Power");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoDebugPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_MainTex", "Font Atlas");
+ DoFloat("_GradientScale", "Gradient Scale");
+ DoFloat("_TextureWidth", "Texture Width");
+ DoFloat("_TextureHeight", "Texture Height");
+ EditorGUILayout.Space();
+ DoFloat("_ScaleX", "Scale X");
+ DoFloat("_ScaleY", "Scale Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
+ DoSlider("_Sharpness", "Sharpness");
+
+ DoSlider("_PerspectiveFilter", "Perspective Filter");
+ EditorGUILayout.Space();
+ DoFloat("_VertexOffsetX", "Offset X");
+ DoFloat("_VertexOffsetY", "Offset Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
+ {
+ EditorGUILayout.Space();
+ s_MaskFeature.ReadState(m_Material);
+ s_MaskFeature.DoPopup(m_Editor, m_Material);
+ if (s_MaskFeature.Active)
+ {
+ DoMaskSubgroup();
+ }
+
+ EditorGUILayout.Space();
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+ else if (m_Material.HasProperty("_MaskTex"))
+ {
+ DoMaskTexSubgroup();
+ }
+ else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_Stencil", "Stencil ID");
+ DoFloat("_StencilComp", "Stencil Comp");
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginChangeCheck();
+ bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo("Use Ratios");
+ if (useRatios)
+ {
+ m_Material.DisableKeyword("RATIOS_OFF");
+ }
+ else
+ {
+ m_Material.EnableKeyword("RATIOS_OFF");
+ }
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
+ {
+ EditorGUILayout.Space();
+ DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginDisabledGroup(true);
+ DoFloat("_ScaleRatioA", "Scale Ratio A");
+ DoFloat("_ScaleRatioB", "Scale Ratio B");
+ DoFloat("_ScaleRatioC", "Scale Ratio C");
+ EditorGUI.EndDisabledGroup();
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoDebugPanelSRP()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_MainTex", "Font Atlas");
+ DoFloat("_GradientScale", "Gradient Scale");
+ //DoFloat("_TextureWidth", "Texture Width");
+ //DoFloat("_TextureHeight", "Texture Height");
+ EditorGUILayout.Space();
+
+ /*
+ DoFloat("_ScaleX", "Scale X");
+ DoFloat("_ScaleY", "Scale Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
+ DoSlider("_Sharpness", "Sharpness");
+
+ DoSlider("_PerspectiveFilter", "Perspective Filter");
+ EditorGUILayout.Space();
+ DoFloat("_VertexOffsetX", "Offset X");
+ DoFloat("_VertexOffsetY", "Offset Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
+ {
+ EditorGUILayout.Space();
+ s_MaskFeature.ReadState(m_Material);
+ s_MaskFeature.DoPopup(m_Editor, m_Material);
+ if (s_MaskFeature.Active)
+ {
+ DoMaskSubgroup();
+ }
+
+ EditorGUILayout.Space();
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+ else if (m_Material.HasProperty("_MaskTex"))
+ {
+ DoMaskTexSubgroup();
+ }
+ else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_Stencil", "Stencil ID");
+ DoFloat("_StencilComp", "Stencil Comp");
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginChangeCheck();
+ bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo("Use Ratios");
+ if (useRatios)
+ {
+ m_Material.DisableKeyword("RATIOS_OFF");
+ }
+ else
+ {
+ m_Material.EnableKeyword("RATIOS_OFF");
+ }
+ }
+ */
+ if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
+ {
+ EditorGUILayout.Space();
+ DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
+ }
+
+ EditorGUILayout.Space();
+ /*
+ EditorGUI.BeginDisabledGroup(true);
+ DoFloat("_ScaleRatioA", "Scale Ratio A");
+ DoFloat("_ScaleRatioB", "Scale Ratio B");
+ DoFloat("_ScaleRatioC", "Scale Ratio C");
+ EditorGUI.EndDisabledGroup();
+ */
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoMaskSubgroup()
+ {
+ DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels);
+ if (Selection.activeGameObject != null)
+ {
+ Renderer renderer = Selection.activeGameObject.GetComponent();
+ if (renderer != null)
+ {
+ Rect rect = EditorGUILayout.GetControlRect();
+ rect.x += EditorGUIUtility.labelWidth;
+ rect.width -= EditorGUIUtility.labelWidth;
+ if (GUI.Button(rect, "Match Renderer Bounds"))
+ {
+ FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4(
+ 0,
+ 0,
+ Mathf.Round(renderer.bounds.extents.x * 1000) / 1000,
+ Mathf.Round(renderer.bounds.extents.y * 1000) / 1000
+ );
+ }
+ }
+ }
+
+ if (s_MaskFeature.State == 1)
+ {
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ }
+ }
+
+ void DoMaskTexSubgroup()
+ {
+ EditorGUILayout.Space();
+ DoTexture2D("_MaskTex", "Mask Texture");
+ DoToggle("_MaskInverse", "Inverse Mask");
+ DoColor("_MaskEdgeColor", "Edge Color");
+ DoSlider("_MaskEdgeSoftness", "Edge Softness");
+ DoSlider("_MaskWipeControl", "Wipe Position");
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ // protected override void SetupMaterialKeywordsAndPassInternal(Material material)
+ // {
+ // BaseLitGUI.SetupBaseLitKeywords(material);
+ // BaseLitGUI.SetupBaseLitMaterialPass(material);
+ // }
+ }
+}
+#endif
diff --git a/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs.meta b/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs.meta
new file mode 100644
index 0000000..9fbf55e
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_SDF_HDRPLitShaderGUI.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 85016528879d5d644981050d1d0a4368
+timeCreated: 1469844718
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs b/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs
new file mode 100644
index 0000000..a84b3c8
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs
@@ -0,0 +1,638 @@
+#if HDRP_7_5_OR_NEWER
+using UnityEngine;
+using UnityEditor;
+
+using UnityEditor.Rendering.HighDefinition;
+
+namespace TMPro.EditorUtilities
+{
+ internal class TMP_SDF_HDRPUnlitShaderGUI : TMP_BaseHDRPUnlitShaderGUI
+ {
+ // private readonly MaterialUIBlockList uiBlocks = new MaterialUIBlockList
+ // {
+ // new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: SurfaceOptionUIBlock.Features.Lit),
+ // new AdvancedOptionsUIBlock(MaterialUIBlock.Expandable.Advance, AdvancedOptionsUIBlock.Features.StandardLit) //AdvancedOptionsUIBlock.Features.Instancing | AdvancedOptionsUIBlock.Features.AddPrecomputedVelocity)
+ // };
+
+ static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature;
+
+ static bool s_Face = true, s_Outline = true, s_Outline2 = true, s_Outline3 = true, s_Underlay = true, s_Lighting = true, s_Glow, s_Bevel, s_Light, s_Bump, s_Env;
+
+ static string[]
+ s_FaceUVSpeedName = { "_FaceUVSpeed" },
+ s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" },
+ s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" },
+ s_OutlineUvSpeedName = { "_OutlineUVSpeed" };
+
+ ///
+ ///
+ ///
+ static TMP_SDF_HDRPUnlitShaderGUI()
+ {
+ s_OutlineFeature = new ShaderFeature()
+ {
+ undoLabel = "Outline",
+ keywords = new[] { "OUTLINE_ON" }
+ };
+
+ s_UnderlayFeature = new ShaderFeature()
+ {
+ undoLabel = "Underlay",
+ keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" },
+ label = new GUIContent("Underlay Type"),
+ keywordLabels = new[]
+ {
+ new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner")
+ }
+ };
+
+ s_BevelFeature = new ShaderFeature()
+ {
+ undoLabel = "Bevel",
+ keywords = new[] { "BEVEL_ON" }
+ };
+
+ s_GlowFeature = new ShaderFeature()
+ {
+ undoLabel = "Glow",
+ keywords = new[] { "GLOW_ON" }
+ };
+
+ s_MaskFeature = new ShaderFeature()
+ {
+ undoLabel = "Mask",
+ keywords = new[] { "MASK_HARD", "MASK_SOFT" },
+ label = new GUIContent("Mask"),
+ keywordLabels = new[]
+ {
+ new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft")
+ }
+ };
+ }
+
+ ///
+ ///
+ ///
+ public TMP_SDF_HDRPUnlitShaderGUI()
+ {
+ // Remove the ShaderGraphUIBlock to avoid having duplicated properties in the UI.
+ uiBlocks.RemoveAll(b => b is ShaderGraphUIBlock);
+
+ // Insert the color block just after the Surface Option block.
+ //uiBlocks.Insert(1, new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: SurfaceOptionUIBlock.Features.Lit));
+ }
+
+ protected override void DoGUI()
+ {
+ s_Face = BeginPanel("Face", s_Face);
+ if (s_Face)
+ {
+ DoFacePanel();
+ }
+
+ EndPanel();
+
+ // Outline panels
+ DoOutlinePanels();
+
+ // Underlay panel
+ s_Underlay = BeginPanel("Underlay", s_Underlay);
+ if (s_Underlay)
+ {
+ DoUnderlayPanel();
+ }
+
+ EndPanel();
+
+ // Lighting panel
+ DrawLightingPanel();
+
+ /*
+ if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor))
+ {
+ s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow);
+ if (s_Glow)
+ {
+ DoGlowPanel();
+ }
+
+ EndPanel();
+ }
+ */
+
+ s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
+ if (s_DebugExtended)
+ {
+ DoDebugPanelSRP();
+ }
+ EndPanel();
+
+ EditorGUILayout.Space();
+ EditorGUILayout.Space();
+
+ using (var changed = new EditorGUI.ChangeCheckScope())
+ {
+ uiBlocks.OnGUI(m_Editor, m_Properties);
+ ApplyKeywordsAndPassesIfNeeded(changed.changed, uiBlocks.materials);
+ }
+ }
+
+ void DoFacePanel()
+ {
+ EditorGUI.indentLevel += 1;
+
+ DoColor("_FaceColor", "Color");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
+ {
+ if (m_Material.HasProperty("_FaceUVSpeedX"))
+ {
+ DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames);
+ }
+ else if (m_Material.HasProperty("_FaceUVSpeed"))
+ {
+ DoTexture2D("_FaceTex", "Texture", true, s_FaceUVSpeedName);
+ }
+ else
+ {
+ DoTexture2D("_FaceTex", "Texture", true);
+ }
+ }
+
+ if (m_Material.HasProperty("_Softness"))
+ {
+ DoSlider("_Softness", "X", new Vector2(0, 1), "Softness");
+ }
+
+ if (m_Material.HasProperty("_OutlineSoftness"))
+ {
+ DoSlider("_OutlineSoftness", "Softness");
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_FaceDilate))
+ {
+ DoSlider("_FaceDilate", "Dilate");
+ if (m_Material.HasProperty(ShaderUtilities.ID_Shininess))
+ {
+ DoSlider("_FaceShininess", "Gloss");
+ }
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
+ {
+ DoSlider("_IsoPerimeter", "X", new Vector2(-1, 1), "Dilate");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoOutlinePanels()
+ {
+ s_Outline = BeginPanel("Outline 1", s_Outline);
+ if (s_Outline)
+ DoOutlinePanelWithTexture(1, "Y", "Color");
+
+ EndPanel();
+
+ s_Outline2 = BeginPanel("Outline 2", s_Outline2);
+ if (s_Outline2)
+ DoOutlinePanel(2, "Z", "Color");
+
+ EndPanel();
+
+ s_Outline3 = BeginPanel("Outline 3", s_Outline3);
+ if (s_Outline3)
+ DoOutlinePanel(3, "W", "Color");
+
+ EndPanel();
+ }
+
+ void DoOutlinePanel(int outlineID, string propertyField, string label)
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_OutlineColor" + outlineID, label);
+
+ if (outlineID != 3)
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ else
+ {
+ if (m_Material.GetFloat(ShaderUtilities.ID_OutlineMode) == 0)
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ }
+
+ DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
+ DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
+
+ if (outlineID == 3)
+ {
+ DoToggle("_OutlineMode", "Outline Mode");
+ }
+
+ if (m_Material.HasProperty("_OutlineShininess"))
+ {
+ //DoSlider("_OutlineShininess", "Gloss");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoOutlinePanelWithTexture(int outlineID, string propertyField, string label)
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_OutlineColor" + outlineID, label);
+ if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
+ {
+ if (m_Material.HasProperty("_OutlineUVSpeedX"))
+ {
+ DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
+ }
+ else if (m_Material.HasProperty("_OutlineUVSpeed"))
+ {
+ DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
+ }
+ else
+ {
+ DoTexture2D("_OutlineTex", "Texture", true);
+ }
+ }
+
+ DoOffset("_OutlineOffset" + outlineID, "Offset");
+ DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
+ DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
+
+ if (m_Material.HasProperty("_OutlineShininess"))
+ {
+ //DoSlider("_OutlineShininess", "Gloss");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoUnderlayPanel()
+ {
+ EditorGUI.indentLevel += 1;
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
+ {
+ DoColor("_UnderlayColor", "Color");
+ DoSlider("_UnderlayOffset", "X", new Vector2(-1, 1), "Offset X");
+ DoSlider("_UnderlayOffset", "Y", new Vector2(-1, 1), "Offset Y");
+ DoSlider("_UnderlayDilate", new Vector2(-1, 1), "Dilate");
+ DoSlider("_UnderlaySoftness", new Vector2(0, 1), "Softness");
+ }
+ else
+ {
+ s_UnderlayFeature.DoPopup(m_Editor, m_Material);
+ DoColor("_UnderlayColor", "Color");
+ DoSlider("_UnderlayOffsetX", "Offset X");
+ DoSlider("_UnderlayOffsetY", "Offset Y");
+ DoSlider("_UnderlayDilate", "Dilate");
+ DoSlider("_UnderlaySoftness", "Softness");
+ }
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ static GUIContent[] s_BevelTypeLabels =
+ {
+ new GUIContent("Outer Bevel"),
+ new GUIContent("Inner Bevel")
+ };
+
+ void DrawLightingPanel()
+ {
+ s_Lighting = BeginPanel("Lighting", s_Lighting);
+ if (s_Lighting)
+ {
+ s_Bevel = BeginPanel("Bevel", s_Bevel);
+ if (s_Bevel)
+ {
+ DoBevelPanel();
+ }
+ EndPanel();
+
+ s_Light = BeginPanel("Local Lighting", s_Light);
+ if (s_Light)
+ {
+ DoLocalLightingPanel();
+ }
+ EndPanel();
+
+ /*
+ s_Bump = BeginPanel("Bump Map", s_Bump);
+ if (s_Bump)
+ {
+ DoBumpMapPanel();
+ }
+
+ EndPanel();
+
+ s_Env = BeginPanel("Environment Map", s_Env);
+ if (s_Env)
+ {
+ DoEnvMapPanel();
+ }
+
+ EndPanel();
+ */
+ }
+
+ EndPanel();
+ }
+
+ void DoBevelPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoPopup("_BevelType", "Type", s_BevelTypeLabels);
+ DoSlider("_BevelAmount", "Amount");
+ DoSlider("_BevelOffset", "Offset");
+ DoSlider("_BevelWidth", "Width");
+ DoSlider("_BevelRoundness", "Roundness");
+ DoSlider("_BevelClamp", "Clamp");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoLocalLightingPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoSlider("_LightAngle", "Light Angle");
+ DoColor("_SpecularColor", "Specular Color");
+ DoSlider("_SpecularPower", "Specular Power");
+ DoSlider("_Reflectivity", "Reflectivity Power");
+ DoSlider("_Diffuse", "Diffuse Shadow");
+ DoSlider("_Ambient", "Ambient Shadow");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoSurfaceLightingPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_SpecColor", "Specular Color");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoBumpMapPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_BumpMap", "Texture");
+ DoSlider("_BumpFace", "Face");
+ DoSlider("_BumpOutline", "Outline");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoEnvMapPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_ReflectFaceColor", "Face Color");
+ DoColor("_ReflectOutlineColor", "Outline Color");
+ DoCubeMap("_Cube", "Texture");
+ DoVector3("_EnvMatrixRotation", "Rotation");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoGlowPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoColor("_GlowColor", "Color");
+ DoSlider("_GlowOffset", "Offset");
+ DoSlider("_GlowInner", "Inner");
+ DoSlider("_GlowOuter", "Outer");
+ DoSlider("_GlowPower", "Power");
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoDebugPanel()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_MainTex", "Font Atlas");
+ DoFloat("_GradientScale", "Gradient Scale");
+ DoFloat("_TextureWidth", "Texture Width");
+ DoFloat("_TextureHeight", "Texture Height");
+ EditorGUILayout.Space();
+ DoFloat("_ScaleX", "Scale X");
+ DoFloat("_ScaleY", "Scale Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
+ DoSlider("_Sharpness", "Sharpness");
+
+ DoSlider("_PerspectiveFilter", "Perspective Filter");
+ EditorGUILayout.Space();
+ DoFloat("_VertexOffsetX", "Offset X");
+ DoFloat("_VertexOffsetY", "Offset Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
+ {
+ EditorGUILayout.Space();
+ s_MaskFeature.ReadState(m_Material);
+ s_MaskFeature.DoPopup(m_Editor, m_Material);
+ if (s_MaskFeature.Active)
+ {
+ DoMaskSubgroup();
+ }
+
+ EditorGUILayout.Space();
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+ else if (m_Material.HasProperty("_MaskTex"))
+ {
+ DoMaskTexSubgroup();
+ }
+ else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_Stencil", "Stencil ID");
+ DoFloat("_StencilComp", "Stencil Comp");
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginChangeCheck();
+ bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo("Use Ratios");
+ if (useRatios)
+ {
+ m_Material.DisableKeyword("RATIOS_OFF");
+ }
+ else
+ {
+ m_Material.EnableKeyword("RATIOS_OFF");
+ }
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
+ {
+ EditorGUILayout.Space();
+ DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginDisabledGroup(true);
+ DoFloat("_ScaleRatioA", "Scale Ratio A");
+ DoFloat("_ScaleRatioB", "Scale Ratio B");
+ DoFloat("_ScaleRatioC", "Scale Ratio C");
+ EditorGUI.EndDisabledGroup();
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoDebugPanelSRP()
+ {
+ EditorGUI.indentLevel += 1;
+ DoTexture2D("_MainTex", "Font Atlas");
+ DoFloat("_GradientScale", "Gradient Scale");
+ //DoFloat("_TextureWidth", "Texture Width");
+ //DoFloat("_TextureHeight", "Texture Height");
+ EditorGUILayout.Space();
+
+ /*
+ DoFloat("_ScaleX", "Scale X");
+ DoFloat("_ScaleY", "Scale Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
+ DoSlider("_Sharpness", "Sharpness");
+
+ DoSlider("_PerspectiveFilter", "Perspective Filter");
+ EditorGUILayout.Space();
+ DoFloat("_VertexOffsetX", "Offset X");
+ DoFloat("_VertexOffsetY", "Offset Y");
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
+ {
+ EditorGUILayout.Space();
+ s_MaskFeature.ReadState(m_Material);
+ s_MaskFeature.DoPopup(m_Editor, m_Material);
+ if (s_MaskFeature.Active)
+ {
+ DoMaskSubgroup();
+ }
+
+ EditorGUILayout.Space();
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+ else if (m_Material.HasProperty("_MaskTex"))
+ {
+ DoMaskTexSubgroup();
+ }
+ else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
+ {
+ EditorGUILayout.Space();
+ DoFloat("_Stencil", "Stencil ID");
+ DoFloat("_StencilComp", "Stencil Comp");
+ }
+
+ EditorGUILayout.Space();
+
+ EditorGUI.BeginChangeCheck();
+ bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_Editor.RegisterPropertyChangeUndo("Use Ratios");
+ if (useRatios)
+ {
+ m_Material.DisableKeyword("RATIOS_OFF");
+ }
+ else
+ {
+ m_Material.EnableKeyword("RATIOS_OFF");
+ }
+ }
+ */
+ if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
+ {
+ EditorGUILayout.Space();
+ DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
+ }
+
+ EditorGUILayout.Space();
+ /*
+ EditorGUI.BeginDisabledGroup(true);
+ DoFloat("_ScaleRatioA", "Scale Ratio A");
+ DoFloat("_ScaleRatioB", "Scale Ratio B");
+ DoFloat("_ScaleRatioC", "Scale Ratio C");
+ EditorGUI.EndDisabledGroup();
+ */
+
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
+ }
+
+ void DoMaskSubgroup()
+ {
+ DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels);
+ if (Selection.activeGameObject != null)
+ {
+ Renderer renderer = Selection.activeGameObject.GetComponent();
+ if (renderer != null)
+ {
+ Rect rect = EditorGUILayout.GetControlRect();
+ rect.x += EditorGUIUtility.labelWidth;
+ rect.width -= EditorGUIUtility.labelWidth;
+ if (GUI.Button(rect, "Match Renderer Bounds"))
+ {
+ FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4(
+ 0,
+ 0,
+ Mathf.Round(renderer.bounds.extents.x * 1000) / 1000,
+ Mathf.Round(renderer.bounds.extents.y * 1000) / 1000
+ );
+ }
+ }
+ }
+
+ if (s_MaskFeature.State == 1)
+ {
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ }
+ }
+
+ void DoMaskTexSubgroup()
+ {
+ EditorGUILayout.Space();
+ DoTexture2D("_MaskTex", "Mask Texture");
+ DoToggle("_MaskInverse", "Inverse Mask");
+ DoColor("_MaskEdgeColor", "Edge Color");
+ DoSlider("_MaskEdgeSoftness", "Edge Softness");
+ DoSlider("_MaskWipeControl", "Wipe Position");
+ DoFloat("_MaskSoftnessX", "Softness X");
+ DoFloat("_MaskSoftnessY", "Softness Y");
+ DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
+ }
+
+ // protected override void SetupMaterialKeywordsAndPassInternal(Material material)
+ // {
+ // BaseLitGUI.SetupBaseLitKeywords(material);
+ // BaseLitGUI.SetupBaseLitMaterialPass(material);
+ // }
+ }
+}
+#endif
diff --git a/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs.meta b/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs.meta
new file mode 100644
index 0000000..f140640
--- /dev/null
+++ b/Scripts/Editor/HDRP/TMP_SDF_HDRPUnlitShaderGUI.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: bad96c2cfa78a124cb8ec890d2386dfe
+timeCreated: 1469844718
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/TMP_BaseEditorPanel.cs b/Scripts/Editor/TMP_BaseEditorPanel.cs
index 709cc9d..44d2e48 100644
--- a/Scripts/Editor/TMP_BaseEditorPanel.cs
+++ b/Scripts/Editor/TMP_BaseEditorPanel.cs
@@ -44,7 +44,7 @@ public abstract class TMP_BaseEditorPanel : Editor
static readonly GUIContent k_LineSpacingLabel = new GUIContent("Line");
static readonly GUIContent k_ParagraphSpacingLabel = new GUIContent("Paragraph");
- static readonly GUIContent k_AlignmentLabel = new GUIContent("Alignment", "Horizontal and vertical aligment of the text within its container.");
+ static readonly GUIContent k_AlignmentLabel = new GUIContent("Alignment", "Horizontal and vertical alignment of the text within its container.");
static readonly GUIContent k_WrapMixLabel = new GUIContent("Wrap Mix (W <-> C)", "How much to favor words versus characters when distributing the text.");
static readonly GUIContent k_WrappingLabel = new GUIContent("Wrapping", "Wraps text to the next line when reaching the edge of the container.");
@@ -140,7 +140,7 @@ protected struct Foldout
protected SerializedProperty m_VerticalMappingProp;
protected SerializedProperty m_UvLineOffsetProp;
- protected SerializedProperty m_EnableWordWrappingProp;
+ protected SerializedProperty m_TextWrappingModeProp;
protected SerializedProperty m_WordWrappingRatiosProp;
protected SerializedProperty m_TextOverflowModeProp;
protected SerializedProperty m_PageToDisplayProp;
@@ -219,7 +219,7 @@ protected virtual void OnEnable()
m_VerticalMappingProp = serializedObject.FindProperty("m_verticalMapping");
m_UvLineOffsetProp = serializedObject.FindProperty("m_uvLineOffset");
- m_EnableWordWrappingProp = serializedObject.FindProperty("m_enableWordWrapping");
+ m_TextWrappingModeProp = serializedObject.FindProperty("m_TextWrappingMode");
m_WordWrappingRatiosProp = serializedObject.FindProperty("m_wordWrappingRatios");
m_TextOverflowModeProp = serializedObject.FindProperty("m_overflowMode");
m_PageToDisplayProp = serializedObject.FindProperty("m_pageToDisplay");
@@ -993,13 +993,12 @@ void DrawWrappingOverflow()
{
// TEXT WRAPPING
Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
- EditorGUI.BeginProperty(rect, k_WrappingLabel, m_EnableWordWrappingProp);
+ EditorGUI.BeginProperty(rect, k_WrappingLabel, m_TextWrappingModeProp);
EditorGUI.BeginChangeCheck();
- int wrapSelection = EditorGUI.Popup(rect, k_WrappingLabel, m_EnableWordWrappingProp.boolValue ? 1 : 0, k_WrappingOptions);
+ EditorGUI.PropertyField(rect, m_TextWrappingModeProp);
if (EditorGUI.EndChangeCheck())
{
- m_EnableWordWrappingProp.boolValue = wrapSelection == 1;
m_HavePropertiesChanged = true;
}
diff --git a/Scripts/Editor/TMP_BaseShaderGUI.cs b/Scripts/Editor/TMP_BaseShaderGUI.cs
index b03140b..64de270 100644
--- a/Scripts/Editor/TMP_BaseShaderGUI.cs
+++ b/Scripts/Editor/TMP_BaseShaderGUI.cs
@@ -127,6 +127,7 @@ static TMP_BaseShaderGUI()
protected MaterialEditor m_Editor;
protected Material m_Material;
+ private int m_ShaderID;
protected MaterialProperty[] m_Properties;
@@ -141,7 +142,7 @@ void PrepareGUI()
{
// There's been at least one undo/redo since the last time this GUI got constructed.
// Maybe the undo/redo was for this material? Assume that is was.
- TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material);
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
s_LastSeenUndoRedoCount = s_UndoRedoCount;
@@ -154,9 +155,7 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro
this.m_Properties = properties;
if (m_IsNewGUI)
- {
PrepareGUI();
- }
DoDragAndDropBegin();
EditorGUI.BeginChangeCheck();
@@ -169,6 +168,13 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro
DoDragAndDropEnd();
}
+ public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
+ {
+ base.AssignNewShaderToMaterial(material, oldShader, newShader);
+
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, material);
+ }
+
/// Override this method to create the specific shader GUI.
protected abstract void DoGUI();
@@ -331,7 +337,7 @@ void DoTilingOffset(Rect rect, MaterialProperty property)
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
- EditorGUIUtility.labelWidth = Mathf.Min(37f, rect.width * 0.40f);
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
Vector4 vector = property.textureScaleAndOffset;
@@ -381,7 +387,7 @@ protected void DoUVSpeed(Rect rect, string[] names)
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
- EditorGUIUtility.labelWidth = Mathf.Min(37f, rect.width * 0.40f);
+ EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
s_TempLabel.text = "Speed";
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
@@ -464,6 +470,17 @@ void DoFloat2(Rect rect, string name)
}
}
+ protected void DoOffset(string name, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
protected void DoSlider(string name, string label)
{
MaterialProperty property = BeginProperty(name);
@@ -476,6 +493,17 @@ protected void DoSlider(string name, string label)
}
}
+ protected void DoSlider(string name, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(name);
+ s_TempLabel.text = label;
+ float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
+ if (EndProperty())
+ {
+ property.floatValue = value;
+ }
+ }
+
protected void DoSlider(string propertyName, string propertyField, string label)
{
MaterialProperty property = BeginProperty(propertyName);
@@ -506,6 +534,35 @@ protected void DoSlider(string propertyName, string propertyField, string label)
}
}
+ protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
+ {
+ MaterialProperty property = BeginProperty(propertyName);
+ s_TempLabel.text = label;
+
+ Vector4 value = property.vectorValue;
+
+ switch (propertyField)
+ {
+ case "X":
+ value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
+ break;
+ case "Y":
+ value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
+ break;
+ case "Z":
+ value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
+ break;
+ case "W":
+ value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
+ break;
+ }
+
+ if (EndProperty())
+ {
+ property.vectorValue = value;
+ }
+ }
+
protected void DoVector2(string name, string label)
{
MaterialProperty property = BeginProperty(name);
@@ -554,6 +611,21 @@ protected void DoVector(string name, string label, GUIContent[] subLabels)
}
}
+ bool IsNewShader()
+ {
+ if (m_Material == null)
+ return false;
+
+ int currentShaderID = m_Material.shader.GetInstanceID();
+
+ if (m_ShaderID == currentShaderID)
+ return false;
+
+ m_ShaderID = currentShaderID;
+
+ return true;
+ }
+
void DoDragAndDropBegin()
{
m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
@@ -563,15 +635,13 @@ void DoDragAndDropEnd()
{
Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
Event evt = Event.current;
+
if (evt.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
evt.Use();
}
- else if (
- evt.type == EventType.DragPerform &&
- Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition)
- )
+ else if (evt.type == EventType.DragPerform && Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition))
{
DragAndDrop.AcceptDrag();
evt.Use();
@@ -581,6 +651,11 @@ void DoDragAndDropEnd()
PerformDrop(droppedMaterial);
}
}
+ else if (evt.type == EventType.DragExited)
+ {
+ if (IsNewShader())
+ TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
+ }
}
void PerformDrop(Material droppedMaterial)
diff --git a/Scripts/Editor/TMP_DropdownEditor.cs b/Scripts/Editor/TMP_DropdownEditor.cs
index 48f8e2b..5e63fd8 100644
--- a/Scripts/Editor/TMP_DropdownEditor.cs
+++ b/Scripts/Editor/TMP_DropdownEditor.cs
@@ -17,6 +17,7 @@ public class DropdownEditor : SelectableEditor
SerializedProperty m_ItemImage;
SerializedProperty m_OnSelectionChanged;
SerializedProperty m_Value;
+ SerializedProperty m_MultiSelect;
SerializedProperty m_AlphaFadeSpeed;
SerializedProperty m_Options;
@@ -31,6 +32,7 @@ protected override void OnEnable()
m_ItemImage = serializedObject.FindProperty("m_ItemImage");
m_OnSelectionChanged = serializedObject.FindProperty("m_OnValueChanged");
m_Value = serializedObject.FindProperty("m_Value");
+ m_MultiSelect = serializedObject.FindProperty("m_MultiSelect");
m_AlphaFadeSpeed = serializedObject.FindProperty("m_AlphaFadeSpeed");
m_Options = serializedObject.FindProperty("m_Options");
}
@@ -48,6 +50,7 @@ public override void OnInspectorGUI()
EditorGUILayout.PropertyField(m_ItemText);
EditorGUILayout.PropertyField(m_ItemImage);
EditorGUILayout.PropertyField(m_Value);
+ EditorGUILayout.PropertyField(m_MultiSelect);
EditorGUILayout.PropertyField(m_AlphaFadeSpeed);
EditorGUILayout.PropertyField(m_Options);
EditorGUILayout.PropertyField(m_OnSelectionChanged);
diff --git a/Scripts/Runtime/TMP_EditorResourceManager.cs b/Scripts/Editor/TMP_EditorResourceManager.cs
similarity index 53%
rename from Scripts/Runtime/TMP_EditorResourceManager.cs
rename to Scripts/Editor/TMP_EditorResourceManager.cs
index 819bd66..6af79b2 100644
--- a/Scripts/Runtime/TMP_EditorResourceManager.cs
+++ b/Scripts/Editor/TMP_EditorResourceManager.cs
@@ -1,13 +1,47 @@
-#if UNITY_EDITOR
-
-using System.Collections.Generic;
+using System.Collections.Generic;
using UnityEngine;
+using UnityEngine.Rendering;
using UnityEditor;
+using UnityEditor.TextCore.LowLevel;
namespace TMPro
{
- public class TMP_EditorResourceManager
+ static class EditorEventCallbacks
+ {
+ [InitializeOnLoadMethod]
+ internal static void InitializeFontAssetResourceChangeCallBacks()
+ {
+ TMP_FontAsset.RegisterResourceForUpdate += TMP_EditorResourceManager.RegisterResourceForUpdate;
+ TMP_FontAsset.RegisterResourceForReimport += TMP_EditorResourceManager.RegisterResourceForReimport;
+ TMP_FontAsset.OnFontAssetTextureChanged += TMP_EditorResourceManager.AddTextureToAsset;
+ TMP_FontAsset.SetAtlasTextureIsReadable += FontEngineEditorUtilities.SetAtlasTextureIsReadable;
+ TMP_FontAsset.GetSourceFontRef += TMP_EditorResourceManager.GetSourceFontRef;
+ TMP_FontAsset.SetSourceFontGUID += TMP_EditorResourceManager.SetSourceFontGUID;
+
+ // Callback to handle clearing dynamic font asset data when closing the Editor
+ EditorApplication.quitting += () =>
+ {
+ // Find all font assets in the project
+ string searchPattern = "t:TMP_FontAsset";
+ string[] fontAssetGUIDs = AssetDatabase.FindAssets(searchPattern);
+
+ for (int i = 0; i < fontAssetGUIDs.Length; i++)
+ {
+ string fontAssetPath = AssetDatabase.GUIDToAssetPath(fontAssetGUIDs[i]);
+ TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath(fontAssetPath);
+
+ if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width != 0)
+ {
+ Debug.Log("Clearing [" + fontAsset.name + "] dynamic font asset data.");
+ fontAsset.ClearFontAssetDataInternal();
+ }
+ }
+ };
+ }
+ }
+
+ internal class TMP_EditorResourceManager
{
private static TMP_EditorResourceManager s_Instance;
@@ -23,7 +57,7 @@ public class TMP_EditorResourceManager
///
/// Get a singleton instance of the manager.
///
- public static TMP_EditorResourceManager instance
+ internal static TMP_EditorResourceManager instance
{
get
{
@@ -39,7 +73,12 @@ public static TMP_EditorResourceManager instance
///
private TMP_EditorResourceManager()
{
- Camera.onPostRender += OnCameraPostRender;
+ // Register to the appropriate callback for the given render pipeline.
+ if (RenderPipelineManager.currentPipeline == null)
+ Camera.onPostRender += OnCameraPostRender;
+ else
+ RenderPipelineManager.endFrameRendering += OnEndOfFrame;
+
Canvas.willRenderCanvases += OnPreRenderCanvases;
}
@@ -57,12 +96,21 @@ void OnPreRenderCanvases()
DoPreRenderUpdates();
}
+ void OnEndOfFrame(ScriptableRenderContext renderContext, Camera[] cameras)
+ {
+ DoPostRenderUpdates();
+ }
+
///
/// Register resource for re-import.
///
///
internal static void RegisterResourceForReimport(Object obj)
{
+ // Return if referenced object is not a persistent asset
+ if (!EditorUtility.IsPersistent(obj))
+ return;
+
instance.InternalRegisterResourceForReimport(obj);
}
@@ -80,9 +128,13 @@ private void InternalRegisterResourceForReimport(Object obj)
///
/// Register resource to be updated.
///
- ///
+ ///
internal static void RegisterResourceForUpdate(Object obj)
{
+ // Return if referenced object is not a persistent asset
+ if (!EditorUtility.IsPersistent(obj))
+ return;
+
instance.InternalRegisterResourceForUpdate(obj);
}
@@ -117,6 +169,44 @@ private void InternalRegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAss
m_FontAssetDefinitionRefreshQueue.Add(fontAsset);
}
+ ///
+ /// Add texture as sub asset to the referenced object.
+ ///
+ /// The texture to be added as sub object.
+ /// The object to which this texture sub object will be added.
+ internal static void AddTextureToAsset(Texture tex, Object obj)
+ {
+ // Return if referenced object is not a persistent asset
+ if (!EditorUtility.IsPersistent(obj))
+ return;
+
+ if (tex != null)
+ AssetDatabase.AddObjectToAsset(tex, obj);
+
+ RegisterResourceForReimport(obj);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static Font GetSourceFontRef(string guid)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ return AssetDatabase.LoadAssetAtPath(path);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static string SetSourceFontGUID(Font font)
+ {
+ return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(font));
+ }
+
void DoPostRenderUpdates()
{
// Handle objects that need updating
@@ -127,7 +217,7 @@ void DoPostRenderUpdates()
Object obj = m_ObjectUpdateQueue[i];
if (obj != null)
{
- EditorUtility.SetDirty(obj);
+ //EditorUtility.SetDirty(obj);
}
}
@@ -148,7 +238,11 @@ void DoPostRenderUpdates()
Object obj = m_ObjectReImportQueue[i];
if (obj != null)
{
- AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(obj));
+ string assetPath = AssetDatabase.GetAssetPath(obj);
+
+ // Exclude Assets not located in the project
+ if (assetPath.StartsWith("Assets/", System.StringComparison.OrdinalIgnoreCase))
+ AssetDatabase.ImportAsset(assetPath);
}
}
@@ -181,4 +275,3 @@ void DoPreRenderUpdates()
}
}
}
-#endif
diff --git a/Scripts/Runtime/TMP_EditorResourceManager.cs.meta b/Scripts/Editor/TMP_EditorResourceManager.cs.meta
similarity index 100%
rename from Scripts/Runtime/TMP_EditorResourceManager.cs.meta
rename to Scripts/Editor/TMP_EditorResourceManager.cs.meta
diff --git a/Scripts/Editor/TMP_FontAssetEditor.cs b/Scripts/Editor/TMP_FontAssetEditor.cs
index c963fa0..ffe9593 100644
--- a/Scripts/Editor/TMP_FontAssetEditor.cs
+++ b/Scripts/Editor/TMP_FontAssetEditor.cs
@@ -56,10 +56,14 @@ private struct UI_PanelState
public static bool glyphTablePanel = false;
public static bool characterTablePanel = false;
public static bool fontFeatureTablePanel = false;
+ public static bool MarkToBaseTablePanel = false;
+ public static bool MarkToMarkTablePanel = false;
}
- private struct AtlasSettings
+ private struct GenerationSettings
{
+ public Font sourceFont;
+ public int faceIndex;
public GlyphRenderMode glyphRenderMode;
public int pointSize;
public int padding;
@@ -120,10 +124,16 @@ private struct Warning
private int m_CurrentGlyphPage = 0;
private int m_CurrentCharacterPage = 0;
private int m_CurrentKerningPage = 0;
+ private int m_CurrentMarkToBasePage = 0;
+ private int m_CurrentMarkToMarkPage = 0;
private int m_SelectedGlyphRecord = -1;
private int m_SelectedCharacterRecord = -1;
private int m_SelectedAdjustmentRecord = -1;
+ private int m_SelectedMarkToBaseRecord = -1;
+ private int m_SelectedMarkToMarkRecord = -1;
+
+ enum RecordSelectionType { CharacterRecord, GlyphRecord, AdjustmentPairRecord, MarkToBaseRecord, MarkToMarkRecord }
private string m_dstGlyphID;
private string m_dstUnicode;
@@ -135,9 +145,13 @@ private struct Warning
private Warning m_AddGlyphWarning;
private Warning m_AddCharacterWarning;
private bool m_DisplayDestructiveChangeWarning;
- private AtlasSettings m_AtlasSettings;
+ private GenerationSettings m_GenerationSettings;
private bool m_MaterialPresetsRequireUpdate;
+ private static readonly string[] k_InvalidFontFaces = { string.Empty };
+ private string[] m_FontFaces;
+ private bool m_FaceInfoDirty;
+
private string m_GlyphSearchPattern;
private List m_GlyphSearchList;
@@ -147,6 +161,13 @@ private struct Warning
private string m_KerningTableSearchPattern;
private List m_KerningTableSearchList;
+ private string m_MarkToBaseTableSearchPattern;
+ private List m_MarkToBaseTableSearchList;
+
+ private string m_MarkToMarkTableSearchPattern;
+ private List m_MarkToMarkTableSearchList;
+
+
private bool m_isSearchDirty;
private const string k_UndoRedo = "UndoRedoPerformed";
@@ -155,6 +176,7 @@ private struct Warning
private SerializedProperty font_atlas_prop;
private SerializedProperty font_material_prop;
+ private SerializedProperty m_FontFaceIndex_prop;
private SerializedProperty m_AtlasRenderMode_prop;
private SerializedProperty m_SamplingPointSize_prop;
private SerializedProperty m_AtlasPadding_prop;
@@ -184,6 +206,8 @@ private struct Warning
private TMP_FontFeatureTable m_FontFeatureTable;
private SerializedProperty m_FontFeatureTable_prop;
private SerializedProperty m_GlyphPairAdjustmentRecords_prop;
+ private SerializedProperty m_MarkToBaseAdjustmentRecords_prop;
+ private SerializedProperty m_MarkToMarkAdjustmentRecords_prop;
private TMP_SerializedPropertyHolder m_SerializedPropertyHolder;
private SerializedProperty m_EmptyGlyphPairAdjustmentRecord_prop;
@@ -193,6 +217,7 @@ private struct Warning
private Material[] m_materialPresets;
private bool isAssetDirty = false;
+ private bool m_IsFallbackGlyphCacheDirty;
private int errorCode;
@@ -204,8 +229,9 @@ public void OnEnable()
m_FaceInfo_prop = serializedObject.FindProperty("m_FaceInfo");
font_atlas_prop = serializedObject.FindProperty("m_AtlasTextures").GetArrayElementAtIndex(0);
- font_material_prop = serializedObject.FindProperty("material");
+ font_material_prop = serializedObject.FindProperty("m_Material");
+ m_FontFaceIndex_prop = m_FaceInfo_prop.FindPropertyRelative("m_FaceIndex");
m_AtlasPopulationMode_prop = serializedObject.FindProperty("m_AtlasPopulationMode");
m_AtlasRenderMode_prop = serializedObject.FindProperty("m_AtlasRenderMode");
m_SamplingPointSize_prop = m_FaceInfo_prop.FindPropertyRelative("m_PointSize");
@@ -231,6 +257,11 @@ public void OnEnable()
EditorGUI.LabelField(rect, "Fallback List");
};
+ m_list.onReorderCallback = itemList =>
+ {
+ m_IsFallbackGlyphCacheDirty = true;
+ };
+
// Clean up fallback list in the event if contains null elements.
CleanFallbackFontAssetTable();
@@ -248,10 +279,15 @@ public void OnEnable()
m_FontFeatureTable_prop = serializedObject.FindProperty("m_FontFeatureTable");
m_GlyphPairAdjustmentRecords_prop = m_FontFeatureTable_prop.FindPropertyRelative("m_GlyphPairAdjustmentRecords");
+ m_MarkToBaseAdjustmentRecords_prop = m_FontFeatureTable_prop.FindPropertyRelative("m_MarkToBaseAdjustmentRecords");
+ m_MarkToMarkAdjustmentRecords_prop = m_FontFeatureTable_prop.FindPropertyRelative("m_MarkToMarkAdjustmentRecords");
m_fontAsset = target as TMP_FontAsset;
m_FontFeatureTable = m_fontAsset.fontFeatureTable;
+ // Get Font Faces and Styles
+ m_FontFaces = GetFontFaces();
+
// Upgrade Font Feature Table if necessary
if (m_fontAsset.m_KerningTable != null && m_fontAsset.m_KerningTable.kerningPairs != null && m_fontAsset.m_KerningTable.kerningPairs.Count > 0)
m_fontAsset.ReadFontAssetDefinition();
@@ -278,7 +314,7 @@ public void OnDisable()
if (m_DisplayDestructiveChangeWarning)
{
m_DisplayDestructiveChangeWarning = false;
- RestoreAtlasGenerationSettings();
+ RestoreGenerationSettings();
GUIUtility.keyboardControl = 0;
serializedObject.ApplyModifiedProperties();
@@ -358,16 +394,28 @@ public override void OnInspectorGUI()
EditorGUI.indentLevel = 1;
EditorGUI.BeginChangeCheck();
- Font sourceFont = (Font)EditorGUILayout.ObjectField("Source Font File", m_fontAsset.m_SourceFontFile_EditorRef, typeof(Font), false);
+ Font sourceFont = (Font)EditorGUILayout.ObjectField("Source Font File", m_fontAsset.SourceFont_EditorRef, typeof(Font), false);
if (EditorGUI.EndChangeCheck())
{
- string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(sourceFont));
- m_fontAsset.m_SourceFontFileGUID = guid;
- m_fontAsset.m_SourceFontFile_EditorRef = sourceFont;
+ m_GenerationSettings.sourceFont = m_fontAsset.SourceFont_EditorRef;
+ m_fontAsset.SourceFont_EditorRef = sourceFont;
+ m_FontFaces = GetFontFaces(0);
+ m_FaceInfoDirty = true;
+ m_DisplayDestructiveChangeWarning = true;
+ //m_MaterialPresetsRequireUpdate = true;
}
EditorGUI.BeginDisabledGroup(sourceFont == null);
{
+ EditorGUI.BeginChangeCheck();
+ m_FontFaceIndex_prop.intValue = EditorGUILayout.Popup(new GUIContent("Font Face"), m_FontFaceIndex_prop.intValue, m_FontFaces);
+ if (EditorGUI.EndChangeCheck())
+ {
+ m_MaterialPresetsRequireUpdate = true;
+ m_DisplayDestructiveChangeWarning = true;
+ m_FaceInfoDirty = true;
+ }
+
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_AtlasPopulationMode_prop, new GUIContent("Atlas Population Mode"));
if (EditorGUI.EndChangeCheck())
@@ -376,6 +424,7 @@ public override void OnInspectorGUI()
bool isDatabaseRefreshRequired = false;
+ // Static font asset
if (m_AtlasPopulationMode_prop.intValue == 0)
{
m_fontAsset.sourceFontFile = null;
@@ -386,16 +435,12 @@ public override void OnInspectorGUI()
Texture2D tex = m_fontAsset.atlasTextures[i];
if (tex != null && tex.isReadable)
- {
- #if UNITY_2018_4_OR_NEWER && !UNITY_2018_4_0 && !UNITY_2018_4_1 && !UNITY_2018_4_2 && !UNITY_2018_4_3 && !UNITY_2018_4_4
- FontEngineEditorUtilities.SetAtlasTextureIsReadable(tex, false);
- #endif
- }
+ FontEngineEditorUtilities.SetAtlasTextureIsReadable(tex, false);
}
- Debug.Log("Atlas Population mode set to [Static].");
+ //Debug.Log("Atlas Population mode set to [Static].");
}
- else if (m_AtlasPopulationMode_prop.intValue == 1)
+ else // Dynamic font asset
{
if (m_fontAsset.m_SourceFontFile_EditorRef.dynamic == false)
{
@@ -414,15 +459,15 @@ public override void OnInspectorGUI()
Texture2D tex = m_fontAsset.atlasTextures[i];
if (tex != null && tex.isReadable == false)
- {
- #if UNITY_2018_4_OR_NEWER && !UNITY_2018_4_0 && !UNITY_2018_4_1 && !UNITY_2018_4_2 && !UNITY_2018_4_3 && !UNITY_2018_4_4
- FontEngineEditorUtilities.SetAtlasTextureIsReadable(tex, true);
- #endif
- }
+ FontEngineEditorUtilities.SetAtlasTextureIsReadable(tex, true);
}
- Debug.Log("Atlas Population mode set to [Dynamic].");
+ //Debug.Log("Atlas Population mode set to [" + (m_AtlasPopulationMode_prop.intValue == 1 ? "Dynamic" : "Dynamic OS") + "].");
}
+
+ // Dynamic OS font asset
+ if (m_AtlasPopulationMode_prop.intValue == 2)
+ m_fontAsset.sourceFontFile = null;
}
if (isDatabaseRefreshRequired)
@@ -435,7 +480,7 @@ public override void OnInspectorGUI()
// Save state of atlas settings
if (m_DisplayDestructiveChangeWarning == false)
{
- SavedAtlasGenerationSettings();
+ SavedGenerationSettings();
//Undo.RegisterCompleteObjectUndo(m_fontAsset, "Font Asset Changes");
}
@@ -467,6 +512,9 @@ public override void OnInspectorGUI()
if (m_DisplayDestructiveChangeWarning)
{
+ bool guiEnabledState = GUI.enabled;
+ GUI.enabled = true;
+
// These changes are destructive on the font asset
rect = EditorGUILayout.GetControlRect(false, 60);
rect.x += 15;
@@ -477,11 +525,12 @@ public override void OnInspectorGUI()
{
m_DisplayDestructiveChangeWarning = false;
- // Update face info is sampling point size was changed.
- if (m_AtlasSettings.pointSize != m_SamplingPointSize_prop.intValue)
+ // Update face info if sampling point size was changed.
+ if (m_GenerationSettings.pointSize != m_SamplingPointSize_prop.intValue || m_FaceInfoDirty)
{
- FontEngine.LoadFontFace(m_fontAsset.sourceFontFile, m_SamplingPointSize_prop.intValue);
+ LoadFontFace(m_SamplingPointSize_prop.intValue, m_FontFaceIndex_prop.intValue);
m_fontAsset.faceInfo = FontEngine.GetFaceInfo();
+ m_FaceInfoDirty = false;
}
Material mat = m_fontAsset.material;
@@ -525,12 +574,14 @@ public override void OnInspectorGUI()
if (GUI.Button(new Rect(rect.width - 56, rect.y + 36, 80, 18), new GUIContent("Revert")))
{
m_DisplayDestructiveChangeWarning = false;
- RestoreAtlasGenerationSettings();
+ RestoreGenerationSettings();
GUIUtility.keyboardControl = 0;
// TODO: Clear undo buffers.
//Undo.ClearUndo(m_fontAsset);
}
+
+ GUI.enabled = guiEnabledState;
}
}
EditorGUI.EndDisabledGroup();
@@ -671,7 +722,6 @@ public override void OnInspectorGUI()
{
EditorGUIUtility.labelWidth = 120;
EditorGUI.indentLevel = 0;
-
m_list.DoLayoutList();
EditorGUILayout.Space();
}
@@ -785,6 +835,9 @@ public override void OnInspectorGUI()
// Draw Selection Highlight and Glyph Options
if (m_SelectedCharacterRecord == i)
{
+ // Reset other selections
+ ResetSelections(RecordSelectionType.CharacterRecord);
+
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw Glyph management options
@@ -984,6 +1037,9 @@ public override void OnInspectorGUI()
// Draw Selection Highlight and Glyph Options
if (m_SelectedGlyphRecord == i)
{
+ // Reset other selections
+ ResetSelections(RecordSelectionType.GlyphRecord);
+
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw Glyph management options
@@ -1179,6 +1235,9 @@ public override void OnInspectorGUI()
// Draw Selection Highlight and Kerning Pair Options
if (m_SelectedAdjustmentRecord == i)
{
+ // Reset other selections
+ ResetSelections(RecordSelectionType.AdjustmentPairRecord);
+
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw Glyph management options
@@ -1229,11 +1288,11 @@ public override void OnInspectorGUI()
errorCode = -1;
uint pairKey = secondGlyphIndex << 16 | firstGlyphIndex;
- if (m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookupDictionary.ContainsKey(pairKey) == false)
+ if (m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookup.ContainsKey(pairKey) == false)
{
TMP_GlyphPairAdjustmentRecord adjustmentRecord = new TMP_GlyphPairAdjustmentRecord(new TMP_GlyphAdjustmentRecord(firstGlyphIndex, firstValueRecord), new TMP_GlyphAdjustmentRecord(secondGlyphIndex, secondValueRecord));
m_FontFeatureTable.m_GlyphPairAdjustmentRecords.Add(adjustmentRecord);
- m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookupDictionary.Add(pairKey, adjustmentRecord);
+ m_FontFeatureTable.m_GlyphPairAdjustmentRecordLookup.Add(pairKey, adjustmentRecord);
errorCode = 0;
}
@@ -1279,11 +1338,313 @@ public override void OnInspectorGUI()
}
#endregion
- if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty)
+ // MARK TO BASE Font Feature Table
+ #region MARK TO BASE
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUIUtility.fieldWidth = fieldWidth;
+ EditorGUI.indentLevel = 0;
+ rect = EditorGUILayout.GetControlRect(false, 24);
+
+ int markToBaseAdjustmentRecordCount = m_fontAsset.fontFeatureTable.MarkToBaseAdjustmentRecords.Count;
+
+ if (GUI.Button(rect, new GUIContent("Mark To Base Adjustment Table [" + markToBaseAdjustmentRecordCount + "]" + (rect.width > 340 ? " Records" : ""), "List of Mark to Base adjustment records."), TMP_UIStyleManager.sectionHeader))
+ UI_PanelState.MarkToBaseTablePanel = !UI_PanelState.MarkToBaseTablePanel;
+
+ GUI.Label(rect, (UI_PanelState.MarkToBaseTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
+
+ if (UI_PanelState.MarkToBaseTablePanel)
+ {
+ int arraySize = m_MarkToBaseAdjustmentRecords_prop.arraySize;
+ int itemsPerPage = 20;
+
+ // Display Mark Adjust Records Management Tools
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ {
+ // Search Bar implementation
+ #region DISPLAY SEARCH BAR
+ EditorGUILayout.BeginHorizontal();
+ {
+ EditorGUIUtility.labelWidth = 150f;
+ EditorGUI.BeginChangeCheck();
+ string searchPattern = EditorGUILayout.TextField("Mark to Base Search", m_MarkToBaseTableSearchPattern, "SearchTextField");
+ if (EditorGUI.EndChangeCheck() || m_isSearchDirty)
+ {
+ if (string.IsNullOrEmpty(searchPattern) == false)
+ {
+ m_MarkToBaseTableSearchPattern = searchPattern;
+
+ // Search Glyph Table for potential matches
+ SearchMarkToBaseTable(m_MarkToBaseTableSearchPattern, ref m_MarkToBaseTableSearchList);
+ }
+ else
+ m_MarkToBaseTableSearchPattern = null;
+
+ m_isSearchDirty = false;
+ }
+
+ string styleName = string.IsNullOrEmpty(m_MarkToBaseTableSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton";
+ if (GUILayout.Button(GUIContent.none, styleName))
+ {
+ GUIUtility.keyboardControl = 0;
+ m_MarkToBaseTableSearchPattern = string.Empty;
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ #endregion
+
+ // Display Page Navigation
+ if (!string.IsNullOrEmpty(m_MarkToBaseTableSearchPattern))
+ arraySize = m_MarkToBaseTableSearchList.Count;
+
+ DisplayPageNavigation(ref m_CurrentKerningPage, arraySize, itemsPerPage);
+ }
+ EditorGUILayout.EndVertical();
+
+ if (arraySize > 0)
+ {
+ // Display each GlyphInfo entry using the GlyphInfo property drawer.
+ for (int i = itemsPerPage * m_CurrentMarkToBasePage; i < arraySize && i < itemsPerPage * (m_CurrentMarkToBasePage + 1); i++)
+ {
+ // Define the start of the selection region of the element.
+ Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+
+ int elementIndex = i;
+ if (!string.IsNullOrEmpty(m_MarkToBaseTableSearchPattern))
+ elementIndex = m_MarkToBaseTableSearchList[i];
+
+ SerializedProperty markToBasePropertyRecord = m_MarkToBaseAdjustmentRecords_prop.GetArrayElementAtIndex(elementIndex);
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+
+ using (new EditorGUI.DisabledScope(i != m_SelectedMarkToBaseRecord))
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(markToBasePropertyRecord, new GUIContent("Selectable"));
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ UpdateMarkToBaseAdjustmentRecordLookup(markToBasePropertyRecord);
+ }
+ }
+
+ EditorGUILayout.EndVertical();
+
+ // Define the end of the selection region of the element.
+ Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+
+ // Check for Item selection
+ Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
+ if (DoSelectionCheck(selectionArea))
+ {
+ if (m_SelectedMarkToBaseRecord == i)
+ {
+ m_SelectedMarkToBaseRecord = -1;
+ }
+ else
+ {
+ m_SelectedMarkToBaseRecord = i;
+ GUIUtility.keyboardControl = 0;
+ }
+ }
+
+ // Draw Selection Highlight and Kerning Pair Options
+ if (m_SelectedMarkToBaseRecord == i)
+ {
+ // Reset other selections
+ ResetSelections(RecordSelectionType.MarkToBaseRecord);
+
+ TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
+
+ // Draw Glyph management options
+ Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f);
+ float optionAreaWidth = controlRect.width;
+ float btnWidth = optionAreaWidth / 4;
+
+ Rect position = new Rect(controlRect.x + controlRect.width - btnWidth, controlRect.y, btnWidth, controlRect.height);
+
+ // Remove Mark to Base Record
+ GUI.enabled = true;
+ if (GUI.Button(position, "Remove"))
+ {
+ GUIUtility.keyboardControl = 0;
+
+ RemoveAdjustmentRecord(m_MarkToBaseAdjustmentRecords_prop, i);
+
+ isAssetDirty = true;
+ m_SelectedMarkToBaseRecord = -1;
+ m_isSearchDirty = true;
+ break;
+ }
+ }
+ }
+ }
+
+ DisplayAddRemoveButtons(m_MarkToBaseAdjustmentRecords_prop, m_SelectedMarkToBaseRecord, markToBaseAdjustmentRecordCount);
+
+ DisplayPageNavigation(ref m_CurrentMarkToBasePage, arraySize, itemsPerPage);
+
+ GUILayout.Space(5);
+ }
+ #endregion
+
+ // MARK TO MARK Font Feature Table
+ #region MARK TO MARK
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUIUtility.fieldWidth = fieldWidth;
+ EditorGUI.indentLevel = 0;
+ rect = EditorGUILayout.GetControlRect(false, 24);
+
+ int markToMarkAdjustmentRecordCount = m_fontAsset.fontFeatureTable.MarkToMarkAdjustmentRecords.Count;
+
+ if (GUI.Button(rect, new GUIContent("Mark To Mark Adjustment Table [" + markToMarkAdjustmentRecordCount + "]" + (rect.width > 340 ? " Records" : ""), "List of Mark to Mark adjustment records."), TMP_UIStyleManager.sectionHeader))
+ UI_PanelState.MarkToMarkTablePanel = !UI_PanelState.MarkToMarkTablePanel;
+
+ GUI.Label(rect, (UI_PanelState.MarkToMarkTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
+
+ if (UI_PanelState.MarkToMarkTablePanel)
+ {
+ int arraySize = m_MarkToMarkAdjustmentRecords_prop.arraySize;
+ int itemsPerPage = 20;
+
+ // Display Kerning Pair Management Tools
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+ {
+ // Search Bar implementation
+ #region DISPLAY SEARCH BAR
+ EditorGUILayout.BeginHorizontal();
+ {
+ EditorGUIUtility.labelWidth = 150f;
+ EditorGUI.BeginChangeCheck();
+ string searchPattern = EditorGUILayout.TextField("Mark to Mark Search", m_MarkToMarkTableSearchPattern, "SearchTextField");
+ if (EditorGUI.EndChangeCheck() || m_isSearchDirty)
+ {
+ if (string.IsNullOrEmpty(searchPattern) == false)
+ {
+ m_MarkToMarkTableSearchPattern = searchPattern;
+
+ // Search Glyph Table for potential matches
+ SearchMarkToMarkTable(m_MarkToMarkTableSearchPattern, ref m_MarkToMarkTableSearchList);
+ }
+ else
+ m_MarkToMarkTableSearchPattern = null;
+
+ m_isSearchDirty = false;
+ }
+
+ string styleName = string.IsNullOrEmpty(m_MarkToMarkTableSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton";
+ if (GUILayout.Button(GUIContent.none, styleName))
+ {
+ GUIUtility.keyboardControl = 0;
+ m_MarkToMarkTableSearchPattern = string.Empty;
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ #endregion
+
+ // Display Page Navigation
+ if (!string.IsNullOrEmpty(m_MarkToMarkTableSearchPattern))
+ arraySize = m_MarkToMarkTableSearchList.Count;
+
+ DisplayPageNavigation(ref m_CurrentMarkToMarkPage, arraySize, itemsPerPage);
+ }
+ EditorGUILayout.EndVertical();
+
+ if (arraySize > 0)
+ {
+ // Display each GlyphInfo entry using the GlyphInfo property drawer.
+ for (int i = itemsPerPage * m_CurrentMarkToMarkPage; i < arraySize && i < itemsPerPage * (m_CurrentMarkToMarkPage + 1); i++)
+ {
+ // Define the start of the selection region of the element.
+ Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+
+ int elementIndex = i;
+ if (!string.IsNullOrEmpty(m_MarkToMarkTableSearchPattern))
+ elementIndex = m_MarkToMarkTableSearchList[i];
+
+ SerializedProperty markToMarkPropertyRecord = m_MarkToMarkAdjustmentRecords_prop.GetArrayElementAtIndex(elementIndex);
+
+ EditorGUILayout.BeginVertical(EditorStyles.helpBox);
+
+ using (new EditorGUI.DisabledScope(i != m_SelectedMarkToMarkRecord))
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(markToMarkPropertyRecord, new GUIContent("Selectable"));
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ UpdateMarkToMarkAdjustmentRecordLookup(markToMarkPropertyRecord);
+ }
+ }
+
+ EditorGUILayout.EndVertical();
+
+ // Define the end of the selection region of the element.
+ Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
+
+ // Check for Item selection
+ Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
+ if (DoSelectionCheck(selectionArea))
+ {
+ if (m_SelectedMarkToMarkRecord == i)
+ {
+ m_SelectedMarkToMarkRecord = -1;
+ }
+ else
+ {
+ m_SelectedMarkToMarkRecord = i;
+ GUIUtility.keyboardControl = 0;
+ }
+ }
+
+ // Draw Selection Highlight and Kerning Pair Options
+ if (m_SelectedMarkToMarkRecord == i)
+ {
+ // Reset other selections
+ ResetSelections(RecordSelectionType.MarkToMarkRecord);
+
+ TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
+
+ // Draw Glyph management options
+ Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f);
+ float optionAreaWidth = controlRect.width;
+ float btnWidth = optionAreaWidth / 4;
+
+ Rect position = new Rect(controlRect.x + controlRect.width - btnWidth, controlRect.y, btnWidth, controlRect.height);
+
+ // Remove Mark to Base Record
+ GUI.enabled = true;
+ if (GUI.Button(position, "Remove"))
+ {
+ GUIUtility.keyboardControl = 0;
+
+ RemoveAdjustmentRecord(m_MarkToMarkAdjustmentRecords_prop, i);
+
+ isAssetDirty = true;
+ m_SelectedMarkToMarkRecord = -1;
+ m_isSearchDirty = true;
+ break;
+ }
+ }
+ }
+ }
+
+ DisplayAddRemoveButtons(m_MarkToMarkAdjustmentRecords_prop, m_SelectedMarkToMarkRecord, markToMarkAdjustmentRecordCount);
+
+ DisplayPageNavigation(ref m_CurrentMarkToMarkPage, arraySize, itemsPerPage);
+
+ GUILayout.Space(5);
+ }
+ #endregion
+
+ if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty || m_IsFallbackGlyphCacheDirty)
{
// Delay callback until user has decided to Apply or Revert the changes.
if (m_DisplayDestructiveChangeWarning == false)
+ {
+ TMP_ResourceManager.RebuildFontAssetCache();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, m_fontAsset);
+ m_IsFallbackGlyphCacheDirty = false;
+ }
if (m_fontAsset.IsFontAssetLookupTablesDirty || evt_cmd == k_UndoRedo)
m_fontAsset.ReadFontAssetDefinition();
@@ -1296,10 +1657,93 @@ public override void OnInspectorGUI()
// Clear selection if mouse event was not consumed.
GUI.enabled = true;
if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
+ {
m_SelectedAdjustmentRecord = -1;
+ m_SelectedMarkToBaseRecord = -1;
+ m_SelectedMarkToMarkRecord = -1;
+ }
+
+ }
+
+ public override bool HasPreviewGUI()
+ {
+ return true;
+ }
+
+ public override void OnPreviewGUI(Rect rect, GUIStyle background)
+ {
+ if (m_SelectedMarkToBaseRecord != -1)
+ DrawMarkToBasePreview(m_SelectedMarkToBaseRecord, rect);
+
+ if (m_SelectedMarkToMarkRecord != -1)
+ DrawMarkToMarkPreview(m_SelectedMarkToMarkRecord, rect);
+
+ }
+
+ void ResetSelections(RecordSelectionType type)
+ {
+ switch (type)
+ {
+ case RecordSelectionType.CharacterRecord:
+ m_SelectedGlyphRecord = -1;
+ m_SelectedAdjustmentRecord = -1;
+ m_SelectedMarkToBaseRecord = -1;
+ m_SelectedMarkToMarkRecord = -1;
+ break;
+ case RecordSelectionType.GlyphRecord:
+ m_SelectedCharacterRecord = -1;
+ m_SelectedAdjustmentRecord = -1;
+ m_SelectedMarkToBaseRecord = -1;
+ m_SelectedMarkToMarkRecord = -1;
+ break;
+ case RecordSelectionType.AdjustmentPairRecord:
+ m_SelectedCharacterRecord = -1;
+ m_SelectedGlyphRecord = -1;
+ m_SelectedMarkToBaseRecord = -1;
+ m_SelectedMarkToMarkRecord = -1;
+ break;
+ case RecordSelectionType.MarkToBaseRecord:
+ m_SelectedCharacterRecord = -1;
+ m_SelectedGlyphRecord = -1;
+ m_SelectedAdjustmentRecord = -1;
+ m_SelectedMarkToMarkRecord = -1;
+ break;
+ case RecordSelectionType.MarkToMarkRecord:
+ m_SelectedCharacterRecord = -1;
+ m_SelectedGlyphRecord = -1;
+ m_SelectedAdjustmentRecord = -1;
+ m_SelectedMarkToBaseRecord = -1;
+ break;
+ }
+ }
+
+ string[] GetFontFaces()
+ {
+ return GetFontFaces(m_FontFaceIndex_prop.intValue);
+ }
+
+ string[] GetFontFaces(int faceIndex)
+ {
+ if (LoadFontFace(m_SamplingPointSize_prop.intValue, faceIndex) == FontEngineError.Success)
+ return FontEngine.GetFontFaces();
+
+ return k_InvalidFontFaces;
}
+ FontEngineError LoadFontFace(int pointSize, int faceIndex)
+ {
+ if (m_fontAsset.SourceFont_EditorRef != null)
+ {
+ if (FontEngine.LoadFontFace(m_fontAsset.SourceFont_EditorRef, pointSize, faceIndex) == FontEngineError.Success)
+ return FontEngineError.Success;
+ }
+
+ // Requires Unity 2018.4.35f1
+ return FontEngine.LoadFontFace(m_fontAsset.faceInfo.familyName, m_fontAsset.faceInfo.styleName, pointSize);
+ }
+
+
void CleanFallbackFontAssetTable()
{
SerializedProperty m_FallbackFontAsseTable = serializedObject.FindProperty("m_FallbackFontAssetTable");
@@ -1328,27 +1772,34 @@ void CleanFallbackFontAssetTable()
}
}
- void SavedAtlasGenerationSettings()
+
+ void SavedGenerationSettings()
{
- m_AtlasSettings.glyphRenderMode = (GlyphRenderMode)m_AtlasRenderMode_prop.intValue;
- m_AtlasSettings.pointSize = m_SamplingPointSize_prop.intValue;
- m_AtlasSettings.padding = m_AtlasPadding_prop.intValue;
- m_AtlasSettings.atlasWidth = m_AtlasWidth_prop.intValue;
- m_AtlasSettings.atlasHeight = m_AtlasHeight_prop.intValue;
+ m_GenerationSettings.faceIndex = m_FontFaceIndex_prop.intValue;
+ m_GenerationSettings.glyphRenderMode = (GlyphRenderMode)m_AtlasRenderMode_prop.intValue;
+ m_GenerationSettings.pointSize = m_SamplingPointSize_prop.intValue;
+ m_GenerationSettings.padding = m_AtlasPadding_prop.intValue;
+ m_GenerationSettings.atlasWidth = m_AtlasWidth_prop.intValue;
+ m_GenerationSettings.atlasHeight = m_AtlasHeight_prop.intValue;
}
- void RestoreAtlasGenerationSettings()
+ void RestoreGenerationSettings()
{
- m_AtlasRenderMode_prop.intValue = (int)m_AtlasSettings.glyphRenderMode;
- m_SamplingPointSize_prop.intValue = m_AtlasSettings.pointSize;
- m_AtlasPadding_prop.intValue = m_AtlasSettings.padding;
- m_AtlasWidth_prop.intValue = m_AtlasSettings.atlasWidth;
- m_AtlasHeight_prop.intValue = m_AtlasSettings.atlasHeight;
+ m_fontAsset.SourceFont_EditorRef = m_GenerationSettings.sourceFont;
+ m_FontFaceIndex_prop.intValue = m_GenerationSettings.faceIndex;
+ m_SamplingPointSize_prop.intValue = m_GenerationSettings.pointSize;
+ m_FontFaces = GetFontFaces();
+
+ m_AtlasRenderMode_prop.intValue = (int)m_GenerationSettings.glyphRenderMode;
+ m_AtlasPadding_prop.intValue = m_GenerationSettings.padding;
+ m_AtlasWidth_prop.intValue = m_GenerationSettings.atlasWidth;
+ m_AtlasHeight_prop.intValue = m_GenerationSettings.atlasHeight;
}
void UpdateFontAssetCreationSettings()
{
+ m_fontAsset.m_CreationSettings.faceIndex = m_FontFaceIndex_prop.intValue;
m_fontAsset.m_CreationSettings.pointSize = m_SamplingPointSize_prop.intValue;
m_fontAsset.m_CreationSettings.renderMode = m_AtlasRenderMode_prop.intValue;
m_fontAsset.m_CreationSettings.padding = m_AtlasPadding_prop.intValue;
@@ -1395,6 +1846,52 @@ void UpdateGlyphData(SerializedProperty property, int index)
}
+ void DisplayAddRemoveButtons(SerializedProperty property, int selectedRecord, int recordCount)
+ {
+ Rect rect = EditorGUILayout.GetControlRect(false, 20);
+
+ rect.width /= 6;
+ // Add Style
+ rect.x = rect.width * 4 + 15;
+ if (GUI.Button(rect, "+"))
+ {
+ int index = selectedRecord == -1 ? 0 : selectedRecord;
+
+ if (index > recordCount)
+ index = recordCount;
+
+ // Copy selected element
+ property.InsertArrayElementAtIndex(index);
+
+ // Select newly inserted element
+ selectedRecord = index + 1;
+
+ serializedObject.ApplyModifiedProperties();
+
+ m_fontAsset.ReadFontAssetDefinition();
+
+ }
+
+ // Delete style
+ rect.x += rect.width;
+ if (selectedRecord == -1 || selectedRecord >= recordCount) GUI.enabled = false;
+ if (GUI.Button(rect, "-"))
+ {
+ int index = selectedRecord == -1 ? 0 : selectedRecord;
+
+ property.DeleteArrayElementAtIndex(index);
+
+ selectedRecord = -1;
+ serializedObject.ApplyModifiedProperties();
+
+ m_fontAsset.ReadFontAssetDefinition();
+ return;
+ }
+
+ GUI.enabled = true;
+ }
+
+
void DisplayPageNavigation(ref int currentPage, int arraySize, int itemsPerPage)
{
Rect pagePos = EditorGUILayout.GetControlRect(false, 20);
@@ -1582,6 +2079,92 @@ void RemoveAdjustmentPairFromList(int index)
m_fontAsset.ReadFontAssetDefinition();
}
+ private void UpdateMarkToBaseAdjustmentRecordLookup(SerializedProperty property)
+ {
+ MarkToBaseAdjustmentRecord adjustmentRecord = GetMarkToBaseAdjustmentRecord(property);
+
+ uint firstGlyphIndex = adjustmentRecord.baseGlyphID;
+ uint secondGlyphIndex = adjustmentRecord.markGlyphID;
+
+ uint key = secondGlyphIndex << 16 | firstGlyphIndex;
+
+ // Lookup dictionary entry and update it
+ if (m_FontFeatureTable.m_MarkToBaseAdjustmentRecordLookup.ContainsKey(key))
+ m_FontFeatureTable.m_MarkToBaseAdjustmentRecordLookup[key] = adjustmentRecord;
+ }
+
+ MarkToBaseAdjustmentRecord GetMarkToBaseAdjustmentRecord(SerializedProperty property)
+ {
+ MarkToBaseAdjustmentRecord adjustmentRecord = new MarkToBaseAdjustmentRecord();
+
+ adjustmentRecord.baseGlyphID = (uint)property.FindPropertyRelative("m_BaseGlyphID").intValue;
+ SerializedProperty baseAnchorPointProperty = property.FindPropertyRelative("m_BaseGlyphAnchorPoint");
+
+ GlyphAnchorPoint baseAnchorPoint = new GlyphAnchorPoint();
+ baseAnchorPoint.xCoordinate = baseAnchorPointProperty.FindPropertyRelative("m_XCoordinate").floatValue;
+ baseAnchorPoint.yCoordinate = baseAnchorPointProperty.FindPropertyRelative("m_YCoordinate").floatValue;
+ adjustmentRecord.baseGlyphAnchorPoint = baseAnchorPoint;
+
+ adjustmentRecord.markGlyphID = (uint)property.FindPropertyRelative("m_MarkGlyphID").intValue;
+ SerializedProperty markAdjustmentRecordProperty = property.FindPropertyRelative("m_MarkPositionAdjustment");
+
+ MarkPositionAdjustment markAdjustmentRecord = new MarkPositionAdjustment();
+ markAdjustmentRecord.xPositionAdjustment = markAdjustmentRecordProperty.FindPropertyRelative("m_XPositionAdjustment").floatValue;
+ markAdjustmentRecord.yPositionAdjustment = markAdjustmentRecordProperty.FindPropertyRelative("m_YPositionAdjustment").floatValue;
+ adjustmentRecord.markPositionAdjustment = markAdjustmentRecord;
+
+ return adjustmentRecord;
+ }
+
+ private void UpdateMarkToMarkAdjustmentRecordLookup(SerializedProperty property)
+ {
+ MarkToMarkAdjustmentRecord adjustmentRecord = GetMarkToMarkAdjustmentRecord(property);
+
+ uint firstGlyphIndex = adjustmentRecord.baseMarkGlyphID;
+ uint secondGlyphIndex = adjustmentRecord.combiningMarkGlyphID;
+
+ uint key = secondGlyphIndex << 16 | firstGlyphIndex;
+
+ // Lookup dictionary entry and update it
+ if (m_FontFeatureTable.m_MarkToMarkAdjustmentRecordLookup.ContainsKey(key))
+ m_FontFeatureTable.m_MarkToMarkAdjustmentRecordLookup[key] = adjustmentRecord;
+ }
+
+ MarkToMarkAdjustmentRecord GetMarkToMarkAdjustmentRecord(SerializedProperty property)
+ {
+ MarkToMarkAdjustmentRecord adjustmentRecord = new MarkToMarkAdjustmentRecord();
+
+ adjustmentRecord.baseMarkGlyphID = (uint)property.FindPropertyRelative("m_BaseMarkGlyphID").intValue;
+ SerializedProperty baseAnchorPointProperty = property.FindPropertyRelative("m_BaseMarkGlyphAnchorPoint");
+
+ GlyphAnchorPoint baseAnchorPoint = new GlyphAnchorPoint();
+ baseAnchorPoint.xCoordinate = baseAnchorPointProperty.FindPropertyRelative("m_XCoordinate").floatValue;
+ baseAnchorPoint.yCoordinate = baseAnchorPointProperty.FindPropertyRelative("m_YCoordinate").floatValue;
+ adjustmentRecord.baseMarkGlyphAnchorPoint = baseAnchorPoint;
+
+ adjustmentRecord.combiningMarkGlyphID = (uint)property.FindPropertyRelative("m_CombiningMarkGlyphID").intValue;
+ SerializedProperty markAdjustmentRecordProperty = property.FindPropertyRelative("m_CombiningMarkPositionAdjustment");
+
+ MarkPositionAdjustment markAdjustment = new MarkPositionAdjustment();
+ markAdjustment.xPositionAdjustment = markAdjustmentRecordProperty.FindPropertyRelative("m_XPositionAdjustment").floatValue;
+ markAdjustment.yPositionAdjustment = markAdjustmentRecordProperty.FindPropertyRelative("m_YPositionAdjustment").floatValue;
+ adjustmentRecord.combiningMarkPositionAdjustment = markAdjustment;
+
+ return adjustmentRecord;
+ }
+
+ void RemoveAdjustmentRecord(SerializedProperty property, int index)
+ {
+ if (index > property.arraySize)
+ return;
+
+ property.DeleteArrayElementAtIndex(index);
+
+ serializedObject.ApplyModifiedProperties();
+
+ m_fontAsset.ReadFontAssetDefinition();
+ }
+
///
///
///
@@ -1735,5 +2318,254 @@ void SearchKerningTable(string searchPattern, ref List searchResults)
searchResults.Add(i);
}
}
+
+ void SearchMarkToBaseTable(string searchPattern, ref List searchResults)
+ {
+ if (searchResults == null) searchResults = new List();
+
+ searchResults.Clear();
+
+ // Lookup glyph index of potential characters contained in the search pattern.
+ uint firstGlyphIndex = 0;
+ TMP_Character firstCharacterSearch;
+
+ if (searchPattern.Length > 0 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[0], out firstCharacterSearch))
+ firstGlyphIndex = firstCharacterSearch.glyphIndex;
+
+ uint secondGlyphIndex = 0;
+ TMP_Character secondCharacterSearch;
+
+ if (searchPattern.Length > 1 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[1], out secondCharacterSearch))
+ secondGlyphIndex = secondCharacterSearch.glyphIndex;
+
+ int arraySize = m_MarkToBaseAdjustmentRecords_prop.arraySize;
+
+ for (int i = 0; i < arraySize; i++)
+ {
+ SerializedProperty record = m_MarkToBaseAdjustmentRecords_prop.GetArrayElementAtIndex(i);
+
+ int baseGlyphIndex = record.FindPropertyRelative("m_BaseGlyphID").intValue;
+ int markGlyphIndex = record.FindPropertyRelative("m_MarkGlyphID").intValue;
+
+ if (firstGlyphIndex == baseGlyphIndex && secondGlyphIndex == markGlyphIndex)
+ searchResults.Add(i);
+ else if (searchPattern.Length == 1 && (firstGlyphIndex == baseGlyphIndex || firstGlyphIndex == markGlyphIndex))
+ searchResults.Add(i);
+ else if (baseGlyphIndex.ToString().Contains(searchPattern))
+ searchResults.Add(i);
+ else if (markGlyphIndex.ToString().Contains(searchPattern))
+ searchResults.Add(i);
+ }
+ }
+
+ void SearchMarkToMarkTable(string searchPattern, ref List searchResults)
+ {
+ if (searchResults == null) searchResults = new List();
+
+ searchResults.Clear();
+
+ // Lookup glyph index of potential characters contained in the search pattern.
+ uint firstGlyphIndex = 0;
+ TMP_Character firstCharacterSearch;
+
+ if (searchPattern.Length > 0 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[0], out firstCharacterSearch))
+ firstGlyphIndex = firstCharacterSearch.glyphIndex;
+
+ uint secondGlyphIndex = 0;
+ TMP_Character secondCharacterSearch;
+
+ if (searchPattern.Length > 1 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[1], out secondCharacterSearch))
+ secondGlyphIndex = secondCharacterSearch.glyphIndex;
+
+ int arraySize = m_MarkToMarkAdjustmentRecords_prop.arraySize;
+
+ for (int i = 0; i < arraySize; i++)
+ {
+ SerializedProperty record = m_MarkToMarkAdjustmentRecords_prop.GetArrayElementAtIndex(i);
+
+ int baseGlyphIndex = record.FindPropertyRelative("m_BaseMarkGlyphID").intValue;
+ int markGlyphIndex = record.FindPropertyRelative("m_CombiningMarkGlyphID").intValue;
+
+ if (firstGlyphIndex == baseGlyphIndex && secondGlyphIndex == markGlyphIndex)
+ searchResults.Add(i);
+ else if (searchPattern.Length == 1 && (firstGlyphIndex == baseGlyphIndex || firstGlyphIndex == markGlyphIndex))
+ searchResults.Add(i);
+ else if (baseGlyphIndex.ToString().Contains(searchPattern))
+ searchResults.Add(i);
+ else if (markGlyphIndex.ToString().Contains(searchPattern))
+ searchResults.Add(i);
+ }
+ }
+
+ void DrawMarkToBasePreview(int selectedRecord, Rect rect)
+ {
+ MarkToBaseAdjustmentRecord adjustmentRecord = m_fontAsset.fontFeatureTable.m_MarkToBaseAdjustmentRecords[selectedRecord];
+
+ uint baseGlyphIndex = adjustmentRecord.baseGlyphID;
+ uint markGlyphIndex = adjustmentRecord.markGlyphID;
+
+ if (baseGlyphIndex == 0 || markGlyphIndex == 0)
+ return;
+
+ float lineHeight = m_fontAsset.faceInfo.ascentLine - m_fontAsset.faceInfo.descentLine;
+ float scale = rect.width < rect.height ? rect.width / lineHeight : rect.height / lineHeight;
+ scale *= 0.9f;
+
+ Glyph baseGlyph;
+ m_fontAsset.glyphLookupTable.TryGetValue(baseGlyphIndex, out baseGlyph);
+
+ if (baseGlyph == null)
+ return;
+
+ Rect center = new Rect(rect.x + rect.width / 2, rect.y + rect.height / 2, rect.width, rect.height);
+
+ Vector2 origin = new Vector2(center.x, center.y);
+ origin.x = origin.x - (baseGlyph.metrics.horizontalBearingX + baseGlyph.metrics.width / 2) * scale;
+ origin.y = origin.y + (baseGlyph.metrics.horizontalBearingY - baseGlyph.metrics.height / 2) * scale;
+
+ // Draw Baseline
+ DrawBaseline(origin, rect.width, Color.grey);
+
+ // Draw Origin
+ DrawAnchorPoint(origin, Color.yellow);
+
+ Rect baseGlyphPosition = new Rect(origin.x + baseGlyph.metrics.horizontalBearingX * scale, origin.y - baseGlyph.metrics.horizontalBearingY * scale , rect.width, rect.height);
+
+ DrawGlyph(baseGlyph, baseGlyphPosition, scale);
+
+ Vector2 baseAnchorPosition = new Vector2(origin.x + adjustmentRecord.baseGlyphAnchorPoint.xCoordinate * scale, origin.y - adjustmentRecord.baseGlyphAnchorPoint.yCoordinate * scale);
+
+ DrawAnchorPoint(baseAnchorPosition, Color.green);
+
+ Glyph markGlyph = m_fontAsset.glyphLookupTable[markGlyphIndex];
+
+ Rect markGlyphPosition = new Rect(baseAnchorPosition.x + (markGlyph.metrics.horizontalBearingX - adjustmentRecord.markPositionAdjustment.xPositionAdjustment) * scale, baseAnchorPosition.y + (adjustmentRecord.markPositionAdjustment.yPositionAdjustment - markGlyph.metrics.horizontalBearingY) * scale, markGlyph.metrics.width, markGlyph.metrics.height);
+
+ // Draw Mark Origin
+ DrawGlyph(markGlyph, markGlyphPosition, scale);
+ }
+
+ void DrawMarkToMarkPreview(int selectedRecord, Rect rect)
+ {
+ MarkToMarkAdjustmentRecord adjustmentRecord = m_fontAsset.fontFeatureTable.m_MarkToMarkAdjustmentRecords[selectedRecord];
+
+ uint baseGlyphIndex = adjustmentRecord.baseMarkGlyphID;
+ uint markGlyphIndex = adjustmentRecord.combiningMarkGlyphID;
+
+ if (baseGlyphIndex == 0 || markGlyphIndex == 0)
+ return;
+
+ float lineHeight = m_fontAsset.faceInfo.ascentLine - m_fontAsset.faceInfo.descentLine;
+ float scale = rect.width < rect.height ? rect.width / lineHeight : rect.height / lineHeight;
+ scale *= 0.9f;
+
+ Glyph baseGlyph;
+ m_fontAsset.glyphLookupTable.TryGetValue(baseGlyphIndex, out baseGlyph);
+
+ if (baseGlyph == null)
+ return;
+
+ Rect center = new Rect(rect.x + rect.width / 2, rect.y + rect.height / 2, rect.width, rect.height);
+
+ Vector2 origin = new Vector2(center.x, center.y);
+ origin.x = origin.x - (baseGlyph.metrics.horizontalBearingX + baseGlyph.metrics.width / 2) * scale;
+ origin.y = origin.y + (baseGlyph.metrics.horizontalBearingY - baseGlyph.metrics.height / 2) * scale;
+
+ // Draw Baseline
+ DrawBaseline(origin, rect.width, Color.grey);
+
+ // Draw Origin
+ DrawAnchorPoint(origin, Color.yellow);
+
+ Rect baseGlyphPosition = new Rect(origin.x + baseGlyph.metrics.horizontalBearingX * scale, origin.y - baseGlyph.metrics.horizontalBearingY * scale , rect.width, rect.height);
+
+ DrawGlyph(baseGlyph, baseGlyphPosition, scale);
+
+ Vector2 baseAnchorPosition = new Vector2(origin.x + adjustmentRecord.baseMarkGlyphAnchorPoint.xCoordinate * scale, origin.y - adjustmentRecord.baseMarkGlyphAnchorPoint.yCoordinate * scale);
+
+ DrawAnchorPoint(baseAnchorPosition, Color.green);
+
+ Glyph markGlyph = m_fontAsset.glyphLookupTable[markGlyphIndex];
+
+ Rect markGlyphPosition = new Rect(baseAnchorPosition.x + (markGlyph.metrics.horizontalBearingX - adjustmentRecord.combiningMarkPositionAdjustment.xPositionAdjustment) * scale, baseAnchorPosition.y + (adjustmentRecord.combiningMarkPositionAdjustment.yPositionAdjustment - markGlyph.metrics.horizontalBearingY) * scale, markGlyph.metrics.width, markGlyph.metrics.height);
+
+ DrawGlyph(markGlyph, markGlyphPosition, scale);
+ }
+
+ void DrawBaseline(Vector2 position, float width, Color color)
+ {
+ Handles.color = color;
+
+ // Horizontal line
+ Handles.DrawLine(new Vector2(0f, position.y), new Vector2(width, position.y));
+ }
+
+ void DrawAnchorPoint(Vector2 position, Color color)
+ {
+ Handles.color = color;
+
+ // Horizontal line
+ Handles.DrawLine(new Vector2(position.x - 25, position.y), new Vector2(position.x + 25, position.y));
+
+ // Vertical line
+ Handles.DrawLine(new Vector2(position.x, position.y - 25), new Vector2(position.x, position.y + 25));
+ }
+
+ void DrawGlyph(Glyph glyph, Rect position, float scale)
+ {
+ // Get the atlas index of the glyph and lookup its atlas texture
+ int atlasIndex = glyph.atlasIndex;
+ Texture2D atlasTexture = m_fontAsset.atlasTextures.Length > atlasIndex ? m_fontAsset.atlasTextures[atlasIndex] : null;
+
+ if (atlasTexture == null)
+ return;
+
+ Material mat;
+ if (((GlyphRasterModes)m_fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
+ {
+ mat = internalBitmapMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ }
+ else
+ {
+ mat = internalSDFMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ mat.SetFloat(ShaderUtilities.ID_GradientScale, m_fontAsset.atlasPadding + 1);
+ }
+
+ GlyphRect glyphRect = glyph.glyphRect;
+
+ int padding = m_fontAsset.atlasPadding;
+
+ int glyphOriginX = glyphRect.x - padding;
+ int glyphOriginY = glyphRect.y - padding;
+ int glyphWidth = glyphRect.width + padding * 2;
+ int glyphHeight = glyphRect.height + padding * 2;
+
+ // Compute the normalized texture coordinates
+ Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
+
+ if (Event.current.type == EventType.Repaint)
+ {
+ // Draw glyph from atlas texture.
+ Rect glyphDrawPosition = new Rect(position.x - padding * scale, position.y - padding * scale, position.width, position.height);
+
+ //glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale); // / 2;
+ //glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale); // / 2;
+ glyphDrawPosition.width = glyphWidth * scale;
+ glyphDrawPosition.height = glyphHeight * scale;
+
+ // Could switch to using the default material of the font asset which would require passing scale to the shader.
+ Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(0.8f, 0.8f, 0.8f), mat);
+ }
+ }
}
}
diff --git a/Scripts/Editor/TMP_FontAsset_CreationMenu.cs b/Scripts/Editor/TMP_FontAsset_CreationMenu.cs
index 3116835..46cfb5f 100644
--- a/Scripts/Editor/TMP_FontAsset_CreationMenu.cs
+++ b/Scripts/Editor/TMP_FontAsset_CreationMenu.cs
@@ -158,6 +158,15 @@ public static void CreateFontAsset()
return;
}
+ // Make sure TMP Essential Resources have been imported in the user project.
+ if (TMP_Settings.instance == null)
+ {
+ Debug.Log("Unable to create font asset. Please import the TMP Essential Resources.");
+
+ // Show Window to Import TMP Essential Resources
+ return;
+ }
+
for (int i = 0; i < targets.Length; i++)
{
Object target = targets[i];
@@ -175,7 +184,7 @@ public static void CreateFontAsset()
static void CreateFontAssetFromSelectedObject(Object target)
{
- Font sourceFont = (Font)target;
+ Font font = (Font)target;
string sourceFontFilePath = AssetDatabase.GetAssetPath(target);
@@ -188,9 +197,9 @@ static void CreateFontAssetFromSelectedObject(Object target)
FontEngine.InitializeFontEngine();
// Load Font Face
- if (FontEngine.LoadFontFace(sourceFont, 90) != FontEngineError.Success)
+ if (FontEngine.LoadFontFace(font, 90) != FontEngineError.Success)
{
- Debug.LogWarning("Unable to load font face for [" + sourceFont.name + "]. Make sure \"Include Font Data\" is enabled in the Font Import Settings.", sourceFont);
+ Debug.LogWarning("Unable to load font face for [" + font.name + "]. Make sure \"Include Font Data\" is enabled in the Font Import Settings.", font);
return;
}
@@ -199,13 +208,15 @@ static void CreateFontAssetFromSelectedObject(Object target)
AssetDatabase.CreateAsset(fontAsset, newAssetFilePathWithName);
fontAsset.version = "1.1.0";
-
fontAsset.faceInfo = FontEngine.GetFaceInfo();
// Set font reference and GUID
+ fontAsset.sourceFontFile = font;
fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(sourceFontFilePath);
- fontAsset.m_SourceFontFile_EditorRef = sourceFont;
+ fontAsset.m_SourceFontFile_EditorRef = font;
+
fontAsset.atlasPopulationMode = AtlasPopulationMode.Dynamic;
+ fontAsset.clearDynamicDataOnBuild = TMP_Settings.clearDynamicDataOnBuild;
// Default atlas resolution is 1024 x 1024.
int atlasWidth = fontAsset.atlasWidth = 1024;
@@ -250,7 +261,7 @@ static void CreateFontAssetFromSelectedObject(Object target)
fontAsset.creationSettings = new FontAssetCreationSettings(fontAsset.m_SourceFontFileGUID, fontAsset.faceInfo.pointSize, 0, atlasPadding, 0, 1024, 1024, 7, string.Empty, (int)GlyphRenderMode.SDFAA);
// Not sure if this is still necessary in newer versions of Unity.
- EditorUtility.SetDirty(fontAsset);
+ //EditorUtility.SetDirty(fontAsset);
AssetDatabase.SaveAssets();
}
diff --git a/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs b/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs
index 69ac6f8..801ef4f 100644
--- a/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs
+++ b/Scripts/Editor/TMP_GlyphPairAdjustmentRecordPropertyDrawer.cs
@@ -10,7 +10,7 @@ namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_GlyphPairAdjustmentRecord))]
- public class TMP_GlyphPairAdjustmentRecordPropertyDrawer : PropertyDrawer
+ internal class TMP_GlyphPairAdjustmentRecordPropertyDrawer : PropertyDrawer
{
private bool isEditingEnabled = false;
private bool isSelectable = false;
diff --git a/Scripts/Editor/TMP_InputFieldEditor.cs b/Scripts/Editor/TMP_InputFieldEditor.cs
index 740379e..a430025 100644
--- a/Scripts/Editor/TMP_InputFieldEditor.cs
+++ b/Scripts/Editor/TMP_InputFieldEditor.cs
@@ -50,7 +50,9 @@ private struct m_foldout
SerializedProperty m_RichText;
SerializedProperty m_RichTextEditingAllowed;
SerializedProperty m_ResetOnDeActivation;
+ SerializedProperty m_KeepTextSelectionVisible;
SerializedProperty m_RestoreOriginalTextOnEscape;
+ SerializedProperty m_ShouldActivateOnSelect;
SerializedProperty m_OnFocusSelectAll;
SerializedProperty m_GlobalPointSize;
@@ -97,9 +99,12 @@ protected override void OnEnable()
m_RichText = serializedObject.FindProperty("m_RichText");
m_RichTextEditingAllowed = serializedObject.FindProperty("m_isRichTextEditingAllowed");
m_ResetOnDeActivation = serializedObject.FindProperty("m_ResetOnDeActivation");
+ m_KeepTextSelectionVisible = serializedObject.FindProperty("m_KeepTextSelectionVisible");
m_RestoreOriginalTextOnEscape = serializedObject.FindProperty("m_RestoreOriginalTextOnEscape");
m_OnFocusSelectAll = serializedObject.FindProperty("m_OnFocusSelectAll");
+ m_ShouldActivateOnSelect = serializedObject.FindProperty("m_ShouldActivateOnSelect");
+
m_GlobalPointSize = serializedObject.FindProperty("m_GlobalPointSize");
m_GlobalFontAsset = serializedObject.FindProperty("m_GlobalFontAsset");
@@ -186,10 +191,10 @@ public override void OnInspectorGUI()
if (text != null)
{
if (m_LineType.enumValueIndex == (int)TMP_InputField.LineType.SingleLine)
- text.enableWordWrapping = false;
+ text.textWrappingMode = TextWrappingModes.PreserveWhitespaceNoWrap;
else
{
- text.enableWordWrapping = true;
+ text.textWrappingMode = TextWrappingModes.Normal;
}
}
}
@@ -254,9 +259,17 @@ public override void OnInspectorGUI()
{
EditorGUI.indentLevel++;
- EditorGUILayout.PropertyField(m_OnFocusSelectAll, new GUIContent("OnFocus - Select All", "Should all the text be selected when the Input Field is selected."));
- EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On DeActivation", "Should the Text and Caret position be reset when Input Field is DeActivated."));
- EditorGUILayout.PropertyField(m_RestoreOriginalTextOnEscape, new GUIContent("Restore On ESC Key", "Should the original text be restored when pressing ESC."));
+ EditorGUILayout.PropertyField(m_OnFocusSelectAll, new GUIContent("OnFocus - Select All", "Should all the text be selected when the Input Field is selected?"));
+ EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On Deactivation", "Should the Text and Caret position be reset when Input Field looses focus and is Deactivated?"));
+
+ EditorGUI.indentLevel++;
+ GUI.enabled = !m_ResetOnDeActivation.boolValue;
+ EditorGUILayout.PropertyField(m_KeepTextSelectionVisible, new GUIContent("Keep Text Selection Visible", "Should the text selection remain visible when the input field looses focus and is deactivated?"));
+ GUI.enabled = true;
+ EditorGUI.indentLevel--;
+
+ EditorGUILayout.PropertyField(m_RestoreOriginalTextOnEscape, new GUIContent("Restore On ESC Key", "Should the original text be restored when pressing ESC?"));
+ EditorGUILayout.PropertyField(m_ShouldActivateOnSelect, new GUIContent("Should Activate On Select", "Determines if the Input Field will be activated when selected."));
EditorGUILayout.PropertyField(m_HideMobileKeyboard, new GUIContent("Hide Soft Keyboard", "Controls the visibility of the mobile virtual keyboard."));
EditorGUILayout.PropertyField(m_HideMobileInput, new GUIContent("Hide Mobile Input", "Controls the visibility of the editable text field above the mobile virtual keyboard."));
EditorGUILayout.PropertyField(m_ReadOnly);
diff --git a/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs b/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs
new file mode 100644
index 0000000..ef3b8ff
--- /dev/null
+++ b/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs
@@ -0,0 +1,271 @@
+using UnityEngine;
+using UnityEngine.TextCore;
+using UnityEngine.TextCore.LowLevel;
+using UnityEditor;
+using System.Collections;
+using System.Text.RegularExpressions;
+
+
+namespace TMPro.EditorUtilities
+{
+
+ [CustomPropertyDrawer(typeof(MarkToBaseAdjustmentRecord))]
+ public class TMP_MarkToBaseAdjustmentRecordPropertyDrawer : PropertyDrawer
+ {
+ private bool isEditingEnabled = false;
+ private bool isSelectable = false;
+
+ private string m_PreviousInput;
+
+ private TMP_FontAsset m_FontAsset;
+
+ static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation.");
+
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty prop_BaseGlyphID = property.FindPropertyRelative("m_BaseGlyphID");
+ SerializedProperty prop_BaseGlyphAnchorPoint = property.FindPropertyRelative("m_BaseGlyphAnchorPoint");
+
+ SerializedProperty prop_MarkGlyphID = property.FindPropertyRelative("m_MarkGlyphID");
+ SerializedProperty prop_MarkAdjustmentRecord = property.FindPropertyRelative("m_MarkPositionAdjustment");
+
+ position.yMin += 2;
+
+ float width = position.width / 2;
+ float padding = 5.0f;
+
+ Rect rect;
+
+ isEditingEnabled = GUI.enabled;
+ isSelectable = label.text == "Selectable" ? true : false;
+
+ if (isSelectable)
+ GUILayoutUtility.GetRect(position.width, 75);
+ else
+ GUILayoutUtility.GetRect(position.width, 55);
+
+ GUIStyle style = new GUIStyle(EditorStyles.label) {richText = true};
+
+ // Base Glyph
+ GUI.enabled = isEditingEnabled;
+ if (isSelectable)
+ {
+ float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_BaseGlyphID.intValue)).x;
+
+ if (!isEditingEnabled)
+ {
+ EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_BaseGlyphID.intValue + ""), style);
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUIUtility.labelWidth = 25f;
+ EditorGUI.DelayedIntField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_BaseGlyphID, new GUIContent("ID:"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+ if (fontAsset != null)
+ {
+ property.serializedObject.ApplyModifiedProperties();
+ fontAsset.ReadFontAssetDefinition();
+ TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
+ }
+ }
+ }
+
+ GUI.enabled = isEditingEnabled;
+ EditorGUIUtility.labelWidth = 30f;
+
+ rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18);
+ EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_XCoordinate"), new GUIContent("X:"));
+
+ rect.y += 20;
+ EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_YCoordinate"), new GUIContent("Y:"));
+
+ DrawGlyph((uint)prop_BaseGlyphID.intValue, new Rect(position.x, position.y, position.width, position.height), property);
+ }
+
+ // Mark Glyph
+ GUI.enabled = isEditingEnabled;
+ if (isSelectable)
+ {
+ float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_MarkGlyphID.intValue)).x;
+
+ if (!isEditingEnabled)
+ {
+ EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_MarkGlyphID.intValue + ""), style);
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUIUtility.labelWidth = 25f;
+ EditorGUI.DelayedIntField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_MarkGlyphID, new GUIContent("ID:"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+ if (fontAsset != null)
+ {
+ property.serializedObject.ApplyModifiedProperties();
+ fontAsset.ReadFontAssetDefinition();
+ TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
+ }
+ }
+ }
+
+ GUI.enabled = isEditingEnabled;
+ EditorGUIUtility.labelWidth = 30f;
+
+ rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18);
+ EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_XPositionAdjustment"), new GUIContent("X:"));
+
+ rect.y += 20;
+ EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_YPositionAdjustment"), new GUIContent("Y:"));
+
+ DrawGlyph((uint)prop_MarkGlyphID.intValue, new Rect(position.width / 2 + 20, position.y, position.width, position.height), property);
+ }
+ }
+
+ bool ValidateInput(string source)
+ {
+ int length = string.IsNullOrEmpty(source) ? 0 : source.Length;
+
+ ////Filter out unwanted characters.
+ Event evt = Event.current;
+
+ char c = evt.character;
+
+ if (c != '\0')
+ {
+ switch (length)
+ {
+ case 0:
+ break;
+ case 1:
+ if (source != m_PreviousInput)
+ return true;
+
+ if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false)
+ evt.character = '\0';
+
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
+ evt.character = '\0';
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
+ evt.character = '\0';
+
+ // Validate input
+ if (length == 6 && source[1] == 'u' && source != m_PreviousInput)
+ return true;
+ break;
+ case 10:
+ if (source != m_PreviousInput)
+ return true;
+
+ evt.character = '\0';
+ break;
+ }
+ }
+
+ m_PreviousInput = source;
+
+ return false;
+ }
+
+ uint GetUnicodeCharacter (string source)
+ {
+ uint unicode;
+
+ if (source.Length == 1)
+ unicode = source[0];
+ else if (source.Length == 6)
+ unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
+ else
+ unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
+
+ return unicode;
+ }
+
+ void DrawGlyph(uint glyphIndex, Rect position, SerializedProperty property)
+ {
+ // Get a reference to the font asset
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+
+ if (fontAsset == null)
+ return;
+
+ Glyph glyph;
+
+ // Check if glyph is present in the atlas texture.
+ if (!fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out glyph))
+ return;
+
+ // Get the atlas index of the glyph and lookup its atlas texture
+ int atlasIndex = glyph.atlasIndex;
+ Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null;
+
+ if (atlasTexture == null)
+ return;
+
+ Material mat;
+ if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
+ {
+ mat = TMP_FontAssetEditor.internalBitmapMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ }
+ else
+ {
+ mat = TMP_FontAssetEditor.internalSDFMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1);
+ }
+
+ // Draw glyph from atlas texture.
+ Rect glyphDrawPosition = new Rect(position.x, position.y + 2, 64, 60);
+
+ GlyphRect glyphRect = glyph.glyphRect;
+
+ int padding = fontAsset.atlasPadding;
+
+ int glyphOriginX = glyphRect.x - padding;
+ int glyphOriginY = glyphRect.y - padding;
+ int glyphWidth = glyphRect.width + padding * 2;
+ int glyphHeight = glyphRect.height + padding * 2;
+
+ float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine;
+ float scale = glyphDrawPosition.width / normalizedHeight;
+
+ // Compute the normalized texture coordinates
+ Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
+
+ if (Event.current.type == EventType.Repaint)
+ {
+ glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
+ glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
+ glyphDrawPosition.width = glyphWidth * scale;
+ glyphDrawPosition.height = glyphHeight * scale;
+
+ // Could switch to using the default material of the font asset which would require passing scale to the shader.
+ Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
+ }
+ }
+
+
+ }
+}
diff --git a/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs.meta b/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs.meta
new file mode 100644
index 0000000..8f5655a
--- /dev/null
+++ b/Scripts/Editor/TMP_MarkToBaseAdjustmentRecordPropertyDrawer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 065a7fcf0d7286d418f3114ec18d1a2d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs b/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs
new file mode 100644
index 0000000..ad36793
--- /dev/null
+++ b/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs
@@ -0,0 +1,270 @@
+using UnityEngine;
+using UnityEngine.TextCore;
+using UnityEngine.TextCore.LowLevel;
+using UnityEditor;
+using System.Collections;
+using System.Text.RegularExpressions;
+
+
+namespace TMPro.EditorUtilities
+{
+ [CustomPropertyDrawer(typeof(MarkToMarkAdjustmentRecord))]
+ public class TMP_MarkToMarkAdjustmentRecordPropertyDrawer : PropertyDrawer
+ {
+ private bool isEditingEnabled = false;
+ private bool isSelectable = false;
+
+ private string m_PreviousInput;
+
+ private TMP_FontAsset m_FontAsset;
+
+ static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation.");
+
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty prop_BaseGlyphID = property.FindPropertyRelative("m_BaseMarkGlyphID");
+ SerializedProperty prop_BaseGlyphAnchorPoint = property.FindPropertyRelative("m_BaseMarkGlyphAnchorPoint");
+
+ SerializedProperty prop_MarkGlyphID = property.FindPropertyRelative("m_CombiningMarkGlyphID");
+ SerializedProperty prop_MarkAdjustmentRecord = property.FindPropertyRelative("m_CombiningMarkPositionAdjustment");
+
+ position.yMin += 2;
+
+ float width = position.width / 2;
+ float padding = 5.0f;
+
+ Rect rect;
+
+ isEditingEnabled = GUI.enabled;
+ isSelectable = label.text == "Selectable" ? true : false;
+
+ if (isSelectable)
+ GUILayoutUtility.GetRect(position.width, 75);
+ else
+ GUILayoutUtility.GetRect(position.width, 55);
+
+ GUIStyle style = new GUIStyle(EditorStyles.label) {richText = true};
+
+ // Base Glyph
+ GUI.enabled = isEditingEnabled;
+ if (isSelectable)
+ {
+ float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_BaseGlyphID.intValue)).x;
+
+ if (!isEditingEnabled)
+ {
+ EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_BaseGlyphID.intValue + ""), style);
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUIUtility.labelWidth = 25f;
+ EditorGUI.DelayedIntField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_BaseGlyphID, new GUIContent("ID:"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+ if (fontAsset != null)
+ {
+ property.serializedObject.ApplyModifiedProperties();
+ fontAsset.ReadFontAssetDefinition();
+ TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
+ }
+ }
+ }
+
+ GUI.enabled = isEditingEnabled;
+ EditorGUIUtility.labelWidth = 30f;
+
+ rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18);
+ EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_XCoordinate"), new GUIContent("X:"));
+
+ rect.y += 20;
+ EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_YCoordinate"), new GUIContent("Y:"));
+
+ DrawGlyph((uint)prop_BaseGlyphID.intValue, new Rect(position.x, position.y, position.width, position.height), property);
+ }
+
+ // Mark Glyph
+ GUI.enabled = isEditingEnabled;
+ if (isSelectable)
+ {
+ float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_MarkGlyphID.intValue)).x;
+
+ if (!isEditingEnabled)
+ {
+ EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: " + prop_MarkGlyphID.intValue + ""), style);
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUIUtility.labelWidth = 25f;
+ EditorGUI.DelayedIntField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_MarkGlyphID, new GUIContent("ID:"));
+ if (EditorGUI.EndChangeCheck())
+ {
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+ if (fontAsset != null)
+ {
+ property.serializedObject.ApplyModifiedProperties();
+ fontAsset.ReadFontAssetDefinition();
+ TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
+ }
+ }
+ }
+
+ GUI.enabled = isEditingEnabled;
+ EditorGUIUtility.labelWidth = 30f;
+
+ rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18);
+ EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_XPositionAdjustment"), new GUIContent("X:"));
+
+ rect.y += 20;
+ EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_YPositionAdjustment"), new GUIContent("Y:"));
+
+ DrawGlyph((uint)prop_MarkGlyphID.intValue, new Rect(position.width / 2 + 20, position.y, position.width, position.height), property);
+ }
+ }
+
+ bool ValidateInput(string source)
+ {
+ int length = string.IsNullOrEmpty(source) ? 0 : source.Length;
+
+ ////Filter out unwanted characters.
+ Event evt = Event.current;
+
+ char c = evt.character;
+
+ if (c != '\0')
+ {
+ switch (length)
+ {
+ case 0:
+ break;
+ case 1:
+ if (source != m_PreviousInput)
+ return true;
+
+ if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false)
+ evt.character = '\0';
+
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
+ evt.character = '\0';
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
+ evt.character = '\0';
+
+ // Validate input
+ if (length == 6 && source[1] == 'u' && source != m_PreviousInput)
+ return true;
+ break;
+ case 10:
+ if (source != m_PreviousInput)
+ return true;
+
+ evt.character = '\0';
+ break;
+ }
+ }
+
+ m_PreviousInput = source;
+
+ return false;
+ }
+
+ uint GetUnicodeCharacter (string source)
+ {
+ uint unicode;
+
+ if (source.Length == 1)
+ unicode = source[0];
+ else if (source.Length == 6)
+ unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
+ else
+ unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
+
+ return unicode;
+ }
+
+ void DrawGlyph(uint glyphIndex, Rect position, SerializedProperty property)
+ {
+ // Get a reference to the font asset
+ TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
+
+ if (fontAsset == null)
+ return;
+
+ Glyph glyph;
+
+ // Check if glyph is present in the atlas texture.
+ if (!fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out glyph))
+ return;
+
+ // Get the atlas index of the glyph and lookup its atlas texture
+ int atlasIndex = glyph.atlasIndex;
+ Texture2D atlasTexture = fontAsset.atlasTextures.Length > atlasIndex ? fontAsset.atlasTextures[atlasIndex] : null;
+
+ if (atlasTexture == null)
+ return;
+
+ Material mat;
+ if (((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
+ {
+ mat = TMP_FontAssetEditor.internalBitmapMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ }
+ else
+ {
+ mat = TMP_FontAssetEditor.internalSDFMaterial;
+
+ if (mat == null)
+ return;
+
+ mat.mainTexture = atlasTexture;
+ mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1);
+ }
+
+ // Draw glyph from atlas texture.
+ Rect glyphDrawPosition = new Rect(position.x, position.y + 2, 64, 60);
+
+ GlyphRect glyphRect = glyph.glyphRect;
+
+ int padding = fontAsset.atlasPadding;
+
+ int glyphOriginX = glyphRect.x - padding;
+ int glyphOriginY = glyphRect.y - padding;
+ int glyphWidth = glyphRect.width + padding * 2;
+ int glyphHeight = glyphRect.height + padding * 2;
+
+ float normalizedHeight = fontAsset.faceInfo.ascentLine - fontAsset.faceInfo.descentLine;
+ float scale = glyphDrawPosition.width / normalizedHeight;
+
+ // Compute the normalized texture coordinates
+ Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
+
+ if (Event.current.type == EventType.Repaint)
+ {
+ glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
+ glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
+ glyphDrawPosition.width = glyphWidth * scale;
+ glyphDrawPosition.height = glyphHeight * scale;
+
+ // Could switch to using the default material of the font asset which would require passing scale to the shader.
+ Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
+ }
+ }
+
+
+ }
+}
diff --git a/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs.meta b/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs.meta
new file mode 100644
index 0000000..8e3062e
--- /dev/null
+++ b/Scripts/Editor/TMP_MarkToMarkAdjustmentRecordPropertyDrawer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 149e85704eb73624ba2d705408274f3e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Scripts/Editor/TMP_MarkupTagUpdateUtility.cs b/Scripts/Editor/TMP_MarkupTagUpdateUtility.cs
new file mode 100644
index 0000000..ffbff32
--- /dev/null
+++ b/Scripts/Editor/TMP_MarkupTagUpdateUtility.cs
@@ -0,0 +1,282 @@
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+
+internal class TMP_MarkupTagUpdateUtility
+{
+ struct MarkupTagDescriptor
+ {
+ public string name;
+ public string tag;
+ public string description;
+
+ public MarkupTagDescriptor(string name, string tag, string description)
+ {
+ this.name = name;
+ this.tag = tag;
+ this.description = description;
+ }
+
+ public MarkupTagDescriptor(string name)
+ {
+ this.name = name;
+ this.tag = null;
+ this.description = null;
+ }
+
+ public static MarkupTagDescriptor linefeed = new MarkupTagDescriptor("\n");
+ }
+
+ private static MarkupTagDescriptor[] m_MarkupTags =
+ {
+ new MarkupTagDescriptor("BOLD", "b", "// "),
+ new MarkupTagDescriptor("SLASH_BOLD", "/b", "// "),
+ new MarkupTagDescriptor("ITALIC", "i", "// "),
+ new MarkupTagDescriptor("SLASH_ITALIC", "/i", "// "),
+ new MarkupTagDescriptor("UNDERLINE", "u", "// "),
+ new MarkupTagDescriptor("SLASH_UNDERLINE", "/u", "// "),
+ new MarkupTagDescriptor("STRIKETHROUGH", "s", "// "),
+ new MarkupTagDescriptor("SLASH_STRIKETHROUGH", "/s", "// "),
+ new MarkupTagDescriptor("SUBSCRIPT", "sub", "// "),
+ new MarkupTagDescriptor("SLASH_SUBSCRIPT", "/sub", "// "),
+ new MarkupTagDescriptor("SUPERSCRIPT", "sup", "// "),
+ new MarkupTagDescriptor("SLASH_SUPERSCRIPT", "/sup", "// "),
+ new MarkupTagDescriptor("MARK", "mark", "// "),
+ new MarkupTagDescriptor("SLASH_MARK", "/mark", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("COLOR", "color", "// "),
+ new MarkupTagDescriptor("SLASH_COLOR", "/color", "// "),
+ new MarkupTagDescriptor("ALPHA", "alpha", "// "),
+ new MarkupTagDescriptor("SLASH_ALPHA", "/alpha", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("FONT", "font", "// or " ),
+ new MarkupTagDescriptor("SLASH_FONT", "/font", "// "),
+ new MarkupTagDescriptor("MATERIAL", "material", "// or as attribute "),
+ new MarkupTagDescriptor("SLASH_MATERIAL", "/material", "// "),
+ new MarkupTagDescriptor("SIZE", "size", "// "),
+ new MarkupTagDescriptor("SLASH_SIZE", "/size", "// "),
+ new MarkupTagDescriptor("FONT_WEIGHT", "font-weight", "// "),
+ new MarkupTagDescriptor("SLASH_FONT_WEIGHT", "/font-weight", "// "),
+ new MarkupTagDescriptor("SCALE", "scale", "// "),
+ new MarkupTagDescriptor("SLASH_SCALE", "/scale", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("SPRITE", "sprite", "// "),
+ new MarkupTagDescriptor("STYLE", "style", "// "),
+ new MarkupTagDescriptor("GRADIENT", "gradient", "// "),
+ new MarkupTagDescriptor("SLASH_GRADIENT", "/gradient", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("A", "a", "// "),
+ new MarkupTagDescriptor("SLASH_A", "/a", "// "),
+ new MarkupTagDescriptor("LINK", "link", "// "),
+ new MarkupTagDescriptor("SLASH_LINK", "/link", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("POSITION", "pos", "// "),
+ new MarkupTagDescriptor("SLASH_POSITION", "/pos", "// "),
+ new MarkupTagDescriptor("VERTICAL_OFFSET", "voffset","// "),
+ new MarkupTagDescriptor("SLASH_VERTICAL_OFFSET", "/voffset", "// "),
+ new MarkupTagDescriptor("ROTATE", "rotate", "// "),
+ new MarkupTagDescriptor("SLASH_ROTATE", "/rotate", "// "),
+ new MarkupTagDescriptor("TRANSFORM", "transform","// "),
+ new MarkupTagDescriptor("SLASH_TRANSFORM", "/transform", "// "),
+ new MarkupTagDescriptor("SPACE", "space", "// "),
+ new MarkupTagDescriptor("SLASH_SPACE", "/space", "// "),
+ new MarkupTagDescriptor("CHARACTER_SPACE", "cspace", "// "),
+ new MarkupTagDescriptor("SLASH_CHARACTER_SPACE", "/cspace", "// "),
+ new MarkupTagDescriptor("MONOSPACE", "mspace", "// "),
+ new MarkupTagDescriptor("SLASH_MONOSPACE", "/mspace", "// "),
+ new MarkupTagDescriptor("CHARACTER_SPACING", "character-spacing", "// "),
+ new MarkupTagDescriptor("SLASH_CHARACTER_SPACING", "/character-spacing", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("ALIGN", "align", "// "),
+ new MarkupTagDescriptor("SLASH_ALIGN", "/align", "// "),
+ new MarkupTagDescriptor("WIDTH", "width", "// "),
+ new MarkupTagDescriptor("SLASH_WIDTH", "/width", "// "),
+ new MarkupTagDescriptor("MARGIN", "margin", "// "),
+ new MarkupTagDescriptor("SLASH_MARGIN", "/margin", "// "),
+ new MarkupTagDescriptor("MARGIN_LEFT", "margin-left", "// "),
+ new MarkupTagDescriptor("MARGIN_RIGHT", "margin-right", "// "),
+ new MarkupTagDescriptor("INDENT", "indent", "// "),
+ new MarkupTagDescriptor("SLASH_INDENT", "/indent", "// "),
+ new MarkupTagDescriptor("LINE_INDENT", "line-indent", "// "),
+ new MarkupTagDescriptor("SLASH_LINE_INDENT", "/line-indent", "// "),
+ new MarkupTagDescriptor("LINE_HEIGHT", "line-height", "// "),
+ new MarkupTagDescriptor("SLASH_LINE_HEIGHT", "/line-height", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("NO_BREAK", "nobr", "// "),
+ new MarkupTagDescriptor("SLASH_NO_BREAK", "/nobr", "// "),
+ new MarkupTagDescriptor("NO_PARSE", "noparse","// "),
+ new MarkupTagDescriptor("SLASH_NO_PARSE", "/noparse", "// "),
+ new MarkupTagDescriptor("PAGE", "page", "// "),
+ new MarkupTagDescriptor("SLASH_PAGE", "/page", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("ACTION", "action", "// "),
+ new MarkupTagDescriptor("SLASH_ACTION", "/action", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("CLASS", "class", "// "),
+ new MarkupTagDescriptor("TABLE", "table", "//
"),
+ new MarkupTagDescriptor("SLASH_TABLE", "/table", "//
"),
+ new MarkupTagDescriptor("TH", "th", "//
"),
+ new MarkupTagDescriptor("SLASH_TH", "/th", "//
"),
+ new MarkupTagDescriptor("TR", "tr", "//
"),
+ new MarkupTagDescriptor("SLASH_TR", "/tr", "//
"),
+ new MarkupTagDescriptor("TD", "td", "//
"),
+ new MarkupTagDescriptor("SLASH_TD", "/td", "//
"),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Text Styles"),
+ new MarkupTagDescriptor("LOWERCASE", "lowercase", "// "),
+ new MarkupTagDescriptor("SLASH_LOWERCASE", "/lowercase", "// "),
+ new MarkupTagDescriptor("ALLCAPS", "allcaps", "// "),
+ new MarkupTagDescriptor("SLASH_ALLCAPS", "/allcaps", "// "),
+ new MarkupTagDescriptor("UPPERCASE", "uppercase", "// "),
+ new MarkupTagDescriptor("SLASH_UPPERCASE", "/uppercase", "// "),
+ new MarkupTagDescriptor("SMALLCAPS", "smallcaps", "// "),
+ new MarkupTagDescriptor("SLASH_SMALLCAPS", "/smallcaps", "// "),
+ new MarkupTagDescriptor("CAPITALIZE", "capitalize", "// "),
+ new MarkupTagDescriptor("SLASH_CAPITALIZE", "/capitalize", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Font Features"),
+ new MarkupTagDescriptor("LIGA", "liga", "// "),
+ new MarkupTagDescriptor("SLASH_LIGA", "/liga", "// "),
+ new MarkupTagDescriptor("FRAC", "frac", "// "),
+ new MarkupTagDescriptor("SLASH_FRAC", "/frac", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Attributes"),
+ new MarkupTagDescriptor("NAME", "name", "// "),
+ new MarkupTagDescriptor("INDEX", "index", "// "),
+ new MarkupTagDescriptor("TINT", "tint", "// "),
+ new MarkupTagDescriptor("ANIM", "anim", "// "),
+ new MarkupTagDescriptor("HREF", "href", "// text to be displayed."),
+ new MarkupTagDescriptor("ANGLE", "angle", "// Italic Slant Angle"),
+ new MarkupTagDescriptor("FAMILY", "family", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Named Colors"),
+ new MarkupTagDescriptor("RED", "red",""),
+ new MarkupTagDescriptor("GREEN", "green", ""),
+ new MarkupTagDescriptor("BLUE", "blue", ""),
+ new MarkupTagDescriptor("WHITE", "white", ""),
+ new MarkupTagDescriptor("BLACK", "black", ""),
+ new MarkupTagDescriptor("CYAN", "cyna", ""),
+ new MarkupTagDescriptor("MAGENTA", "magenta", ""),
+ new MarkupTagDescriptor("YELLOW", "yellow", ""),
+ new MarkupTagDescriptor("ORANGE", "orange", ""),
+ new MarkupTagDescriptor("PURPLE", "purple", ""),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Unicode Characters"),
+ new MarkupTagDescriptor("BR", "br", "// Line Feed (LF) \\u0A"),
+ new MarkupTagDescriptor("ZWSP", "zwsp", "// Zero Width Space \\u200B"),
+ new MarkupTagDescriptor("NBSP", "nbsp", "// Non Breaking Space \\u00A0"),
+ new MarkupTagDescriptor("SHY", "shy", "// Soft Hyphen \\u00AD"),
+ new MarkupTagDescriptor("ZWJ", "zwj", "// Zero Width Joiner \\u200D"),
+ new MarkupTagDescriptor("WJ", "wj", "// Word Joiner \\u2060"),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Alignment"),
+ new MarkupTagDescriptor("LEFT", "left", "// "),
+ new MarkupTagDescriptor("RIGHT", "right", "// "),
+ new MarkupTagDescriptor("CENTER", "center", "// "),
+ new MarkupTagDescriptor("JUSTIFIED", "justified", "// "),
+ new MarkupTagDescriptor("FLUSH", "flush", "// "),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("// Prefix and Unit suffix"),
+ new MarkupTagDescriptor("NONE", "none", ""),
+ new MarkupTagDescriptor("PLUS", "+", ""),
+ new MarkupTagDescriptor("MINUS", "-", ""),
+ new MarkupTagDescriptor("PX", "px", ""),
+ new MarkupTagDescriptor("PLUS_PX", "+px", ""),
+ new MarkupTagDescriptor("MINUS_PX", "-px", ""),
+ new MarkupTagDescriptor("EM", "em", ""),
+ new MarkupTagDescriptor("PLUS_EM", "+em", ""),
+ new MarkupTagDescriptor("MINUS_EM", "-em", ""),
+ new MarkupTagDescriptor("PCT", "pct", ""),
+ new MarkupTagDescriptor("PLUS_PCT", "+pct", ""),
+ new MarkupTagDescriptor("MINUS_PCT", "-pct", ""),
+ new MarkupTagDescriptor("PERCENTAGE", "%", ""),
+ new MarkupTagDescriptor("PLUS_PERCENTAGE", "+%", ""),
+ new MarkupTagDescriptor("MINUS_PERCENTAGE", "-%", ""),
+ new MarkupTagDescriptor("HASH", "#", "// #"),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("TRUE", "true", ""),
+ new MarkupTagDescriptor("FALSE", "false", ""),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("INVALID", "invalid", ""),
+ MarkupTagDescriptor.linefeed,
+
+ new MarkupTagDescriptor("NORMAL", "normal", "// \n" +
@@ -101,7 +99,7 @@ public void InternalResourceCheck(string filePath, string guid)
public void TextParsing_TextInfoTest_WordWrappingDisabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
- m_TextComponent.enableWordWrapping = false;
+ m_TextComponent.textWrappingMode = TextWrappingModes.NoWrap;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
@@ -126,7 +124,7 @@ public void TextParsing_TextInfoTest_WordWrappingDisabled(int sourceTextIndex, i
public void TextParsing_TextInfoTest_WordWrappingEnabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
- m_TextComponent.enableWordWrapping = true;
+ m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
@@ -149,7 +147,7 @@ public void TextParsing_TextInfoTest_WordWrappingEnabled(int sourceTextIndex, in
public void TextParsing_TextInfoTest_TopJustifiedAlignment(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
- m_TextComponent.enableWordWrapping = true;
+ m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopJustified;
// Size the RectTransform
@@ -171,7 +169,7 @@ public void TextParsing_TextInfoTest_TopJustifiedAlignment(int sourceTextIndex,
public void TextParsing_TextInfoTest_RichText(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
- m_TextComponent.enableWordWrapping = true;
+ m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
diff --git a/Tests/Runtime/TMP_RuntimeTests.cs b/Tests/Runtime/TMP_RuntimeTests.cs
index 7b1834d..c4d2c1f 100644
--- a/Tests/Runtime/TMP_RuntimeTests.cs
+++ b/Tests/Runtime/TMP_RuntimeTests.cs
@@ -1,10 +1,9 @@
using UnityEngine;
-using UnityEngine.TestTools;
using NUnit.Framework;
using System.IO;
-using System.Collections;
using System.Collections.Generic;
+
namespace TMPro
{
[Category("Text Parsing & Layout")]
@@ -18,7 +17,7 @@ class TMP_RuntimeTests
// Characters: 104 Spaces: 14 Words: 15 Lines:
private const string m_TextBlock_01 = "Unity 2017 introduces new features that help teams of artists and developers build experiences together.";
- // Characters: 1500 Spaces: 228 Words: 241
+ // Characters: 1500 Spaces: 228 Words: 241
private const string m_TextBlock_02 = "The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words." +
"Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages." +
"The new common language will be more simple and regular than the existing European languages.It will be as simple as Occidental; in fact, it will be Occidental.To an English person, it will seem like simplified English, as a skeptical Cambridge friend of mine told me what Occidental is. The European languages are members of the same family." +
@@ -41,7 +40,7 @@ class TMP_RuntimeTests
"Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent congue erat at massa.Sed cursus turpis vitae tortor.Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci.Phasellus consectetuer vestibulum elit.Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.Vestibulum fringilla pede sit amet augue." +
"In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis.Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus.Ut varius tincidunt libero.Phasellus dolor.Maecenas vestibulum mollis";
- //
+ //
private const string m_TextBlock_05 = "This block of text contains bold and italicized characters.";
private const string m_TextBlock_06 = "\n" +
@@ -87,7 +86,7 @@ public static IEnumerable