private static YogaSize MeasureText(ReactTextShadowNode textNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            // TODO: Measure text with DirectWrite or other API that does not
            // require dispatcher access. Currently, we're instantiating a
            // second CoreApplicationView (that is never activated) and using
            // its Dispatcher thread to calculate layout.
            var textBlock = new TextBlock
            {
                TextAlignment = TextAlignment.Left,
                TextWrapping  = TextWrapping.Wrap,
                TextTrimming  = TextTrimming.CharacterEllipsis,
            };

            textNode.UpdateTextBlockCore(textBlock, true);

            for (var i = 0; i < textNode.ChildCount; ++i)
            {
                var child = textNode.GetChildAt(i);
                textBlock.Inlines.Add(ReactInlineShadowNodeVisitor.Apply(child));
            }

            var normalizedWidth  = YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width;
            var normalizedHeight = YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height;

            textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
            return(MeasureOutput.Make(
                       (float)Math.Ceiling(textBlock.DesiredSize.Width),
                       (float)Math.Ceiling(textBlock.DesiredSize.Height)));
        }
        private static MeasureOutput MeasureText(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
        {
            // This is not a terribly efficient way of projecting the height of
            // the text elements. It requires that we have access to the
            // dispatcher in order to do measurement, which, for obvious
            // reasons, can cause perceived performance issues as it will block
            // the UI thread from handling other work.
            //
            // TODO: determine another way to measure text elements.
            var task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                var textBlock = new TextBlock
                {
                    TextAlignment = TextAlignment.Left,
                    TextTrimming  = TextTrimming.CharacterEllipsis,
                };

                var textNode = (ReactTextShadowNode)node;
                textNode.UpdateTextBlockCore(textBlock, true);

                foreach (var child in textNode.Children)
                {
                    textBlock.Inlines.Add(ReactInlineShadowNodeVisitor.Apply(child));
                }

                var normalizedWidth  = CSSConstants.IsUndefined(width) ? double.PositiveInfinity : width;
                var normalizedHeight = CSSConstants.IsUndefined(height) ? double.PositiveInfinity : height;
                textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
                return(new MeasureOutput(
                           (float)textBlock.DesiredSize.Width,
                           (float)textBlock.DesiredSize.Height));
            });

            return(task.Result);
        }
Example #3
0
        private static YogaSize MeasureText(ReactTextShadowNode textNode, YogaNode node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode)
        {
            // This is not a terribly efficient way of projecting the height of
            // the text elements. It requires that we have access to the
            // dispatcher in order to do measurement, which, for obvious
            // reasons, can cause perceived performance issues as it will block
            // the UI thread from handling other work.
            //
            // TODO: determine another way to measure text elements.
            var task = DispatcherHelpers.CallOnDispatcher(() =>
            {
                var textBlock = new RichTextBlock
                {
                    TextWrapping  = TextWrapping.Wrap,
                    TextAlignment = TextAlignment.DetectFromContent,
                    TextTrimming  = TextTrimming.CharacterEllipsis,
                };

                textNode.UpdateTextBlockCore(textBlock, true);

                var block = new Paragraph();
                for (var i = 0; i < textNode.ChildCount; ++i)
                {
                    var child = textNode.GetChildAt(i);
                    block.Inlines.Add(ReactInlineShadowNodeVisitor.Apply(child));
                }
                textBlock.Blocks.Add(block);

                var normalizedWidth  = YogaConstants.IsUndefined(width) ? double.PositiveInfinity : width;
                var normalizedHeight = YogaConstants.IsUndefined(height) ? double.PositiveInfinity : height;
                textBlock.Measure(new Size(normalizedWidth, normalizedHeight));
                return(MeasureOutput.Make(
                           (float)Math.Ceiling(textBlock.DesiredSize.Width),
                           (float)Math.Ceiling(textBlock.DesiredSize.Height)));
            });

            return(task.Result);
        }