public static extern int ScriptTextOut( [In] IntPtr hdc, [In, Out] ref IntPtr psc, [In] int x, [In] int y, [In] ExtTextOutOptions fuOptions, [In] RECT *lprc, [In] SCRIPT_ANALYSIS *psa, [In] char *pwcReserved, [In] int iReserved, [In] ushort *pwGlyphs, [In] int cGlyphs, [In] int *piAdvance, [In] int *piJustify, [In] GOFFSET *pGoffset);
private static void ScriptTextOut(IntPtr hdc, ref IntPtr scriptCache, int x, int y, ExtTextOutOptions fuOptions, RECT* clipRect, SCRIPT_ANALYSIS* scriptAnalysis, ushort* glyphs, int glyphCount, int* glyphAdvanceWidths, int* justifiedGlyphAdvanceWidths, GOFFSET* glyphOffets) { int result = NativeMethods.ScriptTextOut(hdc, ref scriptCache, x, y, fuOptions, clipRect, scriptAnalysis, null, 0, glyphs, glyphCount, glyphAdvanceWidths, justifiedGlyphAdvanceWidths, glyphOffets); if (result != NativeConstants.S_OK) Marshal.ThrowExceptionForHR(result); }
public void ExtTextOut(Canvas surface, double x, double y, ExtTextOutOptions options, Rect dimensions, string text, double[] dx) { TextBlock block = null; Grid container = null; double deviceX = LtoDX(x); double deviceY = LtoDY(y); double textWidth; double textHeight; Geometry clipGeometry = null; if (dx == null) { // No character placement block = new TextBlock { Inlines = { new Run { Text = text } } }; ApplyTextStyle(block, deviceY, true, options); //Canvas.SetLeft(block, deviceX); surface.Children.Add(block); block.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); textHeight = block.DesiredSize.Height; textWidth = block.DesiredSize.Width; } else { // Place individual characters int stringLength = text.Length; double currentPos = 0; // LtoDX(x); container = new Grid(); for (int i = 0; i < stringLength; i++) { block = new TextBlock { Inlines = { new Run { Text = text.Substring(i, 1) } } }; //TextOptions.SetTextFormattingMode(block, TextFormattingMode.Display); ApplyTextStyle(block, deviceY, false, null); if (i > 0) { currentPos += ScaleWidth(dx[i - 1]); } block.Margin = new Thickness(currentPos, 0, 0, 0); // TODO: Character width //block.Width = dx[i]; container.Children.Add(block); } //Canvas.SetLeft(container, deviceX); ApplyTextContainerStyle(container, deviceY); surface.Children.Add(container); container.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); textHeight = container.DesiredSize.Height; textWidth = container.DesiredSize.Width; } // Horizontal alignment if ((_currentState.TextAlign & (ushort)TextAlignmentMode.TA_CENTER) == (ushort)TextAlignmentMode.TA_CENTER) { deviceX -= textWidth / 2.0; } else if ((_currentState.TextAlign & (ushort)TextAlignmentMode.TA_RIGHT) == (ushort)TextAlignmentMode.TA_RIGHT) { deviceX -= textWidth; } // Vertical Alignment if ((_currentState.TextAlign & (ushort)TextAlignmentMode.TA_BASELINE) == (ushort)TextAlignmentMode.TA_BASELINE) { double baseline; #if NETFX_CORE baseline = textHeight; #else if (block != null) { var formattedText = new FormattedText( text, System.Globalization.CultureInfo.CurrentCulture, block.FlowDirection, new Typeface(block.FontFamily, block.FontStyle, block.FontWeight, block.FontStretch, block.FontFamily), block.FontSize, block.Foreground); baseline = formattedText.Baseline; } else { baseline = textHeight; } #endif deviceY -= baseline; } else if ((_currentState.TextAlign & (ushort)TextAlignmentMode.TA_BOTTOM) == (ushort)TextAlignmentMode.TA_BOTTOM) { deviceY -= textHeight; } // Clip clipGeometry = GetClipGeometryAsChild( new Rect( deviceX, deviceY, textWidth, textHeight) ); if (container == null) { Canvas.SetLeft(block, deviceX); Canvas.SetTop(block, deviceY); #if !NETFX_CORE if (clipGeometry != null) { block.Clip = clipGeometry; } #endif } else { Canvas.SetLeft(container, deviceX); Canvas.SetTop(container, deviceY); #if !NETFX_CORE if (clipGeometry != null) { container.Clip = clipGeometry; } #endif } if ((options & ExtTextOutOptions.ETO_OPAQUE) == ExtTextOutOptions.ETO_OPAQUE) { block.Height = ScaleHeight(dimensions.Height); block.Width = ScaleWidth(dimensions.Width); } //if ((currentState.TextAlign & (ushort)TextAlignmentMode.TA_UPDATECP) == (ushort)TextAlignmentMode.TA_UPDATECP) //{ // // Update current pos // Point pos = currentState.CurrentPosition; // // TODO: Mapx and y // pos.X = Canvas.GetLeft(block) + block.ActualWidth; // pos.Y = Canvas.GetTop(block) + block.ActualHeight; // currentState.CurrentPosition = pos; //} }
private void ApplyTextStyle(TextBlock block, double y, bool applyTransforms, ExtTextOutOptions? options) { block.Foreground = new SolidColorBrush(_currentState.TextColor); if (_currentState.BackgroundMode == MixMode.OPAQUE || (options.HasValue && (options.Value & ExtTextOutOptions.ETO_OPAQUE) == ExtTextOutOptions.ETO_OPAQUE)) { #if !NETFX_CORE block.Background = new SolidColorBrush(_currentState.BackgroundColour); #endif } var font = _currentState.CurrentFont; if (font != null) { block.FontFamily = new FontFamily(font.FaceName); block.FontSize = 12; // TODO //block.FontStretch = FontStretches.UltraExpanded; // TODO if (font.Height != 0) { block.FontSize = Math.Abs(ScaleHeight(font.Height)); } if (font.IsItalic) { #if NETFX_CORE block.FontStyle = FontStyle.Italic; #else block.FontStyle = FontStyles.Italic; #endif } #if !NETFX_CORE if (font.IsStrikeout) { block.TextDecorations.Add(TextDecorations.Strikethrough); } if (font.IsUnderline) { block.TextDecorations.Add(TextDecorations.Underline); } #endif if (font.Weight > 0) { #if NETFX_CORE block.FontWeight = new FontWeight() { Weight = (ushort)font.Weight }; #else block.FontWeight = FontWeight.FromOpenTypeWeight(font.Weight); #endif } if (applyTransforms) { Canvas.SetTop(block, y - block.FontSize); // Rotation if (font.Escapement != 0) { var rotate = new RotateTransform { Angle = -1 * font.Escapement / 10.0 #if !NETFX_CORE , CenterY = block.FontSize * block.FontFamily.Baseline #endif }; block.RenderTransform = rotate; } } } }