public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] custerMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { if (glyphs == null) { return; } var previousTransform = drawingSession.Transform; drawingSession.Transform = CanvasTextLayout.GetGlyphOrientationTransform(glyphOrientation, isSideways, position); drawingSession.DrawGlyphRun( position, fontFace, fontSize, glyphs, isSideways, bidiLevel, textBrush); drawingSession.Transform = previousTransform; }
public FontVariant(CanvasFontFace face, string familyName, StorageFile file) { FontFace = face; Characters = new List <Character>(); FamilyName = familyName; if (file != null) { IsImported = true; FileName = file.Name; Source = $"{FontFinder.GetAppPath(file)}#{familyName}"; } else { Source = familyName; } if (!face.FaceNames.TryGetValue(CultureInfo.CurrentCulture.Name, out string name)) { if (!face.FaceNames.TryGetValue("en-us", out name)) { if (face.FaceNames.Any()) { name = face.FaceNames.FirstOrDefault().Value; } else { name = Utils.GetVariantDescription(face); } } } PreferredName = name; }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] clusterMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { var script = GetScript(textPosition); CanvasTypographyFeatureName[] features = fontFace.GetSupportedTypographicFeatureNames(script); foreach (var featureName in features) { TypographyFeatureInfo featureInfo = new TypographyFeatureInfo(featureName); if (!TypographyOptions.Contains(featureInfo)) { TypographyOptions.Add(featureInfo); } } }
public FontVariant(CanvasFontFace face, StorageFile file, DWriteProperties dwProps) { FontFace = face; FamilyName = dwProps.FamilyName; if (file != null) { IsImported = true; FileName = file.Name; Source = $"{FontFinder.GetAppPath(file)}#{dwProps.FamilyName}"; } else { Source = dwProps.FamilyName; } string name = dwProps.FaceName; if (String.IsNullOrEmpty(name)) { name = Utils.GetVariantDescription(face); } DirectWriteProperties = dwProps; PreferredName = name; Panose = PanoseParser.Parse(face); }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] custerMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { Metrics m = new Metrics(); m.Ascent = fontFace.Ascent; m.LineGap = fontFace.LineGap; m.Descent = fontFace.Descent; m.CapHeight = fontFace.CapHeight; m.LowercaseLetterHeight = fontFace.LowercaseLetterHeight; m.Bounds = fontFace.GetGlyphRunBounds( drawingSession, position, fontSize, glyphs, isSideways, bidiLevel); GlyphRunMetrics.Add(m); }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] custerMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { CanvasGeometry geometry = CanvasGeometry.CreateGlyphRun( resourceCreator, position, fontFace, fontSize, glyphs, isSideways, bidiLevel, measuringMode, glyphOrientation); geometries.Add(geometry); }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] clusterMapIndices, uint startingTextPosition, CanvasGlyphOrientation glyphOrientation) { if (glyphs == null || glyphs.Length == 0) { return; } float scaledFontAscent = fontFace.Ascent * fontSize; float subscriptBaselineDropAmount = scaledFontAscent * subscriptBaselineScale; float superscriptBaselineRaiseAmount = scaledFontAscent * superscriptBaselineScale; // Draw glyph-by-glyph. for (int i = 0; i < glyphs.Length; ++i) { CanvasGlyph[] singleGlyph = new CanvasGlyph[1]; singleGlyph[0] = glyphs[i]; Vector2 positionForThisGlyph = position; CustomBrushData brushData = (CustomBrushData)brush; if (brushData != null) { if (brushData.BaselineAdjustment == CustomBrushData.BaselineAdjustmentType.Lower) { positionForThisGlyph.Y += subscriptBaselineDropAmount; } else if (brushData.BaselineAdjustment == CustomBrushData.BaselineAdjustmentType.Raise) { positionForThisGlyph.Y -= superscriptBaselineRaiseAmount; } } DrawingSession.DrawGlyphRun( positionForThisGlyph, fontFace, fontSize, singleGlyph, isSideways, bidiLevel, TextBrush); position.X += glyphs[i].Advance; } }
private static byte[] GetGlyphBytes(CanvasFontFace fontface, int unicodeIndex, int imageType) { Interop interop = SimpleIoc.Default.GetInstance <Interop>(); IBuffer buffer = interop.GetImageDataBuffer(fontface, 1024, (uint)unicodeIndex, (uint)imageType); using (DataReader reader = DataReader.FromBuffer(buffer)) { byte[] bytes = new byte[buffer.Length]; reader.ReadBytes(bytes); return(bytes); } }
void BeginGlyphRun(Rect rectangle, float advance, List <GlyphRun> glyphRuns, CanvasFontFace fontFace, float fontSize, bool isRightToLeft) { GlyphRun glyphRun = new GlyphRun(); float glyphRunXPosition = isRightToLeft ? (float)rectangle.Right - advance : (float)rectangle.Left + advance; glyphRun.Position = new System.Numerics.Vector2(glyphRunXPosition, (float)rectangle.Bottom); glyphRun.Glyphs = new List <CanvasGlyph>(); glyphRun.FontFace = fontFace; glyphRun.FontSize = fontSize; glyphRun.IsRightToLeft = isRightToLeft; glyphRuns.Add(glyphRun); }
public static FontVariant CreateDefault(CanvasFontFace face) { return(new FontVariant(face, "Segoe UI", null) { PreferredName = "", Characters = new List <Character> { new Character { Char = "", UnicodeIndex = 0 } } }); }
public static string GetVariantDescription(CanvasFontFace fontFace) { StringBuilder s = new StringBuilder(); s.Append(GetWeightName(fontFace.Weight)); if (fontFace.Style != FontStyle.Normal) { s.AppendFormat(", {0}", fontFace.Style); } if (fontFace.Stretch != FontStretch.Normal) { s.AppendFormat(", {0}", fontFace.Stretch); } return(s.ToString()); }
private static KeyValuePair <string, string> GetInfoKey(CanvasFontFace fontFace, CanvasFontInformation info) { var infos = fontFace.GetInformationalStrings(info); if (infos.Count == 0) { return(new KeyValuePair <string, string>()); } var name = info.Humanize().Transform(To.TitleCase); var dic = infos.ToDictionary(k => k.Key, k => k.Value); if (infos.TryGetValue(CultureInfo.CurrentCulture.Name, out string value) || infos.TryGetValue("en-us", out value)) { return(KeyValuePair.Create(name, value)); } return(KeyValuePair.Create(name, infos.First().Value)); }
public void DrawGlyphRun(Vector2 point, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string localeName, string textString, int[] clusterMapIndices, uint characterIndex, CanvasGlyphOrientation glyphOrientation) { Matrix3x2 OTrans = ds.Transform; int i = 0; if (characterIndex == 0) { ds.Transform = Matrix3x2.CreateTranslation(new Vector2(-0.5f * PTextW, -R)) * Matrix3x2.CreateRotation(Offset, Origin); ds.DrawGlyphRun(Origin, fontFace, fontSize, new CanvasGlyph[] { glyphs[0] }, isSideways, bidiLevel, Brush); MovingRad = 0; i++; } while (i < glyphs.Length) { float TextW = TextWidths[i + characterIndex]; float Rad = TextW / R; float OffsetRad = 0.5f * (PTextW + TextW) / R + MovingRad; MovingRad += Rad; // Stop drawing texts if ring is already crowded if (6.2831f < (OffsetRad + Rad)) { break; } ds.Transform = Matrix3x2.CreateTranslation(new Vector2(-0.5f * TextW, -R)) * Matrix3x2.CreateRotation(OffsetRad + Offset, Origin); ds.DrawGlyphRun(Origin, fontFace, fontSize, new CanvasGlyph[] { glyphs[i] }, isSideways, bidiLevel, Brush); i++; } ds.Transform = OTrans; }
public static Panose Parse(CanvasFontFace fontFace) { byte[] panose = fontFace.Panose; // The contents of the Panose byte array depends on the value of the first byte. // See https://docs.microsoft.com/en-us/windows/win32/api/dwrite_1/ns-dwrite_1-dwrite_panose // for how the Family value changes the meaning of the following 9 bytes. PanoseFamily family = (PanoseFamily)panose[0]; // Only fonts in TextDisplay family will identify their serif style SerifStyle style = SerifStyle.Any; if (family == PanoseFamily.TextDisplay) { style = (SerifStyle)panose[1]; } // Warning - not all fonts store correct values for Panose information. // If expanding PanoseParser in the future to read all values, direct casting // enums may lead to errors - safer parsing may be needed to take into account // faulty panose classifications. return(new Panose(family, style)); }
private static IBuffer GetGlyphBuffer(CanvasFontFace fontface, uint unicodeIndex, GlyphImageFormat format) { return(DirectWrite.GetImageDataBuffer(fontface, 1024, unicodeIndex, format)); }
private static float GetLineSpacing(CanvasFontFace fontFace, float fontSize) { return((fontFace.LineGap + fontFace.Ascent + fontFace.Descent) * fontSize); }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] clusterMapIndices, uint startingTextPosition, CanvasGlyphOrientation glyphOrientation) { if (glyphs == null || glyphs.Length == 0) return; float scaledFontAscent = fontFace.Ascent * fontSize; float subscriptBaselineDropAmount = scaledFontAscent * subscriptBaselineScale; float superscriptBaselineRaiseAmount = scaledFontAscent * superscriptBaselineScale; // Draw glyph-by-glyph. for (int i = 0; i < glyphs.Length; ++i) { CanvasGlyph[] singleGlyph = new CanvasGlyph[1]; singleGlyph[0] = glyphs[i]; Vector2 positionForThisGlyph = position; CustomBrushData brushData = (CustomBrushData)brush; if (brushData != null) { if (brushData.BaselineAdjustment == CustomBrushData.BaselineAdjustmentType.Lower) { positionForThisGlyph.Y += subscriptBaselineDropAmount; } else if (brushData.BaselineAdjustment == CustomBrushData.BaselineAdjustmentType.Raise) { positionForThisGlyph.Y -= superscriptBaselineRaiseAmount; } } DrawingSession.DrawGlyphRun( positionForThisGlyph, fontFace, fontSize, singleGlyph, isSideways, bidiLevel, TextBrush); position.X += glyphs[i].Advance; } }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] clusterMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { var script = GetScript(textPosition); if (CurrentMode == Mode.BuildTypographyList) { CanvasTypographyFeatureName[] features = fontFace.GetSupportedTypographicFeatureNames(script); foreach (var featureName in features) { TypographyFeatureInfo featureInfo = new TypographyFeatureInfo(featureName); if (!TypographyOptions.Contains(featureInfo)) { TypographyOptions.Add(featureInfo); } } } else { if (glyphs == null || glyphs.Length == 0) return; // // This demo handles only simple Latin text with no diacritical // markers or ligatures, so we can make assumptions about the // mapping of text positions to glyph indices. This works fine for // the sake of this example. // // In general, apps should use the cluster map to map text // positions to glyphs while knowing that glyph substitution can happen // for reasons besides typography. // uint[] codePoints = new uint[glyphs.Length]; for (int i = 0; i < glyphs.Length; i++) { int glyphTextPosition = 0; for (int j=0; j<clusterMapIndices.Length; j++) { if (clusterMapIndices[j] == i) { glyphTextPosition = j; break; } } codePoints[i] = textString[glyphTextPosition]; } int[] nominalGlyphIndices = fontFace.GetGlyphIndices(codePoints); CanvasGlyph[] unsubstitutedGlyphs = new CanvasGlyph[glyphs.Length]; for (int i = 0; i < glyphs.Length; i++) { unsubstitutedGlyphs[i] = glyphs[i]; unsubstitutedGlyphs[i].Index = nominalGlyphIndices[i]; } bool[] eligible = fontFace.GetTypographicFeatureGlyphSupport(script, FeatureToHighlight, unsubstitutedGlyphs); var highlightBrush = new CanvasSolidColorBrush(currentDrawingSession, Colors.Yellow); for (int i = 0; i < glyphs.Length; ++i) { if (eligible[i]) { CanvasGlyph[] singleGlyph = new CanvasGlyph[1]; singleGlyph[0] = glyphs[i]; currentDrawingSession.DrawGlyphRun( position, fontFace, fontSize, singleGlyph, isSideways, bidiLevel, highlightBrush); } position.X += glyphs[i].Advance; } } }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] custerMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { if (glyphs == null) return; var previousTransform = drawingSession.Transform; drawingSession.Transform = CanvasTextLayout.GetGlyphOrientationTransform(glyphOrientation, isSideways, position); drawingSession.DrawGlyphRun( position, fontFace, fontSize, glyphs, isSideways, bidiLevel, textBrush); drawingSession.Transform = previousTransform; }
public void DrawGlyphRun(Vector2 point, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string localeName, string textString, int[] clusterMapIndices, uint characterIndex, CanvasGlyphOrientation glyphOrientation) { if (points == null) { Vector2 adv = Vector2.Zero; for (int it = 0; it < glyphs.Length; it++) { var previousTransform = drawingSession.Transform; var drawPoint = point + adv; var rotationPoint = point + adv + new Vector2(glyphs[it].Advance / 2f, -fontSize / 4f); drawingSession.Transform = Matrix3x2.CreateRotation(it * 0.01f, rotationPoint); drawingSession.DrawCircle(point + adv + rotationPoint, 0.022f, Colors.Red); drawingSession.DrawGlyphRun( drawPoint, fontFace, fontSize, new CanvasGlyph[] { glyphs[it] }, isSideways, bidiLevel, defaultBrush); drawingSession.Transform = previousTransform; adv += new Vector2(glyphs[it].Advance * Spacing, 0); } } else { float textLength = 0; foreach (var g in glyphs) { textLength += g.Advance; } if (textLength * 3f > dists.Last()) { return; } var labelCount = MathF.Truncate(dists.Last() / (textLength * 3)); labelCount = MathF.Truncate(MathF.Min(labelCount, MathF.Sqrt(labelCount))); var labelSegmentLength = dists.Last() / labelCount; // DEBUG //CanvasPathBuilder path = new CanvasPathBuilder(drawingSession); //path.BeginFigure(points[0]); //points.ToList().ForEach(p => path.AddLine(p)); //path.EndFigure(CanvasFigureLoop.Open); //drawingSession.DrawGeometry(CanvasGeometry.CreatePath(path), Colors.Blue, 0.1f); // ===== for (int label = 0; label < labelCount; label++) { LinearPosition = labelSegmentLength * label + (labelSegmentLength / 2f) - (textLength / 2f); Vector2 adv = Vector2.Zero; for (int it = 0; it < glyphs.Length; it++) { var online = PositionAngleOnPoly(adv.X); var drawPoint = online.pos; var c = fontSize / 4f; var ox = MathF.Cos(online.a + MathF.PI / 2f) * c; var oy = MathF.Sin(online.a + MathF.PI / 2f) * c; drawPoint += new Vector2(ox, oy); var rotationPoint = drawPoint; // + new Vector2(glyphs[it].Advance / 2f, -fontSize / 4f); //drawingSession.DrawCircle(rotationPoint, 0.022f, Colors.Red); var previousTransform = drawingSession.Transform; drawingSession.Transform = Matrix3x2.CreateRotation(online.a, rotationPoint); drawingSession.DrawGlyphRun( drawPoint, fontFace, fontSize, new CanvasGlyph[] { glyphs[it] }, isSideways, bidiLevel, defaultBrush); drawingSession.Transform = previousTransform; adv += new Vector2(glyphs[it].Advance * Spacing, 0); } } } //drawingSession.DrawGlyphRun(point, fontFace, fontSize, glyphs, isSideways, bidiLevel, defaultBrush); }
private static IBuffer GetGlyphBuffer(CanvasFontFace fontface, uint unicodeIndex, GlyphImageFormat format) { return(Utils.GetInterop().GetImageDataBuffer(fontface, 1024, unicodeIndex, format)); }
public void DrawGlyphRun( Vector2 position, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string locale, string textString, int[] clusterMapIndices, uint textPosition, CanvasGlyphOrientation glyphOrientation) { var script = GetScript(textPosition); if (CurrentMode == Mode.BuildTypographyList) { CanvasTypographyFeatureName[] features = fontFace.GetSupportedTypographicFeatureNames(script); foreach (var featureName in features) { TypographyFeatureInfo featureInfo = new TypographyFeatureInfo(featureName); if (!TypographyOptions.Contains(featureInfo)) { TypographyOptions.Add(featureInfo); } } } else { if (glyphs == null || glyphs.Length == 0) { return; } // // This demo handles only simple Latin text with no diacritical // markers or ligatures, so we can make assumptions about the // mapping of text positions to glyph indices. This works fine for // the sake of this example. // // In general, apps should use the cluster map to map text // positions to glyphs while knowing that glyph substitution can happen // for reasons besides typography. // uint[] codePoints = new uint[glyphs.Length]; for (int i = 0; i < glyphs.Length; i++) { int glyphTextPosition = 0; for (int j = 0; j < clusterMapIndices.Length; j++) { if (clusterMapIndices[j] == i) { glyphTextPosition = j; break; } } codePoints[i] = textString[glyphTextPosition]; } int[] nominalGlyphIndices = fontFace.GetGlyphIndices(codePoints); CanvasGlyph[] unsubstitutedGlyphs = new CanvasGlyph[glyphs.Length]; for (int i = 0; i < glyphs.Length; i++) { unsubstitutedGlyphs[i] = glyphs[i]; unsubstitutedGlyphs[i].Index = nominalGlyphIndices[i]; } bool[] eligible = fontFace.GetTypographicFeatureGlyphSupport(script, FeatureToHighlight, unsubstitutedGlyphs); var highlightBrush = new CanvasSolidColorBrush(currentDrawingSession, Colors.Yellow); for (int i = 0; i < glyphs.Length; ++i) { if (eligible[i]) { CanvasGlyph[] singleGlyph = new CanvasGlyph[1]; singleGlyph[0] = glyphs[i]; currentDrawingSession.DrawGlyphRun( position, fontFace, fontSize, singleGlyph, isSideways, bidiLevel, highlightBrush); } position.X += glyphs[i].Advance; } } }
public SystemFont(string name, CanvasFontFace fontFace) { Name = name; FontFamily = new FontFamily(name); FontFace = fontFace; }