Exemple #1
0
 public int addCharacter(char data, LinkSet ls, bool ul)
 {
     WordArea ia = null;
     int remainingWidth = this.getRemainingWidth();
     int width =
         this.currentFontState.GetWidth(currentFontState.MapCharacter(data));
     if (width > remainingWidth)
     {
         return Character.DOESNOT_FIT;
     }
     else
     {
         if (Char.IsWhiteSpace(data)
             && whiteSpaceCollapse == WhiteSpaceCollapse.TRUE)
         {
             return Character.OK;
         }
         ia = new WordArea(currentFontState, this.red, this.green,
                           this.blue, data.ToString(),
                           width);
         ia.setYOffset(placementOffset);
         ia.setUnderlined(ul);
         pendingAreas.Add(ia);
         if (Char.IsWhiteSpace(data))
         {
             this.spaceWidth = +width;
             prev = LineArea.WHITESPACE;
         }
         else
         {
             pendingWidth += width;
             prev = LineArea.TEXT;
         }
         return Character.OK;
     }
 }
Exemple #2
0
        private void addWord(char startChar, StringBuilder wordBuf)
        {
            string word = (wordBuf != null) ? wordBuf.ToString() : "";
            WordArea hia;
            int startCharWidth = getCharWidth(startChar);

            if (isAnySpace(startChar))
            {
                this.addChild(new InlineSpace(startCharWidth));
            }
            else
            {
                hia = new WordArea(currentFontState, this.red, this.green,
                                   this.blue,
                                   startChar.ToString(), 1);
                hia.setYOffset(placementOffset);
                this.addChild(hia);
            }
            int wordWidth = this.getWordWidth(word);
            hia = new WordArea(currentFontState, this.red, this.green, this.blue,
                               word, word.Length);
            hia.setYOffset(placementOffset);
            this.addChild(hia);

            finalWidth += startCharWidth + wordWidth;
        }
Exemple #3
0
 private InlineArea buildSimpleLeader(char c, int leaderLength)
 {
     int width = this.currentFontState.GetWidth(currentFontState.MapCharacter(c));
     if (width == 0)
     {
         FonetDriver.ActiveDriver.FireFonetError(
             "char '" + c + "' has width 0. Using width 100 instead.");
         width = 100;
     }
     int factor = (int)Math.Floor((decimal)leaderLength / width);
     char[] leaderChars = new char[factor];
     for (int i = 0; i < factor; i++)
     {
         leaderChars[i] = c;
     }
     WordArea leaderPatternArea = new WordArea(currentFontState, this.red,
                                               this.green, this.blue,
                                               new String(leaderChars),
                                               leaderLength);
     leaderPatternArea.setYOffset(placementOffset);
     return leaderPatternArea;
 }
