コード例 #1
0
        List<string> NativeFontFamilies()
        {
            if (nativeFontCollection == null)
            {
                var collectionOptions = new CTFontCollectionOptions ();
                collectionOptions.RemoveDuplicates = true;
                nativeFontCollection = new CTFontCollection (collectionOptions);
                nativeFontDescriptors = new Dictionary<string, CTFontDescriptor> ();
            }

            var fontdescs = nativeFontCollection.GetMatchingFontDescriptors ();

            foreach (var fontdesc in fontdescs)
            {
                var font = new CTFont (fontdesc, 0);

                // Just in case RemoveDuplicates collection option is not working
                if (!nativeFontDescriptors.ContainsKey (font.FamilyName))
                {
                    nativeFontDescriptors.Add (font.FamilyName, fontdesc);
                }

            }
            var fontFamilies = new List<string> (nativeFontDescriptors.Keys);

            return fontFamilies;
        }
コード例 #2
0
        private CTFont FindMatchingFont(CTFont reference, CTFontSymbolicTraits trait)
        {
            CTFontSymbolicTraits symbolic;
            CTFontTraits traits = reference.GetTraits ();
            if (traits.SymbolicTraits.HasValue)
                symbolic = traits.SymbolicTraits.Value | trait;
            else
                symbolic = trait;

            CTFont newFont = reference.WithSymbolicTraits (reference.Size, symbolic, symbolic);
            if (newFont != null)
                return newFont;
            else
                return reference;
        }
コード例 #3
0
        private void CreateNativeFont(FontFamily familyName, float emSize, FontStyle style,
			GraphicsUnit unit, byte gdiCharSet, bool  gdiVerticalFont )
        {
            // convert to 96 Dpi to be consistent with Windows
            var dpiSize = emSize * dpiScale;

            try
            {
                nativeFont = new CTFont(familyName.NativeDescriptor,dpiSize);
            }
            catch
            {
                nativeFont = new CTFont("Helvetica",dpiSize);
            }

            CTFontSymbolicTraits tMask = CTFontSymbolicTraits.None;

            if ((style & FontStyle.Bold) == FontStyle.Bold)
                tMask |= CTFontSymbolicTraits.Bold;
            if ((style & FontStyle.Italic) == FontStyle.Italic)
                tMask |= CTFontSymbolicTraits.Italic;
            strikeThrough = (style & FontStyle.Strikeout) == FontStyle.Strikeout;
            underLine = (style & FontStyle.Underline) == FontStyle.Underline;

            var nativeFont2 = nativeFont.WithSymbolicTraits(dpiSize,tMask,tMask);

            if (nativeFont2 != null)
                nativeFont = nativeFont2;

            bold = (nativeFont.SymbolicTraits & CTFontSymbolicTraits.Bold) == CTFontSymbolicTraits.Bold;
            italic = (nativeFont.SymbolicTraits & CTFontSymbolicTraits.Italic) == CTFontSymbolicTraits.Italic;
            sizeInPoints = emSize;
            this.unit = unit;

            // FIXME
            // I do not like the hard coded 72 but am just trying to boot strap the Font class right now
            size = ConversionHelpers.GraphicsUnitConversion(GraphicsUnit.Point, unit, 72.0f, sizeInPoints);
        }
コード例 #4
0
 private CTFont Italicized(CTFont reference)
 {
     return FindMatchingFont (reference, CTFontSymbolicTraits.Italic);
 }
コード例 #5
0
 private CTFont Bolded(CTFont reference)
 {
     return FindMatchingFont (reference, CTFontSymbolicTraits.Bold);
 }
コード例 #6
0
		// Listing 2-12:
		static CTFont CreateBoldFont (CTFont font, bool makeBold)
		{
			var desiredTrait = CTFontSymbolicTraits.None;
			if (makeBold)
				desiredTrait = CTFontSymbolicTraits.Bold;

			// Mask off the bold trait to indicate that it is the only trait
			// desired to be modified.  As CTFontSymbolicTraits is a bit field,
			// we could chooose to change multiple traits if desired.
			var traitMask = CTFontSymbolicTraits.Bold;

			// Create a copy of the original font with the masked trait set to the
			// desired value.  If the font family does not have the appropriate style,
			// This will return null.
			return font.WithSymbolicTraits (0.0f, desiredTrait, traitMask);
		}
コード例 #7
0
		// Listing 2-9: TODO

		// Listing 2-10:
		static float GetLineHeightForFont (CTFont font)
		{
			return font.AscentMetric + font.DescentMetric + font.LeadingMetric;
		}
コード例 #8
0
        void LoadFontAndGatherGlyphInfos(int unitSize, Action<List<GlyphInfo>> endHandler)
        {
            float scale = UIScreen.MainScreen.Scale;
            Task.Factory.StartNew (() => {
                Type typGlyphNames = typeof (FontAwesome.GlyphNames);
                var memberinfos = typGlyphNames.GetMembers (BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty);

                var ctFont = new CTFont (FontAwesomeUtil.Font, 20f, CGAffineTransform.MakeIdentity ());

                var list = memberinfos.Select ((m) => {
                    var fieldInfo = typGlyphNames.GetField (m.Name);
                    var rawName = (string)fieldInfo.GetValue (typGlyphNames);
                    var glyphval = ctFont.GetGlyphWithName (rawName);
                    return new GlyphInfo {
                                GlyphName = m.Name
                                , RawName = rawName
                                , GlyphImage = FontAwesomeUtil.GetImageForBarItem (rawName, unitSize, scale)
                                , GlyphId = glyphval
                    };
                }).ToList ();

                if (endHandler != null)
                    endHandler (list);
            });
        }
コード例 #9
0
 internal static CCSize MeasureString(string textg, CTFont font)
 {
     return(MeasureString(textg, font, CCSize.Zero));
 }
コード例 #10
0
        /// <summary>
        /// Draws text along a given line.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="color"></param>
        /// <param name="size"></param>
        /// <param name="text">Text.</param>
        protected override void DrawLineText(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, string text, int color,
                                             double size, int?haloColor, int?haloRadius, string fontName)
        {
            double[] transformed = this.Tranform(x[0], y[0]);
            float    xPixels     = (float)transformed[0];
            float    yPixels     = (float)transformed[1];
            float    textSize    = this.ToPixels(size);

            // set the fill color as the regular text-color.
            SimpleColor simpleColor = SimpleColor.FromArgb(color);

            target.Target.CGContext.InterpolationQuality = CGInterpolationQuality.High;
            target.Target.CGContext.SetAllowsFontSubpixelQuantization(true);
            target.Target.CGContext.SetAllowsFontSmoothing(true);
            target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f,
                                                 simpleColor.A / 256.0f);
            if (haloColor.HasValue)               // set the stroke color as the halo color.
            {
                SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value);
                target.Target.CGContext.SetStrokeColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f,
                                                       haloSimpleColor.A / 256.0f);
            }
            if (haloRadius.HasValue)               // set the halo radius as line width.
            {
                target.Target.CGContext.SetLineWidth(haloRadius.Value);
            }

            // get the glyhps/paths from the font.
            if (string.IsNullOrWhiteSpace(fontName))
            {
                fontName = "Arial";
            }
            CTFont             font             = new CTFont(fontName, textSize);
            CTStringAttributes stringAttributes = new CTStringAttributes {
                ForegroundColorFromContext = true,
                Font = font
            };
            NSAttributedString attributedString = new NSAttributedString(text, stringAttributes);
            CTLine             line             = new CTLine(attributedString);
            RectangleF         textBounds       = line.GetBounds(CTLineBoundsOptions.UseOpticalBounds);

            CTRun[] runs       = line.GetGlyphRuns();
            var     lineLength = Polyline2D.Length(x, y);

            // set the correct tranformations to draw the resulting paths.
            target.Target.CGContext.SaveState();
            //target.Target.CGContext.TranslateCTM (xPixels, yPixels);
            //target.Target.CGContext.ConcatCTM (new CGAffineTransform (1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));
            foreach (CTRun run in runs)
            {
                ushort[] glyphs          = run.GetGlyphs();
                PointF[] positions       = run.GetPositions();
                float[]  characterWidths = new float[glyphs.Length];
                float    previous        = 0;
                float    textLength      = (float)this.FromPixels(_target, _view, positions [positions.Length - 1].X);
                if (lineLength > textLength * 1.2f)
                {
                    for (int idx = 0; idx < characterWidths.Length - 1; idx++)
                    {
                        characterWidths [idx] = (float)this.FromPixels(_target, _view, positions [idx + 1].X - previous);
                        previous = positions [idx + 1].X;
                    }
                    characterWidths [characterWidths.Length - 1] = characterWidths[characterWidths.Length - 2];
                    float characterHeight = textBounds.Height;

                    this.DrawLineTextSegment(target, x, y, glyphs, color, haloColor, haloRadius,
                                             lineLength / 2f, characterWidths, textLength, characterHeight, font);
                }
            }

            target.Target.CGContext.RestoreState();
        }
