mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-14 09:19:25 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
235 lines
6.7 KiB
C#
235 lines
6.7 KiB
C#
// RichTextKit
|
|
// Copyright © 2019-2020 Topten Software. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this product except in compliance with the License. You may obtain
|
|
// a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Topten.RichTextKit.Utils;
|
|
|
|
namespace Topten.RichTextKit
|
|
{
|
|
/// <summary>
|
|
/// Represents a unicode string and all associated attributes
|
|
/// for each character required for the Bidi algorithm
|
|
/// </summary>
|
|
class BidiData
|
|
{
|
|
/// <summary>
|
|
/// Construct a new empty BidiData
|
|
/// </summary>
|
|
public BidiData()
|
|
{
|
|
_types = new Buffer<Directionality>();
|
|
_pairedBracketTypes = new Buffer<PairedBracketType>();
|
|
_pairedBracketValues = new Buffer<int>();
|
|
}
|
|
|
|
List<int> _paragraphPositions = new List<int>();
|
|
|
|
sbyte _paragraphEmbeddingLevel;
|
|
public sbyte ParagraphEmbeddingLevel => _paragraphEmbeddingLevel;
|
|
|
|
bool _hasBrackets;
|
|
public bool HasBrackets => _hasBrackets;
|
|
|
|
bool _hasEmbeddings;
|
|
public bool HasEmbeddings => _hasEmbeddings;
|
|
|
|
bool _hasIsolates;
|
|
public bool HasIsolates => _hasIsolates;
|
|
|
|
/// <summary>
|
|
/// Initialize with an array of Unicode code points
|
|
/// </summary>
|
|
/// <param name="codePoints">The unicode code points to be processed</param>
|
|
/// <param name="paragraphEmbeddingLevel">The paragraph embedding level</param>
|
|
public void Init( Slice<int> codePoints, sbyte paragraphEmbeddingLevel )
|
|
{
|
|
// Set working buffer sizes
|
|
_types.Length = codePoints.Length;
|
|
_pairedBracketTypes.Length = codePoints.Length;
|
|
_pairedBracketValues.Length = codePoints.Length;
|
|
|
|
_paragraphPositions.Clear();
|
|
_paragraphEmbeddingLevel = paragraphEmbeddingLevel;
|
|
|
|
// Resolve the directionality, paired bracket type and paired bracket values for
|
|
// all code points
|
|
_hasBrackets = false;
|
|
_hasEmbeddings = false;
|
|
_hasIsolates = false;
|
|
for ( int i = 0; i < codePoints.Length; i++ )
|
|
{
|
|
var bidiData = UnicodeClasses.BidiData( codePoints[i] );
|
|
|
|
// Look up directionality
|
|
var dir = (Directionality)(bidiData >> 24);
|
|
_types[i] = dir;
|
|
|
|
switch ( dir )
|
|
{
|
|
case Directionality.LRE:
|
|
case Directionality.LRO:
|
|
case Directionality.RLE:
|
|
case Directionality.RLO:
|
|
case Directionality.PDF:
|
|
_hasEmbeddings = true;
|
|
break;
|
|
|
|
case Directionality.LRI:
|
|
case Directionality.RLI:
|
|
case Directionality.FSI:
|
|
case Directionality.PDI:
|
|
_hasIsolates = true;
|
|
break;
|
|
}
|
|
|
|
// Lookup paired bracket types
|
|
var pbt = (PairedBracketType)((bidiData >> 16) & 0xFF);
|
|
_pairedBracketTypes[i] = pbt;
|
|
switch ( pbt )
|
|
{
|
|
case PairedBracketType.o:
|
|
_pairedBracketValues[i] = MapCanon( (int)(bidiData & 0xFFFF) );
|
|
_hasBrackets = true;
|
|
break;
|
|
|
|
case PairedBracketType.c:
|
|
_pairedBracketValues[i] = MapCanon( codePoints[i] );
|
|
_hasBrackets = true;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
if (_types[i] == RichTextKit.Directionality.B)
|
|
{
|
|
_types[i] = (Directionality)Directionality.WS;
|
|
_paragraphPositions.Add(i);
|
|
}
|
|
*/
|
|
}
|
|
|
|
// Create slices on work buffers
|
|
Types = _types.AsSlice();
|
|
PairedBracketTypes = _pairedBracketTypes.AsSlice();
|
|
PairedBracketValues = _pairedBracketValues.AsSlice();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Map bracket types 0x3008 and 0x3009 to their canonical equivalents
|
|
/// </summary>
|
|
/// <param name="codePoint">The code point to be mapped</param>
|
|
/// <returns>The mapped canonical code point, or the passed code point</returns>
|
|
static int MapCanon( int codePoint )
|
|
{
|
|
if ( codePoint == 0x3008 )
|
|
return 0x2329;
|
|
if ( codePoint == 0x3009 )
|
|
return 0x232A;
|
|
else
|
|
return codePoint;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the length of the data held by the BidiData
|
|
/// </summary>
|
|
public int Length => _types.Length;
|
|
|
|
Buffer<Directionality> _types;
|
|
Buffer<PairedBracketType> _pairedBracketTypes;
|
|
Buffer<int> _pairedBracketValues;
|
|
Buffer<Directionality> _savedTypes;
|
|
Buffer<PairedBracketType> _savedPairedBracketTypes;
|
|
|
|
/// <summary>
|
|
/// Save the Types and PairedBracketTypes of this bididata
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This is used when processing embedded style runs with
|
|
/// directionality overrides. TextBlock saves the data,
|
|
/// overrides the style runs to neutral, processes the bidi
|
|
/// data for the entire paragraph and then restores this data
|
|
/// before processing the embedded runs.
|
|
/// </remarks>
|
|
public void SaveTypes()
|
|
{
|
|
// Make sure we have a buffer
|
|
if ( _savedTypes == null )
|
|
{
|
|
_savedTypes = new Buffer<Directionality>();
|
|
_savedPairedBracketTypes = new Buffer<PairedBracketType>();
|
|
}
|
|
|
|
// Capture the types data
|
|
_savedTypes.Clear();
|
|
_savedTypes.Add( _types.AsSlice() );
|
|
_savedPairedBracketTypes.Clear();
|
|
_savedPairedBracketTypes.Add( _pairedBracketTypes.AsSlice() );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restore the data saved by SaveTypes
|
|
/// </summary>
|
|
public void RestoreTypes()
|
|
{
|
|
_types.Clear();
|
|
_types.Add( _savedTypes.AsSlice() );
|
|
_pairedBracketTypes.Clear();
|
|
_pairedBracketTypes.Add( _savedPairedBracketTypes.AsSlice() );
|
|
}
|
|
|
|
/// <summary>
|
|
/// The directionality of each code point
|
|
/// </summary>
|
|
public Slice<Directionality> Types;
|
|
|
|
/// <summary>
|
|
/// The paired bracket type for each code point
|
|
/// </summary>
|
|
public Slice<PairedBracketType> PairedBracketTypes;
|
|
|
|
/// <summary>
|
|
/// The paired bracket value for code code point
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The paired bracket values are the code points
|
|
/// of each character where the opening code point
|
|
/// is replaced with the closing code point for easier
|
|
/// matching. Also, bracket code points are mapped
|
|
/// to their canonical equivalents
|
|
/// </remarks>
|
|
public Slice<int> PairedBracketValues;
|
|
|
|
public Buffer<sbyte> _tempLevelBuffer;
|
|
|
|
/// <summary>
|
|
/// Gets a temporary level buffer. Used by TextBlock when
|
|
/// resolving style runs with different directionality.
|
|
/// </summary>
|
|
/// <param name="length">Length of the required buffer</param>
|
|
/// <returns>An uninitialized level buffer</returns>
|
|
public Slice<sbyte> GetTempLevelBuffer( int length )
|
|
{
|
|
if ( _tempLevelBuffer == null )
|
|
_tempLevelBuffer = new Buffer<sbyte>();
|
|
|
|
_tempLevelBuffer.Clear();
|
|
return _tempLevelBuffer.Add( length, false );
|
|
}
|
|
}
|
|
}
|