示例#1
0
文件: Form1.cs 项目: ywscr/Typography
        static bool CheckIfNotOverlap(UnicodeRangeInfo test, List <UnicodeRangeInfo> others, int exceptIndex, int exceptIndex2 = -1)
        {
            int count = others.Count;

            for (int i = 0; i < count; ++i)
            {
                if (i == exceptIndex)
                {
                    continue;
                }
                if (exceptIndex2 > -1 && i == exceptIndex2)
                {
                    continue;
                }

                UnicodeRangeInfo rng = others[i];
                int b_begin          = rng.StartCodePoint;
                int b_end            = rng.EndCodePoint;

                if ((test.StartCodePoint >= b_begin && test.StartCodePoint <= b_end) ||
                    (test.EndCodePoint >= b_begin && test.EndCodePoint <= b_begin))
                {
                    //overlap found
                    return(false);
                }
            }
            return(true);
        }
示例#2
0
        static IEnumerable <ushort> GetGlyphIndexIter(Typeface typeface, params UnicodeLangBits[] rangeBits)
        {
            //temp fixed
            GlyphIndexCollector collector = new GlyphIndexCollector();
            int j = rangeBits.Length;

            for (int i = 0; i < j; ++i)
            {
                UnicodeRangeInfo rangeInfo = rangeBits[i].ToUnicodeRangeInfo();
                //get start and end bit
                int startChar       = rangeInfo.StartAt;
                int startGlyphIndex = typeface.LookupIndex((char)startChar);
                while (startGlyphIndex < 1)
                {
                    startChar++;
                    startGlyphIndex = typeface.LookupIndex((char)startChar);
                }
                for (int gindex = startGlyphIndex; gindex < startGlyphIndex + 125; ++gindex)
                {
                    yield return((ushort)gindex);
                }
                //char endAt = (char)rangeInfo.EndAt;
                //for (char c = (char)rangeInfo.StartAt; c <= endAt; ++c)
                //{
                //    typeface.CollectGlyphIndexListFromSampleChar(c, collector);
                //}
            }
        }
示例#3
0
 internal SpanBreakInfo(UnicodeRangeInfo unicodeRange, bool isRightToLeft, uint scriptTag, uint langTag = 0)
 {
     UnicodeRange = unicodeRange; //can be null
     RightToLeft  = isRightToLeft;
     ScriptTag    = scriptTag;
     LangTag      = 0;
 }
示例#4
0
 public static bool GetUniCodeRangeFor(int c1, out UnicodeRangeInfo unicodeRangeInfo, out SpanBreakInfo spanBreakInfo)
 {
     if (Unicode13RangeInfoList.TryGetUnicodeRangeInfo(c1, out unicodeRangeInfo) &&
         s_registerSpanBreakInfo.TryGetValue(unicodeRangeInfo, out spanBreakInfo))
     {
         return(true);
     }
     //we may found unicodeRange info
     //but may not found register spanbreak info
     spanBreakInfo = null;
     return(false);
 }