コード例 #11
0
        private CTFont GetFontFromCache(string key, string name, float size)
        {
            CTFont font;

            lock (_fontCache)
            {
                if (!_fontCache.TryGetValue(key, out font))
                {
                    /*if (name != null && MTFontRegistry.Instance.IsCustomFont(name))
                     * {
                     *  var coreGraphicsFont = MTFontRegistry.Instance.GetCustomFont(name);
                     *  if (coreGraphicsFont != null)
                     *  {
                     *      font = new CTFont(coreGraphicsFont, size, CGAffineTransform.MakeIdentity());
                     *  }
                     * }
                     * else
                     * {*/
                    var fontStyle = GetFontStyleById(name);
                    if (fontStyle == null)
                    {
                        if (_systemFontName.Equals(name))
                        {
                            if (name.StartsWith(".", StringComparison.InvariantCultureIgnoreCase))
                            {
                                var cgfont = _systemFont ?? (_systemFont = CGFont.CreateWithFontName(name));
                                font = new CTFont(cgfont, size, CGAffineTransform.MakeIdentity());
                            }
                            else
                            {
                                font = new CTFont(name, size);
                            }
                        }
                        else if (_boldSystemFontName.Equals(name))
                        {
                            if (name.StartsWith(".", StringComparison.InvariantCultureIgnoreCase))
                            {
                                var cgfont = _boldSystemFont ?? (_boldSystemFont = CGFont.CreateWithFontName(name));
                                font = new CTFont(cgfont, size, CGAffineTransform.MakeIdentity());
                            }
                            else
                            {
                                font = new CTFont(name, size);
                            }
                        }
                        else
                        {
                            fontStyle = GetDefaultFontStyle();
                        }
                    }

                    if (font == null)
                    {
                        font = new CTFont(fontStyle.Id, size);
                    }
                    //}

                    if (font == null)
                    {
                        return(LoadFont("ArialMT", size));
                    }

                    _fontCache[key] = font;
                }
            }

            return(font);
        }
コード例 #12
0
ファイル: IOSFont.cs プロジェクト: saizant/MonoAGS
 public IOSFont(CTFont font, FontStyle style)
 {
     InnerFont = font;
     _style    = style;
 }
コード例 #13
0
ファイル: IOSFont.cs プロジェクト: saizant/MonoAGS
 public TextMeasureKey(string text, CTFont font, int maxWidth)
 {
     Text     = text;
     Font     = font;
     MaxWidth = maxWidth;
 }
コード例 #14
0
        void LoadFontFile(string fileName)
        {
            CTFont nativeFont;
            var    dpiSize = 0;
            var    ext     = Path.GetExtension(fileName);

            if (!String.IsNullOrEmpty(ext))
            {
                if (nativeFontDescriptors == null)
                {
                    nativeFontDescriptors = new Dictionary <string, CTFontDescriptor> ();
                }

                //Try loading from Bundle first
                var fontName        = fileName.Substring(0, fileName.Length - ext.Length);
                var pathForResource = NSBundle.MainBundle.PathForResource(fontName, ext.Substring(1));

                NSUrl url;

                if (!string.IsNullOrEmpty(pathForResource))
                {
                    url = NSUrl.FromFilename(pathForResource);
                }
                else
                {
                    url = NSUrl.FromFilename(fileName);
                }

                // We will not use CTFontManager.RegisterFontsForUrl (url, CTFontManagerScope.Process);
                // here.  The reason is that there is no way we can be sure that the font can be created to
                // to identify the family name afterwards.  So instead we will create a CGFont from a data provider.
                // create CTFont to obtain the CTFontDescriptor, store family name and font descriptor to be accessed
                // later.
                try {
                    var dataProvider = new CGDataProvider(url.Path);
                    var cgFont       = CGFont.CreateFromProvider(dataProvider);

                    try {
                        nativeFont = new CTFont(cgFont, dpiSize, null);
                        if (!nativeFontDescriptors.ContainsKey(nativeFont.FamilyName))
                        {
                            nativeFontDescriptors.Add(nativeFont.FamilyName, nativeFont.GetFontDescriptor());
                            NSError error;
                            var     registered = CTFontManager.RegisterGraphicsFont(cgFont, out error);
                            if (!registered)
                            {
                                // If the error code is 105 then the font we are trying to register is already registered
                                // We will not report this as an error.
                                if (error.Code != 105)
                                {
                                    throw new ArgumentException("Error registering: " + Path.GetFileName(fileName));
                                }
                            }
                        }
                    }
                    catch
                    {
                        // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                        throw new System.IO.FileNotFoundException(fileName);
                    }
                }
                catch (Exception)
                {
                    // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                    throw new System.IO.FileNotFoundException(fileName);
                }
            }
        }
