コード例 #1
0
        } // IRtfElementVisitor.VisitTag

        void IRtfElementVisitor.VisitGroup(IRtfGroup group)
        {
            var groupDestination = group.Destination;

            switch (Context.State)
            {
            case RtfInterpreterState.Init:
                if (RtfSpec.TagRtf.Equals(groupDestination))
                {
                    VisitChildrenOf(group);
                }
                else
                {
                    throw new RtfStructureException(Strings.InvalidInitGroupState(groupDestination));
                }
                break;

            case RtfInterpreterState.InHeader:
                switch (groupDestination)
                {
                case RtfSpec.TagFontTable:
                    _fontTableBuilder.VisitGroup(group);
                    break;

                case RtfSpec.TagColorTable:
                    _colorTableBuilder.VisitGroup(group);
                    break;

                case RtfSpec.TagGenerator:
                    // last group with a destination in header, but no need to process its contents
                    Context.State = RtfInterpreterState.InDocument;
                    var generator = group.Contents.Count == 3 ? group.Contents[2] as IRtfText : null;
                    if (generator != null)
                    {
                        var generatorName = generator.Text;
                        Context.Generator = generatorName.EndsWith(";")
                                    ? generatorName.Substring(0, generatorName.Length - 1)
                                    : generatorName;
                    }
                    else
                    {
                        throw new RtfInvalidDataException(Strings.InvalidGeneratorGroup(group.ToString()));
                    }
                    break;

                case RtfSpec.TagPlain:
                case RtfSpec.TagParagraphDefaults:
                case RtfSpec.TagSectionDefaults:
                case RtfSpec.TagUnderLineNone:
                case null:
                    // <tags>: special tags commonly used to reset state in a beginning group. necessary to recognize
                    //         state transition form header to document in case no other mechanism detects it and the
                    //         content starts with a group with such a 'destination' ...
                    // 'null': group without destination cannot be part of header, but need to process its contents
                    Context.State = RtfInterpreterState.InDocument;
                    if (!group.IsExtensionDestination)
                    {
                        VisitChildrenOf(group);
                    }
                    break;
                }
                break;

            case RtfInterpreterState.InDocument:
                switch (groupDestination)
                {
                case RtfSpec.TagUserProperties:
                    _userPropertyBuilder.VisitGroup(group);
                    break;

                case RtfSpec.TagInfo:
                    _documentInfoBuilder.VisitGroup(group);
                    break;

                case RtfSpec.TagUnicodeAlternativeChoices:
                    var alternativeWithUnicodeSupport =
                        group.SelectChildGroupWithDestination(RtfSpec.TagUnicodeAlternativeUnicode);
                    if (alternativeWithUnicodeSupport != null)
                    {
                        // there is an alternative with unicode formatted content -> use this
                        VisitChildrenOf(alternativeWithUnicodeSupport);
                    }
                    else
                    {
                        // try to locate the alternative without unicode -> only ANSI fallbacks
                        var alternativeWithoutUnicode =         // must be the third element if present
                                                        group.Contents.Count > 2 ? group.Contents[2] as IRtfGroup : null;
                        if (alternativeWithoutUnicode != null)
                        {
                            VisitChildrenOf(alternativeWithoutUnicode);
                        }
                    }
                    break;

                case RtfSpec.TagHeader:
                case RtfSpec.TagHeaderFirst:
                case RtfSpec.TagHeaderLeft:
                case RtfSpec.TagHeaderRight:
                case RtfSpec.TagFooter:
                case RtfSpec.TagFooterFirst:
                case RtfSpec.TagFooterLeft:
                case RtfSpec.TagFooterRight:
                case RtfSpec.TagFootnote:
                case RtfSpec.TagStyleSheet:
                    // groups we currently ignore, so their content doesn't intermix with
                    // the actual document content
                    break;

                case RtfSpec.TagPictureWrapper:
                    VisitChildrenOf(group);
                    _lastGroupWasPictureWrapper = true;
                    break;

                case RtfSpec.TagPictureWrapperAlternative:
                    if (!_lastGroupWasPictureWrapper)
                    {
                        VisitChildrenOf(group);
                    }
                    _lastGroupWasPictureWrapper = false;
                    break;

                case RtfSpec.TagPicture:
                    _imageBuilder.VisitGroup(group);
                    NotifyInsertImage(
                        _imageBuilder.Format,
                        _imageBuilder.Width,
                        _imageBuilder.Height,
                        _imageBuilder.DesiredWidth,
                        _imageBuilder.DesiredHeight,
                        _imageBuilder.ScaleWidthPercent,
                        _imageBuilder.ScaleHeightPercent,
                        _imageBuilder.ImageDataHex);
                    break;

                case RtfSpec.TagParagraphNumberText:
                case RtfSpec.TagListNumberText:
                    NotifyInsertSpecialChar(RtfVisualSpecialCharKind.ParagraphNumberBegin);
                    VisitChildrenOf(group);
                    NotifyInsertSpecialChar(RtfVisualSpecialCharKind.ParagraphNumberEnd);
                    break;

                default:
                    if (!group.IsExtensionDestination)
                    {
                        VisitChildrenOf(group);
                    }
                    break;
                }
                break;
            }
        } // IRtfElementVisitor.VisitGroup