Exemple #4
0
        public void AddLeader(int leaderPattern, int leaderLengthMinimum,
                              int leaderLengthOptimum, int leaderLengthMaximum,
                              int ruleStyle, int ruleThickness,
                              int leaderPatternWidth, int leaderAlignment)
        {
            WordArea leaderPatternArea;
            int leaderLength = 0;
            char dotIndex = '.';
            int dotWidth =
                currentFontState.GetWidth(currentFontState.MapCharacter(dotIndex));
            char whitespaceIndex = ' ';
            int whitespaceWidth =
                currentFontState.GetWidth(currentFontState.MapCharacter(whitespaceIndex));

            int remainingWidth = this.getRemainingWidth();

            if ((remainingWidth <= leaderLengthOptimum)
                || (remainingWidth <= leaderLengthMaximum))
            {
                leaderLength = remainingWidth;
            }
            else if ((remainingWidth > leaderLengthOptimum)
                && (remainingWidth > leaderLengthMaximum))
            {
                leaderLength = leaderLengthMaximum;
            }
            else if ((leaderLengthOptimum > leaderLengthMaximum)
                && (leaderLengthOptimum < remainingWidth))
            {
                leaderLength = leaderLengthOptimum;
            }

            if (leaderLength <= 0)
            {
                return;
            }

            switch (leaderPattern)
            {
                case LeaderPattern.SPACE:
                    InlineSpace spaceArea = new InlineSpace(leaderLength);
                    pendingAreas.Add(spaceArea);
                    break;
                case LeaderPattern.RULE:
                    LeaderArea leaderArea = new LeaderArea(fontState, red, green,
                                                           blue, "", leaderLength,
                                                           leaderPattern,
                                                           ruleThickness, ruleStyle);
                    leaderArea.setYOffset(placementOffset);
                    pendingAreas.Add(leaderArea);
                    break;
                case LeaderPattern.DOTS:
                    if (leaderPatternWidth < dotWidth)
                    {
                        leaderPatternWidth = 0;
                    }
                    if (leaderPatternWidth == 0)
                    {
                        pendingAreas.Add(this.buildSimpleLeader(dotIndex,
                                                                leaderLength));
                    }
                    else
                    {
                        if (leaderAlignment == LeaderAlignment.REFERENCE_AREA)
                        {
                            int spaceBeforeLeader =
                                this.getLeaderAlignIndent(leaderLength,
                                                          leaderPatternWidth);
                            if (spaceBeforeLeader != 0)
                            {
                                pendingAreas.Add(new InlineSpace(spaceBeforeLeader,
                                                                 false));
                                pendingWidth += spaceBeforeLeader;
                                leaderLength -= spaceBeforeLeader;
                            }
                        }

                        InlineSpace spaceBetweenDots =
                            new InlineSpace(leaderPatternWidth - dotWidth, false);

                        leaderPatternArea = new WordArea(currentFontState, this.red,
                                                         this.green, this.blue,
                                                         ".", dotWidth);
                        leaderPatternArea.setYOffset(placementOffset);
                        int dotsFactor =
                            (int)Math.Floor(((double)leaderLength)
                                / ((double)leaderPatternWidth));

                        for (int i = 0; i < dotsFactor; i++)
                        {
                            pendingAreas.Add(leaderPatternArea);
                            pendingAreas.Add(spaceBetweenDots);
                        }
                        pendingAreas.Add(new InlineSpace(leaderLength
                            - dotsFactor
                                * leaderPatternWidth));
                    }
                    break;
                case LeaderPattern.USECONTENT:
                    FonetDriver.ActiveDriver.FireFonetError(
                        "leader-pattern=\"use-content\" not supported by this version of FO.NET");
                    return;
            }
            pendingWidth += leaderLength;
            prev = TEXT;
        }