コード例 #15
0
        private static void AddAttributes(
            NSMutableAttributedString attributedString,
            Text.ITextAttributes attributes,
            int start,
            int length,
            string contextFontName  = null,
            float contextFontSize   = 12f,
            string contextFontColor = null,
            bool coreTextCompatible = false)
        {
            var ctattributes = new CTStringAttributes();

            CTFont font;
            var    fontName = attributes.GetFontName() ?? contextFontName;
            var    fontSize = attributes.GetFontSize(contextFontSize);

            if (fontName != null)
            {
                font = new CTFont(fontName, fontSize);
            }
            else
            {
                /* todo: submit bug to Xamarin as null should be a valid argument to the language */
                font = new CTFont(CTFontUIFontType.System, fontSize, NSLocale.CurrentLocale.Identifier);
            }

            if (attributes.GetBold() && attributes.GetItalic())
            {
                font = font.WithSymbolicTraits(
                    fontSize,
                    CTFontSymbolicTraits.Bold | CTFontSymbolicTraits.Italic,
                    CTFontSymbolicTraits.Bold | CTFontSymbolicTraits.Italic);
            }
            else if (attributes.GetBold())
            {
                font = font.WithSymbolicTraits(fontSize, CTFontSymbolicTraits.Bold, CTFontSymbolicTraits.Bold);
            }
            else if (attributes.GetItalic())
            {
                font = font.WithSymbolicTraits(fontSize, CTFontSymbolicTraits.Italic, CTFontSymbolicTraits.Italic);
            }

            ctattributes.Font = font;

            if (attributes.GetUnderline())
            {
                ctattributes.UnderlineStyle = CTUnderlineStyle.Single;
            }

            var foreground = attributes.GetForegroundColor();

            if (foreground != null)
            {
                ctattributes.ForegroundColor = foreground.Parse().ToCGColor();
            }
            else
            {
                if (contextFontColor != null)
                {
                    ctattributes.ForegroundColor = contextFontColor.Parse().ToCGColor();
                }
                else
                {
                    ctattributes.ForegroundColorFromContext = true;
                }
            }

            var background = attributes.GetBackgroundColor();

            if (background != null)
            {
                ctattributes.BackgroundColor = background.Parse().ToCGColor();
            }

            attributedString.AddAttributes(ctattributes, new NSRange(start, length));

            NSMutableDictionary dictionary = null;

#if MONOMAC
#if DEBUG
            var previousCheckStatus = NSApplication.CheckForIllegalCrossThreadCalls;
            NSApplication.CheckForIllegalCrossThreadCalls = false;
#endif

            if (attributes.GetUnorderedList())
            {
                var paragraphStyle = new NSMutableParagraphStyle();

                var textLists = new NSTextList[1];

                var marker = "{disc}";

                switch (attributes.GetMarker())
                {
                case MarkerType.Hyphen:
                    marker = "{hyphen}";
                    break;

                case MarkerType.OpenCircle:
                    marker = "{circle}";
                    break;
                }

                textLists [0] = new NSTextList(marker, NSTextListOptions.PrependEnclosingMarker);
                paragraphStyle.SetTextLists(textLists);

                if (dictionary == null)
                {
                    dictionary = new NSMutableDictionary();
                }
                dictionary.Add(NSStringAttributeKey.ParagraphStyle, paragraphStyle);
            }

#if DEBUG
            NSApplication.CheckForIllegalCrossThreadCalls = previousCheckStatus;
#endif
#endif

#if MONOMAC
            if (!coreTextCompatible)
            {
                if (attributes.GetSuperscript())
                {
                    if (dictionary == null)
                    {
                        dictionary = new NSMutableDictionary();
                    }
                    dictionary.Add(NSStringAttributeKey.Superscript, NSNumber.FromInt32(1));
                }

                if (attributes.GetSubscript())
                {
                    if (dictionary == null)
                    {
                        dictionary = new NSMutableDictionary();
                    }
                    dictionary.Add(NSStringAttributeKey.Superscript, NSNumber.FromInt32(-1));
                }
            }
            else
            {
#endif
            if (attributes.GetSuperscript())
            {
                if (dictionary == null)
                {
                    dictionary = new NSMutableDictionary();
                }
                dictionary.Add(NSStringAttributeKey.BaselineOffset, NSNumber.FromFloat(fontSize * .5f));
            }

            if (attributes.GetSubscript())
            {
                if (dictionary == null)
                {
                    dictionary = new NSMutableDictionary();
                }
                dictionary.Add(NSStringAttributeKey.BaselineOffset, NSNumber.FromFloat(-fontSize * .2f));
            }

#if MONOMAC
        }
#endif

            if (dictionary != null)
            {
                attributedString.AddAttributes(dictionary, new NSRange(start, length));
            }
        }
コード例 #16
0
        private void DrawLineTextSegment(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, ushort[] glyphs, int color,
                                         int?haloColor, int?haloRadius, double middlePosition, float[] characterWidths,
                                         double textLength, float charachterHeight, CTFont font)
        {
            // see if text is 'upside down'
            double   averageAngle = 0;
            double   first        = middlePosition - (textLength / 2.0);
            PointF2D current      = Polyline2D.PositionAtPosition(x, y, first);

            for (int idx = 0; idx < glyphs.Length; idx++)
            {
                double   nextPosition = middlePosition - (textLength / 2.0) + ((textLength / (glyphs.Length)) * (idx + 1));
                PointF2D next         = Polyline2D.PositionAtPosition(x, y, nextPosition);

                // translate to the final position, the center of the line segment between 'current' and 'next'.
                //PointF2D position = current + ((next - current) / 2.0);

                // calculate the angle.
                VectorF2D vector       = next - current;
                VectorF2D horizontal   = new VectorF2D(1, 0);
                double    angleDegrees = ((Degree)horizontal.Angle(vector)).Value;
                averageAngle = averageAngle + angleDegrees;
                current      = next;
            }
            averageAngle = averageAngle / glyphs.Length;


            // revers if 'upside down'
            double[] xText = x;
            double[] yText = y;
            if (averageAngle > 90 && averageAngle < 180 + 90)
            {
                xText = x.Reverse().ToArray();
                yText = y.Reverse().ToArray();
            }

            first   = middlePosition - (textLength / 2.0);
            current = Polyline2D.PositionAtPosition(xText, yText, first);

            //target.Target.CGContext.SaveState ();
            //target.Target.CGContext.TranslateCTM (xText[0], yText[0]);

            double nextPosition2 = first;

            for (int idx = 0; idx < glyphs.Length; idx++)
            {
                nextPosition2 = nextPosition2 + characterWidths [idx];
                PointF2D next = Polyline2D.PositionAtPosition(xText, yText, nextPosition2);
                //ushort currentChar = glyphs [idx];

                PointF2D position = current;

                target.Target.CGContext.SaveState();

                // translate to the final position, the center of the line segment between 'current' and 'next'.
                double[] transformed = this.Tranform(position[0], position[1]);
                target.Target.CGContext.TranslateCTM(
                    (float)transformed [0],
                    (float)transformed [1]);

                // calculate the angle.
                VectorF2D vector       = next - current;
                VectorF2D horizontal   = new VectorF2D(1, 0);
                double    angleDegrees = (horizontal.Angle(vector)).Value;

                // rotate the character.
                target.Target.CGContext.RotateCTM((float)angleDegrees);
//
//				// translate the character so the center of its base is over the origin.
                target.Target.CGContext.TranslateCTM(0, charachterHeight / 3.0f);

                // rotate 'upside down'
                target.Target.CGContext.ConcatCTM(new CGAffineTransform(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));

                target.Target.CGContext.BeginPath();

                CGPath path = font.GetPathForGlyph(glyphs [idx]);
                target.Target.CGContext.AddPath(path);
                if (haloRadius.HasValue && haloColor.HasValue)                   // also draw the halo.
                {
                    target.Target.CGContext.DrawPath(CGPathDrawingMode.FillStroke);
                }
                else
                {
                    target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill);
                }
                //target.Target.CGContext.ClosePath ();
                target.Target.CGContext.RestoreState();

                current = next;
            }
        }
コード例 #17
0
        private bool NativeStyleAvailable(FontStyle style)
        {
            // we are going to actually have to create a font object here
            // will not create an actual variable for this yet.  We may
            // want to do this in the future so that we do not have to keep
            // creating it over and over again.
            var font = new CTFont (nativeFontDescriptor,0);

            switch (style)
            {
            case FontStyle.Bold:
                var tMaskBold = CTFontSymbolicTraits.None;
                tMaskBold |= CTFontSymbolicTraits.Bold;
                var bFont = font.WithSymbolicTraits (0, tMaskBold, tMaskBold);
                if (bFont == null)
                    return false;
                var bold = (bFont.SymbolicTraits & CTFontSymbolicTraits.Bold) == CTFontSymbolicTraits.Bold;
                return bold;

            case FontStyle.Italic:
                //return (font.SymbolicTraits & CTFontSymbolicTraits.Italic) == CTFontSymbolicTraits.Italic;
                var tMaskItalic = CTFontSymbolicTraits.None;
                tMaskItalic |= CTFontSymbolicTraits.Italic;
                var iFont = font.WithSymbolicTraits (0, tMaskItalic, tMaskItalic);
                if (iFont == null)
                    return false;
                var italic = (iFont.SymbolicTraits & CTFontSymbolicTraits.Italic) == CTFontSymbolicTraits.Italic;
                return italic;

            case FontStyle.Regular:

                // Verify if this is correct somehow - we may need to add Bold here as well not sure
                if ((font.SymbolicTraits & CTFontSymbolicTraits.Condensed) == CTFontSymbolicTraits.Condensed
                    ||  (font.SymbolicTraits & CTFontSymbolicTraits.Expanded) == CTFontSymbolicTraits.Expanded)
                    return false;
                else
                    return true;
            case FontStyle.Underline:
                return font.UnderlineThickness > 0;
            case FontStyle.Strikeout:
                // not implemented yet
                return false;

            }
            return false;
        }
