Ejemplo n.º 1
0
        ////////////////////////////////////////////////////////////////////
        // Character substitution
        // This program accepts character codes 32 to 126 and 160 to 255
        // If the font supports characters above 255, you can map
        // this codes into the valid region.
        ////////////////////////////////////////////////////////////////////

        public void CharSubstitution
        (
            Int32 OrigFrom,
            Int32 OrigTo,
            Int32 DestFrom
        )
        {
            // font must be embedded
            if (!EmbeddedFont)
            {
                throw new ApplicationException("Character substitution is allowed only for embedded fonts");
            }

            // create new character substitution array
            if (CharSubArray == null)
            {
                CharSubArray = new Int32[256];
                for (Int32 CharCode = 0; CharCode < 256; CharCode++)
                {
                    CharSubArray[CharCode] = CharCode;
                }
            }

            // character count
            Int32 Count = OrigTo - OrigFrom + 1;

            // get character width
            Double[] SubWidthArray = FontInfo.GetCharWidthApi(OrigFrom, OrigTo);

            // get array of glyph bounding box and width
            BoundingBox[] SubGlyphArray = FontInfo.GetGlyphMetricsApi(OrigFrom, OrigTo);

            // replace existing character width and bounding box
            for (Int32 Ptr = 0; Ptr < Count; Ptr++)
            {
                CharSubArray[DestFrom + Ptr]   = OrigFrom + Ptr;
                CharWidthArray[DestFrom + Ptr] = SubWidthArray[Ptr];
                GlyphArray[DestFrom + Ptr]     = SubGlyphArray[Ptr];
            }

            // exit
            return;
        }
Ejemplo n.º 2
0
        ////////////////////////////////////////////////////////////////////
        // Constructor
        ////////////////////////////////////////////////////////////////////

        public PdfFont
        (
            PdfDocument Document,                                       // PDF document main object
            String FontFamilyName,                                      // font family name
            FontStyle FontStyle,                                        // font style (Regular, Bold, Italic or Bold | Italic
            Boolean EmbeddedFont                                        // embed font in PDF document file
        ) : base(Document, false, "/Font")
        {
            // save embedded font flag
            this.EmbeddedFont = EmbeddedFont;

            // font style cannot be underline or strikeout
            if ((FontStyle & (FontStyle.Underline | FontStyle.Strikeout)) != 0)
            {
                throw new ApplicationException("Font resource cannot have underline or strikeout");
            }

            // create resource code
            ResourceCode = Document.GenerateResourceNumber('F');

            // get font family structure
            FontFamily = new FontFamily(FontFamilyName);

            // test font style availability
            if (!FontFamily.IsStyleAvailable(FontStyle))
            {
                throw new ApplicationException("Font style not available for font family");
            }

            // design height
            DesignHeight = FontFamily.GetEmHeight(FontStyle);

            // Ascent, descent and line spacing for a one point font
            PdfAscent      = WindowsToPdf(FontFamily.GetCellAscent(FontStyle));
            PdfDescent     = WindowsToPdf(FontFamily.GetCellDescent(FontStyle)); // positive number
            PdfLineSpacing = WindowsToPdf(FontFamily.GetLineSpacing(FontStyle));

            // create design font
            DesignFont = new Font(FontFamily, DesignHeight, FontStyle, GraphicsUnit.Pixel);

            // create windows sdk font info object
            FontInfo = new FontApi(DesignFont, DesignHeight);

            // get character width array
            CharWidthArray = FontInfo.GetCharWidthApi(0, 255);

            // get array of glyph bounding box and width
            GlyphArray = FontInfo.GetGlyphMetricsApi(0, 255);

            // reset active (used) characters to not used
            ActiveChar = new Boolean[256];

            // get outline text metrics structure
            WinOutlineTextMetric OTM = FontInfo.GetOutlineTextMetricsApi();

            // license
            if ((OTM.otmfsType & 2) != 0)
            {
                throw new ApplicationException("Font " + FontFamilyName + " is not licensed for embedding");
            }

            // make sure we have true type font and not device font
            if ((OTM.otmTextMetric.tmPitchAndFamily & 0xe) != 6)
            {
                throw new ApplicationException("Font must be True Type and vector");
            }

            // PDF font flags
            FontFlags = 0;
            if ((OTM.otmfsSelection & 1) != 0)
            {
                FontFlags |= PdfFontFlags.Italic;
            }
            // roman font is a serif font
            if ((OTM.otmTextMetric.tmPitchAndFamily >> 4) == 1)
            {
                FontFlags |= PdfFontFlags.Serif;
            }
            if ((OTM.otmTextMetric.tmPitchAndFamily >> 4) == 4)
            {
                FontFlags |= PdfFontFlags.Script;
            }
            // #define SYMBOL_CHARSET 2
            if (OTM.otmTextMetric.tmCharSet == 2)
            {
                FontFlags   |= PdfFontFlags.Symbolic;
                SymbolicFont = true;
            }
            else
            {
                FontFlags   |= PdfFontFlags.Nonsymbolic;
                SymbolicFont = false;
            }

            // #define TMPF_FIXED_PITCH 0x01 (Note very carefully that those meanings are the opposite of what the constant name implies.)
            if ((OTM.otmTextMetric.tmPitchAndFamily & 1) == 0)
            {
                FontFlags |= PdfFontFlags.FixedPitch;
            }

            // strikeout
            PdfStrikeoutPosition = WindowsToPdf(OTM.otmsStrikeoutPosition);
            PdfStrikeoutWidth    = WindowsToPdf((Int32)OTM.otmsStrikeoutSize);

            // underline
            PdfUnderlinePosition = WindowsToPdf(OTM.otmsUnderscorePosition);
            PdfUnderlineWidth    = WindowsToPdf(OTM.otmsUnderscoreSize);

            // subscript
            PdfSubscriptSize     = WindowsToPdf(OTM.otmptSubscriptSize.Y);
            PdfSubscriptPosition = WindowsToPdf(OTM.otmptSubscriptOffset.Y);

            // superscript
            PdfSuperscriptSize     = WindowsToPdf(OTM.otmptSuperscriptSize.Y);
            PdfSuperscriptPosition = WindowsToPdf(OTM.otmptSuperscriptOffset.Y);

            PdfItalicAngle = (Double)OTM.otmItalicAngle / 10.0;
            PdfFontWeight  = OTM.otmTextMetric.tmWeight;

            // exit
            return;
        }