Exemple #5
0
        private void addSpacedWord(string word, LinkSet ls, int startw,
                                   int spacew, TextState textState,
                                   bool addToPending)
        {
            /*
             * Split string based on four delimeters:
             * \u00A0 - Latin1 NBSP (Non breaking space)
             * \u202F - unknown reserved character according to Unicode Standard
             * \u3000 - CJK IDSP (Ideographic space)
             * \uFEFF - Arabic ZWN BSP (Zero width no break space)
             */
            StringTokenizer st = new StringTokenizer(word, "\u00A0\u202F\u3000\uFEFF", true);
            int extraw = 0;
            while (st.MoveNext())
            {
                string currentWord = (string)st.Current;

                if (currentWord.Length == 1
                    && (isNBSP(currentWord[0])))
                {
                    // Add an InlineSpace
                    int spaceWidth = getCharWidth(currentWord[0]);
                    if (spaceWidth > 0)
                    {
                        InlineSpace ispace = new InlineSpace(spaceWidth);
                        extraw += spaceWidth;
                        if (prevUlState)
                        {
                            ispace.setUnderlined(textState.getUnderlined());
                        }
                        if (prevOlState)
                        {
                            ispace.setOverlined(textState.getOverlined());
                        }
                        if (prevLTState)
                        {
                            ispace.setLineThrough(textState.getLineThrough());
                        }

                        if (addToPending)
                        {
                            pendingAreas.Add(ispace);
                            pendingWidth += spaceWidth;
                        }
                        else
                        {
                            addChild(ispace);
                        }
                    }
                }
                else
                {
                    WordArea ia = new WordArea(currentFontState, this.red,
                                               this.green, this.blue,
                                               currentWord,
                                               getWordWidth(currentWord));
                    ia.setYOffset(placementOffset);
                    ia.setUnderlined(textState.getUnderlined());
                    prevUlState = textState.getUnderlined();
                    ia.setOverlined(textState.getOverlined());
                    prevOlState = textState.getOverlined();
                    ia.setLineThrough(textState.getLineThrough());
                    prevLTState = textState.getLineThrough();
                    ia.setVerticalAlign(vAlign);

                    if (addToPending)
                    {
                        pendingAreas.Add(ia);
                        pendingWidth += getWordWidth(currentWord);
                    }
                    else
                    {
                        addChild(ia);
                    }
                    if (ls != null)
                    {
                        Rectangle lr = new Rectangle(startw + extraw, spacew,
                                                     ia.getContentWidth(),
                                                     fontState.FontSize);
                        ls.addRect(lr, this, ia);
                    }
                }
            }
        }
Exemple #6
0
        /**
        * render inline area to PDF
        *
        * @param area inline area to render
        */

        public void RenderWordArea(WordArea area) {
            // TODO: I don't understand why we are locking the private member
            // _wordAreaPDF.  Maybe this string buffer was originally static? (MG)
            lock (_wordAreaPDF) {
                StringBuilder pdf = _wordAreaPDF;
                pdf.Length = 0;

                GdiKerningPairs kerning = null;
                bool kerningAvailable = false;

                // If no options are supplied, by default we do not enable kerning
                if (options != null && options.Kerning) {
                    kerning = area.GetFontState().Kerning;
                    if (kerning != null && (kerning.Count > 0)) {
                        kerningAvailable = true;
                    }
                }

                String name = area.GetFontState().FontName;
                int size = area.GetFontState().FontSize;

                // This assumes that *all* CIDFonts use a /ToUnicode mapping
                Font font = (Font) area.GetFontState().FontInfo.GetFontByName(name);
                bool useMultiByte = font.MultiByteFont;

                string startText = useMultiByte ? "<" : "(";
                string endText = useMultiByte ? "> " : ") ";

                if ((!name.Equals(this.currentFontName)) || (size != this.currentFontSize)) {
                    CloseText();

                    this.currentFontName = name;
                    this.currentFontSize = size;
                    pdf = pdf.Append("/" + name + " " +
                        PdfNumber.doubleOut(size/1000f) + " Tf\n");
                }

                // Do letter spacing (must be outside of [...] TJ]
                float letterspacing = ((float) area.GetFontState().LetterSpacing)/1000f;
                if (letterspacing != this.currentLetterSpacing) {
                    this.currentLetterSpacing = letterspacing;
                    CloseText();
                    pdf.Append(PdfNumber.doubleOut(letterspacing));
                    pdf.Append(" Tc\n");
                }

                PdfColor areaColor = this.currentFill;

                if (areaColor == null || areaColor.getRed() != (double) area.getRed()
                    || areaColor.getGreen() != (double) area.getGreen()
                    || areaColor.getBlue() != (double) area.getBlue()) {
                    areaColor = new PdfColor((double) area.getRed(),
                                             (double) area.getGreen(),
                                             (double) area.getBlue());


                    CloseText();
                    this.currentFill = areaColor;
                    pdf.Append(this.currentFill.getColorSpaceOut(true));
                }


                int rx = this.currentXPosition;
                int bl = this.currentYPosition;

                AddWordLines(area, rx, bl, size, areaColor);

                if (!textOpen || bl != prevWordY) {
                    CloseText();

                    pdf.Append("1 0 0 1 " + PdfNumber.doubleOut(rx/1000f) +
                        " " + PdfNumber.doubleOut(bl/1000f) + " Tm [" + startText);
                    prevWordY = bl;
                    textOpen = true;
                }
                else {
                    // express the space between words in thousandths of an em
                    int space = prevWordX - rx + prevWordWidth;
                    float emDiff = (float) space/(float) currentFontSize*1000f;
                    // this prevents a problem in Acrobat Reader where large
                    // numbers cause text to disappear or default to a limit
                    if (emDiff < -33000) {
                        CloseText();

                        pdf.Append("1 0 0 1 " + PdfNumber.doubleOut(rx/1000f) +
                            " " + PdfNumber.doubleOut(bl/1000f) + " Tm [" + startText);
                        textOpen = true;
                    }
                    else {
                        pdf.Append(PdfNumber.doubleOut(emDiff));
                        pdf.Append(" ");
                        pdf.Append(startText);
                    }
                }
                prevWordWidth = area.getContentWidth();
                prevWordX = rx;

                string s;
                if (area.getPageNumberID() != null) {
                    // This text is a page number, so resolve it
                    s = idReferences.getPageNumber(area.getPageNumberID());
                    if (s == null) {
                        s = String.Empty;
                    }
                }
                else {
                    s = area.getText();
                }

                int wordLength = s.Length;
                for (int index = 0; index < wordLength; index++) {
                    ushort ch = area.GetFontState().MapCharacter(s[index]);

                    if (!useMultiByte) {
                        if (ch > 127) {
                            pdf.Append("\\");
                            pdf.Append(Convert.ToString((int) ch, 8));

                        }
                        else {
                            switch (ch) {
                                case '(':
                                case ')':
                                case '\\':
                                    pdf.Append("\\");
                                    break;
                            }
                            pdf.Append((char) ch);
                        }
                    }
                    else {
                        pdf.Append(GetUnicodeString(ch));
                    }

                    if (kerningAvailable && (index + 1) < wordLength) {
                        ushort ch2 = area.GetFontState().MapCharacter(s[index + 1]);
                        AddKerning(pdf, ch, ch2, kerning, startText, endText);
                    }

                }
                pdf.Append(endText);

                currentStream.Write(pdf.ToString());

                this.currentXPosition += area.getContentWidth();

            }
        }