コード例 #18
0
        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="text"></param>
        /// <param name="size"></param>
        /// <param name="color">Color.</param>
        protected override void DrawText(Target2DWrapper <CGContextWrapper> target, double x, double y, string text, int color, double size,
                                         int?haloColor, int?haloRadius, string fontName)
        {
            double[] transformed = this.Tranform(x, y);
            float    xPixels     = (float)transformed[0];
            float    yPixels     = (float)transformed[1];
            float    textSize    = this.ToPixels(size) * _scaleFactor;

            // get the glyhps/paths from the font.
            CTFont             font             = this.GetFont(fontName, textSize);
            CTStringAttributes stringAttributes = new CTStringAttributes
            {
                ForegroundColorFromContext = true,
                Font = font
            };
            NSAttributedString attributedString = new NSAttributedString(text, stringAttributes);
            CTLine             line             = new CTLine(attributedString);

            CTRun[] runs = line.GetGlyphRuns();

            // set the correct tranformations to draw the resulting paths.
            target.Target.CGContext.SaveState();
            target.Target.CGContext.TranslateCTM(xPixels, yPixels);
            target.Target.CGContext.ConcatCTM(new CGAffineTransform(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));
            foreach (CTRun run in runs)
            {
                ushort[] glyphs    = run.GetGlyphs();
                PointF[] positions = run.GetPositions();

                float previousOffset = 0;
                for (int idx = 0; idx < glyphs.Length; idx++)
                {
                    CGPath path = font.GetPathForGlyph(glyphs[idx]);
                    target.Target.CGContext.TranslateCTM(positions[idx].X - previousOffset, 0);
                    previousOffset = positions[idx].X;
                    if (haloRadius.HasValue && haloColor.HasValue)
                    {                     // also draw the halo.
                        using (CGPath haloPath = path.CopyByStrokingPath(
                                   haloRadius.Value * 2, CGLineCap.Round, CGLineJoin.Round, 0))
                        {
                            SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value);
                            target.Target.CGContext.SetFillColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f,
                                                                 haloSimpleColor.A / 256.0f);
                            target.Target.CGContext.BeginPath();
                            target.Target.CGContext.AddPath(haloPath);
                            target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill);
                        }
                    }

                    // set the fill color as the regular text-color.
                    SimpleColor simpleColor = SimpleColor.FromArgb(color);
                    target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f,
                                                         simpleColor.A / 256.0f);

                    // draw the text paths.
                    target.Target.CGContext.BeginPath();
                    target.Target.CGContext.AddPath(path);
                    target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill);
                }
            }

            target.Target.CGContext.RestoreState();
        }
コード例 #19
0
 internal static CCSize MeasureString(string textg, CTFont font, CCSize layoutArea)
 {
     return(MeasureString(textg, font, new CCRect(0, 0, layoutArea.Width, layoutArea.Height)));
 }
コード例 #20
0
        /// <summary>
        /// Draws text along a given line.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="color"></param>
        /// <param name="size"></param>
        /// <param name="text">Text.</param>
        protected override void DrawLineText(Target2DWrapper <CGContextWrapper> target, double[] xa, double[] ya, string text, int color,
                                             double size, int?haloColor, int?haloRadius, string fontName)
        {
            float textSize = this.ToPixels(size) * _scaleFactor;

            // transform first.
            double[] xTransformed = new double[xa.Length];
            double[] yTransformed = new double[ya.Length];
            for (int idx = 0; idx < xa.Length; idx++)
            {
                double[] transformed = this.Tranform(xa[idx], ya[idx]);
                xTransformed[idx] = transformed[0];
                yTransformed[idx] = transformed[1];
            }

            // set the fill color as the regular text-color.
            target.Target.CGContext.InterpolationQuality = CGInterpolationQuality.High;
            target.Target.CGContext.SetAllowsFontSubpixelQuantization(true);
            target.Target.CGContext.SetAllowsFontSmoothing(true);
            target.Target.CGContext.SetAllowsAntialiasing(true);
            target.Target.CGContext.SetAllowsSubpixelPositioning(true);
            target.Target.CGContext.SetShouldAntialias(true);

            // get the glyhps/paths from the font.
            CTFont             font             = this.GetFont(fontName, textSize);
            CTStringAttributes stringAttributes = new CTStringAttributes
            {
                ForegroundColorFromContext = true,
                Font = font
            };
            NSAttributedString attributedString = new NSAttributedString(text, stringAttributes);
            CTLine             line             = new CTLine(attributedString);
            RectangleF         textBounds       = line.GetBounds(CTLineBoundsOptions.UseOpticalBounds);

            CTRun[] runs       = line.GetGlyphRuns();
            var     lineLength = Polyline2D.Length(xTransformed, yTransformed);

            // set the correct tranformations to draw the resulting paths.
            target.Target.CGContext.SaveState();
            //target.Target.CGContext.TranslateCTM (xPixels, yPixels);
            //target.Target.CGContext.ConcatCTM (new CGAffineTransform (1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));
            foreach (CTRun run in runs)
            {
                ushort[] glyphs          = run.GetGlyphs();
                PointF[] positions       = run.GetPositions();
                float[]  characterWidths = new float[glyphs.Length];
                float    previous        = 0;
                float    textLength      = (float)positions[positions.Length - 1].X;
                //float textLength = (float)this.FromPixels(_target, _view, positions [positions.Length - 1].X);
                if (lineLength > textLength * 1.2f)
                {
                    for (int idx = 0; idx < characterWidths.Length - 1; idx++)
                    {
                        //characterWidths [idx] = (float)this.FromPixels(_target, _view, positions [idx + 1].X - previous);
                        characterWidths[idx] = (float)(positions[idx + 1].X - previous);
                        previous             = positions[idx + 1].X;
                    }
                    characterWidths[characterWidths.Length - 1] = characterWidths[characterWidths.Length - 2];
                    float characterHeight = textBounds.Height;

                    this.DrawLineTextSegment(target, xTransformed, yTransformed, glyphs, color, haloColor, haloRadius,
                                             lineLength / 2f, characterWidths, textLength, characterHeight, font);
                }
            }

            target.Target.CGContext.RestoreState();
        }
コード例 #21
0
        private static NSMutableAttributedString buildAttributedString(string text, CTFont font,
                                                                       CCColor4B?fontColor = null)
        {
            // Create a new attributed string definition
            var ctAttributes = new CTStringAttributes();

            // Font attribute
            ctAttributes.Font = font;
            // -- end font

            if (fontColor.HasValue)
            {
                // Font color
                var fc      = fontColor.Value;
                var cgColor = new CGColor(fc.R / 255f,
                                          fc.G / 255f,
                                          fc.B / 255f,
                                          fc.A / 255f);

                ctAttributes.ForegroundColor            = cgColor;
                ctAttributes.ForegroundColorFromContext = false;
                // -- end font Color
            }

            if (underLine)
            {
                // Underline
                                #if MACOS
                int single = (int)MonoMac.AppKit.NSUnderlineStyle.Single;
                int solid  = (int)MonoMac.AppKit.NSUnderlinePattern.Solid;
                var attss  = single | solid;
                ctAttributes.UnderlineStyleValue = attss;
                                #else
                ctAttributes.UnderlineStyleValue = 1;
                                #endif
                // --- end underline
            }


            if (strikeThrough)
            {
                // StrikeThrough
                //				NSColor bcolor = NSColor.Blue;
                //				NSObject bcolorObject = new NSObject(bcolor.Handle);
                //				attsDic.Add(NSAttributedString.StrikethroughColorAttributeName, bcolorObject);
//				#if MACOS
//				int stsingle = (int)MonoMac.AppKit.NSUnderlineStyle.Single;
//				int stsolid = (int)MonoMac.AppKit.NSUnderlinePattern.Solid;
//				var stattss = stsingle | stsolid;
//				var stunderlineObject = NSNumber.FromInt32(stattss);
//				#else
//				var stunderlineObject = NSNumber.FromInt32 (1);
//				#endif
//
//				attsDic.Add(StrikethroughStyleAttributeName, stunderlineObject);
                // --- end underline
            }


            // Text alignment
            var alignment         = CTTextAlignment.Left;
            var alignmentSettings = new CTParagraphStyleSettings();
            alignmentSettings.Alignment = alignment;
            var paragraphStyle = new CTParagraphStyle(alignmentSettings);

            ctAttributes.ParagraphStyle = paragraphStyle;
            // end text alignment

            NSMutableAttributedString atts =
                new NSMutableAttributedString(text, ctAttributes.Dictionary);

            return(atts);
        }
