/// <summary> /// 文字描画関数に渡されるフォント構造体を初期化する /// </summary> /// <param name="fontFace">フォント名の識別子</param> /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param> /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param> /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param> /// <param name="thickness">文字の太さ.</param> /// <param name="lineType">線の種類.</param> #else /// <summary> /// Initializes font structure /// </summary> /// <param name="fontFace">Font name identifier. Only a subset of Hershey fonts are supported now.</param> /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param> /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param> /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param> /// <param name="thickness">Thickness of the text strokes. </param> /// <param name="lineType">Type of the strokes, see cvLine description. </param> #endif public CvFont(FontFace fontFace, double hscale, double vscale, double shear, int thickness, LineType lineType) { ptr = AllocMemory(SizeOf); CvInvoke.cvInitFont(ptr, fontFace, hscale, vscale, shear, thickness, lineType); }
public void Dispose() { FontFace?.Dispose(); FontFace = null; }
/// <summary> /// returns bounding box of the text string /// </summary> /// <param name="text"></param> /// <param name="fontFace"></param> /// <param name="fontScale"></param> /// <param name="thickness"></param> /// <param name="baseLine"></param> /// <returns></returns> public static Size GetTextSize(string text, FontFace fontFace, double fontScale, int thickness, out int baseLine) { if (String.IsNullOrEmpty(text)) throw new ArgumentNullException(text); return NativeMethods.core_getTextSize(text, (int)fontFace, fontScale, thickness, out baseLine); }
internal void SetFont(string filename) { FontFace?.Dispose(); FontFace = new Face(lib, filename); SetSize(this.Size); }
private static void GetKerningInfo(CCRawList <char> charset) { _abcValues.Clear(); var fontFace = new FontFace(_currentFont); var value = new ABCFloat[1]; var glyphRun = new GlyphRun(); glyphRun.FontFace = fontFace; glyphRun.FontSize = _currentDIP; /* * var BrushColor = new RawColor3(1.0f, 1.0f, 1.0f); * * SharpDX.DirectWrite.Matrix mtrx = new SharpDX.DirectWrite.Matrix(); * mtrx.M11 = 1F; * mtrx.M12 = 0; * mtrx.M21 = 0; * mtrx.M22 = 1F; * mtrx.Dx = 0; * mtrx.Dy = 0; */ //GlyphMetrics[] metrics = fontFace.GetGdiCompatibleGlyphMetrics(23, 1, mtrx, false, glyphIndices, false); //FontMetrics metr = fontFace.GetGdiCompatibleMetrics(23, 1, new SharpDX.DirectWrite.Matrix()); //_pRenderTarget.DrawGlyphRun(new SharpDX.DrawingPointF(left, top), glyphRun, new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, BrushColor), MeasuringMode.GdiClassic); int[] codePoints = new int[1]; var unitsPerEm = fontFace.Metrics.DesignUnitsPerEm; var familyName = _currentFont.ToString(); for (int i = 0; i < charset.Count; i++) { var ch = charset[i]; if (!_abcValues.ContainsKey(ch)) { var textLayout = new TextLayout(FactoryDWrite, ch.ToString(), textFormat, unitsPerEm, unitsPerEm); var tlMetrics = textLayout.Metrics; var tlmWidth = tlMetrics.Width; var tllWidth = tlMetrics.LayoutWidth; codePoints[0] = (int)ch; short[] glyphIndices = fontFace.GetGlyphIndices(codePoints); glyphRun.Indices = glyphIndices; var metrics = fontFace.GetDesignGlyphMetrics(glyphIndices, false); //var width = metrics[0].AdvanceWidth + metrics[0].LeftSideBearing + metrics[0].RightSideBearing; //var glyphWidth = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm; //var abcWidth = _currentDIP * (float)width / unitsPerEm; //value[0].abcfA = _currentFontSizeEm * (float)metrics[0].LeftSideBearing / unitsPerEm; //value[0].abcfB = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm; //value[0].abcfC = _currentFontSizeEm * (float)metrics[0].RightSideBearing / unitsPerEm; // The A and C values are throwing the spacing off //value[0].abcfA = _currentDIP * (float)metrics[0].LeftSideBearing / unitsPerEm; value[0].abcfB = _currentDIP * (float)metrics[0].AdvanceWidth / unitsPerEm; //value[0].abcfC = _currentDIP * (float)metrics[0].RightSideBearing / unitsPerEm; _abcValues.Add( ch, new KerningInfo() { A = value[0].abcfA, B = value[0].abcfB, C = value[0].abcfC }); } } }
public static extern void cvInitFont(IntPtr font, FontFace font_face, double hscale, double vscale, double shear, int thickness, [MarshalAs(UnmanagedType.U4)] LineType line_type);
unsafe GlyphRect GetGlyph(uint fontHash, FontFace fontFace, short glyphIndex, float fontSize) { var glyphHash = GlyphHash(fontFace, fontHash, glyphIndex); GlyphRect grect; if (!glyphs.TryGetValue(glyphHash, out grect)) { var metrics = fontFace.Metrics; var glyphMetrics = fontFace.GetDesignGlyphMetrics(new short[] { glyphIndex }, false)[0]; var run = new GlyphRun(); run.FontFace = fontFace; run.FontSize = fontSize; run.Indices = new short[] { glyphIndex }; run.Advances = new float[] { 0 }; run.Offsets = new GlyphOffset[] { new GlyphOffset() }; var gdata = new ComputedSize(fontSize, metrics, glyphMetrics); var fillRect = new GDI.RECT() { left = 0, top = 0, right = 2 + gdata.maxWidth + 5, bottom = 2 + gdata.maxHeight + 5 }; GDI.FillRect(hdc, ref fillRect, hBrush); RawRectangle rect; renderTarget.DrawGlyphRun(2.0f - gdata.offsetX, 2.0f - gdata.offsetY, D2D1.MeasuringMode.Natural, run, renderParams, new RawColorBGRA(255, 255, 255, 255), out rect); var left = rect.Left < 0 ? 0 : rect.Left; var right = rect.Right > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Right; var top = rect.Top < 0 ? 0 : rect.Top; var bottom = rect.Bottom > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Bottom; var r = new Rectangle(0, 0, right - left, bottom - top); //Construct grayscale image from GDI byte[] data = new byte[r.Width * r.Height * 4]; byte * srcData = (byte *)bmBits; for (int y = 0; y < r.Height; y++) { for (int x = 0; x < r.Width; x++) { var destP = (y * r.Width * 4) + (x * 4); var pixel = srcData[(top + y) * bytesPerPixel * MAX_GLYPH_SIZE + (left + x) * bytesPerPixel]; data[destP] = data[destP + 1] = data[destP + 2] = 255; data[destP + 3] = (byte)(Math.Pow(pixel / 255.0, 1.0 / 1.45) * 255.0); } } // if (currentX + r.Width > MAX_GLYPH_SIZE) { currentX = 0; currentY += maxLineHeight; maxLineHeight = 0; } if (currentY + r.Height > MAX_GLYPH_SIZE) { pages.Add(new Texture2D(TEXT_PAGE_SIZE, TEXT_PAGE_SIZE, false, SurfaceFormat.Color)); currentX = currentY = maxLineHeight = 0; } r.X = currentX; r.Y = currentY; maxLineHeight = Math.Max(maxLineHeight, r.Height); currentX += r.Width; var page = pages[pages.Count - 1]; page.SetData(0, r, data, 0, data.Length); grect.Texture = page; grect.OffsetX = (int)(gdata.offsetX + left - 2); grect.OffsetY = (int)(gdata.offsetY + top - 2); grect.Rectangle = r; glyphs.Add(glyphHash, grect); } return(grect); }
public IFontFamily[] Initialize() { var familyList = new List <DXFontFamily>(); var families = new Dictionary <string, DXFontFamily>(); var fontCollection = DXGraphicsService.FactoryDirectWrite.GetSystemFontCollection(false); int familyCount = fontCollection.FontFamilyCount; for (int i = 0; i < familyCount; i++) { var fontFamily = fontCollection.GetFontFamily(i); var familyNames = fontFamily.FamilyNames; if (!familyNames.FindLocaleName("en-us", out var index)) { index = 0; } var familyName = familyNames.GetString(index); for (int j = 0; j < fontFamily.FontCount; j++) { string postScriptName = familyName; var font = fontFamily.GetFont(j); var found = font.GetInformationalStrings(InformationalStringId.PostscriptName, out var localizedPostScriptName); if (found) { postScriptName = localizedPostScriptName.GetString(0); } if (!families.TryGetValue(familyName, out var family)) { family = new DXFontFamily(familyName); families[familyName] = family; familyList.Add(family); } var id = postScriptName; if (!font.FaceNames.FindLocaleName("en-us", out index)) { index = 0; } var name = font.FaceNames.GetString(index); var fullName = familyName; if (!("Regular".Equals(name) || "Plain".Equals(name) || "Normal".Equals(name))) { fullName = string.Format("{0} {1}", familyName, name); } var fontFace = new FontFace(font); var style = new DXFontStyle(family, id, name, fullName, font.Style, font.Weight, fontFace); family.AddStyle(style); } } familyList.Sort(); foreach (var family in familyList) { family.RemoveDuplicates(); } return(familyList.OfType <IFontFamily>().ToArray()); }
public void SetGlyphRun(float x, float y, int glyphCount, short[] glyphIndices, float[] glyphAdvances, GlyphOffset[] glyphOffsets, FontFace fontface, float fontEmSize, int BidiLevel, bool isSideways) { // Append this glyph run to the list. int glyphStart = glyphAdvances_.Count; glyphAdvances_.AddRange(glyphAdvances); glyphIndices_.AddRange(glyphIndices); glyphOffsets_.AddRange(glyphOffsets); glyphRuns_.Add(new CustomGlyphRun(fontface, fontEmSize, x, y, glyphStart, glyphCount, BidiLevel, isSideways)); }
internal static unsafe void Main(string[] args) { try { int pixelsCount = 1 << 18; uint[] pixelsArray = new uint[65536]; using (DisposableHandle handle = DisposableHandle.Alloc(pixelsArray)) { NTInvoke.SetUnmanagedMemory(handle, 255, pixelsCount); } byte[] outputData = null; MCvScalar redColor = MCvScalarExtensions.FromColor(Colors.Red); MCvScalar greenColor = MCvScalarExtensions.FromColor(Colors.Green); using (PresentationImage prImage = new PresentationImage(256, 256)) { prImage.WritePixels(pixelsArray); FontFace[] faces = new FontFace[] { FontFace.HersheyComplex, FontFace.HersheyComplexSmall, FontFace.HersheyDuplex, FontFace.HersheyPlain, FontFace.HersheyScriptComplex, FontFace.HersheyScriptSimplex, FontFace.HersheySimplex, FontFace.HersheyTriplex }; Parallel.For(0, 8, (int index) => { Point drawPoint = new Point(10, 30 + 30 * index); FontFace drawFace = faces[index]; string outputText = Enum.GetName(typeof(FontFace), drawFace); CvInvoke.DrawText(prImage, outputText, drawPoint, drawFace, 1.0D, redColor, 1); }); outputData = CvInvoke.Imencode(prImage, ImageEncoding.Jpeg, new int[] { 95 }); } if (outputData != null && outputData.Length > 0) { using (MemoryStream dataStream = new MemoryStream(outputData)) { JpegBitmapDecoder decoder = new JpegBitmapDecoder(dataStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad); BitmapFrame frame = decoder.Frames[0]; Window imageWindow = new Window() { Height = 300.0D, Width = 500.0D, Title = "Image window", ResizeMode = ResizeMode.CanResize, WindowStartupLocation = WindowStartupLocation.CenterScreen }; imageWindow.Content = new Image() { Source = frame }; new Application().Run(imageWindow); } } } catch (Exception exc) { Debug.WriteLine("\tCatched exception: {0}\r\n{1}", exc.Message, exc); } finally { Debug.WriteLine("\tData released succesfully."); } }
protected override bool Init(object controller, object binding, DefinitionFile definition) { if (!base.Init(controller, binding, definition)) { return(false); } DefinitionFileWithStyle file = new DefinitionFileWithStyle(definition, typeof(UiRichView)); string defaultFont = file["Font"] as string; int defaultFontSize = DefinitionResolver.Get <int>(Controller, Binding, file["FontSize"], 0); int defaultFontSpacing = DefinitionResolver.Get <int>(Controller, Binding, file["FontSpacing"], int.MaxValue); for (int idx = 0; idx < (int)FontType.Count; ++idx) { FontType type = (FontType)idx; string font = string.Format("{0}.Font", type); string spacing = string.Format("{0}.FontSpacing", type); string resize = string.Format("{0}.FontResize", type); string fontName = file[font] as string; int fontSpacing = DefinitionResolver.Get <int>(Controller, Binding, file[spacing], defaultFontSpacing == int.MaxValue ? 0 : defaultFontSpacing); int fontResize = DefinitionResolver.Get <int>(Controller, Binding, file[resize], 0); if (fontName == null) { fontName = defaultFont; } FontFace fontObj = FontManager.Instance.FindFont(fontName); if (defaultFont == null) { defaultFont = fontName; } if (defaultFontSpacing == int.MaxValue) { defaultFontSpacing = fontSpacing; } _fonts[idx] = new FontInfo() { Font = fontObj, FontSpacing = (float)fontSpacing / 1000.0f, FontResize = fontResize }; } for (int idx = 0; idx < (int)SizeType.Count; ++idx) { SizeType type = (SizeType)idx; string size = string.Format("{0}.FontSize", type); int fontSize = DefinitionResolver.Get <int>(Controller, Binding, file[size], defaultFontSize); if (defaultFontSize == 0) { defaultFontSize = fontSize; } _sizes[idx] = fontSize; } _bulletText = DefinitionResolver.GetString(Controller, Binding, file["BulletText"]) ?? "* "; //_bulletText = _bulletText.Replace(" ", ((char)0xa0).ToString()); _horizontalRulerHeight = DefinitionResolver.Get <Length>(Controller, Binding, file["HorizontalRulerHeight"], new Length(0, 0, 1)); _indentSize = DefinitionResolver.Get <Length>(Controller, Binding, file["Indent"], Length.Zero); _paragraphSpacing = DefinitionResolver.Get <Length>(Controller, Binding, file["ParagraphSpacing"], Length.Zero); _lineHeight = (float)DefinitionResolver.Get <int>(Controller, Binding, file["LineHeight"], 100) / 100.0f; _justify = DefinitionResolver.Get <bool>(Controller, Binding, file["Justify"], false); Type processorType = file["Processor"] as Type; if (processorType != null) { _richProcessor = Activator.CreateInstance(processorType) as IRichProcessor; } Text = DefinitionResolver.GetString(Controller, Binding, file["Text"]); _colorNormal = DefinitionResolver.GetColorWrapper(Controller, Binding, file["TextColor"]) ?? UiLabel.DefaultTextColor; _colorClickable = DefinitionResolver.GetColorWrapper(Controller, Binding, file["LinkColor"]) ?? UiLabel.DefaultTextColor; _colorClickableActive = DefinitionResolver.GetColorWrapper(Controller, Binding, file["ActiveLinkColor"]) ?? _colorClickable; _colorRuler = DefinitionResolver.GetColorWrapper(Controller, Binding, file["HorizontalRulerColor"]) ?? UiLabel.DefaultTextColor; HorizontalContentAlignment horzAlign = DefinitionResolver.Get <HorizontalContentAlignment>(Controller, Binding, file["HorizontalContentAlignment"], HorizontalContentAlignment.Left); VerticalContentAlignment vertAlign = DefinitionResolver.Get <VerticalContentAlignment>(Controller, Binding, file["VerticalContentAlignment"], VerticalContentAlignment.Top); _textAlign = UiHelper.TextAlignFromContentAlignment(horzAlign, vertAlign); _clickMargin = DefinitionResolver.Get <Length>(Controller, Binding, file["ClickMargin"], Length.Zero); RegisterDelegate("UrlClick", file["UrlClick"]); EnabledGestures = (GestureType.Down | GestureType.Up | GestureType.Move | GestureType.Tap); return(true); }
internal static pTexture CreateText(string text, float size, Vector2 restrictBounds, Color color, ShadowType shadow, bool bold, bool italic, bool underline, TextAlignment alignment, bool forceAa, out Vector2 measured, out RectangleF[] characterRegions, Color background, Color border, int borderWidth, bool measureOnly, bool getCharacterRegions, FontFace fontFace, Vector4 cornerBounds, Vector2 padding, pTexture lastTexture = null, int startIndex = 0, int length = -1) { characterRegions = null; if (text == null) { measured = Vector2.Zero; return(null); } if (ConfigManager.dDisableTextRendering) { measured = new Vector2(text.Length * size, size); return(null); } #if DEBUG if (!text.Contains(@"NativeText")) { int limit_per_second = osu.GameModes.Play.Player.Playing ? 5 : 58; bool newSecond = GameBase.Time / 1000 != currentSecond; drawCount++; if (drawCount == limit_per_second) { Debug.Print(@"NativeText: High number of text refreshes per second."); } if (newSecond) { currentSecond = GameBase.Time / 1000; drawCount = 0; } } #endif //This lock ensures we are only using the shared GDI+ object (FromHwnd) in one place at a time. lock (createTextLock) { try { using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero)) using (StringFormat sf = new StringFormat()) { if (dpiRatio == 0) { dpiRatio = 96 / graphics.DpiX; } size *= dpiRatio; GameBase.PerformanceMonitor.ReportCount(CounterType.NativeText); graphics.TextRenderingHint = TextRenderingHint.AntiAlias; SizeF measuredSize; string face = GetFontFace(fontFace); if (face.StartsWith(@"Aller")) { //if we are using the default osu! font, allow specific language overrides based on simple detection. string fontFaceOverride = getLanguageSpeicificFont(text); if (fontFaceOverride != null) { face = fontFaceOverride; } } if (startIndex != 0 || length > 0) { text = text.Substring(startIndex, length); } else if (length == -1) { length = text.Length; } if (size < 20 && face.EndsWith(@" Light")) { face = face.Replace(@" Light", string.Empty); } FontStyle fs = FontStyle.Regular; if (bold) { if (face.EndsWith(@" Light")) { face = face.Replace(@" Light", string.Empty); } fs |= FontStyle.Bold; } if (italic) { fs |= FontStyle.Italic; } if (underline) { fs |= FontStyle.Underline; } switch (alignment) { case TextAlignment.Left: case TextAlignment.LeftFixed: sf.Alignment = StringAlignment.Near; break; case TextAlignment.Centre: sf.Alignment = StringAlignment.Center; break; case TextAlignment.Right: sf.Alignment = StringAlignment.Far; break; } if (!OsuMain.IsWine && face.StartsWith(@"Aller")) { for (char c = '0'; c <= '9'; c++) { text = text.Replace(c, (char)(c + (0xf83c - '0'))); } } Font f = GetFont(face, size * ScaleModifier, fs); if (ScaleModifier != 1) { restrictBounds *= ScaleModifier; } try { if (text.Length == 0) { text = " "; } measuredSize = restrictBounds != Vector2.Zero ? graphics.MeasureString(text, f, new SizeF(restrictBounds.X, restrictBounds.Y), sf) : graphics.MeasureString(text, f); } catch (InvalidOperationException) { measured = Vector2.Zero; return(null); } int width = (int)(measuredSize.Width + 1); int height = (int)(measuredSize.Height + 1); if (restrictBounds.Y != 0) { height = (int)restrictBounds.Y; } if (restrictBounds.X != 0 && (alignment != TextAlignment.Left || background.A > 0)) { width = (int)restrictBounds.X; } if (padding != Vector2.Zero && restrictBounds == Vector2.Zero) { width += (int)(padding.X * 2); height += (int)(padding.Y * 2); } measured = new Vector2(width, height); float offset = Math.Max(0.5f, Math.Min(1f, (size * ScaleModifier) / 14)); if (getCharacterRegions) { characterRegions = new RectangleF[text.Length]; // SetMeasurableCharacterRanges only accepts a maximum of 32 intervals to be queried, so we as the library user are // forced to split the string into 32 character long chunks and perform MeasureCharacterRanges on each. int numIntervals = (text.Length / 32) + 1; for (int i = 0; i < numIntervals; ++i) { int offsetIndex = i * 32; int end = Math.Min(text.Length - offsetIndex, 32); CharacterRange[] characterRanges = new CharacterRange[end]; for (int j = 0; j < end; ++j) { characterRanges[j] = new CharacterRange(j + offsetIndex, 1); } sf.SetMeasurableCharacterRanges(characterRanges); Region[] regions = graphics.MeasureCharacterRanges( text, f, new RectangleF( padding.X, padding.Y, restrictBounds.X == 0 ? Single.PositiveInfinity : restrictBounds.X, restrictBounds.Y == 0 ? Single.PositiveInfinity : restrictBounds.Y), sf); for (int j = 0; j < end; ++j) { Region region = regions[j] as Region; characterRegions[j + offsetIndex] = region.GetBounds(graphics); } } } if (measureOnly) { int startSpace = 0; int endSpace = 0; int i = 0; while (i < text.Length && text[i++] == ' ') { startSpace++; } int j = text.Length - 1; while (j >= i && text[j--] == ' ') { endSpace++; } if (startSpace == text.Length) { endSpace += startSpace; } measured = new Vector2(width + (endSpace * 5.145f * size / 12), height); return(null); } using (Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb)) using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b)) { //Quality settings g.TextRenderingHint = graphics.TextRenderingHint; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; if (background.A > 0) { if (cornerBounds != Vector4.Zero) { fillRoundedRectangle(g, new Rectangle(0, 0, width, height), new SolidBrush(OsuMathHelper.CConvert(background)), cornerBounds); if (borderWidth > 0) { drawRoundedRectangle(g, new Rectangle(0, 0, width - (int)Math.Ceiling(borderWidth / 2f), height - (int)Math.Ceiling(borderWidth / 2f)), new Pen(OsuMathHelper.CConvert(border), borderWidth), cornerBounds); } } else { g.Clear(OsuMathHelper.CConvert(background)); if (borderWidth > 0) { g.DrawRectangle(new Pen(OsuMathHelper.CConvert(border), borderWidth), new Rectangle(borderWidth / 2, borderWidth / 2, width - borderWidth, height - borderWidth)); } } } else { g.Clear(System.Drawing.Color.FromArgb(1, color.R, color.G, color.B)); } using (Brush brush = new SolidBrush(OsuMathHelper.CConvert(color))) { if (restrictBounds != Vector2.Zero) { restrictBounds.X -= padding.X * 2; restrictBounds.Y -= padding.Y * 2; switch (shadow) { case ShadowType.Normal: g.DrawString(text, f, shadowBrush, new RectangleF(padding.X - offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, shadowBrush, new RectangleF(padding.X + offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf); break; case ShadowType.Border: Brush borderBrush = greyBrush; if (background.A == 0 && borderWidth == 1 && border.A > 0) { borderBrush = new SolidBrush(OsuMathHelper.CConvert(border)); } g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf); break; } g.DrawString(text, f, brush, new RectangleF(padding.X, padding.Y, restrictBounds.X, restrictBounds.Y), sf); } else { switch (shadow) { case ShadowType.Normal: g.DrawString(text, f, shadowBrush, padding.X - offset, padding.Y + offset); g.DrawString(text, f, shadowBrush, padding.X + offset, padding.Y + offset); break; case ShadowType.Border: Brush borderBrush = greyBrush; if (background.A == 0 && borderWidth == 1 && border.A > 0) { borderBrush = new SolidBrush(OsuMathHelper.CConvert(border)); } g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y + offset); g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y + offset); g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y - offset); g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y - offset); break; } g.DrawString(text, f, brush, padding.X, padding.Y); } } //if (lastTexture == null || lastTexture.isDisposed) { lastTexture = pTexture.FromBitmap(b); lastTexture.Disposable = true; } /*else * { * lastTexture.Width = b.Width; * lastTexture.Height = b.Height; * lastTexture.SetData(b); * }*/ return(lastTexture); } } } catch (Exception e) { measured = Vector2.Zero; return(null); } } }
private bool LoadFont(Value value) { Value path = value["url"]; string pathValue; if (path != null) { // Get the text value: pathValue = path.Text; } else { // Read the raw value: pathValue = value.Text; } DataPackage package = new DataPackage(pathValue, Document.basepath); package.onload = delegate(UIEvent e){ // Load the face - it will by default add to it's "native" family: FontFace loaded = FontLoader.Load(package.responseBytes); if (loaded == null || loaded.Family == null) { Dom.Log.Add("@font-face error: invalid font file at " + package.location.absolute); return; } // Got any weight, stretch or style overrides? Css.Value styleValue = style["font-style"]; Css.Value weightValue = style["font-weight"]; Css.Value stretchValue = style["font-stretch"]; if (styleValue != null || weightValue != null || stretchValue != null) { // Yep! // New style value: int styleV = (styleValue == null) ? loaded.Style : styleValue.GetInteger(null, Css.Properties.FontStyle.GlobalProperty); // New weight value: int weight = (weightValue == null) ? loaded.Weight : weightValue.GetInteger(null, Css.Properties.FontWeight.GlobalProperty); // New stretch value: int stretch = (stretchValue == null) ? loaded.Stretch : stretchValue.GetInteger(null, Css.Properties.FontStretch.GlobalProperty); // Update the flags: loaded.SetFlags(styleV, weight, stretch); } Value family = style["font-family"]; // Grab the family name: string familyName; if (family == null || family.Text == null) { familyName = loaded.Family.Name; } else { familyName = family.Text.Trim(); } // Add as an active font: Dictionary <string, DynamicFont> fonts = Document.ActiveFonts; DynamicFont dFont; if (!fonts.TryGetValue(familyName, out dFont)) { // Create the font object: dFont = new DynamicFont(familyName); dFont.Family = loaded.Family; fonts[familyName] = dFont; } else { // Hook up the "real" family: dFont.Family = loaded.Family; // Tell all instances using this dFont that the font is ready: Document.FontLoaded(dFont); } }; // Send now: package.send(); return(true); }
public int GetGlyphIndex(Character c) { int[] results = FontFace.GetGlyphIndices(new uint[] { c.UnicodeIndex }); return(results[0]); }
/// <summary> /// 文字描画関数に渡されるフォント構造体を初期化する /// </summary> /// <param name="font_face">フォント名の識別子</param> /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param> /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param> /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param> /// <param name="thickness">文字の太さ.</param> /// <param name="line_type">線の種類.</param> #else /// <summary> /// Initializes font structure /// </summary> /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param> /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param> /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param> /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param> /// <param name="thickness">Thickness of the text strokes. </param> /// <param name="line_type">Type of the strokes, see cvLine description. </param> #endif public CvFont(FontFace font_face, double hscale, double vscale, double shear, int thickness, LineType line_type) { this._ptr = base.AllocMemory(SizeOf); CvInvoke.cvInitFont(this._ptr, font_face, hscale, vscale, shear, thickness, line_type); }
private static void BlitCharacter(int pixelSize, int maxWidth, FullDictionary <char, CharacterInfo> dict, ref int currentX, ref int currentY, Graphics g, FontFace typeface, char c) { if (c == ' ') { int width = pixelSize / 3; if (currentX + xInterval + width >= maxWidth) { currentX = 0; currentY += yInterval + pixelSize; if (currentY + yInterval + pixelSize >= maxWidth) { throw new Exception("Texture Size not big enough for reuqired characters."); } } Bitmap glyphBitmap = new Bitmap(width + xInterval, pixelSize + yInterval); //float yoffset = pixelSize * 3 / 4 - glyph.HorizontalMetrics.Bearing.Y; g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval); CharacterInfo info = new CharacterInfo(currentX, currentY, width + xInterval, pixelSize + yInterval); dict.Add(c, info); glyphBitmap.Dispose(); currentX += width; } else { Surface surface; Glyph glyph; if (RenderGlyph(typeface, c, pixelSize, out surface, out glyph)) { if (currentX + xInterval + surface.Width >= maxWidth) { currentX = 0; currentY += yInterval + pixelSize; if (currentY + yInterval + pixelSize >= maxWidth) { throw new Exception("Texture Size not big enough for reuqired characters."); } } Bitmap glyphBitmap = GetGlyphBitmap(surface); const int a = 5; const int b = 8; //float yoffset = pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y; #if DEBUG g.DrawRectangle(redPen, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height); g.DrawRectangle(greenPen, currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1); #endif g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height); CharacterInfo info = new CharacterInfo(currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1); dict.Add(c, info); glyphBitmap.Dispose(); currentX += xInterval + surface.Width; } surface.Dispose(); } }
/// <summary> /// 文字描画関数に渡されるフォント構造体を初期化する /// </summary> /// <param name="font_face">フォント名の識別子</param> /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param> /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param> /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param> #else /// <summary> /// Initializes font structure /// </summary> /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param> /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param> /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param> /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param> #endif public CvFont(FontFace font_face, double hscale, double vscale, Double shear) : this(font_face, hscale, vscale, shear, 1, LineType.Link8) { }
public D2DFontPathData([NotNull] string text, RenderContext context, D2DFont d2dFont, FontFace fontFace, float maxWidth, float maxHeight) { Initialize(context, text, d2dFont, fontFace); Size = context.MeasureText(text, d2dFont, maxWidth, maxHeight); }
/// <summary> /// Internal Constructor to create a Game Font Data object. /// </summary> internal GameFont(FontFace ff, int size, Dictionary <char, TextCharacter> fontAtlas) { Size = size; _fontFace = ff; _fontAtlas = fontAtlas; }
public D2DFontPathData([NotNull] string text, RenderContext context, D2DFont d2dFont, FontFace fontFace) { Initialize(context, text, d2dFont, fontFace); Size = context.MeasureText(text, d2dFont); }
/// <inheritdoc/> public void Import(SpriteFontAsset options, List <char> characters) { fontSource = options.FontSource.GetFontPath(); if (string.IsNullOrEmpty(fontSource)) { return; } // Get the msdfgen.exe location var installationDir = DirectoryHelper.GetPackageDirectory("Xenko"); var binDir = UPath.Combine(installationDir, new UDirectory("Bin")); binDir = UPath.Combine(binDir, new UDirectory("Windows")); var msdfgen = UPath.Combine(binDir, new UFile("msdfgen.exe")); if (!File.Exists(msdfgen)) { throw new AssetException("Failed to compile a font asset, msdfgen was not found."); } msdfgenExe = msdfgen.FullPath; tempDir = $"{Environment.GetEnvironmentVariable("TEMP")}\\"; var factory = new Factory(); FontFace fontFace = options.FontSource.GetFontFace(); var fontMetrics = fontFace.Metrics; // Create a bunch of GDI+ objects. var fontSize = options.FontType.Size; var glyphList = new List <Glyph>(); // Remap the LineMap coming from the font with a user defined remapping // Note: // We are remapping the lineMap to allow to shrink the LineGap and to reposition it at the top and/or bottom of the // font instead of using only the top // According to http://stackoverflow.com/questions/13939264/how-to-determine-baseline-position-using-directwrite#comment27947684_14061348 // (The response is from a MSFT employee), the BaseLine should be = LineGap + Ascent but this is not what // we are experiencing when comparing with MSWord (LineGap + Ascent seems to offset too much.) // // So we are first applying a factor to the line gap: // NewLineGap = LineGap * LineGapFactor var lineGap = fontMetrics.LineGap * options.LineGapFactor; // Store the font height. LineSpacing = (float)(lineGap + fontMetrics.Ascent + fontMetrics.Descent) / fontMetrics.DesignUnitsPerEm * fontSize; // And then the baseline is also changed in order to allow the linegap to be distributed between the top and the // bottom of the font: // BaseLine = NewLineGap * LineGapBaseLineFactor BaseLine = (float)(lineGap * options.LineGapBaseLineFactor + fontMetrics.Ascent) / fontMetrics.DesignUnitsPerEm * fontSize; // Generate SDF bitmaps for each character in turn. foreach (var character in characters) { glyphList.Add(ImportGlyph(fontFace, character, fontMetrics, fontSize)); } Glyphs = glyphList; factory.Dispose(); }
/// <summary> /// Adds a font face into the font search list. /// </summary> /// <param name="fontFace">The font face to be added.</param> /// <param name="fontFamily">The font family name associated with the font face.</param> /// <param name="fontStyle">The font style associated with the font face. Mustn't be <c>Inherited</c>.</param> /// <param name="weight">The font weight associated with the font face. Must be in range <c>[100, 1000]</c>.</param> public void AddFontFace(FontFace fontFace, string fontFamily, FontStyle fontStyle, int weight) { this.fontConfig.AddFontFace(fontFace, fontFamily, fontStyle, weight); FontConfigUpdated?.Invoke(this, EventArgs.Empty); }
/// <summary> /// loads a font from a filestream and creates the gl textures for the chars /// </summary> /// <param name="fileStream">Filestream of the font file</param> /// <param name="pixelSize">The Pixel Size</param> /// <param name="fontName">The name of the font</param> /// <returns>A the game font from an font file</returns> internal static GameFont LoadFontInternal(Stream fileStream, int pixelSize, out string fontName) { FontFace ff = new FontFace(fileStream); fontName = ff.FullName; Dictionary <char, TextCharacter> fontAtlas = new Dictionary <char, TextCharacter>(); for (int i = 0; i < ushort.MaxValue; i++) { Glyph g = ff.GetGlyph(new CodePoint(i), pixelSize); if (g == null) { continue; } byte[] buf = new byte[g.RenderWidth * g.RenderHeight]; GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned); Surface s = new Surface { Bits = handle.AddrOfPinnedObject(), Width = g.RenderWidth, Height = g.RenderHeight, Pitch = g.RenderWidth }; g.RenderTo(s); Texture glTex; if (g.RenderWidth != 0 && g.RenderHeight != 0) { Bitmap bmp = new Bitmap(g.RenderWidth, g.RenderHeight); BitmapData data = bmp.LockBits(new Rectangle(0, 0, g.RenderWidth, g.RenderHeight), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); byte[] iimgBuf = new byte[buf.Length * 4]; for (int j = 0; j < buf.Length; j++) { iimgBuf[j * 4 + 3] = 255; iimgBuf[j * 4 + 1] = buf[j]; iimgBuf[j * 4 + 2] = buf[j]; iimgBuf[j * 4] = buf[j]; } Marshal.Copy(iimgBuf, 0, data.Scan0, iimgBuf.Length); bmp.UnlockBits(data); //bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); //Rotating hack data = bmp.LockBits(new Rectangle(0, 0, g.RenderWidth, g.RenderHeight), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Texture tex = TextureLoader.ParameterToTexture(bmp.Width, bmp.Height, fontName + "+" + (char)i); glTex = tex; GL.BindTexture(TextureTarget.Texture2D, tex.TextureId); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R8, g.RenderWidth, g.RenderHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); GL.TextureParameter(tex.TextureId, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TextureParameter(tex.TextureId, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GL.TextureParameter(tex.TextureId, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TextureParameter(tex.TextureId, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); bmp.UnlockBits(data); } else { glTex = null; } TextCharacter c = new TextCharacter { GlTexture = glTex, Width = s.Width, Height = s.Height, Advance = g.HorizontalMetrics.Advance, BearingX = g.HorizontalMetrics.Bearing.X, BearingY = g.HorizontalMetrics.Bearing.Y }; fontAtlas.Add((char)i, c); } GameFont font = new GameFont(ff, pixelSize, fontAtlas); return(font); }
public unsafe void Append(TextAnalyzer analyzer, FontFace font, CharBuffer charBuffer, float fontSize, int atlasWidth, RectangleF drawRect) { Append(analyzer, font, charBuffer, fontSize, atlasWidth, drawRect, RgbaByte.White); }
private Glyph ImportGlyph(Factory factory, FontFace fontFace, char character, FontMetrics fontMetrics, float fontSize, FontAntiAliasMode antiAliasMode) { var indices = fontFace.GetGlyphIndices(new int[] { character }); var metrics = fontFace.GetDesignGlyphMetrics(indices, false); var metric = metrics[0]; var width = (float)(metric.AdvanceWidth - metric.LeftSideBearing - metric.RightSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize; var height = (float)(metric.AdvanceHeight - metric.TopSideBearing - metric.BottomSideBearing) / fontMetrics.DesignUnitsPerEm * fontSize; var xOffset = (float)metric.LeftSideBearing / fontMetrics.DesignUnitsPerEm * fontSize; var yOffset = (float)(metric.TopSideBearing - metric.VerticalOriginY) / fontMetrics.DesignUnitsPerEm * fontSize; var advanceWidth = (float)metric.AdvanceWidth / fontMetrics.DesignUnitsPerEm * fontSize; //var advanceHeight = (float)metric.AdvanceHeight / fontMetrics.DesignUnitsPerEm * fontSize; var pixelWidth = (int)Math.Ceiling(width + 4); var pixelHeight = (int)Math.Ceiling(height + 4); var matrix = new RawMatrix3x2 { M11 = 1, M22 = 1, M31 = -(float)Math.Floor(xOffset) + 1, M32 = -(float)Math.Floor(yOffset) + 1 }; Bitmap bitmap; if (char.IsWhiteSpace(character)) { bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb); } else { var glyphRun = new GlyphRun { FontFace = fontFace, Advances = new[] { (float)Math.Ceiling(advanceWidth) }, FontSize = fontSize, BidiLevel = 0, Indices = indices, IsSideways = false, Offsets = new[] { new GlyphOffset() } }; RenderingMode renderingMode; if (antiAliasMode != FontAntiAliasMode.Aliased) { var rtParams = new RenderingParams(factory); renderingMode = fontFace.GetRecommendedRenderingMode(fontSize, 1.0f, MeasuringMode.Natural, rtParams); rtParams.Dispose(); } else { renderingMode = RenderingMode.Aliased; } using (var runAnalysis = new GlyphRunAnalysis(factory, glyphRun, 1.0f, matrix, renderingMode, MeasuringMode.Natural, 0.0f, 0.0f)) { var bounds = new RawRectangle(0, 0, pixelWidth, pixelHeight); bitmap = new Bitmap(pixelWidth, pixelHeight, PixelFormat.Format32bppArgb); if (renderingMode == RenderingMode.Aliased) { var texture = new byte[pixelWidth * pixelHeight]; runAnalysis.CreateAlphaTexture(TextureType.Aliased1x1, bounds, texture, texture.Length); for (int y = 0; y < pixelHeight; y++) { for (int x = 0; x < pixelWidth; x++) { int pixelX = y * pixelWidth + x; var grey = texture[pixelX]; var color = Color.FromArgb(grey, grey, grey); bitmap.SetPixel(x, y, color); } } } else { var texture = new byte[pixelWidth * pixelHeight * 3]; runAnalysis.CreateAlphaTexture(TextureType.Cleartype3x1, bounds, texture, texture.Length); for (int y = 0; y < pixelHeight; y++) { for (int x = 0; x < pixelWidth; x++) { int pixelX = (y * pixelWidth + x) * 3; var red = LinearToGamma(texture[pixelX]); var green = LinearToGamma(texture[pixelX + 1]); var blue = LinearToGamma(texture[pixelX + 2]); var color = Color.FromArgb(red, green, blue); bitmap.SetPixel(x, y, color); } } } } } var glyph = new Glyph(character, bitmap) { XOffset = -matrix.M31, XAdvance = advanceWidth, YOffset = -matrix.M32, }; return(glyph); }
/// <summary> /// Setzt die Schriftart der Instanz /// </summary> /// <param name="fontFace">zu nutzende Schriftart</param> public void SetFont(FontFace fontFace) { Font = fontFace; }
/// <summary> /// renders text string in the image /// </summary> /// <param name="img"></param> /// <param name="text"></param> /// <param name="org"></param> /// <param name="fontFace"></param> /// <param name="fontScale"></param> /// <param name="color"></param> /// <param name="thickness"></param> /// <param name="lineType"></param> /// <param name="bottomLeftOrigin"></param> public static void PutText(Mat img, string text, Point org, FontFace fontFace, double fontScale, Scalar color, int thickness = 1, LineType lineType = LineType.Link8, bool bottomLeftOrigin = false) { if (img == null) throw new ArgumentNullException("img"); if (String.IsNullOrEmpty(text)) throw new ArgumentNullException(text); img.ThrowIfDisposed(); NativeMethods.core_putText(img.CvPtr, text, org, (int)fontFace, fontScale, color, thickness, (int)lineType, bottomLeftOrigin ? 1 : 0); }
private static extern void cvePutText(IntPtr imagePtr, IntPtr text, ref Point position, FontFace fontFace, double fontScale, ref MCvScalar color, int thickness, LineType lineType, [MarshalAs(UnmanagedType.U1)] bool bottomLeftOrigin);
private static FontStyle GetStyle(FontFace face) { switch (face) { case FontFace.Bold: return FontStyle.Bold; case FontFace.Italic: return FontStyle.Italic; case FontFace.BoldItalic: return FontStyle.Bold | FontStyle.Italic; default: return FontStyle.Regular; } }
public static void DrawText(IInputOutputArray image, string text, Point position, FontFace fontFace, double fontScale, MCvScalar color, int thickness = 1, LineType lineType = LineType.EightConnected, bool bottomLeftOrigin = false) { using (CvString cvString = new CvString(text)) { using (InputOutputArray array = image.GetInputOutputArray()) { cvePutText(array, cvString, ref position, fontFace, fontScale, ref color, thickness, lineType, bottomLeftOrigin); } } }
private static SvgFontWeight MapFontWeight(FontFace face) { switch (face) { case FontFace.Bold: return SvgFontWeight.bold; default: return SvgFontWeight.normal; } }
internal unsafe static void Main(string[] args) { try { int pixelsCount = 1 << 18; uint[] pixelsArray = new uint[65536]; using (DisposableHandle handle = DisposableHandle.Alloc(pixelsArray)) { NTInvoke.SetUnmanagedMemory(handle, 255, pixelsCount); } byte[] outputData = null; MCvScalar redColor = MCvScalarExtensions.FromColor(Colors.Red); MCvScalar greenColor = MCvScalarExtensions.FromColor(Colors.Green); using (PresentationImage prImage = new PresentationImage(256, 256)) { prImage.WritePixels(pixelsArray); FontFace[] faces = new FontFace[] { FontFace.HersheyComplex, FontFace.HersheyComplexSmall, FontFace.HersheyDuplex, FontFace.HersheyPlain, FontFace.HersheyScriptComplex, FontFace.HersheyScriptSimplex, FontFace.HersheySimplex, FontFace.HersheyTriplex }; Parallel.For(0, 8, (int index) => { Point drawPoint = new Point(10, 30 + 30 * index); FontFace drawFace = faces[index]; string outputText = Enum.GetName(typeof(FontFace), drawFace); CvInvoke.DrawText(prImage, outputText, drawPoint, drawFace, 1.0D, redColor, 1); }); outputData = CvInvoke.Imencode(prImage, ImageEncoding.Jpeg, new int[] { 95 }); } if (outputData != null && outputData.Length > 0) { using (MemoryStream dataStream = new MemoryStream(outputData)) { JpegBitmapDecoder decoder = new JpegBitmapDecoder(dataStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad); BitmapFrame frame = decoder.Frames[0]; Window imageWindow = new Window() { Height = 300.0D, Width = 500.0D, Title = "Image window", ResizeMode = ResizeMode.CanResize, WindowStartupLocation = WindowStartupLocation.CenterScreen }; imageWindow.Content = new Image() { Source = frame }; new Application().Run(imageWindow); } } } catch (Exception exc) { Debug.WriteLine("\tCatched exception: {0}\r\n{1}", exc.Message, exc); } finally { Debug.WriteLine("\tData released succesfully."); } }
/// <summary> /// 文字描画関数に渡されるフォント構造体を初期化する /// </summary> /// <param name="font_face">フォント名の識別子</param> /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param> /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param> #else /// <summary> /// Initializes font structure /// </summary> /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param> /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param> /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param> #endif public CvFont(FontFace font_face, double hscale, double vscale) : this(font_face, hscale, vscale, 0, 1, LineType.Link8) { }
public void Import(FontDescription options) { var factory = new DirectWrite.Factory(); DirectWrite.Font font = null; using (var fontCollection = factory.GetSystemFontCollection(false)) { int index; if (!fontCollection.FindFamilyName(options.FontName, out index)) { // Lets try to import System.Drawing for old system bitmap fonts (like MS Sans Serif) throw new FontException(string.Format("Can't find font '{0}'.", options.FontName)); } using (var fontFamily = fontCollection.GetFontFamily(index)) { var weight = FontWeight.Regular; var style = DirectWrite.FontStyle.Normal; switch (options.Style) { case FontStyle.Bold: weight = FontWeight.Bold; break; case FontStyle.Italic: weight = FontWeight.Regular; style = DirectWrite.FontStyle.Italic; break; case FontStyle.Regular: weight = FontWeight.Regular; break; } font = fontFamily.GetFirstMatchingFont(weight, DirectWrite.FontStretch.Normal, style); } } var fontFace = new FontFace(font); var fontMetrics = fontFace.Metrics; // Create a bunch of GDI+ objects. var fontSize = PointsToPixels(options.Size); // Which characters do we want to include? var characters = CharacterRegion.Flatten(options.CharacterRegions); var glyphList = new List <Glyph>(); // Store the font height. LineSpacing = (float)(fontMetrics.LineGap + fontMetrics.Ascent + fontMetrics.Descent) / fontMetrics.DesignUnitsPerEm * fontSize; var baseLine = (float)(fontMetrics.LineGap + fontMetrics.Ascent) / fontMetrics.DesignUnitsPerEm * fontSize; // Rasterize each character in turn. foreach (char character in characters) { var glyph = ImportGlyph(factory, fontFace, character, fontMetrics, fontSize, options.AntiAlias); glyph.YOffset += baseLine; glyphList.Add(glyph); } Glyphs = glyphList; factory.Dispose(); }
/// <summary> /// 文字描画関数に渡されるフォント構造体を初期化する /// </summary> /// <param name="font_face">フォント名の識別子</param> /// <param name="hscale">幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.</param> /// <param name="vscale">高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.</param> /// <param name="shear">垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0fは≈45°を意味する.</param> /// <param name="thickness">文字の太さ.</param> #else /// <summary> /// Initializes font structure /// </summary> /// <param name="font_face">Font name identifier. Only a subset of Hershey fonts are supported now.</param> /// <param name="hscale">Horizontal scale. If equal to 1.0f, the characters have the original width depending on the font type. If equal to 0.5f, the characters are of half the original width. </param> /// <param name="vscale">Vertical scale. If equal to 1.0f, the characters have the original height depending on the font type. If equal to 0.5f, the characters are of half the original height. </param> /// <param name="shear">Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ≈45° slope, etc. thickness Thickness of lines composing letters outlines. The function cvLine is used for drawing letters. </param> /// <param name="thickness">Thickness of the text strokes. </param> #endif public CvFont(FontFace font_face, double hscale, double vscale, double shear, int thickness) : this(font_face, hscale, vscale, shear, thickness, LineType.Link8) { }
private void TextByGlyph(RectangleF rect, string text, TextInfo info, SolidColorBrush brush) { FontFace fontFace; if (!m_faceMap.TryGetValue(info.Font, out fontFace)) { using (var f = new SharpDX.DirectWrite.Factory()) using (var collection = f.GetSystemFontCollection(false)) { int familyIndex; if (!collection.FindFamilyName(info.Font.FamilylName, out familyIndex)) { return; } using (var family = collection.GetFontFamily(familyIndex)) using (var font = family.GetFont(0)) { fontFace = new FontFace(font); m_faceMap.Add(info.Font, fontFace); } } } var codePoints = EnumCodePoints(text).ToArray(); var indices = fontFace.GetGlyphIndices(codePoints); // Get glyph var metrices = fontFace.GetDesignGlyphMetrics(indices, false); // draw var glyphRun = new GlyphRun { FontFace = fontFace, Indices = indices, FontSize = info.Font.Size, }; bool done = false; using (var f = new SharpDX.DirectWrite.Factory()) using (var ff = f.QueryInterface <SharpDX.DirectWrite.Factory4>()) { var desc = new GlyphRunDescription { }; ColorGlyphRunEnumerator it; var result = ff.TryTranslateColorGlyphRun(0, 0, glyphRun, null, MeasuringMode.Natural, null, 0, out it); if (result.Code == DWRITE_E_NOCOLORLOR) { m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size), glyphRun, brush, MeasuringMode.Natural); } else { while (true) { var colorBrush = GetOrCreateBrush(new Color4( it.CurrentRun.RunColor.R, it.CurrentRun.RunColor.G, it.CurrentRun.RunColor.B, it.CurrentRun.RunColor.A)); m_device.D2DDeviceContext.DrawGlyphRun(rect.TopLeft + new Vector2(0, info.Font.Size), it.CurrentRun.GlyphRun, colorBrush, MeasuringMode.Natural); done = true; SharpDX.Mathematics.Interop.RawBool hasNext; it.MoveNext(out hasNext); if (!hasNext) { break;; } } } } }
/// <summary> /// renders text string in the image /// </summary> /// <param name="text"></param> /// <param name="org"></param> /// <param name="fontFace"></param> /// <param name="fontScale"></param> /// <param name="color"></param> /// <param name="thickness"></param> /// <param name="lineType"></param> /// <param name="bottomLeftOrigin"></param> public void PutText(string text, Point org, FontFace fontFace, double fontScale, Scalar color, int thickness = 1, LineType lineType = LineType.Link8, bool bottomLeftOrigin = false) { Cv2.PutText(this, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin); }
public ChatLine(Vector2 position, float drawDepth, float fontSize, float lineWidth, Message msg, FontFace fontFace) { this.fontSize = fontSize; nameSprite = new pText(string.Empty, fontSize, position, new Vector2(lineWidth, 0), drawDepth, true, Color.White); messageSprite = new pText(string.Empty, fontSize, position, new Vector2(lineWidth, 0), drawDepth, true, Color.White); nameSprite.FontFace = fontFace; messageSprite.FontFace = fontFace; bool isMe = msg.Name.Length > 8 && msg.Name[7] == '*' && msg.Content.Length == 0; initialColour = msg.Colour; messageSprite.Text = msg.Content; nameSprite.Text = msg.Name; nameSprite.InitialColour = initialColour; nameSprite.HandleInput = !isMe && msg.User != null; nameSprite.Tag = msg.User; nameSprite.OnHover += delegate(object sender, EventArgs args) { ((pSprite)sender).FadeColour(userFlashColour, 100); }; nameSprite.OnHoverLost += delegate(object sender, EventArgs args) { ((pSprite)sender).FadeColour(initialColour, 700); }; nameSprite.OnClick += ChatEngine.user_OnClick; nameSprite.ClickRequiresConfirmation = true; float offsetX = Math.Max(50, nameSprite.MeasureText().X); messageSprite.Position.X += offsetX; messageSprite.InitialPosition.X += offsetX; messageSprite.TextBounds.X -= offsetX; pText checkSprite = isMe ? nameSprite : messageSprite; if (msg.Colour.A != 0) { Sprites.Add(nameSprite); } Sprites.Add(messageSprite); try { if (checkSprite.Text.Length > 0 && msg.FormatterResults != null && msg.FormatterResults.Links.Count > 0) { System.Drawing.RectangleF[] characterRegions = checkSprite.MeasureCharacters(); List <int> lineBreaks = checkSprite.ComputeLineBreaks(characterRegions); foreach (Link l in msg.FormatterResults.Links) { if (l.Url.IndexOf('\uD83D') == 0 && l.Url.Length == 2) { //emoji float thisOffsetX = (int)(offsetX + checkSprite.MeasureText(0, l.Index).X - (l.Index == 0 ? 4 : 1)); string temp = ((int)l.Url[1]).ToString(); pSprite p = new pSprite(TextureManager.Load("emoji-" + temp), Fields.TopLeft, Origins.TopLeft, Clocks.Game, nameSprite.Position + new Vector2(thisOffsetX, 0), 0.975f, true, Color.White); Sprites.Add(p); } else { // First smaller or equal element. I.E. linebreak immediately before the link starts. int start = lineBreaks.BinarySearch(l.Index); if (start < 0) { start = ~start - 1; } List <pSprite> linkSprites = new List <pSprite>(); int pos = l.Index; while (pos < l.Index + l.Length) { int nextLineBreak = start >= lineBreaks.Count - 1 ? checkSprite.Text.Length : (lineBreaks[start + 1]); pos = Math.Min(nextLineBreak, l.Index + l.Length); int beginIndex = Math.Max(lineBreaks[start], l.Index); // Go backwards until we find the first character that actually has bounds. Reasoning is, that whitespaces at the end of the line can have 0,0,0,0 as rect. int end = pos - 1; while (end > beginIndex && characterRegions[end].Width == 0 && characterRegions[end].Height == 0 && characterRegions[end].X == 0 && characterRegions[end].Y == 0) { --end; } offsetX = characterRegions[beginIndex].X - 1; System.Drawing.RectangleF endRect = characterRegions[end]; float sizeX = endRect.X + endRect.Width - offsetX + 1; linkSprites.Add(AddLinkSprite(l, linkSprites, new Vector2(offsetX, fontSize * start + 1f), new Vector2(sizeX, fontSize))); ++start; } } } } } catch { } }