~ubuntu-branches/ubuntu/oneiric/pdfmod/oneiric

« back to all changes in this revision

Viewing changes to lib/PdfSharp/PdfSharp.Fonts.TrueType/TrueTypeDescriptor.cs

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-09-29 17:34:49 UTC
  • mfrom: (2.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100929173449-4ezagrzettatjk36
Tags: 0.9.0-1
* New upstream release
* debian/copyright: Document PdfSharp.SharpZipLib/*
* Drop all patches: committed upstream
* No change bump of Standards-Version from 3.8.4 to 3.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#region PDFsharp - A .NET library for processing PDF
2
 
//
3
 
// Authors:
4
 
//   Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
5
 
//
6
 
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
7
 
//
8
 
// http://www.pdfsharp.com
9
 
// http://sourceforge.net/projects/pdfsharp
10
 
//
11
 
// Permission is hereby granted, free of charge, to any person obtaining a
12
 
// copy of this software and associated documentation files (the "Software"),
13
 
// to deal in the Software without restriction, including without limitation
14
 
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
 
// and/or sell copies of the Software, and to permit persons to whom the
16
 
// Software is furnished to do so, subject to the following conditions:
17
 
//
18
 
// The above copyright notice and this permission notice shall be included
19
 
// in all copies or substantial portions of the Software.
20
 
//
21
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
27
 
// DEALINGS IN THE SOFTWARE.
28
 
#endregion
29
 
 
30
 
using System;
31
 
using System.Diagnostics;
32
 
using System.Globalization;
33
 
using System.Runtime.InteropServices;
34
 
using System.Text;
35
 
#if GDI
36
 
using System.Drawing;
37
 
using System.Drawing.Drawing2D;
38
 
#endif
39
 
#if WPF
40
 
using System.Windows;
41
 
using System.Windows.Media;
42
 
#endif
43
 
using PdfSharp.Pdf.Internal;
44
 
using PdfSharp.Drawing;
45
 
 
46
 
namespace PdfSharp.Fonts.TrueType
47
 
{
48
 
  /// <summary>
49
 
  /// The TrueType font desriptor.
50
 
  /// </summary>
51
 
  internal sealed class TrueTypeDescriptor : FontDescriptor
52
 
  {
53
 
    //#if 
54
 
    public TrueTypeDescriptor(XFont font, XPdfFontOptions options, XPrivateFontCollection privateFontCollection)
55
 
    {
56
 
      try
57
 
      {
58
 
        this.fontData = new FontData(font, options);
59
 
        this.fontName = font.Name;
60
 
        Initialize();
61
 
      }
62
 
      catch (Exception ex)
63
 
      {
64
 
        throw ex;
65
 
      }
66
 
    }
67
 
    //#endif
68
 
 
69
 
    //#if WPF
70
 
    //    public TrueTypeDescriptor(XFont font, XPdfFontOptions options)
71
 
    //    {
72
 
    //      try
73
 
    //      {
74
 
    //        this.fontData = new FontData(font, options);
75
 
    //        this.fontName = font.Name;
76
 
    //        Initialize();
77
 
    //      }
78
 
    //      catch (Exception ex)
79
 
    //      {
80
 
    //        throw ex;
81
 
    //      }
82
 
    //    }
83
 
    //#endif
84
 
 
85
 
    //internal TrueTypeDescriptor(FontSelector selector)
86
 
    //{
87
 
    //  throw new NotImplementedException("TrueTypeDescriptor(FontSelector selector)");
88
 
    //}
89
 
 
90
 
    internal TrueTypeDescriptor(XFont font,
91
 
      XPrivateFontCollection privateFontCollection)
92
 
      : this(font, font.PdfOptions, privateFontCollection)
93
 
    { }
94
 
 
95
 
    internal TrueTypeDescriptor(string idName, byte[] fontData)
96
 
    {
97
 
      try
98
 
      {
99
 
        this.fontData = new FontData(fontData);
100
 
        // Try to get real name form name table
101
 
        if (idName.Contains("XPS-Font-") && this.fontData.name != null && this.fontData.name.Name.Length != 0)
102
 
        {
103
 
          string tag = String.Empty;
104
 
          if (idName.IndexOf('+') == 6)
105
 
            tag = idName.Substring(0, 6);
106
 
          idName = tag + "+" + this.fontData.name.Name;
107
 
          if (this.fontData.name.Style.Length != 0)
108
 
            idName += "," + this.fontData.name.Style;
109
 
          idName = idName.Replace(" ", "");
110
 
        }
111
 
        this.fontName = idName;
112
 
        Initialize();
113
 
      }
114
 
      catch (Exception ex)
115
 
      {
116
 
        throw ex;
117
 
      }
118
 
    }
119
 
 
120
 
    internal FontData fontData;
121
 
 
122
 
    void Initialize()
123
 
    {
124
 
      bool embeddingRestricted = this.fontData.os2.fsType == 0x0002;
125
 
 
126
 
      //this.fontName = image.n
127
 
      this.italicAngle = this.fontData.post.italicAngle;
128
 
 
129
 
      this.xMin = this.fontData.head.xMin;
130
 
      this.yMin = this.fontData.head.yMin;
131
 
      this.xMax = this.fontData.head.xMax;
132
 
      this.yMax = this.fontData.head.yMax;
133
 
 
134
 
      this.underlinePosition = this.fontData.post.underlinePosition;
135
 
      this.underlineThickness = this.fontData.post.underlineThickness;
136
 
      this.strikeoutPosition = this.fontData.os2.yStrikeoutPosition;
137
 
      this.strikeoutSize = this.fontData.os2.yStrikeoutSize;
138
 
 
139
 
      // No documetation found how to get the set vertical stems width from the
140
 
      // TrueType tables.
141
 
      // The following formula comes from PDFlib Lite source code. Acrobat 5.0 sets
142
 
      // /StemV to 0 always. I think the value doesn't matter.
143
 
      //float weight = (float)(this.image.os2.usWeightClass / 65.0f);
144
 
      //this.stemV = (int)(50 + weight * weight);  // MAGIC
145
 
      this.stemV = 0;
146
 
 
147
 
      // PDFlib states that some Apple fonts miss the OS/2 table.
148
 
      Debug.Assert(fontData.os2 != null, "TrueType font has no OS/2 table.");
149
 
 
150
 
      this.unitsPerEm = fontData.head.unitsPerEm;
151
 
 
152
 
      // PDFlib takes sTypoAscender and sTypoDescender from OS/2 tabel, but GDI+ uses usWinAscent and usWinDescent
153
 
      if (fontData.os2.sTypoAscender != 0)
154
 
        this.ascender = fontData.os2.usWinAscent;
155
 
      else
156
 
        this.ascender = fontData.hhea.ascender;
157
 
      Debug.Assert(this.ascender > 0, "PDFsharp internal: Ascender should be greater than 0.");
158
 
 
159
 
      if (fontData.os2.sTypoDescender != 0)
160
 
      {
161
 
        this.descender = fontData.os2.usWinDescent;
162
 
        Debug.Assert(this.descender > 0, "PDFsharp internal: Font with non positive ascender value found.");
163
 
#if true_
164
 
        Debug.WriteLine(String.Format(CultureInfo.InvariantCulture,
165
 
          "os2.usWinDescent={0}, hhea.descender={1}, os2.sTypoDescender={2}", fontData.os2.usWinDescent, fontData.hhea.descender, fontData.os2.sTypoDescender));
166
 
#endif
167
 
        // Force sign from hhea.descender
168
 
        // TODO:
169
 
        this.descender = Math.Abs(this.descender) * Math.Sign(fontData.hhea.descender);
170
 
      }
171
 
      else
172
 
        this.descender = fontData.hhea.descender;
173
 
      Debug.Assert(this.descender < 0, "PDFsharp internal: Ascender should be less than 0.");
174
 
 
175
 
      this.leading = fontData.hhea.lineGap;
176
 
 
177
 
      // sCapHeight and sxHeight are only valid if version >= 2
178
 
      if (fontData.os2.version >= 2 && fontData.os2.sCapHeight != 0)
179
 
        this.capHeight = fontData.os2.sCapHeight;
180
 
      else
181
 
        this.capHeight = fontData.hhea.ascender;
182
 
 
183
 
      if (fontData.os2.version >= 2 && fontData.os2.sxHeight != 0)
184
 
        this.xHeight = fontData.os2.sxHeight;
185
 
      else
186
 
        this.xHeight = (int)(0.66f * this.ascender);
187
 
 
188
 
      //this.flags = this.image.
189
 
 
190
 
      Encoding ansi = PdfEncoders.WinAnsiEncoding; // System.Text.Encoding.Default;
191
 
      Encoding unicode = System.Text.Encoding.Unicode;
192
 
      byte[] bytes = new byte[256];
193
 
 
194
 
      bool symbol = this.fontData.cmap.symbol;
195
 
      this.widths = new int[256];
196
 
      for (int idx = 0; idx < 256; idx++)
197
 
      {
198
 
        bytes[idx] = (byte)idx;
199
 
        // PDFlib handles some font flaws here...
200
 
        // We wait for bug reports.
201
 
 
202
 
        char ch = (char)idx;
203
 
        string s = ansi.GetString(bytes, idx, 1);
204
 
        if (s.Length != 0)
205
 
        {
206
 
          if (s[0] != ch)
207
 
            ch = s[0];
208
 
        }
209
 
#if DEBUG
210
 
        if (idx == (int)'S')
211
 
          GetType();
212
 
#endif
213
 
        int glyphIndex;
214
 
        if (symbol)
215
 
        {
216
 
          glyphIndex = idx + (this.fontData.os2.usFirstCharIndex & 0xFF00);
217
 
          glyphIndex = CharCodeToGlyphIndex((char)glyphIndex);
218
 
        }
219
 
        else
220
 
        {
221
 
          //Debug.Assert(idx + (this.fontData.os2.usFirstCharIndex & 0xFF00) == idx);
222
 
          //glyphIndex = CharCodeToGlyphIndex((char)idx);
223
 
          glyphIndex = CharCodeToGlyphIndex(ch);
224
 
        }
225
 
        this.widths[idx] = GlyphIndexToPdfWidth(glyphIndex);
226
 
      }
227
 
    }
228
 
    public int[] widths;
229
 
 
230
 
    public override bool IsBoldFace
231
 
    {
232
 
      get
233
 
      {
234
 
        return base.IsBoldFace;
235
 
      }
236
 
    }
237
 
 
238
 
    public override bool IsItalicFace
239
 
    {
240
 
      get
241
 
      {
242
 
        return base.IsItalicFace;
243
 
      }
244
 
    }
245
 
 
246
 
    internal int DesignUnitsToPdf(double value)
247
 
    {
248
 
      return (int)Math.Round(value * 1000.0 / this.fontData.head.unitsPerEm);
249
 
    }
250
 
 
251
 
    /// <summary>
252
 
    /// Maps a unicode to the index of the corresponding glyph.
253
 
    /// See OpenType spec "cmap - Character To Glyph Index Mapping Table / Format 4: Segment mapping to delta values"
254
 
    /// for details about this a little bit strange looking algorythm.
255
 
    /// </summary>
256
 
    public int CharCodeToGlyphIndex(char value)
257
 
    {
258
 
      try
259
 
      {
260
 
        CMap4 cmap = this.fontData.cmap.cmap4;
261
 
        int segCount = cmap.segCountX2 / 2;
262
 
        int seg;
263
 
        for (seg = 0; seg < segCount; seg++)
264
 
        {
265
 
          if (value <= cmap.endCount[seg])
266
 
            break;
267
 
        }
268
 
        Debug.Assert(seg < segCount);
269
 
 
270
 
        if (value < cmap.startCount[seg])
271
 
          return 0;
272
 
 
273
 
        if (cmap.idRangeOffs[seg] == 0)
274
 
          return (value + cmap.idDelta[seg]) & 0xFFFF;
275
 
 
276
 
        int idx = cmap.idRangeOffs[seg] / 2 + (value - cmap.startCount[seg]) - (segCount - seg);
277
 
        Debug.Assert(idx >= 0 && idx < cmap.glyphCount);
278
 
 
279
 
        if (cmap.glyphIdArray[idx] == 0)
280
 
          return 0;
281
 
        else
282
 
          return (cmap.glyphIdArray[idx] + cmap.idDelta[seg]) & 0xFFFF;
283
 
      }
284
 
      catch (Exception ex)
285
 
      {
286
 
        throw ex;
287
 
      }
288
 
    }
289
 
 
290
 
    /// <summary>
291
 
    /// Converts the width of a glyph identified by its index to PDF design units.
292
 
    /// </summary>
293
 
    public int GlyphIndexToPdfWidth(int glyphIndex)
294
 
    {
295
 
      try
296
 
      {
297
 
        int numberOfHMetrics = this.fontData.hhea.numberOfHMetrics;
298
 
        int unitsPerEm = this.fontData.head.unitsPerEm;
299
 
 
300
 
        // glyphIndex >= numberOfHMetrics means the font is mono-spaced and all glyphs have the same width
301
 
        if (glyphIndex >= numberOfHMetrics)
302
 
          glyphIndex = numberOfHMetrics - 1;
303
 
 
304
 
        int width = this.fontData.hmtx.metrics[glyphIndex].advanceWidth;
305
 
 
306
 
        // Sometimes the unitsPerEm is 1000, sometimes a power of 2.
307
 
        if (unitsPerEm == 1000)
308
 
          return width;
309
 
        return width * 1000 / unitsPerEm;
310
 
      }
311
 
      catch (Exception ex)
312
 
      {
313
 
        throw ex;
314
 
      }
315
 
    }
316
 
 
317
 
    public int PdfWidthFromCharCode(char ch)
318
 
    {
319
 
      int idx = CharCodeToGlyphIndex(ch);
320
 
      int width = GlyphIndexToPdfWidth(idx);
321
 
      return width;
322
 
    }
323
 
 
324
 
#if DEBUTG
325
 
    public static void Test()
326
 
    {
327
 
      Font font = new Font("Times New Roman", 10);
328
 
      FontData image = new FontData(font);
329
 
 
330
 
//      Font font = new Font("Isabelle", 12);
331
 
//      LOGFONT logFont = new LOGFONT();
332
 
//      font.ToLogFont(logFont);
333
 
//
334
 
//      IntPtr hfont = CreateFontIndirect(logFont);
335
 
////      IntPtr hfont2 = font.ToHfont();
336
 
////      System.Windows.Forms.MessageBox.Show(hfont2.ToString());
337
 
//
338
 
//      Graphics gfx = Graphics.FromHwnd(IntPtr.Zero);
339
 
//      IntPtr hdc = gfx.GetHdc();
340
 
//      IntPtr oldFont =  SelectObject(hdc, hfont);
341
 
//      int size = GetFontData(hdc, 0, 0, null, 0);
342
 
//
343
 
//      byte[] fontbits = new byte[size];
344
 
//      int xx = GetFontData(hdc, 0, 0, fontbits, size);
345
 
//      SelectObject(hdc, oldFont);
346
 
//      DeleteObject(hfont);
347
 
//      gfx.ReleaseHdc(hdc);
348
 
//
349
 
//      FontData image = new FontData(fontbits);
350
 
//      //image.Read();
351
 
//
352
 
//
353
 
//      //HandleRef
354
 
//
355
 
//      font.GetType();
356
 
    }
357
 
#endif
358
 
  }
359
 
}
 
 
b'\\ No newline at end of file'