コード例 #22
0
        private void DrawLineTextSegment(Target2DWrapper <CGContextWrapper> target, double[] xTransformed, double[] yTransformed, ushort[] glyphs, int color,
                                         int?haloColor, int?haloRadius, double middlePosition, float[] characterWidths,
                                         double textLength, float charachterHeight, CTFont font)
        {
            // see if text is 'upside down'
            double   averageAngle = 0;
            double   first        = middlePosition - (textLength / 2.0);
            PointF2D current      = Polyline2D.PositionAtPosition(xTransformed, yTransformed, first);

            for (int idx = 0; idx < glyphs.Length; idx++)
            {
                double   nextPosition = middlePosition - (textLength / 2.0) + ((textLength / (glyphs.Length)) * (idx + 1));
                PointF2D next         = Polyline2D.PositionAtPosition(xTransformed, yTransformed, nextPosition);

                // translate to the final position, the center of the line segment between 'current' and 'next'.
                //PointF2D position = current + ((next - current) / 2.0);

                // calculate the angle.
                VectorF2D vector       = next - current;
                VectorF2D horizontal   = new VectorF2D(1, 0);
                double    angleDegrees = ((Degree)horizontal.Angle(vector)).Value;
                averageAngle = averageAngle + angleDegrees;
                current      = next;
            }
            averageAngle = averageAngle / glyphs.Length;


            // revers if 'upside down'
            double[] xText = xTransformed;
            double[] yText = yTransformed;
            if (averageAngle > 90 && averageAngle < 180 + 90)
            {
                xText = xTransformed.Reverse().ToArray();
                yText = yTransformed.Reverse().ToArray();
            }
            first   = middlePosition - (textLength / 2.0);
            current = Polyline2D.PositionAtPosition(xText, yText, first);

            double nextPosition2 = first;

            for (int idx = 0; idx < glyphs.Length; idx++)
            {
                nextPosition2 = nextPosition2 + characterWidths[idx];
                PointF2D next = Polyline2D.PositionAtPosition(xText, yText, nextPosition2);
                //ushort currentChar = glyphs [idx];

                PointF2D position = current;

                target.Target.CGContext.SaveState();

                // translate to the final position, the center of the line segment between 'current' and 'next'.
//                double[] transformed = this.Tranform(position[0], position[1]);
//				target.Target.CGContext.TranslateCTM (
//					(float)transformed [0],
//					(float)transformed [1]);
                target.Target.CGContext.TranslateCTM((float)position[0], (float)position[1]);

                // calculate the angle.
                VectorF2D vector       = next - current;
                VectorF2D horizontal   = new VectorF2D(1, 0);
                double    angleDegrees = (horizontal.Angle(vector)).Value;

                // rotate the character.
                target.Target.CGContext.RotateCTM((float)angleDegrees);

                // rotate the text to point down no matter what the map tilt is.
                //target.Target.CGContext.RotateCTM ((float)_view.Angle.Value);

                // translate the character so the center of its base is over the origin.
                target.Target.CGContext.TranslateCTM(0, charachterHeight / 3.0f);

                // rotate 'upside down'
                target.Target.CGContext.ConcatCTM(new CGAffineTransform(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f));

                target.Target.CGContext.BeginPath();

                CGPath path = font.GetPathForGlyph(glyphs[idx]);

                if (haloRadius.HasValue && haloColor.HasValue)
                {                 // also draw the halo.
                    using (CGPath haloPath = path.CopyByStrokingPath(
                               haloRadius.Value * 2, CGLineCap.Round, CGLineJoin.Round, 0))
                    {
                        SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value);
                        target.Target.CGContext.SetFillColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f,
                                                             haloSimpleColor.A / 256.0f);
                        target.Target.CGContext.BeginPath();
                        target.Target.CGContext.AddPath(haloPath);
                        target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill);
                    }
                }

                // set the fill color as the regular text-color.
                SimpleColor simpleColor = SimpleColor.FromArgb(color);
                target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f,
                                                     simpleColor.A / 256.0f);

                // draw the text paths.
                target.Target.CGContext.BeginPath();
                target.Target.CGContext.AddPath(path);
                target.Target.CGContext.DrawPath(CGPathDrawingMode.Fill);

//				target.Target.CGContext.AddPath (path);
//				if (haloRadius.HasValue && haloColor.HasValue) { // also draw the halo.
//					target.Target.CGContext.DrawPath (CGPathDrawingMode.FillStroke);
//				} else {
//					target.Target.CGContext.DrawPath (CGPathDrawingMode.Fill);
//				}
                //target.Target.CGContext.ClosePath ();
                target.Target.CGContext.RestoreState();

                current = next;
            }
        }
コード例 #23
0
		// Listing 2-8
		static NSData CreateFlattenedFontData (CTFont font)
		{
			var descriptor = font.GetFontDescriptor ();
			if (descriptor == null)
				return null;
			var attributes = descriptor.GetAttributes ();
			if (attributes == null)
				return null;
			// TODO: MonoTouch has no binding for CFPropertyListIsValid()
			return null;
		}
コード例 #24
0
        void LoadFontFile(string fileName)
        {
            CTFont nativeFont;
            var dpiSize = 0;
            var ext = Path.GetExtension(fileName);

            if (!String.IsNullOrEmpty(ext))
            {

                if (nativeFontDescriptors == null)
                    nativeFontDescriptors = new Dictionary<string, CTFontDescriptor> ();

                //Try loading from Bundle first
                var fontName = fileName.Substring (0, fileName.Length - ext.Length);
                var pathForResource = NSBundle.MainBundle.PathForResource (fontName, ext.Substring(1));

                NSUrl url;

             				if (!string.IsNullOrEmpty(pathForResource))
                    url = NSUrl.FromFilename (pathForResource);
                else
                    url = NSUrl.FromFilename (fileName);

                // We will not use CTFontManager.RegisterFontsForUrl (url, CTFontManagerScope.Process);
                // here.  The reason is that there is no way we can be sure that the font can be created to
                // to identify the family name afterwards.  So instead we will create a CGFont from a data provider.
                // create CTFont to obtain the CTFontDescriptor, store family name and font descriptor to be accessed
                // later.
                try {
                    var dataProvider = new CGDataProvider (url.Path);
                    var cgFont = CGFont.CreateFromProvider (dataProvider);

                    try {
                        nativeFont = new CTFont(cgFont, dpiSize, null);
                        if (!nativeFontDescriptors.ContainsKey(nativeFont.FamilyName))
                        {
                            nativeFontDescriptors.Add(nativeFont.FamilyName, nativeFont.GetFontDescriptor());
                            NSError error;
                            var registered = CTFontManager.RegisterGraphicsFont(cgFont, out error);
                            if (!registered)
                            {
                                // If the error code is 105 then the font we are trying to register is already registered
                                // We will not report this as an error.
                                if (error.Code != 105)
                                    throw new ArgumentException("Error registering: " + Path.GetFileName(fileName));
                            }
                        }
                    }
                    catch
                    {
                        // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                        throw new System.IO.FileNotFoundException (fileName);
                    }
                }
                catch (Exception)
                {
                    // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                    throw new System.IO.FileNotFoundException (fileName);
                }
            }
        }