示例#5
0
        public static bool TryGetUnicodeRangeInfo(int sampleCodepoint, out UnicodeRangeInfo found)
        {
            int foundAt = Array.BinarySearch(s_beginAt_list, sampleCodepoint);

            foundAt = foundAt < 0 ? ~foundAt - 1 : foundAt;

            found = s_list[foundAt];

            if (sampleCodepoint <= found.EndCodepoint)
            {
                return(true);
            }
            found = null;
            return(false);
        }
        public static void CollectAllAssociateGlyphIndex(this Typeface typeface, List <ushort> outputGlyphIndexList, ScriptLang scLang, UnicodeLangBits[] selectedRangs = null)
        {
            //-----------
            //general glyph index in the unicode range

            //if user dose not specific the unicode lanf bit ranges
            //the we try to select it ourself.
            UnicodeLangBits[] unicodeLangBitsRanges;
            if (ScriptLangs.TryGenUnicodeLangBitsArray(scLang.shortname, out unicodeLangBitsRanges))
            {
                //one lang may contains may ranges
                if (selectedRangs != null)
                {
                    //select only in range
                    unicodeLangBitsRanges = FilterOnlySelectedRange(unicodeLangBitsRanges, selectedRangs);
                }

                foreach (UnicodeLangBits unicodeLangBits in unicodeLangBitsRanges)
                {
                    UnicodeRangeInfo rngInfo = unicodeLangBits.ToUnicodeRangeInfo();
                    int endAt = rngInfo.EndAt;
                    for (int codePoint = rngInfo.StartAt; codePoint <= endAt; ++codePoint)
                    {
                        ushort glyghIndex = typeface.LookupIndex(codePoint);
                        if (glyghIndex > 0)
                        {
                            //add this glyph index
                            outputGlyphIndexList.Add(glyghIndex);
                        }
                    }
                }
            }

            //-----------
            if (typeface.GSUBTable != null)
            {
                var gsub = new GlyphSubstitution(typeface, scLang.shortname);
                gsub.CollectAdditionalSubstitutionGlyphIndices(outputGlyphIndexList);
            }
        }