Ejemplo n.º 3
0
        ////////////////////////////////////////////////////////////////////
        // Character substitution
        // This program accepts character codes 32 to 126 and 160 to 255
        // If the font supports characters above 255, you can map
        // this codes into the valid region.
        ////////////////////////////////////////////////////////////////////

        public void CharSubstitution
        (
            Int32 OrigFrom,
            Int32 OrigTo,
            Int32 DestFrom
        )
        {
            // font must be embedded
            if (!EmbeddedFont)
            {
                throw new ApplicationException("Character substitution is allowed only for embedded fonts");
            }

            // create new character substitution array
            if (CharSubArray == null)
            {
                // create new substitute to original array
                CharSubArray = new Int32[256];
                for (Int32 CharCode = 0; CharCode < 256; CharCode++)
                {
                    CharSubArray[CharCode] = CharCode;
                }

                // create new original character to substitute
                OrigToSubArray = new List <OrigToSub>();
            }

            // character count
            Int32 Count = OrigTo - OrigFrom + 1;

            // get character width for origin array
            Double[] SubWidthArray = FontInfo.GetCharWidthApi(OrigFrom, OrigTo);

            // get array of glyph bounding box and width for origin array
            BoundingBox[] SubGlyphArray = FontInfo.GetGlyphMetricsApi(OrigFrom, OrigTo);

            // replace existing character width and bounding box
            for (Int32 Ptr = 0; Ptr < Count; Ptr++)
            {
                // destination must be 33 to 126 or 161 to 255
                // note: space and non breaking space cannot be used for substitution
                Int32 DestChar = DestFrom + Ptr;
                if (DestChar <= ' ' || DestChar > '~' && DestChar <= 160 || DestChar > 255)
                {
                    throw new ApplicationException("Invalid character substitution. Destination must be 33 to 126 or 161 to 255.");
                }

                // search origin to substitute array
                Int32     OrigChar  = OrigFrom + Ptr;
                OrigToSub origToSub = new OrigToSub(OrigChar, DestChar);
                Int32     index     = OrigToSubArray.BinarySearch(origToSub);

                // duplicate origin overlaping substitution ranges
                if (index >= 0)
                {
                    throw new ApplicationException("CharSubstitution duplicate origin character");
                }

                // test for duplicate destination
                foreach (OrigToSub OTS in OrigToSubArray)
                {
                    if (OTS.Sub == DestChar)
                    {
                        throw new ApplicationException("CharSubstitution duplicate destibation character");
                    }
                }

                // add a new record
                OrigToSubArray.Insert(~index, origToSub);

                // save origin char in destination array
                CharSubArray[DestChar] = OrigChar;

                // change character width and glyph bounding box to origin value
                CharWidthArray[DestChar] = SubWidthArray[Ptr];
                GlyphArray[DestChar]     = SubGlyphArray[Ptr];
            }

            // exit
            return;
        }