コード例 #25
0
		// Listing 2-11:
		static void GetGlyphsForCharacters (CTFont font, string value)
		{
			var count = value.Length;
			var characters = value.ToCharArray ();
			var glyphs = new ushort [characters.Length];

			font.GetGlyphsForCharacters (characters, glyphs);

			// Do something with the glyphs here, if a character is unmapped
		}
コード例 #26
0
        static internal CTFont CreateFont(string familyName, float emSize, FontStyle style,
                                          byte gdiCharSet, bool gdiVerticalFont)
        {
            if (emSize <= 0)
            {
                throw new ArgumentException("emSize is less than or equal to 0, evaluates to infinity, or is not a valid number.", "emSize");
            }

            CTFont nativeFont;
            // convert to 96 Dpi to be consistent with Windows
            var dpiSize = emSize;            // * dpiScale;

            var ext = System.IO.Path.GetExtension(familyName);

            if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf")
            {
                var fontName        = familyName.Substring(0, familyName.Length - ext.Length);
                var path            = CCContentManager.SharedContentManager.RootDirectory + Path.DirectorySeparatorChar + fontName;
                var pathForResource = NSBundle.MainBundle.PathForResource(path, ext.Substring(1));

                try {
                    var dataProvider = new CGDataProvider(pathForResource);
                    var cgFont       = CGFont.CreateFromProvider(dataProvider);

                    try {
                        nativeFont = new CTFont(cgFont, dpiSize, null);
                    }
                    catch
                    {
                        nativeFont = new CTFont("Helvetica", dpiSize);
                    }
                }
                catch (Exception)
                {
                    try {
                        nativeFont = new CTFont(Path.GetFileNameWithoutExtension(familyName), dpiSize);
                    }
                    catch
                    {
                        nativeFont = new CTFont("Helvetica", dpiSize);
                    }
                    CCLog.Log(string.Format("Could not load font: {0} so will use default {1}.", familyName, nativeFont.DisplayName));
                }
            }
            else
            {
                try {
                    nativeFont = new CTFont(familyName, dpiSize);
                }
                catch
                {
                    nativeFont = new CTFont("Helvetica", dpiSize);
                }
            }


            CTFontSymbolicTraits tMask = CTFontSymbolicTraits.None;

            if ((style & FontStyle.Bold) == FontStyle.Bold)
            {
                tMask |= CTFontSymbolicTraits.Bold;
            }
            if ((style & FontStyle.Italic) == FontStyle.Italic)
            {
                tMask |= CTFontSymbolicTraits.Italic;
            }
            strikeThrough = (style & FontStyle.Strikeout) == FontStyle.Strikeout;
            underLine     = (style & FontStyle.Underline) == FontStyle.Underline;

            var nativeFont2 = nativeFont.WithSymbolicTraits(dpiSize, tMask, tMask);

            if (nativeFont2 != null)
            {
                nativeFont = nativeFont2;
            }

            return(nativeFont);
        }
コード例 #27
0
		// Listing 2-13:
		static CTFont CreateFontConvertedToFamily (CTFont font, string family)
		{
			return font.WithFamily (0.0f, family);
		}
コード例 #28
0
        public override void DrawRect(RectangleF dirtyRect)
        {
            // Don't draw if we don't have a font or a title.
            if (Font == null || Title == string.Empty)
            {
                return;
            }

            // Initialize the text matrix to a known value
            CGContext context = NSGraphicsContext.CurrentContext.GraphicsPort;

            context.TextMatrix = CGAffineTransform.MakeIdentity();

            // Draw a white background
            NSColor.White.Set();
            context.FillRect(dirtyRect);

            //CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)self.attributedString);
            CTLine line = new CTLine(AttributedString);

            int glyphCount = line.GlyphCount;

            if (glyphCount == 0)
            {
                return;
            }

            GlyphArcInfo[] glyphArcInfo = new GlyphArcInfo[glyphCount];
            PrepareGlyphArcInfo(line, glyphCount, glyphArcInfo);

            // Move the origin from the lower left of the view nearer to its center.
            context.SaveState();
            context.TranslateCTM(dirtyRect.GetMidX(), dirtyRect.GetMidY() - Radius / 2);

            // Stroke the arc in red for verification.
            context.BeginPath();
            context.AddArc(0, 0, Radius, (float)Math.PI, 0, true);
            context.SetRGBStrokeColor(1, 0, 0, 1);
            context.StrokePath();

            // Rotate the context 90 degrees counterclockwise.
            context.RotateCTM((float)PI_2);

            // Now for the actual drawing. The angle offset for each glyph relative to the previous
            //      glyph has already been calculated; with that information in hand, draw those glyphs
            //      overstruck and centered over one another, making sure to rotate the context after each
            //      glyph so the glyphs are spread along a semicircular path.
            PointF textPosition = new PointF(0, Radius);

            context.TextPosition = textPosition;

            var runArray = line.GetGlyphRuns();
            var runCount = runArray.Count();

            var glyphOffset = 0;
            var runIndex    = 0;

            for (; runIndex < runCount; runIndex++)
            {
                var    run           = runArray[runIndex];
                var    runGlyphCount = run.GlyphCount;
                bool   drawSubstitutedGlyphsManually = false;
                CTFont runFont = run.GetAttributes().Font;

                // Determine if we need to draw substituted glyphs manually. Do so if the runFont is not
                //      the same as the overall font.
                NSFont rrunFont = new NSFont(runFont.Handle);
                // used for comparison
                if (DimsSubstitutedGlyphs && Font != rrunFont)
                {
                    drawSubstitutedGlyphsManually = true;
                }

                var runGlyphIndex = 0;
                for (; runGlyphIndex < runGlyphCount; runGlyphIndex++)
                {
                    var glyphRange = new NSRange(runGlyphIndex, 1);
                    context.RotateCTM(-(glyphArcInfo[runGlyphIndex + glyphOffset].angle));

                    // Center this glyph by moving left by half its width.
                    var glyphWidth           = glyphArcInfo[runGlyphIndex + glyphOffset].width;
                    var halfGlyphWidth       = glyphWidth / 2.0;
                    var positionForThisGlyph = new PointF(textPosition.X - (float)halfGlyphWidth, textPosition.Y);

                    // Glyphs are positioned relative to the text position for the line, so offset text position leftwards by this glyph's
                    //      width in preparation for the next glyph.
                    textPosition.X -= glyphWidth;

                    CGAffineTransform textMatrix = run.TextMatrix;
                    textMatrix.x0      = positionForThisGlyph.X;
                    textMatrix.y0      = positionForThisGlyph.Y;
                    context.TextMatrix = textMatrix;

                    if (!drawSubstitutedGlyphsManually)
                    {
                        run.Draw(context, glyphRange);
                    }
                    else
                    {
                        // We need to draw the glyphs manually in this case because we are effectively applying a graphics operation by
                        //      setting the context fill color. Normally we would use kCTForegroundColorAttributeName, but this does not apply
                        // as we don't know the ranges for the colors in advance, and we wanted demonstrate how to manually draw.
                        var cgFont = runFont.ToCGFont();

                        var glyph    = run.GetGlyphs(glyphRange);
                        var position = run.GetPositions(glyphRange);

                        context.SetFont(cgFont);
                        context.SetFontSize(runFont.Size);
                        context.SetRGBFillColor(0.25f, 0.25f, 0.25f, 1);
                        context.ShowGlyphsAtPositions(glyph, position, 1);
                    }

                    // Draw the glyph bounds
                    if (ShowsGlyphBounds)
                    {
                        var glyphBounds = run.GetImageBounds(context, glyphRange);
                        context.SetRGBStrokeColor(0, 0, 1, 1);
                        context.StrokeRect(glyphBounds);
                    }

                    // Draw the bounding boxes defined by the line metrics
                    if (ShowsLineMetrics)
                    {
                        var   lineMetrics = new RectangleF();
                        float ascent      = 0;
                        float descent     = 0;
                        float leading     = 0;

                        run.GetTypographicBounds(glyphRange, out ascent, out descent, out leading);

                        // The glyph is centered around the y-axis
                        lineMetrics.Location = new PointF(-(float)halfGlyphWidth, positionForThisGlyph.Y - descent);
                        lineMetrics.Size     = new SizeF(glyphWidth, ascent + descent);
                        context.SetRGBStrokeColor(0, 1, 0, 1);
                        context.StrokeRect(lineMetrics);
                    }
                }

                glyphOffset += runGlyphCount;
            }

            context.RestoreState();
        }