示例#7
0
文件: Form1.cs 项目: ywscr/Typography
        void LoadUnicode13Ranges()
        {
            //https://www.unicode.org/versions/Unicode13.0.0/UnicodeStandard-13.0.pdf
            //generate unicode ranges
            string[] allLines = File.ReadAllLines("unicode13_ranges.txt");
            //skip 1st line
            _unicode13Ranges = new List <UnicodeRangeInfo>();
            _unicode13Dic    = new Dictionary <string, UnicodeRangeInfo>();
            for (int i = 1; i < allLines.Length; ++i)
            {
                string line = allLines[i].Trim();

                if (line.Length == 0 || line.StartsWith("#"))
                {
                    continue;
                }                                                          //skip blank line or comment line
                                                                           //

                string[] fields = line.Split(',');
                if (fields.Length != 3)
                {
                    throw new NotSupportedException();
                }
                var rangeInfo = new UnicodeRangeInfo
                {
                    RangeName      = fields[0].Trim(),
                    StartCodePoint = int.Parse(fields[1].Trim(), System.Globalization.NumberStyles.HexNumber),
                    EndCodePoint   = int.Parse(fields[2].Trim(), System.Globalization.NumberStyles.HexNumber)
                };
                _unicode13Ranges.Add(rangeInfo);
                _unicode13Dic.Add(rangeInfo.RangeName, rangeInfo);
            }

            //----------------------
            //from https://www.unicode.org/faq/blocks_ranges.html
            //Q: Can blocks overlap?
            //A: No.Every Unicode block is discrete, and cannot overlap with any other block.
            //Also, every assigned character in the Unicode Standard has to be in a block(and only one block, of course).
            //This ensures that when code charts are printed, no characters are omitted simply because they aren't in a block
            //----------------------

            //***ensure no overlap unicode range***
            int count = _unicode13Ranges.Count;

            for (int i = 0; i < count; ++i)
            {
                if (!CheckIfNotOverlap(_unicode13Ranges[i], _unicode13Ranges, i))
                {
                    //found overlap!
                    throw new NotSupportedException("unicode overlap found!");
                }
            }
            {
                //ensure that code points are arranged ascending
                int latest_codepoint = -1;
                for (int i = 0; i < count; ++i)
                {
                    int cp = _unicode13Ranges[i].StartCodePoint;
                    if (latest_codepoint > cp)
                    {
                        throw new NotSupportedException();
                    }
                    latest_codepoint = cp;
                }
            }

            //----------------------
            //example 1
            //since the range is not overlap each other
            //we can simply search it with binary search
            {
                int[] beginAt_list = new int[count];
                for (int i = 0; i < count; ++i)
                {
                    beginAt_list[i] = _unicode13Ranges[i].StartCodePoint;
                }


                //test
                int test_char = '+';
                int foundAt   = Array.BinarySearch(beginAt_list, test_char);
                foundAt = foundAt < 0 ? ~foundAt - 1 : foundAt;

                UnicodeRangeInfo rangeInfo = _unicode13Ranges[foundAt];
            }
            //----------------------

            {
                //generate code
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < count; ++i)
                {
                    UnicodeRangeInfo rng = _unicode13Ranges[i];

                    sb.AppendLine(GetProperFieldName(rng.RangeName) + $"=_(\"{ rng.RangeName }\",0x{rng.StartCodePoint.ToString("X4")}/*{rng.StartCodePoint}*/,0x{rng.EndCodePoint.ToString("X4")}/*{rng.StartCodePoint}*/),");
                }
                sb.AppendLine();
                sb.AppendLine();

                for (int i = 0; i < count; ++i)
                {
                    UnicodeRangeInfo rng = _unicode13Ranges[i];
                    sb.AppendLine(GetProperFieldName(rng.RangeName) + ",");
                }
            }
        }
        public override SelectedTypeface Select(List <InstalledTypeface> choices, UnicodeRangeInfo unicodeRangeInfo, int hintCodePoint)
        {
            //request font may have hint for typeface
            if (_reqFont != null)
            {
                for (int i = 0; i < _reqFont.OtherChoicesCount; ++i)
                {
                    RequestFont.Choice choice       = _reqFont.GetOtherChoice(i);
                    ResolvedFont       resolvedFont = _textService.ResolveFont(choice);
                    //check if resolvedFont support specific unicodeRange info or not
                    Typeface typeface  = resolvedFont.Typeface;
                    ushort   codepoint = typeface.GetGlyphIndex(unicodeRangeInfo.StartCodepoint);
                    if (codepoint > 0)
                    {
                        //use this
                        return(new SelectedTypeface(typeface));
                    }
                }
            }

            List <PreferredTypeface> list = null;

            if (unicodeRangeInfo == Unicode13RangeInfoList.Emoticons)
            {
                list = _emojiPreferList;
            }
            else if (_dics.TryGetValue(unicodeRangeInfo.Name, out PreferredTypefaceList foundList))
            {
                list = foundList;
            }

            if (list != null)
            {
                int j = list.Count;
                for (int i = 0; i < j; ++i)
                {
                    //select that first one
                    PreferredTypeface p = list[i];

                    if (p.InstalledTypeface == null && !p.ResolvedInstalledTypeface)
                    {
                        //find
                        int choice_count = choices.Count;

                        for (int m = 0; m < choice_count; ++m)
                        {
                            InstalledTypeface instTypeface = choices[m];
                            if (p.RequestTypefaceName == instTypeface.FontName)
                            {
                                //TODO: review here again
                                p.InstalledTypeface = instTypeface;

                                break;
                            }
                        }
                        p.ResolvedInstalledTypeface = true;
                    }
                    //-------
                    if (p.InstalledTypeface != null)
                    {
                        return(new SelectedTypeface(p.InstalledTypeface));
                    }
                }
            }

            //still not found
            if (choices.Count > 0)
            {
                //choose default
                return(new SelectedTypeface(choices[0]));
            }


            return(new SelectedTypeface());//empty
        }
 public void SetPreferredTypefaces(UnicodeRangeInfo unicodeRangeInfo, PreferredTypefaceList typefaceNames)
 {
     _dics[unicodeRangeInfo.Name] = typefaceNames;
 }
示例#10
0
 public abstract SelectedTypeface Select(List <InstalledTypeface> choices, UnicodeRangeInfo unicodeRangeInfo, int codepoint);
示例#11
0
 static void RegisterSpanBreakInfo(UnicodeRangeInfo unicodeRangeInfo, uint scriptTag, bool rightToLeft = false)
 {
     s_registerSpanBreakInfo.Add(unicodeRangeInfo, new SpanBreakInfo(unicodeRangeInfo, rightToLeft, scriptTag));
 }