Exemple #7
0
        private void AddWordLines(WordArea area, int rx, int bl, int size,
                                  PdfColor theAreaColor) {
            if (area.getUnderlined()) {
                int yPos = bl - size/10;
                AddLine(rx, yPos, rx + area.getContentWidth(), yPos, size/14,
                        theAreaColor);
                // save position for underlining a following InlineSpace
                prevUnderlineXEndPos = rx + area.getContentWidth();
                prevUnderlineYEndPos = yPos;
                prevUnderlineSize = size/14;
                prevUnderlineColor = theAreaColor;
            }

            if (area.getOverlined()) {
                int yPos = bl + area.GetFontState().Ascender + size/10;
                AddLine(rx, yPos, rx + area.getContentWidth(), yPos, size/14,
                        theAreaColor);
                prevOverlineXEndPos = rx + area.getContentWidth();
                prevOverlineYEndPos = yPos;
                prevOverlineSize = size/14;
                prevOverlineColor = theAreaColor;
            }

            if (area.getLineThrough()) {
                int yPos = bl + area.GetFontState().Ascender*3/8;
                AddLine(rx, yPos, rx + area.getContentWidth(), yPos, size/14,
                        theAreaColor);
                prevLineThroughXEndPos = rx + area.getContentWidth();
                prevLineThroughYEndPos = yPos;
                prevLineThroughSize = size/14;
                prevLineThroughColor = theAreaColor;
            }
        }