コード例 #29
0
        void setupTextLayer(string l)
        {
            clearLayer();

            var singleLetter = l.Length == 1;

            var fontSize = singleLetter ? letterFontSize : messageFontSize;

            var font = new CTFont(new CTFontDescriptor(new CTFontDescriptorAttributes {
                Name = UIFont.SystemFontOfSize(fontSize).Name, Size = (float?)fontSize
            }), fontSize);

            var attrStr = new NSAttributedString(l, singleLetter ? letterStringAttributes : messageStringAttributes);

            var line = new CTLine(attrStr);

            var runArray = line.GetGlyphRuns();

            var letters = new CGPath();

            for (int runIndex = 0; runIndex < runArray.Length; runIndex++)
            {
                var run = runArray [runIndex];

                for (int runGlyphIndex = 0; runGlyphIndex < run.GlyphCount; runGlyphIndex++)
                {
                    var thisGlyphRange = new NSRange(runGlyphIndex, 1);

                    var glyph = run.GetGlyphs(thisGlyphRange).FirstOrDefault();

                    var position = run.GetPositions(thisGlyphRange).FirstOrDefault();

                    var letter = font.GetPathForGlyph(glyph);

                    var t = CGAffineTransform.MakeTranslation(position.X, position.Y);

                    if (letter != null)
                    {
                        letters.AddPath(t, letter);
                    }
                }
            }

            var path = new UIBezierPath();

            path.MoveTo(CGPoint.Empty);

            path.AppendPath(UIBezierPath.FromPath(letters));

            var layer = new CAShapeLayer();

            layer.Frame           = new CGRect(((animationLayer.Bounds.Width - path.Bounds.Width) / 2) - 10, (animationLayer.Bounds.Height - path.Bounds.Height) / 2, path.Bounds.Width, path.Bounds.Height);
            layer.GeometryFlipped = true;
            layer.Path            = path.CGPath;
            layer.StrokeColor     = UIColor.Blue.CGColor;
            layer.FillColor       = null;
            layer.LineWidth       = 3;
            layer.LineJoin        = CAShapeLayer.JoinBevel;

            animationLayer?.AddSublayer(layer);

            pathLayer = layer;
        }
コード例 #30
0
        void drawLabel(CGContext ctx, CGRect rect, nfloat yCoord, nfloat xCoord, CTTextAlignment alignment, UIColor color, string label, bool flipContext = true)
        {
            Console.WriteLine("Finish Draw code");

            var attrString = new NSMutableAttributedString (label);

            var range = new NSRange (0, attrString.Length);

            var uiFont = UIFont.FromName("HelveticaNeue-Medium", range.Length > 1 ? 15 : 22);

            var font = new CTFont (uiFont.Name, uiFont.PointSize);  //((uiFont.Name as NSString) as CFString, uiFont.pointSize, nil);

            var path = new CGPath ();

            var alignStyle = new CTParagraphStyle (new CTParagraphStyleSettings { Alignment = alignment });

            var attributes = new CTStringAttributes {
                Font = font,
                ForegroundColor = color.CGColor,
                ParagraphStyle = alignStyle
            };

            attrString.SetAttributes(attributes, new NSRange (0, attrString.Length));

            var target = new CGSize (nfloat.MaxValue, nfloat.MaxValue);

            var fit = new NSRange (0, 0);

            var framesetter = new CTFramesetter (attrString);

            var frameSize = framesetter.SuggestFrameSize(range, null, target, out fit);

            var textRect = new CGRect (xCoord - (frameSize.Width / 2), yCoord - (frameSize.Height / 2), frameSize.Width, frameSize.Height);

            path.AddRect(textRect);

            var frame = framesetter.GetFrame(range, path, null);

            if (flipContext) {

                ctx.SaveState();

                ctx.TranslateCTM(0, rect.Height);

                ctx.ScaleCTM(1, -1);

                frame.Draw(ctx);

                ctx.RestoreState();

            } else {
                frame.Draw(ctx);
            }
        }
コード例 #31
0
        /// <summary>
        /// Gets font metrics for the specified font.
        /// </summary>
        /// <param name="font">The font.</param>
        /// <param name="defaultLineHeight">Default line height.</param>
        /// <param name="delta">The vertical delta.</param>
        private void GetFontMetrics(CTFont font, out nfloat defaultLineHeight, out nfloat delta)
        {
            var ascent = font.AscentMetric;
            var descent = font.DescentMetric;
            var leading = font.LeadingMetric;

            //// http://stackoverflow.com/questions/5511830/how-does-line-spacing-work-in-core-text-and-why-is-it-different-from-nslayoutm

            leading = leading < 0 ? 0 : (float)Math.Floor(leading + 0.5f);
            var lineHeight = (nfloat)Math.Floor(ascent + 0.5f) + (nfloat)Math.Floor(descent + 0.5) + leading;
            var ascenderDelta = leading >= 0 ? 0 : (nfloat)Math.Floor((0.2 * lineHeight) + 0.5);
            defaultLineHeight = lineHeight + ascenderDelta;
            delta = ascenderDelta - descent;
        }
コード例 #32
0
        string LoadFontFile(string fileName)
        {
            CTFont nativeFont;
            var    dpiSize = 0;
            var    ext     = Path.GetExtension(fileName);

            if (!String.IsNullOrEmpty(ext))
            {
                if (nativeFontDescriptors == null)
                {
                    nativeFontDescriptors = new Dictionary <string, string> ();
                }

                string fd = null;
                if (nativeFontDescriptors.TryGetValue(fileName, out fd))
                {
                    return(fd);
                }

                // We will not use CTFontManager.RegisterFontsForUrl (url, CTFontManagerScope.Process);
                // here.  The reason is that there is no way we can be sure that the font can be created to
                // to identify the family name afterwards.  So instead we will create a CGFont from a data provider.
                // create CTFont to obtain the CTFontDescriptor, store family name and font descriptor to be accessed
                // later.
                try {
                    var filePath = string.Empty;
                    CCContentManager.SharedContentManager.GetAssetStreamAsBytes(fileName, out filePath);

                    var dataProvider = new CGDataProvider(filePath);
                    var cgFont       = CGFont.CreateFromProvider(dataProvider);

                    try
                    {
                        nativeFont = new CTFont(cgFont, dpiSize, null);
                        if (!nativeFontDescriptors.ContainsKey(fileName))
                        {
                            nativeFontDescriptors.Add(fileName, nativeFont.PostScriptName);
                            NSError error;

                            var registered = CTFontManager.RegisterGraphicsFont(cgFont, out error);
                            if (!registered)
                            {
                                // If the error code is 105 then the font we are trying to register is already registered
                                // We will not report this as an error.
                                if (error.Code != 105)
                                {
                                    throw new ArgumentException("Error registering: " + Path.GetFileName(fileName));
                                }
                            }
                        }

                        return(nativeFont.PostScriptName);
                    }
                    catch
                    {
                        // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                        throw new System.IO.FileNotFoundException(fileName);
                    }
                }
                catch (Exception)
                {
                    // note: MS throw the same exception FileNotFoundException if the file exists but isn't a valid font file
                    throw new System.IO.FileNotFoundException(fileName);
                }
            }
            return(fileName);
        }
コード例 #33
0
        private int GetNativeMetric(Metric metric, FontStyle style)
        {
            // we are going to actually have to create a font object here
            // will not create an actual variable for this yet.  We may
            // want to do this in the future so that we do not have to keep
            // creating it over and over again.
            CTFontSymbolicTraits tMask = CTFontSymbolicTraits.None;

            if ((style & FontStyle.Bold) == FontStyle.Bold)
                tMask |= CTFontSymbolicTraits.Bold;
            if ((style & FontStyle.Italic) == FontStyle.Italic)
                tMask |= CTFontSymbolicTraits.Italic;

            var font = new CTFont (nativeFontDescriptor,0);
            font = font.WithSymbolicTraits (0, tMask, tMask);

            switch (metric)
            {
            case Metric.EMHeight:
                return (int)font.UnitsPerEmMetric;
            case Metric.CellAscent:
                return (int)Math.Round(font.AscentMetric / font.Size * font.UnitsPerEmMetric);
            case Metric.CellDescent:
                return (int)Math.Round(font.DescentMetric / font.Size * font.UnitsPerEmMetric);
            case  Metric.LineSpacing:
                float lineHeight = 0;
                lineHeight += (float)font.AscentMetric;
                lineHeight += (float)font.DescentMetric;
                lineHeight += (float)font.LeadingMetric;
                return (int)Math.Round(lineHeight / font.Size * font.UnitsPerEmMetric);
            }

            return 0;
        }
コード例 #34
0
        internal static void NativeDrawString(CGBitmapContext bitmapContext, string s, CTFont font, CCColor4B brush, CGRect layoutRectangle)
        {
            if (font == null)
            {
                throw new ArgumentNullException("font");
            }

            if (s == null || s.Length == 0)
            {
                return;
            }

            bitmapContext.ConcatCTM(bitmapContext.GetCTM().Invert());

            // This is not needed here since the color is set in the attributed string.
            //bitmapContext.SetFillColor(brush.R/255f, brush.G/255f, brush.B/255f, brush.A/255f);

            // I think we only Fill the text with no Stroke surrounding
            //bitmapContext.SetTextDrawingMode(CGTextDrawingMode.Fill);

            var attributedString = buildAttributedString(s, font, brush);

            // Work out the geometry
            CGRect insetBounds = layoutRectangle;

            CGPoint textPosition = new CGPoint(insetBounds.X,
                                               insetBounds.Y);

            float boundsWidth = (float)insetBounds.Width;

            // Calculate the lines
            nint start  = 0;
            nint length = attributedString.Length;

            var typesetter = new CTTypesetter(attributedString);

            float baselineOffset = 0;

            // First we need to calculate the offset for Vertical Alignment if we
            // are using anything but Top
            if (vertical != CCVerticalTextAlignment.Top)
            {
                while (start < length)
                {
                    nint count = typesetter.SuggestLineBreak((int)start, (double)boundsWidth);

                    var line = typesetter.GetLine(new NSRange(start, count));

                    // Create and initialize some values from the bounds.
                    nfloat ascent;
                    nfloat descent;
                    nfloat leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    baselineOffset += (float)Math.Ceiling((float)(ascent + descent + leading + 1));  // +1 matches best to CTFramesetter's behavior
                    line.Dispose();
                    start += count;
                }
            }

            start = 0;

            while (start < length && textPosition.Y < insetBounds.Bottom)
            {
                // Now we ask the typesetter to break off a line for us.
                // This also will take into account line feeds embedded in the text.
                //  Example: "This is text \n with a line feed embedded inside it"
                nint count = typesetter.SuggestLineBreak((int)start, (double)boundsWidth);
                var  line  = typesetter.GetLine(new NSRange(start, count));

                // Create and initialize some values from the bounds.
                nfloat ascent;
                nfloat descent;
                nfloat leading;
                line.GetTypographicBounds(out ascent, out descent, out leading);

                // Calculate the string format if need be
                var penFlushness = 0.0f;

                if (horizontal == CCTextAlignment.Right)
                {
                    penFlushness = (float)line.GetPenOffsetForFlush(1.0f, boundsWidth);
                }
                else if (horizontal == CCTextAlignment.Center)
                {
                    penFlushness = (float)line.GetPenOffsetForFlush(0.5f, boundsWidth);
                }

                // initialize our Text Matrix or we could get trash in here
                var textMatrix = CGAffineTransform.MakeIdentity();

                if (vertical == CCVerticalTextAlignment.Top)
                {
                    textMatrix.Translate(penFlushness, insetBounds.Height - textPosition.Y - (float)Math.Floor(ascent - 1));
                }
                if (vertical == CCVerticalTextAlignment.Center)
                {
                    textMatrix.Translate(penFlushness, ((insetBounds.Height / 2) + (baselineOffset / 2)) - textPosition.Y - (float)Math.Floor(ascent - 1));
                }
                if (vertical == CCVerticalTextAlignment.Bottom)
                {
                    textMatrix.Translate(penFlushness, baselineOffset - textPosition.Y - (float)Math.Floor(ascent - 1));
                }

                // Set our matrix
                bitmapContext.TextMatrix = textMatrix;

                // and draw the line
                line.Draw(bitmapContext);

                // Move the index beyond the line break.
                start          += count;
                textPosition.Y += (float)Math.Ceiling(ascent + descent + leading + 1);                 // +1 matches best to CTFramesetter's behavior
                line.Dispose();
            }
        }
コード例 #35
0
        private void CreateNativeFontFamily(string name, FontCollection fontCollection, bool createDefaultIfNotExists)
        {
            if (fontCollection != null)
            {
                if (fontCollection.nativeFontDescriptors.ContainsKey (name))
                    nativeFontDescriptor = fontCollection.nativeFontDescriptors [name];

                if (nativeFontDescriptor == null && createDefaultIfNotExists)
                {
                    nativeFontDescriptor = new CTFontDescriptor (SANS_SERIF, 0);
                }
            }
            else
            {
                nativeFontDescriptor = new CTFontDescriptor (name, 0);

                if (nativeFontDescriptor == null && createDefaultIfNotExists)
                {
                    nativeFontDescriptor = new CTFontDescriptor (SANS_SERIF, 0);
                }
            }

            if (nativeFontDescriptor == null)
                throw new ArgumentException ("name specifies a font that is not installed on the computer running the application.");
            else
            {
                var attrs = nativeFontDescriptor.GetAttributes ();
                familyName = attrs.FamilyName;
                // if the font description attributes do not contain a value for FamilyName then we
                // need to try and create the font to get the family name from the actual font.
                if (string.IsNullOrEmpty (familyName))
                {
                    var font = new CTFont (nativeFontDescriptor, 0);
                    familyName = font.FamilyName;
                }
            }
        }
コード例 #36
0
ファイル: AppleMathFont.cs プロジェクト: Gillibald/CSharpMath
 public AppleMathFont(AppleMathFont cloneMe, float pointSize) : this(pointSize) {
     Name   = cloneMe.Name;
     CgFont = cloneMe.CgFont;
     CtFont = new CTFont(CgFont, pointSize, CGAffineTransform.MakeIdentity());
 }